diff --git a/toolchain/fasmg.kl0e/docs/fasmg.txt b/toolchain/fasmg.kl0e/docs/fasmg.txt new file mode 100644 index 0000000..d00d52a --- /dev/null +++ b/toolchain/fasmg.kl0e/docs/fasmg.txt @@ -0,0 +1,1101 @@ + + + +What is flat assembler g? + +It is an assembly engine designed as a successor of the one used in +flat assembler 1, one of the recognized assemblers for x86 processors. +This is a bare engine that by itself has no ability to recognize and +encode instructions of any processor, however it has the ability to +become an assembler for any CPU architecture. It has a macroinstruction +language that is substantially improved compared to the one provided by +flat assembler 1 and it allows to easily implement instruction encoders +in form of customizable macroinstructions. + The source code of this tool can be compiled with flat assembler 1, +but it is also possible to use flat assembler g itself to compile it. +The source contains clauses that include different header files depending +on the assembler used. When flat assembler g compiles itself, it uses +the provided set of headers that implement x86 instructions and formats +with a syntax mostly compatible with flat assembler 1. + The example programs for x86 architecture that come in this package are +the selected samples that originally came with flat assembler 1 and they +use sets of headers that implement instruction encoders and output formatters +required to assemble them just like the original flat assembler did. + To demonstrate how the instruction sets of different architectures +may be implemented, there are some example programs for the microcontrollers, +8051 and AVR. They have been kept simple and therefore they do not provide +a complete framework for programming such CPUs, though they may provide +a solid base for the creation of such environments. + There is also an example of assembling the JVM bytecode, which is +a conversion of the sample originally created for flat assembler 1. For this +reason it is somewhat crude and does not fully utilize the capabilities +offered by the new engine. However it is good at visualising the structure +of a class file. + + + +How does this work? + +The essential function of flat assembler g is to generate output defined +by the instructions in the source code. Given the one line of text as +shown below, the assembler would generate a single byte with the stated +value: + + db 90h + + The macroinstructions can be defined to generate some specific +sequences of data depending on the provided parameters. They may correspond +to the instructions of chosen machine language, as in the following example, +but they could as well be defined to generate other kinds of data, for +various purposes. + + macro int number + if number = 3 + db 0CCh + else + db 0CDh, number + end if + end macro + + int 20h ; generates two bytes + + The assembly as seen this way may be considered a kind of interpreted +language, and the assembler certainly has many characteristics of the +interpreter. However it also shares certain aspects with a compiler. +It is possible for an instruction to use the value which is defined +later in the source and may depend on the instructions that come before +that definition, as demonstrated by the following sample. + + macro jmpi target + if target-($+2) < 80h & target-($+2) >= -80h + db 0EBh + db target-($+1) + else + db 0E9h + dw target-($+2) + end if + end macro + + jmpi start + db 'some data' + start: + + The "jmpi" defined above produces the code of jump instruction as +in 8086 architecture. Such code contains the relative offset of the +target of a jump, stored in either single byte or 16-bit word. +The relative offset is computed as a difference between the address +of the target and the address of the next instruction. The special +symbol "$" provides the address of current instruction and it is +used to calculate the relative offset and determine whether it may +fit in a single byte. + Therefore the code generated by "jmpi start" in the above sample +depends on the value of an address labeled as "start", and this +in turn depends on the length of the output of all the instructions +that precede it, including the said jump. This creates a loop of +dependencies and the assembler needs to find a solution that +fulfills all the constraints created by the source text. This would +not be possible if assembler was just an imperative interpreter. +Its language is thus in some aspects declarative. + Finding a solution for such circular dependencies may resemble +solving an equation, and it is even possible to construct an example +where flat assembler g is indeed capable of solving one: + + x = (x-1)*(x+2)/2-2*(x+1) + db x + + The circular reference has been reduced here to a single definition +that references itself to construct the value. The flat assembler g +is able to find a solution in this case, though in many others it may +fail. The method used by this assembler is to perform multiple passes +over the source text and then try to predict all the values with the +knowledge gathered this way. This approach is in most cases good enough +for the assembly of machine codes, but rarely suffices to solve the +complex equations and the above sample is one of the exceptions. + + + +What are the means of parsing the arguments of an instruction? + +Not all instructions have a simple syntax like then ones in the +previous examples. To aid in the processing of arguments that may +contain special constructions, flat assembler g provides a few +capable tools, demonstrated below on the examples that implement +selected few instructions of the Z80 processor. The rules governing +the use of presented features are found in the manual. + When an instruction has a very small set of allowed arguments, +each one of them can be treated separately with the "match" +construction: + + macro EX? first,second + match (=SP?), first + match =HL?, second + db 0E3h + else match =IX?, second + db 0DDh,0E3h + else match =IY?, second + db 0FDh,0E3h + else + err "incorrect second argument" + end match + else match =AF?, first + match =AF'?, second + db 08h + else + err "incorrect second argument" + end match + else match =DE?, first + match =HL?, second + db 0EBh + else + err "incorrect second argument" + end match + else + err "incorrect first argument" + end match + end macro + + EX (SP),HL + EX (SP),IX + EX AF,AF' + EX DE,HL + + The "?" character appears in many places to mark the names as +case-insensitive and all these occurrences could be removed to +further simplify the example. + When the set of possible values of an argument is larger but +has some regularities, the textual substitutions can be defined +to replace some of the symbols with carefully chosen constructions +that can then be recognized and parsed: + + A? equ [:111b:] + B? equ [:000b:] + C? equ [:001b:] + D? equ [:010b:] + E? equ [:011b:] + H? equ [:100b:] + L? equ [:101b:] + + macro INC? argument + match [:r:], argument + db 100b + r shl 3 + else match (=HL?), argument + db 34h + else match (=IX?+d), argument + db 0DDh,34h,d + else match (=IY?+d), argument + db 0FDh,34h,d + else + err "incorrect argument" + end match + end macro + + INC A + INC B + INC (HL) + INC (IX+2) + +This approach has a trait that may not always be desirable: +it allows to use an expression like "[:0:]" directly in an argument. +But it is possible to prevent exploiting the syntax in such way +by using a prefix in the "match" construction: + + REG.A? equ [:111b:] + REG.B? equ [:000b:] + REG.C? equ [:001b:] + REG.D? equ [:010b:] + REG.E? equ [:011b:] + REG.H? equ [:100b:] + REG.L? equ [:101b:] + + macro INC? argument + match [:r:], REG.argument + db 100b + r shl 3 + else match (=HL?), argument + db 34h + else match (=IX?+d), argument + db 0DDh,34h,d + else match (=IY?+d), argument + db 0FDh,34h,d + else + err "incorrect argument" + end match + end macro + + In case of an argument structured like "(IX+d)" it could sometimes +be desired to allow other algebraically equivalent forms of the +expression, like "(d+IX)" or "(c+IX+d)". Instead of parsing every +possible variant individually, it is possible to let the assembler +evaluate the expression while treating the selected symbol in a distinct +way. When a symbol is declared as an "element", it has no value and +when it is used in an expression, it is treated algebraically like +a variable term in a polynomial. + + element HL? + element IX? + element IY? + + macro INC? argument + match [:r:], REG.argument + db 100b + r shl 3 + else match (a), argument + if a eq HL + db 34h + else if a relativeto IX + db 0DDh,34h,a-IX + else if a relativeto IY + db 0FDh,34h,a-IY + else + err "incorrect argument" + end if + else + err "incorrect argument" + end match + end macro + + INC (3*8+IX+1) + + virtual at IX + x db ? + y db ? + end virtual + + INC (y) + + There is a small problem with the above macroinstruction. A parameter +may contain any text and when such value is placed into an expression, +it may induce erratic behavior. For example if "INC (1|0)" was processed, +it would turn the "a eq HL" expression into "1|0 eq HL" and this logical +expression is correct and true even though the argument was malformed. +Such unfortunate side-effect is a consequence of macroinstructions +operating on a simple principle of text substitution (and the best way +to avoid such problems is to use CALM instead). Here, to prevent it +from happening, a local variable may be used as a proxy holding the value +of an argument: + + macro INC? argument + match [:r:], REG.argument + db 100b + r shl 3 + else match (a), argument + local value + value = a + if value eq HL + db 34h + else if value relativeto IX + db 0DDh,34h,a-IX + else if value relativeto IY + db 0FDh,34h,a-IY + else + err "incorrect argument" + end if + else + err "incorrect argument" + end match + end macro + + There is an additional advantage of such proxy variable, thanks to +the fact that its value is computed before the macroinstruction begins +to generate any output. When an expression contains a symbol like "$", +it may give different values depending where it is calculated and +the use of proxy variable ensures that the value taken is the one +obtained by evaluating the argument before generating the code of +an instruction. + When the set of symbols allowed in expressions is larger, it is +better to have a single construction to process an entire family +of them. An "element" declaration may associate an additional value +with a symbol and this information can then be retrieved with +the "metadata" operator applied to a linear polynomial that contains +given symbol as a variable. The following example is another +variant of the previous macroinstruction that demonstrates the use +of this feature: + + element register + element A? : register + 111b + element B? : register + 000b + element C? : register + 001b + element D? : register + 010b + element E? : register + 011b + element H? : register + 100b + element L? : register + 101b + + element HL? + element IX? + element IY? + + macro INC? argument + local value + match (a), argument + value = a + if value eq HL + db 34h + else if value relativeto IX + db 0DDh,34h,a-IX + else if value relativeto IY + db 0FDh,34h,a-IY + else + err "incorrect argument" + end if + else match any more, argument + err "incorrect argument" + else + value = argument + if value eq value element 1 & value metadata 1 relativeto register + db 100b + (value metadata 1 - register) shl 3 + else + err "incorrect argument" + end if + end match + end macro + + The "any more" pattern is there to catch any argument that +contains a complex expressions consisting of more than one token. +This prevents the use of syntax like "INC A+0" or "INC A+B-A". +But in case of some of the instructions sets, the inclusion of such +constraint may depend on a personal preference. + The "value eq value element 1" condition ensures that the value does not +contain any terms other than the name of a register. Even when an argument +is forced to contain no more than a single token, it is still possible +that is has a complex value, for instance if there were definitions like +"X = A + B" or "Y = 2 * A". Both "INC X" and "INC Y" would then cause +the operator "element 1" to return the value "A", which differs from the +value checked in either case. + If an instruction takes a variable number of arguments, a simple +way to recognize its various forms is to declare an argument with "&" +modifier to pass the complete contents of the arguments to "match": + + element CC + + NZ? := CC + 000b + Z? := CC + 001b + NC? := CC + 010b + C? := CC + 011b + PO := CC + 100b + PE := CC + 101b + P := CC + 110b + M := CC + 111b + + macro CALL? arguments& + local cc,nn + match condition =, target, arguments + cc = condition - CC + nn = target + db 0C4h + cc shl 3 + else + nn = arguments + db 0CDh + end match + dw nn + end macro + + CALL 0 + CALL NC,2135h + +This approach also allows to handle other, more difficult cases, like when +the arguments may contain commas or are delimited in different ways. + + + +How are the labels processed? + +A standard way of defining a label is by following its name with ":" (this +also acts like a line break and any other command, including another label, +may follow in the same line). Such label simply defines a symbol with +the value equal to the current address, which initially is zero and increases +when any bytes are added into the output. + In some variants of assembly language it may be desirable to allow label +to precede an instruction without an additional ":" inbetween. It is then +necessary to create a labeled macroinstruction that after defining a label +passes processing to the original macroinstruction with the same name: + + struc INC? argument + .: + INC argument + end struc + + start INC A + INC B + +This has to be done for every instruction that needs to allow this kind +of syntax. A simple loop like the following one would suffice: + + iterate instruction, EX,INC,CALL + struc instruction? argument + .: instruction argument + end struc + end iterate + +Every built-in instruction that defines data already has the labeled variant. + By defining a labeled instruction that has "?" in place of name it is +possible to intercept every line that starts with an identifier that is not +a known instruction and is therefore assumed to be a label. The following one +would allow a label without ":" to begin any line in the source text (it also +handles the special cases so that labels followed with ":" or with "=" and +a value would still work): + + struc ? tail& + match :, tail + .: + else match : instruction, tail + .: instruction + else match == value, tail + . = value + else + .: tail + end match + end struc + +Obviously, it is no longer needed to define any specific labeled +macrointructions when a global effect of this kind is applied. A variant +should be chosen depending on the type of syntax that needs to be allowed. + Intercepting even the labels defined with ":" may become useful when the +value of current address requires some additional processing before being +assigned to a label - for example when a processor uses addresses with a +unit larger than a byte. The intercepting macroinstruction might then look +like this: + + struc ? tail& + match :, tail + label . at $ shr 1 + else match : instruction, tail + label . at $ shr 1 + instruction + else + . tail + end match + end struc + + The value of current address that is used to define labels may be altered +with "org". If the labels need to be differentiated from absolute values, +a symbol defined with "element" may be used to form an address: + + element CODEBASE + org CODEBASE + 0 + + macro CALL? argument + local value + value = argument + if value relativeto CODEBASE + db 0CDh + dw value - CODEBASE + else + err "incorrect argument" + end if + end macro + + To define labels in an address space that is not going to be reflected in +the output, a "virtual" block should be declared. The following sample +prepares macroinstructions "DATA" and "CODE" to switch between generating +program instructions and data labels. Only the instruction codes would go to +the output: + + element DATA + DATA_OFFSET = 2000h + element CODE + CODE_OFFSET = 1000h + + macro DATA? + _END + virtual at DATA + DATA_OFFSET + end macro + + macro CODE? + _END + org CODE + CODE_OFFSET + end macro + + macro _END? + if $ relativeto DATA + DATA_OFFSET = $ - DATA + end virtual + else if $ relativeto CODE + CODE_OFFSET = $ - CODE + end if + end macro + + postpone + _END + end postpone + + CODE + +The "postpone" block is used here to ensure that the "virtual" block +always gets closed correctly, even if source text ends with data +definitions. + Within the environment prepared by the above sample any instruction +would be able to distinguish data labels from the ones defined within +program. For example a branching instruction could be made to accept +an argument being either a label within a program or an absolute value, +but to disallow any label of data: + + macro CALL? argument + local value + value = argument + if value relativeto CODE + db 0CDh + dw value - CODE + else if value relativeto 0 + db 0CDh + dw value + else + err "incorrect argument" + end if + end macro + + DATA + + variable db ? + + CODE + + routine: + +In this context either "CALL routine" or "CALL 1000h" would be allowed, +while "CALL variable" would not be. + When the labels have values that are not absolute numbers, it is +possible to generate relocations for instructions that use them. +A special "virtual" block may be used to store the offsets of values +inside the program that need to be relocated when its base changes: + + virtual at 0 + Relocations:: + rw RELOCATION_COUNT + end virtual + + RELOCATION_INDEX = 0 + + postpone + RELOCATION_COUNT := RELOCATION_INDEX + end postpone + + macro WORD? value + if value relativeto CODE + store $ - CODE : 2 at Relocations : RELOCATION_INDEX shl 1 + RELOCATION_INDEX = RELOCATION_INDEX + 1 + dw value - CODE + else + dw value + end if + end macro + + macro CALL? argument + local value + value = argument + if value relativeto CODE | value relativeto 0 + db 0CDh + word value + else + err "incorrect argument" + end if + end macro + +The table of relocations that is created this way can then be accessed +with "load". The following two lines could be used to put the table +in its entirety somewhere in the output: + + load RELOCATIONS : RELOCATION_COUNT shl 1 from Relocations : 0 + dw RELOCATIONS + +The "load" reads the whole table into a single string, then "dw" writes it +into output (padded to multiple of a word, but in this case the string never +requires such padding). + For more complex types of relocations additional modifier may need to be +employed. For example, if upper and lower portions of an address needed to be +stored in separate places (likely across two instructions) and relocated +separately, necessary modifiers could be implemented as follows: + + element MOD.HIGH + element MOD.LOW + + HIGH? equ MOD.HIGH + + LOW? equ MOD.LOW + + + macro BYTE? value + if value relativeto MOD.HIGH + CODE + ; register HIGH relocation + db (value - MOD.HIGH - CODE) shr 8 + else if value relativeto MOD.LOW + CODE + ; register LOW relocation + db (value - MOD.LOW - CODE) and 0FFh + else if value relativeto MOD.HIGH + db (value - MOD.HIGH) shr 8 + else if value relativeto MOD.LOW + db (value - MOD.LOW) and 0FFh + else + db value + end if + end macro + +The commands that would register relocation have been omitted for clarity, +in this case not only offset within code but some additional information would +need to registered in appropriate structures. With such preparation, relocatable +units in code might be generated like: + + BYTE HIGH address + BYTE LOW address + +Such approach allows to easily enable syntax with modifiers in any instruction +that internally uses "byte" macroinstruction when generating code. + + + +How can multiple sections of file be generated in parallel? + +This assembly engine has a single main output that has to be generated +sequentially. This may seem problematic when the file needs to contains +distinct sections for code and data, collected from interleaved pieces that +may be spread across multiple source files. There are, however, a couple of +methods to handle it, all based in one way or another on forward-referencing +capabilities of the assembler. + A natural approach is to define contents of auxiliary section in "virtual" +block and copy it to appropriate position in the output with a single +operation. When a "virtual" block is labeled, it can be re-opened multiple +times to append more data to it. + + include '8086.inc' + org 100h + jmp CodeSection + + DataSection: + + virtual + Data:: + end virtual + + postpone + virtual Data + load Data.OctetString : $ - $$ from $$ + end virtual + end postpone + + db Data.OctetString + + CodeSection: + + virtual Data + Hello db "Hello!",24h + end virtual + + mov ah,9 + mov dx,Hello + int 21h + + virtual Data + ExitCode db 37h + end virtual + + mov ah,4Ch + mov al,[ExitCode] + int 21h + +This leads to a relatively simple syntax even without help of additional +macros. + Another method could be to put the pieces of the section into macros and +execute them all at the required position in source. A disadvantage of such +approach is that tracing errors in definitions might become a bit cumbersome. + The techniques that allow to easily append to a section generated in +parallel can also be very useful to generate data structures like relocation +tables. Instead of "store" commands used earlier when demonstrating +the concept, regular data directives could be used inside a re-opened +"virtual" block to create relocation records. + + + +What options are there to parse other kinds of syntax? + +In some cases a command that assembler needs to parse may begin with +something different than a name of instruction or a label. It may be +that a name is preceded by a special character, like "." or "!", +or that it is an entirely different kind of construction. It is then +necessary to use "macro ?" to intercept whole lines of source text +and process any special syntax of such kind. + For example, if it was required to allow a command written as ".CODE", +it would not be possible to implement it directly as a macroinstruction, +because initial dot causes the symbol to be interpreted as a local one +and globally defined instruction could never be executed this way. +The intercepting macroinstruction provides a solution: + + macro ? line& + match .=CODE?, line + CODE + else match .=DATA?, line + DATA + else + line + end match + end macro + +The lines that contain either ".CODE" or ".DATA" text are processed here +in such a way, that they invoke the global macroinstruction with +corresponding name, while all other intercepted lines are executed without +changes. This method allows to filter out any special syntax and let +the assembler process the regular instructions as usual. + Sometimes unconventional syntax is expected only in a specific area +of source text, like inside a block with defined boundaries. The +parsing macroinstruction should then be applied only in this place, +and removed with "purge" when the block ends: + + macro concise + macro ? line& + match =end =concise, line + purge ? + else match dest+==src, line + ADD dest,src + else match dest-==src, line + SUB dest,src + else match dest==src, line + LD dest,src + else match dest++, line + INC dest + else match dest--, line + DEC dest + else match any, line + err "syntax error" + end match + end macro + end macro + + concise + C=0 + B++ + A+=2 + end concise + +A macroinstruction defined this way does not intercept lines that contain +directives controlling the flow of the assembly, like "if" or "repeat", and +they can still be used freely inside such a block. This would change if +the declaration was in the form "macro ?! line&". Such a variant would +intercept every line with no exception. + Another option to catch special commands might be to use "struc ?" +to intercept only lines that do not start with a known instruction +(the initial symbol is then treated as label). Since this one only tests +unknown commands, it should cause less overhead on the assembly: + + struc (head) ? tail& + match .=CODE?, head + CODE tail + else + head tail + end match + end struc + + All these approaches hide a subtle trap. A label defined with ":" may be +followed by another instruction in the same line. If that next instruction +(which here becomes hidden in the "tail" parameter) is a control directive +like "if", putting it inside the "else" clause is going to cause broken nesting +of control blocks. A possible solution is to somehow invoke "tail" contents +outside of "match" block. One way could be to call a special macro: + + struc (head) ? tail& + local invoker + match .=CODE?, head + macro invoker + CODE tail + end macro + else + macro invoker + head tail + end macro + end match + invoker + end struc + +A simpler option is to call the original line directly and when override +is needed, cause it to be ignored with help of another line interceptor +(disposing of itself immediately after): + + struc (head) ? tail& + match .=CODE?, head + CODE tail + macro ? line& + purge ? + end macro + end match + head tail + end struc + +However, a much better way of avoiding this kinds of pitfalls is to use +CALM instructions instead of standard macros. There it is possible to +process arguments and assemble the original or modified line without +use of any control directives. CALM instructions also offer a much better +performance, which might be especially important in case of interceptors +that get called for nearly every line in source text. + + + +How to define an instruction sharing a name with one of the core directives? + + It may happen that a language can be in general easily implemented with +macros, but it needs to include a command with the same name as one of +the directives of assembler. While it is possible to override any +instruction with a macro, macros themself may require an access to +the original directive. To allow the same name call a different instruction +depending on the context, the implemented language may be interpreted +within a namespace that contains overriding macro, while all the macros +requiring access to original directive would have to temporarily switch +to another namespace where it has not have been overridden. This would +require every such macro to pack its contents in a "namespace" block. + But there is another trick, related to how texts of macro parameters +or symbolic variables preserve the context under which the symbols within +them should be interpreted (this includes the base namespace and +the parent label for symbols starting with dot). + Unlike the two mentioned occurences, the text of a macro normally does +not carry such extra information, but if a macro is constructed in such way +that it contains text that was once carried within a parameter to another +macro or within a symbolic variable, then this text retains the information +about context even when it becomes a part of a newly defined macro. +For example: + + macro definitions end? + namespace embedded + struc LABEL? size + match , size + .: + else + label . : size + end match + end struc + macro E#ND? name + end namespace + match any, name + ENTRYPOINT := name + end match + macro ?! line& + end macro + end macro + end macro + + definitions end + + start LABEL + END start + +The parameter given to "definitions" macro may appear to do nothing, as it +replaces every instance of "end" with exactly the same word - but the text +that comes from the parameter is equipped with additional information about +context, and this attribute is then preserved when the text becomes a part +of a new macro. Thanks to that, macro "LABEL" can be used in a namespace +where "end" instruction has taken a different meaning, but the instances +of "end" within its body still refer to the symbol in the outer namespace. + In this example the parameter has been made case-insensitive, and thus +it would replace even the "END" in "macro" statement that is supposed to +define a symbol in "embedded" namespace. For this reason the identifier +has been split with a concatenation operator to prevent it from being +recognized as parameter. This would not be necessary if the parameter +was case-sensitive (as more usual). + The same effect can be achieved through use of symbolic variables instead +of macro parameters, with help of "match" to extract the text of a symbolic +variable: + + define link end + match end, link + namespace embedded + struc LABEL? size + match , size + .: + else + label . : size + end match + end struc + macro END? name + end namespace + match any, name + ENTRYPOINT := name + end match + macro ?! line& + end macro + end macro + end match + + start LABEL + END start + +This would not work without passing the text through symbolic variable, +because parameters defined by control directives like "match" do not +add context information to the text unless it was already there. + CALM instructions allow for another approach to this kind of problems. +If a customized instruction set is defined entirely in form of CALM, +they may not even need an access to original control directives. +However, if CALM instruction needs to assemble a directive that might not +be accessible, the symbolic variable passed to "assemble" should be +defined with appropriate context for the instruction symbol. + + + +How to convert a macroinstruction to CALM? + +A classic macroinstruction consists of lines of text that are preprocessed +(by replacing names of parameters with their corresponding values) every time +the instruction is called and these preprocessed lines are passed to assembly. +For example this macroinstruction generates just a single line to be assembled, +and it does it by replacing "number" with the text given by the only argument +to the instruction: + + macro octet value* + db value + end macro + +A CALM instruction can be viewed as customized preprocessor, which needs to +be written in a special language. It is able to use various commands to +process the arguments and generate lines to be assembled. On the basic +level, it is also able to simulate what standard preprocessor does - with +help of "arrange" command. After preprocessing the line, it also needs to +explicitly pass it to the assembly with an "assemble" command: + + calminstruction octet value* + arrange value, =db value + assemble value + end calminstruction + +This gives the same result as the original macroinstruction, as it performs +the same kind of preprocessing. However, unlike the text of macroinstruction +a pattern given to "arrange" needs to explicitly state which name tokens are +to be replaced with their values and which ones (prepended with "=") should +be left untouched. The tokens that are copied from the pattern are stripped of +any context information, just like the text of macroinstruction is normally not +carrying any (while the values that came from arguments retain the recognition +context in which the instruction was started). + This is the most straightforward method of conversion and a simple sequence +of "arrange" and "assemble" commands could be made to generate the same lines as +by the original macroinstruction. But there is one exception - when a "local" +command is executed by macroinstruction, it creates a preprocessed parameter +with a special value that points to a symbol in the namespace unique to given +instance of the instruction. + + macro pointer + local next + dd next + next: + end macro + +In case of CALM there is no such namespace available, the local namespace of +a CALM instruction is shared among all its instances. Therefore, if a new unique +symbol is needed every time the instruction is called, it has to be constructed +manually. An obvious method might be to append a unique number to the name: + + global_uid = 0 + + calminstruction pointer + compute global_uid, global_uid + 1 + local command + arrange command, =dd =next#global_uid + assemble command + arrange command, =next#global_uid: + assemble command + end calminstruction + +Here "arrange" is given a variable that has a numeric value and it has to +replace it with a text. This works only when the value is a plan non-negative +number, in such case "arrange" converts it to a text token that contains decimal +representation of that number. The lines passed to assembly are therefore +going to contains identifiers like "next#1". + While incrementation of the global counter could be done by preparing +a standard assembly command like "global_uid = global_uid + 1" with "arrange" +and passing it to assembly, "compute" command allows to do it directly in the +CALM processor. Moreover, it is then not affected by anything that alters +the context of assembly. If the instruction was defined as unconditional and +used inside a skipped IF block, the "compute" would still perform its task, +because execution of CALM commands is - just like standard preprocessing - done +independently from the main flow of the assembly. Also, references to +the "global_uid" always point to the same symbol - the one that was in scope +when the CALM instruction was defined and compiled. Therefore incrementing +the value with "compute" is more reliable and predictable. + In a similar manner, the assembly of line defining the label can be replaced +with a "publish" command. Here the value of the label (which should be equal +to the address after the line containing "dd" is assembled) needs to be computed +first, because "publish" only performs the assignment of a value to the symbol: + + global_uid = 0 + + calminstruction pointer + compute global_uid, global_uid + 1 + local symbol, command + arrange symbol, =next#global_uid + arrange command, =dd symbol + assemble command + local address + compute address, $ + publish symbol:, address + end calminstruction + +Because the CALM instruction itself is conditional, the "publish" inside is +effectively conditional, too. Therefore it works correctly as a replacement +for the assembly of line with a label. + While a global counter has several advantages, it can be interfered with, +so sometimes use of a local counter might be preferable. However, the local +namespace of CALM instruction is not normally not accessible from outside, so +it is a bit harder to give an initial value to such counter. One way could be +to check whether the counter has already been initialized with some value using +"take" command: + + calminstruction pointer + local id + take id, id + jyes increment + compute id, 0 + increment: + compute id, id + 1 + local symbol, command + arrange symbol, =next#id + arrange command, =dd symbol + assemble command + local address + compute address, $ + publish symbol:, address + end calminstruction + +But this adds commands that are executed every time the instruction is called. +A better solution makes use of the ability to define custom instructions +processed during the definition of CALM instruction: + + calminstruction calminstruction?.init? var*, val:0 + compute val, val + publish var, val + end calminstruction + + calminstruction pointer + local id + init id, 0 + compute id, id + 1 + local symbol, command + arrange symbol, =next#id + arrange command, =dd symbol + assemble command + local address + compute address, $ + publish symbol:, address + end calminstruction + +The custom statement "init" is called at the time when the CALM instruction is +defined (it does not generate any commands to be executed by the defined +instruction - it would itself have to use "assemble" commands to generate +statements to be compiled). It is given the name of variable from the local +scope of the CALM instruction, and it uses "publish" to assign an initial +numeric value to that variable. + To initialize local variable with a symbolic value, even simpler custom +instruction would suffice: + + calminstruction calminstruction?.initsym? var*, val& + publish var, val + end calminstruction + +The text of "val" argument carries the recognition context of the definition +of CALM instruction that contains the "initsym" statement, therefore it allows +to prepare a text for "assemble" containing references to local symbols: + + calminstruction be32? value + local command + initsym command, dd value + compute value, value bswap 4 + assemble command + end calminstruction + +Again, after this intruction is compiled, it contains just two actual commands, +"compute" and "assemble", and the value of local symbol "command" is a text +that is interpreted in the same local context and refers to the same symbol +"value" as the "compute" does. + This example also demonstrates another advantage of CALM over standard +macroinstructions: its strict semantics prevent various kinds of unwanted +behavior that is allowed by a simple substitution of text. The text of "value" +is going to be evaluated by "compute" as a numeric sub-expression, signalling +an error on any unexpected syntax. Therefore it should be favorable to process +arguments entirely through CALM commands and only use "assemble" for final +simple statements. \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/docs/manual.txt b/toolchain/fasmg.kl0e/docs/manual.txt new file mode 100644 index 0000000..14de759 --- /dev/null +++ b/toolchain/fasmg.kl0e/docs/manual.txt @@ -0,0 +1,2474 @@ + + +flat assembler g +User Manual + + +This document describes the syntax of flat assembler g language, with basic +examples. It was written with an assumption that it would be read sequentially +and at any moment it uses only the concepts and constructions that have been +introduced earlier. However it should be possible to jump right to the +section that interests the reader, and then go back to earlier parts only when +it is needed in order to better understand the later ones. + + +Table of contents + +0. Executing the assembler +1. Fundamental syntax rules +2. Symbol identifiers +3. Basic symbol definitions +4. Expression values +5. Symbol classes +6. Generating data +7. Conditional assembly +8. Macroinstructions +9. Labeled macroinstructions +10. Symbolic variables and recognition context +11. Repeating blocks of instructions +12. Matching parameters +13. Output areas +14. Source and output control +15. CALM instructions +16. Assembly commands in CALM instructions + + +0. Executing the assembler + +To start assembly from the command line it is necessary to provide at least one +parameter, the name of a source file, and optionally a second one - +name of the destination file. If the assembly is successful, the generated +output is written into the destination and a short summary is displayed, +otherwise an information about errors is shown. The maximum number of presented +errors can be controlled with an additional "-e" switch (by default no more than +one error is presented). The "-p" switch controls the maximum number of passes +the assembler is going to attempt. This limit is by default set to 100. +The "-r" switch allows to set up the limit of the recursion stack, that is the +maximum allowed depth of entering macroinstructions and including additional +source files. The "-v" switch can enable showing all the lines from this stack +when reporting an error (by default the assembler tries to select only the +lines that are likely the most informative, but this simple heuristic may not +always be correct). If "-v" switch is used with value 2, it in addition makes +all the messages displayed by commands from the source text to be shown in real +time (in every consecutive pass). The "-i" switch allows to insert any command at +the beginning of processed source. + + +1. Fundamental syntax rules + +Every command in the assembly language occupies a single line of text. +If a line contains the semicolon character, everything from that character up +to the end of the line is treated as a comment and ignored by the assembler. +The main part of a line (i.e. excluding the comment) may end with the backslash +character and in such case the next line from the source text is going to be +appended to this one. This allows to split any command across multiple lines, +when needed. From now on we will refer to a source line as an entity obtained +by stripping comments and joining the lines of text connected with backslash +characters. + The text of source line is divided into syntactical units called tokens. +There is a number of special characters that become separate tokens all by +themselves. Any of the characters listed below is such a syntactical unit: + + +-/*=<>()[]{}:?!,.|&~#`\ + +Any contiguous (i.e. not broken by whitespace) sequence of characters other than +the above ones becomes a single token, which can be a name or a number. +The exception to this rule is when a sequence starts with the single or the double +quote character. This defines a quoted string and it may contain any of the +special characters, whitespace and even semicolons, as it ends only when the +same character that was used to start it is encountered. The quotes that are +used to enclose the string do not become a part of the string themselves. +If it is needed to define a string containing the same character that is used to +enclose it, the character needs to be doubled inside the string - only one copy +of the character will become a part of the string, and the sequence will +continue. + Numbers are distinguished from names by the fact that they either +begin with a decimal digit, or with the "$" character followed by any hexadecimal +digit. This means that a token can be considered numeric even when it is not a +valid number. To be a correct one it must be one of the following: a decimal +number (optionally with the letter "d" attached at the end), a binary number +followed by the letter "b", an octal number followed by the letter "o" or "q", or a +hexadecimal number either prepended with "$" or "0x", or followed by the character +"h". Because the first digit of a hexadecimal number can be a letter, it may be +needed to prepend it with the digit zero in order to make it recognizable as a number. +For example, "0Ah" is a valid number, while "Ah" is just a name. + + +2. Symbol identifiers + +Any name can become a defined symbol by having some meaning (a value) assigned to it. +One of the simplest methods of creating a symbol with a given value is to use +the "=" command: + + a = 1 + +The ":" command defines a label, that is a symbol with a value equal to the +current address in the generated output. At the beginning of the source text this +address is always zero, so when the following two commands are the first ones +in the source file, they define symbols that have identical values: + + first: + second = 0 + +Labels defined with ":" command are special constructs in assembly language, +since they allow any other command (including another label definition) to +follow in the same line. This is the only kind of command that allows this. + What comes before the ":" or "=" character in such definition is a symbol +identifier. It can be a simple name, like in the above samples, but it may +also contain some additional modifiers, described below. + When a name in a symbol definition has the "?" character appended to it (with +no whitespace between them), the symbol is case-insensitive (otherwise it would +be defined as case-sensitive). This means that the value of such +symbol may be referred to (as in an expression to the right of the "=" character) +by the name being any variant of the original name that differs only in the case +of letters. Only the cases of the 26 letters of the English alphabet are +allowed to differ, though. + It is possible to define a case-sensitive symbol that clashes with a +case-insensitive one. Then the case-sensitive symbol takes precedence and the more +general one is used only when corresponding case-sensitive symbol is not defined. +This can be remedied by using the "?" modifier, since it always means that the name +followed by it refers to the case-insensitive symbol. + + tester? = 0 + tester = 1 + TESTER = 2 + x = tester ; x = 1 + y = Tester ; y = 0 + z = TESTER ; z = 2 + t = tester? ; t = 0 + + Every symbol has its own namespace of descendants, called child namespace. When two +names are connected with a dot (with no whitespace in between), such identifier refers to +an entity named by the second one in the namespace of descendants to the symbol specified +by the first one. This operation can be repeated many times within a single identifier, +allowing to refer to descendants of descendants in a chain of any length. + + space: + space.x = 1 + space.y = 2 + space.color: + space.color.r = 0 + space.color.g = 0 + space.color.b = 0 + +Any of the names in such chain may optionally be followed by the "?" character +to mark that it refers to a case-insensitive symbol. If "?" is inserted in +the middle of the name (effectively splitting it into separate tokens) such +identifier is considered a syntactical error. + When an identifier starts with a dot (in other words: when the name of the parent +symbol is empty), it refers to the symbol in the namespace of the most recent +regular label defined before current line. This allows to rewrite the above sample +like this: + + space: + .x = 1 + .y = 2 + .color: + .color.r = 0 + .color.g = 0 + .color.b = 0 + +After the "space" label is defined, it becomes the most recently defined normal +label, so the following ".x" refers to the "space.x" symbol and then the ".color" +refers to the "space.color". + The "namespace" command followed by a symbol identifier changes the base +namespace for a section of source text. It must be paired with the +"end namespace" command later in the source to mark the end of such block. +This can be used to again rewrite the above sample in a different way: + + space: + namespace space + x = 1 + y = 2 + color: + .r = 0 + .g = 0 + .b = 0 + end namespace + +When a name is not preceded by a dot, and as such it does not have explicitly +specified in what namespace the symbol resides, the assembler looks for defined +symbol in the current namespace, and if none is found, in the consecutive namespaces +of parent symbols, starting from the namespace containing the parent symbol of +current namespace. If no defined symbol with such name is found, it is assumed that +the name refers to the symbol in the current namespace (and unless there is "?" +character after such name, it is assumed that the symbol is case-sensitive). +A definition that does not specify the namespace where the new symbol should be +created, always makes a new symbol in the current base namespace. + + global = 0 + regional = 1 + namespace regional + regional = 2 ; regional.regional = 2 + x = global ; regional.x = 0 + regional.x = regional ; regional.regional.x = 2 + global.x = global ; global.x = 0 + end namespace + +The comments in the above sample show equivalent definitions with respect +to the original base namespace. Note that when a name is used to specify the +namespace, the assembler looks for a defined symbol with such name to lookup in +its namespace, but when it is a name of a symbol to be defined, it is always +created within the current base namespace. + When the final dot of an identifier is not followed by any name, it refers +to the parent symbol of the namespace that would be searched for a symbol if +there was a name after this dot. Adding such dot at the end of an identifier may +appear redundant, but it can be used to alter the way the definition of a symbol +works, because it forces the assembler to look for an already existing symbol that +it can alter instead of squarely creating a new one in the current namespace. +For instance, if in the fourth line of the previous example "regional." was put +in place of "regional", it would rewrite a value of the original "regional" +symbol instead of making a new symbol in the child namespace. Similarly, +a definition formed this way may assign a new value to a symbol regardless of +whether it was previously defined as case-insensitive or not. + If an identifier is just a single dot, by the above rules it refers to the most +recent label that did not start with a dot. This can be applied to rewrite +the earlier example in yet another way: + + space: + namespace . + x = 1 + y = 2 + color: + namespace . + r = 0 + g = 0 + b = 0 + end namespace + end namespace + +It also demonstrates how namespace sections can be nested one within another. + The "#" may be inserted anywhere inside an identifier without changing its +meaning. When "#" is the only character separating two name tokens, it causes +them to be interpreted as a single name formed by concatenating the tokens. + + variable = 1 + varia#ble = var#iable + 2 ; variable = 3 + +This can also be applied to numbers. + Inside a block defined with "namespace" there is initially no label that would +be considered base for identifiers starting with dot (even if there was a label +that served this purpose outside of the block, it loses this status and is brought +back to use only after the block is closed with "end namespace"). A similar thing +also happens in the beginning of the source text, before any label has been defined. +This is connected to additional rules concerning dots in identifiers. + When an identifier starts with a dot, but there is no label that would be +a parent for it, the identifier refers to the descendant of a special symbol +that resides in the current namespace but has no name. If an identifier starts +with a sequence of two or more dots, the identifier refers to the descedant of +a similar unnamed symbol, but it is a distinct one for any given number of dots. +While the namespace accessed with a single starting dot changes every time a new +regular label is defined, the special namespace accessed with two or more dots +in the beginning of an identifier remains the same: + + first: + .child = 1 + ..other = 0 + second: + .child = 2 + ..another = ..other + +In this example the meaning of the ".child" identifier changes from place to +place, but the "..other" identifier means the same everywhere. + When two names inside an identifier are connected with a sequence of two or +more dots, the identifier refers to the descendant of such special unnamed +symbol in the namespace specified by the partial identifier before that sequence +of dots. The unnamed child namespace is chosen depending on a number of dots and +in this case the number of required dots is increased by one. The following +example demonstrates the two methods of identifying such symbol: + + namespace base + ..other = 1 + end namespace + + result = base.#..other + +The "#" character has been inserted into the last identifier for a better +readability, but the plain sequence of three dots would do the same. + The unnamed symbol that hosts a special namespace can itself be accessed +when an identifier ends with a sequence of two or more dots - thanks to the +rule that an identifier which ends in a dot refers to the parent symbol of +the namespace that would be accessed if there was a name after this dot. So +in the context of the previous example the "base..." (or "base.#..") would +refer to the unnamed parent of the namespace where the "other" symbol resides, +and it would be the same symbol as identified by simple ".." inside the +namespace of the "base" symbol. + Any identifier can be prepended with a "?" character and such modifier has +an effect when it is used in a context where identifier could mean something +different than a label or variable to be defined. This modifier then +suppresses any other interpretation. For example, identifier starting with "?" +is not going to be treated as an instruction, even if it is the first symbol +on the line. This can be used to define a variable that shares a name with +an existing command: + + ?namespace = 0 + +If such modified identifier is used in a place where it is evaluated and not +defined, it still refers to the same symbol it would refer to in a definition. +Therefore, unless identifier also uses a dot, it always refers to a symbol +in the current namespace. + A number can be used in a role of a name inside an identifier, but not when +it is placed at the beginning, because then it is considered a literal value. +This restriction also may be bypassed by prepending an identifier with "?". + + +3. Basic symbol definitions + +When a symbol is defined as a label, it must be the only definition of +this symbol in the entire source. A value that is assigned to the symbol this way +can be accesed from every place in the source, even before the label is actually +defined. When a symbol is used before it is defined (this is often called +forward-referencing) the assembler tries to correctly predict the value of +the symbol by doing multiple passes over the source text. Only when all +predictions prove to be correct, the assembler generates the final output. + This kind of symbol, which can only be defined once and thus have a universal +value that can always be forward-referenced, is called a constant. All labels +are constants. + When a symbol is defined with a "=" command, it may have multiple definitions +of this kind. Such symbol is called variable and when it is used, the value from +its latest definition is accessed. A symbol defined with such command may also be +forward-referenced, but only when it is defined exactly once in the entire +source and as such has a single unambiguous value. + + a = 1 ; a = 1 + a = a + 1 ; a = 2 + a = b + 1 ; a = 3 + b = 2 + + A special case of forward-referencing is self-referencing, when the value +of a symbol is used in its own definition. The assembly of such construct is +successful only when the assembler is able to find a value that is stable under +such evaluation, effectively solving an equation. But due to the simplicity +of the resolving algorithm based on predictions a solution may not be found even +when it exists. + + x = (x-1)*(x+2)/2-2*(x+1) ; x = 6 or x = -1 + + The ":=" defines a constant value. It may be used instead of "=" to +ensure that the given symbol is defined exactly once and that it can be +forward-referenced. + The "=:" defines a variable symbol like "=", but it differs in how +it treats the previous value (when such exists). While "=" discards the +previous value, "=:" preserves it so it can later be brought back with the +"restore" command: + + a = 1 + a =: 2 ; preserves a = 1 + a = 3 ; discards a = 2 and replaces it with a = 3 + restore a ; brings back a = 1 + +A "restore" may be followed by multiple symbol identifiers separated with +commas, and it discards the latest definition of every one of them. It is not +considered an error to use "restore" with a symbol that has no active +definition (either because it was never defined or because all of its +definitions were already discarded earlier). If a symbol is treated with the +"restore" command, it becomes a variable and can never be forward-referenced. +For this reason "restore" cannot be applied to constants. + The "label" keyword followed by a symbol identifier is an alternative way +of defining a label. In this basic form it is equivalent to a definition made +with ":", but it occupies an entire line. However with this command it is +possible to provide more settings for the defined label. The identifier may +be optionally followed by the ":" token and then an additional value to be +associated with this label (usually denoting the size of the labeled entity). +The assembler has a number of built-in constants defining various sizes for +this purpose, but this value can also be provided as a plain number. + + label character:byte + label char:1 + +The ":" character may be omitted in favor of a plain whitespace, but it is +recommended for clarity. After an identifier and an optional size, the "at" +keyword may follow and then a value that should be assigned to the label instead +of the current address. + + label wchar:word at char + + The built-in size constants are equivalent to the following set of +definitions: + + byte? = 1 ; 8 bits + word? = 2 ; 16 bits + dword? = 4 ; 32 bits + fword? = 6 ; 48 bits + pword? = 6 ; 48 bits + qword? = 8 ; 64 bits + tbyte? = 10 ; 80 bits + tword? = 10 ; 80 bits + dqword? = 16 ; 128 bits + xword? = 16 ; 128 bits + qqword? = 32 ; 256 bits + yword? = 32 ; 256 bits + dqqword? = 64 ; 512 bits + zword? = 64 ; 512 bits + + The "element" keyword followed by a symbol identifier defines a special +constant that has no fixed value and can be used as a variable in the linear +polynomials. The identifier may be optionally followed by the ":" token and +then a value to be associated with this symbol, called metadata of the +element. + + element A + element B:1 + + The metadata assigned to a symbol can be extracted with a special operator, +defined in the next section. + + +4. Expression values + +In every construction described so far where a value of some kind was +provided, like after the "=" command or after the "at" keyword, it could be +a literal value (a number or a quoted string) or a symbol identifier. +A value can also be specified through an expression containing built-in +operators. + The "+", "-" and "*" perform standard arithmetic operations on integers +("+" and "-" can also be used in a unary form - with only one argument). +"/" and "mod" perform division with remainder, giving a quotient or a remainder +respectively. Of these arithmetic operators "mod" has the highest precedence +(it is calculated first), "*" and "/" come next, while "+" and "-" are evaluated +last (even in their unary variants). Operators with the same precedence are +evaluated from left to right. Parentheses can be used to enclose sub-expressions +when a different order of operations is required. + The "xor", "and" and "or" perform bitwise operations on numbers. "xor" is +addition of bits (exclusive or), "and" is multiplication of bits, and "or" is +inclusive or (logical disjunction). These operators have higher precedence +than any arithmetic operators. + The "shl" and "shr" perform bit-shifting of the first argument by the amount +of bits specified by the second one. "shl" shifts bits left (towards the higher +powers of two), while "shr" shifts bits right (towards zero), dropping bits that +fall into the fractional range. These operators have higher precedence than other +binary bitwise operations. + The "not", "bsf" and "bsr" are unary operators with even higher precedence. +"not" inverts all the bits of a number, while "bsf" and "bsr" search for the +lowest or highest set bit respectively, and give the index of that bit as a +result. + All the operations on numbers are performed as if they were done on the +infinite 2-adic representations of those numbers. For example the "bsr" with a +negative number as an argument gives no valid result, since such number has an +infinite chain of set bits extending towards infinity and as such contains no +highest set bit (this is signaled as an error). + The "bswap" operator allows to create a string of bytes containing the +representation of a number in a reverse byte order (big endian). The second +argument to this operator should be the length in bytes of the required string. +This operator has the same precedence as the "shl" and "shr" operators. + When a string value is used as an argument to any of the operations on +numbers, it is treated as a sequence of bits and automatically converted into +a positive number (extended with zero bits towards the infinity). The +consecutive characters of a string correspond to the higher and higher bits of a +number. + To convert a number back to a string, the "string" unary operator may be +used. This operator has the lowest possible precedence, so when it precedes +an expression, all of it is evaluated prior to the conversion. When conversion +in the opposite direction is needed, simple unary "+" is enough to make a string +become a number. + The length of a string may be obtained with the "lengthof" unary operator, +one of the operators with the highest precedence. + The "bappend" operator appends a sequence of bytes of a string given by the +second argument to the sequence of bytes given by the first one. If either of +the arguments is a number, it becomes implicitly converted into a string. This +operator has the same precedence as binary bitwise operations. + When a symbol defined with the "element" command is used in an expression the +result may be a linear polynomial in a variable represented by the symbol. +Only simple arithmetic operations are allowed on the terms of a polynomial, +and it must stay linear - so, for example, it is only allowed to multiply a +polynomial by a number, but not by another polynomial. + There are a few operators with high precedence that allow to extract the information +about the terms of linear polynomial. The polynomial should come as the first argument, +and the index of the term as the second one. The "element" operator extracts +the variable of a polynomial term (with the coefficient of one), the "scale" operator +extracts the coefficient (a number by which the variable is multiplied) and "metadata" +operator gives back the metadata associated with the variable. + When the second argument is an index higher than the index of the last term +of the polynomial, all three operators return zero. When the second argument +is zero, "element" and "scale" give information about the constant term - +"element" returns numeric 1 and "scale" returns the value of the constant term. + + element A + linpoly = A + A + 3 + vterm = linpoly scale 1 * linpoly element 1 ; vterm = 2 * A + cterm = linpoly scale 0 * linpoly element 0 ; cterm = 3 * 1 + + The "metadata" operator with an index of zero returns the size that is associated +with the first argument. This value is definite only when the first argument is +a symbol that has a size associated with it (or an arithmetic expression +that contains such symbol), otherwise it is zero. There exists an additional +unary operator "sizeof", which gives the same value as "metadata 0". + + label table : 256 + length = sizeof table ; length = 256 + + The "elementof", "scaleof" and "metadataof" are variants of "element", "scale" +and "metadata" operators with the opposite order of arguments. Therefore when "sizeof" +is used in an expression it is equivalent to writing "0 metadataof" in its place. +These operators have even higher precendence than their counterparts and are +right-associative. + The order of the terms of the linear polynomial depends on the way in which the value +was constructed. Every arithmetic operation preserves the order of the terms in +the first argument, and the terms that were not present in the first argument are +attached at the end in the same order in which they occurred in the second argument. +This order only matters when extracting terms with appropriate operators. + The "elementsof" is another unary operator of the highest precedence, it +counts the number of variable terms of a linear polynomial. + An expression may also contain a literal value that defines a floating-point +number. Such number must be in decimal notation, it may contain "." character +as a decimal mark and may be followed by the "e" character and then a decimal +value of the exponent (optionally preceded by "+" or "-" to mark the sign of +exponent). When "." or "e" is present, it must be followed by at least +one digit. The "f" character can be appended at the end of such literal value. +If a number contains neither "." nor "e", the final "f" is the only way to +ensure that it is treated as floating-point and not as a simple decimal +integer. + The floating-point numbers are handled by the assembler in the binary form. +Their range and precision are at least as high as they are in the longest +floating-point format that the assembler is able to produce in the output. + Basic arithmetic operations are allowed to have a floating-point +number as any of the arguments, but none of the arguments may contain +a non-scalar (linear polynomial) terms then. The result of such operation is +always a floating-point number. + The unary "float" operator may be used to convert an integer value to +floating-point. This operator has the highest precedence. + The "trunc" is another unary operator with the highest precedence and it can be +applied to floating-point numbers. It extracts the integer part of a number +(it is a truncation toward zero) and the result is always a plain integer, not +a floating-point number. If the argument was already a plain integer, this +operation leaves it unchanged. + The "bsr" operator can be applied to floating-point numbers and it returns +the exponent of such number, which is the exponent of the largest power of +two that is not larger than the given number. The sign of the floating-point value +does not affect the result of this operation. + It is also allowed to use a floating-point number as the first argument +to the "shl" and "shr" operators. The number is then multiplied or divided by the +power of two specified by the second argument. + + +5. Symbol classes + +There are three distinct classes of symbols, determining the position in +source line at which the symbol may be recognized. A symbol belonging to the +instruction class is recognized only when it is the first identifier of the +command, while a symbol from the expression class is recognized only when used +to provide a value of arguments to some command. + All the types of definitions that were described in the earlier sections +create the expression class symbols. The "label" and "restore" are examples +of built-in symbols belonging to the instruction class. + In any namespace it is allowed for symbols of different classes to share the +same name, for example it is possible to define the instruction named "shl", +while there is also an operator with the same name - but an operator belongs +to the expression class. + It is even possible for a single line to contain the same identifier +meaning different things depending on its position: + + ?restore = 1 + restore restore ; remove the value of the expression-class symbol + + The third class of symbols are the labeled instructions. A symbol belonging +to this class may be recognized only when the first identifier of the command +is not an instruction - in such case the first identifier becomes a label to +the instruction defined by the second one. If we treat "=" as a special kind +of identifer, it may serve as an example of labeled instruction. + The assembler contains built-in symbols of all classes. Their names are +always case-insensitive and they may be redefined, but it is not possible to +remove them. When all the values of such symbol are removed with a command +like "restore", the built-in value persists. + The rules concerning namespace apply equally to the symbols of all classes, +for example symbol of instruction class belonging to the child namespace of +latest label can be executed by preceding its name with dot. It should be +noted, however, that when a namespace is specified through its parent symbol, +it is always a symbol belonging to the expression class. It is not possible to +refer to a child namespace of an instruction, only to the namespace belonging +to the expression class symbol with the same name. + + xor?.mask? := 10101010b + a = XOR.MASK ; symbol in the namespace of built-in case-insensitive "XOR" + + label?.test? := 0 + a = LABEL.TEST ; undefined unless "label?" is defined + +Here the namespace containing "test" belongs to an expression-class symbol, +not to the existing instruction "label". When there is no expression-class symbol +that would fit the "LABEL" specifier, the namespace chosen is the one that would +belong to the case-sensitive symbol of such name. The "test" is therefore not found, +because it has been defined in another namespace - the one of case-insensitive "label". + + +6. Generating data + +The "db" instruction allows to generate bytes of data and put them into the +output. It should be followed by one or more values, separated with commas. +When the value is numeric, it defines a single byte. When the value is a +string, it puts the string of bytes into output. + + db 'Hello',13,10 ; generate 7 bytes + +The "dup" keyword may be used to generate the same value multiple times. The +"dup" should be preceded by numeric expression defining the number of +repetitions, and the value to be repeated should follow. A sequence of values +may also be duplicated this way, in such case "dup" should be followed by the +entire sequence enclosed in parentheses (with values separated with commas). + + db 4 dup 90h ; generate 4 bytes + db 2 dup ('abc',10) ; generate 8 bytes + + When a special identifier consisting of a lone "?" character is used as a +value in the arguments to "db", it reserves a single byte. This advances the +address in the output where the next data are going to be put, but the reserved +bytes are not generated themselves unless they are followed by some other data. +Therefore if the bytes are reserved at the end of output, they do not increase +the size of generated file. This kind of data is called uninitialized, while +all the regular data are said to be initialized. + The "rb" instruction reserves a number of bytes specified by its argument. + + db ? ; reserve 1 byte + rb 7 ; reserve 7 bytes + + Every built-in instruction that generates data (traditionally called a data +directive) is paired with a labeled instruction of the same name. Such command +in addition to generating data defines a label at address of generated data, +with associated size equal to the size of data unit used by this instruction. +In case of "db" and "rb" this size is 1. + + some db sizeof some ; generate a byte with value 1 + + The "dw", "dd", "dp", "dq", "dt", "ddq", "dqq" and "ddqq" are instructions +analogous to "db" with a different sizes of data unit. The order of bytes +within a single generated unit is always little-endian. When a string of bytes +is provided as the value to any of these instructions, the generated data +is extended with zero bytes to the length which is the multiple of data unit. +The "rw", "rd", "rp", "rq", "rt", "rdq", "rqq" and "rdqq" are the instructions +that reserve a specified number of data units. The unit sizes associated with +all these instructions are listed in table 1. + The "dw", "dd", "dq", "dt" and "ddq" instructions allow floating-point +numbers as data units. Any such number is then converted into floating-point +format appropriate for a given size. + The "emit" (with a synonym "dbx") is a data directive that uses the size +of unit specified by its first argument to generate data defined by +the remaining ones. The size may be separated from the next argument with +a colon instead of a comma, for better readability. When the unit size +is such that it has a dedicated data directive, the definition made with "emit" +has the same effect as if these values were passed to the instruction tailored +for this size. + + emit 2: 0,1000,2000 ; generate three 16-bit values + + The "file" instruction reads the data from an external file and writes it +into output. The argument must be a string containing the path to the file, it +may optionally be followed by ":" and the numeric value specifying an offset +within the file, next it may be followed by comma and the numeric value +specifying how many bytes to copy. + + file 'data.bin' ; insert entire file + excerpt file 'data.bin':10h,4 ; insert selected four bytes + + + Table 1 Data directives + /------------------------------\ + | Unit | Generate | Reserve | + | (bytes) | data | data | + |=========|==========|=========| + | 1 | db | rb | + | | file | | + |---------|----------|---------| + | 2 | dw | rw | + |---------|----------|---------| + | 4 | dd | rd | + |---------|----------|---------| + | 6 | dp | rp | + |---------|----------|---------| + | 8 | dq | rq | + |---------|----------|---------| + | 10 | dt | rt | + |---------|----------|---------| + | 16 | ddq | rdq | + |---------|----------|---------| + | 32 | dqq | rqq | + |---------|----------|---------| + | 64 | ddqq | rdqq | + |---------|----------|---------| + | * | emit | | + \------------------------------/ + + +7. Conditional assembly + +The "if" instruction causes a block of source text to be assembled only +under certain condition, specified by a logical expression that is an argument +to this instruction. The "else if" command in the following lines +ends the previous conditionally assembled block and opens a new one, assembled +only when the previous conditions were not met and the new condition (an +argument to "else if") is true. The "else" command ends the previous +conditionally assembled block and begins a block that is assembled only when +none of the previous conditions was true. The "end if" command should be used +to end the entire construction. There may be many or none "else if" commands +inside and no more than one "else". + A logical expression is a distinct syntactical entity from the basic +expressions that were described earlier. A logical expression consists of +logical values connected with logical operators. The logical operators are: +unary "~" for negation, "&" for conjunction and "|" for alternative. +The negation is evaluated first, while "&" and "|" are simply evaluated +from left to right, with no precedence over each other. + A logical value in its simplest form may be a basic expression, it then +corresponds to true condition if and only if its value is not constant zero. +Another way to create a logical value is to compare the values of two basic +expressions with one of the following operators: "=" (equal), "<" (less than), +">" (greater than), "<=" (less or equal), ">=" (greater or equal), +"<>" (not equal). + + count = 2 + if count > 1 + db '0' + db count-1 dup ',0' + else if count = 1 + db '0' + end if + + When linear polynomials are compared this way, the logical value is +valid only when they are comparable, which is whey they differ in constant +term only. Otherwise the condition like equality is neither universally true +nor universally false, since it depends on the values substituted for variables, +and assembler signals this as an error. + The "relativeto" operator creates a logical value that is true only when +the difference of compared values does not contain any variable terms. Therefore +it can be used to check whether two linear polynomials are comparable - the +"relativeto" condition is true only when both compared polynomials have the same +variable terms. + Because logical expressions are lazily evaluated, it is possible to create +a single condition that will not cause an error when the polynomials are not +comparable, but will compare them if they are: + + if a relativeto b & a > b + db a - b + end if + + The "eqtype" operator can also be used to compare two basic expressions, +it makes a logical value which is true when the values of the expressions are +of the same type - either both are algebraic, both are strings or both are +floating-point numbers. An algebraic type covers the linear polynomials and +it includes the integer values. + The "eq" operator compares two basic expressions and creates a logical value +which is true only when their values are of the same type and equal. This operator +can be used to check whether a value is a certain string, a certain floating-point +number or a certain linear polynomial. It can compare values that are not +comparable with "=" operator. + The "defined" operator creates a logical value combined with a basic expression +that follows it. This condition is true when the expression does not contain +symbols that have no accessible definition. The expression is only tested for the +availability of its components, it does not need to have a computable value. +This can be used to check whether a symbol of expression class has been defined, +but since the symbol can be accessible through forward-referencing, this condition +may be true even when the symbol is defined later in source. If this is undesirable, +the "definite" operator should be used instead, as it checks whether all symbols +within a basic expression that follows have been defined earlier. + The basic expression that follows "defined" is also allowed to be empty and +the condition is then trivially satisfied. This does not apply to "definite". + The "used" operator forms a logical value if it is followed by a single +identifier. This condition is true when the value of specified symbol has +been used anywhere in the source. + The "assert" is an instruction that signalizes an error when a condition +specified by its argument is not met. + + assert a < 65536 + + +8. Macroinstructions + +The "macro" command allows to define a new instruction, in form of a +macroinstruction. The block of source text between the "macro" and +"end macro" command becomes the text of macroinstruction and this sequence +of lines is assembled in place of the original command that starts with +identifier of instruction defined this way. + + macro null + db 0 + end macro + + null ; "db 0" is assembled here + + The macroinstruction is allowed to have arguments only when the +definition contains them. After the "macro" and the identifier of defined +symbol optionally may come a list of simple names separated with commas, +these names define the parameters of macroinstruction. When this instruction +is then used, it may be followed by at most the same number of arguments +separated with commas, and their values are assigned to the consecutive +parameters. Before any line of text inside the macroinstruction is interpreted, +the name tokens that correspond to any of the parameters are replaced with their +assigned values. + + macro lower name,value + name = value and 0FFh + end macro + + lower a,123h ; a = 23h + +The value of a parameter can be any text, not necessarily a correct expression. +If a line calling the macroinstruction contains fewer arguments than the +number of defined parameters, the excess parameters receive the empty values. + When a name of a parameter is defined, it may be followed by "?" character +to denote that it is case-insensitive, analogously to a name in a symbol +identifier. There must be no whitespace between the name and "?". +A definition of a parameter may also be followed by "*" to denote that it +requires a value that is not empty, or alternatively by ":" character +followed by a default value, which is assigned to the parameter instead of +an empty one when no other value is provided. + + macro prepare name*,value:0 + name = value + end macro + + prepare x ; x = 0 + prepare y,1 ; y = 1 + + If an argument to macroinstruction needs to contain a comma character, the +entire argument must be enclosed between the "<" and ">" characters (they do +not become a part of the value). If another "<" character is encountered inside +such value, it must be balanced with corresponding ">" character inside the +same value. + + macro data name,value + name: + .data db value + .end: + end macro + + data example, <'abc',10> + + The last defined parameter may be followed by "&" character to denote that +this parameter should be assigned a value containing the entire remaining +part of line, even if it normally would define multiple arguments. Therefore +when macroinstruction has just one parameter followed by "&", the value of +this parameter is the entire text of arguments following the instruction. + + macro id first,rest& + dw first + db rest + end macro + + id 2, 7,1,8 + + When a name of a parameter is to be replaced with its value and it is +preceded by "`" character (without any whitespace inbetween), the text of +the value is embedded into a quoted string and this string replaces +both the "`" character and the name of parameter. + + macro text line& + db `line + end macro + + text x+1 ; db 'x+1' + + The "local" is a command that may only be used inside a macroinstruction. +It should be followed by one or more names separated with commas, and it +declares that the names from this list should in the context of current +macroinstruction be interpreted as belonging to a special namespace +associated with this macroinstruction instead of current base namespace. This +allows to create unique symbols every time the macroinstruction is called. +Such declaration defines additional parameters with the specified names and +therefore only affects the uses of those names that follow within the same +macroinstruction. Declaring the same name as local multiple times within +the same macroinstruction gives no additional effect. + + macro measured name,string + local top + name db string + top: name.length = top - name + end macro + + measured hello, 'Hello!' ; hello.length = 6 + +A parameter created with "local" becomes replaced with a text that contains +the same name as the name of parameter, but has added context information +that causes it to be identified as belonging to the unique local namespace +associated with the instance of macroinstruction. This kind of context +information is going to be discussed further in the section about +symbolic variables. + A symbol that is local to a macroinstruction is never considered the most +recent label that is base for symbols starting with dot. Moreover, its +descendant namespace is disconnected from the main tree of symbols, so if +"namespace" command was used with a local symbol as the argument, symbols +from the main tree would no longer be visible (including all the named +instructions of the assembler, even commands like "end namespace"). + Just like an expression symbol may be redefined and refer to its previous +value in the definition of the new one, the macroinstructions can also be +redefined, and use the previous value of this instruction symbol in its +text: + + macro zero + db 0 + end macro + + macro zero name + label name:byte + zero + end macro + + zero x + +And just like other symbols, a macroinstruction may be forward-referenced when +it is defined exactly once in the entire source. + The "purge" command discards the definition of a symbol just like "restore", +but it does so for the symbol of instruction class. It behaves in the same +way as "restore" in all the other aspects. A macroinstruction can remove its +own definition with "purge". + It is possible for a macroinstruction to use its own value in a recursive way, +but to avoid inadvertent infinite recursion this feature is only available when +the macroinstruction is marked as such by following its identifier with ":" +character. + + macro factorial: n + if n + factorial n-1 + result = result * (n) + else + result = 1 + end if + end macro + +In addition to allowing recursion, such macroinstruction behaves like a constant. +It cannot be redefined and "purge" cannot be applied to it. + A macroinstruction may in turn define another macroinstruction or a number +of them. The blocks designated by "macro" and "end macro" must be properly +nested one within the other for such definition to be accepted by the +assembler. + + macro enum enclosing + counter = 0 + macro item name + name := counter + counter = counter + 1 + end macro + macro enclosing + purge item,enclosing + end macro + end macro + + enum x + item a + item b + item c + x + + When it is required that macroinstruction generates unpaired "macro" or +"end macro" command, it can be done with special "esc" instruction. Its +argument becomes a part of macroinstruction, but is not being taken into +account when counting the nested "macro" and "end macro" pairs. + + macro xmacro name + esc macro name x& + end macro + + xmacro text + db `x + end macro + +If "esc" is placed inside a nested definition, it is not processed out until +the innermost macroinstruction becomes defined. This allows a definition +containing "esc" to be placed inside another macroinstruction without having +to repeat "esc" for every nesting level. + When an identifer of macroinstruction in its definition is followed by "!" +character, it defines an unconditional macroinstruction. This is a special +kind of instruction class symbol, which is evaluated even in places where the +assembly is suspended - like inside a conditional block whose condition is +false, or inside a definition of another macroinstruction. This allows to +define instructions that can be used where otherwise a directly stated +"end if" or "end macro" would be required, as in the following example: + + macro proc name + name: + if used name + end macro + + macro endp! + end if + .end: + end macro + + proc tester + db ? + endp + +If the macroinstruction "endp" in the above sample was not defined as an +unconditional one and the block started with "if" was being skipped, the +macroinstruction would not get evaluated, and this would lead to an error +because "end if" would be missing. + It should be noted that "end" command executes an instruction identified +by its argument in the child namespace of case-insensitive "end" symbol. +Therefore command like "end if" could be alternatively invoked with +an "end.if" identifier, and it is possible to override any such instruction +by redefining a symbol in the "end?" namespace. Moreover, any instruction +defined within the "end?" namespace can then be called with the "end" command. +This slighly modified variant of the above sample puts these facts to use: + + macro proc name + name: + if used name + end macro + + macro end?.proc! + end if + .end: + end macro + + proc tester + db ? + end proc + +A similar rule applies to the "else" command and the instructions in the +"else?" namespace. + When an identifier consisting of a lone "?" character is used as an +instruction symbol in the definition of macroinstruction, it defines a special +instruction that is then called every time a line to be assembled does not +contain an unconditional instruction, and the complete text of line becomes +the arguments to this macroinstruction. This special symbol can also be defined +as an unconditional instruction, and then it is called for every following line +with no exception. This allows to completely override the assembly process on +portions of the text. The following sample defines a macroinstruction which +allows to define a block of comments by skiping all the lines of text until it +encounters a line with content equal to the argument given to "comment". + + macro comment? ender + macro ?! line& + if `line = `ender + purge ? + end if + end macro + end macro + + comment ~ + Any text may follow here. + ~ + +An identifier consisting of two question marks can be used to define a special +instruction that is called only as last resort, on lines that contain no +recognizable instruction. This allows to intercept lines that would otherwise +be rejected with "illegal instruction" message due to unknown syntax. + The "mvmacro" is an instruction that takes two arguments, both identifying +an instruction-class symbols. The definition of a macroinstruction specified +by the second argument is moved to the symbol identified by the first one. +For the second symbol the effect of this command is the same as of "purge". +This allows to effectively rename a macroinstruction, or temporarily disable it +only to bring it back later. The symbols affected by this operation become +variables and cannot be forward-referenced. + + +9. Labeled macroinstructions + +The "struc" command allows to define a labeled instruction, in form of a +macroinstruction. Except for the fact that such definition must be closed +with "end struc" instead of "end macro", these macroinstructions are defined +in the same way as with "macro" command. A labeled instruction is evaluated +when the first identifier of a command is not an instruction and the second +identifier is of the labeled instruction class: + + struc some + db 1 + end struc + + get some ; "db 1" is assembled here + + Inside a labeled macroinstruction identifiers starting with dot no longer +refer to the namespace of a previously defined regular label. Instead they +refer to the namespace of label with which the instruction was labeled. + + struc POINT + label . : qword + .x dd ? + .y dd ? + end struc + + my POINT ; defines my.x and my.y + +Note that the parent symbol, which can be refered by "." identifier, is not +defined unless an appropriate definition is generated by the macroinstruction. +Furthermore, this symbol is not considered the most recent label in +the surrounding namespace unless it gets defined as an actual label in +the macroinstruction it labeled. + For an easier use of this feature, other syntaxes may be defined with +macroinstructions, like in this sample: + + macro struct? definition& + esc struc definition + label . : .%top - . + namespace . + end macro + + macro ends?! + %top: + end namespace + esc end struc + end macro + + struct POINT vx:?,vy:? + x dd vx + y dd vy + ends + + my POINT 10,20 + + The "restruc" command is analogous to "purge", but it operates on symbols +from the class of labeled instructions. Similarly, the "mvstruc" command is +the same as "mvmacro" but for labeled instructions. + As with "macro", it is possible to use an identifier consisting of a lone "?" +character with "struc". It defines a special labeled macroinstruction that is +called every time the first symbol of a line is not recognized as an instruction. +Everything that follows that first identifier becomes the arguments to labeled +macroinstruction. The following sample uses this feature to catch any orphaned +labels (the ones that are not followed by any character) and treat them as regular +ones instead of causing an error. It achieves it by making ":" the default value +for "def" parameter: + + struc ? def::& + . def + end struc + + orphan + regular: + assert orphan = regular + +Similarly to "macro" this special variant does not override unconditional labeled +instructions unless it is unconditional itself. + While "." provides an efficient method of accessing the label symbol, +sometimes it may be needed to process the actual text of the label. +A special parameter can be defined for this purpose and its name should be +inserted enclosed in parentheses before the name of labeled macroinstruction: + + struc (name) SYMBOL + . db `name,0 + end struc + + test SYMBOL + + +10. Symbolic variables and recognition context + +The "equ" is a built-in labeled instruction that defines symbol of expression +class with a symbolic value. Such value contains a snippet of source text +consisting of any number of tokens (even zero, allowing for an empty value) +and when it is used in an expression it is equivalent to inserting the text +of its value in place of its identifier, with an effect similar to +evaluation of a parameter of macroinstruction (except that a parameter is +always identified by a single name, while a symbolic value may be hidden +behind a complex identifier). + This can lead to an unexpected outcome compared to the use of standard +variables defined with "=", as the following example demonstrates: + + numeric = 2 + 2 + symbolic equ 2 + 2 + x = numeric*3 ; x = 4*3 + y = symbolic*3 ; y = 2 + 2*3 + +While "x" is assigned the value of 12, the value of "y" is 8. This shows that +the use of such symbols can lead to unintended interactions and therefore +definitions of this type should be avoided unless really necessary. + The "equ" allows redefinitions, and it preserves the previous value of +symbol analogously to the "=:" command, so the earlier value can be brought +back with "restore" instruction. To replace the symbolic value (analogously +to how "=" overwrites the regular value) the "reequ" command should be used +instead of "equ". + A symbolic value, in addition to retaining the exact text it was defined +with, preserves the context in which the symbols contained in this text are +to be interpreted. Therefore it can effectively become a reliable link to +value of some other symbol, lasting even when it is used in a different +context (this includes change of the base namespace or a symbol referred by +a starting dot): + + first: + .x = 1 + link equ .x + .x = 2 + second: + .x = 3 + db link ; db 2 + + It should be noted that the same process is applied to the arguments of any +macroinstruction when they become preprocessed parameters. If during +the execution of a macroinstruction the context changes, the identifiers +within the text of parameters still refer to the same symbols as in the line +that called the instruction: + + x = 1 + namespace x + x = 2 + end namespace + macro prodx value + namespace x + db value*x + end namespace + end macro + prodx x ; db 1*2 + +Furthermore, parameters defined with "local" command use the same mechanism +to alter the context in which given name is interpreted, without altering +the text of the name. However, such modified context is not relevant +if the value of parameter is inserted in a middle or at the end of +a complex identifier, because it is the structure of an identifier that +dictates how its later parts are interpreted and only the context for an +initial part matters. For example, prepending a name of a parameter with +"#" character is going to cause the identifier to use current context instead +of context carried by the text of that parameter, because initial context +for the identifier is then the context associated with text "#". + If the text following "equ" contains identifiers of known symbolic variables, +each of them is replaced with its contents and it is such processed text that +gets assigned to the newly defined symbol. + The "define" is a regular instruction that also creates a symbolic value, +but as opposed to "equ" it does not evaluate symbolic variables in the +assigned text. It should be followed by an identifier of symbol to be defined +and then by the text of the value. + The difference between "equ" and "define" is often not noticeable, because +when used in final expression the symbolic variables are nestedly evaluated +until only the usable constituents of expressions are left. A possible use of +"define" is to create a link to another symbolic variable, like the following +example demonstrates: + + a equ 0* + x equ -a + define y -a + a equ 1* + db x 2 ; db -0*2 + db y 2 ; db -1*2 + +The other uses of "define" will arise in the later sections, with the +introduction of other instructions that operate on symbolic values. + The "define", like "equ", preserves the previous value of symbol. The +"redefine" is a variant of this instruction that discards the earlier value, +analogously to "reequ". + Note that while symbolic variables belong to the expression class of symbols, +their state cannot be determined with operators like "defined", "definite", +or "used", because a logical expression is evaluated as if every symbolic +variable was replaced with the text of corresponding value. Therefore operator +followed by an identifer of symbolic variable is going to be applied to +the content of this variable, whatever it is. For example if a symbolic variable +is made which is a link to a regular symbol, then any operator like "defined" +followed by the identifier of said symbolic variable is going to determine +the status of a linked symbol, not a linking variable. + Unlike the value of a symbolic variable, the body of a macroinstruction +by itself carries no context (although it may contain snippets of text that +came from replaced parameters and because of that have some context associated +with them). Also, if a macroinstruction becomes unrolled at the time when +another one is being defined (this can only happen when called macroinstruction +is unconditional), no context information is added to the arguments, to aid in +preservation of this context-lessness. + It also also possible to force a macro argument to add no context information +to its text. The name of such argument should be preceded by "&" character. +This allows to have an argument whose text is reinterpreted in the new context +during the evaluation of a macro. + + char = 'A' + other.char = 'W' + + macro both a, &b + namespace other + db a, b + end namespace + end macro + + both char+1, char+1 ; db 'B', 'X' + + +11. Repeating blocks of instructions + +The "repeat" instruction allows to assemble a block of instructions multiple +times, with the number of repetitions specified by the value of its argument. +The block of instructions should be ended with "end repeat" command. A synonym +"rept" can be used instead of "repeat". + + a = 2 + repeat a + 3 + a = a + 1 + end repeat + assert a = 7 + + The "while" instruction causes the block of instructions to be assembled +repeatedly as long as the condition specified by its argument is true. Its +argument should be a logical expression, like an argument for "if" or +"assert". The block should be closed with "end while" command. + + a = 7 + while a > 4 + a = a - 2 + end while + assert a = 3 + + The "%" is a special parameter which is preprocessed inside the repeated +block of instructions and is replaced with a decimal number being the number +of current repetition (starting with 1). It works in a similar way to a +parameter of macroinstruction, so it is replaced with its value before the +actual command is processed and so it can be used to create symbol +identifiers containing the number as a part of name: + + repeat 16 + f#% = 1 shl % + end repeat + +The above example defines symbols "f1" to "f16" with values being the +consecutive powers of two. + The "repeat" instruction can have additional arguments, separated with +commas, each containing a name of supplementary parameters specific to this +block. Each of the names can be followed by ":" character and the expression +specifying the base value from which the parameter is going to start counting +the repetitions. This allows to easily change the previous sample to define +the range of symbols from "f0" to "f15": + + repeat 16, i:0 + f#i = 1 shl i + end repeat + + The "%%" is another special parameter that has a value equal to the total +number of repetitions planned. This parameter is undefined inside the "while" +block. The following example uses it to create the sequence of bytes with +values descending from 255 to 0: + + repeat 256 + db %%-% + end repeat + + The "break" instruction allows to stop the repeating prematurely. When it +is encountered, it causes the rest of repeated block to be skipped and no +further repetitions to be executed. It can be used to stop the repeating if +a certain condition is met: + + s = x/2 + repeat 100 + if x/s = s + break + end if + s = (s+x/s)/2 + end repeat + +The above sample tries to find the square root of the value of symbol "x", +which is assumed defined elsewhere. It can easily be rewritten to perform the +same task with "while" instead of "repeat": + + s = x/2 + while x/s <> s + s = (s+x/s)/2 + if % = 100 + break + end if + end while + + The "iterate" instruction (with a synonym "irp") repeats the block of +instructions while iterating through the list of values separated with commas. +The first argument to "iterate" should be the a name of parameter, folowed by +the comma and then a list of values. During each iteration the parameter +receives one of the values from the list. + + iterate value, 1,2,3 + db value + end iterate + +Like it is in the case of an argument to macroinstruction, the value of parameter +that contains commas needs to be enclosed with "<" and ">" characters. It is +also possible to enclose the first argument to "iterate" with "<" and ">", in +order to define multiple parameters. The list of values is then divided +into section containing as many values as there are parameters, and each +iteration operates on one such section, assigning to each parameter a +corresponding value: + + iterate , a,1, b,2, c,3 + name = value + end iterate + +The name of a parameter can also, like in the case of macroinstructions, be +followed by "*" to require that the parameter has a value that is not empty, +or ":" and a default value. If an "iterate" statement ends with a comma not +followed by anything else, it is not interpreted as an additional empty value, +to put a blank value at the end of list an empty enclosing "<>" needs to be used. + The "break" instruction plus both the "%" and "%%" parameters can be used +inside the "iterate" block with the same effects as in case of "repeat". + The "indx" is an instruction that can be only be used inside an iterated +block and it changes the values of all the iterated parameters to the ones +corresponding to iteration with number specified by the argument to "indx" (but +when the next iteration is started, the values of parameters are again assigned +the normal way). This allows to process the iterated values in a different +order. In the following example the values are processed from the last to the +first: + + iterate value, 1,2,3 + indx 1+%%-% + db value + end iterate + +With "indx" it is even possible to move the view of iterated values many times +during the single repetition. In the following example the entire processing +is done during the first repetition of iterated block and then the "break" +instruction is used to prevent further iterations: + + iterate str, 'alpha','beta','gamma' + repeat %% + dw offset#% + end repeat + repeat %% + indx % + offset#% db str + end repeat + break + end iterate + + The parameters defined by "iterate" do not attach the context to iterated +values, but neither do they remove the original context if such is already +attached to the text of arguments. So if the values given to "iterate" were +themselves created from another parameter that preserved the original context +for the symbol identifiers (like the parameter of macroinstruction), then this +context is preserved, but otherwise "iterate" defines just a plain text +substitution. + The parameters defined by instructions like "iterate" or "repeat" are +processed everywhere in the text of associated block, but with some limitations +if the block is defined partly by the text of macroinstruction and partly in +other places. In that case the parameters are only accessible in the parts of +the block that are defined in the same place as the initial command. + Every time a parameter is defined, its name can have the "?" character +attached to it to indicate that this parameter is case-insensitive. However +when parameters are recognized inside the preprocessed line, it does not matter +whether they are followed by "?" there. The only modifier that is recognized +by preprocessor when it replaces the parameter with its value is the "`" +character. + The repeating instructions together with "if" belong to a group called +control directives. They are the instructions that control the flow of +assembly. Each of them defines its own block of subordinate instructions, +closed with corresponding "end" command, and if these blocks are nested within +each other, it always must be a proper nesting - the inner block must always +be closed before the outer one. All control directives are therefore the +unconditional instructions - they are recognized even when they are inside +an otherwise skipped block. + The "postpone" is another control directive, which causes a block of +instructions to be assembled later, when all of the following source text +has already been processed. + + dw final_count + postpone + final_count = counter + end postpone + counter = 0 + +The above sample postpones the definition of "final_count" symbol until the +entire source has been processed, so that it can access the final value of +"counter" variable. + The assembly of the source text that follows "postpone" includes the assembly +of any additional blocks declared with "postpone", therefore if there are +multiple such blocks, they are assembled in the reverse order. The one that +was declared last is assembled first when the end of the source text is reached. + When the "postpone" directive is provided with an argument consisting of +a single "?" character, it tells the assembler that the block contains +operations which should not affect any of the values defined in the main +source and thus the assembler may refrain from evaluating them until all +other values have been successfully resolved. Such blocks are processed +even later than the ones declared by "postpone" with no arguments. They +may be used to perform some finalizing tasks, like the computation of a +checksum of the assembled code. + The "irpv" is another repeating instruction and an iterator. It has just two +arguments, first being a name of parameter and second an identifier of +a variable. It iterates through all the stacked values of symbolic +variable, starting from the oldest one (this applies only to the values +defined earlier in the source). + + var equ 1 + var equ 2 + var equ 3 + var reequ 4 + irpv param, var + db param + end irpv + +In the above example there are three iterations, with values 1, 2, and 4. + "irpv" can effectively convert a value of symbolic variable into a parameter, +and this can be useful all by itself, because the symbolic variable is only +evaluated in the expressions inside the arguments of instructions (labeled or +not), while the parameters are preprocessed in the entire line before any +processing of command is started. This allows, for example, to redefine a +regular value that is linked by symbolic variable: + + x = 1 + var equ x + irpv symbol, var + indx %% + symbol = 2 + break + end irpv + assert x = 2 + +The combination of "indx" and "break" was added to the above sample to limit +the iteration to the latest value of symbolic variable. In the next section +a better solution to the same problem will be presented. + When a variable passed to "irpv" has a value that is not symbolic, the +parameter is given a text that produces the same value upon computation. When +the value is a positive number, the parameter is replaced with its decimal +representation (similarly how the "%" parameter is processed), otherwise +the parameter is replaced with an identifier of a proxy symbol holding the +value from stack. + The "outscope" directive is available while any macroinstruction is processed, +and it modifies the command that follows in the same line. If the command causes +any parameters to be defined, they are created not in the context of currently +processed macroinstruction but in the context of the source text that called it. + + macro irpv?! statement& + display 'IRPV wrapper' + esc outscope irpv statement + end macro + +This allows not only to safely wrap some control directives in macroinstructions, +but also to create additional customized language constructions that define +parameters for a block of text. Because "outscope" needs to be present in the +text of a specific macroinstruction that requires it, it is recommended to use +it in conjunction with "esc" as in the example above, this ensures that it is +handled the same way even when the entire definition is put inside another +macroinstruction. + + +12. Matching parameters + +The "match" is a control directive which causes its block of instructions to +be assembled only when the text specified by its second argument matches the +pattern given by the first one. A text is separated from a pattern with a comma +character, and it includes everything that follows this separator up to the end +of line. + Every special character (except for the "," and "=", which have a specific +meaning in the pattern) is matched literally - it must be paired with identical +token in the text. In the following example the content of the first block +is assembled, while the content of the second one is not. + + match +,+ + assert 1 ; positive match + end match + + match +,- + assert 0 ; negative match + end match + + The quoted strings are also matched literally, but name tokens in the pattern +are treated differently. Every name acts as a wildcard and can match any +sequence of tokens which is not empty. If the match is successful, the +parameters with such names are created, and each is assigned a value equal +to the text the wildcard was matched with. + + match a[b], 100h[3] + dw a+b ; dw 100h+3 + end match + + A parameter name in pattern can have an extra "?" character attached to it +to indicate that it is a case-insensitive name. + The "=" character causes the token that follows it to be matched literally. +It allows to perform matching of name tokens, and also of special characters +that would otherwise have a different meaning, like "," or "=", or "?" following +a name. + + match =a==a, a=8 + db a ; db 8 + end match + + If "=" is followed by name token with "?" character attached to it, this +element is matched literally but in a case-insensitive way: + + match =a?==a, A=8 + db a ; db 8 + end match + + When there are many wildcards in the pattern, each consecutive one is matched +with as few tokens as possible and the last one takes what is left. If the +wildcards follow each other without any literally matched elements between +them, the first one is matched with just a single token, and the second one with +the remaining text: + + match car cdr, 1+2+3 + db car ; db 1 + db cdr ; db +2+3 + end match + +In the above sample the matched text must contain at least two tokens, because +each wildcard needs at least one token to be not empty. In the next example +there are additional constraints, but the same general rules applies and the +first wildcard consumes as little as possible: + + match first:rest, 1+2:3+4:5+6 + db `first ; db '1+2' + db 13,10 + db `rest ; db '3+4:5+6' + end match + + While any whitespace next to a wildcard is ignored, the presence or +absence of whitespace between literally matched elements is meaningful. +If such elements have no whitespace between them, their counterparts must +contain no whitespace between them either. But if there is a whitespace +between elements in pattern, it places no constraints on the use of +whitespace in the corresponding text - it can be present of not. + + match ++,++ + assert 1 ; positive match + end match + + match ++,+ + + assert 0 ; negative match + end match + + match + +,++ + assert 1 ; positive match + end match + + match + +,+ + + assert 1 ; positive match + end match + +The presence of whitespace in the text becomes required when the pattern +contains the "=" character followed by a whitespace: + + match += +, ++ + assert 0 ; negative match + end match + + match += +, + + + assert 1 ; positive match + end match + + The "match" command is analogous to "if" in that it allows to use the +"else" or "else match" to create a selection of blocks from which only one is +executed: + + macro let param + match dest+==src, param + dest = dest + src + else match dest-==src, param + dest = dest - src + else match dest++, param + dest = dest + 1 + else match dest--, param + dest = dest - 1 + else match dest==src, param + dest = src + else + assert 0 + end match + end macro + + let x=3 ; x = 3 + let x+=7 ; x = x + 7 + let x++ ; x = x + 1 + +It is even possible to mix "if" and "match" conditions in a sequence of +"else" blocks. The entire construction must be closed with "end" command +corresponding to whichever of the two was used last: + + macro record text + match any, text + recorded equ `text + else if RECORD_EMPTY + recorded equ '' + end if + end macro + + The "match" is able to recognize symbolic variables and before the matching +is started, their identifiers in the text of the second argument are replaced +with corresponding values (just like they are replaced in the text that follows +the "equ" command): + + var equ 2+3 + + match a+b, var + db a xor b + end match + +This means that the "match" can be used instead of "irpv" to convert the +latest value of a symbolic variable to parameter. The sample from the previous +section, where "irpv" was used with "break" to perform just one iteration on +the last value, can be rewritten to use "match" instead: + + x = 1 + var equ x + match symbol, var + symbol = 2 + end match + assert x = 2 + +The difference between them is that "irpv" would execute its block even for +an empty value, while in the case of "match" the "else" block would need to be +added to handle an empty text. + When the evaluation of symbolic variables in the matched text is undesirable, +a symbol created with "define" can be used as a proxy to preserve the text, +because the replacement is not recursive: + + macro drop value + local temporary + define temporary value + match =A, temporary + db A + restore A + else + db value + end match + end macro + + A equ 1 + A equ 2 + + drop A + drop A + +A concern could arise that "define" may modify the meaning of text by +equipping it with a local context. But when the value for "define" comes from +a parameter of macroinstruction (as in the above sample), it already carries +its original context and "define" does not alter it. + The "rawmatch" directive (with a synonym "rmatch") is very similar to "match", +but it operates on the raw text of the second argument. Not only it does not +evaluate the symbolic variables, but it also strips the text of any additional +context it could have carried. + + struc has instruction + rawmatch text, instruction + namespace . + text + end namespace + end rawmatch + end struc + + define x + x has a = 3 + assert x.a = 3 + +In the above sample the identifier of "a" would be interpreted in the context +effective for the line calling the "has" macroinstruction if it was not +converted back into the raw text by "rmatch". + + +13. Output areas + +The "org" instruction starts a new area of output. The content of such +area is written into the destination file next to the previous data, but the +addresses in the new area are based on the value specified in the argument to +"org". The area is closed automatically when the next one is started or when +the source ends. + + org 100h + start: ; start = 100h + + The "$" is a built-in symbol of expression class which is always equal to +the value of current address. Therefore definition of a constant with the value +specified by "$" symbol is equivalent to defining a label at the same point: + + org 100h + start = $ ; start = 100h + +The "$$" symbol is always equal to the base of current addressing space, so +in the area started with "org" it has the same value as the base address from +the argument of "org". The difference between "$" and "$$" is thus the current +position relative to the start of the area: + + org 2000h + db 'Hello!' + size = $ - $$ ; size = 6 + +The "$@" symbol evaluates to the base address of current block of uninitialized +data. When there was no such data defined just before the current position, +this value is equal to "$", otherwise it is equal to "$" minus the length of +said data inside the current addressing space. Note that reserved data +no longer counts as such when it is followed by an initialized one. + The "section" instruction is similar to "org", but it additionally trims +all the reserved data that precedes it analogously to how the uninitialized +data is not written into output when it is at the end of file. The "section" +can therefore be followed by initialized data definitions without causing +the previously reserved data to be initialized with zeros and written into +output. In this sample only the first of the three reserved buffers is +actually converted into zeroed data and written into output, because it is +followed by some initialized data. The second one is trimmed because of the +"section", and the third one is cut off since it lies at the end of file: + + data1 dw 1 + buffer1 rb 10h ; zeroed and present in the output + + org 400h + data dw 2 + buffer2 rb 20h ; not in the output + + section 1000h + data3 dw 3 + buffer3 rb 30h ; not in the output + + The "$%" is a built-in symbol equal to the offset within the output file at +which the initialized data would be generated if it was defined at this point. +The "$%%" symbol is the current offset within the output file. These two +values differ only when they are used after some data has been reserved - +the "$%" is then larger than "$%%" by the length of unitialized data which +would be generated into output if it was to be followed by some initialized +one. + + db 'Hello!' + rb 4 + position = $%% ; position = 6 + next = $% ; next = 10 + +The values in the comments of the above sample assume that the source contains +no other instructions generating output. + The "virtual" creates a special output area which is not written into the main +output file. This kind of area must reside between the "virtual" and "end virtual" +commands, and after it is closed, the output generator comes back to the area it +was previously operating on, with position and address the same as there were just +before opening the "virtual" block. This allows also to nest the "virtual" blocks +within each other. + When "virtual" has no argument, the base address of this area is the same +as current address in the outer area. An argument to "virtual" can have a form +of "at" keyword followed by an expression defining the base address for the +enclosed area: + + int dw 1234h + virtual at int + low db ? + high db ? + end virtual + + Instead of or in addition to such argument, "virtual" can also be followed by +an "as" keyword and a string defining an extension of additional file where +the initialized content of the area is going to be stored at the end of +a successful assembly. + The "load" instruction defines the value of a variable by loading the string +of bytes from the data generated in an output area. It should be followed by +an identifier of symbol to define, then optionally the ":" character and a +number of bytes to load, then the "from" keyword and an address of the data +to load. This address can be specified in two modes. If it is simply a numeric +expression, it is an address within the current area. In that case the loaded +bytes must have already been generated, so it is only possible to load from the +space between "$$" and "$" addresses. + + virtual at 100h + db 'abc' + load b:byte from 101h ; b = 'b' + end virtual + +When the number of bytes is not specified, the length of loaded string is +determined by the size associated with address. + Another variant of "load" needs a special kind of label, which is created +with "::" instead of ":". Such label has a value that cannot be used directly, +but it can be used with "load" instruction to access the data of the area in +which this label has been defined. The address for "load" has then to be +specified as the area label followed by ":" and then the address within that +area: + + virtual at 0 + hex_digits:: + db '0123456789ABCDEF' + end virtual + load a:byte from hex_digits:10 ; a = 'A' + +This variant of "load" can access the data which is generated later, even +within the current area: + + area:: + db 'abc' + load sub:3 from area:$-2 ; sub = 'bcd' + db 'def' + + The "store" instruction can modify already generated data in the output +area. It should be followed by a value (automatically converted to string +of bytes), then optionally the ":" character followed by a number of bytes +to write (when this setting is not present, the length of string is determined +by the size associated with address), then the "at" keyword and the address of +data to replace, in one of the same two modes as allowed by "load". However the +"store" is not allowed to modify the data that has not been generated yet, and +any area that has been touched by "store" becomes a variable area, forbidding +also the "load" to read a data from such area in advance. + The following example uses the combination of "load" and "store" to encrypt +the entire contents of the current area with a simple "xor" operation: + + db "Text" + key = 7Bh + repeat $-$$ + load a : byte from $$+%-1 + store a xor key : byte at $$+%-1 + end repeat + + If the final data of an area that has been modified by "store" needs to be +read earlier in the source, it can be achieved by copying this data into +a different area that would not be constrained in such way. This is analogous +to defining a constant with a final value of some variable: + + load char : byte from const:0 + + virtual + var:: + db 'abc' + .length = $ + end virtual + + store 'A' : byte at var:0 + + virtual + const:: + repeat var.length + load a : byte from var:%-1 + db a + end repeat + end virtual + + The area label can be forward-referenced by "load", but it can never be +forward-referenced by "store", even if it refers to the current output area. + The "virtual" instruction can have an existing area label as the only +argument. This variant allows to extend a previously defined and closed +block with additional data. The area label must refer to a block that was +created earlier in the source with "virtual". Any definition of data within +an extending block is going to have the same effect as if that definition was +present in the original "virtual" block. + + virtual at 0 as 'log' + Log:: + end virtual + + virtual Log + db 'Hello!',13,10 + end virtual + + If an area label is used in an expression, it forms a variable term of a +linear polynomial. The metadata of such term is the base address of the area. +The metadata of an area label itself, accessible with "sizeof" operator, +is equal to the current length of data within the area. + There is an additional variant of "load" and "store" directives that allows +to read and modify already generated data in the output file given simply +an offset within that output. This variant is recognized when the "at" or +"from" keyword is followed by ":" character and then the value of an offset. + + checksum = 0 + repeat $% + load a : byte from : %-1 + checksum = checksum + a + end repeat + + The "restartout" instruction abandons all the output generated up to this +point and starts anew with an empty one. An optional argument may specify +the base address of newly started output area. When "restartout" has no +argument, the current address is preserved by using it as the base for the +new area. + The "org", "section" and "restartout" instructions cannot be used inside +a "virtual" block, they can only separate areas that go into the output file. + + +14. Source and output control + +The "include" instruction reads the source text from another file and +processes it before proceeding further in the current source. Its argument +should be a string defining the path to a file (the format of the path may +depend on the operating system). If there is a "!" between the instruction +and the argument, the other file is read and processed unconditionally, +even when it is inside a skipped block (the unconditional instructions from +the other file may then get recognized). + + include 'macro.inc' + +An additional argument may be optionally added (separated from the path +by comma), and it is interpreted as a command to be executed after the file +has been read and inserted into the source stream, just before processing +the first line. + The "eval" instruction takes a sequence of bytes defined by its arguments, +treats it as a source text and assembles it. The arguments are either strings +or the numeric values of single bytes, separated with commas. In the next +example "eval" is used to generate definitions of symbols named as a +consecutive letters of the alphabet: + + repeat 26 + eval 'A'+%-1,'=',`% + end repeat + + assert B = 2 + + The "display" instruction causes a sequence of bytes to be written into +standard output, next to the messages generated by the assembler. It should +be followed by strings or numeric values of single bytes, separated +with commas. The following example uses "repeat 1" to define a parameter +with a decimal representation of computed number, and then displays it as +a string: + + macro show description,value + repeat 1, d:value + display description,`d,13,10 + end repeat + end macro + + show '2^64=',1 shl 64 + + The "err" instruction signalizes an error in the assembly process, with +a custom message specified by its argument. It allows the same kind of +arguments as the "display" directive. + + if $>10000h + err 'segment too large' + end if + + The "format" directive allows to set up additional options concerning +the main output. Currently the only available choice is "format binary" followed +by the "as" keyword and a string defining an extension for the output file. +Unless a name of the output file is specified from the command line, it is +constructed from the path to the main source file by dropping the extension and +attaching a new extension if such is defined. + + format binary as 'com' + + The "format" directive, analogously to "end", uses an identifier that follows +it to find an instruction in the child namespace of case-insensitive symbol +named "format". The only built-in instruction that resides in that namespace +is the "binary", but additional ones may be defined in form of macroinstructions. + The built-in symbol "__time__" (with legacy synonym "%t") has the constant value +of the timestamp marking the point in time when the assembly was started. + The "__file__" is a built-in symbol whose value is a string containing +the name of currently processed source file. The accompanying "__line__" symbol +provides the number of currently processed line in that file. When these symbols +are accessed within a macroinstruction, they keep the same value they had for the +calling line. If there are several levels of macroinstructions calling each +other, these symbols have the same value everywhere, corresponding to the line +that called the outermost macroinstruction. + The "__source__" is another built-in symbol, with value being a string containing +the name of the main source file. + The "retaincomments" directive switches the assembler to treat a semicolon as +a regular token and therefore not strip comments from lines before processing. +This allows to use semicolons in places like MATCH pattern. + + retaincomments + macro ? line& + match instruction ; comment , line + virtual + comment + end virtual + instruction + else + line + end match + end macro + + var dd ? ; bvar db ? + + The "isolatelines" directive prevents the assembler from subsequently combining +lines read from the source text when the line break is preceded by a backslash. + The "removecomments" directive brings back the default behavior of semicolons +and the "combinelines" directive allows lines from the source text to be combined +as usual. + + +15. CALM instructions + +The "calminstruction" directive allows to define new instructions in form of +compiled sequences of specialized commands. As opposed to regular macroinstructions, +which operate on a straightforward principle of textual substitution, CALM +(Compiled Assembly-Like Macro) instructions are able to perform many operations +without passing any text through the standard preprocessing and assembly cycle. +This allows for a finer control, better error handling and faster execution. + All references to symbols in the text defining a CALM instruction are fixed +at the time of definition. As a consequence, any symbols local to the CALM instruction +are shared among all its executed instances (for example consecutive instances may see +the values of local symbols left by the previous ones). To aid in reusing these +references, commands in CALM are generally operating on variables, routinely rewriting +the symbols with new values. + A "calminstruction" statement follows the same rules as "macro" declaration, +including options like "!" modifier to define unconditional instruction, "*" to mark +a required argument, ":" to give it a default value and "&" to indicate that +the final argument consumes all the remaining text in line. + However, because CALM instruction operates outside of the standard preprocessing +and assembly cycle, its arguments do not become preprocessed parameters. Instead +they are local symbolic variables, given new values every time the instruction is called. + If the name of defined instruction is preceded by another name enclosed in round +brackets, the statement defines a labeled instruction and enclosed name is the +argument that is going to receive the text of the label. + In the definition of CALM instruction, only the statements of its specialized +language are identified. The initial symbol of every line must be a simple name without +modifiers and it is only recognized as valid instruction if a case-insensitive symbol with +such name is found in the namespace of CALM commands (which, for the purpose +of customization, is accessible as the namespace anchored at the case-insensitive +"calminstruction" symbol). When no such named instruction is found, the initial name may +become a label if it is followed by ":", it is then treated as a case-sensitive symbol +belonging to a specialized class. Symbols of this class are only recognized when used +as arguments to CALM jump commands (described further down). + An "end calminstruction" statement needs to be used to close the definition and +bring back normal mode of assembly. It is not a regular "end" command, +but an identically named instruction in the CALM namespace, which only accepts +"calminstruction" as its argument. + The "assemble" is a command that takes a single argument, which should be +an identifier of a symbolic variable. The text of this variable is passed directly +to assembly, without any preprocessing (if the text came from an argument to +the instruction, it already went through preprocessing when that line was prepared). + + calminstruction please? cmd& + assemble cmd + end calminstruction + + please display 'Hi!' + + The "match" command is in many ways similar to the standard directive with the same +name. Its first argument should be a pattern following the same rules as those for +"match" directive. The second argument must be an identifier of a symbolic variable, +whose text is going to be matched against the pattern. The name tokens in pattern +(except for the ones made literal with "=" symbol) are treated as names of variables +where the matched portions of text should be put if the match is successful. The same +variable that is a source of text can also be used in pattern as a variable +to write to. When there is no match, all variables remain unaffected. + + calminstruction please? cmd& + match (cmd), cmd + assemble cmd + end calminstruction + + please(display 'Hi!') + + Whether the match was successful can also be tested with a conditional jump "jyes" +or "jno" following the "match" command. A "jyes" jump is taken only when the match +succeeded. + + calminstruction please? cmd& + match =do? =not? cmd, cmd + jyes done + assemble cmd + done: + end calminstruction + + please do not display 'Bye!' + +To further control the flow of processing, the "jump" command allows to jump +unconditionally, and with "exit" it is possible to terminate processing of +CALM instruction at any moment (this command takes no arguments). + While the symbols used for the arguments of the instruction are implicitly local, +other identifiers may become fixed references to global symbols if they are seen +as accessible at the time of definition (because in CALM instruction all such references +are treated as uses, not as definitions). A command like "match" may then write to +a global variable. + + define comment + + calminstruction please? cmd& + match cmd //comment, cmd + assemble cmd + end calminstruction + + please display 'Hi!' // 3 + db comment ; db 3 + +To enforce treatment of a symbol as local, a "local" command should be used, followed +by one or more names separated with commas. + + calminstruction please? cmd& + local comment + match cmd //comment, cmd + assemble cmd + end calminstruction + +A symbol made local is initally assigned a defined but unusable value. + If a pattern in CALM instruction has a "?" character immediately following the name +of a wildcard, it does not affect how the symbol is identified (whether the used symbol +is case-insensitive depends on what is present in the local scope at the time +the instruction is defined). Instead, modifying the name of a wildcard with "?" allows it +to be matched with an empty text. + Since the source text for "match" is in this variant given by just a single identifier, +this syntax allows to have more optional arguments. A third argument to "match" may +contain a pair of bracket characters. Any wildcard element must then be matched with +a text that has this kind of brackets properly balanced. + + calminstruction please? cmd& + local first, second + match first + second, cmd, () + jyes split + assemble cmd + exit + split: + assemble first + assemble second + end calminstruction + + please display 'H',('g'+2) + display '!' + + The "arrange" command is like an inverse of "match", it can build up a text +containing the values of one or more symbolic variables. The first argument defines +a variable where the constructed text is going to be stored, while the second argument +is a pattern formed in the same way as for "match" (except that it does not need +to precede a comma with "=" to have it included in the argument). +All non-name tokens other than "=" and tokens preceded with "=" are copied literally +into the constructed text and they do not carry any recognition context with them. +The name tokens that are not made literal with "=" are treates as names of variables +whose symbolic values are put in their place into the constructed text. + + calminstruction addr? arg + local base, index + match base[index], arg + local cmd + arrange cmd, =dd base + index + assemble cmd + end calminstruction + + addr 8[5] ; dd 8 + 5 + +With suitably selected patterns, "arrange" can be used to copy symbolic value +from one variable to another or to assign it a fixed value (even an empty one). + If a variable used in pattern turns out to have a numeric value instead of symbolic, +as long as it is a non-negative number with no additional terms, it is converted +into a decimal token stored into the constructed symbolic value (an operation +that outside of CALM instructions would require use of a "repeat 1" trick): + + digit = 4 - 1 + + calminstruction demo + local cmd + arrange cmd, =display digit#0h + assemble cmd + end calminstruction + + demo ; display 3#0h + +This is the only case when a non-symbolic value is converted to symbols that may be +put into text composed by "arrange", other types are not supported. + The "compute" command allows to evaluate expressions and assign numeric results to +variables. The first argument to "compute" defines a target where the result should +be stored, while the second argument can be any numeric expression, which is +becomes pre-compiled at the time of definition. When the expression is evaluated +and any of the symbols it refers to turns out to have symbolic value, this text +is parsed as a new sub-expression, and its calculated value is then used in the +computation of the main expression. + A "compute" therefore can be used not only to evaluate a pre-defined expression, +but also to parse and compute an expression from a text of a symbolic variable +(like one coming from an argument to the instruction), or a combination of both: + + a = 0 + + calminstruction low expr* + compute a, expr and 0FFh + end calminstruction + + low 200 + 73 ; a = 11h + +Because symbolic variable is evaluated as a sub-expression, its use here has no +side-effects that would be caused by a straightforward text substitution. + The "check" command is analogous to "if". It evaluates a condition defined by +the logical expression that follows it and accordingly sets up the result flag which +may be tested with "jyes" or "jno" command. The values of symbolic variables +are treated as numeric sub-expressions (they may not contain any operators specific +to logical expression). + + calminstruction u8range? value + check value >= 0 & value < 256 + jyes ok + local cmd + arrange cmd, =err 'value out of range' + assemble cmd + ok: + end calminstruction + + u8range -1 + +All commands that are not explicitly said to set the flag that is checked by "jyes" +and "jno", keep the value of this flag unchanged. + The "publish" command allows to assign a value to a symbol identified by the text +held in a variable. This allows to define a symbol with a name constructed with +a command like "arrange", or a name that was passed in an argument to an instruction. +The first argument needs to be the symbolic variable containing the identifier +of the symbol to define, the second argument should be the variable holding +the value to assign (either symbolic or numeric). The first argument may be +followed by ":" character to indicate that the symbol should be made constant, +or it can be preceded by ":" to make the value stacked on top of the previous one +(so that the previous one can be brought back with "restore" directive). + + calminstruction constdefine? var + local val + arrange val, + match var= val, var + publish var:, val + end calminstruction + + constdefine plus? + + +The above instruction allows to define a symbolic constant, something that is not +possible with standard directives of the assembler. + The purpose of "transform" command is to replace identifiers of symbolic variables +(or constants) with their values in a given text, which is the same operation as done +by "equ" directive when it prepares the value to assign. The argument to "transform" +should be a symbolic variable whose value is going to be processed this way and then +replaced by the transformed text. + + calminstruction (var) constequ? val + transform val + publish var:, val + end calminstruction + +A "transform" command updates the result flag to indicate whether any replacement +has been done. + + calminstruction prepasm? cmd& + loop: + transform cmd + jyes loop ; warning: may hang on cyclic references + assemble cmd + end calminstruction + +The result flag is modified only by some of the commands, like "check", "match" +or "transform". Other commands keep it unchanged. + Optionally, "transform" can have two arguments, with second one specifying +a namespace. Identifiers in the text given by the first argument are then interpreted +as symbols in this namespace regardless of their original context. + The "stringify" is a command that converts text of a variable into a string +and writes it into the same variable, specified by the only argument. This operation +is similar to the one performed by "`" operator in preprocessing, but it produces +a value of string type, not a quoted string. + + calminstruction (var) strcalc? val + compute val, val ; compute expression + arrange val, val ; convert result to a decimal token + stringify val ; convert decimal token to string + publish var, val + end calminstruction + + p strcalc 1 shl 1000 + display p + + While most commands available to CALM instructions replace the values of variables +when writing to them, the "take" is a command that allows to work with stacks of values. +It removes the topmost value of the source symbol (specified by the second argument) +and gives it to the destination symbol (the first argument), placing it on top of any +existing values. The destination argument may be empty, in such case the value is +removed completely and the operation is analogous to "restore" directive. This command +updates the result flag to indicate whether there was any value to remove. +If the destination symbol is the same as source, the result flag can be used to check +whether there is an available value without affecting it. + + calminstruction reverse? cmd& + local tmp, stack + collect: + match tmp=,cmd, cmd + take stack, tmp + jyes collect + execute: + assemble cmd + take cmd, stack + jyes execute + end calminstruction + + reverse display '!', display 'i', display 'H' + +A symbol accessed as either destination or source by a "take" command can never be +forward-referenced even if it could otherwise. + Defining macroinstructions in the namespace of case-insensitive "calminstruction" +allows to add customized commands to the language of CALM instructions. However, +they must be defined as case-insensitive to be recognized as such. + + macro calminstruction?.asmarranged? variable*, pattern& + arrange variable, pattern + assemble variable + end macro + + calminstruction writeln? text& + asmarranged text, =display text,10 + end calminstruction + + writeln 'Next!' + +Such additional commands may even be defined as CALM instructions themselves: + + calminstruction calminstruction?.initsym? variable*,value& + publish variable, value + end calminstruction + + calminstruction show? text& + local command + initsym command, display text + stringify text + assemble command + end calminstruction + + show :) + +The command "initsym" in this example is used to assign text to the local +symbolic variable at the time when "show" instruction is defined. +Similarly to "local" (and unlike "stringify" and "assemble") it does not produce +any actual code that would be executed when the "show" instruction is called. +The arguments to "initsym" retain their original context, therefore symbols +in the text assigned to the "command" variable are interpreted as in the local +namespace of the "show" instruction. This allows the "display" command to access +the "text" even though it is local to the CALM instruction and therefore normally +visible only in the scope of the definition of "show". This is similar to the use +of "define" to form symbolic links. + The "call" command allows to directly execute another CALM instruction. Its +first argument must provide an identifier of an instruction-class symbol, and +at the execution time this symbol must be defined as CALM (it is not possible +to call a macroinstruction or a built-in instruction this way). The execution +then proceeds directly to the entry point of that instruction, and only returns +after the called instruction finishes. + + define Msg display 'Hi' + + calminstruction showMsg + assemble Msg + end calminstruction + + calminstruction demo + call showMsg + arrange Msg, =display '!' + call showMsg + end calminstruction + + demo + +When looking up the instruction symbol, the assembler skips the local namespace +of the CALM instruction, as it is not expected to contain instruction definitions. + Additional arguments to "call" should be identifiers of variables (or constants) +whose values are going to be passed as arguments to the called instruction. +The values of these symbols are assigned directly to the argument variables, +without any additional validation - this allows to pass to the CALM instruction +some values that otherwise would be impossible to pass directly, like numeric ones +(because when the instructions are called normally, the arguments are treated as +text and assigned as symbolic values). An argument may be omitted when the definition +of called instruction allows it, in such case the default value for that argument +is used. + + calminstruction hex_nibble digit*, command: display + compute digit, 0FFh and '0123456789ABCDEF' shr (digit*8) + arrange command, command digit + assemble command + end calminstruction + + calminstruction display_hex_byte value: DATA + compute value, value + local digit + compute digit, (value shr 4) and 0Fh + call hex_nibble, digit + compute digit, value and 0Fh + call hex_nibble, digit + end calminstruction + + DATA = 0xedfe + + calminstruction demo + call display_hex_byte + compute DATA, DATA shr 8 + call display_hex_byte + end calminstruction + + demo + + +16. Assembly commands in CALM instructions + + An additional sets of commands for CALM instructions makes it possible +to use them for more than just pre-processing, but also to directly generate +and process output. They perform elementary operations, mostly on a single +unit of data, but at the same time they can perform many calculations in-place, +because their arguments, with few exceptions, are pre-compiled expressions, +similar to the second argument to "compute". + The "display" command presents a string of bytes as a message in +the standard output, just like the regular directive with the same name. +It takes a single argument, an expression giving either a string or a numeric +value of a single byte. + The "err" command signalizes an error, analogously to its namesake in +base language. It takes a single argument, specifying a custom message to +present. The argument is expected to evaluate to string value. + The "emit" command generates data of length specified by the first argument +and the value specified by the second. Both arguments are treated as +pre-compiled expressions. The second argument is optional, if it is omitted, +the data of specified length is generated as uninitialized. When the second +argument is a string, it must fit within the specified size (a "lengthof" +operator may be useful in this case). + The "load" and "store" commands allow to inspect or modify values in the +already generated output or in the virtual blocks. While they are similar +to their counterparts in base language, they have a different syntax, both +always taking three comma-separated arguments. Unlike their cousins, they +do not operate on addresses associated with output areas, but on raw offsets. +To point to the first byte of an area, stated offset must be zero. + The arguments to "load" are, in order: target variable, offset to load from, +number of bytes to load. The first argument must be an identifier of a symbol, +the latter two are pre-compiled expressions. The second argument may contain +a label of the area, followed by ":" and then offset, or just a plain numeric +expression, in which case it is an offset within entire output generated +up to this point. The loaded value is always a string of the specified length. + The arguments to "store" are, in order: offset to store at, number of bytes +to store, the value to store (numeric or string). The last two arguments +are analogous to the arguments to "emit", at the same time the first two +arguments are like the last two arguments to "load". The offset may be +prepended with the label of an area with ":" as the separator. + To convert between the addresses used by classic "load" and "store" and +the raw offsets expected by the CALM commands, it suffices to add or subtract +the base address of the area. If the base address is not known, it can be +obtained with help of "1 metadataof" operator applied to an area label. diff --git a/toolchain/fasmg.kl0e/examples/8051/8051.inc b/toolchain/fasmg.kl0e/examples/8051/8051.inc new file mode 100644 index 0000000..30243c4 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/8051/8051.inc @@ -0,0 +1,861 @@ + +; This is a very basic implementation of 8051 instruction set, which treats +; all types of addresses as plain numeric values and therefore is not able to +; detect whether symbol has been used in context it was not intended for. + +element R + +repeat 8 i:0 + element R#i? : R + i +end repeat + +element @ + +element @R0? : @ +element @R1? : @ + 1 + +macro AJMP? addr + local value + value = +addr + if value and not 7FFh = ($+2) and not 7FFh + db 01h + value shr 3 and 11100000b,value and 0FFh + else + err "address out of range" + end if +end macro + +macro ACALL? addr + local value + value = +addr + if value and not 7FFh = ($+2) and not 7FFh + db 11h + value shr 3 and 11100000b,value and 0FFh + else + err "address out of range" + end if +end macro + +macro LCALL? addr + local value + value = +addr + db 12h,value shr 8,value and 0FFh +end macro + +macro LJMP? addr + local value + value = +addr + db 02h,value shr 8,value and 0FFh +end macro + +macro SJMP? addr + local offset + offset = -($+2)+addr + if offset>=-80h & offset<80h + db 80h,offset + else + err "relative jump out of range" + end if +end macro + +macro CALL? addr + local value + value = +addr + if value and not 7FFh = ($+2) and not 7FFh + db 11h + value shr 3 and 11100000b + else + db 12h,value shr 8 + end if + db value and 0FFh +end macro + +macro JMP? addr + local value,offset + match =@A? + =DPTR?, addr + db 73h + else + value = +addr + offset = value-($+2) + if offset>=-80h & offset<80h + db 80h,offset + else + if value and not 7FFh = ($+2) and not 7FFh + db 01h + value shr 3 and 11100000b + else + db 02h,value shr 8 + end if + db value and 0FFh + end if + end match +end macro + +macro CJNE? operand1,operand2,addr + local value,offset + offset = -($+3)+addr + if offset>=-80h & offset<80h + match =A?, operand1 + match #data, operand2 + value = +data + db 0B4h,value + else + value = +operand2 + db 0B5h,value + end match + else match #data,operand2 + value = +operand1 + if value eq value element 1 + if value metadata 1 relativeto @ + db 0B6h + value metadata 1 - @ + else if value metadata 1 relativeto R + db 0B8h + value metadata 1 - R + else + err "invalid operand" + end if + db +data + else + err "invalid operand" + end if + else + err 'invalid operand' + end match + db offset + else + err "relative jump out of range" + end if +end macro + +macro DJNZ? operand,addr + local value,offset + value = +operand + if value relativeto 0 + offset = -($+3)+addr + if offset>=-80h & offset<80h + db 0D5h,value,offset + else + err "relative jump out of range" + end if + else if value eq value element 1 & value metadata 1 relativeto R + offset = -($+2)+addr + if offset>=-80h & offset<80h + db 0D8h + value metadata 1 - R,offset + else + err "relative jump out of range" + end if + else + err "invalid operand" + end if +end macro + +macro JBC? operand,addr + local offset + offset = -($+3)+addr + if offset>=-80h & offset<80h + db 10h,operand,offset + else + err "relative jump out of range" + end if +end macro + +macro JB? operand,addr + local offset + offset = -($+3)+addr + if offset>=-80h & offset<80h + db 20h,operand,offset + else + err "relative jump out of range" + end if +end macro + +macro JNB? operand,addr + local offset + offset = -($+3)+addr + if offset>=-80h & offset<80h + db 30h,operand,offset + else + err "relative jump out of range" + end if +end macro + +macro JC? addr + local offset + offset = -($+2)+addr + if offset>=-80h & offset<80h + db 40h,offset + else + err "relative jump out of range" + end if +end macro + +macro JNC? addr + local offset + offset = -($+2)+addr + if offset>=-80h & offset<80h + db 50h,offset + else + err "relative jump out of range" + end if +end macro + +macro JZ? addr + local offset + offset = -($+2)+addr + if offset>=-80h & offset<80h + db 60h,offset + else + err "relative jump out of range" + end if +end macro + +macro JNZ? addr + local offset + offset = -($+2)+addr + if offset>=-80h & offset<80h + db 70h,offset + else + err "relative jump out of range" + end if +end macro + +macro ADD? accu,operand + local value + match =A?, accu + match #data, operand + value = +data + db 24h,value + else + value = +operand + if value relativeto 0 + db 25h,value + else if value eq value element 1 + if value metadata 1 relativeto @ + db 26h + value metadata 1 - @ + else if value metadata 1 relativeto R + db 28h + value metadata 1 - R + else + err "invalid operand" + end if + else + err "invalid operand" + end if + end match + else + err 'invalid operand' + end match +end macro + +macro ADDC? accu,operand + local value + match =A?, accu + match #data, operand + value = +data + db 34h,value + else + value = +operand + if value relativeto 0 + db 35h,value + else if value eq value element 1 + if value metadata 1 relativeto @ + db 36h + value metadata 1 - @ + else if value metadata 1 relativeto R + db 38h + value metadata 1 - R + else + err "invalid operand" + end if + else + err "invalid operand" + end if + end match + else + err 'invalid operand' + end match +end macro + +macro SUBB? accu,operand + local value + match =A?, accu + match #data, operand + value = +data + db 94h,value + else + value = +operand + if value relativeto 0 + db 95h,value + else if value eq value element 1 + if value metadata 1 relativeto @ + db 96h + value metadata 1 - @ + else if value metadata 1 relativeto R + db 98h + value metadata 1 - R + else + err "invalid operand" + end if + else + err "invalid operand" + end if + end match + else + err 'invalid operand' + end match +end macro + +macro ANL? dest,src + local value,data_value + match =A?, dest + match #data, src + value = +data + db 54h,value + else + value = +src + if value relativeto 0 + db 55h,value + else if value eq value element 1 + if value metadata 1 relativeto @ + db 56h + value metadata 1 - @ + else if value metadata 1 relativeto R + db 58h + value metadata 1 - R + else + err "invalid operand" + end if + else + err "invalid operand" + end if + end match + else match =C?, dest + match /addr,src + db 0B0h,addr + else + db 82h,src + end match + else + match =A?, src + value = +dest + db 52h,value + else match #data, src + value = +dest + data_value = +data + db 53h,value,data_value + else + err 'invalid operand' + end match + end match +end macro + +macro ORL? dest,src + local value,data_value + match =A?, dest + match #data, src + value = +data + db 44h,value + else + value = +src + if value relativeto 0 + db 45h,value + else if value eq value element 1 + if value metadata 1 relativeto @ + db 46h + value metadata 1 - @ + else if value metadata 1 relativeto R + db 48h + value metadata 1 - R + else + err "invalid operand" + end if + else + err "invalid operand" + end if + end match + else match =C?, dest + match /addr,src + db 0A0h,addr + else + db 72h,src + end match + else + match =A?, src + value = +dest + db 42h,value + else match #data, src + value = +dest + data_value = +data + db 43h,value,data_value + else + err 'invalid operand' + end match + end match +end macro + +macro XRL? dest,src + local value,data_value + match =A?, dest + match #data, src + value = +data + db 64h,value + else + value = +src + if value relativeto 0 + db 65h,value + else if value eq value element 1 + if value metadata 1 relativeto @ + db 66h + value metadata 1 - @ + else if value metadata 1 relativeto R + db 68h + value metadata 1 - R + else + err "invalid operand" + end if + else + err "invalid operand" + end if + end match + else + match =A?, src + value = +dest + db 62h,value + else match #data, src + value = +dest + data_value = +data + db 63h,value,data_value + else + err 'invalid operand' + end match + end match +end macro + +macro CLR? operand + match =A?, operand + db 0E4h + else match =C?, operand + db 0C3h + else + db 0C2h,operand + end match +end macro + +macro CPL? operand + match =A?, operand + db 0F4h + else match =C?, operand + db 0B3h + else + db 0B2h,operand + end match +end macro + +macro SETB? operand + match =C?, operand + db 0D3h + else + db 0D2h,operand + end match +end macro + +macro DEC? operand + local value + match =A?, operand + db 14h + else + value = +operand + if value relativeto 0 + db 15h,value + else if value eq value element 1 + if value metadata 1 relativeto @ + db 16h + value metadata 1 - @ + else if value metadata 1 relativeto R + db 18h + value metadata 1 - R + else + err "invalid operand" + end if + else + err "invalid operand" + end if + end match +end macro + +macro INC? operand + local value + match =A?, operand + db 04h + else match =DPTR?, operand + db 0A3h + else + value = +operand + if value relativeto 0 + db 05h,value + else if value eq value element 1 + if value metadata 1 relativeto @ + db 06h + value metadata 1 - @ + else if value metadata 1 relativeto R + db 08h + value metadata 1 - R + else + err "invalid operand" + end if + else + err "invalid operand" + end if + end match +end macro + +macro MOV? dest,src + local value,data_value + match =A?, dest + match #data, src + value = +data + db 74h,value + else + value = +src + if value relativeto 0 + db 0E5h,value + else if value eq value element 1 + if value metadata 1 relativeto @ + db 0E6h + value metadata 1 - @ + else if value metadata 1 relativeto R + db 0E8h + value metadata 1 - R + else + err "invalid operand" + end if + else + err "invalid operand" + end if + end match + else match =C?, dest + db 0A2h,src + else match =C?, src + db 92h,dest + else match =DPTR?, dest + value = src + db 90h + if value eqtype '' + dw +src + else + db value shr 8,value and 0FFh + end if + else + value = +dest + if value relativeto 0 + match =A?, src + db 0F5h,value + else match #data, src + data_value = +data + db 75h,value,data_value + else + @value2 = +src + if @value2 relativeto 0 + db 85h,@value2,value + else if @value2 eq @value2 element 1 + if @value2 metadata 1 relativeto @ + db 86h + @value2 metadata 1 - @,value + else if @value2 metadata 1 relativeto R + db 88h + @value2 metadata 1 - R,value + end if + else if + err "invalid operand" + end if + end match + else if value eq value element 1 + if value metadata 1 relativeto @ + match =A?, src + db 0F6h + value metadata 1 - @ + else match #data, src + data_value = +data + db 76h + value metadata 1 - @,data_value + else + data_value = +src + db 0A6h + value metadata 1 - @,data_value + end match + else if value metadata 1 relativeto R + match =A?, src + db 0F8h + value metadata 1 - R + else match #data, src + data_value = +data + db 78h + value metadata 1 - R,data_value + else + data_value = +src + db 0A8h + value metadata 1 - R,data_value + end match + else + err "invalid operand" + end if + else + err "invalid operand" + end if + end match +end macro + +macro MOVC? operands& + match =A?=, =@A? + =DPTR?, operands + db 93h + else match =A?=, =@A? + =PC?, operands + db 83h + else + err "invalid operand" + end match +end macro + +macro MOVX? dest,src + local value + match =A?, dest + match =@DPTR?, src + db 0E0h + else + value = +src + if value eq value element 1 & value metadata 1 relativeto @ + db 0E2h + value metadata 1 - @ + else + err "invalid operand" + end if + end match + else match =A?, src + match =@DPTR?, dest + db 0F0h + else + value = +dest + if value eq value element 1 & value metadata 1 relativeto @ + db 0F2h + value metadata 1 - @ + else + err "invalid operand" + end if + end match + else + err "invalid operand" + end match +end macro + +macro SWAP? operand + match =A?, operand + db 0C4h + else + err 'invalid operand' + end match +end macro + +macro DA? operand + match =A?, operand + db 0D4h + else + err 'invalid operand' + end match +end macro + +macro RR? operand + match =A?, operand + db 03h + else + err 'invalid operand' + end match +end macro + +macro RRC? operand + match =A?, operand + db 13h + else + err 'invalid operand' + end match +end macro + +macro RL? operand + match =A?, operand + db 23h + else + err 'invalid operand' + end match +end macro + +macro RLC? operand + match =A?, operand + db 33h + else + err 'invalid operand' + end match +end macro + +macro DIV? operand + match =AB?, operand + db 84h + else + err "invalid operand" + end match +end macro + +macro MUL? operand + match =AB?, operand + db 0A4h + else + err "invalid operand" + end match +end macro + +macro NOP? + db 0 +end macro + +macro POP? addr + local value + value = +addr + db 0D0h,value +end macro + +macro PUSH? addr + local value + value = +addr + db 0C0h,value +end macro + +macro RET? + db 22h +end macro + +macro RETI? + db 32h +end macro + +macro XCH? accu,operand + local value + match =A?, accu + value = +operand + if value relativeto 0 + db 0C5h,value + else if value eq value element 1 + if value metadata 1 relativeto @ + db 0C6h + value metadata 1 - @ + else if value metadata 1 relativeto R + db 0C8h + value metadata 1 - R + else + err "invalid operand" + end if + else + err "invalid operand" + end if + else + err 'invalid operand' + end match +end macro + +macro XCHD? accu,src + local value + match =A?, accu + value = +src + if value eq value element 1 & value metadata 1 relativeto @ + db 0D6h + value metadata 1 - @ + else + err "invalid operand" + end if + else + err "invalid operand" + end match +end macro + +struc EQU? value + . = value +end struc + +DSEG?.$ = 0 +DSEG?.open = 0 + +macro DSEG? @:at DSEG?.$ + if ~ DSEG?.open + virtual @ + DSEG?.open = 1 + else + match =AT? addr, @ + org addr + else + err 'invalid argument' + end match + end if +end macro + +macro CSEG? @ + if DSEG?.open + DSEG?.$ = $ + end virtual + DSEG?.open = 0 + end if + match =AT? addr, @ + org addr + else match any, @ + err 'invalid argument' + end match +end macro + +macro bitslabel definition + match name =at? address, definition + label name at address + repeat 8, i:0 + label name.i at address+i + end repeat + else + err 'syntax error' + end match +end macro + +; Data addresses: + +bitslabel P0 at 080h +bitslabel SP at 081h +bitslabel DPL at 082h +bitslabel DPH at 083h +bitslabel PCON at 087h +bitslabel TCON at 088h +bitslabel TMOD at 089h +bitslabel TL0 at 08Ah +bitslabel TL1 at 08Bh +bitslabel TH0 at 08Ch +bitslabel TH1 at 08Dh +bitslabel P1 at 090h +bitslabel SCON at 098h +bitslabel SBUF at 099h +bitslabel P2 at 0A0h +bitslabel IE at 0A8h +bitslabel P3 at 0B0h +bitslabel IP at 0B8h +bitslabel PSW at 0D0h +bitslabel ACC at 0E0h +bitslabel B at 0F0h + +; Bit addresses: + +label IT0 at 088h +label IE0 at 089h +label IT1 at 08Ah +label IE1 at 08Bh +label TR0 at 08Ch +label TF0 at 08Dh +label TR1 at 08Eh +label TF1 at 08Fh +label RI at 098h +label TI at 099h +label RB8 at 09Ah +label TB8 at 09Bh +label REN at 09Ch +label SM2 at 09Dh +label SM1 at 09Eh +label SM0 at 09Fh +label EX0 at 0A8h +label ET0 at 0A9h +label EX1 at 0AAh +label ET1 at 0ABh +label ES at 0ACh +label EA at 0AFh +label RXD at 0B0h +label TXD at 0B1h +label INT0 at 0B2h +label INT1 at 0B3h +label T0 at 0B4h +label T1 at 0B5h +label WR at 0B6h +label RD at 0B7h +label PX0 at 0B8h +label PT0 at 0B9h +label PX1 at 0BAh +label PT1 at 0BBh +label PS at 0BCh +label P at 0D0h +label OV at 0D2h +label RS0 at 0D3h +label RS1 at 0D4h +label F0 at 0D5h +label AC at 0D6h +label CY at 0D7h + +; Code addresses: + +label RESET at 000h +label EXTI0 at 003h +label TIMER0 at 00Bh +label EXTI1 at 013h +label TIMER1 at 01Bh +label SINT at 023h diff --git a/toolchain/fasmg.kl0e/examples/8051/hex.inc b/toolchain/fasmg.kl0e/examples/8051/hex.inc new file mode 100644 index 0000000..c4fbae2 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/8051/hex.inc @@ -0,0 +1,75 @@ + +define HEX +format binary as 'hex' + +virtual at 0 + HEX.digits:: db '0123456789ABCDEF' +end virtual + +macro HEX.byte value + HEX.checksum = (HEX.checksum + (value)) and 0FFh + local digit + load digit:byte from HEX.digits:(value) shr 4 + db digit + load digit:byte from HEX.digits:(value) and 0Fh + db digit +end macro + +macro HEX.line length,address,type,value + HEX.checksum = 0 + db ':' + HEX.byte length + HEX.byte (address) shr 8 + HEX.byte (address) and 0FFh + HEX.byte type + HEX.data = value + repeat length + HEX.byte HEX.data and 0FFh + HEX.data = HEX.data shr 8 + end repeat + HEX.data = (-HEX.checksum) and 0FFh + HEX.byte HEX.data + db 13,10 +end macro + +macro HEX.seg address:0 + virtual at address +end macro + +macro HEX.endseg + local code,address,high,size,bytes + code:: address = $$ + size = $-$$ + end virtual + high = 0 + while size + if address shr 16 <> high + high = address shr 16 + HEX.line 2,0,4,high bswap 2 + end if + if size>10h + load bytes:10h from code:address + HEX.line 10h,address and 0FFFFh,0,bytes + address = address + 10h + size = size - 10h + else + load bytes:size from code:address + HEX.line size,address and 0FFFFh,0,bytes + break + end if + end while +end macro + +macro ORG? address + if $ <> address + HEX.endseg + HEX.seg address + end if +end macro + +HEX.seg + +postpone + HEX.endseg + HEX.line 0,0,1,0 +end postpone diff --git a/toolchain/fasmg.kl0e/examples/8051/invert.asm b/toolchain/fasmg.kl0e/examples/8051/invert.asm new file mode 100644 index 0000000..67ef711 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/8051/invert.asm @@ -0,0 +1,46 @@ + +; This simple example reads data from external device through P2 +; and outputs it inverted through P1. + +include 'hex.inc' +include '8051.inc' + +ORG 0 + JMP setup + +ORG 3 + JMP ext0_interrupt + +ORG 0Bh + JMP timer0_interrupt + +ORG 30h + +setup: + + SETB EX0 + SETB IT0 + CLR P0.7 + + MOV TH0,#-40 + MOV TL0,#-40 + MOV TMOD,#2 + + SETB TR0 + SETB ET0 + SETB EA + + JMP $ + +timer0_interrupt: + CLR P3.6 + SETB P3.6 + RETI + +ext0_interrupt: + CLR P3.7 + MOV A,P2 + CPL A + MOV P1,A + SETB P3.7 + RETI diff --git a/toolchain/fasmg.kl0e/examples/8051/make.cmd b/toolchain/fasmg.kl0e/examples/8051/make.cmd new file mode 100644 index 0000000..f1cc51f --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/8051/make.cmd @@ -0,0 +1 @@ +fasmg invert.asm invert.hex diff --git a/toolchain/fasmg.kl0e/examples/avr/avr.inc b/toolchain/fasmg.kl0e/examples/avr/avr.inc new file mode 100644 index 0000000..5e2a195 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/avr/avr.inc @@ -0,0 +1,903 @@ + +element R + +repeat 32 i:0 + element R#i? : R + i +end repeat + +XH? = R27 +XL? = R26 +YH? = R29 +YL? = R28 +ZH? = R31 +ZL? = R30 + +element X +element Y +element Z + +iterate , ADC,000111b, ADD,000011b, AND, 001000b, EOR, 001001b, CP,000101b, CPC,000001b, CPSE,000100b, MOV,001011b, MUL,100111b, OR,001010b, SBC,000010b, SUB,000110b + macro instr? Rd,Rr + local value,d,r + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + value = +Rr + if value metadata 1 relativeto R & value eq value element 1 + r = value metadata 1 - R + dw r and 1111b + d shl 4 + (r shr 4) shl 9 + opcode shl 10 + else + err 'invalid operand' + end if + else + err 'invalid operand' + end if + end macro +end iterate + +iterate , ADIW,10010110b, SBIW,10010111b + macro instr? RRd,K + local value,d + match Rdh:Rdl,RRd + value = +Rdl + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + value = +Rdh + if value metadata 1 relativeto R & value eq value element 1 + if value metadata 1 - R = d + 1 + if d = 24 | d = 26 | d = 28 | d = 30 + value = +K + if value >= 0 & value <= 63 + dw value and 1111b + ((d-24) shr 1) shl 4 + (value shr 4) shl 6 + opcode shl 8 + else + err 'immediate value out of range' + end if + else + err 'specified register not allowed for this instruction' + end if + else + err 'invalid operand' + end if + else + err 'invalid operand' + end if + else + err 'invalid operand' + end if + else match Rd,RRd + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + if d = 24 | d = 26 | d = 28 | d = 30 + value = +K + if value >= 0 & value <= 63 + dw value and 1111b + ((d-24) shr 1) shl 4 + (value shr 4) shl 6 + opcode shl 8 + else + err 'immediate value out of range' + end if + else + err 'specified register not allowed for this instruction' + end if + else + err 'invalid operand' + end if + else + err 'invalid operand' + end match + end macro +end iterate + +iterate , ANDI,0111b, CPI,0011b, LDI,1110b, ORI,0110b, SBCI,0100b, SBR,0110b, SUBI,0101b + macro instr? Rd,K + local value,d + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + if d >= 16 + value = +K + if value >= -256 & value <= 255 + value = value and 0FFh + dw value and 1111b + (d-16) shl 4 + (value shr 4) shl 8 + opcode shl 12 + else + err 'immediate value out of range' + end if + else + err 'specified register not allowed for this instruction' + end if + else + err 'invalid operand' + end if + end macro +end iterate + +iterate , ASR,0101b, COM,0000b, DEC,1010b, INC,0011b, LSR,0110b, NEG,0001b, ROR,0111b, SWAP,0010b + macro instr? Rd + local value,d + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + dw opcode + d shl 4 + 1001010b shl 9 + else + err 'invalid operand' + end if + end macro +end iterate + +iterate , BCLR,1001'0100'1000'1000b, BSET,1001'0100'0000'1000b + macro instr? s + local value + value = +s + if value >= 0 & value <= 7 + dw opcode + value shl 4 + else + err 'bit index out of range' + end if + end macro +end iterate + +iterate , BLD,1111100b, BST,1111101b, SBRC,1111110b, SBRS,1111111b + macro instr? Rd,b + local value,d + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + value = +b + if value >= 0 & value <= 7 + dw value + d shl 4 + opcode shl 9 + else + err 'bit index out of range' + end if + else + err 'invalid operand' + end if + end macro +end iterate + +iterate , BRBC,111101b, BRBS,111100b + macro instr? s,k + local index,offset + index = +s + if index >= 0 & index <= 7 + offset = -($ shr 1 + 1) + k + if offset >= -64 & offset <= 63 + dw index + (offset and 1111111b) shl 3 + opcode shl 10 + else + err 'relative jump out of range' + end if + else + err 'bit index out of range' + end if + end macro +end iterate + +macro BRCC? k + BRBC 0,k +end macro + +macro BRCS? k + BRBS 0,k +end macro + +macro BREQ? k + BRBS 1,k +end macro + +macro BRGE? k + BRBC 4,k +end macro + +macro BRHC? k + BRBC 5,k +end macro + +macro BRHS? k + BRBS 5,k +end macro + +macro BRID? k + BRBC 7,k +end macro + +macro BRIE? k + BRBS 7,k +end macro + +macro BRLO? k + BRBS 0,k +end macro + +macro BRLT? k + BRBS 4,k +end macro + +macro BRMI? k + BRBS 2,k +end macro + +macro BRNE? k + BRBC 1,k +end macro + +macro BRPL? k + BRBC 2,k +end macro + +macro BRSH? k + BRBC 0,k +end macro + +macro BRTC? k + BRBC 6,k +end macro + +macro BRTS? k + BRBS 6,k +end macro + +macro BRVC? k + BRBC 3,k +end macro + +macro BRVS? k + BRBS 3,k +end macro + +macro CALL? k + local offset + offset = -($ shr 1 + 1) + k + if offset >= -2048 & offset <= 2047 + dw offset and (1 shl 12 - 1) + 1101b shl 12 + else + offset = +k + if offset >= 0 & offset <= 1 shl 22 - 1 + dw (offset shr 16) and 1 + 111b shl 1 + (offset shr 17) shl 4 + 1001010b shl 9 + dw offset and (1 shl 16 - 1) + else + err 'value out of range' + end if + end if +end macro + +iterate , CBI,10011000b, SBI,10011010b, SBIC,10011001b, SBIS,10011011b + macro instr? A,b + local reg,index + reg = +A + if reg >= 0 & reg <= 31 + index = +b + if index >= 0 & index <= 7 + dw index + reg shl 3 + opcode shl 8 + else + err 'bit index out of range' + end if + else + err 'specified register number not allowed' + end if + end macro +end iterate + +macro CBR? r,K + ANDI r,$FF-(K) +end macro + +macro CLC? + dw 1001'0100'1000'1000b +end macro + +macro CLH? + dw 1001'0100'1101'1000b +end macro + +macro CLI? + dw 1001'0100'1111'1000b +end macro + +macro CLN? + dw 1001'0100'1010'1000b +end macro + +macro CLR? r + EOR r,r +end macro + +macro CLS? + dw 1001'0100'1100'1000b +end macro + +macro CLT? + dw 1001'0100'1110'1000b +end macro + +macro CLV? + dw 1001'0100'1011'1000b +end macro + +macro CLZ? + dw 1001'0100'1001'1000b +end macro + +macro DES? K + local value + value = +K + if value >= 0 & value <= 0x0F + dw 1011b + value shl 4 + 10010100b shl 8 + else + err 'value out of range' + end if +end macro + +macro EICALL? + dw 1001'0101'0001'1001b +end macro + +macro EIJMP? + dw 1001'0100'0001'1001b +end macro + +iterate , ELPM,1001'0101'1101'1000b,0110b,0111b, LPM,1001'0101'1100'1000b,0100b,0101b + macro instr? args& + local value,d + match , args + dw opcode + else match Rd=, =Z?, args + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + dw opcode2 + d shl 4 + 1001000b shl 9 + else + err 'invalid operand' + end if + else match Rd=, =Z?+, args + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + dw opcode3 + d shl 4 + 1001000b shl 9 + else + err 'invalid operand' + end if + else + err 'invalid operand' + end match + end macro +end iterate + +iterate , FMUL,1100001000b, FMULS,1110000000b, FMULSU,1110001000b + macro instr? Rd,Rr + local value,d,r + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + if d >= 16 & d <= 23 + value = +Rr + if value metadata 1 relativeto R & value eq value element 1 + r = value metadata 1 - R + if r >= 16 & r <= 23 + dw opcode + (r-16) + (d-16) shl 4 + else + err 'specified register not allowed for this instruction' + end if + else + err 'invalid operand' + end if + else + err 'specified register not allowed for this instruction' + end if + else + err 'invalid operand' + end if + end macro +end iterate + +macro ICALL? + dw 1001'0101'0000'1001b +end macro + +macro IJMP? + dw 1001'0100'0000'1001b +end macro + +macro IN? Rd,A + local value,d + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + value = +A + if A >= 0 & A <= 63 + dw A and 1111b + d shl 4 + (A shr 4) shl 9 + 10110b shl 11 + else + err 'address out of range' + end if + else + err 'invalid operand' + end if +end macro + +macro JMP? k + local offset + offset = -($ shr 1 + 1) + k + if offset>=-2048 & offset<=2047 + dw offset and 111111111111b + 1100b shl 12 + else + offset = +k + if offset>=0 & offset<=1 shl 22 - 1 + dw (offset shr 16) and 1 + 110b shl 1 + (offset shr 17) shl 4 + 1001010b shl 9 + dw offset and (1 shl 16 - 1) + else + err 'value out of range' + end if + end if +end macro + +iterate , LAC,0110b, LAS,0101b, LAT,0111b, XCH,0100b + macro instr? Rw,Rd + local value,d + match =Z?, Rw + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + dw opcode + d shl 4 + 1001001b shl 9 + else + err 'invalid operand' + end if + else + err 'invalid operand' + end match + end macro +end iterate + +macro LD? Rd,Rw + local value,d + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + match =X?, Rw + dw 1100b + d shl 4 + 1001000b shl 9 + else match =Y?, Rw + dw 1000b + d shl 4 + 1000000b shl 9 + else match =Z?, Rw + dw 0000b + d shl 4 + 1000000b shl 9 + else match =X?+, Rw + dw 1101b + d shl 4 + 1001000b shl 9 + else match =Y?+, Rw + dw 1001b + d shl 4 + 1001000b shl 9 + else match =Z?+, Rw + dw 0001b + d shl 4 + 1001000b shl 9 + else match -=X?, Rw + dw 1110b + d shl 4 + 1001000b shl 9 + else match -=Y?, Rw + dw 1010b + d shl 4 + 1001000b shl 9 + else match -=Z?, Rw + dw 0010b + d shl 4 + 1001000b shl 9 + else + err 'invalid operand' + end match + else + err 'invalid operand' + end if +end macro + +macro LDD? Rd,Rq + local value,d,q + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + value = +Rq + if value relativeto Y + q = value - Y + if q >= 0 & q <= 63 + dw q and 111b + 1 shl 3 + d shl 4 + ((q shr 3) and 11b) shl 10 + (q shr 5) shl 13 + 10b shl 14 + else + err 'value out of range' + end if + else if value relativeto Z + q = value - Z + if q >= 0 & q <= 63 + dw q and 111b + d shl 4 + ((q shr 3) and 11b) shl 10 + (q shr 5) shl 13 + 10b shl 14 + else + err 'value out of range' + end if + else + err 'invalid operand' + end if + else + err 'invalid operand' + end if +end macro + +macro LDS? Rd,k + local value,d + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + value = +k + if value >= 0 & value <= 65535 + dw d shl 4 + 1001000b shl 9 + dw value + else + err 'address out of range' + end if + else + err 'invalid operand' + end if +end macro + +macro LSL? r + ADD r,r +end macro + +macro MOVW? args& + local value,d,r + match Rdh:Rdl=,Rrh:Rrl, args + value = +Rdl + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + value = +Rdh + if value metadata 1 relativeto R & value eq value element 1 + if value metadata 1 - R = d + 1 & d and 1 = 0 + value = +Rrl + if value metadata 1 relativeto R & value eq value element 1 + r = value metadata 1 - R + value = +Rrh + if value metadata 1 relativeto R & value eq value element 1 + if value metadata 1 - R = r + 1 & r and 1 = 0 + dw r shr 1 + (d shr 1) shl 4 + 1 shl 8 + else + err 'invalid operand' + end if + else + err 'invalid operand' + end if + else + err 'invalid operand' + end if + else + err 'invalid operand' + end if + else + err 'invalid operand' + end if + else + err 'invalid operand' + end if + else match Rd=,Rr,args + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + if d and 1 = 0 + value = +Rr + if value metadata 1 relativeto R & value eq value element 1 + r = value metadata 1 - R + if r and 1 = 0 + dw r shr 1 + (d shr 1) shl 4 + 1 shl 8 + else + err 'invalid operand' + end if + else + err 'invalid operand' + end if + else + err 'invalid operand' + end if + else + err 'invalid operand' + end if + else + err 'invalid operand' + end match +end macro + +iterate , MULS,0010b, MULSU,0011b + macro instr? Rd,Rr + local value,d,r + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + if d >= 16 & d <= 31 + value = +Rr + if value metadata 1 relativeto R & value eq value element 1 + r = value metadata 1 - R + if r >= 16 & r <= 31 + dw (r-16) + (d-16) shl 4 + opcode shl 8 + else + err 'specified register not allowed for this instruction' + end if + else + err 'invalid operand' + end if + else + err 'specified register not allowed for this instruction' + end if + else + err 'invalid operand' + end if + end macro +end iterate + +macro NOP? + dw 0 +end macro + +macro OUT? A,Rr + local value,r + value = +Rr + if value metadata 1 relativeto R & value eq value element 1 + r = value metadata 1 - R + value = +A + if A >= 0 & A <= 63 + dw A and 1111b + r shl 4 + (A shr 4) shl 9 + 10111b shl 11 + else + err 'address out of range' + end if + else + err 'invalid operand' + end if +end macro + +iterate , POP,000b, PUSH,001b + macro instr? Rd + local value,d + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + dw 1111b + d shl 4 + opcode shl 9 + 1001b shl 12 + else + err 'invalid operand' + end if + end macro +end iterate + +iterate , RCALL,1101b, RJMP,1100b + macro instr? k + local offset + offset = -($ shr 1 + 1) + k + if offset>=-2048 & offset<=2047 + dw offset and 111111111111b + opcode shl 12 + else + err 'relative jump out of range' + end if + end macro +end iterate + +macro RET? + dw 1001'0101'0000'1000b +end macro + +macro RETI? + dw 1001'0101'0001'1000b +end macro + +macro ROL? r + ADC r,r +end macro + +macro SEC? + dw 1001'0100'0000'1000b +end macro + +macro SEH? + dw 1001'0100'0101'1000b +end macro + +macro SEI? + dw 1001'0100'0111'1000b +end macro + +macro SEN? + dw 1001'0100'0010'1000b +end macro + +macro SER? Rd + local value,d + value = +Rd + if value metadata 1 relativeto R & value eq value element 1 + d = value metadata 1 - R + if d >= 16 + dw 1111b + (d-16) shl 4 + 11101111b shl 8 + else + err 'specified register not allowed for this instruction' + end if + else + err 'invalid operand' + end if +end macro + +macro SES? + dw 1001'0100'0100'1000b +end macro + +macro SET? + dw 1001'0100'0110'1000b +end macro + +macro SEV? + dw 1001'0100'0011'1000b +end macro + +macro SEZ? + dw 1001'0100'0001'1000b +end macro + +macro SLEEP? + dw 1001'0101'1000'1000b +end macro + +macro SPM? args + match , args + dw 1001'0101'1110'1000b + else match =Z?+,args + dw 1001'0101'1111'1000b + else + err 'invalid operand' + end match +end macro + +macro ST? Rw,Rr + local value,r + value = +Rr + if value metadata 1 relativeto R & value eq value element 1 + r = value metadata 1 - R + match =X?, Rw + dw 1100b + r shl 4 + 1001001b shl 9 + else match =Y?, Rw + dw 1000b + r shl 4 + 1000001b shl 9 + else match =Z?, Rw + dw 0000b + r shl 4 + 1000001b shl 9 + else match =X?+, Rw + dw 1101b + r shl 4 + 1001001b shl 9 + else match =Y?+, Rw + dw 1001b + r shl 4 + 1001001b shl 9 + else match =Z?+, Rw + dw 0001b + r shl 4 + 1001001b shl 9 + else match -=X?, Rw + dw 1110b + r shl 4 + 1001001b shl 9 + else match -=Y?, Rw + dw 1010b + r shl 4 + 1001001b shl 9 + else match -=Z?, Rw + dw 0010b + r shl 4 + 1001001b shl 9 + else + err 'invalid operand' + end match + else + err 'invalid operand' + end if +end macro + +macro STD? Rq,Rr + local value,r,q + value = +Rr + if value metadata 1 relativeto R & value eq value element 1 + r = value metadata 1 - R + value = +Rq + if value relativeto Y + q = value - Y + if q >= 0 & q <= 63 + dw q and 111b + 1 shl 3 + r shl 4 + 1 shl 9 + ((q shr 3) and 11b) shl 10 + (q shr 5) shl 13 + 10b shl 14 + else + err 'value out of range' + end if + else if value relativeto Z + q = value - Z + if q >= 0 & q <= 63 + dw q and 111b + r shl 4 + 1 shl 9 + ((q shr 3) and 11b) shl 10 + (q shr 5) shl 13 + 10b shl 14 + else + err 'value out of range' + end if + else + err 'invalid operand' + end if + else + err 'invalid operand' + end if +end macro + +macro STS? k,Rr + local value,r + value = +Rr + if value metadata 1 relativeto R & value eq value element 1 + r = value metadata 1 - R + value = +k + if value >= 0 & value <= 65535 + dw r shl 4 + 1001001b shl 9 + dw value + else + err 'address out of range' + end if + else + err 'invalid operand' + end if +end macro + +macro TST? Rd + AND Rd,Rd +end macro + +macro WDR? + dw 1001'0101'1010'1000b +end macro + +macro BREAK? % + if defined % + break ; loop control directive + else + dw 1001'0101'1001'1000b + end if +end macro + +define __EVAL_BREAK eval 'break %' + +calminstruction BREAK? + assemble __EVAL_BREAK +end calminstruction + +PC? equ ($ shr 1) + +calminstruction (label) ? definition& + local command + match : command?, definition + jno other + match :: command?, definition + jyes other + arrange definition, =LABEL label =AT =$ =shr 1 + assemble definition + assemble command + exit + other: + arrange definition, label definition + assemble definition +end calminstruction + +if defined SRAM_START + DSEG?.$ = SRAM_START +else + DSEG?.$ = 60h +end if + +DSEG? = 0 + +define DIRECTIVE DIRECTIVE + +macro __ORG? addr* + if ~ DSEG? + org (addr) shl 1 + else + org addr + end if +end macro +DIRECTIVE.ORG? equ __ORG + +macro __EQU? definition& + match name == value, definition + name? = value + else + err 'invalid definition' + end match +end macro +DIRECTIVE.EQU? equ __EQU + +macro __DSEG? + if ~ DSEG? + virtual at DSEG?.$ + DSEG? = 1 + end if +end macro +DIRECTIVE.DSEG? equ __DSEG + +macro __CSEG? + if DSEG? + DSEG?.$ = $ + end virtual + DSEG? = 0 + end if +end macro +DIRECTIVE.CSEG? equ __CSEG + +calminstruction ? line& + local command + match .command, line + jno pass + transform command, DIRECTIVE + jno pass + assemble command + exit + pass: + assemble line +end calminstruction diff --git a/toolchain/fasmg.kl0e/examples/avr/counter.asm b/toolchain/fasmg.kl0e/examples/avr/counter.asm new file mode 100644 index 0000000..0b42cae --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/avr/counter.asm @@ -0,0 +1,54 @@ + +; This example upon each reset increases the 8-bit counter stored in EEPROM +; and then presents the bits of this value on the pins of port A. + +include "avr.inc" +include "..\8051\hex.inc" + +include "m16def.inc" + +.org 0 + rjmp start + +start: + ldi r16,RAMEND and $ff + out spl,r16 + ldi r16,RAMEND shr 8 + out sph,r16 + + ldi r16,$37 + call eeprom_read_byte + mov r17,r16 + inc r17 + ldi r16,$37 + call eeprom_write_byte + + ldi r18,11111111b + out DDRA,r18 + out PORTA,r17 + +hang: jmp hang + +eeprom_read_byte: +; r16 = EEPROM address +; returns: r16 = byte data + sbic EECR,EEWE + jmp eeprom_read_byte + out EEARL,r16 + sbi EECR,EERE + in r16,EEDR + ret + +eeprom_write_byte: +; r16 = EEPROM address +; r17 = byte data + cli + while_eeprom_busy: + sbic EECR,EEWE + jmp while_eeprom_busy + out EEARL,r16 + out EEDR,r17 + sbi EECR,EEMWE + sbi EECR,EEWE + sei + ret diff --git a/toolchain/fasmg.kl0e/examples/avr/m16def.inc b/toolchain/fasmg.kl0e/examples/avr/m16def.inc new file mode 100644 index 0000000..6b9d644 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/avr/m16def.inc @@ -0,0 +1,738 @@ + +; Register/Bit Definitions for the ATmega16 + +; I/O Registers +.equ SREG = 0x3f +.equ SPH = 0x3e +.equ SPL = 0x3d +.equ OCR0 = 0x3c +.equ GICR = 0x3b +.equ GIFR = 0x3a +.equ TIMSK = 0x39 +.equ TIFR = 0x38 +.equ SPMCSR = 0x37 +.equ TWCR = 0x36 +.equ MCUCR = 0x35 +.equ MCUCSR = 0x34 +.equ TCCR0 = 0x33 +.equ TCNT0 = 0x32 +.equ OSCCAL = 0x31 +.equ OCDR = 0x31 +.equ SFIOR = 0x30 +.equ TCCR1A = 0x2f +.equ TCCR1B = 0x2e +.equ TCNT1H = 0x2d +.equ TCNT1L = 0x2c +.equ OCR1AH = 0x2b +.equ OCR1AL = 0x2a +.equ OCR1BH = 0x29 +.equ OCR1BL = 0x28 +.equ ICR1H = 0x27 +.equ ICR1L = 0x26 +.equ TCCR2 = 0x25 +.equ TCNT2 = 0x24 +.equ OCR2 = 0x23 +.equ ASSR = 0x22 +.equ WDTCR = 0x21 +.equ UBRRH = 0x20 +.equ UCSRC = 0x20 +.equ EEARH = 0x1f +.equ EEARL = 0x1e +.equ EEDR = 0x1d +.equ EECR = 0x1c +.equ PORTA = 0x1b +.equ DDRA = 0x1a +.equ PINA = 0x19 +.equ PORTB = 0x18 +.equ DDRB = 0x17 +.equ PINB = 0x16 +.equ PORTC = 0x15 +.equ DDRC = 0x14 +.equ PINC = 0x13 +.equ PORTD = 0x12 +.equ DDRD = 0x11 +.equ PIND = 0x10 +.equ SPDR = 0x0f +.equ SPSR = 0x0e +.equ SPCR = 0x0d +.equ UDR = 0x0c +.equ UCSRA = 0x0b +.equ UCSRB = 0x0a +.equ UBRRL = 0x09 +.equ ACSR = 0x08 +.equ ADMUX = 0x07 +.equ ADCSRA = 0x06 +.equ ADCH = 0x05 +.equ ADCL = 0x04 +.equ TWDR = 0x03 +.equ TWAR = 0x02 +.equ TWSR = 0x01 +.equ TWBR = 0x00 + +; TCCR0 - Timer/Counter Control Register +.equ CS00 = 0 ; Clock Select 1 +.equ CS01 = 1 ; Clock Select 1 +.equ CS02 = 2 ; Clock Select 2 +.equ WGM01 = 3 ; Waveform Generation Mode 1 +.equ CTC0 = WGM01 ; For compatibility +.equ COM00 = 4 ; Compare match Output Mode 0 +.equ COM01 = 5 ; Compare Match Output Mode 1 +.equ WGM00 = 6 ; Waveform Generation Mode 0 +.equ PWM0 = WGM00 ; For compatibility +.equ FOC0 = 7 ; Force Output Compare + +; TCNT0 - Timer/Counter Register +.equ TCNT0_0 = 0 +.equ TCNT0_1 = 1 +.equ TCNT0_2 = 2 +.equ TCNT0_3 = 3 +.equ TCNT0_4 = 4 +.equ TCNT0_5 = 5 +.equ TCNT0_6 = 6 +.equ TCNT0_7 = 7 + +; OCR0 - Output Compare Register +.equ OCR0_0 = 0 +.equ OCR0_1 = 1 +.equ OCR0_2 = 2 +.equ OCR0_3 = 3 +.equ OCR0_4 = 4 +.equ OCR0_5 = 5 +.equ OCR0_6 = 6 +.equ OCR0_7 = 7 + +; TIMSK - Timer/Counter Interrupt Mask Register +.equ TOIE0 = 0 ; Timer/Counter0 Overflow Interrupt Enable +.equ OCIE0 = 1 ; Timer/Counter0 Output Compare Match Interrupt register +.equ TOIE1 = 2 ; Timer/Counter1 Overflow Interrupt Enable +.equ OCIE1B = 3 ; Timer/Counter1 Output CompareB Match Interrupt Enable +.equ OCIE1A = 4 ; Timer/Counter1 Output CompareA Match Interrupt Enable +.equ TICIE1 = 5 ; Timer/Counter1 Input Capture Interrupt Enable +.equ TOIE2 = 6 ; Timer/Counter2 Overflow Interrupt Enable +.equ OCIE2 = 7 ; Timer/Counter2 Output Compare Match Interrupt Enable + +; TIFR - Timer/Counter Interrupt Flag register +.equ TOV0 = 0 ; Timer/Counter0 Overflow Flag +.equ OCF0 = 1 ; Output Compare Flag 0 +.equ TOV2 = 6 ; Timer/Counter2 Overflow Flag +.equ OCF2 = 7 ; Output Compare Flag 2 + +; SFIOR - Special Function IO Register +.equ PSR10 = 0 ; Prescaler Reset Timer/Counter1 and Timer/Counter0 + +; TIFR - Timer/Counter Interrupt Flag register +.equ TOV1 = 2 ; Timer/Counter1 Overflow Flag +.equ OCF1B = 3 ; Output Compare Flag 1B +.equ OCF1A = 4 ; Output Compare Flag 1A +.equ ICF1 = 5 ; Input Capture Flag 1 + +; TCCR1A - Timer/Counter1 Control Register A +.equ WGM10 = 0 ; Waveform Generation Mode +.equ PWM10 = WGM10 ; For compatibility +.equ WGM11 = 1 ; Waveform Generation Mode +.equ PWM11 = WGM11 ; For compatibility +.equ FOC1B = 2 ; Force Output Compare 1B +.equ FOC1A = 3 ; Force Output Compare 1A +.equ COM1B0 = 4 ; Compare Output Mode 1B, bit 0 +.equ COM1B1 = 5 ; Compare Output Mode 1B, bit 1 +.equ COM1A0 = 6 ; Comparet Ouput Mode 1A, bit 0 +.equ COM1A1 = 7 ; Compare Output Mode 1A, bit 1 + +; TCCR1B - Timer/Counter1 Control Register B +.equ CS10 = 0 ; Prescaler source of Timer/Counter 1 +.equ CS11 = 1 ; Prescaler source of Timer/Counter 1 +.equ CS12 = 2 ; Prescaler source of Timer/Counter 1 +.equ WGM12 = 3 ; Waveform Generation Mode +.equ CTC10 = WGM12 ; For compatibility +.equ CTC1 = WGM12 ; For compatibility +.equ WGM13 = 4 ; Waveform Generation Mode +.equ CTC11 = WGM13 ; For compatibility +.equ ICES1 = 6 ; Input Capture 1 Edge Select +.equ ICNC1 = 7 ; Input Capture 1 Noise Canceler + +; GICR - General Interrupt Control Register +.equ GIMSK = GICR ; For compatibility +.equ IVCE = 0 ; Interrupt Vector Change Enable +.equ IVSEL = 1 ; Interrupt Vector Select +.equ INT2 = 5 ; External Interrupt Request 2 Enable +.equ INT0 = 6 ; External Interrupt Request 0 Enable +.equ INT1 = 7 ; External Interrupt Request 1 Enable + +; GIFR - General Interrupt Flag Register +.equ INTF2 = 5 ; External Interrupt Flag 2 +.equ INTF0 = 6 ; External Interrupt Flag 0 +.equ INTF1 = 7 ; External Interrupt Flag 1 + +; MCUCR - General Interrupt Control Register +.equ ISC00 = 0 ; Interrupt Sense Control 0 Bit 0 +.equ ISC01 = 1 ; Interrupt Sense Control 0 Bit 1 +.equ ISC10 = 2 ; Interrupt Sense Control 1 Bit 0 +.equ ISC11 = 3 ; Interrupt Sense Control 1 Bit 1 + +; MCUCSR - MCU Control And Status Register +.equ ISC2 = 6 ; Interrupt Sense Control 2 + +; EEDR - EEPROM Data Register +.equ EEDR0 = 0 ; EEPROM Data Register bit 0 +.equ EEDR1 = 1 ; EEPROM Data Register bit 1 +.equ EEDR2 = 2 ; EEPROM Data Register bit 2 +.equ EEDR3 = 3 ; EEPROM Data Register bit 3 +.equ EEDR4 = 4 ; EEPROM Data Register bit 4 +.equ EEDR5 = 5 ; EEPROM Data Register bit 5 +.equ EEDR6 = 6 ; EEPROM Data Register bit 6 +.equ EEDR7 = 7 ; EEPROM Data Register bit 7 + +; EECR - EEPROM Control Register +.equ EERE = 0 ; EEPROM Read Enable +.equ EEWE = 1 ; EEPROM Write Enable +.equ EEMWE = 2 ; EEPROM Master Write Enable +.equ EEWEE = EEMWE ; For compatibility +.equ EERIE = 3 ; EEPROM Ready Interrupt Enable + +; SREG - Status Register +.equ SREG_C = 0 ; Carry Flag +.equ SREG_Z = 1 ; Zero Flag +.equ SREG_N = 2 ; Negative Flag +.equ SREG_V = 3 ; Two's Complement Overflow Flag +.equ SREG_S = 4 ; Sign Bit +.equ SREG_H = 5 ; Half Carry Flag +.equ SREG_T = 6 ; Bit Copy Storage +.equ SREG_I = 7 ; Global Interrupt Enable + +; MCUCR - MCU Control Register +;.equ ISC00 = 0 ; Interrupt Sense Control 0 Bit 0 +;.equ ISC01 = 1 ; Interrupt Sense Control 0 Bit 1 +;.equ ISC10 = 2 ; Interrupt Sense Control 1 Bit 0 +;.equ ISC11 = 3 ; Interrupt Sense Control 1 Bit 1 +.equ SM0 = 4 ; Sleep Mode Select +.equ SM1 = 5 ; Sleep Mode Select +.equ SE = 6 ; Sleep Enable +.equ SM2 = 7 ; Sleep Mode Select + +; MCUCSR - MCU Control And Status Register +.equ MCUSR = MCUCSR; For compatibility +.equ PORF = 0 ; Power-on reset flag +.equ EXTRF = 1 ; External Reset Flag +.equ EXTREF = EXTRF ; For compatibility +.equ BORF = 2 ; Brown-out Reset Flag +.equ WDRF = 3 ; Watchdog Reset Flag +.equ JTRF = 4 ; JTAG Reset Flag +.equ JTD = 7 ; JTAG Interface Disable + +; OSCCAL - Oscillator Calibration Value +.equ CAL0 = 0 ; Oscillator Calibration Value Bit0 +.equ CAL1 = 1 ; Oscillator Calibration Value Bit1 +.equ CAL2 = 2 ; Oscillator Calibration Value Bit2 +.equ CAL3 = 3 ; Oscillator Calibration Value Bit3 +.equ CAL4 = 4 ; Oscillator Calibration Value Bit4 +.equ CAL5 = 5 ; Oscillator Calibration Value Bit5 +.equ CAL6 = 6 ; Oscillator Calibration Value Bit6 +.equ CAL7 = 7 ; Oscillator Calibration Value Bit7 + +; SFIOR - Special function I/O register +;.equ PSR10 = 0 ; Prescaler reset +.equ PSR2 = 1 ; Prescaler reset +.equ PUD = 2 ; Pull-up Disable +.equ ADHSM = 3 ; ADC High Speed Mode +.equ ADTS0 = 5 ; ADC High Speed Mode +.equ ADTS1 = 6 ; ADC Auto Trigger Source +.equ ADTS2 = 7 ; ADC Auto Trigger Source + +; TCCR2 - Timer/Counter2 Control Register +.equ CS20 = 0 ; Clock Select bit 0 +.equ CS21 = 1 ; Clock Select bit 1 +.equ CS22 = 2 ; Clock Select bit 2 +.equ WGM21 = 3 ; Waveform Generation Mode +.equ CTC2 = WGM21 ; For compatibility +.equ COM20 = 4 ; Compare Output Mode bit 0 +.equ COM21 = 5 ; Compare Output Mode bit 1 +.equ WGM20 = 6 ; Waveform Genration Mode +.equ PWM2 = WGM20 ; For compatibility +.equ FOC2 = 7 ; Force Output Compare + +; TCNT2 - Timer/Counter2 +.equ TCNT2_0 = 0 ; Timer/Counter 2 bit 0 +.equ TCNT2_1 = 1 ; Timer/Counter 2 bit 1 +.equ TCNT2_2 = 2 ; Timer/Counter 2 bit 2 +.equ TCNT2_3 = 3 ; Timer/Counter 2 bit 3 +.equ TCNT2_4 = 4 ; Timer/Counter 2 bit 4 +.equ TCNT2_5 = 5 ; Timer/Counter 2 bit 5 +.equ TCNT2_6 = 6 ; Timer/Counter 2 bit 6 +.equ TCNT2_7 = 7 ; Timer/Counter 2 bit 7 + +; OCR2 - Timer/Counter2 Output Compare Register +.equ OCR2_0 = 0 ; Timer/Counter2 Output Compare Register Bit 0 +.equ OCR2_1 = 1 ; Timer/Counter2 Output Compare Register Bit 1 +.equ OCR2_2 = 2 ; Timer/Counter2 Output Compare Register Bit 2 +.equ OCR2_3 = 3 ; Timer/Counter2 Output Compare Register Bit 3 +.equ OCR2_4 = 4 ; Timer/Counter2 Output Compare Register Bit 4 +.equ OCR2_5 = 5 ; Timer/Counter2 Output Compare Register Bit 5 +.equ OCR2_6 = 6 ; Timer/Counter2 Output Compare Register Bit 6 +.equ OCR2_7 = 7 ; Timer/Counter2 Output Compare Register Bit 7 + +; ASSR - Asynchronous Status Register +.equ TCR2UB = 0 ; Timer/counter Control Register2 Update Busy +.equ OCR2UB = 1 ; Output Compare Register2 Update Busy +.equ TCN2UB = 2 ; Timer/Counter2 Update Busy +.equ AS2 = 3 ; Asynchronous Timer/counter2 + +; SFIOR - Special Function IO Register +;.equ PSR2 = 1 ; Prescaler Reset Timer/Counter2 + +; SPDR - SPI Data Register +.equ SPDR0 = 0 ; SPI Data Register bit 0 +.equ SPDR1 = 1 ; SPI Data Register bit 1 +.equ SPDR2 = 2 ; SPI Data Register bit 2 +.equ SPDR3 = 3 ; SPI Data Register bit 3 +.equ SPDR4 = 4 ; SPI Data Register bit 4 +.equ SPDR5 = 5 ; SPI Data Register bit 5 +.equ SPDR6 = 6 ; SPI Data Register bit 6 +.equ SPDR7 = 7 ; SPI Data Register bit 7 + +; SPSR - SPI Status Register +.equ SPI2X = 0 ; Double SPI Speed Bit +.equ WCOL = 6 ; Write Collision Flag +.equ SPIF = 7 ; SPI Interrupt Flag + +; SPCR - SPI Control Register +.equ SPR0 = 0 ; SPI Clock Rate Select 0 +.equ SPR1 = 1 ; SPI Clock Rate Select 1 +.equ CPHA = 2 ; Clock Phase +.equ CPOL = 3 ; Clock polarity +.equ MSTR = 4 ; Master/Slave Select +.equ DORD = 5 ; Data Order +.equ SPE = 6 ; SPI Enable +.equ SPIE = 7 ; SPI Interrupt Enable + +; UDR - USART I/O Data Register +.equ UDR0 = 0 ; USART I/O Data Register bit 0 +.equ UDR1 = 1 ; USART I/O Data Register bit 1 +.equ UDR2 = 2 ; USART I/O Data Register bit 2 +.equ UDR3 = 3 ; USART I/O Data Register bit 3 +.equ UDR4 = 4 ; USART I/O Data Register bit 4 +.equ UDR5 = 5 ; USART I/O Data Register bit 5 +.equ UDR6 = 6 ; USART I/O Data Register bit 6 +.equ UDR7 = 7 ; USART I/O Data Register bit 7 + +; UCSRA - USART Control and Status Register A +.equ USR = UCSRA ; For compatibility +.equ MPCM = 0 ; Multi-processor Communication Mode +.equ U2X = 1 ; Double the USART transmission speed +.equ UPE = 2 ; Parity Error +.equ PE = UPE ; For compatibility +.equ DOR = 3 ; Data overRun +.equ FE = 4 ; Framing Error +.equ UDRE = 5 ; USART Data Register Empty +.equ TXC = 6 ; USART Transmitt Complete +.equ RXC = 7 ; USART Receive Complete + +; UCSRB - USART Control and Status Register B +.equ UCR = UCSRB ; For compatibility +.equ TXB8 = 0 ; Transmit Data Bit 8 +.equ RXB8 = 1 ; Receive Data Bit 8 +.equ UCSZ2 = 2 ; Character Size +.equ CHR9 = UCSZ2 ; For compatibility +.equ TXEN = 3 ; Transmitter Enable +.equ RXEN = 4 ; Receiver Enable +.equ UDRIE = 5 ; USART Data register Empty Interrupt Enable +.equ TXCIE = 6 ; TX Complete Interrupt Enable +.equ RXCIE = 7 ; RX Complete Interrupt Enable + +; UCSRC - USART Control and Status Register C +.equ UCPOL = 0 ; Clock Polarity +.equ UCSZ0 = 1 ; Character Size +.equ UCSZ1 = 2 ; Character Size +.equ USBS = 3 ; Stop Bit Select +.equ UPM0 = 4 ; Parity Mode Bit 0 +.equ UPM1 = 5 ; Parity Mode Bit 1 +.equ UMSEL = 6 ; USART Mode Select +.equ URSEL = 7 ; Register Select + +.equ UBRRHI = UBRRH ; For compatibility + +; TWBR - TWI Bit Rate register +.equ I2BR = TWBR ; For compatibility +.equ TWBR0 = 0 ; +.equ TWBR1 = 1 ; +.equ TWBR2 = 2 ; +.equ TWBR3 = 3 ; +.equ TWBR4 = 4 ; +.equ TWBR5 = 5 ; +.equ TWBR6 = 6 ; +.equ TWBR7 = 7 ; + +; TWCR - TWI Control Register +.equ I2CR = TWCR ; For compatibility +.equ TWIE = 0 ; TWI Interrupt Enable +.equ I2IE = TWIE ; For compatibility +.equ TWEN = 2 ; TWI Enable Bit +.equ I2EN = TWEN ; For compatibility +.equ ENI2C = TWEN ; For compatibility +.equ TWWC = 3 ; TWI Write Collition Flag +.equ I2WC = TWWC ; For compatibility +.equ TWSTO = 4 ; TWI Stop Condition Bit +.equ I2STO = TWSTO ; For compatibility +.equ TWSTA = 5 ; TWI Start Condition Bit +.equ I2STA = TWSTA ; For compatibility +.equ TWEA = 6 ; TWI Enable Acknowledge Bit +.equ I2EA = TWEA ; For compatibility +.equ TWINT = 7 ; TWI Interrupt Flag +.equ I2INT = TWINT ; For compatibility + +; TWSR - TWI Status Register +.equ I2SR = TWSR ; For compatibility +.equ TWPS0 = 0 ; TWI Prescaler +.equ TWS0 = TWPS0 ; For compatibility +.equ I2GCE = TWPS0 ; For compatibility +.equ TWPS1 = 1 ; TWI Prescaler +.equ TWS1 = TWPS1 ; For compatibility +.equ TWS3 = 3 ; TWI Status +.equ I2S3 = TWS3 ; For compatibility +.equ TWS4 = 4 ; TWI Status +.equ I2S4 = TWS4 ; For compatibility +.equ TWS5 = 5 ; TWI Status +.equ I2S5 = TWS5 ; For compatibility +.equ TWS6 = 6 ; TWI Status +.equ I2S6 = TWS6 ; For compatibility +.equ TWS7 = 7 ; TWI Status +.equ I2S7 = TWS7 ; For compatibility + +; TWDR - TWI Data register +.equ I2DR = TWDR ; For compatibility +.equ TWD0 = 0 ; TWI Data Register Bit 0 +.equ TWD1 = 1 ; TWI Data Register Bit 1 +.equ TWD2 = 2 ; TWI Data Register Bit 2 +.equ TWD3 = 3 ; TWI Data Register Bit 3 +.equ TWD4 = 4 ; TWI Data Register Bit 4 +.equ TWD5 = 5 ; TWI Data Register Bit 5 +.equ TWD6 = 6 ; TWI Data Register Bit 6 +.equ TWD7 = 7 ; TWI Data Register Bit 7 + +; TWAR - TWI (Slave) Address register +.equ I2AR = TWAR ; For compatibility +.equ TWGCE = 0 ; TWI General Call Recognition Enable Bit +.equ TWA0 = 1 ; TWI (Slave) Address register Bit 0 +.equ TWA1 = 2 ; TWI (Slave) Address register Bit 1 +.equ TWA2 = 3 ; TWI (Slave) Address register Bit 2 +.equ TWA3 = 4 ; TWI (Slave) Address register Bit 3 +.equ TWA4 = 5 ; TWI (Slave) Address register Bit 4 +.equ TWA5 = 6 ; TWI (Slave) Address register Bit 5 +.equ TWA6 = 7 ; TWI (Slave) Address register Bit 6 + +; SFIOR - Special Function IO Register +.equ ACME = 3 ; Analog Comparator Multiplexer Enable + +; ACSR - Analog Comparator Control And Status Register +.equ ACIS0 = 0 ; Analog Comparator Interrupt Mode Select bit 0 +.equ ACIS1 = 1 ; Analog Comparator Interrupt Mode Select bit 1 +.equ ACIC = 2 ; Analog Comparator Input Capture Enable +.equ ACIE = 3 ; Analog Comparator Interrupt Enable +.equ ACI = 4 ; Analog Comparator Interrupt Flag +.equ ACO = 5 ; Analog Compare Output +.equ ACBG = 6 ; Analog Comparator Bandgap Select +.equ ACD = 7 ; Analog Comparator Disable + +; ADMUX - The ADC multiplexer Selection Register +.equ MUX0 = 0 ; Analog Channel and Gain Selection Bits +.equ MUX1 = 1 ; Analog Channel and Gain Selection Bits +.equ MUX2 = 2 ; Analog Channel and Gain Selection Bits +.equ MUX3 = 3 ; Analog Channel and Gain Selection Bits +.equ MUX4 = 4 ; Analog Channel and Gain Selection Bits +.equ ADLAR = 5 ; Left Adjust Result +.equ REFS0 = 6 ; Reference Selection Bit 0 +.equ REFS1 = 7 ; Reference Selection Bit 1 + +; ADCSRA - The ADC Control and Status register +.equ ADPS0 = 0 ; ADC Prescaler Select Bits +.equ ADPS1 = 1 ; ADC Prescaler Select Bits +.equ ADPS2 = 2 ; ADC Prescaler Select Bits +.equ ADIE = 3 ; ADC Interrupt Enable +.equ ADIF = 4 ; ADC Interrupt Flag +.equ ADATE = 5 ; When this bit is written to one,the Timer/Counter2 prescaler will be reset.The bit will be cleared by hardware after the operation is performed.Writing a zero to this bit will have no effect.This bit will always be read as zero if Timer/Counter2 is clocked by the internal CPU clock.If this bit is written when Timer/Counter2 is operating in asynchronous mode,the bit will remain one until the prescaler has been reset. +.equ ADFR = ADATE ; For compatibility +.equ ADSC = 6 ; ADC Start Conversion +.equ ADEN = 7 ; ADC Enable + +; ADCH - ADC Data Register High Byte +.equ ADCH0 = 0 ; ADC Data Register High Byte Bit 0 +.equ ADCH1 = 1 ; ADC Data Register High Byte Bit 1 +.equ ADCH2 = 2 ; ADC Data Register High Byte Bit 2 +.equ ADCH3 = 3 ; ADC Data Register High Byte Bit 3 +.equ ADCH4 = 4 ; ADC Data Register High Byte Bit 4 +.equ ADCH5 = 5 ; ADC Data Register High Byte Bit 5 +.equ ADCH6 = 6 ; ADC Data Register High Byte Bit 6 +.equ ADCH7 = 7 ; ADC Data Register High Byte Bit 7 + +; ADCL - ADC Data Register Low Byte +.equ ADCL0 = 0 ; ADC Data Register Low Byte Bit 0 +.equ ADCL1 = 1 ; ADC Data Register Low Byte Bit 1 +.equ ADCL2 = 2 ; ADC Data Register Low Byte Bit 2 +.equ ADCL3 = 3 ; ADC Data Register Low Byte Bit 3 +.equ ADCL4 = 4 ; ADC Data Register Low Byte Bit 4 +.equ ADCL5 = 5 ; ADC Data Register Low Byte Bit 5 +.equ ADCL6 = 6 ; ADC Data Register Low Byte Bit 6 +.equ ADCL7 = 7 ; ADC Data Register Low Byte Bit 7 + +; OCDR - On-Chip Debug Related Register in I/O Memory +.equ OCDR0 = 0 ; On-Chip Debug Register Bit 0 +.equ OCDR1 = 1 ; On-Chip Debug Register Bit 1 +.equ OCDR2 = 2 ; On-Chip Debug Register Bit 2 +.equ OCDR3 = 3 ; On-Chip Debug Register Bit 3 +.equ OCDR4 = 4 ; On-Chip Debug Register Bit 4 +.equ OCDR5 = 5 ; On-Chip Debug Register Bit 5 +.equ OCDR6 = 6 ; On-Chip Debug Register Bit 6 +.equ OCDR7 = 7 ; On-Chip Debug Register Bit 7 +.equ IDRD = OCDR7 ; For compatibility + +; MCUCSR - MCU Control And Status Register +;.equ JTRF = 4 ; JTAG Reset Flag +;.equ JTD = 7 ; JTAG Interface Disable + +; SPMCSR - Store Program Memory Control Register +.equ SPMCR = SPMCSR ; For compatibility +.equ SPMEN = 0 ; Store Program Memory Enable +.equ PGERS = 1 ; Page Erase +.equ PGWRT = 2 ; Page Write +.equ BLBSET = 3 ; Boot Lock Bit Set +.equ RWWSRE = 4 ; Read While Write section read enable +.equ ASRE = RWWSRE ; For compatibility +.equ RWWSB = 6 ; Read While Write Section Busy +.equ ASB = RWWSB ; For compatibility +.equ SPMIE = 7 ; SPM Interrupt Enable + +; PORTA - Port A Data Register +.equ PORTA0 = 0 ; Port A Data Register bit 0 +.equ PA0 = 0 ; For compatibility +.equ PORTA1 = 1 ; Port A Data Register bit 1 +.equ PA1 = 1 ; For compatibility +.equ PORTA2 = 2 ; Port A Data Register bit 2 +.equ PA2 = 2 ; For compatibility +.equ PORTA3 = 3 ; Port A Data Register bit 3 +.equ PA3 = 3 ; For compatibility +.equ PORTA4 = 4 ; Port A Data Register bit 4 +.equ PA4 = 4 ; For compatibility +.equ PORTA5 = 5 ; Port A Data Register bit 5 +.equ PA5 = 5 ; For compatibility +.equ PORTA6 = 6 ; Port A Data Register bit 6 +.equ PA6 = 6 ; For compatibility +.equ PORTA7 = 7 ; Port A Data Register bit 7 +.equ PA7 = 7 ; For compatibility + +; DDRA - Port A Data Direction Register +.equ DDA0 = 0 ; Data Direction Register, Port A, bit 0 +.equ DDA1 = 1 ; Data Direction Register, Port A, bit 1 +.equ DDA2 = 2 ; Data Direction Register, Port A, bit 2 +.equ DDA3 = 3 ; Data Direction Register, Port A, bit 3 +.equ DDA4 = 4 ; Data Direction Register, Port A, bit 4 +.equ DDA5 = 5 ; Data Direction Register, Port A, bit 5 +.equ DDA6 = 6 ; Data Direction Register, Port A, bit 6 +.equ DDA7 = 7 ; Data Direction Register, Port A, bit 7 + +; PINA - Port A Input Pins +.equ PINA0 = 0 ; Input Pins, Port A bit 0 +.equ PINA1 = 1 ; Input Pins, Port A bit 1 +.equ PINA2 = 2 ; Input Pins, Port A bit 2 +.equ PINA3 = 3 ; Input Pins, Port A bit 3 +.equ PINA4 = 4 ; Input Pins, Port A bit 4 +.equ PINA5 = 5 ; Input Pins, Port A bit 5 +.equ PINA6 = 6 ; Input Pins, Port A bit 6 +.equ PINA7 = 7 ; Input Pins, Port A bit 7 + +; PORTB - Port B Data Register +.equ PORTB0 = 0 ; Port B Data Register bit 0 +.equ PB0 = 0 ; For compatibility +.equ PORTB1 = 1 ; Port B Data Register bit 1 +.equ PB1 = 1 ; For compatibility +.equ PORTB2 = 2 ; Port B Data Register bit 2 +.equ PB2 = 2 ; For compatibility +.equ PORTB3 = 3 ; Port B Data Register bit 3 +.equ PB3 = 3 ; For compatibility +.equ PORTB4 = 4 ; Port B Data Register bit 4 +.equ PB4 = 4 ; For compatibility +.equ PORTB5 = 5 ; Port B Data Register bit 5 +.equ PB5 = 5 ; For compatibility +.equ PORTB6 = 6 ; Port B Data Register bit 6 +.equ PB6 = 6 ; For compatibility +.equ PORTB7 = 7 ; Port B Data Register bit 7 +.equ PB7 = 7 ; For compatibility + +; DDRB - Port B Data Direction Register +.equ DDB0 = 0 ; Port B Data Direction Register bit 0 +.equ DDB1 = 1 ; Port B Data Direction Register bit 1 +.equ DDB2 = 2 ; Port B Data Direction Register bit 2 +.equ DDB3 = 3 ; Port B Data Direction Register bit 3 +.equ DDB4 = 4 ; Port B Data Direction Register bit 4 +.equ DDB5 = 5 ; Port B Data Direction Register bit 5 +.equ DDB6 = 6 ; Port B Data Direction Register bit 6 +.equ DDB7 = 7 ; Port B Data Direction Register bit 7 + +; PINB - Port B Input Pins +.equ PINB0 = 0 ; Port B Input Pins bit 0 +.equ PINB1 = 1 ; Port B Input Pins bit 1 +.equ PINB2 = 2 ; Port B Input Pins bit 2 +.equ PINB3 = 3 ; Port B Input Pins bit 3 +.equ PINB4 = 4 ; Port B Input Pins bit 4 +.equ PINB5 = 5 ; Port B Input Pins bit 5 +.equ PINB6 = 6 ; Port B Input Pins bit 6 +.equ PINB7 = 7 ; Port B Input Pins bit 7 + +; PORTC - Port C Data Register +.equ PORTC0 = 0 ; Port C Data Register bit 0 +.equ PC0 = 0 ; For compatibility +.equ PORTC1 = 1 ; Port C Data Register bit 1 +.equ PC1 = 1 ; For compatibility +.equ PORTC2 = 2 ; Port C Data Register bit 2 +.equ PC2 = 2 ; For compatibility +.equ PORTC3 = 3 ; Port C Data Register bit 3 +.equ PC3 = 3 ; For compatibility +.equ PORTC4 = 4 ; Port C Data Register bit 4 +.equ PC4 = 4 ; For compatibility +.equ PORTC5 = 5 ; Port C Data Register bit 5 +.equ PC5 = 5 ; For compatibility +.equ PORTC6 = 6 ; Port C Data Register bit 6 +.equ PC6 = 6 ; For compatibility +.equ PORTC7 = 7 ; Port C Data Register bit 7 +.equ PC7 = 7 ; For compatibility + +; DDRC - Port C Data Direction Register +.equ DDC0 = 0 ; Port C Data Direction Register bit 0 +.equ DDC1 = 1 ; Port C Data Direction Register bit 1 +.equ DDC2 = 2 ; Port C Data Direction Register bit 2 +.equ DDC3 = 3 ; Port C Data Direction Register bit 3 +.equ DDC4 = 4 ; Port C Data Direction Register bit 4 +.equ DDC5 = 5 ; Port C Data Direction Register bit 5 +.equ DDC6 = 6 ; Port C Data Direction Register bit 6 +.equ DDC7 = 7 ; Port C Data Direction Register bit 7 + +; PINC - Port C Input Pins +.equ PINC0 = 0 ; Port C Input Pins bit 0 +.equ PINC1 = 1 ; Port C Input Pins bit 1 +.equ PINC2 = 2 ; Port C Input Pins bit 2 +.equ PINC3 = 3 ; Port C Input Pins bit 3 +.equ PINC4 = 4 ; Port C Input Pins bit 4 +.equ PINC5 = 5 ; Port C Input Pins bit 5 +.equ PINC6 = 6 ; Port C Input Pins bit 6 +.equ PINC7 = 7 ; Port C Input Pins bit 7 + +; PORTD - Port D Data Register +.equ PORTD0 = 0 ; Port D Data Register bit 0 +.equ PD0 = 0 ; For compatibility +.equ PORTD1 = 1 ; Port D Data Register bit 1 +.equ PD1 = 1 ; For compatibility +.equ PORTD2 = 2 ; Port D Data Register bit 2 +.equ PD2 = 2 ; For compatibility +.equ PORTD3 = 3 ; Port D Data Register bit 3 +.equ PD3 = 3 ; For compatibility +.equ PORTD4 = 4 ; Port D Data Register bit 4 +.equ PD4 = 4 ; For compatibility +.equ PORTD5 = 5 ; Port D Data Register bit 5 +.equ PD5 = 5 ; For compatibility +.equ PORTD6 = 6 ; Port D Data Register bit 6 +.equ PD6 = 6 ; For compatibility +.equ PORTD7 = 7 ; Port D Data Register bit 7 +.equ PD7 = 7 ; For compatibility + +; DDRD - Port D Data Direction Register +.equ DDD0 = 0 ; Port D Data Direction Register bit 0 +.equ DDD1 = 1 ; Port D Data Direction Register bit 1 +.equ DDD2 = 2 ; Port D Data Direction Register bit 2 +.equ DDD3 = 3 ; Port D Data Direction Register bit 3 +.equ DDD4 = 4 ; Port D Data Direction Register bit 4 +.equ DDD5 = 5 ; Port D Data Direction Register bit 5 +.equ DDD6 = 6 ; Port D Data Direction Register bit 6 +.equ DDD7 = 7 ; Port D Data Direction Register bit 7 + +; PIND - Port D Input Pins +.equ PIND0 = 0 ; Port D Input Pins bit 0 +.equ PIND1 = 1 ; Port D Input Pins bit 1 +.equ PIND2 = 2 ; Port D Input Pins bit 2 +.equ PIND3 = 3 ; Port D Input Pins bit 3 +.equ PIND4 = 4 ; Port D Input Pins bit 4 +.equ PIND5 = 5 ; Port D Input Pins bit 5 +.equ PIND6 = 6 ; Port D Input Pins bit 6 +.equ PIND7 = 7 ; Port D Input Pins bit 7 + +; WDTCR - Watchdog Timer Control Register +.equ WDP0 = 0 ; Watch Dog Timer Prescaler bit 0 +.equ WDP1 = 1 ; Watch Dog Timer Prescaler bit 1 +.equ WDP2 = 2 ; Watch Dog Timer Prescaler bit 2 +.equ WDE = 3 ; Watch Dog Enable +.equ WDTOE = 4 ; RW +.equ WDDE = WDTOE ; For compatibility + +; Locks Bits +.equ LB1 = 0 ; Lock bit +.equ LB2 = 1 ; Lock bit +.equ BLB01 = 2 ; Boot Lock bit +.equ BLB02 = 3 ; Boot Lock bit +.equ BLB11 = 4 ; Boot lock bit +.equ BLB12 = 5 ; Boot lock bit + +; Low Fuse Bits +.equ CKSEL0 = 0 ; Select Clock Source +.equ CKSEL1 = 1 ; Select Clock Source +.equ CKSEL2 = 2 ; Select Clock Source +.equ CKSEL3 = 3 ; Select Clock Source +.equ SUT0 = 4 ; Select start-up time +.equ SUT1 = 5 ; Select start-up time +.equ BODEN = 6 ; Brown out detector enable +.equ BODLEVEL= 7 ; Brown out detector trigger level + +; High Fuse Bits +.equ BOOTRST = 0 ; Select Reset Vector +.equ BOOTSZ0 = 1 ; Select Boot Size +.equ BOOTSZ1 = 2 ; Select Boot Size +.equ EESAVE = 3 ; EEPROM memory is preserved through chip erase +.equ CKOPT = 4 ; Oscillator Options +.equ SPIEN = 5 ; Enable Serial programming and Data Downloading +.equ JTAGEN = 6 ; Enable JTAG +.equ OCDEN = 7 ; Enable OCD + +; Data Memory +.equ FLASHEND = 0x1fff ; Note: Word address +.equ IOEND = 0x003f +.equ SRAM_START = 0x0060 +.equ SRAM_SIZE = 1024 +.equ RAMEND = 0x045f +.equ XRAMEND = 0x0000 +.equ E2END = 0x01ff +.equ EEPROMEND = 0x01ff +.equ EEADRBITS = 9 + +; Bootloader +.equ NRWW_START_ADDR = 0x1c00 +.equ NRWW_STOP_ADDR = 0x1fff +.equ RWW_START_ADDR = 0x0 +.equ RWW_STOP_ADDR = 0x1bff +.equ PAGESIZE = 64 +.equ FIRSTBOOTSTART = 0x1f80 +.equ SECONDBOOTSTART = 0x1f00 +.equ THIRDBOOTSTART = 0x1e00 +.equ FOURTHBOOTSTART = 0x1c00 +.equ SMALLBOOTSTART = FIRSTBOOTSTART +.equ LARGEBOOTSTART = FOURTHBOOTSTART + +; Interrupt Vectors +.equ INT0addr = 0x0002 ; External Interrupt Request 0 +.equ INT1addr = 0x0004 ; External Interrupt Request 1 +.equ OC2addr = 0x0006 ; Timer/Counter2 Compare Match +.equ OVF2addr = 0x0008 ; Timer/Counter2 Overflow +.equ ICP1addr = 0x000a ; Timer/Counter1 Capture Event +.equ OC1Aaddr = 0x000c ; Timer/Counter1 Compare Match A +.equ OC1Baddr = 0x000e ; Timer/Counter1 Compare Match B +.equ OVF1addr = 0x0010 ; Timer/Counter1 Overflow +.equ OVF0addr = 0x0012 ; Timer/Counter0 Overflow +.equ SPIaddr = 0x0014 ; Serial Transfer Complete +.equ URXCaddr = 0x0016 ; USART, Rx Complete +.equ UDREaddr = 0x0018 ; USART Data Register Empty +.equ UTXCaddr = 0x001a ; USART, Tx Complete +.equ ADCCaddr = 0x001c ; ADC Conversion Complete +.equ ERDYaddr = 0x001e ; EEPROM Ready +.equ ACIaddr = 0x0020 ; Analog Comparator +.equ TWIaddr = 0x0022 ; 2-wire Serial Interface +.equ INT2addr = 0x0024 ; External Interrupt Request 2 +.equ OC0addr = 0x0026 ; Timer/Counter0 Compare Match +.equ SPMRaddr = 0x0028 ; Store Program Memory Ready + +.equ INT_VECTORS_SIZE = 42 ; size in words + diff --git a/toolchain/fasmg.kl0e/examples/avr/make.cmd b/toolchain/fasmg.kl0e/examples/avr/make.cmd new file mode 100644 index 0000000..b4a992c --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/avr/make.cmd @@ -0,0 +1 @@ +fasmg counter.asm counter.hex diff --git a/toolchain/fasmg.kl0e/examples/jvm/Test.asm b/toolchain/fasmg.kl0e/examples/jvm/Test.asm new file mode 100644 index 0000000..34aaff1 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/jvm/Test.asm @@ -0,0 +1,134 @@ + +; This example uses a very simple set of macroinstructions to generate +; the basic structures of JVM class file. +; Please refer to "The Java Virtual Machine Specification" for the detailed +; information on this file format. + +include 'jclass.inc' + +format binary as 'class' + + u4 0xcafebabe ; magic + u2 0,49 ; minor and major version + + constant_pool + + _Code constant_utf8 'Code' + _init constant_utf8 '' + _main constant_utf8 'main' + _void_arrstr constant_utf8 '([Ljava/lang/String;)V' + Test_class constant_class _Test + _Test constant_utf8 'Test' + + Object_init constant_methodref Object_class,init_method + Object_class constant_class _Object + _Object constant_utf8 'java/lang/Object' + init_method constant_nameandtype _init,_void + _void constant_utf8 '()V' + + System.out constant_fieldref System_class,out_field + System_class constant_class _System + _System constant_utf8 'java/lang/System' + out_field constant_nameandtype _out,PrintStream_type + _out constant_utf8 'out' + PrintStream_type constant_utf8 'Ljava/io/PrintStream;' + + PrintStream_println constant_methodref PrintStream_class,println_method + PrintStream_class constant_class _PrintStream + _PrintStream constant_utf8 'java/io/PrintStream' + println_method constant_nameandtype _println,_void_str + _println constant_utf8 'println' + _void_str constant_utf8 '(Ljava/lang/String;)V' + + Integer_toString constant_methodref Integer_class,toString_method + Integer_class constant_class _Integer + _Integer constant_utf8 'java/lang/Integer' + toString_method constant_nameandtype _toString,_str_int + _toString constant_utf8 'toString' + _str_int constant_utf8 '(I)Ljava/lang/String;' + + number constant_integer 17 + + end constant_pool + + u2 ACC_PUBLIC+ACC_SUPER ; access flags + u2 Test_class ; this class + u2 Object_class ; super class + + interfaces + + end interfaces + + fields + + end fields + + methods + + method_info ACC_PUBLIC, _init, _void ; public void Test() + + attribute _Code + + u2 1 ; max_stack + u2 1 ; max_locals + + bytecode + + aload 0 + invokespecial Object_init + return + + end bytecode + + exceptions + end exceptions + + attributes + end attributes + + end attribute + + end method_info + + method_info ACC_PUBLIC+ACC_STATIC, _main, _void_arrstr ; public static void main(String[] args) + + attribute _Code + + u2 3 ; max_stack + u2 2 ; max_locals + + bytecode + + ldc number + istore 1 + example_loop: + iload 1 + dup + imul + invokestatic Integer_toString + getstatic System.out + swap + invokevirtual PrintStream_println + iinc 1,-1 + iload 1 + ifne example_loop + + return + + end bytecode + + exceptions + end exceptions + + attributes + end attributes + + end attribute + + end method_info + + end methods + + attributes + + end attributes diff --git a/toolchain/fasmg.kl0e/examples/jvm/bytecode.inc b/toolchain/fasmg.kl0e/examples/jvm/bytecode.inc new file mode 100644 index 0000000..06e9b04 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/jvm/bytecode.inc @@ -0,0 +1,797 @@ + +T_BOOLEAN = 4 +T_CHAR = 5 +T_FLOAT = 6 +T_DOUBLE = 7 +T_BYTE = 8 +T_SHORT = 9 +T_INT = 10 +T_LONG = 11 + +macro aaload + db 0x32 +end macro + +macro aastore + db 0x53 +end macro + +macro aconst_null + db 0x01 +end macro + +macro aload index + if index<0 + err "invalid index" + else if index<=3 + db 0x2a+index + else if index<100h + db 0x19,index + else + db 0xc4,0x19,(index) shr 8,(index) and 0FFh + end if +end macro + +macro anewarray class + db 0xbd,(class) shr 8,(class) and 0FFh +end macro + +macro areturn + db 0xb0 +end macro + +macro arraylength + db 0xbe +end macro + +macro astore index + if index<0 + err "invalid index" + else if index<=3 + db 0x4b+index + else if index<100h + db 0x3a,index + else + db 0xc4,0x3a,(index) shr 8,(index) and 0FFh + end if +end macro + +macro athrow + db 0xbf +end macro + +macro baload + db 0x33 +end macro + +macro bastore + db 0x54 +end macro + +macro bipush byte + if byte>-1 & byte<=5 + db 0x03+byte + else + db 0x10,byte + end if +end macro + +macro caload + db 0x34 +end macro + +macro castore + db 0x55 +end macro + +macro checkcast class + db 0xc0,(class) shr 8,(class) and 0FFh +end macro + +macro d2f + db 0x90 +end macro + +macro d2i + db 0x8e +end macro + +macro d2l + db 0x8f +end macro + +macro dadd + db 0x63 +end macro + +macro daload + db 0x31 +end macro + +macro dastore + db 0x52 +end macro + +macro dcmpg + db 0x98 +end macro + +macro dcmpl + db 0x97 +end macro + +macro dconst_0 + db 0x0e +end macro + +macro dconst_1 + db 0x0f +end macro + +macro ddiv + db 0x6f +end macro + +macro dload index + if index<0 + err "invalid index" + else if index<=3 + db 0x26+index + else if index<100h + db 0x18,index + else + db 0xc4,0x18,(index) shr 8,(index) and 0FFh + end if +end macro + +macro dmul + db 0x6b +end macro + +macro dneg + db 0x77 +end macro + +macro drem + db 0x73 +end macro + +macro dreturn + db 0xaf +end macro + +macro dstore index + if index<0 + err "invalid index" + else if index<=3 + db 0x47+index + else if index<100h + db 0x39,index + else + db 0xc4,0x39,(index) shr 8,(index) and 0FFh + end if +end macro + +macro dsub + db 0x67 +end macro + +macro dup + db 0x59 +end macro + +macro dup_x1 + db 0x5a +end macro + +macro dup_x2 + db 0x5b +end macro + +macro dup2 + db 0x5c +end macro + +macro dup2_x1 + db 0x5d +end macro + +macro dup2_x2 + db 0x5e +end macro + +macro f2d + db 0x8d +end macro + +macro f2i + db 0x8b +end macro + +macro f2l + db 0x8c +end macro + +macro fadd + db 0x62 +end macro + +macro faload + db 0x30 +end macro + +macro fastore + db 0x51 +end macro + +macro fcmpg + db 0x96 +end macro + +macro fcmpl + db 0x95 +end macro + +macro fconst_0 + db 0x0b +end macro + +macro fconst_1 + db 0x0c +end macro + +macro fconst_2 + db 0x0d +end macro + +macro fdiv + db 0x6e +end macro + +macro fload index + if index<0 + err "invalid index" + else if index<=3 + db 0x22+index + else if index<100h + db 0x17,index + else + db 0xc4,0x17,(index) shr 8,(index) and 0FFh + end if +end macro + +macro fmul + db 0x6a +end macro + +macro fneg + db 0x76 +end macro + +macro frem + db 0x72 +end macro + +macro freturn + db 0xae +end macro + +macro fstore index + if index<0 + err "invalid index" + else if index<=3 + db 0x43+index + else if index<100h + db 0x38,index + else + db 0xc4,0x38,(index) shr 8,(index) and 0FFh + end if +end macro + +macro fsub + db 0x66 +end macro + +macro getfield index + db 0xb4,(index) shr 8,(index) and 0FFh +end macro + +macro getstatic index + db 0xb2,(index) shr 8,(index) and 0FFh +end macro + +macro goto branch + offset = branch-$ + if offset>=-8000h & offset<8000h + db 0xa7,offset shr 8,offset and 0FFh + else + db 0xc8,offset shr 24,(offset shr 16) and 0FFh,(offset shr 8) and 0FFh,offset and 0FFh + end if +end macro + +macro goto_w branch + offset = branch-$ + db 0xc8,offset shr 24,(offset shr 16) and 0FFh,(offset shr 8) and 0FFh,offset and 0FFh +end macro + +macro i2b + db 0x91 +end macro + +macro i2c + db 0x92 +end macro + +macro i2d + db 0x87 +end macro + +macro i2f + db 0x86 +end macro + +macro i2l + db 0x85 +end macro + +macro i2s + db 0x93 +end macro + +macro iadd + db 0x60 +end macro + +macro iaload + db 0x2e +end macro + +macro iand + db 0x7e +end macro + +macro iastore + db 0x4f +end macro + +macro iconst_m1 + db 0x02 +end macro + +macro iconst_0 + db 0x03 +end macro + +macro iconst_1 + db 0x04 +end macro + +macro iconst_2 + db 0x05 +end macro + +macro iconst_3 + db 0x06 +end macro + +macro iconst_4 + db 0x07 +end macro + +macro iconst_5 + db 0x08 +end macro + +macro idiv + db 0x6c +end macro + +macro if_acmpeq branch + offset = branch-$ + db 0xa5,offset shr 8,offset and 0FFh +end macro + +macro if_acmpne branch + offset = branch-$ + db 0xa6,offset shr 8,offset and 0FFh +end macro + +macro if_icmpeq branch + offset = branch-$ + db 0x9f,offset shr 8,offset and 0FFh +end macro + +macro if_icmpne branch + offset = branch-$ + db 0xa0,offset shr 8,offset and 0FFh +end macro + +macro if_icmplt branch + offset = branch-$ + db 0xa1,offset shr 8,offset and 0FFh +end macro + +macro if_icmpge branch + offset = branch-$ + db 0xa2,offset shr 8,offset and 0FFh +end macro + +macro if_icmpgt branch + offset = branch-$ + db 0xa3,offset shr 8,offset and 0FFh +end macro + +macro if_icmple branch + offset = branch-$ + db 0xa4,offset shr 8,offset and 0FFh +end macro + +macro ifeq branch + offset = branch-$ + db 0x99,offset shr 8,offset and 0FFh +end macro + +macro ifne branch + offset = branch-$ + db 0x9a,offset shr 8,offset and 0FFh +end macro + +macro iflt branch + offset = branch-$ + db 0x9b,offset shr 8,offset and 0FFh +end macro + +macro ifge branch + offset = branch-$ + db 0x9c,offset shr 8,offset and 0FFh +end macro + +macro ifgt branch + offset = branch-$ + db 0x9d,offset shr 8,offset and 0FFh +end macro + +macro ifle branch + offset = branch-$ + db 0x9e,offset shr 8,offset and 0FFh +end macro + +macro ifnonnull branch + offset = branch-$ + db 0xc7,offset shr 8,offset and 0FFh +end macro + +macro ifnull branch + offset = branch-$ + db 0xc6,offset shr 8,offset and 0FFh +end macro + +macro iinc index,const + if index<0 + err "invalid index" + else if index<100h & const<80h & const>=-80h + db 0x84,index,const + else + db 0xc4,0x84,(index) shr 8,(index) and 0FFh,(const) shr 8,(const) and 0FFh + end if +end macro + +macro iload index + if index<0 + err "invalid index" + else if index<=3 + db 0x1a+index + else if index<100h + db 0x15,index + else + db 0xc4,0x15,(index) shr 8,(index) and 0FFh + end if +end macro + +macro imul + db 0x68 +end macro + +macro ineg + db 0x74 +end macro + +macro instanceof index + db 0xc1,(index) shr 8,(index) and 0FFh +end macro + +macro invokedynamic index + db 0xba,(index) shr 8,(index) and 0FFh,0,0 +end macro + +macro invokeinterface index,count + db 0xb9,(index) shr 8,(index) and 0FFh,count +end macro + +macro invokespecial index + db 0xb7,(index) shr 8,(index) and 0FFh +end macro + +macro invokestatic index + db 0xb8,(index) shr 8,(index) and 0FFh +end macro + +macro invokevirtual index + db 0xb6,(index) shr 8,(index) and 0FFh +end macro + +macro ior + db 0x80 +end macro + +macro irem + db 0x70 +end macro + +macro ireturn + db 0xac +end macro + +macro ishl + db 0x78 +end macro + +macro ishr + db 0x7a +end macro + +macro istore index + if index<0 + err "invalid index" + else if index<=3 + db 0x3b+index + else if index<100h + db 0x36,index + else + db 0xc4,0x36,(index) shr 8,(index) and 0FFh + end if +end macro + +macro isub + db 0x64 +end macro + +macro iushr + db 0x7c +end macro + +macro ixor + db 0x82 +end macro + +macro jsr branch + offset = branch-$ + if offset>=-8000h & offset<8000h + db 0xa8,offset shr 8,offset and 0FFh + else + db 0xc9,offset shr 24,(offset shr 16) and 0FFh,(offset shr 8) and 0FFh,offset and 0FFh + end if +end macro + +macro jsr_w branch + offset = branch-$ + db 0xc9,offset shr 24,(offset shr 16) and 0FFh,(offset shr 8) and 0FFh,offset and 0FFh +end macro + +macro l2d + db 0x8a +end macro + +macro l2f + db 0x89 +end macro + +macro l2i + db 0x88 +end macro + +macro ladd + db 0x61 +end macro + +macro laload + db 0x2f +end macro + +macro land + db 0x7f +end macro + +macro lastore + db 0x50 +end macro + +macro lcmp + db 0x94 +end macro + +macro lconst_0 + db 0x09 +end macro + +macro lconst_1 + db 0x0a +end macro + +macro ldc index + if index<0 + err "invalid index" + else if index<100h + db 0x12,index + else + db 0x13,(index) shr 8,(index) and 0FFh + end if +end macro + +macro ldc_w index + db 0x13,(index) shr 8,(index) and 0FFh +end macro + +macro ldc2_w index + db 0x14,(index) shr 8,(index) and 0FFh +end macro + +macro ldiv + db 0x6d +end macro + +macro lload index + if index<0 + err "invalid index" + else if index<=3 + db 0x1e+index + else if index<100h + db 0x16,index + else + db 0xc4,0x16,(index) shr 8,(index) and 0FFh + end if +end macro + +macro lmul + db 0x69 +end macro + +macro lneg + db 0x75 +end macro + +macro lookupswitch +; db 0xab,... + err "not implemented yet" +end macro + +macro lor + db 0x81 +end macro + +macro lrem + db 0x71 +end macro + +macro lreturn + db 0xad +end macro + +macro lshl + db 0x79 +end macro + +macro lshr + db 0x7b +end macro + +macro lstore index + if index<0 + err "invalid index" + else if index<=3 + db 0x3f+index + else if index<100h + db 0x37,index + else + db 0xc4,0x37,(index) shr 8,(index) and 0FFh + end if +end macro + +macro lsub + db 0x65 +end macro + +macro lushr + db 0x7d +end macro + +macro lxor + db 0x83 +end macro + +macro monitorenter + db 0xc2 +end macro + +macro monitorexit + db 0xc3 +end macro + +macro multianewarray index,dimensions + db 0xc5,(index) shr 8,(index) and 0FFh,dimensions +end macro + +macro new index + db 0xbb,(index) shr 8,(index) and 0FFh +end macro + +macro newarray atype + db 0xbc,atype +end macro + +macro nop + db 0x00 +end macro + +macro pop + db 0x57 +end macro + +macro pop2 + db 0x58 +end macro + +macro putfield index + db 0xb5,(index) shr 8,(index) and 0FFh +end macro + +macro putstatic index + db 0xb3,(index) shr 8,(index) and 0FFh +end macro + +macro ret index + if index<0 + err "invalid index" + else if index<100h + db 0xa9,index + else + db 0xc4,0xa9,(index) shr 8,(index) and 0FFh + end if +end macro + +macro return + db 0xb1 +end macro + +macro saload + db 0x35 +end macro + +macro sastore + db 0x56 +end macro + +macro sipush short + db 0x11,(short) shr 8,(short) and 0FFh +end macro + +macro swap + db 0x5f +end macro + +macro tableswitch +; db 0xaa,... + err "not implemented yet" +end macro + +macro breakpoint + db 0xca +end macro + +macro impdep1 + db 0xfe +end macro + +macro impdep2 + db 0xff +end macro diff --git a/toolchain/fasmg.kl0e/examples/jvm/jclass.inc b/toolchain/fasmg.kl0e/examples/jvm/jclass.inc new file mode 100644 index 0000000..20c062b --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/jvm/jclass.inc @@ -0,0 +1,254 @@ + +ACC_PUBLIC = 0x0001 +ACC_PRIVATE = 0x0002 +ACC_PROTECTED = 0x0004 +ACC_STATIC = 0x0008 +ACC_FINAL = 0x0010 +ACC_SUPER = 0x0020 +ACC_SYNCHRONIZED = 0x0020 +ACC_NATIVE = 0x0200 +ACC_INTERFACE = 0x0200 +ACC_ABSTRACT = 0x0400 +ACC_STRICT = 0x0800 + +macro u1 values& + irp v,values + db v + end irp +end macro + +macro u2 values& + irp v,values + db (v) bswap 2 + end irp +end macro + +macro u4 values& + irp v,values + db (v) bswap 4 + end irp +end macro + +macro constant_pool + + u2 constant_pool_count + constant_pool_counter = 1 + + struc constant_utf8 string& + . = constant_pool_counter + constant_pool_counter = constant_pool_counter + 1 + local data,length + u1 1 + u2 length + data: db string + length = $ - data + end struc + + struc constant_integer value + . = constant_pool_counter + constant_pool_counter = constant_pool_counter + 1 + u1 3 + u4 value + end struc + + struc constant_float value + . = constant_pool_counter + constant_pool_counter = constant_pool_counter + 1 + u1 4 + u4 value + end struc + + struc constant_long value + . = constant_pool_counter + constant_pool_counter = constant_pool_counter + 1 + u1 5 + u4 value shr 32,value and 0FFFFFFFFh + end struc + + struc constant_double value + . = constant_pool_counter + constant_pool_counter = constant_pool_counter + 1 + u1 6 + u4 value shr 32,value and 0FFFFFFFFh + end struc + + struc constant_class name_index + . = constant_pool_counter + constant_pool_counter = constant_pool_counter + 1 + u1 7 + u2 name_index + end struc + + struc constant_string string_index + . = constant_pool_counter + constant_pool_counter = constant_pool_counter + 1 + u1 8 + u2 string_index + end struc + + struc constant_fieldref class_index,name_and_type_index + . = constant_pool_counter + constant_pool_counter = constant_pool_counter + 1 + u1 9 + u2 class_index + u2 name_and_type_index + end struc + + struc constant_methodref class_index,name_and_type_index + . = constant_pool_counter + constant_pool_counter = constant_pool_counter + 1 + u1 10 + u2 class_index + u2 name_and_type_index + end struc + + struc constant_interfacemethodref class_index,name_and_type_index + . = constant_pool_counter + constant_pool_counter = constant_pool_counter + 1 + u1 11 + u2 class_index + u2 name_and_type_index + end struc + + struc constant_nameandtype name_index,descriptor_index + . = constant_pool_counter + constant_pool_counter = constant_pool_counter + 1 + u1 12 + u2 name_index + u2 descriptor_index + end struc + +end macro + +macro end?.constant_pool + constant_pool_count = constant_pool_counter + restruc constant_utf8,constant_integer,constant_float,constant_long,constant_double + restruc constant_class,constant_string + restruc constant_fieldref,constant_methodref,constant_interfacemethodref,constant_nameandtype +end macro + +macro interfaces + u2 interfaces_count + interfaces_counter = 0 + macro interface interface + interfaces_counter = interfaces_counter + 1 + u2 interface + end macro +end macro + +macro end?.interfaces + interfaces_count = interfaces_counter + purge interface +end macro + +macro attributes + local count,counter + u2 count + counter = 0 + attributes_count equ count + attributes_counter equ counter + macro attribute attribute_name_index + match sym,attributes_counter + sym = sym + 1 + end match + u2 attribute_name_index + local start,length + u4 length + start = $ + attribute_start equ start + attribute_length equ length + end macro + macro end?.attribute + match sym,attribute_length + sym = $ - attribute_start + end match + restore atribute_start,attribute_length + end macro +end macro + +macro end?.attributes + match sym,attributes_count + sym = attributes_counter + end match + restore attributes_count,attributes_counter + purge attribute +end macro + +macro fields + u2 fields_count + fields_counter = 0 + macro field_info access_flags,name_index,descriptor_index + fields_counter = fields_counter + 1 + u2 access_flags + u2 name_index + u2 descriptor_index + attributes + end macro + macro end?.field_info + end?.attributes + end macro +end macro + +macro end?.fields + fields_count = fields_counter + purge field_info,end?.field_info +end macro + +macro methods + u2 methods_count + methods_counter = 0 + macro method_info access_flags,name_index,descriptor_index + methods_counter = methods_counter + 1 + u2 access_flags + u2 name_index + u2 descriptor_index + attributes + end macro + macro end?.method_info + end?.attributes + end macro +end macro + +macro end?.methods + methods_count = methods_counter + purge method_info,end?.method_info +end macro + +macro bytecode + local length + bytecode_length equ length + u4 length + bytecode_offset = $ + org 0 +end macro + +macro end?.bytecode + match sym,bytecode_length + sym = $ + end match + org bytecode_offset+bytecode_length + restore bytecode_length +end macro + +macro exceptions + local length + exception_table_length equ length + u2 length + exception_counter = 0 + macro exception start_pc,end_pc,handler_pc,catch_type + exception_counter = exception_counter + 1 + u2 start_pc + u2 end_pc + u2 handler_pc + u2 catch_type + end macro +end macro + +macro end?.exceptions + match sym,exception_table_length + sym = exception_counter + end match + restore exception_table_length +end macro + +include 'bytecode.inc' diff --git a/toolchain/fasmg.kl0e/examples/jvm/make.cmd b/toolchain/fasmg.kl0e/examples/jvm/make.cmd new file mode 100644 index 0000000..3de2823 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/jvm/make.cmd @@ -0,0 +1 @@ +fasmg Test.asm Test.class diff --git a/toolchain/fasmg.kl0e/examples/x86/hello.asm b/toolchain/fasmg.kl0e/examples/x86/hello.asm new file mode 100644 index 0000000..177dd87 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/hello.asm @@ -0,0 +1,14 @@ + +include '8086.inc' + + org 100h + +display_text = 9 + + mov ah,display_text + mov dx,hello + int 21h + + int 20h + +hello db 'Hello world!',24h diff --git a/toolchain/fasmg.kl0e/examples/x86/include/80186.inc b/toolchain/fasmg.kl0e/examples/x86/include/80186.inc new file mode 100644 index 0000000..f92cd53 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/80186.inc @@ -0,0 +1,383 @@ + +include '8086.inc' + +define @aux @aux + +calminstruction push? src* + + call x86.parse_operand@src, src + + check @src.size and not 2 + jno main + + err 'invalid operand size' + + main: + check @src.type = 'mem' + jyes push_mem + check @src.type = 'reg' + jyes push_reg + check @src.type = 'sreg' + jyes push_sreg + check @src.type = 'imm' + jyes push_imm + + err 'invalid operand' + exit + + push_mem: + xcall x86.store_instruction@src, (0FFh),(110b) + exit + + push_reg: + emit 1, 50h + @src.rm + exit + + push_sreg: + emit 1, 6 + @src.rm shl 3 + exit + + push_imm: + check @src.imm relativeto 0 & @src.imm < 80h & @src.imm >= -80h + jyes push_simm + check @src.imm relativeto 0 & @src.imm - 10000h >= -80h & @src.imm < 10000h + jyes push_simm_wrap + emit 1, 68h + asm dw @src.imm + exit + push_simm_wrap: + compute @src.imm, @src.imm - 10000h + push_simm: + emit 1, 6Ah + emit 1, @src.imm + exit + +end calminstruction + +calminstruction x86.pop_instruction size:0,dest* + + call x86.parse_operand@dest, dest + + check @dest.size and not 2 + jno main + + err 'invalid operand size' + + main: + check @dest.type = 'mem' + jyes pop_mem + check @dest.type = 'reg' + jyes pop_reg + check @dest.type = 'sreg' + jyes pop_sreg + + invalid_operand: + err 'invalid operand' + exit + + pop_mem: + xcall x86.store_instruction@dest, (8Fh),(0) + exit + + pop_reg: + emit 1, 58h + @dest.rm + exit + + pop_sreg: + check @dest.rm = 1 + jyes invalid_operand + emit 1, 7 + @dest.rm shl 3 + exit + +end calminstruction + +iterate , push,pop + + calminstruction instr? operand + + local head, tail + + match head tail, operand + jno plain + transform head, x86.compact + jno plain + match {head}, head + jno plain + loop: + arrange operand, =instr head + assemble operand + match head tail, tail + jno final + transform head, x86.compact + jno error + match {head}, head + jyes loop + error: + err 'only register operands allowed in compact syntax' + exit + final: + transform tail, x86.compact + jno error + match {operand}, tail + jno error + plain: + arrange operand, =instr operand + assemble operand + + end calminstruction + +end iterate + +iterate , pusha,60h, popa,61h, insb,6Ch, outsb,6Eh, insw,6Dh, outsw,6Fh, leave,0C9h + + calminstruction instr? + emit 1, opcode + end calminstruction + +end iterate + +calminstruction imul? dest*,src& + + local size + + call x86.parse_operand@dest, dest + + match , src + jyes imul_rm + + local src1, src2 + + match src1 =, src2, src + jyes imul_second_source + + call x86.parse_operand@src, src + + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + check @src.type = 'imm' & @dest.type = 'reg' + jno invalid_combination_of_operands + + compute @aux.type, @src.type + compute @aux.imm, @src.imm + compute @src.type, @dest.type + compute @src.mod, @dest.mod + compute @src.rm, @dest.rm + + jump main + + imul_second_source: + call x86.parse_operand@src, src1 + call x86.parse_operand@aux, src2 + + check @dest.size = 0 & @src.size = 0 & @aux.size = 0 + jyes operand_size_not_specified + + compute size, @dest.size or @src.size or @aux.size + + check (@dest.size & @dest.size <> size) | (@src.size & @src.size <> size) | (@aux.size & @aux.size <> size) + jyes operand_sizes_do_not_match + + jump main + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + main: + check @aux.type = 'imm' & ( @src.type = 'mem' | @src.type = 'reg' ) & @dest.type = 'reg' & size = 2 + jyes imul_reg_rm_imm + + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + + imul_rm: + check @dest.size + jyes imul_rm_size_ok + err 'operand size not specified' + imul_rm_size_ok: + check @dest.type = 'mem' | @dest.type = 'reg' + jno invalid_combination_of_operands + check @dest.size < 2 + jyes imul_rm_8bit + xcall x86.store_instruction@dest, (0F7h),(5) + exit + imul_rm_8bit: + xcall x86.store_instruction@dest, (0F6h),(5) + exit + + imul_reg_rm_imm: + check @aux.imm relativeto 0 & @aux.imm < 80h & @aux.imm >= -80h + jyes imul_reg_rm_simm + check @aux.imm relativeto 0 & @aux.imm - 10000h >= -80h & @aux.imm < 10000h + jyes imul_reg_rm_simm_wrap + xcall x86.store_instruction@src, (69h),@dest.rm,size,@aux.imm + exit + imul_reg_rm_simm_wrap: + compute @aux.imm, @aux.imm - 1 shl (size shl 3) + imul_reg_rm_simm: + xcall x86.store_instruction@src, (6Bh),@dest.rm,byte,@aux.imm + exit + +end calminstruction + +iterate , rol,0, ror,1, rcl,2, rcr,3, shl,4, sal, 4, shr,5, sar,7 + + calminstruction instr? dest*,cnt* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, cnt + + check @dest.size = 0 + jyes operand_size_not_specified + check @src.size and not 1 + jyes invalid_operand_size + + main: + check @src.type = 'reg' & @src.size = 1 & @src.rm = 1 & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes shift_rm_cl + check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes shift_rm_imm + + err 'invalid combination of operands' + exit + + shift_rm_cl: + check @dest.size < 2 + jyes shift_r8_cl + xcall x86.store_instruction@dest, (0D3h),(postbyte) + exit + shift_r8_cl: + xcall x86.store_instruction@dest, (0D2h),(postbyte) + exit + shift_rm_imm: + check @dest.size < 2 + jyes shift_rm8_imm + check @src.imm = 1 + jyes shift_rm_1 + xcall x86.store_instruction@dest, (0C1h),(postbyte),byte,@src.imm + exit + shift_rm_1: + xcall x86.store_instruction@dest, (0D1h),(postbyte) + exit + shift_rm8_imm: + check @src.imm = 1 + jyes shift_rm8_1 + xcall x86.store_instruction@dest, (0C0h),(postbyte),byte,@src.imm + exit + shift_rm8_1: + xcall x86.store_instruction@dest, (0D0h),(postbyte) + exit + + operand_size_not_specified: + err 'operand size not specified' + jump main + invalid_operand_size: + err 'invalid operand size' + jump main + + end calminstruction + +end iterate + +calminstruction ins? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.size + jyes size_ok + err 'operand size not specified' + compute size, 0 + size_ok: + check @src.type = 'reg' & @src.size = 2 & @src.rm = 2 & @dest.type = 'mem' & @dest.mod = 0 & @dest.rm = 5 & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h ) + jno invalid_combination_of_operands + check @dest.size = 2 + jyes ins_word + assemble x86.insb + exit + ins_word: + assemble x86.insw + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + exit +end calminstruction + +calminstruction outs? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @dest.type = 'reg' & @dest.size = 2 & @dest.rm = 2 & @src.type = 'mem' & @src.mod = 0 & @src.rm = 4 + jno invalid_combination_of_operands + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check @src.size = 2 + jyes outs_word + assemble x86.outsb + exit + outs_word: + assemble x86.outsw + exit + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump size_ok + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump size_ok + invalid_combination_of_operands: + err 'invalid combination of operands' + exit +end calminstruction + +calminstruction enter? alloc*,nesting* + call x86.parse_operand@src, alloc + call x86.parse_operand@aux, nesting + check (@src.size and not 2) | (@aux.size and not 1) + jno size_ok + err 'invalid operand size' + size_ok: + check @src.type = 'imm' & @aux.type = 'imm' + jno operand_ok + err 'invalid operand' + exit + operand_ok: + emit 1, 0C8h + asm dw @src.imm + emit 1, @aux.imm +end calminstruction + +calminstruction bound? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.type = 'mem' & @dest.type = 'reg' + jno invalid_combination_of_operands + check @dest.size = 2 + jno invalid_operand_size + check @src.size and not @dest.size + jno size_ok + err 'operand sizes do not match' + size_ok: + xcall x86.store_instruction@src, (62h),@dest.rm + exit + invalid_operand_size: + err 'invalid operand size' + invalid_combination_of_operands: + err 'invalid combination of operands' +end calminstruction diff --git a/toolchain/fasmg.kl0e/examples/x86/include/80286.inc b/toolchain/fasmg.kl0e/examples/x86/include/80286.inc new file mode 100644 index 0000000..c344996 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/80286.inc @@ -0,0 +1,86 @@ + +include '80186.inc' + +iterate , loadall,<0Fh,05h>, clts,<0Fh,06h> + + calminstruction instr? + asm db opcode + end calminstruction + +end iterate + +calminstruction arpl? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.type = 'reg' & (@dest.type = 'mem' | @dest.type = 'reg') + jno invalid_combination_of_operands + check @src.size = 2 + jno invalid_operand_size + check @dest.size and not @src.size + jno size_ok + err 'operand sizes do not match' + jump size_ok + invalid_operand_size: + err 'invalid operand size' + size_ok: + xcall x86.store_instruction@dest, (63h),@src.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' +end calminstruction + +iterate , sldt,0,0, str,0,1, lldt,0,2, ltr,0,3, verr,0,4, verw,0,5, smsw,1,4, lmsw,1,6 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.size and not 2 + jno size_ok + err 'invalid operand size' + size_ok: + check @dest.type = 'reg' | @dest.type = 'mem' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + xcall x86.store_instruction@dest, <0Fh,ext>,(postbyte) + end calminstruction + +end iterate + +iterate , lgdt,2, lidt,3, sgdt,0, sidt,1 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.type = 'mem' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + check @dest.size and not 5 + jno store_instruction + err 'invalid operand size' + store_instruction: + xcall x86.store_instruction@dest, <0Fh,1>,(postbyte) + exit + end calminstruction + +end iterate + +iterate , lar,2, lsl,3 + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') + jno invalid_combination_of_operands + check @src.size and not 2 + jno size_ok + err 'invalid operand size' + size_ok: + xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + end calminstruction + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/80287.inc b/toolchain/fasmg.kl0e/examples/x86/include/80287.inc new file mode 100644 index 0000000..acf0e23 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/80287.inc @@ -0,0 +1,16 @@ + +if ~ defined i80287 + + restore i80287 ; this ensures that symbol cannot be forward-referenced + i80287 = 1 + + include '8087.inc' + + purge feni?,fneni?,fdisi?,fndisi? + + calminstruction fsetpm? + emit 1, 0DBh + emit 1, 0E4h + end calminstruction + +end if \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/examples/x86/include/80386.inc b/toolchain/fasmg.kl0e/examples/x86/include/80386.inc new file mode 100644 index 0000000..1b9b575 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/80386.inc @@ -0,0 +1,2712 @@ + +define x86 x86 + +element x86.reg +element x86.r8 : x86.reg + 1 +element x86.r16 : x86.reg + 2 +element x86.r32 : x86.reg + 4 + +element al? : x86.r8 + 0 +element cl? : x86.r8 + 1 +element dl? : x86.r8 + 2 +element bl? : x86.r8 + 3 +element ah? : x86.r8 + 4 +element ch? : x86.r8 + 5 +element dh? : x86.r8 + 6 +element bh? : x86.r8 + 7 + +element ax? : x86.r16 + 0 +element cx? : x86.r16 + 1 +element dx? : x86.r16 + 2 +element bx? : x86.r16 + 3 +element sp? : x86.r16 + 4 +element bp? : x86.r16 + 5 +element si? : x86.r16 + 6 +element di? : x86.r16 + 7 + +element eax? : x86.r32 + 0 +element ecx? : x86.r32 + 1 +element edx? : x86.r32 + 2 +element ebx? : x86.r32 + 3 +element esp? : x86.r32 + 4 +element ebp? : x86.r32 + 5 +element esi? : x86.r32 + 6 +element edi? : x86.r32 + 7 + +element x86.sreg + +element es? : x86.sreg + 0 +element cs? : x86.sreg + 1 +element ss? : x86.sreg + 2 +element ds? : x86.sreg + 3 +element fs? : x86.sreg + 4 +element gs? : x86.sreg + 5 + +element x86.creg + +element x86.crx : x86.creg + 0 +element x86.drx : x86.creg + 1 +element x86.trx : x86.creg + 4 + +repeat 8, i:0 + element cr#i? : x86.crx + i + element dr#i? : x86.drx + i + element tr#i? : x86.trx + i +end repeat + +define x86.byte? :1 +define x86.word? :2 +define x86.dword? :4 +define x86.pword? :6 +define x86.fword? :6 +define x86.qword? :8 + +x86.mode = 16 + +macro use16? + x86.mode = 16 +end macro + +macro use32? + x86.mode = 32 +end macro + + +calminstruction calminstruction?.initsym? var*, val& + publish var, val +end calminstruction + +calminstruction calminstruction?.asm? line& + local name, i + initsym name, name.0 + match name.i, name + compute i, i+1 + arrange name, name.i + publish name, line + arrange line, =assemble name + assemble line +end calminstruction + +calminstruction calminstruction?.xcall? instruction*, arguments& + arrange instruction, =call instruction + convert: + match , arguments + jyes ready + local v + match v=,arguments, arguments, <> + jyes recognize + arrange v, arguments + arrange arguments, + recognize: + match (v), v + jyes numeric + match , v + jyes symbolic + append: + arrange instruction, instruction=,v + jump convert + numeric: + compute v, v + symbolic: + local proxy, base, i + initsym base, proxy + initsym i, 0 + compute i, i+1 + arrange proxy, base.i + publish proxy, v + arrange instruction, instruction=,proxy + jump convert + ready: + assemble instruction +end calminstruction + + +define @dest @dest +define @src @src +define @src2 @src2 +define @aux @aux + +iterate context, @dest,@src,@src2,@aux + + namespace context + + iterate name, size, type, segment_prefix, prefix, opcode_prefix, \ + imm, unresolved, displacement, displacement_size, \ + address, address_registers, segment, offset, jump_type, \ + mode, mod, rm, \ + scale, index, base + define name + end iterate + + calminstruction x86.parse_operand#context operand + + local i, pre, suf, sym + + compute segment_prefix, 0 + compute prefix, 0 + compute opcode_prefix, 0 + + compute size, 0 + compute displacement_size, 0 + + transform operand + + match pre suf, operand + jno no_size_prefix + transform pre, x86 + jno no_size_prefix + match :size, pre + jno no_size_prefix + arrange operand, suf + no_size_prefix: + + match [address], operand + jyes memory_operand + match =ptr? address, operand + jyes memory_operand + match segment:offset, operand + jyes far_operand + + immediate_operand: + compute type, 'imm' + compute imm, +operand + + compute unresolved, 0 + check defined operand + jyes operand_resolved + compute unresolved, 1 + operand_resolved: + + check imm eq 1 elementof imm + jno operand_ready + check 1 metadataof (1 metadataof imm) relativeto x86.reg + jyes register_operand + check 1 metadataof imm relativeto x86.sreg + jyes segment_register_operand + + operand_ready: + exit + + register_operand: + + compute type, 'reg' + compute mode, x86.mode + compute mod, 11b + compute rm, 1 metadataof imm - 1 elementof (1 metadataof imm) + check size & size <> 1 metadataof (1 metadataof imm) - x86.reg + jyes operand_sizes_do_not_match + compute size, 1 metadataof (1 metadataof imm) - x86.reg + + exit + + segment_register_operand: + + compute type, 'sreg' + compute mode, x86.mode + compute mod, 11b + compute rm, 1 metadataof imm - x86.sreg + check size & size <> 2 & size <> 4 + jyes invalid_operand_size + + exit + + memory_operand: + compute type, 'mem' + + match segment:address, address + jno segment_prefix_ok + check segment eq 1 elementof segment & 1 metadataof segment relativeto x86.sreg + jno invalid_operand + compute segment, 1 metadataof segment - x86.sreg + check segment >= 4 + jyes segment_prefix_386 + compute segment_prefix, 26h + segment shl 3 + jump segment_prefix_ok + segment_prefix_386: + compute segment_prefix, 64h + segment-4 + segment_prefix_ok: + + compute mode, 0 + + match pre suf, address + jno no_address_size_prefix + transform pre, x86 + jno no_address_size_prefix + match :pre, pre + jno no_address_size_prefix + arrange address, suf + check pre = 2 | pre = 4 | pre = 8 + jno invalid_address_size + compute mode, pre shl 3 + no_address_size_prefix: + + compute scale, 0 + compute index, 0 + compute base, 0 + + check size + jyes size_override + compute size, sizeof address + size_override: + + compute address, address + compute address_registers, 0 + compute i, 1 + extract_registers: + check i > elementsof address + jyes registers_extracted + check i metadataof address relativeto x86.r16 | i metadataof address relativeto x86.r32 + jno next_term + compute address_registers, address_registers + i elementof address * i scaleof address + next_term: + compute i, i+1 + jump extract_registers + registers_extracted: + compute displacement, address - address_registers + + check mode + jyes verify_mode + compute mode, x86.mode + check mode = 16 & displacement relativeto 0 & displacement >= 10000h & address_registers eq 0 + jno mode_ok + compute mode, 32 + jump mode_ok + verify_mode: + check (mode = 16 & 1 metadataof address_registers relativeto x86.r32) | (mode = 32 & 1 metadataof address_registers relativeto x86.r16) + jyes invalid_address + mode_ok: + + check address_registers eq 0 + jyes direct_address + check 1 metadataof address_registers relativeto x86.r32 + jyes address_32bit + check 1 metadataof address_registers relativeto x86.r16 + jyes address_16bit + jump invalid_address + + direct_address: + compute mod, 0 + check mode = 16 + jyes direct_address_16bit + direct_address_32bit: + compute rm, 5 + compute displacement_size, 4 + exit + direct_address_16bit: + compute rm, 6 + compute displacement_size, 2 + exit + + address_16bit: + compute mode, 16 + + check address_registers relativeto bx+si + jyes rm_0 + check address_registers relativeto bx+di + jyes rm_1 + check address_registers relativeto bp+si + jyes rm_2 + check address_registers relativeto bp+di + jyes rm_3 + check address_registers relativeto si + jyes rm_4 + check address_registers relativeto di + jyes rm_5 + check address_registers relativeto bp + jyes rm_6 + check address_registers relativeto bx + jyes rm_7 + jump invalid_address + + rm_0: + compute rm, 0 + jump rm_ok + rm_1: + compute rm, 1 + jump rm_ok + rm_2: + compute rm, 2 + jump rm_ok + rm_3: + compute rm, 3 + jump rm_ok + rm_4: + compute rm, 4 + jump rm_ok + rm_5: + compute rm, 5 + jump rm_ok + rm_6: + compute rm, 6 + jump rm_ok + rm_7: + compute rm, 7 + rm_ok: + + check displacement relativeto 0 + jno displacement_16bit + check displacement = 0 & rm <> 6 + jyes displacement_empty + check displacement<80h & displacement>=-80h + jyes displacement_8bit + check displacement-10000h>=-80h & displacement<10000h + jyes displacement_8bit_wrap_16bit + displacement_16bit: + compute displacement_size, 2 + compute mod, 2 + exit + displacement_empty: + compute displacement_size, 0 + compute mod, 0 + exit + displacement_8bit_wrap_16bit: + compute displacement, displacement-10000h + displacement_8bit: + compute displacement_size, 1 + compute mod, 1 + exit + + address_32bit: + compute mode,32 + check 2 scaleof address_registers = 0 + jyes one_register + check 3 scaleof address_registers = 0 & 2 metadataof address_registers relativeto x86.r32 + jyes two_registers + jump invalid_address + + one_register: + compute scale, 1 scaleof address_registers + compute base, 1 metadataof address_registers - x86.r32 + check scale = 1 + jyes one_register_unscaled + check base <> 4 & (scale = 4 | scale = 8) + jyes one_register_scaled + check base <> 4 & (scale = 2 | scale = 3 | scale = 5 | scale = 9) + jyes one_register_split + jump invalid_address + one_register_unscaled: + compute rm, base + check rm = 4 + jno setup_displacement + compute index, 4 + jump setup_displacement + one_register_scaled: + compute rm, 4 + compute index, base + compute base, 5 + jump index_only + one_register_split: + compute rm, 4 + compute index, base + compute scale, scale - 1 + jump setup_displacement + two_registers: + compute rm,4 + check 1 scaleof address_registers = 1 + jyes base_first + check 2 scaleof address_registers = 1 + jyes base_second + jump invalid_address + base_first: + compute base, 1 metadataof address_registers - x86.r32 + compute index, 2 metadataof address_registers - x86.r32 + compute scale, 2 scaleof address_registers + jump process_sib + base_second: + compute base, 2 metadataof address_registers - x86.r32 + compute index, 1 metadataof address_registers - x86.r32 + compute scale, 1 scaleof address_registers + process_sib: + check index = 4 + jyes forbidden_index + check segment_prefix = 36h & index = 5 & scale = 1 + jyes switch_to_index + check segment_prefix = 3Eh & base = 5 & scale = 1 + jyes switch_to_base + check scale and (scale-1) | scale > 8 + jyes invalid_address + jump setup_displacement + forbidden_index: + check scale = 1 + jno invalid_address + compute index, base + compute base, 4 + jump setup_displacement + switch_to_index: + compute index, base + compute base, 5 + jump setup_displacement + switch_to_base: + compute base, index + compute index, 5 + jump setup_displacement + + setup_displacement: + check displacement relativeto 0 + jno displacement_32bit + check displacement = 0 & rm <> 5 & (rm <> 4 | base <> 5) + jyes displacement_empty + check displacement < 80h & displacement >= -80h + jyes displacement_8bit + check displacement-100000000h >= -80h & displacement < 100000000h + jyes displacement_8bit_wrap_32bit + check segment_prefix = 3Eh & base = 5 & index = 5 & scale = 1 + jno displacement_32bit + compute scale, 2 + jump index_only + displacement_32bit: + compute displacement_size, 4 + compute mod, 2 + exit + displacement_8bit_wrap_32bit: + compute displacement, displacement-100000000h + jump displacement_8bit + index_only: + compute displacement_size, 4 + compute mod, 0 + exit + + far_operand: + compute type, 'far' + + check size & size <> 4 & size <> 6 + jyes operand_sizes_do_not_match + + exit + + invalid_operand: + err 'invalid operand' + exit + invalid_operand_size: + err 'invalid operand size' + exit + operand_sizes_do_not_match: + err 'operand sizes do not match' + exit + invalid_address: + err 'invalid address' + exit + invalid_address_size: + err 'invalid address size' + exit + + end calminstruction + + calminstruction x86.parse_jump_operand#context operand + + match =far? operand, operand + jyes far_jump + match =near? operand, operand + jyes near_jump + match =short? operand, operand + jyes short_jump + compute jump_type, '' + jump parse_operand + far_jump: + compute jump_type, 'far' + jump parse_operand + near_jump: + compute jump_type, 'near' + jump parse_operand + short_jump: + compute jump_type, 'short' + + parse_operand: + + call x86.parse_operand#context, operand + + check type = 'imm' + jno done + + check size = 0 + jno verify_target_address + + compute size, x86.mode shr 3 + + verify_target_address: + + check imm relativeto 0 + jno done + check imm < 0 + jyes negative + check imm >= 1 shl (size*8) + jno done + out_of_range: + err 'value out of range' + exit + negative: + check imm < - 1 shl (size*8-1) + jyes out_of_range + compute imm, imm and (1 shl (size*8) - 1) + + done: + + end calminstruction + + calminstruction x86.select_operand_prefix#context size* + + check (size = 2 & x86.mode = 32) | (size = 4 & x86.mode = 16) + jno no_prefix + + compute prefix, 66h + + no_prefix: + + check size <> 0 & size <> 2 & size <> 4 + jno done + + err 'invalid operand size' + + done: + + end calminstruction + + calminstruction x86.store_instruction#context opcode*,reg*,imm_size:0,immediate + + check segment_prefix + jno segment_prefix_ok + + check mode = 16 & ( rm = 2 | rm = 3 | ( mod > 0 & rm = 6 ) ) + jyes ss_segment_default + check mode = 32 & ( ( mod > 0 & rm = 5 ) | ( rm = 4 & base = 4 ) | ( mod > 0 & rm = 4 & base = 5 ) ) + jyes ss_segment_default + + ds_segment_default: + check segment_prefix = 3Eh + jyes segment_prefix_ok + jump store_segment_prefix + ss_segment_default: + check segment_prefix = 36h + jyes segment_prefix_ok + store_segment_prefix: + emit 1, segment_prefix + segment_prefix_ok: + + check mod <> 11b & mode <> x86.mode + jno addressing_prefix_ok + emit 1, 67h + addressing_prefix_ok: + + check prefix + jno operand_prefix_ok + emit 1, prefix + operand_prefix_ok: + + check opcode_prefix + jno opcode_prefix_ok + emit 1, opcode_prefix + opcode_prefix_ok: + + asm db opcode + emit 1, mod shl 6 + (reg and 111b) shl 3 + rm and 111b + + check mod <> 11b & rm = 4 & mode = 32 + jno sib_ok + emit 1, (bsf scale) shl 6 + (index and 111b) shl 3 + base and 111b + sib_ok: + + check displacement_size = 1 + jyes displacement_8bit + check displacement_size = 2 + jyes displacement_16bit + check displacement_size = 4 + jno displacement_ok + displacement_32bit: + asm dd displacement + jump displacement_ok + displacement_16bit: + asm dw displacement + jump displacement_ok + displacement_8bit: + emit 1, displacement + displacement_ok: + + check imm_size = 1 + jyes immediate_8bit + check imm_size = 2 + jyes immediate_16bit + check imm_size = 4 + jno immediate_ok + immediate_32bit: + compute imm, +immediate + asm dd imm + jump immediate_ok + immediate_16bit: + compute imm, +immediate + asm dw imm + jump immediate_ok + immediate_8bit: + compute imm, +immediate + emit 1, imm + jump immediate_ok + immediate_ok: + + end calminstruction + + end namespace + +end iterate + +calminstruction x86.store_operand_prefix size* + + check (size = 2 & x86.mode = 32) | (size = 4 & x86.mode = 16) + jno no_prefix + + emit 1, 66h + exit + + no_prefix: + + check size <> 0 & size <> 2 & size <> 4 + jno done + + err 'invalid operand size' + + done: + +end calminstruction + + +iterate , add,0, or,8, adc,10h, sbb,18h, and,20h, sub,28h, xor,30h, cmp,38h + + calminstruction instr? dest*,src* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + + local opcode, rm, size + + compute opcode, basecode + + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + main: + + check @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes reg_rm + check @src.type = 'mem' & @dest.type = 'reg' + jyes rm_reg + check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes rm_imm + + err 'invalid combination of operands' + exit + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + reg_rm: + check size > 1 + jno reg_rm_store + call x86.select_operand_prefix@dest, size + compute opcode, opcode + 1 + reg_rm_store: + call x86.store_instruction@dest, opcode,@src.rm + exit + + rm_reg: + compute opcode, opcode + 2 + check size > 1 + jno rm_reg_store + call x86.select_operand_prefix@src, size + compute opcode, opcode + 1 + rm_reg_store: + call x86.store_instruction@src, opcode,@dest.rm + exit + + rm_imm: + check size > 1 + jyes rm_imm_word + check @dest.type = 'reg' & @dest.rm = 0 + jyes al_imm + + compute opcode, opcode shr 3 + xcall x86.store_instruction@dest, (80h),opcode,byte,@src.imm + exit + + al_imm: + emit 1, opcode+4 + emit 1, @src.imm + exit + + rm_imm_word: + + call x86.select_operand_prefix@dest, size + + check @src.imm eqtype 0.0 + jno rm_imm_optimize + + asm virtual at 0 + asm emit size: @src.imm + asm load @src.imm:size from 0 + asm end virtual + compute @src.imm, +@src.imm + + rm_imm_optimize: + check @src.imm relativeto 0 & @src.imm<80h & @src.imm>=-80h + jyes rm_simm + check size = 2 & @src.imm relativeto 0 & @src.imm-10000h>=-80h & @src.imm<10000h + jyes rm_simm_wrap + check size = 4 & @src.imm relativeto 0 & @src.imm-100000000h>=-80h & @src.imm<100000000h + jyes rm_simm_wrap + check @dest.type = 'reg' & @dest.rm = 0 + jyes ax_imm + + compute rm, opcode shr 3 + xcall x86.store_instruction@dest, (81h),rm,size,@src.imm + exit + + ax_imm: + check @dest.prefix + jno ax_imm_prefix_ok + emit 1, @dest.prefix + ax_imm_prefix_ok: + emit 1, opcode+5 + check size = 4 + jyes imm32 + asm dw @src.imm + exit + imm32: + asm dd @src.imm + exit + + rm_simm_wrap: + compute @src.imm, @src.imm - 1 shl (size shl 3) + + rm_simm: + compute rm, opcode shr 3 + xcall x86.store_instruction@dest, (83h),rm,byte,@src.imm + + end calminstruction + +end iterate + +iterate , not,2, neg,3, mul,4, div,6, idiv,7 + + calminstruction instr? src* + + call x86.parse_operand@src, src + + check @src.size = 0 + jyes operand_size_not_specified + + main: + check @src.type = 'mem' | @src.type = 'reg' + jno invalid_operand + check @src.size > 1 + jyes rm_word + + xcall x86.store_instruction@src, (0F6h),(postbyte) + exit + + rm_word: + call x86.select_operand_prefix@src, @src.size + xcall x86.store_instruction@src, (0F7h),(postbyte) + exit + + operand_size_not_specified: + err 'operand size not specified' + jump main + + invalid_operand: + err 'invalid operand' + exit + + end calminstruction + +end iterate + +calminstruction mov? dest*,src* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + + local ext, rm, size + + check @dest.size = 0 & @src.size = 0 & @dest.type <> 'sreg' + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + main: + + check @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes mov_rm_reg + check @src.type = 'mem' & @dest.type = 'reg' + jyes mov_reg_mem + check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes mov_rm_imm + check @src.type = 'reg' & @dest.type = 'imm' + jyes mov_creg_reg + check @src.type = 'sreg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes mov_rm_sreg + check @dest.type = 'sreg' & @dest.rm <> 1 & ( @src.type = 'reg' | @src.type = 'mem' ) + jyes mov_sreg_rm + + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + mov_rm_reg: + check @src.type = 'reg' & @dest.type = 'mem' & @src.rm = 0 & @dest.address_registers eq 0 + jyes mov_dirmem_ax + check size > 1 + jno mov_reg_rm_8bit + call x86.select_operand_prefix@dest, size + xcall x86.store_instruction@dest, (89h),@src.rm + exit + mov_reg_rm_8bit: + xcall x86.store_instruction@dest, (88h),@src.rm + exit + + mov_reg_mem: + check @src.type = 'mem' & @dest.type = 'reg' & @dest.rm = 0 & @src.address_registers eq 0 + jyes mov_ax_dirmem + check size > 1 + jno mov_mem_reg_8bit + call x86.select_operand_prefix@src, size + xcall x86.store_instruction@src, (8Bh),@dest.rm + exit + mov_mem_reg_8bit: + xcall x86.store_instruction@src, (8Ah),@dest.rm + exit + + mov_dirmem_ax: + check @dest.segment_prefix = 0 | @dest.segment_prefix = 3Eh + jyes dest_seg_ok + emit 1, @dest.segment_prefix + dest_seg_ok: + check @dest.mode = x86.mode + jyes dest_addr_size_ok + emit 1, 67h + dest_addr_size_ok: + check size > 1 + jno mov_dirmem_al + call x86.store_operand_prefix, size + emit 1, 0A3h + jump dest_displacement + mov_dirmem_al: + emit 1, 0A2h + dest_displacement: + check @dest.mode = 16 + jyes dest_displacement_16bit + asm dd @dest.address + exit + dest_displacement_16bit: + asm dw @dest.address + exit + + mov_ax_dirmem: + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh + jyes src_seg_ok + emit 1, @src.segment_prefix + src_seg_ok: + check @src.mode = x86.mode + jyes src_addr_size_ok + emit 1, 67h + src_addr_size_ok: + check size > 1 + jno mov_al_dirmem + call x86.store_operand_prefix, size + emit 1, 0A1h + jump src_displacement + mov_al_dirmem: + emit 1, 0A0h + src_displacement: + check @src.mode = 16 + jyes src_displacement_16bit + asm dd @src.address + exit + src_displacement_16bit: + asm dw @src.address + exit + + mov_rm_imm: + check @dest.type = 'mem' + jyes mov_mem_imm + check @dest.type = 'reg' & 1 metadataof (1 metadataof @src.imm) relativeto x86.creg & @src.imm relativeto 1 elementof @src.imm + jyes mov_reg_creg + + mov_reg_imm: + check size > 1 + jno mov_reg_imm_8bit + call x86.store_operand_prefix, size + emit 1, 0B8h + @dest.rm + check size = 2 + jyes src_imm_16bit + asm dd @src.imm + exit + src_imm_16bit: + asm dw @src.imm + exit + mov_reg_imm_8bit: + emit 1, 0B0h + @dest.rm + emit 1, @src.imm + exit + + mov_mem_imm: + check size > 1 + jno mov_mem_imm_8bit + call x86.select_operand_prefix@dest, size + xcall x86.store_instruction@dest, (0C7h),(0),size,@src.imm + exit + mov_mem_imm_8bit: + xcall x86.store_instruction@dest, (0C6h),(0),byte,@src.imm + exit + + mov_reg_creg: + check @dest.size = 4 + jno invalid_operand_size + compute ext, 20h + 1 metadataof (1 metadataof @src.imm) - x86.creg + compute rm, 1 metadataof @src.imm - 1 elementof (1 metadataof @src.imm) + xcall x86.store_instruction@dest, <0Fh,ext>,rm + exit + + mov_creg_reg: + check 1 metadataof (1 metadataof @dest.imm) relativeto x86.creg & @dest.imm relativeto 1 elementof @dest.imm + jno invalid_combination_of_operands + check @src.size = 4 + jno invalid_operand_size + compute ext, 22h + 1 metadataof (1 metadataof @dest.imm) - x86.creg + compute rm, 1 metadataof @dest.imm - 1 elementof (1 metadataof @dest.imm) + xcall x86.store_instruction@src, <0Fh,ext>,rm + exit + + mov_rm_sreg: + check @dest.type = 'mem' + jyes mov_mem_sreg + mov_reg_sreg: + check size > 1 + jno invalid_operand_size + call x86.select_operand_prefix@dest, size + jump mov_rm_sreg_store + mov_mem_sreg: + check size and not 2 + jyes invalid_operand_size + mov_rm_sreg_store: + xcall x86.store_instruction@dest, (8Ch),@src.rm + exit + + mov_sreg_rm: + check size = 1 + jyes invalid_operand_size + xcall x86.store_instruction@src, (8Eh),@dest.rm + exit + + invalid_operand_size: + err 'invalid operand size' + exit + +end calminstruction + +calminstruction test? dest*,src* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + + local ext, rm, size + + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + main: + + check @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes test_reg_rm + check @src.type = 'mem' & @dest.type = 'reg' + jyes test_mem_reg + check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes test_rm_imm + + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + test_reg_rm: + check size > 1 + jno test_reg_rm_8bit + call x86.select_operand_prefix@dest, size + xcall x86.store_instruction@dest, (85h),@src.rm + exit + test_reg_rm_8bit: + xcall x86.store_instruction@dest, (84h),@src.rm + exit + + test_mem_reg: + check size > 1 + jno test_mem_reg_8bit + call x86.select_operand_prefix@src, size + xcall x86.store_instruction@src, (85h),@dest.rm + exit + test_mem_reg_8bit: + xcall x86.store_instruction@src, (84h),@dest.rm + exit + + test_rm_imm: + check size > 1 + jno test_rm_imm_8bit + check @dest.type = 'reg' & @dest.rm = 0 + jyes test_ax_imm + call x86.select_operand_prefix@dest, size + xcall x86.store_instruction@dest, (0F7h),(0),size,@src.imm + exit + + test_ax_imm: + call x86.store_operand_prefix, size + emit 1, 0A9h + check size = 2 + jyes src_imm_16bit + asm dd @src.imm + exit + src_imm_16bit: + asm dw @src.imm + exit + + test_rm_imm_8bit: + check @dest.type = 'reg' & @dest.rm = 0 + jyes test_al_imm + xcall x86.store_instruction@dest, (0F6h),(0),byte,@src.imm + exit + test_al_imm: + emit 1, 0A8h + emit 1, @src.imm + exit + +end calminstruction + +calminstruction xchg? dest*,src* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + + local ext, rm, size + + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + main: + + check @src.type = 'reg' & @dest.type = 'reg' + jyes xchg_reg_reg + check @src.type = 'reg' & @dest.type = 'mem' + jyes xchg_reg_rm + check @src.type = 'mem' & @dest.type = 'reg' + jyes xchg_rm_reg + + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + xchg_reg_reg: + check @src.rm = 0 | @dest.rm = 0 + jno xchg_rm_reg + check size > 1 + jno xchg_rm_reg_8bit + call x86.store_operand_prefix, size + emit 1, 90h + @src.rm + @dest.rm + exit + + xchg_reg_rm: + check size > 1 + jno xchg_reg_rm_8bit + call x86.select_operand_prefix@dest, size + xcall x86.store_instruction@dest, (87h),@src.rm + exit + xchg_reg_rm_8bit: + xcall x86.store_instruction@dest, (86h),@src.rm + exit + + xchg_rm_reg: + check size > 1 + jno xchg_rm_reg_8bit + call x86.select_operand_prefix@src, size + xcall x86.store_instruction@src, (87h),@dest.rm + exit + xchg_rm_reg_8bit: + xcall x86.store_instruction@src, (86h),@dest.rm + exit + +end calminstruction + +iterate , inc,00 ,dec,01 + + calminstruction instr? dest* + + call x86.parse_operand@dest, dest + + check @dest.size + jyes main + + err 'operand size not specified' + + main: + check @dest.type = 'reg' + jyes inc_reg + check @dest.type = 'mem' + jyes inc_rm + + err 'invalid operand' + exit + + inc_reg: + check @dest.size > 1 + jno inc_rm_8bit + call x86.store_operand_prefix, @dest.size + emit 1, 40h + @dest.rm + 0x#postbyte shl 3 + exit + + inc_rm: + check @dest.size > 1 + jno inc_rm_8bit + call x86.select_operand_prefix@dest, @dest.size + xcall x86.store_instruction@dest, (0FFh),(postbyte) + exit + inc_rm_8bit: + xcall x86.store_instruction@dest, (0FEh),(postbyte) + + end calminstruction + +end iterate + +calminstruction imul? dest*,src& + + local size + + call x86.parse_operand@dest, dest + + match , src + jyes imul_rm + + local src1, src2 + + match src1 =, src2, src + jyes imul_second_source + + call x86.parse_operand@src, src + + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + check @dest.type = 'reg' & (@src.type = 'reg' | @src.type = 'mem') + jyes imul_reg_rm + + check @src.type = 'imm' & @dest.type = 'reg' + jno invalid_combination_of_operands + + compute @aux.type, @src.type + compute @aux.imm, @src.imm + compute @src.type, @dest.type + compute @src.mod, @dest.mod + compute @src.rm, @dest.rm + + jump main + + imul_second_source: + call x86.parse_operand@src, src1 + call x86.parse_operand@aux, src2 + + check @dest.size = 0 & @src.size = 0 & @aux.size = 0 + jyes operand_size_not_specified + + compute size, @dest.size or @src.size or @aux.size + + check (@dest.size & @dest.size <> size) | (@src.size & @src.size <> size) | (@aux.size & @aux.size <> size) + jyes operand_sizes_do_not_match + + jump main + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + main: + check @aux.type = 'imm' & ( @src.type = 'mem' | @src.type = 'reg' ) & @dest.type = 'reg' + jyes imul_reg_rm_imm + + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + + imul_rm: + check @dest.size + jyes imul_rm_size_ok + err 'operand size not specified' + imul_rm_size_ok: + check @dest.type = 'mem' | @dest.type = 'reg' + jno invalid_combination_of_operands + check @dest.size > 1 + jno imul_rm_8bit + call x86.select_operand_prefix@dest, @dest.size + xcall x86.store_instruction@dest, (0F7h),(5) + exit + imul_rm_8bit: + xcall x86.store_instruction@dest, (0F6h),(5) + exit + + imul_reg_rm: + call x86.select_operand_prefix@src, size + xcall x86.store_instruction@src, <0Fh,0AFh>,@dest.rm + exit + + imul_reg_rm_imm: + call x86.select_operand_prefix@src, size + check @aux.imm eqtype 0.0 + jno imul_reg_rm_imm_optimize + asm virtual at 0 + asm emit size: @aux.imm + asm load @aux.imm:size from 0 + asm end virtual + compute @aux.imm, +@aux.imm + imul_reg_rm_imm_optimize: + check @aux.imm relativeto 0 & @aux.imm < 80h & @aux.imm >= -80h + jyes imul_reg_rm_simm + check size = 2 & @aux.imm relativeto 0 & @aux.imm - 10000h >= -80h & @aux.imm < 10000h + jyes imul_reg_rm_simm_wrap + check size = 4 & @aux.imm relativeto 0 & @aux.imm - 100000000h >= -80h & @aux.imm < 100000000h + jyes imul_reg_rm_simm_wrap + xcall x86.store_instruction@src, (69h),@dest.rm,size,@aux.imm + exit + imul_reg_rm_simm_wrap: + compute @aux.imm, @aux.imm - 1 shl (size shl 3) + imul_reg_rm_simm: + xcall x86.store_instruction@src, (6Bh),@dest.rm,byte,@aux.imm + exit + +end calminstruction + +calminstruction x86.push_instruction size:0,src* + + call x86.parse_operand@src, src + + check size <> 0 & @src.size and not size + jyes invalid_operand_size + compute size, size or @src.size + check size = 0 | size = 2 | size = 4 + jyes main + + invalid_operand_size: + err 'invalid operand size' + + main: + check @src.type = 'mem' + jyes push_mem + check @src.type = 'reg' + jyes push_reg + check @src.type = 'sreg' + jyes push_sreg + check @src.type = 'imm' + jyes push_imm + + err 'invalid operand' + exit + + push_mem: + call x86.select_operand_prefix@src, size + xcall x86.store_instruction@src, (0FFh),(110b) + exit + + push_reg: + call x86.store_operand_prefix, size + emit 1, 50h + @src.rm + exit + + push_sreg: + call x86.store_operand_prefix, size + check @src.rm >= 4 + jyes push_sreg_386 + emit 1, 6 + @src.rm shl 3 + exit + push_sreg_386: + emit 1, 0Fh + emit 1, 0A0h + (@src.rm-4) shl 3 + exit + + push_imm: + check size + jyes push_imm_size_ok + check x86.mode = 16 + jyes push_imm_16bit + compute size, 4 + jump push_imm_size_ok + push_imm_16bit: + compute size, 2 + push_imm_size_ok: + + call x86.store_operand_prefix, size + + check @src.imm eqtype 0.0 + jno push_imm_optimize + asm virtual at 0 + asm emit size: @src.imm + asm load @src.imm:size from 0 + asm end virtual + compute @src.imm, +@src.imm + push_imm_optimize: + check @src.imm relativeto 0 & @src.imm < 80h & @src.imm >= -80h + jyes push_simm + check size = 2 & @src.imm relativeto 0 & @src.imm - 10000h >= -80h & @src.imm < 10000h + jyes push_simm_wrap + check size = 4 & @src.imm relativeto 0 & @src.imm - 100000000h >= -80h & @src.imm < 100000000h + jyes push_simm_wrap + emit 1, 68h + check size = 2 + jyes src_imm_16bit + asm dd @src.imm + exit + src_imm_16bit: + asm dw @src.imm + exit + push_simm_wrap: + compute @src.imm, @src.imm - 1 shl (size shl 3) + push_simm: + emit 1, 6Ah + emit 1, @src.imm + exit + +end calminstruction + +calminstruction x86.pop_instruction size:0,dest* + + call x86.parse_operand@dest, dest + + check size <> 0 & @dest.size and not size + jyes invalid_operand_size + compute size, size or @dest.size + check size = 0 | size = 2 | size = 4 + jyes main + + invalid_operand_size: + err 'invalid operand size' + + main: + check @dest.type = 'mem' + jyes pop_mem + check @dest.type = 'reg' + jyes pop_reg + check @dest.type = 'sreg' + jyes pop_sreg + + invalid_operand: + err 'invalid operand' + exit + + pop_mem: + call x86.select_operand_prefix@dest, size + xcall x86.store_instruction@dest, (8Fh),(0) + exit + + pop_reg: + call x86.store_operand_prefix, size + emit 1, 58h + @dest.rm + exit + + pop_sreg: + check @dest.rm = 1 + jyes invalid_operand + call x86.store_operand_prefix, size + check @dest.rm >= 4 + jyes pop_sreg_386 + emit 1, 7 + @dest.rm shl 3 + exit + pop_sreg_386: + emit 1, 0Fh + emit 1, 0A1h + (@dest.rm-4) shl 3 + exit + +end calminstruction + +iterate reg, ax,cx,dx,bx,sp,bp,si,di, eax,ecx,edx,ebx,esp,ebp,esi,edi, es,cs,ss,ds,fs,gs + define x86.compact.reg? {reg} +end iterate + +iterate , push,push_instruction,0, pushw,push_instruction,2, pushd,push_instruction,4, \ + pop,pop_instruction,0, popw,pop_instruction,2, popd,pop_instruction,4 + + calminstruction instr? operand + + local head, tail + + match head tail, operand + jno plain + transform head, x86.compact + jno plain + match {head}, head + jno plain + loop: + xcall x86.handler, (size),head + match head tail, tail + jno final + transform head, x86.compact + jno error + match {head}, head + jyes loop + error: + err 'only register operands allowed in compact syntax' + exit + final: + transform tail, x86.compact + jno error + match {operand}, tail + jno error + plain: + xcall x86.handler, (size),operand + + end calminstruction + +end iterate + +iterate , ret,0C2h, retn,0C2h, retf,0CAh + + calminstruction instr? operand + match , operand + jyes ret_short + check operand + jno ret_short + emit 1, opcode + asm dw operand + exit + ret_short: + emit 1, opcode + 1 + end calminstruction + +end iterate + +iterate , retw,2,0C2h, retnw,2,0C2h, retd,4,0C2h, retnd,4,0C2h, retfw,2,0CAh, retfd,4,0CAh + + calminstruction instr? operand + xcall x86.store_operand_prefix, (size) + match , operand + jyes ret_short + emit 1, opcode + asm dw operand + exit + ret_short: + emit 1, opcode + 1 + end calminstruction + +end iterate + +calminstruction lea? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.type = 'mem' & @dest.type = 'reg' + jno invalid_combination_of_operands + call x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, (8Dh),@dest.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' +end calminstruction + +iterate , les,0C4h, lds,0C5h, lss,<0Fh,0B2h>, lfs,<0Fh,0B4h>, lgs,<0Fh,0B5h> + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check (@dest.size = 2 & (@src.size <> 0 & @src.size <> 4)) | (@dest.size = 4 & (@src.size <> 0 & @src.size <> 6)) + jyes invalid_operand_size + check @src.type = 'mem' & @dest.type = 'reg' + jno invalid_combination_of_operands + call x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, ,@dest.rm + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + end calminstruction + +end iterate + +iterate , rol,0, ror,1, rcl,2, rcr,3, shl,4, sal, 4, shr,5, sar,7 + + calminstruction instr? dest*,cnt* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, cnt + + check @dest.size = 0 + jyes operand_size_not_specified + check @src.size and not 1 + jyes invalid_operand_size + + main: + check @src.type = 'reg' & @src.size = 1 & @src.rm = 1 & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes shift_rm_cl + check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes shift_rm_imm + + err 'invalid combination of operands' + exit + + shift_rm_cl: + check @dest.size > 1 + jno shift_r8_cl + call x86.select_operand_prefix@dest, @dest.size + xcall x86.store_instruction@dest, (0D3h),(postbyte) + exit + shift_r8_cl: + xcall x86.store_instruction@dest, (0D2h),(postbyte) + exit + shift_rm_imm: + check @dest.size > 1 + jno shift_rm8_imm + call x86.select_operand_prefix@dest, @dest.size + check @src.imm = 1 + jyes shift_rm_1 + xcall x86.store_instruction@dest, (0C1h),(postbyte),byte,@src.imm + exit + shift_rm_1: + xcall x86.store_instruction@dest, (0D1h),(postbyte) + exit + shift_rm8_imm: + check @src.imm = 1 + jyes shift_rm8_1 + xcall x86.store_instruction@dest, (0C0h),(postbyte),byte,@src.imm + exit + shift_rm8_1: + xcall x86.store_instruction@dest, (0D0h),(postbyte) + exit + + operand_size_not_specified: + err 'operand size not specified' + jump main + invalid_operand_size: + err 'invalid operand size' + jump main + + end calminstruction + +end iterate + +iterate , shld,0A4h, shrd,0ACh + + calminstruction instr? dest*,src*,cnt* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + call x86.parse_operand@aux, cnt + check @aux.size and not 1 + jyes invalid_operand_size + check @dest.size and not @src.size + jno main + err 'operand sizes do not match' + main: + check @aux.type = 'reg' & @aux.size = 1 & @aux.rm = 1 & @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes shld_cl + check @aux.type = 'imm' & @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes shld_imm + err 'invalid combination of operands' + exit + shld_cl: + call x86.select_operand_prefix@dest, @src.size + xcall x86.store_instruction@dest, <0Fh,ext+1>,@src.rm + exit + shld_imm: + call x86.select_operand_prefix@dest, @src.size + xcall x86.store_instruction@dest, <0Fh,ext>,@src.rm,byte,@aux.imm + exit + invalid_operand_size: + err 'invalid operand size' + end calminstruction + +end iterate + +iterate , bt,4, bts,5, btr,6, btc,7 + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.type = 'reg' & (@dest.type = 'mem' | @dest.type = 'reg') + jyes bt_rm_reg + check @src.type = 'imm' & (@dest.type = 'mem' | @dest.type = 'reg') + jyes bt_rm_imm + err 'invalid combination of operands' + exit + bt_rm_reg: + local opcode + check @dest.size and not @src.size + jno bt_rm_reg_ok + err 'operand sizes do not match' + bt_rm_reg_ok: + compute opcode, 0A3h+(postbyte-4) shl 3 + call x86.select_operand_prefix@dest, @src.size + xcall x86.store_instruction@dest, <0Fh,opcode>,@src.rm + exit + bt_rm_imm: + check @src.size and not 1 + jno bt_rm_imm_ok + err 'invalid operand size' + bt_rm_imm_ok: + check @dest.size + jno bt_rm_imm_prefix_ok + call x86.select_operand_prefix@dest, @dest.size + bt_rm_imm_prefix_ok: + xcall x86.store_instruction@dest, <0Fh,0BAh>,(postbyte),byte,@src.imm + end calminstruction + +end iterate + +iterate , bsf,0BCh, bsr,0BDh + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') + jyes bsf_reg_rm + err 'invalid combination of operands' + exit + bsf_reg_rm: + check @src.size and not @dest.size + jno bsf_reg_rm_ok + err 'operand sizes do not match' + bsf_reg_rm_ok: + call x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm + end calminstruction + +end iterate + +iterate , movzx,0B6h, movsx,0BEh + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.size > @src.size + jyes size_ok + err 'operand sizes do not match' + size_ok: + check @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') + jyes operands_ok + err 'invalid combination of operands' + exit + operands_ok: + check @src.size = 2 + jyes movzx_word + check @src.size = 1 | (@src.size = 0 & @dest.size = 2) + jyes movzx_byte + check @src.size + jyes invalid_operand_size + err 'operand size not specified' + movzx_word: + call x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, <0Fh,ext+1>,@dest.rm + exit + movzx_byte: + call x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm + exit + invalid_operand_size: + err 'invalid operand size' + end calminstruction + +end iterate + +iterate , o,0, no,1, c,2, b,2, nae,2, nc,3, nb,3, ae,3, z,4, e,4, nz,5, ne,5, na,6, be,6, a,7, nbe,7, \ + s,8, ns,9, p,0Ah, pe,0Ah, np,0Bh, po,0Bh, l,0Ch, nge,0Ch, nl,0Dh, ge,0Dh, ng,0Eh, le,0Eh, g,0Fh, nle,0Fh + + calminstruction set#cond? dest* + call x86.parse_operand@dest, dest + check @dest.size > 1 + jno size_ok + err 'invalid operand size' + size_ok: + check @dest.type = 'reg' | @dest.type = 'mem' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + xcall x86.store_instruction@dest, <0Fh,90h+code>,(0) + end calminstruction + +end iterate + +calminstruction call? dest* + + call x86.parse_jump_operand@dest, dest + + check @dest.type = 'imm' + jyes call_imm + check @dest.type = 'mem' | @dest.type = 'reg' + jyes call_rm + check @dest.type = 'far' + jyes call_direct_far + + invalid_operand: + err 'invalid operand' + exit + + call_direct_far: + check @dest.jump_type & @dest.jump_type <> 'far' + jyes invalid_operand + check @dest.size = 0 + jyes prefix_ok + local size + compute size, @dest.size - 2 + call x86.store_operand_prefix, size + prefix_ok: + check @dest.size and not 4 & @dest.size and not 6 + jyes invalid_operand + emit 1, 9Ah + check (@dest.size = 0 & x86.mode = 16) | @dest.size = 4 + jyes far_dword + asm dd @dest.offset + asm dw @dest.segment + exit + far_dword: + asm dw @dest.offset,@dest.segment + exit + + call_rm: + check @dest.size = 6 + jyes call_rm_pword + check @dest.size = 4 + jyes call_rm_dword + check @dest.size = 2 + jyes call_rm_word + check @dest.size + jyes invalid_operand + check @dest.jump_type = 'far' + jyes call_rm_far + check @dest.jump_type = 'near' + jyes call_rm_near + err 'operand size not specified' + exit + + call_rm_pword: + check @dest.jump_type & @dest.jump_type <> 'far' + jyes invalid_operand + xcall x86.select_operand_prefix@dest, (4) + call_rm_far: + xcall x86.store_instruction@dest, (0FFh),(11b) + exit + + call_rm_dword: + check @dest.jump_type | @dest.type = 'reg' + jno call_rm_dword_auto + check @dest.jump_type = 'far' + jyes call_rm_dword_far + call_rm_dword_near: + xcall x86.select_operand_prefix@dest, (4) + jump call_rm_near + call_rm_dword_auto: + check x86.mode = 16 + jno call_rm_dword_near + call_rm_dword_far: + xcall x86.select_operand_prefix@dest, (2) + jump call_rm_far + + call_rm_word: + check @dest.jump_type & @dest.jump_type <> 'near' + jyes invalid_operand + xcall x86.select_operand_prefix@dest, (2) + call_rm_near: + xcall x86.store_instruction@dest, (0FFh),(10b) + exit + + call_imm: + check @dest.jump_type & @dest.jump_type <> 'near' + jyes invalid_operand + check @dest.size = 2 + jyes call_imm_word + check @dest.size = 4 + jno invalid_operand + xcall x86.store_operand_prefix, (4) + emit 1, 0E8h + compute @dest.imm, @dest.imm-($+4) + asm dd @dest.imm + exit + call_imm_word: + xcall x86.store_operand_prefix, (2) + emit 1, 0E8h + compute @dest.imm, @dest.imm-($+2) + check @dest.imm relativeto 0 + jno store_word + compute @dest.imm, @dest.imm and 0FFFFh + store_word: + asm dw @dest.imm + exit + +end calminstruction + +calminstruction jmp? dest* + + call x86.parse_jump_operand@dest, dest + + check @dest.type = 'imm' + jyes jmp_imm + check @dest.type = 'mem' | @dest.type = 'reg' + jyes jmp_rm + check @dest.type = 'far' + jyes jmp_direct_far + + invalid_operand: + err 'invalid operand' + exit + + jmp_direct_far: + check @dest.jump_type & @dest.jump_type <> 'far' + jyes invalid_operand + check @dest.size = 0 + jyes prefix_ok + local size + compute size, @dest.size - 2 + call x86.store_operand_prefix, size + prefix_ok: + check @dest.size and not 4 & @dest.size and not 6 + jyes invalid_operand + emit 1, 0EAh + check (@dest.size = 0 & x86.mode = 16) | @dest.size = 4 + jyes far_dword + asm dd @dest.offset + asm dw @dest.segment + exit + far_dword: + asm dw @dest.offset,@dest.segment + exit + + jmp_rm: + check @dest.size = 6 + jyes jmp_rm_pword + check @dest.size = 4 + jyes jmp_rm_dword + check @dest.size = 2 + jyes jmp_rm_word + check @dest.size + jyes invalid_operand + check @dest.jump_type = 'far' + jyes jmp_rm_far + check @dest.jump_type = 'near' + jyes jmp_rm_near + err 'operand size not specified' + exit + + jmp_rm_pword: + check @dest.jump_type & @dest.jump_type <> 'far' + jyes invalid_operand + xcall x86.select_operand_prefix@dest, (4) + jmp_rm_far: + xcall x86.store_instruction@dest, (0FFh),(101b) + exit + + jmp_rm_dword: + check @dest.jump_type | @dest.type = 'reg' + jno jmp_rm_dword_auto + check @dest.jump_type = 'far' + jyes jmp_rm_dword_far + jmp_rm_dword_near: + xcall x86.select_operand_prefix@dest, (4) + jump jmp_rm_near + jmp_rm_dword_auto: + check x86.mode = 16 + jno jmp_rm_dword_near + jmp_rm_dword_far: + xcall x86.select_operand_prefix@dest, (2) + jump jmp_rm_far + + jmp_rm_word: + check @dest.jump_type & @dest.jump_type <> 'near' + jyes invalid_operand + xcall x86.select_operand_prefix@dest, (2) + jmp_rm_near: + xcall x86.store_instruction@dest, (0FFh),(100b) + exit + + jmp_imm: + call x86.store_operand_prefix, @dest.size + check @dest.jump_type = 'near' + jyes jmp_imm_near + check @dest.jump_type = 'short' + jyes jmp_imm_short_verify + check @dest.jump_type + jyes invalid_operand + check ~ $ relativeto 0 & @dest.imm relativeto 0 + jno jmp_optimize + compute @dest.imm, @dest.imm + $ - 0 scaleof $ + err 'invalid address' + jmp_optimize: + check @dest.unresolved + jyes jmp_imm_short + check @dest.imm relativeto $ + jno jmp_imm_near + check (@dest.imm-($+2)) < 80h & (@dest.imm-($+2)) >= -80h + jyes jmp_imm_short + check (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) < 80h | (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) >= 1 shl (@dest.size*8) - 80h + jyes jmp_imm_short + jmp_imm_near: + check @dest.size = 2 + jyes jmp_imm_word + check @dest.size = 4 + jno invalid_operand + emit 1, 0E9h + compute @dest.imm, @dest.imm-($+4) + asm dd @dest.imm + exit + jmp_imm_word: + emit 1, 0E9h + compute @dest.imm, @dest.imm-($+2) + check @dest.imm relativeto 0 + jno store_word + compute @dest.imm, @dest.imm and 0FFFFh + store_word: + asm dw @dest.imm + exit + jmp_imm_short_verify: + check (@dest.imm-($+2)) < 80h & (@dest.imm-($+2)) >= -80h + jyes jmp_imm_short + check (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) < 80h | (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) >= 1 shl (@dest.size*8) - 80h + jyes jmp_imm_short + emit 1, 0EBh + emit 1 + jump relative_jump_out_of_range + jmp_imm_short: + emit 1, 0EBh + compute @dest.imm, (@dest.imm-($+1)) and 0FFh + emit 1, @dest.imm + exit + relative_jump_out_of_range: + err 'relative jump out of range' + exit + +end calminstruction + +iterate , jo,70h, jno,71h, jc,72h, jb,72h, jnae,72h, jnc,73h, jnb,73h, jae,73h, jz,74h, je,74h, jnz,75h, jne,75h, jna,76h, jbe,76h, ja,77h, jnbe,77h, \ + js,78h, jns,79h, jp,7Ah, jpe,7Ah, jnp,7Bh, jpo,7Bh, jl,7Ch, jnge,7Ch, jnl,7Dh, jge,7Dh, jng,7Eh, jle,7Eh, jg,7Fh, jnle,7Fh + + calminstruction instr? dest* + + call x86.parse_jump_operand@dest, dest + + check @dest.type <> 'imm' | @dest.jump_type = 'far' + jyes invalid_operand + + call x86.store_operand_prefix, @dest.size + + check ~ $ relativeto 0 & @dest.imm relativeto 0 + jno optimize + compute @dest.imm, @dest.imm + $ - 0 scaleof $ + err 'invalid address' + optimize: + + check @dest.jump_type <> 'near' & ( @dest.unresolved | ( @dest.imm relativeto $ & @dest.imm-($+2) < 80h & @dest.imm-($+2) >= -80h ) ) + jyes short + check @dest.jump_type <> 'near' & @dest.imm relativeto $ & ( (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) < 80h | (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) >= 1 shl (@dest.size*8) - 80h ) + jyes short + check @dest.jump_type = 'short' + jyes relative_jump_out_of_range + + emit 1, 0Fh + emit 1, 10h+opcode + + check @dest.size = 2 + jyes relative_word + compute @dest.imm, @dest.imm-($+4) + asm dd @dest.imm + exit + relative_word: + compute @dest.imm, @dest.imm-($+2) + check @dest.imm relativeto 0 + jno store_word + compute @dest.imm, @dest.imm and 0FFFFh + store_word: + asm dw @dest.imm + exit + + short: + compute @dest.imm, (@dest.imm-($+2)) and 0FFh + emit 1, opcode + emit 1, @dest.imm + exit + + relative_jump_out_of_range: + emit 2 + err 'relative jump out of range' + exit + + invalid_operand: + err 'invalid operand' + exit + + end calminstruction +end iterate + +iterate , loopnz,0E0h,0, loopne,0E0h,0, loopz,0E1h,0, loope,0E1h,0, loop,0E2h,0, \ + loopnzw,0E0h,2, loopnew,0E0h,2, loopzw,0E1h,2, loopew,0E1h,2, loopw,0E2h,2, \ + loopnzd,0E0h,4, loopned,0E0h,4, loopzd,0E1h,4, looped,0E1h,4, loopd,0E2h,4, \ + jcxz,0E3h,2, jecxz,0E3h,4 + calminstruction instr? dest* + + call x86.parse_jump_operand@dest, dest + + check @dest.type = 'imm' & ( @dest.jump_type = 'short' | ~ @dest.jump_type ) + jno invalid_operand + + check len shl 3 and not x86.mode + jno address_prefix_ok + emit 1, 67h + address_prefix_ok: + check @dest.size shl 3 <> x86.mode + jno operand_prefix_ok + emit 1, 66h + operand_prefix_ok: + + emit 1, opcode + + check @dest.imm-($+1) < 80h & @dest.imm-($+1) >= -80h + jyes relative_offset_ok + check (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) < 80h | (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) >= 1 shl (@dest.size*8) - 80h + jyes relative_offset_ok + emit 1 + err 'relative jump out of range' + exit + relative_offset_ok: + compute @dest.imm, (@dest.imm-($+1)) and 0FFh + emit 1, @dest.imm + exit + + invalid_operand: + err 'invalid operand' + exit + + end calminstruction +end iterate + +iterate , daa,27h, das,2Fh, aaa,37h, aas,3Fh, nop,90h, int3,0CCh, into,0CEh, int1,0F1h, iret,0CFh, salc,0D6h, \ + hlt,0F4h, cmc,0F5h, clc,0F8h, stc,0F9h, cli,0FAh, sti,0FBh, cld,0FCh, std,0FDh, \ + pusha,60h, popa,61h, pushf,9Ch, popf,9Dh, sahf,9Eh, lahf,9Fh, leave,0C9h, \ + insb,6Ch, outsb,6Eh, movsb,0A4h, cmpsb,0A6h, stosb,0AAh, lodsb,0ACh, scasb,0AEh, xlatb,0D7h, \ + clts,<0Fh,06h>, loadall,<0Fh,07h> + + match byte1=,byte2, opcode + calminstruction instr? + emit 1, byte1 + emit 1, byte2 + end calminstruction + else + calminstruction instr? + emit 1, opcode + end calminstruction + end match + + +end iterate + +iterate , cbw,98h, cwd,99h, iretw,0CFh, pushaw,60h, popaw,61h, pushfw,9Ch, popfw,9Dh, \ + insw,6Dh, outsw,6Fh, movsw,0A5h, cmpsw,0A7h, stosw,0ABh, lodsw,0ADh, scasw,0AFh + + calminstruction instr? + xcall x86.store_operand_prefix, (2) + emit 1, opcode + end calminstruction + +end iterate + +iterate , cwde,98h, cdq,99h, iretd,0CFh, pushad,60h, popad,61h, pushfd,9Ch, popfd,9Ch, \ + insd,6Dh, outsd,6Fh, movsd,0A5h, cmpsd,0A7h, stosd,0ABh, lodsd,0ADh, scasd,0AFh + + calminstruction instr? + xcall x86.store_operand_prefix, (4) + emit 1, opcode + end calminstruction + +end iterate + +iterate , lock,0F0h, repnz,0F2h, repne,0F2h, rep,0F3h, repz,0F3h, repe,0F3h + + calminstruction prefix? instr& + emit 1, opcode + assemble instr + end calminstruction + +end iterate + +calminstruction int? number* + emit 1, 0CDh + emit 1, number +end calminstruction + +calminstruction aam? number:10 + emit 1, 0D4h + emit 1, number +end calminstruction + +calminstruction aad? number:10 + emit 1, 0D5h + emit 1, number +end calminstruction + +if defined SSE2 + + purge movsd?, cmpsd? + +end if + +calminstruction movs? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + local size + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + compute size, @dest.size or @src.size + size_ok: + check @src.type = 'mem' & @src.mod = 0 & @dest.type = 'mem' & @dest.mod = 0 & ( (@src.mode = 16 & @src.rm = 4 & @dest.mode = 16 & @dest.rm = 5) | (@src.mode = 32 & @src.rm = 6 & @dest.mode = 32 & @dest.rm = 7) ) & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h ) + jno invalid_combination_of_operands + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check @dest.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check size > 1 + jyes movs_word + emit 1, 0A4h + exit + movs_word: + call x86.store_operand_prefix, size + emit 1, 0A5h + exit + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump size_ok + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump size_ok + invalid_combination_of_operands: + err 'invalid combination of operands' + exit +end calminstruction + +calminstruction cmps? src*,dest* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + local size + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + compute size, @dest.size or @src.size + size_ok: + check @src.type = 'mem' & @src.mod = 0 & @dest.type = 'mem' & @dest.mod = 0 & ( (@src.mode = 16 & @src.rm = 4 & @dest.mode = 16 & @dest.rm = 5) | (@src.mode = 32 & @src.rm = 6 & @dest.mode = 32 & @dest.rm = 7) ) & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h ) + jno invalid_combination_of_operands + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check @dest.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check size > 1 + jyes cmps_word + emit 1, 0A6h + exit + cmps_word: + call x86.store_operand_prefix, size + emit 1, 0A7h + exit + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump size_ok + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump size_ok + invalid_combination_of_operands: + err 'invalid combination of operands' + exit +end calminstruction + +calminstruction stos? dest* + call x86.parse_operand@dest, dest + check @dest.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @dest.type = 'mem' & @dest.mod = 0 & ( (@dest.mode = 16 & @dest.rm = 5) | (@dest.mode = 32 & @dest.rm = 7) ) & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h ) + jno invalid_operand + check @dest.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check @dest.size > 1 + jyes stos_word + emit 1, 0AAh + exit + stos_word: + call x86.store_operand_prefix, @dest.size + emit 1, 0ABh + exit + invalid_operand: + err 'invalid operand' + exit +end calminstruction + +calminstruction lods? src* + call x86.parse_operand@src, src + check @src.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @src.type = 'mem' & @src.mod = 0 & ( (@src.mode = 16 & @src.rm = 4) | (@src.mode = 32 & @src.rm = 6) ) + jno invalid_operand + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check @src.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check @src.size > 1 + jyes lods_word + emit 1, 0ACh + exit + lods_word: + call x86.store_operand_prefix, @src.size + emit 1, 0ADh + exit + invalid_operand: + err 'invalid operand' + exit +end calminstruction + +calminstruction scas? dest* + call x86.parse_operand@dest, dest + check @dest.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @dest.type = 'mem' & @dest.mod = 0 & ( (@dest.mode = 16 & @dest.rm = 5) | (@dest.mode = 32 & @dest.rm = 7) ) & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h ) + jno invalid_operand + check @dest.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check @dest.size > 1 + jyes scas_word + emit 1, 0AEh + exit + scas_word: + call x86.store_operand_prefix, @dest.size + emit 1, 0AFh + exit + invalid_operand: + err 'invalid operand' + exit +end calminstruction + +calminstruction ins? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.size + jyes size_ok + err 'operand size not specified' + compute size, 0 + size_ok: + check @src.type = 'reg' & @src.size = 2 & @src.rm = 2 & @dest.type = 'mem' & @dest.mod = 0 & ( (@dest.mode = 16 & @dest.rm = 5) | (@dest.mode = 32 & @dest.rm = 7) ) & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h ) + jno invalid_combination_of_operands + check @dest.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check @dest.size > 1 + jyes ins_word + emit 1, 6Ch + exit + ins_word: + call x86.store_operand_prefix, @dest.size + emit 1, 6Dh + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + exit +end calminstruction + +calminstruction outs? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @dest.type = 'reg' & @dest.size = 2 & @dest.rm = 2 & @src.type = 'mem' & @src.mod = 0 & ( (@src.mode = 16 & @src.rm = 4) | (@src.mode = 32 & @src.rm = 6) ) + jno invalid_combination_of_operands + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check @src.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check @src.size > 1 + jyes outs_word + emit 1, 6Eh + exit + outs_word: + call x86.store_operand_prefix, @src.size + emit 1, 6Fh + exit + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump size_ok + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump size_ok + invalid_combination_of_operands: + err 'invalid combination of operands' + exit +end calminstruction + +calminstruction xlat? src* + call x86.parse_operand@src, src + check @src.size > 1 + jno size_ok + err 'invalid operand size' + size_ok: + check @src.type = 'mem' & @src.mod = 0 & ( (@src.mode = 16 & @src.rm = 7) | (@src.mode = 32 & @src.rm = 3) ) + jno invalid_operand + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check @src.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + emit 1, 0D7h + exit + invalid_operand: + err 'invalid operand' + exit +end calminstruction + +calminstruction in? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @src.type = 'reg' & @src.size = 2 & @src.rm = 2 & @dest.type = 'reg' & @dest.rm = 0 + jyes in_ax_dx + check @src.type = 'imm' & @dest.type = 'reg' & @dest.rm = 0 + jyes in_ax_imm + err 'invalid combination of operands' + exit + in_ax_dx: + check @dest.size > 1 + jno in_al_dx + call x86.store_operand_prefix, @dest.size + emit 1, 0EDh + exit + in_al_dx: + emit 1, 0ECh + exit + in_ax_imm: + check @dest.size > 1 + jno in_al_imm + call x86.store_operand_prefix, @dest.size + emit 1, 0E5h + emit 1, @src.imm + exit + in_al_imm: + emit 1, 0E4h + emit 1, @src.imm + exit +end calminstruction + +calminstruction out? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @dest.type = 'reg' & @dest.size = 2 & @dest.rm = 2 & @src.type = 'reg' & @src.rm = 0 + jyes out_dx_ax + check @dest.type = 'imm' & @src.type = 'reg' & @src.rm = 0 + jyes out_imm_ax + err 'invalid combination of operands' + exit + out_dx_ax: + check @src.size > 1 + jno out_dx_al + call x86.store_operand_prefix, @src.size + emit 1, 0EFh + exit + out_dx_al: + emit 1, 0EEh + exit + out_imm_ax: + check @src.size > 1 + jno out_imm_al + call x86.store_operand_prefix, @src.size + emit 1, 0E7h + emit 1, @dest.imm + exit + out_imm_al: + emit 1, 0E6h + emit 1, @dest.imm + exit +end calminstruction + +calminstruction enter? alloc*,nesting* + call x86.parse_operand@src, alloc + call x86.parse_operand@aux, nesting + check (@src.size and not 2) | (@aux.size and not 1) + jno size_ok + err 'invalid operand size' + size_ok: + check @src.type = 'imm' & @aux.type = 'imm' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + emit 1, 0C8h + asm dw @src.imm + emit 1, @aux.imm +end calminstruction + +calminstruction bound? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.type = 'mem' & @dest.type = 'reg' + jno invalid_combination_of_operands + check @src.size and not @dest.size + jno size_ok + err 'operand sizes do not match' + size_ok: + call x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, (62h),@dest.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' +end calminstruction + +calminstruction arpl? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.type = 'reg' & (@dest.type = 'mem' | @dest.type = 'reg') + jno invalid_combination_of_operands + check @src.size = 2 + jno invalid_operand_size + check @dest.size and not @src.size + jno size_ok + err 'operand sizes do not match' + jump size_ok + invalid_operand_size: + err 'invalid operand size' + size_ok: + xcall x86.store_instruction@dest, (63h),@src.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' +end calminstruction + +iterate , lldt,0,2, ltr,0,3, verr,0,4, verw,0,5, lmsw,1,6 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.size and not 2 + jno size_ok + err 'invalid operand size' + size_ok: + check @dest.type = 'reg' | @dest.type = 'mem' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + xcall x86.store_instruction@dest, <0Fh,ext>,(postbyte) + end calminstruction + +end iterate + +iterate , sldt,0,0, str,0,1, smsw,1,4 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.type = 'reg' + jyes select_operand_prefix + check @dest.size and not 2 + jno size_ok + err 'invalid operand size' + size_ok: + check @dest.type = 'mem' + jyes store_instruction + err 'invalid combination of operands' + exit + select_operand_prefix: + call x86.select_operand_prefix@dest, @dest.size + store_instruction: + xcall x86.store_instruction@dest, <0Fh,ext>,(postbyte) + end calminstruction + +end iterate + +iterate , lgdt,2, lidt,3, sgdt,0, sidt,1 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.type = 'mem' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + check @dest.size = 6 + jyes o32 + check @dest.size = 5 + jyes o16 + check @dest.size + jno store_instruction + err 'invalid operand size' + jump store_instruction + o16: + xcall x86.select_operand_prefix@dest, (2) + jump store_instruction + o32: + xcall x86.select_operand_prefix@dest, (4) + store_instruction: + xcall x86.store_instruction@dest, <0Fh,1>,(postbyte) + end calminstruction + +end iterate + +iterate , lar,2, lsl,3 + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') + jno invalid_combination_of_operands + check @src.size and not 2 + jno size_ok + err 'invalid operand size' + size_ok: + call x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + end calminstruction + +end iterate + +calminstruction xbts? dest*,src*,offs*,len* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + call x86.parse_operand@src2, offs + call x86.parse_operand@aux, len + check @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') & \ + @src2.type = 'reg' & @src2.rm = 0 & @aux.type = 'reg' & @aux.size = 1 & @aux.rm = 1 + jno invalid_combination_of_operands + check @src.size and not @dest.size | @src2.size <> @dest.size + jyes operand_sizes_no_not_match + check @dest.size > 1 + jyes size_ok + err 'invalid operand size' + jump size_ok + operand_sizes_no_not_match: + err 'operand sizes do not match' + size_ok: + call x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, <0Fh,0A6h>,@dest.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' +end calminstruction + +calminstruction ibts? dest*,offs*,len*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + call x86.parse_operand@src2, offs + call x86.parse_operand@aux, len + check @src.type = 'reg' & (@dest.type = 'mem' | @dest.type = 'reg') & \ + @src2.type = 'reg' & @src2.rm = 0 & @aux.type = 'reg' & @aux.size = 1 & @aux.rm = 1 + jno invalid_combination_of_operands + check @dest.size and not @src.size | @src2.size <> @src.size + jyes operand_sizes_no_not_match + check @src.size > 1 + jyes size_ok + err 'invalid operand size' + jump size_ok + operand_sizes_no_not_match: + err 'operand sizes do not match' + size_ok: + call x86.select_operand_prefix@dest, @src.size + xcall x86.store_instruction@dest, <0Fh,0A7h>,@src.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' +end calminstruction diff --git a/toolchain/fasmg.kl0e/examples/x86/include/80387.inc b/toolchain/fasmg.kl0e/examples/x86/include/80387.inc new file mode 100644 index 0000000..e8e659b --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/80387.inc @@ -0,0 +1,158 @@ + +if ~ defined i80387 + + restore i80387 ; this ensures that symbol cannot be forward-referenced + i80387 = 1 + + include '80287.inc' + + purge fsetpm? + + iterate , fprem1,<0D9h,0F5h>, fsincos,<0D9h,0FBh>, fsin,<0D9h,0FEh>, fcos,<0D9h,0FFh>, fucompp,<0DAh,0E9h> + + calminstruction instr? + asm db opcode + end calminstruction + + end iterate + + iterate , fucom,4, fucomp,5 + + calminstruction instr? src:st1 + call x87.parse_operand@src, src + check @src.type = 'streg' + jno invalid_operand + xcall x86.store_instruction@src, (0DDh),(postbyte) + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + + iterate , fldenv,4, fnstenv,6 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.size & ( ( x86.mode = 16 & @dest.size <> 14 ) | ( x86.mode = 32 & @dest.size <> 28 ) ) + jyes invalid_operand_size + check @dest.type = 'mem' + jno invalid_operand + xcall x86.store_instruction@dest, (0D9h),(postbyte) + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + iterate , fldenvw,4, fnstenvw,6 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.size and not 14 + jyes invalid_operand_size + check @dest.type = 'mem' + jno invalid_operand + xcall x86.store_operand_prefix, (2) + xcall x86.store_instruction@dest, (0D9h),(postbyte) + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + iterate , fldenvd,4, fnstenvd,6 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.size and not 28 + jyes invalid_operand_size + check @dest.type = 'mem' + jno invalid_operand + xcall x86.store_operand_prefix, (4) + xcall x86.store_instruction@dest, (0D9h),(postbyte) + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + iterate , frstor,4, fnsave,6 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.size & ( ( x86.mode = 16 & @dest.size <> 94 ) | ( x86.mode = 32 & @dest.size <> 108 ) ) + jyes invalid_operand_size + check @dest.type = 'mem' + jno invalid_operand + xcall x86.store_instruction@dest, (0DDh),(postbyte) + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + iterate , frstorw,4, fnsavew,6 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.size and not 94 + jyes invalid_operand_size + check @dest.type = 'mem' + jno invalid_operand + xcall x86.store_operand_prefix, (2) + xcall x86.store_instruction@dest, (0DDh),(postbyte) + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + iterate , frstord,4, fnsaved,6 + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.size and not 108 + jyes invalid_operand_size + check @dest.type = 'mem' + jno invalid_operand + xcall x86.store_operand_prefix, (4) + xcall x86.store_instruction@dest, (0DDh),(postbyte) + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + iterate op, stenvw, stenvd, savew, saved + calminstruction f#op? dest* + asm fwait? + asm fn#op? dest + end calminstruction + end iterate + +end if \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/examples/x86/include/80486.inc b/toolchain/fasmg.kl0e/examples/x86/include/80486.inc new file mode 100644 index 0000000..acb521f --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/80486.inc @@ -0,0 +1,62 @@ + +include '80386.inc' + +purge loadall? +purge xbts?,ibts? + +iterate , cmpxchg,0B0h, xadd,0C0h + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes xadd_rm_reg + err 'invalid combination of operands' + exit + xadd_rm_reg: + check @dest.size and not @src.size + jno size_ok + err 'operand sizes do not match' + size_ok: + check @src.size > 1 + jno xadd_rm_reg_8bit + call x86.select_operand_prefix@dest, @src.size + xcall x86.store_instruction@dest, <0Fh,ext+1>,@src.rm + exit + xadd_rm_reg_8bit: + xcall x86.store_instruction@dest, <0Fh,ext>,@src.rm + end calminstruction + +end iterate + +calminstruction bswap? dest* + call x86.parse_operand@dest, dest + check @dest.type = 'reg' & @dest.size = 4 + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + call x86.store_operand_prefix, @dest.size + emit 1, 0Fh + emit 1, 0C8h + @dest.rm and 111b +end calminstruction + +calminstruction invlpg? dest* + call x86.parse_operand@dest, dest + check @dest.type = 'mem' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + xcall x86.store_instruction@dest, <0Fh,1>,(7) +end calminstruction + +iterate , invd,<0Fh,8>, wbinvd,<0Fh,9> + + define x86.instr? db opcode + + calminstruction instr? + assemble x86.instr? + end calminstruction + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/8086.inc b/toolchain/fasmg.kl0e/examples/x86/include/8086.inc new file mode 100644 index 0000000..81b8e5e --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/8086.inc @@ -0,0 +1,1605 @@ + +define x86 x86 + +element x86.reg +element x86.r8 : x86.reg + 1 +element x86.r16 : x86.reg + 2 + +element al? : x86.r8 + 0 +element cl? : x86.r8 + 1 +element dl? : x86.r8 + 2 +element bl? : x86.r8 + 3 +element ah? : x86.r8 + 4 +element ch? : x86.r8 + 5 +element dh? : x86.r8 + 6 +element bh? : x86.r8 + 7 + +element ax? : x86.r16 + 0 +element cx? : x86.r16 + 1 +element dx? : x86.r16 + 2 +element bx? : x86.r16 + 3 +element sp? : x86.r16 + 4 +element bp? : x86.r16 + 5 +element si? : x86.r16 + 6 +element di? : x86.r16 + 7 + +element x86.sreg + +element es? : x86.sreg + 0 +element cs? : x86.sreg + 1 +element ss? : x86.sreg + 2 +element ds? : x86.sreg + 3 + +define x86.byte? :1 +define x86.word? :2 +define x86.dword? :4 + + +calminstruction calminstruction?.initsym? var*, val& + publish var, val +end calminstruction + +calminstruction calminstruction?.asm? line& + local name, i + initsym name, name.0 + match name.i, name + compute i, i+1 + arrange name, name.i + publish name, line + arrange line, =assemble name + assemble line +end calminstruction + +calminstruction calminstruction?.xcall? instruction*, arguments& + arrange instruction, =call instruction + convert: + match , arguments + jyes ready + local v + match v=,arguments, arguments, <> + jyes recognize + arrange v, arguments + arrange arguments, + recognize: + match (v), v + jyes numeric + match , v + jyes symbolic + append: + arrange instruction, instruction=,v + jump convert + numeric: + compute v, v + symbolic: + local proxy, base, i + initsym base, proxy + initsym i, 0 + compute i, i+1 + arrange proxy, base.i + publish proxy, v + arrange instruction, instruction=,proxy + jump convert + ready: + assemble instruction +end calminstruction + + +define @dest @dest +define @src @src +define @aux @aux + +iterate context, @dest,@src,@src2,@aux + + namespace context + + iterate name, size, type, segment_prefix, \ + imm, unresolved, displacement, displacement_size, \ + address, address_registers, segment, offset, jump_type, \ + mod, rm, + define name + end iterate + + calminstruction x86.parse_operand#context operand + + local i, pre, suf, sym + + compute segment_prefix, 0 + + compute size, 0 + compute displacement_size, 0 + + transform operand + + match pre suf, operand + jno no_size_prefix + transform pre, x86 + jno no_size_prefix + match :size, pre + jno no_size_prefix + arrange operand, suf + no_size_prefix: + + match [address], operand + jyes memory_operand + match =ptr? address, operand + jyes memory_operand + match segment:offset, operand + jyes far_operand + + immediate_operand: + compute type, 'imm' + compute imm, +operand + + compute unresolved, 0 + check defined operand + jyes operand_resolved + compute unresolved, 1 + operand_resolved: + + check imm eq 1 elementof imm + jno operand_ready + check 1 metadataof (1 metadataof imm) relativeto x86.reg + jyes register_operand + check 1 metadataof imm relativeto x86.sreg + jyes segment_register_operand + + operand_ready: + exit + + register_operand: + + compute type, 'reg' + compute mod, 11b + compute rm, 1 metadataof imm - 1 elementof (1 metadataof imm) + check size & size <> 1 metadataof (1 metadataof imm) - x86.reg + jyes operand_sizes_do_not_match + compute size, 1 metadataof (1 metadataof imm) - x86.reg + + exit + + segment_register_operand: + + compute type, 'sreg' + compute mod, 11b + compute rm, 1 metadataof imm - x86.sreg + check size and not 2 + jyes operand_sizes_do_not_match + compute size, 2 + + exit + + memory_operand: + compute type, 'mem' + + match segment:address, address + jno segment_prefix_ok + check segment eq 1 elementof segment & 1 metadataof segment relativeto x86.sreg + jno invalid_operand + compute segment, 1 metadataof segment - x86.sreg + compute segment_prefix, 26h + segment shl 3 + segment_prefix_ok: + + check size + jyes size_override + compute size, sizeof address + size_override: + + compute address, address + compute address_registers, 0 + compute i, 1 + extract_registers: + check i > elementsof address + jyes registers_extracted + check i metadataof address relativeto x86.r16 | i metadataof address relativeto x86.r32 + jno next_term + compute address_registers, address_registers + i elementof address * i scaleof address + next_term: + compute i, i+1 + jump extract_registers + registers_extracted: + compute displacement, address - address_registers + + check address_registers eq 0 + jyes direct_address + check address_registers relativeto bx+si + jyes rm_0 + check address_registers relativeto bx+di + jyes rm_1 + check address_registers relativeto bp+si + jyes rm_2 + check address_registers relativeto bp+di + jyes rm_3 + check address_registers relativeto si + jyes rm_4 + check address_registers relativeto di + jyes rm_5 + check address_registers relativeto bp + jyes rm_6 + check address_registers relativeto bx + jyes rm_7 + jump invalid_address + + direct_address: + compute mod, 0 + compute rm, 6 + compute displacement_size, 2 + exit + + rm_0: + compute rm, 0 + jump rm_ok + rm_1: + compute rm, 1 + jump rm_ok + rm_2: + compute rm, 2 + jump rm_ok + rm_3: + compute rm, 3 + jump rm_ok + rm_4: + compute rm, 4 + jump rm_ok + rm_5: + compute rm, 5 + jump rm_ok + rm_6: + compute rm, 6 + jump rm_ok + rm_7: + compute rm, 7 + rm_ok: + + check displacement relativeto 0 + jno displacement_16bit + check displacement = 0 & rm <> 6 + jyes displacement_empty + check displacement<80h & displacement>=-80h + jyes displacement_8bit + check displacement-10000h>=-80h & displacement<10000h + jyes displacement_8bit_wrap_16bit + displacement_16bit: + compute displacement_size, 2 + compute mod, 2 + exit + displacement_empty: + compute displacement_size, 0 + compute mod, 0 + exit + displacement_8bit_wrap_16bit: + compute displacement, displacement-10000h + displacement_8bit: + compute displacement_size, 1 + compute mod, 1 + exit + + far_operand: + compute type, 'far' + + check size and not 4 + jyes operand_sizes_do_not_match + + exit + + invalid_operand: + err 'invalid operand' + exit + invalid_operand_size: + err 'invalid operand size' + exit + operand_sizes_do_not_match: + err 'operand sizes do not match' + exit + invalid_address: + err 'invalid address' + exit + invalid_address_size: + err 'invalid address size' + exit + + end calminstruction + + calminstruction x86.parse_jump_operand#context operand + + match =far? operand, operand + jyes far_jump + match =near? operand, operand + jyes near_jump + match =short? operand, operand + jyes short_jump + compute jump_type, '' + jump parse_operand + far_jump: + compute jump_type, 'far' + jump parse_operand + near_jump: + compute jump_type, 'near' + jump parse_operand + short_jump: + compute jump_type, 'short' + + parse_operand: + + call x86.parse_operand#context, operand + + end calminstruction + + calminstruction x86.store_instruction#context opcode*,reg*,imm_size:0,immediate + + check segment_prefix + jno segment_prefix_ok + check rm = 2 | rm = 3 | ( mod > 0 & rm = 6 ) + jyes ss_segment_default + ds_segment_default: + check segment_prefix = 3Eh + jyes segment_prefix_ok + jump store_segment_prefix + ss_segment_default: + check segment_prefix = 36h + jyes segment_prefix_ok + store_segment_prefix: + emit 1, segment_prefix + segment_prefix_ok: + + emit 1, opcode + emit 1, mod shl 6 + reg shl 3 + rm + + check displacement_size = 1 + jyes displacement_8bit + check displacement_size = 2 + jno displacement_ok + displacement_16bit: + asm dw displacement + jump displacement_ok + displacement_8bit: + emit 1, displacement + displacement_ok: + + check imm_size = 1 + jyes immediate_8bit + check imm_size = 2 + jno immediate_ok + immediate_16bit: + compute imm, +immediate + asm dw imm + jump immediate_ok + immediate_8bit: + compute imm, +immediate + emit 1, imm + immediate_ok: + + end calminstruction + + end namespace + +end iterate + + +iterate , add,0, or,8, adc,10h, sbb,18h, and,20h, sub,28h, xor,30h, cmp,38h + + calminstruction instr? dest*,src* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + + local opcode, rm, size + + compute opcode, basecode + + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + check size > 2 + jyes invalid_operand_size + + main: + + check @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes reg_rm + check @src.type = 'mem' & @dest.type = 'reg' + jyes rm_reg + check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes rm_imm + + err 'invalid combination of operands' + exit + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + invalid_operand_size: + err 'invalid operand size' + compute size, 0 + jump main + + reg_rm: + check size = 2 + jno reg_rm_store + compute opcode, opcode + 1 + reg_rm_store: + call x86.store_instruction@dest, opcode,@src.rm + exit + + rm_reg: + compute opcode, opcode + 2 + check size = 2 + jno rm_reg_store + compute opcode, opcode + 1 + rm_reg_store: + call x86.store_instruction@src, opcode,@dest.rm + exit + + rm_imm: + check size = 2 + jyes rm_imm_word + check @dest.type = 'reg' & @dest.rm = 0 + jyes al_imm + + compute opcode, opcode shr 3 + xcall x86.store_instruction@dest, (80h),opcode,byte,@src.imm + exit + + al_imm: + emit 1, opcode+4 + emit 1, @src.imm + exit + + rm_imm_word: + + check @src.imm relativeto 0 & @src.imm<80h & @src.imm>=-80h + jyes rm_simm + check @src.imm relativeto 0 & @src.imm-10000h>=-80h & @src.imm<10000h + jyes rm_simm_wrap + check @dest.type = 'reg' & @dest.rm = 0 + jyes ax_imm + + compute rm, opcode shr 3 + xcall x86.store_instruction@dest, (81h),rm,size,@src.imm + exit + + ax_imm: + emit 1, opcode+5 + asm dw @src.imm + exit + + rm_simm_wrap: + compute @src.imm, @src.imm - 10000h + + rm_simm: + compute rm, opcode shr 3 + xcall x86.store_instruction@dest, (83h),rm,byte,@src.imm + + end calminstruction + +end iterate + +iterate , not,2, neg,3, mul,4, imul,5, div,6, idiv,7 + + calminstruction instr? src* + + call x86.parse_operand@src, src + + check @src.size = 0 + jyes operand_size_not_specified + + check @src.size > 2 + jyes invalid_operand_size + + main: + check @src.type = 'mem' | @src.type = 'reg' + jno invalid_operand + check @src.size = 2 + jyes rm_word + + xcall x86.store_instruction@src, (0F6h),(postbyte) + exit + + rm_word: + xcall x86.store_instruction@src, (0F7h),(postbyte) + exit + + operand_size_not_specified: + err 'operand size not specified' + jump main + + invalid_operand_size: + err 'invalid operand size' + jump main + + invalid_operand: + err 'invalid operand' + exit + + end calminstruction + +end iterate + +calminstruction mov? dest*,src* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + + local ext, rm, size + + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + check size > 2 + jyes invalid_operand_size + + main: + + check @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes mov_reg_rm + check @src.type = 'mem' & @dest.type = 'reg' + jyes mov_mem_reg + check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes mov_rm_imm + check @src.type = 'sreg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes mov_rm_sreg + check @dest.type = 'sreg' & @dest.rm <> 1 & ( @src.type = 'reg' | @src.type = 'mem' ) + jyes mov_sreg_rm + + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + invalid_operand_size: + err 'invalid operand size' + compute size, 0 + jump main + + mov_reg_rm: + check @src.type = 'reg' & @dest.type = 'mem' & @src.rm = 0 & @dest.address_registers eq 0 + jyes mov_ax_dirmem + check size < 2 + jyes mov_reg_rm_8bit + xcall x86.store_instruction@dest, (89h),@src.rm + exit + mov_reg_rm_8bit: + xcall x86.store_instruction@dest, (88h),@src.rm + exit + + mov_mem_reg: + check @src.type = 'mem' & @dest.type = 'reg' & @dest.rm = 0 & @src.address_registers eq 0 + jyes mov_dirmem_ax + check size < 2 + jyes mov_mem_reg_8bit + xcall x86.store_instruction@src, (8Bh),@dest.rm + exit + mov_mem_reg_8bit: + xcall x86.store_instruction@src, (8Ah),@dest.rm + exit + + mov_ax_dirmem: + check @dest.segment_prefix = 0 | @dest.segment_prefix = 3Eh + jyes dest_seg_ok + emit 1, @dest.segment_prefix + dest_seg_ok: + check size < 2 + jyes mov_al_dirmem + emit 1, 0A3h + asm dw @dest.address + exit + mov_al_dirmem: + emit 1, 0A2h + asm dw @dest.address + exit + + mov_dirmem_ax: + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh + jyes src_seg_ok + emit 1, @src.segment_prefix + src_seg_ok: + check size < 2 + jyes mov_dirmem_al + emit 1, 0A1h + asm dw @src.address + exit + mov_dirmem_al: + emit 1, 0A0h + asm dw @src.address + exit + + mov_rm_imm: + check @dest.type = 'mem' + jyes mov_mem_imm + + mov_reg_imm: + check size < 2 + jyes mov_reg_imm_8bit + emit 1, 0B8h + @dest.rm + asm dw @src.imm + exit + mov_reg_imm_8bit: + emit 1, 0B0h + @dest.rm + emit 1, @src.imm + exit + + mov_mem_imm: + check size < 2 + jyes mov_mem_imm_8bit + xcall x86.store_instruction@dest, (0C7h),(0),size,@src.imm + exit + mov_mem_imm_8bit: + xcall x86.store_instruction@dest, (0C6h),(0),byte,@src.imm + exit + + mov_rm_sreg: + check size < 2 + jyes invalid_operand_size + xcall x86.store_instruction@dest, (8Ch),@src.rm + exit + + mov_sreg_rm: + check size < 2 + jyes invalid_operand_size + xcall x86.store_instruction@src, (8Eh),@dest.rm + exit + +end calminstruction + +calminstruction test? dest*,src* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + + local ext, rm, size + + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + check size > 2 + jyes invalid_operand_size + + main: + + check @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes test_reg_rm + check @src.type = 'mem' & @dest.type = 'reg' + jyes test_mem_reg + check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes test_rm_imm + + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + invalid_operand_size: + err 'invalid operand size' + compute size, 0 + jump main + + test_reg_rm: + check size < 2 + jyes test_reg_rm_8bit + xcall x86.store_instruction@dest, (85h),@src.rm + exit + test_reg_rm_8bit: + xcall x86.store_instruction@dest, (84h),@src.rm + exit + + test_mem_reg: + check size < 2 + jyes test_mem_reg_8bit + xcall x86.store_instruction@src, (85h),@dest.rm + exit + test_mem_reg_8bit: + xcall x86.store_instruction@src, (84h),@dest.rm + exit + + test_rm_imm: + check size < 2 + jyes test_rm_imm_8bit + check @dest.type = 'reg' & @dest.rm = 0 + jyes test_ax_imm + xcall x86.store_instruction@dest, (0F7h),(0),size,@src.imm + exit + + test_ax_imm: + emit 1, 0A9h + asm dw @src.imm + exit + + test_rm_imm_8bit: + check @dest.type = 'reg' & @dest.rm = 0 + jyes test_al_imm + xcall x86.store_instruction@dest, (0F6h),(0),byte,@src.imm + exit + test_al_imm: + emit 1, 0A8h + emit 1, @src.imm + exit + +end calminstruction + +calminstruction xchg? dest*,src* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + + local ext, rm, size + + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + check size > 2 + jyes invalid_operand_size + + main: + + check @src.type = 'reg' & @dest.type = 'reg' + jyes xchg_reg_reg + check @src.type = 'reg' & @dest.type = 'mem' + jyes xchg_reg_rm + check @src.type = 'mem' & @dest.type = 'reg' + jyes xchg_rm_reg + + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + invalid_operand_size: + err 'invalid operand size' + compute size, 0 + jump main + + xchg_reg_reg: + check @src.rm = 0 | @dest.rm = 0 + jno xchg_rm_reg + check size < 2 + jyes xchg_rm_reg_8bit + emit 1, 90h + @src.rm + @dest.rm + exit + + xchg_reg_rm: + check size < 2 + jyes xchg_reg_rm_8bit + xcall x86.store_instruction@dest, (87h),@src.rm + exit + xchg_reg_rm_8bit: + xcall x86.store_instruction@dest, (86h),@src.rm + exit + + xchg_rm_reg: + check size < 2 + jyes xchg_rm_reg_8bit + xcall x86.store_instruction@src, (87h),@dest.rm + exit + xchg_rm_reg_8bit: + xcall x86.store_instruction@src, (86h),@dest.rm + exit + +end calminstruction + +iterate , inc,0 ,dec,1 + + calminstruction instr? dest* + + call x86.parse_operand@dest, dest + + check @dest.size > 2 + jyes invalid_operand_size + check @dest.size + jyes main + + err 'operand size not specified' + jump main + + invalid_operand_size: + err 'invalid operand size' + jump main + + main: + check @dest.type = 'reg' + jyes inc_reg + check @dest.type = 'mem' + jyes inc_rm + + err 'invalid operand' + exit + + inc_reg: + check @dest.size < 2 + jyes inc_rm_8bit + emit 1, 40h + @dest.rm + postbyte shl 3 + exit + + inc_rm: + check @dest.size < 2 + jyes inc_rm_8bit + xcall x86.store_instruction@dest, (0FFh),(postbyte) + exit + inc_rm_8bit: + xcall x86.store_instruction@dest, (0FEh),(postbyte) + + end calminstruction + +end iterate + +calminstruction push? src* + + call x86.parse_operand@src, src + + check @src.size and not 2 + jno main + + err 'invalid operand size' + + main: + check @src.type = 'mem' + jyes push_mem + check @src.type = 'reg' + jyes push_reg + check @src.type = 'sreg' + jyes push_sreg + + err 'invalid operand' + exit + + push_mem: + xcall x86.store_instruction@src, (0FFh),(110b) + exit + + push_reg: + emit 1, 50h + @src.rm + exit + + push_sreg: + emit 1, 6 + @src.rm shl 3 + exit + +end calminstruction + +calminstruction pop? dest* + + call x86.parse_operand@dest, dest + + check @dest.size and not 2 + jno main + + err 'invalid operand size' + + main: + check @dest.type = 'mem' + jyes pop_mem + check @dest.type = 'reg' + jyes pop_reg + check @dest.type = 'sreg' + jyes pop_sreg + + invalid_operand: + err 'invalid operand' + exit + + pop_mem: + xcall x86.store_instruction@dest, (8Fh),(0) + exit + + pop_reg: + emit 1, 58h + @dest.rm + exit + + pop_sreg: + emit 1, 7 + @dest.rm shl 3 + exit + +end calminstruction + +iterate reg, ax,cx,dx,bx,sp,bp,si,di, es,cs,ss,ds + define x86.compact.reg? {reg} +end iterate + +iterate , push,pop + + calminstruction instr? operand + + local head, tail + + match head tail, operand + jno plain + transform head, x86.compact + jno plain + match {head}, head + jno plain + loop: + arrange operand, =instr head + assemble operand + match head tail, tail + jno final + transform head, x86.compact + jno error + match {head}, head + jyes loop + error: + err 'only register operands allowed in compact syntax' + exit + final: + transform tail, x86.compact + jno error + match {operand}, tail + jno error + plain: + arrange operand, =instr operand + assemble operand + + end calminstruction + +end iterate + +iterate , ret,0C2h, retn,0C2h, retf,0CAh + + calminstruction instr? operand + match , operand + jyes ret_short + check operand + jno ret_short + emit 1, opcode + asm dw operand + exit + ret_short: + emit 1, opcode + 1 + end calminstruction + +end iterate + +calminstruction lea? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.type = 'mem' & @dest.type = 'reg' + jno invalid_combination_of_operands + check @dest.size = 2 + jyes ok + err 'invalid operand size' + ok: + xcall x86.store_instruction@src, (8Dh),@dest.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' +end calminstruction + +iterate , les,0C4h, lds,0C5h + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.size and not 2 | @src.size and not 4 + jyes invalid_operand_size + check @src.type = 'mem' & @dest.type = 'reg' + jno invalid_combination_of_operands + xcall x86.store_instruction@src, (opcode),@dest.rm + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + end calminstruction + +end iterate + +iterate , rol,0, ror,1, rcl,2, rcr,3, shl,4, sal, 4, shr,5, sar,7 + + calminstruction instr? dest*,cnt* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, cnt + + check @dest.size = 0 + jyes operand_size_not_specified + check @dest.size > 2 + jyes invalid_operand_size + check @src.size and not 1 + jyes invalid_operand_size + + main: + check @src.type = 'reg' & @src.size = 1 & @src.rm = 1 & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes shift_rm_cl + check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes shift_rm_imm + + err 'invalid combination of operands' + exit + + shift_rm_cl: + check @dest.size < 2 + jyes shift_r8_cl + xcall x86.store_instruction@dest, (0D3h),(postbyte) + exit + shift_r8_cl: + xcall x86.store_instruction@dest, (0D2h),(postbyte) + exit + + shift_rm_imm: + compute @src.imm, @src.imm and (1 shl (@dest.size shl 3) - 1) + check @dest.size < 2 + jyes shift_rm8_imm + shift_rm16_imm: + check @src.imm + jno done + xcall x86.store_instruction@dest, (0D1h),(postbyte) + compute @src.imm, @src.imm - 1 + jump shift_rm16_imm + shift_rm8_imm: + check @src.imm + jno done + xcall x86.store_instruction@dest, (0D0h),(postbyte) + compute @src.imm, @src.imm - 1 + jump shift_rm8_imm + done: + exit + + operand_size_not_specified: + err 'operand size not specified' + jump main + invalid_operand_size: + err 'invalid operand size' + jump main + + end calminstruction + +end iterate + +calminstruction call? dest* + + call x86.parse_jump_operand@dest, dest + + check @dest.type = 'imm' + jyes call_imm + check @dest.type = 'mem' | @dest.type = 'reg' + jyes call_rm + check @dest.type = 'far' + jyes call_direct_far + + invalid_operand: + err 'invalid operand' + exit + + call_direct_far: + check @dest.jump_type & @dest.jump_type <> 'far' + jyes invalid_operand + check @dest.size and not 4 + jyes invalid_operand + emit 1, 9Ah + asm dw @dest.offset,@dest.segment + exit + + call_rm: + check @dest.size = 4 + jyes call_rm_dword + check @dest.size = 2 + jyes call_rm_word + check @dest.size + jyes invalid_operand + check @dest.jump_type = 'far' + jyes call_rm_far + check @dest.jump_type = 'near' + jyes call_rm_near + err 'operand size not specified' + exit + + call_rm_dword: + check @dest.jump_type & @dest.jump_type <> 'far' + jyes invalid_operand + call_rm_far: + xcall x86.store_instruction@dest, (0FFh),(11b) + exit + + call_rm_word: + check @dest.jump_type & @dest.jump_type <> 'near' + jyes invalid_operand + call_rm_near: + xcall x86.store_instruction@dest, (0FFh),(10b) + exit + + call_imm: + check @dest.jump_type & @dest.jump_type <> 'near' + jyes invalid_operand + check @dest.imm relativeto 0 & (@dest.imm < 0 | @dest.imm >= 10000h) + jyes value_out_of_range + emit 1, 0E8h + compute @dest.imm, @dest.imm-($+2) + asm dw @dest.imm + exit + + value_out_of_range: + err 'value out of range' + +end calminstruction + +calminstruction jmp? dest* + + call x86.parse_jump_operand@dest, dest + + check @dest.type = 'imm' + jyes jmp_imm + check @dest.type = 'mem' | @dest.type = 'reg' + jyes jmp_rm + check @dest.type = 'far' + jyes jmp_direct_far + + invalid_operand: + err 'invalid operand' + exit + + jmp_direct_far: + check @dest.jump_type & @dest.jump_type <> 'far' + jyes invalid_operand + check @dest.size and not 4 + jyes invalid_operand + emit 1, 0EAh + asm dw @dest.offset,@dest.segment + exit + + jmp_rm: + check @dest.size = 4 + jyes jmp_rm_dword + check @dest.size = 2 + jyes jmp_rm_word + check @dest.size + jyes invalid_operand + check @dest.jump_type = 'far' + jyes jmp_rm_far + check @dest.jump_type = 'near' + jyes jmp_rm_near + err 'operand size not specified' + exit + + jmp_rm_dword: + check @dest.jump_type & @dest.jump_type <> 'far' + jyes invalid_operand + jmp_rm_far: + xcall x86.store_instruction@dest, (0FFh),(101b) + exit + + jmp_rm_word: + check @dest.jump_type & @dest.jump_type <> 'near' + jyes invalid_operand + jmp_rm_near: + xcall x86.store_instruction@dest, (0FFh),(100b) + exit + + jmp_imm: + check @dest.imm relativeto 0 & (@dest.imm < 0 | @dest.imm >= 10000h) + jyes value_out_of_range + check @dest.jump_type = 'near' + jyes jmp_imm_near + check @dest.jump_type = 'short' + jyes jmp_imm_short_verify + check @dest.jump_type + jyes invalid_operand + check ~ $ relativeto 0 & @dest.imm relativeto 0 + jno jmp_optimize + compute @dest.imm, @dest.imm + $ - 0 scaleof $ + err 'invalid address' + jmp_optimize: + check @dest.unresolved + jyes jmp_imm_short + check @dest.imm relativeto $ + jno jmp_imm_near + check (@dest.imm-($+2)) and 0FFFFh < 80h | (@dest.imm-($+2)) and 0FFFFh >= 0FF80h + jyes jmp_imm_short + jmp_imm_near: + emit 1, 0E9h + compute @dest.imm, @dest.imm-($+2) + asm dw @dest.imm + exit + jmp_imm_short_verify: + check (@dest.imm-($+2)) and 0FFFFh < 80h | (@dest.imm-($+2)) and 0FFFFh >= 0FF80h + jno relative_jump_out_of_range + jmp_imm_short: + emit 1, 0EBh + compute @dest.imm, (@dest.imm-($+1)) and 0FFh + emit 1, @dest.imm + exit + + relative_jump_out_of_range: + emit 2 + err 'relative jump out of range' + exit + + value_out_of_range: + err 'value out of range' + +end calminstruction + +x86.jumps = 0 + +calminstruction jumps? + compute x86.jumps, 1 +end calminstruction + +calminstruction nojumps? + compute x86.jumps, 0 +end calminstruction + +iterate , jo,70h, jno,71h, jc,72h, jb,72h, jnae,72h, jnc,73h, jnb,73h, jae,73h, jz,74h, je,74h, jnz,75h, jne,75h, jna,76h, jbe,76h, ja,77h, jnbe,77h, \ + js,78h, jns,79h, jp,7Ah, jpe,7Ah, jnp,7Bh, jpo,7Bh, jl,7Ch, jnge,7Ch, jnl,7Dh, jge,7Dh, jng,7Eh, jle,7Eh, jg,7Fh, jnle,7Fh + + calminstruction instr? dest* + + call x86.parse_jump_operand@dest, dest + + check @dest.type <> 'imm' & ( @dest.jump_type & @dest.jump_type <> 'short' ) + jyes invalid_operand + + check @dest.imm relativeto 0 & (@dest.imm < 0 | @dest.imm >= 10000h) + jyes value_out_of_range + + check @dest.unresolved | ( @dest.imm-($+2) < 80h & @dest.imm-($+2) >= -80h ) + jyes in_range + check (@dest.imm-($+2)) and 0FFFFh < 80h | (@dest.imm-($+2)) and 0FFFFh >= 0FF80h + jyes in_range + + check x86.jumps & ~ @dest.jump_type + jyes trampoline + + emit 1 + emit 1 + err 'relative jump out of range' + exit + + in_range: + compute @dest.imm, (@dest.imm-($+2)) and 0FFh + emit 1, opcode + emit 1, @dest.imm + exit + + trampoline: + emit 1, opcode xor 1 + emit 1, 3 + emit 1, 0E9h + compute @dest.imm, @dest.imm-($+2) + asm dw @dest.imm + exit + + invalid_operand: + err 'invalid operand' + exit + + value_out_of_range: + err 'value out of range' + + end calminstruction +end iterate + +iterate , loopnz,0E0h, loopne,0E0h, loopz,0E1h, loope,0E1h, loop,0E2h, jcxz,0E3h + + calminstruction instr? dest* + + call x86.parse_jump_operand@dest, dest + + check @dest.type = 'imm' & ( @dest.jump_type = 'short' | ~ @dest.jump_type ) + jno invalid_operand + + emit 1, opcode + + check @dest.imm-($+1) < 80h & @dest.imm-($+1) >= -80h + jyes relative_offset_ok + check (@dest.imm-($+2)) and 0FFFFh < 80h | (@dest.imm-($+2)) and 0FFFFh >= 0FF80h + jyes relative_offset_ok + emit 1 + err 'relative jump out of range' + exit + relative_offset_ok: + compute @dest.imm, (@dest.imm-($+1)) and 0FFh + emit 1, @dest.imm + exit + + invalid_operand: + err 'invalid operand' + exit + + end calminstruction +end iterate + +iterate , daa,27h, das,2Fh, aaa,37h, aas,3Fh, nop,90h, cbw,98h, cwd,99h, \ + int3,0CCh, into,0CEh, iret,0CFh, salc,0D6h, \ + hlt,0F4h, cmc,0F5h, clc,0F8h, stc,0F9h, cli,0FAh, sti,0FBh, cld,0FCh, std,0FDh, \ + pushf,9Ch, popf,9Dh, sahf,9Eh, lahf,9Fh, \ + movsb,0A4h, cmpsb,0A6h, stosb,0AAh, lodsb,0ACh, scasb,0AEh, xlatb,0D7h, \ + movsw,0A5h, cmpsw,0A7h, stosw,0ABh, lodsw,0ADh, scasw,0AFh + + calminstruction instr? + emit 1, opcode + end calminstruction + +end iterate + +iterate , lock,0F0h, repnz,0F2h, repne,0F2h, rep,0F3h, repz,0F3h, repe,0F3h + + calminstruction prefix? instr& + emit 1, opcode + assemble instr + end calminstruction + +end iterate + +calminstruction int? number* + emit 1, 0CDh + emit 1, number +end calminstruction + +calminstruction aam? number:10 + emit 1, 0D4h + emit 1, number +end calminstruction + +calminstruction aad? number:10 + emit 1, 0D5h + emit 1, number +end calminstruction + +calminstruction movs? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + local size + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + compute size, @dest.size or @src.size + size_ok: + check @src.type = 'mem' & @src.mod = 0 & @src.rm = 4 & @dest.type = 'mem' & @dest.mod = 0 & @dest.rm = 5 & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h ) + jno invalid_combination_of_operands + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check size = 2 + jyes movs_word + emit 1, 0A4h + exit + movs_word: + emit 1, 0A5h + exit + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump size_ok + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump size_ok + invalid_combination_of_operands: + err 'invalid combination of operands' + exit +end calminstruction + +calminstruction cmps? src*,dest* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + local size + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + compute size, @dest.size or @src.size + size_ok: + check @src.type = 'mem' & @src.mod = 0 & @src.rm = 4 & @dest.type = 'mem' & @dest.mod = 0 & @dest.rm = 5 & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h ) + jno invalid_combination_of_operands + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check size = 2 + jyes cmps_word + emit 1, 0A6h + exit + cmps_word: + emit 1, 0A7h + exit + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump size_ok + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump size_ok + invalid_combination_of_operands: + err 'invalid combination of operands' + exit +end calminstruction + +calminstruction stos? dest* + call x86.parse_operand@dest, dest + check @dest.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @dest.type = 'mem' & @dest.mod = 0 & @dest.rm = 5 & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h ) + jno invalid_operand + check @dest.size = 2 + jyes stos_word + emit 1, 0AAh + exit + stos_word: + emit 1, 0ABh + exit + invalid_operand: + err 'invalid operand' + exit +end calminstruction + +calminstruction lods? src* + call x86.parse_operand@src, src + check @src.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @src.type = 'mem' & @src.mod = 0 & @src.rm = 4 + jno invalid_operand + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check @src.size = 2 + jyes lods_word + emit 1, 0ACh + exit + lods_word: + emit 1, 0ADh + exit + invalid_operand: + err 'invalid operand' + exit +end calminstruction + +calminstruction scas? dest* + call x86.parse_operand@dest, dest + check @dest.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @dest.type = 'mem' & @dest.mod = 0 & @dest.rm = 5 & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h ) + jno invalid_operand + check @dest.size = 2 + jyes scas_word + emit 1, 0AEh + exit + scas_word: + emit 1, 0AFh + exit + invalid_operand: + err 'invalid operand' + exit +end calminstruction + +calminstruction xlat? src* + call x86.parse_operand@src, src + check @src.size > 1 + jno size_ok + err 'invalid operand size' + size_ok: + check @src.type = 'mem' & @src.mod = 0 & @src.rm = 7 + jno invalid_operand + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + emit 1, 0D7h + exit + invalid_operand: + err 'invalid operand' + exit +end calminstruction + +calminstruction in? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @src.type = 'reg' & @src.size = 2 & @src.rm = 2 & @dest.type = 'reg' & @dest.rm = 0 + jyes in_ax_dx + check @src.type = 'imm' & @dest.type = 'reg' & @dest.rm = 0 + jyes in_ax_imm + err 'invalid combination of operands' + exit + in_ax_dx: + check @dest.size = 2 + jno in_al_dx + emit 1, 0EDh + exit + in_al_dx: + emit 1, 0ECh + exit + in_ax_imm: + check @dest.size = 2 + jno in_al_imm + emit 1, 0E5h + emit 1, @src.imm + exit + in_al_imm: + emit 1, 0E4h + emit 1, @src.imm + exit +end calminstruction + +calminstruction out? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @dest.type = 'reg' & @dest.size = 2 & @dest.rm = 2 & @src.type = 'reg' & @src.rm = 0 + jyes out_dx_ax + check @dest.type = 'imm' & @src.type = 'reg' & @src.rm = 0 + jyes out_imm_ax + err 'invalid combination of operands' + exit + out_dx_ax: + check @src.size = 2 + jno out_dx_al + emit 1, 0EFh + exit + out_dx_al: + emit 1, 0EEh + exit + out_imm_ax: + check @src.size = 2 + jno out_imm_al + emit 1, 0E7h + emit 1, @dest.imm + exit + out_imm_al: + emit 1, 0E6h + emit 1, @dest.imm + exit +end calminstruction diff --git a/toolchain/fasmg.kl0e/examples/x86/include/8087.inc b/toolchain/fasmg.kl0e/examples/x86/include/8087.inc new file mode 100644 index 0000000..7d75514 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/8087.inc @@ -0,0 +1,555 @@ + +if ~ defined i8087 + + restore i8087 ; this ensures that symbol cannot be forward-referenced + i8087 = 1 + + define x87 x87 + + element st? + + repeat 8, i:0 + element st#i? : st? + i + end repeat + + define x86.qword? :8 + define x86.tword? :10 + define x86.tbyte? :10 + + iterate context, @dest,@src,@src2,@aux + + namespace context + + calminstruction x87.parse_operand#context operand + + local i + + match =st?(i), operand + jyes indexed_streg_operand + + call x86.parse_operand#context, operand + + check type = 'imm' & size = 0 + jno done + check imm eq 1 elementof imm & 1 metadataof imm relativeto st? + jyes streg_operand + check imm relativeto st? & imm = st? + jno done + + compute type, 'streg' + compute mod, 11b + compute rm, 0 + + exit + + streg_operand: + + compute type, 'streg' + compute mod, 11b + compute rm, 1 metadataof imm - st? + + exit + + indexed_streg_operand: + + compute size, 0 + compute type, 'streg' + compute mod, 11b + compute rm, +i + + done: + + end calminstruction + + end namespace + + end iterate + + iterate , fwait,9Bh, wait,9Bh, fnop,<0D9h,0D0h>, \ + fchs,<0D9h,0E0h>, fabs,<0D9h,0E1h>, ftst,<0D9h,0E4h>, fxam,<0D9h,0E5h>, fld1,<0D9h,0E8h>, \ + fldl2t,<0D9h,0E9h>, fldl2e,<0D9h,0EAh>, fldpi,<0D9h,0EBh>, fldlg2,<0D9h,0ECh>, fldln2,<0D9h,0EDh>, fldz,<0D9h,0EEh>, \ + f2xm1,<0D9h,0F0h>, fyl2x,<0D9h,0F1h>, fptan,<0D9h,0F2h>, fpatan,<0D9h,0F3h>, fxtract,<0D9h,0F4h>, fdecstp,<0D9h,0F6h>, fincstp,<0D9h,0F7h>, fprem,<0D9h,0F8h>, \ + fyl2xp1,<0D9h,0F9h>, fsqrt,<0D9h,0FAh>, frndint,<0D9h,0FCh>, fscale,<0D9h,0FDh>, \ + fneni,<0DBh,0E0h>, fndisi,<0DBh,0E1h>, fnclex,<0DBh,0E2h>, fninit,<0DBh,0E3h>, \ + fcompp,<0DEh,0D9h> + + calminstruction instr? + asm db opcode + end calminstruction + + end iterate + + iterate op, eni, disi, clex, init + calminstruction f#op? + asm fwait? + asm fn#op? + end calminstruction + end iterate + + iterate , fadd,0, fmul,1, fsub,4, fsubr,5, fdiv,6, fdivr,7 + + calminstruction instr? operand& + local dest, src + match dest=,src, operand + jyes st + call x87.parse_operand@dest, operand + check @dest.type = 'mem' + jno invalid_combination_of_operands + check @dest.size = 4 + jyes mem_dword + check @dest.size = 8 + jyes mem_qword + check @dest.size + jno unknown_size + err 'invalid operand size' + jump mem_dword + unknown_size: + err 'operand size not specified' + mem_dword: + xcall x86.store_instruction@dest, (0D8h),(postbyte) + exit + mem_qword: + xcall x86.store_instruction@dest, (0DCh),(postbyte) + exit + st: + call x87.parse_operand@dest, dest + call x87.parse_operand@src, src + check @dest.type = 'streg' & @src.type = 'streg' + jno invalid_combination_of_operands + check @dest.rm = 0 + jyes st0_sti + check @src.rm = 0 + jyes sti_st0 + jump invalid_combination_of_operands + st0_sti: + emit 1, 0D8h + emit 1, 11b shl 6 + postbyte shl 3 + @src.rm + exit + sti_st0: + check postbyte >= 4 + jyes switched + emit 1, 0DCh + emit 1, 11b shl 6 + postbyte shl 3 + @dest.rm + exit + switched: + emit 1, 0DCh + emit 1, 11b shl 6 + (postbyte xor 1) shl 3 + @dest.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + end calminstruction + + end iterate + + iterate , faddp,0, fmulp,1, fsubrp,4, fsubp,5, fdivrp,6, fdivp,7 + + calminstruction instr? operand& + local dest, src + match , operand + jyes default + match dest=,src, operand + jno invalid_combination_of_operands + call x87.parse_operand@dest, dest + call x87.parse_operand@src, src + check @dest.type = 'streg' & @src.type = 'streg' & @src.rm = 0 + jyes ok + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + default: + compute @dest.rm, 1 + ok: + emit 1, 0DEh + emit 1, 11b shl 6 + postbyte shl 3 + @dest.rm + end calminstruction + + end iterate + + iterate , fcom,2, fcomp,3 + + calminstruction instr? src:st1 + call x87.parse_operand@src, src + check @src.type = 'streg' + jyes st + check @src.type = 'mem' + jno invalid_operand + check @src.size = 4 + jyes mem_dword + check @src.size = 8 + jyes mem_qword + check @src.size + jno unknown_size + err 'invalid operand size' + jump mem_dword + unknown_size: + err 'operand size not specified' + mem_dword: st: + xcall x86.store_instruction@src, (0D8h),(postbyte) + exit + mem_qword: + xcall x86.store_instruction@src, (0DCh),(postbyte) + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + iterate , fiadd,0, fimul,1, ficom,2, ficomp,3, fisub,4, fisubr,5, fidiv,6, fidivr,7 + + calminstruction instr? src* + call x87.parse_operand@src, src + check @src.type = 'mem' + jno invalid_operand + check @src.size = 2 + jyes mem_word + check @src.size = 4 + jyes mem_dword + check @src.size + jno unknown_size + err 'invalid operand size' + jump mem_word + unknown_size: + err 'operand size not specified' + mem_word: + xcall x86.store_instruction@src, (0DEh),(postbyte) + exit + mem_dword: + xcall x86.store_instruction@src, (0DAh),(postbyte) + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + calminstruction fld? src* + call x87.parse_operand@src, src + check @src.type = 'streg' + jyes st + check @src.type = 'mem' + jno invalid_operand + check @src.size = 4 + jyes mem_dword + check @src.size = 8 + jyes mem_qword + check @src.size = 10 + jyes mem_tword + check @src.size + jno unknown_size + err 'invalid operand size' + jump mem_dword + unknown_size: + err 'operand size not specified' + mem_dword: st: + xcall x86.store_instruction@src, (0D9h),(0) + exit + mem_qword: + xcall x86.store_instruction@src, (0DDh),(0) + exit + mem_tword: + xcall x86.store_instruction@src, (0DBh),(5) + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + calminstruction fst? dest* + call x87.parse_operand@dest, dest + check @dest.type = 'streg' + jyes st + check @dest.type = 'mem' + jno invalid_operand + check @dest.size = 4 + jyes mem_dword + check @dest.size = 8 + jyes mem_qword + check @dest.size + jno unknown_size + err 'invalid operand size' + jump mem_dword + unknown_size: + err 'operand size not specified' + mem_dword: + xcall x86.store_instruction@dest, (0D9h),(2) + exit + mem_qword: st: + xcall x86.store_instruction@dest, (0DDh),(2) + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + calminstruction fstp? dest* + call x87.parse_operand@dest, dest + check @dest.type = 'streg' + jyes st + check @dest.type = 'mem' + jno invalid_operand + check @dest.size = 4 + jyes mem_dword + check @dest.size = 8 + jyes mem_qword + check @dest.size = 10 + jyes mem_tword + check @dest.size + jno unknown_size + err 'invalid operand size' + jump mem_dword + unknown_size: + err 'operand size not specified' + mem_dword: + xcall x86.store_instruction@dest, (0D9h),(3) + exit + mem_qword: st: + xcall x86.store_instruction@dest, (0DDh),(3) + exit + mem_tword: + xcall x86.store_instruction@dest, (0DBh),(7) + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + calminstruction fild? src* + call x87.parse_operand@src, src + check @src.type = 'mem' + jno invalid_operand + check @src.size = 2 + jyes mem_word + check @src.size = 4 + jyes mem_dword + check @src.size = 8 + jyes mem_qword + check @src.size + jno unknown_size + err 'invalid operand size' + jump mem_word + unknown_size: + err 'operand size not specified' + mem_word: + xcall x86.store_instruction@src, (0DFh),(0) + exit + mem_dword: + xcall x86.store_instruction@src, (0DBh),(0) + exit + mem_qword: + xcall x86.store_instruction@src, (0DFh),(5) + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + calminstruction fist? dest* + call x87.parse_operand@dest, dest + check @dest.type = 'mem' + jno invalid_operand + check @dest.size = 2 + jyes mem_word + check @dest.size = 4 + jyes mem_dword + check @dest.size + jno unknown_size + err 'invalid operand size' + jump mem_word + unknown_size: + err 'operand size not specified' + mem_word: + xcall x86.store_instruction@dest, (0DFh),(2) + exit + mem_dword: + xcall x86.store_instruction@dest, (0DBh),(2) + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + calminstruction fistp? dest* + call x87.parse_operand@dest, dest + check @dest.type = 'mem' + jno invalid_operand + check @dest.size = 2 + jyes mem_word + check @dest.size = 4 + jyes mem_dword + check @dest.size = 8 + jyes mem_qword + check @dest.size + jno unknown_size + err 'invalid operand size' + jump mem_word + unknown_size: + err 'operand size not specified' + mem_word: + xcall x86.store_instruction@dest, (0DFh),(3) + exit + mem_dword: + xcall x86.store_instruction@dest, (0DBh),(3) + exit + mem_qword: + xcall x86.store_instruction@dest, (0DFh),(7) + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + calminstruction fisttp? dest* + call x87.parse_operand@dest, dest + check @dest.type = 'mem' + jno invalid_operand + check @dest.size = 2 + jyes mem_word + check @dest.size = 4 + jyes mem_dword + check @dest.size = 8 + jyes mem_qword + check @dest.size + jno unknown_size + err 'invalid operand size' + jump mem_word + unknown_size: + err 'operand size not specified' + mem_word: + xcall x86.store_instruction@dest, (0DFh),(1) + exit + mem_dword: + xcall x86.store_instruction@dest, (0DBh),(1) + exit + mem_qword: + xcall x86.store_instruction@dest, (0DDh),(1) + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + iterate , fbld,4, fbstp,6 + + calminstruction instr? src* + call x87.parse_operand@src, src + check @src.type = 'mem' + jno invalid_operand + check @src.size and not 10 + jyes invalid_operand_size + xcall x86.store_instruction@src, (0DFh),(postbyte) + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + calminstruction fxch? src:st1 + call x87.parse_operand@src, src + check @src.type = 'streg' + jno invalid_operand + emit 1, 0D9h + emit 1, 11b shl 6 + 1 shl 3 + @src.rm + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + iterate , ffree,0DDh, ffreep,0DFh + + calminstruction instr? src* + call x87.parse_operand@src, src + check @src.type = 'streg' + jno invalid_operand + emit 1, basecode + emit 1, 11b shl 6 + @src.rm + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + calminstruction fnstsw? dest* + call x86.parse_operand@dest, dest + check @dest.size and not 2 + jyes invalid_operand_size + check @dest.type = 'mem' + jyes mem + check @dest.type = 'reg' & @dest.rm = 0 + jno invalid_operand + emit 1, 0DFh + emit 1, 0E0h + exit + mem: + xcall x86.store_instruction@dest, (0DDh),(7) + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + iterate , fldcw,5, fnstcw,7 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.size and not 2 + jyes invalid_operand_size + check @dest.type = 'mem' + jno invalid_operand + xcall x86.store_instruction@dest, (0D9h),(postbyte) + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + iterate , fldenv,4, fnstenv,6 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.size and not 14 + jyes invalid_operand_size + check @dest.type = 'mem' + jno invalid_operand + xcall x86.store_instruction@dest, (0D9h),(postbyte) + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + iterate , frstor,4, fnsave,6 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.size and not 94 + jyes invalid_operand_size + check @dest.type = 'mem' + jno invalid_operand + xcall x86.store_instruction@dest, (0DDh),(postbyte) + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_operand: + err 'invalid operand' + end calminstruction + + end iterate + + iterate op, stsw, stcw, stenv, save + calminstruction f#op? dest* + asm fwait? + asm fn#op? dest + end calminstruction + end iterate + +end if \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/adx.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/adx.inc new file mode 100644 index 0000000..2bf55b9 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/adx.inc @@ -0,0 +1,21 @@ + +iterate , adcx,66h, adox,0F3h + macro instr? dest*,src* + x86.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') + if @src.size <> 0 & @src.size <> @dest.size + err 'operand sizes do not match' + end if + if @dest.size = 8 & x86.mode = 64 + @src.prefix = 48h + else if @dest.size <> 4 + err 'invalid operand size' + end if + @src.opcode_prefix = pfx + x86.store_instruction@src <0Fh,38h,0F6h>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/aes.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/aes.inc new file mode 100644 index 0000000..048ca3c --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/aes.inc @@ -0,0 +1,43 @@ + +include 'sse.inc' + +iterate , aesdec,0DEh, aesenc,0DCh, aesimc,0DBh, aesdeclast,0DFh, aesenclast,0DDh + macro instr? dest*,src* + SSE.basic_instruction 66h,<38h,supp>,16,dest,src + end macro +end iterate + +iterate , aeskeygenassist,0DFh + macro instr? dest*,src*,imm* + SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm + end macro +end iterate + +if defined AVX + + iterate , aesenc,0DCh, aesenclast,0DDh, aesdec,0DEh, aesdeclast,0DFh + + macro v#instr? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F38_W0,opcode,16,dest,src,src2 + end macro + + end iterate + + iterate , aesimc,0DBh + + macro v#instr? dest*,src* + AVX.single_source_instruction VEX_66_0F38_W0,opcode,16,dest,src + end macro + + end iterate + + iterate , aeskeygenassist,0DFh + + macro v#instr? dest*,src*,imm* + AVX.single_source_instruction_imm8 VEX_66_0F3A_W0,opcode,16,dest,src,imm + end macro + + end iterate + +end if + diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx.inc new file mode 100644 index 0000000..50c2fbd --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx.inc @@ -0,0 +1,1266 @@ + +if ~ defined AVX + + restore AVX ; this ensures that symbol cannot be forward-referenced + AVX = 1 + + include 'sse4.2.inc' + include 'xsave.inc' + + element AVX.reg + + repeat 8, i:0 + element ymm#i? : AVX.reg + i + end repeat + + if defined xmm8 + repeat 8, i:8 + element ymm#i? : AVX.reg + i + end repeat + end if + + define x86.qqword? :32 + define x86.yword? :32 + + VEX_0F_W0 = 1 + VEX_66_0F_W0 = 1 + 1 shl 8 + VEX_F3_0F_W0 = 1 + 10b shl 8 + VEX_F2_0F_W0 = 1 + 11b shl 8 + + VEX_0F38_W0 = 10b + VEX_66_0F38_W0 = 10b + 1 shl 8 + VEX_F3_0F38_W0 = 10b + 10b shl 8 + VEX_F2_0F38_W0 = 10b + 11b shl 8 + + VEX_0F3A_W0 = 11b + VEX_66_0F3A_W0 = 11b + 1 shl 8 + VEX_F3_0F3A_W0 = 11b + 10b shl 8 + VEX_F2_0F3A_W0 = 11b + 11b shl 8 + + VEX_0F_W1 = VEX_0F_W0 or 8000h + VEX_66_0F_W1 = VEX_66_0F_W0 or 8000h + VEX_F3_0F_W1 = VEX_F3_0F_W0 or 8000h + VEX_F2_0F_W1 = VEX_F2_0F_W0 or 8000h + + VEX_0F38_W1 = VEX_0F38_W0 or 8000h + VEX_66_0F38_W1 = VEX_66_0F38_W0 or 8000h + VEX_F3_0F38_W1 = VEX_F3_0F38_W0 or 8000h + VEX_F2_0F38_W1 = VEX_F2_0F38_W0 or 8000h + + VEX_0F3A_W1 = VEX_0F3A_W0 or 8000h + VEX_66_0F3A_W1 = VEX_66_0F3A_W0 or 8000h + VEX_F3_0F3A_W1 = VEX_F3_0F3A_W0 or 8000h + VEX_F2_0F3A_W1 = VEX_F2_0F3A_W0 or 8000h + + iterate context, @dest,@src,@src2,@aux + + namespace context + + calminstruction AVX.parse_operand#context operand + + call x86.parse_operand#context, operand + + check type = 'reg' & size = 1 & rm >= 4 & (~ defined x86.REX_FORBIDDEN | rm and x86.REX_FORBIDDEN) + jyes invalid_operand + check type = 'imm' & size = 0 + jno done + + check imm eq 1 elementof imm & 1 metadataof imm relativeto SSE.reg + jyes xmm_register + check imm eq 1 elementof imm & 1 metadataof imm relativeto AVX.reg + jyes ymm_register + exit + + invalid_operand: + err 'invalid operand' + + xmm_register: + + compute rm, 1 metadataof imm - SSE.reg + compute size, 16 + + jump export_mmreg + + ymm_register: + + compute rm, 1 metadataof imm - AVX.reg + compute size, 32 + + export_mmreg: + + compute type, 'mmreg' + compute mod, 11b + + done: + + end calminstruction + + calminstruction AVX.store_instruction#context vsize*,vex_mpw*,opcode*,reg*,vreg:0,imm_size:0,immediate + + check segment_prefix + jno segment_prefix_ok + + check mode = 64 + jyes segment_in_long_mode + check mode = 16 & ( rm = 2 | rm = 3 | ( mod > 0 & rm = 6 ) ) + jyes ss_segment_default + check mode = 32 & ( ( mod > 0 & rm = 5 ) | ( rm = 4 & base = 4 ) | ( mod > 0 & rm = 4 & base = 5 ) ) + jyes ss_segment_default + + ds_segment_default: + check segment_prefix = 3Eh + jyes segment_prefix_ok + jump store_segment_prefix + ss_segment_default: + check segment_prefix = 36h + jyes segment_prefix_ok + jump store_segment_prefix + segment_in_long_mode: + check segment_prefix < 64h + jyes segment_prefix_ok + store_segment_prefix: + emit 1, segment_prefix + segment_prefix_ok: + + check mod <> 11b & mode <> x86.mode + jno addressing_prefix_ok + check mode = 64 | (mode = 16 & x86.mode = 64) + jno store_addressing_prefix + err 'illegal addressing mode' + store_addressing_prefix: + emit 1, 67h + addressing_prefix_ok: + + compute vex, vex_mpw + vex_L: + check vsize = 32 + jno vex_B + compute vex, vex or 1 shl 10 + vex_B: + check rm and 1000b | (mod <> 11b & mode > 16 & rm = 4 & base and 1000b) + jno vex_X + compute vex, vex or 1 shl 5 + vex_X: + check mod <> 11b & mode > 16 & rm = 4 & index and 1000b + jno vex_R + compute vex, vex or 1 shl 6 + vex_R: + check reg and 1000b + jno vex_vvvv + compute vex, vex or 1 shl 7 + vex_vvvv: + compute vex, vex or (vreg and 1111b) shl 11 + + check x86.mode < 64 & vex and 01000000_11100000b + jno allowed + err 'instruction requires long mode' + allowed: + + check vex and 10000000_01111111b <> 1 + jyes vex_3byte + vex_2byte: + emit 1, 0C5h + emit 1, ((vex and 10000000b) or ((vex shr 8) and 1111111b)) xor 11111000b + jump vex_done + vex_3byte: + emit 1, 0C4h + emit 1, (vex and 11111111b) xor 11100000b + emit 1, (vex shr 8) xor 01111000b + vex_done: + + emit 1, opcode + emit 1, mod shl 6 + (reg and 111b) shl 3 + rm and 111b + + check mod <> 11b & rm = 4 & mode <> 16 + jno sib_ok + emit 1, (bsf scale) shl 6 + (index and 111b) shl 3 + base and 111b + sib_ok: + + check displacement_size = 1 + jyes displacement_8bit + check displacement_size = 2 + jyes displacement_16bit + check displacement_size = 4 | displacement_size = 8 + jno displacement_ok + + compute displacement, displacement + + check auto_relative + jno auto_relative_ok + check imm_size < 8 + jyes adjust_auto_relative_displacement + compute displacement, displacement - ($ + 4 + 4) + jump auto_relative_ok + adjust_auto_relative_displacement: + compute displacement, displacement - ($ + 4 + imm_size) + auto_relative_ok: + + check mode = 64 & displacement relativeto 0 + jno displacement_ready + check displacement - 1 shl 64 >= -80000000h & displacement < 1 shl 64 + jyes adjust_displacement_wrap + check displacement >= -80000000h & displacement < 80000000h + jyes displacement_ready + err 'address value out of signed range' + adjust_displacement_wrap: + compute displacement, displacement - 1 shl 64 + displacement_ready: + + asm dd displacement + + jump displacement_ok + displacement_16bit: + asm dw displacement + jump displacement_ok + displacement_8bit: + emit 1, displacement + displacement_ok: + + check imm_size = 1 + jyes immediate_8bit + check imm_size = 2 + jyes immediate_16bit + check imm_size = 4 + jyes immediate_32bit + check imm_size = 8 + jno immediate_ok + call x86.simm32, immediate + jump immediate_ok + immediate_32bit: + compute imm, +immediate + asm dd imm + jump immediate_ok + immediate_16bit: + compute imm, +immediate + asm dw imm + jump immediate_ok + immediate_8bit: + compute imm, +immediate + emit 1, imm + immediate_ok: + + end calminstruction + + end namespace + + end iterate + + macro AVX.basic_instruction vex_mpw,opcode,msize,dest,src,src2 + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if msize & (@dest.size < msize | (@dest.size > msize & @dest.size <> 16) | (@src2.type = 'mem' & @src2.size and not msize)) + err 'invalid operand size' + else if @src.size <> @dest.size | (@src2.size and not @dest.size & (@src2.type = 'mmreg' | msize = 0)) + err 'operand sizes do not match' + end if + AVX.store_instruction@src2 @dest.size,vex_mpw,opcode,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX.basic_instruction_imm8 vex_mpw,opcode,msize,dest,src,src2,aux + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm' + if (msize & (@dest.size < msize | (@dest.size > msize & @dest.size <> 16) | (@src2.type = 'mem' & @src2.size and not msize))) | @aux.size and not 1 + err 'invalid operand size' + else if @src.size <> @dest.size | (@src2.size and not @dest.size & (@src2.type = 'mmreg' | msize = 0)) + err 'operand sizes do not match' + end if + AVX.store_instruction@src2 @dest.size,vex_mpw,opcode,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX.single_source_instruction vex_mpw,opcode,msize,dest,src + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if msize & (@dest.size < msize | (@dest.size > msize & @dest.size <> 16) | (@src.type = 'mem' & @src.size and not msize)) + err 'invalid operand size' + else if @src.size and not @dest.size & (@src.type = 'mmreg' | msize = 0) + err 'operand sizes do not match' + end if + AVX.store_instruction@src @dest.size,vex_mpw,opcode,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX.single_source_instruction_imm8 vex_mpw,opcode,msize,dest,src,aux + AVX.parse_operand@dest dest + AVX.parse_operand@src src + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm' + if (msize & (@dest.size < msize | (@dest.size > msize & @dest.size <> 16) | (@src.type = 'mem' & @src.size and not msize))) | @aux.size and not 1 + err 'invalid operand size' + else if @src.size and not @dest.size & (@src.type = 'mmreg' | msize = 0) + err 'operand sizes do not match' + end if + AVX.store_instruction@src @dest.size,vex_mpw,opcode,@dest.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + iterate , add,58h, mul,59h, sub,5Ch, min,5Dh, div,5Eh, max,5Fh + + macro v#instr#pd? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F_W0,opcode,0,dest,src,src2 + end macro + + macro v#instr#ps? dest*,src*,src2* + AVX.basic_instruction VEX_0F_W0,opcode,0,dest,src,src2 + end macro + + macro v#instr#sd? dest*,src*,src2* + AVX.basic_instruction VEX_F2_0F_W0,opcode,8,dest,src,src2 + end macro + + macro v#instr#ss? dest*,src*,src2* + AVX.basic_instruction VEX_F3_0F_W0,opcode,4,dest,src,src2 + end macro + + end iterate + + iterate , and,54h, andn,55h, or,56h, unpckh,15h, unpckl,14h, xor,57h + + macro v#instr#pd? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F_W0,opcode,0,dest,src,src2 + end macro + + macro v#instr#ps? dest*,src*,src2* + AVX.basic_instruction VEX_0F_W0,opcode,0,dest,src,src2 + end macro + + end iterate + + iterate , addsub,0D0h, hadd,7Ch, hsub,7Dh + + macro v#instr#pd? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F_W0,opcode,0,dest,src,src2 + end macro + + macro v#instr#ps? dest*,src*,src2* + AVX.basic_instruction VEX_F2_0F_W0,opcode,0,dest,src,src2 + end macro + + end iterate + + iterate , rsqrt,52h, rcp,53h + + macro v#instr#ps? dest*,src* + AVX.single_source_instruction VEX_0F_W0,opcode,0,dest,src + end macro + + macro v#instr#ss? dest*,src*,src2* + AVX.basic_instruction VEX_F3_0F_W0,opcode,4,dest,src,src2 + end macro + + end iterate + + macro vsqrtpd? dest*,src* + AVX.single_source_instruction VEX_66_0F_W0,51h,0,dest,src + end macro + + macro vsqrtps? dest*,src* + AVX.single_source_instruction VEX_0F_W0,51h,0,dest,src + end macro + + macro vsqrtsd? dest*,src*,src2* + AVX.basic_instruction VEX_F2_0F_W0,51h,8,dest,src,src2 + end macro + + macro vsqrtss? dest*,src*,src2* + AVX.basic_instruction VEX_F3_0F_W0,51h,4,dest,src,src2 + end macro + + macro vroundpd? dest*,src*,aux* + AVX.single_source_instruction_imm8 VEX_66_0F3A_W0,9,0,dest,src,aux + end macro + + macro vroundps? dest*,src*,aux* + AVX.single_source_instruction_imm8 VEX_66_0F3A_W0,8,0,dest,src,aux + end macro + + macro vroundsd? dest*,src*,src2*,aux* + AVX.basic_instruction_imm8 VEX_66_0F3A_W0,0Bh,8,dest,src,src2,aux + end macro + + macro vroundss? dest*,src*,src2*,aux* + AVX.basic_instruction_imm8 VEX_66_0F3A_W0,0Ah,4,dest,src,src2,aux + end macro + + macro vshufpd? dest*,src*,src2*,aux* + AVX.basic_instruction_imm8 VEX_66_0F_W0,0C6h,0,dest,src,src2,aux + end macro + + macro vshufps? dest*,src*,src2*,aux* + AVX.basic_instruction_imm8 VEX_0F_W0,0C6h,0,dest,src,src2,aux + end macro + + iterate , blendps,0Ch, blendpd,0Dh + + macro v#instr? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_66_0F3A_W0,opcode,0,dest,src,src2,imm + end macro + + end iterate + + iterate , blendvps,4Ah, blendvpd,4Bh + + macro v#instr? dest*,src*,src2*,mask* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + AVX.parse_operand@aux mask + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'mmreg' + if @src.size <> @dest.size | @src2.size and not @dest.size | @aux.size <> @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src2 @dest.size,VEX_66_0F3A_W0,opcode,@dest.rm,@src.rm,1,(@aux.rm and 1111b) shl 4 + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vbroadcastss? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mem' + if @src.size and not 4 + err 'invalid operand size' + end if + AVX.store_instruction@src @dest.size,VEX_66_0F38_W0,18h,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vbroadcastsd,19h,8, vbroadcastf128,1Ah,16 + + macro instr? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mem' + if @dest.size <> 32 | @src.size and not msize + err 'invalid operand size' + end if + AVX.store_instruction@src 32,VEX_66_0F38_W0,opcode,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vextractps? dest*,src*,aux* + x86.parse_operand@dest dest + AVX.parse_operand@src src + x86.parse_operand@aux aux + if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm' + if @dest.size and not 4 | @src.size <> 16 | @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@dest 16,VEX_66_0F3A_W0,17h,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro vinsertps? dest*,src*,src2*,aux* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mmreg' | @src2.type = 'mem') & @aux.type = 'imm' + if @dest.size <> 16 | @src.size <> 16 | (@src2.type = 'mmreg' & @src2.size <> 16) | (@src2.type = 'mem' & @src2.size and not 4) | @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@src2 16,VEX_66_0F3A_W0,21h,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro vextractf128? dest*,src*,aux* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + x86.parse_operand@aux aux + if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm' + if @dest.size and not 16 | @src.size <> 32 | @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@dest 32,VEX_66_0F3A_W0,19h,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro vinsertf128? dest*,src*,src2*,aux* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mmreg' | @src2.type = 'mem') & @aux.type = 'imm' + if @dest.size <> 32 | @src.size <> 32 | @src2.size and not 16 | @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@src2 32,VEX_66_0F3A_W0,18h,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + iterate , cmp,0C2h + + macro v#instr#pd? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_66_0F_W0,opcode,0,dest,src,src2,imm + end macro + + macro v#instr#ps? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_0F_W0,opcode,0,dest,src,src2,imm + end macro + + macro v#instr#sd? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_F2_0F_W0,opcode,8,dest,src,src2,imm + end macro + + macro v#instr#ss? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_F3_0F_W0,opcode,4,dest,src,src2,imm + end macro + + end iterate + + iterate , eq,0, lt,1, le,2, unord,3, neq,4, nlt,5, nle,6, ord,7, \ + eq_uq,8, nge,9, ngt,0Ah, false,0Bh, neq_qq,0Ch, ge,0Dh, gt,0Eh, true,0Fh, \ + eq_os,10h, lt_oq,11h, le_oq,12h, unord_s,13h, neq_us,14h, nlt_uq,15h, nle_uq,16h, ord_s,17h, \ + eq_us,18h, nge_uq,19h, ngt_uq,1Ah, false_os,1Bh, neq_os,1Ch, ge_oq,1Dh, gt_oq,1Eh, true_us,1Fh + + macro vcmp#cond#pd? dest*,src*,src2* + vcmppd dest,src,src2,code + end macro + + macro vcmp#cond#ps? dest*,src*,src2* + vcmpps dest,src,src2,code + end macro + + macro vcmp#cond#sd? dest*,src*,src2* + vcmpsd dest,src,src2,code + end macro + + macro vcmp#cond#ss? dest*,src*,src2* + vcmpss dest,src,src2,code + end macro + + end iterate + + iterate , vcomiss,VEX_0F_W0,2Fh,4, vcomisd,VEX_66_0F_W0,2Fh,8, vucomiss,VEX_0F_W0,2Eh,4, vucomisd,VEX_66_0F_W0,2Eh,8 + + macro instr? dest*,src* + AVX.single_source_instruction vex_mpw,opcode,msize,dest,src + end macro + + end iterate + + iterate , vcvtdq2pd,VEX_F3_0F_W0,0E6h, vcvtps2pd,VEX_0F_W0,5Ah + + macro instr? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if (@src.type = 'mem' & @src.size and not (@dest.size shr 1)) | (@src.type = 'mmreg' & @src.size <> 16) + err 'invalid operand size' + end if + AVX.store_instruction@src @dest.size,vex_mpw,opcode,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vcvtpd2dq,VEX_F2_0F_W0,0E6h, vcvttpd2dq,VEX_66_0F_W0,0E6h, vcvtpd2ps,VEX_66_0F_W0,5Ah + + macro instr? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @src.size = 0 + err ' operand size not specified' + else if @dest.size <> 16 | (@src.size <> 16 & @src.size <> 32) + err 'invalid operand size' + end if + AVX.store_instruction@src @dest.size,vex_mpw,opcode,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vcvtdq2ps? dest*,src* + AVX.single_source_instruction VEX_0F_W0,5Bh,0,dest,src + end macro + + macro vcvtps2dq? dest*,src* + AVX.single_source_instruction VEX_66_0F_W0,5Bh,0,dest,src + end macro + + macro vcvttps2dq? dest*,src* + AVX.single_source_instruction VEX_F3_0F_W0,5Bh,0,dest,src + end macro + + iterate , vcvtsd2si,VEX_F2_0F,2Dh,8, vcvttsd2si,VEX_F2_0F,2Ch,8, vcvtss2si,VEX_F3_0F,2Dh,4, vcvttss2si,VEX_F3_0F,2Ch,4 + + macro instr? dest*,src* + x86.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'mmreg') + if (@dest.size <> 4 & @dest.size <> 8) | (@src.type = 'mem' & @src.size and not msize) | (@src.type = 'mmreg' & @src.size <> 16) + err 'invalid operand size' + end if + if @dest.size = 8 + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@src 16,vex_mp#_W1,opcode,@dest.rm + else + AVX.store_instruction@src 16,vex_mp#_W0,opcode,@dest.rm + end if + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vcvtsd2ss? dest*,src*,src2* + AVX.basic_instruction VEX_F2_0F_W0,5Ah,8,dest,src,src2 + end macro + + macro vcvtss2sd? dest*,src*,src2* + AVX.basic_instruction VEX_F3_0F_W0,5Ah,4,dest,src,src2 + end macro + + iterate , vcvtsi2sd,VEX_F2_0F,2Ah, vcvtsi2ss,VEX_F3_0F,2Ah + + macro instr? dest*,src*,src2* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + x86.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'reg' | @src2.type = 'mem') + if @src.size = 0 + err ' operand size not specified' + else if @dest.size <> 16 | @src.size <> 16 | (@src2.size <> 4 & @src2.size <> 8) + err 'invalid operand size' + end if + if @src2.size = 8 + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@src2 16,vex_mp#_W1,opcode,@dest.rm,@src.rm + else + AVX.store_instruction@src2 16,vex_mp#_W0,opcode,@dest.rm,@src.rm + end if + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vdppd? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_66_0F3A_W0,41h,16,dest,src,src2,imm + end macro + + macro vdpps? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_66_0F3A_W0,40h,16,dest,src,src2,imm + end macro + + macro vlddqu? dest*,src* + AVX.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mem' + if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src @dest.size,VEX_F2_0F_W0,0F0h,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vldmxcsr,2, vstmxcsr,3 + + macro instr? src* + x86.parse_operand@src src + if @src.type = 'mem' + if @src.size and not 4 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,VEX_0F_W0,0AEh,postbyte + else + err 'invalid operand' + end if + end macro + + end iterate + + macro vmaskmovdqu? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mmreg' + if @dest.size <> 16 | @src.size <> 16 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,VEX_66_0F_W0,0F7h,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vmaskmovps,2Ch, vmaskmovpd,2Dh + + macro instr? dest*,src*,src2* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'mem' + if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src2 @dest.size,VEX_66_0F38_W0,opcode,@dest.rm,@src.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' & @src2.type = 'mmreg' + if @src.size <> @src2.size | @dest.size and not @src.size + err 'operand sizes do not match' + end if + AVX.store_instruction@dest @dest.size,VEX_66_0F38_W0,opcode+2,@src2.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vmovapd,VEX_66_0F_W0,28h,29h, vmovaps,VEX_0F_W0,28h,29h, vmovdqa,VEX_66_0F_W0,6Fh,7Fh, vmovdqu,VEX_F3_0F_W0,6Fh,7Fh, vmovupd,VEX_66_0F_W0,10h,11h, vmovups,VEX_0F_W0,10h,11h + + macro instr? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src @dest.size,vex_mpw,opcode_rm,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not @src.size + err 'operand sizes do not match' + end if + AVX.store_instruction@dest @src.size,vex_mpw,opcode_mr,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vmovd? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'reg' | @src.type = 'mem') + if @dest.size <> 16 | @src.size and not 4 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,VEX_66_0F_W0,6Eh,@dest.rm + else if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' + if @dest.size and not 4 | @src.size <> 16 + err 'operand sizes do not match' + end if + AVX.store_instruction@dest 16,VEX_66_0F_W0,7Eh,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro vmovq? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if @dest.size <> 16 | (@src.type = 'mmreg' & @src.size <> 16) | (@src.type = 'mem' and @src.size and not 8) + err 'invalid operand size' + end if + AVX.store_instruction@src 16,VEX_F3_0F_W0,7Eh,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not 8 | @src.size <> 16 + err 'invalid operand size' + end if + AVX.store_instruction@dest 16,VEX_66_0F_W0,0D6h,@src.rm + else if @dest.type = 'mmreg' & @src.type = 'reg' + if @dest.size <> 16 | @src.size <> 8 + err 'invalid operand size' + end if + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@src 16,VEX_66_0F_W1,6Eh,@dest.rm + else if @dest.type = 'reg' & @src.type = 'mmreg' + if @dest.size <> 8 | @src.size <> 16 + err 'invalid operand size' + end if + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@dest 16,VEX_66_0F_W1,7Eh,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro vmovddup? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if ((@src.type = 'mmreg' | @dest.size = 32) & @src.size and not @dest.size) | (@src.type = 'mem' & @dest.size = 16 & @src.size and not 8) + err 'operand sizes do not match' + end if + AVX.store_instruction@src @dest.size,VEX_F2_0F_W0,12h,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vmovhlps,12h, vmovlhps,16h + + macro instr? dest*,src*,src2* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'mmreg' + if @dest.size <> 16 + err 'invalid operand size' + else if @src.size <> @dest.size | @src2.size <> @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src2 16,VEX_0F_W0,opcode,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vmovhpd,VEX_66_0F_W0,16h, vmovhps,VEX_0F_W0,16h, vmovlpd,VEX_66_0F_W0,12h, vmovlps,VEX_0F_W0,12h + + macro instr? dest*,src*,src2 + AVX.parse_operand@dest dest + AVX.parse_operand@src src + match , src2 + if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not 8 | @src.size <> 16 + err 'invalid operand size' + end if + AVX.store_instruction@dest 16,vex_mpw,opcode+1,@src.rm + else + err 'invalid combination of operands' + end if + else + AVX.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'mem' + if @dest.size <> 16 | @src.size <> 16 | @src2.size and not 8 + err 'invalid operand size' + end if + AVX.store_instruction@src2 16,vex_mpw,opcode,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end match + end macro + + end iterate + + iterate , vmovmskpd,VEX_66_0F_W0, vmovmskps,VEX_0F_W0 + + macro instr? dest*,src* + x86.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'reg' & @src.type = 'mmreg' + if @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8) + err 'invalid operand size' + end if + AVX.store_instruction@src @src.size,vex_mpw,50h,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vmovntdq,VEX_66_0F_W0,0E7h, vmovntpd,VEX_66_0F_W0,2Bh, vmovntps,VEX_0F_W0,2Bh + + macro instr? dest*,src* + x86.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not @src.size + err 'operand sizes do not match' + end if + AVX.store_instruction@dest @src.size,vex_mpw,opcode,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vmovntdqa? dest*,src* + AVX.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mem' + if @dest.size <> 16 + err 'invalid operand size' + else if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src 16,VEX_66_0F38_W0,2Ah,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vmovsd,VEX_F2_0F_W0,8, vmovss,VEX_F3_0F_W0,4 + + macro instr? dest*,src*,src2 + AVX.parse_operand@dest dest + AVX.parse_operand@src src + match , src2 + if @dest.type = 'mmreg' & @src.type = 'mem' + if @dest.size <> 16 | @src.size and not msize + err 'invalid operand size' + end if + AVX.store_instruction@src 16,vex_mpw,10h,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not msize | @src.size <> 16 + err 'invalid operand size' + end if + AVX.store_instruction@dest 16,vex_mpw,11h,@src.rm + else + err 'invalid combination of operands' + end if + else + AVX.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'mmreg' + if @dest.size <> 16 | @src.size <> 16 | @src2.size <> 16 + err 'invalid operand size' + end if + AVX.store_instruction@src2 16,vex_mpw,10h,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end match + end macro + + end iterate + + macro vmovshdup? dest*,src* + AVX.single_source_instruction VEX_F3_0F_W0,16h,0,dest,src + end macro + + macro vmovsldup? dest*,src* + AVX.single_source_instruction VEX_F3_0F_W0,12h,0,dest,src + end macro + + macro vperm2f128? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_66_0F3A_W0,6,32,dest,src,src2,imm + end macro + + iterate , vpermilps,0Ch,4, vpermilpd,0Dh,5 + + macro instr? dest*,src*,src2* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src2 @dest.size,VEX_66_0F38_W0,opcode_rrm,@dest.rm,@src.rm + else if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @src2.type = 'imm' + if @src2.size and not 1 + err 'invalid operand size' + else if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src @dest.size,VEX_66_0F3A_W0,opcode_rri,@dest.rm,,1,@src2.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , packsswb,63h, packuswb,67h, packssdw,6Bh, paddb,0FCh, paddw,0FDh, paddd,0FEh, paddq,0D4h, paddsb,0ECh, paddsw,0EDh, paddusb,0DCh, paddusw,0DDh, \ + pand,0DBh, pandn,0DFh, pavgb,0E0h, pavgw,0E3h, pcmpeqb,74h, pcmpeqw,75h, pcmpeqd,76h, pcmpgtb,64h, pcmpgtw,65h, pcmpgtd,66h, \ + pmaddwd,0F5h, pmaxsw,0EEh, pmaxub,0DEh, pminsw,0EAh, pminub,0DAh, pmulhuw,0E4h, pmulhw,0E5h, pmullw,0D5h, pmuludq,0F4h, \ + por,0EBh, psadbw,0F6h, psubb,0F8h, psubw,0F9h, psubd,0FAh, psubq,0FBh, psubsb,0E8h, psubsw,0E9h, psubusb,0D8h, psubusw,0D9h, \ + punpckhbw,68h, punpckhwd,69h, punpckhdq,6Ah, punpckhqdq,6Dh, punpcklbw,60h, punpcklwd,61h, punpckldq,62h, punpcklqdq,6Ch, pxor,0EFh + + macro v#instr? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F_W0,opcode,16,dest,src,src2 + end macro + + end iterate + + iterate , packusdw,2Bh, pcmpeqq,29h, pcmpgtq,37h, phaddw,1, phaddd,2, phaddsw,3, phsubw,5, phsubd,6, phsubsw,7, pmaddubsw,4, \ + pmaxsb,3Ch, pmaxsd,3Dh, pmaxuw,3Eh, pmaxud,3Fh, pminsb,38h, pminsd,39h, pminuw,3Ah, pminud,3Bh, pmulhrsw,0Bh, pmulld,40h, pmuldq,28h, \ + pshufb,0, psignb,8, psignw,9, psignd,0Ah + + macro v#instr? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F38_W0,opcode,16,dest,src,src2 + end macro + + end iterate + + iterate , mpsadbw,42h, palignr,0Fh + + macro v#instr? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_66_0F3A_W0,opcode,16,dest,src,src2,imm + end macro + + end iterate + + iterate , pabsb,1Ch, pabsw,1Dh, pabsd,1Eh, pblendw,0Eh, phminposuw,41h + + macro v#instr? dest*,src* + AVX.single_source_instruction VEX_66_0F38_W0,opcode,16,dest,src + end macro + + end iterate + + iterate , pcmpestrm,60h, pcmpestri,61h, pcmpistrm,62h, pcmpistri,63h + + macro v#instr? dest*,src*,imm* + AVX.single_source_instruction_imm8 VEX_66_0F3A_W0,opcode,16,dest,src,imm + end macro + + end iterate + + iterate , pshufd,VEX_66_0F_W0, pshufhw,VEX_F3_0F_W0, pshuflw,VEX_F2_0F_W0 + + macro v#instr? dest*,src*,imm* + AVX.single_source_instruction_imm8 vex_mpw,70h,16,dest,src,imm + end macro + + end iterate + + macro vpblendvb? dest*,src*,src2*,mask* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + AVX.parse_operand@aux mask + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'mmreg' + if @dest.size <> 16 + err 'invalid operand size' + else if @src.size <> @dest.size | @src2.size and not @dest.size | @aux.size <> @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src2 16,VEX_66_0F3A_W0,4Ch,@dest.rm,@src.rm,1,(@aux.rm and 1111b) shl 4 + else + err 'invalid combination of operands' + end if + end macro + + iterate , vpextrb,14h,1, vpextrd,16h,4 + + macro instr? dest*,src*,aux* + x86.parse_operand@dest dest + AVX.parse_operand@src src + x86.parse_operand@aux aux + if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm' + if (@dest.type = 'reg' & @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | (@dest.type = 'mem' & @dest.size and not msize) | @src.size <> 16 | @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@dest 16,VEX_66_0F3A_W0,opcode,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vpextrw? dest*,src*,aux* + x86.parse_operand@dest dest + AVX.parse_operand@src src + x86.parse_operand@aux aux + if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm' + if @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8) | @src.size <> 16 | @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,VEX_66_0F_W0,0C5h,@dest.rm,,1,@aux.imm + else if @dest.type = 'mem' & @src.type = 'mmreg' & @aux.type = 'imm' + if @dest.size and not 2 | @src.size <> 16 | @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@dest 16,VEX_66_0F3A_W0,15h,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro vpextrq? dest*,src*,aux* + x86.parse_operand@dest dest + AVX.parse_operand@src src + x86.parse_operand@aux aux + if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm' + if @dest.size and not 8 | @src.size <> 16 | @aux.size and not 1 + err 'invalid operand size' + end if + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@dest 16,VEX_66_0F3A_W1,16h,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vpinsrb,VEX_66_0F3A_W0,20h,1, vpinsrw,VEX_66_0F_W0,0C4h,2, vpinsrd,VEX_66_0F3A_W0,22h,4 + + macro instr? dest*,src*,src2*,aux* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + x86.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'reg' | @src2.type = 'mem') & @aux.type = 'imm' + if @dest.size <> 16 | @src.size <> 16 | (@src2.type = 'reg' & @src2.size <> 4) | (@src2.type = 'mem' & @src2.size and not msize) | @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@src2 16,vex_mpw,opcode,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vpinsrq? dest*,src*,src2*,aux* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + x86.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'reg' | @src2.type = 'mem') & @aux.type = 'imm' + if @dest.size <> 16 | @src.size <> 16 | @src2.size and not 8 | @aux.size and not 1 + err 'invalid operand size' + end if + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@src2 16,VEX_66_0F3A_W1,22h,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro vpmovmskb? dest*,src* + x86.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'reg' & @src.type = 'mmreg' + if (@dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | @src.size <> 16 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,VEX_66_0F_W0,0D7h,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , pmovsxbw,20h,8, pmovsxbd,21h,4, pmovsxbq,22h,2, pmovsxwd,23h,8, pmovsxwq,24h,4, pmovsxdq,25h,8, \ + pmovzxbw,30h,8, pmovzxbd,31h,4, pmovzxbq,32h,2, pmovzxwd,33h,8, pmovzxwq,34h,4, pmovzxdq,35h,8 + + macro v#instr? dest*,src* + AVX.single_source_instruction VEX_66_0F38_W0,opcode,msize,dest,src + end macro + + end iterate + + iterate , pslldq,7, psrldq,3 + + macro v#instr dest*,src*,src2* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + x86.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'imm' + if @dest.size <> 16 | @src2.size and not 1 + err 'invalid operand size' + else if @src.size <> @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src 16,VEX_66_0F_W0,73h,postbyte,@dest.rm,1,@src2.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , psllw,0F1h,71h,6, pslld,0F2h,72h,6, psllq,0F3h,73h,6, psraw,0E1h,71h,4, psrad,0E2h,72h,4, psrlw,0D1h,71h,2, psrld,0D2h,72h,2, psrlq,0D3h,73h,2 + + macro v#instr? dest*,src*,src2* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @dest.size <> 16 | @src2.size and not 16 + err 'invalid operand size' + else if @src.size <> @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src2 16,VEX_66_0F_W0,opcode_rrm,@dest.rm,@src.rm + else if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'imm' + if @dest.size <> 16 | @src2.size and not 1 + err 'invalid operand size' + else if @src.size <> @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src 16,VEX_66_0F_W0,opcode,postbyte,@dest.rm,1,@src2.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vtestps,0Eh, vtestpd,0Fh, vptest,17h + + macro instr? dest*,src* + AVX.single_source_instruction VEX_66_0F38_W0,opcode,0,dest,src + end macro + + end iterate + + macro vzeroall? + db 0C5h,11111100b,77h + end macro + + macro vzeroupper? + db 0C5h,11111000b,77h + end macro + + macro xsaveopt? src* + x86.parse_operand@src src + if @src.type = 'mem' + x86.store_instruction@src <0Fh,0AEh>,6 + else + err 'invalid operand' + end if + end macro + +end if diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx2.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx2.inc new file mode 100644 index 0000000..3ce9c23 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx2.inc @@ -0,0 +1,502 @@ + +if ~ defined AVX2 + + restore AVX2 ; this ensures that symbol cannot be forward-referenced + AVX2 = 1 + + include 'avx.inc' + + iterate context, @dest,@src,@src2,@aux + + namespace context + + define visize + + calminstruction AVX.parse_vsib_operand#context operand + + local i, pre, suf + + compute segment_prefix, 0 + + compute size, 0 + compute displacement_size, 0 + + transform operand + + match pre suf, operand + jno no_size_prefix + transform pre, x86 + jno no_size_prefix + match :size, pre + jno no_size_prefix + arrange operand, suf + no_size_prefix: + + match [address], operand + jyes memory_operand + match =ptr? address, operand + jyes memory_operand + + jump invalid_operand + + memory_operand: + compute type, 'mem' + + match segment:address, address + jno segment_prefix_ok + check segment eq 1 elementof segment & 1 metadataof segment relativeto x86.sreg + jno invalid_operand + compute segment, 1 metadataof segment - x86.sreg + check segment >= 4 + jyes segment_prefix_386 + compute segment_prefix, 26h + segment shl 3 + jump segment_prefix_ok + segment_prefix_386: + compute segment_prefix, 64h + segment-4 + segment_prefix_ok: + + match pre suf, address + jno no_address_size_prefix + transform pre, x86 + jno no_address_size_prefix + match :pre, pre + jno no_address_size_prefix + arrange address, suf + check pre = 4 | pre = 8 + jno invalid_address_size + compute mode, pre shl 3 + no_address_size_prefix: + + compute mode, 0 + compute scale, 0 + compute index, 0 + compute base, 0 + compute auto_relative, 0 + + check size + jyes size_override + compute size, sizeof address + size_override: + + compute address, address + compute base_registers, 0 + compute index_registers, 0 + compute i, 1 + extract_registers: + check i > elementsof address + jyes registers_extracted + check i metadataof address relativeto SSE.reg | i metadataof address relativeto AVX.reg + jyes index_term + check i metadataof address relativeto x86.r32 | i metadataof address relativeto x86.r64 + jno next_term + compute base_registers, base_registers + i elementof address * i scaleof address + jump next_term + index_term: + compute index_registers, index_registers + i elementof address * i scaleof address + next_term: + compute i, i+1 + jump extract_registers + registers_extracted: + compute displacement, address - base_registers - index_registers + compute auto_relative, 0 + + check elementsof index_registers = 1 + jno invalid_address + compute scale, 1 scaleof index_registers + compute index, 0 scaleof (1 metadataof index_registers) + check scale and (scale-1) | scale > 8 + jyes invalid_address + check 1 metadataof index_registers relativeto SSE.reg + jyes xmm_index + compute visize, 32 + jump index_ok + xmm_index: + compute visize, 16 + index_ok: + + compute rm, 4 + check elementsof base_registers = 1 & 1 scaleof base_registers = 1 + jyes base_and_index + check elementsof base_registers = 0 + jno invalid_address + compute base, 5 + compute displacement_size, 4 + compute mod, 0 + compute mode, x86.mode + check mode > 16 + jyes ready + compute mode, 32 + jump ready + base_and_index: + compute base, 0 scaleof (1 metadataof base_registers) + check mode & mode <> 0 scaleof (1 metadataof (1 metadataof base_registers)) shl 3 + jyes invalid_address + compute mode, 0 scaleof (1 metadataof (1 metadataof base_registers)) shl 3 + + setup_displacement: + check displacement relativeto 0 + jno displacement_32bit + check displacement = 0 & rm and 111b <> 5 & (rm <> 4 | base and 111b <> 5) + jyes displacement_empty + check displacement < 80h & displacement >= -80h + jyes displacement_8bit + check displacement - 1 shl mode >= -80h & displacement < 1 shl mode + jyes displacement_8bit_wrap + displacement_32bit: + compute displacement_size, 4 + compute mod, 2 + jump ready + displacement_8bit_wrap: + compute displacement, displacement - 1 shl mode + displacement_8bit: + compute displacement_size, 1 + compute mod, 1 + jump ready + index_only: + compute displacement_size, 4 + compute mod, 0 + jump ready + displacement_empty: + compute displacement_size, 0 + compute mod, 0 + + ready: + + exit + + invalid_operand: + err 'invalid operand' + exit + invalid_address: + err 'invalid address' + exit + invalid_address_size: + err 'invalid address size' + exit + + end calminstruction + + end namespace + + end iterate + + iterate , vpgatherdd,90h,4, vpgatherqd,91h,8, vgatherdps,92h,4, vgatherqps,93h,8 + + macro instr? dest*,src*,mask* + AVX.parse_operand@dest dest + AVX.parse_vsib_operand@src src + AVX.parse_operand@aux mask + if @dest.type = 'mmreg' & @src.type = 'mem' & @aux.type = 'mmreg' + if @src.size and not 4 | (@dest.size > 16 & @dest.size * (asize shr 2) > @src.visize) | (@src.visize > 16 & @dest.size * (asize shr 2) < @src.visize) + err 'invalid operand size' + else if @aux.size <> @dest.size + err 'operand sizes do not match' + else if @dest.rm = @aux.rm | @dest.rm = @src.index | @aux.rm = @src.index + err 'disallowed combination of registers' + end if + AVX.store_instruction@src @src.visize,VEX_66_0F38_W0,opcode,@dest.rm,@aux.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vpgatherdq,90h,4, vpgatherqq,91h,8, vgatherdpd,92h,4, vgatherqpd,93h,8 + + macro instr? dest*,src*,mask* + AVX.parse_operand@dest dest + AVX.parse_vsib_operand@src src + AVX.parse_operand@aux mask + if @dest.type = 'mmreg' & @src.type = 'mem' & @aux.type = 'mmreg' + if @src.size and not 8 | (@dest.size > 16 & @dest.size * (asize shr 2) > @src.visize * 2) | (@src.visize > 16 & @dest.size * (asize shr 2) < @src.visize * 2) + err 'invalid operand size' + else if @aux.size <> @dest.size + err 'operand sizes do not match' + else if @dest.rm = @aux.rm | @dest.rm = @src.index | @aux.rm = @src.index + err 'disallowed combination of registers' + end if + AVX.store_instruction@src @dest.size,VEX_66_0F38_W1,opcode,@dest.rm,@aux.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , packsswb,63h, packuswb,67h, packssdw,6Bh, paddb,0FCh, paddw,0FDh, paddd,0FEh, paddq,0D4h, paddsb,0ECh, paddsw,0EDh, paddusb,0DCh, paddusw,0DDh, \ + pand,0DBh, pandn,0DFh, pavgb,0E0h, pavgw,0E3h, pcmpeqb,74h, pcmpeqw,75h, pcmpeqd,76h, pcmpgtb,64h, pcmpgtw,65h, pcmpgtd,66h, \ + pmaddwd,0F5h, pmaxsw,0EEh, pmaxub,0DEh, pminsw,0EAh, pminub,0DAh, pmulhuw,0E4h, pmulhw,0E5h, pmullw,0D5h, pmuludq,0F4h, \ + por,0EBh, psadbw,0F6h, psubb,0F8h, psubw,0F9h, psubd,0FAh, psubq,0FBh, psubsb,0E8h, psubsw,0E9h, psubusb,0D8h, psubusw,0D9h, \ + punpckhbw,68h, punpckhwd,69h, punpckhdq,6Ah, punpckhqdq,6Dh, punpcklbw,60h, punpcklwd,61h, punpckldq,62h, punpcklqdq,6Ch, pxor,0EFh + + macro v#instr? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F_W0,opcode,0,dest,src,src2 + end macro + + end iterate + + iterate , packusdw,2Bh, pcmpeqq,29h, pcmpgtq,37h, phaddw,1, phaddd,2, phaddsw,3, phsubw,5, phsubd,6, phsubsw,7, pmaddubsw,4, \ + pmaxsb,3Ch, pmaxsd,3Dh, pmaxuw,3Eh, pmaxud,3Fh, pminsb,38h, pminsd,39h, pminuw,3Ah, pminud,3Bh, pmulhrsw,0Bh, pmulld,40h, pmuldq,28h, \ + pshufb,0, psignb,8, psignw,9, psignd,0Ah + + macro v#instr? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F38_W0,opcode,0,dest,src,src2 + end macro + + end iterate + + iterate , mpsadbw,42h, palignr,0Fh, pblendd,02h + + macro v#instr? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_66_0F3A_W0,opcode,0,dest,src,src2,imm + end macro + + end iterate + + iterate , pabsb,1Ch, pabsw,1Dh, pabsd,1Eh, pblendw,0Eh + + macro v#instr? dest*,src* + AVX.single_source_instruction VEX_66_0F38_W0,opcode,0,dest,src + end macro + + end iterate + + iterate , pshufd,VEX_66_0F_W0, pshufhw,VEX_F3_0F_W0, pshuflw,VEX_F2_0F_W0 + + macro v#instr? dest*,src*,imm* + AVX.single_source_instruction_imm8 vex_mpw,70h,0,dest,src,imm + end macro + + end iterate + + iterate , vpsllvd,VEX_66_0F38_W0,47h, vpsllvq,VEX_66_0F38_W1,47h, vpsrlvd,VEX_66_0F38_W0,45h, vpsrlvq,VEX_66_0F38_W1,45h, vpsravd,VEX_66_0F38_W0,46h + + macro instr? dest*,src*,src2* + AVX.basic_instruction vex_mpw,opcode,0,dest,src,src2 + end macro + + end iterate + + macro vpblendvb? dest*,src*,src2*,mask* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + AVX.parse_operand@aux mask + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'mmreg' + if @src.size <> @dest.size | @src2.size and not @dest.size | @aux.size <> @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src2 @dest.size,VEX_66_0F3A_W0,4Ch,@dest.rm,@src.rm,1,(@aux.rm and 1111b) shl 4 + else + err 'invalid combination of operands' + end if + end macro + + macro vpmovmskb? dest*,src* + x86.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'reg' & @src.type = 'mmreg' + if (@dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) + err 'invalid operand size' + end if + AVX.store_instruction@src @src.size,VEX_66_0F_W0,0D7h,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , pmovsxbw,20h,8, pmovsxbd,21h,4, pmovsxbq,22h,2, pmovsxwd,23h,8, pmovsxwq,24h,4, pmovsxdq,25h,8, \ + pmovzxbw,30h,8, pmovzxbd,31h,4, pmovzxbq,32h,2, pmovzxwd,33h,8, pmovzxwq,34h,4, pmovzxdq,35h,8 + + macro v#instr? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if (@src.type = 'mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not (msize * (@dest.size shr 4))) + err 'invalid operand size' + end if + AVX.store_instruction@src @dest.size,VEX_66_0F38_W0,opcode,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , pslldq,7, psrldq,3 + + macro v#instr dest*,src*,src2* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + x86.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'imm' + if @src2.size and not 1 + err 'invalid operand size' + else if @src.size <> @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src @dest.size,VEX_66_0F_W0,73h,postbyte,@dest.rm,1,@src2.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , psllw,0F1h,71h,6, pslld,0F2h,72h,6, psllq,0F3h,73h,6, psraw,0E1h,71h,4, psrad,0E2h,72h,4, psrlw,0D1h,71h,2, psrld,0D2h,72h,2, psrlq,0D3h,73h,2 + + macro v#instr? dest*,src*,src2* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src2.size and not 16 + err 'invalid operand size' + else if @src.size <> @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src2 @dest.size,VEX_66_0F_W0,opcode_rrm,@dest.rm,@src.rm + else if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'imm' + if @src2.size and not 1 + err 'invalid operand size' + else if @src.size <> @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src @dest.size,VEX_66_0F_W0,opcode,postbyte,@dest.rm,1,@src2.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vmovntdqa? dest*,src* + AVX.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mem' + if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src @dest.size,VEX_66_0F38_W0,2Ah,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vpmaskmovd,0, vpmaskmovq,1 + + macro instr? dest*,src*,src2* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'mem' + if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX.store_instruction@src2 @dest.size,VEX_66_0F38_W#w,8Ch,@dest.rm,@src.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' & @src2.type = 'mmreg' + if @src.size <> @src2.size | @dest.size and not @src.size + err 'operand sizes do not match' + end if + AVX.store_instruction@dest @src.size,VEX_66_0F38_W#w,8Eh,@src2.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vbroadcasti128? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mem' + if @dest.size <> 32 | @src.size and not 16 + err 'invalid operand size' + end if + AVX.store_instruction@src 32,VEX_66_0F38_W0,5Ah,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro vextracti128? dest*,src*,aux* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + x86.parse_operand@aux aux + if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm' + if @dest.size and not 16 | @src.size <> 32 | @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@dest 32,VEX_66_0F3A_W0,39h,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro vinserti128? dest*,src*,src2*,aux* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + AVX.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mmreg' | @src2.type = 'mem') & @aux.type = 'imm' + if @dest.size <> 32 | @src.size <> 32 | @src2.size and not 16 | @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@src2 32,VEX_66_0F3A_W0,38h,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro vperm2i128? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_66_0F3A_W0,46h,32,dest,src,src2,imm + end macro + + iterate , vbroadcastss,18h,4, vpbroadcastb,78h,1, vpbroadcastw,79h,2, vpbroadcastd,58h,4, vpbroadcastq,59h,8 + + macro instr? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if (@src.type='mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not msize) + err 'invalid operand size' + end if + AVX.store_instruction@src @dest.size,VEX_66_0F38_W0,opcode,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vbroadcastsd? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if @dest.size <> 32 | (@src.type='mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not 8) + err 'invalid operand size' + end if + AVX.store_instruction@src 32,VEX_66_0F38_W0,19h,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vpermq,0, vpermpd,1 + + macro instr? dest*,src*,imm* + AVX.single_source_instruction_imm8 VEX_66_0F3A_W1,opcode,32,dest,src,imm + end macro + + end iterate + + iterate , vpermd,36h, vpermps,16h + + macro instr? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F38_W0,opcode,32,dest,src,src2 + end macro + + end iterate + +end if diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512.inc new file mode 100644 index 0000000..a2586ce --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512.inc @@ -0,0 +1,10 @@ + +include 'avx512f.inc' +include 'avx512cd.inc' + +include 'avx512vl.inc' +include 'avx512bw.inc' +include 'avx512dq.inc' + +include 'avx512_ifma.inc' +include 'avx512_vbmi.inc' diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_4vnniw.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_4vnniw.inc new file mode 100644 index 0000000..6ae5825 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_4vnniw.inc @@ -0,0 +1,31 @@ + +if ~ defined AVX_512 + + include 'avx512f.inc' + +end if + +iterate , vp4dpwssd,52h, vp4dpwssds,53h + + macro instr? dest*,src*,src2* + AVX_512.parse_k1z_operand@dest dest + match rsrc+=3, src + AVX_512.parse_operand@src rsrc + else + AVX_512.parse_operand@src src + end match + AVX_512.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'mem' + if @dest.size <> 64 | @src2.size and not 16 + err 'invalid operand size' + else if @dest.size <> @src.size + err 'operand sizes do not match' + end if + @src2.memsize = 0 + AVX_512.store_instruction@src2 @dest.size,VEX_F2_0F38_W0,EVEX_REQUIRED,opcode,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_bitalg.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_bitalg.inc new file mode 100644 index 0000000..b78d5d8 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_bitalg.inc @@ -0,0 +1,29 @@ + +if ~ defined AVX_512 + + include 'avx512f.inc' + +end if + +iterate , vpopcntb,VEX_66_0F38_W0,54h, vpopcntw,VEX_66_0F38_W1,54h + + + macro instr? dest*,src* + AVX_512.single_source_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src + end macro + +end iterate + +macro vpshufbitqmb? dest*,src*,src2* + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src2.size and not @src.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @src.size,VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,8Fh,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_ifma.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_ifma.inc new file mode 100644 index 0000000..637c8a8 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_ifma.inc @@ -0,0 +1,15 @@ + +if ~ defined AVX_512 + + include 'avx512f.inc' + +end if + +iterate , vpmadd52luq,0B4h, vpmadd52huq,0B5h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2 + end macro + +end iterate + diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vbmi.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vbmi.inc new file mode 100644 index 0000000..8600257 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vbmi.inc @@ -0,0 +1,22 @@ + +if ~ defined AVX_512 + + include 'avx512f.inc' + +end if + +iterate , vpermb,VEX_66_0F38_W0,8Dh, vpermi2b,VEX_66_0F38_W0,75h, vpermt2b,VEX_66_0F38_W0,7Dh + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2 + end macro + +end iterate + +iterate , vpmultishiftqb,83h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2 + end macro + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vbmi2.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vbmi2.inc new file mode 100644 index 0000000..3620a56 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vbmi2.inc @@ -0,0 +1,65 @@ + +if ~ defined AVX_512 + + include 'avx512f.inc' + +end if + +iterate , vpshldw,VEX_66_0F3A_W1,70h, vpshrdw,VEX_66_0F3A_W1,72h + + macro instr? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_imm8 vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2,aux + end macro + +end iterate + +iterate , vpshldd,4,VEX_66_0F3A_W0,71h, vpshldq,8,VEX_66_0F3A_W1,71h, \ + vpshrdd,4,VEX_66_0F3A_W0,73h, vpshrdq,8,VEX_66_0F3A_W1,73h + + macro instr? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_bcst_imm8 vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src,src2,aux + end macro + +end iterate + +iterate , vpshldvw,VEX_66_0F38_W1,70h, vpshrdvw,VEX_66_0F38_W1,72h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2 + end macro + +end iterate + +iterate , vpshldvd,4,VEX_66_0F38_W0,71h, vpshldvq,8,VEX_66_0F38_W1,71h, \ + vpshrdvd,4,VEX_66_0F38_W0,73h, vpshrdvq,8,VEX_66_0F38_W1,73h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src,src2 + end macro + +end iterate + +iterate , vpcompressb,VEX_66_0F38_W0,63h, vpcompressw,VEX_66_0F38_W1,63h + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' + if @dest.size and not @src.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@dest @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vpexpandb,VEX_66_0F38_W0,62h, vpexpandw,VEX_66_0F38_W1,62h + + macro instr? dest*,src* + AVX_512.single_source_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src + end macro + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vnni.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vnni.inc new file mode 100644 index 0000000..bf9c0d6 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vnni.inc @@ -0,0 +1,14 @@ + +if ~ defined AVX_512 + + include 'avx512f.inc' + +end if + +iterate , vpdpbusd,50h, vpdpbusds,51h, vpdpwssd,52h, vpdpwssds,53h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,4,dest,src,src2 + end macro + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vpopcntdq.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vpopcntdq.inc new file mode 100644 index 0000000..6491f0e --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vpopcntdq.inc @@ -0,0 +1,16 @@ + +if ~ defined AVX_512 + + include 'avx512f.inc' + +end if + +iterate , vpopcntd,4,VEX_66_0F38_W0,55h, vpopcntq,8,VEX_66_0F38_W1,55h + + + macro instr? dest*,src* + AVX_512.single_source_instruction_bcst vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src + end macro + +end iterate + diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512bw.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512bw.inc new file mode 100644 index 0000000..43617a0 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512bw.inc @@ -0,0 +1,494 @@ + + +if ~ defined AVX_512 + + include 'avx512f.inc' + +end if + +iterate , d,VEX_66_0F_W1,4, q,VEX_0F_W1,8 + + iterate , kand,41h, kandn,42h, knot,44h, kor,45h, kxnor,46h, kxor,47h, kadd,4Ah + + macro instr#t? dest*,src*,src2* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + if @dest.type = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg' + AVX.store_instruction@src2 32,vex_mpw,opcode,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , knot,44h, kortest,98h, ktest,99h + + macro instr#t? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'maskreg' & @src.type = 'maskreg' + AVX.store_instruction@src 16,vex_mpw,opcode,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro kmov#t? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'maskreg' & (@src.type = 'maskreg' | @src.type = 'mem') + if @src.type = 'mem' & @src.size and not msize + err 'invalid operand size' + end if + AVX.store_instruction@src 16,vex_mpw,90h,@dest.rm + else if @dest.type = 'mem' & @src.type = 'maskreg' + if @dest.size and not msize + err 'invalid operand size' + end if + AVX.store_instruction@dest 16,vex_mpw,91h,@src.rm + else if @dest.type = 'maskreg' & @src.type = 'reg' + if (msize < 8 & @src.size <> 4) | (msize = 8 & @src.size <> 8) + err 'invalid operand size' + else if msize = 8 & x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@src 16,vex_mpw,92h,@dest.rm + else if @dest.type = 'reg' & @src.type = 'maskreg' + if (msize < 8 & @dest.size <> 4) | (msize = 8 & @dest.size <> 8) + err 'invalid operand size' + else if msize = 8 & x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@src 16,vex_mpw,93h,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , kshiftrd,VEX_66_0F3A_W0,31h, kshiftrq,VEX_66_0F3A_W1,31h, \ + kshiftld,VEX_66_0F3A_W0,33h, kshiftlq,VEX_66_0F3A_W1,33h + + macro instr? dest*,src*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if @dest.type = 'maskreg' & @src.type = 'maskreg' & @aux.type = 'imm' + if @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,vex_mpw,opcode,@dest.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , kunpckwd,VEX_0F_W0, kunpckdq,VEX_0F_W1 + + macro instr? dest*,src*,src2* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + if @dest.type = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg' + AVX.store_instruction@src2 32,vex_mpw,4Bh,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vmovdqu8,VEX_F2_0F_W0,EVEX_REQUIRED+EVEX_VL,6Fh,7Fh, vmovdqu16,VEX_F2_0F_W1,EVEX_REQUIRED+EVEX_VL,6Fh,7Fh + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src @dest.size,vex_mpw,evex_f,opcode_rm,@dest.mask,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not @src.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@dest @src.size,vex_mpw,evex_f,opcode_mr,@dest.mask,@src.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vpabsb,1Ch, vpabsw,1Dh + + macro instr? dest*,src* + AVX_512.single_source_instruction VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src + end macro + +end iterate + +iterate , vpacksswb,63h, vpackuswb,67h, vpaddb,0FCh, vpaddw,0FDh, vpaddsb,0ECh, vpaddsw,0EDh, vpaddusb,0DCh, vpaddusw,0DDh, vpavgb,0E0h, vpavgw,0E3h, \ + vpmaddwd,0F5h, vpmaxsw,0EEh, vpmaxub,0DEh, vpminsw,0EAh, vpminub,0DAh, vpmulhuw,0E4h, vpmulhw,0E5h, vpmullw,0D5h, \ + vpsadbw,0F6h, vpsubb,0F8h, vpsubw,0F9h, vpsubsb,0E8h, vpsubsw,0E9h, vpsubusb,0D8h, vpsubusw,0D9h, \ + vpunpckhbw,68h, vpunpckhwd,69h, vpunpcklbw,60h, vpunpcklwd,61h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src,src2 + end macro + +end iterate + +iterate , vpackssdw,6Bh + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2 + end macro + +end iterate + +iterate , vpackusdw,2Bh + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2 + end macro + +end iterate + +iterate , vpalignr,0Fh + + macro instr? dest*,src*,src2*,imm* + AVX_512.basic_instruction_imm8 VEX_66_0F3A_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src,src2,imm + end macro + +end iterate + +iterate , vpmaddubsw,4, vpmaxsb,3Ch, vpmaxuw,3Eh, vpminsb,38h, vpminuw,3Ah, vpmulhrsw,0Bh, vpshufb,0 + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src,src2 + end macro + +end iterate + +iterate , vpcmpeqb,74h, vpcmpeqw,75h, vpcmpgtb,64h, vpcmpgtw,65h + + macro instr? dest*,src*,src2* + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src2.size and not @src.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @src.size,VEX_66_0F_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm + else if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @src.size,VEX_66_0F_W0,EVEX_FORBIDDEN,opcode,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +macro vpextrb? dest*,src*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm' + if (@dest.type = 'reg' & @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | (@dest.type = 'mem' & @dest.size and not 1) | @src.size <> 16 | @aux.size and not 1 + err 'invalid operand size' + end if + @dest.memsize = 1 + AVX_512.store_instruction@dest 16,VEX_66_0F3A_W0,EVEX_AS_VEX,14h,0,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +macro vpextrw? dest*,src*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm' + if @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8) | @src.size <> 16 | @aux.size and not 1 + err 'invalid operand size' + end if + AVX_512.store_instruction@src 16,VEX_66_0F_W0,EVEX_AS_VEX,0C5h,0,@dest.rm,,1,@aux.imm + else if @dest.type = 'mem' & @src.type = 'mmreg' & @aux.type = 'imm' + if @dest.size and not 2 | @src.size <> 16 | @aux.size and not 1 + err 'invalid operand size' + end if + @dest.memsize = 2 + AVX_512.store_instruction@dest 16,VEX_66_0F3A_W0,EVEX_AS_VEX,15h,0,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +iterate , vpinsrb,VEX_66_0F3A_W0,20h,1, vpinsrw,VEX_66_0F_W0,0C4h,2 + + macro instr? dest*,src*,src2*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'reg' | @src2.type = 'mem') & @aux.type = 'imm' + if @dest.size <> 16 | @src.size <> 16 | (@src2.type = 'reg' & @src2.size <> 4) | (@src2.type = 'mem' & @src2.size and not msize) | @aux.size and not 1 + err 'invalid operand size' + end if + @src2.memsize = msize + AVX_512.store_instruction@src2 16,vex_mpw,EVEX_AS_VEX,opcode,0,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vpmovsxbw,20h,8, vpmovzxbw,30h,8 + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + @src.memsize = msize * (@dest.size shr 4) + if (@src.type = 'mmreg' & @src.size <> (@src.memsize-1) and not 15 + 16) | (@src.type = 'mem' & @src.size and not @src.memsize) + err 'invalid operand size' + end if + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vpshufhw,VEX_F3_0F_W0, vpshuflw,VEX_F2_0F_W0 + + macro instr? dest*,src*,aux* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm' + if @aux.size and not 1 + err 'invalid operand size' + else if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_AS_VEX+EVEX_VL,70h,@dest.mask,@dest.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vpslldq,7, vpsrldq,3 + + macro instr? dest*,src*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') & @aux.type = 'imm' + if @aux.size and not 1 + err 'invalid operand size' + else if @src.size <> @dest.size + err 'operand sizes do not match' + end if + if @src.type = 'mem' + AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_REQUIRED+EVEX_VL,73h,0,postbyte,@dest.rm,1,@aux.imm + else + AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,73h,0,postbyte,@dest.rm,1,@aux.imm + end if + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vpsllw,0F1h,71h,6, vpsraw,0E1h,71h,4, vpsrlw,0D1h,71h,2 + + macro instr? dest*,src*,src2* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + @src2.memsize = 16 + if @src2.size and not @src2.memsize + err 'invalid operand size' + else if @src.size <> @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @dest.size,VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode_rrm,@dest.mask,@dest.rm,@src.rm + else if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') & @src2.type = 'imm' + if @src2.size and not 1 + err 'invalid operand size' + else if @src.size <> @dest.size + err 'operand sizes do not match' + end if + if @src.type = 'mem' + AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,postbyte,@dest.rm,1,@src2.imm + else + AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,@dest.mask,postbyte,@dest.rm,1,@src2.imm + end if + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vdbpsadbw,VEX_66_0F3A_W0,42h + + macro instr? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_imm8 vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2,aux + end macro + +end iterate + +iterate , vpblendmb,VEX_66_0F38_W0,66h, vpblendmw,VEX_66_0F38_W1,66h + + macro instr? dest*,src*,src2*& + AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2 + end macro + +end iterate + +iterate , vpbroadcastb,78h,7Ah,1, vpbroadcastw,79h,7Bh,2 + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if (@src.type='mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not msize) + err 'invalid operand size' + end if + @src.memsize = msize + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,@dest.mask,@dest.rm + else if @dest.type = 'mmreg' & @src.type = 'reg' + if @src.size <> msize & (@src.size <> 4 | msize = 8) + err 'invalid operand size' + end if + @src.memsize = msize + if msize = 8 + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode_g,@dest.mask,@dest.rm + else + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode_g,@dest.mask,@dest.rm + end if + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vpcmpb,VEX_66_0F3A_W0,3Fh, vpcmpub,VEX_66_0F3A_W0,3Eh, vpcmpw,VEX_66_0F3A_W1,3Fh, vpcmpuw,VEX_66_0F3A_W1,3Eh + + macro instr? dest*,src*,src2*,aux* + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm' + if @src2.size and not @src.size | @aux.size and not 1 + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vpermw,VEX_66_0F38_W1,8Dh, vpermi2w,VEX_66_0F38_W1,75h, vpermt2w,VEX_66_0F38_W1,7Dh + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2 + end macro + +end iterate + +iterate , vpmovb2m,VEX_F3_0F38_W0,29h, vpmovw2m,VEX_F3_0F38_W1,29h + + macro instr? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'maskreg' & @src.type = 'mmreg' + AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vpmovm2b,VEX_F3_0F38_W0,28h, vpmovm2w,VEX_F3_0F38_W1,28h + + macro instr? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'maskreg' + AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vpmovuswb,2,10h, vpmovswb,2,20h, vpmovwb,2,30h + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' + @dest.memsize = @src.size / ratio + if (@dest.type = 'mmreg' & @dest.size <> (@dest.memsize-1) and not 15 + 16) | (@dest.type = 'mem' & @dest.size and not @dest.memsize) + err 'invalid operand size' + end if + AVX_512.store_instruction@dest @src.size,VEX_F3_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vpsllvw,12h, vpsrlvw,10h, vpsravw,11h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src,src2 + end macro + +end iterate + +iterate , vptestnmb,VEX_F3_0F38_W0,26h, vptestnmw,VEX_F3_0F38_W1,26h, vptestmb,VEX_66_0F38_W0,26h, vptestmw,VEX_66_0F38_W1,26h + + macro instr? dest*,src*,src2* + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src2.size and not @src.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512cd.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512cd.inc new file mode 100644 index 0000000..c7b9376 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512cd.inc @@ -0,0 +1,29 @@ + +if ~ defined AVX_512 + + include 'avx512f.inc' + +end if + +iterate , vpbroadcastmb2q,VEX_F3_0F38_W1,2Ah, vpbroadcastmw2d,VEX_F3_0F38_W0,3Ah + + macro instr? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'maskreg' + AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vpconflictd,4,VEX_66_0F38_W0,0C4h, vpconflictq,8,VEX_66_0F38_W1,0C4h, vplzcntd,4,VEX_66_0F38_W0,44h, vplzcntq,8,VEX_66_0F38_W1,44h + + macro instr? dest*,src*& + AVX_512.single_source_instruction_bcst vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src + end macro + +end iterate + diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512dq.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512dq.inc new file mode 100644 index 0000000..c831ea0 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512dq.inc @@ -0,0 +1,463 @@ + +if ~ defined AVX_512 + + include 'avx512f.inc' + +end if + +iterate , kandb,41h, kandnb,42h, knotb,44h, korb,45h, kxnorb,46h, kxorb,47h, kaddb,4Ah + + macro instr? dest*,src*,src2* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + if @dest.type = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg' + AVX.store_instruction@src2 32,VEX_66_0F_W0,opcode,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , knotb,44h, kortestb,98h, ktestb,99h + + macro instr? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'maskreg' & @src.type = 'maskreg' + AVX.store_instruction@src 16,VEX_66_0F_W0,opcode,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +macro kmovb? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'maskreg' & (@src.type = 'maskreg' | @src.type = 'mem') + if @src.type = 'mem' & @src.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,VEX_66_0F_W0,90h,@dest.rm + else if @dest.type = 'mem' & @src.type = 'maskreg' + if @dest.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@dest 16,VEX_66_0F_W0,91h,@src.rm + else if @dest.type = 'maskreg' & @src.type = 'reg' + if @src.size <> 4 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,VEX_66_0F_W0,92h,@dest.rm + else if @dest.type = 'reg' & @src.type = 'maskreg' + if @dest.size <> 4 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,VEX_66_0F_W0,93h,@dest.rm + else + err 'invalid combination of operands' + end if +end macro + +macro kaddw? dest*,src*,src2* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + if @dest.type = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg' + AVX.store_instruction@src2 32,VEX_0F_W0,opcode,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if +end macro + +macro ktestw? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'maskreg' & @src.type = 'maskreg' + AVX.store_instruction@src 16,VEX_0F_W0,opcode,@dest.rm + else + err 'invalid combination of operands' + end if +end macro + +iterate , kshiftrb,VEX_66_0F3A_W0,30h, kshiftlb,VEX_66_0F3A_W0,32h + + macro instr? dest*,src*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if @dest.type = 'maskreg' & @src.type = 'maskreg' & @aux.type = 'imm' + if @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,vex_mpw,opcode,@dest.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , and,54h, andn,55h, or,56h, xor,57h + + macro v#instr#pd? dest*,src*,src2*& + AVX_512.basic_instruction_bcst VEX_66_0F_W0,EVEX_W1+EVEX_VL,opcode,8,dest,src,src2 + end macro + + macro v#instr#ps? dest*,src*,src2*& + AVX_512.basic_instruction_bcst VEX_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2 + end macro + +end iterate + +iterate , vbroadcastf32x2,19h, vbroadcasti32x2,59h + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if @dest.size = 16 | (@src.type = 'mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not 8) + err 'invalid operand size' + end if + @src.memsize = 8 + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vbroadcastf32x8,VEX_66_0F38_W0,1Bh,32, vbroadcastf64x2,VEX_66_0F38_W1,1Ah,16, \ + vbroadcasti32x8,VEX_66_0F38_W0,5Bh,32, vbroadcasti64x2,VEX_66_0F38_W1,5Ah,16 + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mem' + if @dest.size <= msize | @src.size and not msize + err 'invalid operand size' + end if + @src.memsize = msize + AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vcvtpd2qq,VEX_66_0F_W1,7Bh, vcvtpd2uqq,VEX_66_0F_W1,79h, \ + vcvtqq2pd,VEX_F3_0F_W1,0E6h, vcvtuqq2pd,VEX_F3_0F_W1,7Ah + + macro instr? dest*,src*& + AVX_512.single_source_instruction_bcst_er vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src + end macro + +end iterate + +iterate , vcvttpd2qq,VEX_66_0F_W1,7Ah, vcvttpd2uqq,VEX_66_0F_W1,78h + + macro instr? dest*,src*& + AVX_512.single_source_instruction_bcst_sae vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src + end macro + +end iterate + +iterate , vcvtps2qq,VEX_66_0F_W0,7Bh, vcvtps2uqq,VEX_66_0F_W0,79h + + macro instr? dest*,src_er*& + AVX_512.parse_k1z_operand@dest dest + match src=,er, src_er + AVX_512.parse_operand@src src + AVX_512.parse_er@src er,32 + else + AVX_512.parse_bcst_operand@src src_er,4 + end match + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if (@src.type = 'mem' & @src.size and not (@dest.size shr 1)) | (@src.type = 'mmreg' & (@dest.size shr 1 - 1) and not 15 + 16 <> @src.size) + err 'invalid operand size' + end if + if @src.memsize = 0 + @src.memsize = @dest.size shr 1 + end if + AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vcvtqq2ps,VEX_0F_W1,5Bh, vcvtuqq2ps,VEX_F2_0F_W1,7Ah + + macro instr? dest*,src_er*& + AVX_512.parse_k1z_operand@dest dest + match src=,er, src_er + AVX_512.parse_operand@src src + AVX_512.parse_er@src er + else + AVX_512.parse_bcst_operand@src src_er,8 + end match + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @src.size = 0 + if @dest.size = 16 + err 'operand size not specified' + else + @src.size = 64 + end if + end if + if (@src.size shr 1 - 1) and not 15 + 16 <> @dest.size | @src.size > 64 + err 'invalid operand size' + end if + AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vcvttps2qq,VEX_66_0F_W0,7Ah, vcvttps2uqq,VEX_66_0F_W0,78h + + macro instr? dest*,src_sae*& + AVX_512.parse_k1z_operand@dest dest + match src=,sae, src_sae + AVX_512.parse_operand@src src + AVX_512.parse_sae @src,sae + else + AVX_512.parse_bcst_operand@src src_sae,4 + end match + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if (@src.type = 'mem' & @src.size and not (@dest.size shr 1)) | (@src.type = 'mmreg' & (@dest.size shr 1 - 1) and not 15 + 16 <> @src.size) + err 'invalid operand size' + end if + if @src.memsize = 0 + @src.memsize = @dest.size shr 1 + end if + AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vextractf32x8,VEX_66_0F3A_W0,1Bh,32, vextractf64x2,VEX_66_0F3A_W1,19h,16, \ + vextracti32x8,VEX_66_0F3A_W0,3Bh,32, vextracti64x2,VEX_66_0F3A_W1,39h,16 + + macro instr? dest*,src*,aux* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm' + if @dest.size and not msize | @src.size <= msize | @aux.size and not 1 + err 'invalid operand size' + end if + @dest.memsize = msize + AVX_512.store_instruction@dest @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vinsertf32x8,VEX_66_0F3A_W0,1Ah,32, vinsertf64x2,VEX_66_0F3A_W1,18h,16, \ + vinserti32x8,VEX_66_0F3A_W0,3Ah,32, vinserti64x2,VEX_66_0F3A_W1,38h,16 + + macro instr? dest*,src*,src2*,aux* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mmreg' | @src2.type = 'mem') & @aux.type = 'imm' + if @dest.size <= msize | @src.size <= msize | @src2.size and not msize | @aux.size and not 1 + err 'invalid operand size' + end if + @src2.memsize = msize + AVX_512.store_instruction@src2 @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vfpclasspd,8,VEX_66_0F3A_W1, vfpclassps,4,VEX_66_0F3A_W0 + + macro instr? dest*,src*,aux* + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_bcst_operand@src src,unit + x86.parse_operand@aux aux + if @dest.type = 'maskreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm' + if @src.size = 0 + err 'operand size not specified' + else if (@src.size <> 16 & @src.size <> 32 & @src.size <> 64) | @aux.size and not 1 + err 'invalid operand size' + end if + AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,66h,@dest.mask,@dest.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vfpclasssd,8,VEX_66_0F3A_W1, vfpclassss,4,VEX_66_0F3A_W0 + + macro instr? dest*,src*,aux* + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if @dest.type = 'maskreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm' + if (@src.type = 'mem' & @src.size and not unit) | (@src.type = 'mmreg' & @src.size <> 16) | @aux.size and not 1 + err 'invalid operand size' + end if + @src.memsize = 16 + AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED,67h,@dest.mask,@dest.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +macro vpextrd? dest*,src*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm' + if (@dest.type = 'reg' & @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | (@dest.type = 'mem' & @dest.size and not 4) | @src.size <> 16 | @aux.size and not 1 + err 'invalid operand size' + end if + @dest.memsize = 4 + AVX_512.store_instruction@dest 16,VEX_66_0F3A_W0,EVEX_AS_VEX,16h,0,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +macro vpinsrd? dest*,src*,src2*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'reg' | @src2.type = 'mem') & @aux.type = 'imm' + if @dest.size <> 16 | @src.size <> 16 | (@src2.type = 'reg' & @src2.size <> 4) | (@src2.type = 'mem' & @src2.size and not 4) | @aux.size and not 1 + err 'invalid operand size' + end if + @src2.memsize = 4 + AVX_512.store_instruction@src2 16,VEX_66_0F3A_W0,EVEX_AS_VEX,22h,0,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +macro vpextrq? dest*,src*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm' + if @dest.size and not 8 | @src.size <> 16 | @aux.size and not 1 + err 'invalid operand size' + end if + if x86.mode < 64 + err 'instruction requires long mode' + end if + @dest.memsize = 8 + AVX_512.store_instruction@dest 16,VEX_66_0F3A_W1,EVEX_AS_VEX,16h,0,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +macro vpinsrq? dest*,src*,src2*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'reg' | @src2.type = 'mem') & @aux.type = 'imm' + if @dest.size <> 16 | @src.size <> 16 | @src2.size and not 8 | @aux.size and not 1 + err 'invalid operand size' + end if + if x86.mode < 64 + err 'instruction requires long mode' + end if + @src2.memsize = 8 + AVX_512.store_instruction@src2 16,VEX_66_0F3A_W1,EVEX_AS_VEX,22h,0,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +macro vpmullq? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,40h,8,dest,src,src2 +end macro + +iterate , vpmovm2d,VEX_F3_0F38_W0,38h, vpmovm2q,VEX_F3_0F38_W1,38h + + macro instr? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'maskreg' + AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vpmovd2m,VEX_F3_0F38_W0,39h, vpmovq2m,VEX_F3_0F38_W1,39h + + macro instr? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'maskreg' & @src.type = 'mmreg' + AVX_512.store_instruction@src @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , range,50h + + macro v#instr#pd? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_bcst_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2,aux + end macro + + macro v#instr#ps? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_bcst_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED+EVEX_VL,opcode,4,dest,src,src2,aux + end macro + + macro v#instr#sd? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED,opcode+1,8,dest,src,src2,aux + end macro + + macro v#instr#ss? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED,opcode+1,4,dest,src,src2,aux + end macro + +end iterate + +macro vreducepd? dest*,src*,aux*& + AVX_512.single_source_instruction_bcst_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED+EVEX_VL,56h,8,dest,src,aux +end macro + +macro vreduceps? dest*,src*,aux*& + AVX_512.single_source_instruction_bcst_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED+EVEX_VL,56h,4,dest,src,aux +end macro + +macro vreducesd? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED,57h,8,dest,src,src2,aux +end macro + +macro vreducess? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED,57h,4,dest,src,src2,aux +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512er.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512er.inc new file mode 100644 index 0000000..ba430f8 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512er.inc @@ -0,0 +1,39 @@ + +if ~ defined AVX_512 + + include 'avx512f.inc' + +end if + +iterate , vexp2ps,4,VEX_66_0F38_W0,0C8h, vexp2pd,4,VEX_66_0F38_W1,0C8h, \ + vrcp28ps,4,VEX_66_0F38_W0,0CAh, vrcp28pd,8,VEX_66_0F38_W1,0CAh, vrsqrt28ps,4,VEX_66_0F38_W0,0CCh, vrsqrt28pd,8,VEX_66_0F38_W1,0CCh + + macro instr? dest*,src_sae*& + AVX_512.parse_k1z_operand@dest dest + match src=,sae, src_sae + AVX_512.parse_operand@src src + AVX_512.parse_sae@src sae + else + AVX_512.parse_bcst_operand@src src_sae,unit + end match + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @dest.size <> 64 + err 'invalid operand size' + else if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , vrcp28ss,4,VEX_66_0F38_W0,0CBh, vrcp28sd,8,VEX_66_0F38_W1,0CBh, vrsqrt28ss,4,VEX_66_0F38_W0,0CDh, vrsqrt28sd,8,VEX_66_0F38_W1,0CDh + + macro instr? dest*,src*,src2*& + AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED,opcode,unit,dest,src,src2 + end macro + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512f.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512f.inc new file mode 100644 index 0000000..6efafe2 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512f.inc @@ -0,0 +1,2660 @@ + +if ~ defined AVX_512 + + restore AVX_512 ; this ensures that symbol cannot be forward-referenced + AVX_512 = 1 + + include 'avx2.inc' + + element AVX_512.reg + + element AVX_512.r128 : AVX_512.reg + 16 + element AVX_512.r256 : AVX_512.reg + 32 + element AVX_512.r512 : AVX_512.reg + 64 + + repeat 8, i:0 + element zmm#i? : AVX_512.r512 + i + end repeat + + if defined xmm8 + repeat 16, i:16 + element xmm#i? : AVX_512.r128 + i + element ymm#i? : AVX_512.r256 + i + end repeat + repeat 8+16, i:8 + element zmm#i? : AVX_512.r512 + i + end repeat + end if + + element AVX_512.maskreg + + repeat 8, i:0 + element k#i? : AVX_512.maskreg + i + end repeat + + define x86.dqqword? :64 + define x86.zword? :64 + + EVEX_AS_VEX = 0 + EVEX_W1 = 1 shl 15 + EVEX_REQUIRED = 1 shl 10 + EVEX_FORBIDDEN = 1 shl 2 + EVEX_VL = 1 shl 22 + + AVX512VL = 0 + + iterate context, @dest,@src,@src2,@aux + + namespace context + + define mask + define evex_b + define memsize + define broadcast + define rounding + define visize + + calminstruction AVX_512.parse_operand#context operand + + call x86.parse_operand#context, operand + + check type = 'reg' & size = 1 & rm >= 4 & (~ defined x86.REX_FORBIDDEN | rm and x86.REX_FORBIDDEN) + jyes invalid_operand + check type = 'imm' & size = 0 + jno export_common + + check imm eq 1 elementof imm & 1 metadataof imm relativeto SSE.reg + jyes xmm_register + check imm eq 1 elementof imm & 1 metadataof imm relativeto AVX.reg + jyes ymm_register + check 1 metadataof (1 metadataof imm) relativeto AVX_512.reg & imm eq 1 elementof imm + jyes xyzmm_register + check imm eq 1 elementof imm & 1 metadataof imm relativeto AVX_512.maskreg + jyes mask_register + exit + + invalid_operand: + err 'invalid operand' + + xmm_register: + + compute rm, 1 metadataof imm - SSE.reg + compute size, 16 + + jump export_mmreg + + ymm_register: + + compute rm, 1 metadataof imm - AVX.reg + compute size, 32 + + jump export_mmreg + + mask_register: + + compute rm, 1 metadataof imm - AVX_512.maskreg + compute size, 8 + compute type, 'maskreg' + + jump export_reg + + xyzmm_register: + + compute rm, 1 metadataof imm - 1 elementof (1 metadataof imm) + compute size, 1 metadataof (1 metadataof imm) - AVX_512.reg + + export_mmreg: + + compute type, 'mmreg' + + export_reg: + + compute mod, 11b + + export_common: + + compute mask, 0 + compute evex_b, 0 + compute memsize, 0 + + end calminstruction + + calminstruction AVX_512.parse_k1z_operand#context operand + + local k1, z + transform operand + match operand {k1} { =z? }, operand + jyes k1z + match operand {k1}, operand + jyes k1 + call AVX_512.parse_operand#context, operand + exit + k1z: + compute z, 80h + jump masked + k1: + compute z, 0 + masked: + call AVX_512.parse_operand#context, operand + check z & type = 'mem' + jyes invalid_mask + check k1 eq 1 elementof k1 & 1 metadataof k1 relativeto AVX_512.maskreg & 1 metadataof k1 - AVX_512.maskreg > 0 + jno invalid_mask + compute mask, (1 metadataof k1 - AVX_512.maskreg) or z + exit + invalid_mask: + err 'invalid mask' + + end calminstruction + + calminstruction AVX_512.parse_k1_operand#context operand + + local k1 + transform operand + match operand {k1}, operand + jyes k1 + call AVX_512.parse_operand#context, operand + exit + k1: + call AVX_512.parse_operand#context, operand + check k1 eq 1 elementof k1 & 1 metadataof k1 relativeto AVX_512.maskreg & 1 metadataof k1 - AVX_512.maskreg > 0 + jno invalid_mask + compute mask, 1 metadataof k1 - AVX_512.maskreg + exit + invalid_mask: + err 'invalid mask' + + end calminstruction + + calminstruction AVX_512.parse_bcst_operand#context operand,unit + + transform operand + match operand {broadcast}, operand + jyes mem_bcst + call AVX_512.parse_operand#context, operand + exit + + invalid_operand: + err 'invalid operand' + + mem_bcst: + call AVX_512.parse_operand#context, operand + + check type = 'mem' + jno invalid_operand + + compute memsize, unit + check memsize + jyes implied_unit + check size + jno operand_size_not_specified + compute memsize, size + jump unit_ok + operand_size_not_specified: + err 'operand size not specified' + exit + implied_unit: + check size and not memsize + jno unit_ok + err 'invalid operand size' + exit + unit_ok: + + match =1to2?, broadcast + jyes bcst_2 + match =1to4?, broadcast + jyes bcst_4 + match =1to8?, broadcast + jyes bcst_8 + match =1to16?, broadcast + jyes bcst_16 + err 'invalid broadcast' + exit + bcst_2: + compute broadcast, 2 + jump bcst_ok + bcst_4: + compute broadcast, 4 + jump bcst_ok + bcst_8: + compute broadcast, 8 + jump bcst_ok + bcst_16: + compute broadcast, 16 + bcst_ok: + compute size, memsize * broadcast + compute evex_b, 1 + + end calminstruction + + calminstruction AVX_512.parse_er#context operand,vsize:64 + + check type = 'mem' | size <> vsize + jyes invalid_operand + + match { =rn?-=sae? }, operand + jyes rounding_0 + match { =rd?-=sae? }, operand + jyes rounding_1 + match { =ru?-=sae? }, operand + jyes rounding_2 + match { =rz?-=sae? }, operand + jyes rounding_3 + invalid_operand: + err 'invalid operand' + exit + rounding_0: + compute rounding, 0 + jump rounding_ok + rounding_1: + compute rounding, 1 + jump rounding_ok + rounding_2: + compute rounding, 2 + jump rounding_ok + rounding_3: + compute rounding, 3 + jump rounding_ok + + rounding_ok: + compute evex_b, 1 + + end calminstruction + + calminstruction AVX_512.parse_sae#context operand + + check type = 'mem' + jyes invalid_operand + + match { =sae? }, operand + jno invalid_operand + + compute evex_b, 1 + compute rounding, -1 + + exit + + invalid_operand: + err 'invalid operand' + + end calminstruction + + calminstruction AVX_512.parse_vsib_operand#context operand + + local i, pre, suf + + compute segment_prefix, 0 + + compute size, 0 + compute displacement_size, 0 + + transform operand + + match pre suf, operand + jno no_size_prefix + transform pre, x86 + jno no_size_prefix + match :size, pre + jno no_size_prefix + arrange operand, suf + no_size_prefix: + + match [address], operand + jyes memory_operand + match =ptr? address, operand + jyes memory_operand + + jump invalid_operand + + memory_operand: + compute type, 'mem' + + match segment:address, address + jno segment_prefix_ok + check segment eq 1 elementof segment & 1 metadataof segment relativeto x86.sreg + jno invalid_operand + compute segment, 1 metadataof segment - x86.sreg + check segment >= 4 + jyes segment_prefix_386 + compute segment_prefix, 26h + segment shl 3 + jump segment_prefix_ok + segment_prefix_386: + compute segment_prefix, 64h + segment-4 + segment_prefix_ok: + + match pre suf, address + jno no_address_size_prefix + transform pre, x86 + jno no_address_size_prefix + match :pre, pre + jno no_address_size_prefix + arrange address, suf + check pre = 4 | pre = 8 + jno invalid_address_size + compute mode, pre shl 3 + no_address_size_prefix: + + compute mode, 0 + compute scale, 0 + compute index, 0 + compute base, 0 + compute auto_relative, 0 + + check size + jyes size_override + compute size, sizeof address + size_override: + + compute address, address + compute base_registers, 0 + compute index_registers, 0 + compute i, 1 + extract_registers: + check i > elementsof address + jyes registers_extracted + check i metadataof address relativeto SSE.reg | i metadataof address relativeto AVX.reg | 1 metadataof (i metadataof address) relativeto AVX_512.reg + jyes index_term + check i metadataof address relativeto x86.r32 | i metadataof address relativeto x86.r64 + jno next_term + compute base_registers, base_registers + i elementof address * i scaleof address + jump next_term + index_term: + compute index_registers, index_registers + i elementof address * i scaleof address + next_term: + compute i, i+1 + jump extract_registers + registers_extracted: + compute displacement, address - base_registers - index_registers + compute auto_relative, 0 + + check elementsof index_registers = 1 + jno invalid_address + compute scale, 1 scaleof index_registers + compute index, 0 scaleof (1 metadataof index_registers) + check scale and (scale-1) | scale > 8 + jyes invalid_address + check 1 metadataof index_registers relativeto SSE.reg + jyes xmm_index + check 1 metadataof index_registers relativeto AVX.reg + jyes ymm_index + compute visize, 1 metadataof (1 metadataof index_registers) - AVX_512.reg + jump index_ok + ymm_index: + compute visize, 32 + jump index_ok + xmm_index: + compute visize, 16 + index_ok: + + compute rm, 4 + check elementsof base_registers = 1 & 1 scaleof base_registers = 1 + jyes base_and_index + check elementsof base_registers = 0 + jno invalid_address + compute base, 5 + compute displacement_size, 4 + compute mod, 0 + compute mode, x86.mode + check mode > 16 + jyes ready + compute mode, 32 + jump ready + base_and_index: + compute base, 0 scaleof (1 metadataof base_registers) + check mode & mode <> 0 scaleof (1 metadataof (1 metadataof base_registers)) shl 3 + jyes invalid_address + compute mode, 0 scaleof (1 metadataof (1 metadataof base_registers)) shl 3 + + setup_displacement: + check displacement relativeto 0 + jno displacement_32bit + check displacement = 0 & rm and 111b <> 5 & (rm <> 4 | base and 111b <> 5) + jyes displacement_empty + check displacement < 80h & displacement >= -80h + jyes displacement_8bit + check displacement - 1 shl mode >= -80h & displacement < 1 shl mode + jyes displacement_8bit_wrap + displacement_32bit: + compute displacement_size, 4 + compute mod, 2 + jump ready + displacement_8bit_wrap: + compute displacement, displacement - 1 shl mode + displacement_8bit: + compute displacement_size, 1 + compute mod, 1 + jump ready + index_only: + compute displacement_size, 4 + compute mod, 0 + jump ready + displacement_empty: + compute displacement_size, 0 + compute mod, 0 + + ready: + + compute mask, 0 + compute evex_b, 0 + compute memsize, 0 + + exit + + invalid_operand: + err 'invalid operand' + exit + invalid_address: + err 'invalid address' + exit + invalid_address_size: + err 'invalid address size' + exit + + end calminstruction + + calminstruction AVX_512.parse_k1_vsib_operand#context operand + + local k1 + transform operand + match operand {k1}, operand + jyes k1 + call AVX_512.parse_vsib_operand#context, operand + exit + k1: + call AVX_512.parse_vsib_operand#context, operand + check k1 eq 1 elementof k1 & 1 metadataof k1 relativeto AVX_512.maskreg & 1 metadataof k1 - AVX_512.maskreg > 0 + jno invalid_mask + compute mask, 1 metadataof k1 - AVX_512.maskreg + exit + invalid_mask: + err 'invalid mask' + + end calminstruction + + calminstruction AVX_512.store_instruction#context vsize*,vex_mpw*,evex_f*,opcode*,mask*,reg*,vreg:0,imm_size:0,immediate + + check segment_prefix + jno segment_prefix_ok + + check mode = 64 + jyes segment_in_long_mode + check mode = 16 & ( rm = 2 | rm = 3 | ( mod > 0 & rm = 6 ) ) + jyes ss_segment_default + check mode = 32 & ( ( mod > 0 & rm = 5 ) | ( rm = 4 & base = 4 ) | ( mod > 0 & rm = 4 & base = 5 ) ) + jyes ss_segment_default + + ds_segment_default: + check segment_prefix = 3Eh + jyes segment_prefix_ok + jump store_segment_prefix + ss_segment_default: + check segment_prefix = 36h + jyes segment_prefix_ok + jump store_segment_prefix + segment_in_long_mode: + check segment_prefix < 64h + jyes segment_prefix_ok + store_segment_prefix: + emit 1, segment_prefix + segment_prefix_ok: + + check mod <> 11b & mode <> x86.mode + jno addressing_prefix_ok + check mode = 64 | (mode = 16 & x86.mode = 64) + jno store_addressing_prefix + err 'illegal addressing mode' + store_addressing_prefix: + emit 1, 67h + addressing_prefix_ok: + + compute evex, vex_mpw + compute evex_flags, evex_f + + check evex_b + jno evex_L'L + compute evex, evex or evex_b shl 20 + evex_L'L: + check mod = 11b & evex_b & rounding >= 0 + jyes evex_rounding + check vsize = 64 + jyes evex_L' + check evex_flags and EVEX_VL & AVX512VL = 0 + jno evex_L + compute evex_flags, evex_flags or EVEX_FORBIDDEN + evex_L: + check vsize = 32 + jno evex_mask + compute evex, evex or 1 shl 21 + jump evex_mask + evex_L': + compute evex, evex or 1 shl 22 + jump evex_mask + evex_rounding: + compute evex, evex or rounding shl 21 + + evex_mask: + check mask + jno evex_X + compute evex, evex or mask shl 16 + + evex_X: + check rm and 10000b | (mod <> 11b & mode > 16 & rm = 4 & index and 1000b) + jno evex_B + compute evex, evex or 1 shl 6 + evex_B: + check rm and 1000b | (mod <> 11b & mode > 16 & rm = 4 & base and 1000b) + jno evex_R' + compute evex, evex or 1 shl 5 + evex_R': + check reg and 10000b + jno evex_R + compute evex, evex or 1 shl 4 + evex_R: + check reg and 1000b + jno evex_V' + compute evex, evex or 1 shl 7 + evex_V': + check vreg and 10000b + jno evex_vvvv + compute evex, evex or 1 shl 19 + evex_vvvv: + compute evex, evex or (vreg and 1111b) shl 11 + + check x86.mode < 64 & evex and 00001000_01000000_11110000b + jno allowed + err 'instruction requires long mode' + allowed: + + local evex_displacement_size, compressed_displacement + + check displacement_size + jno no_displacement_compression + compute displacement, displacement + check (mode > 16 & rm = 5) | (mode = 16 & rm = 6) + jyes no_displacement_compression + check memsize + jyes displacement_compression + compute memsize, vsize + displacement_compression: + check displacement relativeto 0 & displacement mod? memsize = 0 + jno displacement_incompressible + compute compressed_displacement, displacement / memsize + check compressed_displacement < 80h & compressed_displacement >= -80h + jyes displacement_compressed + check compressed_displacement - 1 shl mode >= -80h & compressed_displacement < 1 shl mode + jno displacement_incompressible + compute compressed_displacement, compressed_displacement - 1 shl mode + displacement_compressed: + compute evex_displacement_size, 1 + jump choose_prefix + displacement_incompressible: + compute evex_displacement_size, 4 + check mode > 16 + jyes choose_prefix + compute evex_displacement_size, 2 + jump choose_prefix + no_displacement_compression: + compute evex_displacement_size, displacement_size + + choose_prefix: + check evex_flags and EVEX_REQUIRED | evex and 11011111_00000000_00010000b | rm and 10000b + jyes evex_required + check ~ evex_flags and EVEX_FORBIDDEN & evex_displacement_size + 1 < displacement_size + jyes evex + jump vex + evex_required: + check evex_flags and EVEX_FORBIDDEN + jno evex + err 'invalid operand' + + vex: + compute vex, evex and 11111011_11111111b or (evex and 1 shl 21) shr (21-10) + check vex and 10000000_01111111b <> 1 + jyes vex_3byte + vex_2byte: + emit 1, 0C5h + emit 1, ((vex and 10000000b) or ((vex shr 8) and 1111111b)) xor 11111000b + jump evex_done + vex_3byte: + emit 1, 0C4h + emit 1, (vex and 11111111b) xor 11100000b + emit 1, (vex shr 8) xor 01111000b + jump evex_done + + evex: + compute evex, evex or 1 shl 10 + check evex_flags and EVEX_W1 + jno evex_4byte + compute evex, evex or 1 shl 15 + evex_4byte: + emit 4, 62h + (evex xor 00001000_01111000_11110000b) shl 8 + check mod <> 11b & mod <> 0 & evex_displacement_size > 0 + jno evex_done + compute displacement_size, evex_displacement_size + check evex_displacement_size = 1 + jyes evex_compressed_displacement + compute mod, 2 + jump evex_done + evex_compressed_displacement: + compute displacement, compressed_displacement + compute mod, 1 + evex_done: + + asm db opcode + emit 1, mod shl 6 + (reg and 111b) shl 3 + rm and 111b + + check mod <> 11b & rm = 4 & mode <> 16 + jno sib_ok + emit 1, (bsf scale) shl 6 + (index and 111b) shl 3 + base and 111b + sib_ok: + + check displacement_size = 1 + jyes displacement_8bit + check displacement_size = 2 + jyes displacement_16bit + check displacement_size = 4 | displacement_size = 8 + jno displacement_ok + + check auto_relative + jno auto_relative_ok + check imm_size < 8 + jyes adjust_auto_relative_displacement + compute displacement, displacement - ($ + 4 + 4) + jump auto_relative_ok + adjust_auto_relative_displacement: + compute displacement, displacement - ($ + 4 + imm_size) + auto_relative_ok: + + check mode = 64 & displacement relativeto 0 + jno displacement_ready + check displacement - 1 shl 64 >= -80000000h & displacement < 1 shl 64 + jyes adjust_displacement_wrap + check displacement >= -80000000h & displacement < 80000000h + jyes displacement_ready + err 'address value out of signed range' + adjust_displacement_wrap: + compute displacement, displacement - 1 shl 64 + displacement_ready: + + asm dd displacement + + jump displacement_ok + displacement_16bit: + asm dw displacement + jump displacement_ok + displacement_8bit: + emit 1, displacement + displacement_ok: + + check imm_size = 1 + jyes immediate_8bit + check imm_size = 2 + jyes immediate_16bit + check imm_size = 4 + jyes immediate_32bit + check imm_size = 8 + jno immediate_ok + call x86.simm32, immediate + jump immediate_ok + immediate_32bit: + compute imm, +immediate + asm dd imm + jump immediate_ok + immediate_16bit: + compute imm, +immediate + asm dw imm + jump immediate_ok + immediate_8bit: + compute imm, +immediate + emit 1, imm + immediate_ok: + + end calminstruction + + end namespace + + end iterate + + macro AVX_512.basic_instruction_bcst_er vex_mpw,evex_f,opcode,unit,dest,src,src_er& + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + match src2=,er, src_er + AVX_512.parse_operand@src2 src2 + AVX_512.parse_er@src2 er + else + AVX_512.parse_bcst_operand@src2 src_er,unit + end match + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.basic_instruction_bcst_sae vex_mpw,evex_f,opcode,unit,dest,src,src_sae& + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + match src2=,sae, src_sae + AVX_512.parse_operand@src2 src2 + AVX_512.parse_sae@src2 sae + else + AVX_512.parse_bcst_operand@src2 src_sae,unit + end match + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.basic_instruction_bcst_sae_imm8 vex_mpw,evex_f,opcode,unit,dest,src,src2,aux& + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_bcst_operand@src2 src2,unit + match sae=,imm, aux + AVX_512.parse_sae@src2 sae + x86.parse_operand@aux imm + else + x86.parse_operand@aux aux + end match + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm' + if @src.size <> @dest.size | @src2.size and not @dest.size | @aux.size and not 1 + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.basic_instruction_bcst vex_mpw,evex_f,opcode,unit,dest,src,src2 + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_bcst_operand@src2 src2,unit + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.basic_instruction_bcst_imm8 vex_mpw,evex_f,opcode,unit,dest,src,src2,aux + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_bcst_operand@src2 src2,unit + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm' + if @aux.size and not 1 + err 'invalid operand size' + else if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.basic_instruction_er vex_mpw,evex_f,opcode,unit,dest,src,src_er& + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + match src2=,er, src_er + AVX_512.parse_operand@src2 src2 + AVX_512.parse_er@src2 er,(unit-1) and not 15 + 16 + else + AVX_512.parse_operand@src2 src_er + end match + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if unit & ( @dest.size <> (unit-1) and not 15 + 16 | (@src2.type = 'mem' & @src2.size and not unit) ) + err 'invalid operand size' + else if @dest.size <> @src.size | (@src2.size and not @dest.size & (unit = 0 | @src2.type = 'mmreg')) + err 'operand sizes do not match' + end if + @src2.memsize = unit + AVX_512.store_instruction@src2 @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.basic_instruction_sae vex_mpw,evex_f,opcode,unit,dest,src,src_sae& + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + match src2=,sae, src_sae + AVX_512.parse_operand@src2 src2 + AVX_512.parse_sae@src2 sae + else + AVX_512.parse_operand@src2 src_sae + end match + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if unit & ( @dest.size <> (unit-1) and not 15 + 16 | (@src2.type = 'mem' & @src2.size and not unit) ) + err 'invalid operand size' + else if @dest.size <> @src.size | (@src2.size and not @dest.size & (unit = 0 | @src2.type = 'mmreg')) + err 'operand sizes do not match' + end if + @src2.memsize = unit + AVX_512.store_instruction@src2 @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.basic_instruction_sae_imm8 vex_mpw,evex_f,opcode,unit,dest,src,src2,aux& + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + match sae=,imm, aux + AVX_512.parse_sae@src2 sae + x86.parse_operand@aux imm + else + x86.parse_operand@aux aux + end match + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm' + if ( unit & ( @dest.size <> (unit-1) and not 15 + 16 | (@src2.type = 'mem' & @src2.size and not unit) ) ) | @aux.size and not 1 + err 'invalid operand size' + else if @dest.size <> @src.size | (@src2.size and not @dest.size & (unit = 0 | @src2.type = 'mmreg')) + err 'operand sizes do not match' + end if + @src2.memsize = unit + AVX_512.store_instruction@src2 @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.basic_instruction vex_mpw,evex_f,opcode,unit,dest,src,src2 + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if unit & ( @dest.size <> (unit-1) and not 15 + 16 | (@src2.type = 'mem' & @src2.size and not unit) ) + err 'invalid operand size' + else if @dest.size <> @src.size | (@src2.size and not @dest.size & (unit = 0 | @src2.type = 'mmreg')) + err 'operand sizes do not match' + end if + @src2.memsize = unit + AVX_512.store_instruction@src2 @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.basic_instruction_imm8 vex_mpw,evex_f,opcode,unit,dest,src,src2,aux& + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm' + if ( unit & ( @dest.size <> (unit-1) and not 15 + 16 | (@src2.type = 'mem' & @src2.size and not unit) ) ) | @aux.size and not 1 + err 'invalid operand size' + else if @dest.size <> @src.size | (@src2.size and not @dest.size & (unit = 0 | @src2.type = 'mmreg')) + err 'operand sizes do not match' + end if + @src2.memsize = unit + AVX_512.store_instruction@src2 @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.single_source_instruction_bcst_er vex_mpw,evex_f,opcode,unit,dest,src_er& + AVX_512.parse_k1z_operand@dest dest + match src=,er, src_er + AVX_512.parse_operand@src src + AVX_512.parse_er@src er + else + AVX_512.parse_bcst_operand@src src_er,unit + end match + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.single_source_instruction_bcst_sae vex_mpw,evex_f,opcode,unit,dest,src_sae& + AVX_512.parse_k1z_operand@dest dest + match src=,sae, src_sae + AVX_512.parse_operand@src src + AVX_512.parse_sae@src sae + else + AVX_512.parse_bcst_operand@src src_sae,unit + end match + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.single_source_instruction_bcst_sae_imm8 vex_mpw,evex_f,opcode,unit,dest,src,aux& + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_bcst_operand@src src,unit + match sae=,imm, aux + AVX_512.parse_sae@src sae + x86.parse_operand@aux imm + else + x86.parse_operand@aux aux + end match + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm' + if @aux.size and not 1 + err 'invalid operand size' + else if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.single_source_instruction_bcst vex_mpw,evex_f,opcode,unit,dest,src& + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_bcst_operand@src src,unit + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro AVX_512.single_source_instruction vex_mpw,evex_f,opcode,unit,dest,src + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if unit & ( @dest.size <> (unit-1) and not 15 + 16 | (@src.type = 'mem' & @src.size and not unit) ) + err 'invalid operand size' + else if @src.size and not @dest.size & (unit = 0 | @src.type = 'mmreg') + err 'operand sizes do not match' + end if + @src.memsize = unit + AVX_512.store_instruction@src @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , add,58h, mul,59h, sub,5Ch, div,5Eh + + macro v#instr#pd? dest*,src*,src2*& + AVX_512.basic_instruction_bcst_er VEX_66_0F_W0,EVEX_W1+EVEX_VL,opcode,8,dest,src,src2 + end macro + + macro v#instr#ps? dest*,src*,src2*& + AVX_512.basic_instruction_bcst_er VEX_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2 + end macro + + macro v#instr#sd? dest*,src*,src2*& + AVX_512.basic_instruction_er VEX_F2_0F_W0,EVEX_W1,opcode,8,dest,src,src2 + end macro + + macro v#instr#ss? dest*,src*,src2*& + AVX_512.basic_instruction_er VEX_F3_0F_W0,EVEX_AS_VEX,opcode,4,dest,src,src2 + end macro + + end iterate + + iterate , min,5Dh, max,5Fh + + macro v#instr#pd? dest*,src*,src2*& + AVX_512.basic_instruction_bcst_sae VEX_66_0F_W0,EVEX_W1+EVEX_VL,opcode,8,dest,src,src2 + end macro + + macro v#instr#ps? dest*,src*,src2*& + AVX_512.basic_instruction_bcst_sae VEX_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2 + end macro + + macro v#instr#sd? dest*,src*,src2*& + AVX_512.basic_instruction_sae VEX_F2_0F_W0,EVEX_W1,opcode,8,dest,src,src2 + end macro + + macro v#instr#ss? dest*,src*,src2*& + AVX_512.basic_instruction_sae VEX_F3_0F_W0,EVEX_AS_VEX,opcode,4,dest,src,src2 + end macro + + end iterate + + iterate , unpckh,15h, unpckl,14h + + macro v#instr#pd? dest*,src*,src2*& + AVX_512.basic_instruction_bcst VEX_66_0F_W0,EVEX_W1+EVEX_VL,opcode,8,dest,src,src2 + end macro + + macro v#instr#ps? dest*,src*,src2*& + AVX_512.basic_instruction_bcst VEX_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2 + end macro + + end iterate + + macro vsqrtpd? dest*,src*& + AVX_512.single_source_instruction_bcst_er VEX_66_0F_W0,EVEX_W1+EVEX_VL,51h,8,dest,src + end macro + + macro vsqrtps? dest*,src*& + AVX_512.single_source_instruction_bcst_er VEX_0F_W0,EVEX_AS_VEX+EVEX_VL,51h,4,dest,src + end macro + + macro vsqrtsd? dest*,src*,src2*& + AVX_512.basic_instruction_er VEX_F2_0F_W0,EVEX_W1,51h,8,dest,src,src2 + end macro + + macro vsqrtss? dest*,src*,src2*& + AVX_512.basic_instruction_er VEX_F3_0F_W0,EVEX_AS_VEX,51h,4,dest,src,src2 + end macro + + macro vshufpd? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_bcst_imm8 VEX_66_0F_W0,EVEX_W1+EVEX_VL,0C6h,8,dest,src,src2,aux + end macro + + macro vshufps? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_bcst_imm8 VEX_0F_W0,EVEX_AS_VEX+EVEX_VL,0C6h,4,dest,src,src2,aux + end macro + + macro vbroadcastss? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if (@src.type = 'mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not 4) + err 'invalid operand size' + end if + @src2.memsize = 4 + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,18h,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro vbroadcastsd? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if @dest.size = 16 | (@src.type = 'mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not 8) + err 'invalid operand size' + end if + @src.memsize = 8 + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_W1+EVEX_VL,19h,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vpbroadcastd,58h,7Ch,4, vpbroadcastq,59h,7Ch,8 + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if (@src.type='mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size and not msize) + err 'invalid operand size' + end if + @src.memsize = msize + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX,opcode,@dest.mask,@dest.rm + else if @dest.type = 'mmreg' & @src.type = 'reg' + if @src.size <> msize & (@src.size <> 4 | msize = 8) + err 'invalid operand size' + end if + @src.memsize = msize + if msize = 8 + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode_g,@dest.mask,@dest.rm + else + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode_g,@dest.mask,@dest.rm + end if + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vbroadcastf32x4,VEX_66_0F38_W0,1Ah,16, vbroadcastf64x4,VEX_66_0F38_W1,1Bh,32, \ + vbroadcasti32x4,VEX_66_0F38_W0,5Ah,16, vbroadcasti64x4,VEX_66_0F38_W1,5Bh,32 + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mem' + if @dest.size <= msize | @src.size and not msize + err 'invalid operand size' + end if + @src.memsize = msize + AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vshuff32x4,VEX_66_0F3A_W0,23h,4, vshuff64x2,VEX_66_0F3A_W1,23h,4, \ + vshufi32x4,VEX_66_0F3A_W0,43h,4, vshufi64x2,VEX_66_0F3A_W1,43h,4 + + macro instr? dest*,src*,src2*,aux* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_bcst_operand@src2 src2,unit + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm' + if @dest.size < 32 | @aux.size and not 1 + err 'invalid operand size' + else if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vextractps? dest*,src*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm' + if @dest.size and not 4 | @src.size <> 16 | @aux.size and not 1 + err 'invalid operand size' + end if + @dest.memsize = 4 + AVX_512.store_instruction@dest 16,VEX_66_0F3A_W0,EVEX_AS_VEX,17h,0,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro vinsertps? dest*,src*,src2*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mmreg' | @src2.type = 'mem') & @aux.type = 'imm' + if @dest.size <> 16 | @src.size <> 16 | (@src2.type = 'mmreg' & @src2.size <> 16) | (@src2.type = 'mem' & @src2.size and not 4) | @aux.size and not 1 + err 'invalid operand size' + end if + @src2.memsize = 4 + AVX_512.store_instruction@src2 16,VEX_66_0F3A_W0,EVEX_AS_VEX,21h,0,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vextractf32x4,VEX_66_0F3A_W0,19h,16, vextractf64x4,VEX_66_0F3A_W1,1Bh,32, \ + vextracti32x4,VEX_66_0F3A_W0,39h,16, vextracti64x4,VEX_66_0F3A_W1,3Bh,32 + + macro instr? dest*,src*,aux* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm' + if @dest.size and not msize | @src.size <= msize | @aux.size and not 1 + err 'invalid operand size' + end if + @dest.memsize = msize + AVX_512.store_instruction@dest @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vinsertf32x4,VEX_66_0F3A_W0,18h,16, vinsertf64x4,VEX_66_0F3A_W1,1Ah,32, \ + vinserti32x4,VEX_66_0F3A_W0,38h,16, vinserti64x4,VEX_66_0F3A_W1,3Ah,32 + + macro instr? dest*,src*,src2*,aux* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mmreg' | @src2.type = 'mem') & @aux.type = 'imm' + if @dest.size <= msize | @src.size <= msize | @src2.size and not msize | @aux.size and not 1 + err 'invalid operand size' + end if + @src2.memsize = msize + AVX_512.store_instruction@src2 @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vcmpps,VEX_0F_W0,VEX_0F_W0,4, vcmppd,VEX_66_0F_W0,VEX_66_0F_W1,8 + + macro instr? dest*,src*,src2*,aux*& + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_bcst_operand@src2 src2,unit + match sae=,imm, aux + AVX_512.parse_sae@src2 sae + x86.parse_operand@aux imm + else + x86.parse_operand@aux aux + end match + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm' + if @aux.size and not 1 + err 'invalid operand size' + else if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @src.size,vex_mpw,EVEX_FORBIDDEN,0C2h,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm' + if @aux.size and not 1 + err 'invalid operand size' + else if @src2.size and not @src.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @src.size,evex_mpw,EVEX_REQUIRED+EVEX_VL,0C2h,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vcmpss,VEX_F3_0F_W0,VEX_F3_0F_W0,4, vcmpsd,VEX_F2_0F_W0,VEX_F2_0F_W1,8 + + macro instr? dest*,src*,src2*,aux*& + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + match sae=,imm, aux + AVX_512.parse_sae@src2 sae + x86.parse_operand@aux imm + else + x86.parse_operand@aux aux + end match + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm' + if @dest.size <> 16 | (@src2.type = 'mem' & @src2.size and not unit) + err 'invalid operand size' + else if @dest.size <> @src.size | (@src2.type = 'mmreg' & @src2.size <> @dest.size) + err 'operand sizes do not match' + end if + @src2.memsize = unit + AVX_512.store_instruction@src2 @src.size,vex_mpw,EVEX_FORBIDDEN,0C2h,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm' + if @src.size <> 16 | (@src2.type = 'mem' & @src2.size and not unit) | @aux.size and not 1 + err 'invalid operand size' + else if @src2.type = 'mmreg' & @src2.size <> @src.size + err 'operand sizes do not match' + end if + @src2.memsize = unit + AVX_512.store_instruction@src2 @src.size,evex_mpw,EVEX_REQUIRED,0C2h,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , eq,0, lt,1, le,2, unord,3, neq,4, nlt,5, nle,6, ord,7, \ + eq_uq,8, nge,9, ngt,0Ah, false,0Bh, neq_qq,0Ch, ge,0Dh, gt,0Eh, true,0Fh, \ + eq_os,10h, lt_oq,11h, le_oq,12h, unord_s,13h, neq_us,14h, nlt_uq,15h, nle_uq,16h, ord_s,17h, \ + eq_us,18h, nge_uq,19h, ngt_uq,1Ah, false_os,1Bh, neq_os,1Ch, ge_oq,1Dh, gt_oq,1Eh, true_us,1Fh + + macro vcmp#cond#pd? dest*,src*,src2*& + vcmppd dest,src,src2,code + end macro + + macro vcmp#cond#ps? dest*,src*,src2*& + vcmpps dest,src,src2,code + end macro + + macro vcmp#cond#sd? dest*,src*,src2*& + vcmpsd dest,src,src2,code + end macro + + macro vcmp#cond#ss? dest*,src*,src2*& + vcmpss dest,src,src2,code + end macro + + end iterate + + iterate , vcomiss,VEX_0F_W0,EVEX_AS_VEX,2Fh,4, vcomisd,VEX_66_0F_W0,EVEX_W1,2Fh,8, vucomiss,VEX_0F_W0,EVEX_AS_VEX,2Eh,4, vucomisd,VEX_66_0F_W0,EVEX_W1,2Eh,8 + + macro instr? dest*,src_sae*& + AVX_512.parse_k1z_operand@dest dest + match src=,sae, src_sae + AVX_512.parse_operand@src src + AVX_512.parse_sae@src sae + else + AVX_512.parse_operand@src src_sae + end match + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if unit & ( @dest.size <> (unit-1) and not 15 + 16 | (@src.type = 'mem' & @src.size and not unit) ) + err 'invalid operand size' + else if @src.size and not @dest.size & (unit = 0 | @src.type = 'mmreg') + err 'operand sizes do not match' + end if + @src.memsize = unit + AVX_512.store_instruction@src @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , kandw,41h, kandnw,42h, knotw,44h, korw,45h, kxnorw,46h, kxorw,47h + + macro instr? dest*,src*,src2* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + if @dest.type = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg' + AVX.store_instruction@src2 32,VEX_0F_W0,opcode,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , knotw,44h, kortestw,98h + + macro instr? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'maskreg' & @src.type = 'maskreg' + AVX.store_instruction@src 16,VEX_0F_W0,opcode,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro kmovw? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'maskreg' & (@src.type = 'maskreg' | @src.type = 'mem') + if @src.type = 'mem' & @src.size and not 2 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,VEX_0F_W0,90h,@dest.rm + else if @dest.type = 'mem' & @src.type = 'maskreg' + if @dest.size and not 2 + err 'invalid operand size' + end if + AVX.store_instruction@dest 16,VEX_0F_W0,91h,@src.rm + else if @dest.type = 'maskreg' & @src.type = 'reg' + if @src.size <> 4 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,VEX_0F_W0,92h,@dest.rm + else if @dest.type = 'reg' & @src.type = 'maskreg' + if @dest.size <> 4 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,VEX_0F_W0,93h,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , kshiftrw,VEX_66_0F3A_W1,30h, kshiftlw,VEX_66_0F3A_W1,32h + + macro instr? dest*,src*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if @dest.type = 'maskreg' & @src.type = 'maskreg' & @aux.type = 'imm' + if @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@src 16,vex_mpw,opcode,@dest.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro kunpckbw? dest*,src*,src2* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + if @dest.type = 'maskreg' & @src.type = 'maskreg' & @src2.type = 'maskreg' + AVX.store_instruction@src2 32,VEX_66_0F_W0,4Bh,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vcvtdq2pd,EVEX_AS_VEX+EVEX_VL,0E6h, vcvtudq2pd,EVEX_REQUIRED+EVEX_VL,7Ah + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_bcst_operand@src src,4 + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if (@src.type = 'mem' & @src.size and not (@dest.size shr 1)) | (@src.type = 'mmreg' & (@dest.size shr 1 - 1) and not 15 + 16 <> @src.size) + err 'invalid operand size' + end if + if @src.memsize = 0 + @src.memsize = @dest.size shr 1 + end if + AVX_512.store_instruction@src @dest.size,VEX_F3_0F_W0,evex_f,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vcvtpd2dq,VEX_F2_0F_W0,EVEX_W1+EVEX_VL,0E6h, vcvtpd2ps,VEX_66_0F_W0,EVEX_W1+EVEX_VL,5Ah, vcvtpd2udq,VEX_0F_W1,EVEX_REQUIRED+EVEX_VL,79h + + macro instr? dest*,src_er*& + AVX_512.parse_k1z_operand@dest dest + match src=,er, src_er + AVX_512.parse_operand@src src + AVX_512.parse_er@src er + else + AVX_512.parse_bcst_operand@src src_er,8 + end match + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @src.size = 0 + if @dest.size = 16 + err 'operand size not specified' + else + @src.size = 64 + end if + end if + if (@src.size shr 1 - 1) and not 15 + 16 <> @dest.size | @src.size > 64 + err 'invalid operand size' + end if + AVX_512.store_instruction@src @src.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vcvtps2pd,VEX_0F_W0,EVEX_AS_VEX+EVEX_VL,5Ah + + macro instr? dest*,src_sae*& + AVX_512.parse_k1z_operand@dest dest + match src=,sae, src_sae + AVX_512.parse_operand@src src + AVX_512.parse_sae@src sae + else + AVX_512.parse_bcst_operand@src src_sae,4 + end match + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if (@src.type = 'mem' & @src.size and not (@dest.size shr 1)) | (@src.type = 'mmreg' & (@dest.size shr 1 - 1) and not 15 + 16 <> @src.size) + err 'invalid operand size' + end if + if @src.memsize = 0 + @src.memsize = @dest.size shr 1 + end if + AVX_512.store_instruction@src @dest.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vcvttpd2dq,VEX_66_0F_W0,EVEX_W1+EVEX_VL,0E6h, vcvttpd2udq,VEX_0F_W1,EVEX_REQUIRED+EVEX_VL,78h + + macro instr? dest*,src_sae*& + AVX_512.parse_k1z_operand@dest dest + match src=,sae, src_sae + AVX_512.parse_operand@src src + AVX_512.parse_sae@src sae + else + AVX_512.parse_bcst_operand@src src_sae,8 + end match + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @src.size = 0 + if @dest.size = 16 + err 'operand size not specified' + else + @src.size = 64 + end if + end if + if (@src.size shr 1 - 1) and not 15 + 16 <> @dest.size | @src.size > 64 + err 'invalid operand size' + end if + AVX_512.store_instruction@src @src.size,vex_mpw,evex_f,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vcvtdq2ps,VEX_0F_W0,EVEX_AS_VEX+EVEX_VL,5Bh, vcvtudq2ps,VEX_F2_0F_W0,EVEX_REQUIRED+EVEX_VL,7Ah, \ + vcvtps2dq,VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,5Bh, vcvtps2udq,VEX_0F_W0,EVEX_REQUIRED+EVEX_VL,79h + + macro instr? dest*,src*& + AVX_512.single_source_instruction_bcst_er vex_mpw,evex_f,opcode,4,dest,src + end macro + + end iterate + + + iterate , vcvttps2dq,VEX_F3_0F_W0,EVEX_AS_VEX+EVEX_VL,5Bh, vcvttps2udq,VEX_0F_W0,EVEX_REQUIRED+EVEX_VL,78h + + macro instr? dest*,src*& + AVX_512.single_source_instruction_bcst_sae vex_mpw,evex_f,opcode,4,dest,src + end macro + + end iterate + + macro vcvtph2ps? dest*,src_sae*& + AVX_512.parse_k1z_operand@dest dest + match src=,sae, src_sae + AVX_512.parse_operand@src src + AVX_512.parse_sae@src sae + else + AVX_512.parse_operand@src src_sae + end match + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if (@src.type = 'mem' & @src.size and not (@dest.size shr 1)) | (@src.type = 'mmreg' & (@dest.size shr 1 - 1) and not 15 + 16 <> @src.size) + err 'invalid operand size' + end if + if @src.memsize = 0 + @src.memsize = @dest.size shr 1 + end if + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,13h,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro vcvtps2ph? dest*,src*,aux*& + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + match sae=,imm, aux + AVX_512.parse_sae@dest sae + x86.parse_operand@aux imm + else + x86.parse_operand@aux aux + end match + if (@dest.type = 'mem' | @dest.type = 'mmreg') & @src.type = 'mmreg' + if (@dest.type = 'mem' & @dest.size and not (@src.size shr 1)) | (@dest.type = 'mmreg' & (@src.size shr 1 - 1) and not 15 + 16 <> @dest.size) + err 'invalid operand size' + end if + if @dest.memsize = 0 + @dest.memsize = @src.size shr 1 + end if + AVX_512.store_instruction@dest @src.size,VEX_66_0F3A_W0,EVEX_AS_VEX+EVEX_VL,1Dh,@dest.mask,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vcvtsd2si,VEX_F2_0F,EVEX_AS_VEX,2Dh,8, vcvtss2si,VEX_F3_0F,EVEX_AS_VEX,2Dh,4, \ + vcvtsd2usi,VEX_F2_0F,EVEX_REQUIRED,79h,8, vcvtss2usi,VEX_F3_0F,EVEX_REQUIRED,79h,4 + + macro instr? dest*,src_er*& + x86.parse_operand@dest dest + match src=,er, src_er + AVX_512.parse_operand@src src + AVX_512.parse_er@src er,16 + else + AVX_512.parse_operand@src src_er + end match + if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'mmreg') + if (@dest.size <> 4 & @dest.size <> 8) | (@src.type = 'mem' & @src.size and not msize) | (@src.type = 'mmreg' & @src.size <> 16) + err 'invalid operand size' + end if + if @dest.size = 8 + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX_512.store_instruction@src 16,vex_mp#_W1,evex_f,opcode,0,@dest.rm + else + AVX_512.store_instruction@src 16,vex_mp#_W0,evex_f,opcode,0,@dest.rm + end if + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vcvttsd2si,VEX_F2_0F,EVEX_AS_VEX,2Ch,8, vcvttss2si,VEX_F3_0F,EVEX_AS_VEX,2Ch,4, \ + vcvttsd2usi,VEX_F2_0F,EVEX_REQUIRED,78h,8, vcvttss2usi,VEX_F3_0F,EVEX_REQUIRED,78h,4 + + macro instr? dest*,src_sae*& + x86.parse_operand@dest dest + match src=,sae, src_sae + AVX_512.parse_operand@src src + AVX_512.parse_sae@src sae + else + AVX_512.parse_operand@src src_sae + end match + if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'mmreg') + if (@dest.size <> 4 & @dest.size <> 8) | (@src.type = 'mem' & @src.size and not msize) | (@src.type = 'mmreg' & @src.size <> 16) + err 'invalid operand size' + end if + if @dest.size = 8 + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX_512.store_instruction@src 16,vex_mp#_W1,evex_f,opcode,0,@dest.rm + else + AVX_512.store_instruction@src 16,vex_mp#_W0,evex_f,opcode,0,@dest.rm + end if + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vcvtsd2ss? dest*,src*,src2*& + AVX_512.basic_instruction_er VEX_F2_0F_W0,EVEX_W1,5Ah,8,dest,src,src2 + end macro + + macro vcvtss2sd? dest*,src*,src2*& + AVX_512.basic_instruction_sae VEX_F3_0F_W0,EVEX_AS_VEX,5Ah,4,dest,src,src2 + end macro + + iterate , vcvtsi2sd,EVEX_AS_VEX,2Ah, vcvtusi2sd,EVEX_REQUIRED,7Bh + + macro instr? dest*,src*,src_er*& + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + match src2=,er, src_er + AVX_512.parse_operand@src2 src2 + AVX_512.parse_er@src2 er,8 + else + AVX_512.parse_operand@src2 src_er + end match + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'reg' | @src2.type = 'mem') + if @src.size = 0 + err ' operand size not specified' + else if @dest.size <> 16 | @src.size <> 16 | (@src2.size <> 4 & @src2.size <> 8) + err 'invalid operand size' + end if + if @src2.size = 8 + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX_512.store_instruction@src2 16,VEX_F2_0F_W1,evex_f,opcode,0,@dest.rm,@src.rm + else + AVX_512.store_instruction@src2 16,VEX_F2_0F_W0,evex_f,opcode,0,@dest.rm,@src.rm + end if + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vcvtsi2ss,EVEX_AS_VEX,2Ah, vcvtusi2ss,EVEX_REQUIRED,7Bh + + macro instr? dest*,src*,src_er*& + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + match src2=,er, src_er + AVX_512.parse_operand@src2 src2 + AVX_512.parse_er@src2 er,@src2.size + else + AVX_512.parse_operand@src2 src_er + end match + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'reg' | @src2.type = 'mem') + if @src.size = 0 + err ' operand size not specified' + else if @dest.size <> 16 | @src.size <> 16 | (@src2.size <> 4 & @src2.size <> 8) + err 'invalid operand size' + end if + if @src2.size = 8 + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX_512.store_instruction@src2 16,VEX_F3_0F_W1,evex_f,opcode,0,@dest.rm,@src.rm + else + AVX_512.store_instruction@src2 16,VEX_F3_0F_W0,evex_f,opcode,0,@dest.rm,@src.rm + end if + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vmovapd,VEX_66_0F_W0,EVEX_W1+EVEX_VL,28h,29h, vmovaps,VEX_0F_W0,EVEX_AS_VEX+EVEX_VL,28h,29h, \ + vmovupd,VEX_66_0F_W0,EVEX_W1+EVEX_VL,10h,11h, vmovups,VEX_0F_W0,EVEX_AS_VEX+EVEX_VL,10h,11h, \ + vmovdqa32,VEX_66_0F_W0,EVEX_REQUIRED+EVEX_VL,6Fh,7Fh, vmovdqa64,VEX_66_0F_W1,EVEX_REQUIRED+EVEX_VL,6Fh,7Fh, \ + vmovdqu32,VEX_F3_0F_W0,EVEX_REQUIRED+EVEX_VL,6Fh,7Fh, vmovdqu64,VEX_F3_0F_W1,EVEX_REQUIRED+EVEX_VL,6Fh,7Fh + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src @dest.size,vex_mpw,evex_f,opcode_rm,@dest.mask,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not @src.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@dest @src.size,vex_mpw,evex_f,opcode_mr,@dest.mask,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vmovd? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'reg' | @src.type = 'mem') + if @dest.size <> 16 | @src.size and not 4 + err 'invalid operand size' + end if + @src.memsize = 4 + AVX_512.store_instruction@src 16,VEX_66_0F_W0,EVEX_AS_VEX,6Eh,0,@dest.rm + else if (@dest.type = 'reg' | @dest.type = 'mem') & @src.type = 'mmreg' + if @dest.size and not 4 | @src.size <> 16 + err 'operand sizes do not match' + end if + @dest.memsize = 4 + AVX_512.store_instruction@dest 16,VEX_66_0F_W0,EVEX_AS_VEX,7Eh,0,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro vmovq? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if @dest.size <> 16 | (@src.type = 'mmreg' & @src.size <> 16) | (@src.type = 'mem' and @src.size and not 8) + err 'invalid operand size' + end if + @src.memsize = 8 + AVX_512.store_instruction@src 16,VEX_F3_0F_W0,EVEX_W1,7Eh,0,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not 8 | @src.size <> 16 + err 'invalid operand size' + end if + @dest.memsize = 8 + AVX_512.store_instruction@dest 16,VEX_66_0F_W0,EVEX_W1,0D6h,0,@src.rm + else if @dest.type = 'mmreg' & @src.type = 'reg' + if @dest.size <> 16 | @src.size <> 8 + err 'invalid operand size' + end if + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX_512.store_instruction@src 16,VEX_66_0F_W1,EVEX_W1,6Eh,0,@dest.rm + else if @dest.type = 'reg' & @src.type = 'mmreg' + if @dest.size <> 8 | @src.size <> 16 + err 'invalid operand size' + end if + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX_512.store_instruction@dest 16,VEX_66_0F_W1,EVEX_W1,7Eh,0,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro vmovddup? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if @src.type = 'mem' & @dest.size = 16 + if @src.size and not 8 + err 'invalid operand size' + end if + @src.memsize = 8 + else + if @src.size and not @dest.size + err 'operand sizes do not match' + end if + @src.memsize = @dest.size + end if + AVX_512.store_instruction@src @dest.size,VEX_F2_0F_W0,EVEX_W1+EVEX_VL,12h,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vmovhlps,12h, vmovlhps,16h + + macro instr? dest*,src*,src2* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'mmreg' + if @dest.size <> 16 + err 'invalid operand size' + else if @src.size <> @dest.size | @src2.size <> @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 16,VEX_0F_W0,EVEX_AS_VEX,opcode,0,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vmovhpd,VEX_66_0F_W0,EVEX_W1,16h, vmovhps,VEX_0F_W0,EVEX_AS_VEX,16h, vmovlpd,VEX_66_0F_W0,EVEX_W1,12h, vmovlps,VEX_0F_W0,EVEX_AS_VEX,12h + + macro instr? dest*,src*,src2 + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + match , src2 + if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not 8 | @src.size <> 16 + err 'invalid operand size' + end if + @dest.memsize = 8 + AVX_512.store_instruction@dest 16,vex_mpw,evex_f,opcode+1,0,@src.rm + else + err 'invalid combination of operands' + end if + else + AVX_512.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'mem' + if @dest.size <> 16 | @src.size <> 16 | @src2.size and not 8 + err 'invalid operand size' + end if + @src2.memsize = 8 + AVX_512.store_instruction@src2 16,vex_mpw,evex_f,opcode,0,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end match + end macro + + end iterate + + iterate , vmovntdq,VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,0E7h, vmovntpd,VEX_66_0F_W0,EVEX_W1+EVEX_VL,2Bh, vmovntps,VEX_0F_W0,EVEX_AS_VEX+EVEX_VL,2Bh + + macro instr? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not @src.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@dest @src.size,vex_mpw,evex_f,opcode,0,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + macro vmovntdqa? dest*,src* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mem' + if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,2Ah,0,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , vmovsd,VEX_F2_0F_W0,EVEX_W1,8, vmovss,VEX_F3_0F_W0,EVEX_AS_VEX,4 + + macro instr? dest*,src*,src2 + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + match , src2 + if @dest.type = 'mmreg' & @src.type = 'mem' + if @dest.size <> 16 | @src.size and not msize + err 'invalid operand size' + end if + @src.memsize = msize + AVX_512.store_instruction@src 16,vex_mpw,evex_f,10h,@dest.mask,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not msize | @src.size <> 16 + err 'invalid operand size' + end if + @dest.memsize = msize + AVX_512.store_instruction@dest 16,vex_mpw,evex_f,11h,@dest.mask,@src.rm + else + err 'invalid combination of operands' + end if + else + AVX_512.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & @src2.type = 'mmreg' + if @dest.size <> 16 | @src.size <> 16 | @src2.size <> 16 + err 'invalid operand size' + end if + AVX_512.store_instruction@src2 16,vex_mpw,evex_f,10h,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end match + end macro + + end iterate + + macro vmovshdup? dest*,src* + AVX_512.single_source_instruction VEX_F3_0F_W0,EVEX_AS_VEX+EVEX_VL,16h,0,dest,src + end macro + + macro vmovsldup? dest*,src* + AVX_512.single_source_instruction VEX_F3_0F_W0,EVEX_AS_VEX+EVEX_VL,12h,0,dest,src + end macro + + iterate , vpermilps,4,EVEX_AS_VEX+EVEX_VL,0Ch,4, vpermilpd,8,EVEX_W1+EVEX_VL,0Dh,5 + + macro instr? dest*,src*,src2* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_bcst_operand@src src,unit + AVX_512.parse_bcst_operand@src2 src2,unit + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @dest.size,VEX_66_0F38_W0,evex_f,opcode_rrm,@dest.mask,@dest.rm,@src.rm + else if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @src2.type = 'imm' + if @src2.size and not 1 + err 'invalid operand size' + else if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src @dest.size,VEX_66_0F3A_W0,evex_f,opcode_rri,@dest.mask,@dest.rm,,1,@src2.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vpaddd,0FEh, vpsubd,0FAh, vpunpckhdq,6Ah, vpunpckldq,62h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2 + end macro + + end iterate + + iterate , vpaddq,0D4h, vpmuludq,0F4h, vpsubq,0FBh, vpunpckhqdq,6Dh, vpunpcklqdq,6Ch + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F_W0,EVEX_W1+EVEX_VL,opcode,8,dest,src,src2 + end macro + + end iterate + + iterate , vpandd,0DBh, vpandnd,0DFh, vpord,0EBh, vpxord,0EFh + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F_W0,EVEX_REQUIRED+EVEX_VL,opcode,4,dest,src,src2 + end macro + + end iterate + + iterate , vpandq,0DBh, vpandnq,0DFh, vporq,0EBh, vpxorq,0EFh + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2 + end macro + + end iterate + + iterate , vpmaxsd,3Dh, vpmaxud,3Fh, vpminsd,39h, vpminud,3Bh, vpmulld,40h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2 + end macro + + end iterate + + iterate , vpmuldq,28h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F38_W0,EVEX_W1+EVEX_VL,opcode,8,dest,src,src2 + end macro + + end iterate + + iterate , vpmuldq,28h, vpmaxsq,3Dh, vpmaxuq,3Fh, vpminsq,39h, vpminuq,3Bh, vpmullq,40h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2 + end macro + + end iterate + + iterate , vpabsd,1Eh + + macro instr? dest*,src* + AVX_512.single_source_instruction_bcst VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src + end macro + + end iterate + + iterate , vpabsq,1Fh + + macro instr? dest*,src* + AVX_512.single_source_instruction_bcst VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src + end macro + + end iterate + + iterate , vpshufd,VEX_66_0F_W0 + + macro instr? dest*,src*,aux* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm' + if @aux.size and not 1 + err 'invalid operand size' + else if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_AS_VEX+EVEX_VL,70h,@dest.mask,@dest.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vpsllvd,47h, vpsrlvd,45h, vpsravd,46h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,4,dest,src,src2 + end macro + + end iterate + + iterate , vpsllvq,EVEX_AS_VEX+EVEX_VL,47h, vpsrlvq,EVEX_AS_VEX+EVEX_VL,45h, vpsravq,EVEX_REQUIRED+EVEX_VL,46h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst VEX_66_0F38_W1,evex_f,opcode,8,dest,src,src2 + end macro + + end iterate + + iterate , vpermi2d,4,VEX_66_0F38_W0,76h, vpermi2q,8,VEX_66_0F38_W1,76h, \ + vpermt2d,4,VEX_66_0F38_W0,7Eh, vpermt2q,8,VEX_66_0F38_W1,7Eh, \ + vprorvd,4,VEX_66_0F38_W0,14h, vprorvq,8,VEX_66_0F38_W1,14h, \ + vprolvd,4,VEX_66_0F38_W0,15h, vprolvq,8,VEX_66_0F38_W1,15h + + macro instr? dest*,src*,src2* + AVX_512.basic_instruction_bcst vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src,src2 + end macro + + end iterate + + iterate , vprord,4,VEX_66_0F_W0,0, vprorq,8,VEX_66_0F_W1,0, vprold,4,VEX_66_0F_W0,1, vprolq,8,VEX_66_0F_W1,1 + + macro instr? dest*,src*,aux* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_bcst_operand@src src,unit + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm' + if @src.size and not @dest.size | @aux.size and not 1 + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src @dest.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,72h,@dest.mask,postbyte,@dest.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vpslld,0F2h,72h,6, vpsrad,0E2h,72h,4, vpsrld,0D2h,72h,2 + + macro instr? dest*,src*,src2* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src2 src2 + if @src2.type = 'imm' + AVX_512.parse_bcst_operand@src src,4 + else + AVX_512.parse_operand@src src + end if + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + @src2.memsize = 16 + if @src2.size and not @src2.memsize + err 'invalid operand size' + else if @src.size <> @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @dest.size,VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode_rrm,@dest.mask,@dest.rm,@src.rm + else if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') & @src2.type = 'imm' + if @src2.size and not 1 + err 'invalid operand size' + else if @src.size <> @dest.size + err 'operand sizes do not match' + end if + if @src.type = 'mem' + AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,postbyte,@dest.rm,1,@src2.imm + else + AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_AS_VEX+EVEX_VL,opcode,@dest.mask,postbyte,@dest.rm,1,@src2.imm + end if + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vpsllq,0F3h,73h,6, vpsraq,0E2h,72h,4, vpsrlq,0D3h,73h,2 + + macro instr? dest*,src*,src2* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src2 src2 + if @src2.type = 'imm' + AVX_512.parse_bcst_operand@src src,8 + else + AVX_512.parse_operand@src src + end if + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + @src2.memsize = 16 + if @src2.size and not @src2.memsize + err 'invalid operand size' + else if @src.size <> @dest.size + err 'operand sizes do not match' + end if + if `instr = 'vpsraq' + AVX_512.store_instruction@src2 @dest.size,VEX_66_0F_W1,EVEX_REQUIRED+EVEX_VL,opcode_rrm,@dest.mask,@dest.rm,@src.rm + else + AVX_512.store_instruction@src2 @dest.size,VEX_66_0F_W0,EVEX_W1+EVEX_VL,opcode_rrm,@dest.mask,@dest.rm,@src.rm + end if + else if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') & @src2.type = 'imm' + if @src2.size and not 1 + err 'invalid operand size' + else if @src.size and not @dest.size + err 'operand sizes do not match' + end if + if @src.type = 'mem' | `instr = 'vpsraq' + AVX_512.store_instruction@src @dest.size,VEX_66_0F_W1,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,postbyte,@dest.rm,1,@src2.imm + else + AVX_512.store_instruction@src @dest.size,VEX_66_0F_W0,EVEX_W1+EVEX_VL,opcode,@dest.mask,postbyte,@dest.rm,1,@src2.imm + end if + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vpcmpeqd,76h, vpcmpgtd,66h + + macro instr? dest*,src*,src2* + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_bcst_operand@src2 src2,4 + if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src2.size and not @src.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @src.size,VEX_66_0F_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm + else if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @src.size,VEX_66_0F_W0,EVEX_FORBIDDEN,opcode,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vpcmpeqq,29h, vpcmpgtq,37h + + macro instr? dest*,src*,src2* + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_bcst_operand@src2 src2,8 + if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src2.size and not @src.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @src.size,VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm + else if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @src.size,VEX_66_0F38_W0,EVEX_FORBIDDEN,opcode,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vptestnmd,4,VEX_F3_0F38_W0,27h, vptestnmq,8,VEX_F3_0F38_W1,27h, vptestmd,4,VEX_66_0F38_W0,27h, vptestmq,8,VEX_66_0F38_W1,27h + + macro instr? dest*,src*,src2* + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_bcst_operand@src2 src2,unit + if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @src2.size and not @src.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vpcmpd,4,VEX_66_0F3A_W0,1Fh, vpcmpud,4,VEX_66_0F3A_W0,1Eh, vpcmpq,8,VEX_66_0F3A_W1,1Fh, vpcmpuq,8,VEX_66_0F3A_W1,1Eh + + macro instr? dest*,src*,src2*,aux* + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_bcst_operand@src2 src2,unit + x86.parse_operand@aux aux + if @dest.type = 'maskreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm' + if @src2.size and not @src.size | @aux.size and not 1 + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vpmovsxbd,21h,4, vpmovsxbq,22h,2, vpmovsxwd,23h,8, vpmovsxwq,24h,4, vpmovsxdq,25h,8, \ + vpmovzxbd,31h,4, vpmovzxbq,32h,2, vpmovzxwd,33h,8, vpmovzxwq,34h,4, vpmovzxdq,35h,8 + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + @src.memsize = msize * (@dest.size shr 4) + if (@src.type = 'mmreg' & @src.size <> (@src.memsize-1) and not 15 + 16) | (@src.type = 'mem' & @src.size and not @src.memsize) + err 'invalid operand size' + end if + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,@dest.mask,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vpermq,0, vpermpd,1 + + macro instr? dest*,src*,aux* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_bcst_operand@src src,8 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm' + if @dest.size < 32 | @aux.size and not 1 + err 'invalid operand size' + else if @src.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src @dest.size,VEX_66_0F3A_W1,EVEX_AS_VEX+EVEX_VL,opcode,@dest.mask,@dest.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vpermd,36h, vpermps,16h + + macro instr? dest*,src*,src2* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_bcst_operand@src2 src2,4 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @dest.size < 32 + err 'invalid operand size' + else if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@src2 @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vfmaddsub,6, vfmsubadd,7, vfmaddsub,8, vfmsub,0Ah, vfnmadd,0Ch, vfnmsub,0Eh + + iterate , 132,90h, 213,0A0h, 231,0B0h + + macro instr#order#pd? dest*,src*,src2*& + AVX_512.basic_instruction_bcst_er VEX_66_0F38_W1,EVEX_AS_VEX+EVEX_VL,hcode+lcode,8,dest,src,src2 + end macro + + macro instr#order#ps? dest*,src*,src2*& + AVX_512.basic_instruction_bcst_er VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,hcode+lcode,4,dest,src,src2 + end macro + + if lcode > 7 + + macro instr#order#sd? dest*,src*,src2*& + AVX_512.basic_instruction_er VEX_66_0F38_W1,EVEX_AS_VEX,hcode+lcode+1,8,dest,src,src2 + end macro + + macro instr#order#ss? dest*,src*,src2*& + AVX_512.basic_instruction_er VEX_66_0F38_W0,EVEX_AS_VEX,hcode+lcode+1,4,dest,src,src2 + end macro + + end if + + end iterate + + end iterate + + iterate , valignd,4,VEX_66_0F3A_W0,3, vpternlogd,4,VEX_66_0F3A_W0,25h, vpternlogq,8,VEX_66_0F3A_W1,25h + + macro instr? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_bcst_imm8 vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src,src2,aux + end macro + + end iterate + + iterate , valignq,3 + + macro instr? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_bcst_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2,aux + end macro + + end iterate + + iterate , vblendmps,65h, vpblendmd,64h + + macro instr? dest*,src*,src2*& + AVX_512.basic_instruction_bcst VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,4,dest,src,src2 + end macro + + end iterate + + iterate , vblendmpd,65h, vpblendmq,64h + + macro instr? dest*,src*,src2*& + AVX_512.basic_instruction_bcst VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2 + end macro + + end iterate + + iterate , vrcp14ps,4,VEX_66_0F38_W0,4Ch, vrcp14pd,8,VEX_66_0F38_W1,4Ch, vrsqrt14ps,4,VEX_66_0F38_W0,4Eh, vrsqrt14pd,8,VEX_66_0F38_W1,4Eh + + macro instr? dest*,src*& + AVX_512.single_source_instruction_bcst vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,unit,dest,src + end macro + + end iterate + + iterate , vrcp14ss,4,VEX_66_0F38_W0,4Dh, vrcp14sd,8,VEX_66_0F38_W1,4Dh, vrsqrt14ss,4,VEX_66_0F38_W0,4Fh, vrsqrt14sd,8,VEX_66_0F38_W1,4Fh + + macro instr? dest*,src*& + AVX_512.basic_instruction vex_mpw,EVEX_REQUIRED,opcode,unit,dest,src + end macro + + end iterate + + iterate , vcompressps,VEX_66_0F_W0,8Ah, vcompresspd,VEX_66_0F_W1,8Ah, vpcompressd,VEX_66_0F38_W0,8Bh, vpcompressq,VEX_66_0F38_W1,8Bh + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' + if @dest.size and not @src.size + err 'operand sizes do not match' + end if + AVX_512.store_instruction@dest @src.size,vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vexpandps,VEX_66_0F38_W0,88h, vexpandpd,VEX_66_0F38_W1,88h, vpexpandd,VEX_66_0F38_W0,89h, vpexpandq,VEX_66_0F38_W1,89h + + macro instr? dest*,src* + AVX_512.single_source_instruction vex_mpw,EVEX_REQUIRED+EVEX_VL,opcode,0,dest,src + end macro + + end iterate + + iterate , fixupimm,54h + + macro v#instr#pd? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_bcst_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src,src2,aux + end macro + + macro v#instr#ps? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_bcst_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED+EVEX_VL,opcode,4,dest,src,src2,aux + end macro + + macro v#instr#sd? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED,opcode+1,8,dest,src,src2,aux + end macro + + macro v#instr#ss? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED,opcode+1,4,dest,src,src2,aux + end macro + + end iterate + + iterate , getexp,42h + + macro v#instr#pd? dest*,src*& + AVX_512.single_source_instruction_bcst_sae VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,8,dest,src + end macro + + macro v#instr#ps? dest*,src*& + AVX_512.single_source_instruction_bcst_sae VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,4,dest,src + end macro + + macro v#instr#sd? dest*,src*,src2*& + AVX_512.basic_instruction_sae VEX_66_0F38_W1,EVEX_REQUIRED,opcode+1,8,dest,src,src2 + end macro + + macro v#instr#ss? dest*,src*,src2*& + AVX_512.basic_instruction_sae VEX_66_0F38_W0,EVEX_REQUIRED,opcode+1,4,dest,src,src2 + end macro + + end iterate + + iterate , getmant,26h,26h,27h,27h, rndscale,8,9,0Ah,0Bh + + macro v#instr#pd? dest*,src*,aux*& + AVX_512.single_source_instruction_bcst_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED+EVEX_VL,opcode_pd,8,dest,src,aux + end macro + + macro v#instr#ps? dest*,src*,aux*& + AVX_512.single_source_instruction_bcst_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED+EVEX_VL,opcode_ps,4,dest,src,aux + end macro + + macro v#instr#sd? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W1,EVEX_REQUIRED,opcode_sd,8,dest,src,src2,aux + end macro + + macro v#instr#ss? dest*,src*,src2*,aux*& + AVX_512.basic_instruction_sae_imm8 VEX_66_0F3A_W0,EVEX_REQUIRED,opcode_ss,4,dest,src,src2,aux + end macro + + end iterate + + iterate , vscalefpd,8,VEX_66_0F38_W1, vscalefps,4,VEX_66_0F38_W0 + + macro instr? dest*,src*,src2*& + AVX_512.basic_instruction_bcst_er vex_mpw,EVEX_REQUIRED+EVEX_VL,2Ch,unit,dest,src,src2 + end macro + + end iterate + + iterate , vscalefsd,8,VEX_66_0F38_W1, vscalefss,4,VEX_66_0F38_W0 + + macro instr? dest*,src*,src2*& + AVX_512.basic_instruction_er vex_mpw,EVEX_REQUIRED,2Dh,unit,dest,src,src2 + end macro + + end iterate + + iterate , vpmovusdb,4,11h, vpmovsdb,4,21h, vpmovdb,4,31h, \ + vpmovusqb,8,12h, vpmovsqb,8,22h, vpmovqb,8,32h, \ + vpmovusdw,2,13h, vpmovsdw,2,23h, vpmovdw,2,33h, \ + vpmovusqw,4,14h, vpmovsqw,4,24h, vpmovqw,4,34h, \ + vpmovusqd,2,15h, vpmovsqd,2,25h, vpmovqd,2,35h + + macro instr? dest*,src* + AVX_512.parse_k1z_operand@dest dest + AVX_512.parse_operand@src src + if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' + @dest.memsize = @src.size / ratio + if (@dest.type = 'mmreg' & @dest.size <> (@dest.memsize-1) and not 15 + 16) | (@dest.type = 'mem' & @dest.size and not @dest.memsize) + err 'invalid operand size' + end if + AVX_512.store_instruction@dest @src.size,VEX_F3_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vpgatherdd,90h,4, vpgatherqd,91h,8, vgatherdps,92h,4, vgatherqps,93h,8 + + macro instr? dest*,src*,aux + match , aux + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_vsib_operand@src src + if @dest.type = 'mmreg' & @dest.mask & @src.type = 'mem' + if @src.size and not 4 | (@dest.size > 16 & @dest.size * (asize shr 2) > @src.visize) | (@src.visize > 16 & @dest.size * (asize shr 2) < @src.visize) + err 'invalid operand size' + else if @dest.rm = @src.index + err 'disallowed combination of registers' + end if + @src.memsize = 4 + AVX_512.store_instruction@src @src.visize,VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.index and 10000b + else + err 'invalid combination of operands' + end if + else + AVX.parse_operand@dest dest + AVX.parse_vsib_operand@src src + AVX.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mem' & @aux.type = 'mmreg' + if @src.size and not 4 | (@dest.size > 16 & @dest.size * (asize shr 2) > @src.visize) | (@src.visize > 16 & @dest.size * (asize shr 2) < @src.visize) + err 'invalid operand size' + else if @aux.size <> @dest.size + err 'operand sizes do not match' + else if @dest.rm = @aux.rm | @dest.rm = @src.index | @aux.rm = @src.index + err 'disallowed combination of registers' + end if + AVX.store_instruction@src @src.visize,VEX_66_0F38_W0,opcode,@dest.rm,@aux.rm + else + err 'invalid combination of operands' + end if + end match + end macro + + end iterate + + iterate , vpgatherdq,90h,4, vpgatherqq,91h,8, vgatherdpd,92h,4, vgatherqpd,93h,8 + + macro instr? dest*,src*,aux + match , aux + AVX_512.parse_k1_operand@dest dest + AVX_512.parse_vsib_operand@src src + if @dest.type = 'mmreg' & @dest.mask & @src.type = 'mem' + if @src.size and not 8 | (@dest.size > 16 & @dest.size * (asize shr 2) > @src.visize * 2) | (@src.visize > 16 & @dest.size * (asize shr 2) < @src.visize * 2) + err 'invalid operand size' + else if @dest.rm = @src.index + err 'disallowed combination of registers' + end if + @src.memsize = 8 + AVX_512.store_instruction@src @dest.size,VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@dest.rm,@src.index and 10000b + else + err 'invalid combination of operands' + end if + else + AVX.parse_operand@dest dest + AVX.parse_vsib_operand@src src + AVX.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mem' & @aux.type = 'mmreg' + if @src.size and not 8 | (@dest.size > 16 & @dest.size * (asize shr 2) > @src.visize * 2) | (@src.visize > 16 & @dest.size * (asize shr 2) < @src.visize * 2) + err 'invalid operand size' + else if @aux.size <> @dest.size + err 'operand sizes do not match' + else if @dest.rm = @aux.rm | @dest.rm = @src.index | @aux.rm = @src.index + err 'disallowed combination of registers' + end if + AVX.store_instruction@src @dest.size,VEX_66_0F38_W1,opcode,@dest.rm,@aux.rm + else + err 'invalid combination of operands' + end if + end match + end macro + + end iterate + + iterate , vpscatterdd,0A0h,4, vpscatterqd,0A1h,8, vscatterdps,0A2h,4, vscatterqps,0A3h,8 + + macro instr? dest*,src* + AVX_512.parse_k1_vsib_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mem' & @dest.mask & @src.type = 'mmreg' + if @dest.size and not 4 | (@src.size > 16 & @src.size * (asize shr 2) > @dest.visize) | (@dest.visize > 16 & @src.size * (asize shr 2) < @dest.visize) + err 'invalid operand size' + else if @src.rm = @dest.index + err 'disallowed combination of registers' + end if + @dest.memsize = 4 + AVX_512.store_instruction@dest @dest.visize,VEX_66_0F38_W0,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm,@dest.index and 10000b + else + err 'invalid combination of operands' + end if + end macro + + end iterate + + iterate , vpscatterdq,0A0h,4, vpscatterqq,0A1h,8, vscatterdpd,0A2h,4, vscatterqpd,0A3h,8 + + macro instr? dest*,src* + AVX_512.parse_k1_vsib_operand@dest dest + AVX_512.parse_operand@src src + if @dest.type = 'mem' & @dest.mask & @src.type = 'mmreg' + if @dest.size and not 8 | (@src.size > 16 & @src.size * (asize shr 2) > @dest.visize * 2) | (@dest.visize > 16 & @src.size * (asize shr 2) < @dest.visize * 2) + err 'invalid operand size' + else if @src.rm = @dest.index + err 'disallowed combination of registers' + end if + @dest.memsize = 8 + AVX_512.store_instruction@dest @src.size,VEX_66_0F38_W1,EVEX_REQUIRED+EVEX_VL,opcode,@dest.mask,@src.rm,@dest.index and 10000b + else + err 'invalid combination of operands' + end if + end macro + + end iterate + +end if diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512pf.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512pf.inc new file mode 100644 index 0000000..6944016 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512pf.inc @@ -0,0 +1,62 @@ + +if ~ defined AVX_512 + + include 'avx512f.inc' + +end if + +iterate , gatherpf0,1 ,gatherpf1,2 ,scatterpf0,5, scatterpf1,6 + + macro v#instr#dps? src* + AVX_512.parse_k1_vsib_operand@src src + if @src.type = 'mem' & @src.mask + if @src.size and not 4 | @src.visize <> 64 + err 'invalid operand size' + end if + @src.memsize = 4 + AVX_512.store_instruction@src 64,VEX_66_0F38_W0,EVEX_REQUIRED,0C6h,@src.mask,postbyte,@src.index and 10000b + else + err 'invalid combination of operands' + end if + end macro + + macro v#instr#qps? src* + AVX_512.parse_k1_vsib_operand@src src + if @src.type = 'mem' & @src.mask + if @src.size and not 8 | @src.visize <> 64 + err 'invalid operand size' + end if + @src.memsize = 4 + AVX_512.store_instruction@src 64,VEX_66_0F38_W0,EVEX_REQUIRED,0C7h,@src.mask,postbyte,@src.index and 10000b + else + err 'invalid combination of operands' + end if + end macro + + macro v#instr#dpd? src* + AVX_512.parse_k1_vsib_operand@src src + if @src.type = 'mem' & @src.mask + if @src.size and not 4 | @src.visize <> 32 + err 'invalid operand size' + end if + @src.memsize = 8 + AVX_512.store_instruction@src 64,VEX_66_0F38_W1,EVEX_REQUIRED,0C6h,@src.mask,postbyte,@src.index and 10000b + else + err 'invalid combination of operands' + end if + end macro + + macro v#instr#qpd? src* + AVX_512.parse_k1_vsib_operand@src src + if @src.type = 'mem' & @src.mask + if @src.size and not 8 | @src.visize <> 64 + err 'invalid operand size' + end if + @src.memsize = 8 + AVX_512.store_instruction@src 64,VEX_66_0F38_W1,EVEX_REQUIRED,0C7h,@src.mask,postbyte,@src.index and 10000b + else + err 'invalid combination of operands' + end if + end macro + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512vl.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512vl.inc new file mode 100644 index 0000000..0c803fa --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/avx512vl.inc @@ -0,0 +1,8 @@ + +if ~ defined AVX_512 + + include 'avx512f.inc' + +end if + +AVX512VL = 1 diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/bmi1.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/bmi1.inc new file mode 100644 index 0000000..5bed9b2 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/bmi1.inc @@ -0,0 +1,97 @@ + +include 'avx.inc' + +macro andn? dest*,src*,src2* + x86.parse_operand@dest dest + x86.parse_operand@src src + x86.parse_operand@src2 src2 + if @dest.type = 'reg' & @src.type = 'reg' & (@src2.type = 'mem' | @src2.type = 'reg') + if @dest.size < 4 + err 'invalid operand size' + else if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + if @dest.size = 8 + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@src2 16,VEX_0F38_W1,0F2h,@dest.rm,@src.rm + else + AVX.store_instruction@src2 16,VEX_0F38_W0,0F2h,@dest.rm,@src.rm + end if + else + err 'invalid combination of operands' + end if +end macro + +macro bextr? dest*,src*,src2* + x86.parse_operand@dest dest + x86.parse_operand@src src + x86.parse_operand@src2 src2 + if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') & @src2.type = 'reg' + if @dest.size < 4 + err 'invalid operand size' + else if @src.size and not @dest.size | @src2.size <> @dest.size + err 'operand sizes do not match' + end if + if @dest.size = 8 + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@src 16,VEX_0F38_W1,0F7h,@dest.rm,@src2.rm + else + AVX.store_instruction@src 16,VEX_0F38_W0,0F7h,@dest.rm,@src2.rm + end if + else + err 'invalid combination of operands' + end if +end macro + +iterate , blsi,0F3h,3, blsmsk,0F3h,2, blsr,0F3h,1 + + macro instr? dest*,src* + x86.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') + if @dest.size < 4 + err 'invalid operand size' + else if @src.size and not @dest.size + err 'operand sizes do not match' + end if + if @dest.size = 8 + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@src 16,VEX_0F38_W1,opcode,postbyte,@dest.rm + else + AVX.store_instruction@src 16,VEX_0F38_W0,opcode,postbyte,@dest.rm + end if + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , lzcnt,0BDh, tzcnt,0BCh + + macro instr? dest*,src* + x86.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'reg' & ( @src.type = 'reg' | @src.type = 'mem' ) + if @src.size and not @dest.size + err 'operand sizes do not match' + end if + @src.opcode_prefix = 0F3h + if @dest.size > 1 + x86.select_operand_prefix@src @dest.size + x86.store_instruction@src <0Fh,opcode>,@dest.rm + else + err 'invalid operand size' + end if + else + err 'invalid combination of operands' + end if + end macro + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/bmi2.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/bmi2.inc new file mode 100644 index 0000000..1e7f599 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/bmi2.inc @@ -0,0 +1,106 @@ + +include 'bmi1.inc' + +iterate , bzhi,0F5h + + macro instr? dest*,src*,src2* + x86.parse_operand@dest dest + x86.parse_operand@src src + x86.parse_operand@src2 src2 + if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') & @src2.type = 'reg' + if @dest.size < 4 + err 'invalid operand size' + else if @src.size and not @dest.size | @src2.size <> @dest.size + err 'operand sizes do not match' + end if + if @dest.size = 8 + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@src 16,VEX_0F38_W1,opcode,@dest.rm,@src2.rm + else + AVX.store_instruction@src 16,VEX_0F38_W0,opcode,@dest.rm,@src2.rm + end if + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , mulx,VEX_F2_0F38,0F6h, pdep,VEX_F2_0F38,0F5h, pext,VEX_F3_0F38,0F5h + + macro instr? dest*,src*,src2* + x86.parse_operand@dest dest + x86.parse_operand@src src + x86.parse_operand@src2 src2 + if @dest.type = 'reg' & @src.type = 'reg' & (@src2.type = 'mem' | @src2.type = 'reg') + if @dest.size < 4 + err 'invalid operand size' + else if @src.size <> @dest.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + if @dest.size = 8 + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@src2 16,vex_mp#_W1,opcode,@dest.rm,@src.rm + else + AVX.store_instruction@src2 16,vex_mp#_W0,opcode,@dest.rm,@src.rm + end if + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +macro rorx? dest*,src*,src2* + x86.parse_operand@dest dest + x86.parse_operand@src src + x86.parse_operand@src2 src2 + if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') & @src2.type = 'imm' + if @dest.size < 4 | @src2.size and not 1 + err 'invalid operand size' + else if @src.size and not @dest.size + err 'operand sizes do not match' + end if + if @dest.size = 8 + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@src 16,VEX_F2_0F3A_W1,0F0h,@dest.rm,,1,@src2.imm + else + AVX.store_instruction@src 16,VEX_F2_0F3A_W0,0F0h,@dest.rm,,1,@src2.imm + end if + else + err 'invalid combination of operands' + end if +end macro + +iterate , sarx,VEX_F3_0F38,0F7h, shlx,VEX_66_0F38,0F7h, shrx,VEX_F2_0F38,0F7h + + macro instr? dest*,src*,src2* + x86.parse_operand@dest dest + x86.parse_operand@src src + x86.parse_operand@src2 src2 + if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') & @src2.type = 'reg' + if @dest.size < 4 + err 'invalid operand size' + else if @src.size and not @dest.size | @src2.size <> @dest.size + err 'operand sizes do not match' + end if + if @dest.size = 8 + if x86.mode < 64 + err 'instruction requires long mode' + end if + AVX.store_instruction@src 16,vex_mp#_W1,opcode,@dest.rm,@src2.rm + else + AVX.store_instruction@src 16,vex_mp#_W0,opcode,@dest.rm,@src2.rm + end if + else + err 'invalid combination of operands' + end if + end macro + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/cet_ibt.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/cet_ibt.inc new file mode 100644 index 0000000..d7b04fc --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/cet_ibt.inc @@ -0,0 +1,8 @@ + +iterate , endbr32,0FBh, endbr64,0FAh + + macro instr? + db 0F3h,0Fh,1Eh,modrm + end macro + +end iterate \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/cet_ss.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/cet_ss.inc new file mode 100644 index 0000000..294b6e1 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/cet_ss.inc @@ -0,0 +1,106 @@ + +iterate , clrssbsy,0AEh,6, rstorssp,01h,5 + + macro instr? src* + x86.parse_operand@src src + if @src.type = 'mem' + if @src.size and not 8 + err 'invalid operand size' + else + @src.opcode_prefix = 0F3h + x86.store_instruction@src <0Fh,ext>,postbyte + end if + else + err 'invalid operand' + end if + end macro + +end iterate + +iterate , incsspd,0AEh,5, rdsspd,1Eh,1 + + macro instr? src* + x86.parse_operand@src src + if @src.type = 'reg' + if @src.size <> 4 + err 'invalid operand size' + else + @src.opcode_prefix = 0F3h + x86.store_instruction@src <0Fh,ext>,postbyte + end if + else + err 'invalid operand' + end if + end macro + +end iterate + +iterate , incsspq,0AEh,5, rdsspq,1Eh,1 + + macro instr? src* + x86.parse_operand@src src + if @src.type = 'reg' + if @src.size <> 8 + err 'invalid operand size' + else + x86.select_operand_prefix@src 8 + @src.opcode_prefix = 0F3h + x86.store_instruction@src <0Fh,ext>,postbyte + end if + else + err 'invalid operand' + end if + end macro + +end iterate + +iterate , saveprevssp,0EAh, setssbsy,0E8h + + macro instr? + db 0F3h,0Fh,01h,modrm + end macro + +end iterate + +iterate , wrssd,0,0F6h, wrussd,66h,0F5h + + macro instr? dest*,src* + x86.parse_operand@dest dest + x86.parse_operand@src src + local size + if @src.size <> 4 + err 'invalid operand size' + else if @dest.size and not @src.size + err 'operand sizes do not match' + end if + if @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + @dest.opcode_prefix = prefix + x86.store_instruction@dest <0Fh,38h,ext>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate + +iterate , wrssq,0,0F6h, wrussq,66h,0F5h + + macro instr? dest*,src* + x86.parse_operand@dest dest + x86.parse_operand@src src + local size + if @src.size <> 8 + err 'invalid operand size' + else if @dest.size and not @src.size + err 'operand sizes do not match' + end if + if @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + x86.select_operand_prefix@dest 8 + @dest.opcode_prefix = prefix + x86.store_instruction@dest <0Fh,38h,ext>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/f16c.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/f16c.inc new file mode 100644 index 0000000..8fa7d7d --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/f16c.inc @@ -0,0 +1,29 @@ + +include 'avx.inc' + +macro vcvtph2ps? dest*,src* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mmreg' | @src.type = 'mem') + if (@src.type = 'mmreg' & @src.size <> 16) | (@src.type = 'mem' & @src.size*2 <> @dest.size) + err 'invalid operand size' + end if + AVX.store_instruction@src @dest.size,VEX_66_0F38_W0,13h,@dest.rm + else + err 'invalid combination of operands' + end if +end macro + +macro vcvtps2ph? dest*,src*,round* + AVX.parse_operand@dest dest + AVX.parse_operand@src src + x86.parse_operand@aux round + if (@dest.type = 'mmreg' | @dest.type = 'mem') & @src.type = 'mmreg' & @aux.type = 'imm' + if (@dest.type = 'mmreg' & @dest.size <> 16) | (@dest.type = 'mem' & @dest.size*2 <> @src.size) | @aux.size and not 1 + err 'invalid operand size' + end if + AVX.store_instruction@dest @src.size,VEX_66_0F3A_W0,1Dh,@src.rm,,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/fma.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/fma.inc new file mode 100644 index 0000000..e76dad3 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/fma.inc @@ -0,0 +1,30 @@ + +include 'avx.inc' + +iterate , vfmaddsub,6, vfmsubadd,7, vfmadd,8, vfmsub,0Ah, vfnmadd,0Ch, vfnmsub,0Eh + + iterate , 132,90h, 213,0A0h, 231,0B0h + + macro instr#order#pd? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F38_W1,hcode+lcode,0,dest,src,src2 + end macro + + macro instr#order#ps? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F38_W0,hcode+lcode,0,dest,src,src2 + end macro + + if lcode > 7 + + macro instr#order#sd? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F38_W1,hcode+lcode+1,8,dest,src,src2 + end macro + + macro instr#order#ss? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F38_W0,hcode+lcode+1,4,dest,src,src2 + end macro + + end if + + end iterate + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/fsgsbase.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/fsgsbase.inc new file mode 100644 index 0000000..dc3d461 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/fsgsbase.inc @@ -0,0 +1,24 @@ + +iterate , rdfsbase,0, rdgsbase,1, wrfsbase,2, wrgsbase,3 + + macro instr? dest* + if x86.mode = 64 + x86.parse_operand@dest dest + if @dest.type = 'reg' + if @dest.size >= 4 + @dest.opcode_prefix = 0F3h + x86.select_operand_prefix@dest @dest.size + x86.store_instruction@dest <0Fh,0AEh>,postbyte + else + err 'invalid operand size' + end if + else + err 'invalid operand' + end if + else + err 'instruction requires long mode' + end if + end macro + +end iterate + diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/gfni.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/gfni.inc new file mode 100644 index 0000000..812d580 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/gfni.inc @@ -0,0 +1,53 @@ + +include 'sse.inc' + +iterate , gf2p8mulb,0CFh + macro instr? dest*,src* + SSE.basic_instruction 66h,<38h,supp>,16,dest,src + end macro +end iterate + +iterate , gf2p8affineinvqb,0CFh, gf2p8affineqb,0CEh + macro instr? dest*,src*,imm* + SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm + end macro +end iterate + +if defined AVX_512 + + iterate , gf2p8mulb,0CFh + + macro v#instr? dest*,src*,src2*& + AVX_512.basic_instruction VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,dest,src,src2 + end macro + + end iterate + + iterate , gf2p8affineinvqb,0CFh, gf2p8affineqb,0CEh + + macro v#instr? dest*,src*,src2*,imm*& + AVX_512.basic_instruction_bcst_imm8 VEX_66_0F3A_W1,EVEX_W1+EVEX_VL,opcode,8,dest,src,src2,imm + end macro + + end iterate + +else if defined AVX + + iterate , gf2p8mulb,0CFh + + macro v#instr? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F38_W0,opcode,0,dest,src,src2 + end macro + + end iterate + + iterate , gf2p8affineinvqb,0CFh, gf2p8affineqb,0CEh + + macro v#instr? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_66_0F3A_W1,opcode,0,dest,src,src2,imm + end macro + + end iterate + +end if + diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/hle.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/hle.inc new file mode 100644 index 0000000..b21ff71 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/hle.inc @@ -0,0 +1,16 @@ + +macro xacquire? instr& + db 0F2h + instr +end macro + +macro xrelease? instr& + db 0F3h + instr +end macro + +macro xtest? + db 0Fh,1,0D6h +end macro + + diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/invpcid.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/invpcid.inc new file mode 100644 index 0000000..b5fe830 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/invpcid.inc @@ -0,0 +1,15 @@ + +macro invpcid? dest*,src* + x86.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'reg' & @src.type = 'mem' + if (x86.mode < 64 & @dest.size <> 4) | (x86.mode = 64 & @dest.size <> 8) | @src.size and not 16 + err 'invalid operand size' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,38h,82h>,@dest.rm + else + err 'invalid combination of operands' + end if +end macro + diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/mmx.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/mmx.inc new file mode 100644 index 0000000..55fe599 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/mmx.inc @@ -0,0 +1,149 @@ + +if ~ defined MMX + + restore MMX ; this ensures that symbol cannot be forward-referenced + MMX = 1 + + element MMX.reg + + repeat 8, i:0 + element mm#i? : MMX.reg + i + end repeat + + iterate context, @dest,@src,@src2,@aux + + namespace context + + calminstruction MMX.parse_operand#context operand + + call x86.parse_operand#context, operand + + check type = 'imm' & size = 0 + jno done + check imm eq 1 elementof imm & 1 metadataof imm relativeto MMX.reg + jno done + + compute type, 'mmreg' + compute mod, 11b + compute rm, 1 metadataof imm - MMX.reg + compute size, 8 + + done: + + end calminstruction + + end namespace + + end iterate + + calminstruction MMX.basic_instruction ext,dest,src + call MMX.parse_operand@dest, dest + call MMX.parse_operand@src, src + check (@src.size or @dest.size) and not 8 + jno size_ok + err 'invalid operand size' + size_ok: + check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + jno invalid_combination_of_operands + xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + end calminstruction + + iterate , punpcklbw,60h, punpcklwd,61h, punpckldq,62h, packsswb,63h, pcmpgtb,64h, pcmpgtw,65h, pcmpgtd,66h, packuswb,67h, punpckhbw,68h, \ + punpckhwd,69h, punpckhdq,6Ah, packssdw,6Bh, pcmpeqb,74h, pcmpeqw,75h, pcmpeqd,76h, pmullw,0D5h, psubusb,0D8h, psubusw,0D9h, \ + pand,0DBh, paddusb,0DCh, paddusw,0DDh, pandn,0DFh, pmulhw,0E5h, psubsb,0E8h, psubsw,0E9h, por,0EBh, paddsb,0ECh, paddsw,0EDh, \ + pxor,0EFh, pmaddwd,0F5h, psubb,0F8h, psubw,0F9h, psubd,0FAh, paddb,0FCh, paddw,0FDh, paddd,0FEh + + macro instr? dest*,src* + MMX.basic_instruction opcode,dest,src + end macro + + end iterate + + calminstruction movq? dest*,src* + call MMX.parse_operand@dest, dest + call MMX.parse_operand@src, src + check (@src.size or @dest.size) and not 8 + jno size_ok + err 'invalid operand size' + size_ok: + check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + jyes mmreg_mem + check @dest.type = 'mem' & @src.type = 'mmreg' + jyes mem_mmreg + err 'invalid combination of operands' + exit + mmreg_mem: + xcall x86.store_instruction@src, <0Fh,6Fh>,@dest.rm + exit + mem_mmreg: + xcall x86.store_instruction@dest, <0Fh,7Fh>,@src.rm + exit + end calminstruction + + calminstruction movd? dest*,src* + call MMX.parse_operand@dest, dest + call MMX.parse_operand@src, src + check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg') + jyes mmreg_rm + check (@dest.type = 'mem' | @dest.type = 'reg') & @src.type = 'mmreg' + jyes rm_mmreg + err 'invalid combination of operands' + exit + mmreg_rm: + check @src.size and not 4 + jno mmreg_rm_ok + err 'invalid operand size' + mmreg_rm_ok: + xcall x86.store_instruction@src, <0Fh,6Eh>,@dest.rm + exit + rm_mmreg: + check @dest.size and not 4 + jno rm_mmreg_ok + err 'invalid operand size' + rm_mmreg_ok: + xcall x86.store_instruction@dest, <0Fh,7Eh>,@src.rm + end calminstruction + + calminstruction MMX.bit_shift_instruction ext,dest,src + call MMX.parse_operand@dest, dest + call MMX.parse_operand@src, src + check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + jyes mmreg_rm + check @dest.type = 'mmreg' & @src.type = 'imm' + jyes mmreg_imm + err 'invalid combination of operands' + exit + mmreg_rm: + check @src.size and not 8 + jno mmreg_rm_ok + err 'invalid operand size' + mmreg_rm_ok: + xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm + exit + mmreg_imm: + check @src.size and not 1 + jno rm_mmreg_ok + err 'invalid operand size' + rm_mmreg_ok: + local iext, irm + compute iext, 70h+(ext and 0Fh) + compute irm, ((ext shr 4)-0Ch) shl 1 + xcall x86.store_instruction@dest, <0Fh,iext>,irm,byte,@src.imm + end calminstruction + + iterate , psrlw,0D1h, psrld,0D2h, psrlq,0D3h, psrad,0E2h, psraw,0E1h, psllw,0F1h, pslld,0F2h, psllq,0F3h + + macro instr? dest*,src* + MMX.bit_shift_instruction opcode,dest,src + end macro + + end iterate + + macro emms? + db 0Fh,77h + end macro + +end if diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/movdir64b.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/movdir64b.inc new file mode 100644 index 0000000..9b89cec --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/movdir64b.inc @@ -0,0 +1,23 @@ + +if ~ defined AVX512 + define x86.dqqword? :64 + define x86.zword? :64 +end if + +macro movdir64b? dest*,src* + x86.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'reg' & @src.type = 'mem' + if @src.size and not 64 + err 'invalid operand size' + end if + if (@src.mode = 16 & @dest.size <> 2) | (@src.mode = 32 & @dest.size <> 4) | (@src.mode = 64 & @dest.size <> 8) + err 'invalid operand size' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,38h,0F8h>,@dest.rm + else + err 'invalid combination of operands' + end if +end macro + diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/movdiri.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/movdiri.inc new file mode 100644 index 0000000..9bfa26d --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/movdiri.inc @@ -0,0 +1,19 @@ + +macro movdiri? dest*,src* + x86.parse_operand@dest dest + x86.parse_operand@src src + if @src.type = 'reg' & @dest.type = 'mem' + if @dest.size <> 0 & @src.size <> @dest.size + err 'operand sizes do not match' + end if + if @src.size = 8 & x86.mode = 64 + @dest.prefix = 48h + else if @src.size <> 4 + err 'invalid operand size' + end if + x86.store_instruction@dest <0Fh,38h,0F9h>,@src.rm + else + err 'invalid combination of operands' + end if +end macro + diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/mpx.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/mpx.inc new file mode 100644 index 0000000..8493aa1 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/mpx.inc @@ -0,0 +1,196 @@ + +if ~ defined MPX + + restore MPX ; this ensures that symbol cannot be forward-referenced + MPX = 1 + + element MPX.bnd + + repeat 4, i:0 + element bnd#i? : MPX.bnd + i + end repeat + + macro MPX.parse_operand ns,op + x86.parse_operand#ns op + if ns.type = 'imm' & ns.size = 0 & ns.imm eq 1 elementof ns.imm & 1 metadataof ns.imm relativeto MPX.bnd + ns.type = 'bnd' + ns.mod = 11b + ns.rm = 1 metadataof ns.imm - MPX.bnd + ns.size = 0 + end if + end macro + + macro MPX.parse_sib_operand ns,op& + match [b=,si], op + ns.split = 1 + ns.segment_prefix = 0 + ns.prefix = 0 + ns.opcode_prefix = 0 + ns.rex_prefix = 0 + ns.size = 0 + ns.type = 'mem' + ns.base_part = +b + ns.index_part = +si + if x86.mode = 64 + ns.mode = 64 + ns.address_registers_type = x86.r64 + else + ns.mode = 32 + ns.address_registers_type = x86.r32 + end if + ns.base_registers = 0 + ns.index_registers = 0 + repeat elementsof ns.base_part + if % metadataof ns.base_part relativeto x86.r16 | % metadataof ns.base_part relativeto x86.r32 | % metadataof ns.base_part relativeto x86.r64 | % metadataof ns.address relativeto x86.ip + ns.base_registers = ns.base_registers + % elementof ns.base_part * % scaleof ns.base_part + end if + end repeat + repeat elementsof ns.index_part + if % metadataof ns.index_part relativeto x86.r16 | % metadataof ns.index_part relativeto x86.r32 | % metadataof ns.index_part relativeto x86.r64 | % metadataof ns.address relativeto x86.ip + ns.index_registers = ns.index_registers + % elementof ns.index_part * % scaleof ns.index_part + end if + end repeat + ns.displacement = ns.base_part - ns.base_registers + ns.index_part - ns.index_registers + if ns.index_registers eq 0 + ns.index = 4 + ns.scale = 1 + else if elementsof ns.index_registers = 1 & 1 metadataof ns.index_registers relativeto ns.address_registers_type & 1 metadataof ns.index_registers - ns.address_registers_type <> 4 + ns.index = 1 metadataof ns.index_registers - ns.address_registers_type + ns.scale = 1 scaleof ns.index_registers + else + err 'invalid address' + end if + if ns.base_registers eq 0 + ns.rm = 4 + ns.base = 5 + ns.index_only = 1 + else if ns.base_registers eq 1 elementof ns.base_registers & 1 metadataof ns.base_registers relativeto ns.address_registers_type + ns.base = 1 metadataof ns.base_registers - ns.address_registers_type + if ns.index = 4 & ns.base <> 4 + ns.rm = ns.base + else + ns.rm = 4 + end if + ns.index_only = 0 + else + err 'invalid address' + end if + ns.auto_relative = 0 + ns.displacement_size = 4 + ns.mod = 2 + if ns.index_only + ns.mod = 0 + else if ns.displacement relativeto 0 + if ns.displacement = 0 & ns.rm and 111b <> 5 & (ns.rm <> 4 | ns.base and 111b <> 5) + ns.displacement_size = 0 + ns.mod = 0 + else if ns.displacement < 80h & ns.displacement >= -80h + ns.displacement_size = 1 + ns.mod = 1 + else if ns.displacement - 1 shl ns.mode >= -80h & ns.displacement < 1 shl ns.mode + ns.displacement = ns.displacement - 1 shl ns.mode + ns.displacement_size = 1 + ns.mod = 1 + end if + end if + else + ns.split = 0 + x86.parse_operand#ns op + end match + end macro + + macro bndmk? dest*,src*& + MPX.parse_operand @dest,dest + MPX.parse_sib_operand @src,src + if @dest.type = 'bnd' & @src.type = 'mem' + if @src.split & ~ 0 scaleof @src.base_part eq 0 + err 'invalid base address' + end if + if (x86.mode = 64 & @src.size and not 8) | (x86.mode < 64 & @src.size and not 4) + err 'invalid operand size' + end if + @src.opcode_prefix = 0F3h + x86.store_instruction@src <0Fh,1Bh>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro bndmov? dest*,src* + MPX.parse_operand @dest,dest + MPX.parse_operand @src,src + if @dest.type = 'bnd' & (@src.type = 'bnd' | @src.type = 'mem') + if (x86.mode = 64 & @src.size and not 16) | (x86.mode < 64 & @src.size and not 8) + err 'invalid operand size' + end if + if @src.type = 'mem' & @src.mode <> x86.mode + err 'invalid address' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,1Ah>,@dest.rm + else if @dest.type = 'mem' & @src.type = 'bnd' + if (x86.mode = 64 & @dest.size and not 16) | (x86.mode < 64 & @dest.size and not 8) + err 'invalid operand size' + end if + if @dest.type = 'mem' & @dest.mode <> x86.mode + err 'invalid address' + end if + @dest.opcode_prefix = 66h + x86.store_instruction@dest <0Fh,1Bh>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , bndcl,0F3h,1Ah, bndcu,0F2h,1Ah, bndcn,0F2h,1Bh + + macro instr? dest*,src* + MPX.parse_operand @dest,dest + x86.parse_operand @src,src + if @dest.type = 'bnd' & (@src.type = 'reg' | @src.type = 'mem') + if (x86.mode = 64 & @src.size and not 8) | (x86.mode < 64 & @src.size and not 4) + err 'invalid operand size' + end if + if @src.type = 'mem' & @src.mode <> x86.mode + err 'invalid address' + end if + @src.opcode_prefix = prefix + x86.store_instruction@src <0Fh,ext>,@dest.rm + else + err 'invalid operand' + end if + end macro + + end iterate + + macro bndldx? dest*,src*& + MPX.parse_operand @dest,dest + MPX.parse_sib_operand @src,src + if @dest.type = 'bnd' & @src.type = 'mem' + if @src.scale > 1 | ( @src.split & ~ 0 scaleof @src.index_part eq 0 ) + err 'invalid index' + end if + x86.store_instruction@src <0Fh,1Ah>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro bndstx? operands*& + match [dest] =, src, operands + MPX.parse_sib_operand @dest,[dest] + MPX.parse_operand @src,src + if @dest.type = 'mem' & @src.type = 'bnd' + if @dest.scale > 1 | ( @dest.split & ~ 0 scaleof @dest.index_part eq 0 ) + err 'invalid index' + end if + x86.store_instruction@dest <0Fh,1Bh>,@src.rm + else + err 'invalid combination of operands' + end if + else + err 'invalid combination of operands' + end match + end macro + +end if diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/pclmulqdq.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/pclmulqdq.inc new file mode 100644 index 0000000..c11bcaa --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/pclmulqdq.inc @@ -0,0 +1,14 @@ + +include 'sse.inc' + +macro pclmulqdq? dest*,src*,imm* + SSE.basic_instruction_imm8 66h,<3Ah,44h>,16,dest,src,imm +end macro + +if defined AVX + + macro vpclmulqdq? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_66_0F3A_W0,44h,16,dest,src,src2,imm + end macro + +end if diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/ptwrite.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/ptwrite.inc new file mode 100644 index 0000000..65f52df --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/ptwrite.inc @@ -0,0 +1,18 @@ + +macro ptwrite? src* + x86.parse_operand@src src + if @src.size = 0 + err 'operand size not specified' + else if @src.size <> 4 & (@src.size <> 8 | x86.mode <> 64) + err 'invalid operand size' + end if + if @src.type = 'reg' | @src.type = 'mem' + if @src.size = 8 + x86.select_operand_prefix@src 8 + end if + @src.opcode_prefix = 0F3h + x86.store_instruction@src <0Fh,0AEh>,4 + else + err 'invalid operand' + end if +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/rdrand.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/rdrand.inc new file mode 100644 index 0000000..5f8be1b --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/rdrand.inc @@ -0,0 +1,10 @@ + +macro rdrand? dest* + x86.parse_operand@dest dest + if @dest.type = 'reg' + x86.select_operand_prefix@dest @dest.size + x86.store_instruction@dest <0Fh,0C7h>,6 + else + err 'invalid operand' + end if +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/rdseed.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/rdseed.inc new file mode 100644 index 0000000..9a1562d --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/rdseed.inc @@ -0,0 +1,10 @@ + +macro rdseed? dest* + x86.parse_operand@dest dest + if @dest.type = 'reg' + x86.select_operand_prefix@dest @dest.size + x86.store_instruction@dest <0Fh,0C7h>,7 + else + err 'invalid operand' + end if +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/rdtscp.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/rdtscp.inc new file mode 100644 index 0000000..7dab1b7 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/rdtscp.inc @@ -0,0 +1,4 @@ + +macro rdtscp? + db 0Fh,1,0F9h +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/rtm.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/rtm.inc new file mode 100644 index 0000000..b2bad0f --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/rtm.inc @@ -0,0 +1,39 @@ + +macro xbegin? dest* + x86.parse_jump_operand@dest dest + if @dest.type = 'imm' & ~ @dest.jump_type + if x86.mode shr 3 <> @dest.size + err 'invalid operand size' + end if + if x86.mode = 16 + db 0C7h,0F8h + dw @dest.imm-($+2) + else + if ~ $ relativeto 0 & @dest.imm relativeto 0 + @dest.imm = @dest.imm + $ - 0 scaleof $ + err 'invalid address' + end if + if @dest.unresolved | ( @dest.imm relativeto $ & @dest.imm-($+5) < 8000h & @dest.imm-($+5) >= -8000h ) + db 66h,0C7h,0F8h + dw @dest.imm-($+2) + else + db 0C7h,0F8h + dd @dest.imm-($+4) + end if + end if + else + err 'invalid operand' + end if +end macro + +macro xabort? imm* + db 0C6h,0F8h,imm +end macro + +macro xend? + db 0Fh,1,0D5h +end macro + +macro xtest? + db 0Fh,1,0D6h +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/smx.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/smx.inc new file mode 100644 index 0000000..e282952 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/smx.inc @@ -0,0 +1,4 @@ + +macro getsec? + db 0Fh,37h +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/sse.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/sse.inc new file mode 100644 index 0000000..b7748b0 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/sse.inc @@ -0,0 +1,433 @@ + +if ~ defined SSE + + restore SSE ; this ensures that symbol cannot be forward-referenced + SSE = 1 + + include 'mmx.inc' + + element SSE.reg + + repeat 8, i:0 + element xmm#i? : SSE.reg + i + end repeat + + define x86.dqword? :16 + define x86.xword? :16 + + iterate context, @dest,@src,@src2,@aux + + namespace context + + calminstruction SSE.parse_operand#context operand + + call x86.parse_operand#context, operand + + check type = 'imm' & size = 0 + jno done + check imm eq 1 elementof imm & 1 metadataof imm relativeto MMX.reg + jyes mm_register + check imm eq 1 elementof imm & 1 metadataof imm relativeto SSE.reg + jyes xmm_register + exit + + mm_register: + + compute rm, 1 metadataof imm - MMX.reg + compute size, 8 + + jump export_mmreg + + xmm_register: + + compute rm, 1 metadataof imm - SSE.reg + compute size, 16 + + export_mmreg: + + compute type, 'mmreg' + compute mod, 11b + + done: + + end calminstruction + + end namespace + + end iterate + + calminstruction SSE.basic_instruction pre,ext,msize,dest,src + call SSE.parse_operand@dest, dest + call SSE.parse_operand@src, src + check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + jno invalid_combination_of_operands + check @dest.size <> 16 | (@src.type = 'mem' & @src.size and not msize) | (@src.type = 'mmreg' & @src.size <> 16) + jno size_ok + err 'invalid operand size' + size_ok: + compute @src.opcode_prefix, pre + xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + end calminstruction + + calminstruction SSE.basic_instruction_imm8 pre,ext,msize,dest,src,aux + call SSE.parse_operand@dest, dest + call SSE.parse_operand@src, src + call x86.parse_operand@aux, aux + check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm' + jno invalid_combination_of_operands + check @dest.size <> 16 | (@src.type = 'mem' & @src.size and not msize) | (@src.type = 'mmreg' & @src.size <> 16) | @aux.size and not 1 + jno size_ok + err 'invalid operand size' + size_ok: + compute @src.opcode_prefix, pre + xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm,byte,@aux.imm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + end calminstruction + + iterate , sqrt,51h, rsqrt,52h, rcp,53h, add,58h, mul,59h, sub,5Ch, min,5Dh, div,5Eh, max,5Fh + macro instr#ps? dest*,src* + SSE.basic_instruction 0,ext,16,dest,src + end macro + macro instr#ss? dest*,src* + SSE.basic_instruction 0F3h,ext,4,dest,src + end macro + end iterate + + iterate , and,54h, andn,55h, or,56h, xor,57h, unpckl,14h, unpckh,15h + macro instr#ps? dest*,src* + SSE.basic_instruction 0,ext,16,dest,src + end macro + end iterate + + macro cmpps? dest*,src*,code* + SSE.basic_instruction_imm8 0,0C2h,16,dest,src,code + end macro + + macro cmpss? dest*,src*,code* + SSE.basic_instruction_imm8 0F3h,0C2h,4,dest,src,code + end macro + + iterate , eq,0, lt,1, le,2, unord,3, neq,4, nlt,5, nle,6, ord,7 + macro cmp#cond#ps? dest*,src* + cmpps dest,src,code + end macro + macro cmp#cond#ss? dest*,src* + cmpss dest,src,code + end macro + end iterate + + macro shufps? dest*,src*,imm* + SSE.basic_instruction_imm8 0,0C6h,16,dest,src,imm + end macro + + iterate , movaps,28h, movups,10h + macro instr? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if (@dest.size or @src.size) and not 16 + err 'invalid operand size' + end if + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + x86.store_instruction@src <0Fh,ext>,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + x86.store_instruction@dest <0Fh,ext+1>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + iterate , movlps,12h, movhps,16h + macro instr? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mem' + if @dest.size <> 16 | @src.size and not 8 + err 'invalid operand size' + end if + x86.store_instruction@src <0Fh,ext>,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not 8 | @src.size <> 16 + err 'invalid operand size' + end if + x86.store_instruction@dest <0Fh,ext+1>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + iterate , movhlps,12h, movlhps,16h + macro instr? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if (@dest.size or @src.size) and not 16 + err 'invalid operand size' + end if + if @dest.type = 'mmreg' & @src.type = 'mmreg' + x86.store_instruction@src <0Fh,ext>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + macro movss? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 4) | (@src.type = 'mmreg' & @src.size <> 16) + err 'invalid operand size' + end if + @src.opcode_prefix = 0F3h + x86.store_instruction@src <0Fh,10h>,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not 4 | @src.size <> 16 + err 'invalid operand size' + end if + @dest.opcode_prefix = 0F3h + x86.store_instruction@dest <0Fh,11h>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro movntps? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mem' & @src.type = 'mmreg' + if (@dest.size or @src.size) and not 16 + err 'invalid operand size' + end if + x86.store_instruction@dest <0Fh,2Bh>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro movmskps? dest*,src* + x86.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'reg' & @src.type = 'mmreg' + if (@dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | @src.size <> 16 + err 'invalid operand size' + end if + x86.store_instruction@src <0Fh,50h>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , ucomiss,2Eh, comiss,2Fh + macro instr? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 4) | (@src.type = 'mmreg' & @src.size <> 16) + err 'invalid operand size' + end if + x86.store_instruction@src <0Fh,ext>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + macro cvtpi2ps? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @dest.size <> 16 | @src.size and not 8 + err 'invalid operand size' + end if + x86.store_instruction@src <0Fh,2Ah>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro cvtsi2ss? dest*,src* + SSE.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg') + if @src.size = 0 + err 'operand size not specified' + else if @dest.size <> 16 | @src.size < 4 + err 'invalid operand size' + end if + x86.select_operand_prefix@src @src.size + @src.opcode_prefix = 0F3h + x86.store_instruction@src <0Fh,2Ah>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , cvttps2pi,2Ch, cvtps2pi,2Dh + macro instr? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @dest.size <> 8 | (@src.size = 'mem' & @src.size and not 8) | (@src.size = 'mmreg' & @src.size <> 16) + err 'invalid operand size' + end if + x86.store_instruction@src <0Fh,ext>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + iterate , cvttss2si,2Ch, cvtss2si,2Dh + macro instr? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @dest.size < 4 | (@src.size = 'mem' & @src.size and not 4) | (@src.size = 'mmreg' & @src.size <> 16) + err 'invalid operand size' + end if + x86.select_operand_prefix@src @dest.size + @src.opcode_prefix = 0F3h + x86.store_instruction@src <0Fh,ext>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + iterate , pminub,0DAh, pmaxub,0DEh, pavgb,0E0h, pavgw,0E3h, pmulhuw,0E4h, pminsw,0EAh, pmaxsw,0EEh, psadbw,0F6h + macro instr? dest*,src* + MMX.basic_instruction ext,dest,src + end macro + end iterate + + macro pinsrw? dest*,src*,sel* + MMX.parse_operand@dest dest + x86.parse_operand@src src + x86.parse_operand@aux sel + if @dest.type = 'mmreg' & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm' + if (@src.type = 'reg' & @src.size <> 4) | (@src.type = 'mem' & @src.size and not 2) | @aux.size and not 1 + err 'invalid operand size' + end if + x86.store_instruction@src <0Fh,0C4h>,@dest.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro pextrw? dest*,src*,sel* + x86.parse_operand@dest dest + MMX.parse_operand@src src + x86.parse_operand@aux sel + if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm' + if @dest.size <> 4 | @aux.size and not 1 + err 'invalid operand size' + end if + x86.store_instruction@src <0Fh,0C5h>,@dest.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro pshufw? dest*,src*,sel* + MMX.parse_operand@dest dest + MMX.parse_operand@src src + x86.parse_operand@aux sel + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm' + if @src.size and not 8 | @aux.size and not 1 + err 'invalid operand size' + end if + x86.store_instruction@src <0Fh,70h>,@dest.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro pmovmskb? dest*,src* + x86.parse_operand@dest dest + MMX.parse_operand@src src + if @dest.type = 'reg' & @src.type = 'mmreg' + if @dest.size <> 4 + err 'invalid operand size' + end if + x86.store_instruction@src <0Fh,0D7h>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro movntq? dest*,src* + MMX.parse_operand@dest dest + MMX.parse_operand@src src + if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not 8 + err 'invalid operand size' + end if + x86.store_instruction@dest <0Fh,0E7h>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro maskmovq? src*,sel* + MMX.parse_operand@src src + MMX.parse_operand@aux sel + if @src.type = 'mmreg' & @aux.type = 'mmreg' + x86.store_instruction@aux <0Fh,0F7h>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , prefetchnta,0, prefetcht0,1, prefetcht1,2, prefetcht2,3 + macro instr? src* + x86.parse_operand@src src + if @src.type = 'mem' + if @src.size and not 1 + err 'invalid operand size' + end if + x86.store_instruction@src <0Fh,18h>,postbyte + else + err 'invalid operand' + end if + end macro + end iterate + + macro sfence? + db 0Fh,0AEh,0F8h + end macro + + iterate , fxsave,0, fxrstor,1 + macro instr? src* + x86.parse_operand@src src + if @src.type = 'mem' + if @src.size and not 512 + err 'invalid operand size' + end if + x86.store_instruction@src <0Fh,0AEh>,postbyte + else + err 'invalid operand' + end if + end macro + end iterate + + iterate , ldmxcsr,2, stmxcsr,3 + macro instr? src* + x86.parse_operand@src src + if @src.type = 'mem' + if @src.size and not 4 + err 'invalid operand size' + end if + x86.store_instruction@src <0Fh,0AEh>,postbyte + else + err 'invalid operand' + end if + end macro + end iterate + +end if \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/sse2.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/sse2.inc new file mode 100644 index 0000000..93cc963 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/sse2.inc @@ -0,0 +1,603 @@ + +if ~ defined SSE2 + + restore SSE2 ; this ensures that symbol cannot be forward-referenced + SSE2 = 1 + + include 'sse.inc' + + iterate , sqrt,51h, rsqrt,52h, rcp,53h, add,58h, mul,59h, sub,5Ch, min,5Dh, div,5Eh, max,5Fh + macro instr#pd? dest*,src* + SSE.basic_instruction 66h,ext,16,dest,src + end macro + macro instr#sd? dest*,src* + SSE.basic_instruction 0F2h,ext,8,dest,src + end macro + end iterate + + iterate , and,54h, andn,55h, or,56h, xor,57h, unpckl,14h, unpckh,15h + macro instr#pd? dest*,src* + SSE.basic_instruction 66h,ext,16,dest,src + end macro + end iterate + + macro cmppd? dest*,src*,code* + SSE.basic_instruction_imm8 66h,0C2h,16,dest,src,code + end macro + + macro SSE.cmpsd? dest*,src*,code* + SSE.basic_instruction_imm8 0F2h,0C2h,8,dest,src,code + end macro + + calminstruction cmpsd? args& + match , args + jno sse + xcall x86.store_operand_prefix, (4) + emit 1, 0A7h + exit + sse: + arrange args, =SSE.=cmpsd args + assemble args + end calminstruction + + iterate , eq,0, lt,1, le,2, unord,3, neq,4, nlt,5, nle,6, ord,7 + macro cmp#cond#pd? dest*,src* + cmppd dest,src,code + end macro + macro cmp#cond#sd? dest*,src* + cmpsd dest,src,code + end macro + end iterate + + macro shufpd? dest*,src*,imm* + SSE.basic_instruction_imm8 66h,0C6h,16,dest,src,imm + end macro + + iterate , movapd,28h, movupd,10h + macro instr? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if (@dest.size or @src.size) and not 16 + err 'invalid operand size' + end if + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,ext>,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + @dest.opcode_prefix = 66h + x86.store_instruction@dest <0Fh,ext+1>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + iterate , movlpd,12h, movhpd,16h + macro instr? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mem' + if @dest.size <> 16 | @src.size and not 8 + err 'invalid operand size' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,ext>,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not 8 | @src.size <> 16 + err 'invalid operand size' + end if + @dest.opcode_prefix = 66h + x86.store_instruction@dest <0Fh,ext+1>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + macro SSE.movsd? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <> 16) + err 'invalid operand size' + end if + @src.opcode_prefix = 0F2h + x86.store_instruction@src <0Fh,10h>,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not 8 | @src.size <> 16 + err 'invalid operand size' + end if + @dest.opcode_prefix = 0F2h + x86.store_instruction@dest <0Fh,11h>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + calminstruction movsd? args& + match , args + jno sse + xcall x86.store_operand_prefix, (4) + emit 1, 0A5h + exit + sse: + arrange args, =SSE.=movsd args + assemble args + end calminstruction + + iterate , movdqa,66h, movdqu,0F3h + macro instr? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if (@dest.size or @src.size) and not 16 + err 'invalid operand size' + end if + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + @src.opcode_prefix = pre + x86.store_instruction@src <0Fh,6Fh>,@dest.rm + else if @dest.type = 'mem' & @src.type = 'mmreg' + @dest.opcode_prefix = pre + x86.store_instruction@dest <0Fh,7Fh>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + iterate , movntpd,2Bh, movntdq,0E7h + macro instr? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mem' & @src.type = 'mmreg' + if (@dest.size or @src.size) and not 16 + err 'invalid operand size' + end if + @dest.opcode_prefix = 66h + x86.store_instruction@dest <0Fh,ext>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + macro movmskpd? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'reg' & @src.type = 'mmreg' + if (@dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8)) | @src.size <> 16 + err 'invalid operand size' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,50h>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro maskmovdqu? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mmreg' + if (@dest.size or @src.size) <> 16 + err 'invalid operand size' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,0F7h>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , ucomisd,2Eh, comisd,2Fh + macro instr? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @dest.size <> 16 | (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <> 16) + err 'invalid operand size' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,ext>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + macro cvtps2pd? dest*,src* + SSE.basic_instruction 0,5Ah,8,dest,src + end macro + + macro cvtpd2ps? dest*,src* + SSE.basic_instruction 66h,5Ah,16,dest,src + end macro + + macro cvtsd2ss? dest*,src* + SSE.basic_instruction 0F2h,5Ah,8,dest,src + end macro + + macro cvtss2sd? dest*,src* + SSE.basic_instruction 0F3h,5Ah,4,dest,src + end macro + + macro cvtdq2ps? dest*,src* + SSE.basic_instruction 0,5Bh,16,dest,src + end macro + + macro cvtps2dq? dest*,src* + SSE.basic_instruction 66h,5Bh,16,dest,src + end macro + + macro cvttps2dq? dest*,src* + SSE.basic_instruction 0F3h,5Bh,16,dest,src + end macro + + macro cvttpd2dq? dest*,src* + SSE.basic_instruction 66h,0E6h,16,dest,src + end macro + + macro cvtpd2dq? dest*,src* + SSE.basic_instruction 0F2h,0E6h,16,dest,src + end macro + + macro cvtdq2pd? dest*,src* + SSE.basic_instruction 0F3h,0E6h,8,dest,src + end macro + + macro movdq2q? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mmreg' + if @dest.size <> 8 | @src.size <> 16 + err 'invalid operand size' + end if + @src.opcode_prefix = 0F2h + x86.store_instruction@src <0Fh,0D6h>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro movq2dq? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mmreg' + if @dest.size <> 16 | @src.size <> 8 + err 'invalid operand size' + end if + @src.opcode_prefix = 0F3h + x86.store_instruction@src <0Fh,0D6h>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro cvtpi2pd? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @dest.size <> 16 | @src.size and not 8 + err 'invalid operand size' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,2Ah>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro cvtsi2sd? dest*,src* + SSE.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg') + if @src.size = 0 + err 'operand size not specified' + else if @dest.size <> 16 | @src.size < 4 + err 'invalid operand size' + end if + x86.select_operand_prefix@src @src.size + @src.opcode_prefix = 0F2h + x86.store_instruction@src <0Fh,2Ah>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , cvttpd2pi,2Ch, cvtpd2pi,2Dh + macro instr? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @dest.size <> 8 | @src.size and not 16 + err 'invalid operand size' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,ext>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + iterate , cvttsd2si,2Ch, cvtsd2si,2Dh + macro instr? dest*,src* + x86.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'mmreg') + if @dest.size < 4 | (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <>16) + err 'invalid operand size' + end if + x86.select_operand_prefix@src @dest.size + @src.opcode_prefix = 0F2h + x86.store_instruction@src <0Fh,ext>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + calminstruction MMX.select_operand_prefix rm_operand*,size* + local sym, prefix + check size = 16 + jno no_prefix + compute prefix, 66h + arrange sym, rm_operand.=prefix + publish sym, prefix + exit + no_prefix: + check size <> 8 + jno done + err 'invalid operand size' + done: + end calminstruction + + calminstruction MMX.basic_instruction ext,dest,src + call SSE.parse_operand@dest, dest + call SSE.parse_operand@src, src + check @src.size and not @dest.size + jno size_ok + err 'operand sizes do not match' + size_ok: + check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + jno invalid_combination_of_operands + call MMX.select_operand_prefix, @src,@dest.size + xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + end calminstruction + + calminstruction MMX.bit_shift_instruction ext,dest,src + call SSE.parse_operand@dest, dest + call SSE.parse_operand@src, src + check @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + jyes mmreg_rm + check @dest.type = 'mmreg' & @src.type = 'imm' + jyes mmreg_imm + err 'invalid combination of operands' + exit + mmreg_rm: + check @src.size and not @dest.size + jno mmreg_rm_ok + err 'operand sizes do not match' + mmreg_rm_ok: + call MMX.select_operand_prefix, @src,@dest.size + xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm + exit + mmreg_imm: + check @src.size and not 1 + jno rm_mmreg_ok + err 'invalid operand size' + rm_mmreg_ok: + local iext, irm + compute iext, 70h+(ext and 0Fh) + compute irm, ((ext shr 4)-0Ch) shl 1 + call MMX.select_operand_prefix, @dest,@dest.size + xcall x86.store_instruction@dest, <0Fh,iext>,irm,byte,@src.imm + end calminstruction + + iterate , paddq,0D4h, pmuludq,0F4h, psubq,0FBh + macro instr? dest*,src* + MMX.basic_instruction ext,dest,src + end macro + end iterate + + macro movq? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if (@src.type = 'mem' & @src.size and not 8) | (@src.type = 'mmreg' & @src.size <> @dest.size) + err 'invalid operand size' + end if + if @dest.size = 8 + x86.store_instruction@src <0Fh,6Fh>,@dest.rm + else + @src.opcode_prefix = 0F3h + x86.store_instruction@src <0Fh,7Eh>,@dest.rm + end if + else if @dest.type = 'mem' & @src.type = 'mmreg' + if @dest.size and not 8 + err 'invalid operand size' + end if + if @src.size = 8 + x86.store_instruction@dest <0Fh,7Fh>,@src.rm + else + @dest.opcode_prefix = 66h + x86.store_instruction@dest <0Fh,0D6h>,@src.rm + end if + else if @dest.type = 'reg' & @src.type = 'mmreg' + if @dest.size <> 8 + err 'invalid operand size' + end if + if @src.size = 16 + @dest.opcode_prefix = 66h + end if + @dest.prefix = 48h + x86.store_instruction@dest <0Fh,7Eh>,@src.rm + else if @dest.type = 'mmreg' & @src.type = 'reg' + if @src.size <> 8 + err 'invalid operand size' + end if + if @dest.size = 16 + @src.opcode_prefix = 66h + end if + @src.prefix = 48h + x86.store_instruction@src <0Fh,6Eh>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + macro movd? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'reg') + if @src.size and not 4 + err 'invalid operand size' + end if + MMX.select_operand_prefix @src,@dest.size + x86.store_instruction@src <0Fh,6Eh>,@dest.rm + else if (@dest.type = 'mem' | @dest.type = 'reg') & @src.type = 'mmreg' + if @dest.size and not 4 + err 'invalid operand size' + end if + MMX.select_operand_prefix @dest,@src.size + x86.store_instruction@dest <0Fh,7Eh>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro pinsrw? dest*,src*,sel* + SSE.parse_operand@dest dest + x86.parse_operand@src src + x86.parse_operand@aux sel + if @dest.type = 'mmreg' & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm' + if (@src.type = 'reg' & @src.size <> 4) | (@src.type = 'mem' & @src.size and not 2) | @aux.size and not 1 + err 'invalid operand size' + end if + MMX.select_operand_prefix @src,@dest.size + x86.store_instruction@src <0Fh,0C4h>,@dest.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + macro pextrw? dest*,src*,sel* + x86.parse_operand@dest dest + SSE.parse_operand@src src + x86.parse_operand@aux sel + if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm' + if x86.mode = 64 & @dest.size = 8 + @dest.size = 4 + end if + if @dest.size <> 4 | @aux.size and not 1 + err 'invalid operand size' + end if + MMX.select_operand_prefix @src,@src.size + x86.store_instruction@src <0Fh,0C5h>,@dest.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + + iterate , pshufd,66h, pshuflw,0F2h, pshufhw,0F3h + macro instr? dest*,src*,sel* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + x86.parse_operand@aux sel + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm' + if @dest.size <> 16 | @src.size and not 16 | @aux.size and not 1 + err 'invalid operand size' + end if + @src.opcode_prefix = pre + x86.store_instruction@src <0Fh,70h>,@dest.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + macro pmovmskb? dest*,src* + x86.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'reg' & @src.type = 'mmreg' + if @dest.size <> 4 & (x86.mode < 64 | @dest.size <> 8) + err 'invalid operand size' + end if + MMX.select_operand_prefix @src,@src.size + x86.store_instruction@src <0Fh,0D7h>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + + iterate , psrldq,3, pslldq,7 + macro instr? dest*,cnt* + SSE.parse_operand@dest dest + x86.parse_operand@aux cnt + if @dest.type = 'mmreg' & @aux.type = 'imm' + if @dest.size <> 16 | @aux.size and not 1 + err 'invalid operand size' + end if + @dest.opcode_prefix = 66h + x86.store_instruction@dest <0Fh,73h>,postbyte,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + iterate , punpcklqdq,6Ch, punpckhqdq,6Dh + macro instr? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') + if (@dest.size or @src.size) and not 16 + err 'invalid operand size' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,ext>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro + end iterate + + macro movnti? dest*,src* + x86.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'mem' & @src.type = 'reg' + if @dest.size and not @src.size + err 'operand sizes do not match' + else if @src.size <> 4 & @src.size <> 8 + err 'invalid operand size' + end if + x86.select_operand_prefix@dest @src.size + x86.store_instruction@dest <0Fh,0C3h>,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + macro clflush? src* + x86.parse_operand@src src + if @src.type = 'mem' + if @src.size and not 1 + err 'invalid operand size' + end if + x86.store_instruction@src <0Fh,0AEh>,7 + else + err 'invalid operand' + end if + end macro + + macro lfence? + db 0Fh,0AEh,0E8h + end macro + + macro mfence? + db 0Fh,0AEh,0F0h + end macro + +end if \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/sse3.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/sse3.inc new file mode 100644 index 0000000..217884c --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/sse3.inc @@ -0,0 +1,72 @@ + +include 'sse2.inc' + +macro fisttp? src* + x86.parse_operand@src src + if @src.type = 'mem' + if @src.size = 2 + x86.store_instruction@src 0DFh,1 + else if @src.size = 4 + x86.store_instruction@src 0DBh,1 + else if @src.size = 8 + x86.store_instruction@src 0DDh,1 + else if @src.size + err 'invalid operand size' + else + err 'operand size not specified' + end if + else + err 'invalid operand' + end if +end macro + +iterate , addsub,0D0h, hadd,7Ch, hsub,7Dh + macro instr#pd? dest*,src* + SSE.basic_instruction 66h,ext,16,dest,src + end macro + macro instr#ps? dest*,src* + SSE.basic_instruction 0F2h,ext,16,dest,src + end macro +end iterate + +iterate , movsldup,12h, movshdup,16h + macro instr? dest*,src* + SSE.basic_instruction 0F3h,ext,16,dest,src + end macro +end iterate + +macro movddup? dest*,src* + SSE.basic_instruction 0F2h,12h,8,dest,src +end macro + +macro lddqu? dest*,src* + SSE.parse_operand@src dest + SSE.parse_operand@src src + if (@dest.size or @src.size) and not 16 + err 'invalid operand size' + end if + if @dest.type = 'mmreg' & @src.type = 'mem' + @src.opcode_prefix = 0F2h + x86.store_instruction@src <0Fh,0F0h>,@dest.rm + else + err 'invalid combination of operands' + end if +end macro + +macro monitor? arg1,arg2,arg3 + match any, arg1 arg2 arg3 + if ~ arg1 eq eax | ~ arg2 eq ecx | ~ arg3 eq edx + err 'invalid combination of operands' + end if + end match + db 0Fh,01h,0C8h +end macro + +macro mwait? arg1,arg2 + match any, arg1 arg2 + if ~ arg1 eq eax | ~ arg2 eq ecx + err 'invalid combination of operands' + end if + end match + db 0Fh,01h,0C9h +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.1.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.1.inc new file mode 100644 index 0000000..d98d1f5 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.1.inc @@ -0,0 +1,204 @@ + +include 'ssse3.inc' + +iterate , ptest,17h, pmuldq,28h, pcmpeqq,29h, packusdw,2Bh, pminsb,38h, pminsd,39h, pminuw,3Ah, pminud,3Bh, pmaxsb,3Ch, pmaxsd,3Dh, pmaxuw,3Eh, pmaxud,3Fh, pmulld,40h, phminposuw,41h + macro instr? dest*,src* + SSE.basic_instruction 66h,<38h,supp>,16,dest,src + end macro +end iterate + +iterate , roundps,08h, roundpd,09h, roundss,0Ah, roundsd,0Bh, blendps,0Ch, blendpd,0Dh, pblendw,0Eh, dpps,40h, dppd,41h, mpsadbw,42h + macro instr? dest*,src*,imm* + SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm + end macro +end iterate + +iterate , pblendvb,10h, blendvps,14h, blendvpd,15h + macro instr? dest*,src*,sel* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + SSE.parse_operand@aux sel + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'mmreg' & @aux.size = 16 & @aux.rm = 0 + if @dest.size or @src.size and not 16 + err 'invalid operand size' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,38h,supp>,@dest.rm + else + err 'invalid combination of operands' + end if + end macro +end iterate + +iterate , bw,0,8, bd,1,4, bq,2,2, wd,3,8, wq,4,4, dq,5,8 + macro pmovsx#conv? dest*,src* + SSE.basic_instruction 66h,<38h,20h+code>,msize,dest,src + end macro + macro pmovzx#conv? dest*,src* + SSE.basic_instruction 66h,<38h,30h+code>,msize,dest,src + end macro +end iterate + +macro insertps? dest*,src*,sel* + SSE.basic_instruction_imm8 66h,<3Ah,21h>,4,dest,src,sel +end macro + +macro extractps? dest*,src*,sel* + x86.parse_operand@dest dest + SSE.parse_operand@src src + x86.parse_operand@aux sel + if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm' + if x86.mode = 64 & @dest.size = 8 + @dest.size = 4 + end if + if @dest.size <> 4 | @src.size and not 16 | @aux.size and not 1 + err 'invalid operand size' + end if + @dest.opcode_prefix = 66h + x86.store_instruction@dest <0Fh,3Ah,17h>,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +macro pinsrb? dest*,src*,sel* + SSE.parse_operand@dest dest + x86.parse_operand@src src + x86.parse_operand@aux sel + if (@dest.type = 'mmreg' & @dest.size = 16) & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm' + if (@src.type = 'reg' & @src.size <> 4) | (@src.type = 'mem' & @src.size and not 1) | @aux.size and not 1 + err 'invalid operand size' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,3Ah,20h>,@dest.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +macro pinsrd? dest*,src*,sel* + SSE.parse_operand@dest dest + x86.parse_operand@src src + x86.parse_operand@aux sel + if (@dest.type = 'mmreg' & @dest.size = 16) & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm' + if @src.size and not 4 | @aux.size and not 1 + err 'invalid operand size' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,3Ah,22h>,@dest.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +macro pinsrq? dest*,src*,sel* + SSE.parse_operand@dest dest + x86.parse_operand@src src + x86.parse_operand@aux sel + if (@dest.type = 'mmreg' & @dest.size = 16) & (@src.type = 'reg' | @src.type = 'mem') & @aux.type = 'imm' + if @src.size and not 8 | @aux.size and not 1 + err 'invalid operand size' + end if + if x86.mode < 64 + err 'instruction requires long mode' + end if + @src.opcode_prefix = 66h + @src.rex_prefix = 48h + x86.store_instruction@src <0Fh,3Ah,22h>,@dest.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +macro pextrb? dest*,src*,sel* + x86.parse_operand@dest dest + SSE.parse_operand@src src + x86.parse_operand@aux sel + if (@dest.type = 'reg' | @dest.type = 'mem') & (@src.type = 'mmreg' & @src.size = 16) & @aux.type = 'imm' + if x86.mode = 64 & @dest.type = 'reg' & @dest.size = 8 + @dest.size = 4 + end if + if (@dest.type = 'reg' & @dest.size <> 4) | (@dest.size = 'mem' & @dest.size and not 1) | @aux.size and not 1 + err 'invalid operand size' + end if + @dest.opcode_prefix = 66h + x86.store_instruction@dest <0Fh,3Ah,14h>,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +macro pextrw? dest*,src*,sel* + x86.parse_operand@dest dest + SSE.parse_operand@src src + x86.parse_operand@aux sel + if @dest.type = 'reg' & @src.type = 'mmreg' & @aux.type = 'imm' + if x86.mode = 64 & @dest.size = 8 + @dest.size = 4 + end if + if @dest.size <> 4 | @aux.size and not 1 + err 'invalid operand size' + end if + MMX.select_operand_prefix @src,@src.size + x86.store_instruction@src <0Fh,0C5h>,@dest.rm,1,@aux.imm + else if @dest.type = 'mem' & (@src.type = 'mmreg' & @src.size = 16) & @aux.type = 'imm' + if @dest.size and not 2 | @aux.size and not 1 + err 'invalid operand size' + end if + @dest.opcode_prefix = 66h + x86.store_instruction@dest <0Fh,3Ah,15h>,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +macro pextrd? dest*,src*,sel* + x86.parse_operand@dest dest + SSE.parse_operand@src src + x86.parse_operand@aux sel + if (@dest.type = 'reg' | @dest.type = 'mem') & (@src.type = 'mmreg' & @src.size = 16) & @aux.type = 'imm' + if x86.mode = 64 & @dest.type = 'reg' & @dest.size = 8 + @dest.size = 4 + end if + if @dest.size and not 4 | @aux.size and not 1 + err 'invalid operand size' + end if + @dest.opcode_prefix = 66h + x86.store_instruction@dest <0Fh,3Ah,16h>,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +macro pextrq? dest*,src*,sel* + x86.parse_operand@dest dest + SSE.parse_operand@src src + x86.parse_operand@aux sel + if (@dest.type = 'reg' | @dest.type = 'mem') & (@src.type = 'mmreg' & @src.size = 16) & @aux.type = 'imm' + if @dest.size and not 8 | @aux.size and not 1 + err 'invalid operand size' + end if + if x86.mode < 64 + err 'instruction requires long mode' + end if + @dest.opcode_prefix = 66h + @dest.rex_prefix = 48h + x86.store_instruction@dest <0Fh,3Ah,16h>,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro + +macro movntdqa? dest*,src* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + if @dest.type = 'mmreg' & @src.type = 'mem' + if (@dest.size or @src.size) and not 16 + err 'invalid operand size' + end if + @src.opcode_prefix = 66h + x86.store_instruction@src <0Fh,38h,2Ah>,@dest.rm + else + err 'invalid combination of operands' + end if +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.2.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.2.inc new file mode 100644 index 0000000..5886da5 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.2.inc @@ -0,0 +1,54 @@ + +include 'sse4.1.inc' + +iterate , pcmpgtq,37h + macro instr? dest*,src* + SSE.basic_instruction 66h,<38h,supp>,16,dest,src + end macro +end iterate + +iterate , pcmpestrm,60h, pcmpestri,61h, pcmpistrm,62h, pcmpistri,63h + macro instr? dest*,src*,imm* + SSE.basic_instruction_imm8 66h,<3Ah,supp>,16,dest,src,imm + end macro +end iterate + +macro crc32? dest*,src* + x86.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'reg' & ( @src.type = 'reg' | @src.type = 'mem' ) + if @dest.size <> 4 & ( @dest.size <> 8 | x86.mode <> 64 ) + err 'invalid operand size' + end if + @src.opcode_prefix = 0F2h + if @src.size > 1 + x86.select_operand_prefix@src @src.size + x86.store_instruction@src <0Fh,38h,0F1h>,@dest.rm + else if @src.size > 0 + x86.store_instruction@src <0Fh,38h,0F0h>,@dest.rm + else + err 'operand size not specified' + end if + else + err 'invalid combination of operands' + end if +end macro + +macro popcnt? dest*,src* + x86.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'reg' & ( @src.type = 'reg' | @src.type = 'mem' ) + if @src.size and not @dest.size + err 'operand sizes do not match' + end if + @src.opcode_prefix = 0F3h + if @dest.size > 1 + x86.select_operand_prefix@src @dest.size + x86.store_instruction@src <0Fh,0B8h>,@dest.rm + else + err 'invalid operand size' + end if + else + err 'invalid combination of operands' + end if +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/ssse3.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/ssse3.inc new file mode 100644 index 0000000..fbfe10f --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/ssse3.inc @@ -0,0 +1,26 @@ + +include 'sse3.inc' + +iterate , pshufb,0, phaddw,1, phaddd,2, phaddsw,3, pmaddubsw,4, phsubw,5, phsubd,6, phsubsw,7, psignb,8, psignw,9, psignd,0Ah, pmulhrsw,0Bh, pabsb,1Ch, pabsw,1Dh, pabsd,1Eh + macro instr? dest*,src* + MMX.basic_instruction <38h,supp>,dest,src + end macro +end iterate + +macro palignr? dest*,src*,aux* + SSE.parse_operand@dest dest + SSE.parse_operand@src src + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & (@src.type = 'mem' | @src.type = 'mmreg') & @aux.type = 'imm' + if @src.size and not @dest.size + err 'operand sizes do not match' + end if + if @aux.size and not 1 + err 'invalid operand size' + end if + MMX.select_operand_prefix @src,@dest.size + x86.store_instruction@src <0Fh,3Ah,0Fh>,@dest.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/vaes.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/vaes.inc new file mode 100644 index 0000000..ec6af6e --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/vaes.inc @@ -0,0 +1,37 @@ + +include 'aes.inc' + +if defined AVX_512 + + iterate , aesenc,0DCh, aesenclast,0DDh, aesdec,0DEh, aesdeclast,0DFh + + macro v#instr? dest*,src*,src2* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') + if @dest.size <> @src.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + @src2.memsize = 0 + AVX_512.store_instruction@src2 @dest.size,VEX_66_0F38_W0,EVEX_AS_VEX+EVEX_VL,opcode,0,@dest.rm,@src.rm + else + err 'invalid combination of operands' + end if + end macro + + end iterate + +else + + include 'avx.inc' + + iterate , aesenc,0DCh, aesenclast,0DDh, aesdec,0DEh, aesdeclast,0DFh + + macro v#instr? dest*,src*,src2* + AVX.basic_instruction VEX_66_0F38_W0,opcode,0,dest,src,src2 + end macro + + end iterate + +end if diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/vmx.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/vmx.inc new file mode 100644 index 0000000..43493c5 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/vmx.inc @@ -0,0 +1,65 @@ + +iterate , vmxon,0F3h,0C7h,6, vmclear,66h,0C7h,6, \ + vmptrld,0,0C7h,6, vmptrst,0,0C7h,7 + + macro instr? src* + x86.parse_operand@src src + if @src.type = 'mem' + if @src.size and not 8 + err 'invalid operand size' + else + @src.opcode_prefix = prefix + x86.store_instruction@src <0Fh,ext>,postbyte + end if + else + err 'invalid operand' + end if + end macro + +end iterate + +macro vmxoff? + db 0Fh,1,0C4h +end macro + +macro vmcall? + db 0Fh,1,0C1h +end macro + +macro vmlaunch? + db 0Fh,1,0C2h +end macro + +macro vmresume? + db 0Fh,1,0C3h +end macro + +macro vmread? dest*,src* + x86.parse_operand@dest dest + x86.parse_operand@src src + if @src.type = 'reg' & (@dest.type = 'mem' | @dest.type = 'reg') + if (x86.mode < 64 & @src.size <> 4) | (x86.mode = 64 & @src.size <> 8) + err 'invalid operand size' + else if @dest.size and not @src.size + err 'operand sizes do not match' + end if + x86.store_instruction@dest <0Fh,78h>,@src.rm + else + err 'invalid combination of operands' + end if +end macro + +macro vmwrite? dest*,src* + x86.parse_operand@dest dest + x86.parse_operand@src src + if @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') + if (x86.mode < 64 & @dest.size <> 4) | (x86.mode = 64 & @dest.size <> 8) + err 'invalid operand size' + else if @src.size and not @dest.size + err 'operand sizes do not match' + end if + x86.store_instruction@src <0Fh,79h>,@dest.rm + else + err 'invalid combination of operands' + end if +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/vpclmulqdq.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/vpclmulqdq.inc new file mode 100644 index 0000000..7af97a2 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/vpclmulqdq.inc @@ -0,0 +1,32 @@ + +include 'pclmulqdq.inc' + +if defined AVX_512 + + macro vpclmulqdq? dest*,src*,src2*,aux* + AVX_512.parse_operand@dest dest + AVX_512.parse_operand@src src + AVX_512.parse_operand@src2 src2 + x86.parse_operand@aux aux + if @dest.type = 'mmreg' & @src.type = 'mmreg' & (@src2.type = 'mem' | @src2.type = 'mmreg') & @aux.type = 'imm' + if @aux.size and not 1 + err 'invalid operand size' + else if @dest.size <> @src.size | @src2.size and not @dest.size + err 'operand sizes do not match' + end if + @src2.memsize = 0 + AVX_512.store_instruction@src2 @dest.size,VEX_66_0F3A_W0,EVEX_AS_VEX+EVEX_VL,44h,@dest.mask,@dest.rm,@src.rm,1,@aux.imm + else + err 'invalid combination of operands' + end if + end macro + +else + + include 'avx.inc' + + macro vpclmulqdq? dest*,src*,src2*,imm* + AVX.basic_instruction_imm8 VEX_66_0F3A_W0,44h,0,dest,src,src2,imm + end macro + +end if diff --git a/toolchain/fasmg.kl0e/examples/x86/include/ext/xsave.inc b/toolchain/fasmg.kl0e/examples/x86/include/ext/xsave.inc new file mode 100644 index 0000000..445a286 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/ext/xsave.inc @@ -0,0 +1,35 @@ + +iterate , xsave,4, xrstor,5 + + macro instr? src* + x86.parse_operand@src src + if @src.type = 'mem' + x86.store_instruction@src <0Fh,0AEh>,postbyte + else + err 'invalid operand' + end if + end macro + + macro instr#64? src* + if x86.mode = 64 + x86.parse_operand@src src + if @src.type = 'mem' + x86.select_operand_prefix@src 8 + x86.store_instruction@src <0Fh,0AEh>,postbyte + else + err 'invalid operand' + end if + else + err 'instruction requires long mode' + end if + end macro + +end iterate + +macro xgetbv? + db 0Fh,1,0D0h +end macro + +macro xsetbv? + db 0Fh,1,0D1h +end macro diff --git a/toolchain/fasmg.kl0e/examples/x86/include/format/coff.inc b/toolchain/fasmg.kl0e/examples/x86/include/format/coff.inc new file mode 100644 index 0000000..5ae5c08 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/format/coff.inc @@ -0,0 +1,470 @@ + +macro struct? name + macro end?.struct?! + end namespace + esc end struc + virtual at 0 + name name + sizeof.name = $ + end virtual + purge end?.struct? + end macro + esc struc name + label . : sizeof.name + namespace . +end macro + +struct SCNHDR + s_name db 8 dup ? + s_paddr dd ? + s_vaddr dd ? + s_size dd ? + s_scnptr dd ? + s_relptr dd ? + s_lnnoptr dd ? + s_nreloc dw ? + s_nlnno dw ? + s_flags dd ? +end struct + +SCNHSZ = sizeof SCNHDR + +struct RELOC + r_vaddr dd ? + r_symndx dd ? + r_type dw ? +end struct + +RELSZ = sizeof RELOC + +struct SYMENT + e_name db 8 dup ? + virtual at e_name + e_zeroes dd ? + e_offset dd ? + end virtual + e_value dd ? + e_scnum dw ? + e_type dw ? + e_sclass db ? + e_numaux db ? +end struct + +SYMESZ = sizeof SYMENT + +I386MAGIC = 0x14c + +F_RELFLG = 0x0001 +F_EXEC = 0x0002 +F_LNNO = 0x0004 +F_LSYMS = 0x0008 +F_AR32WR = 0x0100 + +STYP_TEXT = 0x0020 +STYP_DATA = 0x0040 +STYP_BSS = 0x0080 + +N_UNDEF = 0 +N_ABS = -1 +N_DEBUG = -2 + +T_NULL = 0000b +T_VOID = 0001b +T_CHAR = 0010b +T_SHORT = 0011b +T_INT = 0100b +T_LONG = 0101b +T_FLOAT = 0110b +T_DOUBLE = 0111b +T_STRUCT = 1000b +T_UNION = 1001b +T_ENUM = 1010b +T_MOE = 1011b +T_UCHAR = 1100b +T_USHORT = 1101b +T_UINT = 1110b +T_ULONG = 1111b +T_LNGDBL = 01_0000b + +DT_NON = 00b +DT_PTR = 01b +DT_FCN = 10b +DT_ARY = 11b + +C_NULL = 0 +C_AUTO = 1 +C_EXT = 2 +C_STAT = 3 +C_REG = 4 +C_EXTDEF = 5 +C_LABEL = 6 +C_ULABEL = 7 +C_MOS = 8 +C_ARG = 9 +C_STRTAG = 10 +C_MOU = 11 +C_UNTAG = 12 +C_TPDEF = 13 +C_USTATIC = 14 +C_ENTAG = 15 +C_MOE = 16 +C_REGPARM = 17 +C_FIELD = 18 +C_AUTOARG = 19 +C_LASTENT = 20 +C_BLOCK = 100 +C_FCN = 101 +C_EOS = 102 +C_FILE = 103 +C_LINE = 104 +C_ALIAS = 105 +C_HIDDEN = 106 +C_EFCN = 255 + +RELOC_ADDR32 = 6 +RELOC_REL32 = 20 + +COFF:: + +namespace COFF + + Header: + + f_magic dw I386MAGIC + f_nscns dw NUMBER_OF_SECTIONS + f_timdat dd __TIME__ + f_symptr dd SYMBOL_TABLE_OFFSET + f_nsyms dd NUMBER_OF_SYMBOLS + f_opthdr dw 0 + f_flags dw F_AR32WR + F_LNNO + + Sections: db NUMBER_OF_SECTIONS * SCNHSZ dup 0 + + virtual at 0 + symbol_table:: rb NUMBER_OF_SYMBOLS * SYMESZ + end virtual + + virtual at 0 + string_table:: dd STRING_TABLE_SIZE + STRING_POSITION = $ + rb STRING_TABLE_SIZE - $ + end virtual + + virtual at 0 + relocations:: rb NUMBER_OF_RELOCATIONS * RELSZ + end virtual + + element relocatable? + + macro section_start + local sym + element sym : relocatable * (1+SECTION_INDEX) + SYMBOL_INDEX + SECTION_BASE = sym + org sym + if DEFINED_SECTION | defined DEFAULT_SECTION + store SECTION_NAME : 8 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_name + store C_STAT at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_sclass + store 1+SECTION_INDEX at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_scnum + SYMBOL_INDEX = SYMBOL_INDEX + 1 + end if + end macro + + RELOCATION_INDEX = 0 + SECTION_INDEX = 0 + SECTION_RELOCATION_INDEX = RELOCATION_INDEX + SYMBOL_INDEX = 0 + + SECTION_OFFSET = $% + SECTION_ALIGN = 4 + SECTION_NAME = '.flat' + SECTION_FLAGS = STYP_TEXT + STYP_DATA + DEFINED_SECTION = 0 + section_start + +end namespace + +macro section? + namespace COFF + + SECTION_SIZE = $% - SECTION_OFFSET + + if DEFINED_SECTION | SECTION_SIZE > 0 + + if ~ DEFINED_SECTION + DEFAULT_SECTION := 1 + end if + + if $%% = SECTION_OFFSET + SECTION_FLAGS = SECTION_FLAGS or STYP_BSS + SECTION_OFFSET = 0 + section $ + else + UNINITIALIZED_LENGTH = $% - $%% + section $ + db UNINITIALIZED_LENGTH dup 0 + end if + + store SECTION_NAME : 8 at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_name + store SECTION_OFFSET at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_scnptr + store SECTION_SIZE at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_size + store SECTION_FLAGS at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_flags + + if RELOCATION_INDEX > SECTION_RELOCATION_INDEX + store RELOCATION_INDEX - SECTION_RELOCATION_INDEX at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_nreloc + store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * RELSZ at COFF:Sections + SECTION_INDEX * SCNHSZ + SCNHDR.s_relptr + end if + + SECTION_INDEX = SECTION_INDEX + 1 + + end if + + end namespace +end macro + +macro section? declaration* + namespace COFF + + section + + DEFINED_SECTION = 1 + SECTION_FLAGS = 0 + SECTION_OFFSET = $% + SECTION_ALIGN = 4 + + match name attributes, declaration + + SECTION_NAME = name + + local seq,list + define seq attributes + while 1 + match car cdr, seq + define list car + define seq cdr + else + match any, seq + define list any + end match + break + end match + end while + irpv attribute, list + match =code?, attribute + SECTION_FLAGS = SECTION_FLAGS or STYP_TEXT + else match =data?, attribute + SECTION_FLAGS = SECTION_FLAGS or STYP_DATA + else + err 'unknown attribute "',`attribute,'"' + end match + end irpv + + else + + SECTION_NAME = declaration + + end match + + section_start + + SECTION_RELOCATION_INDEX = RELOCATION_INDEX + + end namespace +end macro + +calminstruction align? boundary,value:? + check COFF.SECTION_ALIGN mod (boundary) = 0 + jyes allowed + err 'section not aligned enough' + exit + allowed: + compute boundary, (boundary-1)-($-COFF.SECTION_BASE+boundary-1) mod boundary + arrange value, =db boundary =dup value + assemble value +end calminstruction + +macro public? declaration* + namespace COFF + match =static? value =as? str, declaration + SYMBOL_VALUE = value + SYMBOL_NAME = string str + SYMBOL_CLASS = C_STAT + else match value =as? str, declaration + SYMBOL_VALUE = value + SYMBOL_NAME = string str + SYMBOL_CLASS = C_EXT + else match =static? value, declaration + SYMBOL_VALUE = value + SYMBOL_NAME = `value + SYMBOL_CLASS = C_STAT + else + SYMBOL_VALUE = declaration + SYMBOL_NAME = `declaration + SYMBOL_CLASS = C_EXT + end match + if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & 1 scaleof (1 metadataof SYMBOL_VALUE) > 0 + SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE) + SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE + else + SYMBOL_SECTION_INDEX = N_ABS + end if + if lengthof SYMBOL_NAME > 8 + store 0 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_zeroes + store STRING_POSITION at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_offset + store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION + STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1 + else + store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_name + end if + store SYMBOL_VALUE at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_value + store SYMBOL_SECTION_INDEX at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_scnum + store SYMBOL_CLASS at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_sclass + SYMBOL_INDEX = SYMBOL_INDEX + 1 + end namespace +end macro + +macro extrn? declaration* + namespace COFF + local sym,psym + element sym : relocatable * (-1) + SYMBOL_INDEX + match str =as? name:size, declaration + label name:size at sym + SYMBOL_NAME = string str + else match name:size, declaration + label name:size at sym + SYMBOL_NAME = `name + else match str =as? name, declaration + label name at sym + SYMBOL_NAME = string str + else + label declaration at sym + SYMBOL_NAME = `declaration + end match + if lengthof SYMBOL_NAME > 8 + store 0 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_zeroes + store STRING_POSITION at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_offset + store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION + STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1 + else + store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_name + end if + store C_EXT at symbol_table : SYMBOL_INDEX * SYMESZ + SYMENT.e_sclass + SYMBOL_INDEX = SYMBOL_INDEX + 1 + end namespace +end macro + +calminstruction calminstruction?.initsym? var*, val& + publish var, val +end calminstruction + +calminstruction calminstruction?.asm? line& + local name, i + initsym name, name.0 + match name.i, name + compute i, i+1 + arrange name, name.i + publish name, line + arrange line, =assemble name + assemble line +end calminstruction + +calminstruction dword? value + compute value, value + check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable + jyes addr32 + check ~ value relativeto 0 & (value + COFF.SECTION_BASE) relativeto 1 elementof (value + COFF.SECTION_BASE) + jno plain + check 1 elementof (1 metadataof (value + COFF.SECTION_BASE)) relativeto COFF.relocatable + jyes rel32 + plain: + emit 4, value + exit + local offset, symndx, type + addr32: + compute symndx, 0 scaleof (1 metadataof value) + compute type, RELOC_ADDR32 + jump add_relocation + rel32: + compute value, value + COFF.SECTION_BASE + compute symndx, 0 scaleof (1 metadataof value) + compute type, RELOC_REL32 + jump add_relocation + add_relocation: + compute offset, $% + emit 4, 0 scaleof value + check $% > offset + jno done + compute offset, offset - COFF.SECTION_OFFSET + local reloc + compute reloc, COFF.RELOCATION_INDEX * RELSZ + asm store offset at COFF.relocations : reloc + RELOC.r_vaddr + asm store symndx at COFF.relocations : reloc + RELOC.r_symndx + asm store type at COFF.relocations : reloc + RELOC.r_type + compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1 + done: +end calminstruction + +calminstruction dd? definitions& + local value, n + start: + match value=,definitions, definitions, () + jyes recognize + match value, definitions + arrange definitions, + recognize: + match n =dup? value, value, () + jyes duplicate + match ?, value + jyes reserve + call dword, value + next: + match , definitions + jno start + take , definitions + take definitions, definitions + jyes next + exit + reserve: + emit dword + jump next + duplicate: + match (value), value + stack: + check n + jno next + take definitions, value + arrange value, definitions + compute n, n - 1 + jump stack +end calminstruction + +calminstruction (label) dd? definitions& + local cmd + arrange cmd, =label label : =dword + assemble cmd + arrange cmd, =dd definitions + assemble cmd +end calminstruction + +postpone + purge section? + section + namespace COFF + + NUMBER_OF_SECTIONS := SECTION_INDEX + STRING_TABLE_SIZE := STRING_POSITION + NUMBER_OF_SYMBOLS := SYMBOL_INDEX + NUMBER_OF_RELOCATIONS := RELOCATION_INDEX + + RELOCATIONS_OFFSET = $% + load byte_sequence : NUMBER_OF_RELOCATIONS * RELSZ from relocations:0 + db byte_sequence + + SYMBOL_TABLE_OFFSET = $% + load byte_sequence : NUMBER_OF_SYMBOLS * SYMESZ from symbol_table:0 + db byte_sequence + + load byte_sequence : STRING_TABLE_SIZE from string_table:0 + db byte_sequence + + end namespace +end postpone diff --git a/toolchain/fasmg.kl0e/examples/x86/include/format/coffms.inc b/toolchain/fasmg.kl0e/examples/x86/include/format/coffms.inc new file mode 100644 index 0000000..0935344 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/format/coffms.inc @@ -0,0 +1,754 @@ + +macro struct? name + macro end?.struct?! + end namespace + esc end struc + virtual at 0 + name name + sizeof.name = $ + end virtual + purge end?.struct? + end macro + esc struc name + label . : sizeof.name + namespace . +end macro + +struct IMAGE_SECTION_HEADER + Name db 8 dup ? + VirtualSize dd ? + VirtualAddress dd ? + SizeOfRawData dd ? + PointerToRawData dd ? + PointerToRelocations dd ? + PointerToLinenumbers dd ? + NumberOfRelocations dw ? + NumberOfLinenumbers dw ? + Characteristics dd ? +end struct + +struct IMAGE_RELOCATION + VirtualAddress dd ? + SymbolTableIndex dd ? + Type dw ? +end struct + +struct IMAGE_SYMBOL + ShortName db 8 dup ? + virtual at ShortName + Zeroes dd ? + Offset dd ? + end virtual + Value dd ? + SectionNumber dw ? + Type dw ? + StorageClass db ? + NumberOfAuxSymbols db ? +end struct + +IMAGE_FILE_MACHINE_UNKNOWN = 0x0 +IMAGE_FILE_MACHINE_AM33 = 0x1D3 +IMAGE_FILE_MACHINE_AMD64 = 0x8664 +IMAGE_FILE_MACHINE_ARM = 0x1C0 +IMAGE_FILE_MACHINE_ARMNT = 0x1C4 +IMAGE_FILE_MACHINE_ARM64 = 0xAA64 +IMAGE_FILE_MACHINE_EBC = 0xEBC +IMAGE_FILE_MACHINE_I386 = 0x14C +IMAGE_FILE_MACHINE_IA64 = 0x200 +IMAGE_FILE_MACHINE_M32R = 0x9041 +IMAGE_FILE_MACHINE_MIPS16 = 0x266 +IMAGE_FILE_MACHINE_MIPSFPU = 0x366 +IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466 +IMAGE_FILE_MACHINE_POWERPC = 0x1F0 +IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1 +IMAGE_FILE_MACHINE_R4000 = 0x166 +IMAGE_FILE_MACHINE_SH3 = 0x1A2 +IMAGE_FILE_MACHINE_SH3DSP = 0x1A3 +IMAGE_FILE_MACHINE_SH4 = 0x1A6 +IMAGE_FILE_MACHINE_SH5 = 0x1A8 +IMAGE_FILE_MACHINE_THUMB = 0x1C2 +IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169 + +IMAGE_FILE_RELOCS_STRIPPED = 0x0001 +IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002 +IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004 +IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008 +IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010 +IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020 +IMAGE_FILE_BYTES_REVERSED_LO = 0x0080 +IMAGE_FILE_32BIT_MACHINE = 0x0100 +IMAGE_FILE_DEBUG_STRIPPED = 0x0200 +IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400 +IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800 +IMAGE_FILE_SYSTEM = 0x1000 +IMAGE_FILE_DLL = 0x2000 +IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000 +IMAGE_FILE_BYTES_REVERSED_HI = 0x8000 + +IMAGE_SCN_TYPE_NO_PAD = 0x00000008 +IMAGE_SCN_CNT_CODE = 0x00000020 +IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040 +IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080 +IMAGE_SCN_LNK_OTHER = 0x00000100 +IMAGE_SCN_LNK_INFO = 0x00000200 +IMAGE_SCN_LNK_REMOVE = 0x00000800 +IMAGE_SCN_LNK_COMDAT = 0x00001000 +IMAGE_SCN_GPREL = 0x00008000 +IMAGE_SCN_MEM_PURGEABLE = 0x00020000 +IMAGE_SCN_MEM_16BIT = 0x00020000 +IMAGE_SCN_MEM_LOCKED = 0x00040000 +IMAGE_SCN_MEM_PRELOAD = 0x00080000 +IMAGE_SCN_ALIGN_1BYTES = 0x00100000 +IMAGE_SCN_ALIGN_2BYTES = 0x00200000 +IMAGE_SCN_ALIGN_4BYTES = 0x00300000 +IMAGE_SCN_ALIGN_8BYTES = 0x00400000 +IMAGE_SCN_ALIGN_16BYTES = 0x00500000 +IMAGE_SCN_ALIGN_32BYTES = 0x00600000 +IMAGE_SCN_ALIGN_64BYTES = 0x00700000 +IMAGE_SCN_ALIGN_128BYTES = 0x00800000 +IMAGE_SCN_ALIGN_256BYTES = 0x00900000 +IMAGE_SCN_ALIGN_512BYTES = 0x00A00000 +IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000 +IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000 +IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000 +IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000 +IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000 +IMAGE_SCN_MEM_DISCARDABLE = 0x02000000 +IMAGE_SCN_MEM_NOT_CACHED = 0x04000000 +IMAGE_SCN_MEM_NOT_PAGED = 0x08000000 +IMAGE_SCN_MEM_SHARED = 0x10000000 +IMAGE_SCN_MEM_EXECUTE = 0x20000000 +IMAGE_SCN_MEM_READ = 0x40000000 +IMAGE_SCN_MEM_WRITE = 0x80000000 + +IMAGE_REL_AMD64_ABSOLUTE = 0x0000 +IMAGE_REL_AMD64_ADDR64 = 0x0001 +IMAGE_REL_AMD64_ADDR32 = 0x0002 +IMAGE_REL_AMD64_ADDR32NB = 0x0003 +IMAGE_REL_AMD64_REL32 = 0x0004 +IMAGE_REL_AMD64_REL32_1 = 0x0005 +IMAGE_REL_AMD64_REL32_2 = 0x0006 +IMAGE_REL_AMD64_REL32_3 = 0x0007 +IMAGE_REL_AMD64_REL32_4 = 0x0008 +IMAGE_REL_AMD64_REL32_5 = 0x0009 +IMAGE_REL_AMD64_SECTION = 0x000A +IMAGE_REL_AMD64_SECREL = 0x000B +IMAGE_REL_AMD64_SECREL7 = 0x000C +IMAGE_REL_AMD64_TOKEN = 0x000D +IMAGE_REL_AMD64_SREL32 = 0x000E +IMAGE_REL_AMD64_PAIR = 0x000F +IMAGE_REL_AMD64_SSPAN32 = 0x0010 + +IMAGE_REL_I386_ABSOLUTE = 0x0000 +IMAGE_REL_I386_DIR16 = 0x0001 +IMAGE_REL_I386_REL16 = 0x0002 +IMAGE_REL_I386_DIR32 = 0x0006 +IMAGE_REL_I386_DIR32NB = 0x0007 +IMAGE_REL_I386_SEG12 = 0x0009 +IMAGE_REL_I386_SECTION = 0x000A +IMAGE_REL_I386_SECREL = 0x000B +IMAGE_REL_I386_TOKEN = 0x000C +IMAGE_REL_I386_SECREL7 = 0x000D +IMAGE_REL_I386_REL32 = 0x0014 + +IMAGE_SYM_UNDEFINED = 0 +IMAGE_SYM_ABSOLUTE = -1 +IMAGE_SYM_DEBUG = -2 + +IMAGE_SYM_TYPE_NULL = 0 +IMAGE_SYM_TYPE_VOID = 1 +IMAGE_SYM_TYPE_CHAR = 2 +IMAGE_SYM_TYPE_SHORT = 3 +IMAGE_SYM_TYPE_INT = 4 +IMAGE_SYM_TYPE_LONG = 5 +IMAGE_SYM_TYPE_FLOAT = 6 +IMAGE_SYM_TYPE_DOUBLE = 7 +IMAGE_SYM_TYPE_STRUCT = 8 +IMAGE_SYM_TYPE_UNION = 9 +IMAGE_SYM_TYPE_ENUM = 10 +IMAGE_SYM_TYPE_MOE = 11 +IMAGE_SYM_TYPE_BYTE = 12 +IMAGE_SYM_TYPE_WORD = 13 +IMAGE_SYM_TYPE_UINT = 14 +IMAGE_SYM_TYPE_DWORD = 15 + +IMAGE_SYM_DTYPE_NULL = 0 +IMAGE_SYM_DTYPE_POINTER = 1 +IMAGE_SYM_DTYPE_FUNCTION = 2 +IMAGE_SYM_DTYPE_ARRAY = 3 + +IMAGE_SYM_CLASS_END_OF_FUNCTION = -1 +IMAGE_SYM_CLASS_NULL = 0 +IMAGE_SYM_CLASS_AUTOMATIC = 1 +IMAGE_SYM_CLASS_EXTERNAL = 2 +IMAGE_SYM_CLASS_STATIC = 3 +IMAGE_SYM_CLASS_REGISTER = 4 +IMAGE_SYM_CLASS_EXTERNAL_DEF = 5 +IMAGE_SYM_CLASS_LABEL = 6 +IMAGE_SYM_CLASS_UNDEFINED_LABEL = 7 +IMAGE_SYM_CLASS_MEMBER_OF_STRUCT = 8 +IMAGE_SYM_CLASS_ARGUMENT = 9 +IMAGE_SYM_CLASS_STRUCT_TAG = 10 +IMAGE_SYM_CLASS_MEMBER_OF_UNION = 11 +IMAGE_SYM_CLASS_UNION_TAG = 12 +IMAGE_SYM_CLASS_TYPE_DEFINITION = 13 +IMAGE_SYM_CLASS_UNDEFINED_STATIC = 14 +IMAGE_SYM_CLASS_ENUM_TAG = 15 +IMAGE_SYM_CLASS_MEMBER_OF_ENUM = 16 +IMAGE_SYM_CLASS_REGISTER_PARAM = 17 +IMAGE_SYM_CLASS_BIT_FIELD = 18 +IMAGE_SYM_CLASS_BLOCK = 100 +IMAGE_SYM_CLASS_FUNCTION = 101 +IMAGE_SYM_CLASS_END_OF_STRUCT = 102 +IMAGE_SYM_CLASS_FILE = 103 +IMAGE_SYM_CLASS_SECTION = 104 +IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105 +IMAGE_SYM_CLASS_CLR_TOKEN = 107 + +IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY = 1 +IMAGE_WEAK_EXTERN_SEARCH_LIBRARY = 2 +IMAGE_WEAK_EXTERN_SEARCH_ALIAS = 3 + +COFF:: + +namespace COFF + + if defined Settings.Machine + MACHINE := Settings.Machine + else + MACHINE := IMAGE_FILE_MACHINE_I386 + end if + + if defined Settings.Characteristics + CHARACTERISTICS = Settings.Characteristics + else + CHARACTERISTICS = IMAGE_FILE_32BIT_MACHINE + end if + + Header: + + Machine dw MACHINE + NumberOfSections dw NUMBER_OF_SECTIONS + TimeDateStamp dd __TIME__ + PointerToSymbolTable dd SYMBOL_TABLE_OFFSET + NumberOfSymbols dd NUMBER_OF_SYMBOLS + SizeOfOptionalHeader dw 0 + Characteristics dw CHARACTERISTICS + + Sections: db NUMBER_OF_SECTIONS * sizeof IMAGE_SECTION_HEADER dup 0 + + virtual at 0 + symbol_table:: rb NUMBER_OF_SYMBOLS * sizeof IMAGE_SYMBOL + end virtual + + virtual at 0 + string_table:: dd STRING_TABLE_SIZE + STRING_POSITION = $ + rb STRING_TABLE_SIZE - $ + end virtual + + virtual at 0 + relocations:: rb NUMBER_OF_RELOCATIONS * sizeof IMAGE_RELOCATION + end virtual + + element relocatable? + + macro section_start + local sym + element sym : relocatable * (1+SECTION_INDEX) + SYMBOL_INDEX + SECTION_BASE = sym + org sym + if DEFINED_SECTION | defined DEFAULT_SECTION + store SECTION_NAME : 8 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.ShortName + store IMAGE_SYM_CLASS_STATIC at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.StorageClass + store 1+SECTION_INDEX at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.SectionNumber + SYMBOL_INDEX = SYMBOL_INDEX + 1 + end if + end macro + + RELOCATION_INDEX = 0 + SECTION_INDEX = 0 + SECTION_RELOCATION_INDEX = RELOCATION_INDEX + SYMBOL_INDEX = 0 + + SECTION_OFFSET = $% + SECTION_ALIGN = 4 + SECTION_NAME = '.flat' + SECTION_FLAGS = IMAGE_SCN_CNT_CODE + IMAGE_SCN_CNT_INITIALIZED_DATA + DEFINED_SECTION = 0 + section_start + +end namespace + +macro section? + namespace COFF + + SECTION_SIZE = $% - SECTION_OFFSET + + if DEFINED_SECTION | SECTION_SIZE > 0 + + if ~ DEFINED_SECTION + DEFAULT_SECTION := 1 + end if + + if $%% = SECTION_OFFSET + SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_CNT_UNINITIALIZED_DATA + SECTION_OFFSET = 0 + section $ + else + UNINITIALIZED_LENGTH = $% - $%% + section $ + db UNINITIALIZED_LENGTH dup 0 + end if + + if RELOCATION_INDEX > SECTION_RELOCATION_INDEX + store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.PointerToRelocations + if RELOCATION_INDEX - SECTION_RELOCATION_INDEX > 65535 + SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_LNK_NRELOC_OVFL + store 0FFFFh at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.NumberOfRelocations + load RELOCATIONS : (RELOCATION_INDEX - SECTION_RELOCATION_INDEX) * sizeof IMAGE_RELOCATION from relocations : SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION + store RELOCATIONS : (RELOCATION_INDEX - SECTION_RELOCATION_INDEX) * sizeof IMAGE_RELOCATION at relocations : (SECTION_RELOCATION_INDEX+1) * sizeof IMAGE_RELOCATION + RELOCATION_INDEX = RELOCATION_INDEX + 1 + store RELOCATION_INDEX - SECTION_RELOCATION_INDEX at relocations : SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION + IMAGE_RELOCATION.VirtualAddress + store 0 at relocations : SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION + IMAGE_RELOCATION.SymbolTableIndex + store 0 at relocations : SECTION_RELOCATION_INDEX * sizeof IMAGE_RELOCATION + IMAGE_RELOCATION.Type + else + store RELOCATION_INDEX - SECTION_RELOCATION_INDEX at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.NumberOfRelocations + end if + end if + + store SECTION_NAME : 8 at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.Name + store SECTION_OFFSET at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.PointerToRawData + store SECTION_SIZE at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.SizeOfRawData + store SECTION_FLAGS at COFF:Sections + SECTION_INDEX * sizeof IMAGE_SECTION_HEADER + IMAGE_SECTION_HEADER.Characteristics + + SECTION_INDEX = SECTION_INDEX + 1 + + end if + + end namespace +end macro + +macro section? declaration* + namespace COFF + + section + + DEFINED_SECTION = 1 + SECTION_FLAGS = 0 + SECTION_OFFSET = $% + SECTION_ALIGN = 4 + + match name attributes, declaration + + SECTION_NAME = name + + local seq,list + match flags =align? boundary, attributes + SECTION_ALIGN = boundary + define seq flags + else match =align? boundary, attributes + SECTION_ALIGN = boundary + define seq + else + define seq attributes + end match + while 1 + match car cdr, seq + define list car + define seq cdr + else + match any, seq + define list any + end match + break + end match + end while + irpv attribute, list + match =code?, attribute + SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_CNT_CODE + else match =data?, attribute + SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_CNT_INITIALIZED_DATA + else match =readable?, attribute + SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_READ + else match =writeable?, attribute + SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_WRITE + else match =executable?, attribute + SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_EXECUTE + else match =shareable?, attribute + SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_SHARED + else match =discardable?, attribute + SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_DISCARDABLE + else match =notpageable?, attribute + SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_MEM_NOT_PAGED + else match =linkremove?, attribute + SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_LNK_REMOVE + else match =linkinfo?, attribute + SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_LNK_INFO + else + err 'unknown attribute "',`attribute,'"' + end match + end irpv + + else + + SECTION_NAME = declaration + + end match + + repeat 1, i:SECTION_ALIGN + if defined IMAGE_SCN_ALIGN_#i#BYTES + SECTION_FLAGS = SECTION_FLAGS or IMAGE_SCN_ALIGN_#i#BYTES + else + err 'invalid section alignment' + end if + end repeat + + section_start + + SECTION_RELOCATION_INDEX = RELOCATION_INDEX + + end namespace +end macro + +calminstruction align? boundary,value:? + check COFF.SECTION_ALIGN mod (boundary) = 0 + jyes allowed + err 'section not aligned enough' + exit + allowed: + compute boundary, (boundary-1)-($-COFF.SECTION_BASE+boundary-1) mod boundary + arrange value, =db boundary =dup value + assemble value +end calminstruction + +macro public? declaration* + namespace COFF + match =static? value =as? str, declaration + SYMBOL_VALUE = value + SYMBOL_NAME = string str + SYMBOL_CLASS = IMAGE_SYM_CLASS_STATIC + else match value =as? str, declaration + SYMBOL_VALUE = value + SYMBOL_NAME = string str + SYMBOL_CLASS = IMAGE_SYM_CLASS_EXTERNAL + else match =static? value, declaration + SYMBOL_VALUE = value + SYMBOL_NAME = `value + SYMBOL_CLASS = IMAGE_SYM_CLASS_STATIC + else + SYMBOL_VALUE = declaration + SYMBOL_NAME = `declaration + SYMBOL_CLASS = IMAGE_SYM_CLASS_EXTERNAL + end match + if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & SYMBOL_CLASS = IMAGE_SYM_CLASS_EXTERNAL + if 1 scaleof (1 metadataof SYMBOL_VALUE) > 0 + SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE) + SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE + else + SYMBOL_SECTION_INDEX = IMAGE_SYM_UNDEFINED + SYMBOL_VALUE = 0 + SYMBOL_CLASS = IMAGE_SYM_CLASS_WEAK_EXTERNAL + SYMBOL_TAG = 0 scaleof (1 metadataof SYMBOL_VALUE) + end if + else + SYMBOL_SECTION_INDEX = IMAGE_SYM_ABSOLUTE + end if + if lengthof SYMBOL_NAME > 8 + store 0 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Zeroes + store STRING_POSITION at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Offset + store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION + STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1 + else + store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.ShortName + end if + store SYMBOL_VALUE at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Value + store SYMBOL_SECTION_INDEX at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.SectionNumber + store SYMBOL_CLASS at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.StorageClass + if SYMBOL_CLASS = IMAGE_SYM_CLASS_WEAK_EXTERNAL + store 1 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.NumberOfAuxSymbols + SYMBOL_INDEX = SYMBOL_INDEX + 1 + store SYMBOL_TAG : 4 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + store IMAGE_WEAK_EXTERN_SEARCH_ALIAS : 4 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + 4 + end if + SYMBOL_INDEX = SYMBOL_INDEX + 1 + end namespace +end macro + +macro extrn? declaration* + namespace COFF + local sym,psym + element sym : relocatable * (-1) + SYMBOL_INDEX + match str =as? name:size, declaration + label name:size at sym + SYMBOL_NAME = string str + else match name:size, declaration + label name:size at sym + SYMBOL_NAME = `name + else match str =as? name, declaration + label name at sym + SYMBOL_NAME = string str + else + label declaration at sym + SYMBOL_NAME = `declaration + end match + if lengthof SYMBOL_NAME > 8 + store 0 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Zeroes + store STRING_POSITION at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.Offset + store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION + STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1 + else + store SYMBOL_NAME : 8 at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.ShortName + end if + store IMAGE_SYM_CLASS_EXTERNAL at symbol_table : SYMBOL_INDEX * sizeof IMAGE_SYMBOL + IMAGE_SYMBOL.StorageClass + SYMBOL_INDEX = SYMBOL_INDEX + 1 + end namespace +end macro + +element COFF.IMAGE_BASE +RVA? equ -COFF.IMAGE_BASE+ + +calminstruction calminstruction?.initsym? var*, val& + publish var, val +end calminstruction + +calminstruction calminstruction?.asm? line& + local name, i + initsym name, name.0 + match name.i, name + compute i, i+1 + arrange name, name.i + publish name, line + arrange line, =assemble name + assemble line +end calminstruction + +if COFF.MACHINE = IMAGE_FILE_MACHINE_I386 + + calminstruction dword? value + compute value, value + check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable + jyes dir32 + check ~ value relativeto 0 & (value + COFF.IMAGE_BASE) relativeto 1 elementof (value + COFF.IMAGE_BASE) & 1 elementof (1 metadataof (value + COFF.IMAGE_BASE)) relativeto COFF.relocatable + jyes dir32nb + check ~ value relativeto 0 & (value + COFF.SECTION_BASE) relativeto 1 elementof (value + COFF.SECTION_BASE) + jno plain + check 1 elementof (1 metadataof (value + COFF.SECTION_BASE)) relativeto COFF.relocatable + jyes rel32 + plain: + emit 4, value + exit + local offset, symndx, type + dir32: + compute symndx, 0 scaleof (1 metadataof value) + compute type, IMAGE_REL_I386_DIR32 + jump add_relocation + dir32nb: + compute value, value + COFF.IMAGE_BASE + compute symndx, 0 scaleof (1 metadataof value) + compute type, IMAGE_REL_I386_DIR32NB + jump add_relocation + rel32: + compute value, value + (COFF.SECTION_BASE + $% + 4 - COFF.SECTION_OFFSET) + compute symndx, 0 scaleof (1 metadataof value) + compute type, IMAGE_REL_I386_REL32 + jump add_relocation + add_relocation: + compute offset, $% + emit 4, 0 scaleof value + check $% > offset + jno done + compute offset, offset - COFF.SECTION_OFFSET + local relocation + compute relocation, COFF.RELOCATION_INDEX * sizeof IMAGE_RELOCATION + asm store offset at COFF.relocations : relocation + IMAGE_RELOCATION.VirtualAddress + asm store symndx at COFF.relocations : relocation + IMAGE_RELOCATION.SymbolTableIndex + asm store type at COFF.relocations : relocation + IMAGE_RELOCATION.Type + compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1 + done: + end calminstruction + + calminstruction qword? value + compute value, value + check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable + jyes dir32 + check ~ value relativeto 0 & (value + COFF.IMAGE_BASE) relativeto 1 elementof (value + COFF.IMAGE_BASE) & 1 elementof (1 metadataof (value + COFF.IMAGE_BASE)) relativeto COFF.relocatable + jyes dir32nb + plain: + emit 8, value + exit + local offset, symndx, type + dir32: + compute symndx, 0 scaleof (1 metadataof value) + compute type, IMAGE_REL_I386_DIR32 + jump add_relocation + dir32nb: + compute value, value + COFF.IMAGE_BASE + compute symndx, 0 scaleof (1 metadataof value) + compute type, IMAGE_REL_I386_DIR32NB + jump add_relocation + add_relocation: + compute offset, $% + emit 8, 0 scaleof value + check $% > offset + jno done + compute offset, offset - COFF.SECTION_OFFSET + local relocation + compute relocation, COFF.RELOCATION_INDEX * sizeof IMAGE_RELOCATION + asm store offset at COFF.relocations : relocation + IMAGE_RELOCATION.VirtualAddress + asm store symndx at COFF.relocations : relocation + IMAGE_RELOCATION.SymbolTableIndex + asm store type at COFF.relocations : relocation + IMAGE_RELOCATION.Type + compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1 + done: + end calminstruction + +else if COFF.MACHINE = IMAGE_FILE_MACHINE_AMD64 + + calminstruction dword? value + compute value, value + check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable + jyes addr32 + check ~ value relativeto 0 & (value + COFF.IMAGE_BASE) relativeto 1 elementof (value + COFF.IMAGE_BASE) & 1 elementof (1 metadataof (value + COFF.IMAGE_BASE)) relativeto COFF.relocatable + jyes addr32nb + check ~ value relativeto 0 & (value + COFF.SECTION_BASE) relativeto 1 elementof (value + COFF.SECTION_BASE) + jno plain + check 1 elementof (1 metadataof (value + COFF.SECTION_BASE)) relativeto COFF.relocatable + jyes rel32 + plain: + emit 4, value + exit + local offset, symndx, type + addr32: + compute symndx, 0 scaleof (1 metadataof value) + compute type, IMAGE_REL_AMD64_ADDR32 + jump add_relocation + addr32nb: + compute value, value + COFF.IMAGE_BASE + compute symndx, 0 scaleof (1 metadataof value) + compute type, IMAGE_REL_AMD64_ADDR32NB + jump add_relocation + rel32: + compute value, value + (COFF.SECTION_BASE + $% + 4 - COFF.SECTION_OFFSET) + compute symndx, 0 scaleof (1 metadataof value) + compute type, IMAGE_REL_AMD64_REL32 + jump add_relocation + add_relocation: + compute offset, $% + emit 4, 0 scaleof value + check $% > offset + jno done + compute offset, offset - COFF.SECTION_OFFSET + local relocation + compute relocation, COFF.RELOCATION_INDEX * sizeof IMAGE_RELOCATION + asm store offset at COFF.relocations : relocation + IMAGE_RELOCATION.VirtualAddress + asm store symndx at COFF.relocations : relocation + IMAGE_RELOCATION.SymbolTableIndex + asm store type at COFF.relocations : relocation + IMAGE_RELOCATION.Type + compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1 + done: + end calminstruction + + calminstruction qword? value + compute value, value + check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto COFF.relocatable + jyes addr64 + check ~ value relativeto 0 & (value + COFF.IMAGE_BASE) relativeto 1 elementof (value + COFF.IMAGE_BASE) & 1 elementof (1 metadataof (value + COFF.IMAGE_BASE)) relativeto COFF.relocatable + jyes addr64nb + plain: + emit 8, value + exit + local offset, symndx, type + addr64: + compute symndx, 0 scaleof (1 metadataof value) + compute type, IMAGE_REL_AMD64_ADDR64 + jump add_relocation + addr64nb: + compute value, value + COFF.IMAGE_BASE + compute symndx, 0 scaleof (1 metadataof value) + compute type, IMAGE_REL_AMD64_ADDR64NB + jump add_relocation + add_relocation: + compute offset, $% + emit 8, 0 scaleof value + check $% > offset + jno done + compute offset, offset - COFF.SECTION_OFFSET + local relocation + compute relocation, COFF.RELOCATION_INDEX * sizeof IMAGE_RELOCATION + asm store offset at COFF.relocations : relocation + IMAGE_RELOCATION.VirtualAddress + asm store symndx at COFF.relocations : relocation + IMAGE_RELOCATION.SymbolTableIndex + asm store type at COFF.relocations : relocation + IMAGE_RELOCATION.Type + compute COFF.RELOCATION_INDEX, COFF.RELOCATION_INDEX + 1 + done: + end calminstruction + +end if + +iterate , dd,dword, dq,qword + + calminstruction dd? definitions& + local value, n + start: + match value=,definitions, definitions, () + jyes recognize + match value, definitions + arrange definitions, + recognize: + match n =dup? value, value, () + jyes duplicate + match ?, value + jyes reserve + call dword, value + next: + match , definitions + jno start + take , definitions + take definitions, definitions + jyes next + exit + reserve: + emit dword + jump next + duplicate: + match (value), value + stack: + check n + jno next + take definitions, value + arrange value, definitions + compute n, n - 1 + jump stack + end calminstruction + + calminstruction (label) dd? definitions& + local cmd + arrange cmd, =label label : =dword + assemble cmd + arrange cmd, =dd definitions + assemble cmd + end calminstruction + +end iterate + +postpone + purge section? + section + namespace COFF + + NUMBER_OF_SECTIONS := SECTION_INDEX + STRING_TABLE_SIZE := STRING_POSITION + NUMBER_OF_SYMBOLS := SYMBOL_INDEX + NUMBER_OF_RELOCATIONS := RELOCATION_INDEX + + RELOCATIONS_OFFSET = $% + load byte_sequence : NUMBER_OF_RELOCATIONS * sizeof IMAGE_RELOCATION from relocations:0 + db byte_sequence + + SYMBOL_TABLE_OFFSET = $% + load byte_sequence : NUMBER_OF_SYMBOLS * sizeof IMAGE_SYMBOL from symbol_table:0 + db byte_sequence + + load byte_sequence : STRING_TABLE_SIZE from string_table:0 + db byte_sequence + + end namespace +end postpone diff --git a/toolchain/fasmg.kl0e/examples/x86/include/format/elf32.inc b/toolchain/fasmg.kl0e/examples/x86/include/format/elf32.inc new file mode 100644 index 0000000..b8f65b9 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/format/elf32.inc @@ -0,0 +1,640 @@ + +macro struct? name + macro end?.struct?! + end namespace + esc end struc + virtual at 0 + name name + sizeof.name = $ + end virtual + purge end?.struct? + end macro + esc struc name + label . : sizeof.name + namespace . +end macro + +struct Elf32_Shdr + sh_name dd ? + sh_type dd ? + sh_flags dd ? + sh_addr dd ? + sh_offset dd ? + sh_size dd ? + sh_link dd ? + sh_info dd ? + sh_addralign dd ? + sh_entsize dd ? +end struct + +struct Elf32_Sym + st_name dd ? + st_value dd ? + st_size dd ? + st_info db ? + st_other db ? + st_shndx dw ? +end struct + +struct Elf32_Rel + r_offset dd ? + r_info dd ? +end struct + +struct Elf32_Rela + r_offset dd ? + r_info dd ? + r_addend dd ? +end struct + +struct Elf32_Phdr + p_type dd ? + p_offset dd ? + p_vaddr dd ? + p_paddr dd ? + p_filesz dd ? + p_memsz dd ? + p_flags dd ? + p_align dd ? +end struct + +purge struct? + +ELFCLASSNONE = 0 +ELFCLASS32 = 1 +ELFCLASS64 = 2 + +ELFDATANONE = 0 +ELFDATA2LSB = 1 +ELFDATA2MSB = 2 + +ELFOSABI_NONE = 0 +ELFOSABI_HPUX = 1 +ELFOSABI_NETBSD = 2 +ELFOSABI_GNU = 3 +ELFOSABI_LINUX = 3 +ELFOSABI_SOLARIS = 6 +ELFOSABI_AIX = 7 +ELFOSABI_IRIX = 8 +ELFOSABI_FREEBSD = 9 +ELFOSABI_TRU64 = 10 +ELFOSABI_MODESTO = 11 +ELFOSABI_OPENBSD = 12 +ELFOSABI_OPENVMS = 13 +ELFOSABI_NSK = 14 +ELFOSABI_AROS = 15 +ELFOSABI_FENIXOS = 16 +ELFOSABI_CLOUDABI = 17 +ELFOSABI_OPENVOS = 18 + +ET_NONE = 0 +ET_REL = 1 +ET_EXEC = 2 +ET_DYN = 3 +ET_CORE = 4 +ET_LOPROC = 0xff00 +ET_HIPROC = 0xffff + +EM_NONE = 0 +EM_M32 = 1 +EM_SPARC = 2 +EM_386 = 3 +EM_68K = 4 +EM_88K = 5 +EM_860 = 7 +EM_MIPS = 8 +EM_X86_64 = 62 + +EV_NONE = 0 +EV_CURRENT = 1 + +SHN_UNDEF = 0 +SHN_LORESERVE = 0xff00 +SHN_LOPROC = 0xff00 +SHN_HIPROC = 0xff1f +SHN_ABS = 0xfff1 +SHN_COMMON = 0xfff2 +SHN_HIRESERVE = 0xffff + +SHT_NULL = 0 +SHT_PROGBITS = 1 +SHT_SYMTAB = 2 +SHT_STRTAB = 3 +SHT_RELA = 4 +SHT_HASH = 5 +SHT_DYNAMIC = 6 +SHT_NOTE = 7 +SHT_NOBITS = 8 +SHT_REL = 9 +SHT_SHLIB = 10 +SHT_DYNSYM = 11 +SHT_LOPROC = 0x70000000 +SHT_HIPROC = 0x7fffffff +SHT_LOUSER = 0x80000000 +SHT_HIUSER = 0xffffffff + +SHF_WRITE = 0x1 +SHF_ALLOC = 0x2 +SHF_EXECINSTR = 0x4 +SHF_MASKPROC = 0xf0000000 + +STT_NOTYPE = 0 +STT_OBJECT = 1 +STT_FUNC = 2 +STT_SECTION = 3 +STT_FILE = 4 +STT_LOPROC = 13 +STT_HIPROC = 15 + +STB_LOCAL = 0 +STB_GLOBAL = 1 +STB_WEAK = 2 +STB_LOPROC = 13 +STB_HIPROC = 15 + +R_386_NONE = 0 +R_386_32 = 1 +R_386_PC32 = 2 +R_386_GOT32 = 3 +R_386_PLT32 = 4 +R_386_COPY = 5 +R_386_GLOB_DAT = 6 +R_386_JMP_SLOT = 7 +R_386_RELATIVE = 8 +R_386_GOTOFF = 9 +R_386_GOTPC = 10 + +R_X86_64_NONE = 0 +R_X86_64_64 = 1 +R_X86_64_PC32 = 2 +R_X86_64_GOT32 = 3 +R_X86_64_PLT32 = 4 +R_X86_64_COPY = 5 +R_X86_64_GLOB_DAT = 6 +R_X86_64_JUMP_SLOT = 7 +R_X86_64_RELATIVE = 8 +R_X86_64_GOTPCREL = 9 +R_X86_64_32 = 10 +R_X86_64_32S = 11 +R_X86_64_16 = 12 +R_X86_64_PC16 = 13 +R_X86_64_8 = 14 +R_X86_64_PC8 = 15 +R_X86_64_DPTMOD64 = 16 +R_X86_64_DTPOFF64 = 17 +R_X86_64_TPOFF64 = 18 +R_X86_64_TLSGD = 19 +R_X86_64_TLSLD = 20 +R_X86_64_DTPOFF32 = 21 +R_X86_64_GOTTPOFF = 22 +R_X86_64_TPOFF32 = 23 +R_X86_64_PC64 = 24 +R_X86_64_GOTOFF64 = 25 +R_X86_64_GOTPC32 = 26 + +ELF:: + +namespace ELF + + if defined Settings.Machine + MACHINE := Settings.Machine + else + MACHINE := EM_386 + end if + + if defined Settings.ABI + ABI := Settings.ABI + else + ABI := ELFOSABI_NONE + end if + + if MACHINE = EM_386 + R_32 = R_386_32 + R_PC32 = R_386_PC32 + R_GOTOFF = R_386_GOTOFF + R_PLT32 = R_386_PLT32 + else if MACHINE = EM_X86_64 + R_32 = R_X86_64_32 + R_PC32 = R_X86_64_PC32 + R_PLT32 = R_X86_64_PLT32 + end if + + Header: + + e_ident db 0x7F,'ELF',ELFCLASS32,ELFDATA2LSB,EV_CURRENT,ABI,(16-$) dup 0 + e_type dw ET_REL + e_machine dw MACHINE + e_version dd EV_CURRENT + e_entry dd 0 + e_phoff dd 0 + e_shoff dd SECTION_TABLE_OFFSET + e_flags dd 0 + e_ehsize dw Content + e_phentsize dw 0 + e_phnum dw 0 + e_shentsize dw sizeof Elf32_Shdr + e_shnum dw NUMBER_OF_SECTIONS + e_shstrndx dw STRING_TABLE_SECTION_INDEX + + Content: + + virtual at 0 + section_table:: rb NUMBER_OF_SECTIONS * sizeof Elf32_Shdr + end virtual + + virtual at 0 + symbol_table:: rb NUMBER_OF_SYMBOLS * sizeof Elf32_Sym + end virtual + + virtual at 0 + string_table:: + _null db 0 + _symtab db '.symtab',0 + _strtab db '.strtab',0 + SECTION_NAME_POSITION = $ + rb SECTION_NAME_TABLE_SIZE - $ + STRING_POSITION = $ + rb STRING_TABLE_SIZE - $ + end virtual + + virtual at 0 + relocations:: rb NUMBER_OF_RELOCATIONS * sizeof Elf32_Rel + end virtual + + element relocatable? + + macro section_org + local sym + element sym : relocatable * SECTION_INDEX + SECTION_SYMBOL_INDEX + SECTION_BASE = sym + org sym + end macro + + RELOCATION_INDEX = 0 + SECTION_INDEX = 1 + SECTION_SYMBOL_INDEX = SECTION_INDEX + SECTION_RELOCATION_INDEX = RELOCATION_INDEX + SYMBOL_INDEX = NUMBER_OF_SECTION_SYMBOLS + + SECTION_OFFSET = $% + SECTION_ALIGN = 4 + SECTION_NAME = '.flat' + SECTION_FLAGS = SHF_ALLOC + SHF_WRITE + SHF_EXECINSTR + DEFINED_SECTION = 0 + section_org + +end namespace + +macro section? + namespace ELF + + SECTION_SIZE = $% - SECTION_OFFSET + + if DEFINED_SECTION | SECTION_SIZE > 0 + + store SECTION_OFFSET at section_table : Elf32_Shdr.sh_offset + SECTION_INDEX * sizeof Elf32_Shdr + store SECTION_SIZE at section_table : Elf32_Shdr.sh_size + SECTION_INDEX * sizeof Elf32_Shdr + store SECTION_ALIGN at section_table : Elf32_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf32_Shdr + store SECTION_FLAGS at section_table : Elf32_Shdr.sh_flags + SECTION_INDEX * sizeof Elf32_Shdr + + if $%% = SECTION_OFFSET + store SHT_NOBITS at section_table : Elf32_Shdr.sh_type + SECTION_INDEX * sizeof Elf32_Shdr + section $ + else + store SHT_PROGBITS at section_table : Elf32_Shdr.sh_type + SECTION_INDEX * sizeof Elf32_Shdr + UNINITIALIZED_LENGTH = $% - $%% + section $ + db UNINITIALIZED_LENGTH dup 0 + end if + + store SECTION_INDEX at symbol_table : Elf32_Sym.st_shndx + SECTION_SYMBOL_INDEX * sizeof Elf32_Sym + store STT_SECTION + STB_LOCAL shl 4 at symbol_table : Elf32_Sym.st_info + SECTION_SYMBOL_INDEX * sizeof Elf32_Sym + + if RELOCATION_INDEX > SECTION_RELOCATION_INDEX + + store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * sizeof Elf32_Rel at section_table : Elf32_Shdr.sh_offset + (SECTION_INDEX+1) * sizeof Elf32_Shdr + store (RELOCATION_INDEX - SECTION_RELOCATION_INDEX) * sizeof Elf32_Rel at section_table : Elf32_Shdr.sh_size + (SECTION_INDEX+1) * sizeof Elf32_Shdr + store SHT_REL at section_table : Elf32_Shdr.sh_type + (SECTION_INDEX+1) * sizeof Elf32_Shdr + store SYMBOL_TABLE_SECTION_INDEX at section_table : Elf32_Shdr.sh_link + (SECTION_INDEX+1) * sizeof Elf32_Shdr + store SECTION_INDEX at section_table : Elf32_Shdr.sh_info + (SECTION_INDEX+1) * sizeof Elf32_Shdr + store sizeof Elf32_Rel at section_table : Elf32_Shdr.sh_entsize + (SECTION_INDEX+1) * sizeof Elf32_Shdr + store 4 at section_table : Elf32_Shdr.sh_addralign + (SECTION_INDEX+1) * sizeof Elf32_Shdr + + store SECTION_NAME_POSITION at section_table : Elf32_Shdr.sh_name + (SECTION_INDEX+1) * sizeof Elf32_Shdr + store SECTION_NAME_POSITION + 4 at section_table : Elf32_Shdr.sh_name + SECTION_INDEX * sizeof Elf32_Shdr + store SECTION_NAME_POSITION + 4 at symbol_table : Elf32_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf32_Sym + store '.rel' + SECTION_NAME shl (4*8) : 4 + lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION + SECTION_NAME_POSITION = SECTION_NAME_POSITION + 4 + lengthof (string SECTION_NAME) + 1 + + SECTION_INDEX = SECTION_INDEX + 2 + SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1 + + else + store SECTION_NAME_POSITION at section_table : Elf32_Shdr.sh_name + SECTION_INDEX * sizeof Elf32_Shdr + store SECTION_NAME_POSITION at symbol_table : Elf32_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf32_Sym + store SECTION_NAME : lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION + SECTION_NAME_POSITION = SECTION_NAME_POSITION + lengthof (string SECTION_NAME) + 1 + + SECTION_INDEX = SECTION_INDEX + 1 + SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1 + + end if + + end if + + end namespace +end macro + +macro section? declaration* + namespace ELF + + section + + DEFINED_SECTION = 1 + SECTION_FLAGS = SHF_ALLOC + SECTION_OFFSET = $% + SECTION_ALIGN = 4 + + match name attributes, declaration + + SECTION_NAME = name + + local seq,list + match flags =align? boundary, attributes + SECTION_ALIGN = boundary + define seq flags + else match =align? boundary, attributes + SECTION_ALIGN = boundary + define seq + else + define seq attributes + end match + while 1 + match car cdr, seq + define list car + define seq cdr + else + match any, seq + define list any + end match + break + end match + end while + irpv attribute, list + match =writeable?, attribute + SECTION_FLAGS = SECTION_FLAGS or SHF_WRITE + else match =executable?, attribute + SECTION_FLAGS = SECTION_FLAGS or SHF_EXECINSTR + else + err 'unknown attribute "',`attribute,'"' + end match + end irpv + + else + + SECTION_NAME = declaration + + end match + + section_org + + SECTION_RELOCATION_INDEX = RELOCATION_INDEX + + end namespace +end macro + +calminstruction align? boundary,value:? + check ELF.SECTION_ALIGN mod (boundary) = 0 + jyes allowed + err 'section not aligned enough' + exit + allowed: + compute boundary, (boundary-1)-($-ELF.SECTION_BASE+boundary-1) mod boundary + arrange value, =db boundary =dup value + assemble value +end calminstruction + +macro public? declaration* + namespace ELF + match value =as? str, declaration + SYMBOL_VALUE = value + SYMBOL_SIZE = sizeof value + SYMBOL_NAME = string str + else + SYMBOL_VALUE = declaration + SYMBOL_SIZE = sizeof declaration + SYMBOL_NAME = `declaration + end match + if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & 1 scaleof (1 metadataof SYMBOL_VALUE) > 0 + SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE) + SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE + else + SYMBOL_SECTION_INDEX = SHN_ABS + end if + store STRING_POSITION at symbol_table : Elf32_Sym.st_name + SYMBOL_INDEX * sizeof Elf32_Sym + store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION + STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1 + store SYMBOL_VALUE at symbol_table : Elf32_Sym.st_value + SYMBOL_INDEX * sizeof Elf32_Sym + store SYMBOL_SIZE at symbol_table : Elf32_Sym.st_size + SYMBOL_INDEX * sizeof Elf32_Sym + store SYMBOL_SECTION_INDEX at symbol_table : Elf32_Sym.st_shndx + SYMBOL_INDEX * sizeof Elf32_Sym + if SYMBOL_SIZE + store STT_OBJECT + STB_GLOBAL shl 4 at symbol_table : Elf32_Sym.st_info + SYMBOL_INDEX * sizeof Elf32_Sym + else + store STT_FUNC + STB_GLOBAL shl 4 at symbol_table : Elf32_Sym.st_info + SYMBOL_INDEX * sizeof Elf32_Sym + end if + SYMBOL_INDEX = SYMBOL_INDEX + 1 + end namespace +end macro + +macro extrn? declaration* + namespace ELF + local sym,psym + element sym : relocatable * (-1) + SYMBOL_INDEX + element psym : PLT + SYMBOL_INDEX + match str =as? name:size, declaration + label name:size at sym + label PLT.name at psym + SYMBOL_NAME = string str + SYMBOL_SIZE = size + else match name:size, declaration + label name:size at sym + label PLT.name at psym + SYMBOL_NAME = `name + SYMBOL_SIZE = size + else match str =as? name, declaration + label name at sym + label PLT.name at psym + SYMBOL_NAME = string str + SYMBOL_SIZE = 0 + else + label declaration at sym + label PLT.declaration at psym + SYMBOL_NAME = `declaration + SYMBOL_SIZE = 0 + end match + store STRING_POSITION at symbol_table : Elf32_Sym.st_name + SYMBOL_INDEX * sizeof Elf32_Sym + store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION + STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1 + store SYMBOL_SIZE at symbol_table : Elf32_Sym.st_size + SYMBOL_INDEX * sizeof Elf32_Sym + store STT_NOTYPE + STB_GLOBAL shl 4 at symbol_table : Elf32_Sym.st_info + SYMBOL_INDEX * sizeof Elf32_Sym + SYMBOL_INDEX = SYMBOL_INDEX + 1 + end namespace +end macro + +element _GLOBAL_OFFSET_TABLE_ +RVA? equ -_GLOBAL_OFFSET_TABLE_+ +element PLT? + +calminstruction calminstruction?.initsym? var*, val& + publish var, val +end calminstruction + +calminstruction calminstruction?.asm? line& + local name, i + initsym name, name.0 + match name.i, name + compute i, i+1 + arrange name, name.i + publish name, line + arrange line, =assemble name + assemble line +end calminstruction + +calminstruction dword? value + compute value, value + check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto ELF.relocatable + jyes r_32 + check ~ value relativeto 0 & (value + _GLOBAL_OFFSET_TABLE_) relativeto 1 elementof (value + _GLOBAL_OFFSET_TABLE_) & 1 elementof (1 metadataof (value + _GLOBAL_OFFSET_TABLE_)) relativeto ELF.relocatable + jyes r_gotoff + check ~ value relativeto 0 & (value + ELF.SECTION_BASE) relativeto 1 elementof (value + ELF.SECTION_BASE) + jno plain + check 1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto ELF.relocatable + jyes r_pc32 + check 1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto PLT + jyes r_plt32 + plain: + emit 4, value + exit + local offset, info + r_32: + compute info, ELF.R_32 + (0 scaleof (1 metadataof value)) shl 8 + jump add_relocation + r_gotoff: + compute value, value + _GLOBAL_OFFSET_TABLE_ + compute info, ELF.R_GOTOFF + (0 scaleof (1 metadataof value)) shl 8 + jump add_relocation + r_pc32: + compute value, value + (ELF.SECTION_BASE + $% - ELF.SECTION_OFFSET) + compute info, ELF.R_PC32 + (0 scaleof (1 metadataof value)) shl 8 + jump add_relocation + r_plt32: + compute value, value + (ELF.SECTION_BASE + $% - ELF.SECTION_OFFSET) + compute info, ELF.R_PLT32 + (0 scaleof (1 metadataof value)) shl 8 + jump add_relocation + add_relocation: + compute offset, $% + emit 4, 0 scaleof value + check $% > offset + jno done + compute offset, offset - ELF.SECTION_OFFSET + local Rel + compute Rel, ELF.RELOCATION_INDEX * sizeof Elf32_Rel + asm store offset at ELF.relocations : Rel + Elf32_Rel.r_offset + asm store info at ELF.relocations : Rel + Elf32_Rel.r_info + compute ELF.RELOCATION_INDEX, ELF.RELOCATION_INDEX + 1 + done: +end calminstruction + +calminstruction dd? definitions& + local value, n + start: + match value=,definitions, definitions, () + jyes recognize + match value, definitions + arrange definitions, + recognize: + match n =dup? value, value, () + jyes duplicate + match ?, value + jyes reserve + call dword, value + next: + match , definitions + jno start + take , definitions + take definitions, definitions + jyes next + exit + reserve: + emit dword + jump next + duplicate: + match (value), value + stack: + check n + jno next + take definitions, value + arrange value, definitions + compute n, n - 1 + jump stack +end calminstruction + +calminstruction (label) dd? definitions& + local cmd + arrange cmd, =label label : =dword + assemble cmd + arrange cmd, =dd definitions + assemble cmd +end calminstruction + +postpone + purge section? + section + namespace ELF + + SECTION_NAME_TABLE_SIZE := SECTION_NAME_POSITION + STRING_TABLE_SIZE := STRING_POSITION + + NUMBER_OF_SECTION_SYMBOLS := SECTION_SYMBOL_INDEX + NUMBER_OF_SYMBOLS := SYMBOL_INDEX + SYMBOL_TABLE_SIZE := NUMBER_OF_SYMBOLS * sizeof Elf32_Sym + + NUMBER_OF_RELOCATIONS := RELOCATION_INDEX + rb (-$%) and 11b + RELOCATIONS_OFFSET = $% + load byte_sequence : NUMBER_OF_RELOCATIONS * sizeof Elf32_Rel from relocations:0 + db byte_sequence + + store _symtab at section_table : Elf32_Shdr.sh_name + SECTION_INDEX * sizeof Elf32_Shdr + store $% at section_table : Elf32_Shdr.sh_offset + SECTION_INDEX * sizeof Elf32_Shdr + store SYMBOL_TABLE_SIZE at section_table : Elf32_Shdr.sh_size + SECTION_INDEX * sizeof Elf32_Shdr + store sizeof Elf32_Sym at section_table : Elf32_Shdr.sh_entsize + SECTION_INDEX * sizeof Elf32_Shdr + store 4 at section_table : Elf32_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf32_Shdr + store SHT_SYMTAB at section_table : Elf32_Shdr.sh_type + SECTION_INDEX * sizeof Elf32_Shdr + store STRING_TABLE_SECTION_INDEX at section_table : Elf32_Shdr.sh_link + SECTION_INDEX * sizeof Elf32_Shdr + store NUMBER_OF_SECTION_SYMBOLS at section_table : Elf32_Shdr.sh_info + SECTION_INDEX * sizeof Elf32_Shdr + SYMBOL_TABLE_SECTION_INDEX := SECTION_INDEX + load byte_sequence : SYMBOL_TABLE_SIZE from symbol_table:0 + db byte_sequence + SECTION_INDEX = SECTION_INDEX + 1 + + store _strtab at section_table : Elf32_Shdr.sh_name + SECTION_INDEX * sizeof Elf32_Shdr + store $% at section_table : Elf32_Shdr.sh_offset + SECTION_INDEX * sizeof Elf32_Shdr + store STRING_TABLE_SIZE at section_table : Elf32_Shdr.sh_size + SECTION_INDEX * sizeof Elf32_Shdr + store 1 at section_table : Elf32_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf32_Shdr + store SHT_STRTAB at section_table : Elf32_Shdr.sh_type + SECTION_INDEX * sizeof Elf32_Shdr + STRING_TABLE_SECTION_INDEX := SECTION_INDEX + load byte_sequence : STRING_TABLE_SIZE from string_table:0 + db byte_sequence + SECTION_INDEX = SECTION_INDEX + 1 + + assert SECTION_INDEX <= SHN_LORESERVE + + NUMBER_OF_SECTIONS := SECTION_INDEX + rb (-$%) and 11b + SECTION_TABLE_OFFSET := $% + load byte_sequence : NUMBER_OF_SECTIONS * sizeof Elf32_Shdr from section_table:0 + db byte_sequence + + end namespace +end postpone diff --git a/toolchain/fasmg.kl0e/examples/x86/include/format/elf64.inc b/toolchain/fasmg.kl0e/examples/x86/include/format/elf64.inc new file mode 100644 index 0000000..0794f9d --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/format/elf64.inc @@ -0,0 +1,652 @@ + +macro struct? name + macro end?.struct?! + end namespace + esc end struc + virtual at 0 + name name + sizeof.name = $ + end virtual + purge end?.struct? + end macro + esc struc name + label . : sizeof.name + namespace . +end macro + +struct Elf64_Shdr + sh_name dd ? + sh_type dd ? + sh_flags dq ? + sh_addr dq ? + sh_offset dq ? + sh_size dq ? + sh_link dd ? + sh_info dd ? + sh_addralign dq ? + sh_entsize dq ? +end struct + +struct Elf64_Sym + st_name dd ? + st_info db ? + st_other db ? + st_shndx dw ? + st_value dq ? + st_size dq ? +end struct + +struct Elf64_Rel + r_offset dq ? + r_info dq ? +end struct + +struct Elf64_Rela + r_offset dq ? + r_info dq ? + r_addend dq ? +end struct + +struct Elf64_Phdr + p_type dd ? + p_flags dd ? + p_offset dq ? + p_vaddr dq ? + p_paddr dq ? + p_filesz dq ? + p_memsz dq ? + p_align dq ? +end struct + +purge struct? + +ELFCLASSNONE = 0 +ELFCLASS32 = 1 +ELFCLASS64 = 2 + +ELFDATANONE = 0 +ELFDATA2LSB = 1 +ELFDATA2MSB = 2 + +ELFOSABI_NONE = 0 +ELFOSABI_HPUX = 1 +ELFOSABI_NETBSD = 2 +ELFOSABI_GNU = 3 +ELFOSABI_LINUX = 3 +ELFOSABI_SOLARIS = 6 +ELFOSABI_AIX = 7 +ELFOSABI_IRIX = 8 +ELFOSABI_FREEBSD = 9 +ELFOSABI_TRU64 = 10 +ELFOSABI_MODESTO = 11 +ELFOSABI_OPENBSD = 12 +ELFOSABI_OPENVMS = 13 +ELFOSABI_NSK = 14 +ELFOSABI_AROS = 15 +ELFOSABI_FENIXOS = 16 +ELFOSABI_CLOUDABI = 17 +ELFOSABI_OPENVOS = 18 + +ET_NONE = 0 +ET_REL = 1 +ET_EXEC = 2 +ET_DYN = 3 +ET_CORE = 4 +ET_LOPROC = 0xff00 +ET_HIPROC = 0xffff + +EM_NONE = 0 +EM_IA_64 = 50 +EM_X86_64 = 62 + +EV_NONE = 0 +EV_CURRENT = 1 + +SHN_UNDEF = 0 +SHN_LORESERVE = 0xff00 +SHN_LOPROC = 0xff00 +SHN_HIPROC = 0xff1f +SHN_ABS = 0xfff1 +SHN_COMMON = 0xfff2 +SHN_HIRESERVE = 0xffff + +SHT_NULL = 0 +SHT_PROGBITS = 1 +SHT_SYMTAB = 2 +SHT_STRTAB = 3 +SHT_RELA = 4 +SHT_HASH = 5 +SHT_DYNAMIC = 6 +SHT_NOTE = 7 +SHT_NOBITS = 8 +SHT_REL = 9 +SHT_SHLIB = 10 +SHT_DYNSYM = 11 +SHT_LOPROC = 0x70000000 +SHT_HIPROC = 0x7fffffff +SHT_LOUSER = 0x80000000 +SHT_HIUSER = 0xffffffff + +SHF_WRITE = 0x1 +SHF_ALLOC = 0x2 +SHF_EXECINSTR = 0x4 +SHF_MASKPROC = 0xf0000000 + +STT_NOTYPE = 0 +STT_OBJECT = 1 +STT_FUNC = 2 +STT_SECTION = 3 +STT_FILE = 4 +STT_LOPROC = 13 +STT_HIPROC = 15 + +STB_LOCAL = 0 +STB_GLOBAL = 1 +STB_WEAK = 2 +STB_LOPROC = 13 +STB_HIPROC = 15 + +R_X86_64_NONE = 0 +R_X86_64_64 = 1 +R_X86_64_PC32 = 2 +R_X86_64_GOT32 = 3 +R_X86_64_PLT32 = 4 +R_X86_64_COPY = 5 +R_X86_64_GLOB_DAT = 6 +R_X86_64_JUMP_SLOT = 7 +R_X86_64_RELATIVE = 8 +R_X86_64_GOTPCREL = 9 +R_X86_64_32 = 10 +R_X86_64_32S = 11 +R_X86_64_16 = 12 +R_X86_64_PC16 = 13 +R_X86_64_8 = 14 +R_X86_64_PC8 = 15 +R_X86_64_DPTMOD64 = 16 +R_X86_64_DTPOFF64 = 17 +R_X86_64_TPOFF64 = 18 +R_X86_64_TLSGD = 19 +R_X86_64_TLSLD = 20 +R_X86_64_DTPOFF32 = 21 +R_X86_64_GOTTPOFF = 22 +R_X86_64_TPOFF32 = 23 +R_X86_64_PC64 = 24 +R_X86_64_GOTOFF64 = 25 +R_X86_64_GOTPC32 = 26 + +ELF:: + +namespace ELF + + if defined Settings.Machine + MACHINE := Settings.Machine + else + MACHINE := EM_X86_64 + end if + + if defined Settings.ABI + ABI := Settings.ABI + else + ABI := ELFOSABI_NONE + end if + + if MACHINE = EM_X86_64 + R_64 = R_X86_64_64 + R_32 = R_X86_64_32S + R_PC32 = R_X86_64_PC32 + R_PLT32 = R_X86_64_PLT32 + end if + + Header: + + e_ident db 0x7F,'ELF',ELFCLASS64,ELFDATA2LSB,EV_CURRENT,ABI,(16-$) dup 0 + e_type dw ET_REL + e_machine dw MACHINE + e_version dd EV_CURRENT + e_entry dq 0 + e_phoff dq 0 + e_shoff dq SECTION_TABLE_OFFSET + e_flags dd 0 + e_ehsize dw Content + e_phentsize dw 0 + e_phnum dw 0 + e_shentsize dw sizeof Elf64_Shdr + e_shnum dw NUMBER_OF_SECTIONS + e_shstrndx dw STRING_TABLE_SECTION_INDEX + + Content: + + virtual at 0 + section_table:: rb NUMBER_OF_SECTIONS * sizeof Elf64_Shdr + end virtual + + virtual at 0 + symbol_table:: rb NUMBER_OF_SYMBOLS * sizeof Elf64_Sym + end virtual + + virtual at 0 + string_table:: + _null db 0 + _symtab db '.symtab',0 + _strtab db '.strtab',0 + SECTION_NAME_POSITION = $ + rb SECTION_NAME_TABLE_SIZE - $ + STRING_POSITION = $ + rb STRING_TABLE_SIZE - $ + end virtual + + virtual at 0 + relocations:: rb NUMBER_OF_RELOCATIONS * sizeof Elf64_Rela + end virtual + + element relocatable? + + macro section_org + local sym + element sym : relocatable * SECTION_INDEX + SECTION_SYMBOL_INDEX + SECTION_BASE = sym + org sym + end macro + + RELOCATION_INDEX = 0 + SECTION_INDEX = 1 + SECTION_SYMBOL_INDEX = SECTION_INDEX + SECTION_RELOCATION_INDEX = RELOCATION_INDEX + SYMBOL_INDEX = NUMBER_OF_SECTION_SYMBOLS + + SECTION_OFFSET = $% + SECTION_ALIGN = 8 + SECTION_NAME = '.flat' + SECTION_FLAGS = SHF_ALLOC + SHF_WRITE + SHF_EXECINSTR + DEFINED_SECTION = 0 + section_org + +end namespace + +macro section? + namespace ELF + + SECTION_SIZE = $% - SECTION_OFFSET + + if DEFINED_SECTION | SECTION_SIZE > 0 + + store SECTION_OFFSET at section_table : Elf64_Shdr.sh_offset + SECTION_INDEX * sizeof Elf64_Shdr + store SECTION_SIZE at section_table : Elf64_Shdr.sh_size + SECTION_INDEX * sizeof Elf64_Shdr + store SECTION_ALIGN at section_table : Elf64_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf64_Shdr + store SECTION_FLAGS at section_table : Elf64_Shdr.sh_flags + SECTION_INDEX * sizeof Elf64_Shdr + + if $%% = SECTION_OFFSET + store SHT_NOBITS at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr + section $ + else + store SHT_PROGBITS at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr + UNINITIALIZED_LENGTH = $% - $%% + section $ + db UNINITIALIZED_LENGTH dup 0 + end if + + store SECTION_INDEX at symbol_table : Elf64_Sym.st_shndx + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym + store STT_SECTION + STB_LOCAL shl 4 at symbol_table : Elf64_Sym.st_info + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym + + if RELOCATION_INDEX > SECTION_RELOCATION_INDEX + + store RELOCATIONS_OFFSET + SECTION_RELOCATION_INDEX * sizeof Elf64_Rela at section_table : Elf64_Shdr.sh_offset + (SECTION_INDEX+1) * sizeof Elf64_Shdr + store (RELOCATION_INDEX - SECTION_RELOCATION_INDEX) * sizeof Elf64_Rela at section_table : Elf64_Shdr.sh_size + (SECTION_INDEX+1) * sizeof Elf64_Shdr + store SHT_RELA at section_table : Elf64_Shdr.sh_type + (SECTION_INDEX+1) * sizeof Elf64_Shdr + store SYMBOL_TABLE_SECTION_INDEX at section_table : Elf64_Shdr.sh_link + (SECTION_INDEX+1) * sizeof Elf64_Shdr + store SECTION_INDEX at section_table : Elf64_Shdr.sh_info + (SECTION_INDEX+1) * sizeof Elf64_Shdr + store sizeof Elf64_Rela at section_table : Elf64_Shdr.sh_entsize + (SECTION_INDEX+1) * sizeof Elf64_Shdr + store 8 at section_table : Elf64_Shdr.sh_addralign + (SECTION_INDEX+1) * sizeof Elf64_Shdr + + store SECTION_NAME_POSITION at section_table : Elf64_Shdr.sh_name + (SECTION_INDEX+1) * sizeof Elf64_Shdr + store SECTION_NAME_POSITION + 5 at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr + store SECTION_NAME_POSITION + 5 at symbol_table : Elf64_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym + store '.rela' + SECTION_NAME shl (5*8) : 5 + lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION + SECTION_NAME_POSITION = SECTION_NAME_POSITION + 5 + lengthof (string SECTION_NAME) + 1 + + SECTION_INDEX = SECTION_INDEX + 2 + SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1 + + else + store SECTION_NAME_POSITION at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr + store SECTION_NAME_POSITION at symbol_table : Elf64_Sym.st_name + SECTION_SYMBOL_INDEX * sizeof Elf64_Sym + store SECTION_NAME : lengthof (string SECTION_NAME) at string_table:SECTION_NAME_POSITION + SECTION_NAME_POSITION = SECTION_NAME_POSITION + lengthof (string SECTION_NAME) + 1 + + SECTION_INDEX = SECTION_INDEX + 1 + SECTION_SYMBOL_INDEX = SECTION_SYMBOL_INDEX + 1 + + end if + + end if + + end namespace +end macro + +macro section? declaration* + namespace ELF + + section + + DEFINED_SECTION = 1 + SECTION_FLAGS = SHF_ALLOC + SECTION_OFFSET = $% + SECTION_ALIGN = 8 + + match name attributes, declaration + + SECTION_NAME = name + + local seq,list + match flags =align? boundary, attributes + SECTION_ALIGN = boundary + define seq flags + else match =align? boundary, attributes + SECTION_ALIGN = boundary + define seq + else + define seq attributes + end match + while 1 + match car cdr, seq + define list car + define seq cdr + else + match any, seq + define list any + end match + break + end match + end while + irpv attribute, list + match =writeable?, attribute + SECTION_FLAGS = SECTION_FLAGS or SHF_WRITE + else match =executable?, attribute + SECTION_FLAGS = SECTION_FLAGS or SHF_EXECINSTR + else + err 'unknown attribute "',`attribute,'"' + end match + end irpv + + else + + SECTION_NAME = declaration + + end match + + section_org + + SECTION_RELOCATION_INDEX = RELOCATION_INDEX + + end namespace +end macro + +calminstruction align? boundary,value:? + check ELF.SECTION_ALIGN mod (boundary) = 0 + jyes allowed + err 'section not aligned enough' + exit + allowed: + compute boundary, (boundary-1)-($-ELF.SECTION_BASE+boundary-1) mod boundary + arrange value, =db boundary =dup value + assemble value +end calminstruction + +macro public? declaration* + namespace ELF + match value =as? str, declaration + SYMBOL_VALUE = value + SYMBOL_SIZE = sizeof value + SYMBOL_NAME = string str + else + SYMBOL_VALUE = declaration + SYMBOL_SIZE = sizeof declaration + SYMBOL_NAME = `declaration + end match + if SYMBOL_VALUE relativeto 1 elementof SYMBOL_VALUE & 1 elementof (1 metadataof SYMBOL_VALUE) relativeto relocatable & 1 scaleof (1 metadataof SYMBOL_VALUE) > 0 + SYMBOL_SECTION_INDEX = 1 scaleof (1 metadataof SYMBOL_VALUE) + SYMBOL_VALUE = SYMBOL_VALUE - 1 elementof SYMBOL_VALUE + else + SYMBOL_SECTION_INDEX = SHN_ABS + end if + store STRING_POSITION at symbol_table : Elf64_Sym.st_name + SYMBOL_INDEX * sizeof Elf64_Sym + store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION + STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1 + store SYMBOL_VALUE at symbol_table : Elf64_Sym.st_value + SYMBOL_INDEX * sizeof Elf64_Sym + store SYMBOL_SIZE at symbol_table : Elf64_Sym.st_size + SYMBOL_INDEX * sizeof Elf64_Sym + store SYMBOL_SECTION_INDEX at symbol_table : Elf64_Sym.st_shndx + SYMBOL_INDEX * sizeof Elf64_Sym + if SYMBOL_SIZE + store STT_OBJECT + STB_GLOBAL shl 4 at symbol_table : Elf64_Sym.st_info + SYMBOL_INDEX * sizeof Elf64_Sym + else + store STT_FUNC + STB_GLOBAL shl 4 at symbol_table : Elf64_Sym.st_info + SYMBOL_INDEX * sizeof Elf64_Sym + end if + SYMBOL_INDEX = SYMBOL_INDEX + 1 + end namespace +end macro + +macro extrn? declaration* + namespace ELF + local sym,psym + element sym : relocatable * (-1) + SYMBOL_INDEX + element psym : PLT + SYMBOL_INDEX + match str =as? name:size, declaration + label name:size at sym + label PLT.name at psym + SYMBOL_NAME = string str + SYMBOL_SIZE = size + else match name:size, declaration + label name:size at sym + label PLT.name at psym + SYMBOL_NAME = `name + SYMBOL_SIZE = size + else match str =as? name, declaration + label name at sym + label PLT.name at psym + SYMBOL_NAME = string str + SYMBOL_SIZE = 0 + else + label declaration at sym + label PLT.declaration at psym + SYMBOL_NAME = `declaration + SYMBOL_SIZE = 0 + end match + store STRING_POSITION at symbol_table : Elf64_Sym.st_name + SYMBOL_INDEX * sizeof Elf64_Sym + store SYMBOL_NAME : lengthof SYMBOL_NAME at string_table:STRING_POSITION + STRING_POSITION = STRING_POSITION + lengthof SYMBOL_NAME + 1 + store SYMBOL_SIZE at symbol_table : Elf64_Sym.st_size + SYMBOL_INDEX * sizeof Elf64_Sym + store STT_NOTYPE + STB_GLOBAL shl 4 at symbol_table : Elf64_Sym.st_info + SYMBOL_INDEX * sizeof Elf64_Sym + SYMBOL_INDEX = SYMBOL_INDEX + 1 + end namespace +end macro + +element PLT? + +calminstruction calminstruction?.initsym? var*, val& + publish var, val +end calminstruction + +calminstruction calminstruction?.asm? line& + local name, i + initsym name, name.0 + match name.i, name + compute i, i+1 + arrange name, name.i + publish name, line + arrange line, =assemble name + assemble line +end calminstruction + +calminstruction dword? value + compute value, value + check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto ELF.relocatable + jyes r_32 + check ~ value relativeto 0 & (value + ELF.SECTION_BASE) relativeto 1 elementof (value + ELF.SECTION_BASE) + jno plain + check 1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto ELF.relocatable + jyes r_pc32 + check 1 elementof (1 metadataof (value + ELF.SECTION_BASE)) relativeto PLT + jyes r_plt32 + plain: + emit 4, value + exit + local offset, addend, info + r_32: + compute offset, $% + emit 4 + check $% > offset + jno done + compute offset, offset - ELF.SECTION_OFFSET + compute addend, 0 scaleof value + compute info, ELF.R_32 + (0 scaleof (1 metadataof value)) shl 32 + jump add_relocation + r_pc32: + compute offset, $% + emit 4 + check $% > offset + jno done + compute offset, offset - ELF.SECTION_OFFSET + compute addend, 0 scaleof (value + ELF.SECTION_BASE + offset) + compute info, ELF.R_PC32 + (0 scaleof (1 metadataof value)) shl 32 + jump add_relocation + r_plt32: + compute offset, $% + emit 4 + check $% > offset + jno done + compute offset, offset - ELF.SECTION_OFFSET + compute addend, 0 scaleof (value + ELF.SECTION_BASE + offset) + compute info, ELF.R_PLT32 + (0 scaleof (1 metadataof value)) shl 32 + jump add_relocation + add_relocation: + local Rela + compute Rela, ELF.RELOCATION_INDEX * sizeof Elf64_Rela + asm store offset at ELF.relocations : Rela + Elf64_Rela.r_offset + asm store addend at ELF.relocations : Rela + Elf64_Rela.r_addend + asm store info at ELF.relocations : Rela + Elf64_Rela.r_info + compute ELF.RELOCATION_INDEX, ELF.RELOCATION_INDEX + 1 + done: +end calminstruction + +calminstruction qword? value + compute value, value + check ~ value relativeto 0 & value relativeto 1 elementof value & 1 elementof (1 metadataof value) relativeto ELF.relocatable + jyes r_64 + plain: + emit 8, value + exit + local offset, addend, info + r_64: + compute offset, $% + emit 8 + check $% > offset + jno done + compute offset, offset - ELF.SECTION_OFFSET + compute addend, 0 scaleof value + compute info, ELF.R_64 + (0 scaleof (1 metadataof value)) shl 32 + add_relocation: + local Rela + compute Rela, ELF.RELOCATION_INDEX * sizeof Elf64_Rela + asm store offset at ELF.relocations : Rela + Elf64_Rela.r_offset + asm store addend at ELF.relocations : Rela + Elf64_Rela.r_addend + asm store info at ELF.relocations : Rela + Elf64_Rela.r_info + compute ELF.RELOCATION_INDEX, ELF.RELOCATION_INDEX + 1 + done: +end calminstruction + +iterate , dd,dword, dq,qword + + calminstruction dd? definitions& + local value, n + start: + match value=,definitions, definitions, () + jyes recognize + match value, definitions + arrange definitions, + recognize: + match n =dup? value, value, () + jyes duplicate + match ?, value + jyes reserve + call dword, value + next: + match , definitions + jno start + take , definitions + take definitions, definitions + jyes next + exit + reserve: + emit dword + jump next + duplicate: + match (value), value + stack: + check n + jno next + take definitions, value + arrange value, definitions + compute n, n - 1 + jump stack + end calminstruction + + calminstruction (label) dd? definitions& + local cmd + arrange cmd, =label label : =dword + assemble cmd + arrange cmd, =dd definitions + assemble cmd + end calminstruction + +end iterate + +postpone + purge section? + section + namespace ELF + + SECTION_NAME_TABLE_SIZE := SECTION_NAME_POSITION + STRING_TABLE_SIZE := STRING_POSITION + + NUMBER_OF_SECTION_SYMBOLS := SECTION_SYMBOL_INDEX + NUMBER_OF_SYMBOLS := SYMBOL_INDEX + SYMBOL_TABLE_SIZE := NUMBER_OF_SYMBOLS * sizeof Elf64_Sym + + NUMBER_OF_RELOCATIONS := RELOCATION_INDEX + rb (-$%) and 111b + RELOCATIONS_OFFSET = $% + load byte_sequence : NUMBER_OF_RELOCATIONS * sizeof Elf64_Rela from relocations:0 + db byte_sequence + + store _symtab at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr + store $% at section_table : Elf64_Shdr.sh_offset + SECTION_INDEX * sizeof Elf64_Shdr + store SYMBOL_TABLE_SIZE at section_table : Elf64_Shdr.sh_size + SECTION_INDEX * sizeof Elf64_Shdr + store sizeof Elf64_Sym at section_table : Elf64_Shdr.sh_entsize + SECTION_INDEX * sizeof Elf64_Shdr + store 8 at section_table : Elf64_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf64_Shdr + store SHT_SYMTAB at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr + store STRING_TABLE_SECTION_INDEX at section_table : Elf64_Shdr.sh_link + SECTION_INDEX * sizeof Elf64_Shdr + store NUMBER_OF_SECTION_SYMBOLS at section_table : Elf64_Shdr.sh_info + SECTION_INDEX * sizeof Elf64_Shdr + SYMBOL_TABLE_SECTION_INDEX := SECTION_INDEX + load byte_sequence : SYMBOL_TABLE_SIZE from symbol_table:0 + db byte_sequence + SECTION_INDEX = SECTION_INDEX + 1 + + store _strtab at section_table : Elf64_Shdr.sh_name + SECTION_INDEX * sizeof Elf64_Shdr + store $% at section_table : Elf64_Shdr.sh_offset + SECTION_INDEX * sizeof Elf64_Shdr + store STRING_TABLE_SIZE at section_table : Elf64_Shdr.sh_size + SECTION_INDEX * sizeof Elf64_Shdr + store 1 at section_table : Elf64_Shdr.sh_addralign + SECTION_INDEX * sizeof Elf64_Shdr + store SHT_STRTAB at section_table : Elf64_Shdr.sh_type + SECTION_INDEX * sizeof Elf64_Shdr + STRING_TABLE_SECTION_INDEX := SECTION_INDEX + load byte_sequence : STRING_TABLE_SIZE from string_table:0 + db byte_sequence + SECTION_INDEX = SECTION_INDEX + 1 + + assert SECTION_INDEX <= SHN_LORESERVE + + NUMBER_OF_SECTIONS := SECTION_INDEX + rb (-$%) and 111b + SECTION_TABLE_OFFSET := $% + load byte_sequence : NUMBER_OF_SECTIONS * sizeof Elf64_Shdr from section_table:0 + db byte_sequence + + end namespace +end postpone diff --git a/toolchain/fasmg.kl0e/examples/x86/include/format/elfexe.inc b/toolchain/fasmg.kl0e/examples/x86/include/format/elfexe.inc new file mode 100644 index 0000000..34d114a --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/format/elfexe.inc @@ -0,0 +1,326 @@ + +ELFCLASSNONE = 0 +ELFCLASS32 = 1 +ELFCLASS64 = 2 + +ELFDATANONE = 0 +ELFDATA2LSB = 1 +ELFDATA2MSB = 2 + +ELFOSABI_NONE = 0 +ELFOSABI_HPUX = 1 +ELFOSABI_NETBSD = 2 +ELFOSABI_GNU = 3 +ELFOSABI_LINUX = 3 +ELFOSABI_SOLARIS = 6 +ELFOSABI_AIX = 7 +ELFOSABI_IRIX = 8 +ELFOSABI_FREEBSD = 9 +ELFOSABI_TRU64 = 10 +ELFOSABI_MODESTO = 11 +ELFOSABI_OPENBSD = 12 +ELFOSABI_OPENVMS = 13 +ELFOSABI_NSK = 14 +ELFOSABI_AROS = 15 +ELFOSABI_FENIXOS = 16 +ELFOSABI_CLOUDABI = 17 +ELFOSABI_OPENVOS = 18 + +ET_NONE = 0 +ET_REL = 1 +ET_EXEC = 2 +ET_DYN = 3 +ET_CORE = 4 +ET_LOPROC = 0xff00 +ET_HIPROC = 0xffff + +EM_NONE = 0 +EM_M32 = 1 +EM_SPARC = 2 +EM_386 = 3 +EM_68K = 4 +EM_88K = 5 +EM_860 = 7 +EM_MIPS = 8 +EM_X86_64 = 62 + +EV_NONE = 0 +EV_CURRENT = 1 + +PT_NULL = 0 +PT_LOAD = 1 +PT_DYNAMIC = 2 +PT_INTERP = 3 +PT_NOTE = 4 +PT_SHLIB = 5 +PT_PHDR = 6 +PT_GNU_EH_FRAME = 0x6474e550 +PT_GNU_STACK = 0x6474e551 +PT_GNU_RELRO = 0x6474e552 +PT_LOPROC = 0x70000000 +PT_HIPROC = 0x7fffffff + +PF_X = 1 +PF_W = 2 +PF_R = 4 +PF_MASKOS = 0x0ff00000 +PF_MASKPROC = 0xf0000000 + +calminstruction align? boundary,value:? + compute boundary, (boundary-1)-($-ELF.DYNAMIC+boundary-1) mod boundary + arrange value, =db boundary =dup value + assemble value +end calminstruction + +ELF:: + +namespace ELF + + if defined Settings.Class + CLASS := Settings.Class + else + CLASS := ELFCLASS32 + end if + + if defined Settings.Type + TYPE := Settings.Type + else + TYPE := ET_EXEC + end if + + if defined Settings.Machine + MACHINE := Settings.Machine + else + MACHINE := EM_386 + end if + + if defined Settings.ABI + ABI := Settings.ABI + else + ABI := ELFOSABI_NONE + end if + + if TYPE = ET_DYN + element DYNAMIC + else + DYNAMIC := 0 + end if + + if defined Settings.BaseAddress + BASE_ADDRESS := DYNAMIC + Settings.BaseAddress + else + BASE_ADDRESS := DYNAMIC + 8048000h + end if + + if defined Settings.LoadHeaders + LOAD_HEADERS := Settings.LoadHeaders + else + LOAD_HEADERS := 1 + end if + + Header: + + e_ident db 0x7F,'ELF',CLASS,ELFDATA2LSB,EV_CURRENT,ABI,(16-$) dup 0 + e_type dw TYPE + e_machine dw MACHINE + e_version dd EV_CURRENT + if CLASS <> ELFCLASS64 + e_entry dd start - DYNAMIC + e_phoff dd ProgramHeader + e_shoff dd 0 + e_flags dd 0 + e_ehsize dw ProgramHeader + e_phentsize dw SEGMENT_HEADER_LENGTH + e_phnum dw NUMBER_OF_SEGMENTS + e_shentsize dw 28h + e_shnum dw 0 + e_shstrndx dw 0 + else + e_entry dq start - DYNAMIC + e_phoff dq ProgramHeader + e_shoff dq 0 + e_flags dd 0 + e_ehsize dw ProgramHeader + e_phentsize dw SEGMENT_HEADER_LENGTH + e_phnum dw NUMBER_OF_SEGMENTS + e_shentsize dw 40h + e_shnum dw 0 + e_shstrndx dw 0 + end if + + ProgramHeader: + if CLASS <> ELFCLASS64 + p_type dd PT_LOAD + p_offset dd 0 + p_vaddr dd BASE_ADDRESS - DYNAMIC + p_paddr dd BASE_ADDRESS - DYNAMIC + p_filesz dd 0 + p_memsz dd 0 + p_flags dd PF_R+PF_W+PF_X + p_align dd 1000h + else + p_type dd PT_LOAD + p_flags dd PF_R+PF_W+PF_X + p_offset dq 0 + p_vaddr dq BASE_ADDRESS - DYNAMIC + p_paddr dq BASE_ADDRESS - DYNAMIC + p_filesz dq 0 + p_memsz dq 0 + p_align dq 1000h + end if + + SEGMENT_HEADER_LENGTH = $ - ProgramHeader + + db (NUMBER_OF_SEGMENTS-1)*SEGMENT_HEADER_LENGTH dup 0 + + HEADERS_OFFSET = 0 + HEADERS_BASE = BASE_ADDRESS + OVERLAY_HEADERS = LOAD_HEADERS + + SEGMENT_INDEX = 0 + DEFINED_SEGMENT = 0 + SEGMENT_TYPE = PT_LOAD + FILE_OFFSET = $% + SEGMENT_BASE = BASE_ADDRESS + FILE_OFFSET and 0FFFh + org SEGMENT_BASE + start: + +end namespace + +RVA? equ -ELF.BASE_ADDRESS + + +macro entry? address* + namespace ELF + store address-DYNAMIC at ELF:e_entry + end namespace +end macro + +macro segment? + namespace ELF + + DEFINED_SEGMENT_SIZE = $ - SEGMENT_BASE + + if (DEFINED_SEGMENT | DEFINED_SEGMENT_SIZE > 0) & SEGMENT_TYPE = PT_LOAD & OVERLAY_HEADERS + FILE_OFFSET = HEADERS_OFFSET + SEGMENT_BASE = HEADERS_BASE + OVERLAY_HEADERS = 0 + end if + + store SEGMENT_BASE-DYNAMIC at ELF:p_vaddr+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH + store SEGMENT_BASE-DYNAMIC at ELF:p_paddr+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH + store FILE_OFFSET at ELF:p_offset+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH + + if SEGMENT_TYPE = PT_LOAD + + RAW_DATA_SIZE = $%% - FILE_OFFSET + SEGMENT_SIZE = $ - SEGMENT_BASE + store RAW_DATA_SIZE at ELF:p_filesz+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH + store SEGMENT_SIZE at ELF:p_memsz+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH + + if DEFINED_SEGMENT | DEFINED_SEGMENT_SIZE > 0 + FILE_OFFSET = $%% + align 1000h + SEGMENT_BASE = $ + FILE_OFFSET and 0FFFh + end if + + section SEGMENT_BASE + + else + + if OVERLAY_HEADERS = 0 & ( LOAD_HEADERS | SEGMENT_TYPE = PT_GNU_RELRO ) & ~ SEGMENT_TYPE = PT_GNU_STACK & ~ SEGMENT_TYPE = PT_NOTE + OVERLAY_HEADERS = 1 + HEADERS_OFFSET = FILE_OFFSET + HEADERS_BASE = SEGMENT_BASE + end if + + FILE_OFFSET = $% + SEGMENT_SIZE = $ - SEGMENT_BASE + store SEGMENT_SIZE at ELF:p_filesz+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH + store SEGMENT_SIZE at ELF:p_memsz+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH + + if OVERLAY_HEADERS = 0 + SEGMENT_BASE = DYNAMIC + (SEGMENT_BASE-DYNAMIC) and not 0FFFh + FILE_OFFSET and 0FFFh + else + SEGMENT_BASE = $ + end if + + if $% > $%% + store 0:byte at $-1 + end if + org SEGMENT_BASE + + end if + + if DEFINED_SEGMENT | DEFINED_SEGMENT_SIZE > 0 + SEGMENT_INDEX = SEGMENT_INDEX + 1 + end if + + end namespace +end macro + +macro segment? attributes* + namespace ELF + + segment + + SEGMENT_TYPE = PT_LOAD + SEGMENT_FLAGS = 0 + + local seq,list + define seq attributes + while 1 + match car cdr, seq + define list car + define seq cdr + else + match any, seq + define list any + end match + break + end match + end while + irpv attribute, list + match =readable?, attribute + SEGMENT_FLAGS = SEGMENT_FLAGS or PF_R + else match =writeable?, attribute + SEGMENT_FLAGS = SEGMENT_FLAGS or PF_W + else match =executable?, attribute + SEGMENT_FLAGS = SEGMENT_FLAGS or PF_X + else match =interpreter?, attribute + SEGMENT_TYPE = PT_INTERP + else match =dynamic?, attribute + SEGMENT_TYPE = PT_DYNAMIC + else match =note?, attribute + SEGMENT_TYPE = PT_NOTE + else match =gnustack?, attribute + SEGMENT_TYPE = PT_GNU_STACK + else match =gnuehframe?, attribute + SEGMENT_TYPE = PT_GNU_EH_FRAME + else match =gnurelro?, attribute + SEGMENT_TYPE = PT_GNU_RELRO + else + err 'unknown attribute "',`attribute,'"' + end match + end irpv + + DEFINED_SEGMENT = 1 + + store SEGMENT_TYPE at ELF:p_type+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH + store SEGMENT_FLAGS at ELF:p_flags+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH + + if SEGMENT_TYPE = PT_LOAD + store 1000h at ELF:p_align+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH + else + store 1 at ELF:p_align+SEGMENT_INDEX*SEGMENT_HEADER_LENGTH + end if + + end namespace +end macro + +postpone + purge segment? + segment + namespace ELF + NUMBER_OF_SEGMENTS := SEGMENT_INDEX + end namespace +end postpone diff --git a/toolchain/fasmg.kl0e/examples/x86/include/format/format.inc b/toolchain/fasmg.kl0e/examples/x86/include/format/format.inc new file mode 100644 index 0000000..5d9fdbd --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/format/format.inc @@ -0,0 +1,328 @@ + +macro format?.MZ? + format binary as 'exe' + include 'format/mz.inc' + include 'p6.inc' +end macro + +macro format?.PE? settings + PE.Settings.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_32BIT_MACHINE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_LOCAL_SYMS_STRIPPED + PE.Settings.DllCharacteristics = 0 + local seq + define seq settings: + while 1 + match :, seq + break + else match =DLL? more, seq + PE.Settings.Characteristics = PE.Settings.Characteristics or IMAGE_FILE_DLL + redefine seq more + else match =large? more, seq + PE.Settings.Characteristics = PE.Settings.Characteristics or IMAGE_FILE_LARGE_ADDRESS_AWARE + redefine seq more + else match =WDM? more, seq + PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_WDM_DRIVER + redefine seq more + else match =NX? more, seq + PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_NX_COMPAT + redefine seq more + else match =at? base =on? stub :, seq + PE.Settings.ImageBase = base + PE.Settings.Stub = stub + break + else match =at? base :, seq + PE.Settings.ImageBase = base + break + else match =on? stub :, seq + PE.Settings.Stub = stub + break + else + match =GUI? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI + redefine seq more + else match =console? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI + redefine seq more + else match =native? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_NATIVE + PE.Settings.SectionAlignment = 32 + PE.Settings.FileAlignment = 32 + redefine seq more + else match =EFI? more, seq + PE.Settings.Magic = 0x20B + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION + redefine seq more + else match =EFIboot? more, seq + PE.Settings.Magic = 0x20B + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER + redefine seq more + else match =EFIruntime? more, seq + PE.Settings.Magic = 0x20B + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER + redefine seq more + else + err 'invalid argument' + break + end match + match V.v more, seq + PE.Settings.MajorSubsystemVersion = V + PE.Settings.MinorSubsystemVersion = v + redefine seq more + end match + end match + end while + if PE.Settings.Characteristics and IMAGE_FILE_DLL + format binary as 'dll' + else + format binary as 'exe' + end if + include 'format/pe.inc' + include 'p6.inc' + use32 +end macro + +macro format?.PE64? settings + PE.Settings.Magic = 0x20B + PE.Settings.Machine = IMAGE_FILE_MACHINE_AMD64 + PE.Settings.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_LARGE_ADDRESS_AWARE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_LOCAL_SYMS_STRIPPED + PE.Settings.DllCharacteristics = 0 + PE.Settings.MajorSubsystemVersion = 5 + PE.Settings.MinorSubsystemVersion = 0 + local seq + define seq settings: + while 1 + match :, seq + break + else match =DLL? more, seq + PE.Settings.Characteristics = PE.Settings.Characteristics or IMAGE_FILE_DLL + redefine seq more + else match =WDM? more, seq + PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_WDM_DRIVER + redefine seq more + else match =NX? more, seq + PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_NX_COMPAT + redefine seq more + else match =at? base =on? stub :, seq + PE.Settings.ImageBase = base + PE.Settings.Stub = stub + break + else match =at? base :, seq + PE.Settings.ImageBase = base + break + else match =on? stub :, seq + PE.Settings.Stub = stub + break + else + match =GUI? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI + redefine seq more + else match =console? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI + redefine seq more + else match =native? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_NATIVE + PE.Settings.SectionAlignment = 32 + PE.Settings.FileAlignment = 32 + redefine seq more + else match =EFI? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION + redefine seq more + else match =EFIboot? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER + redefine seq more + else match =EFIruntime? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER + redefine seq more + else + err 'invalid argument' + break + end match + match V.v more, seq + PE.Settings.MajorSubsystemVersion = V + PE.Settings.MinorSubsystemVersion = v + redefine seq more + end match + end match + end while + if PE.Settings.Characteristics and IMAGE_FILE_DLL + format binary as 'dll' + else + format binary as 'exe' + end if + include 'format/pe.inc' + include 'x64.inc' + use64 +end macro + +macro format?.ELF? variant + match , variant + format binary as 'o' + include 'format/elf32.inc' + include 'p6.inc' + use32 + else match =executable? settings, variant: + match brand =at? base:, settings + ELF.Settings.ABI = brand + ELF.Settings.BaseAddress = base + else match =at? base:, settings + ELF.Settings.BaseAddress = base + else match brand:, settings + ELF.Settings.ABI = brand + end match + include 'format/elfexe.inc' + include 'p6.inc' + use32 + else match =dynamic? settings, variant: + ELF.Settings.Type = ET_DYN + match brand =at? base:, settings + ELF.Settings.ABI = brand + ELF.Settings.BaseAddress = base + else match =at? base:, settings + ELF.Settings.BaseAddress = base + else match brand:, settings + ELF.Settings.ABI = brand + end match + include 'format/elfexe.inc' + include 'p6.inc' + use32 + else + err 'invalid argument' + end match +end macro + +macro format?.ELF64? variant + match , variant + format binary as 'o' + include 'format/elf64.inc' + include 'x64.inc' + use64 + else match =executable? settings, variant: + ELF.Settings.Class = ELFCLASS64 + ELF.Settings.Machine = EM_X86_64 + ELF.Settings.BaseAddress = 400000h + match brand =at? base:, settings + ELF.Settings.ABI = brand + ELF.Settings.BaseAddress = base + else match =at? base:, settings + ELF.Settings.BaseAddress = base + else match brand:, settings + ELF.Settings.ABI = brand + end match + include 'format/elfexe.inc' + include 'x64.inc' + use64 + else match =dynamic? settings, variant: + ELF.Settings.Class = ELFCLASS64 + ELF.Settings.Type = ET_DYN + ELF.Settings.Machine = EM_X86_64 + ELF.Settings.BaseAddress = 400000h + match brand =at? base:, settings + ELF.Settings.ABI = brand + ELF.Settings.BaseAddress = base + else match =at? base:, settings + ELF.Settings.BaseAddress = base + else match brand:, settings + ELF.Settings.ABI = brand + end match + include 'format/elfexe.inc' + include 'x64.inc' + use64 + else + err 'invalid argument' + end match +end macro + +macro format?.ELFx32? variant + match , variant + format binary as 'o' + ELF.Settings.Machine = EM_X86_64 + include 'format/elf32.inc' + include 'x64.inc' + use64 + else match =executable? settings, variant: + ELF.Settings.Class = ELFCLASS32 + ELF.Settings.Machine = EM_X86_64 + ELF.Settings.BaseAddress = 400000h + match brand =at? base:, settings + ELF.Settings.ABI = brand + ELF.Settings.BaseAddress = base + else match =at? base:, settings + ELF.Settings.BaseAddress = base + else match brand:, settings + ELF.Settings.ABI = brand + end match + include 'format/elfexe.inc' + include 'x64.inc' + use64 + else + err 'invalid argument' + end match +end macro + +macro format?.COFF? + format binary as 'obj' + include 'format/coff.inc' + include 'p6.inc' + use32 +end macro + +macro format?.MS? variant + match =COFF?, variant + format binary as 'obj' + COFF.Settings.Characteristics = IMAGE_FILE_32BIT_MACHINE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_BYTES_REVERSED_LO + include 'format/coffms.inc' + include 'p6.inc' + use32 + else + err 'invalid argument' + end match +end macro + +macro format?.MS64? variant + match =COFF?, variant + format binary as 'obj' + COFF.Settings.Machine = IMAGE_FILE_MACHINE_AMD64 + COFF.Settings.Characteristics = IMAGE_FILE_32BIT_MACHINE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_BYTES_REVERSED_LO + include 'format/coffms.inc' + include 'x64.inc' + use64 + else + err 'invalid argument' + end match +end macro + +macro format?.MachO? variant + match , variant + format binary as 'o' + MachO.Settings.FileType equ MH_OBJECT + include 'format/macho.inc' + include 'p6.inc' + use32 + else match =executable?, variant + MachO.Settings.BaseAddress = 0x1000 + include 'format/macho.inc' + include 'p6.inc' + use32 + else + err 'invalid argument' + end match +end macro + +macro format?.MachO64? variant + MachO.Settings.ProcessorType equ CPU_TYPE_X86_64 + MachO.Settings.ProcessorSubtype equ CPU_SUBTYPE_X86_64_ALL + match , variant + format binary as 'o' + MachO.Settings.FileType equ MH_OBJECT + include 'format/macho.inc' + include 'x64.inc' + use64 + else match =executable?, variant + MachO.Settings.BaseAddress = 0x100000000 + include 'format/macho.inc' + include 'x64.inc' + use64 + else + err 'invalid argument' + end match +end macro + diff --git a/toolchain/fasmg.kl0e/examples/x86/include/format/macho.inc b/toolchain/fasmg.kl0e/examples/x86/include/format/macho.inc new file mode 100644 index 0000000..8d1d3f9 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/format/macho.inc @@ -0,0 +1,1186 @@ + +CPU_TYPE_ANY = -1 +CPU_ARCH_ABI64 = 0x1000000 +CPU_TYPE_VAX = 1 +CPU_TYPE_ROMP = 2 +CPU_TYPE_NS32032 = 4 +CPU_TYPE_NS32332 = 5 +CPU_TYPE_MC680x0 = 6 +CPU_TYPE_I386 = 7 +CPU_TYPE_X86_64 = CPU_TYPE_I386 or CPU_ARCH_ABI64 +CPU_TYPE_MIPS = 8 +CPU_TYPE_NS32532 = 9 +CPU_TYPE_HPPA = 11 +CPU_TYPE_ARM = 12 +CPU_TYPE_MC88000 = 13 +CPU_TYPE_SPARC = 14 +CPU_TYPE_I860 = 15 +CPU_TYPE_I860_LITTLE = 16 +CPU_TYPE_RS6000 = 17 +CPU_TYPE_MC98000 = 18 +CPU_TYPE_POWERPC = 18 +CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC or CPU_ARCH_ABI64 +CPU_TYPE_VEO = 255 + +CPU_SUBTYPE_MASK = 0xff000000 +CPU_SUBTYPE_LIB64 = 0x80000000 + +CPU_SUBTYPE_I386_ALL = 3 +CPU_SUBTYPE_X86_64_ALL = CPU_SUBTYPE_I386_ALL +CPU_SUBTYPE_386 = 3 +CPU_SUBTYPE_486 = 4 +CPU_SUBTYPE_486SX = 4 + 128 +CPU_SUBTYPE_586 = 5 +CPU_SUBTYPE_PENT = 5 + 0 shl 4 +CPU_SUBTYPE_PENTPRO = 6 + 1 shl 4 +CPU_SUBTYPE_PENTII_M3 = 6 + 3 shl 4 +CPU_SUBTYPE_PENTII_M5 = 6 + 5 shl 4 +CPU_SUBTYPE_PENTIUM_4 = 10 + 0 shl 4 + +MH_OBJECT = 0x1 +MH_EXECUTE = 0x2 +MH_FVMLIB = 0x3 +MH_CORE = 0x4 +MH_PRELOAD = 0x5 +MH_DYLIB = 0x6 +MH_DYLINKER = 0x7 +MH_BUNDLE = 0x8 +MH_DYLIB_STUB = 0x9 +MH_DSYM = 0xA +MH_KEXT_BUNDLE = 0xB + +MH_NOUNDEFS = 0x1 +MH_INCRLINK = 0x2 +MH_DYLDLINK = 0x4 +MH_BINDATLOAD = 0x8 +MH_PREBOUND = 0x10 +MH_SPLIT_SEGS = 0x20 +MH_LAZY_INIT = 0x40 +MH_TWOLEVEL = 0x80 +MH_FORCE_FLAT = 0x100 +MH_NOMULTIDEFS = 0x200 +MH_NOFIXPREBINDING = 0x400 +MH_PREBINDABLE = 0x800 +MH_ALLMODSBOUND = 0x1000 +MH_SUBSECTIONS_VIA_SYMBOLS = 0x2000 +MH_CANONICAL = 0x4000 +MH_WEAK_DEFINES = 0x8000 +MH_BINDS_TO_WEAK = 0x10000 +MH_ALLOW_STACK_EXECUTION = 0x20000 +MH_ROOT_SAFE = 0x40000 +MH_SETUID_SAFE = 0x80000 +MH_NO_REEXPORTED_DYLIBS = 0x100000 +MH_PIE = 0x200000 +MH_DEAD_STRIPPABLE_DYLIB = 0x400000 +MH_HAS_TLV_DESCRIPTORS = 0x800000 +MH_NO_HEAP_EXECUTION = 0x1000000 +MH_APP_EXTENSION_SAFE = 0x2000000 + +LC_REQ_DYLD = 0x80000000 +LC_SEGMENT = 0x1 +LC_SYMTAB = 0x2 +LC_SYMSEG = 0x3 +LC_THREAD = 0x4 +LC_UNIXTHREAD = 0x5 +LC_LOADFVMLIB = 0x6 +LC_IDFVMLIB = 0x7 +LC_IDENT = 0x8 +LC_FVMFILE = 0x9 +LC_PREPAGE = 0xa +LC_DYSYMTAB = 0xb +LC_LOAD_DYLIB = 0xc +LC_ID_DYLIB = 0xd +LC_LOAD_DYLINKER = 0xe +LC_ID_DYLINKER = 0xf +LC_PREBOUND_DYLIB = 0x10 +LC_ROUTINES = 0x11 +LC_SUB_FRAMEWORK = 0x12 +LC_SUB_UMBRELLA = 0x13 +LC_SUB_CLIENT = 0x14 +LC_SUB_LIBRARY = 0x15 +LC_TWOLEVEL_HINTS = 0x16 +LC_PREBIND_CKSUM = 0x17 +LC_LOAD_WEAK_DYLIB = 0x18 +LC_SEGMENT_64 = 0x19 +LC_ROUTINES_64 = 0x1a +LC_UUID = 0x1b +LC_RPATH = 0x1c + LC_REQ_DYLD +LC_CODE_SIGNATURE = 0x1d +LC_SEGMENT_SPLIT_INFO = 0x1e +LC_REEXPORT_DYLIB = 0x1f + LC_REQ_DYLD +LC_LAZY_LOAD_DYLIB = 0x20 +LC_ENCRYPTION_INFO = 0x21 +LC_DYLD_INFO = 0x22 +LC_DYLD_INFO_ONLY = 0x22 + LC_REQ_DYLD + +SG_HIGHVM = 0x1 +SG_FVMLIB = 0x2 +SG_NORELOC = 0x4 + +SECTION_TYPE = 0x000000ff +SECTION_ATTRIBUTES = 0xffffff00 + +S_REGULAR = 0x0 +S_ZEROFILL = 0x1 +S_CSTRING_LITERALS = 0x2 +S_4BYTE_LITERALS = 0x3 +S_8BYTE_LITERALS = 0x4 +S_LITERAL_POINTERS = 0x5 +S_NON_LAZY_SYMBOL_POINTERS = 0x6 +S_LAZY_SYMBOL_POINTERS = 0x7 +S_SYMBOL_STUBS = 0x8 +S_MOD_INIT_FUNC_POINTERS = 0x9 +S_MOD_TERM_FUNC_POINTERS = 0x0a +S_COALESCED = 0x0b +S_GB_ZEROFILL = 0x0c +S_INTERPOSING = 0x0d +S_16BYTE_LITERALS = 0x0e +S_DTRACE_DOF = 0x0f +S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10 +S_THREAD_LOCAL_REGULAR = 0x11 +S_THREAD_LOCAL_ZEROFILL = 0x12 +S_THREAD_LOCAL_VARIABLES = 0x13 +S_THREAD_LOCAL_VARIABLE_POINTERS = 0x14 +S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15 + +SECTION_ATTRIBUTES_USR = 0xff000000 +S_ATTR_PURE_INSTRUCTIONS = 0x80000000 +S_ATTR_NO_TOC = 0x40000000 +S_ATTR_STRIP_STATIC_SYMS = 0x20000000 +S_ATTR_NO_DEAD_STRIP = 0x10000000 +S_ATTR_LIVE_SUPPORT = 0x08000000 +S_ATTR_SELF_MODIFYING_CODE = 0x04000000 +S_ATTR_DEBUG = 0x02000000 + +SECTION_ATTRIBUTES_SYS = 0x00ffff00 +S_ATTR_SOME_INSTRUCTIONS = 0x00000400 +S_ATTR_EXT_RELOC = 0x00000200 +S_ATTR_LOC_RELOC = 0x00000100 + +VM_PROT_NONE = 0x00 +VM_PROT_READ = 0x01 +VM_PROT_WRITE = 0x02 +VM_PROT_EXECUTE = 0x04 +VM_PROT_DEFAULT = VM_PROT_READ or VM_PROT_WRITE +VM_PROT_ALL = VM_PROT_READ or VM_PROT_WRITE or VM_PROT_EXECUTE +VM_PROT_NO_CHANGE = 0x08 +VM_PROT_COPY = 0x10 +VM_PROT_WANTS_COPY = 0x10 + +x86_THREAD_STATE32 = 1 +x86_FLOAT_STATE32 = 2 +x86_EXCEPTION_STATE32 = 3 +x86_THREAD_STATE64 = 4 +x86_FLOAT_STATE64 = 5 +x86_EXCEPTION_STATE64 = 6 +x86_THREAD_STATE = 7 +x86_FLOAT_STATE = 8 +x86_EXCEPTION_STATE = 9 +x86_DEBUG_STATE32 = 10 +x86_DEBUG_STATE64 = 11 +x86_DEBUG_STATE = 12 +THREAD_STATE_NONE = 13 + +N_STAB = 0xe0 +N_PEXT = 0x10 +N_TYPE = 0x0e +N_EXT = 0x01 +N_UNDF = 0x0 +N_ABS = 0x2 +N_SECT = 0xe +N_PBUD = 0xc +N_INDR = 0xa + +NO_SECT = 0 +MAX_SECT = 255 + +REFERENCE_TYPE = 0xf +REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0 +REFERENCE_FLAG_UNDEFINED_LAZY = 1 +REFERENCE_FLAG_DEFINED = 2 +REFERENCE_FLAG_PRIVATE_DEFINED = 3 +REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4 +REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5 +REFERENCED_DYNAMICALLY = 0x0010 + +GENERIC_RELOC_VANILLA = 0 +GENERIC_RELOC_PAIR = 1 +GENERIC_RELOC_SECTDIFF = 2 +GENERIC_RELOC_PB_LA_PTR = 3 +GENERIC_RELOC_LOCAL_SECTDIFF = 4 +GENERIC_RELOC_TLV = 5 + +X86_64_RELOC_UNSIGNED = 0 +X86_64_RELOC_SIGNED = 1 +X86_64_RELOC_BRANCH = 2 +X86_64_RELOC_GOT_LOAD = 3 +X86_64_RELOC_GOT = 4 +X86_64_RELOC_SUBTRACTOR = 5 +X86_64_RELOC_SIGNED_1 = 6 +X86_64_RELOC_SIGNED_2 = 7 +X86_64_RELOC_SIGNED_4 = 8 +X86_64_RELOC_TLV = 9 + +; Basic layer: command headers + +MachO:: + +namespace MachO + + if defined Settings.ProcessorType + CPUTYPE := Settings.ProcessorType + else + CPUTYPE := CPU_TYPE_I386 + end if + + if defined Settings.ProcessorSubtype + CPUSUBTYPE := Settings.ProcessorSubtype + else + if CPUTYPE and CPU_ARCH_ABI64 + CPUSUBTYPE := CPU_SUBTYPE_I386_ALL + CPU_SUBTYPE_LIB64 + else + CPUSUBTYPE := CPU_SUBTYPE_I386_ALL + end if + end if + + if defined Settings.FileType + FILETYPE := Settings.FileType + else + FILETYPE := MH_EXECUTE + end if + + if defined Settings.Flags + FLAGS := Settings.Flags + else if FILETYPE <> MH_OBJECT + FLAGS := MH_NOUNDEFS + MH_DYLDLINK + else + FLAGS := 0 + end if + + if defined Settings.SegmentAlignment + SEGMENT_ALIGNMENT := Settings.SegmentAlignment + else + SEGMENT_ALIGNMENT := 1000h + end if + + if defined Settings.FileAlignment + FILE_ALIGNMENT := Settings.FileAlignment + else + FILE_ALIGNMENT := 1000h + end if + + if defined Settings.HeaderPad + HEADER_PAD := Settings.HeaderPad + else + HEADER_PAD := 16 + end if + + if CPUTYPE and CPU_ARCH_ABI64 + magic dd 0xFEEDFACF + else + magic dd 0xFEEDFACE + end if + cputype dd CPUTYPE + cpusubtype dd CPUSUBTYPE + filetype dd FILETYPE + ncmds dd NUMBER_OF_COMMANDS + sizeofcmds dd SIZE_OF_COMMANDS + flags dd FLAGS + if CPUTYPE and CPU_ARCH_ABI64 + reserved dd ? + end if + + COMMAND_NUMBER = 0 + COMMAND_POSITION = $ + + commands db SIZE_OF_COMMANDS dup 0, HEADER_PAD dup ? + + org $ + + macro command type + if MachO.COMMAND_POSITION > 0 + virtual at MachO.COMMAND_POSITION + MachO.COMMAND_POSITION = 0 + end if + match t, type + if MachO.COMMAND_NUMBER > 0 + repeat 1, p:MachO.COMMAND_NUMBER + MachO.load#p.SIZE := $ - MachO.load#p.cmd + end repeat + end if + MachO.COMMAND_NUMBER = MachO.COMMAND_NUMBER + 1 + MachO.COMMAND = $ + repeat 1, n:MachO.COMMAND_NUMBER + namespace MachO.load#n + cmd dd t + cmdsize dd SIZE + end namespace + end repeat + end match + end macro + + macro text + if MachO.COMMAND_POSITION = 0 + MachO.COMMAND_POSITION = $ + load MachO.COMMAND_DATA:$-$$ from $$ + store MachO.COMMAND_DATA:$-$$ at MachO:$$ + end virtual + end if + end macro + +end namespace + +calminstruction align? boundary,value:? + compute boundary, (boundary-1)-($+boundary-1) mod boundary + arrange value, =db boundary =dup value + assemble value +end calminstruction + +postpone + MachO.text + namespace MachO + if COMMAND_NUMBER > 0 + repeat 1, p:COMMAND_NUMBER + load#p.SIZE := COMMAND_POSITION - MachO.load#p.cmd + end repeat + end if + NUMBER_OF_COMMANDS := COMMAND_NUMBER + SIZE_OF_COMMANDS := COMMAND_POSITION - commands + end namespace +end postpone + +; Intermediate layer: segments and sections + +namespace MachO + + if defined Settings.BaseAddress + + VM_ADDRESS = Settings.BaseAddress + + if CPUTYPE and CPU_ARCH_ABI64 + MachO.command LC_SEGMENT_64 + else + MachO.command LC_SEGMENT + end if + namespace MachO.segment1 + segname emit 16: '__PAGEZERO' + if CPUTYPE and CPU_ARCH_ABI64 + vmaddr dq 0 + vmsize dq VM_ADDRESS + fileoff dq 0 + filesize dq 0 + else + vmaddr dd 0 + vmsize dd VM_ADDRESS + fileoff dd 0 + filesize dd 0 + end if + maxprot dd 0 + initprot dd 0 + nsects dd 0 + flags dd 0 + end namespace + + SEGMENT_NUMBER = 1 + else + VM_ADDRESS = 0 + SEGMENT_NUMBER = 0 + end if + + GLOBAL_SECTION_NUMBER = 0 + TEXT_OFFSET = $% + +end namespace + +macro MachO.segment declaration + MachO.close_segment + + local NAME,VMADDR,VMSIZE,FILEOFF,FILESIZE,MAXPROT,INITPROT,NSECTS + + INITPROT = VM_PROT_NONE + MAXPROT = VM_PROT_ALL + match name attributes, declaration + NAME = name + local sequence + define sequence attributes: + while 1 + match attribute tail, sequence + match =readable?, attribute + INITPROT = INITPROT or VM_PROT_READ + MAXPROT = MAXPROT or VM_PROT_READ + else match =notreadable?, attribute + INITPROT = INITPROT and not VM_PROT_READ + MAXPROT = MAXPROT and not VM_PROT_READ + else match =writeable?, attribute + INITPROT = INITPROT or VM_PROT_WRITE + MAXPROT = MAXPROT or VM_PROT_WRITE + else match =writable?, attribute + INITPROT = INITPROT or VM_PROT_WRITE + MAXPROT = MAXPROT or VM_PROT_WRITE + else match =notwriteable?, attribute + INITPROT = INITPROT and not VM_PROT_WRITE + MAXPROT = MAXPROT and not VM_PROT_WRITE + else match =notwritable?, attribute + INITPROT = INITPROT and not VM_PROT_WRITE + MAXPROT = MAXPROT and not VM_PROT_WRITE + else match =executable?, attribute + INITPROT = INITPROT or VM_PROT_EXECUTE + MAXPROT = MAXPROT or VM_PROT_EXECUTE + else match =notexecutable?, attribute + INITPROT = INITPROT and not VM_PROT_EXECUTE + MAXPROT = MAXPROT and not VM_PROT_EXECUTE + else + err 'unknown attribute "',`attribute,'"' + end match + redefine sequence tail + else + break + end match + end while + else + NAME = definition + end match + if NAME eqtype '' & lengthof NAME > 16 + err 'name too long' + end if + + VMADDR := MachO.VM_ADDRESS + + if $% = MachO.TEXT_OFFSET & FILESIZE > 0 & MachO.FILETYPE <> MH_OBJECT + MachO.FILE_OFFSET = 0 + else + MachO.FILE_OFFSET = $% + end if + + if FILESIZE + FILEOFF := MachO.FILE_OFFSET + else + FILEOFF := 0 + end if + + MachO.SEGMENT_NUMBER = MachO.SEGMENT_NUMBER + 1 + if MachO.CPUTYPE and CPU_ARCH_ABI64 + MachO.command LC_SEGMENT_64 + else + MachO.command LC_SEGMENT + end if + repeat 1, s:MachO.SEGMENT_NUMBER + namespace MachO.segment#s + segname emit 16: NAME + if MachO.CPUTYPE and CPU_ARCH_ABI64 + vmaddr dq VMADDR + vmsize dq VMSIZE + fileoff dq FILEOFF + filesize dq FILESIZE + else + vmaddr dd VMADDR + vmsize dd VMSIZE + fileoff dd FILEOFF + filesize dd FILESIZE + end if + maxprot dd MAXPROT + initprot dd INITPROT + nsects dd NSECTS + flags dd 0 + end namespace + repeat NSECTS + namespace MachO.segment#s#_section#% + sectname emit 16: ? + segname emit 16: ? + if MachO.CPUTYPE and CPU_ARCH_ABI64 + addr dq ? + size dq ? + else + addr dd ? + size dd ? + end if + offset dd ? + ?align dd ? + reloff dd ? + nreloc dd ? + flags dd ? + reserved1 dd ? + reserved2 dd ? + if MachO.CPUTYPE and CPU_ARCH_ABI64 + dd ? + end if + end namespace + end repeat + end repeat + + macro MachO.close_segment + MachO.close_section + local OFFSET,NEXT,TOP,FILL + TOP = $% + NSECTS := MachO.SECTION_NUMBER + if MachO.FILE_OFFSET >= $%% + FILL = MachO.FILE_OFFSET + else + FILL = $%% + end if + repeat 1, s:MachO.SEGMENT_NUMBER + repeat NSECTS, n:2 + if % = 1 + load OFFSET from MachO:MachO.segment#s#_section#%.offset + else + OFFSET = NEXT + end if + if % < %% + load NEXT from MachO:MachO.segment#s#_section#n.offset + else + NEXT = TOP + end if + if OFFSET >= $%% + store S_ZEROFILL at MachO:MachO.segment#s#_section#%.flags + store 0 at MachO:MachO.segment#s#_section#%.size + else if OFFSET + FILL = NEXT + end if + end repeat + end repeat + FILESIZE := FILL - MachO.FILE_OFFSET + FILL = FILL - $%% + MachO.SECTION_BYPASS = 1 + section MachO.VM_ADDRESS + FILESIZE - FILL + restore MachO.SECTION_BYPASS + db FILL dup 0 + if FILESIZE + rb (MachO.FILE_ALIGNMENT-$%) and (MachO.FILE_ALIGNMENT-1) + end if + MachO.VM_ADDRESS = MachO.VM_ADDRESS + TOP - MachO.FILE_OFFSET + MachO.VM_ADDRESS = MachO.VM_ADDRESS + (MachO.SEGMENT_ALIGNMENT-MachO.VM_ADDRESS) and (MachO.SEGMENT_ALIGNMENT-1) + VMSIZE := MachO.VM_ADDRESS - VMADDR + purge MachO.close_segment + end macro + + MachO.text + org VMADDR + $% - MachO.FILE_OFFSET + MachO.SECTION_NUMBER = 0 + +end macro + +macro MachO.section declaration + if MachO.SEGMENT_NUMBER = 0 + MachO.segment '__TEXT' readable writable executable + end if + MachO.close_section + + local SECTNAME,SEGNAME,FLAGS,ALIGN,RESERVED1,RESERVED2 + + FLAGS = S_REGULAR + ALIGN = 0 + RESERVED1 = 0 + RESERVED2 = 0 + + local sequence + match segname:sectname tail, declaration: + SECTNAME = sectname + SEGNAME = segname + define sequence tail + else match name tail, declaration: + SECTNAME = name + repeat 1, s:MachO.SEGMENT_NUMBER + load SEGNAME from MachO:MachO.segment#s.segname + end repeat + define sequence tail + end match + + while 1 + match :, sequence + break + else match =align? boundary tail, sequence + ALIGN = bsf boundary + if bsf boundary <> bsr boundary + err 'invalid alignment value' + end if + redefine sequence tail + else match =flags?(value) tail, sequence + FLAGS = value + redefine sequence tail + else match =reserved1?(value) tail, sequence + RESERVED1 = value + redefine sequence tail + else match =reserved2?(value) tail, sequence + RESERVED2 = value + redefine sequence tail + else + err 'invalid arguments' + end match + end while + + MachO.text + if ALIGN + align 1 shl ALIGN + end if + + MachO.SECTION_ALIGN = 1 shl ALIGN + + MachO.SECTION_NUMBER = MachO.SECTION_NUMBER + 1 + MachO.GLOBAL_SECTION_NUMBER = MachO.GLOBAL_SECTION_NUMBER + 1 + + repeat 1, s:MachO.SEGMENT_NUMBER, t:MachO.SECTION_NUMBER + if ~ defined MachO.segment#s#_section#t.sectname + MachO.command + namespace MachO.segment#s#_section#t + sectname emit 16: ? + segname emit 16: ? + if MachO.CPUTYPE and CPU_ARCH_ABI64 + addr dq ? + size dq ? + else + addr dd ? + size dd ? + end if + offset dd ? + ?align dd ? + reloff dd ? + nreloc dd ? + flags dd ? + reserved1 dd ? + reserved2 dd ? + if MachO.CPUTYPE and CPU_ARCH_ABI64 + dd ? + end if + end namespace + MachO.text + end if + store SECTNAME at MachO:MachO.segment#s#_section#t.sectname + store SEGNAME at MachO:MachO.segment#s#_section#t.segname + store $ at MachO:MachO.segment#s#_section#t.addr + store $% at MachO:MachO.segment#s#_section#t.offset + store FLAGS at MachO:MachO.segment#s#_section#t.flags + store ALIGN at MachO:MachO.segment#s#_section#t.align + store RESERVED1 at MachO:MachO.segment#s#_section#t.reserved1 + store RESERVED2 at MachO:MachO.segment#s#_section#t.reserved2 + end repeat + +end macro + +macro MachO.close_section + MachO.text + if MachO.SECTION_NUMBER + local SIZE + repeat 1, s:MachO.SEGMENT_NUMBER, t:MachO.SECTION_NUMBER + load OFFSET from MachO:MachO.segment#s#_section#t.offset + store $%-OFFSET at MachO:MachO.segment#s#_section#t.size + end repeat + end if +end macro + +macro MachO.close_segment +end macro + +postpone + MachO.close_segment + if MachO.FILETYPE <> MH_OBJECT & $%% < 1000h + store 0:byte at $-1 ; enforce minimum file size for OS X 10.10.5 and higher + end if +end postpone + +macro segment? args& + MachO.segment args +end macro + +macro section? args& + if defined MachO.SECTION_BYPASS + section args + else + MachO.section args + end if +end macro + +macro entry? regs& + iterate reg, regs + match name:value, reg + MachO.thread.name? := value + else if MachO.CPUTYPE = CPU_TYPE_I386 + MachO.thread.eip? := reg + else if MachO.CPUTYPE = CPU_TYPE_X86_64 + MachO.thread.rip? := reg + end if + end iterate + MachO.command LC_UNIXTHREAD + if MachO.CPUTYPE = CPU_TYPE_I386 + MachO.thread.flavor dd x86_THREAD_STATE32 + iterate name, eax,ebx,ecx,edx,edi,esi,ebp,esp,ss,eflags,eip,cs,ds,es,fs,gs + if % = 1 + MachO.thread.count dd %% + end if + if defined MachO.thread.name? + dd MachO.thread.name? + else + dd ? + end if + end iterate + else if MachO.CPUTYPE = CPU_TYPE_X86_64 + MachO.thread.flavor dd x86_THREAD_STATE64 + iterate name, rax,rbx,rcx,rdx,rdi,rsi,rbp,rsp,r8,r9,r10,r11,r12,r13,r14,r15,rip,rflags,cs,fs,gs + if % = 1 + MachO.thread.count dd %%*2 + end if + if defined MachO.thread.name? + dq MachO.thread.name? + else + dq ? + end if + end iterate + else + err 'CPU not supported' + end if + MachO.text +end macro + +; Upper layer: symbol tables + +define macroBuilder? + +macro macroBuilder? declaration& + macro macroBuilder?.definition + esc macro declaration + end macro +end macro + +macro macroBuilder?.line? content& + macro macroBuilder?.definition + macroBuilder?.definition + content + end macro +end macro + +macro macroBuilder?.end? + macroBuilder?.definition + esc end macro +end macro + +if MachO.FILETYPE <> MH_OBJECT + + namespace MachO + NSYMS = 0 + LIB_NUMBER = 0 + end namespace + + macro interpreter? path + MachO.command LC_LOAD_DYLINKER + namespace MachO.dylinker_command + lc_str dd dylinker-MachO.COMMAND + dylinker db path,0 + if MachO.CPUTYPE and CPU_ARCH_ABI64 + align 8 + else + align 4 + end if + end namespace + end macro + + macro uses? lib& + MachO.LIB_NUMBER = MachO.LIB_NUMBER + 1 + MachO.command LC_LOAD_DYLIB + repeat 1, l:MachO.LIB_NUMBER + namespace MachO.dylib#l#_command + lc_str dd dylib-MachO.COMMAND + timestamp dd 2 + match path (a.b.c=,x.y.z), lib + current_version dd (x and 0FFFFh) shl 16 + y shl 8 + z + compatibility_version dd (a and 0FFFFh) shl 16 + b shl 8 + c + dylib db path,0 + else + current_version dd 10000h + compatibility_version dd 10000h + dylib db lib,0 + end match + if MachO.CPUTYPE and CPU_ARCH_ABI64 + align 8 + else + align 4 + end if + end namespace + end repeat + end macro + + macro import? definitions& + iterate , definitions + MachO.NSYMS = MachO.NSYMS + 1 + define MachO.nlist name + name.imported := 1 + name.type := N_EXT + name.desc := REFERENCE_FLAG_UNDEFINED_NON_LAZY + define name.str string + end iterate + end macro + + MachO.__TEXT = 0 + MachO.__DATA = 0 + + macro segment? args& + MachO.segment args + if MachO.NSYMS + repeat 1, s:MachO.SEGMENT_NUMBER + load MachO.SEGNAME from MachO:MachO.segment#s.segname + end repeat + if ~MachO.__TEXT & MachO.SEGNAME = '__TEXT' + MachO.__TEXT = 1 + MachO.__stubs + else if ~MachO.__DATA & MachO.SEGNAME = '__DATA' + MachO.__DATA = 1 + MachO.__nl_symbol_ptr + end if + end if + end macro + + postpone + if MachO.NSYMS + + macroBuilder MachO.__stubs + + macroBuilder.line section '__stubs' flags(S_SYMBOL_STUBS+S_ATTR_SOME_INSTRUCTIONS+S_ATTR_PURE_INSTRUCTIONS) reserved1(0) reserved2(MachO.JUMP_SIZE) align 16 + + irpv sym, MachO.nlist + if sym.imported + macroBuilder.line sym: jmp [sym.ptr] + if % = 1 + macroBuilder.line MachO.JUMP_SIZE := $ - sym + end if + end if + end irpv + + macroBuilder.end + + macroBuilder MachO.__nl_symbol_ptr + + if MachO.CPUTYPE and CPU_ARCH_ABI64 + macroBuilder.line section '__nl_symbol_ptr' flags(S_NON_LAZY_SYMBOL_POINTERS) reserved1(0) align 8 + else + macroBuilder.line section '__nl_symbol_ptr' flags(S_NON_LAZY_SYMBOL_POINTERS) reserved1(0) align 4 + end if + + irpv sym, MachO.nlist + if sym.imported + if MachO.CPUTYPE and CPU_ARCH_ABI64 + macroBuilder.line sym.ptr dq 0 + else + macroBuilder.line sym.ptr dd 0 + end if + end if + end irpv + + macroBuilder.end + + if ~MachO.__TEXT + segment '__TEXT' readable executable + end if + + if ~MachO.__DATA + segment '__DATA' readable writable + end if + + segment '__LINKEDIT' readable + + MachO.SYMOFF := $% + irpv sym, MachO.nlist + namespace MachO.nlist#% + n_strx dd sym.strx + n_type db sym.type + n_sect db 0 + n_desc dw sym.desc + if MachO.CPUTYPE and CPU_ARCH_ABI64 + n_value dq sym + else + n_value dd sym + end if + end namespace + end irpv + + MachO.INDIRECTSYMOFF := $% + irpv sym, MachO.nlist + if sym.imported + dd %-1 + end if + end irpv + + MachO.STROFF := $% + db 20h,0 + irpv sym, MachO.nlist + sym.strx := $% - MachO.STROFF + db string sym.str, 0 + end irpv + MachO.STRSIZE := $% - MachO.STROFF + + MachO.command LC_SYMTAB + namespace MachO.symtab_command + symoff dd SYMOFF + nsyms dd NSYMS + stroff dd STROFF + strsize dd STRSIZE + end namespace + + MachO.command LC_DYSYMTAB + namespace MachO.dysymtab_command + ilocalsym dd 0 + nlocalsym dd 0 + iextdefsym dd 0 + nextdefsym dd 0 + iundefsym dd 0 + nundefsym dd NSYMS + tocoff dd 0 + ntoc dd 0 + modtaboff dd 0 + nmodtab dd 0 + extrefsymoff dd 0 + nextrefsyms dd 0 + indirectsymoff dd INDIRECTSYMOFF + nindirectsyms dd NSYMS + extreloff dd 0 + nextrel dd 0 + locreloff dd 0 + nlocrel dd 0 + end namespace + + end if + end postpone + +else + + namespace MachO + + element MachO.section? + element MachO.symbol? + + VM_ADDRESS = 0 + + define nlist null + null.value := 0 + null.type := 0 + null.sect := 0 + null.desc := 0 + null.str := '' + + NSYMS = 1 + NRELOC = 0 + + end namespace + + segment 0 readable writable executable + + macro MachO.section declaration + if MachO.SECTION_NUMBER + org 0 scaleof (1 metadataof $) + 0 scaleof $ + end if + MachO.section declaration + local sym + element sym : MachO.GLOBAL_SECTION_NUMBER * MachO.section + $ + org sym + MachO.SECTION_OFFSET = $% + MachO.SECTION_REL_INDEX = MachO.NRELOC + repeat 1, s:MachO.SEGMENT_NUMBER, t:MachO.SECTION_NUMBER + store MachO.RELOFF+MachO.SECTION_REL_INDEX*8 at MachO:MachO.segment#s#_section#t.reloff + end repeat + end macro + + macro MachO.close_section + MachO.close_section + if MachO.SECTION_NUMBER + repeat 1, s:MachO.SEGMENT_NUMBER, t:MachO.SECTION_NUMBER + store MachO.NRELOC-MachO.SECTION_REL_INDEX at MachO:MachO.segment#s#_section#t.nreloc + end repeat + end if + end macro + + macro public? declaration* + local name + define MachO.nlist name + match value =as? namestr, declaration + name = value + define name.str string namestr + else + name = declaration + define name.str `declaration + end match + if name relativeto 1 elementof name & 1 elementof (1 metadataof name) eq MachO.section + name.value := 0 scaleof (1 metadataof name) + 0 scaleof name + name.type := N_SECT + N_EXT + name.sect := 1 scaleof (1 metadataof name) + else + name.value := name + name.type := N_ABS + name.sect := 0 + end if + name.desc := REFERENCE_FLAG_DEFINED + MachO.NSYMS = MachO.NSYMS + 1 + end macro + + macro extrn? declaration* + match namestr =as? sym, declaration + define MachO.nlist sym + define sym.str string namestr + else + define MachO.nlist declaration + define declaration.str `declaration + end match + match sym, MachO.nlist + element sym : MachO.NSYMS * MachO.symbol + sym.type := N_EXT + sym.sect := 0 + sym.desc := 0 + sym.value := 0 + end match + MachO.NSYMS = MachO.NSYMS + 1 + end macro + + MachO.reloc.stack equ MachO.reloc + + calminstruction dword? v* + compute v, v + check ~ v relativeto 0 & v relativeto 1 elementof v & (1 elementof (1 metadataof v) eq MachO.section | 1 elementof (1 metadataof v) eq MachO.symbol) + jyes dir + check ~ v relativeto 0 & (v + $) relativeto 1 elementof (v + $) & (1 elementof (1 metadataof (v + $)) eq MachO.section | 1 elementof (1 metadataof (v + $)) eq MachO.symbol) + jyes rel + emit 4, v + exit + + local r, o + dir: + compute r, $% - MachO.SECTION_OFFSET + (1 scaleof (1 metadataof v)) shl 32 + 2 shl 57 + GENERIC_RELOC_VANILLA shl 60 + check 1 elementof (1 metadataof v) eq MachO.symbol + jno dir_ready + compute r, r + 1 shl 59 + dir_ready: + compute o, $% + emit 4, 0 scaleof (1 metadataof v) + 0 scaleof v + check $% > o + jyes record + exit + + rel: + check MachO.CPUTYPE = CPU_TYPE_X86_64 + jyes rel_x64 + compute v, v + 0 scaleof (1 metadataof v) - 0 scaleof (1 metadataof $) + compute r, $% - MachO.SECTION_OFFSET + (1 scaleof (1 metadataof (v + $))) shl 32 + 1 shl 56 + 2 shl 57 + GENERIC_RELOC_VANILLA shl 60 + jump rel_prepared + rel_x64: + check 1 elementof (1 metadataof (v + $)) eq MachO.symbol + jyes rel_x64_symbol + compute v, v + 0 scaleof (1 metadataof v) - 0 scaleof (1 metadataof $) + jump rel_x64_prepare + rel_x64_symbol: + compute v, v + $ + 4 + rel_x64_prepare: + compute r, $% - MachO.SECTION_OFFSET + (1 scaleof (1 metadataof (v + $))) shl 32 + 1 shl 56 + 2 shl 57 + X86_64_RELOC_SIGNED_4 shl 60 + rel_prepared: + check 1 elementof (1 metadataof (v + $)) eq MachO.symbol + jno rel_ready + compute r, r + 1 shl 59 + rel_ready: + compute o, $% + emit 4, 0 scaleof v + check $% > o + jyes record + exit + + record: + publish :MachO.reloc.stack, r + compute MachO.NRELOC, MachO.NRELOC + 1 + + end calminstruction + + postpone + if MachO.NSYMS + + MachO.close_section + macro MachO.close_section + MachO.text + end macro + + rb (-$%) and 11b + + MachO.RELOFF := $% + irpv rel, MachO.reloc + dq rel + end irpv + + MachO.SYMOFF := $% + irpv sym, MachO.nlist + namespace MachO.nlist#% + n_strx dd sym.strx + n_type db sym.type + n_sect db sym.sect + n_desc dw sym.desc + if MachO.CPUTYPE and CPU_ARCH_ABI64 + n_value dq sym.value + else + n_value dd sym.value + end if + end namespace + end irpv + + MachO.STROFF := $% + irpv sym, MachO.nlist + sym.strx := $% - MachO.STROFF + db string sym.str, 0 + end irpv + MachO.STRSIZE := $% - MachO.STROFF + + MachO.command LC_SYMTAB + namespace MachO.symtab_command + symoff dd SYMOFF + nsyms dd NSYMS + stroff dd STROFF + strsize dd STRSIZE + end namespace + + end if + end postpone + + calminstruction align? boundary,value:? + check $ relativeto 0 | MachO.SECTION_ALIGN mod (boundary) = 0 + jyes allowed + err 'section not aligned enough' + exit + allowed: + compute boundary, (boundary-1)-(0 scaleof $+boundary-1) mod boundary + arrange value, =db boundary =dup value + assemble value + end calminstruction + + calminstruction dd? definitions& + local value, n + start: + match value=,definitions, definitions, () + jyes recognize + match value, definitions + arrange definitions, + recognize: + match n =dup? value, value, () + jyes duplicate + match ?, value + jyes reserve + call dword, value + next: + match , definitions + jno start + take , definitions + take definitions, definitions + jyes next + exit + reserve: + emit dword + jump next + duplicate: + match (value), value + stack: + check n + jno next + take definitions, value + arrange value, definitions + compute n, n - 1 + jump stack + end calminstruction + + calminstruction (label) dd? definitions& + local cmd + arrange cmd, =label label : =dword + assemble cmd + arrange cmd, =dd definitions + assemble cmd + end calminstruction + +end if diff --git a/toolchain/fasmg.kl0e/examples/x86/include/format/mz.inc b/toolchain/fasmg.kl0e/examples/x86/include/format/mz.inc new file mode 100644 index 0000000..74e115e --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/format/mz.inc @@ -0,0 +1,209 @@ + +MZ:: +.signature dw "MZ" +.bytes_in_last_page dw .LENGTH and 1FFh +.number_of_pages dw (.LENGTH-1) shr 9 + 1 +.number_of_relocations dw .NUMBER_OF_RELOCATIONS +.number_of_header_paragraphs dw .HEADER_LENGTH shr 4 +.minimum_heap dw (.LENGTH+.RESERVED_LENGTH-1) shr 4 - (.LENGTH-1) shr 4 +.maximum_heap dw 0FFFFh +.initial_ss dw 0 +.initial_sp dw 0 +.checksum dw 0 +.initial_ip dw 0 +.initial_cs dw 0 +.relocations_offset dw .relocations +.overlay_number dw 0 +.relocations dw .NUMBER_OF_RELOCATIONS dup (?,?) + rb 0Fh - ($%+0Fh) and 0Fh +.HEADER_LENGTH = $ +.RELOCATION_INDEX = 0 + +.ENTRY_DEFINED = 0 +.HEAP_DEFINED = 0 +.STACK_DEFINED = 0 +.STACK_LENGTH = 1000h + +org 0 + +macro entry? definition + local v + if MZ.ENTRY_DEFINED + err 'setting already specified' + else match seg:offs, definition + v = seg + if v relativeto MZ.segment + store v - MZ.segment : word at MZ : MZ.initial_cs + else + err 'incorrect segment' + end if + v = offs + if v >= 0 & v < 10000h + store v : word at MZ : MZ.initial_ip + else + err 'value out of range' + end if + MZ.ENTRY_DEFINED = 1 + else + err 'invalid argument' + end match +end macro + +macro heap? definition + local v,min + if MZ.HEAP_DEFINED + err 'setting already specified' + else + v = definition + if v >= 0 & v < 10000h + load min : word from MZ : MZ.minimum_heap + v = v + min + if v > 0FFFFh + v = 0FFFFh + end if + store v : word at MZ : MZ.maximum_heap + else + err 'value out of range' + end if + MZ.HEAP_DEFINED = 1 + end if +end macro + +macro stack? definition + local v + if MZ.STACK_DEFINED + err 'setting already specified' + else match seg:offs, definition + v = seg + if v relativeto MZ.segment + store v - MZ.segment : word at MZ : MZ.initial_ss + else + err 'incorrect segment' + end if + v = offs + if v >= 0 & v < 10000h + store v : word at MZ : MZ.initial_sp + else + err 'value out of range' + end if + MZ.STACK_DEFINED = 1 + MZ.STACK_LENGTH = 0 + else + MZ.STACK_DEFINED = 1 + MZ.STACK_LENGTH = definition + end match +end macro + +element MZ.segment + +macro segment? definition + rb 0Fh - ($%+0Fh) and 0Fh + match name =use16?, definition + name := MZ.segment + ($%-MZ.HEADER_LENGTH) shr 4 + use16 + else match name =use32?, definition + name := MZ.segment + ($%-MZ.HEADER_LENGTH) shr 4 + use32 + else match name, definition + name := MZ.segment + ($%-MZ.HEADER_LENGTH) shr 4 + end match + org 0 +end macro + +calminstruction calminstruction?.initsym? var*, val& + publish var, val +end calminstruction + +calminstruction calminstruction?.asm? line& + local name, i + initsym name, name.0 + match name.i, name + compute i, i+1 + arrange name, name.i + publish name, line + arrange line, =assemble name + assemble line +end calminstruction + +iterate , dw,word, dd,dword + + calminstruction word? value + compute value, value + check value relativeto MZ.segment + jno plain + local offset + compute offset, $% + emit word, value - MZ.segment + check $% > offset + jno done + compute offset, offset - MZ.HEADER_LENGTH + compute offset, offset and 0FFFFh + (offset and not 0FFFFh) shl 12 + asm store offset:4 at MZ : MZ.relocations + MZ.RELOCATION_INDEX shl 2 + compute MZ.RELOCATION_INDEX, MZ.RELOCATION_INDEX + 1 + done: + exit + plain: + emit word, value + end calminstruction + + calminstruction dw? definitions& + local value, n + start: + match value=,definitions, definitions, () + jyes recognize + match value, definitions + arrange definitions, + recognize: + match n =dup? value, value, () + jyes duplicate + match ?, value + jyes reserve + call word, value + next: + match , definitions + jno start + take , definitions + take definitions, definitions + jyes next + exit + reserve: + emit word + jump next + duplicate: + match (value), value + stack: + check n + jno next + take definitions, value + arrange value, definitions + compute n, n - 1 + jump stack + end calminstruction + + calminstruction (label) dw? definitions& + local cmd + arrange cmd, =label label : =word + assemble cmd + arrange cmd, =dw definitions + assemble cmd + end calminstruction + +end iterate + +calminstruction align? boundary,value:? + compute boundary, (boundary-1)-((0 scaleof $)+boundary-1) mod boundary + arrange value, =db boundary =dup value + assemble value +end calminstruction + +postpone + if MZ.STACK_LENGTH + rb 0Fh - ($%+0Fh) and 0Fh + store ($%-MZ.HEADER_LENGTH) shr 4 : word at MZ : MZ.initial_ss + rb MZ.STACK_LENGTH + store MZ.STACK_LENGTH : word at MZ : MZ.initial_sp + end if + MZ.LENGTH = $%% + MZ.RESERVED_LENGTH = $%-$%% + MZ.NUMBER_OF_RELOCATIONS = MZ.RELOCATION_INDEX +end postpone diff --git a/toolchain/fasmg.kl0e/examples/x86/include/format/pe.inc b/toolchain/fasmg.kl0e/examples/x86/include/format/pe.inc new file mode 100644 index 0000000..98ab575 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/format/pe.inc @@ -0,0 +1,1064 @@ + +IMAGE_FILE_MACHINE_UNKNOWN = 0x0 +IMAGE_FILE_MACHINE_AM33 = 0x1D3 +IMAGE_FILE_MACHINE_AMD64 = 0x8664 +IMAGE_FILE_MACHINE_ARM = 0x1C0 +IMAGE_FILE_MACHINE_ARMNT = 0x1C4 +IMAGE_FILE_MACHINE_ARM64 = 0xAA64 +IMAGE_FILE_MACHINE_EBC = 0xEBC +IMAGE_FILE_MACHINE_I386 = 0x14C +IMAGE_FILE_MACHINE_IA64 = 0x200 +IMAGE_FILE_MACHINE_M32R = 0x9041 +IMAGE_FILE_MACHINE_MIPS16 = 0x266 +IMAGE_FILE_MACHINE_MIPSFPU = 0x366 +IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466 +IMAGE_FILE_MACHINE_POWERPC = 0x1F0 +IMAGE_FILE_MACHINE_POWERPCFP = 0x1F1 +IMAGE_FILE_MACHINE_R4000 = 0x166 +IMAGE_FILE_MACHINE_SH3 = 0x1A2 +IMAGE_FILE_MACHINE_SH3DSP = 0x1A3 +IMAGE_FILE_MACHINE_SH4 = 0x1A6 +IMAGE_FILE_MACHINE_SH5 = 0x1A8 +IMAGE_FILE_MACHINE_THUMB = 0x1C2 +IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169 + +IMAGE_FILE_RELOCS_STRIPPED = 0x0001 +IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002 +IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004 +IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008 +IMAGE_FILE_AGGRESSIVE_WS_TRIM = 0x0010 +IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020 +IMAGE_FILE_BYTES_REVERSED_LO = 0x0080 +IMAGE_FILE_32BIT_MACHINE = 0x0100 +IMAGE_FILE_DEBUG_STRIPPED = 0x0200 +IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400 +IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800 +IMAGE_FILE_SYSTEM = 0x1000 +IMAGE_FILE_DLL = 0x2000 +IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000 +IMAGE_FILE_BYTES_REVERSED_HI = 0x8000 + +IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA = 0x0020 +IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040 +IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY = 0x0080 +IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100 +IMAGE_DLLCHARACTERISTICS_NO_ISOLATION = 0x0200 +IMAGE_DLLCHARACTERISTICS_NO_SEH = 0x0400 +IMAGE_DLLCHARACTERISTICS_NO_BIND = 0x0800 +IMAGE_DLLCHARACTERISTICS_APPCONTAINER = 0x1000 +IMAGE_DLLCHARACTERISTICS_WDM_DRIVER = 0x2000 +IMAGE_DLLCHARACTERISTICS_GUARD_CF = 0x4000 +IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000 + +IMAGE_SUBSYSTEM_UNKNOWN = 0 +IMAGE_SUBSYSTEM_NATIVE = 1 +IMAGE_SUBSYSTEM_WINDOWS_GUI = 2 +IMAGE_SUBSYSTEM_WINDOWS_CUI = 3 +IMAGE_SUBSYSTEM_POSIX_CUI = 7 +IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9 +IMAGE_SUBSYSTEM_EFI_APPLICATION = 10 +IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER = 11 +IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER = 12 +IMAGE_SUBSYSTEM_EFI_ROM = 13 +IMAGE_SUBSYSTEM_XBOX = 14 + +IMAGE_SCN_TYPE_NO_PAD = 0x00000008 +IMAGE_SCN_CNT_CODE = 0x00000020 +IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040 +IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080 +IMAGE_SCN_LNK_OTHER = 0x00000100 +IMAGE_SCN_LNK_INFO = 0x00000200 +IMAGE_SCN_LNK_REMOVE = 0x00000800 +IMAGE_SCN_LNK_COMDAT = 0x00001000 +IMAGE_SCN_GPREL = 0x00008000 +IMAGE_SCN_MEM_PURGEABLE = 0x00020000 +IMAGE_SCN_MEM_16BIT = 0x00020000 +IMAGE_SCN_MEM_LOCKED = 0x00040000 +IMAGE_SCN_MEM_PRELOAD = 0x00080000 +IMAGE_SCN_ALIGN_1BYTES = 0x00100000 +IMAGE_SCN_ALIGN_2BYTES = 0x00200000 +IMAGE_SCN_ALIGN_4BYTES = 0x00300000 +IMAGE_SCN_ALIGN_8BYTES = 0x00400000 +IMAGE_SCN_ALIGN_16BYTES = 0x00500000 +IMAGE_SCN_ALIGN_32BYTES = 0x00600000 +IMAGE_SCN_ALIGN_64BYTES = 0x00700000 +IMAGE_SCN_ALIGN_128BYTES = 0x00800000 +IMAGE_SCN_ALIGN_256BYTES = 0x00900000 +IMAGE_SCN_ALIGN_512BYTES = 0x00A00000 +IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000 +IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000 +IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000 +IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000 +IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000 +IMAGE_SCN_MEM_DISCARDABLE = 0x02000000 +IMAGE_SCN_MEM_NOT_CACHED = 0x04000000 +IMAGE_SCN_MEM_NOT_PAGED = 0x08000000 +IMAGE_SCN_MEM_SHARED = 0x10000000 +IMAGE_SCN_MEM_EXECUTE = 0x20000000 +IMAGE_SCN_MEM_READ = 0x40000000 +IMAGE_SCN_MEM_WRITE = 0x80000000 + +IMAGE_REL_BASED_ABSOLUTE = 0 +IMAGE_REL_BASED_HIGH = 1 +IMAGE_REL_BASED_LOW = 2 +IMAGE_REL_BASED_HIGHLOW = 3 +IMAGE_REL_BASED_HIGHADJ = 4 +IMAGE_REL_BASED_DIR64 = 10 + +calminstruction align? boundary,value:? + check $ relativeto 0 | ( $ relativeto PE.RELOCATION & PE.SECTION_ALIGNMENT mod boundary = 0 ) + jyes allowed + err 'section not aligned enough' + exit + allowed: + compute boundary, (boundary-1)-((0 scaleof $)+boundary-1) mod boundary + arrange value, =db boundary =dup value + assemble value +end calminstruction + +PE:: + +namespace PE + + if defined Settings.Magic + MAGIC = Settings.Magic + else + MAGIC = 0x10B + end if + + if defined Settings.Machine + MACHINE = Settings.Machine + else + MACHINE = IMAGE_FILE_MACHINE_I386 + end if + + if defined Settings.Characteristics + CHARACTERISTICS = Settings.Characteristics + else + CHARACTERISTICS = IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_32BIT_MACHINE + end if + + if defined Settings.DllCharacteristics + DLL_CHARACTERISTICS = Settings.DllCharacteristics + else + DLL_CHARACTERISTICS = 0 + end if + + if defined Settings.Subsystem + SUBSYSTEM = Settings.Subsystem + else + SUBSYSTEM = IMAGE_SUBSYSTEM_WINDOWS_CUI + end if + + if defined Settings.MajorSubsystemVersion + MAJOR_SUBSYSTEM_VERSION = Settings.MajorSubsystemVersion + else + MAJOR_SUBSYSTEM_VERSION = 3 + end if + + if defined Settings.MinorSubsystemVersion + MINOR_SUBSYSTEM_VERSION = Settings.MinorSubsystemVersion + else + MINOR_SUBSYSTEM_VERSION = 10 + end if + + if defined Fixups + element RELOCATION + DLL_CHARACTERISTICS = DLL_CHARACTERISTICS or IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE + else + RELOCATION := 0 + CHARACTERISTICS = CHARACTERISTICS or IMAGE_FILE_RELOCS_STRIPPED + end if + + if defined Settings.ImageBase + IMAGE_BASE := RELOCATION + Settings.ImageBase + else + IMAGE_BASE := RELOCATION + 400000h + end if + + if defined Settings.SectionAlignment + SECTION_ALIGNMENT := Settings.SectionAlignment + else + SECTION_ALIGNMENT := 1000h + end if + + if defined Settings.FileAlignment + FILE_ALIGNMENT := Settings.FileAlignment + else + FILE_ALIGNMENT := 512 + end if + + if defined Settings.LegacyHeaders + LEGACY_HEADERS := Settings.LegacyHeaders + else + LEGACY_HEADERS := 1 + end if + + NUMBER_OF_DIRECTORIES := 16 + + if defined Settings.Stub + + virtual at 0 + file Settings.Stub + if $ >= 1Ch + load SIGNATURE : word from 0 + if SIGNATURE = "MZ" | SIGNATURE = "ZM" + StubTemplate:: + end if + end if + end virtual + + if defined StubTemplate + + load .BYTES_IN_LAST_PAGE : word from StubTemplate:2 + load .NUMBER_OF_PAGES : word from StubTemplate:4 + .TEMPLATE_LENGTH = .NUMBER_OF_PAGES shl 9 - (-.BYTES_IN_LAST_PAGE) and 1FFh + + load .RELOCATIONS_OFFSET : word from StubTemplate:18h + if .RELOCATIONS_OFFSET >= 40h + file Settings.Stub,.TEMPLATE_LENGTH + else + load .NUMBER_OF_RELOCATIONS : word from StubTemplate:6 + .RELOCATIONS_LENGTH = .NUMBER_OF_RELOCATIONS shl 2 + load .NUMBER_OF_HEADER_PARAGRAPHS : word from StubTemplate:8 + .TEMPLATE_HEADER_LENGTH = .NUMBER_OF_HEADER_PARAGRAPHS shl 4 + + file Settings.Stub,1Ch + rb 40h - $ + file Settings.Stub:.RELOCATIONS_OFFSET,.RELOCATIONS_LENGTH + align 16 + .HEADER_LENGTH = $ + file Settings.Stub:.TEMPLATE_HEADER_LENGTH,.TEMPLATE_LENGTH-.TEMPLATE_HEADER_LENGTH + .LENGTH = $ + + store 40h : word at 18h + store .HEADER_LENGTH shr 4 : word at 8 + store .LENGTH and 1FFh : word at 2 + store (.LENGTH-1) shr 9 + 1 : word at 4 + end if + + store Header : dword at 3Ch + + else + + Stub: + .signature dw "MZ" + .bytes_in_last_page dw .LENGTH and 1FFh + .number_of_pages dw (.LENGTH-1) shr 9 + 1 + .number_of_relocations dw 0 + .number_of_header_paragraphs dw .HEADER_LENGTH shr 4 + .minimum_heap dw (10000h - (.LENGTH-.HEADER_LENGTH)) shr 4 + .maximum_heap dw 0FFFFh + .initial_ss dw (-100h) shr 4 + .initial_sp dw 0FFFEh + .checksum dw 0 + .initial_ip dw 100h + .initial_cs dw (-100h) shr 4 + .relocations_offset dw 40h + .overlay_number dw 0 + rb 3Ch - $ + .new_header_offset dd Header + + .HEADER_LENGTH = $ + + file Settings.Stub + + .LENGTH = $ + + end if + + else + + Stub: + .signature dw "MZ" + .bytes_in_last_page dw .LENGTH and 1FFh + .number_of_pages dw (.LENGTH-1) shr 9 + 1 + .number_of_relocations dw 0 + .number_of_header_paragraphs dw .HEADER_LENGTH shr 4 + .minimum_heap dw .STACK_LENGTH shr 4 + .maximum_heap dw 0FFFFh + .initial_ss dw 0 + .initial_sp dw .LENGTH - .HEADER_LENGTH + .STACK_LENGTH + .checksum dw 0 + .initial_ip dw 0 + .initial_cs dw 0 + .relocations_offset dw 40h + .overlay_number dw 0 + rb 3Ch - $ + .new_header_offset dd Header + + .HEADER_LENGTH = $ + .STACK_LENGTH = 100h + + namespace Stub + + include '../8086.inc' + + start: + push cs + pop ds + mov dx,message - start + mov ah,9 + int 21h + mov ax,4C01h + int 21h + + message db 'This program cannot be run in DOS mode.',0Dh,0Ah,24h + + end namespace + + align 16 + + .LENGTH = $ + + end if + + if defined Settings.Stamp + TIMESTAMP := Settings.Stamp + else + TIMESTAMP := __TIME__ + end if + + align 8 + + Header: + .Signature dw "PE",0 + .Machine dw MACHINE + .NumberOfSections dw NUMBER_OF_SECTIONS + .TimeDateStamp dd TIMESTAMP + .PointerToSymbolTable dd 0 + .NumberOfSymbols dd 0 + .SizeOfOptionalHeader dw SectionTable - OptionalHeader + .Characteristics dw CHARACTERISTICS + + OptionalHeader: + .Magic dw MAGIC + .MajorLinkerVersion db 0 + .MinorLinkerVersion db 0 + .SizeOfCode dd 0 + .SizeOfInitializedData dd 0 + .SizeOfUninitializedData dd 0 + .AddressOfEntryPoint dd 0 + .BaseOfCode dd 0 + if MAGIC <> 0x20B + .BaseOfData dd 0 + .ImageBase dd IMAGE_BASE - RELOCATION + else + .ImageBase dq IMAGE_BASE - RELOCATION + end if + .SectionAlignment dd SECTION_ALIGNMENT + .FileAlignment dd FILE_ALIGNMENT + .MajorOperatingSystemVersion dw 1 + .MinorOperatingSystemVersion dw 0 + .MajorImageVersion dw 0 + .MinorImageVersion dw 0 + .MajorSubsystemVersion dw MAJOR_SUBSYSTEM_VERSION + .MinorSubsystemVersion dw MINOR_SUBSYSTEM_VERSION + .Win32VersionValue dd 0 + .SizeOfImage dd SIZE_OF_IMAGE + .SizeOfHeaders dd SIZE_OF_HEADERS + .CheckSum dd 0 + .Subsystem dw SUBSYSTEM + .DllCharacteristics dw DLL_CHARACTERISTICS + if MAGIC <> 0x20B + .SizeOfStackReserve dd 1000h + .SizeOfStackCommit dd 1000h + .SizeOfHeapReserve dd 10000h + .SizeOfHeapCommit dd 0 + else + .SizeOfStackReserve dq 1000h + .SizeOfStackCommit dq 1000h + .SizeOfHeapReserve dq 10000h + .SizeOfHeapCommit dq 0 + end if + .LoaderFlags dd 0 + .NumberOfRvaAndSizes dd NUMBER_OF_DIRECTORIES + RvaAndSizes: + .Rva dd 0 + .Size dd 0 + .ENTRY_LENGTH = $ - RvaAndSizes + db (NUMBER_OF_DIRECTORIES-1)*RvaAndSizes.ENTRY_LENGTH dup 0 + SectionTable: + .Name dq '.flat' + .VirtualSize dd 0 + .VirtualAddress dd 0 + .SizeOfRawData dd 0 + .PointerToRawData dd 0 + .PointerToRelocations dd 0 + .PointerToLineNumbers dd 0 + .NumberOfRelocations dw 0 + .NumberOfLineNumbers dw 0 + .Characteristics dd IMAGE_SCN_MEM_EXECUTE + IMAGE_SCN_MEM_READ + IMAGE_SCN_MEM_WRITE + .ENTRY_LENGTH = $ - SectionTable + db (NUMBER_OF_SECTIONS-1)*SectionTable.ENTRY_LENGTH dup 0 + + HeadersEnd: + define CheckSumBlocks PE,0,HeadersEnd + + SECTION_INDEX = 0 + RELOCATION_INDEX = 0 + DEFINED_SECTION = 0 + SECTION_DIRECTORIES = 0 + align SECTION_ALIGNMENT + FIRST_SECTION_RVA: + section $%% + align FILE_ALIGNMENT,0 + SIZE_OF_HEADERS = $% + FILE_OFFSET = $% + SECTION_BASE = IMAGE_BASE + FIRST_SECTION_RVA + org SECTION_BASE + + store SECTION_BASE-IMAGE_BASE at PE:OptionalHeader.AddressOfEntryPoint + store SECTION_BASE-IMAGE_BASE at PE:SectionTable.VirtualAddress + store FILE_OFFSET at PE:SectionTable.PointerToRawData + + virtual at 0 + relocated_addresses:: rd NUMBER_OF_RELOCATIONS + end virtual + + virtual at 0 + relocation_types:: rw NUMBER_OF_RELOCATIONS + end virtual + +end namespace + +RVA? equ -PE.IMAGE_BASE + + +macro entry? address* + namespace PE + store address-IMAGE_BASE at PE:OptionalHeader.AddressOfEntryPoint + end namespace +end macro + +macro stack? reserve*,commit:1000h + namespace PE + store reserve at PE:OptionalHeader.SizeOfStackReserve + store commit at PE:OptionalHeader.SizeOfStackCommit + end namespace +end macro + +macro heap? reserve*,commit:0 + namespace PE + store reserve at PE:OptionalHeader.SizeOfHeapReserve + store commit at PE:OptionalHeader.SizeOfHeapCommit + end namespace +end macro + +calminstruction calminstruction?.initsym? var*, val& + publish var, val +end calminstruction + +calminstruction calminstruction?.asm? line& + local name, i + initsym name, name.0 + match name.i, name + compute i, i+1 + arrange name, name.i + publish name, line + arrange line, =assemble name + assemble line +end calminstruction + +macro section? + namespace PE + + repeat SECTION_DIRECTORIES + end data + end repeat + + local AREA,DATA_START,DATA_END + AREA:: + DATA_START = $$ + DATA_END = $-($%-$%%) + CheckSumBlocks reequ CheckSumBlocks,AREA,DATA_START,DATA_END + + SECTION_SIZE = $ - SECTION_BASE + store SECTION_SIZE at PE:SectionTable.VirtualSize+SECTION_INDEX*SectionTable.ENTRY_LENGTH + align SECTION_ALIGNMENT + SECTION_BASE = $ + section $%% + align FILE_ALIGNMENT,0 + RAW_DATA_SIZE = $% - FILE_OFFSET + store RAW_DATA_SIZE at PE:SectionTable.SizeOfRawData+SECTION_INDEX*SectionTable.ENTRY_LENGTH + FILE_OFFSET = $% + org SECTION_BASE + + load SECTION_CHARACTERISTICS from PE:SectionTable.Characteristics+SECTION_INDEX*SectionTable.ENTRY_LENGTH + if SECTION_SIZE > 0 & RAW_DATA_SIZE = 0 + SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_CNT_UNINITIALIZED_DATA + store SECTION_CHARACTERISTICS at PE:SectionTable.Characteristics+SECTION_INDEX*SectionTable.ENTRY_LENGTH + end if + + if LEGACY_HEADERS + if SECTION_CHARACTERISTICS and IMAGE_SCN_CNT_CODE & RAW_DATA_SIZE > 0 + load CODE_SIZE from PE:OptionalHeader.SizeOfCode + if CODE_SIZE = 0 + load CODE_BASE from PE:SectionTable.VirtualAddress+SECTION_INDEX*SectionTable.ENTRY_LENGTH + store CODE_BASE at PE:OptionalHeader.BaseOfCode + end if + CODE_SIZE = CODE_SIZE + RAW_DATA_SIZE + store CODE_SIZE at PE:OptionalHeader.SizeOfCode + end if + if SECTION_CHARACTERISTICS and IMAGE_SCN_CNT_INITIALIZED_DATA & RAW_DATA_SIZE > 0 + load DATA_SIZE from PE:OptionalHeader.SizeOfInitializedData + if DATA_SIZE = 0 & MAGIC <> 0x20B + load DATA_BASE from PE:SectionTable.VirtualAddress+SECTION_INDEX*SectionTable.ENTRY_LENGTH + store DATA_BASE at PE:OptionalHeader.BaseOfData + end if + DATA_SIZE = DATA_SIZE + RAW_DATA_SIZE + store DATA_SIZE at PE:OptionalHeader.SizeOfInitializedData + end if + if SECTION_CHARACTERISTICS and IMAGE_SCN_CNT_UNINITIALIZED_DATA + load BSS_SIZE from PE:OptionalHeader.SizeOfUninitializedData + BSS_SIZE = BSS_SIZE + SECTION_SIZE + store BSS_SIZE at PE:OptionalHeader.SizeOfUninitializedData + end if + end if + + if DEFINED_SECTION | SECTION_SIZE > 0 + SECTION_INDEX = SECTION_INDEX + 1 + end if + + end namespace +end macro + +macro section? declaration* + namespace PE + + section + + DEFINED_SECTION = 1 + + store SECTION_BASE-IMAGE_BASE at PE:SectionTable.VirtualAddress+SECTION_INDEX*SectionTable.ENTRY_LENGTH + store FILE_OFFSET at PE:SectionTable.PointerToRawData+SECTION_INDEX*SectionTable.ENTRY_LENGTH + + SECTION_DIRECTORIES = 0 + + match name attributes, declaration + + store name:qword at PE:SectionTable.Name+SECTION_INDEX*SectionTable.ENTRY_LENGTH + + SECTION_CHARACTERISTICS = 0 + + local seq + define seq attributes: + while 1 + match :, seq + break + else match =readable? tail, seq + redefine seq tail + SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_READ + else match =writeable? tail, seq + redefine seq tail + SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_WRITE + else match =writable? tail, seq + redefine seq tail + SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_WRITE + else match =executable? tail, seq + redefine seq tail + SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_EXECUTE + else match =discardable? tail, seq + redefine seq tail + SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_DISCARDABLE + else match =shareable? tail, seq + redefine seq tail + SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_MEM_SHARED + else match =import? tail, seq + redefine seq tail + SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1 + data import + else match =export? tail, seq + redefine seq tail + SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1 + data export + else match =resource? =from? path tail, seq + redefine seq tail + SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1 + data resource from path + else match =resource? tail, seq + redefine seq tail + SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1 + data resource + else match =fixups? tail, seq + redefine seq tail + SECTION_DIRECTORIES = SECTION_DIRECTORIES + 1 + data fixups + else match =code? tail, seq + redefine seq tail + SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_CNT_CODE + else match =data? tail, seq + redefine seq tail + SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_CNT_INITIALIZED_DATA + else match =udata? tail, seq + redefine seq tail + SECTION_CHARACTERISTICS = SECTION_CHARACTERISTICS or IMAGE_SCN_CNT_UNINITIALIZED_DATA + else match attribute tail, seq + err 'unknown attribute "',`attribute,'"' + redefine seq : + end match + end while + + store SECTION_CHARACTERISTICS at PE:SectionTable.Characteristics+SECTION_INDEX*SectionTable.ENTRY_LENGTH + else + + store declaration:qword at PE:SectionTable.Name+SECTION_INDEX*SectionTable.ENTRY_LENGTH + + end match + + end namespace +end macro + +macro data? type* + namespace PE + local number,content + define content + match =export?, type + number = 0 + else match =import?, type + number = 1 + else match =resource? =from? path, type + number = 2 + define content resource_from path + else match =resource?, type + number = 2 + else match =fixups?, type + number = 5 + define content fixups + else + number = type + end match + define DATA_DIRECTORY number + load DATA_BASE:dword from PE:RvaAndSizes.Rva+DATA_DIRECTORY*RvaAndSizes.ENTRY_LENGTH + if DATA_BASE = 0 + store $-IMAGE_BASE:dword at PE:RvaAndSizes.Rva+DATA_DIRECTORY*RvaAndSizes.ENTRY_LENGTH + match instruction, content + instruction + end match + else + err 'data already defined' + end if + end namespace +end macro + +macro end?.data? + namespace PE + load DATA_BASE:dword from PE:RvaAndSizes.Rva+DATA_DIRECTORY*RvaAndSizes.ENTRY_LENGTH + store $-IMAGE_BASE-DATA_BASE:dword at PE:RvaAndSizes.Size+DATA_DIRECTORY*RvaAndSizes.ENTRY_LENGTH + restore DATA_DIRECTORY + end namespace +end macro + +macro PE.resource_directory? + namespace PE + Resource: rb RESOURCE_HEADERS_LENGTH + Resource.counter = 0 + define RESOURCE_DIRECTORIES_LIST Resource_root + Resource_root.counter = 0 + end namespace +end macro + +macro PE.resource_data? type*,id*,lang*,codepage:0 + namespace PE + local _type,_id,_lang + _type = type + _id = id + _lang = lang + if ~ type eqtype 0 + _type = _type shl 32 + end if + if ~ id eqtype 0 + _id = id shl 32 + end if + if ~ lang eqtype 0 + _lang = lang shl 32 + end if + repeat 1, %type:_type, %id:_id, %lang:_lang + if ~ defined Resource_#%type#_#%id.counter + if ~ defined Resource_#%type.counter + repeat 1, i:Resource_root.counter + Resource_root.entry#i = type + Resource_root.offset#i = (Resource_#%type - Resource) or 80000000h + end repeat + Resource_root.counter = Resource_root.counter + 1 + match list, RESOURCE_DIRECTORIES_LIST + define RESOURCE_DIRECTORIES_LIST list,Resource_#%type + end match + Resource_#%type.counter = 0 + end if + repeat 1, i:Resource_#%type.counter + Resource_#%type.entry#i = id + Resource_#%type.offset#i = (Resource_#%type#_#%id - Resource) or 80000000h + end repeat + Resource_#%type.counter = Resource_#%type.counter + 1 + + match list, RESOURCE_DIRECTORIES_LIST + define RESOURCE_DIRECTORIES_LIST list,Resource_#%type#_#%id + end match + Resource_#%type#_#%id.counter = 0 + end if + repeat 1, i:Resource_#%type#_#%id.counter + Resource_#%type#_#%id.entry#i = lang + Resource_#%type#_#%id.offset#i = Resource_#%type#_#%id#_#%lang - Resource + end repeat + Resource_#%type#_#%id.counter = Resource_#%type#_#%id.counter + 1 + repeat 1, i:Resource.counter + Resource_#%type#_#%id#_#%lang := Resource.entry#i + Resource.cp#i := codepage + Resource.data#i: + end repeat + end repeat + end namespace +end macro + +macro PE.end_resource_data? + namespace PE + repeat 1, i:Resource.counter + Resource.size#i := $ - Resource.data#i + end repeat + Resource.counter = Resource.counter + 1 + align 4 + end namespace +end macro + +macro PE.end_resource_directory? + namespace PE + RESOURCE_HEADERS_POINTER = 0 + + match list, RESOURCE_DIRECTORIES_LIST + iterate dir, list + dir := Resource + RESOURCE_HEADERS_POINTER + RESOURCE_HEADERS_POINTER = RESOURCE_HEADERS_POINTER + 16 + dir.counter * 8 + local x,y,z,a,b + x = dir.counter shr 1 + while x > 0 + y = x + while y < dir.counter + z = y + while z-x >= 0 + repeat 1, i:z, j:z-x + if dir.entry#i eqtype 0 + if ~ dir.entry#j eqtype 0 | dir.entry#i >= dir.entry#j + z = 0 + end if + else if ~ dir.entry#j eqtype 0 + a = dir.entry#i bswap lengthof dir.entry#i + b = dir.entry#j bswap lengthof dir.entry#j + if ( lengthof a >= lengthof b & a shr ((lengthof a - lengthof b)*8) >= b ) | ( lengthof a < lengthof b & a > b shr ((lengthof b - lengthof a)*8) ) + z = 0 + end if + end if + if z > 0 + a = dir.entry#i + b = dir.offset#i + dir.entry#i = dir.entry#j + dir.offset#i = dir.offset#j + dir.entry#j = a + dir.offset#j = b + z = z - x + end if + end repeat + end while + y = y + 1 + end while + x = x shr 1 + end while + end iterate + iterate dir, list + store __TIME__ : 4 at dir + 4 + dir.names_counter = 0 + repeat dir.counter, i:0 + if dir.entry#i eqtype 0 + store dir.entry#i : 4 at dir + 16 + i * 8 + else + dir.names_counter = dir.names_counter + 1 + repeat 1, %id:dir.entry#i + if ~ defined Resource_string#%id + restore Resource_string#%id + Resource_string#%id = Resource + RESOURCE_HEADERS_POINTER + if lengthof dir.entry#i and 1 + err 'a word-aligned string is expected as a name' + end if + RESOURCE_HEADERS_POINTER = RESOURCE_HEADERS_POINTER + lengthof dir.entry#i + 2 + store (lengthof dir.entry#i)/2 : 2 at Resource_string#%id + store dir.entry#i : lengthof dir.entry#i at Resource_string#%id + 2 + end if + store (Resource_string#%id - Resource) or 80000000h : 4 at dir + 16 + i * 8 + end repeat + end if + store dir.offset#i : 4 at dir + 16 + i * 8 + 4 + end repeat + store dir.names_counter : 2 at dir + 12 + store dir.counter - dir.names_counter : 2 at dir + 14 + end iterate + end match + + if RESOURCE_HEADERS_POINTER and 11b + RESOURCE_HEADERS_POINTER = RESOURCE_HEADERS_POINTER + 4 - RESOURCE_HEADERS_POINTER and 11b + end if + + repeat Resource.counter, i:0 + Resource.entry#i := Resource + RESOURCE_HEADERS_POINTER + RESOURCE_HEADERS_POINTER = RESOURCE_HEADERS_POINTER + 16 + store RVA(Resource.data#i) : 4 at Resource.entry#i + store Resource.size#i : 4 at Resource.entry#i + 4 + store Resource.cp#i : 4 at Resource.entry#i + 8 + end repeat + + RESOURCE_HEADERS_LENGTH = RESOURCE_HEADERS_POINTER + end namespace +end macro + +macro PE.resource_from path* + + local res_file,res_size,res_header_size,res_data_size,res_data + local offset,char,type,id,lang + + virtual at 0 + res_file:: file path + res_size := $ + end virtual + + PE.resource_directory + + offset = 0 + while offset < res_size + load res_header_size : 4 from res_file : offset + 4 + load res_data_size : 4 from res_file : offset + 0 + + if res_data_size > 0 + + offset =: offset + 8 + load char : 2 from res_file : offset + if char = 0FFFFh + load char : 2 from res_file : offset + 2 + type = +char + offset = offset + 4 + else + while 1 + if char = 0 + load type : (%-1)*2 from res_file : offset + offset = offset + (% + % and 1)*2 + break + end if + load char : 2 from res_file : offset + %*2 + end while + end if + load char : 2 from res_file : offset + if char = 0FFFFh + load char : 2 from res_file : offset + 2 + id = +char + offset = offset + 4 + else + while 1 + if char = 0 + load id : (%-1)*2 from res_file : offset + offset = offset + (% + % and 1)*2 + break + end if + load char : 2 from res_file : offset + %*2 + end while + end if + load char : 2 from res_file : offset + 6 + lang = +char + + restore offset + + PE.resource_data type,id,lang + load res_data : res_data_size from res_file : offset + res_header_size + db res_data + PE.end_resource_data + + end if + + offset = offset + res_header_size + res_data_size + if offset and 11b + offset = offset + 4 - offset and 11b + end if + end while + + PE.end_resource_directory + +end macro + +macro PE.fixups + namespace PE + Fixups: + calminstruction BuildFixups + local PAGE_RVA, BLOCK_HEADER, BLOCK_SIZE + local INDEX, ADDRESS, TYPE, FIXUP + compute PAGE_RVA, -1 + compute BLOCK_HEADER, 0 + compute BLOCK_SIZE, 0 + compute INDEX,0 + process: + check INDEX = NUMBER_OF_RELOCATIONS + jyes close_block + asm load ADDRESS:4 from relocated_addresses:INDEX shl 2 + check PAGE_RVA >= 0 & ADDRESS and not 0FFFh = PAGE_RVA + jyes append_to_block + close_block: + check BLOCK_HEADER + jno start_new_block + check BLOCK_SIZE and 11b + jno finish_block + asm dw 0 + compute BLOCK_SIZE, BLOCK_SIZE + 2 + finish_block: + asm store BLOCK_SIZE:4 at BLOCK_HEADER+4 + start_new_block: + check INDEX = NUMBER_OF_RELOCATIONS + jyes done + compute PAGE_RVA, ADDRESS and not 0FFFh + compute BLOCK_HEADER, $ + asm dd PAGE_RVA, 0 + compute BLOCK_SIZE, 8 + append_to_block: + asm load TYPE:2 from relocation_types:INDEX shl 1 + compute FIXUP, (ADDRESS and 0FFFh) or (TYPE shl 12) + asm dw FIXUP + compute BLOCK_SIZE, BLOCK_SIZE + 2 + compute INDEX, INDEX + 1 + jump process + done: + end calminstruction + BuildFixups + end namespace +end macro + +if defined PE.Fixups + + calminstruction dword? value* + compute value, value + check value relativeto 0 | ~ value relativeto PE.RELOCATION + jyes plain + local offset + compute offset, $% + emit 4, value - PE.RELOCATION + check $% > offset + jno done + asm store $-4-PE.IMAGE_BASE:4 at PE.relocated_addresses:PE.RELOCATION_INDEX shl 2 + asm store IMAGE_REL_BASED_HIGHLOW:2 at PE.relocation_types:PE.RELOCATION_INDEX shl 1 + compute PE.RELOCATION_INDEX, PE.RELOCATION_INDEX + 1 + done: + exit + plain: + emit 4, value + end calminstruction + + calminstruction qword? value* + compute value, value + check value relativeto 0 | ~ value relativeto PE.RELOCATION + jyes plain + local offset + compute offset, $% + emit 8, value - PE.RELOCATION + check $% > offset + jno done + asm store $-8-PE.IMAGE_BASE:4 at PE.relocated_addresses:PE.RELOCATION_INDEX shl 2 + asm store IMAGE_REL_BASED_DIR64:2 at PE.relocation_types:PE.RELOCATION_INDEX shl 1 + compute PE.RELOCATION_INDEX, PE.RELOCATION_INDEX + 1 + done: + exit + plain: + emit 8, value + end calminstruction + + iterate , dd,dword, dq,qword + + calminstruction dd? definitions& + local value, n + start: + match value=,definitions, definitions, () + jyes recognize + match value, definitions + arrange definitions, + recognize: + match n =dup? value, value, () + jyes duplicate + match ?, value + jyes reserve + call dword, value + next: + match , definitions + jno start + take , definitions + take definitions, definitions + jyes next + exit + reserve: + emit dword + jump next + duplicate: + match (value), value + stack: + check n + jno next + take definitions, value + arrange value, definitions + compute n, n - 1 + jump stack + end calminstruction + + calminstruction (label) dd? definitions& + local cmd + arrange cmd, =label label : =dword + assemble cmd + arrange cmd, =dd definitions + assemble cmd + end calminstruction + + end iterate + +end if + +postpone + purge section? + section + namespace PE + SIZE_OF_IMAGE := SECTION_BASE - IMAGE_BASE + NUMBER_OF_SECTIONS := SECTION_INDEX + NUMBER_OF_RELOCATIONS := RELOCATION_INDEX + end namespace +end postpone + +postpone ? + namespace PE + CHECKSUM = 0 + + calminstruction CheckSum + local AREA, DATA_START, DATA_END, POS, H + get_block: + match AREA=,DATA_START=,DATA_END=,CheckSumBlocks, CheckSumBlocks + jyes block_ready + match AREA=,DATA_START=,DATA_END, CheckSumBlocks + jyes last_block + exit + last_block: + arrange CheckSumBlocks, + block_ready: + compute POS, DATA_START + process_block: + check POS + 2 <= DATA_END + jno finish_block + asm load H:2 from AREA:POS + compute CHECKSUM, CHECKSUM + H + compute POS, POS + 2 + jump process_block + finish_block: + check POS + 1 = DATA_END + jno reduce_checksum + asm load H:1 from AREA:POS + compute CHECKSUM, CHECKSUM + H + reduce_checksum: + check CHECKSUM shr 16 + jno get_block + compute CHECKSUM, CHECKSUM shr 16 + CHECKSUM and 0FFFFh + jump reduce_checksum + done: + end calminstruction + + CheckSum + CHECKSUM = CHECKSUM + $% + store CHECKSUM at PE:OptionalHeader.CheckSum + end namespace +end postpone diff --git a/toolchain/fasmg.kl0e/examples/x86/include/p5.inc b/toolchain/fasmg.kl0e/examples/x86/include/p5.inc new file mode 100644 index 0000000..aa8c2ce --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/p5.inc @@ -0,0 +1,37 @@ + +calminstruction element? definition + local name, meta + match =tr? any, definition + jyes skip + arrange definition, =element? definition + assemble definition + skip: +end calminstruction + +include '80486.inc' + +purge element? + +iterate , wrmsr,<0Fh,30h>, rdtsc,<0Fh,31h>, rdmsr,<0Fh,32h>, rdpmc,<0Fh,33h>, cpuid,<0Fh,0A2h>, rsm,<0Fh,0AAh> + + calminstruction instr? + asm db opcode + end calminstruction + +end iterate + +calminstruction cmpxchg8b? dest* + call x86.parse_operand@dest, dest + check @dest.type = 'mem' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + check @dest.size and not 8 + jno size_ok + err 'invalid operand size' + size_ok: + xcall x86.store_instruction@dest, <0Fh,0C7h>,(1) +end calminstruction + +include '80387.inc' diff --git a/toolchain/fasmg.kl0e/examples/x86/include/p6.inc b/toolchain/fasmg.kl0e/examples/x86/include/p6.inc new file mode 100644 index 0000000..186eb3c --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/p6.inc @@ -0,0 +1,62 @@ + +include 'p5.inc' + +iterate , sysenter,<0Fh,34h>, sysexit,<0Fh,35h> + + calminstruction instr? + asm db opcode + end calminstruction + +end iterate + +iterate , o,0, no,1, c,2, b,2, nae,2, nc,3, nb,3, ae,3, z,4, e,4, nz,5, ne,5, na,6, be,6, a,7, nbe,7, \ + s,8, ns,9, p,0Ah, pe,0Ah, np,0Bh, po,0Bh, l,0Ch, nge,0Ch, nl,0Dh, ge,0Dh, ng,0Eh, le,0Eh, g,0Fh, nle,0Fh + + calminstruction cmov#cond? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') + jyes cmov_rm_reg + err 'invalid combination of operands' + exit + cmov_rm_reg: + check @src.size and not @dest.size + jno cmov_rm_reg_ok + err 'operand sizes do not match' + cmov_rm_reg_ok: + call x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, <0Fh,40h+code>,@dest.rm + end calminstruction + +end iterate + +iterate , fcmovb,<0DAh,0C0h>, fcmove,<0DAh,0C8h>, fcmovbe,<0DAh,0D0h>, fcmovu,<0DAh,0D8h>, \ + fcmovnb,<0DBh,0C0h>, fcmovne,<0DBh,0C8h>, fcmovnbe,<0DBh,0D0h>, fcmovnu,<0DBh,0D8h> + + calminstruction instr? dest*,src* + call x87.parse_operand@dest, dest + call x87.parse_operand@src, src + check @dest.type = 'streg' & @dest.rm = 0 & @src.type = 'streg' + jyes ok + err 'invalid operand' + exit + ok: + asm db opcode + @src.rm + end calminstruction + +end iterate + +iterate , fucomi,0DBh,5, fucomip,0DFh,5, fcomi,0DBh,6, fcomip,0DFh,6 + + calminstruction instr? src:st1 + call x87.parse_operand@src, src + check @src.type = 'streg' + jyes ok + err 'invalid operand' + exit + ok: + emit 1, opcode + emit 1, 11b shl 6 + postbyte shl 3 + @src.rm + end calminstruction + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/include/x64.inc b/toolchain/fasmg.kl0e/examples/x86/include/x64.inc new file mode 100644 index 0000000..5498429 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/include/x64.inc @@ -0,0 +1,3476 @@ + +define x86 x86 + +element x86.reg +element x86.r8 : x86.reg + 1 +element x86.r16 : x86.reg + 2 +element x86.r32 : x86.reg + 4 +element x86.r64 : x86.reg + 8 + +element al? : x86.r8 + 0 +element cl? : x86.r8 + 1 +element dl? : x86.r8 + 2 +element bl? : x86.r8 + 3 + +element spl? : x86.r8 + 4 +element bpl? : x86.r8 + 5 +element sil? : x86.r8 + 6 +element dil? : x86.r8 + 7 + +element ah? : x86.r8 - 4 +element ch? : x86.r8 - 5 +element dh? : x86.r8 - 6 +element bh? : x86.r8 - 7 + +repeat 8, i:8 + element r#i#b? : x86.r8 + i + element r#i#l? : x86.r8 + i +end repeat + +element ax? : x86.r16 + 0 +element cx? : x86.r16 + 1 +element dx? : x86.r16 + 2 +element bx? : x86.r16 + 3 +element sp? : x86.r16 + 4 +element bp? : x86.r16 + 5 +element si? : x86.r16 + 6 +element di? : x86.r16 + 7 + +repeat 8, i:8 + element r#i#w? : x86.r16 + i +end repeat + +element eax? : x86.r32 + 0 +element ecx? : x86.r32 + 1 +element edx? : x86.r32 + 2 +element ebx? : x86.r32 + 3 +element esp? : x86.r32 + 4 +element ebp? : x86.r32 + 5 +element esi? : x86.r32 + 6 +element edi? : x86.r32 + 7 + +repeat 8, i:8 + element r#i#d? : x86.r32 + i +end repeat + +element rax? : x86.r64 + 0 +element rcx? : x86.r64 + 1 +element rdx? : x86.r64 + 2 +element rbx? : x86.r64 + 3 +element rsp? : x86.r64 + 4 +element rbp? : x86.r64 + 5 +element rsi? : x86.r64 + 6 +element rdi? : x86.r64 + 7 + +repeat 8, i:8 + element r#i? : x86.r64 + i +end repeat + +element x86.ip + +element eip? : x86.ip + 4 +element rip? : x86.ip + 8 + +element x86.sreg + +element es? : x86.sreg + 0 +element cs? : x86.sreg + 1 +element ss? : x86.sreg + 2 +element ds? : x86.sreg + 3 +element fs? : x86.sreg + 4 +element gs? : x86.sreg + 5 + +element x86.creg + +element x86.crx : x86.creg + 0 +element x86.drx : x86.creg + 1 + +repeat 16, i:0 + element cr#i? : x86.crx + i + element dr#i? : x86.drx + i +end repeat + +define x86.byte? :1 +define x86.word? :2 +define x86.dword? :4 +define x86.pword? :6 +define x86.fword? :6 +define x86.qword? :8 +define x86.tword? :10 +define x86.tbyte? :10 +define x86.dqword? :16 + +x86.mode = 16 + +macro use16? + x86.mode = 16 +end macro + +macro use32? + x86.mode = 32 +end macro + +macro use64? + x86.mode = 64 +end macro + +x86.REX_REQUIRED = 100h +x86.REX_FORBIDDEN = 200h + + +calminstruction calminstruction?.initsym? var*, val& + publish var, val +end calminstruction + +calminstruction calminstruction?.asm? line& + local name, i + initsym name, name.0 + match name.i, name + compute i, i+1 + arrange name, name.i + publish name, line + arrange line, =assemble name + assemble line +end calminstruction + +calminstruction calminstruction?.xcall? instruction*, arguments& + arrange instruction, =call instruction + convert: + match , arguments + jyes ready + local v + match v=,arguments, arguments, <> + jyes recognize + arrange v, arguments + arrange arguments, + recognize: + match (v), v + jyes numeric + match , v + jyes symbolic + append: + arrange instruction, instruction=,v + jump convert + numeric: + compute v, v + symbolic: + local proxy, base, i + initsym base, proxy + initsym i, 0 + compute i, i+1 + arrange proxy, base.i + publish proxy, v + arrange instruction, instruction=,proxy + jump convert + ready: + assemble instruction +end calminstruction + + +define @dest @dest +define @src @src +define @src2 @src2 +define @aux @aux + +iterate context, @dest,@src,@src2,@aux + + namespace context + + iterate name, size, type, segment_prefix, prefix, opcode_prefix, rex_prefix, \ + imm, unresolved, displacement, displacement_size, auto_relative, \ + address, address_registers, segment, offset, jump_type, \ + mode, mod, rm, \ + scale, index, base + define name + end iterate + + calminstruction x86.parse_operand#context operand + + local i, pre, suf, sym + + compute segment_prefix, 0 + compute prefix, 0 + compute opcode_prefix, 0 + compute rex_prefix, 0 + + compute size, 0 + compute displacement_size, 0 + + transform operand + + match pre suf, operand + jno no_size_prefix + transform pre, x86 + jno no_size_prefix + match :size, pre + jno no_size_prefix + arrange operand, suf + no_size_prefix: + + match [address], operand + jyes memory_operand + match =ptr? address, operand + jyes memory_operand + match segment:offset, operand + jyes far_operand + + immediate_operand: + compute type, 'imm' + compute imm, +operand + + compute unresolved, 0 + check defined operand + jyes operand_resolved + compute unresolved, 1 + operand_resolved: + + check imm eq 1 elementof imm + jno operand_ready + check 1 metadataof (1 metadataof imm) relativeto x86.reg + jyes register_operand + check 1 metadataof imm relativeto x86.sreg + jyes segment_register_operand + + operand_ready: + exit + + register_operand: + + compute type, 'reg' + compute mode, x86.mode + compute mod, 11b + compute rm, 1 metadataof imm - 1 elementof (1 metadataof imm) + check size & size <> 1 metadataof (1 metadataof imm) - x86.reg + jyes operand_sizes_do_not_match + compute size, 1 metadataof (1 metadataof imm) - x86.reg + check rm < 0 + jyes register_precluding_rex + check size = 1 & rm >= 4 & rm < 8 + jyes register_requiring_rex + + exit + + register_precluding_rex: + compute rm, x86.REX_FORBIDDEN - rm + exit + + register_requiring_rex: + compute rm, x86.REX_REQUIRED + rm + exit + + segment_register_operand: + + compute type, 'sreg' + compute mode, x86.mode + compute mod, 11b + compute rm, 1 metadataof imm - x86.sreg + check size & size <> 2 & size <> 4 + jyes invalid_operand_size + + exit + + memory_operand: + compute type, 'mem' + + match segment:address, address + jno segment_prefix_ok + check segment eq 1 elementof segment & 1 metadataof segment relativeto x86.sreg + jno invalid_operand + compute segment, 1 metadataof segment - x86.sreg + check segment >= 4 + jyes segment_prefix_386 + compute segment_prefix, 26h + segment shl 3 + jump segment_prefix_ok + segment_prefix_386: + compute segment_prefix, 64h + segment-4 + segment_prefix_ok: + + compute mode, 0 + + match pre suf, address + jno no_address_size_prefix + transform pre, x86 + jno no_address_size_prefix + match :pre, pre + jno no_address_size_prefix + arrange address, suf + check pre = 2 | pre = 4 | pre = 8 + jno invalid_address_size + compute mode, pre shl 3 + no_address_size_prefix: + + compute scale, 0 + compute index, 0 + compute base, 0 + + check size + jyes size_override + compute size, sizeof address + size_override: + + compute address, address + compute address_registers, 0 + compute i, 1 + extract_registers: + check i > elementsof address + jyes registers_extracted + check i metadataof address relativeto x86.r16 | i metadataof address relativeto x86.r32 | i metadataof address relativeto x86.r64 | i metadataof address relativeto x86.ip + jno next_term + compute address_registers, address_registers + i elementof address * i scaleof address + next_term: + compute i, i+1 + jump extract_registers + registers_extracted: + compute displacement, address - address_registers + compute auto_relative, 0 + + check address_registers eq 0 + jyes direct_address + check mode & mode <> 0 scaleof (1 metadataof (1 metadataof address_registers)) shl 3 & ~ 1 metadataof address_registers relativeto x86.ip + jyes invalid_address + check 1 metadataof address_registers relativeto x86.r64 | 1 metadataof address_registers relativeto x86.r32 + jyes address_32bit_64bit + check 1 metadataof address_registers relativeto x86.r16 + jyes address_16bit + check address_registers eq rip | address_registers eq eip + jyes rip_relative_address + jump invalid_address + + rip_relative_address: + compute mode, 0 scaleof (1 metadataof address_registers) shl 3 + compute mod, 0 + compute rm, 5 + compute displacement_size, 4 + exit + + direct_address: + compute mod, 0 + check x86.mode = 64 + jyes direct_address_in_long_mode + check mode = 0 + jno mode_ok + compute mode, x86.mode + check mode = 16 & displacement relativeto 0 & displacement >= 10000h + jno mode_ok + compute mode, 32 + mode_ok: + check mode = 16 + jyes direct_address_16bit + direct_address_32bit: + compute rm, 5 + compute displacement_size, 4 + exit + direct_address_16bit: + compute rm, 6 + compute displacement_size, 2 + exit + + direct_address_in_long_mode: + compute displacement_size, 4 + check mode = 0 & segment_prefix < 64h + jyes auto_relative_address + check mode = 16 + jyes invalid_address_size + compute rm, 4 + compute base, 5 + compute index, 4 + compute scale, 1 + check mode = 32 + jno direct_address_displacement_ready + check ~ displacement relativeto 0 | displacement >= 100000000h | displacement < -100000000h + jyes address_out_of_range + compute displacement, displacement and 0FFFFFFFFh + direct_address_displacement_ready: + check displacement relativeto 0 & displacement > 7FFFFFFFh & displacement < 100000000h + jyes direct_address_switch_to_32bit + compute mode, 64 + compute displacement_size, 8 + exit + direct_address_switch_to_32bit: + compute mode, 32 + exit + + auto_relative_address: + compute mode, 64 + compute rm, 5 + compute auto_relative, 1 + exit + + address_16bit: + compute mode, 16 + + check address_registers relativeto bx+si + jyes rm_0 + check address_registers relativeto bx+di + jyes rm_1 + check address_registers relativeto bp+si + jyes rm_2 + check address_registers relativeto bp+di + jyes rm_3 + check address_registers relativeto si + jyes rm_4 + check address_registers relativeto di + jyes rm_5 + check address_registers relativeto bp + jyes rm_6 + check address_registers relativeto bx + jyes rm_7 + jump invalid_address + + rm_0: + compute rm, 0 + jump rm_ok + rm_1: + compute rm, 1 + jump rm_ok + rm_2: + compute rm, 2 + jump rm_ok + rm_3: + compute rm, 3 + jump rm_ok + rm_4: + compute rm, 4 + jump rm_ok + rm_5: + compute rm, 5 + jump rm_ok + rm_6: + compute rm, 6 + jump rm_ok + rm_7: + compute rm, 7 + rm_ok: + + check displacement relativeto 0 + jno displacement_16bit + check displacement = 0 & rm <> 6 + jyes displacement_empty + check displacement<80h & displacement>=-80h + jyes displacement_8bit + check displacement-10000h>=-80h & displacement<10000h + jyes displacement_8bit_wrap_16bit + displacement_16bit: + compute displacement_size, 2 + compute mod, 2 + exit + displacement_empty: + compute displacement_size, 0 + compute mod, 0 + exit + displacement_8bit_wrap_16bit: + compute displacement, displacement-10000h + displacement_8bit: + compute displacement_size, 1 + compute mod, 1 + exit + + address_32bit_64bit: + + local address_registers_type + check 1 metadataof address_registers relativeto x86.r64 + jyes address_64bit + address_32bit: + compute mode, 32 + compute address_registers_type, x86.r32 + jump check_address_registers + address_64bit: + compute mode, 64 + compute address_registers_type, x86.r64 + check_address_registers: + check 2 scaleof address_registers = 0 + jyes one_register + check 3 scaleof address_registers = 0 & 2 metadataof address_registers relativeto address_registers_type + jyes two_registers + jump invalid_address + + one_register: + compute scale, 1 scaleof address_registers + compute base, 1 metadataof address_registers - address_registers_type + check scale = 1 + jyes one_register_unscaled + check base <> 4 & (scale = 4 | scale = 8) + jyes one_register_scaled + check base <> 4 & (scale = 2 | scale = 3 | scale = 5 | scale = 9) + jyes one_register_split + jump invalid_address + one_register_unscaled: + check base and 111b = 4 + jyes one_register_unscaled_in_sib + compute rm, base + jump setup_displacement + one_register_unscaled_in_sib: + compute rm, 4 + compute index, 4 + jump setup_displacement + one_register_scaled: + compute rm, 4 + compute index, base + compute base, 5 + jump index_only + one_register_split: + compute rm, 4 + compute index, base + compute scale, scale - 1 + jump setup_displacement + two_registers: + compute rm,4 + check 1 scaleof address_registers = 1 + jyes base_first + check 2 scaleof address_registers = 1 + jyes base_second + jump invalid_address + base_first: + compute base, 1 metadataof address_registers - address_registers_type + compute index, 2 metadataof address_registers - address_registers_type + compute scale, 2 scaleof address_registers + jump process_sib + base_second: + compute base, 2 metadataof address_registers - address_registers_type + compute index, 1 metadataof address_registers - address_registers_type + compute scale, 1 scaleof address_registers + process_sib: + check index = 4 + jyes forbidden_index + check (x86.mode <> 64 & segment_prefix = 36h) & index = 5 & scale = 1 + jyes switch_to_index + check (x86.mode = 64 | segment_prefix = 3Eh) & base = 5 & scale = 1 + jyes switch_to_base + check scale and (scale-1) | scale > 8 + jyes invalid_address + jump setup_displacement + forbidden_index: + check scale = 1 + jno invalid_address + compute index, base + compute base, 4 + jump setup_displacement + switch_to_index: + compute index, base + compute base,5 + jump setup_displacement + switch_to_base: + compute base, index + compute index, 5 + jump setup_displacement + + setup_displacement: + check displacement relativeto 0 + jno displacement_32bit + check displacement = 0 & rm and 111b <> 5 & (rm <> 4 | base and 111b <> 5) + jyes displacement_empty + check displacement < 80h & displacement >= -80h + jyes displacement_8bit + check displacement - 1 shl mode >= -80h & displacement < 1 shl mode + jyes displacement_8bit_wrap + check (x86.mode = 64 | segment_prefix = 3Eh) & base = 5 & index = 5 & scale = 1 + jno displacement_32bit + compute scale, 2 + jump index_only + displacement_32bit: + compute displacement_size, 4 + compute mod, 2 + exit + displacement_8bit_wrap: + compute displacement, displacement - 1 shl mode + jump displacement_8bit + index_only: + compute displacement_size, 4 + compute mod, 0 + exit + + far_operand: + compute type, 'far' + + check size & size <> 4 & size <> 6 & size <> 10 + jyes operand_sizes_do_not_match + + exit + + invalid_operand: + err 'invalid operand' + exit + invalid_operand_size: + err 'invalid operand size' + exit + operand_sizes_do_not_match: + err 'operand sizes do not match' + exit + invalid_address: + err 'invalid address' + exit + invalid_address_size: + err 'invalid address size' + exit + address_out_of_range: + err 'address out of range' + exit + + end calminstruction + + calminstruction x86.parse_jump_operand#context operand + + match =far? operand, operand + jyes far_jump + match =near? operand, operand + jyes near_jump + match =short? operand, operand + jyes short_jump + compute jump_type, '' + jump parse_operand + far_jump: + compute jump_type, 'far' + jump parse_operand + near_jump: + compute jump_type, 'near' + jump parse_operand + short_jump: + compute jump_type, 'short' + + parse_operand: + + call x86.parse_operand#context, operand + + check type = 'imm' + jno done + + check size = 0 + jno verify_target_address + + compute size, x86.mode shr 3 + + verify_target_address: + + check imm relativeto 0 + jno done + check imm < 0 + jyes negative + check imm >= 1 shl (size*8) + jno done + out_of_range: + err 'value out of range' + exit + negative: + check imm < - 1 shl (size*8-1) + jyes out_of_range + compute imm, imm and (1 shl (size*8) - 1) + + done: + + end calminstruction + + calminstruction x86.select_operand_prefix#context size* + + check (size = 2 & x86.mode <> 16) | (size = 4 & x86.mode = 16) + jyes prefix_66h + check size = 8 + jyes prefix_48h + check size <> 0 & size <> 2 & size <> 4 + jyes invalid_size + exit + + prefix_66h: + compute prefix, 66h + exit + + prefix_48h: + compute prefix, 48h + exit + + invalid_size: + err 'invalid operand size' + + end calminstruction + + calminstruction x86.store_instruction#context opcode*,reg*,imm_size:0,immediate + + check segment_prefix + jno segment_prefix_ok + + check mode = 64 + jyes segment_in_long_mode + check mode = 16 & ( rm = 2 | rm = 3 | ( mod > 0 & rm = 6 ) ) + jyes ss_segment_default + check mode = 32 & ( ( mod > 0 & rm = 5 ) | ( rm = 4 & base = 4 ) | ( mod > 0 & rm = 4 & base = 5 ) ) + jyes ss_segment_default + + ds_segment_default: + check segment_prefix = 3Eh + jyes segment_prefix_ok + jump store_segment_prefix + ss_segment_default: + check segment_prefix = 36h + jyes segment_prefix_ok + jump store_segment_prefix + segment_in_long_mode: + check segment_prefix < 64h + jyes segment_prefix_ok + store_segment_prefix: + emit 1, segment_prefix + segment_prefix_ok: + + check mod <> 11b & mode <> x86.mode + jno addressing_prefix_ok + check mode = 64 | (mode = 16 & x86.mode = 64) + jno store_addressing_prefix + err 'illegal addressing mode' + store_addressing_prefix: + emit 1, 67h + addressing_prefix_ok: + + check (reg or rm) and x86.REX_REQUIRED + jno rex_1 + compute rex_prefix, rex_prefix or 40h + rex_1: + check rm and 1000b | (mod <> 11b & mode > 16 & rm = 4 & base and 1000b) + jno rex_2 + compute rex_prefix, rex_prefix or 41h + rex_2: + check mod <> 11b & mode > 16 & rm = 4 & index and 1000b + jno rex_4 + compute rex_prefix, rex_prefix or 42h + rex_4: + check reg and 1000b + jno rex_8 + compute rex_prefix, rex_prefix or 44h + rex_8: + check prefix = 48h + jno operand_prefix + compute rex_prefix, rex_prefix or 48h + jump operand_prefix_ok + + operand_prefix: + check prefix + jno operand_prefix_ok + emit 1, prefix + operand_prefix_ok: + + check opcode_prefix + jno opcode_prefix_ok + emit 1, opcode_prefix + opcode_prefix_ok: + + check rex_prefix + jno rex_prefix_ok + check x86.mode < 64 + jyes instruction_requires_long_mode + check reg and x86.REX_FORBIDDEN + jno store_rex_prefix + err 'disallowed combination of registers' + jump store_rex_prefix + instruction_requires_long_mode: + err 'instruction requires long mode' + store_rex_prefix: + emit 1, rex_prefix + rex_prefix_ok: + + asm db opcode + emit 1, mod shl 6 + (reg and 111b) shl 3 + rm and 111b + + check mod <> 11b & rm = 4 & mode <> 16 + jno sib_ok + emit 1, (bsf scale) shl 6 + (index and 111b) shl 3 + base and 111b + sib_ok: + + check displacement_size = 1 + jyes displacement_8bit + check displacement_size = 2 + jyes displacement_16bit + check displacement_size = 4 | displacement_size = 8 + jno displacement_ok + + compute displacement, displacement + + check auto_relative + jno auto_relative_ok + check imm_size < 8 + jyes adjust_auto_relative_displacement + compute displacement, displacement - ($ + 4 + 4) + jump auto_relative_ok + adjust_auto_relative_displacement: + compute displacement, displacement - ($ + 4 + imm_size) + auto_relative_ok: + + check mode = 64 & displacement relativeto 0 + jno displacement_ready + check displacement - 1 shl 64 >= -80000000h & displacement < 1 shl 64 + jyes adjust_displacement_wrap + check displacement >= -80000000h & displacement < 80000000h + jyes displacement_ready + err 'address value out of signed range' + adjust_displacement_wrap: + compute displacement, displacement - 1 shl 64 + displacement_ready: + + asm dd displacement + + jump displacement_ok + displacement_16bit: + asm dw displacement + jump displacement_ok + displacement_8bit: + emit 1, displacement + displacement_ok: + + check imm_size = 1 + jyes immediate_8bit + check imm_size = 2 + jyes immediate_16bit + check imm_size = 4 + jyes immediate_32bit + check imm_size = 8 + jno immediate_ok + call x86.simm32, immediate + jump immediate_ok + immediate_32bit: + compute imm, +immediate + asm dd imm + jump immediate_ok + immediate_16bit: + compute imm, +immediate + asm dw imm + jump immediate_ok + immediate_8bit: + compute imm, +immediate + emit 1, imm + immediate_ok: + + end calminstruction + + end namespace + +end iterate + +calminstruction x86.store_operand_prefix size*, reg:0 + + local rex_prefix + + compute rex_prefix, 0 + + check (size = 2 & x86.mode <> 16) | (size = 4 & x86.mode = 16) + jyes prefix_66h + check size = 8 + jyes rex_8 + check size <> 0 & size <> 2 & size <> 4 + jno check_register + err 'invalid operand size' + jump check_register + + prefix_66h: + emit 1, 66h + jump check_register + + rex_8: + compute rex_prefix, 48h + + check_register: + check reg and 1000b + jyes rex_1 + check reg and x86.REX_REQUIRED + jno rex_ready + compute rex_prefix, rex_prefix or 40h + jump rex_ready + rex_1: + compute rex_prefix, rex_prefix or 41h + + rex_ready: + check rex_prefix + jno rex_prefix_ok + check x86.mode < 64 + jyes instruction_requires_long_mode + check reg and x86.REX_FORBIDDEN + jno store_rex_prefix + err 'disallowed combination of registers' + jump store_rex_prefix + instruction_requires_long_mode: + err 'instruction requires long mode' + store_rex_prefix: + emit 1, rex_prefix + rex_prefix_ok: + +end calminstruction + +calminstruction x86.simm32 immediate* + compute immediate, +immediate + check immediate eqtype 0.0 + jno check_value + asm virtual at 0 + asm emit 8: immediate + asm load immediate:8 from 0 + asm end virtual + compute immediate, +immediate + check_value: + check immediate relativeto 0 + jyes check_range + asm dd immediate + exit + check_range: + check immediate - 1 shl 64 >= -80000000h & immediate < 1 shl 64 + jyes wrap + check immediate >= 80000000h | immediate < -80000000h + jyes out_of_range + emit 4, immediate + exit + wrap: + emit 4, immediate - 1 shl 64 + exit + out_of_range: + err 'immediate value out of signed range' +end calminstruction + + +iterate , add,0, or,8, adc,10h, sbb,18h, and,20h, sub,28h, xor,30h, cmp,38h + + calminstruction instr? dest*,src* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + + local opcode, rm, size + + compute opcode, basecode + + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + main: + + check @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes reg_rm + check @src.type = 'mem' & @dest.type = 'reg' + jyes rm_reg + check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes rm_imm + + err 'invalid combination of operands' + exit + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + reg_rm: + check size > 1 + jno reg_rm_store + call x86.select_operand_prefix@dest, size + compute opcode, opcode + 1 + reg_rm_store: + call x86.store_instruction@dest, opcode,@src.rm + exit + + rm_reg: + compute opcode, opcode + 2 + check size > 1 + jno rm_reg_store + call x86.select_operand_prefix@src, size + compute opcode, opcode + 1 + rm_reg_store: + call x86.store_instruction@src, opcode,@dest.rm + exit + + rm_imm: + check size > 1 + jyes rm_imm_word + check @dest.type = 'reg' & @dest.rm = 0 + jyes al_imm + + compute opcode, opcode shr 3 + xcall x86.store_instruction@dest, (80h),opcode,byte,@src.imm + exit + + al_imm: + emit 1, opcode+4 + emit 1, @src.imm + exit + + rm_imm_word: + + call x86.select_operand_prefix@dest, size + + check @src.imm eqtype 0.0 + jno rm_imm_optimize + + asm virtual at 0 + asm emit size: @src.imm + asm load @src.imm:size from 0 + asm end virtual + compute @src.imm, +@src.imm + + rm_imm_optimize: + check @src.imm relativeto 0 & @src.imm < 80h & @src.imm >= -80h + jyes rm_simm + check @src.imm relativeto 0 & @src.imm - 1 shl (size shl 3) >= -80h & @src.imm < 1 shl (size shl 3) + jyes rm_simm_wrap + check @dest.type = 'reg' & @dest.rm = 0 + jyes ax_imm + + compute rm, opcode shr 3 + xcall x86.store_instruction@dest, (81h),rm,size,@src.imm + exit + + ax_imm: + check @dest.prefix + jno ax_imm_prefix_ok + emit 1, @dest.prefix + ax_imm_prefix_ok: + emit 1, opcode+5 + check size = 4 + jyes imm32 + check size = 8 + jyes simm32 + asm emit size: @src.imm + exit + imm32: + asm dd @src.imm + exit + simm32: + call x86.simm32, @src.imm + exit + + rm_simm_wrap: + compute @src.imm, @src.imm - 1 shl (size shl 3) + + rm_simm: + compute rm, opcode shr 3 + xcall x86.store_instruction@dest, (83h),rm,byte,@src.imm + + end calminstruction + +end iterate + +iterate , not,2, neg,3, mul,4, div,6, idiv,7 + + calminstruction instr? src* + + call x86.parse_operand@src, src + + check @src.size = 0 + jyes operand_size_not_specified + + main: + check @src.type = 'mem' | @src.type = 'reg' + jno invalid_operand + check @src.size > 1 + jyes rm_word + + xcall x86.store_instruction@src, (0F6h),(postbyte) + exit + + rm_word: + call x86.select_operand_prefix@src, @src.size + xcall x86.store_instruction@src, (0F7h),(postbyte) + exit + + operand_size_not_specified: + err 'operand size not specified' + jump main + + invalid_operand: + err 'invalid operand' + exit + + end calminstruction + +end iterate + +calminstruction mov? dest*,src* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + + local ext, rm, size + + check @dest.size = 0 & @src.size = 0 & @dest.type <> 'sreg' + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + main: + + check @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes mov_rm_reg + check @src.type = 'mem' & @dest.type = 'reg' + jyes mov_reg_mem + check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes mov_rm_imm + check @src.type = 'reg' & @dest.type = 'imm' + jyes mov_creg_reg + check @src.type = 'sreg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes mov_rm_sreg + check @dest.type = 'sreg' & @dest.rm <> 1 & ( @src.type = 'reg' | @src.type = 'mem' ) + jyes mov_sreg_rm + + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + mov_rm_reg: + check @src.type = 'reg' & @dest.type = 'mem' & @src.rm = 0 & @dest.address_registers eq 0 & \ + ~ @dest.auto_relative & ( @dest.displacement_size <> 8 | ~ @dest.displacement relativeto 0 | @dest.displacement and 0FFFFFFFF80000000h <> 0FFFFFFFF80000000h) + jyes mov_dirmem_ax + check size > 1 + jno mov_reg_rm_8bit + call x86.select_operand_prefix@dest, size + xcall x86.store_instruction@dest, (89h),@src.rm + exit + mov_reg_rm_8bit: + xcall x86.store_instruction@dest, (88h),@src.rm + exit + + mov_reg_mem: + check @src.type = 'mem' & @dest.type = 'reg' & @dest.rm = 0 & @src.address_registers eq 0 & \ + ~ @src.auto_relative & ( @src.displacement_size <> 8 | ~ @src.displacement relativeto 0 | @src.displacement and 0FFFFFFFF80000000h <> 0FFFFFFFF80000000h) + jyes mov_ax_dirmem + check size > 1 + jno mov_mem_reg_8bit + call x86.select_operand_prefix@src, size + xcall x86.store_instruction@src, (8Bh),@dest.rm + exit + mov_mem_reg_8bit: + xcall x86.store_instruction@src, (8Ah),@dest.rm + exit + + mov_dirmem_ax: + check x86.mode = 64 + jyes mov_dirmem_ax_longmode + check @dest.segment_prefix = 0 | @dest.segment_prefix = 3Eh + jyes dest_seg_ok + emit 1, @dest.segment_prefix + dest_seg_ok: + check @dest.mode = x86.mode + jyes dest_addr_size_ok + emit 1, 67h + dest_addr_size_ok: + check size > 1 + jno mov_dirmem_al + call x86.store_operand_prefix, size + emit 1, 0A3h + jump dest_displacement + mov_dirmem_al: + emit 1, 0A2h + dest_displacement: + check @dest.mode = 16 + jyes dest_displacement_16bit + check @dest.displacement_size = 8 + jyes dest_displacement_64bit + asm dd @dest.address + exit + dest_displacement_16bit: + asm dw @dest.address + exit + dest_displacement_64bit: + asm dq @dest.address + exit + mov_dirmem_ax_longmode: + check @dest.displacement_size = 8 & @dest.displacement relativeto 0 & @dest.displacement >= 0 & @dest.displacement < 100000000h + jno dest_displacement_size_ok + compute @dest.displacement_size, 4 + dest_displacement_size_ok: + check @dest.segment_prefix & @dest.segment_prefix >= 64h + jno dest_longmode_seg_ok + emit 1, @dest.segment_prefix + dest_longmode_seg_ok: + check @dest.mode = 16 + jyes illegal_addressing_mode + check @dest.displacement_size = 8 + jyes dest_addr_size_ok + emit 1, 67h + jump dest_addr_size_ok + + mov_ax_dirmem: + check x86.mode = 64 + jyes mov_ax_dirmem_longmode + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh + jyes src_seg_ok + emit 1, @src.segment_prefix + src_seg_ok: + check @src.mode = x86.mode + jyes src_addr_size_ok + emit 1, 67h + src_addr_size_ok: + check size > 1 + jno mov_al_dirmem + call x86.store_operand_prefix, size + emit 1, 0A1h + jump src_displacement + mov_al_dirmem: + emit 1, 0A0h + src_displacement: + check @src.mode = 16 + jyes src_displacement_16bit + check @src.displacement_size = 8 + jyes src_displacement_64bit + asm dd @src.address + exit + src_displacement_16bit: + asm dw @src.address + exit + src_displacement_64bit: + asm dq @src.address + exit + mov_ax_dirmem_longmode: + check @src.displacement_size = 8 & @src.displacement relativeto 0 & @src.displacement >= 0 & @src.displacement < 100000000h + jno src_displacement_size_ok + compute @src.displacement_size, 4 + src_displacement_size_ok: + check @src.segment_prefix & @src.segment_prefix >= 64h + jno src_longmode_seg_ok + emit 1, @src.segment_prefix + src_longmode_seg_ok: + check @src.mode = 16 + jyes illegal_addressing_mode + check @src.displacement_size = 8 + jyes src_addr_size_ok + emit 1, 67h + jump src_addr_size_ok + + mov_rm_imm: + check @dest.type = 'mem' + jyes mov_mem_imm + check @dest.type = 'reg' & 1 metadataof (1 metadataof @src.imm) relativeto x86.creg & @src.imm relativeto 1 elementof @src.imm + jyes mov_reg_creg + + mov_reg_imm: + check size > 1 + jno mov_reg_imm_8bit + check @src.imm eqtype 0.0 + jno mov_reg_imm_optimize + asm virtual at 0 + asm emit size: @src.imm + asm load @src.imm:size from 0 + asm end virtual + compute @src.imm, +@src.imm + mov_reg_imm_optimize: + check size = 8 & @src.imm relativeto 0 & @src.imm < 80000000h & @src.imm >= -80000000h + jyes mov_reg_simm + check size = 8 & @src.imm relativeto 0 & @src.imm - 1 shl 64 < 80000000h & @src.imm - 1 shl 64 >= -80000000h + jyes mov_reg_simm_wrap + call x86.store_operand_prefix, size,@dest.rm + emit 1, 0B8h + @dest.rm and 111b + check size = 2 + jyes src_imm_16bit + check size = 4 + jyes src_imm_32bit + asm dq @src.imm + exit + src_imm_32bit: + asm dd @src.imm + exit + src_imm_16bit: + asm dw @src.imm + exit + mov_reg_imm_8bit: + xcall x86.store_operand_prefix, (0),@dest.rm + emit 1, 0B0h + @dest.rm and 111b + emit 1, @src.imm + exit + mov_reg_simm_wrap: + compute @src.imm, @src.imm - 1 shl 64 + mov_reg_simm: + call x86.select_operand_prefix@dest, size + xcall x86.store_instruction@dest, (0C7h),(0),size,@src.imm + exit + + mov_mem_imm: + check size > 1 + jno mov_mem_imm_8bit + call x86.select_operand_prefix@dest, size + xcall x86.store_instruction@dest, (0C7h),(0),size,@src.imm + exit + mov_mem_imm_8bit: + xcall x86.store_instruction@dest, (0C6h),(0),byte,@src.imm + exit + + mov_reg_creg: + check (x86.mode <> 64 & @dest.size = 4) | (x86.mode = 64 & @dest.size = 8) + jno invalid_operand_size + compute ext, 20h + 1 metadataof (1 metadataof @src.imm) - x86.creg + compute rm, 1 metadataof @src.imm - 1 elementof (1 metadataof @src.imm) + xcall x86.store_instruction@dest, <0Fh,ext>,rm + exit + + mov_creg_reg: + check 1 metadataof (1 metadataof @dest.imm) relativeto x86.creg & @dest.imm relativeto 1 elementof @dest.imm + jno invalid_combination_of_operands + check (x86.mode <> 64 & @src.size = 4) | (x86.mode = 64 & @src.size = 8) + jno invalid_operand_size + compute ext, 22h + 1 metadataof (1 metadataof @dest.imm) - x86.creg + compute rm, 1 metadataof @dest.imm - 1 elementof (1 metadataof @dest.imm) + xcall x86.store_instruction@src, <0Fh,ext>,rm + exit + + mov_rm_sreg: + check @dest.type = 'mem' + jyes mov_mem_sreg + mov_reg_sreg: + check size > 1 + jno invalid_operand_size + call x86.select_operand_prefix@dest, size + jump mov_rm_sreg_store + mov_mem_sreg: + check size and not 2 + jyes invalid_operand_size + mov_rm_sreg_store: + xcall x86.store_instruction@dest, (8Ch),@src.rm + exit + + mov_sreg_rm: + check size = 1 + jyes invalid_operand_size + xcall x86.store_instruction@src, (8Eh),@dest.rm + exit + + invalid_operand_size: + err 'invalid operand size' + exit + + illegal_addressing_mode: + err 'illegal addressing mode' + exit + +end calminstruction + +calminstruction test? dest*,src* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + + local ext, rm, size + + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + main: + + check @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes test_reg_rm + check @src.type = 'mem' & @dest.type = 'reg' + jyes test_mem_reg + check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes test_rm_imm + + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + test_reg_rm: + check size > 1 + jno test_reg_rm_8bit + call x86.select_operand_prefix@dest, size + xcall x86.store_instruction@dest, (85h),@src.rm + exit + test_reg_rm_8bit: + xcall x86.store_instruction@dest, (84h),@src.rm + exit + + test_mem_reg: + check size > 1 + jno test_mem_reg_8bit + call x86.select_operand_prefix@src, size + xcall x86.store_instruction@src, (85h),@dest.rm + exit + test_mem_reg_8bit: + xcall x86.store_instruction@src, (84h),@dest.rm + exit + + test_rm_imm: + check size > 1 + jno test_rm_imm_8bit + check @dest.type = 'reg' & @dest.rm = 0 + jyes test_ax_imm + call x86.select_operand_prefix@dest, size + xcall x86.store_instruction@dest, (0F7h),(0),size,@src.imm + exit + + test_ax_imm: + call x86.store_operand_prefix, size + emit 1, 0A9h + check size = 2 + jyes src_imm_16bit + check size = 4 + jyes src_imm_32bit + call x86.simm32, @src.imm + exit + src_imm_16bit: + asm dw @src.imm + exit + src_imm_32bit: + asm dd @src.imm + exit + + test_rm_imm_8bit: + check @dest.type = 'reg' & @dest.rm = 0 + jyes test_al_imm + xcall x86.store_instruction@dest, (0F6h),(0),byte,@src.imm + exit + test_al_imm: + emit 1, 0A8h + emit 1, @src.imm + exit + +end calminstruction + +calminstruction xchg? dest*,src* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + + local ext, rm, size + + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + main: + + check @src.type = 'reg' & @dest.type = 'reg' + jyes xchg_reg_reg + check @src.type = 'reg' & @dest.type = 'mem' + jyes xchg_reg_rm + check @src.type = 'mem' & @dest.type = 'reg' + jyes xchg_rm_reg + + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + xchg_reg_reg: + check (@src.rm & @dest.rm) | (size = 4 & @src.rm or @dest.rm = 0) + jyes xchg_rm_reg + check size > 1 + jno xchg_rm_reg_8bit + compute @src.rm, @src.rm or @dest.rm + call x86.store_operand_prefix, size,@src.rm + emit 1, 90h + @src.rm and 111b + exit + + xchg_reg_rm: + check size > 1 + jno xchg_reg_rm_8bit + call x86.select_operand_prefix@dest, size + xcall x86.store_instruction@dest, (87h),@src.rm + exit + xchg_reg_rm_8bit: + xcall x86.store_instruction@dest, (86h),@src.rm + exit + + xchg_rm_reg: + check size > 1 + jno xchg_rm_reg_8bit + call x86.select_operand_prefix@src, size + xcall x86.store_instruction@src, (87h),@dest.rm + exit + xchg_rm_reg_8bit: + xcall x86.store_instruction@src, (86h),@dest.rm + exit + +end calminstruction + +iterate , inc,0 ,dec,1 + + calminstruction instr? dest* + + call x86.parse_operand@dest, dest + + check @dest.size + jyes main + + err 'operand size not specified' + + main: + check @dest.type = 'mem' | (x86.mode = 64 & @dest.type = 'reg') + jyes inc_rm + check @dest.type = 'reg' + jyes inc_reg + + err 'invalid operand' + exit + + inc_reg: + check @dest.size > 1 + jno inc_rm_8bit + call x86.store_operand_prefix, @dest.size + emit 1, 40h + @dest.rm + postbyte shl 3 + exit + + inc_rm: + check @dest.size > 1 + jno inc_rm_8bit + xcall x86.select_operand_prefix@dest, @dest.size + xcall x86.store_instruction@dest, (0FFh),(postbyte) + exit + inc_rm_8bit: + xcall x86.store_instruction@dest, (0FEh),(postbyte) + + end calminstruction + +end iterate + +calminstruction imul? dest*,src& + + local size + + call x86.parse_operand@dest, dest + + match , src + jyes imul_rm + + local src1, src2 + + match src1 =, src2, src + jyes imul_second_source + + call x86.parse_operand@src, src + + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + + compute size, @dest.size or @src.size + + check @dest.type = 'reg' & (@src.type = 'reg' | @src.type = 'mem') + jyes imul_reg_rm + + check @src.type = 'imm' & @dest.type = 'reg' + jno invalid_combination_of_operands + + compute @aux.type, @src.type + compute @aux.imm, @src.imm + compute @src.type, @dest.type + compute @src.mod, @dest.mod + compute @src.rm, @dest.rm + + jump main + + imul_second_source: + call x86.parse_operand@src, src1 + call x86.parse_operand@aux, src2 + + check @dest.size = 0 & @src.size = 0 & @aux.size = 0 + jyes operand_size_not_specified + + compute size, @dest.size or @src.size or @aux.size + + check (@dest.size & @dest.size <> size) | (@src.size & @src.size <> size) | (@aux.size & @aux.size <> size) + jyes operand_sizes_do_not_match + + jump main + + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump main + + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump main + + main: + check @aux.type = 'imm' & ( @src.type = 'mem' | @src.type = 'reg' ) & @dest.type = 'reg' + jyes imul_reg_rm_imm + + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + + imul_rm: + check @dest.size + jyes imul_rm_size_ok + err 'operand size not specified' + imul_rm_size_ok: + check @dest.type = 'mem' | @dest.type = 'reg' + jno invalid_combination_of_operands + check @dest.size > 1 + jno imul_rm_8bit + xcall x86.select_operand_prefix@dest, @dest.size + xcall x86.store_instruction@dest, (0F7h),(5) + exit + imul_rm_8bit: + xcall x86.store_instruction@dest, (0F6h),(5) + exit + + imul_reg_rm: + call x86.select_operand_prefix@src, size + xcall x86.store_instruction@src, <0Fh,0AFh>,@dest.rm + exit + + imul_reg_rm_imm: + call x86.select_operand_prefix@src, size + check @aux.imm eqtype 0.0 + jno imul_reg_rm_imm_optimize + asm virtual at 0 + asm emit size: @aux.imm + asm load @aux.imm:size from 0 + asm end virtual + compute @aux.imm, +@aux.imm + imul_reg_rm_imm_optimize: + check @aux.imm relativeto 0 & @aux.imm < 80h & @aux.imm >= -80h + jyes imul_reg_rm_simm + check @aux.imm relativeto 0 & @aux.imm - 1 shl (size shl 3) >= -80h & @aux.imm < 1 shl (size shl 3) + jyes imul_reg_rm_simm_wrap + xcall x86.store_instruction@src, (69h),@dest.rm,size,@aux.imm + exit + imul_reg_rm_simm_wrap: + compute @aux.imm, @aux.imm - 1 shl (size shl 3) + imul_reg_rm_simm: + xcall x86.store_instruction@src, (6Bh),@dest.rm,byte,@aux.imm + exit + +end calminstruction + +calminstruction x86.push_instruction size:0,src* + + call x86.parse_operand@src, src + + check size <> 0 & @src.size and not size + jyes invalid_operand_size + compute size, size or @src.size + check size = 0 | size = 2 | (size = 4 & x86.mode < 64) | (size = 8 & x86.mode = 64) + jyes main + + invalid_operand_size: + err 'invalid operand size' + + main: + check (x86.mode <> 16 & size = 2) | (x86.mode = 16 & size = 4) + jno prefix_ready + compute @src.prefix, 66h + prefix_ready: + + check @src.type = 'mem' + jyes push_mem + + check @src.prefix + jno prefix_stored + emit 1, @src.prefix + prefix_stored: + + check @src.type = 'reg' + jyes push_reg + check @src.type = 'sreg' + jyes push_sreg + check @src.type = 'imm' + jyes push_imm + + invalid_operand: + err 'invalid operand' + exit + + push_mem: + xcall x86.store_instruction@src, (0FFh),(110b) + exit + + push_reg: + check @src.rm and 1000b + jyes push_new_reg + emit 1, 50h + @src.rm + exit + push_new_reg: + emit 1, 41h + emit 1, 50h + @src.rm and 111b + exit + + push_sreg: + check @src.rm >= 4 + jyes push_sreg_386 + check x86.mode = 64 + jyes invalid_operand + emit 1, 6 + @src.rm shl 3 + exit + push_sreg_386: + emit 1, 0Fh + emit 1, 0A0h + (@src.rm-4) shl 3 + exit + + push_imm: + check size + jyes push_imm_size_ok + check x86.mode = 16 + jyes push_imm_16bit + check x86.mode = 32 + jyes push_imm_32bit + compute size, 8 + jump push_imm_size_ok + push_imm_32bit: + compute size, 4 + jump push_imm_size_ok + push_imm_16bit: + compute size, 2 + push_imm_size_ok: + + check @src.imm eqtype 0.0 + jno push_imm_check + asm virtual at 0 + asm emit size: @src.imm + asm load @src.imm:size from 0 + asm end virtual + compute @src.imm, +@src.imm + push_imm_check: + check size = 8 & @src.imm relativeto 0 + jno push_imm_optimize + check @src.imm - 10000000000000000h >= -80000000h & @src.imm < 10000000000000000h + jyes push_imm_wrap + check @src.imm >= 80000000h | @src.imm < -80000000h + jyes out_of_signed_range + jump push_imm_optimize + push_imm_wrap: + compute @src.imm, @src.imm - 10000000000000000h + push_imm_optimize: + check @src.imm relativeto 0 & @src.imm < 80h & @src.imm >= -80h + jyes push_simm + check size = 2 & @src.imm relativeto 0 & @src.imm - 10000h >= -80h & @src.imm < 10000h + jyes push_simm_wrap + check size = 4 & @src.imm relativeto 0 & @src.imm - 100000000h >= -80h & @src.imm < 100000000h + jyes push_simm_wrap + emit 1, 68h + check size = 2 + jyes src_imm_16bit + asm dd @src.imm + exit + src_imm_16bit: + asm dw @src.imm + exit + push_simm_wrap: + compute @src.imm, @src.imm - 1 shl (size shl 3) + push_simm: + emit 1, 6Ah + emit 1, @src.imm + exit + + out_of_signed_range: + err 'immediate value out of signed range' + exit + +end calminstruction + +calminstruction x86.pop_instruction size:0,dest* + + call x86.parse_operand@dest, dest + + check size <> 0 & @dest.size and not size + jyes invalid_operand_size + compute size, size or @dest.size + check size = 0 | size = 2 | (size = 4 & x86.mode < 64) | (size = 8 & x86.mode = 64) + jyes main + + invalid_operand_size: + err 'invalid operand size' + + main: + check (x86.mode <> 16 & size = 2) | (x86.mode = 16 & size = 4) + jno prefix_ready + compute @dest.prefix, 66h + prefix_ready: + + check @dest.type = 'mem' + jyes pop_mem + + check @dest.prefix + jno prefix_stored + emit 1, @dest.prefix + prefix_stored: + + check @dest.type = 'reg' + jyes pop_reg + check @dest.type = 'sreg' + jyes pop_sreg + + invalid_operand: + err 'invalid operand' + exit + + pop_mem: + xcall x86.store_instruction@dest, (8Fh),(0) + exit + + pop_reg: + check @dest.rm and 1000b + jyes pop_new_reg + emit 1, 58h + @dest.rm + exit + pop_new_reg: + emit 1, 41h + emit 1, 58h + @dest.rm and 111b + exit + + pop_sreg: + check @dest.rm = 1 + jyes invalid_operand + check @dest.rm >= 4 + jyes pop_sreg_386 + check x86.mode = 64 + jyes invalid_operand + emit 1, 7 + @dest.rm shl 3 + exit + pop_sreg_386: + emit 1, 0Fh + emit 1, 0A1h + (@dest.rm-4) shl 3 + exit + +end calminstruction + +iterate reg, ax,cx,dx,bx,sp,bp,si,di,r8w,r9w,r10w,r11w,r12w,r13w,r14w,r15w, \ + eax,ecx,edx,ebx,esp,ebp,esi,edi,r8d,r9d,r10d,r11d,r12d,r13d,r14d,r15d, \ + rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15, \ + es,cs,ss,ds,fs,gs + define x86.compact.reg? {reg} +end iterate + +iterate , push,push_instruction,0, pushw,push_instruction,2, pushd,push_instruction,4, pushq,push_instruction,8, \ + pop,pop_instruction,0, popw,pop_instruction,2, popd,pop_instruction,4, popq,pop_instruction,8 + + calminstruction instr? operand + + local head, tail + + match head tail, operand + jno plain + transform head, x86.compact + jno plain + match {head}, head + jno plain + loop: + xcall x86.handler, (size),head + match head tail, tail + jno final + transform head, x86.compact + jno error + match {head}, head + jyes loop + error: + err 'only register operands allowed in compact syntax' + exit + final: + transform tail, x86.compact + jno error + match {operand}, tail + jno error + plain: + xcall x86.handler, (size),operand + + end calminstruction + +end iterate + +iterate , ret,0C2h, retn,0C2h, retf,0CAh + + calminstruction instr? operand + match , operand + jyes ret_short + check operand + jno ret_short + emit 1, opcode + asm dw operand + exit + ret_short: + emit 1, opcode + 1 + end calminstruction + +end iterate + +iterate , retw,2,0C2h, retnw,2,0C2h, retd,4,0C2h, retnd,4,0C2h, retfw,2,0CAh, retfd,4,0CAh + + calminstruction instr? operand + check x86.mode < 64 + jyes illegal_instruction + xcall x86.store_operand_prefix, (size) + match , operand + jyes ret_short + emit 1, opcode + asm dw operand + exit + ret_short: + emit 1, opcode + 1 + exit + illegal_instruction: + err 'illegal instruction' + end calminstruction + +end iterate + +iterate , retq,0C2h, retnq,0C2h, retfq,0CAh + + calminstruction instr? operand + check x86.mode = 64 + jno instruction_requires_long_mode + match , operand + jyes ret_short + emit 1, opcode + asm dw operand + exit + ret_short: + emit 1, opcode + 1 + exit + instruction_requires_long_mode: + err 'instruction requires long mode' + end calminstruction + +end iterate + +calminstruction lea? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.type = 'mem' & @dest.type = 'reg' + jno invalid_combination_of_operands + xcall x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, (8Dh),@dest.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' +end calminstruction + +iterate , les,0C4h, lds,0C5h + + calminstruction instr? dest*,src* + check x86.mode = 64 + jyes illegal_instruction + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check (@dest.size = 2 & (@src.size <> 0 & @src.size <> 4)) | (@dest.size = 4 & (@src.size <> 0 & @src.size <> 6)) + jyes invalid_operand_size + check @src.type = 'mem' & @dest.type = 'reg' + jno invalid_combination_of_operands + xcall x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, (opcode),@dest.rm + exit + illegal_instruction: + err 'illegal instruction' + exit + invalid_operand_size: + err 'invalid operand size' + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + end calminstruction + +end iterate + +iterate , lss,<0Fh,0B2h>, lfs,<0Fh,0B4h>, lgs,<0Fh,0B5h> + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check (@dest.size = 2 & (@src.size <> 0 & @src.size <> 4)) | (@dest.size = 4 & (@src.size <> 0 & @src.size <> 6)) | (@dest.size = 8 & (@src.size <> 0 & @src.size <> 10)) + jyes invalid_operand_size + check @src.type = 'mem' & @dest.type = 'reg' + jno invalid_combination_of_operands + xcall x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, ,@dest.rm + exit + invalid_operand_size: + err 'invalid operand size' + invalid_combination_of_operands: + err 'invalid combination of operands' + end calminstruction + +end iterate + +iterate , rol,0, ror,1, rcl,2, rcr,3, shl,4, sal, 4, shr,5, sar,7 + + calminstruction instr? dest*,cnt* + + call x86.parse_operand@dest, dest + call x86.parse_operand@src, cnt + + check @dest.size = 0 + jyes operand_size_not_specified + check @src.size and not 1 + jyes invalid_operand_size + + main: + check @src.type = 'reg' & @src.size = 1 & @src.rm = 1 & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes shift_rm_cl + check @src.type = 'imm' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes shift_rm_imm + + err 'invalid combination of operands' + exit + + shift_rm_cl: + check @dest.size > 1 + jno shift_r8_cl + xcall x86.select_operand_prefix@dest, @dest.size + xcall x86.store_instruction@dest, (0D3h),(postbyte) + exit + shift_r8_cl: + xcall x86.store_instruction@dest, (0D2h),(postbyte) + exit + shift_rm_imm: + check @dest.size > 1 + jno shift_rm8_imm + xcall x86.select_operand_prefix@dest, @dest.size + check @src.imm = 1 + jyes shift_rm_1 + xcall x86.store_instruction@dest, (0C1h),(postbyte),byte,@src.imm + exit + shift_rm_1: + xcall x86.store_instruction@dest, (0D1h),(postbyte) + exit + shift_rm8_imm: + check @src.imm = 1 + jyes shift_rm8_1 + xcall x86.store_instruction@dest, (0C0h),(postbyte),byte,@src.imm + exit + shift_rm8_1: + xcall x86.store_instruction@dest, (0D0h),(postbyte) + exit + + operand_size_not_specified: + err 'operand size not specified' + jump main + invalid_operand_size: + err 'invalid operand size' + jump main + + end calminstruction + +end iterate + +iterate , shld,0A4h, shrd,0ACh + + calminstruction instr? dest*,src*,cnt* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + call x86.parse_operand@aux, cnt + check @aux.size and not 1 + jyes invalid_operand_size + check @dest.size and not @src.size + jno main + err 'operand sizes do not match' + main: + check @aux.type = 'reg' & @aux.size = 1 & @aux.rm = 1 & @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes shld_cl + check @aux.type = 'imm' & @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes shld_imm + err 'invalid combination of operands' + exit + shld_cl: + xcall x86.select_operand_prefix@dest, @src.size + xcall x86.store_instruction@dest, <0Fh,ext+1>,@src.rm + exit + shld_imm: + xcall x86.select_operand_prefix@dest, @src.size + xcall x86.store_instruction@dest, <0Fh,ext>,@src.rm,byte,@aux.imm + exit + invalid_operand_size: + err 'invalid operand size' + end calminstruction + +end iterate + +iterate , bt,4, bts,5, btr,6, btc,7 + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.type = 'reg' & (@dest.type = 'mem' | @dest.type = 'reg') + jyes bt_rm_reg + check @src.type = 'imm' & (@dest.type = 'mem' | @dest.type = 'reg') + jyes bt_rm_imm + err 'invalid combination of operands' + exit + bt_rm_reg: + local opcode + check @dest.size and not @src.size + jno bt_rm_reg_ok + err 'operand sizes do not match' + bt_rm_reg_ok: + compute opcode, 0A3h+(postbyte-4) shl 3 + xcall x86.select_operand_prefix@dest, @src.size + xcall x86.store_instruction@dest, <0Fh,opcode>,@src.rm + exit + bt_rm_imm: + check @src.size and not 1 + jno bt_rm_imm_ok + err 'invalid operand size' + bt_rm_imm_ok: + check @dest.size + jno operand_size_not_specified + xcall x86.select_operand_prefix@dest, @dest.size + xcall x86.store_instruction@dest, <0Fh,0BAh>,(postbyte),byte,@src.imm + exit + operand_size_not_specified: + err 'operand size not specified' + end calminstruction + +end iterate + +iterate , bsf,0BCh, bsr,0BDh + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') + jyes bsf_rm_reg + err 'invalid combination of operands' + exit + bsf_rm_reg: + check @src.size and not @dest.size + jno bsf_rm_reg_ok + err 'operand sizes do not match' + bsf_rm_reg_ok: + xcall x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm + end calminstruction + +end iterate + +iterate , movzx,0B6h, movsx,0BEh + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.size > @src.size + jyes size_ok + err 'operand sizes do not match' + size_ok: + check @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') + jyes operands_ok + err 'invalid combination of operands' + exit + operands_ok: + check @src.size = 2 + jyes movzx_word + check @src.size = 1 | (@src.size = 0 & @dest.size = 2) + jyes movzx_byte + check @src.size + jyes invalid_operand_size + err 'operand size not specified' + movzx_word: + xcall x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, <0Fh,ext+1>,@dest.rm + exit + movzx_byte: + xcall x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm + exit + invalid_operand_size: + err 'invalid operand size' + end calminstruction + +end iterate + +calminstruction movsxd? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.size > @src.size + jyes size_ok + err 'operand sizes do not match' + size_ok: + check @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') + jyes operands_ok + err 'invalid combination of operands' + exit + operands_ok: + check @src.size and not 4 + jyes invalid_operand_size + xcall x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, (63h),@dest.rm + exit + invalid_operand_size: + err 'invalid operand size' +end calminstruction + +iterate , o,0, no,1, c,2, b,2, nae,2, nc,3, nb,3, ae,3, z,4, e,4, nz,5, ne,5, na,6, be,6, a,7, nbe,7, \ + s,8, ns,9, p,0Ah, pe,0Ah, np,0Bh, po,0Bh, l,0Ch, nge,0Ch, nl,0Dh, ge,0Dh, ng,0Eh, le,0Eh, g,0Fh, nle,0Fh + + calminstruction set#cond? dest* + call x86.parse_operand@dest, dest + check @dest.size > 1 + jno size_ok + err 'invalid operand size' + size_ok: + check @dest.type = 'reg' | @dest.type = 'mem' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + xcall x86.store_instruction@dest, <0Fh,90h+code>,(0) + end calminstruction + + calminstruction cmov#cond? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') + jyes cmov_rm_reg + err 'invalid combination of operands' + exit + cmov_rm_reg: + check @src.size and not @dest.size + jno cmov_rm_reg_ok + err 'operand sizes do not match' + cmov_rm_reg_ok: + xcall x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, <0Fh,40h+code>,@dest.rm + end calminstruction + +end iterate + +calminstruction call? dest* + + call x86.parse_jump_operand@dest, dest + + check @dest.type = 'imm' + jyes call_imm + check @dest.type = 'mem' | @dest.type = 'reg' + jyes call_rm + check @dest.type = 'far' + jyes call_direct_far + + invalid_operand: + err 'invalid operand' + exit + illegal_instruction: + err 'illegal instruction' + exit + + call_direct_far: + check @dest.jump_type & @dest.jump_type <> 'far' + jyes invalid_operand + check x86.mode = 64 + jyes illegal_instruction + check @dest.size = 0 + jyes prefix_ok + local size + compute size, @dest.size - 2 + call x86.store_operand_prefix, size + prefix_ok: + check @dest.size and not 4 & @dest.size and not 6 + jyes invalid_operand + emit 1, 9Ah + check (@dest.size = 0 & x86.mode = 16) | @dest.size = 4 + jyes far_dword + asm dd @dest.offset + asm dw @dest.segment + exit + far_dword: + asm dw @dest.offset,@dest.segment + exit + + call_rm: + check @dest.size = 6 | @dest.size = 10 + jyes call_rm_pword + check @dest.size = 8 & x86.mode = 64 + jyes call_rm_qword + check @dest.size = 4 & x86.mode < 64 + jyes call_rm_dword + check @dest.size = 2 & x86.mode < 64 + jyes call_rm_word + check @dest.size + jyes invalid_operand + check x86.mode = 64 + jno rex_prefix_ok + compute @dest.prefix, 48h + rex_prefix_ok: + check @dest.jump_type = 'far' + jyes call_rm_far + check @dest.jump_type = 'near' + jyes call_rm_near + err 'operand size not specified' + exit + + call_rm_pword: + check @dest.jump_type & @dest.jump_type <> 'far' + jyes invalid_operand + local size + compute size, @dest.size - 2 + call x86.select_operand_prefix@dest, size + call_rm_far: + xcall x86.store_instruction@dest, (0FFh),(11b) + exit + + call_rm_qword: + check @dest.jump_type & @dest.jump_type <> 'near' + jyes invalid_operand + jump call_rm_near + + call_rm_dword: + check @dest.jump_type | @dest.type = 'reg' + jno call_rm_dword_auto + check @dest.jump_type = 'far' + jyes call_rm_dword_far + call_rm_dword_near: + xcall x86.select_operand_prefix@dest, (4) + jump call_rm_near + call_rm_dword_auto: + check x86.mode = 16 + jno call_rm_dword_near + call_rm_dword_far: + xcall x86.select_operand_prefix@dest, (2) + jump call_rm_far + + call_rm_word: + check @dest.jump_type & @dest.jump_type <> 'near' + jyes invalid_operand + xcall x86.select_operand_prefix@dest, (2) + call_rm_near: + xcall x86.store_instruction@dest, (0FFh),(10b) + exit + + call_imm: + check @dest.jump_type & @dest.jump_type <> 'near' + jyes invalid_operand + check @dest.size = 8 & x86.mode = 64 + jyes call_imm_qword + check @dest.size = 2 & x86.mode < 64 + jyes call_imm_word + check @dest.size = 4 & x86.mode < 64 + jno invalid_operand + xcall x86.store_operand_prefix, (4) + emit 1, 0E8h + compute @dest.imm, @dest.imm-($+4) + asm dd @dest.imm + exit + call_imm_word: + xcall x86.store_operand_prefix, (2) + emit 1, 0E8h + compute @dest.imm, @dest.imm-($+2) + check @dest.imm relativeto 0 + jno store_word + compute @dest.imm, @dest.imm and 0FFFFh + store_word: + asm dw @dest.imm + exit + call_imm_qword: + emit 1, 0E8h + compute @dest.imm, @dest.imm-($+4) + check @dest.imm relativeto 0 & (@dest.imm < -80000000h | @dest.imm >= 80000000h) + jno store_dword + err 'relative jump out of range' + store_dword: + asm dd @dest.imm + exit + +end calminstruction + +calminstruction jmp? dest* + + call x86.parse_jump_operand@dest, dest + + check @dest.type = 'imm' + jyes jmp_imm + check @dest.type = 'mem' | @dest.type = 'reg' + jyes jmp_rm + check @dest.type = 'far' + jyes jmp_direct_far + + invalid_operand: + err 'invalid operand' + exit + illegal_instruction: + err 'illegal instruction' + exit + + jmp_direct_far: + check @dest.jump_type & @dest.jump_type <> 'far' + jyes invalid_operand + check x86.mode = 64 + jyes illegal_instruction + check @dest.size = 0 + jyes prefix_ok + local size + compute size, @dest.size - 2 + call x86.store_operand_prefix, size + prefix_ok: + check @dest.size and not 4 & @dest.size and not 6 + jyes invalid_operand + emit 1, 0EAh + check (@dest.size = 0 & x86.mode = 16) | @dest.size = 4 + jyes far_dword + asm dd @dest.offset + asm dw @dest.segment + exit + far_dword: + asm dw @dest.offset,@dest.segment + exit + + jmp_rm: + check @dest.size = 6 | @dest.size = 10 + jyes jmp_rm_pword + check @dest.size = 8 & x86.mode = 64 + jyes jmp_rm_qword + check @dest.size = 4 & x86.mode < 64 + jyes jmp_rm_dword + check @dest.size = 2 & x86.mode < 64 + jyes jmp_rm_word + check @dest.size + jyes invalid_operand + check x86.mode = 64 + jno rex_prefix_ok + compute @dest.prefix, 48h + rex_prefix_ok: + check @dest.jump_type = 'far' + jyes jmp_rm_far + check @dest.jump_type = 'near' + jyes jmp_rm_near + err 'operand size not specified' + exit + + jmp_rm_pword: + check @dest.jump_type & @dest.jump_type <> 'far' + jyes invalid_operand + local size + compute size, @dest.size - 2 + call x86.select_operand_prefix@dest, size + jmp_rm_far: + xcall x86.store_instruction@dest, (0FFh),(101b) + exit + + jmp_rm_qword: + check @dest.jump_type & @dest.jump_type <> 'near' + jyes invalid_operand + jump jmp_rm_near + + jmp_rm_dword: + check @dest.jump_type | @dest.type = 'reg' + jno jmp_rm_dword_auto + check @dest.jump_type = 'far' + jyes jmp_rm_dword_far + jmp_rm_dword_near: + xcall x86.select_operand_prefix@dest, (4) + jump jmp_rm_near + jmp_rm_dword_auto: + check x86.mode = 16 + jno jmp_rm_dword_near + jmp_rm_dword_far: + xcall x86.select_operand_prefix@dest, (2) + jump jmp_rm_far + + jmp_rm_word: + check @dest.jump_type & @dest.jump_type <> 'near' + jyes invalid_operand + xcall x86.select_operand_prefix@dest, (2) + jmp_rm_near: + xcall x86.store_instruction@dest, (0FFh),(100b) + exit + + jmp_imm: + check @dest.jump_type = 'far' + jyes invalid_operand + check (@dest.size = 8 & x86.mode < 64) | (@dest.size < 8 & x86.mode = 64) + jyes invalid_operand + check @dest.size = 8 + jyes jmp_imm_prefix_ok + call x86.store_operand_prefix, @dest.size + jmp_imm_prefix_ok: + check @dest.jump_type = 'short' + jyes jmp_imm_short_verify + check @dest.jump_type = 'near' + jyes jmp_imm_near + check ~ $ relativeto 0 & @dest.imm relativeto 0 + jno jmp_optimize + compute @dest.imm, @dest.imm + $ - 0 scaleof $ + err 'invalid address' + jmp_optimize: + check @dest.unresolved + jyes jmp_imm_short + check @dest.imm relativeto $ + jno jmp_imm_near + check (@dest.imm-($+2)) < 80h & (@dest.imm-($+2)) >= -80h + jyes jmp_imm_short + check (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) < 80h | (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) >= 1 shl (@dest.size*8) - 80h + jyes jmp_imm_short + jmp_imm_near: + check @dest.size = 8 + jyes jmp_imm_qword + check @dest.size = 2 + jyes jmp_imm_word + check @dest.size = 4 + jno invalid_operand + emit 1, 0E9h + compute @dest.imm, @dest.imm-($+4) + asm dd @dest.imm + exit + jmp_imm_word: + emit 1, 0E9h + compute @dest.imm, @dest.imm-($+2) + check @dest.imm relativeto 0 + jno store_word + compute @dest.imm, @dest.imm and 0FFFFh + store_word: + asm dw @dest.imm + exit + jmp_imm_qword: + emit 1, 0E9h + compute @dest.imm, @dest.imm-($+4) + asm dd @dest.imm + check @dest.imm relativeto 0 & (@dest.imm < -80000000h | @dest.imm >= 80000000h) + jyes relative_jump_out_of_range + exit + jmp_imm_short_verify: + check (@dest.imm-($+2)) < 80h & (@dest.imm-($+2)) >= -80h + jyes jmp_imm_short + check (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) < 80h | (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) >= 1 shl (@dest.size*8) - 80h + jyes jmp_imm_short + emit 1, 0EBh + emit 1 + relative_jump_out_of_range: + err 'relative jump out of range' + exit + jmp_imm_short: + emit 1, 0EBh + compute @dest.imm, (@dest.imm-($+1)) and 0FFh + emit 1, @dest.imm + exit + +end calminstruction + +iterate , jo,70h, jno,71h, jc,72h, jb,72h, jnae,72h, jnc,73h, jnb,73h, jae,73h, jz,74h, je,74h, jnz,75h, jne,75h, jna,76h, jbe,76h, ja,77h, jnbe,77h, \ + js,78h, jns,79h, jp,7Ah, jpe,7Ah, jnp,7Bh, jpo,7Bh, jl,7Ch, jnge,7Ch, jnl,7Dh, jge,7Dh, jng,7Eh, jle,7Eh, jg,7Fh, jnle,7Fh + + calminstruction instr? dest* + + call x86.parse_jump_operand@dest, dest + + check @dest.type <> 'imm' | @dest.jump_type = 'far' + jyes invalid_operand + + check x86.mode = 64 | @dest.size = 8 + jyes long + call x86.store_operand_prefix, @dest.size + jump prefix_ok + long: + check x86.mode < 64 | @dest.size <> 8 + jyes invalid_operand + prefix_ok: + + check ~ $ relativeto 0 & @dest.imm relativeto 0 + jno optimize + compute @dest.imm, @dest.imm + $ - 0 scaleof $ + err 'invalid address' + optimize: + + check @dest.jump_type <> 'near' & ( @dest.unresolved | ( @dest.imm relativeto $ & @dest.imm-($+2) < 80h & @dest.imm-($+2) >= -80h ) ) + jyes short + check @dest.jump_type <> 'near' & @dest.imm relativeto $ & ( (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) < 80h | (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) >= 1 shl (@dest.size*8) - 80h ) + jyes short + check @dest.jump_type = 'short' + jyes relative_jump_out_of_range + + emit 1, 0Fh + emit 1, 10h+opcode + + check @dest.size = 2 + jyes relative_word + compute @dest.imm, @dest.imm-($+4) + asm dd @dest.imm + exit + relative_word: + compute @dest.imm, @dest.imm-($+2) + check @dest.imm relativeto 0 + jno store_word + compute @dest.imm, @dest.imm and 0FFFFh + store_word: + asm dw @dest.imm + exit + + short: + compute @dest.imm, (@dest.imm-($+2)) and 0FFh + emit 1, opcode + emit 1, @dest.imm + exit + + relative_jump_out_of_range: + emit 2 + err 'relative jump out of range' + exit + + invalid_operand: + err 'invalid operand' + exit + + end calminstruction +end iterate + +iterate , loopnz,0E0h,0, loopne,0E0h,0, loopz,0E1h,0, loope,0E1h,0, loop,0E2h,0, \ + loopnzw,0E0h,2, loopnew,0E0h,2, loopzw,0E1h,2, loopew,0E1h,2, loopw,0E2h,2, \ + loopnzd,0E0h,4, loopned,0E0h,4, loopzd,0E1h,4, looped,0E1h,4, loopd,0E2h,4, \ + loopnzq,0E0h,8, loopneq,0E0h,8, loopzq,0E1h,8, loopeq,0E1h,8, loopq,0E2h,8, \ + jcxz,0E3h,2, jecxz,0E3h,4, jrcxz,0E3h,8 + calminstruction instr? dest* + + call x86.parse_jump_operand@dest, dest + + check @dest.type = 'imm' & ( @dest.jump_type = 'short' | ~ @dest.jump_type ) + jno invalid_operand + + check len shl 3 and not x86.mode + jno address_prefix_ok + check len = 8 | (len = 2 & x86.mode = 64) + jyes illegal_instruction + emit 1, 67h + address_prefix_ok: + check @dest.size shl 3 <> x86.mode + jno operand_prefix_ok + check @dest.size = 8 | x86.mode = 64 + jyes invalid_operand + emit 1, 66h + operand_prefix_ok: + + emit 1, opcode + + check @dest.imm-($+1) < 80h & @dest.imm-($+1) >= -80h + jyes relative_offset_ok + check (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) < 80h | (@dest.imm-($+2)) and (1 shl (@dest.size*8) - 1) >= 1 shl (@dest.size*8) - 80h + jyes relative_offset_ok + emit 1 + err 'relative jump out of range' + exit + relative_offset_ok: + compute @dest.imm, (@dest.imm-($+1)) and 0FFh + emit 1, @dest.imm + exit + + illegal_instruction: + err 'illegal instruction' + exit + invalid_operand: + err 'invalid operand' + exit + + end calminstruction +end iterate + +iterate , nop,90h, int3,0CCh, into,0CEh, int1,0F1h, salc,0D6h, \ + hlt,0F4h, cmc,0F5h, clc,0F8h, stc,0F9h, cli,0FAh, sti,0FBh, cld,0FCh, std,0FDh, \ + pushf,9Ch, popf,9Dh, sahf,9Eh, lahf,9Fh, leave,0C9h, \ + insb,6Ch, outsb,6Eh, movsb,0A4h, cmpsb,0A6h, stosb,0AAh, lodsb,0ACh, scasb,0AEh, xlatb,0D7h, \ + clts,<0Fh,6>, invd,<0Fh,8>, wbinvd,<0Fh,9>, wrmsr,<0Fh,30h>, rdtsc,<0Fh,31h>, rdmsr,<0Fh,32h>, rdpmc,<0Fh,33h>, \ + sysenter,<0Fh,34h>, sysexit,<0Fh,35h>, cpuid,<0Fh,0A2h>, rsm,<0Fh,0AAh> + + match byte1=,byte2, opcode + calminstruction instr? + emit 1, byte1 + emit 1, byte2 + end calminstruction + else + calminstruction instr? + emit 1, opcode + end calminstruction + end match + +end iterate + +iterate , cbw,98h, cwd,99h, iretw,0CFh, \ + insw,6Dh, outsw,6Fh, movsw,0A5h, cmpsw,0A7h, stosw,0ABh, lodsw,0ADh, scasw,0AFh + + calminstruction instr? + xcall x86.store_operand_prefix, (2) + emit 1, opcode + end calminstruction + +end iterate + +iterate , cwde,98h, cdq,99h, iretd,0CFh, \ + insd,6Dh, outsd,6Fh, stosd,0ABh, lodsd,0ADh, scasd,0AFh + + calminstruction instr? + xcall x86.store_operand_prefix, (4) + emit 1, opcode + end calminstruction + +end iterate + +iterate , cdqe,98h, cqo,99h, iretq,0CFh, \ + movsq,0A5h, cmpsq,0A7h, stosq,0ABh, lodsq,0ADh, scasq,0AFh, \ + sysretq,<0Fh,7>, wrmsrq,<0Fh,30h>, rdmsrq,<0Fh,32h>, sysexitq,<0Fh,35h> + + match byte1=,byte2, opcode + calminstruction instr? + xcall x86.store_operand_prefix, (8) + emit 1, byte1 + emit 1, byte2 + end calminstruction + else + calminstruction instr? + xcall x86.store_operand_prefix, (8) + emit 1, opcode + end calminstruction + end match + +end iterate + +iterate , swapgs,<0Fh,1,0F8h>, syscall,<0Fh,5>, sysret,<0Fh,7> + + calminstruction instr? + check x86.mode = 64 + jyes ok + err 'instruction requires long mode' + exit + ok: + asm db opcode + end calminstruction + +end iterate + +iterate , lock,0F0h, repnz,0F2h, repne,0F2h, rep,0F3h, repz,0F3h, repe,0F3h + + calminstruction prefix? instr& + emit 1, opcode + assemble instr + end calminstruction + +end iterate + +calminstruction int? number* + emit 1, 0CDh + emit 1, number +end calminstruction + +calminstruction iret? + check x86.mode < 64 + jyes prefix_ok + emit 1, 48h + prefix_ok: + emit 1, 0CFh +end calminstruction + +iterate , daa,27h, das,2Fh, aaa,37h, aas,3Fh, pusha,60h, popa,61h + + calminstruction instr? + check x86.mode < 64 + jyes allowed + err 'illegal instruction' + exit + allowed: + emit 1, opcode + end calminstruction + +end iterate + +calminstruction aam? number:10 + check x86.mode < 64 + jyes allowed + err 'illegal instruction' + exit + allowed: + emit 1, 0D4h + emit 1, number +end calminstruction + +calminstruction aad? number:10 + check x86.mode < 64 + jyes allowed + err 'illegal instruction' + exit + allowed: + emit 1, 0D5h + emit 1, number +end calminstruction + +iterate , pushaw,60h, popaw,61h, pushfw,9Ch, popfw,9Dh + + calminstruction instr? + check x86.mode < 64 + jyes allowed + err 'illegal instruction' + exit + allowed: + xcall x86.store_operand_prefix, (2) + emit 1, opcode + end calminstruction + +end iterate + +iterate , pushad,60h, popad,61h, pushfd,9Ch, popfd,9Dh + + calminstruction instr? + check x86.mode < 64 + jyes allowed + err 'illegal instruction' + exit + allowed: + xcall x86.store_operand_prefix, (4) + emit 1, opcode + end calminstruction + +end iterate + +iterate , pushfq,9Ch, popfq,9Dh + + calminstruction instr? + check x86.mode = 64 + jyes allowed + err 'instruction requires long mode' + exit + allowed: + emit 1, opcode + end calminstruction + +end iterate + +calminstruction movs? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + local size + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + compute size, @dest.size or @src.size + size_ok: + check @src.type = 'mem' & @src.mod = 0 & @dest.type = 'mem' & @dest.mod = 0 & ( (x86.mode < 64 & @src.mode = 16 & @src.rm = 4 & @dest.mode = 16 & @dest.rm = 5) | (@src.mode > 16 & @src.rm = 6 & @dest.mode = @src.mode & @dest.rm = 7) ) & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h | (x86.mode = 64 & @dest.segment_prefix < 64h)) + jno invalid_combination_of_operands + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh | (x86.mode = 64 & @src.segment_prefix < 64h) + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check @dest.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check size > 1 + jyes movs_word + emit 1, 0A4h + exit + movs_word: + call x86.store_operand_prefix, size + emit 1, 0A5h + exit + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump size_ok + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump size_ok + invalid_combination_of_operands: + err 'invalid combination of operands' + exit +end calminstruction + +calminstruction cmps? src*,dest* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + local size + check @dest.size = 0 & @src.size = 0 + jyes operand_size_not_specified + check @dest.size <> 0 & @src.size <> 0 & @dest.size <> @src.size + jyes operand_sizes_do_not_match + compute size, @dest.size or @src.size + size_ok: + check @src.type = 'mem' & @src.mod = 0 & @dest.type = 'mem' & @dest.mod = 0 & ( (x86.mode < 64 & @src.mode = 16 & @src.rm = 4 & @dest.mode = 16 & @dest.rm = 5) | (@src.mode > 16 & @src.rm = 6 & @dest.mode = @src.mode & @dest.rm = 7) ) & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h | (x86.mode = 64 & @dest.segment_prefix < 64h)) + jno invalid_combination_of_operands + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh | (x86.mode = 64 & @src.segment_prefix < 64h) + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check @dest.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check size > 1 + jyes cmps_word + emit 1, 0A6h + exit + cmps_word: + call x86.store_operand_prefix, size + emit 1, 0A7h + exit + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump size_ok + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump size_ok + invalid_combination_of_operands: + err 'invalid combination of operands' + exit +end calminstruction + +calminstruction stos? dest* + call x86.parse_operand@dest, dest + check @dest.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @dest.type = 'mem' & @dest.mod = 0 & ( (x86.mode < 64 & @dest.mode = 16 & @dest.rm = 5) | (@dest.mode > 16 & @dest.rm = 7) ) & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h | (x86.mode = 64 & @dest.segment_prefix < 64h)) + jno invalid_operand + check @dest.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check @dest.size > 1 + jyes stos_word + emit 1, 0AAh + exit + stos_word: + call x86.store_operand_prefix, @dest.size + emit 1, 0ABh + exit + invalid_operand: + err 'invalid operand' + exit +end calminstruction + +calminstruction lods? src* + call x86.parse_operand@src, src + check @src.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @src.type = 'mem' & @src.mod = 0 & ( (x86.mode < 64 & @src.mode = 16 & @src.rm = 4) | (@src.mode > 16 & @src.rm = 6) ) + jno invalid_operand + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh | (x86.mode = 64 & @src.segment_prefix < 64h) + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check @src.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check @src.size > 1 + jyes lods_word + emit 1, 0ACh + exit + lods_word: + call x86.store_operand_prefix, @src.size + emit 1, 0ADh + exit + invalid_operand: + err 'invalid operand' + exit +end calminstruction + +calminstruction scas? dest* + call x86.parse_operand@dest, dest + check @dest.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @dest.type = 'mem' & @dest.mod = 0 & ( (x86.mode < 64 & @dest.mode = 16 & @dest.rm = 5) | (@dest.mode > 16 & @dest.rm = 7) ) & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h | (x86.mode = 64 & @dest.segment_prefix < 64h)) + jno invalid_operand + check @dest.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check @dest.size > 1 + jyes scas_word + emit 1, 0AEh + exit + scas_word: + call x86.store_operand_prefix, @dest.size + emit 1, 0AFh + exit + invalid_operand: + err 'invalid operand' + exit +end calminstruction + +calminstruction ins? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.size + jyes size_ok + err 'operand size not specified' + compute size, 0 + size_ok: + check @src.type = 'reg' & @src.size = 2 & @src.rm = 2 & @dest.type = 'mem' & @dest.mod = 0 & ( (x86.mode < 64 & @dest.mode = 16 & @dest.rm = 5) | (@dest.mode > 16 & @dest.rm = 7) ) & ( @dest.segment_prefix = 0 | @dest.segment_prefix = 26h | (x86.mode = 64 & @dest.segment_prefix < 64h)) + jno invalid_combination_of_operands + check @dest.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check @dest.size > 1 + jyes ins_word + emit 1, 6Ch + exit + ins_word: + call x86.store_operand_prefix, @dest.size + emit 1, 6Dh + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + exit +end calminstruction + +calminstruction outs? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.size + jyes size_ok + err 'operand size not specified' + size_ok: + check @dest.type = 'reg' & @dest.size = 2 & @dest.rm = 2 & @src.type = 'mem' & @src.mod = 0 & ( (x86.mode < 64 & @src.mode = 16 & @src.rm = 4) | (@src.mode > 16 & @src.rm = 6) ) + jno invalid_combination_of_operands + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh | (x86.mode = 64 & @src.segment_prefix < 64h) + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check @src.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + check @src.size > 1 + jyes outs_word + emit 1, 6Eh + exit + outs_word: + call x86.store_operand_prefix, @src.size + emit 1, 6Fh + exit + operand_size_not_specified: + err 'operand size not specified' + compute size, 0 + jump size_ok + operand_sizes_do_not_match: + err 'operand sizes do not match' + compute size, 0 + jump size_ok + invalid_combination_of_operands: + err 'invalid combination of operands' + exit +end calminstruction + +calminstruction xlat? src* + call x86.parse_operand@src, src + check @src.size > 1 + jno size_ok + err 'invalid operand size' + size_ok: + check @src.type = 'mem' & @src.mod = 0 & ( (x86.mode < 64 & @src.mode = 16 & @src.rm = 7) | (@src.mode > 16 & @src.rm = 3) ) + jno invalid_operand + check @src.segment_prefix = 0 | @src.segment_prefix = 3Eh | (x86.mode = 64 & @src.segment_prefix < 64h) + jyes segment_prefix_ok + emit 1, @src.segment_prefix + segment_prefix_ok: + check @src.mode = x86.mode + jyes address_prefix_ok + emit 1, 67h + address_prefix_ok: + emit 1, 0D7h + exit + invalid_operand: + err 'invalid operand' + exit +end calminstruction + +calminstruction in? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.size = 8 + jyes invalid_size + check @dest.size + jyes size_ok + err 'operand size not specified' + jump size_ok + invalid_size: + err 'invalid_operand_size' + size_ok: + check @src.type = 'reg' & @src.size = 2 & @src.rm = 2 & @dest.type = 'reg' & @dest.rm = 0 + jyes in_ax_dx + check @src.type = 'imm' & @dest.type = 'reg' & @dest.rm = 0 + jyes in_ax_imm + err 'invalid combination of operands' + exit + in_ax_dx: + check @dest.size > 1 + jno in_al_dx + call x86.store_operand_prefix, @dest.size + emit 1, 0EDh + exit + in_al_dx: + emit 1, 0ECh + exit + in_ax_imm: + check @dest.size > 1 + jno in_al_imm + call x86.store_operand_prefix, @dest.size + emit 1, 0E5h + emit 1, @src.imm + exit + in_al_imm: + emit 1, 0E4h + emit 1, @src.imm + exit +end calminstruction + +calminstruction out? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.size = 8 + jyes invalid_size + check @src.size + jyes size_ok + err 'operand size not specified' + jump size_ok + invalid_size: + err 'invalid_operand_size' + size_ok: + check @dest.type = 'reg' & @dest.size = 2 & @dest.rm = 2 & @src.type = 'reg' & @src.rm = 0 + jyes out_dx_ax + check @dest.type = 'imm' & @src.type = 'reg' & @src.rm = 0 + jyes out_imm_ax + err 'invalid combination of operands' + exit + out_dx_ax: + check @src.size > 1 + jno out_dx_al + call x86.store_operand_prefix, @src.size + emit 1, 0EFh + exit + out_dx_al: + emit 1, 0EEh + exit + out_imm_ax: + check @src.size > 1 + jno out_imm_al + call x86.store_operand_prefix, @src.size + emit 1, 0E7h + emit 1, @dest.imm + exit + out_imm_al: + emit 1, 0E6h + emit 1, @dest.imm + exit +end calminstruction + +calminstruction enter? alloc*,nesting* + call x86.parse_operand@src, alloc + call x86.parse_operand@aux, nesting + check (@src.size and not 2) | (@aux.size and not 1) + jno size_ok + err 'invalid operand size' + size_ok: + check @src.type = 'imm' & @aux.type = 'imm' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + emit 1, 0C8h + asm dw @src.imm + emit 1, @aux.imm +end calminstruction + +calminstruction bound? dest*,src* + check x86.mode < 64 + jyes allowed + err 'illegal instruction' + exit + allowed: + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.type = 'mem' & @dest.type = 'reg' + jno invalid_combination_of_operands + check @src.size and not @dest.size + jno size_ok + err 'operand sizes do not match' + size_ok: + xcall x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, (62h),@dest.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + exit +end calminstruction + +calminstruction arpl? dest*,src* + check x86.mode < 64 + jyes allowed + err 'illegal instruction' + exit + allowed: + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.type = 'reg' & (@dest.type = 'mem' | @dest.type = 'reg') + jno invalid_combination_of_operands + check @src.size = 2 + jno invalid_operand_size + check @dest.size and not @src.size + jno size_ok + err 'operand sizes do not match' + jump size_ok + invalid_operand_size: + err 'invalid operand size' + size_ok: + xcall x86.store_instruction@dest, (63h),@src.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + exit + exit +end calminstruction + +iterate , lldt,0,2, ltr,0,3, verr,0,4, verw,0,5, lmsw,1,6 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.size and not 2 + jno size_ok + err 'invalid operand size' + size_ok: + check @dest.type = 'reg' | @dest.type = 'mem' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + xcall x86.store_instruction@dest, <0Fh,ext>,(postbyte) + end calminstruction + +end iterate + +iterate , sldt,0,0, str,0,1, smsw,1,4 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.type = 'reg' + jyes select_operand_prefix + check @dest.size and not 2 + jno size_ok + err 'invalid operand size' + size_ok: + check @dest.type = 'mem' + jyes store_instruction + err 'invalid combination of operands' + exit + select_operand_prefix: + xcall x86.select_operand_prefix@dest, @dest.size + store_instruction: + xcall x86.store_instruction@dest, <0Fh,ext>,(postbyte) + end calminstruction + +end iterate + +iterate , lgdt,2, lidt,3, sgdt,0, sidt,1 + + calminstruction instr? dest* + call x86.parse_operand@dest, dest + check @dest.type = 'mem' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + check x86.mode = 64 & @dest.size = 10 + jyes store_instruction + check x86.mode < 64 & @dest.size = 6 + jyes o32 + check x86.mode < 64 & @dest.size = 5 + jyes o16 + check @dest.size + jno store_instruction + err 'invalid operand size' + jump store_instruction + o16: + xcall x86.select_operand_prefix@dest, (2) + jump store_instruction + o32: + xcall x86.select_operand_prefix@dest, (4) + store_instruction: + xcall x86.store_instruction@dest, <0Fh,1>,(postbyte) + end calminstruction + +end iterate + +iterate , lar,2, lsl,3 + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @dest.type = 'reg' & (@src.type = 'mem' | @src.type = 'reg') + jno invalid_combination_of_operands + check @src.size and not 2 + jno size_ok + err 'invalid operand size' + size_ok: + xcall x86.select_operand_prefix@src, @dest.size + xcall x86.store_instruction@src, <0Fh,ext>,@dest.rm + exit + invalid_combination_of_operands: + err 'invalid combination of operands' + end calminstruction + +end iterate + +iterate , cmpxchg,0B0h, xadd,0C0h + + calminstruction instr? dest*,src* + call x86.parse_operand@dest, dest + call x86.parse_operand@src, src + check @src.type = 'reg' & ( @dest.type = 'reg' | @dest.type = 'mem' ) + jyes xadd_rm_reg + err 'invalid combination of operands' + exit + xadd_rm_reg: + check @dest.size and not @src.size + jno size_ok + err 'operand sizes do not match' + size_ok: + check @src.size > 1 + jno xadd_rm_reg_8bit + xcall x86.select_operand_prefix@dest, @src.size + xcall x86.store_instruction@dest, <0Fh,ext+1>,@src.rm + exit + xadd_rm_reg_8bit: + xcall x86.store_instruction@dest, <0Fh,ext>,@src.rm + end calminstruction + +end iterate + +calminstruction cmpxchg8b? dest* + call x86.parse_operand@dest, dest + check @dest.type = 'mem' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + check @dest.size and not 8 + jno size_ok + err 'invalid operand size' + size_ok: + xcall x86.store_instruction@dest, <0Fh,0C7h>,(1) +end calminstruction + +calminstruction cmpxchg16b? dest* + call x86.parse_operand@dest, dest + check @dest.type = 'mem' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + check @dest.size and not 16 + jno size_ok + err 'invalid operand size' + size_ok: + xcall x86.store_operand_prefix, (8) + xcall x86.store_instruction@dest, <0Fh,0C7h>,(1) +end calminstruction + +calminstruction bswap? dest* + call x86.parse_operand@dest, dest + check @dest.type = 'reg' & @dest.size > 2 + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + call x86.store_operand_prefix, @dest.size,@dest.rm + emit 1, 0Fh + emit 1, 0C8h + @dest.rm and 111b +end calminstruction + +calminstruction invlpg? dest* + call x86.parse_operand@dest, dest + check @dest.type = 'mem' + jyes operand_ok + err 'invalid operand' + exit + operand_ok: + xcall x86.store_instruction@dest, <0Fh,1>,(7) +end calminstruction + +include '80387.inc' + +iterate , fcmovb,0DAh,0C0h, fcmove,0DAh,0C8h, fcmovbe,0DAh,0D0h, fcmovu,0DAh,0D8h, \ + fcmovnb,0DBh,0C0h, fcmovne,0DBh,0C8h, fcmovnbe,0DBh,0D0h, fcmovnu,0DBh,0D8h + + calminstruction instr? dest*,src* + call x87.parse_operand@dest, dest + call x87.parse_operand@src, src + check @dest.type = 'streg' & @dest.rm = 0 & @src.type = 'streg' + jyes ok + err 'invalid operand' + exit + ok: + emit 1, opcode + emit 1, postbyte + @src.rm + end calminstruction + +end iterate + +iterate , fucomi,0DBh,5, fucomip,0DFh,5, fcomi,0DBh,6, fcomip,0DFh,6 + + calminstruction instr? src:st1 + call x87.parse_operand@src, src + check @src.type = 'streg' + jyes ok + err 'invalid operand' + exit + ok: + emit 1, opcode + emit 1, 11b shl 6 + postbyte shl 3 + @src.rm + end calminstruction + +end iterate + +include 'ext/sse2.inc' + +repeat 8, i:8 + element xmm#i? : SSE.reg + i +end repeat + +iterate , fxsave64,0, fxrstor64,1 + + calminstruction instr? src* + check x86.mode = 64 + jyes allowed + err 'instruction requires long mode' + exit + allowed: + call x86.parse_operand@src, src + check @src.type = 'mem' + jno invalid_operand + check @src.size and not 512 + jno size_ok + err 'invalid operand size' + size_ok: + xcall x86.select_operand_prefix@src, (8) + xcall x86.store_instruction@src, <0Fh,0AEh>,(postbyte) + exit + invalid_operand: + err 'invalid operand' + end calminstruction + +end iterate diff --git a/toolchain/fasmg.kl0e/examples/x86/life.asm b/toolchain/fasmg.kl0e/examples/x86/life.asm new file mode 100644 index 0000000..51151bd --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/life.asm @@ -0,0 +1,209 @@ + +; Life - fasm example program + +; Controls: +; arrow keys - move cursor +; Space - switch cell +; Enter - move to next generation +; Esc - exit program + + include '80186.inc' + + org 100h + jumps + + mov di,screen_data + xor al,al + mov cx,80*50*2 + rep stosb + + mov ax,3 + int 10h ; set text mode + mov ah,1 + mov ch,20h + int 10h ; hide cursor + mov ax,1003h + xor bx,bx + int 10h ; enable background intensity + + mov ax,1100h + mov bp,DCh_pattern + mov cx,1 + mov dx,0DCh + mov bx,1000h + int 10h + + mov ax,0B800h + mov es,ax + xor di,di + mov ax,0DCh + mov cx,80*25 + rep stosw + + redraw_screen: + mov si,[cursor_y] + imul si,80 + add si,[cursor_x] + and byte [screen_data+si],8 + or byte [screen_data+si],2 + + mov si,screen_data + xor di,di + mov cx,50 + draw_screen: + push cx + mov cx,80 + draw_line: + mov ah,[si+80] + lodsb + shl al,4 + and ah,0Fh + or al,ah + inc di + stosb + loop draw_line + pop cx + add si,80 + loop draw_screen + + wait_for_key: + xor ah,ah + int 16h + cmp ah,1 + je exit + cmp ah,1Ch + je next_generation + cmp ah,39h + je switch_cell + cmp ah,4Bh + je cursor_left + cmp ah,4Dh + je cursor_right + cmp ah,48h + je cursor_up + cmp ah,50h + je cursor_down + jmp wait_for_key + + switch_cell: + mov si,[cursor_y] + imul si,80 + add si,[cursor_x] + xor byte [screen_data+si],8 + jmp redraw_screen + + cursor_left: + cmp [cursor_x],1 + jbe wait_for_key + call clear_cursor + dec [cursor_x] + jmp redraw_screen + cursor_right: + cmp [cursor_x],78 + jae wait_for_key + call clear_cursor + inc [cursor_x] + jmp redraw_screen + cursor_up: + cmp [cursor_y],1 + jbe wait_for_key + call clear_cursor + dec [cursor_y] + jmp redraw_screen + cursor_down: + cmp [cursor_y],48 + jae wait_for_key + call clear_cursor + inc [cursor_y] + jmp redraw_screen + + next_generation: + call clear_cursor + mov si,screen_data+81 + mov di,screen_data+80*50+81 + mov cx,48 + process_screen: + push cx + mov cx,78 + process_line: + xor bl,bl + mov al,[si+1] + and al,1 + add bl,al + mov al,[si-1] + and al,1 + add bl,al + mov al,[si+80] + and al,1 + add bl,al + mov al,[si-80] + and al,1 + add bl,al + mov al,[si+80+1] + and al,1 + add bl,al + mov al,[si+80-1] + and al,1 + add bl,al + mov al,[si-80+1] + and al,1 + add bl,al + mov al,[si-80-1] + and al,1 + add bl,al + mov al,byte [si] + mov byte [di],al + cmp bl,1 + jbe clear_cell + cmp bl,4 + jae clear_cell + cmp bl,2 + je cell_ok + mov byte [di],0Fh + jmp cell_ok + clear_cell: + mov byte [di],0 + cell_ok: + inc si + inc di + loop process_line + pop cx + add si,2 + add di,2 + loop process_screen + push es + push ds + pop es + mov si,screen_data+80*50 + mov di,screen_data + mov cx,80*50 + rep movsb + pop es + jmp redraw_screen + + exit: + mov ax,3 + int 10h + int 20h + + clear_cursor: + mov si,[cursor_y] + imul si,80 + add si,[cursor_x] + mov al,byte [screen_data+si] + cmp al,2 + je empty_cell + mov byte [screen_data+si],0Fh + ret + empty_cell: + mov byte [screen_data+si],0 + ret + +cursor_x dw 40 +cursor_y dw 25 + +DCh_pattern: + db 8 dup 0 + db 8 dup 0FFh + +screen_data rb 80*50*2 diff --git a/toolchain/fasmg.kl0e/examples/x86/make.cmd b/toolchain/fasmg.kl0e/examples/x86/make.cmd new file mode 100644 index 0000000..81249be --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/make.cmd @@ -0,0 +1,9 @@ +set include=include +fasmg hello.asm hello.com +fasmg life.asm life.com +fasmg mandel.asm mandel.com +fasmg multiseg.asm multiseg.exe +fasmg usedpmi.asm usedpmi.exe +fasmg win32.asm win32.exe +fasmg win64.asm win64.exe +fasmg win64avx.asm win64avx.exe diff --git a/toolchain/fasmg.kl0e/examples/x86/mandel.asm b/toolchain/fasmg.kl0e/examples/x86/mandel.asm new file mode 100644 index 0000000..ce17a50 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/mandel.asm @@ -0,0 +1,94 @@ + +; Mandelbrot Set - fasm example program + +include '80186.inc' +include '8087.inc' + + org 100h + + mov ax,13h ; MCGA/VGA + int 10h + push 0A000h + pop es + + mov dx,3C8h + xor al,al + out dx,al + inc dl + mov cx,64 + vga_palette: + out dx,al + out dx,al + out dx,al + inc al + loop vga_palette + + xor di,di + xor dx,dx + finit + fld [y_top] + fstp [y] +screen: + xor bx,bx + fld [x_left] + fstp [x] + row: + finit + fldz + fldz + mov cx,63 + iteration: + fld st0 + fmul st0,st0 + fxch st1 + fmul st0,st2 + fadd st0,st0 + fxch st2 + fmul st0,st0 + fsubp st1,st0 + fxch st1 + fadd [y] + fxch st1 + fadd [x] + fld st1 + fmul st0,st0 + fld st1 + fmul st0,st0 + faddp st1,st0 + fsqrt + fistp [i] + cmp [i],2 + ja over + loop iteration + over: + mov al,cl + stosb + fld [x] + fadd [x_step] + fstp [x] + inc bx + cmp bx,320 + jb row + fld [y] + fsub [y_step] + fstp [y] + inc dx + cmp dx,200 + jb screen + + xor ah,ah + int 16h + mov ax,3 + int 10h + int 20h + +x_left dd -2.2 +y_top dd 1.25 + +x_step dd 0.009375 +y_step dd 0.0125 + +x dd ? +y dd ? + +i dw ? diff --git a/toolchain/fasmg.kl0e/examples/x86/multiseg.asm b/toolchain/fasmg.kl0e/examples/x86/multiseg.asm new file mode 100644 index 0000000..f015101 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/multiseg.asm @@ -0,0 +1,29 @@ + +include '8086.inc' +include 'format/mz.inc' + +entry code:start ; program entry point +stack 100h ; stack size + +segment code + + start: + mov ax,data + mov ds,ax + + mov dx,hello + call extra:write_text + + mov ax,4C00h + int 21h + +segment data + + hello db 'Hello world!',24h + +segment extra + + write_text: + mov ah,9 + int 21h + retf diff --git a/toolchain/fasmg.kl0e/examples/x86/usedpmi.asm b/toolchain/fasmg.kl0e/examples/x86/usedpmi.asm new file mode 100644 index 0000000..37f2c5c --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/usedpmi.asm @@ -0,0 +1,99 @@ + +; This is an example of setting up 32-bit program with flat memory model +; using DPMI. It requires 32-bit DPMI host in order to start. + +include '80386.inc' +include 'format/mz.inc' + +heap 0 ; no additional memory + +segment loader use16 + + push cs + pop ds + + mov ax,1687h + int 2Fh + or ax,ax ; DPMI installed? + jnz error + test bl,1 ; 32-bit programs supported? + jz error + mov word [mode_switch],di + mov word [mode_switch+2],es + mov bx,si ; allocate memory for DPMI data + mov ah,48h + int 21h + jc error + mov es,ax + mov ax,1 + call far [mode_switch] ; switch to protected mode + jc error + + mov cx,1 + xor ax,ax + int 31h ; allocate descriptor for code + mov si,ax + xor ax,ax + int 31h ; allocate descriptor for data + mov di,ax + mov dx,cs + lar cx,dx + shr cx,8 + or cx,0C000h + mov bx,si + mov ax,9 + int 31h ; set code descriptor access rights + mov dx,ds + lar cx,dx + shr cx,8 + or cx,0C000h + mov bx,di + int 31h ; set data descriptor access rights + mov ecx,main + shl ecx,4 + mov dx,cx + shr ecx,16 + mov ax,7 ; set descriptor base address + int 31h + mov bx,si + int 31h + mov cx,0FFFFh + mov dx,0FFFFh + mov ax,8 ; set segment limit to 4 GB + int 31h + mov bx,di + int 31h + + mov ds,di + mov es,di + mov fs,di + mov gs,di + push 0 + push si + push dword start + retfd + + error: + mov ax,4CFFh + int 21h + + mode_switch dd ? + +segment main use32 + + start: + mov esi,hello + .loop: + lodsb + or al,al + jz .done + mov dl,al + mov ah,2 + int 21h + jmp .loop + .done: + + mov ax,4C00h + int 21h + + hello db 'Hello from protected mode!',0Dh,0Ah,0 diff --git a/toolchain/fasmg.kl0e/examples/x86/win32.asm b/toolchain/fasmg.kl0e/examples/x86/win32.asm new file mode 100644 index 0000000..683ba9f --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/win32.asm @@ -0,0 +1,46 @@ + +include 'format/format.inc' + +format PE GUI +entry start + +section '.text' code readable executable + + start: + + push 0 + push _caption + push _message + push 0 + call [MessageBoxA] + + push 0 + call [ExitProcess] + +section '.data' data readable writeable + + _caption db 'Win32 assembly program',0 + _message db 'Hello World!',0 + +section '.idata' import data readable writeable + + dd 0,0,0,RVA kernel_name,RVA kernel_table + dd 0,0,0,RVA user_name,RVA user_table + dd 0,0,0,0,0 + + kernel_table: + ExitProcess dd RVA _ExitProcess + dd 0 + user_table: + MessageBoxA dd RVA _MessageBoxA + dd 0 + + kernel_name db 'KERNEL32.DLL',0 + user_name db 'USER32.DLL',0 + + _ExitProcess dw 0 + db 'ExitProcess',0 + _MessageBoxA dw 0 + db 'MessageBoxA',0 + +section '.reloc' fixups data readable discardable ; needed for Win32s diff --git a/toolchain/fasmg.kl0e/examples/x86/win64.asm b/toolchain/fasmg.kl0e/examples/x86/win64.asm new file mode 100644 index 0000000..7e493b4 --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/win64.asm @@ -0,0 +1,45 @@ + +include 'format/format.inc' + +format PE64 GUI +entry start + +section '.text' code readable executable + + start: + sub rsp,8*5 ; reserve stack for API use and make stack dqword aligned + + mov r9d,0 + lea r8,[_caption] + lea rdx,[_message] + mov rcx,0 + call [MessageBoxA] + + mov ecx,eax + call [ExitProcess] + +section '.data' data readable writeable + + _caption db 'Win64 assembly program',0 + _message db 'Hello World!',0 + +section '.idata' import data readable writeable + + dd 0,0,0,RVA kernel_name,RVA kernel_table + dd 0,0,0,RVA user_name,RVA user_table + dd 0,0,0,0,0 + + kernel_table: + ExitProcess dq RVA _ExitProcess + dq 0 + user_table: + MessageBoxA dq RVA _MessageBoxA + dq 0 + + kernel_name db 'KERNEL32.DLL',0 + user_name db 'USER32.DLL',0 + + _ExitProcess dw 0 + db 'ExitProcess',0 + _MessageBoxA dw 0 + db 'MessageBoxA',0 diff --git a/toolchain/fasmg.kl0e/examples/x86/win64avx.asm b/toolchain/fasmg.kl0e/examples/x86/win64avx.asm new file mode 100644 index 0000000..d2969ff --- /dev/null +++ b/toolchain/fasmg.kl0e/examples/x86/win64avx.asm @@ -0,0 +1,114 @@ + +include 'format/format.inc' + +format PE64 NX GUI 5.0 +entry start + +include 'ext/avx.inc' + +section '.data' data readable writeable + + _title db 'AVX playground',0 + _error db 'AVX instructions are not supported.',0 + + x dq 3.14159265389 + + vector_output: + repeat 16, i:0 + db 'ymm',`i,': %f,%f,%f,%f',13,10 + end repeat + db 0 + + buffer db 1000h dup ? + +section '.text' code readable executable + + start: + + mov eax,1 + cpuid + and ecx,18000000h + cmp ecx,18000000h + jne no_AVX + xor ecx,ecx + xgetbv + and eax,110b + cmp eax,110b + jne no_AVX + + vbroadcastsd ymm0, [x] + vsqrtpd ymm1, ymm0 + + vsubpd ymm2, ymm0, ymm1 + vsubpd ymm3, ymm1, ymm2 + + vaddpd xmm4, xmm2, xmm3 + vaddpd ymm5, ymm4, ymm0 + + vperm2f128 ymm6, ymm4, ymm5, 03h + vshufpd ymm7, ymm6, ymm5, 10010011b + + vroundpd ymm8, ymm7, 0011b + vroundpd ymm9, ymm7, 0 + + sub rsp,418h + + repeat 16, i:0 + vmovups [rsp+10h+i*32],ymm#i + end repeat + + mov r8,[rsp+10h] + mov r9,[rsp+18h] + lea rdx,[vector_output] + lea rcx,[buffer] + call [sprintf] + + xor ecx,ecx + lea rdx,[buffer] + lea r8,[_title] + xor r9d,r9d + call [MessageBoxA] + + xor ecx,ecx + call [ExitProcess] + + no_AVX: + + sub rsp,28h + + xor ecx,ecx + lea rdx,[_error] + lea r8,[_title] + mov r9d,10h + call [MessageBoxA] + + mov ecx,1 + call [ExitProcess] + +section '.idata' import data readable writeable + + dd 0,0,0,RVA kernel_name,RVA kernel_table + dd 0,0,0,RVA user_name,RVA user_table + dd 0,0,0,RVA msvcrt_name,RVA msvcrt_table + dd 0,0,0,0,0 + + kernel_table: + ExitProcess dq RVA _ExitProcess + dq 0 + user_table: + MessageBoxA dq RVA _MessageBoxA + dq 0 + msvcrt_table: + sprintf dq RVA _sprintf + dq 0 + + kernel_name db 'KERNEL32.DLL',0 + user_name db 'USER32.DLL',0 + msvcrt_name db 'MSVCRT.DLL',0 + + _ExitProcess dw 0 + db 'ExitProcess',0 + _MessageBoxA dw 0 + db 'MessageBoxA',0 + _sprintf dw 0 + db 'sprintf',0 diff --git a/toolchain/fasmg.kl0e/fasmg b/toolchain/fasmg.kl0e/fasmg new file mode 100644 index 0000000..ff039c5 Binary files /dev/null and b/toolchain/fasmg.kl0e/fasmg differ diff --git a/toolchain/fasmg.kl0e/fasmg.exe b/toolchain/fasmg.kl0e/fasmg.exe new file mode 100644 index 0000000..d012aa5 Binary files /dev/null and b/toolchain/fasmg.kl0e/fasmg.exe differ diff --git a/toolchain/fasmg.kl0e/fasmg.x64 b/toolchain/fasmg.kl0e/fasmg.x64 new file mode 100644 index 0000000..d3b8364 Binary files /dev/null and b/toolchain/fasmg.kl0e/fasmg.x64 differ diff --git a/toolchain/fasmg.kl0e/license.txt b/toolchain/fasmg.kl0e/license.txt new file mode 100644 index 0000000..05e1d61 --- /dev/null +++ b/toolchain/fasmg.kl0e/license.txt @@ -0,0 +1,24 @@ +flat assembler g +Copyright (c) 2015-2024, Tomasz Grysztar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/toolchain/fasmg.kl0e/readme.txt b/toolchain/fasmg.kl0e/readme.txt new file mode 100644 index 0000000..38042bf --- /dev/null +++ b/toolchain/fasmg.kl0e/readme.txt @@ -0,0 +1,20 @@ + +The name of flat assembler g (abbreviated to fasmg) is intentionally stylized +with lowercase letters. This is a nod to the history of its precedessor. + +The "source" directory contains the complete source code which +can be assembled with either fasm or fasmg except for MacOS version, +which can only be assembled with fasmg. + +The executable file for Windows is "fasmg.exe", while "fasmg" and "fasmg.x64" +are for Linux in 32-bit and 64-bit format respectively. The files for MacOS +are at "source/macos/fasmg" and "source/macos/x64/fasmg". + +The "source/libc/fasmg.asm" may be used to assemble fasmg as an ELF object +that can then be linked to a 32-bit C library with a third-party linker to +produce an executable native to a particular operating system. A similar +object file in Mach-O format can be assembled from "source/macos/fasmg.o.asm". + +When the source code is assembled with fasmg, it depends on the files from +"examples/x86/include" directory that implement the instruction sets and +output formats compatible with flat assembler 1. \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/source/assembler.inc b/toolchain/fasmg.kl0e/source/assembler.inc new file mode 100644 index 0000000..2eaba21 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/assembler.inc @@ -0,0 +1,3383 @@ + +; general note: +; with the ability to run in various environments in mind, the entire assembler core +; does not use ebp register and never directly touches esp; the stack is managed +; with push and pop instructions, occasionally [esp] may be used to access the top value, +; but no other assumptions about the stack layout are made + +struct Workspace + memory_start dd ? + memory_end dd ? +ends + +struct SourceContext + number_of_entries dd ? + ; entries SourceEntry[] +ends + +struct SourceEntry + type db ? ; SOURCE_# + flags db ? ; SRCF_# + saved_result db ? + reserved db ? + name dd ? + name_length dd ? + text dd ? + offset dd ? + line_number dd ? + number_of_attached_lines dd ? + line_offset dd ? + local_namespace dd ? +ends + +struct RecognitionContext + base_namespace dd ? ; SymbolTree_Root + base_label dd ? ; SymbolTree_Foliage +ends + +struct LineEmbedding + previous_pointer dd ? + previous_end dd ? + recognition_context dd ? + definition dd ? + whitespace dd ? +ends + +struct LineExcerpt + data_start dd ? + data_end dd ? + recognition_context dd ? + leftover_context dd ? +ends + +SOURCE_FILE = 0 +SOURCE_MEMORY = 1 +SOURCE_MACRO = 2 +SOURCE_CALM = 3 + +SRCF_PREPROCESSED = 1 +SRCF_ALM_STATEMENT = 2 + +PMODE_RETAIN_COMMENTS = 1 +PMODE_ISOLATE_LINES = 2 + +AMODE_SKIP = 1 +AMODE_DEFINITION = 2 +AMODE_POSTPONED = 4 +AMODE_CALM_DEFINITION = 8 + +TRACE_ERROR_STACK = 1 +TRACE_DISPLAY = 2 + +assembly_init: +; in: +; al = any combination of TRACE_# flags + + mov [trace_mode],al + + xor eax,eax + mov edi,variables + mov ecx,(variables_end - variables) shr 2 + rep stosd + if (variables_end - variables) and 11b + mov cl,(variables_end - variables) and 11b + rep stosb + end if + mov edi,characters + prepare_characters: + stosb + inc al + jnz prepare_characters + mov esi,characters+'a' + mov edi,characters+'A' + mov ecx,'z'+1-'a' + rep movsb + mov edi,characters + mov esi,control_characters + mov cl,control_characters.count + mark_control_characters: + lodsb + mov byte [edi+eax],20h + loop mark_control_characters + mov esi,syntactical_characters + mov cl,syntactical_characters.count + mark_syntactical_characters: + lodsb + mov byte [edi+eax],0 + loop mark_syntactical_characters + + mov esi,include_variable + xor ecx,ecx + call get_environment_variable + mov ecx,eax + call malloc_fixed + mov [include_paths],eax + mov edi,eax + call get_environment_variable + + mov cl,10 + call create_string_map + mov [file_source_cache],ebx + + mov cl,12 + call create_string_map + mov [memory_source_cache],ebx + + mov cl,10 + call create_string_map + mov [file_data_cache],ebx + + mov cl,7 + call create_string_map + mov [auxiliary_output_areas],ebx + + mov ecx,sizeof.SymbolTree_Root + sizeof.SymbolTree_Node + call create_tree_element + mov [root_namespace],eax + + call create_parameter_namespace + mov [root_parameter_namespace],eax + + mov ecx,4*sizeof.SymbolTree_Leaf + call create_tree_element + mov [eax+SymbolTree_Leaf.class],SYMCLASS_INSTRUCTION + mov [eax+SymbolTree_Leaf.flags],SYM_VARIABLE + mov [interceptor_symbol],eax + add eax,sizeof.SymbolTree_Leaf + mov [eax+SymbolTree_Leaf.class],SYMCLASS_STRUCTURE + mov [eax+SymbolTree_Leaf.flags],SYM_VARIABLE + mov [label_interceptor_symbol],eax + add eax,sizeof.SymbolTree_Leaf + mov [eax+SymbolTree_Leaf.class],SYMCLASS_INSTRUCTION + mov [eax+SymbolTree_Leaf.flags],SYM_VARIABLE + mov [other_interceptor_symbol],eax + add eax,sizeof.SymbolTree_Leaf + mov [void_symbol],eax + + mov ecx,400 + call malloc_growable + mov [tree_stack_base],eax + add eax,ecx + mov [tree_stack_end],eax + + mov ecx,4000 + call malloc_growable + mov [source_context],eax + mov [source_context_maximum_length],ecx + + mov ecx,1000 + call malloc_growable + mov [line_embeddings],eax + mov [line_embeddings_maximum_length],ecx + + mov ecx,1000 + call malloc_growable + mov [display_buffer],eax + mov [display_buffer_length],ecx + + mov ecx,1000 + call malloc_growable + mov [macro_buffer],eax + mov [macro_buffer_length],ecx + + mov ecx,32*6*sizeof.ExpressionTerm + call malloc_fixed + mov [temporary_terms],eax + mov [free_temporary_terms],eax + + mov ecx,4*sizeof.FloatData + call malloc_fixed + mov [temporary_floats],eax + + mov ecx,400 + call malloc_growable + mov [output_areas_list],eax + mov edi,eax + add eax,ecx + mov [output_areas_list_end],eax + xor eax,eax + shr ecx,2 + rep stosd + mov [number_of_line_embeddings],eax + mov [virtual_area],eax + + mov ecx,1000 + call malloc_growable + mov [directives_stack_base],eax + add eax,ecx + mov [directives_stack_end],eax + + mov ecx,1000 + call malloc_growable + mov [counters_stack_base],eax + add eax,ecx + mov [counters_stack_end],eax + + mov ecx,400 + call malloc_growable + mov [operator_stack_base],eax + add eax,ecx + mov [operator_stack_end],eax + + mov ecx,400 + call malloc_growable + mov [condition_stack_base],eax + add eax,ecx + mov [condition_stack_end],eax + + mov ecx,400 + call malloc_growable + mov [assembly_stack_base],eax + add eax,ecx + mov [assembly_stack_end],eax + + mov edx,preprocessing_workspace + call initialize_workspace + + mov edx,assembly_workspace + call initialize_workspace + + mov edx,identifier_workspace + call initialize_workspace + + mov edx,auxiliary_workspace + call initialize_workspace + + mov edx,value_workspace + call initialize_workspace + + mov edx,expression_workspace + call initialize_workspace + + mov edx,calculation_workspace + call initialize_workspace + + mov edx,calm_code_buffer + call initialize_workspace + + mov edx,calm_literals_buffer + call initialize_workspace + + mov edx,calm_auxiliary_buffer + call initialize_workspace + + mov ecx,256*4 + call malloc_fixed + mov [operator_table],eax + mov edi,eax + mov ecx,256 + xor eax,eax + rep stosd + mov esi,separating_operators + register_operators: + lodsb + test al,al + jz operators_registered + movzx ebx,al + shl ebx,2 + add ebx,[operator_table] + mov ecx,sizeof.ValueDefinition + call create_tree_element + mov edx,eax + xchg [ebx],eax + mov [edx+ValueDefinition.previous],eax + inc [edx+ValueDefinition.reference_count] + lodsb + mov [edx+ValueDefinition.type],al + lodsb + mov [edx+ValueDefinition.flags],al + lodsb + mov [edx+ValueDefinition.attribute],al + lodsd + mov [edx+ValueDefinition.value],eax + jmp register_operators + operators_registered: + + xor eax,eax + mov [name_volatile],al + mov [name_token],eax + mov [name_kind],NAME_CASEINSENSITIVE + or [symbol_required],1 + or [symbol_expected],1 + mov eax,[root_namespace] + mov [current_context.base_namespace],eax + mov esi,symbols + register_internal_symbols: + lodsb + test al,al + jnz prepare_internal_symbol + lodsb + test al,al + jz internal_symbols_registered + and [current_context.base_namespace],0 + prepare_internal_symbol: + movzx ecx,al + + xor ebx,ebx + mov edx,FNV_OFFSET + hash_internal_symbol: + movzx eax,byte [esi+ebx] + xor dl,[characters+eax] + imul edx,FNV_PRIME + inc ebx + cmp ebx,ecx + jb hash_internal_symbol + + mov ebx,[current_context.base_namespace] + test ebx,ebx + jz register_internal_namespace + mov al,[esi+ecx] + mov [symbol_class],al + push esi + call scan_namespace + pop esi + add esi,ecx + mov ecx,sizeof.ValueDefinition + call create_tree_element + mov edx,eax + xchg [ebx+SymbolTree_Leaf.definition],eax + mov [edx+ValueDefinition.previous],eax + inc [edx+ValueDefinition.reference_count] + lodsb + lodsb + mov [edx+ValueDefinition.type],al + lodsb + mov [edx+ValueDefinition.flags],al + lodsb + mov [edx+ValueDefinition.attribute],al + lodsd + mov [edx+ValueDefinition.value],eax + jmp register_internal_symbols + register_internal_namespace: + mov [symbol_class],SYMCLASS_EXPRESSION + mov ebx,[root_namespace] + push esi + call scan_namespace + pop esi + add esi,ecx + mov ecx,sizeof.ValueDefinition + call create_tree_element + mov [ebx+SymbolTree_Leaf.definition],eax + inc [eax+ValueDefinition.reference_count] + mov [eax+ValueDefinition.type],VALTYPE_RESERVED + mov [eax+ValueDefinition.flags],VAL_INTERNAL + call get_symbol_namespace + mov [current_context.base_namespace],ebx + jmp register_internal_symbols + internal_symbols_registered: + + retn + +assembly_shutdown: + + call discard_errors + + mov ebx,[auxiliary_output_areas] + test ebx,ebx + jz auxiliary_output_areas_released + call destroy_string_map + auxiliary_output_areas_released: + + mov ebx,[value_definition_chain] + release_values_from_chain: + test ebx,ebx + jz values_released + cmp [ebx+ValueDefinition.block_length],0 + je release_next_value + mov eax,[ebx+ValueDefinition.value] + call mfree + release_next_value: + mov ebx,[ebx+ValueDefinition.interlink] + jmp release_values_from_chain + values_released: + + mov eax,[include_paths] + call mfree + + mov ebx,[file_source_cache] + test ebx,ebx + jz file_source_cache_released + mov edi,mfree + call iterate_through_map + mov ebx,[file_source_cache] + call destroy_string_map + file_source_cache_released: + + mov ebx,[file_data_cache] + test ebx,ebx + jz file_data_cache_released + mov edi,release_file_data + call iterate_through_map + mov ebx,[file_data_cache] + call destroy_string_map + file_data_cache_released: + + mov ebx,[memory_source_cache] + test ebx,ebx + jz memory_source_cache_released + mov edi,mfree + call iterate_through_map + mov ebx,[memory_source_cache] + call destroy_string_map + memory_source_cache_released: + + mov eax,[tree_stack_base] + call mfree + mov eax,[source_context] + call mfree + mov eax,[line_embeddings] + call mfree + mov eax,[output_areas_list] + call mfree + mov eax,[directives_stack_base] + call mfree + mov eax,[counters_stack_base] + call mfree + mov eax,[operator_stack_base] + call mfree + mov eax,[condition_stack_base] + call mfree + mov eax,[assembly_stack_base] + call mfree + + mov eax,[preprocessing_workspace.memory_start] + call mfree + mov eax,[assembly_workspace.memory_start] + call mfree + mov eax,[identifier_workspace.memory_start] + call mfree + mov eax,[value_workspace.memory_start] + call mfree + mov eax,[expression_workspace.memory_start] + call mfree + mov eax,[calculation_workspace.memory_start] + call mfree + mov eax,[auxiliary_workspace.memory_start] + call mfree + mov eax,[calm_code_buffer.memory_start] + call mfree + mov eax,[calm_literals_buffer.memory_start] + call mfree + mov eax,[calm_auxiliary_buffer.memory_start] + call mfree + + mov eax,[display_buffer] + call mfree + mov eax,[macro_buffer] + call mfree + mov eax,[temporary_terms] + call mfree + mov eax,[temporary_floats] + call mfree + mov eax,[operator_table] + call mfree + + mov eax,[tree_blocks] + call release_chained_blocks + + mov eax,[storage_blocks] + call release_chained_blocks + + retn + + release_chained_blocks: + test eax,eax + jz blocks_released + mov ebx,[eax] + call mfree + mov eax,ebx + jmp release_chained_blocks + blocks_released: + retn + + release_file_data: + test eax,eax + jz file_data_released + mov ebx,[eax+FileData.cache] + call mfree + release_file_cache: + mov eax,ebx + test eax,eax + jz file_data_released + mov ebx,[ebx+FileCache.next] + call mfree + jmp release_file_cache + file_data_released: + retn + + release_auxiliary_output: + test eax,eax + jz auxiliary_output_released + dec [eax+ValueDefinition.reference_count] + xor eax,eax + mov [edx+MapEntry.value],eax + auxiliary_output_released: + retn + +assembly_pass: +; in: +; esi - ASCIIZ string containing source text +; edx - path to source file +; out: +; cf clear if another pass is needed +; note: +; if both string and file sources are present, they are assembled as combined text + mov [source_file],edx + inc [current_pass] + call discard_errors + mov eax,[directives_stack_base] + mov [directives_stack],eax + mov eax,[root_namespace] + mov [current_context.base_namespace],eax + mov edx,[counters_stack_base] + mov [current_counter],edx + xor eax,eax + mov [edx],al + mov [preprocessing_mode],al + mov [next_pass_needed],al + mov [assembly_mode],al + mov [use_raw_values],al + mov [shift_tracking],al + mov [current_area],eax + mov [current_output_area_entry],eax + mov [initial_output_area_entry],eax + mov [predicted_shift],eax + mov [display_data_length],eax + mov [macro_end_position],eax + mov [proxy_number],eax + mov [output_extension],eax + mov [output_extension_length],eax + mov ebx,[source_context] + mov [ebx+SourceContext.number_of_entries],eax + add ebx,sizeof.SourceContext + mov edi,ebx + mov ecx,sizeof.SourceEntry shr 2 + assert sizeof.SourceEntry and 11b = 0 + rep stosd + mov [line_start],eax + mov [line_end],eax + test esi,esi + jz read_main_source_file + cmp byte [esi],0 + je read_main_source_file + push ebx + call use_source + pop ebx + mov [ebx+SourceEntry.type],SOURCE_MEMORY + jmp fill_main_source_entry + read_main_source_file: + mov esi,[source_file] + test esi,esi + jz no_source_to_assemble + cmp byte [esi],0 + je no_source_to_assemble + push ebx + call read_source + pop ebx + test eax,eax + jz main_source_file_not_found + mov [ebx+SourceEntry.type],SOURCE_FILE + fill_main_source_entry: + mov [ebx+SourceEntry.name],esi + mov [ebx+SourceEntry.text],eax + mov eax,[root_parameter_namespace] + and [eax+SymbolTree_Root.parameters],0 + mov [local_parameter_namespace],eax + mov [ebx+SourceEntry.local_namespace],eax + mov ebx,[source_context] + inc [ebx+SourceContext.number_of_entries] + mov esi,zero_value + mov ecx,4+4 + call create_output_area + mov [current_area],edx + inc [edx+ValueDefinition.reference_count] + mov ebx,[auxiliary_output_areas] + mov edi,release_auxiliary_output + call iterate_through_map +assembly_line: + xor eax,eax + mov [value_position],eax + mov [current_constituent],al + call clear_line_embeddings + get_line: + xor eax,eax + mov [symbol_class],SYMCLASS_PARAMETER + mov [symbol_expected],al + mov [symbol_required],al + mov [name_volatile],al + mov [preprocessed_context],eax + mov [alm_statement],al + mov ebx,[source_context] + mov ecx,[ebx+SourceContext.number_of_entries] + dec ecx + imul ecx,sizeof.SourceEntry + lea ebx,[ebx+sizeof.SourceContext+ecx] + xchg eax,[ebx+SourceEntry.number_of_attached_lines] + inc eax + add [ebx+SourceEntry.line_number],eax + cmp [ebx+SourceEntry.type],SOURCE_CALM + je calm_virtual_machine + mov eax,[ebx+SourceEntry.local_namespace] + mov [parameter_namespace],eax + xor edx,edx + test [eax+SymbolTree_Root.flags],NAMESPACE_UNATTACHED + jnz no_local_namespace + mov edx,eax + mov ecx,[eax+SymbolTree_Root.current_label] + test ecx,ecx + jnz local_namespace_ok + no_local_namespace: + mov eax,[current_context.base_namespace] + mov ecx,[eax+SymbolTree_Root.current_label] + local_namespace_ok: + mov [local_namespace],edx + mov [current_context.base_label],ecx + cmp [ebx+SourceEntry.type],SOURCE_MACRO + je get_line_from_macro + and [name_token],0 + mov esi,[ebx+SourceEntry.text] + mov eax,[ebx+SourceEntry.offset] + add esi,eax + mov [ebx+SourceEntry.line_offset],eax + cmp byte [esi],0 + je source_ended + mov edi,[preprocessing_workspace.memory_start] + preprocess_line_from_file: + mov ecx,14 + mov edx,preprocessing_workspace + call reserve_workspace + lodsb + cmp al,1Ah + je convert_name_symbol + cmp al,22h + je convert_quoted_string + cmp al,27h + je convert_quoted_string + test al,al + jz file_ended + cmp al,0Ah + je line_ended + cmp al,';' + jne preprocess_syntactical_character + xor edx,edx + test [preprocessing_mode],PMODE_RETAIN_COMMENTS + jz skip_comment + preprocess_syntactical_character: + stosb + cmp al,'`' + je convert_parameter + cmp al,'\' + jne preprocess_line_from_file + test [preprocessing_mode],PMODE_ISOLATE_LINES + jnz preprocess_line_from_file + mov edx,esi + detect_line_concatenation: + mov al,[edx] + inc edx + cmp al,0Ah + je concatenate_line + cmp al,';' + je concatenation_comment + cmp al,20h + jne preprocess_line_from_file + jmp detect_line_concatenation + concatenate_line: + mov byte [edi-1],20h + inc esi + inc [ebx+SourceEntry.number_of_attached_lines] + jmp preprocess_line_from_file + concatenation_comment: + test [preprocessing_mode],PMODE_RETAIN_COMMENTS + jnz preprocess_line_from_file + mov byte [edi-1],20h + mov esi,edx + inc [ebx+SourceEntry.number_of_attached_lines] + skip_comment: + lodsb + test al,al + jz file_ended + cmp al,0Ah + je comment_ended + cmp al,22h + je skip_quoted_string + cmp al,27h + je skip_quoted_string + cmp al,1Ah + jne skip_comment + lodsd + lea esi,[esi+eax+12] + jmp skip_comment + comment_ended: + test edx,edx + jnz preprocess_line_from_file + jmp line_ended + skip_quoted_string: + lodsd + add esi,eax + jmp skip_comment + convert_quoted_string: + stosb + mov eax,esi + stosd + lodsd + add esi,eax + jmp preprocess_line_from_file + convert_name_symbol: + mov ecx,[esi] + lea eax,[esi+4+ecx+12] + push eax ebx + mov eax,[eax-4] + test eax,eax + jz name_symbol_not_cached + mov esi,eax + name_symbol_not_cached: + call preprocess_symbol + name_symbol_converted: + pop ebx esi + jmp preprocess_line_from_file + convert_parameter: + cmp byte [esi],1Ah + jne preprocess_line_from_file + lodsb + mov ecx,[esi] + lea eax,[esi+4+ecx+12] + push eax ebx + mov eax,[eax-4] + test eax,eax + jz parameter_to_convert_not_cached + mov esi,eax + parameter_to_convert_not_cached: + call preprocess_symbol + jc name_symbol_converted + call convert_parameter_to_string + jmp name_symbol_converted + file_ended: + dec esi + line_ended: + sub esi,[ebx+SourceEntry.text] + mov [ebx+SourceEntry.offset],esi + jmp line_preprocessed + source_ended: + mov ebx,[source_context] + dec [ebx+SourceContext.number_of_entries] + jnz get_line + cmp [ebx+sizeof.SourceContext+SourceEntry.type],SOURCE_MEMORY + jne no_more_lines + mov esi,[source_file] + test esi,esi + jz no_more_lines + cmp byte [esi],0 + je no_more_lines + lea edi,[ebx+sizeof.SourceContext] + mov ecx,sizeof.SourceEntry shr 2 + assert sizeof.SourceEntry and 11b = 0 + xor eax,eax + rep stosd + call read_source + test eax,eax + jz main_source_file_not_found + mov ebx,[source_context] + inc [ebx+SourceContext.number_of_entries] + add ebx,sizeof.SourceContext + mov [ebx+SourceEntry.type],SOURCE_FILE + mov [ebx+SourceEntry.name],esi + mov [ebx+SourceEntry.text],eax + mov eax,[parameter_namespace] + mov [ebx+SourceEntry.local_namespace],eax + jmp get_line + no_more_lines: + jmp pass_done + get_line_from_macro: + mov edx,[ebx+SourceEntry.text] + mov esi,[edx+ValueDefinition.value] + mov ecx,[edx+ValueDefinition.value_length] + mov eax,[ebx+SourceEntry.offset] + test [ebx+SourceEntry.flags],SRCF_PREPROCESSED + jnz use_preprocessed_line + add ecx,esi + mov [source_end],ecx + add esi,eax + cmp esi,[source_end] + je macro_ended + mov [ebx+SourceEntry.line_offset],eax + mov edi,[preprocessing_workspace.memory_start] + preprocess_line_from_macro: + cmp esi,[source_end] + je macro_line_ended + mov ecx,14 + mov edx,preprocessing_workspace + call reserve_workspace + lodsb + cmp al,1Ah + je reproduce_name_symbol + test al,al + jz macro_line_ended + stosb + cmp al,22h + je reproduce_quoted_string + cmp al,27h + je reproduce_quoted_string + cmp al,30h + je reproduce_internal_token + cmp al,40h + je reproduce_context_token + cmp al,'`' + je conversion_operator_in_macro + jmp preprocess_line_from_macro + reproduce_quoted_string: + movsd + jmp preprocess_line_from_macro + reproduce_internal_token: + mov ecx,[esi] + add ecx,4 + mov edx,preprocessing_workspace + call reserve_workspace + lodsd + stosd + mov ecx,eax + rep movsb + jmp preprocess_line_from_macro + reproduce_context_token: + mov [preprocessed_context],esi + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep movsd + cmp esi,[source_end] + je macro_line_ended + cmp byte [esi],40h + jne preprocess_line_from_macro + inc esi + sub edi,sizeof.RecognitionContext + jmp reproduce_context_token + reproduce_name_symbol: + mov [name_token],esi + lodsd + push esi ebx + mov esi,eax + call preprocess_symbol + name_symbol_reproduced: + pop ebx esi + jmp preprocess_line_from_macro + conversion_operator_in_macro: + cmp esi,[source_end] + je macro_ended + cmp byte [esi],1Ah + jne preprocess_line_from_macro + inc esi + mov [name_token],esi + lodsd + push esi ebx + mov esi,eax + call preprocess_symbol + jc name_symbol_reproduced + call convert_parameter_to_string + jmp name_symbol_reproduced + convert_parameter_to_string: + call convert_symbolic_value_to_string + mov ebx,[memory_source_cache] + xor eax,eax + call put_into_map + mov edi,[symbol_value_start] + dec edi + mov al,22h + stosb + mov eax,esi + stosd + retn + macro_ended: + mov edx,[ebx+SourceEntry.text] + and [edx+ValueDefinition.flags],not VAL_IN_USE + dec [edx+ValueDefinition.reference_count] + mov ebx,[source_context] + dec [ebx+SourceContext.number_of_entries] + jnz get_line + jmp pass_done + use_preprocessed_line: + test eax,eax + jnz macro_ended + dec eax + mov [ebx+SourceEntry.offset],eax + add ecx,esi + mov [line_start],esi + mov [line_end],ecx + jmp got_line + macro_line_ended: + mov edx,[ebx+SourceEntry.text] + sub esi,[edx+ValueDefinition.value] + mov [ebx+SourceEntry.offset],esi + line_preprocessed: + mov [line_end],edi + mov esi,[preprocessing_workspace.memory_start] + mov [line_start],esi + got_line: + and [line_context],0 +assemble_instruction: + mov ebx,[interceptor_symbol] + call get_available_value + jc no_interceptor + test [edx+ValueDefinition.flags],VAL_UNCONDITIONAL + jz weak_interceptor + jmp execute_instruction + no_interceptor: + xor edx,edx + weak_interceptor: + mov [interceptor],edx + xor eax,eax + mov [label_interceptor],eax + test [assembly_mode],AMODE_CALM_DEFINITION + jnz assemble_alm_instruction + mov [symbol_definition],al + mov [instruction_branch],eax + mov dl,SYMCLASS_INSTRUCTION + call identify_symbol + jc empty_line + mov [label_branch],edx + mov al,[symbol_independent] + mov [label_independent],al + test ebx,ebx + jz unrecognized_instruction + cmp [ebx+SymbolTree_Leaf.class],SYMCLASS_INSTRUCTION + jne labeled_instruction + cmp [symbol_independent],-1 + je unrecognized_instruction + call get_available_value + jc unrecognized_instruction + test [edx+ValueDefinition.flags],VAL_UNCONDITIONAL + jnz execute_instruction + cmp [interceptor],0 + jne unrecognized_instruction + test [assembly_mode],AMODE_SKIP or AMODE_DEFINITION + jnz unrecognized_instruction + execute_instruction: + mov al,[edx+ValueDefinition.type] + cmp al,VALTYPE_CALM + je launch_calm + cmp al,VALTYPE_NATIVE_COMMAND + je execute_native_instruction + cmp al,VALTYPE_SYMBOLIC + je use_macro + cmp al,VALTYPE_RESERVED + jne unrecognized_instruction + mov edx,_symbolic_self_reference + call register_error + unrecognized_instruction: + test [assembly_mode],AMODE_SKIP + jnz assembly_line + test [assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + cmp [interceptor],0 + jne execute_interceptor + cmp [label_interceptor],0 + jne execute_label_interceptor + mov ebx,[other_interceptor_symbol] + call get_available_value + jnc execute_other_interceptor + mov edx,_illegal_instruction + call register_error + mov ebx,[label_branch] + test ebx,ebx + jz assembly_line + mov [symbol_class],SYMCLASS_INSTRUCTION + or [symbol_required],1 + or [symbol_expected],1 + call scan_symbol_branch + xor edx,edx + call mark_symbol_as_used + mov ebx,[instruction_branch] + test ebx,ebx + jz assembly_line + mov [symbol_class],SYMCLASS_STRUCTURE + or [symbol_required],1 + or [symbol_expected],1 + call scan_symbol_branch + xor edx,edx + call mark_symbol_as_used + jmp assembly_line + labeled_instruction: + mov [label_leaf],ebx + mov [label_instruction_start],esi + mov ebx,[label_interceptor_symbol] + call get_available_value + jc no_label_interceptor + test [edx+ValueDefinition.flags],VAL_UNCONDITIONAL + jnz execute_labeled_instruction + mov [label_interceptor],edx + mov eax,[embedded_context] + mov [label_instruction_context],eax + jmp identify_structure_instruction + no_label_interceptor: + call move_to_next_symbol + jc unrecognized_instruction ; orphan label + cmp al,':' + je define_label + cmp al,'=' + je define_numeric_symbol + identify_structure_instruction: + mov dl,SYMCLASS_STRUCTURE + call identify_symbol + mov [instruction_branch],edx + test ebx,ebx + jz unrecognized_instruction + cmp [ebx+SymbolTree_Leaf.class],SYMCLASS_STRUCTURE + jne unrecognized_instruction + call get_available_value + jc unrecognized_instruction + test [edx+ValueDefinition.flags],VAL_UNCONDITIONAL + jnz execute_labeled_instruction + test [assembly_mode],AMODE_SKIP or AMODE_DEFINITION + jnz unrecognized_instruction + cmp [interceptor],0 + jne execute_interceptor + cmp [label_interceptor],0 + jne execute_label_interceptor + execute_labeled_instruction: + mov al,[edx+ValueDefinition.type] + cmp al,VALTYPE_CALM + je launch_calm + cmp al,VALTYPE_SYMBOLIC + je use_struc + cmp al,VALTYPE_NATIVE_COMMAND + jne unrecognized_instruction + execute_native_instruction: + mov eax,[current_pass] + mov [ebx+SymbolTree_Leaf.last_use_pass],eax + jmp [edx+ValueDefinition.value] + empty_line: + mov al,[assembly_mode] + and al,AMODE_SKIP or AMODE_DEFINITION + cmp al,AMODE_DEFINITION + je add_line_to_macro + jmp assembly_line + execute_interceptor: + mov ebx,[interceptor_symbol] + mov edx,[interceptor] + xor eax,eax + mov [embedded_context],eax + mov esi,[line_start] + jmp execute_instruction + execute_label_interceptor: + mov ebx,[label_interceptor_symbol] + mov edx,[label_interceptor] + mov eax,[label_instruction_context] + mov [embedded_context],eax + mov esi,[label_instruction_start] + cmp [edx+ValueDefinition.type],VALTYPE_CALM + je launch_calm + jmp use_struc + execute_other_interceptor: + mov ebx,[other_interceptor_symbol] + xor eax,eax + mov [embedded_context],eax + mov esi,[line_start] + jmp execute_instruction +instruction_assembled: + cmp [current_constituent],0 + jne extra_characters_on_line + call warp_to_next_symbol + jc assembly_line + extra_characters_on_line: + mov edx,_extra_characters_on_line + call register_error + jmp assembly_line + pass_done: + mov dl,DBLOCK_CONTROL + call find_directive_block + jc assemble_postponed_block + mov esi,edi + sub esi,[edi+DirectiveBlock.length_of_data] + mov edx,_missing_end_directive + call register_delayed_error + call close_control_directive_block + jmp pass_done + assemble_postponed_block: + mov dl,DBLOCK_POSTPONED + call find_directive_block + jc no_postponed_blocks + mov ebx,edi + mov esi,edi + sub esi,[edi+DirectiveBlock.length_of_data] + mov edi,[source_context] + call clone_source_context + mov edi,ebx + call close_directive_block + or [assembly_mode],AMODE_POSTPONED + jmp assembly_line + no_postponed_blocks: + mov ebx,[root_namespace] + call detect_mispredictions + assemble_suspended_block: + mov dl,DBLOCK_SUSPENDED + call find_directive_block + jc no_suspended_blocks + cmp [next_pass_needed],0 + jne ignore_suspended_block + mov ebx,edi + mov esi,edi + sub esi,[edi+DirectiveBlock.length_of_data] + mov edi,[source_context] + call clone_source_context + mov edi,ebx + call close_directive_block + or [assembly_mode],AMODE_POSTPONED + jmp assembly_line + ignore_suspended_block: + call close_directive_block + jmp assemble_suspended_block + no_suspended_blocks: + mov esi,[directives_stack] + signal_unclosed_blocks: + cmp esi,[directives_stack_base] + je unclosed_blocks_signalled + sub esi,sizeof.DirectiveBlock + mov eax,[esi+DirectiveBlock.length_of_data] + sub esi,eax + mov edx,_missing_end_directive + call register_delayed_error + jmp signal_unclosed_blocks + unclosed_blocks_signalled: + xor eax,eax + xchg eax,[current_area] + dec [eax+ValueDefinition.reference_count] + mov al,[next_pass_needed] + sub al,1 + retn + main_source_file_not_found: + mov ebx,esi + mov edx,_source_file_not_found + call register_error + no_source_to_assemble: + mov esi,zero_value + mov ecx,4+4 + call create_output_area + mov [current_area],edx + inc [edx+ValueDefinition.reference_count] + stc + retn + +initialize_workspace: +; in: +; edx - Workspace +; preserves: ebx, edx, esi, edi + push edx + mov ecx,1000h + call malloc_growable + pop edx + mov [edx+Workspace.memory_start],eax + add eax,ecx + mov [edx+Workspace.memory_end],eax + retn + +reserve_workspace: +; in: +; edx - Workspace +; edi - top of used workspace area +; ecx = size of required reserve +; out: +; cf set if workspace had to be expanded +; edi - top of used workspace area (possibly relocated when cf is set) +; preserves: ebx, edx, esi + mov eax,[edx+Workspace.memory_end] + sub eax,ecx + jc not_enough_workspace + cmp edi,eax + ja not_enough_workspace + clc + retn + not_enough_workspace: + add ecx,edi + jc allocation_overflow + sub ecx,[edx+Workspace.memory_start] + push ecx + bsr eax,ecx + xchg ecx,eax + dec cl + shr eax,cl + inc eax + shl eax,cl + mov ecx,eax + pop eax + cmp ecx,eax + jbe allocation_overflow + cmp edi,[edx+Workspace.memory_start] + je reestablish_workspace + expand_workspace: + mov eax,[edx+Workspace.memory_start] + sub edi,eax + push edx + call realloc + pop edx + update_workspace: + mov [edx+Workspace.memory_start],eax + add edi,eax + add eax,ecx + mov [edx+Workspace.memory_end],eax + stc + retn + reestablish_workspace: + push edx ecx + xor eax,eax + xchg eax,[edx+Workspace.memory_start] + call mfree + pop ecx + call malloc_growable + pop edx + xor edi,edi + jmp update_workspace + allocation_overflow: + jmp out_of_memory + +grow_stack: +; in: +; eax = base address of memory block containing stack data +; ecx = required minimum size of memory block +; out: +; eax = new base address of memory block containing stack data +; ecx = new size of memory block +; preserves: ebx, esi, edi + push ecx + bsr edx,ecx + xchg ecx,edx + sub cl,2 + shr edx,cl + inc edx + shl edx,cl + mov ecx,edx + pop edx + cmp ecx,edx + jbe allocation_overflow + call realloc + retn + +create_source_entry: +; out: +; cf set when the maximum number of entries in context has been exceeded +; when cf = 0: +; ebx - new SourceEntry in the main SourceContext +; preserves: edx, esi + mov ebx,[source_context] + mov eax,[ebx+SourceContext.number_of_entries] + cmp eax,[maximum_depth_of_stack] + jae source_context_full + inc [ebx+SourceContext.number_of_entries] + imul eax,sizeof.SourceEntry + add eax,sizeof.SourceContext + mov edi,eax + add eax,sizeof.SourceEntry + cmp eax,[source_context_maximum_length] + jbe source_context_length_ok + mov ecx,eax + mov eax,ebx + mov ebx,edx + call realloc + mov [source_context],eax + mov [source_context_maximum_length],ecx + mov edx,ebx + mov ebx,eax + source_context_length_ok: + add ebx,edi + mov edi,ebx + mov ecx,sizeof.SourceEntry shr 2 + assert sizeof.SourceEntry and 11b = 0 + xor eax,eax + rep stosd + cmp [alm_statement],0 + je source_entry_created + mov [edi-sizeof.SourceEntry+SourceEntry.flags],SRCF_ALM_STATEMENT + source_entry_created: + clc + retn + source_context_full: + stc + retn + +create_parameter_namespace: +; out: +; eax - SymbolTree_Root +; preserves: ebx, edx, esi, edi + mov ecx,sizeof.SymbolTree_Root + sizeof.SymbolTree_LocalNode + call create_tree_element + or [eax+SymbolTree_Root.attributes],SYMTREE_LOCAL + or [eax+SymbolTree_Root.flags],NAMESPACE_UNATTACHED + retn + +clone_source_context: +; in: +; esi - SourceContext +; edi - buffer +; out: +; edi = pointer advanced past the stored data +; preserves: ebx + cmp edi,[source_context] + sete [source_context_affected] + mov eax,[esi+SourceContext.number_of_entries] + assert sizeof.SourceContext and 11b = 0 + mov ecx,sizeof.SourceContext shr 2 + rep movsd + test eax,eax + jnz clone_source_entry + retn + clone_source_entry: + assert SOURCE_FILE < SOURCE_MACRO & SOURCE_MEMORY < SOURCE_MACRO & SOURCE_CALM > SOURCE_MACRO + cmp [esi+SourceEntry.type],SOURCE_MACRO + jb copy_source_entry + mov edx,[esi+SourceEntry.text] + inc [edx+ValueDefinition.reference_count] + cmp [source_context_affected],0 + je copy_source_entry + or [edx+ValueDefinition.flags],VAL_IN_USE + copy_source_entry: + assert sizeof.SourceEntry and 11b = 0 + mov ecx,sizeof.SourceEntry shr 2 + rep movsd + dec eax + jnz clone_source_entry + retn + +release_source_context: +; in: +; eax - SourceContext +; preserves: eax, ebx, esi, edi + cmp eax,[source_context] + sete [source_context_affected] + push eax + mov ecx,[eax+SourceContext.number_of_entries] + add eax,sizeof.SourceContext + test ecx,ecx + jnz release_source_entry + pop eax + retn + release_source_entry: + assert SOURCE_FILE < SOURCE_MACRO & SOURCE_MEMORY < SOURCE_MACRO & SOURCE_CALM > SOURCE_MACRO + cmp [eax+SourceEntry.type],SOURCE_MACRO + jb source_entry_released + mov edx,[eax+SourceEntry.text] + dec [edx+ValueDefinition.reference_count] + cmp [source_context_affected],0 + je source_entry_released + and [edx+ValueDefinition.flags],not VAL_IN_USE + source_entry_released: + add eax,sizeof.SourceEntry + loop release_source_entry + pop eax + retn + +get_file_source_entry: +; out: +; ebx - SourceEntry in the main SourceContext +; preserves: edx, esi, edi + mov ebx,[source_context] + mov ecx,[ebx+SourceContext.number_of_entries] + mov eax,ecx + imul eax,sizeof.SourceEntry + lea ebx,[ebx+sizeof.SourceContext+eax] + find_file_source_entry: + sub ebx,sizeof.SourceEntry + cmp [ebx+SourceEntry.type],SOURCE_FILE + loopne find_file_source_entry + retn + +preprocess_symbol: +; in: +; esi - contents of the name token (32-bit length and name followed by two hashes) +; edi - pointer into preprocessing_workspace where the preprocessed text should be stored +; out: +; edi - just after the preprocessed text +; cf set when symbol was used as-is (was not recognized as a parameter) +; when cf = 0: +; [symbol_value_start] - start of the preprocessed text +; [symbol_value_end] - end of the preprocessed text (the same as edi) + mov eax,edi + sub eax,[preprocessing_workspace.memory_start] + mov [symbol_value_start],eax + mov [symbol_data],esi + lodsd + mov ecx,eax + mov eax,[esi+ecx+4] + mov [case_insensitive_hash],eax + mov edx,[esi+ecx] + mov [name_kind],NAME_CASESENSITIVE + mov ebx,[parameter_namespace] + call scan_namespace + jnc parameter_found + mov [name_kind],NAME_CASEINSENSITIVE + mov ebx,[parameter_namespace] + test [ebx+SymbolTree_Root.attributes],SYMTREE_WITH_CASEINSENSITIVE_PARAMETERS + jz no_local_parameter_recognized + mov edx,[case_insensitive_hash] + call scan_namespace + jnc parameter_found + no_local_parameter_recognized: + cmp byte [esi],'%' + jne no_parameter_recognized + cmp ecx,2 + ja no_parameter_recognized + jb current_counter_value + cmp byte [esi+1],'%' + je current_limit_value + no_parameter_recognized: + mov edi,[preprocessing_workspace.memory_start] + add edi,[symbol_value_start] + mov al,1Ah + stosb + mov eax,[symbol_data] + stosd + stc + retn + parameter_found: + mov edi,[preprocessing_workspace.memory_start] + add edi,[symbol_value_start] + mov edx,[ebx+SymbolTree_Leaf.definition] + mov al,[edx+ValueDefinition.type] + cmp al,VALTYPE_SYMBOLIC + je simple_parameter_value + cmp al,VALTYPE_SYMBOLIC_SEQUENCE + je iterator_value + cmp al,VALTYPE_NUMERIC_SEQUENCE + je named_counter_value + cmp al,VALTYPE_NATIVE_COMMAND + jne no_parameter_recognized + jmp [edx+ValueDefinition.value] + current_counter_value: + mov ebx,[parameter_namespace] + test [ebx+SymbolTree_Root.parameters],SPECPARM_COUNTER + jz no_parameter_recognized + mov esi,[current_counter] + mov dl,DBLOCK_CONTROL + call find_directive_block + find_breakable_block: + jc no_parameter_recognized + test [edi+DirectiveBlock.flags],CTRLF_BREAKABLE + jz look_deeper_for_breakable_block + mov eax,[parameter_namespace] + cmp eax,[edi+DirectiveBlock.parameter_namespace] + je found_breakable_block + look_deeper_for_breakable_block: + mov esi,[edi+DirectiveBlock.prior_counter_position] + add esi,[counters_stack_base] + call find_next_directive_block + jmp find_breakable_block + found_breakable_block: + cmp byte [esi],0 + je no_parameter_recognized + mov edi,[preprocessing_workspace.memory_start] + add edi,[symbol_value_start] + movzx ecx,byte [esi] + add ecx,6 + mov edx,preprocessing_workspace + call reserve_workspace + mov al,30h + stosb + mov edx,edi + xor eax,eax + lodsb + stosd + mov ecx,eax + rep movsb + test byte [edi-1],80h + jz parameter_replaced + xor al,al + stosb + inc dword [edx] + jmp parameter_replaced + current_limit_value: + mov ebx,[parameter_namespace] + test [ebx+SymbolTree_Root.parameters],SPECPARM_LIMIT + jz no_parameter_recognized + mov dl,DBLOCK_CONTROL + call find_directive_block + find_block_with_limit: + jc no_parameter_recognized + test [edi+DirectiveBlock.flags],CTRLF_BREAKABLE + jz look_deeper_for_block_with_limit + test [edi+DirectiveBlock.flags],CTRLF_HAS_REPEAT_DATA + jz look_deeper_for_block_with_limit + mov eax,[parameter_namespace] + cmp eax,[edi+DirectiveBlock.parameter_namespace] + je found_block_with_limit + look_deeper_for_block_with_limit: + call find_next_directive_block + jmp find_block_with_limit + found_block_with_limit: + mov ebx,edi + sub ebx,sizeof.RepeatData + mov edi,[preprocessing_workspace.memory_start] + add edi,[symbol_value_start] + mov ecx,[ebx+RepeatData.limit_length] + add ecx,6 + mov edx,preprocessing_workspace + call reserve_workspace + mov al,30h + stosb + mov edx,edi + mov eax,[ebx+RepeatData.limit_length] + stosd + sub ebx,eax + mov esi,ebx + mov ecx,eax + rep movsb + test byte [edi-1],80h + jz parameter_replaced + xor al,al + stosb + inc dword [edx] + jmp parameter_replaced + named_counter_value: + mov edx,[edx+ValueDefinition.value] + mov ebx,[edx] + add ebx,[counters_stack_base] + cmp byte [ebx],0 + je no_parameter_recognized + add edx,4 + movzx ecx,byte [ebx] + cmp ecx,[edx] + jae estimate_counter_length + mov ecx,[edx] + estimate_counter_length: + add ecx,6 + mov esi,edx + mov edx,preprocessing_workspace + call reserve_workspace + mov al,30h + stosb + xor eax,eax + stosd + push edi + movzx ecx,byte [ebx] + inc ebx + lodsd + sub eax,ecx + jnc counter_base_selected + add ecx,eax + neg eax + xchg ebx,esi + counter_base_selected: + mov edx,eax + jecxz counter_added_to_base + xor ah,ah + add_counter_to_base: + lodsb + add al,ah + setc ah + add al,[ebx] + adc ah,0 + inc ebx + add al,-1 + adc ah,0 + stosb + loop add_counter_to_base + counter_added_to_base: + mov ecx,edx + jecxz counter_carried + carry_counter: + lodsb + add al,ah + setc ah + add al,-1 + adc ah,0 + stosb + loop carry_counter + counter_carried: + pop edx + mov al,ah + dec al + jnz extend_counter_value + cmp edx,edi + je counter_value_finished + test byte [edi-1],80h + jz counter_value_finished + extend_counter_value: + stosb + counter_value_finished: + mov ecx,edi + sub ecx,edx + mov [edx-4],ecx + jmp parameter_replaced + iterator_value: + mov edx,[edx+ValueDefinition.value] + mov ebx,[edx] + add ebx,[counters_stack_base] + movzx ecx,byte [ebx] + test ecx,ecx + jz no_parameter_recognized + push edi + mov edi,value_index + xor eax,eax + mov [edi],eax + mov esi,ebx + inc esi + rep movsb + mov eax,[value_index] + pop edi + shl eax,2 + mov esi,[edx+eax] + mov ecx,[edx+eax+4] + sub ecx,esi + add esi,edx + jmp copy_parameter_value + simple_parameter_value: + mov esi,[edx+ValueDefinition.value] + mov ecx,[edx+ValueDefinition.value_length] + copy_parameter_value: + push ecx + mov edx,preprocessing_workspace + call reserve_workspace + pop ecx + cmp [preprocessed_context],0 + jne copy_with_preprocessed_context + rep movsb + jmp parameter_replaced + copy_token_pointer: + movsd + sub ecx,4 + copy_with_preprocessed_context: + test ecx,ecx + jz parameter_replaced + lodsb + stosb + dec ecx + cmp al,1Ah + je copy_token_pointer + cmp al,22h + je copy_token_pointer + cmp al,27h + je copy_token_pointer + cmp al,30h + je copy_token_data + cmp al,40h + jne copy_with_preprocessed_context + mov eax,ecx + cmp dword [esi],0 + jne copy_parameter_context + mov edx,esi + mov esi,[preprocessed_context] + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep movsd + lea esi,[edx+sizeof.RecognitionContext] + mov ecx,eax + sub ecx,sizeof.RecognitionContext + jmp copy_with_preprocessed_context + copy_parameter_context: + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep movsd + mov ecx,eax + sub ecx,sizeof.RecognitionContext + jmp copy_with_preprocessed_context + copy_token_data: + lodsd + stosd + sub ecx,4 + sub ecx,eax + xchg ecx,eax + rep movsb + xchg ecx,eax + jmp copy_with_preprocessed_context + local_symbol_name: + mov ecx,1+sizeof.RecognitionContext+1+4+1+sizeof.RecognitionContext + mov edx,preprocessing_workspace + call reserve_workspace + mov al,40h + stosb + mov eax,[local_namespace] + mov [edi+RecognitionContext.base_namespace],eax + xor eax,eax + mov [edi+RecognitionContext.base_label],eax + add edi,sizeof.RecognitionContext + mov al,1Ah + stosb + mov eax,[symbol_data] + stosd + mov al,40h + stosb + mov esi,[preprocessed_context] + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + test esi,esi + jz reset_context + rep movsd + stc + retn + reset_context: + xor eax,eax + rep stosd + stc + retn + parameter_replaced: + mov [symbol_value_end],edi + mov eax,[preprocessing_workspace.memory_start] + add [symbol_value_start],eax + clc + retn + +convert_symbolic_value_to_string: +; in: +; [symbol_value_start] - start of the preprocessed text to convert +; [symbol_value_end] - end of the preprocessed text to convert +; out: +; esi - 32-bit length followed by string data +; ecx = total length of string data (including the length prefix) + mov esi,[symbol_value_start] + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + add edi,4 + convert_token_to_text: + mov ecx,[symbol_value_end] + sub ecx,esi + jbe finish_conversion + mov edx,assembly_workspace + call reserve_workspace + lodsb + cmp al,1Ah + je convert_name_token_to_text + cmp al,22h + je convert_string_token_to_text + cmp al,27h + je convert_string_token_to_text + cmp al,30h + je convert_internal_number_to_text + cmp al,40h + je ignore_context_token + stosb + jmp convert_token_to_text + ignore_context_token: + add esi,sizeof.RecognitionContext + jmp convert_token_to_text + convert_name_token_to_text: + lodsd + mov ebx,esi + mov esi,eax + mov ecx,[esi] + mov edx,assembly_workspace + call reserve_workspace + lodsd + mov ecx,eax + rep movsb + mov esi,ebx + jmp convert_token_to_text + convert_string_token_to_text: + lodsd + mov ebx,esi + mov esi,eax + call enclose_string + mov esi,ebx + cmp byte [esi-4-1],27h + jne convert_token_to_text + dec edi + jmp convert_token_to_text + enclose_string: + mov ecx,[esi] + inc ecx + shl ecx,1 + mov edx,assembly_workspace + call reserve_workspace + lodsd + mov ecx,eax + mov al,27h + stosb + copy_string_characters: + jecxz string_characters_copied + lodsb + stosb + dec ecx + cmp al,27h + jne copy_string_characters + stosb + jmp copy_string_characters + string_characters_copied: + mov al,27h + stosb + retn + convert_internal_number_to_text: + mov edx,esi + lodsd + add esi,eax + push esi edi + call convert_number_back + pop edi + mov esi,edx + mov ecx,[esi] + mov edx,assembly_workspace + call reserve_workspace + lodsd + mov ecx,eax + rep movsb + pop esi + jmp convert_token_to_text + finish_conversion: + mov esi,[assembly_workspace.memory_start] + mov ecx,edi + sub ecx,esi + lea eax,[ecx-4] + mov [esi],eax + retn + +compare_symbolic_values: +; in: +; esi - first symbolic value +; edi - second symbolic value +; ecx = length to compare +; out: +; ecx = zero when values equal, or a number of bytes following the point of difference +; esi - the point of difference in first value +; edi - the point of difference in second value + mov al,[esi] + cmp al,[edi] + jne symbolic_values_compared + inc esi + inc edi + cmp al,1Ah + je compare_tokens_with_data + cmp al,22h + je compare_tokens_with_data + cmp al,27h + je compare_tokens_with_data + cmp al,30h + je compare_internal_tokens + cmp al,40h + je compare_context_tokens + loop compare_symbolic_values + symbolic_values_compared: + retn + compare_tokens_with_data: + dec ecx + mov eax,[esi] + mov edx,[edi] + cmp eax,edx + jne compare_token_data + add esi,4 + add edi,4 + sub ecx,4 + jnz compare_symbolic_values + retn + compare_token_data: + mov ebx,[eax] + cmp ebx,[edx] + jne symbolic_values_compared + add eax,ebx + add edx,ebx + xchg esi,eax + xchg edi,edx + xchg ecx,ebx + dec ecx + shr ecx,2 + inc ecx + cmp byte [eax-1],1Ah + jne compare_token_dwords + inc ecx + add esi,4 + add edi,4 + compare_token_dwords: + std + repe cmpsd + cld + jne token_data_content_differs + lea esi,[eax+4] + lea edi,[edx+4] + mov ecx,ebx + sub ecx,4 + jnz compare_symbolic_values + retn + token_data_content_differs: + mov esi,eax + mov edi,edx + mov ecx,ebx + retn + compare_internal_tokens: + mov eax,[esi] + cmp eax,[edi] + jne symbolic_values_compared + add esi,4 + add edi,4 + sub ecx,1+4 + sub ecx,eax + xchg ecx,eax + repe cmpsb + je internal_tokens_equal + inc ecx + dec esi + dec edi + add ecx,eax + retn + internal_tokens_equal: + add ecx,eax + jnz compare_symbolic_values + retn + compare_context_tokens: + dec ecx + assert sizeof.RecognitionContext and 11b = 0 + mov edx,sizeof.RecognitionContext shr 2 + compare_contexts: + mov eax,[esi] + cmp eax,[edi] + jne symbolic_values_compared + add esi,4 + add edi,4 + sub ecx,4 + jz symbolic_values_compared + dec edx + jnz compare_contexts + jmp compare_symbolic_values + +move_to_next_symbol: +; in: +; esi = pointer into preprocessed line or current embedded value +; zeroed ecx is recommended for whitespace detection +; out: +; esi = pointer advanced past the whitespace and context tokens +; cf set when reached end of line or embedded value +; ecx increased when there was whitespace on the way, preserved otherwise +; when cf = 0: +; esi - next symbol +; al = initial byte of the next symbol +; preserves: ebx, edx, edi +; note: +; [embedded_context] is updated to point to a RecognitionContext that should be in force at the new position (null means current namespace context); + cmp esi,[line_end] + jb next_token_available + stc + retn + next_token_available: + mov al,[esi] + cmp al,40h + je set_embedded_context + cmp al,20h + je pass_whitespace + clc + retn + pass_whitespace: + inc esi + inc ecx + jmp move_to_next_symbol + set_embedded_context: + inc esi + cmp [esi+RecognitionContext.base_namespace],0 + je restore_embedded_context + mov [embedded_context],esi + add esi,sizeof.RecognitionContext + jmp move_to_next_symbol + restore_embedded_context: + add esi,sizeof.RecognitionContext + mov eax,[number_of_line_embeddings] + test eax,eax + jz clear_embedded_context + dec eax + imul eax,sizeof.LineEmbedding + add eax,[line_embeddings] + mov eax,[eax+LineEmbedding.recognition_context] + mov [embedded_context],eax + jmp move_to_next_symbol + clear_embedded_context: + and [embedded_context],0 + jmp move_to_next_symbol + +warp_to_next_symbol: +; in: +; esi = pointer into preprocessed line or current embedded value +; zeroed ecx is recommended for whitespace detection +; out: +; esi - next symbol +; cf set when end of line reached +; ecx increased when there was whitespace on the way, preserved otherwise +; when cf = 0: +; al = initial byte of the next symbol +; preserves: ebx, edx, edi +; note: +; [embedded_context] is updated to point to a RecognitionContext that should be in force at the new position (null means current namespace context); + call move_to_next_symbol + jc warp_through_embedding_boundary + retn + warp_through_embedding_boundary: + mov eax,[number_of_line_embeddings] + sub eax,1 + jc reached_end_of_line + mov [number_of_line_embeddings],eax + imul eax,sizeof.LineEmbedding + add eax,[line_embeddings] + mov esi,eax + push edx + add ecx,[esi+LineEmbedding.whitespace] + mov edx,[esi+LineEmbedding.recognition_context] + mov [embedded_context],edx + mov edx,[esi+LineEmbedding.definition] + dec [edx+ValueDefinition.reference_count] + and [edx+ValueDefinition.flags],not VAL_IN_USE + mov edx,[esi+LineEmbedding.previous_end] + mov [line_end],edx + mov esi,[esi+LineEmbedding.previous_pointer] + pop edx + jmp warp_to_next_symbol + reached_end_of_line: + ; stc + retn + +cut_piece_of_line: +; in: +; esi = pointer into preprocessed line or current embedded value +; edi - LineExcerpt to be filled with information about cut piece of line +; dl = initial byte of symbol that should end the cut value, zero to cut up to the end of line (or current embedded value) +; dh = initial byte of symbol that would open the nested piece, zero for no nesting +; [breakpoint_token] = initial byte of symbol that should unconditionally end the cut value if it is met +; out: +; esi = pointer advanced past the cut piece +; al = initial byte of symbol at pointer, zero when no more symbols there +; preserves: ebx, edx, edi +; note: when [breakpoint_token] has the same value as either dl or dh, it has no effect + mov [number_of_enclosings],1 + call move_to_next_symbol + mov [edi+LineExcerpt.data_start],esi + mov [edi+LineExcerpt.data_end],esi + jc last_piece_in_line + mov ecx,[embedded_context] + mov [edi+LineExcerpt.recognition_context],ecx + cut_piece: + cmp al,dh + je nested_piece + cmp al,dl + je close_nested_piece + cmp al,[breakpoint_token] + jne cut_token + retn + nested_piece: + inc [number_of_enclosings] + jmp cut_token + close_nested_piece: + dec [number_of_enclosings] + jz end_of_piece + cut_token: + cmp al,1Ah + je cut_token_with_data + cmp al,22h + je cut_token_with_data + cmp al,27h + je cut_token_with_data + cmp al,30h + je cut_internal_token + inc esi + cut_next_token: + mov [edi+LineExcerpt.data_end],esi + call move_to_next_symbol + jnc cut_piece + last_piece_in_line: + xor al,al + end_of_piece: + mov ecx,[embedded_context] + mov [edi+LineExcerpt.leftover_context],ecx + retn + cut_token_with_data: + add esi,1+4 + jmp cut_next_token + cut_internal_token: + inc esi + lodsd + add esi,eax + jmp cut_next_token + +extract_piece_of_line: +; in: +; esi = pointer into preprocessed line (not an embedded value) +; edi - buffer for token sequence, must be large enough to hold all the remaining tokens in line and an additional context token +; dl = initial byte of symbol that should end the cut value, zero to cut up to the end of line +; dh = initial byte of symbol that would open the nested piece, zero for no nesting +; [breakpoint_token] = initial byte of symbol that should unconditionally end the cut value if it is met +; [contextless_processing] = zero to have current context added to the extracted value +; out: +; esi = pointer advanced past the processed piece +; edi - end of the extracted sequence of tokens in provided buffer +; al = initial byte of symbol at pointer, zero when no more symbols there +; [context_boundary] = equal to edi if the extracted sequence ends with a context token +; preserves: ebx, edx +; note: +; when [breakpoint_token] has the same value as either dl or dh, it has no effect + and [context_boundary],0 + call move_to_next_symbol + jc no_piece_to_extract + mov [number_of_enclosings],1 + mov [whitespace_boundary],edi + mov al,40h + stosb + mov eax,[embedded_context] + test eax,eax + jz extract_current_context + xchg esi,eax + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep movsd + mov esi,eax + mov [context_boundary],edi + jmp extract_piece + extract_contextless: + dec edi + jmp extract_piece + extract_current_context: + cmp [contextless_processing],0 + jne extract_contextless + call store_current_context + extract_piece: + lodsb + cmp al,dh + je nested_piece_to_extract + cmp al,dl + je close_extracted_nested_piece + cmp al,[breakpoint_token] + je extraction_breakpoint + extract_token: + cmp al,40h + je extract_context_token + cmp al,20h + je extract_whitespace + and [whitespace_boundary],0 + stosb + cmp al,1Ah + je extract_token_with_data + cmp al,22h + je extract_token_with_data + cmp al,27h + je extract_token_with_data + cmp al,30h + je extract_internal_token + extract_next_token: + cmp esi,[line_end] + jne extract_piece + xor al,al + cmp [whitespace_boundary],0 + jne drop_final_whitespace + retn + nested_piece_to_extract: + inc [number_of_enclosings] + jmp extract_token + close_extracted_nested_piece: + dec [number_of_enclosings] + jnz extract_token + extraction_breakpoint: + dec esi + cmp [whitespace_boundary],0 + jne drop_final_whitespace + retn + drop_final_whitespace: + mov edi,[whitespace_boundary] + retn + no_piece_to_extract: + xor al,al + retn + extract_whitespace: + cmp [whitespace_boundary],0 + jne whitespace_boundary_ok + mov [whitespace_boundary],edi + whitespace_boundary_ok: + stosb + jmp extract_next_token + extract_token_with_data: + movsd + jmp extract_next_token + extract_internal_token: + lodsd + stosd + mov ecx,eax + rep movsb + jmp extract_next_token + extract_context_token: + cmp [whitespace_boundary],0 + jne context_whitespace_boundary_ok + mov [whitespace_boundary],edi + context_whitespace_boundary_ok: + mov [embedded_context],esi + cmp dword [esi],0 + jne embedded_context_for_extraction_ok + and [embedded_context],0 + embedded_context_for_extraction_ok: + call make_recognition_context_token + jmp extract_next_token + +make_recognition_context_token: +; in: +; al = 40h +; esi - RecognitionContext (contents of the context token) +; edi - buffer for the context token +; [context_boundary] = equal to edi if it is at the end of another context token +; [contextless_processing] = zero to convert context reset into a context switch capturing the current context +; out: +; esi - past the processed RecognitionContext +; edi - past the extracted context token +; [context_boundary] - past the extracted context token +; preserves: ebx, edx + cmp edi,[context_boundary] + je reuse_recognition_context + stosb + jmp store_recognition_context + reuse_recognition_context: + sub edi,sizeof.RecognitionContext + store_recognition_context: + ; in: + ; esi - RecognitionContext to read (may have base namespace zeroed to indicate context reset) + ; edi - RecognitionContext to fill + ; out: + ; esi - past the processed RecognitionContext + ; edi - past the filled RecognitionContext + ; [context_boundary] - past the filled RecognitionContext + ; [contextless_processing] = zero to convert context reset into a context switch capturing the current context + ; preserves: ebx, edx + cmp [contextless_processing],0 + jne copy_recognition_context + cmp [esi+RecognitionContext.base_namespace],0 + je capture_context_reset + copy_recognition_context: + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep movsd + mov [context_boundary],edi + retn + capture_context_reset: + add esi,sizeof.RecognitionContext + store_current_context: + ; in: + ; edi - RecognitionContext to fill + ; out: + ; edi - past the filled RecognitionContext + ; [context_boundary] - past the filled RecognitionContext + ; preserves: ebx, edx, esi + mov eax,[current_context.base_namespace] + mov ecx,[current_context.base_label] + mov [edi+RecognitionContext.base_namespace],eax + mov [edi+RecognitionContext.base_label],ecx + add edi,sizeof.RecognitionContext + mov [context_boundary],edi + retn + +embed_symbolic_value: +; in: +; ebx - SymbolTree_Leaf +; edx - ValueDefinition +; esi = pointer into preprocessed line or current embedded value +; ecx = number of whitespace tokens to imply after emdedding +; out: +; esi = pointer into embedded value +; preserves: ebx, edx + mov eax,[number_of_line_embeddings] + inc eax + mov [number_of_line_embeddings],eax + imul eax,sizeof.LineEmbedding + cmp eax,[line_embeddings_maximum_length] + jbe line_embedding_allocated + push eax ecx edx + mov ecx,sizeof.LineEmbedding + add ecx,[line_embeddings_maximum_length] + mov eax,[line_embeddings] + call grow_stack + mov [line_embeddings_maximum_length],ecx + mov [line_embeddings],eax + pop edx ecx eax + line_embedding_allocated: + sub eax,sizeof.LineEmbedding + add eax,[line_embeddings] + mov [eax+LineEmbedding.whitespace],ecx + mov edi,[line_end] + mov [eax+LineEmbedding.previous_pointer],esi + mov [eax+LineEmbedding.previous_end],edi + mov ecx,[embedded_context] + mov [eax+LineEmbedding.recognition_context],ecx + and [embedded_context],0 + mov esi,[edx+ValueDefinition.value] + mov ecx,[edx+ValueDefinition.value_length] + add ecx,esi + mov [line_end],ecx + mov [eax+LineEmbedding.definition],edx + inc [edx+ValueDefinition.reference_count] + or [edx+ValueDefinition.flags],VAL_IN_USE + retn + +clear_line_embeddings: +; preserves: ebx, ecx, edx, esi, edi +; note: +; when esi is said to point into preprocessed line or current embedded value, it must be between [line_start] and [line_end]; +; these two pointers change upon entering a symbolic value of evaluated identifier (with embed_symbolic_value) +; and are restored when warp_to_next_symbol goes past the end of that embedded value; +; this function needs to be called before setting up a new line for the assembly +; and it discards the stack of stored [line_start] and [line_end] boundaries + xor eax,eax + mov [line_start],eax + mov [line_end],eax + mov [embedded_context],eax + cmp eax,[number_of_line_embeddings] + je embedded_values_ok + push ecx + discard_line_embedding: + mov ecx,eax + imul ecx,sizeof.LineEmbedding + add ecx,[line_embeddings] + mov ecx,[ecx+LineEmbedding.definition] + dec [ecx+ValueDefinition.reference_count] + and [ecx+ValueDefinition.flags],not VAL_IN_USE + inc eax + cmp eax,[number_of_line_embeddings] + jne discard_line_embedding + and [number_of_line_embeddings],0 + pop ecx + embedded_values_ok: + retn + +identify_symbol_in_namespace: +; in: +; ebx - SymbolTree_Root +; esi = pointer into preprocessed line or current embedded value +; dl = SYMCLASS_# +; [symbol_definition] = non-zero when symbol needs to be identified for the purpose of definition +; out: +; cf set when there were no more symbols in preprocessed line or current embedded value +; esi = pointer advanced past the processed identifier and following whitespace or to the first token of a different symbol +; ecx = number of whitespace tokens encountered immediately before the new position +; when cf = 0: +; ebx - SymbolTree_Leaf, null when no symbol was identified +; edx - SymbolTree_Foliage, may be null if either ebx or edi is null +; edi - SymbolTree_Root, null when there was no identifier at all or when identified symbol is not in a namespace +; [symbol_start] - first token of identified symbol +; [symbol_independent] = zero when identifier is relative to current label, all bits set for special identifiers +; note: +; when ebx is null but edi is not, the identifier was malformed +; when edi is null but ebx is not, a special symbol was identified; this is possible only for SYMCLASS_INSTRUCTION and SYMCLASS_STRUCTURE + mov [expected_class],dl + xor ecx,ecx + call move_to_next_symbol + jnc namespaces_ok + retn +identify_symbol: +; in: +; esi = pointer into preprocessed line or current embedded value +; dl = SYMCLASS_# +; [symbol_definition] = non-zero when symbol needs to be identified for the purpose of definition +; out: +; cf set when there were no more symbols in preprocessed line or current embedded value +; esi = pointer advanced past the processed identifier and following whitespace or to the first token of a different symbol +; ecx = number of whitespace tokens encountered immediately before the new position +; [recognition_context] = applied recognition context +; when cf = 0: +; ebx - SymbolTree_Leaf, null when no symbol was identified +; edx - SymbolTree_Foliage, may be null if either ebx or edi is null +; edi - SymbolTree_Root, null when there was no identifier at all or when identified symbol is not in a namespace +; [symbol_start] - first token of identified symbol (within current embedded value or preprocessed line) +; [symbol_independent] = zero when identifier is relative to current label, all bits set for special identifiers +; note: +; when ebx is null but edi is not, the identifier was malformed +; when edi is null but ebx is not, a special symbol was identified; this is possible only for SYMCLASS_INSTRUCTION and SYMCLASS_STRUCTURE + mov [expected_class],dl + xor ecx,ecx + call move_to_next_symbol + jc identification_finished + xor ebx,ebx + mov edx,[embedded_context] + test edx,edx + jnz use_namespace + mov edx,current_context + use_namespace: + mov eax,[edx+RecognitionContext.base_namespace] + mov [recognition_context.base_namespace],eax + mov eax,[edx+RecognitionContext.base_label] + mov [recognition_context.base_label],eax + namespaces_ok: + mov [symbol_start],esi + and [symbol_independent],0 + cmp [symbol_definition],0 + setnz al + shl al,bsf RECOGNIZE_DEFINITION + mov [recognizer_setting],al + xor edx,edx + xor edi,edi + mov al,[esi] + cmp al,1Ah + je starting_with_name + cmp al,'.' + je starting_dot + cmp al,'#' + je starting_with_concatenation + cmp al,'?' + je starting_question_mark + return_no_identifier: + xor ebx,ebx + return_no_namespace: + xor edx,edx + xor edi,edi + clc + retn + starting_with_name: + call detect_numeric_symbol + jc return_no_identifier + valid_starting_name: + or [symbol_independent],1 + valid_name: + inc esi + mov [name_token],esi + lodsd + mov edi,eax + and [name_volatile],0 + xor ecx,ecx + identify_name: + mov dh,[recognizer_setting] + call move_to_next_symbol + jc run_recognizer + cmp al,'#' + jne name_complete + call check_concatenation + jnc name_concatenation + xor al,al + name_complete: + test ecx,ecx + jnz run_recognizer + cmp al,'?' + jne run_recognizer + or dh,RECOGNIZE_CASE_INSENSITIVE + inc esi + call move_to_next_symbol + jc run_recognizer + cmp al,'#' + jne name_modifiers_complete + call check_concatenation + jc run_recognizer + name_modifiers_complete: + test ecx,ecx + jnz run_recognizer + cmp al,1Ah + je malformed_identifier + run_recognizer: + push esi ecx + cmp esi,[line_end] + je recognize_final_symbol + test ecx,ecx + jnz recognize_final_symbol + cmp byte [esi],'.' + jne recognize_final_symbol + mov esi,edi + lodsd + mov ecx,eax + mov dl,SYMCLASS_EXPRESSION + and dh,not RECOGNIZE_DEFINITION + call recognize_symbol + pop ecx esi + dot_operator: + inc esi + xor ecx,ecx + call move_to_next_symbol + jc ending_with_dot + cmp al,'#' + je name_concatenation_after_dot + test ecx,ecx + jnz ending_with_dot + cmp al,'.' + je multiple_dot_operator + identify_name_after_dot: + cmp al,30h + je number_after_dot + cmp al,1Ah + jne ending_with_dot + call get_symbol_namespace + xor edi,edi + jmp valid_name + name_concatenation_after_dot: + call check_concatenation + jc ending_with_dot + cmp al,'.' + je multiple_dot_operator + number_after_dot: + call get_symbol_namespace + mov al,[esi] + xor edi,edi + jmp name_concatenation + recognize_final_symbol: + mov dl,[expected_class] + mov esi,edi + lodsd + mov ecx,eax + call recognize_symbol + pop ecx esi + symbol_identified: + clc + identification_finished: + retn + ending_with_dot: + mov al,[expected_class] + cmp al,SYMCLASS_EXPRESSION + jne find_expected_class + clc + retn + starting_question_mark: + inc esi + xor ecx,ecx + call move_to_next_symbol + jc alone_question_mark + cmp al,'#' + jne symbol_after_question_mark + call check_concatenation + jc alone_question_mark + symbol_after_question_mark: + test ecx,ecx + jnz alone_question_mark + cmp al,'?' + je repeated_question_mark + cmp [symbol_definition],0 + jne no_forced_definition + mov [expected_class],SYMCLASS_EXPRESSION + or [recognizer_setting],RECOGNIZE_DEFINITION + no_forced_definition: + cmp al,'.' + je starting_dot + cmp al,1Ah + je valid_starting_name + cmp al,30h + je concatenation_with_internal_number + alone_question_mark: + mov dl,[expected_class] + cmp dl,SYMCLASS_INSTRUCTION + je return_interceptor_symbol + cmp dl,SYMCLASS_STRUCTURE + je return_label_interceptor_symbol + mov eax,[symbol_start] + cmp byte [eax],'?' + jne malformed_identifier + mov esi,eax + jmp return_no_identifier + return_label_interceptor_symbol: + mov ebx,[label_interceptor_symbol] + jmp return_special_symbol + return_interceptor_symbol: + mov ebx,[interceptor_symbol] + return_special_symbol: + or [symbol_independent],-1 + jmp return_no_namespace + repeated_question_mark: + inc esi + xor ecx,ecx + call move_to_next_symbol + jc return_other_interceptor_symbol + cmp al,'#' + jne return_other_interceptor_symbol + call check_concatenation + jnc symbol_after_question_mark + return_other_interceptor_symbol: + cmp [expected_class],SYMCLASS_INSTRUCTION + jne malformed_identifier + mov ebx,[other_interceptor_symbol] + jmp return_special_symbol + multiple_dot_operator: + mov ebx,edi + xor edi,edi + jmp starting_dot + additional_dot: + inc edi + starting_dot: + inc esi + xor ecx,ecx + call move_to_next_symbol + jc alone_dot + cmp al,'#' + jne symbol_after_starting_dot + call check_concatenation + jc alone_dot + symbol_after_starting_dot: + test ecx,ecx + jnz alone_dot + cmp al,'.' + je additional_dot + cmp al,30h + je name_after_starting_dot + cmp al,1Ah + jne alone_dot + name_after_starting_dot: + test ebx,ebx + jnz name_after_multiple_dot_operator + call get_base_label + mov edi,ebx + mov al,[esi] + jmp identify_name_after_dot + name_after_multiple_dot_operator: + test edx,edx + jz parent_namespace_ready + call get_symbol_namespace + parent_namespace_ready: + call synthesize_dot_label + mov edi,ebx + mov al,[esi] + jmp identify_name_after_dot + alone_dot: + test ebx,ebx + jz identify_current_label + test edx,edx + jz malformed_identifier + push ecx + call get_symbol_namespace + pop ecx + call synthesize_dot_label + jmp get_label_symbol + malformed_identifier: + xor ebx,ebx + xor edx,edx + mov edi,[recognition_context.base_namespace] + jmp symbol_identified + identify_current_label: + call get_base_label + mov eax,[local_namespace] + test eax,eax + jz get_label_symbol + cmp edx,[eax+SymbolTree_Root.current_label] + jne get_label_symbol + test [eax+SymbolTree_Root.flags],NAMESPACE_LABEL_FORWARDING + setnz [symbol_independent] + get_label_symbol: + mov edi,ebx + mov al,[expected_class] + find_expected_class: + mov [symbol_class],al + mov al,[symbol_definition] + mov [symbol_required],al + mov [symbol_expected],al + mov ebx,edx + call scan_symbol_branch + jnc current_label_identified + mov [symbol_class],SYMCLASS_EXPRESSION + or [symbol_required],1 + or [symbol_expected],1 + mov ebx,edx + call scan_symbol_branch + current_label_identified: + clc + retn + get_base_label: + mov edx,[recognition_context.base_label] + test edi,edi + jnz synthesize_dot_label + test edx,edx + jnz current_label_ready + synthesize_dot_label: + push ecx esi + mov esi,[identifier_workspace.memory_start] + mov eax,edi + mov [esi],eax + mov edx,FNV_OFFSET + xor ecx,ecx + hash_dot_label: + test eax,eax + jz dot_label_synthesised + xor dl,al + imul edx,FNV_PRIME + inc ecx + shr eax,8 + jmp hash_dot_label + dot_label_synthesised: + or [name_volatile],1 + and [name_token],0 + mov [name_kind],NAME_NUMERIC + mov [symbol_class],SYMCLASS_EXPRESSION + or [symbol_required],1 + or [symbol_expected],1 + test ebx,ebx + jnz identify_dot_label + mov ebx,[recognition_context.base_namespace] + identify_dot_label: + call scan_namespace + pop esi ecx + current_label_ready: + mov ebx,[edx+SymbolTree_Foliage.root] + retn + starting_with_concatenation: + xor ecx,ecx + call check_concatenation + jc empty_concatenation + name_concatenation: + cmp al,30h + je concatenation_with_internal_number + cmp al,1Ah + jne empty_concatenation + test edi,edi + jz starting_with_name + inc esi + lodsd + push ebx esi + mov ebx,eax + attach_to_name: + mov esi,edi + mov edi,[identifier_workspace.memory_start] + cmp esi,edi + jne initial_concatenation + lodsd + add esi,eax + mov edi,esi + jmp get_precalculated_hashes + initial_concatenation: + test esi,esi + jz initial_conversion + mov ecx,[esi] + add ecx,4+8 + mov edx,identifier_workspace + call reserve_workspace + lodsd + stosd + mov ecx,eax + rep movsb + get_precalculated_hashes: + xchg ebx,esi + mov ecx,[esi] + mov eax,[identifier_workspace.memory_start] + add [eax],ecx + add ecx,8 + mov edx,identifier_workspace + call reserve_workspace + mov ecx,[ebx] + mov edx,[ebx+4] + lodsd + lea ebx,[esi+eax] + xor eax,eax + concatenation_hash: + lodsb + xor cl,al + xor dl,[characters+eax] + imul ecx,FNV_PRIME + imul edx,FNV_PRIME + stosb + cmp esi,ebx + jne concatenation_hash + mov eax,ecx + stosd + mov eax,edx + stosd + pop esi ebx + mov edi,[identifier_workspace.memory_start] + or [name_volatile],1 + and [name_token],0 + xor ecx,ecx + jmp identify_name + initial_conversion: + xor eax,eax + stosd + mov esi,edi + mov eax,FNV_OFFSET + mov [esi],eax + mov [esi+4],eax + jmp get_precalculated_hashes + concatenation_with_internal_number: + inc esi + mov edx,esi + lodsd + add esi,eax + push ebx esi + push edi + call convert_number_back + pop edi + mov ebx,edx + jmp attach_to_name + empty_concatenation: + test edi,edi + jnz identify_name_with_empty_concatenation + call move_to_next_symbol + jc malformed_identifier + cmp al,'.' + je starting_dot + cmp al,'?' + je starting_question_mark + jmp malformed_identifier + identify_name_with_empty_concatenation: + mov dh,[recognizer_setting] + call move_to_next_symbol + jc run_recognizer + jmp name_complete + +detect_numeric_symbol: +; in: +; esi - name token in preprocessed line or in current embedded value +; out: +; cf set when symbol starting with this token should be considered numeric +; preserves: ebx, ecx, edx, esi, edi + mov eax,[esi+1] + mov al,[eax+4] + cmp al,'$' + je detect_pascal_hexadecimal + sub al,'0' + cmp al,10 + jb numeric_symbol_detected + not_a_numeric_symbol: + clc + retn + detect_pascal_hexadecimal: + mov eax,[esi+1] + cmp dword [eax],2 + jb not_a_numeric_symbol + movzx eax,byte [eax+4+1] + mov al,[characters+eax] + sub al,'0' + cmp al,10 + jb numeric_symbol_detected + sub al,'a'-'0' + jc not_a_numeric_symbol + cmp al,16-10 + jae not_a_numeric_symbol + numeric_symbol_detected: + stc + retn + +check_concatenation: +; in: +; esi - concatenation character in preprocessed line or in current embedded value +; ecx = number of whitespace tokens encountered immediately before current position +; out: +; cf set when there is no concatenation applicable to previous symbol +; esi = pointer advanced past the processed operator and the whitespace that follows it +; ecx = number of whitespace tokens encountered immediately before the new position +; when cf = 0: +; esi - symbol that follows concatenation operator +; al = initial byte of symbol following concatenation operator +; preserves: ebx, edx, edi + test ecx,ecx + jnz no_concatenation + inc esi + call move_to_next_symbol + jc no_concatenation + cmp al,'#' + je check_concatenation + test ecx,ecx + jnz no_concatenation + ; clc + retn + no_concatenation: + stc + retn + +get_literal: +; in: +; esi - token in preprocessed line or in current embedded value +; out: +; al = type of value +; esi = pointer advanced past the processed literal and the whitespace that follows it +; ecx = number of whitespace tokens encountered immediately before the new position +; when al = 22h: +; edx - 32-bit length followed by string data +; when al = 30h: +; edx - 32-bit length followed by numeric data, null when invalid number +; when al = 2Eh: +; edx - FloatData, null when invalid number +; when al is any other value, it is a simple special character, and edx is zero + xor ecx,ecx + mov al,[esi] + cmp al,1Ah + je get_literal_number + cmp al,22h + je get_literal_string + cmp al,27h + je missing_end_quote + cmp al,30h + je get_internal_number + inc esi + mov dl,al + call move_to_next_symbol + mov al,dl + xor edx,edx + retn + get_literal_number: + mov edx,[esi+1] + add esi,5 + check_for_more_parts_of_number: + call move_to_next_symbol + jc number_ready_for_conversion + test ecx,ecx + jnz check_for_number_concatenation + cmp al,'.' + je get_literal_float + check_for_number_concatenation: + cmp al,'#' + jne number_ready_for_conversion + call check_concatenation + jc number_ready_for_conversion + number_concatenation: + cmp al,30h + je attach_internal_number_to_number + cmp al,'.' + je get_literal_float + cmp al,1Ah + jne number_ready_for_conversion + attach_name_to_number: + mov ebx,[esi+1] + add esi,5 + push esi + attach_to_number: + mov esi,edx + mov edi,[identifier_workspace.memory_start] + cmp esi,edi + jne initial_concatenation_of_number + lodsd + add esi,eax + mov edi,esi + jmp attach_segment_of_number + initial_concatenation_of_number: + mov ecx,[esi] + add ecx,4 + mov edx,identifier_workspace + call reserve_workspace + lodsd + stosd + mov ecx,eax + rep movsb + attach_segment_of_number: + mov esi,ebx + mov ecx,[esi] + mov eax,[identifier_workspace.memory_start] + add [eax],ecx + mov edx,identifier_workspace + call reserve_workspace + lodsd + mov ecx,eax + rep movsb + pop esi + mov edx,[identifier_workspace.memory_start] + jmp check_for_more_parts_of_number + attach_internal_number_to_number: + mov ebx,edx + inc esi + mov edx,esi + lodsd + add esi,eax + push esi + push ebx + call convert_number_back + mov ebx,edx + pop edx + jmp attach_to_number + number_ready_for_conversion: + push ecx + call convert_number + pop ecx + jc get_literal_float + mov al,30h + retn + missing_end_quote: + mov edx,_missing_end_quote + call register_error + get_literal_string: + mov edx,[esi+1] + add esi,5 + call move_to_next_symbol + mov al,22h + retn + get_internal_number: + lea edx,[esi+1] + mov eax,[edx] + lea esi,[esi+1+4+eax] + call move_to_next_symbol + jc internal_number_ready + test ecx,ecx + jnz check_for_internal_number_concatenation + cmp al,'.' + je convert_internal_number_back + check_for_internal_number_concatenation: + cmp al,'#' + jne internal_number_ready + call check_concatenation + jc internal_number_ready + cmp al,1Ah + je convert_internal_number_back + cmp al,30h + jne internal_number_ready + convert_internal_number_back: + push esi + call convert_number_back + mov esi,edx + mov ecx,[esi] + add ecx,4 + mov edi,[identifier_workspace.memory_start] + mov edx,identifier_workspace + call reserve_workspace + lodsd + stosd + mov ecx,eax + rep movsb + pop esi + mov edx,[identifier_workspace.memory_start] + mov al,[esi] + jmp number_concatenation + internal_number_ready: + mov al,30h + retn + get_literal_float: + xor eax,eax + mov [zero_digits],eax + mov [decimal_places],eax + mov [literal_exponent],eax + mov [literal_exponent_sign],al + mov [literal_fractional_part],al + mov [waiting_for_digit],al + mov [float_literal_status],al + push esi ecx + mov ebx,edx + call start_decimal_converter + lea esi,[ebx+4] + mov ecx,[ebx] + get_float_digit: + lodsb + cmp al,27h + je skip_float_digit + cmp al,'_' + je skip_float_digit + cmp al,'9' + ja float_nondigit + sub al,'0' + jz float_digit_zero + jc float_nondigit + test [float_literal_status],1 + jnz reject_float_digit + inc [decimal_places] + push esi ecx + xor ecx,ecx + xchg ecx,[zero_digits] + call convert_decimal_digit + pop ecx esi + and [waiting_for_digit],0 + skip_float_digit: + loop get_float_digit + jmp float_digits_ok + float_digit_zero: + test [float_literal_status],1 + jnz reject_float_digit + inc [decimal_places] + inc [zero_digits] + and [waiting_for_digit],0 + loop get_float_digit + float_digits_ok: + pop ecx esi + call move_to_next_symbol + jc no_more_tokens_in_float + cmp al,'.' + je decimal_point + cmp al,'#' + jne no_more_tokens_in_float + call check_concatenation + jc no_more_tokens_in_float + jmp next_token_in_float + decimal_point: + test ecx,ecx + jnz no_more_tokens_in_float + mov al,[literal_fractional_part] + or al,[literal_exponent_sign] + jz decimal_point_allowed + or [float_literal_status],-1 + decimal_point_allowed: + or [literal_fractional_part],1 + or [waiting_for_digit],1 + and [decimal_places],0 + get_following_digits: + inc esi + xor ecx,ecx + call move_to_adjacent_symbol + jc invalid_float_value + next_token_in_float: + cmp al,1Ah + je next_digits_section + cmp al,30h + je internal_number_as_digits + no_more_tokens_in_float: + cmp [waiting_for_digit],0 + jne invalid_float_value + cmp [float_literal_status],-1 + je invalid_float_value + call finish_decimal_conversion + push esi ecx + mov esi,edi + xor ecx,ecx + cmp [literal_fractional_part],0 + je float_decimal_places_ok + mov ecx,[decimal_places] + float_decimal_places_ok: + sub ecx,[zero_digits] + neg ecx + add ecx,[literal_exponent] + jo float_conversion_failed + call multiply_float_by_power_of_ten + test [edi+FloatData.attributes],FLOAT_INFINITE or FLOAT_INDETERMINATE or FLOAT_UNDERFLOW + jnz float_conversion_failed + mov edx,edi + pop ecx esi + mov al,2Eh + retn + float_conversion_failed: + pop ecx esi + invalid_float_value: + xor edx,edx + mov al,2Eh + retn + next_digits_section: + inc esi + lodsd + xor ecx,ecx + push esi ecx + mov esi,eax + lodsd + mov ecx,eax + cmp [literal_exponent_sign],0 + jne get_exponent_digit + jmp get_float_digit + internal_number_as_digits: + inc esi + mov edx,esi + lodsd + add esi,eax + xor ecx,ecx + push esi ecx + call convert_number_back + mov esi,edx + lodsd + mov ecx,eax + cmp [literal_exponent_sign],0 + jne get_exponent_digit + jmp get_float_digit + get_literal_exponent: + mov al,1 + xchg al,[literal_exponent_sign] + test al,al + jnz reject_exponent_digit + or [waiting_for_digit],1 + loop get_exponent_digit + pop ecx esi + call move_to_adjacent_symbol + jc invalid_float_value + cmp al,1Ah + je next_digits_section + cmp al,30h + je internal_number_as_digits + cmp al,'+' + je get_following_digits + cmp al,'-' + jne invalid_float_value + neg [literal_exponent_sign] + jmp get_following_digits + get_exponent_digit: + xor eax,eax + lodsb + cmp al,27h + je skip_exponent_digit + cmp al,'_' + je skip_exponent_digit + sub al,'0' + jc reject_exponent_digit + cmp al,10 + jae reject_exponent_digit + test [float_literal_status],1 + jnz reject_exponent_digit + mov edx,[literal_exponent] + imul edx,10 + jo reject_exponent_digit + cmp [literal_exponent_sign],0 + jnl exponent_digit_ok + neg eax + exponent_digit_ok: + add edx,eax + jo reject_exponent_digit + mov [literal_exponent],edx + and [waiting_for_digit],0 + skip_exponent_digit: + loop get_exponent_digit + jmp float_digits_ok + reject_exponent_digit: + or [float_literal_status],-1 + jmp skip_exponent_digit + float_nondigit: + cmp [waiting_for_digit],0 + jne reject_float_digit + movzx eax,byte [esi-1] + mov al,[characters+eax] + cmp al,'e' + je get_literal_exponent + cmp al,'f' + jne reject_float_digit + or [float_literal_status],1 + jmp skip_float_digit + reject_float_digit: + or [float_literal_status],-1 + jmp skip_float_digit + move_to_adjacent_symbol: + call move_to_next_symbol + jc adjacent_symbol_ok + cmp al,'#' + je check_concatenation + neg ecx + adjacent_symbol_ok: + retn + +skip_literal: +; in: +; esi - token in preprocessed line or in current embedded value +; out: +; esi = pointer advanced past the processed literal and the whitespace that follows it +; ecx = number of whitespace tokens encountered immediately before the new position + xor ecx,ecx + mov al,[esi] + cmp al,1Ah + je skip_literal_number + cmp al,22h + je skip_literal_string + cmp al,27h + je skip_literal_string + cmp al,30h + je skip_internal_number + inc esi + call move_to_next_symbol + retn + skip_literal_string: + add esi,5 + call move_to_next_symbol + retn + skip_literal_number: + xor dh,dh + inc esi + lodsd + mov dl,[eax+4] + cmp dl,'0' + jb skip_number_segments + cmp dl,'9' + ja skip_number_segments + or dh,1 + check_for_possible_exponent: + mov ecx,[eax] + mov dl,[eax+4+ecx-1] + cmp dl,'e' + je possible_exponent + cmp dl,'E' + jne skip_number_segments + possible_exponent: + or dh,2 + jmp skip_number_segments + skip_internal_number: + inc esi + lodsd + add esi,eax + mov dh,1 + skip_number_segments: + xor ecx,ecx + call move_to_next_symbol + jc literal_symbol_skipped + cmp al,'#' + je check_literal_concatenation + test ecx,ecx + jnz literal_symbol_skipped + cmp al,'.' + jne check_for_exponent + skip_decimal_point: + inc esi + xor ecx,ecx + call move_to_next_symbol + jc literal_symbol_skipped + cmp al,'#' + je check_literal_concatenation + test ecx,ecx + jnz literal_symbol_skipped + skip_attached_segment: + cmp al,'.' + je skip_decimal_point + cmp al,30h + je skip_attached_internal_number + cmp al,1Ah + jne check_for_exponent + skip_attached_number: + inc esi + lodsd + test dh,1 + jnz check_for_possible_exponent + jmp skip_number_segments + skip_attached_internal_number: + inc esi + lodsd + add esi,eax + and dh,not 2 + jmp skip_number_segments + check_for_exponent: + cmp dh,1+2 + jne literal_symbol_skipped + cmp al,'+' + je skip_exponent + cmp al,'-' + jne literal_symbol_skipped + skip_exponent: + xor dh,dh + jmp skip_decimal_point + check_literal_concatenation: + call check_concatenation + jnc skip_attached_segment + literal_symbol_skipped: + retn + +get_processed_value: +; in: +; esi = pointer into preprocessed line or current embedded value +; out: +; cf set when there were no more symbols on the line +; when cf = 0: +; al = type of value +; esi = pointer advanced past the processed element and the whitespace that follows it within the boundaries of current embedded value or preprocessed line +; ecx = number of whitespace tokens encountered immediately before the new position +; when al = 1Ah: +; ebx - SymbolTree_Leaf, null when malformed identifier +; edx - ValueDefinition, null when symbol with no valid value +; additional variables set as by identify_symbol +; when al = 22h: +; edx - 32-bit length followed by string data +; when al = 30h: +; edx - 32-bit length followed by numeric data, null when invalid number +; when al = 2Eh: +; edx - FloatData, null when invalid number +; when al is any other value, it is a simple special character, and edx is zero +; note: +; to detect whitespace between two consecutive symbols, warp_to_next_symbol should be called after this function, +; since it may further increase ecx when there is additional whitespace outside of current embedded value +; when [use_raw_values] flag is set, this function is identical to get_raw_value + call get_raw_value + jc no_more_values + cmp al,1Ah + jne value_ok + test edx,edx + jz value_ok + cmp [edx+ValueDefinition.type],VALTYPE_SYMBOLIC + je symbolic_value + value_ok: + clc + retn + symbolic_value: + cmp [use_raw_values],0 + jne value_ok + mov eax,[current_pass] + mov [ebx+SymbolTree_Leaf.last_use_pass],eax + test [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + jnz no_infinite_regress + test [edx+ValueDefinition.flags],VAL_IN_USE + jz no_infinite_regress + push edx + mov edx,_symbolic_self_reference + call register_error + pop edx + retn + no_infinite_regress: + call embed_symbolic_value + jmp get_processed_value + +get_raw_value: +; same as get_processed_value, but it does not expand symbolic value and returns it just like any other + call warp_to_next_symbol + jc no_more_values + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc get_raw_value + test edi,edi + jz literal_value + mov edi,edx + test ebx,ebx + jz invalid_symbol_value + call get_available_value + jc invalid_symbol_value + mov al,1Ah + clc + retn + invalid_symbol_value: + xor edx,edx + mov al,1Ah + clc + retn + literal_value: + call get_literal + clc + retn + no_more_values: + ; stc + retn diff --git a/toolchain/fasmg.kl0e/source/calm.inc b/toolchain/fasmg.kl0e/source/calm.inc new file mode 100644 index 0000000..64f0f2e --- /dev/null +++ b/toolchain/fasmg.kl0e/source/calm.inc @@ -0,0 +1,3293 @@ + +struct CompiledMacroHeader + shared_namespace dd ? + literals_offset dd ? + label_argument_leaf dd ? + label_argument_contextless db ? + reserved db ? + reserved2 dw ? +ends + +struct CompiledMacroArgument + symbol_leaf dd ? + contextless db ? + reserved db ? + reserved2 dw ? + default_value_length dd ? + default_value_offset dd ? +ends + +struct UnresolvedJump + offset dd ? + entry_length dd ? + ; source_context SourceContext +ends + +struct MatchedExcerpt + data_start dd ? + data_end dd ? + recognition_context dd ? + symbol_leaf dd ? +ends + +BOOL_NEG = -1 +BOOL_AND = -2 +BOOL_OR = -3 + +define_calm_instruction: + mov dl,DBLOCK_CALMINSTRUCTION + mov ecx,sizeof.MacroData + call add_directive_block + mov edx,[ebx+SymbolTree_Leaf.branch] + call get_symbol_namespace + mov [alm_namespace],ebx + or [assembly_mode],AMODE_CALM_DEFINITION + mov [calm_definition_active],0 + test [assembly_mode],AMODE_SKIP + jnz assembly_line + test [assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + mov eax,[calm_code_buffer.memory_start] + mov [calm_code_cursor],eax + mov eax,[calm_literals_buffer.memory_start] + mov [calm_literals_cursor],eax + mov eax,[calm_auxiliary_buffer.memory_start] + mov [calm_auxiliary_cursor],eax + call move_to_next_symbol + jc missing_argument + cmp al,'(' + je calm_labeled_instruction + and [argument_start],0 + mov dl,SYMCLASS_INSTRUCTION + get_calm_instruction_identifier: + call get_macro_definition_symbol + jc invalid_identifier + push esi + mov eax,ebx + mov ecx,[alm_namespace] + call get_local_anchor + call get_symbol_namespace + or [ebx+SymbolTree_Root.flags],NAMESPACE_CALM + mov [new_local_namespace],ebx + pop esi + mov edi,[calm_code_buffer.memory_start] + mov [edi+CompiledMacroHeader.shared_namespace],ebx + or [symbol_definition],1 + mov ebx,[argument_start] + test ebx,ebx + jz calm_instruction_label_argument_ok + push esi edi + mov esi,ebx + cmp byte [esi],'&' + sete al + mov [edi+CompiledMacroHeader.label_argument_contextless],al + jne calm_instruction_label_prefix_ok + inc esi + calm_instruction_label_prefix_ok: + mov dl,SYMCLASS_EXPRESSION + mov ebx,[new_local_namespace] + call identify_symbol_in_namespace + mov eax,esi + pop edi esi + jc invalid_argument + test ebx,ebx + jz invalid_argument + cmp byte [eax],')' + jne invalid_argument + call update_value_definition + push esi edi + mov [value_type],VALTYPE_RESERVED + xor ecx,ecx + call assign_value + pop edi esi + calm_instruction_label_argument_ok: + mov [edi+CompiledMacroHeader.label_argument_leaf],ebx + add edi,sizeof.CompiledMacroHeader + calm_instruction_argument_declaration: + call move_to_next_symbol + jc calm_instruction_arguments_declared + cmp al,'&' + sete al + mov [contextless_processing],al + jne calm_instruction_argument_name + inc esi + calm_instruction_argument_name: + mov dl,SYMCLASS_EXPRESSION + push edi + mov ebx,[new_local_namespace] + call identify_symbol_in_namespace + pop edi + jc invalid_argument + test ebx,ebx + jz invalid_argument + mov edx,calm_code_buffer + mov ecx,sizeof.CompiledMacroArgument+4 + call reserve_workspace + mov [edi+CompiledMacroArgument.symbol_leaf],ebx + mov al,[contextless_processing] + mov [edi+CompiledMacroArgument.contextless],al + call update_value_definition + test edx,edx + jz calm_instruction_argument_prepared + push esi edi + mov [value_type],VALTYPE_RESERVED + xor ecx,ecx + call assign_value + pop edi esi + xor edx,edx + calm_instruction_argument_prepared: + call move_to_next_symbol + jc calm_instruction_argument_ready + cmp al,':' + je calm_instruction_argument_default_value + cmp al,'=' + je calm_instruction_argument_default_value + cmp al,'*' + jne calm_instruction_argument_ready + dec edx + inc esi + calm_instruction_argument_ready: + mov [edi+CompiledMacroArgument.default_value_length],edx + add edi,sizeof.CompiledMacroArgument + call move_to_next_symbol + jc calm_instruction_arguments_declared + inc esi + cmp al,'&' + je calm_instruction_greedy_argument + cmp al,',' + jne invalid_argument + call move_to_next_symbol + jc invalid_argument + jmp calm_instruction_argument_declaration + calm_instruction_argument_default_value: + inc esi + mov [calm_code_cursor],edi + mov edx,calm_literals_buffer + mov edi,[calm_literals_cursor] + mov ecx,[line_end] + sub ecx,esi + add ecx,1+sizeof.RecognitionContext + call reserve_workspace + mov [calm_literals_cursor],edi + call move_to_next_symbol + jc calm_plain_default_value + cmp al,'<' + je calm_enclosed_default_value + calm_plain_default_value: + mov dl,',' + xor dh,dh + mov [breakpoint_token],'&' + call extract_piece_of_line + jmp calm_default_value_ready + calm_enclosed_default_value: + inc esi + mov dl,'>' + mov dh,'<' + mov [breakpoint_token],0 + call extract_piece_of_line + cmp al,'>' + jne invalid_argument + inc esi + calm_default_value_ready: + mov edx,edi + xchg edi,[calm_literals_cursor] + mov eax,edi + sub edx,edi + sub eax,[calm_literals_buffer.memory_start] + mov edi,[calm_code_cursor] + mov [edi+CompiledMacroArgument.default_value_offset],eax + jmp calm_instruction_argument_ready + calm_instruction_greedy_argument: + assert CompiledMacroArgument.symbol_leaf = 0 + or eax,-1 + stosd + jmp call_instruction_begin_code + calm_labeled_instruction: + inc esi + call move_to_next_symbol + jc missing_argument + mov [argument_start],esi + mov edi,[expression_workspace.memory_start] + mov dl,')' + xor dh,dh + mov [breakpoint_token],dh + call cut_piece_of_line + cmp al,')' + jne invalid_argument + inc esi + mov dl,SYMCLASS_STRUCTURE + jmp get_calm_instruction_identifier + calm_instruction_arguments_declared: + assert CompiledMacroArgument.symbol_leaf = 0 + xor eax,eax + stosd + call_instruction_begin_code: + mov [calm_code_cursor],edi + mov eax,[new_local_namespace] + mov [current_context.base_namespace],eax + and [calm_line_number],0 + mov [calm_definition_active],1 + jmp instruction_assembled + +assemble_alm_instruction: + or [alm_statement],1 + mov ebx,[source_context] + mov eax,[ebx+SourceContext.number_of_entries] + dec eax + imul eax,sizeof.SourceEntry + test [ebx+sizeof.SourceContext+eax+SourceEntry.flags],SRCF_ALM_STATEMENT + jnz identify_alm_instruction + inc [calm_line_number] + identify_alm_instruction: + call move_to_next_symbol + jc empty_line + call get_alm_identifier + jc unrecognized_alm_instruction + mov dl,SYMCLASS_INSTRUCTION + call identify_alm_symbol + jc alm_label + call get_available_value + jc alm_label + test [edx+ValueDefinition.flags],VAL_UNCONDITIONAL + jnz execute_alm_instruction + test [assembly_mode],AMODE_SKIP + jnz assembly_line + test [assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + execute_alm_instruction: + cmp [edx+ValueDefinition.type],VALTYPE_CALM + je launch_calm + cmp [edx+ValueDefinition.type],VALTYPE_SYMBOLIC + je use_macro + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_COMMAND + jne unrecognized_alm_instruction + jmp [edx+ValueDefinition.value] + alm_label: + call move_to_next_symbol + jc unrecognized_alm_instruction + cmp al,':' + jne unrecognized_alm_instruction + inc esi + test [assembly_mode],AMODE_SKIP + jnz identify_alm_instruction + test [assembly_mode],AMODE_DEFINITION + jnz add_label_to_macro + call identify_calm_location + jc unrecognized_alm_instruction + call create_constant_value_definition + test edx,edx + jz assembly_line + mov [edx+ValueDefinition.type],VALTYPE_PLAIN + mov eax,[calm_code_cursor] + sub eax,[calm_code_buffer.memory_start] + mov [edx+ValueDefinition.value],eax + mov eax,[current_pass] + mov [edx+ValueDefinition.pass],eax + jmp identify_alm_instruction + unrecognized_alm_instruction: + test [assembly_mode],AMODE_SKIP + jnz assembly_line + test [assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + mov edx,_unexpected_instruction + call register_error + jmp assembly_line + get_alm_identifier: + xor ecx,ecx + call move_to_next_symbol + jc malformed_alm_identifier + cmp al,1Ah + je alm_plain_name + cmp al,30h + je alm_numeric_name + cmp al,'#' + jne malformed_alm_identifier + call check_concatenation + jnc get_alm_identifier + malformed_alm_identifier: + stc + retn + alm_plain_name: + inc esi + lodsd + mov ebx,eax + mov ecx,[ebx] + mov eax,[ebx+4+ecx] + mov [case_sensitive_hash],eax + mov eax,[ebx+4+ecx+4] + mov [case_insensitive_hash],eax + alm_check_for_concatenation: + xor ecx,ecx + call move_to_next_symbol + jc alm_identifier_ok + cmp al,'#' + jne alm_identifier_ok + call check_concatenation + jc alm_identifier_ok + call move_to_next_symbol + jc alm_identifier_ok + cmp al,1Ah + je alm_concatenation + cmp al,30h + je alm_concatenation + alm_identifier_ok: + mov [symbol_data],ebx + cmp ebx,[assembly_workspace.memory_start] + je alm_identifier_volatile + mov [name_volatile],0 + clc + retn + alm_identifier_volatile: + sub edi,ebx + sub edi,4 + mov [ebx],edi + mov [name_volatile],1 + clc + retn + alm_concatenation: + mov edx,assembly_workspace + cmp ebx,[edx+Workspace.memory_start] + je alm_name_segment + mov edi,[edx+Workspace.memory_start] + add edi,4 + mov ecx,[ebx] + call reserve_workspace + xchg ebx,esi + lodsd + mov ecx,eax + rep movsb + mov esi,ebx + mov ebx,[edx+Workspace.memory_start] + alm_name_segment: + lodsb + cmp al,30h + je alm_attach_numeric_segment + lodsd + push ebx esi + alm_append_name: + mov esi,eax + mov ecx,[esi] + mov edx,assembly_workspace + call reserve_workspace + lodsd + lea ebx,[esi+eax] + mov ecx,[case_sensitive_hash] + mov edx,[case_insensitive_hash] + xor eax,eax + alm_name_hash: + lodsb + xor cl,al + xor dl,[characters+eax] + imul ecx,FNV_PRIME + imul edx,FNV_PRIME + stosb + cmp esi,ebx + jne alm_name_hash + mov [case_sensitive_hash],ecx + mov [case_insensitive_hash],edx + pop esi ebx + jmp alm_check_for_concatenation + alm_numeric_name: + inc esi + mov ebx,[assembly_workspace.memory_start] + lea edi,[ebx+4] + mov eax,FNV_OFFSET + mov [case_sensitive_hash],eax + mov [case_insensitive_hash],eax + alm_attach_numeric_segment: + mov edx,esi + mov ecx,[edx] + lea esi,[esi+4+ecx] + push ebx esi + push edi + call convert_number_back + pop edi + mov eax,edx + jmp alm_append_name + identify_alm_symbol: + mov [symbol_class],dl + push esi + mov esi,[symbol_data] + lodsd + mov ecx,eax + mov edx,[case_insensitive_hash] + mov ebx,[alm_namespace] + mov [name_kind],NAME_CASEINSENSITIVE + and [name_token],0 + and [symbol_required],0 + and [symbol_expected],0 + call scan_namespace + pop esi + retn + identify_calm_location: + mov [symbol_class],SYMCLASS_CALM_LOCATION + push esi + mov esi,[symbol_data] + lodsd + mov ecx,eax + mov edx,[case_sensitive_hash] + mov ebx,[current_context.base_namespace] + and [name_kind],0 + and [name_token],0 + or [symbol_required],1 + or [symbol_expected],1 + call scan_namespace + pop esi + retn + +alm_jyes: + mov [value],calm_jyes + jmp assemble_alm_jump +alm_jno: + mov [value],calm_jno + jmp assemble_alm_jump +alm_jump: + mov [value],calm_jump + assemble_alm_jump: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + call move_to_next_symbol + jc missing_argument + call get_alm_identifier + jc invalid_argument + call identify_calm_location + jc invalid_argument + mov edx,[ebx+SymbolTree_Leaf.definition] + test edx,edx + jz alm_unresolved_jump + mov eax,[edx+ValueDefinition.pass] + cmp eax,[current_pass] + jne alm_unresolved_jump + mov ebx,[edx+ValueDefinition.value] + emit_calm_jump: + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov ecx,8+4 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,[value] + stosd + mov eax,ebx + stosd + mov [calm_code_cursor],edi + jmp instruction_assembled + alm_unresolved_jump: + push esi + mov edx,calm_auxiliary_buffer + mov edi,[calm_auxiliary_cursor] + mov esi,[source_context] + mov ecx,[esi+SourceContext.number_of_entries] + imul ecx,sizeof.SourceEntry + add ecx,sizeof.SourceContext + add ecx,sizeof.UnresolvedJump + call reserve_workspace + mov [calm_auxiliary_cursor],edi + mov eax,[calm_code_cursor] + add eax,8 + sub eax,[calm_code_buffer.memory_start] + mov [edi+UnresolvedJump.offset],eax + add edi,sizeof.UnresolvedJump + call clone_source_context + mov ecx,edi + xchg edi,[calm_auxiliary_cursor] + sub ecx,edi + mov [edi+UnresolvedJump.entry_length],ecx + pop esi + jmp emit_calm_jump + +alm_end: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_unconditional_alm_instruction + call move_to_next_symbol + jc finish_calm_definition + call get_alm_identifier + jc invalid_argument + mov dl,SYMCLASS_STRUCTURE + call identify_alm_symbol + jc invalid_argument + mov edx,[ebx+SymbolTree_Leaf.definition] + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_COMMAND + jne invalid_argument + cmp [edx+ValueDefinition.value],alm_end + jne invalid_argument + finish_calm_definition: + mov dl,DBLOCK_CALMINSTRUCTION + call find_directive_block + jc unexpected_unconditional_alm_instruction + call close_directive_block + and [assembly_mode],not AMODE_CALM_DEFINITION + test [assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + cmp [calm_definition_active],0 + je instruction_assembled + push esi + mov esi,[calm_auxiliary_buffer.memory_start] + resolve_calm_jumps: + cmp esi,[calm_auxiliary_cursor] + je calm_jumps_resolved + mov eax,[esi+UnresolvedJump.offset] + add eax,[calm_code_buffer.memory_start] + mov ebx,[eax] + mov edx,[ebx+SymbolTree_Leaf.definition] + test edx,edx + jz unresolvable_calm_jump + mov ecx,[edx+ValueDefinition.pass] + cmp ecx,[current_pass] + jne unresolvable_calm_jump + mov ebx,[edx+ValueDefinition.value] + mov [eax],ebx + resolve_next_calm_jump: + add esi,[esi+UnresolvedJump.entry_length] + jmp resolve_calm_jumps + unresolvable_calm_jump: + mov edx,[calm_code_cursor] + sub edx,[calm_code_buffer.memory_start] + mov [eax],edx + add esi,sizeof.UnresolvedJump + mov edx,_undefined_jump_target + call register_delayed_error + sub esi,sizeof.UnresolvedJump + jmp resolve_next_calm_jump + calm_jumps_resolved: + mov ebx,[current_context.base_namespace] + mov edx,[ebx+SymbolTree_Root.parent_branch] + mov eax,[edx+SymbolTree_Foliage.root] + mov [current_context.base_namespace],eax + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov ecx,[calm_literals_cursor] + mov esi,[calm_literals_buffer.memory_start] + sub ecx,esi + add ecx,8 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,calm_end + stosd + mov ebx,[calm_code_buffer.memory_start] + mov eax,edi + sub eax,ebx + mov [ebx+CompiledMacroHeader.literals_offset],eax + mov ecx,[calm_literals_cursor] + sub ecx,esi + rep movsb + mov ebx,[macro_leaf] + test ebx,ebx + jz calm_definition_done + call create_value_definition + test edx,edx + jz calm_definition_done + mov esi,[calm_code_buffer.memory_start] + mov ecx,edi + sub ecx,esi + mov [value_type],VALTYPE_CALM + call assign_value + mov al,[macro_flags] + or [edx+ValueDefinition.flags],al + calm_definition_done: + pop esi + jmp instruction_assembled + unexpected_unconditional_alm_instruction: + test [assembly_mode],AMODE_SKIP + jnz assembly_line + test [assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + jmp unexpected_instruction + +alm_local: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + call move_to_next_symbol + jc missing_argument + or [symbol_definition],1 + mov dl,SYMCLASS_EXPRESSION + mov ebx,[current_context.base_namespace] + call identify_symbol_in_namespace + jc invalid_argument + test ebx,ebx + jz invalid_argument + call update_value_definition + test edx,edx + jz alm_next_local + push esi + mov [value_type],VALTYPE_RESERVED + xor ecx,ecx + call assign_value + pop esi + alm_next_local: + call move_to_next_symbol + jc instruction_assembled + cmp al,',' + jne invalid_argument + inc esi + jmp alm_local + +alm_assemble: + mov [value],calm_assemble + jmp assemble_alm_operation_on_variable +alm_stringify: + mov [value],calm_stringify + assemble_alm_operation_on_variable: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc invalid_identifier + test ebx,ebx + jz invalid_identifier + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov ecx,8+4 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,[value] + stosd + mov eax,ebx + stosd + mov [calm_code_cursor],edi + jmp instruction_assembled + +alm_arrange: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc invalid_identifier + test ebx,ebx + jz invalid_identifier + call move_to_next_symbol + jc missing_argument + cmp al,',' + jne instruction_assembled + inc esi + call move_to_next_symbol + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov ecx,8+12 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,calm_arrange + stosd + mov eax,ebx + stosd + mov edx,calm_literals_buffer + mov ebx,[calm_literals_cursor] + mov eax,ebx + sub eax,[edx+Workspace.memory_start] + stosd + mov [calm_code_cursor],edi + mov edi,ebx + mov ecx,[line_end] + sub ecx,esi + shl ecx,1 + call reserve_workspace + mov [breakpoint_token],0 + call parse_pattern + mov [calm_literals_cursor],edi + mov eax,edi + mov edi,[calm_code_cursor] + sub eax,[calm_literals_buffer.memory_start] + stosd + mov [calm_code_cursor],edi + jmp instruction_assembled + parse_pattern: + ; in: + ; esi - first token of the pattern in the preprocessed line + ; edi - buffer with enough space to hold twice the length of the preprocessed text left in line + ; [breakpoint_token] = initial byte of symbol that should end the pattern + ; out: + ; esi - after the processed portion of line (might be at [line_end]) + ; edi - in the buffer after the stored pattern + cmp esi,[line_end] + je pattern_parsed + lodsb + token_available: + cmp al,[breakpoint_token] + je pattern_breakpoint + token_in_pattern: + cmp al,'=' + je parse_pattern_literal + cmp al,1Ah + je parse_reference_in_pattern + cmp al,40h + je ignore_context_in_pattern + cmp al,20h + je whitespace_in_pattern + stosb + literal_token_in_pattern: + cmp al,22h + je copy_pattern_data + cmp al,27h + je copy_pattern_data + cmp al,30h + jne parse_pattern + lodsd + mov ecx,eax + stosd + rep movsb + jmp parse_pattern + whitespace_in_pattern: + cmp esi,[line_end] + je pattern_parsed + lodsb + cmp al,20h + je whitespace_in_pattern + cmp al,[breakpoint_token] + je pattern_breakpoint + cmp al,40h + jne store_whitespace_in_pattern + call pass_context + jmp whitespace_in_pattern + store_whitespace_in_pattern: + mov byte [edi],20h + inc edi + jmp token_in_pattern + pattern_breakpoint: + dec esi + pattern_parsed: + retn + pass_context: + mov eax,esi + add esi,sizeof.RecognitionContext + cmp dword [eax],0 + je zero_context + mov [embedded_context],eax + retn + zero_context: + and [embedded_context],0 + retn + copy_pattern_data: + movsd + jmp parse_pattern + ignore_context_in_pattern: + call pass_context + jmp parse_pattern + ignore_context_in_pattern_literal: + call pass_context + parse_pattern_literal: + cmp esi,[line_end] + je error_in_parsed_pattern + lodsb + cmp al,40h + je ignore_context_in_pattern_literal + cmp al,20h + je parse_hard_space_in_pattern + stosb + cmp al,1Ah + jne literal_token_in_pattern + movsd + jmp parsed_name_in_pattern + parse_hard_space_in_pattern: + mov al,0A0h + stosb + jmp parse_pattern + parse_reference_in_pattern: + dec esi + call detect_numeric_symbol + jc numeric_name_in_pattern + inc esi + mov [name_token],esi + lodsd + mov dx,SYMCLASS_EXPRESSION + mov [name_volatile],0 + push esi edi + mov esi,eax + lodsd + mov ecx,eax + xor ebx,ebx + mov eax,[embedded_context] + test eax,eax + jz use_current_namespace_in_pattern + mov eax,[eax+RecognitionContext.base_namespace] + jmp namespace_in_pattern_ok + use_current_namespace_in_pattern: + mov eax,[current_context.base_namespace] + namespace_in_pattern_ok: + mov [recognition_context.base_namespace],eax + call recognize_symbol + pop edi esi + mov al,1Bh + stosb + mov eax,[name_token] + mov eax,[eax] + stosd + mov eax,ebx + stosd + parsed_name_in_pattern: + cmp esi,[line_end] + je pattern_parsed + lodsb + cmp al,40h + je ignore_context_after_name_in_pattern + cmp al,'?' + jne token_available + mov al,0BFh + stosb + jmp parse_pattern + ignore_context_after_name_in_pattern: + call pass_context + jmp parsed_name_in_pattern + numeric_name_in_pattern: + movsb + movsd + jmp parsed_name_in_pattern + error_in_parsed_pattern: + mov edx,_invalid_argument + call register_error + jmp parse_pattern + +alm_match: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + call move_to_next_symbol + jc missing_argument + mov edx,calm_literals_buffer + mov edi,[calm_literals_cursor] + mov ecx,[line_end] + sub ecx,esi + shl ecx,1 + call reserve_workspace + mov [calm_literals_cursor],edi + mov [breakpoint_token],',' + call parse_pattern + xchg edi,[calm_literals_cursor] + mov [pattern_start],edi + cmp esi,[line_end] + je missing_argument + lodsb + cmp al,',' + jne invalid_argument + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc invalid_identifier + test ebx,ebx + jz invalid_identifier + and [brackets],0 + call move_to_next_symbol + jc no_brackets + cmp al,',' + jne no_brackets + inc esi + call move_to_next_symbol + jc invalid_argument + mov dl,al + lea edi,[esi+1] + call skip_token + cmp esi,edi + jne invalid_argument + call move_to_next_symbol + jc invalid_argument + mov dh,al + lea edi,[esi+1] + call skip_token + cmp esi,edi + jne invalid_argument + mov word [brackets],dx + no_brackets: + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov ecx,8+16 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,calm_match + stosd + mov eax,ebx + stosd + mov ebx,[calm_literals_buffer.memory_start] + mov eax,[pattern_start] + sub eax,ebx + stosd + mov eax,[calm_literals_cursor] + sub eax,ebx + stosd + mov eax,[brackets] + stosd + mov [calm_code_cursor],edi + jmp instruction_assembled + +alm_compute: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc invalid_identifier + test ebx,ebx + jz invalid_identifier + call move_to_next_symbol + jc missing_argument + cmp al,',' + jne instruction_assembled + inc esi + call move_to_next_symbol + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov ecx,8+8 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,calm_compute + stosd + mov eax,ebx + stosd + call compile_expression + jnc instruction_assembled + sub [calm_code_cursor],8+8 + jmp instruction_assembled + compile_expression: + xor eax,eax + stosd + mov [calm_code_cursor],edi + mov edi,[expression_workspace.memory_start] + and [leave_opening_parentheses],0 + or [use_raw_values],1 + call parse_expression + and [use_raw_values],0 + push esi + mov esi,[expression_workspace.memory_start] + mov ecx,edi + sub ecx,esi + add ecx,4 + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + call reserve_workspace + mov [calm_code_cursor],edi + call convert_parsed_expression + pop esi + jc no_computable_expression + mov ecx,edi + xchg edi,[calm_code_cursor] + sub ecx,edi + mov [edi-4],ecx + ; clc + retn + no_computable_expression: + retn + convert_parsed_expression: + xor ebx,ebx + xor ecx,ecx + xor dl,dl + mov [subexpression_end],esi + scan_reducible_subexpression: + mov eax,[esi+ebx] + test eax,eax + jz end_subexpression + cmp al,EXPR_OPERATOR + je scan_operator + cmp al,EXPR_SYMBOL_VALUE + je scan_parsed_symbol + cmp al,EXPR_NUMBER + je scan_parsed_value + cmp al,EXPR_STRING + je scan_parsed_value + cmp al,EXPR_FLOAT + je scan_parsed_value + jmp end_subexpression + scan_parsed_value: + add ebx,8 + inc ecx + jmp scan_reducible_subexpression + scan_parsed_symbol: + mov eax,[esi+ebx+4] + test eax,eax + jz end_subexpression + test [eax+SymbolTree_Leaf.flags],SYM_CONSTANT + jz end_subexpression + mov eax,[esi+ebx+8] + test eax,eax + jz end_subexpression + cmp [eax+ValueDefinition.type],VALTYPE_SYMBOLIC + je end_subexpression + add ebx,12 + inc ecx + jmp scan_reducible_subexpression + scan_operator: + test eax,EXPRF_OPERATOR_UNARY + setz al + movzx eax,al + cmp ecx,eax + jbe end_subexpression + sub ecx,eax + add ebx,8 + or dl,1 + jmp scan_reducible_subexpression + end_subexpression: + add ebx,esi + mov [subexpression_end],ebx + test dl,dl + jz convert_irreducible_expression + cmp ecx,1 + jne convert_irreducible_expression + push edi + xor eax,eax + xchg eax,[ebx] + push eax + mov edi,[calculation_workspace.memory_start] + call calculate_parsed_expression + mov esi,[subexpression_end] + pop dword [esi] + call pop_terms + mov ebx,edi + pop edi + jc convert_irreducible_expression + cmp [ebx+sizeof.ExpressionTerm+ExpressionTerm.attributes],0 + jne embed_numeric_value + mov eax,[ebx+ExpressionTerm.attributes] + mov ebx,[ebx+ExpressionTerm.value] + jmp copy_expression_literal + embed_numeric_value: + push edi + mov edi,ebx + call convert_terms_to_numeric_value + pop edi + mov ebx,esi + mov esi,[subexpression_end] + mov eax,EXPR_POLYNOMIAL + EXPRF_CALM_LITERAL + jmp parsed_value_length_ok + convert_irreducible_expression: + lodsd + test eax,eax + jz parsed_expression_converted + cmp al,EXPR_SYMBOL_VALUE + je copy_parsed_symbol + cmp al,EXPR_OPERATOR + je copy_parsed_operator + cmp al,EXPR_NUMBER + je copy_parsed_value + cmp al,EXPR_STRING + je copy_parsed_value + cmp al,EXPR_FLOAT + je copy_parsed_value + cmp al,EXPR_MISSING_PARENTHESIS + je expression_missing_parenthesis + jmp invalid_expression + copy_parsed_value: + mov ebx,[esi] + add esi,4 + copy_expression_literal: + or eax,EXPRF_CALM_LITERAL + test eax,EXPRF_VALUE_IN_WORKSPACE + jnz parsed_value_in_workspace + test ebx,ebx + jnz parsed_value_pointer_ok + jmp invalid_expression + parsed_value_in_workspace: + add ebx,[value_workspace.memory_start] + and eax,not EXPRF_VALUE_IN_WORKSPACE + parsed_value_pointer_ok: + cmp al,EXPR_FLOAT + je parsed_float_to_copy + mov ecx,[ebx] + add ecx,4 + jmp parsed_value_length_ok + parsed_float_to_copy: + mov ecx,sizeof.FloatData + parsed_value_length_ok: + stosd + mov edx,[calm_literals_cursor] + mov eax,edx + sub eax,[calm_literals_buffer.memory_start] + stosd + push edi + push ecx + mov edi,edx + mov edx,calm_literals_buffer + call reserve_workspace + pop ecx + xchg esi,ebx + rep movsb + mov [calm_literals_cursor],edi + mov esi,ebx + pop edi + parsed_item_converted: + cmp esi,[subexpression_end] + jbe convert_irreducible_expression + jmp convert_parsed_expression + copy_parsed_symbol: + mov al,EXPR_SYMBOL + stosd + lodsd + test eax,eax + jz invalid_expression + stosd + add esi,4 + jmp parsed_item_converted + copy_parsed_operator: + stosd + movsd + jmp parsed_item_converted + parsed_expression_converted: + stosd + clc + retn + +alm_check: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov eax,edi + sub eax,[edx+Workspace.memory_start] + mov [calm_rollback_offset],eax + mov ecx,8 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,calm_check + stosd + mov [calm_code_cursor],edi + or [use_raw_values],1 + mov ebx,[condition_stack_base] + and dword [ebx],0 + add ebx,4 + mov [condition_stack],ebx + parse_alm_condition: + call peek_at_constituent_value + jc calm_condition_parsed + cmp al,'~' + jne parse_alm_logical_value + and [current_constituent],0 + mov ecx,BOOL_NEG + call push_to_condition_stack + jmp parse_alm_condition + alm_logical_value_empty: + test ecx,ecx + jz calm_condition_parsed + call push_to_condition_stack + jmp parse_alm_condition + parse_alm_logical_value: + call parse_logical_value + jc alm_logical_value_empty + jecxz convert_logical_value + call push_to_condition_stack + convert_logical_value: + mov [calm_source_pointer],esi + mov esi,[expression_workspace.memory_start] + mov ecx,edi + sub ecx,esi + add ecx,8 + add ecx,[condition_stack] + sub ecx,[condition_stack_base] + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + call reserve_workspace + xor eax,eax + stosd + mov [calm_code_cursor],edi + mov eax,[comparator] + stosd + mov eax,[expression_end] + convert_argument_sequences: + push eax + call convert_parsed_expression + pop eax + jc condition_malformed + cmp esi,eax + jb convert_argument_sequences + mov ecx,edi + xchg edi,[calm_code_cursor] + sub ecx,edi + mov [edi-4],ecx + mov esi,[calm_source_pointer] + parse_alm_logical_operator: + call get_constituent_value + jc calm_condition_parsed + cmp al,')' + je close_subconditions + cmp al,'|' + je parse_or + cmp al,'&' + jne condition_malformed + parse_and: + mov ecx,BOOL_AND + jmp prepare_stack_for_logical_operator + parse_or: + mov ecx,BOOL_OR + prepare_stack_for_logical_operator: + mov ebx,[condition_stack] + sub ebx,4 + cmp dword [ebx],0 + jge push_logical_operator + mov [condition_stack],ebx + mov edi,[calm_code_cursor] + mov eax,[ebx] + stosd + mov [calm_code_cursor],edi + jmp prepare_stack_for_logical_operator + push_logical_operator: + call push_to_condition_stack + jmp parse_alm_condition + close_subconditions: + mov ebx,[condition_stack] + sub ebx,4 + cmp dword [ebx],0 + jl store_logical_operator + je condition_malformed + dec dword [ebx] + jnz parse_alm_logical_operator + mov [condition_stack],ebx + jmp parse_alm_logical_operator + store_logical_operator: + mov edi,[calm_code_cursor] + mov eax,[ebx] + mov [condition_stack],ebx + stosd + mov [calm_code_cursor],edi + jmp close_subconditions + push_to_condition_stack: + mov ebx,[condition_stack] + mov [ebx],ecx + add ebx,4 + cmp [condition_stack_end],ebx + je grow_condition_stack + mov [condition_stack],ebx + retn + grow_condition_stack: + mov eax,[condition_stack_base] + sub ebx,eax + lea ecx,[ebx+4] + call grow_stack + mov [condition_stack_base],eax + add ebx,eax + mov [condition_stack],ebx + add ecx,eax + mov [condition_stack_end],ecx + retn + calm_condition_parsed: + mov edi,[calm_code_cursor] + mov ebx,[condition_stack] + mov ecx,ebx + sub ecx,[condition_stack_base] + mov edx,calm_code_buffer + call reserve_workspace + finish_calm_condition: + sub ebx,4 + mov eax,[ebx] + cmp eax,0 + jg condition_malformed + stosd + jne finish_calm_condition + mov [calm_code_cursor],edi + and [use_raw_values],0 + jmp instruction_assembled + condition_malformed: + and [use_raw_values],0 + mov edx,_invalid_expression + alm_abort: + call register_error + mov eax,[calm_rollback_offset] + add eax,[calm_code_buffer.memory_start] + mov [calm_code_cursor],eax + jmp assembly_line + +alm_publish: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + mov [value],calm_publish_variable + call move_to_next_symbol + jc missing_argument + cmp al,':' + jne get_identifier_variable + inc esi + mov [value],calm_publish_stack + get_identifier_variable: + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc invalid_identifier + test ebx,ebx + jz invalid_identifier + mov [label_leaf],ebx + call move_to_next_symbol + jc missing_argument + cmp al,':' + jne get_value_variable + mov eax,calm_publish_constant + xchg [value],eax + cmp eax,calm_publish_variable + jne invalid_argument + inc esi + call move_to_next_symbol + jc missing_argument + get_value_variable: + cmp al,',' + jne missing_argument + inc esi + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc invalid_identifier + test ebx,ebx + jz invalid_identifier + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov ecx,8+8 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,[value] + stosd + mov eax,[label_leaf] + stosd + mov eax,ebx + stosd + mov [calm_code_cursor],edi + jmp instruction_assembled + +alm_transform: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + call move_to_next_symbol + jc missing_argument + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc invalid_identifier + test ebx,ebx + jz invalid_identifier + mov [label_leaf],ebx + xor ebx,ebx + call move_to_next_symbol + jc alm_transform_arguments_ready + cmp al,',' + jne alm_transform_arguments_ready + inc esi + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc invalid_identifier + test edx,edx + jz invalid_identifier + call get_symbol_namespace + alm_transform_arguments_ready: + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov ecx,8+8 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,calm_transform + stosd + mov eax,[label_leaf] + stosd + mov eax,ebx + stosd + mov [calm_code_cursor],edi + jmp instruction_assembled + +alm_take: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + call move_to_next_symbol + jc missing_argument + xor ebx,ebx + and [symbol_definition],0 + cmp al,',' + je alm_take_destination_ready + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc invalid_identifier + test ebx,ebx + jz invalid_identifier + call move_to_next_symbol + jc missing_argument + cmp al,',' + jne missing_argument + alm_take_destination_ready: + mov [label_leaf],ebx + inc esi + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc invalid_identifier + test ebx,ebx + jz invalid_identifier + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov ecx,8+8 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,calm_take + stosd + mov eax,[label_leaf] + stosd + mov eax,ebx + stosd + mov [calm_code_cursor],edi + jmp instruction_assembled + +alm_err: + mov [value],calm_err + jmp assemble_alm_operation_on_expression +alm_display: + mov [value],calm_display + assemble_alm_operation_on_expression: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov ecx,8+4 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,[value] + stosd + call compile_expression + jmp instruction_assembled + +alm_emit: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov ecx,8+4 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,calm_emit + stosd + call compile_expression + mov edi,[calm_code_cursor] + call peek_at_constituent_value + jc alm_call_arguments_ready + cmp al,',' + jne alm_call_arguments_ready + and [current_constituent],0 + call compile_expression + jmp instruction_assembled + +alm_load: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc invalid_identifier + test ebx,ebx + jz invalid_identifier + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov eax,edi + sub eax,[edx+Workspace.memory_start] + mov [calm_rollback_offset],eax + mov ecx,12+4 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,calm_load + stosd + mov eax,ebx + stosd + call move_to_next_symbol + jc alm_missing_argument + cmp al,',' + jne alm_malformed_argument + inc esi + call move_to_next_symbol + call compile_expression + push ecx + call get_constituent_value + pop ecx + jc alm_missing_argument + cmp al,':' + je alm_load_offset + cmp al,',' + jne alm_malformed_argument + mov edi,[calm_rollback_offset] + add edi,[calm_code_buffer.memory_start] + mov dword [edi+4],calm_load_from_output + jmp alm_load_length + alm_load_offset: + mov edi,[calm_code_cursor] + call compile_expression + call get_constituent_value + jc alm_missing_argument + cmp al,',' + jne alm_malformed_argument + alm_load_length: + mov edi,[calm_code_cursor] + call compile_expression + jmp instruction_assembled + alm_missing_argument: + mov edx,_missing_argument + jmp alm_abort + alm_malformed_argument: + mov edx,_invalid_argument + jmp alm_abort + +alm_store: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov eax,edi + sub eax,[edx+Workspace.memory_start] + mov [calm_rollback_offset],eax + mov ecx,8+4 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,calm_store + stosd + call compile_expression + call get_constituent_value + jc alm_missing_argument + cmp al,':' + je alm_store_offset + cmp al,',' + jne alm_malformed_argument + mov edi,[calm_rollback_offset] + add edi,[calm_code_buffer.memory_start] + mov dword [edi+4],calm_store_in_output + jmp alm_store_length + alm_store_offset: + mov edi,[calm_code_cursor] + call compile_expression + call get_constituent_value + jc alm_missing_argument + cmp al,',' + jne alm_malformed_argument + alm_store_length: + mov edi,[calm_code_cursor] + call compile_expression + call get_constituent_value + jc alm_missing_argument + cmp al,',' + jne alm_malformed_argument + mov edi,[calm_code_cursor] + call compile_expression + jmp instruction_assembled + +alm_call: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + and [symbol_definition],0 + mov edx,[embedded_context] + mov [line_context],edx + test edx,edx + jnz alm_call_context_adjust + mov edx,current_context + alm_call_context_adjust: + mov ebx,[edx+RecognitionContext.base_namespace] + test [ebx+SymbolTree_Root.flags],NAMESPACE_CALM + jz alm_call_context_ready + mov eax,[ebx+SymbolTree_Root.parent_branch] + test eax,eax + jz alm_call_context_ready + mov ebx,[eax+SymbolTree_Foliage.root] + mov eax,alm_adjusted_context + mov [eax+RecognitionContext.base_namespace],ebx + mov ecx,[edx+RecognitionContext.base_label] + mov [eax+RecognitionContext.base_label],ecx + mov [embedded_context],eax + alm_call_context_ready: + mov dl,SYMCLASS_INSTRUCTION + call identify_symbol + jc invalid_identifier + test ebx,ebx + jz invalid_identifier + cmp [ebx+SymbolTree_Leaf.class],SYMCLASS_INSTRUCTION + je alm_call_instruction_ok + mov ebx,edx + mov [symbol_class],SYMCLASS_INSTRUCTION + or [symbol_required],1 + or [symbol_expected],1 + call scan_symbol_branch + jc invalid_identifier + mov edi,ebx + mark_instruction_fallbacks: + mov edx,[edi+SymbolTree_Leaf.fallback_neighbour] + test edx,edx + jz instruction_fallback_neighbour_ok + or [edx+SymbolTree_Leaf.extra_flags],SYMX_INSTRUCTION_PREDICTED + instruction_fallback_neighbour_ok: + mov edi,[edi+SymbolTree_Leaf.fallback_parent] + test edi,edi + jz alm_call_instruction_ok + or [edi+SymbolTree_Leaf.extra_flags],SYMX_INSTRUCTION_PREDICTED + jmp mark_instruction_fallbacks + alm_call_instruction_ok: + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov ecx,8+8 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,calm_call + stosd + mov eax,ebx + stosd + mov eax,alm_adjusted_context + cmp [embedded_context],eax + jne alm_call_argument + mov eax,[line_context] + mov [embedded_context],eax + alm_call_argument: + call move_to_next_symbol + jc alm_call_arguments_ready + cmp al,',' + jne alm_call_invalid_argument + inc esi + mov edx,calm_code_buffer + mov ecx,8 + call reserve_workspace + call move_to_next_symbol + jc alm_call_empty_argument + cmp al,',' + je alm_call_empty_argument + push edi + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + pop edi + jc alm_call_invalid_argument + test ebx,ebx + jz alm_call_invalid_argument + mov eax,ebx + stosd + jmp alm_call_argument + alm_call_empty_argument: + or eax,-1 + stosd + jmp alm_call_argument + alm_call_invalid_argument: + mov edx,_invalid_argument + call register_error + alm_call_arguments_ready: + xor eax,eax + stosd + mov [calm_code_cursor],edi + jmp instruction_assembled + +alm_exit: + test [assembly_mode],AMODE_CALM_DEFINITION + jz unexpected_instruction + mov edi,[calm_code_cursor] + mov edx,calm_code_buffer + mov ecx,8 + call reserve_workspace + mov eax,[calm_line_number] + stosd + mov eax,calm_end + stosd + mov [calm_code_cursor],edi + jmp instruction_assembled + +launch_calm: + mov eax,[current_pass] + mov [ebx+SymbolTree_Leaf.last_use_pass],eax + mov eax,[ebx+SymbolTree_Leaf.branch] + mov [instruction_branch],eax + mov [calm_value],edx + mov [calm_source_pointer],esi + mov esi,[edx+ValueDefinition.value] + mov eax,[esi+CompiledMacroHeader.literals_offset] + add eax,esi + mov [calm_literals],eax + mov [breakpoint_token],0 + mov ebx,[esi+CompiledMacroHeader.label_argument_leaf] + test ebx,ebx + jz calm_label_argument_ok + test [assembly_mode],AMODE_DEFINITION + setnz al + or al,[esi+CompiledMacroHeader.label_argument_contextless] + mov [contextless_processing],al + call update_value_definition + test edx,edx + jz calm_label_argument_ok + push esi + push edx + push [line_end] + push [embedded_context] + mov eax,[line_context] + mov [embedded_context],eax + mov esi,[line_start] + mov ecx,[label_instruction_start] + mov [line_end],ecx + sub ecx,esi + add ecx,1+sizeof.RecognitionContext + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + call reserve_workspace + xor edx,edx + mov [breakpoint_token],dl + call extract_piece_of_line + pop [embedded_context] + pop [line_end] + pop edx + mov [value_type],VALTYPE_SYMBOLIC + mov esi,[assembly_workspace.memory_start] + mov ecx,edi + sub ecx,esi + call assign_value + pop esi + calm_label_argument_ok: + add esi,sizeof.CompiledMacroHeader + mov eax,[esi] + inc eax + cmp eax,1 + jbe calm_arguments_defined + get_calm_argument: + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + mov ecx,[line_end] + sub ecx,[calm_source_pointer] + add ecx,1+sizeof.RecognitionContext + call reserve_workspace + test [assembly_mode],AMODE_DEFINITION + setnz al + or al,[esi+CompiledMacroArgument.contextless] + mov [contextless_processing],al + mov eax,[esi+sizeof.CompiledMacroArgument] + xchg esi,[calm_source_pointer] + inc eax + jz get_calm_greedy_argument + call extract_argument_value + jmp calm_argument_value_cut + get_calm_greedy_argument: + xor edx,edx + call extract_piece_of_line + calm_argument_value_cut: + xchg esi,[calm_source_pointer] + mov ebx,[esi+CompiledMacroArgument.symbol_leaf] + call update_value_definition + test edx,edx + jz calm_argument_ok + mov ecx,edi + sub ecx,[assembly_workspace.memory_start] + test ecx,ecx + jnz calm_argument_value_ready + or ecx,[esi+CompiledMacroArgument.default_value_length] + jz calm_argument_value_ready + cmp ecx,-1 + je missing_argument + push esi + mov esi,[esi+CompiledMacroArgument.default_value_offset] + add esi,[calm_literals] + jmp calm_assign_argument_value + calm_argument_value_ready: + push esi + mov esi,[assembly_workspace.memory_start] + calm_assign_argument_value: + mov [value_type],VALTYPE_SYMBOLIC + call assign_value + pop esi + calm_argument_ok: + add esi,sizeof.CompiledMacroArgument + mov eax,[esi] + inc eax + cmp eax,1 + jbe calm_arguments_defined + xchg esi,[calm_source_pointer] + call move_to_next_symbol + jc calm_next_argument + cmp al,',' + jne invalid_argument + inc esi + calm_next_argument: + xchg esi,[calm_source_pointer] + jmp get_calm_argument + calm_arguments_defined: + add esi,4 + and [calm_instruction_number],0 + call create_source_entry + jc calm_exceeded_stack_limit + mov edx,[calm_value] + mov [ebx+SourceEntry.type],SOURCE_CALM + mov [ebx+SourceEntry.text],edx + sub esi,[edx+ValueDefinition.value] + mov [ebx+SourceEntry.offset],esi + or [edx+ValueDefinition.flags],VAL_IN_USE + inc [edx+ValueDefinition.reference_count] + mov eax,[parameter_namespace] + mov [ebx+SourceEntry.local_namespace],eax + mov esi,[calm_source_pointer] + mov ecx,[instruction_branch] + test ecx,ecx + jz instruction_assembled + mov [ebx+SourceEntry.name],ecx + or [ebx+SourceEntry.name_length],-1 + jmp instruction_assembled + calm_exceeded_stack_limit: + mov edx,_stack_limit_exceeded + call register_error + jmp assembly_line + +calm_virtual_machine: + mov al,[ebx+SourceEntry.saved_result] + mov [calm_result],al + mov edx,[ebx+SourceEntry.text] + mov [calm_value],edx + mov esi,[edx+ValueDefinition.value] + mov eax,[esi+CompiledMacroHeader.literals_offset] + add eax,esi + mov [calm_literals],eax + add esi,[ebx+SourceEntry.offset] + calm_execution_unit: + lodsd + mov [calm_instruction_number],eax + lodsd + jmp eax + +calm_end: + mov ebx,[source_context] + mov ecx,[ebx+SourceContext.number_of_entries] + dec ecx + ; jz internal_error + mov [ebx+SourceContext.number_of_entries],ecx + imul ecx,sizeof.SourceEntry + mov edx,[ebx+sizeof.SourceContext+ecx+SourceEntry.text] + and [edx+ValueDefinition.flags],not VAL_IN_USE + dec [edx+ValueDefinition.reference_count] + jmp assembly_line + +calm_arrange: + lodsd + mov [label_leaf],eax + lodsd + mov ecx,eax + lodsd + push esi + mov esi,[calm_literals] + add eax,esi + add esi,ecx + mov [pattern_end],eax + mov edi,[assembly_workspace.memory_start] + arrange_by_pattern: + mov edx,assembly_workspace + mov ecx,[pattern_end] + sub ecx,esi + call reserve_workspace + arrange_token: + cmp esi,[pattern_end] + je assign_arranged_value + lodsb + cmp al,1Bh + je arrange_by_reference + cmp al,0A0h + je downgrade_hard_space + cmp al,0BFh + je restore_question_mark + stosb + cmp al,1Ah + je copy_arranged_token_data + cmp al,22h + je copy_arranged_token_data + cmp al,27h + je copy_arranged_token_data + cmp al,30h + jne arrange_token + lodsd + stosd + mov ecx,eax + rep movsb + jmp arrange_token + copy_arranged_token_data: + movsd + jmp arrange_token + downgrade_hard_space: + mov al,20h + stosb + jmp arrange_token + restore_question_mark: + mov al,'?' + stosb + jmp arrange_token + arrange_by_reference: + mov ebx,[esi+4] + call use_available_value + jc arrange_missing_value + mov al,[edx+ValueDefinition.type] + cmp al,VALTYPE_NUMERIC + je arrange_numeric_value + cmp al,VALTYPE_PLAIN + je arrange_plain_value + cmp al,VALTYPE_SYMBOLIC + jne arrange_unsupported_value + mov ecx,[edx+ValueDefinition.value_length] + jecxz arrange_empty_value + add ecx,1+sizeof.RecognitionContext + mov ebx,edx + mov edx,assembly_workspace + call reserve_workspace + mov edx,ebx + mov ebx,esi + mov esi,[edx+ValueDefinition.value] + mov ecx,[edx+ValueDefinition.value_length] + rep movsb + lea esi,[ebx+8] + cmp esi,[pattern_end] + je assign_arranged_value + mov al,40h + stosb + xor eax,eax + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep stosd + jmp arrange_by_pattern + arrange_numeric_value: + mov eax,[edx+ValueDefinition.value] + mov ecx,[eax] + cmp dword [eax+4+ecx],0 + jne arrange_unsupported_value + test byte [eax+4+ecx-1],80h + jnz arrange_unsupported_value + mov ebx,esi + mov esi,eax + mov edx,assembly_workspace + add ecx,1+4 + call reserve_workspace + mov al,30h + stosb + lodsd + stosd + mov ecx,eax + rep movsb + lea esi,[ebx+8] + jmp arrange_by_pattern + arrange_empty_value: + add esi,8 + jmp arrange_token + arrange_plain_value: + mov edx,[edx+ValueDefinition.value] + mov al,30h + stosb + mov ebx,edi + xor eax,eax + stosd + mov eax,edx + store_plain_bytes: + inc dword [ebx] + stosb + shr eax,8 + jnz store_plain_bytes + test byte [edi-1],80h + jnz store_plain_bytes + add esi,8 + jmp arrange_by_pattern + arrange_unsupported_value: + mov edx,_invalid_symbol_value + jmp arrange_failed_reference + arrange_missing_value: + mov edx,_undefined_symbol + arrange_failed_reference: + call register_error + mov al,1Ah + stosb + movsd + lodsd + mov eax,[eax+SymbolTree_Leaf.branch] + cmp [eax+SymbolTree_Foliage.name_kind],NAME_CASEINSENSITIVE + jne arrange_token + mov al,'?' + stosb + jmp arrange_token + assign_arranged_value: + mov ebx,[label_leaf] + call update_value_definition + test edx,edx + jz arranged_value_assigned + mov [value_type],VALTYPE_SYMBOLIC + mov ecx,edi + mov esi,[assembly_workspace.memory_start] + sub ecx,esi + call assign_value + arranged_value_assigned: + pop esi + jmp calm_execution_unit + +calm_match: + and [calm_result],0 + lodsd + mov ebx,eax + lodsd + mov ecx,eax + lodsd + mov edi,[calm_literals] + add eax,edi + add edi,ecx + mov [pattern_end],eax + lodsd + mov [brackets],eax + call use_available_value + jc calm_undefined_symbol + mov al,[edx+ValueDefinition.type] + cmp al,VALTYPE_RESERVED + je calm_undefined_symbol + cmp al,VALTYPE_SYMBOLIC + jne calm_invalid_value + push esi + mov [value],edx + inc [edx+ValueDefinition.reference_count] + mov esi,[edx+ValueDefinition.value] + mov ecx,[edx+ValueDefinition.value_length] + add ecx,esi + mov [line_end],ecx + mov ebx,[expression_workspace.memory_start] + and [matched_context],0 + and [stored_position],0 + calm_match_with_pattern: + cmp edi,[pattern_end] + je calm_end_of_pattern + mov ah,[edi] + cmp ah,1Bh + jne calm_exact_match + calm_wildcard_match: + and [stored_position],0 + add edi,1+8 + cmp edi,[pattern_end] + je calm_required_wildcard_match + cmp byte [edi],0BFh + je calm_optional_wildcard_match + calm_required_wildcard_match: + cmp esi,[line_end] + je calm_match_done + call calm_consume_whitespace + jz calm_match_done + xchg edi,ebx + mov edx,expression_workspace + mov ecx,sizeof.MatchedExcerpt + call reserve_workspace + xchg edi,ebx + mov eax,[edi-4] + mov ecx,[matched_context] + mov [ebx+MatchedExcerpt.symbol_leaf],eax + mov [ebx+MatchedExcerpt.recognition_context],ecx + mov [ebx+MatchedExcerpt.data_start],esi + mov al,[esi] + call calm_consume_token + jc calm_match_done + mov [ebx+MatchedExcerpt.data_end],esi + add ebx,sizeof.MatchedExcerpt + jmp calm_match_with_pattern + calm_optional_wildcard_match: + xchg edi,ebx + mov edx,expression_workspace + mov ecx,sizeof.MatchedExcerpt + call reserve_workspace + xchg edi,ebx + mov eax,[edi-4] + inc edi + mov ecx,[matched_context] + mov [ebx+MatchedExcerpt.symbol_leaf],eax + mov [ebx+MatchedExcerpt.recognition_context],ecx + mov [ebx+MatchedExcerpt.data_start],esi + mov [ebx+MatchedExcerpt.data_end],esi + add ebx,sizeof.MatchedExcerpt + jmp calm_match_with_pattern + calm_exact_match: + cmp esi,[line_end] + je calm_end_of_text + mov al,[esi] + cmp al,40h + jne found_token_to_match + inc esi + mov [matched_context],esi + add esi,sizeof.RecognitionContext + jmp calm_exact_match + found_token_to_match: + cmp [stored_position],0 + jne calm_match_position_stored + mov [stored_position],esi + mov ecx,[matched_context] + mov [stored_context],ecx + mov [stored_pattern],edi + calm_match_position_stored: + cmp al,20h + je calm_match_whitespace + cmp ah,20h + je calm_skip_pattern_whitespace + cmpsb + jne calm_token_mismatch + cmp ah,1Ah + je calm_match_name_tokens + cmp ah,22h + je calm_match_string_tokens + cmp ah,27h + je calm_match_string_tokens + cmp ah,30h + jne calm_match_with_pattern + mov ecx,esi + mov edx,edi + lodsd + add esi,eax + mov eax,[edi] + lea edi,[edi+4+eax] + cmp byte [edi],0BFh + jne calm_compare_token_contents + inc edi + jmp calm_compare_token_contents + calm_match_string_tokens: + lodsd + mov ecx,eax + mov edx,[edi] + add edi,4 + calm_compare_token_contents: + cmp ecx,edx + je calm_match_with_pattern + push esi edi + mov esi,ecx + mov edi,edx + mov ecx,[esi] + add ecx,4 + repe cmpsb + pop edi esi + jne calm_retract_match + jmp calm_match_with_pattern + calm_match_name_tokens: + lodsd + mov ecx,eax + mov edx,[edi] + add edi,4 + cmp byte [edi],0BFh + je calm_case_insensitive_match + cmp ecx,edx + je calm_match_with_pattern + push esi edi + mov esi,ecx + mov edi,edx + lodsd + scasd + jne calm_name_mismatch + mov ecx,eax + mov eax,[esi+ecx] + cmp eax,[edi+ecx] + jne calm_name_mismatch + repe cmpsb + jne calm_name_mismatch + pop edi esi + jmp calm_match_with_pattern + calm_name_mismatch: + pop edi esi + jmp calm_retract_match + calm_case_insensitive_match: + inc edi + cmp ecx,edx + je calm_match_with_pattern + push esi edi + mov esi,ecx + mov edi,edx + lodsd + scasd + jne calm_name_mismatch + mov ecx,eax + mov eax,[esi+ecx+4] + cmp eax,[edi+ecx+4] + jne calm_name_mismatch + xor eax,eax + calm_compare_case_insensitively: + lodsb + mov dl,[characters+eax] + mov al,[edi] + inc edi + cmp dl,[characters+eax] + jne name_mismatch + loop calm_compare_case_insensitively + pop edi esi + jmp calm_match_with_pattern + calm_match_converted_number: + call convert_number_to_match + jmp calm_compare_token_contents + calm_match_with_converted_number: + xchg esi,edi + call convert_number_to_match + xchg esi,edi + jmp calm_compare_token_contents + calm_match_whitespace: + cmp ah,20h + je calm_optional_whitespace + cmp ah,0A0h + je calm_required_whitespace + cmp [stored_pattern],edi + jne calm_retract_match + call calm_consume_whitespace + jz calm_match_done + and [stored_position],0 + jmp calm_match_with_pattern + calm_optional_whitespace: + inc edi + cmp edi,[pattern_end] + je calm_whitespace_matched + cmp byte [edi],0A0h + jne calm_whitespace_matched + calm_required_whitespace: + inc edi + cmp edi,[pattern_end] + je calm_whitespace_matched + cmp byte [edi],20h + jne calm_whitespace_matched + inc edi + calm_whitespace_matched: + call calm_consume_whitespace + jz calm_end_of_text + jmp calm_match_with_pattern + calm_skip_pattern_whitespace: + inc edi + jmp calm_match_with_pattern + calm_token_mismatch: + cmp ax,1A30h + je calm_match_converted_number + cmp ax,301Ah + je calm_match_with_converted_number + calm_retract_match: + xor esi,esi + xchg esi,[stored_position] + mov ecx,[stored_context] + mov [matched_context],ecx + mov edi,[stored_pattern] + call calm_consume_whitespace + jz calm_match_done + calm_expand_wildcard_match: + cmp ebx,[expression_workspace.memory_start] + je calm_match_done + call calm_consume_token + jc calm_match_done + mov [ebx-sizeof.MatchedExcerpt+MatchedExcerpt.data_end],esi + jmp calm_match_with_pattern + calm_consume_whitespace: + mov al,[esi] + cmp al,40h + je calm_consume_context_token + cmp al,20h + jne calm_whitespace_consumed + inc esi + cmp esi,[line_end] + jne calm_consume_whitespace + calm_whitespace_consumed: + retn + calm_consume_context_token: + inc esi + mov [matched_context],esi + add esi,sizeof.RecognitionContext + cmp esi,[line_end] + jne calm_consume_whitespace + retn + calm_consume_token: + xor ecx,ecx + mov edx,[brackets] + inc esi + consume_token_content: + cmp al,dh + je consume_closing + cmp al,dl + je consume_opening + cmp al,1Ah + je consume_token_with_data + cmp al,22h + je consume_token_with_data + cmp al,27h + je consume_token_with_data + cmp al,30h + je consume_internal_token + cmp al,40h + je consume_context_token + test ecx,ecx + jnz consume_more + retn + consume_token_with_data: + add esi,4 + test ecx,ecx + jnz consume_more + retn + consume_internal_token: + lodsd + add esi,eax + test ecx,ecx + jnz consume_more + retn + consume_context_token: + add esi,sizeof.RecognitionContext + test ecx,ecx + jnz consume_more + retn + consume_closing: + sub ecx,1 + jg consume_more + retn + consume_opening: + inc ecx + consume_more: + cmp esi,[line_end] + je consume_unsatisfied + lodsb + jmp consume_token_content + consume_unsatisfied: + stc + retn + calm_end_of_pattern: + cmp esi,[line_end] + je calm_match_found + lodsb + cmp al,20h + je calm_end_of_pattern + cmp al,40h + jne calm_another_token_to_match + add esi,sizeof.RecognitionContext + jmp calm_end_of_pattern + calm_another_token_to_match: + dec esi + cmp [stored_position],0 + je calm_expand_wildcard_match + jmp calm_retract_match + calm_end_of_text: + cmp edi,[pattern_end] + je calm_match_found + mov ah,[edi] + cmp ah,1Bh + je calm_wildcard_match + cmp ah,20h + jne calm_match_done + inc edi + jmp calm_end_of_text + calm_match_found: + or [calm_result],1 + mov esi,ebx + mov [value_type],VALTYPE_SYMBOLIC + calm_assign_matched_values: + cmp esi,[expression_workspace.memory_start] + je calm_match_done + sub esi,sizeof.MatchedExcerpt + mov ebx,[esi+MatchedExcerpt.symbol_leaf] + call update_value_definition + test edx,edx + jz calm_assign_matched_values + push esi + mov eax,[esi+MatchedExcerpt.recognition_context] + mov ecx,[esi+MatchedExcerpt.data_end] + mov esi,[esi+MatchedExcerpt.data_start] + sub ecx,esi + jz calm_matched_value_ready + test eax,eax + jz calm_matched_value_ready + cmp dword [eax],0 + je calm_matched_value_ready + push esi ecx edx + mov esi,eax + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + add ecx,1+sizeof.RecognitionContext + call reserve_workspace + mov al,40h + stosb + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep movsd + pop edx ecx esi + rep movsb + mov ecx,edi + mov esi,[assembly_workspace.memory_start] + sub ecx,esi + calm_matched_value_ready: + call assign_value + pop esi + jmp calm_assign_matched_values + calm_match_done: + mov edx,[value] + dec [edx+ValueDefinition.reference_count] + pop esi + jmp calm_execution_unit + +calm_compute: + lodsd + mov [label_leaf],eax + lodsd + add eax,esi + push eax + mov edi,[calculation_workspace.memory_start] + and [value_position],0 + call calculate_parsed_expression + call pop_terms + jc calm_compute_done + mov al,byte [edi+ExpressionTerm.attributes] + cmp al,EXPR_STRING + je calm_computed_string + cmp al,EXPR_FLOAT + je calm_computed_float + call convert_terms_to_numeric_value + mov [value_type],VALTYPE_NUMERIC + calm_computed_value_ready: + mov edi,ecx + mov ebx,[label_leaf] + call update_value_definition + test edx,edx + jz calm_compute_done + mov ecx,edi + call assign_value + calm_compute_done: + pop esi + jmp calm_execution_unit + calm_computed_string: + call get_term_value + mov esi,edx + mov ecx,[esi] + add ecx,4 + mov [value_type],VALTYPE_STRING + jmp calm_computed_value_ready + calm_computed_float: + call get_term_value + mov esi,edx + mov ecx,sizeof.FloatData + mov [value_type],VALTYPE_FLOAT + jmp calm_computed_value_ready + +calm_check: + lodsd + test eax,eax + jz calm_execution_unit + js calm_check + calm_evaluate_logical_value: + call evaluate_stored_logical_value + mov [calm_result],al + add esi,[esi-4] + find_next_logical_value: + lodsd + test eax,eax + jz calm_execution_unit + jns next_logical_value_found + cmp eax,BOOL_NEG + jne find_next_logical_value + xor [calm_result],1 + jmp find_next_logical_value + next_logical_value_found: + mov ebx,esi + xor ecx,ecx + skip_next_logical_value: + inc ecx + add esi,eax + skip_logical_operator: + lodsd + assert BOOL_NEG = -1 + cmp eax,BOOL_NEG + jg skip_next_logical_value + je skip_logical_operator + dec ecx + jnz skip_logical_operator + cmp eax,BOOL_AND + je calm_and + calm_or: + cmp [calm_result],0 + jne find_next_logical_value + mov esi,ebx + jmp calm_evaluate_logical_value + calm_and: + cmp [calm_result],0 + je find_next_logical_value + mov esi,ebx + jmp calm_evaluate_logical_value + +calm_jyes: + cmp [calm_result],0 + jne calm_jump + add esi,4 + jmp calm_execution_unit +calm_jno: + cmp [calm_result],0 + je calm_jump + add esi,4 + jmp calm_execution_unit +calm_jump: + lodsd + mov edx,[calm_value] + add eax,[edx+ValueDefinition.value] + mov esi,eax + jmp calm_execution_unit + +calm_assemble: + lodsd + mov ebx,eax + mov eax,[current_pass] + mov [ebx+SymbolTree_Leaf.last_use_pass],eax + mov eax,[ebx+SymbolTree_Leaf.branch] + mov [instruction_branch],eax + call use_available_value + jc calm_undefined_symbol + mov al,[edx+ValueDefinition.type] + cmp al,VALTYPE_SYMBOLIC + jne calm_invalid_value + call create_source_entry + jc calm_assemble_exceeded_stack_limit + mov [ebx+SourceEntry.type],SOURCE_MACRO + or [ebx+SourceEntry.flags],SRCF_PREPROCESSED + mov [ebx+SourceEntry.text],edx + or [edx+ValueDefinition.flags],VAL_IN_USE + inc [edx+ValueDefinition.reference_count] + mov eax,[calm_instruction_number] + mov [ebx-sizeof.SourceEntry+SourceEntry.line_number],eax + mov edx,[ebx-sizeof.SourceEntry+SourceEntry.text] + mov ecx,[edx+ValueDefinition.value] + sub esi,ecx + mov [ebx-sizeof.SourceEntry+SourceEntry.offset],esi + mov eax,[ebx-sizeof.SourceEntry+SourceEntry.local_namespace] + mov [ebx+SourceEntry.local_namespace],eax + mov al,[calm_result] + mov [ebx-sizeof.SourceEntry+SourceEntry.saved_result],al + mov ecx,[instruction_branch] + test ecx,ecx + jz assembly_line + mov [ebx+SourceEntry.name],ecx + or [ebx+SourceEntry.name_length],-1 + jmp assembly_line + calm_undefined_symbol: + mov edx,_undefined_symbol + jmp calm_execution_error + calm_invalid_value: + mov edx,_invalid_symbol_value + jmp calm_execution_error + calm_assemble_exceeded_stack_limit: + mov edx,_stack_limit_exceeded + calm_execution_error: + call register_error + jmp calm_execution_unit + +calm_transform: + mov [calm_result],0 + lodsd + mov [label_leaf],eax + mov ebx,eax + lodsd + mov [transforming_namespace],eax + call get_available_value + jc calm_undefined_symbol + cmp [edx+ValueDefinition.type],VALTYPE_SYMBOLIC + jne calm_invalid_value + push esi + call clear_line_embeddings + mov esi,[edx+ValueDefinition.value] + mov [line_start],esi + xor eax,eax + mov [embedded_context],eax + mov [line_context],eax + mov ecx,[edx+ValueDefinition.value_length] + add ecx,esi + mov [line_end],ecx + mov edi,[assembly_workspace.memory_start] + mov [hidden_context],0 + transform_symbolic_value: + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + push edi + mov eax,[embedded_context] + mov [line_context],eax + mov ebx,[transforming_namespace] + test ebx,ebx + jz transform_identify + call identify_symbol_in_namespace + jmp transform_identification_done + transform_identify: + call identify_symbol + transform_identification_done: + jc symbolic_value_transformed + test edi,edi + jnz ready_to_transform + call skip_literal + xor ebx,ebx + ready_to_transform: + pop edi + test ebx,ebx + jz untransformed_literal + mov [further_whitespace],ecx + call get_available_value + jc untransformed_literal + cmp [edx+ValueDefinition.type],VALTYPE_SYMBOLIC + jne untransformed_literal + mov eax,[current_pass] + mov [ebx+SymbolTree_Leaf.last_use_pass],eax + mov [calm_result],1 + mov [line_start],esi + mov esi,[edx+ValueDefinition.value] + mov ecx,[edx+ValueDefinition.value_length] + mov ebx,ecx + add ecx,[further_whitespace] + add ecx,1+sizeof.RecognitionContext + mov edx,assembly_workspace + call reserve_workspace + test ebx,ebx + jz symbol_transformed + mov al,1 + xchg al,[hidden_context] + test al,al + jnz reset_hidden_context + cmp [line_context],0 + je copy_transformed_value + reset_hidden_context: + xor edx,edx + call reset_transformed_context + copy_transformed_value: + mov ecx,ebx + rep movsb + symbol_transformed: + mov ecx,[further_whitespace] + mov al,20h + rep stosb + mov esi,[line_start] + jmp transform_symbolic_value + untransformed_literal: + mov ecx,esi + xchg esi,[line_start] + sub ecx,esi + mov ebx,ecx + add ecx,1+sizeof.RecognitionContext + mov edx,assembly_workspace + call reserve_workspace + xor al,al + xchg al,[hidden_context] + test al,al + jz copy_untransformed_literal + mov edx,[line_context] + call reset_transformed_context + copy_untransformed_literal: + mov ecx,ebx + rep movsb + jmp transform_symbolic_value + reset_transformed_context: + mov al,40h + cmp [esi],al + je transformed_context_ok + stosb + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + test edx,edx + jz clear_transformed_context + xchg esi,edx + rep movsd + mov esi,edx + transformed_context_ok: + retn + clear_transformed_context: + xor eax,eax + rep stosd + retn + symbolic_value_transformed: + pop edi + cmp [calm_result],0 + je calm_transform_done + mov ebx,[label_leaf] + call update_value_definition + test edx,edx + jz calm_transform_done + mov esi,[assembly_workspace.memory_start] + mov ecx,edi + sub ecx,esi + mov [value_type],VALTYPE_SYMBOLIC + call assign_value + calm_transform_done: + pop esi + jmp calm_execution_unit + +calm_stringify: + lodsd + mov [label_leaf],eax + mov ebx,eax + call get_available_value + jc calm_undefined_symbol + mov al,[edx+ValueDefinition.type] + cmp al,VALTYPE_SYMBOLIC + jne calm_invalid_value + mov eax,[edx+ValueDefinition.value] + mov [symbol_value_start],eax + mov ecx,[edx+ValueDefinition.value_length] + add ecx,eax + mov [symbol_value_end],ecx + push esi + call convert_symbolic_value_to_string + mov edi,ecx + mov ebx,[label_leaf] + call update_value_definition + test edx,edx + jz calm_stringify_done + mov ecx,edi + mov [value_type],VALTYPE_STRING + call assign_value + calm_stringify_done: + pop esi + jmp calm_execution_unit + +calm_publish_constant: + mov edi,create_constant_value_definition + jmp calm_publish +calm_publish_stack: + mov edi,create_value_definition + jmp calm_publish +calm_publish_variable: + mov edi,update_value_definition + calm_publish: + lodsd + mov ebx,eax + lodsd + mov [label_leaf],eax + call use_available_value + jc calm_undefined_symbol + mov al,[edx+ValueDefinition.type] + cmp al,VALTYPE_SYMBOLIC + jne calm_invalid_value + push esi edi + call clear_line_embeddings + mov esi,[edx+ValueDefinition.value] + mov [line_start],esi + mov ecx,[edx+ValueDefinition.value_length] + add ecx,esi + mov [line_end],ecx + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + mov eax,esi + pop edi esi + jc calm_invalid_identifier + test ebx,ebx + jz calm_invalid_identifier + cmp eax,[line_end] + jne calm_invalid_identifier + xchg ebx,[label_leaf] + call use_available_value + jc calm_undefined_symbol + mov al,[edx+ValueDefinition.type] + cmp al,VALTYPE_SYMBOLIC + jb calm_invalid_value + cmp al,VALTYPE_PLAIN + je calm_value_type_ok + cmp al,VALTYPE_AREA + ja calm_invalid_value + calm_value_type_ok: + mov [value_type],al + mov [value],edx + mov ebx,[label_leaf] + call edi + test edx,edx + jz calm_execution_unit + push esi + mov eax,[value] + mov esi,[eax+ValueDefinition.value] + mov ecx,[eax+ValueDefinition.value_length] + call assign_value + pop esi + jmp calm_execution_unit + calm_invalid_identifier: + mov edx,_invalid_identifier + call register_error + jmp calm_execution_unit + +calm_take: + lodsd + mov edi,eax + lodsd + mov ebx,eax + xor edx,edx + call remove_value_definition + setnc [calm_result] + jmp calm_execution_unit + +calm_display: + call compute_calm_constant + jc calm_execution_unit + cmp al,EXPR_STRING + je calm_display_string + cmp al,EXPR_NUMBER + je calm_display_character + calm_invalid_argument: + mov edx,_invalid_argument + call register_error + jmp calm_execution_unit + calm_display_string: + call display_string_data + jmp calm_execution_unit + calm_display_character: + call display_single_byte_data + jmp calm_execution_unit + +calm_err: + call compute_calm_constant + jc calm_execution_unit + cmp al,EXPR_STRING + jne calm_invalid_argument + call register_volatile_error + test edx,edx + jz calm_execution_unit + or [edx+Error.flags],ERR_CUSTOM + jmp calm_execution_unit + +calm_emit: + call compute_calm_constant + jc calm_invalid_data_unit + cmp al,EXPR_NUMBER + jne calm_invalid_data_unit + mov edi,data_unit_length + mov ecx,4 + call fit_value + jc calm_invalid_data_unit + jns calm_emit_data + calm_invalid_data_unit: + mov edx,_invalid_argument + call register_error + mov [data_unit_length],1 + calm_emit_data: + lodsd + test eax,eax + jz calm_reserve_data + add eax,esi + push eax + mov edi,[calculation_workspace.memory_start] + and [value_position],0 + call calculate_parsed_expression + pop esi + call pop_terms + jc calm_execution_unit + push edi + mov ecx,[data_unit_length] + call initialize_output + xchg edi,[esp] + call get_calculated_constant_value + pop edi + cmp al,EXPR_FLOAT + je calm_emit_float + cmp al,EXPR_STRING + je calm_emit_string + cmp al,EXPR_NUMBER + jne calm_invalid_argument + mov ecx,[data_unit_length] + call fit_value + jnc calm_execution_unit + calm_emit_out_of_range: + mov edx,_value_out_of_range + call register_error + jmp calm_execution_unit + calm_emit_string: + mov eax,[data_unit_length] + mov ecx,[edx] + sub eax,ecx + jc calm_emit_out_of_range + xchg esi,edx + add esi,4 + rep movsb + mov ecx,eax + xor al,al + rep stosb + mov esi,edx + jmp calm_execution_unit + calm_emit_float: + push esi + mov esi,edx + mov ecx,[data_unit_length] + call fit_float + pop esi + jmp calm_execution_unit + calm_reserve_data: + mov ecx,[data_unit_length] + call uninitialized_output + jmp calm_execution_unit + compute_calm_constant: + lodsd + test eax,eax + jz calm_constant_invalid + add eax,esi + push eax + mov edi,[calculation_workspace.memory_start] + and [value_position],0 + call calculate_parsed_expression + pop esi + call pop_terms + jc calm_constant_invalid + call get_calculated_constant_value + clc + retn + calm_constant_invalid: + stc + retn + +calm_load: + lodsd + mov [label_leaf],eax + lodsd + add eax,esi + push eax + mov edi,esi + and [value_position],0 + call get_area_value + pop esi + jc calm_load_area_invalid + mov [data_area_symbol],ebx + mov [data_area],edx + call compute_calm_constant + jc calm_load_offset_invalid + cmp al,EXPR_NUMBER + jne calm_load_offset_invalid + mov edi,data_offset + mov ecx,4 + call fit_value + jc calm_load_offset_invalid + js calm_load_offset_invalid + call compute_calm_constant + jc calm_load_length_invalid + cmp al,EXPR_NUMBER + jne calm_load_length_invalid + mov edi,value_length + mov ecx,4 + call fit_value + jc calm_load_length_invalid + js calm_load_length_invalid + mov ebx,[label_leaf] + call update_value_definition + test edx,edx + jz calm_execution_unit + mov ecx,[value_length] + add ecx,4 + mov [value_type],VALTYPE_STRING + push edx esi + xor esi,esi + call assign_value + mov edi,[edx+ValueDefinition.value] + mov eax,[value_length] + mov ecx,eax + stosd + mov edx,[data_area] + call load_from_area + pop esi edx + jnc calm_execution_unit + mov [edx+ValueDefinition.value_length],4 + mov edi,[edx+ValueDefinition.value] + and dword [edi],0 + jmp calm_execution_unit + calm_load_area_invalid: + lodsd + add esi,eax + calm_load_offset_invalid: + lodsd + add esi,eax + calm_load_length_invalid: + jmp calm_invalid_argument +calm_load_from_output: + lodsd + mov [label_leaf],eax + call compute_calm_constant + jc calm_load_offset_invalid + cmp al,EXPR_NUMBER + jne calm_load_offset_invalid + mov edi,file_offset + mov ecx,8 + call fit_value + jc calm_load_offset_invalid + js calm_load_offset_invalid + call compute_calm_constant + jc calm_load_length_invalid + cmp al,EXPR_NUMBER + jne calm_load_length_invalid + mov edi,value_length + mov ecx,4 + call fit_value + jc calm_load_length_invalid + js calm_load_length_invalid + mov ebx,[label_leaf] + call update_value_definition + test edx,edx + jz calm_execution_unit + mov ecx,[value_length] + add ecx,4 + mov [value_type],VALTYPE_STRING + push esi + xor esi,esi + call assign_value + mov edi,[edx+ValueDefinition.value] + mov eax,[value_length] + mov ecx,eax + stosd + push edx + call read_from_output + pop edx esi + mov ecx,[value_length] + test ecx,ecx + jz calm_execution_unit + sub [edx+ValueDefinition.value_length],ecx + mov edi,[edx+ValueDefinition.value] + sub [edi],ecx + calm_address_out_of_range: + mov edx,_address_out_of_range + call register_error + jmp calm_execution_unit + +calm_store: + lodsd + add eax,esi + push eax + mov edi,esi + and [value_position],0 + call get_area_value + pop esi + jc calm_store_area_invalid + mov [data_area_symbol],ebx + mov [data_area],edx + call compute_calm_constant + jc calm_store_offset_invalid + cmp al,EXPR_NUMBER + jne calm_store_offset_invalid + mov edi,data_offset + mov ecx,4 + call fit_value + jc calm_store_offset_invalid + js calm_store_offset_invalid + call compute_calm_constant + jc calm_store_length_invalid + cmp al,EXPR_NUMBER + jne calm_store_length_invalid + mov edi,value_length + mov ecx,4 + call fit_value + jc calm_store_length_invalid + js calm_store_length_invalid + call prepare_area_to_write + jc calm_store_not_possible + push edi + call compute_calm_constant + pop edi + jc calm_store_value_invalid + mov ecx,[value_length] + cmp al,EXPR_STRING + je calm_store_string + cmp al,EXPR_NUMBER + jne calm_store_value_invalid + call fit_value + jc calm_emit_out_of_range + jmp calm_execution_unit + calm_store_string: + mov eax,ecx + mov ecx,[edx] + sub eax,ecx + jc calm_emit_out_of_range + push esi + lea esi,[edx+4] + rep movsb + xchg ecx,eax + rep stosb + pop esi + jmp calm_execution_unit + calm_store_area_invalid: + lodsd + add esi,eax + calm_store_offset_invalid: + lodsd + add esi,eax + calm_store_length_invalid: + lodsd + add esi,eax + calm_store_value_invalid: + jmp calm_invalid_argument + calm_store_not_possible: + lodsd + add esi,eax + jmp calm_execution_unit +calm_store_in_output: + call compute_calm_constant + jc calm_store_offset_invalid + cmp al,EXPR_NUMBER + jne calm_store_offset_invalid + mov edi,file_offset + mov ecx,8 + call fit_value + jc calm_store_offset_invalid + js calm_store_offset_invalid + call compute_calm_constant + jc calm_store_length_invalid + cmp al,EXPR_NUMBER + jne calm_store_length_invalid + mov edi,value_length + mov ecx,4 + call fit_value + jc calm_store_length_invalid + js calm_store_length_invalid + call compute_calm_constant + mov ecx,[value_length] + cmp al,EXPR_STRING + je try_exact_store + cmp al,EXPR_NUMBER + jne calm_store_value_invalid + try_exact_store: + cmp ecx,[edx] + jne indirect_store + push esi + lea esi,[edx+4] + jmp calm_rewrite_output + indirect_store: + push eax ecx edx + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + call reserve_workspace + pop edx ecx eax + cmp al,EXPR_STRING + je calm_store_string_in_output + call fit_value + jc calm_emit_out_of_range + push esi + calm_store_finish: + mov esi,[assembly_workspace.memory_start] + calm_rewrite_output: + call rewrite_output + pop esi + cmp [value_length],0 + jne calm_address_out_of_range + jmp calm_execution_unit + calm_store_string_in_output: + mov eax,ecx + mov ecx,[edx] + sub eax,ecx + jc calm_emit_out_of_range + push esi + lea esi,[edx+4] + rep movsb + xchg ecx,eax + rep stosb + jmp calm_store_finish + +calm_call: + lodsd + mov ebx,eax + mov eax,[current_pass] + mov [ebx+SymbolTree_Leaf.last_use_pass],eax + mov eax,[ebx+SymbolTree_Leaf.branch] + mov [instruction_branch],eax + call use_available_value + jc calm_call_undefined + mov al,[edx+ValueDefinition.type] + cmp al,VALTYPE_CALM + jne calm_call_invalid + call create_source_entry + jc calm_call_exceeded_stack_limit + xor eax,eax + xchg eax,[calm_instruction_number] + mov [ebx-sizeof.SourceEntry+SourceEntry.line_number],eax + mov eax,[parameter_namespace] + mov [ebx+SourceEntry.local_namespace],eax + mov ecx,[instruction_branch] + test ecx,ecx + jz called_name_ok + mov [ebx+SourceEntry.name],ecx + or [ebx+SourceEntry.name_length],-1 + called_name_ok: + mov [ebx+SourceEntry.type],SOURCE_CALM + mov [ebx+SourceEntry.text],edx + or [edx+ValueDefinition.flags],VAL_IN_USE + inc [edx+ValueDefinition.reference_count] + mov edi,esi + mov esi,[edx+ValueDefinition.value] + mov eax,[esi+CompiledMacroHeader.literals_offset] + add eax,esi + mov [calm_value],edx + mov [calm_literals],eax + add esi,sizeof.CompiledMacroHeader + push ebx + process_call_arguments: + mov eax,[esi] + inc eax + cmp eax,1 + jbe call_arguments_ready + mov ebx,[edi] + test ebx,ebx + jz omitted_call_argument + add edi,4 + cmp ebx,-1 + je omitted_call_argument + call use_available_value + jc missing_argument_value + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_COMMAND + jae unassignable_value + push edx + mov ebx,[esi+CompiledMacroArgument.symbol_leaf] + call update_value_definition + pop eax + push esi edi + mov esi,[eax+ValueDefinition.value] + mov ecx,[eax+ValueDefinition.value_length] + mov al,[eax+ValueDefinition.type] + cmp al,VALTYPE_ELEMENT + je assign_element + cmp al,VALTYPE_AREA + je assign_element + assign_call_argument: + test edx,edx + jz call_argument_assigned + mov [value_type],al + call assign_value + call_argument_assigned: + pop edi esi + next_call_argument: + add esi,sizeof.CompiledMacroArgument + jmp process_call_arguments + missing_argument_value: + mov edx,_undefined_symbol + call register_error + jmp next_call_argument + unassignable_value: + mov edx,_invalid_symbol_value + call register_error + jmp next_call_argument + omitted_call_argument: + mov ebx,[esi+CompiledMacroArgument.symbol_leaf] + call update_value_definition + push esi edi + mov ecx,[esi+CompiledMacroArgument.default_value_length] + mov esi,[esi+CompiledMacroArgument.default_value_offset] + add esi,[calm_literals] + mov al,VALTYPE_SYMBOLIC + cmp ecx,-1 + jne assign_call_argument + inc ecx + push edx + mov edx,_invalid_argument + call register_error + pop edx + jmp assign_call_argument + assign_element: + mov ecx,[edi-4] + mov edi,[assembly_workspace.memory_start] + mov esi,edi + xor eax,eax + stosd + mov eax,ecx + stosd + xor eax,eax + inc eax + stosd + stosb + dec eax + stosd + mov ecx,17 + mov al,VALTYPE_NUMERIC + jmp assign_call_argument + call_arguments_ready: + add esi,4 + mov eax,[edi] + add edi,4 + test eax,eax + jz call_arguments_ok + mov edx,_invalid_argument + call register_error + skip_excess_arguments: + mov eax,[edi] + add edi,4 + test eax,eax + jnz skip_excess_arguments + call_arguments_ok: + pop ebx + mov eax,[ebx-sizeof.SourceEntry+SourceEntry.text] + mov ecx,[eax+ValueDefinition.value] + sub edi,ecx + mov [ebx-sizeof.SourceEntry+SourceEntry.offset],edi + mov al,[calm_result] + mov [ebx-sizeof.SourceEntry+SourceEntry.saved_result],al + jmp calm_execution_unit + calm_call_undefined: + mov edx,_undefined_symbol + jmp calm_call_error + calm_call_invalid: + mov edx,_invalid_symbol_value + jmp calm_call_error + calm_call_exceeded_stack_limit: + mov edx,_stack_limit_exceeded + calm_call_error: + call register_error + skip_call_arguments: + lodsd + test eax,eax + jnz skip_call_arguments + jmp calm_execution_unit \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/source/conditions.inc b/toolchain/fasmg.kl0e/source/conditions.inc new file mode 100644 index 0000000..2ed713e --- /dev/null +++ b/toolchain/fasmg.kl0e/source/conditions.inc @@ -0,0 +1,669 @@ + +COND_NEGATED = 1 ; only with COND_EVALUATE +COND_TRUE = 1 ; only with COND_DETERMINED +COND_EVALUATE = 2 +COND_DETERMINED = 4 + +get_condition_value: +; in: +; esi = pointer into preprocessed line or the last embedded line +; out: +; esi = pointer advanced past the processed line +; al = logical value + mov ebx,[condition_stack_base] + mov [condition_stack],ebx + mov byte [ebx],COND_EVALUATE + get_logical_value: + call peek_at_constituent_value + cmp al,'~' + jne negation_registered + and [current_constituent],0 + mov ebx,[condition_stack] + mov al,[ebx] + test byte [ebx],COND_EVALUATE + jz get_logical_value + xor byte [ebx],COND_NEGATED + jmp get_logical_value + negation_registered: + call parse_logical_value + setnc dh + mov dl,al + jecxz get_logical_operator + mov ebx,[condition_stack] + lea eax,[ebx+ecx+1] + cmp eax,[condition_stack_end] + jbe condition_stack_ready + push ecx edx + mov ecx,eax + mov eax,[condition_stack_base] + sub ecx,eax + sub ebx,eax + call grow_stack + mov [condition_stack_base],eax + add ebx,eax + mov [condition_stack],ebx + add eax,ecx + mov [condition_stack_end],eax + pop edx ecx + condition_stack_ready: + xor al,al + test byte [ebx],COND_EVALUATE + jz store_opening_parentheses + or al,COND_EVALUATE + store_opening_parentheses: + inc ebx + mov [ebx],al + loop store_opening_parentheses + mov [condition_stack],ebx + cmp dx,'~' + je get_logical_value + get_logical_operator: + call peek_at_constituent_value + jc end_of_logical_expression + cmp al,')' + je close_logical_subexpression + cmp al,'|' + je logical_or + cmp al,'&' + jne end_of_logical_expression + logical_and: + and [current_constituent],0 + mov ebx,[condition_stack] + mov al,[ebx] + test al,COND_EVALUATE + jnz evaluate_logical_and + test al,COND_DETERMINED + jz get_logical_value + test al,COND_TRUE + jz determined_false + jmp continue_evaluation + evaluate_logical_and: + test al,COND_NEGATED + jnz evaluate_negated_logical_and + call evaluate_logical_value + mov ebx,[condition_stack] + test al,al + jnz continue_evaluation + determined_false: + mov byte [ebx],COND_DETERMINED + jmp get_logical_value + evaluate_negated_logical_and: + call evaluate_logical_value + mov ebx,[condition_stack] + test al,al + jnz determined_false + continue_evaluation: + mov byte [ebx],COND_EVALUATE + jmp get_logical_value + logical_or: + and [current_constituent],0 + mov ebx,[condition_stack] + mov al,[ebx] + test al,COND_EVALUATE + jnz evaluate_logical_or + test al,COND_DETERMINED + jz get_logical_value + test al,COND_TRUE + jnz determined_true + jmp continue_evaluation + evaluate_logical_or: + test al,COND_NEGATED + jnz evaluate_negated_logical_or + call evaluate_logical_value + mov ebx,[condition_stack] + test al,al + jnz determined_true + jmp continue_evaluation + evaluate_negated_logical_or: + call evaluate_logical_value + mov ebx,[condition_stack] + test al,al + jnz continue_evaluation + determined_true: + mov byte [ebx],COND_DETERMINED + COND_TRUE + jmp get_logical_value + close_logical_subexpression: + and [current_constituent],0 + mov ebx,[condition_stack] + cmp ebx,[condition_stack_base] + je excess_parenthesis + mov al,[ebx] + dec ebx + mov [condition_stack],ebx + test al,COND_DETERMINED + jnz subexpression_determined + cmp al,COND_EVALUATE + COND_NEGATED + jne get_logical_operator + test byte [ebx],COND_EVALUATE + jz get_logical_operator + xor byte [ebx],COND_NEGATED + jmp get_logical_operator + subexpression_determined: + test al,COND_TRUE + jnz subexpression_determined_true + mov [comparator],evaluated_false + jmp get_logical_operator + subexpression_determined_true: + mov [comparator],evaluated_true + jmp get_logical_operator + end_of_logical_expression: + mov ebx,[condition_stack] + cmp ebx,[condition_stack_base] + jne missing_parenthesis + mov al,[ebx] + test al,COND_DETERMINED + jnz condition_determined + test al,COND_NEGATED + jz evaluate_logical_value + call evaluate_logical_value + test al,al + setz al + retn + condition_determined: + and al,COND_TRUE + retn + excess_parenthesis: + mov edx,_excess_closing_parenthesis + call register_error + jmp unknown_condition + missing_parenthesis: + mov edx,_missing_closing_parenthesis + call register_error + unknown_condition: + xor al,al + retn + +parse_logical_value: +; in: +; esi = pointer into preprocessed line or the last embedded line +; out: +; [comparator] - evaluating routine +; [expression_workspace.memory_start] - parsed argument sequences +; [expression_end] - end of the parsed argument sequences +; esi = pointer advanced past the parsed value +; al = special character that follows parsed value, zero if no more symbols in line +; ecx = number of parentheses opened before the value that did not get closed +; cf set if value was empty + mov edi,[expression_workspace.memory_start] + xor eax,eax + mov [comparator],eax + or [leave_opening_parentheses],1 + call parse_expression + mov [initial_parentheses],ecx + mov [expression_end],edi + call peek_at_constituent_value + jc end_of_line + cmp al,'&' + je end_of_logical_value + cmp al,'|' + je end_of_logical_value + cmp al,'~' + je end_of_logical_value + cmp al,')' + je end_of_logical_value + cmp al,1Ah + je identify_comparator + cmp al,'=' + je parse_equal + cmp al,'<' + je parse_less + cmp al,'>' + je parse_greater + jmp end_of_logical_value + identify_comparator: + test edx,edx + jz end_of_logical_value + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_COMPARATOR + jne end_of_logical_value + and [current_constituent],0 + mov eax,[edx+ValueDefinition.value] + jmp set_comparator + parse_less: + and [current_constituent],0 + call warp_to_next_symbol + jc parse_less_than + test ecx,ecx + jnz parse_less_than + call peek_at_constituent_value + jc parse_less_than + cmp al,'=' + je parse_less_or_equal + cmp al,'>' + je parse_not_equal + parse_less_than: + mov eax,check_if_less + jmp set_comparator + parse_less_or_equal: + and [current_constituent],0 + mov eax,check_if_not_greater + jmp set_comparator + parse_not_equal: + and [current_constituent],0 + mov eax,check_if_not_equal + jmp set_comparator + parse_greater: + and [current_constituent],0 + call warp_to_next_symbol + jc parse_greater_than + test ecx,ecx + jnz parse_greater_than + call peek_at_constituent_value + jc parse_greater_than + cmp al,'=' + je parse_greater_or_equal + parse_greater_than: + mov eax,check_if_greater + jmp set_comparator + parse_greater_or_equal: + and [current_constituent],0 + mov eax,check_if_not_less + jmp set_comparator + parse_equal: + and [current_constituent],0 + mov eax,check_if_equal + set_comparator: + mov edi,[expression_end] + mov [comparator],eax + and [leave_opening_parentheses],0 + call parse_expression + mov [expression_end],edi + call peek_at_constituent_value + jnc end_of_logical_value + end_of_line: + xor al,al + end_of_logical_value: + mov ecx,[initial_parentheses] + cmp [comparator],0 + jnz logical_value_not_empty + mov [comparator],check_if_not_zero + mov ebx,[expression_workspace.memory_start] + cmp dword [ebx],0 + jne logical_value_not_empty + stc + retn + logical_value_not_empty: + clc + retn + +evaluate_logical_value: +; in: +; [comparator] - evaluating routine +; [expression_workspace.memory_start] - parsed argument sequences +; out: al = logical value +; note: evaluates value prepared by previous call to parse_logical_value +; preserves: esi + push esi + mov esi,[expression_workspace.memory_start] + jmp [comparator] + evaluated_false: + pop esi + xor al,al + retn + evaluated_true: + pop esi + mov al,1 + retn + +evaluate_stored_logical_value: +; in: esi - pointer to evaluating routine followed by parsed argument sequences +; out: al = logical value +; preserves: esi + push esi + lodsd + jmp eax + +invalid_logical_value: + mov edx,_invalid_expression + call register_error + jmp evaluated_false + +check_if_equal: + call get_difference_signum + test al,al + jz evaluated_true + jmp evaluated_false +check_if_not_equal: + call get_difference_signum + test al,al + jnz evaluated_true + jmp evaluated_false +check_if_less: + call get_difference_signum + cmp al,0 + jl evaluated_true + jmp evaluated_false +check_if_not_less: + call get_difference_signum + cmp al,0 + jnl evaluated_true + jmp evaluated_false +check_if_greater: + call get_difference_signum + cmp al,0 + jg evaluated_true + jmp evaluated_false +check_if_not_greater: + call get_difference_signum + cmp al,0 + jng evaluated_true + jmp evaluated_false + get_difference_signum: + mov edi,[calculation_workspace.memory_start] + call calculate_parsed_expression + jc signum_error + call calculate_parsed_expression + jc signum_error + mov esi,subtraction_operator + call calculate_parsed_expression + call pop_terms + mov eax,edi + jnc check_difference_for_variable_terms + signum_error: + xor al,al + retn + check_difference_for_variable_terms: + add eax,sizeof.ExpressionTerm + cmp [eax+ExpressionTerm.attributes],0 + je difference_terms_ok + cmp [eax+ExpressionTerm.metadata],0 + je check_difference_for_variable_terms + mov edx,_values_not_comparable + call register_error + difference_terms_ok: + cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT + je get_float_signum + call get_numeric_term_value + mov ecx,1 + call fit_value + js signum_negative + jc signum_positive + xor al,al + cmp [edi],al + jne signum_positive + retn + get_float_signum: + call get_term_value + mov esi,edx + call get_float_exponent + jz signum_zero + test [esi+FloatData.attributes],FLOAT_NEGATIVE + jnz signum_negative + signum_positive: + mov al,1 + retn + signum_negative: + or al,-1 + retn + signum_zero: + xor al,al + retn + +check_if_not_zero: + mov edi,[calculation_workspace.memory_start] + call calculate_parsed_expression + jc evaluated_false + call pop_terms + jc evaluated_false + cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT + je check_if_not_zero_float + call get_numeric_term_value + mov ecx,1 + call fit_value + js evaluated_true + jc evaluated_true + cmp byte [edi],0 + jne evaluated_true + check_if_has_variable_terms: + add edi,sizeof.ExpressionTerm + cmp [edi+ExpressionTerm.attributes],0 + je evaluated_false + cmp [edi+ExpressionTerm.metadata],0 + je check_if_has_variable_terms + jmp evaluated_true + check_if_not_zero_float: + call get_term_value + mov esi,edx + call get_float_exponent + jz check_if_has_variable_terms + jmp evaluated_true + +check_if_relative: + mov edi,[calculation_workspace.memory_start] + call calculate_parsed_expression + jc evaluated_false + call calculate_parsed_expression + jc evaluated_false + mov ebx,edi + call pop_terms + jc evaluated_false + mov edx,edi + call pop_terms + jc evaluated_false + cmp [edx+sizeof.ExpressionTerm+ExpressionTerm.attributes],0 + je check_difference_terms + xchg edi,edx + cmp [edx+sizeof.ExpressionTerm+ExpressionTerm.attributes],0 + je check_difference_terms + mov esi,subtraction_operator + mov edi,ebx + call calculate_parsed_expression + call pop_terms + jc evaluated_false + check_difference_terms: + add edi,sizeof.ExpressionTerm + cmp [edi+ExpressionTerm.attributes],0 + je evaluated_true + cmp [edi+ExpressionTerm.metadata],0 + je check_difference_terms + jmp evaluated_false + undefined_condition: + mov edx,_invalid_value + call register_error + jmp evaluated_false + +check_if_type_equal: + mov edi,[calculation_workspace.memory_start] + call calculate_parsed_expression + jc evaluated_false + call pop_terms + jc evaluated_false + mov eax,[edi+ExpressionTerm.attributes] + mov [result_type],al + call calculate_parsed_expression + jc evaluated_false + call pop_terms + jc evaluated_false + mov eax,[edi+ExpressionTerm.attributes] + cmp al,[result_type] + je evaluated_true + jmp evaluated_false + +check_if_value_equal: + mov edi,[calculation_workspace.memory_start] + call calculate_parsed_expression + jc evaluated_false + mov ebx,edi + call pop_terms + jc evaluated_false + mov eax,[edi+ExpressionTerm.attributes] + mov [result_type],al + mov edi,ebx + call calculate_parsed_expression + jc evaluated_false + mov ebx,edi + call pop_terms + jc evaluated_false + mov eax,[edi+ExpressionTerm.attributes] + cmp al,[result_type] + jne evaluated_false + cmp al,EXPR_STRING + jne compare_values_numerically + call get_term_value + mov ecx,[edx] + call pop_terms + call get_term_value + cmp ecx,[edx] + jne evaluated_false + compare_values_numerically: + mov esi,subtraction_operator + mov edi,ebx + call calculate_parsed_expression + call pop_terms + jc evaluated_false + mov eax,edi + check_if_terms_equal: + add eax,sizeof.ExpressionTerm + cmp [eax+ExpressionTerm.attributes],0 + je check_if_constant_term_equal + cmp [eax+ExpressionTerm.metadata],0 + je check_if_terms_equal + jmp evaluated_false + check_if_constant_term_equal: + cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT + je check_if_float_equal + call get_numeric_term_value + xor ecx,ecx + xor edi,edi + call fit_value + jc evaluated_false + jmp evaluated_true + check_if_float_equal: + call get_term_value + mov esi,edx + call get_float_exponent + jnz evaluated_false + jmp evaluated_true + +check_if_defined: + xor ecx,ecx + jmp check_if_expression_defined +check_if_defined_earlier: + mov ecx,[current_pass] + check_if_expression_defined: + and [outer_expression],0 + and [defined_element],0 + lodsd + test eax,eax + jnz checked_expression_invalid + check_expression_element: + lodsd + test eax,eax + jz check_expression_end + cmp al,EXPR_SYMBOL + je check_if_subexpression_defined + cmp al,EXPR_SYMBOL_VALUE + je check_if_symbol_defined + or [defined_element],1 + add esi,4 + cmp al,EXPR_NUMBER + je check_expression_element + cmp al,EXPR_STRING + je check_expression_element + cmp al,EXPR_FLOAT + je check_expression_element + cmp al,EXPR_OPERATOR + je check_expression_element + cmp al,EXPR_POLYNOMIAL + je check_expression_element + checked_expression_invalid: + jmp invalid_logical_value + check_expression_end: + xor esi,esi + xchg esi,[outer_expression] + test esi,esi + jnz check_expression_element + jecxz checked_expression_defined + cmp [defined_element],0 + je checked_expression_invalid + checked_expression_defined: + jmp evaluated_true + check_if_symbol_defined: + lodsd + test eax,eax + jz evaluated_false + lodsd + test eax,eax + jz evaluated_false + check_symbol_value: + or [defined_element],1 + jecxz check_expression_element + test [eax+ValueDefinition.flags],VAL_INTERNAL + jnz check_expression_element + cmp [eax+ValueDefinition.pass],ecx + jne evaluated_false + jmp check_expression_element + check_if_subexpression_defined: + mov ebx,[esi] + test ebx,ebx + jz evaluated_false + add esi,4 + call get_available_value + mov eax,edx + test eax,eax + jz evaluated_false + cmp [eax+ValueDefinition.type],VALTYPE_SYMBOLIC + jne check_symbol_value + mov [outer_expression],esi + push ecx + call get_subexpression + pop ecx + jnc invalid_logical_value + jmp check_expression_element + get_subexpression: + call clear_line_embeddings + xor esi,esi + xor ecx,ecx + call embed_symbolic_value + mov edi,[expression_workspace.memory_start] + and [leave_opening_parentheses],0 + call parse_expression + call get_constituent_value + mov esi,[expression_workspace.memory_start] + retn + +check_if_used: + lodsd + test eax,eax + jnz invalid_logical_value + check_if_expression_is_used_symbol: + lodsd + cmp al,EXPR_SYMBOL + je check_for_indirect_symbol + cmp al,EXPR_SYMBOL_VALUE + jne invalid_logical_value + lodsd + mov ebx,eax + lodsd + check_if_used_symbol: + lodsd + test eax,eax + jnz invalid_logical_value + test ebx,ebx + jz evaluated_false + mov ecx,[ebx+SymbolTree_Leaf.last_use_pass] + jecxz symbol_predicted_unused + mov eax,[current_pass] + sub eax,ecx + jz evaluated_true + cmp eax,1 + ja symbol_predicted_unused + symbol_predicted_used: + or [ebx+SymbolTree_Leaf.flags],SYM_USAGE_PREDICTED + SYM_PREDICTED_USED + jmp evaluated_true + symbol_predicted_unused: + mov al,[ebx+SymbolTree_Leaf.flags] + or al,SYM_USAGE_PREDICTED + and al,not SYM_PREDICTED_USED + mov [ebx+SymbolTree_Leaf.flags],al + jmp evaluated_false + check_for_indirect_symbol: + lodsd + mov ebx,eax + call get_available_value + test edx,edx + jz check_if_used_symbol + cmp [edx+ValueDefinition.type],VALTYPE_SYMBOLIC + jne check_if_used_symbol + call get_subexpression + jnc invalid_logical_value + jmp check_if_expression_is_used_symbol diff --git a/toolchain/fasmg.kl0e/source/console.inc b/toolchain/fasmg.kl0e/source/console.inc new file mode 100644 index 0000000..5b9eea2 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/console.inc @@ -0,0 +1,560 @@ + +display_string_data: +; in: +; edx - 32-bit length followed by string data +; preserves: esi + test [trace_mode],TRACE_DISPLAY + jnz bypass_display_buffer + cmp [next_pass_needed],0 + jne display_ok + mov ecx,[edx] + call reserve_display_buffer + mov ebx,esi + mov esi,edx + lodsd + mov ecx,eax + rep movsb + string_displayed: + mov esi,ebx + display_ok: + retn + bypass_display_buffer: + mov ebx,esi + mov esi,edx + lodsd + mov ecx,eax + jecxz string_displayed + call display_string + jmp string_displayed + reserve_display_buffer: + mov edi,[display_data_length] + add ecx,edi + add edi,[display_buffer] + mov [display_data_length],ecx + cmp ecx,[display_buffer_length] + jbe display_buffer_reserve_ok + mov eax,[display_buffer] + sub edi,eax + push edx + call grow_stack + pop edx + add edi,eax + mov [display_buffer],eax + mov [display_buffer_length],ecx + display_buffer_reserve_ok: + retn + +display_single_byte_data: +; in: +; edx - 32-bit length followed by numeric data +; preserves: esi + test [trace_mode],TRACE_DISPLAY + jnz byte_bypassing_display_buffer + cmp [next_pass_needed],0 + jne display_ok + mov ecx,1 + call reserve_display_buffer + mov ecx,1 + call fit_value + jc byte_out_of_range + retn + byte_bypassing_display_buffer: + mov edi,displayed_byte + mov ecx,1 + call fit_value + jc byte_out_of_range + mov ebx,esi + mov esi,edi + mov ecx,1 + call display_string + jmp string_displayed + byte_out_of_range: + mov edx,_value_out_of_range + call register_error + retn + +show_display_data: + test [trace_mode],TRACE_DISPLAY + jnz display_line_feed + mov ecx,[display_data_length] + jecxz display_data_shown + mov esi,[display_buffer] + call display_string + display_line_feed: + mov esi,_new_line + xor ecx,ecx + call display_string + display_data_shown: + retn + +show_errors: + mov esi,[first_error] + display_error: + test esi,esi + jz display_data_shown + push esi + mov eax,[esi+sizeof.Error+SourceContext.number_of_entries] + test eax,eax + jz display_error_message + lea ebx,[esi+sizeof.Error+sizeof.SourceContext] + dec eax + imul eax,sizeof.SourceEntry + lea eax,[ebx+eax] + mov [last_source_entry],eax + test [trace_mode],TRACE_ERROR_STACK + jnz show_source_context + and [last_file_source_entry],0 + find_last_file_entry: + cmp [eax+SourceEntry.type],SOURCE_FILE + je last_file_entry_found + cmp eax,ebx + je show_source_context + sub eax,sizeof.SourceEntry + jmp find_last_file_entry + last_file_entry_found: + mov [last_file_source_entry],eax + show_source_context: + push ebx + cmp [ebx+SourceEntry.type],SOURCE_MEMORY + je display_memory_source + cmp [ebx+SourceEntry.type],SOURCE_MACRO + jne display_source_name + mov esi,_macro_source + test [ebx+SourceEntry.flags],SRCF_PREPROCESSED + jz display_source_type + mov esi,_preprocessed_source + display_source_type: + xor ecx,ecx + call display_error_string + display_source_name: + mov esi,[ebx+SourceEntry.name] + test esi,esi + jz unnamed_source + mov ecx,[ebx+SourceEntry.name_length] + cmp ecx,-1 + je display_source_symbol + call display_error_string + jmp display_line_number + display_source_symbol: + xchg ebx,esi + call show_symbol_name + mov ebx,esi + jmp display_line_number + unnamed_source: + mov esi,_unnamed_source + xor ecx,ecx + call display_error_string + jmp display_line_number + display_memory_source: + mov esi,_memory_source + xor ecx,ecx + call display_error_string + display_line_number: + mov esi,_line_number_prefix + xor ecx,ecx + call display_error_string + mov eax,[ebx+SourceEntry.line_number] + xor edx,edx + call itoa + call display_error_string + mov esi,_line_number_suffix + xor ecx,ecx + call display_error_string + pop ebx + mov esi,[esp] + push ebx + cmp [ebx+SourceEntry.line_number],0 + je skip_line_content + test [trace_mode],TRACE_ERROR_STACK + jnz show_source_line + cmp ebx,[last_source_entry] + je last_source_entry_line_content + cmp ebx,[last_file_source_entry] + je show_source_line + skip_line_content: + mov esi,_space + next_source_entry: + pop ebx + find_next_source_entry: + cmp ebx,[last_source_entry] + je source_context_shown + add ebx,sizeof.SourceEntry + test [trace_mode],TRACE_ERROR_STACK + jnz show_source_entry + test [ebx+SourceEntry.flags],SRCF_PREPROCESSED + jnz find_next_source_entry + show_source_entry: + xor ecx,ecx + call display_error_string + jmp show_source_context + last_source_entry_line_content: + test [esi+Error.flags],ERR_CUSTOM + jnz skip_line_content + show_source_line: + cmp [ebx+SourceEntry.type],SOURCE_CALM + je show_calm_source + mov esi,_line_content_prefix + xor ecx,ecx + call display_error_string + call show_line_content + mov esi,_new_line + jmp next_source_entry + show_calm_source: + mov esi,_calm_source + xor ecx,ecx + call display_error_string + mov esi,_new_line + jmp next_source_entry + source_context_shown: + mov esi,_new_line + xor ecx,ecx + call display_error_string + mov ebx,[esp] + test [ebx+Error.flags],ERR_CUSTOM + jnz display_error_message + cmp [ebx+Error.preprocessed_length],0 + je display_error_message + mov esi,_preprocessed_text_prefix + xor ecx,ecx + call display_error_string + mov esi,[ebx+Error.preprocessed_data] + mov ecx,[ebx+Error.preprocessed_length] + call show_preprocessed_line + mov esi,_new_line + xor ecx,ecx + call display_error_string + display_error_message: + pop ebx + call show_error_message + mov esi,ebx + next_error: + mov esi,[esi+Error.next] + jmp display_error + +show_error_message: +; in: +; ebx - Error +; preserves: ebx + mov esi,_error_prefix + test [ebx+Error.flags],ERR_CUSTOM + jz display_error_prefix + mov esi,_custom_error_prefix + display_error_prefix: + xor ecx,ecx + call display_error_string + mov esi,[ebx+Error.message] + test [ebx+Error.flags],ERR_CUSTOM + jz format_error_message + xor ecx,ecx + call display_error_string + finish_error_message: + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + retn + format_error_message: + mov edx,esi + cut_error_message: + lodsb + test al,al + jz show_error_message_segment + cmp al,'%' + jne cut_error_message + show_error_message_segment: + dec esi + push esi + xchg ecx,esi + sub ecx,edx + mov esi,edx + call display_error_string + pop esi + lodsb + test al,al + jz finish_error_message + lodsb + cmp al,'s' + je insert_string_into_error_message + cmp al,'i' + jne format_error_message + push ebx + mov ebx,[ebx+Error.symbol] + mov ebx,[ebx+SymbolTree_Leaf.branch] + call show_symbol_name + pop ebx + jmp format_error_message + insert_string_into_error_message: + push esi + mov esi,[ebx+Error.symbol] + xor ecx,ecx + call display_error_string + pop esi + jmp format_error_message + +show_symbol_name: +; in: +; ebx - SymbolTree_Foliage, may be null +; preserves: esi + test ebx,ebx + jz symbol_name_shown + mov edi,[identifier_workspace.memory_start] + cmp [ebx+SymbolTree_Foliage.name_kind],NAME_NUMERIC + je next_name_segment + compose_symbol_name: + mov ecx,[ebx+SymbolTree_Foliage.name_length] + mov edx,identifier_workspace + mov al,[ebx+SymbolTree_Foliage.name_kind] + cmp al,NAME_CASESENSITIVE + je name_segment_to_copy + cmp al,NAME_ABSTRACT + je name_segment_copied + cmp al,NAME_NUMERIC + je dot_label_name + mov al,'?' + stosb + name_segment_to_copy: + push ecx + add ecx,2 + call reserve_workspace + pop ecx + mov edx,[ebx+SymbolTree_Foliage.name_data] + copy_name_segment: + jecxz name_segment_copied + dec ecx + mov al,[edx+ecx] + stosb + jmp copy_name_segment + dot_label_name: + push esi + mov esi,[ebx+SymbolTree_Foliage.name_data] + xor eax,eax + read_dot_count: + jecxz dot_count_read + dec ecx + shl eax,8 + mov al,[esi+ecx] + jmp read_dot_count + dot_count_read: + pop esi + push eax + lea ecx,[eax+2] + call reserve_workspace + pop ecx + mov al,'.' + rep stosb + name_segment_copied: + mov edx,[ebx+SymbolTree_Foliage.root] + mov ebx,[edx+SymbolTree_Root.parent_branch] + test [edx+SymbolTree_Root.flags],NAMESPACE_LOCAL or NAMESPACE_CALM + jnz mark_local_symbol_name + test ebx,ebx + jz symbol_name_ready + next_name_segment: + mov al,'.' + stosb + jmp compose_symbol_name + mark_local_symbol_name: + mov al,':' + stosb + test [edx+SymbolTree_Root.flags],NAMESPACE_CALM + jz symbol_name_ready + mov eax,[ebx+SymbolTree_Foliage.name_data] + mov ebx,[eax+SymbolTree_Leaf.branch] + test ebx,ebx + jnz compose_symbol_name + symbol_name_ready: + mov ebx,[identifier_workspace.memory_start] + mov ecx,edi + sub ecx,ebx + jz symbol_name_shown + push esi + mov esi,ebx + reverse_composed_name: + dec edi + cmp ebx,edi + jae show_composed_name + mov al,[ebx] + xchg al,[edi] + mov [ebx],al + inc ebx + jmp reverse_composed_name + show_composed_name: + call display_error_string + pop esi + symbol_name_shown: + retn + +show_line_content: +; in: +; ebx - SourceEntry + cmp [ebx+SourceEntry.type],SOURCE_MACRO + je show_line_from_macro + mov esi,[ebx+SourceEntry.text] + add esi,[ebx+SourceEntry.line_offset] + mov ecx,[ebx+SourceEntry.number_of_attached_lines] + inc ecx + mov [number_of_lines],ecx + show_token: + mov al,[esi] + test al,al + jz line_content_shown + cmp al,0Ah + je line_content_shown + cmp al,1Ah + je show_name_token + cmp al,22h + je show_string_token + cmp al,27h + je show_string_token + cmp al,'\' + jne show_basic_token + cmp byte [esi+1],0Ah + jne show_basic_token + dec [number_of_lines] + jnz show_attached_line + show_basic_token: + mov ecx,1 + call display_error_string + inc esi + jmp show_token + show_name_token: + add esi,1+4 + mov ecx,[esi-4] + call display_error_string + add esi,[esi-4] + add esi,12 + jmp show_token + show_string_token: + mov ebx,esi + inc esi + call show_string_token_content + lea esi,[ebx+1] + lodsd + add esi,eax + jmp show_token + show_string_token_content: + lea edi,[esi+4] + mov ecx,[esi] + show_string_segment: + push ecx edi + mov esi,_single_quote + mov ecx,1 + call display_error_string + pop edi ecx + jecxz show_end_quote + mov edx,ecx + mov al,27h + repne scasb + sub edx,ecx + mov esi,edi + sub esi,edx + push ecx edi + mov ecx,edx + call display_error_string + pop edi ecx + test ecx,ecx + jnz show_string_segment + show_end_quote: + cmp byte [ebx],27h + je string_token_shown + mov esi,_single_quote + mov ecx,1 + call display_error_string + string_token_shown: + retn + show_attached_line: + mov ecx,1 + call display_error_string + lea ebx,[esi+2] + mov esi,_line_segment_prefix + xor ecx,ecx + call display_error_string + mov esi,ebx + jmp show_token + show_line_from_macro: + mov edx,[ebx+SourceEntry.text] + mov esi,[edx+ValueDefinition.value] + mov ecx,[edx+ValueDefinition.value_length] + mov eax,[ebx+SourceEntry.line_offset] + add esi,eax + sub ecx,eax + jbe line_content_shown + call show_preprocessed_line + line_content_shown: + retn + +show_preprocessed_line: +; in: +; esi - preprocessed tokens +; ecx = total length of preprocessed tokens + lea eax,[esi+ecx] + mov [preprocessed_text_end],eax + show_preprocessed_token: + cmp esi,[preprocessed_text_end] + jae preprocessed_line_shown + mov al,[esi] + test al,al + jz preprocessed_line_shown + cmp al,1Ah + je show_preprocessed_name_token + cmp al,22h + je show_preprocessed_string_token + cmp al,27h + je show_preprocessed_string_token + cmp al,30h + je show_internal_number + cmp al,40h + je show_context_token + mov ecx,1 + call display_error_string + inc esi + jmp show_preprocessed_token + show_preprocessed_name_token: + inc esi + lodsd + mov ebx,esi + mov esi,eax + lodsd + mov ecx,eax + call display_error_string + mov esi,ebx + jmp show_preprocessed_token + show_preprocessed_string_token: + mov ebx,esi + mov esi,[esi+1] + call show_string_token_content + lea esi,[ebx+1+4] + jmp show_preprocessed_token + show_internal_number: + inc esi + mov edx,esi + push esi + call convert_number_back + lea esi,[edx+4] + mov ecx,[edx] + call display_error_string + pop esi + add esi,[esi] + add esi,4 + jmp show_preprocessed_token + show_context_token: + add esi,1+sizeof.RecognitionContext + jmp show_preprocessed_token + preprocessed_line_shown: + retn + +itoa: +; in: +; edx:eax = unsigned number +; out: +; esi - temporary buffer containing decimal digits +; ecx = length of string (number of digits) + mov edi,temporary_value+4 + stosd + mov eax,edx + stosd + mov edx,temporary_value + mov dword [edx],8 + call convert_number_back + lea esi,[edx+4] + mov ecx,[edx] + retn diff --git a/toolchain/fasmg.kl0e/source/directives.inc b/toolchain/fasmg.kl0e/source/directives.inc new file mode 100644 index 0000000..0e21e37 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/directives.inc @@ -0,0 +1,4852 @@ + +struct DirectiveBlock + type db ? ; DBLOCK_# + subtype db ? ; CTRL_# for DBLOCK_CONTROL + flags db ? ; CTRLF_# for DBLOCK_CONTROL + reserved db ? + reserved2 dw ? + prior_assembly_mode db ? + prior_special_parameters db ? + prior_counter_position dd ? + parameter_namespace dd ? + parameter dd ? ; pointer to first BlockParameter + length_of_data dd ? +ends + +struct BlockParameter + symbol dd ? ; pointer to SymbolTree_Leaf + definition dd ? ; pointer to ValueDefinition + next dd ? ; pointer to another BlockParameter +ends + +struct NamespaceData + prior_namespace dd ? + prior_label dd ? +ends + +struct VirtualBlockData + outer_area dd ? + shift_tracking db ? +ends + +struct ConditionalRepeatData + condition_length dd ? +ends + +struct RepeatData + limit_length dd ? + index_position dd ? +ends + +struct MacroData + nesting_counter dd ? +ends + +struct SymbolSubstitution + symbol_start dd ? + symbol_end dd ? + value_start dd ? + value_end dd ? + leftover_context dd ? +ends + +struct MatchedParameter + pattern dd ? + assembly_position dd ? +ends + +DBLOCK_CLOSED = 0 +DBLOCK_NAMESPACE = 1 +DBLOCK_CONTROL = 2 +DBLOCK_MACRO = 3 +DBLOCK_VIRTUAL = 4 +DBLOCK_CALMINSTRUCTION = 5 +DBLOCK_POSTPONED = 8 +DBLOCK_SUSPENDED = 9 + +CTRL_IF = 0 +CTRL_WHILE = 2 +CTRL_REPEAT = 3 +CTRL_IRP = 4 +CTRL_IRPV = 5 +CTRL_MATCH = 6 +CTRL_RMATCH = 7 +CTRL_POSTPONE = 9 + +CTRLF_INACTIVE = 1 +CTRLF_BREAKABLE = 2 +CTRLF_HAS_REPEAT_DATA = 4 +CTRLF_HAS_WRITABLE_INDEX = 8 +CTRLF_ALLOWS_ELSE = 16 +CTRLF_SUSPENDED = 32 + +add_directive_block: +; in: +; dl = DBLOCK_# +; ecx = length of additional data +; out: edi - new DirectiveBlock +; note: area for additional data is placed below the DirectiveBlock structure +; preserves: ebx, edx, esi + dec ecx + and ecx,(-1) shl 2 + add ecx,1 shl 2 + push esi ecx + mov esi,[source_context] + mov eax,[esi+SourceContext.number_of_entries] + imul eax,sizeof.SourceEntry + add eax,sizeof.SourceContext + add ecx,eax + add ecx,sizeof.DirectiveBlock + mov edi,[directives_stack] + lea eax,[edi+ecx] + cmp eax,[directives_stack_end] + jbe directives_stack_ready + add ecx,[directives_stack_end] + jc out_of_memory + mov eax,[directives_stack_base] + sub ecx,eax + push edx + call grow_stack + pop edx + add ecx,eax + mov [directives_stack_end],ecx + mov edi,eax + xchg eax,[directives_stack_base] + sub edi,eax + add edi,[directives_stack] + mov [directives_stack],edi + directives_stack_ready: + push edx + call clone_source_context + pop edx ecx + add edi,ecx + mov eax,edi + sub eax,[directives_stack] + mov [edi+DirectiveBlock.length_of_data],eax + mov [edi+DirectiveBlock.type],dl + mov al,[assembly_mode] + mov [edi+DirectiveBlock.prior_assembly_mode],al + mov ecx,[parameter_namespace] + mov [edi+DirectiveBlock.parameter_namespace],ecx + mov al,[ecx+SymbolTree_Root.parameters] + mov [edi+DirectiveBlock.prior_special_parameters],al + xor eax,eax + mov [edi+DirectiveBlock.subtype],al + mov [edi+DirectiveBlock.flags],al + mov [edi+DirectiveBlock.parameter],eax + mov eax,[current_counter] + sub eax,[counters_stack_base] + mov [edi+DirectiveBlock.prior_counter_position],eax + lea eax,[edi+sizeof.DirectiveBlock] + mov [directives_stack],eax + pop esi + retn + +find_directive_block: +; in: +; dl = DBLOCK_# +; out: +; cf set when no such block found +; when cf = 0 +; edi - DirectiveBlock of the latest block of this type +; preserves: ebx, edx, esi + mov edi,[directives_stack] + scan_directive_blocks: + cmp edi,[directives_stack_base] + je directive_block_not_found + sub edi,sizeof.DirectiveBlock + cmp dl,[edi+DirectiveBlock.type] + je directive_block_found + find_next_directive_block: + ; in: + ; dl = DBLOCK_# + ; edi - DirectiveBlock + ; out: + ; cf set when no such block found + ; when cf = 0 + ; edi - DirectiveBlock of the next latest block of this type + ; preserves: ebx, edx, esi + mov ecx,[edi+DirectiveBlock.length_of_data] + sub edi,ecx + jmp scan_directive_blocks + directive_block_found: + clc + retn + directive_block_not_found: + stc + retn + +close_control_directive_block: +; in: edi - DirectiveBlock +; preserves: esi + mov al,[edi+DirectiveBlock.prior_assembly_mode] + mov [assembly_mode],al + mov eax,[edi+DirectiveBlock.prior_counter_position] + add eax,[counters_stack_base] + mov [current_counter],eax + mov ecx,[edi+DirectiveBlock.parameter_namespace] + mov al,[edi+DirectiveBlock.prior_special_parameters] + mov [ecx+SymbolTree_Root.parameters],al + close_directive_block: + ; in: edi - DirectiveBlock + ; preserves: esi + mov [edi+DirectiveBlock.type],DBLOCK_CLOSED + mov eax,edi + mov ecx,[eax+DirectiveBlock.length_of_data] + sub eax,ecx + call release_source_context + call remove_block_parameters + lea eax,[edi+sizeof.DirectiveBlock] + cmp eax,[directives_stack] + je remove_directive_block + retn + remove_directive_block: + sub eax,sizeof.DirectiveBlock + mov ecx,[eax+DirectiveBlock.length_of_data] + sub eax,ecx + cmp eax,[directives_stack_base] + je directives_stack_cleared + cmp [eax-sizeof.DirectiveBlock+DirectiveBlock.type],DBLOCK_CLOSED + je remove_directive_block + directives_stack_cleared: + mov [directives_stack],eax + retn + +add_block_parameter: +; in: +; ebx - SymbolTree_Leaf +; edi - DirectiveBlock +; esi - value +; ecx = length of value +; [value_type] = VALTYPE_# +; preserves: ebx, edi + push ecx + or [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + call create_value_definition + pop ecx + mov eax,[current_pass] + mov [edx+ValueDefinition.pass],eax + mov [edx+ValueDefinition.value_length],ecx + add ecx,sizeof.BlockParameter + push edi + mov edi,[edx+ValueDefinition.value] + cmp ecx,[edx+ValueDefinition.block_length] + jbe write_parameter_value + push edx + push ecx + cmp [edx+ValueDefinition.block_length],0 + je allocate_memory_for_parameter + xor eax,eax + xchg eax,[edx+ValueDefinition.value] + call mfree + allocate_memory_for_parameter: + pop ecx + call malloc + pop edx + mov [edx+ValueDefinition.value],eax + mov [edx+ValueDefinition.block_length],ecx + mov edi,eax + write_parameter_value: + mov al,[value_type] + mov [edx+ValueDefinition.type],al + mov ecx,[edx+ValueDefinition.value_length] + rep movsb + mov ecx,edi + pop edi + mov [ecx+BlockParameter.symbol],ebx + mov [ecx+BlockParameter.definition],edx + inc [edx+ValueDefinition.reference_count] + mov eax,ecx + xchg eax,[edi+DirectiveBlock.parameter] + mov [ecx+BlockParameter.next],eax + retn + +remove_block_parameters: +; in: edi - DirectiveBlock +; preserves: esi, edi + mov eax,[edi+DirectiveBlock.parameter] + test eax,eax + jz no_block_parameters + push esi edi + mov esi,eax + remove_block_parameter: + mov ebx,[esi+BlockParameter.symbol] + mov edx,[esi+BlockParameter.definition] + dec [edx+ValueDefinition.reference_count] + xor edi,edi + call remove_value_definition + mov esi,[esi+BlockParameter.next] + test esi,esi + jnz remove_block_parameter + pop edi esi + no_block_parameters: + retn + +identify_parameter_symbol: +; in: +; esi = pointer into preprocessed line or current embedded value +; out: +; same as from identify_symbol_in_namespace + or [symbol_definition],1 + mov ebx,[parameter_namespace] + mov dl,SYMCLASS_PARAMETER + call identify_symbol_in_namespace + jc parameter_symbol_identified + cmp edi,[parameter_namespace] + je parameter_symbol_identified + xor ebx,ebx + parameter_symbol_identified: + retn + +cut_argument_value: +; in: +; esi = pointer into preprocessed line or current embedded value +; edi - LineExcerpt to be filled with information about cut piece of line +; [breakpoint_token] = initial byte of symbol that - if encountered - should immediately end the value +; out: +; esi = pointer advanced past the cut piece +; al = initial byte of symbol at pointer, zero when no more symbols there +; preserves: ebx, edi + call move_to_next_symbol + jc cut_plain_value + cmp byte [esi],'<' + je cut_enclosed_value + cut_plain_value: + mov dl,',' + xor dh,dh + call cut_piece_of_line + retn + cut_enclosed_value: + inc esi + mov dl,'>' + mov dh,'<' + call cut_piece_of_line + cmp al,'>' + jne missing_enclosing + inc esi + call move_to_next_symbol + jnc parameter_value_cut + xor al,al + parameter_value_cut: + retn + missing_enclosing: + mov edx,_missing_closing_chevron + call register_error + retn + +extract_argument_value: +; in: +; esi = pointer into preprocessed line (not an embedded value) +; edi - buffer for token sequence, must be large enough to hold all the remaining tokens in line and an additional context token +; [breakpoint_token] = initial byte of symbol that - if encountered - should immediately end the value +; [contextless_processing] = zero to have current context added to the extracted value +; out: +; esi = pointer advanced past the processed piece +; edi - end of the extracted sequence of tokens in provided buffer +; al = initial byte of symbol at pointer, zero when no more symbols there +; preserves: ebx +; note: +; when AMODE_DEFINITION is active, current context is not added to the extracted value + call move_to_next_symbol + jc extract_plain_value + cmp byte [esi],'<' + je extract_enclosed_value + extract_plain_value: + mov dl,',' + xor dh,dh + call extract_piece_of_line + retn + extract_enclosed_value: + inc esi + mov dl,'>' + mov dh,'<' + call extract_piece_of_line + cmp al,'>' + jne missing_enclosing + inc esi + call move_to_next_symbol + jnc parameter_value_extracted + xor al,al + parameter_value_extracted: + retn + +get_macro_definition_symbol: +; in: +; esi = pointer into preprocessed line or current embedded value +; al = initial byte of symbol at esi +; dl = SYMCLASS_# +; out: +; ebx - SymbolTree_Leaf +; esi = pointer advanced past the processed declaration +; [macro_leaf] - SymbolTree_Leaf +; [macro_flags] = VAL_# + mov [macro_flags],VAL_NONRECURSIVE + cmp al,'!' + je unconditional_interceptor + or [symbol_definition],1 + call identify_symbol + jc invalid_macro_symbol + test ebx,ebx + jz invalid_macro_symbol + macro_symbol_identified: + call move_to_next_symbol + jc macro_symbol_ok + cmp al,':' + je recursive_macro + test ecx,ecx + jnz macro_symbol_ok + cmp al,'!' + je unconditional_macro + jmp macro_symbol_ok + unconditional_interceptor: + mov ebx,[interceptor_symbol] + cmp dl,SYMCLASS_STRUCTURE + jne unconditional_macro + mov ebx,[label_interceptor_symbol] + unconditional_macro: + or [macro_flags],VAL_UNCONDITIONAL + inc esi + call move_to_next_symbol + jc macro_symbol_ok + cmp al,':' + jne macro_symbol_ok + recursive_macro: + inc esi + call move_to_next_symbol + and [macro_flags],not VAL_NONRECURSIVE + or [ebx+SymbolTree_Leaf.flags],SYM_CONSTANT + jmp macro_symbol_ok + macro_symbol_ok: + mov [macro_leaf],ebx + mov edx,[ebx+SymbolTree_Leaf.definition] + test edx,edx + jz create_placeholder_value + test [edx+ValueDefinition.flags],VAL_INTERNAL + jnz macro_already_defined + mov eax,[current_pass] + sub eax,[edx+ValueDefinition.pass] + jz macro_already_defined + cmp eax,1 + je macro_symbol_ready + create_placeholder_value: + ; for VAL_UNCONDITIONAL macros this helps to detect when a macro tries to call itself, + ; for regular ones this section interferes with operation of SYM_PREDICTED to sometimes prevent excess passes, + ; when SYM_PREDICTED is needed to behave reliably for an instruction, its symbol + ; should be marked with SYMX_INSTRUCTION_PREDICTED to skip this section + test [ebx+SymbolTree_Leaf.extra_flags],SYMX_INSTRUCTION_PREDICTED + jnz macro_symbol_ready + call create_value_definition + test edx,edx + jz macro_symbol_ready + mov eax,[current_pass] + dec eax + mov [edx+ValueDefinition.pass],eax + mov [edx+ValueDefinition.type],VALTYPE_RESERVED + mov al,[macro_flags] + mov [edx+ValueDefinition.flags],al + test al,VAL_UNCONDITIONAL + jnz macro_symbol_ready + or [edx+ValueDefinition.flags],VAL_IN_USE + test [ebx+SymbolTree_Leaf.flags],SYM_PREDICTED + jz macro_symbol_ready + mov edi,ebx + mov ecx,[current_pass] + check_macro_usage: + cmp ecx,[edi+SymbolTree_Leaf.last_use_pass] + je macro_possibly_used_earlier + mov edx,[edi+SymbolTree_Leaf.fallback_neighbour] + test edx,edx + jz look_up_parent_namespace_macro + cmp ecx,[edx+SymbolTree_Leaf.last_use_pass] + je macro_possibly_used_earlier + look_up_parent_namespace_macro: + mov edi,[edi+SymbolTree_Leaf.fallback_parent] + test edi,edi + jnz check_macro_usage + and [ebx+SymbolTree_Leaf.flags],not SYM_PREDICTED + jmp macro_symbol_ready + macro_possibly_used_earlier: + test al,VAL_NONRECURSIVE + jnz macro_symbol_ready + or [next_pass_needed],-1 + macro_symbol_ready: + clc + retn + macro_already_defined: + test [ebx+SymbolTree_Leaf.flags],SYM_CONSTANT + jz macro_symbol_ready + mov edx,_conflicting_definition + call register_error + invalid_macro_symbol: + stc + retn + +; instruction handler +; in: +; esi = pointer into preprocessed line +; ecx = number of whitespace tokens between previous symbol and current position +; edx - ValueDefinition of instruction +; ebx - SymbolTree_Leaf of instruction +; edi - SymbolTree_Root of instruction +; when [SymbolTree_Leaf.class] = SYMCLASS_STRUCTURE: +; [label_leaf] - SymbolTree_Leaf of structure label +; [label_branch] - SymbolTree_Foliage of structure label +; [label_independent] = zero when identifier of structure label is relative to current label +; out: +; when done, handler should jump to instruction_assembled with esi containing a pointer moved past the processed part of line, +; or jump directly to assembly_line when the rest of line should be ignored +; note: +; when esi is equal to [line_end], pointer is at the end of line and there is no data available at this address + +set_namespace: + mov dl,DBLOCK_NAMESPACE + mov ecx,sizeof.NamespaceData + call add_directive_block + mov edx,[current_context.base_namespace] + mov [edi-sizeof.NamespaceData+NamespaceData.prior_namespace],edx + mov eax,[edx+SymbolTree_Root.current_label] + mov [edi-sizeof.NamespaceData+NamespaceData.prior_label],eax + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc missing_argument + test ebx,ebx + jz invalid_identifier + call get_symbol_namespace + mov [current_context.base_namespace],ebx + and [ebx+SymbolTree_Root.current_label],0 + jmp instruction_assembled +end_namespace: + mov dl,DBLOCK_NAMESPACE + call find_directive_block + jc unexpected_instruction + mov edx,[edi-sizeof.NamespaceData+NamespaceData.prior_namespace] + mov eax,[edi-sizeof.NamespaceData+NamespaceData.prior_label] + mov [current_context.base_namespace],edx + mov [edx+SymbolTree_Root.current_label],eax + call close_directive_block + jmp instruction_assembled + +set_base_address: + mov edx,[current_area] + mov ebx,[edx+ValueDefinition.value] + test [ebx+AreaHeader.flags],AREA_VIRTUAL + jnz unexpected_instruction + call get_expression_value + jc invalid_argument + push esi + call convert_terms_to_numeric_value + begin_new_output_area: + call create_output_area + inc [edx+ValueDefinition.reference_count] + xchg edx,[current_area] + dec [edx+ValueDefinition.reference_count] + ; jz internal_error + pop esi + jmp instruction_assembled +begin_new_section: + mov edx,[current_area] + mov ebx,[edx+ValueDefinition.value] + test [ebx+AreaHeader.flags],AREA_VIRTUAL + jnz unexpected_instruction + call get_expression_value + jc invalid_argument + push esi + call convert_terms_to_numeric_value + call trim_output + call create_output_area + mov eax,edx + inc [eax+ValueDefinition.reference_count] + xchg eax,[current_area] + dec [eax+ValueDefinition.reference_count] + ; jz internal_error + pop esi + jmp instruction_assembled +restart_output: + mov edx,[current_area] + mov ebx,[edx+ValueDefinition.value] + test [ebx+AreaHeader.flags],AREA_VIRTUAL + jnz unexpected_instruction + call peek_at_constituent_value + jc restart_output_at_current_address + call get_expression_value + jc invalid_argument + push esi + call convert_terms_to_numeric_value + jmp make_new_initial_output_area + restart_output_at_current_address: + push esi + call get_current_address_value + make_new_initial_output_area: + and [initial_output_area_entry],0 + jmp begin_new_output_area + +define_label: + inc esi + xor ecx,ecx + call move_to_next_symbol + jc define_simple_label + test ecx,ecx + jnz define_simple_label + cmp al,'=' + je define_numeric_constant + cmp al,':' + je define_area_label + define_simple_label: + test [assembly_mode],AMODE_SKIP + jnz assemble_after_label + test [assembly_mode],AMODE_DEFINITION + jnz add_label_to_macro + cmp [interceptor],0 + jne execute_interceptor + mov [argument_start],esi + call get_current_address_value + mov edi,ecx + mov ebx,[label_leaf] + call create_constant_value_definition + test edx,edx + jz assembly_line + mov ecx,edi + call assign_shiftable_value + label_defined: + call update_current_label + mov esi,[argument_start] + assemble_after_label: + mov [line_start],esi + mov eax,[embedded_context] + mov [line_context],eax + jmp assemble_instruction + define_area_label: + inc esi + test [assembly_mode],AMODE_SKIP + jnz assemble_after_label + test [assembly_mode],AMODE_DEFINITION + jnz add_label_to_macro + cmp [interceptor],0 + jne execute_interceptor + mov [argument_start],esi + mov ebx,[label_leaf] + mov edx,[current_area] + call update_value_link + jmp label_defined + assign_shiftable_value: + mov [value_type],VALTYPE_NUMERIC + mov eax,[current_area] + mov eax,[eax+ValueDefinition.value] + test [eax+AreaHeader.flags],AREA_SHIFT_TRACKING_DISABLED + jnz assign_value + or [shift_tracking],-1 + call update_predicted_shift + call assign_value + or [edx+ValueDefinition.flags],VAL_SHIFTABLE + retn + update_current_label: + mov edx,[label_branch] + cmp [label_independent],0 + je current_label_ok + mov edi,[edx+SymbolTree_Foliage.root] + test [edi+SymbolTree_Root.flags],NAMESPACE_LOCAL + jnz current_label_ok + mov edi,[current_context.base_namespace] + mov [edi+SymbolTree_Root.current_label],edx + current_label_ok: + retn + +define_numeric_symbol: + test [assembly_mode],AMODE_SKIP + jnz assembly_line + test [assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + cmp [interceptor],0 + jne execute_interceptor + inc esi + xor ecx,ecx + call move_to_next_symbol + jc define_numeric_variable + test ecx,ecx + jnz define_numeric_variable + cmp al,':' + jne define_numeric_variable + inc esi + call get_expression_value + jc missing_argument + mov ebx,[label_leaf] + call create_value_definition + jmp define_numeric_value +define_numeric_constant: + test [assembly_mode],AMODE_SKIP + jnz assembly_line + test [assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + cmp [interceptor],0 + jne execute_interceptor + inc esi + call get_expression_value + jc missing_argument + mov ebx,[label_leaf] + call create_constant_value_definition + jmp define_numeric_value +define_numeric_variable: + call get_expression_value + jc missing_argument + mov ebx,[label_leaf] + call update_value_definition + define_numeric_value: + test edx,edx + jz assembly_line + push esi + push ebx edx + mov eax,[edi+ExpressionTerm.attributes] + cmp al,EXPR_STRING + je define_string_variable + cmp al,EXPR_FLOAT + je define_float_variable + mov [value_type],VALTYPE_NUMERIC + call convert_terms_to_numeric_value + assign_numeric_value: + pop edx ebx + call assign_value + pop esi + jmp instruction_assembled + define_string_variable: + mov [value_type],VALTYPE_STRING + call get_term_value + mov esi,edx + mov ecx,[esi] + add ecx,4 + jmp assign_numeric_value + define_float_variable: + mov [value_type],VALTYPE_FLOAT + call get_term_value + mov esi,edx + mov ecx,sizeof.FloatData + jmp assign_numeric_value + +define_element: + or [symbol_definition],1 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc missing_argument + test ebx,ebx + jz invalid_identifier + mov [label_leaf],ebx + call move_to_next_symbol + jc element_with_no_metadata + cmp al,':' + jne get_element_metadata + inc esi + get_element_metadata: + call get_expression_value + jc invalid_argument + mov ebx,[label_leaf] + call create_constant_value_definition + test edx,edx + jz assembly_line + mov [value_type],VALTYPE_ELEMENT + push esi + push ebx edx + call convert_terms_to_numeric_value + pop edx ebx + call assign_value + pop esi + jmp instruction_assembled + element_with_no_metadata: + mov ebx,[label_leaf] + call create_constant_value_definition + test edx,edx + jz assembly_line + mov [value_type],VALTYPE_ELEMENT + push esi + xor esi,esi + xor ecx,ecx + call assign_value + pop esi + jmp instruction_assembled + +redefine_raw_symbolic_variable: + mov [update_function],update_value_definition + jmp raw_symbolic_variable +define_raw_symbolic_variable: + mov [update_function],create_value_definition + raw_symbolic_variable: + or [symbol_definition],1 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc missing_argument + test ebx,ebx + jz invalid_identifier + mov [label_leaf],ebx + or [raw_value],1 + jmp symbolic_variable +redefine_symbolic_variable: + mov [update_function],update_value_definition + and [raw_value],0 + jmp symbolic_variable +define_symbolic_variable: + mov [update_function],create_value_definition + and [raw_value],0 + symbolic_variable: + mov edi,[assembly_workspace.memory_start] + and [previous_symbol_end],0 + and [contextless_processing],0 + expand_symbols: + cmp [raw_value],0 + jne copy_raw_symbols + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + push edi + call identify_symbol + jc symbols_expanded + test edi,edi + jnz symbol_ready + call skip_literal + xor ebx,ebx + symbol_ready: + pop edi + test ebx,ebx + jz copy_symbol + mov [further_whitespace],ecx + call get_available_value + jc copy_symbol + cmp [edx+ValueDefinition.type],VALTYPE_SYMBOLIC + jne copy_symbol + and [previous_symbol_end],0 + mov eax,[current_pass] + mov [ebx+SymbolTree_Leaf.last_use_pass],eax + cmp ebx,[label_leaf] + jne replace_symbolic_variable + mov ecx,[edx+ValueDefinition.pass] + cmp ecx,[current_pass] + je replace_symbolic_variable + mov edx,_symbolic_self_reference + call register_error + jmp expand_symbols + replace_symbolic_variable: + mov ecx,[edx+ValueDefinition.value_length] + test ecx,ecx + jz expand_symbols + push esi + mov esi,[edx+ValueDefinition.value] + push ecx + add ecx,1+sizeof.RecognitionContext + add ecx,[further_whitespace] + mov edx,assembly_workspace + call reserve_workspace + mov al,40h + cmp al,[esi] + je copy_symbolic_value + stosb + mov eax,esi + mov esi,current_context + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep movsd + mov esi,eax + copy_symbolic_value: + pop ecx + rep movsb + pop esi + mov al,20h + mov ecx,[further_whitespace] + rep stosb + jmp expand_symbols + copy_raw_symbols: + mov eax,esi + mov esi,[line_end] + cmp esi,eax + je symbolic_value_ready + mov [symbol_start],eax + copy_symbol: + mov ebx,esi + xchg [previous_symbol_end],esi + test esi,esi + jz copy_symbol_with_recognition_context + mov ecx,ebx + sub ecx,esi + mov edx,assembly_workspace + call reserve_workspace + and [context_boundary],0 + jmp copy_symbol_tokens + copy_symbol_with_recognition_context: + mov ecx,ebx + sub ecx,[symbol_start] + add ecx,1+sizeof.RecognitionContext + mov edx,assembly_workspace + call reserve_workspace + mov al,40h + stosb + cmp [raw_value],0 + je use_recognition_context + mov esi,[embedded_context] + test esi,esi + jz use_current_context + call store_recognition_context + jmp symbol_context_stored + use_current_context: + call store_current_context + jmp symbol_context_stored + use_recognition_context: + mov esi,recognition_context + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep movsd + mov [context_boundary],edi + symbol_context_stored: + mov esi,[symbol_start] + copy_symbol_tokens: + cmp esi,ebx + jae expand_symbols + call store_token + jmp copy_symbol_tokens + symbols_expanded: + pop edi + symbolic_value_ready: + mov ebx,[label_leaf] + call [update_function] + test edx,edx + jz assembly_line + mov [value_type],VALTYPE_SYMBOLIC + mov esi,[assembly_workspace.memory_start] + mov ecx,edi + sub ecx,esi + call assign_value + jmp assembly_line + store_token: + lodsb + cmp al,40h + je make_recognition_context_token + stosb + cmp al,1Ah + je store_token_with_data + cmp al,22h + je store_token_with_data + cmp al,27h + je store_token_with_data + cmp al,30h + je store_internal_token + retn + store_token_with_data: + movsd + retn + store_internal_token: + lodsd + stosd + mov ecx,eax + rep movsb + retn + +restore_variables: + mov al,[edx+ValueDefinition.attribute] + mov [chosen_class],al + restore_symbol_value: + mov dl,[chosen_class] + or [symbol_definition],1 + call identify_symbol + jc missing_argument + test ebx,ebx + jz invalid_identifier + remove_variable_value: + xor edx,edx + xor edi,edi + call remove_value_definition + call move_to_next_symbol + jc assembly_line + cmp al,',' + jne invalid_argument + inc esi + jmp restore_symbol_value +move_variable_values: + mov dl,[edx+ValueDefinition.attribute] + mov [chosen_class],dl + or [symbol_definition],1 + call identify_symbol + jc missing_argument + test ebx,ebx + jz invalid_identifier + mov [label_leaf],ebx + call move_to_next_symbol + jc missing_argument + cmp al,',' + jne invalid_argument + inc esi + mov dl,[chosen_class] + call identify_symbol + jc missing_argument + test ebx,ebx + jz invalid_identifier + xor edx,edx + mov edi,[label_leaf] + call remove_value_definition + jmp instruction_assembled + +label_directive: + or [symbol_definition],1 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc missing_argument + test ebx,ebx + jz invalid_identifier + mov [label_leaf],ebx + mov [label_branch],edx + mov al,[symbol_independent] + mov [label_independent],al + and [metadata_length],0 + call peek_at_constituent_value + jc label_at_current_address + cmp al,1Ah + jne label_with_size + test edx,edx + jz label_with_size + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_PREPOSITION + jne label_with_size + cmp [edx+ValueDefinition.value],PREPOSITION_AT + je label_at_specified_address + label_with_size: + cmp al,':' + jne get_label_size + and [current_constituent],0 + get_label_size: + call get_expression_value + jc invalid_argument + push esi + mov edx,auxiliary_workspace + call convert_terms_to_numeric_value_in_workspace + mov [metadata_length],ecx + pop esi + call peek_at_constituent_value + jc label_at_current_address + cmp al,1Ah + jne label_at_current_address + test edx,edx + jz invalid_argument + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_PREPOSITION + jne label_at_current_address + cmp [edx+ValueDefinition.value],PREPOSITION_AT + jne invalid_argument + label_at_specified_address: + and [current_constituent],0 + call get_expression_value + jc invalid_argument + push esi + call convert_terms_to_numeric_value + mov edi,ecx + mov ebx,[label_leaf] + call create_constant_value_definition + test edx,edx + jz label_ready + call prepare_label_value + mov [value_type],VALTYPE_NUMERIC + call assign_value + jmp label_ready + label_at_current_address: + push esi + call get_current_address_value + mov edi,ecx + mov ebx,[label_leaf] + call create_constant_value_definition + test edx,edx + jz label_ready + call prepare_label_value + call assign_shiftable_value + label_ready: + pop esi + call update_current_label + jmp instruction_assembled + prepare_label_value: + mov ecx,edi + cmp [metadata_length],0 + je label_metadata_ok + add edi,esi + push edx ecx + mov ecx,[metadata_length] + mov edx,assembly_workspace + call reserve_workspace + mov esi,[auxiliary_workspace.memory_start] + mov ecx,[metadata_length] + pop eax + add eax,ecx + rep movsb + pop edx + mov ecx,eax + mov esi,edi + sub esi,ecx + label_metadata_ok: + retn + +virtual_block: + mov dl,DBLOCK_VIRTUAL + mov ecx,sizeof.VirtualBlockData + call add_directive_block + mov edx,[current_area] + mov [edi-sizeof.VirtualBlockData+VirtualBlockData.outer_area],edx + mov al,[shift_tracking] + mov [edi-sizeof.VirtualBlockData+VirtualBlockData.shift_tracking],al + call peek_at_constituent_value + jc virtual_at_current_address + cmp al,1Ah + jne invalid_argument + test edx,edx + jz invalid_argument + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_PREPOSITION + jne continue_virtual_block + mov eax,[edx+ValueDefinition.value] + cmp eax,PREPOSITION_AS + je virtual_at_current_address + cmp eax,PREPOSITION_AT + jne invalid_argument + and [current_constituent],0 + call get_expression_value + jc invalid_argument + push esi + call convert_terms_to_numeric_value + jmp create_virtual_block + virtual_at_current_address: + push esi + call get_current_address_value + create_virtual_block: + lea ebx,[virtual_area] + call create_area + or [ebx+AreaHeader.flags],AREA_VIRTUAL + cmp [shift_tracking],0 + je virtual_block_ready + or [ebx+AreaHeader.flags],AREA_SHIFT_TRACKING_DISABLED + virtual_block_ready: + inc [edx+ValueDefinition.reference_count] + or [edx+ValueDefinition.flags],VAL_IN_USE + mov [current_area],edx + pop esi + call get_constituent_value + jc instruction_assembled + cmp al,1Ah + jne invalid_argument + test edx,edx + jz invalid_argument + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_PREPOSITION + jne invalid_argument + cmp [edx+ValueDefinition.value],PREPOSITION_AS + jne invalid_argument + call get_constant_value + cmp al,22h + jne invalid_argument + mov ebx,[auxiliary_output_areas] + mov edi,esi + mov ecx,[edx] + lea esi,[edx+4] + test ecx,ecx + jnz register_auxiliary_file + dec esi + register_auxiliary_file: + mov eax,[current_area] + inc [eax+ValueDefinition.reference_count] + push ecx + call put_into_map + pop ecx + jmp validate_extension + continue_virtual_block: + and [leave_opening_parentheses],0 + mov edi,[expression_workspace.memory_start] + call parse_expression + mov edi,[expression_workspace.memory_start] + call get_area_value + jc invalid_area + mov ecx,[current_pass] + cmp [edx+ValueDefinition.pass],ecx + jne invalid_area + mov eax,[edx+ValueDefinition.value] + test [eax+AreaHeader.flags],AREA_VIRTUAL + jz invalid_area + test [edx+ValueDefinition.flags],VAL_IN_USE + jnz invalid_area + inc [edx+ValueDefinition.reference_count] + or [edx+ValueDefinition.flags],VAL_IN_USE + mov [current_area],edx + jmp instruction_assembled + invalid_area: + mov edx,_invalid_area + call register_error + jmp assembly_line + +end_virtual_block: + mov dl,DBLOCK_VIRTUAL + call find_directive_block + jc unexpected_instruction + mov al,[edi-sizeof.VirtualBlockData+VirtualBlockData.shift_tracking] + mov [shift_tracking],al + mov edx,[edi-sizeof.VirtualBlockData+VirtualBlockData.outer_area] + xchg edx,[current_area] + and [edx+ValueDefinition.flags],not VAL_IN_USE + dec [edx+ValueDefinition.reference_count] + jnz close_virtual_block + mov eax,edx + xchg eax,[retired_definition] + mov [edx+ValueDefinition.previous],eax + close_virtual_block: + call close_directive_block + jmp instruction_assembled + +include_source: + call move_to_next_symbol + jc missing_argument + cmp al,'!' + jne conditional_include + inc esi + jmp get_file_name + conditional_include: + test [assembly_mode],AMODE_SKIP + jnz assembly_line + test [assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + get_file_name: + call get_constant_value + cmp al,22h + jne invalid_argument + push esi + mov [file_name],edx + call prepare_file_path + mov esi,[assembly_workspace.memory_start] + call read_source + test eax,eax + jnz include_read + mov esi,[local_path] + call read_source + test eax,eax + jnz include_read + mov ebx,esi + mov esi,[include_paths] + try_include_paths: + lodsb + test al,al + jz include_not_found + cmp al,';' + je try_include_paths + lea ebx,[esi-1] + measure_path: + lodsb + test al,al + jz path_measured + cmp al,';' + jne measure_path + path_measured: + dec esi + xchg esi,ebx + mov ecx,ebx + sub ecx,esi + mov edx,[file_name] + add ecx,[edx] + add ecx,2 + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + call reserve_workspace + mov ecx,ebx + sub ecx,esi + rep movsb + mov al,[esi-1] + cmp al,'/' + je path_separator_ok + cmp al,'\' + je path_separator_ok + mov al,'/' + stosb + path_separator_ok: + mov esi,[file_name] + lodsd + mov ecx,eax + rep movsb + xor al,al + stosb + mov esi,[assembly_workspace.memory_start] + push ebx + call read_source + mov ebx,esi + pop esi + test eax,eax + jz try_include_paths + mov esi,ebx + include_read: + mov edx,eax + call create_source_entry + jc include_stack_limit_exceeded + mov [ebx+SourceEntry.type],SOURCE_FILE + mov [ebx+SourceEntry.name],esi + mov [ebx+SourceEntry.text],edx + mov edx,[local_parameter_namespace] + mov eax,[edx+SymbolTree_Root.chain] + test eax,eax + jnz new_parameter_namespace_ok + call create_parameter_namespace + mov [edx+SymbolTree_Root.chain],eax + new_parameter_namespace_ok: + and [eax+SymbolTree_Root.parameters],0 + mov [ebx+SourceEntry.local_namespace],eax + pop esi + call get_constituent_value + jc instruction_assembled + cmp al,',' + jne extra_characters_on_line + cmp [number_of_line_embeddings],0 + jne invalid_argument + jmp assemble_after_label + include_stack_limit_exceeded: + pop esi + mov edx,_stack_limit_exceeded + call register_error + jmp instruction_assembled + include_not_found: + pop esi + mov edx,_source_file_not_found + call register_error + jmp instruction_assembled + prepare_file_path: + mov [local_path],edx + call get_file_source_entry + mov esi,[ebx+SourceEntry.name] + mov ecx,esi + cut_parent_path: + lodsb + test al,al + jz parent_path_cut + cmp al,'/' + je found_path_segment + cmp al,'\' + jne cut_parent_path + found_path_segment: + mov ecx,esi + jmp cut_parent_path + parent_path_cut: + mov esi,[ebx+SourceEntry.name] + sub ecx,esi + mov ebx,ecx + add ecx,[edx] + inc ecx + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + call reserve_workspace + mov ecx,ebx + rep movsb + mov edx,edi + xchg edx,[local_path] + lea esi,[edx+4] + mov ecx,[edx] + mov ebx,edi + rep movsb + xor al,al + stosb + retn + +evaluate_string: + mov edi,[assembly_workspace.memory_start] + mov [string_end],edi + collect_source_string: + call get_constant_value + cmp al,30h + je collect_source_byte + cmp al,22h + jne invalid_argument + mov ebx,edx + mov edi,[string_end] + mov ecx,[ebx] + inc ecx + mov edx,assembly_workspace + call reserve_workspace + xchg esi,ebx + lodsd + mov ecx,eax + rep movsb + mov esi,ebx + source_fragment_collected: + mov [string_end],edi + call get_constituent_value + jc source_string_ready + cmp al,',' + jne invalid_argument + jmp collect_source_string + collect_source_byte: + mov ebx,edx + mov edi,[string_end] + mov ecx,2 + mov edx,assembly_workspace + call reserve_workspace + mov edx,ebx + mov ecx,1 + call fit_value + jc value_out_of_range + inc edi + jmp source_fragment_collected + source_string_ready: + mov edi,[string_end] + xor al,al + stosb + push esi + mov esi,[assembly_workspace.memory_start] + call use_source + mov edx,eax + call create_source_entry + jc include_stack_limit_exceeded + mov [ebx+SourceEntry.type],SOURCE_MEMORY + mov [ebx+SourceEntry.name],esi + mov [ebx+SourceEntry.text],edx + mov eax,[parameter_namespace] + mov [ebx+SourceEntry.local_namespace],eax + pop esi + jmp instruction_assembled + +assert_condition: + call get_condition_value + test al,al + jnz instruction_assembled + mov edx,_assertion_failed + call register_error + jmp instruction_assembled + +conditional_block: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + mov dl,DBLOCK_CONTROL + xor ecx,ecx + call add_directive_block + mov [edi+DirectiveBlock.subtype],CTRL_IF + or [edi+DirectiveBlock.flags],CTRLF_ALLOWS_ELSE + test [assembly_mode],AMODE_SKIP + jnz skip_conditional_block + evaluate_conditional_block: + call get_condition_value + test al,al + jnz instruction_assembled + or [assembly_mode],AMODE_SKIP + jmp instruction_assembled + ignored_directive: + test [assembly_mode],AMODE_SKIP + jz add_line_to_macro + jmp assembly_line + +else_conditional_block: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + mov dl,DBLOCK_CONTROL + call find_directive_block + jc unexpected_instruction + mov al,[edi+DirectiveBlock.flags] + test al,CTRLF_ALLOWS_ELSE + jz unexpected_instruction + mov ah,[assembly_mode] + push eax + call close_control_directive_block + mov dl,DBLOCK_CONTROL + xor ecx,ecx + call add_directive_block + mov [edi+DirectiveBlock.subtype],CTRL_IF + or [edi+DirectiveBlock.flags],CTRLF_ALLOWS_ELSE + pop eax + test al,CTRLF_INACTIVE + jnz skip_conditional_block + test ah,AMODE_SKIP + jnz evaluate_conditional_block + skip_conditional_block: + or [assembly_mode],AMODE_SKIP + or [edi+DirectiveBlock.flags],CTRLF_INACTIVE + jmp assembly_line + +end_conditional_block: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + mov dl,DBLOCK_CONTROL + call find_directive_block + jc unexpected_instruction + cmp [edi+DirectiveBlock.subtype],CTRL_IF + jne unexpected_instruction + end_control_block: + call close_control_directive_block + jmp instruction_assembled + +conditionally_repeated_block: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + test [assembly_mode],AMODE_SKIP + jnz inactive_conditionally_repeated_block + mov ecx,[line_end] + sub ecx,esi + add ecx,sizeof.ConditionalRepeatData + cmp [embedded_context],0 + je condition_length_ok + add ecx,1+sizeof.RecognitionContext + condition_length_ok: + mov dl,DBLOCK_CONTROL + call add_directive_block + push esi + mov ecx,[line_end] + sub ecx,esi + sub edi,sizeof.ConditionalRepeatData + mov edx,ecx + sub edi,ecx + rep movsb + mov esi,[embedded_context] + test esi,esi + jz condition_stored + add edx,1+sizeof.RecognitionContext + mov ebx,edi + sub edi,edx + mov al,40h + stosb + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep movsd + mov edi,ebx + condition_stored: + mov [edi+ConditionalRepeatData.condition_length],edx + add edi,sizeof.ConditionalRepeatData + pop esi + mov [edi+DirectiveBlock.subtype],CTRL_WHILE + or [edi+DirectiveBlock.flags],CTRLF_BREAKABLE + call get_condition_value + test al,al + jz skip_repeated_block + start_repeated_block: + mov ecx,2 + call allocate_counter + mov edi,ebx + mov al,1 + stosb + stosb + mov [current_counter],ebx + mov ecx,[parameter_namespace] + mov [ecx+SymbolTree_Root.parameters],SPECPARM_COUNTER + test esi,esi + jz assembly_line + jmp instruction_assembled + inactive_conditionally_repeated_block: + xor esi,esi + mov dh,CTRL_WHILE + inactive_breakable_block: + mov dl,DBLOCK_CONTROL + xor ecx,ecx + call add_directive_block + mov [edi+DirectiveBlock.subtype],dh + or [edi+DirectiveBlock.flags],CTRLF_BREAKABLE + skip_repeated_block: + or [assembly_mode],AMODE_SKIP + mov ecx,1 + call allocate_counter + mov byte [ebx],0 + mov [current_counter],ebx + mov ecx,[parameter_namespace] + mov [ecx+SymbolTree_Root.parameters],0 + test esi,esi + jz assembly_line + jmp instruction_assembled + allocate_counter: + mov ebx,[current_counter] + movzx eax,byte [ebx] + lea ebx,[ebx+1+eax] + add ecx,ebx + cmp ecx,[counters_stack_end] + jbe counter_allocated + mov eax,[counters_stack_base] + sub ecx,eax + sub ebx,eax + call grow_stack + add ecx,eax + mov [counters_stack_end],ecx + mov [counters_stack_base],eax + add ebx,eax + counter_allocated: + retn + +end_conditionally_repeated_block: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + mov dl,DBLOCK_CONTROL + call find_directive_block + jc unexpected_instruction + cmp [edi+DirectiveBlock.subtype],CTRL_WHILE + jne unexpected_instruction + test [assembly_mode],AMODE_SKIP + jnz end_control_block + push esi edi + push [line_end] + push [source_context] + lea esi,[edi-sizeof.ConditionalRepeatData] + mov [line_end],esi + sub esi,[esi+ConditionalRepeatData.condition_length] + sub edi,[edi+DirectiveBlock.length_of_data] + mov [source_context],edi + and [embedded_context],0 + call get_condition_value + pop [source_context] + pop [line_end] + pop edi esi + test al,al + jz end_control_block + repeat_condition_upheld: + mov ebx,[current_counter] + movzx ecx,byte [ebx] + inc ebx + increase_counter: + inc byte [ebx] + jnz counter_increased + inc ebx + loop increase_counter + cmp ebx,[counters_stack_end] + jb counter_length_grown + lea ecx,[ebx+1] + mov eax,[counters_stack_base] + sub ecx,eax + sub ebx,eax + sub [current_counter],eax + call grow_stack + add ecx,eax + mov [counters_stack_end],ecx + mov [counters_stack_base],eax + add [current_counter],eax + add ebx,eax + counter_length_grown: + mov byte [ebx],1 + mov ebx,[current_counter] + inc byte [ebx] + counter_increased: + push esi + test [edi+DirectiveBlock.flags],CTRLF_HAS_REPEAT_DATA + jz index_updated + mov esi,[current_counter] + mov eax,[counters_stack_base] + add eax,[edi-sizeof.RepeatData+RepeatData.index_position] + cmp eax,esi + je index_updated + xchg eax,edi + movzx ecx,byte [esi] + inc ecx + rep movsb + mov edi,eax + index_updated: + mov eax,[source_context] + mov esi,eax + call release_source_context + sub edi,[edi+DirectiveBlock.length_of_data] + xchg esi,edi + call clone_source_context + pop esi + jmp instruction_assembled + +repeated_block: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + test [assembly_mode],AMODE_SKIP + jnz inactive_repeated_block + call get_numeric_constant_value + test edx,edx + jz invalid_count + mov ecx,[edx] + add edx,4 + test ecx,ecx + jz inactive_repeated_block + mov al,[edx+ecx-1] + test al,al + js count_out_of_range + jnz count_ok + optimize_counter: + test ecx,ecx + jz inactive_repeated_block + dec ecx + mov al,[edx+ecx-1] + test al,al + jz optimize_counter + count_ok: + push esi ecx + mov esi,edx + mov dl,DBLOCK_CONTROL + add ecx,sizeof.RepeatData + call add_directive_block + mov [edi+DirectiveBlock.subtype],CTRL_REPEAT + or [edi+DirectiveBlock.flags],CTRLF_BREAKABLE + CTRLF_HAS_REPEAT_DATA + mov [directive_block],edi + pop ecx + sub edi,sizeof.RepeatData + mov [edi+RepeatData.limit_length],ecx + sub edi,ecx + rep movsb + pop esi + mov ecx,2 + call allocate_counter + mov eax,ebx + sub eax,[counters_stack_base] + mov [edi+RepeatData.index_position],eax + mov edi,ebx + mov al,1 + stosb + stosb + mov [current_counter],ebx + mov ecx,[parameter_namespace] + mov [ecx+SymbolTree_Root.parameters],SPECPARM_COUNTER + SPECPARM_LIMIT + define_named_counters: + xor al,al + xchg al,[current_constituent] + test al,al + jz get_counter_name + cmp al,',' + je get_counter_name + cmp al,1Ah + jne invalid_argument + mov esi,[symbol_start] + get_counter_name: + call identify_parameter_symbol + jc instruction_assembled + test ebx,ebx + jz invalid_argument + mov [label_leaf],ebx + call peek_at_constituent_value + jc counter_with_default_base + cmp al,':' + jne counter_with_default_base + and [current_constituent],0 + call get_numeric_constant_value + test edx,edx + jz invalid_counter_base + mov ecx,[edx] + test byte [edx+4+ecx-1],80h + jns counter_base_ok + mov edx,_value_out_of_range + call register_error + jmp counter_with_default_base + invalid_counter_base: + mov edx,_invalid_value + call register_error + counter_with_default_base: + mov edx,singular_value + counter_base_ok: + push esi + mov esi,edx + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + mov ecx,[esi] + add ecx,8 + call reserve_workspace + mov eax,[current_counter] + sub eax,[counters_stack_base] + stosd + lodsd + mov ecx,eax + stosd + rep movsb + mov esi,[assembly_workspace.memory_start] + mov ecx,edi + sub ecx,esi + mov [value_type],VALTYPE_NUMERIC_SEQUENCE + mov ebx,[label_leaf] + mov edi,[directive_block] + call add_block_parameter + pop esi + jmp define_named_counters + invalid_count: + mov edx,_invalid_value + call register_error + jmp inactive_repeated_block + count_out_of_range: + mov edx,_value_out_of_range + call register_error + inactive_repeated_block: + xor esi,esi + mov dh,CTRL_REPEAT + jmp inactive_breakable_block + +end_repeated_block: + mov dh,CTRL_REPEAT + close_repeat: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + mov dl,DBLOCK_CONTROL + call find_directive_block + jc unexpected_instruction + cmp dh,[edi+DirectiveBlock.subtype] + jne unexpected_instruction + test [assembly_mode],AMODE_SKIP + jnz end_control_block + mov edx,[current_counter] + movzx ecx,byte [edx] + inc edx + lea ebx,[edi-sizeof.RepeatData] + cmp ecx,[ebx+RepeatData.limit_length] + jne repeat_condition_upheld + sub ebx,ecx + compare_counter_with_limit: + mov al,[ebx] + cmp al,[edx] + jne repeat_condition_upheld + inc ebx + inc edx + loop compare_counter_with_limit + jmp end_control_block + +iterator_block: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + test [assembly_mode],AMODE_SKIP + jnz inactive_iterator_block + xor eax,eax + mov [breakpoint_token],al + mov [number_of_parameters],eax + mov edi,[expression_workspace.memory_start] + call move_to_next_symbol + jc invalid_iterator + cmp al,'<' + jne iterator_parameter_declaration + inc esi + mov [breakpoint_token],'>' + iterator_parameter_declaration: + push edi + call identify_parameter_symbol + pop edi + jc invalid_iterator + test ebx,ebx + jz invalid_iterator + mov eax,[number_of_parameters] + shl eax,2 + add eax,[assembly_stack_base] + lea ecx,[eax+4] + cmp ecx,[assembly_stack_end] + jbe store_parameter_leaf + mov eax,[assembly_stack_base] + sub ecx,eax + call grow_stack + mov [assembly_stack_base],eax + add ecx,eax + mov [assembly_stack_end],ecx + mov ecx,[number_of_parameters] + shl ecx,2 + add eax,ecx + store_parameter_leaf: + mov [eax],ebx + mov edx,expression_workspace + mov ecx,sizeof.LineExcerpt + call reserve_workspace + mov [edi+LineExcerpt.data_start],esi + mov [edi+LineExcerpt.data_end],esi + inc [number_of_parameters] + call move_to_next_symbol + jc invalid_iterator + cmp al,':' + je parameter_with_default_value + cmp al,'=' + je parameter_with_default_value + cmp al,'*' + jne parameter_declaration_done + and [edi+LineExcerpt.data_start],0 + inc esi + call move_to_next_symbol + jc invalid_iterator + jmp parameter_declaration_done + parameter_with_default_value: + inc esi + call cut_argument_value + parameter_declaration_done: + add edi,sizeof.LineExcerpt + mov ah,[breakpoint_token] + test ah,ah + jz iterator_parameters_declared + inc esi + cmp al,',' + je iterator_parameter_declaration + cmp al,ah + jne invalid_iterator + call move_to_next_symbol + jc invalid_iterator + iterator_parameters_declared: + cmp al,',' + jne invalid_iterator + mov ebx,[number_of_parameters] + mov [number_of_values],ebx + and [number_of_iterations],0 + collect_iterator_values: + inc esi + call move_to_next_symbol + jc initialize_iterator + mov edx,expression_workspace + mov ecx,sizeof.LineExcerpt + call reserve_workspace + call cut_argument_value + add edi,sizeof.LineExcerpt + inc [number_of_values] + cmp ebx,[number_of_parameters] + jne iterator_value_collected + inc [number_of_iterations] + xor ebx,ebx + iterator_value_collected: + inc ebx + cmp al,',' + je collect_iterator_values + initialize_iterator: + cmp [number_of_iterations],0 + je inactive_iterator_block + mov dl,DBLOCK_CONTROL + mov ecx,5+sizeof.RepeatData + call add_directive_block + mov [edi+DirectiveBlock.subtype],CTRL_IRP + or [edi+DirectiveBlock.flags],CTRLF_BREAKABLE + CTRLF_HAS_REPEAT_DATA + CTRLF_HAS_WRITABLE_INDEX + mov [directive_block],edi + bsr ecx,[number_of_iterations] + shr ecx,3 + inc ecx + push esi + sub edi,sizeof.RepeatData + mov [edi+RepeatData.limit_length],ecx + sub edi,ecx + mov esi,number_of_iterations + rep movsb + mov ecx,[edi+RepeatData.limit_length] + add ecx,3 + call allocate_counter + mov eax,ebx + sub eax,[counters_stack_base] + mov [edi+RepeatData.index_position],eax + mov ecx,[edi+RepeatData.limit_length] + mov edi,ebx + mov al,1 + stosb + stosb + lea edi,[edi+ecx-1] + mov [current_counter],edi + stosb + stosb + mov ecx,[parameter_namespace] + mov [ecx+SymbolTree_Root.parameters],SPECPARM_COUNTER + SPECPARM_LIMIT + xor eax,eax + create_iterator_sequences: + mov [parameter_index],eax + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + mov ecx,[number_of_iterations] + add ecx,2 + shl ecx,2 + call reserve_workspace + mov eax,[directive_block] + mov eax,[eax-sizeof.RepeatData+RepeatData.index_position] + stosd + mov eax,[number_of_iterations] + add eax,2 + shl eax,2 + stosd + mov [sequence_header_length],eax + mov edx,edi + mov edi,[assembly_workspace.memory_start] + sub edx,edi + mov [sequence_header_cursor],edx + add edi,eax + mov eax,[number_of_parameters] + add eax,[parameter_index] + cmp eax,[number_of_values] + jae copy_default_value + copy_individual_value: + mov [value_index],eax + mov ebx,eax + assert sizeof.LineExcerpt = 1 shl 4 + shl ebx,4 + add ebx,[expression_workspace.memory_start] + mov esi,[ebx+LineExcerpt.data_start] + mov ecx,[ebx+LineExcerpt.data_end] + sub ecx,esi + jnz individual_value_ready + copy_default_value: + mov ebx,[parameter_index] + assert sizeof.LineExcerpt = 1 shl 4 + shl ebx,4 + add ebx,[expression_workspace.memory_start] + mov esi,[ebx+LineExcerpt.data_start] + test esi,esi + jz missing_required_individual_value + mov ecx,[ebx+LineExcerpt.data_end] + sub ecx,esi + individual_value_ready: + mov edx,assembly_workspace + add ecx,2*(1+sizeof.RecognitionContext) + call reserve_workspace + mov ecx,[ebx+LineExcerpt.data_end] + sub ecx,esi + jz next_iterator_value + cmp [ebx+LineExcerpt.recognition_context],0 + je copy_iterator_value + mov al,40h + stosb + mov eax,esi + mov edx,ecx + mov esi,[ebx+LineExcerpt.recognition_context] + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep movsd + mov ecx,edx + mov esi,eax + copy_iterator_value: + rep movsb + mov eax,[ebx+LineExcerpt.recognition_context] + or eax,[ebx+LineExcerpt.leftover_context] + jz next_iterator_value + mov al,40h + stosb + xor eax,eax + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep stosd + next_iterator_value: + mov edx,[assembly_workspace.memory_start] + mov ecx,edi + sub ecx,edx + add edx,[sequence_header_cursor] + mov [edx],ecx + add [sequence_header_cursor],4 + mov eax,[value_index] + add eax,[number_of_parameters] + cmp eax,[number_of_values] + jb copy_individual_value + mov eax,[sequence_header_length] + sub eax,[sequence_header_cursor] + jne copy_default_value + mov ecx,edi + mov esi,[assembly_workspace.memory_start] + sub ecx,esi + mov eax,[parameter_index] + shl eax,2 + add eax,[assembly_stack_base] + mov ebx,[eax] + mov edi,[directive_block] + mov [value_type],VALTYPE_SYMBOLIC_SEQUENCE + call add_block_parameter + mov eax,[parameter_index] + inc eax + cmp eax,[number_of_parameters] + jb create_iterator_sequences + pop esi + jmp instruction_assembled + missing_required_individual_value: + mov edx,_missing_argument + call register_error + jmp next_iterator_value + invalid_iterator: + mov edx,_invalid_argument + call register_error + inactive_iterator_block: + xor esi,esi + mov dh,CTRL_IRP + jmp inactive_breakable_block + +end_iterator_block: + mov dh,CTRL_IRP + jmp close_repeat + +variable_iterator_block: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + test [assembly_mode],AMODE_SKIP + jnz skipped_variable_iterator_block + call move_to_next_symbol + jc invalid_iterator + call identify_parameter_symbol + jc invalid_variable_iterator + test ebx,ebx + jz invalid_variable_iterator + mov [label_leaf],ebx + call move_to_next_symbol + jc invalid_variable_iterator + cmp al,',' + jne invalid_variable_iterator + inc esi + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc invalid_variable_identifier + test ebx,ebx + jz invalid_variable_identifier + mov eax,[current_pass] + mov [ebx+SymbolTree_Leaf.last_use_pass],eax + mov edi,[assembly_stack_base] + xor ecx,ecx + mov [number_of_values],ecx + mov edx,[ebx+SymbolTree_Leaf.definition] + collect_variable_values: + test edx,edx + jz variable_values_collected + mov eax,[edx+ValueDefinition.pass] + cmp eax,[current_pass] + jne variable_values_collected + cmp [edx+ValueDefinition.type],VALTYPE_RESERVED + je skip_variable_value + add edi,4 + cmp edi,[assembly_stack_end] + jbe store_variable_value + push ecx edx + mov eax,[assembly_stack_base] + sub edi,eax + mov ecx,edi + call grow_stack + add edi,eax + mov [assembly_stack_base],eax + add eax,ecx + mov [assembly_stack_end],eax + pop edx ecx + store_variable_value: + mov [edi-4],edx + inc [number_of_values] + add ecx,[edx+ValueDefinition.value_length] + add ecx,1+sizeof.RecognitionContext + skip_variable_value: + mov edx,[edx+ValueDefinition.previous] + jmp collect_variable_values + variable_values_collected: + mov eax,[number_of_values] + test eax,eax + jz inactive_variable_iterator_block + add eax,2 + shl eax,2 + add ecx,eax + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + call reserve_workspace + mov dl,DBLOCK_CONTROL + mov ecx,5+sizeof.RepeatData + call add_directive_block + mov [edi+DirectiveBlock.subtype],CTRL_IRPV + or [edi+DirectiveBlock.flags],CTRLF_BREAKABLE + CTRLF_HAS_REPEAT_DATA + CTRLF_HAS_WRITABLE_INDEX + mov [directive_block],edi + bsr ecx,[number_of_values] + shr ecx,3 + inc ecx + push esi + sub edi,sizeof.RepeatData + mov [edi+RepeatData.limit_length],ecx + sub edi,ecx + mov esi,number_of_values + rep movsb + mov ecx,[edi+RepeatData.limit_length] + add ecx,3 + call allocate_counter + mov eax,ebx + sub eax,[counters_stack_base] + mov [edi+RepeatData.index_position],eax + mov ecx,[edi+RepeatData.limit_length] + mov edi,ebx + mov al,1 + stosb + stosb + lea edi,[edi+ecx-1] + mov [current_counter],edi + stosb + stosb + mov ecx,[parameter_namespace] + mov [ecx+SymbolTree_Root.parameters],SPECPARM_COUNTER + SPECPARM_LIMIT + mov edi,[assembly_workspace.memory_start] + mov ecx,[number_of_values] + mov edx,ecx + add ecx,2 + shl ecx,2 + mov ebx,edi + add edi,ecx + mov eax,[directive_block] + mov eax,[eax-sizeof.RepeatData+RepeatData.index_position] + mov [ebx],eax + add ebx,4 + mov [ebx],ecx + create_value_sequence: + mov eax,edx + dec eax + shl eax,2 + add eax,[assembly_stack_base] + mov eax,[eax] + push edx + mov cl,[eax+ValueDefinition.type] + cmp cl,VALTYPE_SYMBOLIC + je symbolic_value_in_sequence + cmp cl,VALTYPE_NUMERIC + jne proxy_value_in_sequence + mov esi,[eax+ValueDefinition.value] + mov ecx,[esi] + add esi,4 + test byte [esi+ecx-1],80h + jnz proxy_value_in_sequence + cmp dword [esi+ecx],0 + jne proxy_value_in_sequence + push ecx + add ecx,1+4 + call allocate_value_in_sequence + pop ecx + mov al,30h + stosb + mov eax,ecx + stosd + rep movsb + jmp next_value_in_sequence + allocate_value_in_sequence: + mov eax,[ebx] + add eax,ecx + add ebx,4 + mov [ebx],eax + mov edx,assembly_workspace + sub ebx,[edx+Workspace.memory_start] + call reserve_workspace + add ebx,[assembly_workspace.memory_start] + retn + proxy_value_in_sequence: + mov esi,eax + mov ecx,(1+sizeof.RecognitionContext)*2+1 + call allocate_value_in_sequence + push ebx edi + push esi + xor eax,eax + mov ecx,[proxy_number] + inc [proxy_number] + mov dl,SYMCLASS_EXPRESSION + mov ebx,[current_context.base_namespace] + call get_abstract_symbol + xchg edx,[esp] + call update_value_link + pop edx + pop edi ebx + mov al,40h + stosb + mov eax,[current_context.base_namespace] + mov [edi+RecognitionContext.base_namespace],eax + mov [edi+RecognitionContext.base_label],edx + add edi,sizeof.RecognitionContext + mov al,'.' + stosb + jmp close_symbolic_value_in_sequence + symbolic_value_in_sequence: + mov esi,[eax+ValueDefinition.value] + mov ecx,[eax+ValueDefinition.value_length] + push ecx + add ecx,1+sizeof.RecognitionContext + call allocate_value_in_sequence + pop ecx + rep movsb + close_symbolic_value_in_sequence: + mov al,40h + stosb + xor eax,eax + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep stosd + next_value_in_sequence: + pop edx + dec edx + jnz create_value_sequence + mov esi,[assembly_workspace.memory_start] + mov ecx,edi + sub ecx,esi + mov ebx,[label_leaf] + mov edi,[directive_block] + mov [value_type],VALTYPE_SYMBOLIC_SEQUENCE + call add_block_parameter + pop esi + jmp instruction_assembled + invalid_variable_identifier: + mov edx,_invalid_identifier + call register_error + jmp inactive_variable_iterator_block + invalid_variable_iterator: + mov edx,_invalid_argument + call register_error + skipped_variable_iterator_block: + xor esi,esi + inactive_variable_iterator_block: + mov dh,CTRL_IRPV + jmp inactive_breakable_block + +end_variable_iterator_block: + mov dh,CTRL_IRPV + jmp close_repeat + +set_iterator_index: + mov dl,DBLOCK_CONTROL + call find_directive_block + jc unexpected_instruction + find_indexable_block: + test [edi+DirectiveBlock.flags],CTRLF_HAS_WRITABLE_INDEX + jnz indexable_block_found + call find_next_directive_block + jc unexpected_instruction + jmp find_indexable_block + indexable_block_found: + ; test [edi+DirectiveBlock.flags],CTRLF_HAS_REPEAT_DATA + ; jnz internal_error + mov [directive_block],edi + call get_numeric_constant_value + test edx,edx + jz invalid_argument + mov ecx,[edx] + add edx,4 + mov al,[edx+ecx-1] + test al,al + js value_out_of_range + jnz index_optimized + optimize_index: + test ecx,ecx + jz value_out_of_range + dec ecx + mov al,[edx+ecx-1] + test al,al + jz optimize_index + index_optimized: + mov edi,[directive_block] + sub edi,sizeof.RepeatData + mov ebx,[edi+RepeatData.limit_length] + cmp ecx,ebx + ja value_out_of_range + jb index_ok + sub edi,ebx + compare_index_with_limit: + mov al,[edx+ebx-1] + cmp al,[edi+ebx-1] + ja value_out_of_range + jb index_ok + dec ebx + jnz compare_index_with_limit + index_ok: + xchg esi,edx + mov edi,[directive_block] + mov edi,[edi-sizeof.RepeatData+RepeatData.index_position] + add edi,[counters_stack_base] + mov al,cl + stosb + rep movsb + mov esi,edx + jmp instruction_assembled + +break_directive: + mov dl,DBLOCK_CONTROL + call find_directive_block + jc unexpected_instruction + find_block_to_break: + test [edi+DirectiveBlock.flags],CTRLF_BREAKABLE + jnz block_to_break_found + call find_next_directive_block + jc unexpected_instruction + jmp find_block_to_break + block_to_break_found: + or [assembly_mode],AMODE_SKIP + mov dl,DBLOCK_CONTROL + call find_directive_block + break_blocks: + or [edi+DirectiveBlock.flags],CTRLF_INACTIVE + test [edi+DirectiveBlock.flags],CTRLF_BREAKABLE + jnz disable_counter + or [edi+DirectiveBlock.prior_assembly_mode],AMODE_SKIP + call find_next_directive_block + jc unexpected_instruction + jmp break_blocks + disable_counter: + mov edi,[current_counter] + xor al,al + stosb + jmp instruction_assembled + +else_directive: + mov edx,[ebx+SymbolTree_Leaf.branch] + call get_symbol_namespace + and [symbol_definition],0 + mov dl,SYMCLASS_INSTRUCTION + call identify_symbol_in_namespace + jc plain_else + test ebx,ebx + jz invalid_else + mov al,[ebx+SymbolTree_Leaf.class] + cmp al,SYMCLASS_INSTRUCTION + jne invalid_else + call get_available_value + jc invalid_else + jmp prefixed_directive + invalid_else: + mov esi,[symbol_start] + plain_else: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + mov dl,DBLOCK_CONTROL + call find_directive_block + jc unexpected_instruction + test [edi+DirectiveBlock.flags],CTRLF_ALLOWS_ELSE + jz unexpected_instruction + and [edi+DirectiveBlock.flags],not CTRLF_ALLOWS_ELSE + call remove_block_parameters + test [edi+DirectiveBlock.flags],CTRLF_INACTIVE + jnz assembly_line + xor [assembly_mode],AMODE_SKIP + jmp instruction_assembled + +end_directive: + mov edx,[ebx+SymbolTree_Leaf.branch] + call get_symbol_namespace + and [symbol_definition],0 + mov dl,SYMCLASS_INSTRUCTION + call identify_symbol_in_namespace + jc missing_prefixed_directive + test ebx,ebx + jz invalid_prefixed_directive + mov al,[ebx+SymbolTree_Leaf.class] + cmp al,SYMCLASS_INSTRUCTION + jne invalid_prefixed_directive + call get_available_value + jc invalid_prefixed_directive + prefixed_directive: + test [edx+ValueDefinition.flags],VAL_UNCONDITIONAL + jnz execute_prefixed_directive + test [assembly_mode],AMODE_SKIP + jnz assembly_line + test [assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + execute_prefixed_directive: + mov al,[edx+ValueDefinition.type] + cmp al,VALTYPE_CALM + je launch_calm + cmp al,VALTYPE_SYMBOLIC + je use_macro + cmp al,VALTYPE_NATIVE_COMMAND + jne invalid_argument + jmp [edx+ValueDefinition.value] + missing_prefixed_directive: + test [assembly_mode],AMODE_SKIP + jnz assembly_line + test [assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + cmp [interceptor],0 + jne execute_interceptor + jmp missing_argument + invalid_prefixed_directive: + test [assembly_mode],AMODE_SKIP + jnz assembly_line + test [assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + cmp [interceptor],0 + jne execute_interceptor + jmp invalid_argument + +raw_match_block: + mov bl,CTRL_RMATCH + jmp begin_match_block +match_block: + mov bl,CTRL_MATCH + begin_match_block: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + cmp bl,CTRL_RMATCH + sete [unprocessed_matching] + mov dl,DBLOCK_CONTROL + xor ecx,ecx + call add_directive_block + mov [directive_block],edi + mov [edi+DirectiveBlock.subtype],bl + or [edi+DirectiveBlock.flags],CTRLF_ALLOWS_ELSE + test [assembly_mode],AMODE_SKIP + jnz skip_conditional_block + evaluate_match: + mov [pattern_start],esi + and [number_of_parameters],0 + get_match_pattern: + call move_to_next_symbol + jc invalid_match + qualify_pattern_element: + cmp al,',' + je match_pattern_ok + cmp al,1Ah + je count_pattern_parameter + cmp al,30h + je invalid_match + cmp al,'=' + jne skip_pattern_symbol + call skip_token + xor ecx,ecx + call move_to_next_symbol + jc invalid_match + test ecx,ecx + jz skip_pattern_symbol + jmp qualify_pattern_element + count_pattern_parameter: + call detect_numeric_symbol + jc invalid_match + inc [number_of_parameters] + add esi,1+4 + jmp get_match_pattern + skip_pattern_symbol: + call skip_token + jmp get_match_pattern + match_pattern_ok: + mov [pattern_end],esi + inc esi + mov [argument_start],esi + mov eax,[embedded_context] + mov [matched_context],eax + mov edi,[expression_workspace.memory_start] + mov ecx,[number_of_parameters] + assert sizeof.MatchedParameter = 1 shl 3 + shl ecx,3 + mov ebx,ecx + mov edx,expression_workspace + call reserve_workspace + add edi,ebx + mov [substitutions_end],edi + cmp [unprocessed_matching],0 + jne substitutions_ready + detect_substitutions: + mov eax,[embedded_context] + mov [stored_context],eax + and [symbol_definition],0 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc substitutions_ready + test edi,edi + jnz check_for_substitution + call skip_literal + xor ebx,ebx + check_for_substitution: + test ebx,ebx + jz detect_substitutions + call get_available_value + jc detect_substitutions + cmp [edx+ValueDefinition.type],VALTYPE_SYMBOLIC + jne detect_substitutions + mov eax,[current_pass] + mov [ebx+SymbolTree_Leaf.last_use_pass],eax + mov ebx,edx + mov edi,[substitutions_end] + mov edx,expression_workspace + mov ecx,sizeof.SymbolSubstitution + call reserve_workspace + mov eax,[ebx+ValueDefinition.value] + mov [edi+SymbolSubstitution.value_start],eax + add eax,[ebx+ValueDefinition.value_length] + mov [edi+SymbolSubstitution.value_end],eax + mov ebx,esi + mov esi,[symbol_start] + mov [edi+SymbolSubstitution.symbol_start],esi + scan_replaced_symbol: + mov al,[esi] + cmp al,20h + je whitespace_in_replaced_symbol + cmp al,40h + jne actual_replaced_symbol + inc esi + mov [stored_context],esi + add esi,sizeof.RecognitionContext + jmp next_token_in_replaced_symbol + whitespace_in_replaced_symbol: + inc esi + jmp next_token_in_replaced_symbol + actual_replaced_symbol: + call skip_token + mov ecx,esi + mov edx,[stored_context] + next_token_in_replaced_symbol: + cmp esi,ebx + jb scan_replaced_symbol + mov [edi+SymbolSubstitution.symbol_end],ecx + mov [edi+SymbolSubstitution.leftover_context],edx + add edi,sizeof.SymbolSubstitution + mov [substitutions_end],edi + jmp detect_substitutions + substitutions_ready: + mov ebx,[number_of_parameters] + assert sizeof.MatchedParameter = 1 shl 3 + shl ebx,3 + add ebx,[expression_workspace.memory_start] + mov esi,[argument_start] + mov edi,[pattern_start] + xor eax,eax + mov [parameter_index],eax + mov [stored_position],eax + mov [substitution_active],al + match_with_pattern: + call get_pattern_token + cmp ah,1Ah + jne exact_match + wildcard_match: + call get_matched_token + jc no_match + cmp al,20h + jne wildcard_matched + inc esi + jmp wildcard_match + wildcard_matched: + xor eax,eax + mov edx,[expression_workspace.memory_start] + mov ecx,[parameter_index] + jecxz prepare_matched_parameter + dec ecx + assert sizeof.MatchedParameter = 1 shl 3 + shl ecx,3 + add edx,ecx + push edi + mov edi,[assembly_workspace.memory_start] + add edi,[edx+MatchedParameter.assembly_position] + push edx + call close_matched_value + pop edx + mov eax,edi + sub eax,[assembly_workspace.memory_start] + mov [edx+MatchedParameter.assembly_position],eax + pop edi + add edx,sizeof.MatchedParameter + prepare_matched_parameter: + mov [edx+MatchedParameter.pattern],edi + inc [parameter_index] + mov edi,[assembly_workspace.memory_start] + add edi,eax + xor eax,eax + mov [embedded_context],eax + mov [stored_position],eax + mov [whitespace_matching],al + push edx + call copy_matched_token + pop edx + sub edi,[assembly_workspace.memory_start] + mov [edx+MatchedParameter.assembly_position],edi + mov edi,[edx+MatchedParameter.pattern] + add edi,1+4 + call get_pattern_token + cmp ah,1Ah + je wildcard_match + cmp ah,'?' + jne exact_match + inc edi + jmp match_with_pattern + exact_match: + cmp [stored_position],0 + jne match_position_stored + mov [stored_position],esi + mov [stored_substitution],ebx + mov dl,[substitution_active] + mov [stored_substitution_activity],dl + mov ecx,[matched_context] + mov [stored_context],ecx + mov [stored_pattern],edi + or [whitespace_matching],1 + match_position_stored: + cmp ah,',' + je end_of_pattern + cmp ah,20h + je allow_whitespace + cmp ah,'=' + jne match_tokens + inc edi + call get_pattern_token + match_tokens: + call get_matched_token + jc no_match + cmp al,20h + je match_whitespace + and [whitespace_matching],0 + cmpsb + jne token_mismatch + cmp ah,1Ah + je match_name_tokens + cmp ah,22h + je match_string_tokens + cmp ah,27h + je match_string_tokens + cmp ah,30h + jne match_with_pattern + mov ecx,esi + mov edx,edi + lodsd + add esi,eax + mov eax,[edi] + lea edi,[edi+4+eax] + call get_pattern_token + cmp ah,'?' + jne compare_token_contents + inc edi + jmp compare_token_contents + match_string_tokens: + lodsd + mov ecx,eax + mov edx,[edi] + add edi,4 + compare_token_contents: + cmp ecx,edx + je match_with_pattern + push esi edi + mov esi,ecx + mov edi,edx + mov ecx,[esi] + add ecx,4 + repe cmpsb + pop edi esi + jne retract_match + jmp match_with_pattern + match_name_tokens: + lodsd + mov ecx,eax + mov edx,[edi] + add edi,4 + call get_pattern_token + cmp ah,'?' + je case_insensitive_match + cmp ecx,edx + je match_with_pattern + push esi edi + mov esi,ecx + mov edi,edx + lodsd + scasd + jne name_mismatch + mov ecx,eax + mov eax,[esi+ecx] + cmp eax,[edi+ecx] + jne name_mismatch + repe cmpsb + jne name_mismatch + pop edi esi + jmp match_with_pattern + name_mismatch: + pop edi esi + jmp retract_match + case_insensitive_match: + inc edi + cmp ecx,edx + je match_with_pattern + push esi edi + mov esi,ecx + mov edi,edx + lodsd + scasd + jne name_mismatch + mov ecx,eax + mov eax,[esi+ecx+4] + cmp eax,[edi+ecx+4] + jne name_mismatch + xor eax,eax + compare_case_insensitively: + lodsb + mov dl,[characters+eax] + mov al,[edi] + inc edi + cmp dl,[characters+eax] + jne name_mismatch + loop compare_case_insensitively + pop edi esi + jmp match_with_pattern + match_converted_number: + call convert_number_to_match + jmp compare_token_contents + match_with_converted_number: + xchg esi,edi + call convert_number_to_match + xchg esi,edi + jmp compare_token_contents + convert_number_to_match: + mov edx,esi + lodsd + add esi,eax + push ebx esi edi + call convert_number_back + pop edi esi ebx + mov ecx,[edi] + add edi,4 + retn + token_mismatch: + cmp ax,1A30h + je match_converted_number + cmp ax,301Ah + je match_with_converted_number + retract_match: + xor esi,esi + xchg esi,[stored_position] + test esi,esi + jz no_match + mov ebx,[stored_substitution] + mov dl,[stored_substitution_activity] + mov [substitution_active],dl + mov ecx,[stored_context] + mov [matched_context],ecx + mov edi,[stored_pattern] + and [whitespace_matching],0 + mov edx,[parameter_index] + sub edx,1 + jc no_match + assert sizeof.MatchedParameter = 1 shl 3 + shl edx,3 + add edx,[expression_workspace.memory_start] + push edi + mov edi,[assembly_workspace.memory_start] + add edi,[edx+MatchedParameter.assembly_position] + push edx + copy_whitespace: + call get_matched_token + jc no_match + cmp al,20h + jne copy_additional_symbol + call copy_matched_token + jmp copy_whitespace + copy_additional_symbol: + call copy_matched_token + pop edx + sub edi,[assembly_workspace.memory_start] + mov [edx+MatchedParameter.assembly_position],edi + pop edi + jmp match_with_pattern + match_whitespace: + cmp al,ah + je required_whitespace + cmp [whitespace_matching],0 + je retract_match + inc esi + jmp match_tokens + required_whitespace: + inc esi + allow_whitespace: + inc edi + or [whitespace_matching],1 + jmp match_with_pattern + end_of_pattern: + call get_matched_token + jc pattern_matched + cmp al,20h + jne retract_match + call skip_token + jmp end_of_pattern + pattern_matched: + mov ebx,[parameter_index] + sub ebx,1 + jc matching_done + assert sizeof.MatchedParameter = 1 shl 3 + shl ebx,3 + add ebx,[expression_workspace.memory_start] + mov edi,[assembly_workspace.memory_start] + add edi,[ebx+MatchedParameter.assembly_position] + call close_matched_value + sub edi,[assembly_workspace.memory_start] + mov [ebx+MatchedParameter.assembly_position],edi + matching_done: + cmp [number_of_parameters],0 + je assembly_line + mov [symbol_class],SYMCLASS_PARAMETER + and [name_volatile],0 + and [name_token],0 + or [symbol_required],1 + or [symbol_expected],1 + mov [value_type],VALTYPE_SYMBOLIC + xor eax,eax + mov [value_index],eax + define_matched_parameters: + mov [parameter_index],eax + assert sizeof.MatchedParameter = 1 shl 3 + shl eax,3 + add eax,[expression_workspace.memory_start] + mov edi,[eax+MatchedParameter.pattern] + mov esi,[edi+1] + lodsd + mov ecx,eax + add edi,1+4 + call get_pattern_token + mov edx,[esi+ecx] + mov al,NAME_CASESENSITIVE + cmp ah,'?' + jne matched_name_kind_ok + mov edx,[esi+ecx+4] + mov al,NAME_CASEINSENSITIVE + matched_name_kind_ok: + mov [name_kind],al + mov ebx,[parameter_namespace] + call scan_namespace + mov eax,[parameter_index] + assert sizeof.MatchedParameter = 1 shl 3 + shl eax,3 + add eax,[expression_workspace.memory_start] + mov ecx,[eax+MatchedParameter.assembly_position] + mov esi,ecx + xchg esi,[value_index] + sub ecx,esi + add esi,[assembly_workspace.memory_start] + mov edi,[directive_block] + call add_block_parameter + mov eax,[parameter_index] + inc eax + cmp eax,[number_of_parameters] + jb define_matched_parameters + jmp assembly_line + no_match: + or [assembly_mode],AMODE_SKIP + jmp assembly_line + invalid_match: + mov edx,_invalid_argument + call register_error + or [assembly_mode],AMODE_SKIP + jmp assembly_line + get_pattern_token: + mov ah,[edi] + cmp ah,40h + je skip_pattern_context + retn + skip_pattern_context: + add edi,1+sizeof.RecognitionContext + jmp get_pattern_token + get_matched_token: + cmp ebx,[substitutions_end] + je token_in_line + cmp [substitution_active],0 + jne token_in_substitution + cmp esi,[ebx+SymbolSubstitution.symbol_start] + je substitution_encountered + token_in_line: + cmp esi,[line_end] + je no_more_matched_tokens + check_for_matched_token: + mov al,[esi] + cmp al,40h + je matched_context_change + clc + retn + no_more_matched_tokens: + stc + retn + matched_context_change: + inc esi + cmp [unprocessed_matching],0 + jne matched_context_change_done + mov [matched_context],esi + matched_context_change_done: + add esi,sizeof.RecognitionContext + jmp get_matched_token + substitution_encountered: + mov esi,[ebx+SymbolSubstitution.value_start] + and [matched_context],0 + or [substitution_active],1 + token_in_substitution: + cmp esi,[ebx+SymbolSubstitution.value_end] + jb check_for_matched_token + mov esi,[ebx+SymbolSubstitution.symbol_end] + mov ecx,[ebx+SymbolSubstitution.leftover_context] + mov [matched_context],ecx + add ebx,sizeof.SymbolSubstitution + and [substitution_active],0 + jmp get_matched_token + skip_token: + inc esi + cmp al,1Ah + je skip_token_with_data + cmp al,22h + je skip_token_with_data + cmp al,27h + je skip_token_with_data + cmp al,30h + je skip_internal_token + cmp al,40h + je skip_context_token + retn + skip_token_with_data: + add esi,4 + retn + skip_internal_token: + lodsd + add esi,eax + retn + skip_context_token: + add esi,sizeof.RecognitionContext + retn + copy_matched_token: + mov edx,[matched_context] + cmp edx,[embedded_context] + je matched_context_ok + test edx,edx + jz copy_matched_context + mov eax,[edx] + test eax,eax + jnz copy_matched_context + mov [matched_context],eax + cmp eax,[embedded_context] + je matched_context_ok + mov edx,eax + copy_matched_context: + mov [embedded_context],edx + mov ecx,1+sizeof.RecognitionContext + mov edx,assembly_workspace + call reserve_workspace + mov al,40h + stosb + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + mov edx,[matched_context] + test edx,edx + jz clear_matched_context + xchg esi,edx + rep movsd + mov esi,edx + jmp matched_context_ok + clear_matched_context: + xor eax,eax + rep stosd + matched_context_ok: + mov ecx,1+4 + mov edx,assembly_workspace + call reserve_workspace + lodsb + stosb + cmp al,1Ah + je copy_token_with_data + cmp al,22h + je copy_token_with_data + cmp al,27h + je copy_token_with_data + cmp al,30h + je copy_internal_token + retn + copy_token_with_data: + movsd + retn + copy_internal_token: + mov ecx,[esi] + add ecx,4 + mov edx,assembly_workspace + call reserve_workspace + lodsd + stosd + mov ecx,eax + rep movsb + retn + close_matched_value: + mov eax,[embedded_context] + test eax,eax + jz matched_value_closed + mov ecx,1+sizeof.RecognitionContext + mov edx,assembly_workspace + call reserve_workspace + mov al,40h + stosb + xor eax,eax + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep stosd + matched_value_closed: + retn + +else_raw_match_block: + mov bl,CTRL_RMATCH + jmp begin_else_match_block +else_match_block: + mov bl,CTRL_MATCH + begin_else_match_block: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + mov dl,DBLOCK_CONTROL + call find_directive_block + jc unexpected_instruction + mov al,[edi+DirectiveBlock.flags] + test al,CTRLF_ALLOWS_ELSE + jz unexpected_instruction + mov ah,[assembly_mode] + push eax ebx + call close_control_directive_block + mov dl,DBLOCK_CONTROL + xor ecx,ecx + call add_directive_block + mov [directive_block],edi + pop ebx eax + cmp bl,CTRL_RMATCH + sete [unprocessed_matching] + mov [edi+DirectiveBlock.subtype],bl + or [edi+DirectiveBlock.flags],CTRLF_ALLOWS_ELSE + test al,CTRLF_INACTIVE + jnz skip_conditional_block + test ah,AMODE_SKIP + jnz evaluate_match + jmp skip_conditional_block + +end_raw_match_block: + mov bl,CTRL_RMATCH + jmp close_match_block +end_match_block: + mov bl,CTRL_MATCH + close_match_block: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + mov dl,DBLOCK_CONTROL + call find_directive_block + jc unexpected_instruction + cmp [edi+DirectiveBlock.subtype],bl + jne unexpected_instruction + call close_control_directive_block + jmp instruction_assembled + +postponed_block: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + mov dl,DBLOCK_CONTROL + xor ecx,ecx + call add_directive_block + mov [edi+DirectiveBlock.subtype],CTRL_POSTPONE + mov [directive_block],edi + or [assembly_mode],AMODE_SKIP + call get_constituent_value + jc instruction_assembled + cmp al,'?' + jne invalid_argument + mov edi,[directive_block] + or [edi+DirectiveBlock.flags],CTRLF_SUSPENDED + jmp instruction_assembled + +end_postponed_block: + test [assembly_mode],AMODE_DEFINITION + jnz ignored_directive + mov dl,DBLOCK_CONTROL + call find_directive_block + jc end_postponed_execution + cmp [edi+DirectiveBlock.subtype],CTRL_POSTPONE + jne unexpected_instruction + mov al,[edi+DirectiveBlock.prior_assembly_mode] + mov [assembly_mode],al + test al,AMODE_SKIP + jz keep_postponed_block + call close_directive_block + jmp instruction_assembled + keep_postponed_block: + test [edi+DirectiveBlock.flags],CTRLF_SUSPENDED + jnz keep_suspended_block + mov [edi+DirectiveBlock.type],DBLOCK_POSTPONED + jmp instruction_assembled + keep_suspended_block: + mov [edi+DirectiveBlock.type],DBLOCK_SUSPENDED + jmp instruction_assembled + end_postponed_execution: + test [assembly_mode],AMODE_POSTPONED + jz unexpected_instruction + mov eax,[source_context] + mov esi,eax + call release_source_context + and [esi+SourceContext.number_of_entries],0 + jmp pass_done + +define_struc: + mov bl,SYMCLASS_STRUCTURE + jmp begin_macro_definition +define_macro: + mov bl,SYMCLASS_INSTRUCTION + begin_macro_definition: + test [assembly_mode],AMODE_DEFINITION + jnz nested_macro_definition + mov dl,DBLOCK_MACRO + mov ecx,sizeof.MacroData + call add_directive_block + mov [edi+DirectiveBlock.subtype],bl + mov [edi-sizeof.MacroData+MacroData.nesting_counter],1 + xor eax,eax + mov [macro_end_position],eax + mov [macro_definition_active],al + or [assembly_mode],AMODE_DEFINITION + test [assembly_mode],AMODE_SKIP + jnz assembly_line + xor ecx,ecx + call move_to_next_symbol + jc invalid_macro_definition + cmp al,'(' + je macro_with_label_parameter + read_macro_name: + mov dl,bl + call get_macro_definition_symbol + jc invalid_identifier + mov [argument_start],esi + mov eax,[embedded_context] + mov [macro_parameters_context],eax + xor ecx,ecx + call move_to_next_symbol + jc macro_parameters_correct + check_macro_parameters: + cmp al,'&' + jne macro_parameter_prefix_ok + inc esi + call move_to_next_symbol + jc invalid_macro_definition + macro_parameter_prefix_ok: + cmp al,'#' + jne check_parameter_name + call check_concatenation + jnc check_macro_parameters + invalid_macro_definition: + mov edx,_invalid_argument + call register_error + jmp assembly_line + check_parameter_name: + cmp al,'?' + je parameter_starting_question_mark + cmp al,1Ah + jne invalid_macro_definition + call detect_numeric_symbol + jc invalid_macro_definition + parameter_name_token: + inc esi + lodsd + parameter_name_present: + xor ecx,ecx + call move_to_next_symbol + jc macro_parameters_correct + cmp al,'?' + je check_parameter_name_modifier + cmp al,'#' + jne check_parameter_modifiers + call check_concatenation + jnc check_parameter_name_concatenation + call move_to_next_symbol + jc macro_parameters_correct + jmp check_parameter_modifiers + parameter_starting_question_mark: + inc esi + parameter_name_freeform: + call move_to_next_symbol + jc macro_parameters_correct + cmp al,1Ah + je parameter_name_token + cmp al,'#' + je parameter_name_freeform_concatenation + cmp al,30h + jne invalid_macro_definition + parameter_number_token: + inc esi + lodsd + add esi,eax + jmp parameter_name_present + parameter_name_freeform_concatenation: + call check_concatenation + jc invalid_macro_definition + jmp parameter_name_freeform + check_parameter_name_concatenation: + cmp al,1Ah + je parameter_name_token + cmp al,30h + je parameter_number_token + cmp al,'?' + jne check_parameter_modifiers + check_parameter_name_modifier: + inc esi + call move_to_next_symbol + jc macro_parameters_correct + check_parameter_modifiers: + cmp al,':' + je check_default_value + cmp al,'=' + je check_default_value + cmp al,'*' + jne check_next_parameter + inc esi + call move_to_next_symbol + jnc check_next_parameter + jmp macro_parameters_correct + check_default_value: + mov edi,[expression_workspace.memory_start] + inc esi + call move_to_next_symbol + jc check_plain_default_value + cmp al,'<' + je check_enclosed_default_value + check_plain_default_value: + mov dl,',' + xor dh,dh + mov [breakpoint_token],'&' + call cut_piece_of_line + jmp check_next_parameter + check_enclosed_default_value: + inc esi + mov dl,'>' + mov dh,'<' + mov [breakpoint_token],0 + call cut_piece_of_line + cmp al,'>' + jne invalid_macro_definition + inc esi + call move_to_next_symbol + jc macro_parameters_correct + check_next_parameter: + test al,al + jz macro_parameters_correct + inc esi + cmp al,',' + jne check_final_parameter_modifiers + call move_to_next_symbol + jc invalid_macro_definition + jmp check_macro_parameters + check_final_parameter_modifiers: + cmp al,'&' + jne invalid_macro_definition + call move_to_next_symbol + jnc invalid_macro_definition + macro_parameters_correct: + or [macro_definition_active],1 + cmp [macro_parameters_context],0 + je store_macro_header + xor esi,esi + mov ecx,1+sizeof.RecognitionContext + call append_to_macro + mov al,40h + stosb + mov esi,[macro_parameters_context] + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep movsd + store_macro_header: + mov esi,[argument_start] + mov ecx,[line_end] + sub ecx,esi + call append_to_macro + call add_line_break_to_macro + jmp instruction_assembled + nested_macro_definition: + mov dl,DBLOCK_MACRO + call find_directive_block + ; jc internal_error + cmp bl,[edi+DirectiveBlock.subtype] + jne add_nested_macro_block + inc [edi-sizeof.MacroData+MacroData.nesting_counter] + jmp add_line_to_macro + add_nested_macro_block: + mov ecx,sizeof.MacroData + call add_directive_block + mov [edi+DirectiveBlock.subtype],bl + mov [edi-sizeof.MacroData+MacroData.nesting_counter],1 + jmp add_line_to_macro + macro_with_label_parameter: + cmp bl,SYMCLASS_STRUCTURE + jne invalid_macro_definition + mov [argument_start],esi + inc esi + xor ecx,ecx + call move_to_next_symbol + jc invalid_macro_definition + cmp al,'&' + jne check_label_parameter_initial_concatenation + inc esi + call move_to_next_symbol + jc invalid_macro_definition + check_label_parameter_initial_concatenation: + cmp al,'#' + jne check_label_parameter_name + call check_concatenation + jnc check_label_parameter_initial_concatenation + jmp invalid_macro_definition + check_label_parameter_name: + cmp al,1Ah + jne invalid_macro_definition + call detect_numeric_symbol + jc invalid_macro_definition + label_parameter_name_present: + inc esi + lodsd + xor ecx,ecx + call move_to_next_symbol + jc invalid_macro_definition + cmp al,'?' + je check_label_parameter_name_modifier + cmp al,'#' + jne label_parameter_name_end + call check_concatenation + jnc check_label_parameter_name_concatenation + call move_to_next_symbol + jc invalid_macro_definition + jmp label_parameter_name_end + check_label_parameter_name_concatenation: + cmp al,1Ah + je label_parameter_name_present + cmp al,'?' + jne label_parameter_name_end + check_label_parameter_name_modifier: + inc esi + call move_to_next_symbol + jc invalid_macro_definition + label_parameter_name_end: + inc esi + cmp al,')' + jne invalid_macro_definition + push esi + or [macro_definition_active],1 + mov ecx,esi + mov esi,[argument_start] + sub ecx,esi + call append_to_macro + and [macro_definition_active],0 + pop esi + xor ecx,ecx + call move_to_next_symbol + jc invalid_macro_definition + jmp read_macro_name + +end_struc: + mov bl,SYMCLASS_STRUCTURE + jmp close_macro_block +end_macro: + mov bl,SYMCLASS_INSTRUCTION + close_macro_block: + mov dl,DBLOCK_MACRO + call find_directive_block + jc unexpected_instruction + cmp bl,[edi+DirectiveBlock.subtype] + je close_macro_definition + ; handle improper nesting, for partial backward-compatibility: + cmp bl,SYMCLASS_INSTRUCTION + jne add_line_to_macro + call close_directive_block + mov dl,DBLOCK_MACRO + call find_directive_block + jc unexpected_instruction + ; cmp [edi+DirectiveBlock.subtype],SYMCLASS_INSTRUCTION + ; jne internal_error + close_macro_definition: + dec [edi-sizeof.MacroData+MacroData.nesting_counter] + jnz add_line_to_macro + mov al,[assembly_mode] + and al,not (AMODE_SKIP or AMODE_DEFINITION) + or al,[edi+DirectiveBlock.prior_assembly_mode] + mov [assembly_mode],al + call close_directive_block + mov al,[assembly_mode] + test al,AMODE_DEFINITION + jne add_line_to_macro + test al,AMODE_SKIP + jnz assembly_line + push esi + cmp [macro_definition_active],0 + je macro_definition_done + mov ebx,[macro_leaf] + call create_value_definition + test edx,edx + jz macro_definition_done + mov [value],eax + mov [value_length],ecx + mov esi,[macro_buffer] + mov ecx,[macro_end_position] + mov [value_type],VALTYPE_SYMBOLIC + call assign_value + mov al,[macro_flags] + or [edx+ValueDefinition.flags],al + macro_definition_done: + pop esi + jmp instruction_assembled + +escape_directive: + mov dl,DBLOCK_MACRO + call find_directive_block + jc unexpected_instruction + cmp [edi-sizeof.MacroData+MacroData.nesting_counter],1 + ja add_line_to_macro + test [edi+DirectiveBlock.prior_assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + cmp [embedded_context],0 + je escape_context_ok + push esi + xor esi,esi + mov ecx,1+sizeof.RecognitionContext + call append_to_macro + mov al,40h + stosb + mov esi,[embedded_context] + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep movsd + pop esi + escape_context_ok: + mov ecx,[line_end] + sub ecx,esi + call append_to_macro + call add_line_break_to_macro + jmp assembly_line +add_line_to_macro: + mov esi,[line_start] + mov ecx,[line_end] + sub ecx,esi + call append_to_macro + call add_line_break_to_macro + jmp assembly_line + append_to_macro: + cmp [macro_definition_active],0 + je macro_appended + mov edi,[macro_buffer] + mov eax,[macro_end_position] + add edi,eax + add eax,ecx + mov [macro_end_position],eax + cmp eax,[macro_buffer_length] + jbe macro_block_ready + push ecx + mov ecx,eax + mov eax,[macro_buffer] + sub edi,eax + call realloc + add edi,eax + mov [macro_buffer],eax + mov [macro_buffer_length],ecx + pop ecx + macro_block_ready: + test esi,esi + jz macro_appended + rep movsb + macro_appended: + retn +add_label_to_macro: + mov ecx,esi + xchg esi,[line_start] + sub ecx,esi + call append_to_macro + mov esi,[line_start] + cmp esi,[line_end] + jne assemble_instruction + call add_line_break_to_macro + jmp assemble_instruction +add_line_break_to_macro: + mov eax,[macro_buffer] + mov ecx,[macro_end_position] + cmp ecx,[macro_buffer_length] + jb macro_line_break + add ecx,100h + call realloc + mov [macro_buffer],eax + mov [macro_buffer_length],ecx + mov ecx,[macro_end_position] + macro_line_break: + lea edi,[eax+ecx] + xor al,al + stosb + inc [macro_end_position] + retn + +use_macro: + and [label_branch],0 +use_struc: + mov eax,[current_pass] + mov [ebx+SymbolTree_Leaf.last_use_pass],eax + mov [instruction_value],edx + mov eax,[ebx+SymbolTree_Leaf.branch] + mov [instruction_branch],eax + xor ecx,ecx + call embed_symbolic_value + measure_macro_header: + lodsb + test al,al + jz macro_header_measured + cmp al,1Ah + je measure_token_with_data + cmp al,22h + je measure_token_with_data + cmp al,27h + je measure_token_with_data + cmp al,30h + je measure_internal_token + cmp al,40h + jne measure_macro_header + add esi,sizeof.RecognitionContext + jmp measure_macro_header + measure_token_with_data: + add esi,4 + jmp measure_macro_header + measure_internal_token: + lodsd + add esi,eax + jmp measure_macro_header + macro_header_measured: + mov [instruction_body],esi + dec esi + mov [line_end],esi + mov eax,ebx + mov ecx,[parameter_namespace] + call get_local_anchor + call get_local_namespace + mov [new_local_namespace],ebx + mov eax,[parameter_namespace] + mov [ebx+SymbolTree_Root.chain],eax + mov edx,[instruction_value] + local_namespace_ready: + mov esi,[edx+ValueDefinition.value] + or [symbol_definition],1 + mov ebx,[new_local_namespace] + mov eax,[label_branch] + mov [ebx+SymbolTree_Root.current_label],eax + cmp [label_independent],0 + je struc_label_ok + or [ebx+SymbolTree_Root.flags],NAMESPACE_LABEL_FORWARDING + struc_label_ok: + cmp byte [esi],'(' + jne prepare_macro_parameters + inc esi + call move_to_next_symbol + jc invalid_argument + test [assembly_mode],AMODE_DEFINITION + setnz dl + cmp al,'&' + sete al + jne struc_label_prefix_ok + inc esi + struc_label_prefix_ok: + or al,dl + mov [contextless_processing],al + mov ebx,[new_local_namespace] + mov dl,SYMCLASS_PARAMETER + call identify_symbol_in_namespace + jc invalid_argument + test ebx,ebx + jz invalid_argument + cmp edi,[new_local_namespace] + jne invalid_argument + push esi + push [line_end] + push [embedded_context] + mov eax,[line_context] + mov [embedded_context],eax + mov esi,[line_start] + mov ecx,[label_instruction_start] + mov [line_end],ecx + sub ecx,esi + add ecx,(1+sizeof.RecognitionContext)*2 + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + call reserve_workspace + xor edx,edx + mov [breakpoint_token],dl + call extract_piece_of_line + call finish_extracted_parameter + pop [embedded_context] + pop [line_end] + or [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + call update_value_definition + mov [value_type],VALTYPE_SYMBOLIC + mov esi,[assembly_workspace.memory_start] + mov ecx,edi + sub ecx,esi + call assign_value + pop esi + call move_to_next_symbol + jc invalid_argument + cmp al,')' + jne invalid_argument + inc esi + prepare_macro_parameters: + mov edi,[expression_workspace.memory_start] + add edi,sizeof.LineExcerpt + xor eax,eax + mov [macro_greedy],al + mov [number_of_parameters],eax + macro_parameter_declaration: + call move_to_next_symbol + jc macro_parameters_declared + cmp al,'&' + sete al + mov [contextless_processing],al + jne identify_macro_parameter_name + inc esi + identify_macro_parameter_name: + mov ebx,[new_local_namespace] + mov dl,SYMCLASS_PARAMETER + push edi + call identify_symbol_in_namespace + mov eax,edi + pop edi + jc macro_parameters_declared + test ebx,ebx + jz invalid_argument + cmp eax,[new_local_namespace] + jne invalid_argument + mov eax,[number_of_parameters] + shl eax,3 + add eax,[assembly_stack_base] + lea ecx,[eax+8] + cmp ecx,[assembly_stack_end] + jbe store_macro_parameter_leaf + mov eax,[assembly_stack_base] + sub ecx,eax + call grow_stack + mov [assembly_stack_base],eax + add ecx,eax + mov [assembly_stack_end],ecx + mov ecx,[number_of_parameters] + shl ecx,3 + add eax,ecx + store_macro_parameter_leaf: + mov [eax],ebx + mov cl,[contextless_processing] + mov [eax+4],cl + mov edx,expression_workspace + mov ecx,sizeof.LineExcerpt + call reserve_workspace + mov [edi+LineExcerpt.data_start],esi + mov [edi+LineExcerpt.data_end],esi + inc [number_of_parameters] + call move_to_next_symbol + jc macro_parameters_declared + cmp al,':' + je macro_parameter_with_default_value + cmp al,'=' + je macro_parameter_with_default_value + cmp al,'*' + jne next_parameter_declaration + and [edi+LineExcerpt.data_start],0 + inc esi + call move_to_next_symbol + jnc next_parameter_declaration + xor al,al + jmp next_parameter_declaration + macro_parameter_with_default_value: + inc esi + call move_to_next_symbol + jc get_plain_default_value + cmp al,'<' + je get_enclosed_default_value + get_plain_default_value: + mov dl,',' + xor dh,dh + mov [breakpoint_token],'&' + call cut_piece_of_line + jmp next_parameter_declaration + get_enclosed_default_value: + inc esi + mov dl,'>' + mov dh,'<' + mov [breakpoint_token],0 + call cut_piece_of_line + cmp al,'>' + jne invalid_argument + inc esi + call move_to_next_symbol + jc macro_parameters_declared + next_parameter_declaration: + test al,al + jz macro_parameters_declared + inc esi + add edi,sizeof.LineExcerpt + cmp al,',' + je macro_parameter_declaration + cmp al,'&' + jne invalid_argument + or [macro_greedy],1 + call move_to_next_symbol + jnc invalid_argument + macro_parameters_declared: + call warp_to_next_symbol + ; cmp [number_of_line_embeddings],0 + ; jne internal_error + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + mov ecx,[line_end] + sub ecx,esi + add ecx,(1+sizeof.RecognitionContext)*2 + call reserve_workspace + xor eax,eax + mov [breakpoint_token],al + mov [parameter_index],eax + macro_parameter_definition: + mov eax,[number_of_parameters] + sub eax,[parameter_index] + jz macro_parameters_ready + jmp get_macro_parameter + macro_parameter_after_comma: + mov eax,[number_of_parameters] + sub eax,[parameter_index] + jz macro_parameters_ready + inc esi + get_macro_parameter: + mov edi,[assembly_workspace.memory_start] + mov ecx,[parameter_index] + shl ecx,3 + add ecx,[assembly_stack_base] + mov ebx,[ecx] + test [assembly_mode],AMODE_DEFINITION + setnz dl + or dl,[ecx+4] + mov [contextless_processing],dl + cmp [macro_greedy],0 + je standard_parameter_value + cmp eax,1 + ja standard_parameter_value + xor edx,edx + call extract_piece_of_line + jmp parameter_value_ready + standard_parameter_value: + call extract_argument_value + parameter_value_ready: + or [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + call update_value_definition + mov [value_type],VALTYPE_SYMBOLIC + cmp edi,[assembly_workspace.memory_start] + je empty_parameter_value + call finish_extracted_parameter + push esi + mov esi,[assembly_workspace.memory_start] + mov ecx,edi + sub ecx,esi + assign_parameter_value: + call assign_value + pop esi + parameter_value_assigned: + inc [parameter_index] + call move_to_next_symbol + jc macro_parameter_definition + cmp al,',' + je macro_parameter_after_comma + macro_parameters_ready: + mov edx,[instruction_value] + mov ecx,[instruction_body] + sub ecx,[edx+ValueDefinition.value] + push ecx + call create_source_entry + pop eax + jc stack_limit_exceeded + mov [ebx+SourceEntry.type],SOURCE_MACRO + mov [ebx+SourceEntry.text],edx + mov [ebx+SourceEntry.offset],eax + or [edx+ValueDefinition.flags],VAL_IN_USE + inc [edx+ValueDefinition.reference_count] + mov eax,[new_local_namespace] + mov [local_namespace],eax + and [eax+SymbolTree_Root.parameters],0 + mov [ebx+SourceEntry.local_namespace],eax + mov ecx,[instruction_branch] + test ecx,ecx + jz instruction_assembled + mov [ebx+SourceEntry.name],ecx + or [ebx+SourceEntry.name_length],-1 + jmp instruction_assembled + stack_limit_exceeded: + mov edx,_stack_limit_exceeded + call register_error + test [assembly_mode],AMODE_SKIP + jnz assembly_line + test [assembly_mode],AMODE_DEFINITION + jz assembly_line + jmp add_line_to_macro + empty_parameter_value: + mov edi,[parameter_index] + inc edi + assert sizeof.LineExcerpt = 1 shl 4 + shl edi,4 + add edi,[expression_workspace.memory_start] + mov eax,[edi+LineExcerpt.data_start] + test eax,eax + jz missing_argument + mov ecx,[edi+LineExcerpt.data_end] + sub ecx,eax + push esi + mov esi,eax + test ecx,ecx + jz assign_parameter_value + push ebx edx + mov ebx,edi + mov edi,[assembly_workspace.memory_start] + add ecx,2*(1+sizeof.RecognitionContext) + mov edx,assembly_workspace + call reserve_workspace + mov al,40h + cmp [ebx+LineExcerpt.recognition_context],0 + je parameter_with_current_context + stosb + mov eax,esi + mov esi,[ebx+LineExcerpt.recognition_context] + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep movsd + mov [context_boundary],edi + mov esi,eax + jmp copy_parameter_contents + parameter_with_current_context: + cmp [contextless_processing],0 + jne copy_parameter_contents + stosb + call store_current_context + copy_parameter_contents: + call store_token + cmp esi,[ebx+LineExcerpt.data_end] + jne copy_parameter_contents + call store_context_reset_token + pop edx ebx + mov esi,[assembly_workspace.memory_start] + mov ecx,edi + sub ecx,esi + jmp assign_parameter_value + finish_extracted_parameter: + test [assembly_mode],AMODE_DEFINITION + jz store_context_reset_token + cmp [embedded_context],0 + jne store_context_reset_token + retn + store_context_reset_token: + cmp edi,[context_boundary] + je context_reset_in_reused_token + mov al,40h + stosb + store_context_reset: + xor eax,eax + assert sizeof.RecognitionContext and 11b = 0 + mov ecx,sizeof.RecognitionContext shr 2 + rep stosd + retn + context_reset_in_reused_token: + sub edi,sizeof.RecognitionContext + jmp store_context_reset + +local_directive: + test [assembly_mode],AMODE_SKIP + jnz assembly_line + test [assembly_mode],AMODE_DEFINITION + jnz add_line_to_macro + mov ebx,[local_namespace] + test ebx,ebx + jz unexpected_instruction + or [symbol_definition],1 + mov dl,SYMCLASS_PARAMETER + call identify_symbol_in_namespace + jc missing_argument + test ebx,ebx + jz invalid_argument + cmp edi,[local_namespace] + jne invalid_argument + or [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + call update_value_definition + mov eax,[current_pass] + mov [edx+ValueDefinition.pass],eax + mov [edx+ValueDefinition.type],VALTYPE_NATIVE_COMMAND + mov eax,local_symbol_name + xchg eax,[edx+ValueDefinition.value] + cmp [edx+ValueDefinition.block_length],0 + je next_local_declaration + and [edx+ValueDefinition.block_length],0 + call mfree + next_local_declaration: + call move_to_next_symbol + jc assembly_line + cmp al,',' + jne invalid_argument + inc esi + jmp local_directive +outscope_directive: + test [assembly_mode],AMODE_SKIP + jnz assemble_prefixed_instruction + mov ebx,[source_context] + mov eax,[ebx+SourceContext.number_of_entries] + dec eax + imul eax,sizeof.SourceEntry + lea ebx,[ebx+sizeof.SourceContext+eax] + test [assembly_mode],AMODE_DEFINITION + jnz define_outscope + mov ecx,[ebx+SourceEntry.local_namespace] + test [ecx+SymbolTree_Root.flags],NAMESPACE_UNATTACHED + jnz unexpected_instruction + mov eax,[ecx+SymbolTree_Root.chain] + test eax,eax + jz unexpected_instruction + outscope_namespace_ok: + mov [parameter_namespace],eax + test [eax+SymbolTree_Root.flags],NAMESPACE_UNATTACHED + jz outscope_local_namespace_ok + xor eax,eax + outscope_local_namespace_ok: + mov [local_namespace],eax + assemble_prefixed_instruction: + mov [line_start],esi + mov eax,[embedded_context] + mov [line_context],eax + jmp assemble_instruction + define_outscope: + cmp [ebx+SourceEntry.type],SOURCE_MACRO + je assemble_prefixed_instruction + jmp ignored_directive + +define_data: + and [label_leaf],0 +define_labeled_data: + movzx eax,[edx+ValueDefinition.attribute] + mov [data_unit_length],eax + test eax,eax + jnz data_unit_length_ok + call get_numeric_constant_value + test edx,edx + jz invalid_argument + mov ecx,4 + mov edi,data_unit_length + call fit_value + jc value_out_of_range + js value_out_of_range + cmp [data_unit_length],0 + je value_out_of_range + call get_constituent_value + jc missing_argument + cmp al,':' + je data_unit_length_ok + cmp al,',' + jne invalid_argument + data_unit_length_ok: + cmp [label_leaf],0 + je data_definition + call define_data_label + data_definition: + call peek_at_constituent_value + jc missing_argument + cmp al,'?' + je single_uninitialized_unit + call get_constant_value + cmp al,30h + je numeric_data + cmp al,2Eh + je float_data + cmp al,22h + jne invalid_argument + call output_string + data_outputted: + call get_constituent_value + jc instruction_assembled + cmp al,',' + jne invalid_argument + jmp data_definition + float_data: + push esi + push edx + mov ecx,[data_unit_length] + call initialize_output + pop esi + mov ecx,[data_unit_length] + call fit_float + pop esi + jmp data_outputted + numeric_data: + call keep_value + call peek_at_constituent_value + jc single_data_unit + cmp al,1Ah + jne single_data_unit + test edx,edx + jz single_data_unit + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_PREPOSITION + jne single_data_unit + cmp [edx+ValueDefinition.value],PREPOSITION_DUP + je duplication_operator + single_data_unit: + mov ecx,[data_unit_length] + call initialize_output + call get_kept_value + mov ecx,[data_unit_length] + call fit_value + jc value_out_of_range + jmp data_outputted + single_uninitialized_unit: + and [current_constituent],0 + mov ecx,[data_unit_length] + call uninitialized_output + jmp data_outputted + duplication_operator: + call get_kept_value + mov edi,number_of_iterations + mov ecx,4 + call fit_value + jc value_out_of_range + js value_out_of_range + xor eax,eax + mov [current_constituent],al + mov [initial_parentheses],eax + call peek_at_constituent_value + jc invalid_argument + cmp al,'?' + je reserve_through_duplication + mov edi,[expression_workspace.memory_start] + mov [expression_sequence_end],edi + or [leave_opening_parentheses],1 + parse_duplicated_expression: + call parse_expression + add [initial_parentheses],ecx + jecxz duplicated_value_parsed + mov eax,[expression_workspace.memory_start] + mov eax,[eax] + test eax,eax + jnz duplicated_value_parsed + call get_constituent_value + jc invalid_argument + cmp al,'?' + jne invalid_argument + mov edi,[expression_workspace.memory_start] + or eax,-1 + stosd + duplicated_value_parsed: + mov [expression_sequence_end],edi + and [leave_opening_parentheses],0 + cmp [initial_parentheses],1 + jb duplicated_data_parsed + ja invalid_argument + call get_constituent_value + jc missing_closing_parenthesis + cmp al,')' + je duplicated_data_parsed + cmp al,',' + jne invalid_argument + mov edi,[expression_sequence_end] + call peek_at_constituent_value + jc invalid_argument + mov edi,[expression_sequence_end] + cmp al,'?' + jne parse_duplicated_expression + and [current_constituent],0 + mov ecx,4 + mov edx,expression_workspace + call reserve_workspace + or eax,-1 + stosd + jmp duplicated_value_parsed + duplicated_data_parsed: + cmp [number_of_iterations],0 + je data_outputted + duplicated_data: + mov eax,[expression_workspace.memory_start] + mov [expression_sequence_cursor],eax + generate_duplicate: + mov eax,[expression_sequence_cursor] + cmp eax,[expression_sequence_end] + je duplicate_outputted + cmp dword [eax],-1 + je duplicated_uninitialized_unit + push esi + mov esi,eax + mov edi,[calculation_workspace.memory_start] + call calculate_parsed_expression + mov [expression_sequence_cursor],esi + pop esi + jc duplicate_outputted + call pop_terms + jc invalid_argument + call get_calculated_constant_value + cmp al,30h + je duplicated_data_unit + cmp al,2Eh + je duplicated_data_unit + cmp al,22h + jne invalid_argument + call output_string + jmp generate_duplicate + duplicated_data_unit: + push eax edx + mov ecx,[data_unit_length] + call initialize_output + pop edx eax + mov ecx,[data_unit_length] + cmp al,2Eh + je duplicated_float + call fit_value + jc value_out_of_range + jmp generate_duplicate + duplicated_float: + push esi + mov esi,edx + call fit_float + pop esi + jmp generate_duplicate + duplicated_uninitialized_unit: + add eax,4 + mov [expression_sequence_cursor],eax + mov ecx,[data_unit_length] + call uninitialized_output + jmp generate_duplicate + duplicate_outputted: + dec [number_of_iterations] + jnz duplicated_data + jmp data_outputted + reserve_through_duplication: + and [current_constituent],0 + mov eax,[number_of_iterations] + mul [data_unit_length] + test edx,edx + jnz duplication_overflow + mov ecx,eax + call uninitialized_output + jmp data_outputted + duplication_overflow: + mov edx,_area_overflow + call register_error + jmp data_outputted + output_string: + push esi + mov esi,edx + mov ecx,[esi] + call initialize_output + lodsd + mov ecx,eax + rep movsb + pop esi + mov ecx,[data_unit_length] + xor edx,edx + div ecx + test edx,edx + jz string_outputted + sub ecx,edx + push ecx + call initialize_output + pop ecx + xor al,al + rep stosb + string_outputted: + retn + define_data_label: + push esi + call get_current_address_value + lea edi,[esi+ecx] + mov ecx,4+4+4 + mov edx,assembly_workspace + call reserve_workspace + mov edx,[data_unit_length] + bsr eax,edx + inc al + shr al,3 + inc al + stosd + mov [edi],edx + add edi,eax + xor eax,eax + stosd + mov ebx,[label_leaf] + call create_constant_value_definition + test edx,edx + jz data_label_defined + mov ecx,edi + sub ecx,esi + call assign_shiftable_value + data_label_defined: + call update_current_label + pop esi + retn + +reserve_labeled_data: + movzx eax,[edx+ValueDefinition.attribute] + mov [data_unit_length],eax + call define_data_label + jmp data_reservation +reserve_data: + movzx eax,[edx+ValueDefinition.attribute] + mov [data_unit_length],eax + data_reservation: + call get_numeric_constant_value + test edx,edx + jz invalid_argument + mov ecx,4 + mov edi,[assembly_workspace.memory_start] + call fit_value + jc reservation_out_of_range + js reservation_out_of_range + mov eax,[edi] + mul [data_unit_length] + test edx,edx + jnz reservation_overflow + mov ecx,eax + call uninitialized_output + jmp instruction_assembled + reservation_out_of_range: + mov edx,_value_out_of_range + call register_error + jmp instruction_assembled + reservation_overflow: + mov edx,_area_overflow + call register_error + jmp instruction_assembled + +include_labeled_data: + mov [data_unit_length],1 + call define_data_label +include_data: + xor eax,eax + mov [data_offset],eax + mov [data_offset+4],eax + call get_constant_value + cmp al,22h + jne invalid_argument + push esi + call prepare_file_path + pop esi + call get_constituent_value + jc include_all_available_data + cmp al,':' + jne get_data_length + call get_numeric_constant_value + test edx,edx + jz invalid_argument + mov edi,file_offset + mov ecx,8 + call fit_value + jc value_out_of_range + js value_out_of_range + call get_constituent_value + jc include_all_available_data + get_data_length: + cmp al,',' + jne invalid_argument + call get_numeric_constant_value + test edx,edx + jz invalid_argument + mov edi,data_length + mov ecx,4 + call fit_value + jc value_out_of_range + js value_out_of_range + push esi + mov ecx,[data_length] + call initialize_output + mov esi,[assembly_workspace.memory_start] + call get_file_data + test ebx,ebx + jnz read_from_file + mov esi,[local_path] + call get_file_data + test ebx,ebx + jz data_file_not_found + read_from_file: + call read_file_data + jc file_data_not_read + pop esi + jmp instruction_assembled + data_file_not_found: + mov ebx,esi + mov edx,_source_file_not_found + call register_error + pop esi + jmp instruction_assembled + include_all_available_data: + push esi + mov esi,[assembly_workspace.memory_start] + call get_file_data + test ebx,ebx + jnz measure_available_data + mov esi,[local_path] + call get_file_data + test ebx,ebx + jz data_file_not_found + measure_available_data: + mov ecx,dword [ebx+FileData.length] + mov edx,dword [ebx+FileData.length+4] + sub ecx,dword [file_offset] + sbb edx,dword [file_offset+4] + jc file_data_not_read + jnz out_of_memory + mov [data_length],ecx + push ebx + call initialize_output + pop ebx + call read_file_data + jc file_data_not_read + pop esi + jmp instruction_assembled + file_data_not_read: + mov ebx,esi + mov edx,_error_reading_file + call register_error + pop esi + jmp instruction_assembled + +load_value: + or [symbol_definition],1 + mov dl,SYMCLASS_EXPRESSION + call identify_symbol + jc missing_argument + test ebx,ebx + jz invalid_identifier + mov [label_leaf],ebx + mov [size_specified],0 + call peek_at_constituent_value + jc load_syntax_error + cmp al,':' + je size_after_separator + cmp al,1Ah + jne get_load_size + test edx,edx + jz get_load_size + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_PREPOSITION + jne get_load_size + cmp [edx+ValueDefinition.value],PREPOSITION_FROM + jne load_syntax_error + and [current_constituent],0 + jmp get_source_address + size_after_separator: + and [current_constituent],0 + get_load_size: + call get_numeric_constant_value + test edx,edx + jz load_syntax_error + or [size_specified],1 + mov edi,value_length + mov ecx,4 + call fit_value + jc value_out_of_range + js value_out_of_range + call get_constituent_value + jc load_syntax_error + cmp al,1Ah + jne load_syntax_error + test edx,edx + jz load_syntax_error + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_PREPOSITION + jne load_syntax_error + cmp [edx+ValueDefinition.value],PREPOSITION_FROM + jne load_syntax_error + get_source_address: + call peek_at_constituent_value + jc invalid_argument + cmp al,':' + je load_from_output_offset + mov eax,[current_area] + mov [data_area],eax + and [data_area_symbol],0 + and [leave_opening_parentheses],0 + mov edi,[expression_workspace.memory_start] + call parse_expression + call peek_at_constituent_value + jc source_address_parsed + cmp al,':' + jne source_address_parsed + and [current_constituent],0 + mov edi,[expression_workspace.memory_start] + call get_area_value + jc invalid_area + mov [data_area],edx + mov [data_area_symbol],ebx + mov edi,[expression_workspace.memory_start] + call parse_expression + source_address_parsed: + call calculate_relative_address + jc invalid_argument + mov edi,data_offset + mov ecx,4 + call fit_value + jc data_out_of_area + js data_out_of_area + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + mov eax,[value_length] + stosd + mov ecx,eax + call reserve_workspace + mov edx,[data_area] + call load_from_area + jc loaded_no_value + value_loaded: + mov ebx,[label_leaf] + call update_value_definition + test edx,edx + jz instruction_assembled + push esi + mov esi,[assembly_workspace.memory_start] + mov ecx,[esi] + add ecx,4 + mov [value_type],VALTYPE_STRING + call assign_value + pop esi + jmp instruction_assembled + load_syntax_error: + mov edx,_invalid_argument + jmp error_while_loading + data_out_of_area: + mov edx,_address_out_of_range + error_while_loading: + call register_error + loaded_no_value: + mov edi,[assembly_workspace.memory_start] + xor eax,eax + stosd + jmp value_loaded + calculate_relative_address: + push esi + mov esi,[expression_workspace.memory_start] + mov edi,[calculation_workspace.memory_start] + call calculate_parsed_expression + jc invalid_relative_address + mov ebx,edi + mov edi,[expression_workspace.memory_start] + mov esi,edi + mov eax,EXPR_SYMBOL_VALUE + stosd + mov edx,[data_area] + mov eax,[data_area_symbol] + test eax,eax + jnz data_area_symbol_ok + mov eax,[void_symbol] + mov [eax+SymbolTree_Leaf.definition],edx + data_area_symbol_ok: + stosd + mov eax,edx + stosd + mov eax,EXPR_OPERATOR + stosd + mov eax,extract_first_term_metadata + stosd + mov eax,EXPR_OPERATOR + stosd + mov eax,calculate_sub + stosd + xor eax,eax + stosd + mov edi,ebx + call calculate_parsed_expression + jc invalid_relative_address + call pop_terms + jc invalid_relative_address + cmp [size_specified],0 + jne addressed_length_ok + and [value_length],0 + mov edx,[edi+ExpressionTerm.metadata] + test edx,edx + jz addressed_length_ok + cmp dword [edx],0 + jne addressed_length_ok + add edx,4 + mov esi,edi + mov ecx,4 + mov edi,value_length + call fit_value + jc invalid_relative_address + js invalid_relative_address + mov ecx,[edx] + cmp dword [edx+4+ecx],0 + jne invalid_relative_address + mov edi,esi + addressed_length_ok: + pop esi + mov eax,edi + check_for_uncanceled_terms: + add eax,sizeof.ExpressionTerm + cmp [eax+ExpressionTerm.attributes],0 + je relative_address_ok + cmp [eax+ExpressionTerm.metadata],0 + je check_for_uncanceled_terms + mov edx,_address_out_of_range + call register_error + relative_address_ok: + call get_term_value + clc + retn + invalid_relative_address: + pop esi + stc + retn + load_from_output_offset: + call read_output_offset + jc value_out_of_range + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + mov eax,[value_length] + stosd + mov ecx,eax + call reserve_workspace + push esi + call read_from_output + pop esi + cmp [value_length],0 + jne data_out_of_area + jmp value_loaded + read_output_offset: + and [current_constituent],0 + call get_numeric_constant_value + test edx,edx + jz output_offset_out_of_range + push edi + mov edi,file_offset + mov ecx,8 + call fit_value + pop edi + jc output_offset_out_of_range + js output_offset_out_of_range + cmp [size_specified],0 + jne output_offset_ok + and [value_length],0 + mov edx,[edi+ExpressionTerm.metadata] + test edx,edx + jz output_offset_ok + cmp dword [edx],0 + jne output_offset_ok + add edx,4 + mov ecx,4 + mov edi,value_length + call fit_value + jc output_offset_out_of_range + js output_offset_out_of_range + output_offset_ok: + clc + retn + output_offset_out_of_range: + stc + retn + +store_value: + mov [size_specified],0 + call get_constant_value + cmp al,22h + je store_string_value + cmp al,30h + jne invalid_argument + call keep_value + call peek_at_constituent_value + jc invalid_argument + cmp al,':' + je size_after_value + cmp al,1Ah + jne size_before_value + test edx,edx + jz invalid_argument + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_PREPOSITION + je get_destination_address + size_before_value: + or [size_specified],1 + call get_kept_value + mov edi,value_length + mov ecx,4 + call fit_value + jc value_out_of_range + js value_out_of_range + call get_constant_value + cmp al,22h + je value_after_size_ok + cmp al,30h + jne invalid_argument + value_after_size_ok: + call keep_value + jmp value_with_size_ready + store_string_value: + mov eax,[edx] + mov [value_length],eax + call keep_value + call peek_at_constituent_value + jc invalid_argument + cmp al,':' + jne check_symbol_after_value_with_size + size_after_value: + and [current_constituent],0 + call get_constant_value + cmp al,30h + jne invalid_argument + or [size_specified],1 + mov edi,value_length + mov ecx,4 + call fit_value + jc value_out_of_range + js value_out_of_range + value_with_size_ready: + call peek_at_constituent_value + jc invalid_argument + check_symbol_after_value_with_size: + cmp al,1Ah + jne invalid_argument + test edx,edx + jz invalid_argument + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_PREPOSITION + jne invalid_argument + get_destination_address: + cmp [edx+ValueDefinition.value],PREPOSITION_AT + jne invalid_argument + and [current_constituent],0 + call peek_at_constituent_value + jc invalid_argument + cmp al,':' + je store_at_output_offset + mov eax,[current_area] + mov [data_area],eax + and [data_area_symbol],0 + and [leave_opening_parentheses],0 + mov edi,[expression_workspace.memory_start] + call parse_expression + call peek_at_constituent_value + jc destination_address_parsed + cmp al,':' + jne destination_address_parsed + and [current_constituent],0 + mov edi,[expression_workspace.memory_start] + call get_area_value + jc invalid_area + mov ecx,[current_pass] + cmp [edx+ValueDefinition.pass],ecx + jne invalid_area + mov [data_area],edx + mov [data_area_symbol],ebx + mov edi,[expression_workspace.memory_start] + call parse_expression + destination_address_parsed: + call calculate_relative_address + jc invalid_argument + mov edi,data_offset + mov ecx,4 + call fit_value + jc store_out_of_area + js store_out_of_area + call prepare_area_to_write + call get_kept_value + call fit_value + jc value_out_of_range + jmp instruction_assembled + store_out_of_area: + mov edx,_address_out_of_range + call register_error + jmp instruction_assembled + store_at_output_offset: + call read_output_offset + jc value_out_of_range + mov ecx,[value_length] + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + call reserve_workspace + call get_kept_value + mov ecx,[value_length] + call fit_value + jc value_out_of_range + push esi + mov esi,[assembly_workspace.memory_start] + call rewrite_output + pop esi + cmp [value_length],0 + jne store_out_of_area + jmp instruction_assembled + +display_data: + call get_constant_value + cmp al,30h + je display_character_data + cmp al,22h + jne invalid_argument + call display_string_data + display_next_value: + call get_constituent_value + jc assembly_line + cmp al,',' + jne invalid_argument + jmp display_data + display_character_data: + call display_single_byte_data + jmp display_next_value + +format_directive: + mov edx,[ebx+SymbolTree_Leaf.branch] + call get_symbol_namespace + and [symbol_definition],0 + mov dl,SYMCLASS_INSTRUCTION + call identify_symbol_in_namespace + jc invalid_argument + test ebx,ebx + jz invalid_argument + mov al,[ebx+SymbolTree_Leaf.class] + cmp al,SYMCLASS_INSTRUCTION + jne invalid_argument + call get_available_value + jc invalid_argument + jmp prefixed_directive +format_binary: + call get_constituent_value + jc instruction_assembled + cmp al,1Ah + jne invalid_argument + test edx,edx + jz invalid_argument + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_PREPOSITION + jne invalid_argument + cmp [edx+ValueDefinition.value],PREPOSITION_AS + jne invalid_argument + cmp [output_extension],0 + jne repeated_declaration + call get_constant_value + cmp al,22h + jne invalid_argument + mov edi,esi + mov ecx,[edx] + lea esi,[edx+4] + mov [output_extension_length],ecx + mov ebx,[auxiliary_output_areas] + call get_from_map + jnc extension_stored + xor eax,eax + mov ecx,[output_extension_length] + call put_into_map + extension_stored: + mov [output_extension],esi + validate_extension: + mov ebx,characters + scan_extension: + test ecx,ecx + jz extension_valid + lodsb + xlatb + test al,al + jz invalid_argument + dec ecx + jmp scan_extension + extension_valid: + mov esi,edi + jmp instruction_assembled + +custom_error: + mov edi,[assembly_workspace.memory_start] + add edi,4 + create_custom_error_message: + push edi + call get_constant_value + pop edi + cmp al,30h + je attach_byte_to_error_message + cmp al,22h + jne invalid_argument + mov ebx,edx + mov ecx,[edx] + mov edx,assembly_workspace + call reserve_workspace + mov edx,esi + lea esi,[ebx+4] + mov ecx,[ebx] + rep movsb + mov esi,edx + jmp collect_next_part_of_message + attach_byte_to_error_message: + mov ebx,edx + mov ecx,1 + mov edx,assembly_workspace + call reserve_workspace + mov edx,ebx + mov ecx,1 + call fit_value + jc value_out_of_range + inc edi + collect_next_part_of_message: + push edi + call get_constituent_value + pop edi + jc custom_error_message_ready + cmp al,',' + jne invalid_argument + jmp create_custom_error_message + custom_error_message_ready: + mov edx,[assembly_workspace.memory_start] + sub edi,edx + sub edi,4 + mov [edx],edi + call register_volatile_error + test edx,edx + jz instruction_assembled + or [edx+Error.flags],ERR_CUSTOM + jmp instruction_assembled + +choose_to_remove_comments: + and [preprocessing_mode],not PMODE_RETAIN_COMMENTS + jmp instruction_assembled +choose_to_retain_comments: + or [preprocessing_mode],PMODE_RETAIN_COMMENTS + jmp instruction_assembled +choose_to_combine_lines: + and [preprocessing_mode],not PMODE_ISOLATE_LINES + jmp instruction_assembled +choose_to_isolate_lines: + or [preprocessing_mode],PMODE_ISOLATE_LINES + jmp instruction_assembled + +missing_argument: + mov edx,_missing_argument + call register_error + jmp assembly_line + +invalid_argument: + mov edx,_invalid_argument + call register_error + jmp assembly_line + +invalid_identifier: + mov edx,_invalid_identifier + call register_error + jmp assembly_line + +value_out_of_range: + mov edx,_value_out_of_range + call register_error + jmp assembly_line + +missing_closing_parenthesis: + mov edx,_missing_closing_parenthesis + call register_error + jmp assembly_line + +unexpected_instruction: + mov edx,_unexpected_instruction + call register_error + jmp assembly_line + +repeated_declaration: + mov edx,_repeated_declaration + call register_error + jmp assembly_line diff --git a/toolchain/fasmg.kl0e/source/dos/fasmg.asm b/toolchain/fasmg.kl0e/source/dos/fasmg.asm new file mode 100644 index 0000000..6815ce0 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/dos/fasmg.asm @@ -0,0 +1,651 @@ + +match ,{ + + include '../libc/struct.inc' + +} match -,{ +else + + include 'selfhost.inc' + +end match +_ equ } + +include '../version.inc' + +BUFFER_SIZE = 4000h +STACK_SIZE = 4000h + + format MZ + heap 0 + stack stack_segment:stack_top-stack_bottom + entry loader:startup + +segment loader use16 + + startup: + + mov ax,1687h + int 2Fh + or ax,ax ; DPMI installed? + jnz short no_dpmi + test bl,1 ; 32-bit programs supported? + jz short no_dpmi + mov word [cs:mode_switch],di + mov word [cs:mode_switch+2],es + mov bx,si ; allocate memory for DPMI data + mov ah,48h + int 21h + jnc switch_to_protected_mode + init_failed: + call startup_error + db 'DPMI initialization failed.',0Dh,0Ah,0 + no_dpmi: + call startup_error + db '32-bit DPMI services are not available.',0Dh,0Ah,0 + startup_error: + pop si + push cs + pop ds + show_message: + lodsb + test al,al + jz message_shown + mov dl,al + mov ah,2 + int 21h + jmp show_message + message_shown: + mov ax,4CFFh + int 21h + switch_to_protected_mode: + mov es,ax + mov ds,[ds:2Ch] + mov ax,1 + call far [cs:mode_switch] ; switch to protected mode + jc init_failed + mov cx,1 + xor ax,ax + int 31h ; allocate descriptor for code + jc init_failed + mov si,ax + xor ax,ax + int 31h ; allocate descriptor for data + jc init_failed + mov di,ax + mov dx,cs + lar cx,dx + shr cx,8 + or cx,0C000h + mov bx,si + mov ax,9 + int 31h ; set code descriptor access rights + jc init_failed + mov dx,ds + lar cx,dx + shr cx,8 + or cx,0C000h + mov bx,di + int 31h ; set data descriptor access rights + jc init_failed + mov ecx,main + shl ecx,4 + mov dx,cx + shr ecx,16 + mov ax,7 + int 31h ; set data descriptor base address + jc init_failed + mov bx,si + int 31h ; set code descriptor base address + jc init_failed + mov cx,0FFFFh + mov dx,0FFFFh + mov ax,8 ; set segment limit to 4 GB + int 31h + jc init_failed + mov bx,di + int 31h + jc init_failed + mov ax,ds + mov ds,di + mov [main_selector],di + mov [psp_selector],es + mov gs,ax ; environment selector in GS + cli + mov ss,di + mov esp,stack_top + sti + mov es,di + mov cx,1 + xor ax,ax + int 31h ; allocate descriptor for BIOS data segment + jc init_failed + mov bx,ax + mov ax,gs + lar cx,ax + shr cx,8 + mov ax,9 + int 31h ; set descriptor access rights + jc init_failed + xor cx,cx + mov dx,400h + mov ax,7 + int 31h ; set base address of BIOS data segment + jc init_failed + xor cx,cx + mov dx,0FFh + mov ax,8 + int 31h ; set limit of BIOS data segment + jc init_failed + mov fs,bx ; BIOS data selector in FS + push si + push start + retf + + mode_switch dd ? + +segment main use32 + + start: + + call system_init + + call get_arguments + mov bl,al + cmp [no_logo],0 + jne logo_ok + mov esi,_logo + xor ecx,ecx + call display_string + logo_ok: + test bl,bl + jnz display_usage_information + + xor al,al + mov ecx,[verbosity_level] + jecxz init + or al,TRACE_ERROR_STACK + dec ecx + jz init + or al,TRACE_DISPLAY + init: + + call assembly_init + + mov eax,[fs:6Ch] + mov [timer],eax + + assemble: + mov esi,[initial_commands] + mov edx,[source_path] + call assembly_pass + jc assembly_done + + mov eax,[current_pass] + cmp eax,[maximum_number_of_passes] + jb assemble + + call show_display_data + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,_code_cannot_be_generated + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + jmp assembly_failed + + assembly_done: + + call show_display_data + + cmp [first_error],0 + jne assembly_failed + + cmp [no_logo],0 + jne summary_done + mov eax,[current_pass] + xor edx,edx + call itoa + call display_string + mov esi,_passes + cmp [current_pass],1 + jne display_passes_suffix + mov esi,_pass + display_passes_suffix: + xor ecx,ecx + call display_string + mov eax,[fs:6Ch] + sub eax,[timer] + mov ecx,36000 + mul ecx + shrd eax,edx,16 + shr edx,16 + mov ecx,10 + div ecx + mov [timer],edx + or edx,eax + jz display_output_length + xor edx,edx + call itoa + call display_string + mov esi,_message_suffix + mov ecx,1 + call display_string + mov eax,[timer] + xor edx,edx + call itoa + call display_string + mov esi,_seconds + xor ecx,ecx + call display_string + display_output_length: + call get_output_length + push eax edx + call itoa + call display_string + pop edx eax + mov esi,_bytes + cmp eax,1 + jne display_bytes_suffix + test edx,edx + jnz display_bytes_suffix + mov esi,_byte + display_bytes_suffix: + xor ecx,ecx + call display_string + mov esi,_new_line + xor ecx,ecx + call display_string + summary_done: + + mov ebx,[source_path] + mov edi,[output_path] + call write_output_file + jc write_failed + + call assembly_shutdown + call system_shutdown + + mov ax,4C00h + int 21h + + assembly_failed: + + call show_errors + + call assembly_shutdown + call system_shutdown + + mov ax,4C02h + int 21h + + write_failed: + mov ebx,_write_failed + jmp fatal_error + + out_of_memory: + mov ebx,_out_of_memory + jmp fatal_error + + fatal_error: + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,ebx + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + call assembly_shutdown + call system_shutdown + + mov ax,4C03h + int 21h + + display_usage_information: + + mov esi,_usage + xor ecx,ecx + call display_string + + call system_shutdown + + mov ax,4C01h + int 21h + + get_arguments: + push ds + mov ds,[psp_selector] + mov esi,81h + mov edi,command_line + mov ecx,7Fh + move_command_line: + lodsb + cmp al,0Dh + je command_line_moved + stosb + loop move_command_line + command_line_moved: + pop ds + xor eax,eax + stosb + mov [initial_commands],eax + mov [source_path],eax + mov [output_path],eax + mov [no_logo],al + mov [verbosity_level],eax + mov [maximum_number_of_passes],100 + mov [maximum_number_of_errors],1 + mov [maximum_depth_of_stack],10000 + mov esi,command_line + mov edi,parameters + get_argument: + xor ah,ah + read_character: + lodsb + test al,al + jz no_more_arguments + cmp al,22h + je switch_quote + cmp ax,20h + je end_argument + stosb + jmp read_character + end_argument: + xor al,al + stosb + find_next_argument: + mov al,[esi] + test al,al + jz no_more_arguments + cmp al,20h + jne next_argument_found + inc esi + jmp find_next_argument + switch_quote: + xor ah,1 + jmp read_character + next_argument_found: + cmp al,'-' + je get_option + cmp al,'/' + je get_option + cmp [source_path],0 + je get_source_path + cmp [output_path],0 + je get_output_path + error_in_arguments: + or al,-1 + retn + get_source_path: + mov [source_path],edi + jmp get_argument + get_output_path: + mov [output_path],edi + jmp get_argument + no_more_arguments: + cmp [source_path],0 + je error_in_arguments + xor al,al + stosb + retn + get_option: + inc esi + lodsb + cmp al,'e' + je set_errors_limit + cmp al,'E' + je set_errors_limit + cmp al,'i' + je insert_initial_command + cmp al,'I' + je insert_initial_command + cmp al,'p' + je set_passes_limit + cmp al,'P' + je set_passes_limit + cmp al,'r' + je set_recursion_limit + cmp al,'R' + je set_recursion_limit + cmp al,'v' + je set_verbose_mode + cmp al,'V' + je set_verbose_mode + cmp al,'n' + je set_no_logo + cmp al,'N' + jne error_in_arguments + set_no_logo: + or [no_logo],-1 + mov al,[esi] + cmp al,20h + je find_next_argument + test al,al + jnz error_in_arguments + jmp find_next_argument + set_verbose_mode: + call get_option_value + jc error_in_arguments + cmp edx,2 + ja error_in_arguments + mov [verbosity_level],edx + jmp find_next_argument + set_errors_limit: + call get_option_value + jc error_in_arguments + test edx,edx + jz error_in_arguments + mov [maximum_number_of_errors],edx + jmp find_next_argument + set_recursion_limit: + call get_option_value + jc error_in_arguments + test edx,edx + jz error_in_arguments + mov [maximum_depth_of_stack],edx + jmp find_next_argument + set_passes_limit: + call get_option_value + jc error_in_arguments + test edx,edx + jz error_in_arguments + mov [maximum_number_of_passes],edx + jmp find_next_argument + get_option_value: + xor eax,eax + mov edx,eax + find_option_value: + cmp byte [esi],20h + jne get_option_digit + inc esi + jmp find_option_value + get_option_digit: + lodsb + cmp al,20h + je option_value_ok + test al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + invalid_option_value: + stc + ret + insert_initial_command: + push edi + find_command_segment: + cmp byte [esi],20h + jne command_segment_found + inc esi + jmp find_command_segment + command_segment_found: + xor ah,ah + cmp byte [esi],22h + jne measure_command_segment + inc esi + inc ah + measure_command_segment: + mov ebx,esi + scan_command_segment: + mov ecx,esi + mov al,[esi] + test al,al + jz command_segment_measured + cmp ax,20h + je command_segment_measured + cmp ax,22h + je command_segment_measured + inc esi + cmp al,22h + jne scan_command_segment + command_segment_measured: + sub ecx,ebx + mov edi,[initial_commands] + lea eax,[ecx+2] + test edi,edi + jz allocate_initial_commands_buffer + mov edx,[initial_commands_length] + add edi,edx + add eax,edx + cmp eax,[initial_commands_maximum_length] + ja grow_initial_commands_buffer + copy_initial_command: + xchg esi,ebx + rep movsb + mov esi,ebx + sub edi,[initial_commands] + mov [initial_commands_length],edi + mov al,[esi] + test al,al + jz initial_command_ready + cmp al,20h + jne command_segment_found + initial_command_ready: + mov edi,[initial_commands] + add edi,[initial_commands_length] + mov ax,0Ah + stosw + inc [initial_commands_length] + pop edi + jmp find_next_argument + allocate_initial_commands_buffer: + push ecx + mov ecx,eax + call malloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + pop ecx + jmp copy_initial_command + grow_initial_commands_buffer: + push ecx + mov ecx,eax + mov eax,[initial_commands] + call realloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + add edi,[initial_commands_length] + pop ecx + jmp copy_initial_command + + include 'system.inc' + + include '../malloc.inc' + include '../assembler.inc' + include '../symbols.inc' + include '../expressions.inc' + include '../conditions.inc' + include '../floats.inc' + include '../directives.inc' + include '../calm.inc' + include '../errors.inc' + include '../map.inc' + include '../reader.inc' + include '../output.inc' + include '../console.inc' + + _logo db 'flat assembler version g.',VERSION,13,10,0 + + _usage db 'Usage: fasmg source [output]',13,10 + db 'Optional settings:',13,10 + db ' -e limit Set the maximum number of displayed errors (default 1)',13,10 + db ' -p limit Set the maximum allowed number of passes (default 100)',13,10 + db ' -r limit Set the maximum depth of the stack (default 10000)',13,10 + db ' -v flag Enable or disable showing all lines from the stack (default 0)',13,10 + db ' -i command Insert instruction at the beginning of source',13,10 + db ' -n Do not show logo nor summary',13,10 + db 0 + + _pass db ' pass, ',0 + _passes db ' passes, ',0 + _dot db '.' + _seconds db ' seconds, ',0 + _byte db ' byte.',0 + _bytes db ' bytes.',0 + + _write_failed db 'failed to write the output file',0 + _out_of_memory db 'not enough memory to complete the assembly',0 + _code_cannot_be_generated db 'could not generate code within the allowed number of passes',0 + + include '../tables.inc' + include '../messages.inc' + + align 4 + + include '../variables.inc' + + psp_selector dw ? + main_selector dw ? + + malloc_freelist dd ? + + source_path dd ? + output_path dd ? + maximum_number_of_passes dd ? + + initial_commands dd ? + initial_commands_length dd ? + initial_commands_maximum_length dd ? + + timestamp dq ? + + timer dd ? + verbosity_level dd ? + no_logo db ? + + command_line db 80h dup ? + parameters db 80h dup ? + +segment buffer_segment + + buffer = (buffer_segment-main) shl 4 + + db BUFFER_SIZE dup ? + +segment stack_segment + + stack_bottom = (stack_segment-main) shl 4 + + db STACK_SIZE dup ? + + stack_top = stack_bottom + $ diff --git a/toolchain/fasmg.kl0e/source/dos/selfhost.inc b/toolchain/fasmg.kl0e/source/dos/selfhost.inc new file mode 100644 index 0000000..6c1fd5e --- /dev/null +++ b/toolchain/fasmg.kl0e/source/dos/selfhost.inc @@ -0,0 +1,22 @@ + +include '../../examples/x86/include/80386.inc' + +macro format?.MZ? + format binary as 'exe' + include '../../examples/x86/include/format/mz.inc' +end macro + +macro struct? name + macro ends?! + end namespace + esc end struc + virtual at 0 + name name + sizeof.name = $ + end virtual + purge ends? + end macro + esc struc name + label . : sizeof.name + namespace . +end macro diff --git a/toolchain/fasmg.kl0e/source/dos/system.inc b/toolchain/fasmg.kl0e/source/dos/system.inc new file mode 100644 index 0000000..12d9374 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/dos/system.inc @@ -0,0 +1,415 @@ + +LINE_FEED equ 13,10 + +system_init: + cld + mov [malloc_freelist],0 + mov ah,2Ah + int 21h + push dx cx + movzx ecx,cx + mov eax,ecx + sub eax,1970 + mov ebx,365 + mul ebx + mov ebp,eax + mov eax,ecx + sub eax,1969 + shr eax,2 + add ebp,eax + mov eax,ecx + sub eax,1901 + mov ebx,100 + div ebx + sub ebp,eax + mov eax,ecx + xor edx,edx + sub eax,1601 + mov ebx,400 + div ebx + add ebp,eax + movzx ecx,byte [esp+3] + mov eax,ecx + dec eax + mov ebx,30 + mul ebx + add ebp,eax + cmp ecx,8 + jbe months_correction + mov eax,ecx + sub eax,7 + shr eax,1 + add ebp,eax + mov ecx,8 + months_correction: + mov eax,ecx + shr eax,1 + add ebp,eax + cmp ecx,2 + pop cx + jbe day_correction_ok + sub ebp,2 + test ecx,11b + jnz day_correction_ok + xor edx,edx + mov eax,ecx + mov ebx,100 + div ebx + or edx,edx + jnz day_correction + mov eax,ecx + mov ebx,400 + div ebx + or edx,edx + jnz day_correction_ok + day_correction: + inc ebp + day_correction_ok: + pop dx + movzx eax,dl + dec eax + add eax,ebp + mov ebx,24 + mul ebx + push eax + mov ah,2Ch + int 21h + pop eax + push dx + movzx ebx,ch + add eax,ebx + mov ebx,60 + mul ebx + movzx ebx,cl + add eax,ebx + mov ebx,60 + mul ebx + pop bx + movzx ebx,bh + add eax,ebx + adc edx,0 + mov dword [timestamp],eax + mov dword [timestamp+4],edx + retn + +system_shutdown: + ; call mcheck + retn + +dos_int: + push 0 + push 0 + push 0 + pushw buffer_segment + pushw buffer_segment + stc + pushfw + push eax + push ecx + push edx + push ebx + push 0 + push ebp + push esi + push edi + mov ax,300h + mov bx,21h + xor cx,cx + mov edi,esp + push es ss + pop es + int 31h + pop es + mov edi,[esp] + mov esi,[esp+4] + mov ebp,[esp+8] + mov ebx,[esp+10h] + mov edx,[esp+14h] + mov ecx,[esp+18h] + mov ah,[esp+20h] + sahf + mov eax,[esp+1Ch] + lea esp,[esp+32h] + retn + +open: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + push esi edi + call adapt_path + mov ax,716Ch + mov bx,100000b + mov dx,1 + xor cx,cx + xor si,si + call dos_int + jnc open_done + cmp ax,7100h + je old_open + stc + jmp open_done + old_open: + mov ax,3D00h + xor dx,dx + call dos_int + open_done: + mov bx,ax + pop edi esi + retn + adapt_path: + mov esi,edx + mov edi,buffer + copy_path: + lodsb + cmp al,'/' + jne path_char_ok + mov al,'\' + path_char_ok: + stosb + cmp edi,buffer+BUFFER_SIZE + jae out_of_memory + test al,al + jnz copy_path + retn + +create: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + push esi edi + call adapt_path + mov ax,716Ch + mov bx,100001b + mov dx,10010b + xor cx,cx + xor si,si + xor di,di + call dos_int + jnc create_done + cmp ax,7100h + je old_create + stc + jmp create_done + old_create: + mov ah,3Ch + xor cx,cx + xor dx,dx + call dos_int + create_done: + mov bx,ax + pop edi esi + retn + +write: +; in: ebx = file handle, edx - data, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push esi edi ebp + mov ebp,ecx + mov esi,edx + write_loop: + mov ecx,BUFFER_SIZE + sub ebp,BUFFER_SIZE + jnc do_write + add ebp,BUFFER_SIZE + mov ecx,ebp + xor ebp,ebp + do_write: + push ecx + mov edi,buffer + rep movsb + pop ecx + mov ah,40h + xor dx,dx + call dos_int + or ebp,ebp + jnz write_loop + pop ebp edi esi + ret + +read: +; in: ebx = file handle, edx - buffer, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push esi edi ebp + mov ebp,ecx + mov edi,edx + read_loop: + mov ecx,BUFFER_SIZE + sub ebp,BUFFER_SIZE + jnc do_read + add ebp,BUFFER_SIZE + mov ecx,ebp + xor ebp,ebp + do_read: + push ecx + mov ah,3Fh + xor dx,dx + call dos_int + cmp ax,cx + jne read_eof + mov esi,buffer + pop ecx + rep movsb + or ebp,ebp + jnz read_loop + read_done: + pop ebp edi esi + ret + read_eof: + pop ecx + stc + jmp read_done + +close: +; in: ebx = file handle +; preserves: ebx, esi, edi + mov ah,3Eh + int 21h + ret + +lseek: +; in: ebx = file handle, cl = method, edx:eax = offset +; out: edx:eax = new offset from the beginning of file, cf set on error +; preserves: ebx, esi, edi + mov dx,ax + xchg ecx,eax + shr ecx,16 + mov ah,42h + int 21h + pushf + shl edx,16 + popf + mov dx,ax + mov eax,edx + xor edx,edx + ret + +get_timestamp: +; out: edx:eax = timestamp +; preserves: ebx, ecx, esi, edi +; note: during the passes of a single assembly this function should always return the same value + mov eax,dword [timestamp] + mov edx,dword [timestamp+4] + retn + +display_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push ebx + mov ebx,1 + jmp write_string +display_error_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push ebx + mov ebx,2 + write_string: + test ecx,ecx + jnz string_length_ok + xor al,al + mov edi,esi + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + string_length_ok: + mov edx,esi + call write + pop ebx + retn + +get_environment_variable: +; in: +; esi - name +; edi - buffer for value +; ecx = size of buffer +; out: +; eax = length of value +; preserves: ebx, esi, edi + push ebx esi edi + mov ebx,esi + xor esi,esi + compare_variable_names: + mov edx,ebx + compare_name_character: + lods byte [gs:esi] + mov ah,[edx] + inc edx + cmp al,'=' + je end_of_variable_name + test ah,ah + jz next_variable + sub ah,al + jz compare_name_character + cmp ah,20h + jne next_variable + cmp al,41h + jb next_variable + cmp al,5Ah + jna compare_name_character + next_variable: + lods byte [gs:esi] + test al,al + jnz next_variable + cmp byte [gs:esi],0 + jne compare_variable_names + mov ah,al + end_of_variable_name: + test ah,ah + jnz next_variable + add ecx,edi + mov edx,esi + copy_variable_value: + lods byte [gs:esi] + cmp edi,ecx + jae variable_value_next_character + stosb + variable_value_next_character: + or al,al + jnz copy_variable_value + lea eax,[esi-1] + sub eax,edx + pop edi esi ebx + ret + +VALLOC_MIN = 40000h + +valloc: +; in: ecx = requested minimum size +; out: eax - allocated block, ecx = allocated size, zero if failed +; preserves: ebx, esi, edi + cmp ecx,VALLOC_MIN + jbe valloc_size_minimum + dec ecx + and ecx,(-1) shl 12 + add ecx,1 shl 12 + jmp valloc_size_ready + valloc_size_minimum: + mov ecx,VALLOC_MIN + valloc_size_ready: + push ebx esi edi + push ecx + mov ebx,ecx + shr ebx,16 + mov ax,501h + int 31h + movzx eax,cx + pop ecx + jc valloc_failed + shl ebx,16 + or eax,ebx + mov edx,main + shl edx,4 + sub eax,edx + pop edi esi ebx + ret + valloc_failed: + xor ecx,ecx + pop edi esi ebx + retn diff --git a/toolchain/fasmg.kl0e/source/errors.inc b/toolchain/fasmg.kl0e/source/errors.inc new file mode 100644 index 0000000..daafd17 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/errors.inc @@ -0,0 +1,177 @@ + +struct Error + flags dd ? ; ERR_# + message dd ? + symbol dd ? + preprocessed_data dd ? + preprocessed_length dd ? + next dd ? ; pointer to another Error + ; source SourceContext +ends + +ERR_CUSTOM = 1 + +register_volatile_error: +; in: +; edx - 32-bit length followed by string data +; ebx - data for message formatting (only relevant for non-custom messages that contain % character) +; out: +; edx - Error +; preserves: eax, ebx, ecx, esi, edi + cmp [next_pass_needed],0 + jne error_ignored + push eax ebx ecx esi edi + or [message_volatile],1 + jmp get_error_line +register_delayed_error: +; in: +; edx - error message +; esi - SourceContext +; ebx - data for message formatting (only relevant for non-custom messages that contain % character) +; out: +; edx - Error +; preserves: eax, ebx, ecx, esi, edi + cmp [next_pass_needed],0 + jne error_ignored + push eax ebx ecx esi edi + and [message_volatile],0 + and [error_line_start],0 + and [error_line_end],0 + jmp add_error +register_error: +; in: +; edx - error message +; ebx - data for message formatting (only relevant for non-custom messages that contain % character) +; out: +; edx - Error, null when error was not registered +; preserves: eax, ebx, ecx, esi, edi + cmp [next_pass_needed],0 + jne error_ignored + push eax ebx ecx esi edi + and [message_volatile],0 + get_error_line: + mov eax,[line_start] + mov [error_line_start],eax + mov ecx,[line_end] + cmp [number_of_line_embeddings],0 + je error_line_end_ok + mov eax,[line_embeddings] + mov ecx,[eax+LineEmbedding.previous_end] + error_line_end_ok: + mov [error_line_end],ecx + xor esi,esi + add_error: + mov [error_symbol],ebx + lea ebx,[first_error] + xor ecx,ecx + find_last_error: + mov eax,[ebx] + test eax,eax + jz last_error_found + lea ebx,[eax+Error.next] + inc ecx + cmp ecx,[maximum_number_of_errors] + jb find_last_error + pop edi esi ecx ebx eax + xor edx,edx + retn + last_error_found: + cmp [message_volatile],0 + jne prepare_volatile_error + test esi,esi + jnz prepare_error + mov esi,[source_context] + prepare_error: + mov ecx,[esi+SourceContext.number_of_entries] + imul ecx,sizeof.SourceEntry + add ecx,sizeof.SourceContext + cmp [esi+ecx-sizeof.SourceEntry+SourceEntry.type],SOURCE_CALM + jne error_source_context_ready + mov eax,[calm_instruction_number] + mov [esi+ecx-sizeof.SourceEntry+SourceEntry.line_number],eax + and [error_line_start],0 + and [error_line_end],0 + error_source_context_ready: + add ecx,sizeof.Error + add ecx,[error_line_end] + sub ecx,[error_line_start] + mov edi,edx + call malloc + mov [ebx],eax + mov [eax+Error.message],edi + mov ecx,[error_symbol] + mov [eax+Error.symbol],ecx + xor ecx,ecx + mov [eax+Error.flags],ecx + mov [eax+Error.next],ecx + lea edi,[eax+sizeof.Error] + push eax + call clone_source_context + pop edx + store_preprocessed_data: + mov [edx+Error.preprocessed_data],edi + mov esi,[error_line_start] + mov ecx,[error_line_end] + sub ecx,esi + mov [edx+Error.preprocessed_length],ecx + rep movsb + pop edi esi ecx ebx eax + retn + error_ignored: + xor edx,edx + retn + prepare_volatile_error: + mov esi,edx + mov eax,[source_context] + mov ecx,[eax+SourceContext.number_of_entries] + imul ecx,sizeof.SourceEntry + add ecx,sizeof.SourceContext + cmp [eax+ecx-sizeof.SourceEntry+SourceEntry.type],SOURCE_CALM + jne volatile_error_source_context_ready + mov edx,[calm_instruction_number] + mov [eax+ecx-sizeof.SourceEntry+SourceEntry.line_number],edx + and [error_line_start],0 + and [error_line_end],0 + volatile_error_source_context_ready: + add ecx,sizeof.Error + add ecx,[error_line_end] + sub ecx,[error_line_start] + mov edi,ecx + add ecx,[esi] + inc ecx + call malloc + add edi,eax + mov [ebx],eax + mov edx,eax + mov [edx+Error.message],edi + xor eax,eax + mov [edx+Error.next],eax + mov [edx+Error.flags],eax + lodsd + mov ecx,eax + rep movsb + xor al,al + stosb + mov esi,[source_context] + lea edi,[edx+sizeof.Error] + push edx + call clone_source_context + pop edx + jmp store_preprocessed_data + +discard_errors: + mov eax,[first_error] + test eax,eax + jnz discard_error + retn + discard_error: + add eax,sizeof.Error + call release_source_context + sub eax,sizeof.Error + mov ebx,[eax+Error.next] + call mfree + mov eax,ebx + test eax,eax + jnz discard_error + mov [first_error],eax + retn \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/source/expressions.inc b/toolchain/fasmg.kl0e/source/expressions.inc new file mode 100644 index 0000000..9f87a69 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/expressions.inc @@ -0,0 +1,4252 @@ + +struct ExpressionTerm + attributes dd ? ; EXPR_# in low byte, plus any EXPRF_# + metadata dd ? + value dd ? +ends + +EXPR_NUMBER = 30h +EXPR_STRING = 22h +EXPR_FLOAT = 2Eh + +EXPR_SYMBOL_VALUE = 10h +EXPR_OPERATOR = 20h +EXPR_SYMBOL = 40h + +EXPR_POLYNOMIAL = 31h + +EXPR_MISSING_ARGUMENT = 29h +EXPR_MISSING_PARENTHESIS = 28h + +EXPRF_VALUE_IN_WORKSPACE = 100h +EXPRF_CALM_LITERAL = 200h + +EXPRF_OPERATOR_UNARY = 1000h + +convert_number: +; in: +; edx - 32-bit length followed by a string of that length +; out: +; cf set when number has no known prefix or suffix but is not a plain decimal number +; when cf = 0: +; edx - 32-bit length followed by binary data of that length, null when string did not represent a valid number +; when cf = 1: +; edx preserved +; preserves: esi + mov edi,[value_workspace.memory_start] + add edi,[value_position] + mov ecx,[edx] + add edx,4 + cmp byte [edx],'$' + je pascal_hexadecimal_number + cmp ecx,2 + jb check_number_suffix + cmp word [edx],'0x' + je c_hexadecimal_number + check_number_suffix: + movzx eax,byte [edx+ecx-1] + mov al,[characters+eax] + cmp al,'h' + je suffixed_hexadecimal_number + cmp al,'b' + je suffixed_binary_number + cmp al,'o' + je suffixed_octal_number + cmp al,'q' + je suffixed_octal_number + cmp al,'d' + jne decimal_number + or ah,1 + dec ecx + jz invalid_number + decimal_number: + mov ebx,ecx + check_decimal_digits: + mov al,[edx+ebx-1] + cmp al,27h + je check_next_decimal_digit + cmp al,'_' + je check_next_decimal_digit + cmp al,'0' + jb unknown_number + cmp al,'9' + ja unknown_number + check_next_decimal_digit: + dec ebx + jnz check_decimal_digits + push ecx edx + add ecx,12 + mov edx,value_workspace + call reserve_workspace + xor eax,eax + mov dword [edi+4],eax + add eax,4 + mov dword [edi],eax + pop edx ebx + convert_decimal_number: + mov al,[edx] + cmp al,27h + je skip_decimal_digit + cmp al,'_' + je skip_decimal_digit + sub al,'0' + mov ecx,[edi] + xor ecx,ecx + add_decimal_digit: + add ecx,4 + movzx eax,al + add [edi+ecx],eax + setc al + sets ah + cmp ecx,[edi] + jb add_decimal_digit + or ah,al + jz decimal_digit_added + xor ah,ah + add ecx,4 + mov [edi+ecx],eax + mov [edi],ecx + decimal_digit_added: + dec ebx + jz decimal_number_converted + next_decimal_digit: + inc edx + push ebx edx + mov ebx,10 + xor ecx,ecx + xor edx,edx + multiply_decimal_number: + add ecx,4 + mov eax,[edi+ecx] + mov [edi+ecx],edx + mul ebx + add [edi+ecx],eax + cmp ecx,[edi] + jb multiply_decimal_number + test edx,edx + jz decimal_number_multiplied + add ecx,4 + mov [edi+ecx],edx + mov [edi],ecx + decimal_number_multiplied: + pop edx ebx + xor eax,eax + jmp convert_decimal_number + skip_decimal_digit: + inc edx + dec ebx + jnz convert_decimal_number + decimal_number_converted: + lea edx,[edi+4] + mov ecx,[edi] + dec ecx + optimize_number: + movsx eax,byte [edx+ecx-1] + cmp ah,[edx+ecx] + jne number_optimized + loop optimize_number + cmp byte [edx],0 + je number_finished + number_optimized: + inc ecx + number_finished: + sub edx,4 + mov [edx],ecx + lea edi,[edx+4+ecx] + sub edi,[value_workspace.memory_start] + mov [value_position],edi + ; clc + retn + c_hexadecimal_number: + sub ecx,3 + jc invalid_number + add edx,2 + jmp hexadecimal_number + pascal_hexadecimal_number: + inc edx + suffixed_hexadecimal_number: + sub ecx,2 + jc invalid_number + hexadecimal_number: + push edx ecx + shr ecx,1 + add ecx,6 + mov edx,value_workspace + call reserve_workspace + pop ebx edx + push edi + xor eax,eax + stosd + mov [edi],al + xor cl,cl + hexadecimal_digit: + movzx eax,byte [edx+ebx] + cmp al,27h + je skip_hexadecimal_digit + cmp al,'_' + je skip_hexadecimal_digit + mov al,[characters+eax] + sub al,'0' + jc invalid_digit + cmp al,10 + jb hexadecimal_digit_ok + sub al,'a'-'0' + jc invalid_digit + add al,10 + cmp al,16 + jae invalid_digit + hexadecimal_digit_ok: + shl al,cl + or [edi],al + sub ebx,1 + jc number_converted + xor cl,4 + jnz hexadecimal_digit + inc edi + mov [edi],cl + jmp hexadecimal_digit + skip_hexadecimal_digit: + sub ebx,1 + jnc hexadecimal_digit + number_converted: + pop edx + inc edi + and byte [edi],0 + add edx,4 + mov ecx,edi + sub ecx,edx + jmp optimize_number + suffixed_binary_number: + sub ecx,2 + jc invalid_number + push edx ecx + shr ecx,3 + add ecx,6 + mov edx,value_workspace + call reserve_workspace + pop ebx edx + push edi + xor eax,eax + stosd + mov [edi],al + xor cl,cl + binary_digit: + mov al,[edx+ebx] + cmp al,27h + je skip_binary_digit + cmp al,'_' + je skip_binary_digit + sub al,'0' + jc invalid_digit + cmp al,2 + jae invalid_digit + shl al,cl + or [edi],al + sub ebx,1 + jc number_converted + inc cl + and cl,111b + jnz binary_digit + inc edi + mov [edi],cl + jmp binary_digit + skip_binary_digit: + sub ebx,1 + jnc binary_digit + jmp number_converted + suffixed_octal_number: + sub ecx,2 + jc invalid_number + push edx ecx + shr ecx,1 + add ecx,6 + mov edx,value_workspace + call reserve_workspace + pop ebx edx + push edi + xor eax,eax + stosd + mov [edi],al + xor cl,cl + octal_digit: + mov al,[edx+ebx] + cmp al,27h + je skip_octal_digit + cmp al,'_' + je skip_octal_digit + sub al,'0' + jc invalid_digit + cmp al,8 + jae invalid_digit + shl eax,cl + or [edi],al + add cl,3 + cmp cl,8 + jb skip_octal_digit + sub cl,8 + inc edi + mov [edi],ah + xor eax,eax + skip_octal_digit: + sub ebx,1 + jnc octal_digit + jmp number_converted + unknown_number: + test ah,ah + jnz invalid_number + sub edx,4 + stc + retn + invalid_digit: + pop edi + invalid_number: + xor edx,edx + mov al,30h + clc + retn + +convert_number_back: +; in: +; edx - 32-bit length followed by binary data of that length +; out: +; edx - 32-bit length followed by a string of that length +; note: +; the number is treated as unsigned +; returned string is in temporary storage and should be copied out of it immediately + mov edi,[value_workspace.memory_start] + add edi,[value_position] + mov ecx,[edx] + add ecx,2 + shl ecx,2 + mov esi,edx + mov edx,value_workspace + call reserve_workspace + lodsd + lea ebx,[edi+4+(eax+1)*4] + mov edx,edi + mov ecx,eax + rep movsb + xchg eax,ecx + stosd + jecxz highest_dword_offset_ok + dec ecx + and ecx,not 11b + highest_dword_offset_ok: + mov esi,edx + mov edi,ebx + push edi + obtain_digit: + xor edx,edx + divide_highest_dwords: + mov eax,[esi+ecx] + call div10 + test eax,eax + jnz more_digits_to_come + sub ecx,4 + jnc divide_highest_dwords + pop ecx + cmp ecx,edi + je store_final_digit + test dl,dl + jz finish_number + store_final_digit: + add dl,'0' + dec edi + mov [edi],dl + finish_number: + sub ecx,edi + sub edi,4 + mov [edi],ecx + mov edx,edi + retn + more_digits_to_come: + mov ebx,ecx + divide_remaining_dwords: + mov [esi+ebx],eax + sub ebx,4 + jc store_digit + mov eax,[esi+ebx] + call div10 + jmp divide_remaining_dwords + store_digit: + add dl,'0' + dec edi + mov [edi],dl + jmp obtain_digit + div10: + ; cmp edx,10 + ; jae internal_error + push ebx ecx + push eax + mov ebx,eax + mov ecx,edx + shld edx,eax,2 + sub ebx,edx + sbb ecx,0 + mov eax,ebx + mov ebx,1999999Ah + mul ebx + mov eax,ecx + imul eax,ebx + add eax,edx + pop edx + imul ecx,eax,10 + sub edx,ecx + cmp edx,10 + jb div10_done + sub edx,10 + inc eax + div10_done: + pop ecx ebx + retn + +fit_value: +; in: +; edx - 32-bit length followed by numeric data +; ecx = number of bytes that the value has to fit into +; edi - buffer for the specified amount of bytes, null when just checking whether value fits in range +; out: +; sf set when value is negative +; cf set if value does not fit into extended range for specified size +; when cf = 0: +; edi - value fit into specified amount of bytes +; preserves: edx, esi, edi +; note: when value is zero, it fits even into zero byte range + mov ebx,ecx + cmp [edx],ecx + jbe term_in_range + xor al,al + cmp [edx+4+ecx],al + je check_redundant_bytes + dec al + cmp [edx+4+ecx],al + jne term_out_of_range + jecxz term_out_of_range + check_redundant_bytes: + inc ecx + cmp ecx,[edx] + je term_in_range + cmp [edx+4+ecx],al + je check_redundant_bytes + term_out_of_range: + mov ecx,[edx] + mov al,[edx+4+ecx-1] + test al,al + stc + retn + term_in_range: + test edi,edi + jz value_fit + mov ecx,[edx] + cmp ecx,ebx + jbe copy_value + mov ecx,ebx + copy_value: + lea eax,[edx+4] + xchg eax,esi + rep movsb + mov esi,eax + mov ecx,[edx] + movsx eax,byte [edx+4+ecx-1] + mov al,ah + mov ecx,ebx + sub ecx,[edx] + jbe value_ready + rep stosb + value_ready: + sub edi,ebx + value_fit: + test al,al + clc + retn + +start_decimal_converter: +; preserves: ebx + mov edx,value_workspace + mov edi,[value_position] + mov [converter_position],edi + add edi,[edx+Workspace.memory_start] + mov ecx,2*sizeof.FloatData + call reserve_workspace + lea ecx,[edi+2*sizeof.FloatData] + sub ecx,[edx+Workspace.memory_start] + mov [value_position],ecx + mov esi,edi + xor eax,eax + assert sizeof.FloatData and 11b = 0 + mov ecx,sizeof.FloatData shr 2 + rep stosd + mov edx,edi + mov ecx,sizeof.FloatData shr 2 + rep stosd + mov [edx+FloatData.exponent],7 + retn + +convert_decimal_digit: +; in: +; al = value of subsequent digit +; ecx = number of zero digits to insert before +; out: +; edi - FloatData holding the value corresponding to digits converted so far +; note: start_decimal_converter should be called before converting the first digit + mov esi,[value_workspace.memory_start] + add esi,[converter_position] + mov edi,esi + shl eax,24 + mov [esi+sizeof.FloatData+FloatData.mantissa],eax + jecxz multiply_by_ten + inc ecx + call multiply_float_by_power_of_ten + jmp add_subsequent_digit + multiply_by_ten: + mov ecx,10 + call multiply_float_by_unsigned_int + add_subsequent_digit: + mov esi,edi + lea ebx,[esi+sizeof.FloatData] + call add_floats + retn + +finish_decimal_conversion: +; out: +; edi - FloatData holding the converted value +; preserves: ebx, ecx, esi, edi +; note: this function should not be called before all the digits of a value have been processed by convert_decimal_digit + mov eax,[converter_position] + mov edi,[value_workspace.memory_start] + add edi,eax + add eax,2*sizeof.FloatData + cmp eax,[value_position] + jne decimal_conversion_finished + sub eax,sizeof.FloatData + mov [value_position],eax + decimal_conversion_finished: + retn + +keep_value: +; in: +; edx - numeric or string data returned by source parsing or expression evaluating functions +; preserves: ebx, esi, edi +; note: +; this function should be used in conjunction with get_kept_value to retain access to data +; while calling other parsing or expression evaluating functions + xor al,al + cmp edx,[value_workspace.memory_end] + jae keep_value_pointer + mov ecx,edx + sub ecx,[value_workspace.memory_start] + jc keep_value_pointer + mov edx,ecx + inc al + keep_value_pointer: + mov [kept_value],edx + mov [kept_value_in_workspace],al + retn + +get_kept_value: +; out: +; edx - numeric or string data previously passed to keep_value +; preserves: eax, ebx, ecx, esi, edi + mov edx,[kept_value] + cmp [kept_value_in_workspace],0 + je kept_value_ok + add edx,[value_workspace.memory_start] + kept_value_ok: + retn + +get_constant_value: +; in: +; esi = pointer into preprocessed line or the last embedded line +; out: +; esi = pointer advanced past the processed part of line +; al = type of value, zero when expression gave no result +; when al = 22h: +; edx - 32-bit length followed by string data +; when al = 30h: +; edx - 32-bit length followed by numeric data +; when al = 2Eh: +; edx - FloatData + call get_expression_value + jc return_empty_type + get_calculated_constant_value: + ; in: + ; edi - list of ExpressionTerm elements as returned by get_expression_value + ; out: + ; same as get_constant_value + ; preserves: esi, edi + call forbid_variable_terms + call get_term_value + mov eax,[edi+ExpressionTerm.attributes] + assert EXPR_STRING = 22h + assert EXPR_NUMBER = 30h + assert EXPR_FLOAT = 2Eh + retn + return_empty_type: + xor al,al + retn + forbid_variable_terms: + mov eax,edi + detect_variable_terms: + add eax,sizeof.ExpressionTerm + cmp [eax+ExpressionTerm.attributes],0 + je expression_terms_ok + cmp [eax+ExpressionTerm.metadata],0 + je detect_variable_terms + mov edx,_misused_variable_term + call register_error + expression_terms_ok: + retn + +get_numeric_constant_value: +; in: +; esi = pointer into preprocessed line or the last embedded line +; out: +; esi = pointer advanced past the processed part of line +; edx - 32-bit length followed by numeric data, null when expression gave no result +; edi - ExpressionTerm, null when expression gave no result + call get_expression_value + jc empty_numeric_constant + call forbid_variable_terms + call get_numeric_term_value + retn + empty_numeric_constant: + xor edx,edx + xor edi,edi + retn + +get_expression_value: +; in: +; esi = pointer into preprocessed line or the last embedded line +; out: +; cf set if expression gave no result +; esi = pointer advanced past the processed part of line +; when cf = 0: +; edi - list of ExpressionTerm elements, the closing element has attributes set to zero + mov edi,[expression_workspace.memory_start] + and [leave_opening_parentheses],0 + call parse_expression + push esi + mov esi,[expression_workspace.memory_start] + mov edi,[calculation_workspace.memory_start] + call calculate_parsed_expression + call pop_terms + pop esi + retn + +convert_terms_to_numeric_value: +; in: +; edi - list of ExpressionTerm elements as returned by get_expression_value +; out: +; esi - value in VALTYPE_NUMERIC format +; ecx = length of value +; note: the returned value is placed in assembly workspace + mov edx,assembly_workspace + convert_terms_to_numeric_value_in_workspace: + ; in: + ; edx - Workspace + ; edi - list of ExpressionTerm elements as returned by get_expression_value + ; out: + ; esi - value in VALTYPE_NUMERIC format (same as [edx+Workspace.memory_start]) + ; ecx = length of value + ; preserves: edx + mov ebx,[edx+Workspace.memory_start] + copy_numeric_term_values: + mov esi,edx + call get_numeric_term_value + xchg esi,edx + xchg ebx,edi + mov ecx,[esi] + add ecx,8 + call reserve_workspace + lodsd + stosd + mov ecx,eax + rep movsb + next_numeric_term: + add ebx,sizeof.ExpressionTerm + cmp [ebx+ExpressionTerm.attributes],0 + je numeric_term_values_copied + mov eax,[ebx+ExpressionTerm.metadata] + test eax,eax + jz next_numeric_term + stosd + xchg ebx,edi + jmp copy_numeric_term_values + numeric_term_values_copied: + xor eax,eax + stosd + mov esi,[edx+Workspace.memory_start] + mov ecx,edi + sub ecx,esi + retn + +update_predicted_shift: +; in: +; edx - ValueDefinition that is going to be updated +; esi - new value in VALTYPE_NUMERIC fomat +; preserves: ebx, ecx, edx, esi + test edx,edx + jz zero_shift + cmp [edx+ValueDefinition.type],VALTYPE_NUMERIC + jne zero_shift + mov eax,[current_pass] + dec eax + cmp eax,[edx+ValueDefinition.pass] + jne zero_shift + call get_low_dword + mov [predicted_shift],eax + mov edi,[edx+ValueDefinition.value] + xchg esi,edi + call get_low_dword + sub [predicted_shift],eax + test byte [predicted_shift+3],11000000b + mov esi,edi + jnp zero_shift + retn + zero_shift: + mov [predicted_shift],0 + retn + get_low_dword: + mov eax,[esi] + cmp eax,1 + jb low_dword_ready + je dword_from_single_byte + cmp eax,3 + jb dword_from_two_bytes + je dword_from_three_bytes + mov eax,[esi+4] + low_dword_ready: + retn + dword_from_single_byte: + movsx eax,byte [esi+4] + retn + dword_from_two_bytes: + movsx eax,word [esi+4] + retn + dword_from_three_bytes: + mov eax,[esi+4-1] + sar eax,8 + retn + +get_area_value: +; in: +; edi - command sequence created by parse_expression +; out: +; cf set if expression does not yield a valid and accessible VALTYPE_AREA value +; when cf = 0: +; ebx - SymbolTree_Leaf +; edx - ValueDefinition +; preserves: esi + mov al,[edi] + cmp al,EXPR_SYMBOL + je check_for_plain_symbol + cmp al,EXPR_SYMBOL_VALUE + jne no_plain_area_symbol + cmp dword [edi+3*4],0 + jne no_plain_area_symbol + mov edx,[edi+2*4] + test edx,edx + jz no_plain_area_symbol + check_area_symbol: + cmp [edx+ValueDefinition.type],VALTYPE_AREA + jne no_plain_area_symbol + mov ebx,[edi+4] + call mark_symbol_as_used + clc + retn + check_for_plain_symbol: + cmp dword [edi+2*4],0 + jne no_plain_area_symbol + mov ebx,[edi+4] + call get_available_value + jnc check_area_symbol + no_plain_area_symbol: + push esi + mov esi,edi + mov edi,[calculation_workspace.memory_start] + call calculate_parsed_expression + jc invalid_area_expression + call pop_terms + jc invalid_area_expression + mov eax,edi + xor esi,esi + extract_variable_term: + add eax,sizeof.ExpressionTerm + cmp [eax+ExpressionTerm.attributes],0 + je variable_term_extracted + cmp [eax+ExpressionTerm.metadata],0 + je extract_variable_term + test esi,esi + jnz invalid_area_expression + mov esi,eax + jmp extract_variable_term + variable_term_extracted: + test esi,esi + jz invalid_area_expression + call get_term_value + xor ecx,ecx + mov edi,ecx + call fit_value + jc invalid_area_expression + mov edi,esi + call get_term_value + mov ecx,1 + mov edi,value + call fit_value + jc invalid_area_expression + cmp byte [value],1 + jne invalid_area_expression + mov ebx,[esi+ExpressionTerm.metadata] + mov edx,[ebx+SymbolTree_Leaf.definition] + test edx,edx + jz invalid_area_expression + cmp [edx+ValueDefinition.type],VALTYPE_AREA + jne invalid_area_expression + pop esi + clc + retn + invalid_area_expression: + pop esi + invalid_area_symbol: + stc + retn + +get_constituent_value: +; same as get_processed_value +; note: after any expression evaluation functions have been used, only this function should be used to retrieve constituents of line + xor al,al + xchg al,[current_constituent] + test al,al + jz get_processed_value + get_constituent_components: + mov ebx,[constituent_symbol] + mov edx,[constituent_value] + mov ecx,[constituent_whitespace] + clc + retn + +peek_at_constituent_value: +; same as get_constituent_value, but returned values are also kept in constituent variables +; note: +; the retrieved value is still going to be available to expression evaluation functions or to the next call of get_constituent_value +; to consume the value it is enough to set [current_constituent] to zero + cmp [current_constituent],0 + jne get_current_constituent + call get_processed_value + jc constituent_value_ok + mov [current_constituent],al + mov [constituent_symbol],ebx + mov [constituent_value],edx + mov [constituent_whitespace],ecx + constituent_value_ok: + retn + get_current_constituent: + mov al,[current_constituent] + jmp get_constituent_components + +parse_expression: +; in: +; esi = pointer into preprocessed line or the last embedded line +; edi = pointer to a place in expression workspace where the parsed command sequence should be stored +; [leave_opening_parentheses] = non-zero when parentheses opened in the beginning of expression that did not get closed should be returned to caller instead of being registered in parsed expression +; out: +; esi = pointer advanced past the processed part of line +; edi = pointer advanced past the created sequence in expression workspace +; ecx = number of parentheses opened in the beginning of expression that did not get closed (zero when [leave_opening_parentheses] was zero) + mov [expression_end],edi + sub edi,[expression_workspace.memory_start] + mov [expression_position],edi + mov eax,[operator_stack_base] + mov [operator_stack],eax + mov [operator_stack_position],eax + mov [operator_argument_expected],1 + get_expression_element: + mov edi,[expression_end] + mov edx,expression_workspace + mov ecx,[operator_stack_position] + sub ecx,[operator_stack_base] + add ecx,16 + call reserve_workspace + mov [expression_end],edi + call peek_at_constituent_value + mov edi,[expression_end] + jc expression_line_end + cmp al,'(' + je open_subexpression + cmp al,')' + je close_subexpression + cmp al,30h + je store_expression_number + cmp al,22h + je store_expression_string + cmp al,2Eh + je store_expression_float + cmp al,1Ah + je expression_symbol + movzx eax,al + shl eax,2 + add eax,[operator_table] + mov edx,[eax] + test edx,edx + jz terminate_expression + xor ebx,ebx + mov ecx,edx + jmp identify_operator + expression_symbol: + test edx,edx + jz store_expression_symbol + mov ecx,edx + identify_operator: + cmp [ecx+ValueDefinition.type],VALTYPE_NATIVE_COMMAND + jne inspect_expression_symbol + test [ecx+ValueDefinition.attribute],OPERATOR_UNARY + setnz al + xor al,[operator_argument_expected] + jz store_expression_operator + mov ecx,[ecx+ValueDefinition.previous] + test ecx,ecx + jnz identify_operator + inspect_expression_symbol: + cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_COMPARATOR + je terminate_expression + store_expression_symbol: + cmp [operator_argument_expected],0 + je terminate_expression + mov eax,EXPR_SYMBOL_VALUE + stosd + mov eax,ebx + stosd + mov eax,edx + stosd + expression_symbol_stored: + mov [expression_end],edi + and [operator_argument_expected],0 + and [current_constituent],0 + jmp get_expression_element + store_expression_number: + cmp [operator_argument_expected],0 + je terminate_expression + mov eax,EXPR_NUMBER + value_pointer_in_expression: + cmp edx,[value_workspace.memory_end] + jae value_pointer_in_expression_ok + mov ebx,edx + sub ebx,[value_workspace.memory_start] + jc value_pointer_in_expression_ok + mov edx,ebx + or eax,EXPRF_VALUE_IN_WORKSPACE + value_pointer_in_expression_ok: + stosd + mov eax,edx + stosd + jmp expression_symbol_stored + store_expression_string: + cmp [operator_argument_expected],0 + je terminate_expression + mov eax,EXPR_STRING + jmp value_pointer_in_expression + store_expression_float: + cmp [operator_argument_expected],0 + je terminate_expression + mov eax,EXPR_FLOAT + jmp value_pointer_in_expression + store_expression_operator: + mov edx,[ecx+ValueDefinition.value] + mov cl,[ecx+ValueDefinition.attribute] + mov ch,cl + and cl,OPERATOR_PRECEDENCE_MASK + mov ebx,[operator_stack_position] + cmp [operator_argument_expected],0 + jne push_operator + establish_operator_precedence: + cmp ebx,[operator_stack] + je push_operator + cmp cl,[ebx-8] + ja push_operator + jb store_pending_operator + test ch,OPERATOR_RIGHT_ASSOCIATIVE + jnz push_operator + store_pending_operator: + sub ebx,8 + xor eax,eax + test byte [ebx+1],OPERATOR_UNARY + setnz al + shl eax,bsf EXPRF_OPERATOR_UNARY + mov al,EXPR_OPERATOR + stosd + mov eax,[ebx+4] + stosd + jmp establish_operator_precedence + push_operator: + call reserve_operator_stack + mov [ebx],ecx + mov [ebx+4],edx + add ebx,8 + mov [operator_stack_position],ebx + mov [expression_end],edi + or [operator_argument_expected],1 + and [current_constituent],0 + jmp get_expression_element + open_subexpression: + cmp [operator_argument_expected],0 + je terminate_expression + mov ebx,[operator_stack_position] + call reserve_operator_stack + mov eax,[operator_stack] + sub eax,[operator_stack_base] + mov [ebx],eax + add ebx,4 + mov [operator_stack],ebx + mov [operator_stack_position],ebx + and [current_constituent],0 + jmp get_expression_element + close_subexpression: + mov eax,[operator_stack] + cmp eax,[operator_stack_base] + je terminate_expression + cmp [operator_argument_expected],0 + je subexpression_closed + mov eax,EXPR_MISSING_ARGUMENT + stosd + subexpression_closed: + call store_remaining_operators + mov [expression_end],edi + sub ebx,4 + mov eax,[ebx] + add eax,[operator_stack_base] + mov [operator_stack],eax + mov [operator_stack_position],ebx + and [current_constituent],0 + jmp get_expression_element + expression_line_end: + and [current_constituent],0 + terminate_expression: + cmp [operator_argument_expected],0 + je close_expression + mov eax,[operator_stack_position] + cmp eax,[operator_stack] + jne expression_terminated_prematurely + mov eax,edi + sub eax,[expression_workspace.memory_start] + cmp eax,[expression_position] + je close_expression + expression_terminated_prematurely: + mov eax,EXPR_MISSING_ARGUMENT + stosd + close_expression: + call store_remaining_operators + xor ecx,ecx + cmp ebx,[operator_stack_base] + jne forcibly_close_subexpressions + expression_parsed: + xor eax,eax + stosd + retn + forcibly_close_subexpressions: + sub ebx,4 + mov eax,[ebx] + add eax,[operator_stack_base] + mov [operator_stack],eax + cmp [leave_opening_parentheses],0 + je internal_parenthesis + cmp eax,ebx + je external_parenthesis + internal_parenthesis: + mov eax,EXPR_MISSING_PARENTHESIS + inc ecx + rep stosd + mov [operator_stack_position],ebx + call store_remaining_operators + cmp ebx,[operator_stack_base] + jne forcibly_close_subexpressions + jmp expression_parsed + external_parenthesis: + inc ecx + cmp ebx,[operator_stack_base] + jne forcibly_close_subexpressions + jmp expression_parsed + reserve_operator_stack: + mov eax,[operator_stack_end] + sub eax,8 + cmp ebx,eax + jbe operator_stack_ready + push edx + mov eax,[operator_stack_base] + sub ebx,eax + sub [operator_stack],eax + mov ecx,[operator_stack_end] + sub ecx,eax + add ecx,8 + call grow_stack + add ebx,eax + add [operator_stack],eax + mov [operator_stack_base],eax + add eax,ecx + mov [operator_stack_end],eax + pop edx + operator_stack_ready: + retn + store_remaining_operators: + mov ebx,[operator_stack_position] + store_operator: + cmp ebx,[operator_stack] + je remaining_operators_stored + sub ebx,8 + xor eax,eax + test byte [ebx+1],OPERATOR_UNARY + setnz al + shl eax,bsf EXPRF_OPERATOR_UNARY + mov al,EXPR_OPERATOR + stosd + mov eax,[ebx+4] + stosd + jmp store_operator + remaining_operators_stored: + retn + +calculate_parsed_expression: +; in: +; esi - command sequence created by parse_expression +; edi - top of the stack in the calculation workspace +; out: +; cf set if expression had structural errors +; esi = pointer moved past the processed sequence +; edi - top of the updated stack +; when cf = 0: +; eax = non-zero if result is considered not yet known for resolving purposes + mov [expression_end],esi + mov eax,edi + sub eax,[calculation_workspace.memory_start] + mov [calculation_position],eax + cmp dword [esi],0 + je invalid_expression + calculation_loop: + mov esi,[expression_end] + lodsd + cmp al,EXPR_OPERATOR + je execute_operator + cmp al,EXPR_NUMBER + je push_literal + cmp al,EXPR_STRING + je push_literal + cmp al,EXPR_FLOAT + je push_literal + cmp al,EXPR_SYMBOL_VALUE + je push_symbol_value + cmp al,EXPR_SYMBOL + je push_symbol_current_value + cmp al,EXPR_POLYNOMIAL + je push_polynomial_literal + test eax,eax + jnz structural_error + ; clc + retn + execute_operator: + lodsd + mov [expression_end],esi + jmp eax + push_literal: + mov ebx,eax + mov edx,calculation_workspace + mov ecx,2*sizeof.ExpressionTerm + call reserve_workspace + lodsd + test ebx,EXPRF_CALM_LITERAL + jnz calm_literal_value + test ebx,EXPRF_VALUE_IN_WORKSPACE + jnz valid_literal_value + test eax,eax + jnz valid_literal_value + jmp invalid_number_in_expression + calm_literal_value: + add eax,[calm_literals] + valid_literal_value: + mov [edi+ExpressionTerm.attributes],ebx + mov [edi+ExpressionTerm.value],eax + xor eax,eax + mov [edi+ExpressionTerm.metadata],eax + mov [edi+sizeof.ExpressionTerm+ExpressionTerm.attributes],eax + add edi,2*sizeof.ExpressionTerm + mov [expression_end],esi + jmp calculation_loop + push_polynomial_literal: + ; occurring only in reduced CALM expressions + mov ebx,eax + lodsd + mov [expression_end],esi + test ebx,EXPRF_CALM_LITERAL + jz polynomial_value_ready + add eax,[calm_literals] + polynomial_value_ready: + xor esi,esi + mov ebx,eax + jmp push_polynomial + push_symbol_current_value: + ; occurring only in CALM expressions, entire expression workspace should be free to use + lodsd + test eax,eax + jz invalid_identifier_in_expression + mov ebx,eax + mov [expression_end],esi + call use_available_value + jc undefined_symbol_in_expression + mov al,[edx+ValueDefinition.type] + cmp al,VALTYPE_SYMBOLIC + jne identify_value_to_push + push esi edi + call clear_line_embeddings + xor esi,esi + xor ecx,ecx + call embed_symbolic_value + mov edi,[expression_workspace.memory_start] + and [leave_opening_parentheses],0 + call parse_expression + pop edi + call get_constituent_value + jnc invalid_subexpression + mov esi,[expression_workspace.memory_start] + push [calculation_position] + call calculate_parsed_expression + pop [calculation_position] + jc invalid_subexpression + pop [expression_end] + test eax,eax + jnz unknown_result + jmp calculation_loop + invalid_subexpression: + pop [expression_end] + mov edx,_invalid_expression + call register_error + jmp unknown_result + push_symbol_value: + lodsd + test eax,eax + jz invalid_identifier_in_expression + mov ebx,eax + lodsd + mov edx,eax + call mark_symbol_as_used + mov [expression_end],esi + test edx,edx + jz undefined_symbol_in_expression + mov al,[edx+ValueDefinition.type] + identify_value_to_push: + cmp al,VALTYPE_NUMERIC + je push_numeric_symbol + cmp al,VALTYPE_ELEMENT + je push_element + cmp al,VALTYPE_AREA + je push_area + cmp al,VALTYPE_STRING + je push_string + cmp al,VALTYPE_FLOAT + je push_float + cmp al,VALTYPE_PLAIN + je push_plain_symbol + cmp al,VALTYPE_NATIVE_FUNCTION + jne invalid_symbol_in_expression + jmp [edx+ValueDefinition.value] + push_numeric_symbol: + xor esi,esi + test [edx+ValueDefinition.flags],VAL_SHIFTABLE + jz predicted_shift_ok + mov eax,[edx+ValueDefinition.pass] + cmp eax,[current_pass] + je predicted_shift_ok + mov esi,[predicted_shift] + predicted_shift_ok: + mov ebx,[edx+ValueDefinition.value] + mov eax,ebx + add eax,[edx+ValueDefinition.value_length] + push_polynomial: + push eax edi + mov edx,calculation_workspace + mov ecx,2*sizeof.ExpressionTerm + call reserve_workspace + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + mov [edi+ExpressionTerm.value],ebx + test esi,esi + jz push_numeric_terms + or [next_pass_needed],1 + mov ecx,temporary_value + mov dword [ecx],4 + mov dword [ecx+4],esi + lea esi,[edi+sizeof.ExpressionTerm] + mov [esi+ExpressionTerm.attributes],EXPR_NUMBER + mov [esi+ExpressionTerm.value],ecx + push ebx + call add_term_values + pop ebx + push_numeric_terms: + add edi,sizeof.ExpressionTerm + mov edx,calculation_workspace + mov ecx,sizeof.ExpressionTerm + call reserve_workspace + mov eax,[ebx] + lea ebx,[ebx+4+eax] + mov eax,[ebx] + test eax,eax + jz numeric_terms_pushed + mov eax,[ebx] + mov [edi+ExpressionTerm.metadata],eax + add ebx,4 + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + mov [edi+ExpressionTerm.value],ebx + jmp push_numeric_terms + numeric_terms_pushed: + pop edx ecx + sub ecx,8 + cmp ebx,ecx + jbe symbol_metadata_ok + xor ebx,ebx + symbol_metadata_ok: + mov [edx+ExpressionTerm.metadata],ebx + xor eax,eax + mov [edi+ExpressionTerm.attributes],eax + add edi,sizeof.ExpressionTerm + jmp calculation_loop + push_plain_symbol: + mov ebx,[edx+ValueDefinition.value] + push_plain_value: + mov edx,calculation_workspace + mov ecx,2*sizeof.ExpressionTerm + call reserve_workspace + mov esi,edi + mov edx,value_workspace + mov edi,[edx+Workspace.memory_start] + add edi,[value_position] + mov ecx,4+4 + call reserve_workspace + xor eax,eax + test ebx,ebx + jz number_length_ok + bsr eax,ebx + inc al + shr al,3 + inc al + number_length_ok: + stosd + mov [edi],ebx + add eax,edi + sub eax,[value_workspace.memory_start] + xchg eax,[value_position] + mov edi,esi + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + EXPRF_VALUE_IN_WORKSPACE + mov [edi+ExpressionTerm.value],eax + xor eax,eax + mov [edi+ExpressionTerm.metadata],eax + mov [edi+sizeof.ExpressionTerm+ExpressionTerm.attributes],eax + add edi,2*sizeof.ExpressionTerm + jmp calculation_loop + push_string: + mov al,EXPR_STRING + push_value: + mov [term_type],al + mov ebx,[edx+ValueDefinition.value] + mov edx,calculation_workspace + mov ecx,2*sizeof.ExpressionTerm + call reserve_workspace + mov [edi+ExpressionTerm.value],ebx + xor eax,eax + mov [edi+ExpressionTerm.metadata],eax + mov [edi+sizeof.ExpressionTerm+ExpressionTerm.attributes],eax + mov al,[term_type] + mov [edi+ExpressionTerm.attributes],eax + add edi,2*sizeof.ExpressionTerm + jmp calculation_loop + push_float: + mov al,EXPR_FLOAT + jmp push_value + push_area: + mov esi,edx + jmp push_variable_term + push_element: + xor esi,esi + push_variable_term: + mov edx,calculation_workspace + mov ecx,3*sizeof.ExpressionTerm + call reserve_workspace + mov eax,EXPR_NUMBER + mov [edi+ExpressionTerm.attributes],eax + mov [edi+ExpressionTerm.metadata],esi + mov [edi+sizeof.ExpressionTerm+ExpressionTerm.attributes],eax + mov [edi+ExpressionTerm.value],zero_value + mov [edi+sizeof.ExpressionTerm+ExpressionTerm.value],singular_value + mov [edi+sizeof.ExpressionTerm+ExpressionTerm.metadata],ebx + and [edi+2*sizeof.ExpressionTerm+ExpressionTerm.attributes],0 + add edi,3*sizeof.ExpressionTerm + jmp calculation_loop + base_address_value: + mov edx,[current_area] + area_address_value: + mov ebx,[edx+ValueDefinition.value] + add ebx,sizeof.AreaHeader + push_numeric_value: + mov edx,calculation_workspace + mov ecx,sizeof.ExpressionTerm + call reserve_workspace + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + mov [edi+ExpressionTerm.value],ebx + and [edi+ExpressionTerm.metadata],0 + jmp push_variable_terms + truncated_address_value: + xor esi,esi + jmp push_current_address + current_address_value: + or esi,-1 + push_current_address: + mov edx,calculation_workspace + mov ecx,2*sizeof.ExpressionTerm + call reserve_workspace + mov eax,[current_area] + mov ebx,[eax+ValueDefinition.value] + mov ecx,[eax+ValueDefinition.value_length] + sub ecx,[ebx+AreaHeader.base_address_length] + sub ecx,sizeof.AreaHeader + and esi,[ebx+AreaHeader.uninitialized_length] + add ecx,esi + add ebx,sizeof.AreaHeader + mov esi,temporary_value + mov dword [esi],4 + mov [esi+4],ecx + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + mov [edi+ExpressionTerm.value],esi + and [edi+ExpressionTerm.metadata],0 + lea esi,[edi+sizeof.ExpressionTerm] + mov [esi+ExpressionTerm.attributes],EXPR_NUMBER + mov [esi+ExpressionTerm.value],ebx + call add_term_values + mov ebx,[esi+ExpressionTerm.value] + push_variable_terms: + mov eax,[ebx] + lea ebx,[ebx+4+eax] + convert_variable_term: + add edi,sizeof.ExpressionTerm + mov edx,calculation_workspace + mov ecx,sizeof.ExpressionTerm + call reserve_workspace + mov eax,[ebx] + test eax,eax + jz variable_terms_converted + mov [edi+ExpressionTerm.metadata],eax + add ebx,4 + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + mov [edi+ExpressionTerm.value],ebx + mov eax,[ebx] + lea ebx,[ebx+4+eax] + jmp convert_variable_term + variable_terms_converted: + mov [edi+ExpressionTerm.attributes],eax + add edi,sizeof.ExpressionTerm + jmp calculation_loop + truncated_position_value: + call prepare_to_push_computed_value + call get_output_length + jmp push_output_position + prepare_to_push_computed_value: + mov edx,calculation_workspace + mov ecx,2*sizeof.ExpressionTerm + call reserve_workspace + mov esi,edi + mov edx,value_workspace + mov edi,[edx+Workspace.memory_start] + add edi,[value_position] + mov ecx,4+8 + call reserve_workspace + retn + current_position_value: + call prepare_to_push_computed_value + call get_output_position + push_output_position: + mov edi,[value_workspace.memory_start] + add edi,[value_position] + push_computed_value: + mov ecx,eax + or ecx,edx + jz computed_value_length_ok + bsr ecx,edx + jnz long_computed_value + bsr ecx,eax + inc cl + shr cl,3 + inc cl + jmp computed_value_length_ok + long_computed_value: + inc cl + shr cl,3 + add cl,1+4 + computed_value_length_ok: + mov [edi],ecx + add edi,4 + stosd + mov eax,edx + stosd + add ecx,edi + sub ecx,[value_workspace.memory_start] + xchg ecx,[value_position] + mov edi,esi + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + EXPRF_VALUE_IN_WORKSPACE + mov [edi+ExpressionTerm.value],ecx + xor eax,eax + mov [edi+ExpressionTerm.metadata],eax + mov [edi+sizeof.ExpressionTerm+ExpressionTerm.attributes],eax + add edi,2*sizeof.ExpressionTerm + jmp calculation_loop + current_time_value: + call prepare_to_push_computed_value + call get_timestamp + jmp push_computed_value + current_line_number_value: + call prepare_to_push_computed_value + call get_file_source_entry + mov eax,[ebx+SourceEntry.line_number] + xor edx,edx + jmp push_computed_value + current_file_name_value: + mov edx,calculation_workspace + mov ecx,2*sizeof.ExpressionTerm + call reserve_workspace + push edi + call get_file_source_entry + jmp push_file_name_value + main_file_name_value: + mov edx,calculation_workspace + mov ecx,2*sizeof.ExpressionTerm + call reserve_workspace + push edi + mov ebx,[source_context] + lea ebx,[ebx+sizeof.SourceContext] + push_file_name_value: + mov esi,[ebx+SourceEntry.name] + xor ecx,ecx + cmp [ebx+SourceEntry.type],SOURCE_FILE + jne file_name_length_ok + mov ecx,[ebx+SourceEntry.name_length] + test ecx,ecx + jnz file_name_length_ok + mov edi,esi + xor al,al + dec ecx + repne scasb + add ecx,2 + neg ecx + file_name_length_ok: + mov ebx,ecx + add ecx,4 + mov edx,value_workspace + mov edi,[edx+Workspace.memory_start] + add edi,[value_position] + call reserve_workspace + mov eax,ebx + stosd + mov ecx,ebx + rep movsb + mov eax,edi + sub eax,[value_workspace.memory_start] + xchg eax,[value_position] + pop edi + mov [edi+ExpressionTerm.attributes],EXPR_STRING + EXPRF_VALUE_IN_WORKSPACE + mov [edi+ExpressionTerm.value],eax + xor eax,eax + mov [edi+ExpressionTerm.metadata],eax + mov [edi+sizeof.ExpressionTerm+ExpressionTerm.attributes],eax + add edi,2*sizeof.ExpressionTerm + jmp calculation_loop + structural_error: + cmp eax,EXPR_MISSING_PARENTHESIS + je expression_missing_parenthesis + invalid_expression: + mov edx,_invalid_expression + call register_error + stc + retn + expression_missing_parenthesis: + mov edx,_missing_closing_parenthesis + call register_error + stc + retn + undefined_symbol_in_expression: + cmp [next_pass_needed],0 + jne unknown_result + mov edx,_undefined_symbol + jmp error_causing_unknown_result + invalid_identifier_in_expression: + mov edx,_invalid_identifier + jmp error_causing_unknown_result + invalid_number_in_expression: + mov edx,_invalid_number + jmp error_causing_unknown_result + invalid_symbol_in_expression: + mov edx,_invalid_symbol_value + error_causing_unknown_result: + call register_error + unknown_result: + mov eax,edi + mov edi,[calculation_position] + add edi,[calculation_workspace.memory_start] + cmp edi,eax + jb unknown_result_terms_ready + mov edi,eax + mov edx,calculation_workspace + mov ecx,2*sizeof.ExpressionTerm + call reserve_workspace + xor eax,eax + mov [edi+ExpressionTerm.metadata],eax + mov [edi+sizeof.ExpressionTerm+ExpressionTerm.attributes],eax + unknown_result_terms_ready: + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + mov [edi+ExpressionTerm.value],zero_value + add edi,2*sizeof.ExpressionTerm + mov esi,[expression_end] + skip_expression: + lodsd + cmp al,EXPR_OPERATOR + je skip_dword + cmp al,EXPR_NUMBER + je skip_dword + cmp al,EXPR_STRING + je skip_dword + cmp al,EXPR_FLOAT + je skip_dword + cmp al,EXPR_SYMBOL + je skip_dword + cmp al,EXPR_SYMBOL_VALUE + je skip_two_dwords + cmp al,EXPR_POLYNOMIAL + je skip_dword + test eax,eax + jnz invalid_expression + inc eax + ; clc + retn + skip_two_dwords: + add esi,4 + skip_dword: + add esi,4 + jmp skip_expression + +pop_terms: +; in: +; edi = top of the stack +; out: +; edi = new top of the stack, at the same time a pointer to the first term of retrieved linear polynomial +; cf set when there were no more entries on the stack +; preserves: eax, ebx, ecx, edx, esi + cmp edi,[calculation_workspace.memory_start] + je nothing_to_pop + sub edi,sizeof.ExpressionTerm + find_first_term: + cmp edi,[calculation_workspace.memory_start] + je first_term_found + cmp [edi-sizeof.ExpressionTerm+ExpressionTerm.attributes],0 + je first_term_found + sub edi,sizeof.ExpressionTerm + jmp find_first_term + first_term_found: + clc + retn + nothing_to_pop: + and [edi+ExpressionTerm.metadata],0 + and [edi+sizeof.ExpressionTerm+ExpressionTerm.attributes],0 + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + mov [edi+ExpressionTerm.value],zero_value + stc + retn + +calculate_to_number: + call pop_terms + cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT + je single_term_result + make_terms_numeric: + mov eax,[edi+ExpressionTerm.attributes] + test eax,eax + jz all_terms_numeric + call get_numeric_term_value + add edi,sizeof.ExpressionTerm + jmp make_terms_numeric + all_terms_numeric: + add edi,sizeof.ExpressionTerm + jmp calculation_loop + +calculate_to_string: + call pop_terms + call get_string_term_value + jmp single_term_result + +calculate_to_float: + call pop_terms + call get_float_term_value + jmp single_term_result + +extract_integer_part: + call pop_terms + call truncate_term_value + jmp single_term_result + +calculate_neg: + call pop_terms + cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT + je negate_float_term + call negate_term_value + add edi,sizeof.ExpressionTerm + negate_element_terms: + cmp [edi+ExpressionTerm.attributes],0 + je all_terms_negated + cmp [edi+ExpressionTerm.metadata],0 + je negate_next_term + call negate_term_value + negate_next_term: + add edi,sizeof.ExpressionTerm + jmp negate_element_terms + all_terms_negated: + add edi,sizeof.ExpressionTerm + jmp calculation_loop + negate_float_term: + call prepare_altered_float_term + xor [ebx+FloatData.attributes],FLOAT_NEGATIVE + single_term_result: + add edi,sizeof.ExpressionTerm + mov eax,edi + call check_for_excess_terms + jnc single_term_result_ok + mov edx,_misused_variable_term + call register_error + single_term_result_ok: + and [edi+ExpressionTerm.attributes],0 + add edi,sizeof.ExpressionTerm + jmp calculation_loop + check_for_excess_terms: + cmp [eax+ExpressionTerm.attributes],0 + je no_excess_terms + cmp [eax+ExpressionTerm.metadata],0 + jne excess_terms + add eax,sizeof.ExpressionTerm + jne check_for_excess_terms + no_excess_terms: + clc + retn + excess_terms: + stc + retn + prepare_altered_float_term: + mov ebx,edi + mov edx,value_workspace + mov edi,[edx+Workspace.memory_start] + add edi,[value_position] + mov ecx,sizeof.FloatData + call reserve_workspace + xchg edi,ebx + call get_term_value + xchg edi,ebx + mov esi,edx + assert sizeof.FloatData and 11b = 0 + mov ecx,sizeof.FloatData shr 2 + rep movsd + mov eax,edi + sub eax,[value_workspace.memory_start] + xchg eax,[value_position] + sub edi,sizeof.FloatData + xchg edi,ebx + mov [edi+ExpressionTerm.value],eax + or [edi+ExpressionTerm.attributes],EXPRF_VALUE_IN_WORKSPACE + retn + +calculate_add: + call pop_terms + mov esi,edi + call pop_terms + cmp byte [esi+ExpressionTerm.attributes],EXPR_FLOAT + je add_float_terms + cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT + je add_float_terms + cmp [edi+ExpressionTerm.metadata],0 + jne add_constant_terms + mov eax,[esi+ExpressionTerm.metadata] + mov [edi+ExpressionTerm.metadata],eax + add_constant_terms: + call add_term_values + add esi,sizeof.ExpressionTerm + add_variable_terms: + cmp [esi+ExpressionTerm.attributes],0 + je all_terms_added + mov eax,[esi+ExpressionTerm.metadata] + test eax,eax + jz add_next_term + push edi + find_element_to_add_to: + add edi,sizeof.ExpressionTerm + cmp [edi+ExpressionTerm.attributes],0 + je attach_new_element + cmp eax,[edi+ExpressionTerm.metadata] + jne find_element_to_add_to + push esi + call add_term_values + jnz variable_term_added + and [edi+ExpressionTerm.metadata],0 + variable_term_added: + pop esi edi + add_next_term: + add esi,sizeof.ExpressionTerm + jmp add_variable_terms + attach_new_element: + assert sizeof.ExpressionTerm and 11b = 0 + mov ecx,sizeof.ExpressionTerm shr 2 + rep movsd + and [edi+ExpressionTerm.attributes],0 + pop edi + jmp add_variable_terms + all_terms_added: + add edi,sizeof.ExpressionTerm + cmp [edi+ExpressionTerm.attributes],0 + jne all_terms_added + add edi,sizeof.ExpressionTerm + jmp calculation_loop + add_float_terms: + mov eax,add_floats + operation_on_float_terms: + push esi edi eax + mov ebx,edi + mov edx,value_workspace + mov edi,[edx+Workspace.memory_start] + add edi,[value_position] + mov ecx,sizeof.FloatData + call reserve_workspace + lea ecx,[edi+sizeof.FloatData] + sub ecx,[edx+Workspace.memory_start] + mov [value_position],ecx + xchg edi,ebx + call get_float_term_value + xchg edi,esi + call get_float_term_value + mov edi,esi + mov esi,edx + call get_term_value + mov edi,ebx + mov ebx,edx + pop eax + call eax + mov ebx,edi + sub ebx,[value_workspace.memory_start] + test [edi+FloatData.attributes],FLOAT_INFINITE or FLOAT_INDETERMINATE or FLOAT_UNDERFLOW + jz operation_on_float_terms_ok + mov edx,_indeterminate_result + call register_error + xor eax,eax + mov [edi+FloatData.attributes],eax + add edi,FloatData.mantissa + mov ecx,MANTISSA_SEGMENTS + rep stosd + operation_on_float_terms_ok: + pop edi esi + mov [edi+ExpressionTerm.value],ebx + mov [edi+ExpressionTerm.attributes],EXPR_FLOAT + EXPRF_VALUE_IN_WORKSPACE + and [edi+ExpressionTerm.metadata],0 + finish_calculation_on_single_terms: + add edi,sizeof.ExpressionTerm + mov eax,edi + call check_for_excess_terms + jc single_terms_violation + lea eax,[esi+sizeof.ExpressionTerm] + call check_for_excess_terms + jnc single_terms_ok + single_terms_violation: + mov edx,_misused_variable_term + call register_error + single_terms_ok: + and [edi+ExpressionTerm.attributes],0 + add edi,sizeof.ExpressionTerm + jmp calculation_loop + +calculate_sub: + call pop_terms + mov esi,edi + call pop_terms + cmp byte [esi+ExpressionTerm.attributes],EXPR_FLOAT + je subtract_float_terms + cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT + je subtract_float_terms + cmp [edi+ExpressionTerm.metadata],0 + jne subtract_constant_terms + mov eax,[esi+ExpressionTerm.metadata] + mov [edi+ExpressionTerm.metadata],eax + subtract_constant_terms: + call subtract_term_values + add esi,sizeof.ExpressionTerm + subtract_variable_terms: + cmp [esi+ExpressionTerm.attributes],0 + je all_terms_subtracted + mov eax,[esi+ExpressionTerm.metadata] + test eax,eax + jz subtract_next_term + push edi + find_element_to_subtract_from: + add edi,sizeof.ExpressionTerm + cmp [edi+ExpressionTerm.attributes],0 + je attach_negated_element + cmp eax,[edi+ExpressionTerm.metadata] + jne find_element_to_subtract_from + push esi + call subtract_term_values + jnz variable_term_subtracted + and [edi+ExpressionTerm.metadata],0 + variable_term_subtracted: + pop esi edi + subtract_next_term: + add esi,sizeof.ExpressionTerm + jmp subtract_variable_terms + attach_negated_element: + assert sizeof.ExpressionTerm and 11b = 0 + mov ecx,sizeof.ExpressionTerm shr 2 + rep movsd + sub edi,sizeof.ExpressionTerm + call negate_term_value + add edi,sizeof.ExpressionTerm + and [edi+ExpressionTerm.attributes],0 + pop edi + jmp subtract_variable_terms + all_terms_subtracted: + add edi,sizeof.ExpressionTerm + cmp [edi+ExpressionTerm.attributes],0 + jne all_terms_subtracted + add edi,sizeof.ExpressionTerm + jmp calculation_loop + subtract_float_terms: + mov eax,subtract_floats + jmp operation_on_float_terms + +calculate_mul: + call pop_terms + mov esi,edi + call pop_terms + cmp byte [esi+ExpressionTerm.attributes],EXPR_FLOAT + je multiply_float_terms + cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT + je multiply_float_terms + cmp [esi+sizeof.ExpressionTerm+ExpressionTerm.attributes],0 + jne multiply_by_destination + multiply_terms: + call multiply_term_values + jnz multiply_next_term + and [edi+ExpressionTerm.metadata],0 + multiply_next_term: + add edi,sizeof.ExpressionTerm + cmp [edi+ExpressionTerm.attributes],0 + je terms_multiplied + jmp multiply_terms + terms_multiplied: + add edi,sizeof.ExpressionTerm + jmp calculation_loop + multiply_by_destination: + and [esi+ExpressionTerm.metadata],0 + cmp [edi+sizeof.ExpressionTerm+ExpressionTerm.attributes],0 + je duplicate_destination_constant_term + mov edx,_nonlinear_polynomial + call register_error + duplicate_destination_constant_term: + mov eax,[edi+ExpressionTerm.attributes] + mov edx,[edi+ExpressionTerm.value] + mov [edi+sizeof.ExpressionTerm+ExpressionTerm.attributes],eax + mov [edi+sizeof.ExpressionTerm+ExpressionTerm.value],edx + multiply_source_terms: + mov eax,[esi+ExpressionTerm.metadata] + mov [edi+ExpressionTerm.metadata],eax + call multiply_term_values + jnz multiply_next_source_term + and [edi+ExpressionTerm.metadata],0 + multiply_next_source_term: + add esi,sizeof.ExpressionTerm + add edi,sizeof.ExpressionTerm + cmp [esi+ExpressionTerm.attributes],0 + je source_terms_multiplied + cmp [esi+sizeof.ExpressionTerm+ExpressionTerm.attributes],0 + je multiply_source_terms + jmp duplicate_destination_constant_term + source_terms_multiplied: + and [edi+ExpressionTerm.attributes],0 + jmp terms_multiplied + multiply_float_terms: + mov eax,multiply_floats + jmp operation_on_float_terms + +calculate_div: + call pop_terms + mov eax,edi + call check_for_excess_terms + jnc divisor_ok + mov edx,_misused_variable_term + call register_error + divisor_ok: + mov esi,edi + call pop_terms + cmp byte [esi+ExpressionTerm.attributes],EXPR_FLOAT + je divide_float_terms + cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT + je divide_float_terms + and [edi+ExpressionTerm.metadata],0 + mov eax,[esi+ExpressionTerm.attributes] + mov edx,[esi+ExpressionTerm.value] + mov [esi+sizeof.ExpressionTerm+ExpressionTerm.attributes],eax + mov [esi+sizeof.ExpressionTerm+ExpressionTerm.value],edx + call divide_term_values + divide_variable_term: + add edi,sizeof.ExpressionTerm + cmp [edi+ExpressionTerm.attributes],0 + je division_done + cmp [edi+ExpressionTerm.metadata],0 + je divide_variable_term + mov eax,[esi+sizeof.ExpressionTerm+ExpressionTerm.attributes] + mov edx,[esi+sizeof.ExpressionTerm+ExpressionTerm.value] + mov [esi+ExpressionTerm.attributes],eax + mov [esi+ExpressionTerm.value],edx + call divide_term_values + jz divide_variable_term + mov edx,_subdivided_variable_term + call register_error + jmp divide_variable_term + division_done: + add edi,sizeof.ExpressionTerm + jmp calculation_loop + divide_float_terms: + mov eax,divide_floats + jmp operation_on_float_terms + +calculate_mod: + call pop_terms + mov esi,edi + call pop_terms + call divide_term_values + and [esi+ExpressionTerm.metadata],0 + assert sizeof.ExpressionTerm and 11b = 0 + mov ecx,sizeof.ExpressionTerm shr 2 + rep movsd + mov eax,edi + call check_for_excess_terms + jc mod_variable_term + mov eax,esi + call check_for_excess_terms + jnc mod_terms_ok + mod_variable_term: + mov edx,_misused_variable_term + call register_error + mod_terms_ok: + and [edi+ExpressionTerm.attributes],0 + add edi,sizeof.ExpressionTerm + jmp calculation_loop + +calculate_not: + call pop_terms + call invert_term_value_bits + jmp single_term_result + +calculate_xor: + call pop_terms + mov esi,edi + call pop_terms + call bitwise_add_term_values + finish_bitwise_calculation: + cmp [edi+ExpressionTerm.metadata],0 + jne finish_calculation_on_single_terms + mov eax,[esi+ExpressionTerm.metadata] + mov [edi+ExpressionTerm.metadata],eax + jmp finish_calculation_on_single_terms + +calculate_and: + call pop_terms + mov esi,edi + call pop_terms + call bitwise_multiply_term_values + jmp finish_bitwise_calculation + +calculate_or: + call pop_terms + mov esi,edi + call pop_terms + call bitwise_inclusive_or_of_term_values + jmp finish_bitwise_calculation + +calculate_shl: + call pop_terms + call get_numeric_term_value + mov ecx,5 + call fit_value + js negative_shift_left + jc huge_shift_left + shift_left: + mov esi,edi + check_shift_left_argument: + add edi,sizeof.ExpressionTerm + cmp [edi+ExpressionTerm.attributes],0 + je shift_left_argument_ok + cmp [edi+ExpressionTerm.metadata],0 + je check_shift_left_argument + mov edx,_misused_variable_term + call register_error + shift_left_argument_ok: + mov edi,esi + call pop_terms + and [edi+ExpressionTerm.metadata],0 + cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT + je shift_floating_point_left + shift_term_left: + mov eax,[esi] + mov dl,[esi+4] + call shift_term_value_left + shift_variable_term_left: + add edi,sizeof.ExpressionTerm + cmp [edi+ExpressionTerm.attributes],0 + je shift_done + cmp [edi+ExpressionTerm.metadata],0 + je shift_variable_term_left + jmp shift_term_left + shift_done: + add edi,sizeof.ExpressionTerm + jmp calculation_loop + negative_shift_left: + jc huge_shift_right + not byte [edi+4] + neg dword [edi] + jc shift_right + inc byte [edi+4] + jnz shift_right + huge_shift_right: + or eax,-1 + mov [edi],eax + mov [edi+4],al + jmp shift_right + shift_floating_point_left: + push esi + call prepare_altered_float_term + pop esi + xchg esi,ebx + call get_float_unnormalization + jc single_term_result + mov eax,[esi+FloatData.exponent] + cdq + add eax,[ebx] + movzx ebx,byte [ebx+4] + adc ebx,edx + mov [esi+FloatData.exponent],eax + cdq + cmp ebx,edx + jne floating_point_over_boundary + test ecx,ecx + jz single_term_result + push edi + mov edi,esi + and [mantissa_tail],0 + call normalize_float + pop edi + jmp single_term_result + floating_point_over_boundary: + jecxz floating_point_out_of_range + test ebx,ebx + jnz floating_point_out_of_range + mov ecx,7FFFFFFFh + sub eax,ecx + mov [esi+FloatData.exponent],ecx + push eax edi + mov edi,esi + and [mantissa_tail],0 + call normalize_float + pop edi ecx + mov eax,[esi+FloatData.exponent] + cdq + add eax,ecx + js floating_point_out_of_range + adc edx,0 + jnz floating_point_out_of_range + mov [esi+FloatData.exponent],eax + jmp single_term_result + floating_point_out_of_range: + mov edx,_value_out_of_range + call register_error + jmp single_term_result + +calculate_shr: + call pop_terms + call get_numeric_term_value + mov ecx,5 + call fit_value + js negative_shift_right + jc huge_shift_right + shift_right: + mov esi,edi + check_shift_right_argument: + add edi,sizeof.ExpressionTerm + cmp [edi+ExpressionTerm.attributes],0 + je shift_right_argument_ok + cmp [edi+ExpressionTerm.metadata],0 + je check_shift_right_argument + mov edx,_misused_variable_term + call register_error + shift_right_argument_ok: + mov edi,esi + call pop_terms + and [edi+ExpressionTerm.metadata],0 + cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT + je shift_floating_point_right + shift_term_right: + mov eax,[esi] + mov dl,[esi+4] + call shift_term_value_right + shift_variable_term_right: + add edi,sizeof.ExpressionTerm + cmp [edi+ExpressionTerm.attributes],0 + je shift_done + cmp [edi+ExpressionTerm.metadata],0 + je shift_variable_term_right + call get_term_value + mov ecx,[esi] + mov bl,cl + mov al,[esi+4] + shrd ecx,eax,3 + shr al,3 + jnz not_exact_shift + cmp ecx,[edx] + jae not_exact_shift + xchg edi,edx + add edi,4 + xor al,al + repe scasb + xchg edi,edx + jne not_exact_shift + mov cl,bl + and cl,8-1 + jz shift_term_right + mov al,1 + shl al,cl + dec al + test [edx],al + jz shift_term_right + not_exact_shift: + mov edx,_subdivided_variable_term + call register_error + jmp shift_variable_term_right + negative_shift_right: + jc huge_shift_left + not byte [edi+4] + neg dword [edi] + jc shift_left + inc byte [edi+4] + jnz shift_left + huge_shift_left: + or eax,-1 + mov [edi],eax + mov [edi+4],al + jmp shift_left + shift_floating_point_right: + push esi + call prepare_altered_float_term + pop esi + xchg esi,ebx + call get_float_unnormalization + jc single_term_result + mov eax,[esi+FloatData.exponent] + cdq + sub eax,[ebx] + movzx ecx,byte [ebx+4] + sbb edx,ecx + mov ecx,edx + mov [esi+FloatData.exponent],eax + cdq + cmp ecx,edx + je single_term_result + cmp ecx,-1 + jne floating_point_out_of_range + mov [esi+FloatData.exponent],-80000000h + mov ecx,eax + neg ecx + push edi + mov edi,esi + and [mantissa_tail],0 + call unnormalize_float + pop edi + mov [esi+FloatData.exponent],-80000000h + call get_float_unnormalization + jc floating_point_out_of_range + jmp single_term_result + +calculate_bsf: + call pop_terms + mov esi,edi + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov ecx,10 + mov edx,value_workspace + call reserve_workspace + call find_first_set_bit_in_term_value + jz bit_scan_result_undefined + movzx edx,dl + bit_scan_result_ready: + mov ebx,edi + and dword [edi],0 + add edi,4 + stosd + mov ax,dx + stosw + mov ecx,6 + optimize_result_value: + cmp [edi-1],dh + jne result_value_ready + movsx eax,byte [edi-2] + cmp ah,dh + jne result_value_ready + dec edi + loop optimize_result_value + result_value_ready: + mov [ebx],ecx + sub edi,[value_workspace.memory_start] + mov [value_position],edi + sub ebx,[value_workspace.memory_start] + mov edi,esi + mov [edi+ExpressionTerm.value],ebx + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + EXPRF_VALUE_IN_WORKSPACE + and [edi+ExpressionTerm.metadata],0 + jmp single_term_result + +calculate_bsr: + call pop_terms + mov esi,edi + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov ecx,10 + mov edx,value_workspace + call reserve_workspace + cmp byte [esi+ExpressionTerm.attributes],EXPR_FLOAT + je extract_float_exponent + call find_last_set_bit_in_term_value + jc bit_scan_result_undefined + movzx edx,dl + jmp bit_scan_result_ready + bit_scan_result_undefined: + mov edi,esi + mov edx,_indeterminate_result + call register_error + mov [edi+ExpressionTerm.value],zero_value + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + and [edi+ExpressionTerm.metadata],0 + jmp single_term_result + extract_float_exponent: + mov edi,esi + mov [destination_term],edi + call get_term_value + mov esi,edx + call get_float_unnormalization + jc exponent_indeterminate + mov eax,[esi+FloatData.exponent] + cdq + sub eax,ecx + sbb edx,0 + exponent_extracted: + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov esi,[destination_term] + jmp bit_scan_result_ready + exponent_indeterminate: + mov edx,_indeterminate_result + call register_error + xor eax,eax + xor edx,edx + jmp exponent_extracted + +calculate_bswap: + call pop_terms + call get_numeric_term_value + mov ecx,4 + call fit_value + js bswap_argument_out_of_range + jc bswap_argument_out_of_range + mov esi,edi + mov eax,edi + call check_for_excess_terms + jnc bswap_argument_ok + mov edx,_misused_variable_term + call register_error + bswap_argument_ok: + call pop_terms + and [edi+ExpressionTerm.metadata],0 + mov ebx,[esi] + call reverse_term_value_bytes + jmp single_term_result + bswap_argument_out_of_range: + mov edx,_value_out_of_range + call register_error + call pop_terms + jmp single_term_result + +calculate_bappend: + call pop_terms + mov [source_term],edi + call pop_terms + mov [destination_term],edi + call get_string_term_value + mov ecx,[edx] + mov edi,[source_term] + call get_string_term_value + add ecx,[edx] + add ecx,4 + mov edi,[value_position] + mov edx,value_workspace + add edi,[edx+Workspace.memory_start] + call reserve_workspace + push edi + mov edi,[destination_term] + call get_term_value + mov [edi+ExpressionTerm.attributes],EXPR_STRING + EXPRF_VALUE_IN_WORKSPACE + mov eax,[value_position] + mov [edi+ExpressionTerm.value],eax + pop edi + mov esi,edx + mov ecx,[esi] + movsd + rep movsb + push edi + mov edi,[source_term] + call get_term_value + pop edi + mov esi,edx + lodsd + mov ecx,eax + rep movsb + mov edx,[value_workspace.memory_start] + sub edi,edx + xchg [value_position],edi + add edi,edx + add [edi],eax + mov esi,[source_term] + mov edi,[destination_term] + jmp finish_calculation_on_single_terms + +count_bytes: + call pop_terms + call get_string_term_value + mov esi,edi + add esi,sizeof.ExpressionTerm + mov eax,esi + call check_for_excess_terms + mov ebx,[edx] + jnc push_plain_value + mov edx,_misused_variable_term + call register_error + jmp push_plain_value + +count_elements: + call pop_terms + mov edx,[edi+ExpressionTerm.metadata] + xor ebx,ebx + mov edx,edi + count_variable_terms: + add edx,sizeof.ExpressionTerm + cmp [edx+ExpressionTerm.attributes],0 + je push_plain_value + cmp [edx+ExpressionTerm.metadata],0 + je count_variable_terms + inc ebx + jmp count_variable_terms + +extract_element_reverse: + xor eax,eax +extract_element: + call get_indexed_term + jc replace_with_zero + jecxz replace_with_constant_unit + mov ebx,[ebx+ExpressionTerm.metadata] + jmp push_element + get_indexed_term: + call pop_terms + mov esi,edi + call pop_terms + mov ebx,edi + test eax,eax + jnz process_term_indexing + xchg ebx,esi + process_term_indexing: + mov edx,esi + check_term_index: + add edx,sizeof.ExpressionTerm + cmp [edx+ExpressionTerm.attributes],0 + je term_index_ok + cmp [edx+ExpressionTerm.metadata],0 + je check_term_index + mov edx,_misused_variable_term + call register_error + term_index_ok: + push ebx + xchg edi,esi + call get_numeric_term_value + mov ecx,4 + call fit_value + xchg esi,edi + pop ebx + js no_such_term + jc no_such_term + xor ecx,ecx + find_indexed_term: + cmp ecx,[esi] + je term_found + find_next_term: + add ebx,sizeof.ExpressionTerm + cmp [ebx+ExpressionTerm.attributes],0 + je no_such_term + cmp [ebx+ExpressionTerm.metadata],0 + je find_next_term + inc ecx + jmp find_indexed_term + term_found: + clc + retn + no_such_term: + stc + retn + replace_with_constant_unit: + mov edx,singular_value + jmp replace_with_simple_number + replace_with_zero: + mov edx,zero_value + replace_with_simple_number: + mov eax,EXPR_NUMBER + replace_with_simple_constant: + mov [edi+ExpressionTerm.attributes],eax + mov [edi+ExpressionTerm.value],edx + xor eax,eax + mov [edi+ExpressionTerm.metadata],eax + mov [edi+sizeof.ExpressionTerm+ExpressionTerm.attributes],eax + add edi,2*sizeof.ExpressionTerm + jmp calculation_loop + +extract_scale_reverse: + xor eax,eax +extract_scale: + call get_indexed_term + jc replace_with_zero + mov eax,[ebx+ExpressionTerm.attributes] + mov edx,[ebx+ExpressionTerm.value] + mov [edi+ExpressionTerm.attributes],eax + mov [edi+ExpressionTerm.value],edx + and [edi+sizeof.ExpressionTerm+ExpressionTerm.attributes],0 + add edi,2*sizeof.ExpressionTerm + jmp calculation_loop + +extract_metadata_reverse: + xor eax,eax +extract_metadata: + call get_indexed_term + jc replace_with_zero + extract_term_metadata: + mov ebx,[ebx+ExpressionTerm.metadata] + test ebx,ebx + jz replace_with_zero + test ecx,ecx + jz extract_label_metadata + mov edx,[ebx+SymbolTree_Leaf.definition] + test edx,edx + jz replace_with_zero + cmp [edx+ValueDefinition.type],VALTYPE_AREA + je area_address_value + cmp [edx+ValueDefinition.type],VALTYPE_ELEMENT + jne replace_with_zero + mov ecx,[edx+ValueDefinition.value_length] + jecxz replace_with_zero + jmp push_numeric_symbol +extract_size: + call pop_terms + mov ebx,[edi+ExpressionTerm.metadata] + test ebx,ebx + jz replace_with_zero + extract_label_metadata: + cmp dword [ebx],0 + jne extract_area_size + add ebx,4 + jmp push_numeric_value + extract_area_size: + call prepare_to_push_computed_value + xor edx,edx + mov eax,[ebx+ValueDefinition.value_length] + mov edi,[ebx+ValueDefinition.value] + sub eax,sizeof.AreaHeader + sub eax,[edi+AreaHeader.base_address_length] + add eax,[edi+AreaHeader.uninitialized_length] + adc edx,0 + jmp push_output_position +extract_first_term_metadata: + call pop_terms + lea ebx,[edi+sizeof.ExpressionTerm] + mov ecx,1 + jmp extract_term_metadata + +get_term_value: +; in: edi - ExpressionTerm +; out: edx - 32-bit length followed by data +; preserves: eax, ebx, ecx, esi, edi + mov edx,[edi+ExpressionTerm.value] + test [edi+ExpressionTerm.attributes],EXPRF_VALUE_IN_WORKSPACE + jz value_pointer_ready + add edx,[value_workspace.memory_start] + value_pointer_ready: + retn + +get_numeric_term_value: +; in: edi - ExpressionTerm +; out: edx - 32-bit length followed by numeric data +; preserves: ebx, esi, edi +; note: +; term is converted to numeric and the value workspace may be modified in process +; other pointers to term values may become invalidated + mov eax,[edi+ExpressionTerm.attributes] + mov edx,[edi+ExpressionTerm.value] + test eax,EXPRF_VALUE_IN_WORKSPACE + jz convert_to_numeric + add edx,[value_workspace.memory_start] + convert_to_numeric: + cmp al,EXPR_FLOAT + je wrong_numeric_type + cmp al,EXPR_NUMBER + je value_pointer_ready + mov eax,[edx] + test byte [edx+4+eax-1],80h + jnz extend_to_unsigned_value + mov byte [edi+ExpressionTerm.attributes],EXPR_NUMBER + retn + wrong_numeric_type: + mov edx,_invalid_value + call register_error + mov edx,zero_value + mov [edi+ExpressionTerm.value],edx + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + retn + extend_to_unsigned_value: + push esi edi + mov esi,edi + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov ecx,[edx] + add ecx,5 + mov edx,value_workspace + call reserve_workspace + jnc pointer_for_unsigned_value_ready + mov edi,[value_position] + add edi,[value_workspace.memory_start] + pointer_for_unsigned_value_ready: + mov eax,EXPR_NUMBER + EXPRF_VALUE_IN_WORKSPACE + xchg eax,[esi+ExpressionTerm.attributes] + mov edx,[value_position] + xchg edx,[esi+ExpressionTerm.value] + mov esi,edx + test eax,EXPRF_VALUE_IN_WORKSPACE + jz make_unsigned_value + add esi,[value_workspace.memory_start] + make_unsigned_value: + mov edx,edi + lodsd + stosd + mov ecx,eax + rep movsb + xor al,al + stosb + sub edi,[value_workspace.memory_start] + mov [value_position],edi + inc dword [edx] + pop edi esi + retn + +get_string_term_value: +; in: edi - ExpressionTerm +; out: edx - 32-bit length followed by string data +; preserves: ebx, ecx, esi, edi + mov eax,[edi+ExpressionTerm.attributes] + cmp al,EXPR_STRING + je string_value_available + mov byte [edi+ExpressionTerm.attributes],EXPR_STRING + cmp al,EXPR_NUMBER + je string_value_available + mov edx,_invalid_value + call register_error + mov edx,zero_value + mov [edi+ExpressionTerm.value],edx + mov [edi+ExpressionTerm.attributes],EXPR_STRING + retn + string_value_available: + mov edx,[edi+ExpressionTerm.value] + test eax,EXPRF_VALUE_IN_WORKSPACE + jz string_value_pointer_ready + add edx,[value_workspace.memory_start] + string_value_pointer_ready: + retn + +get_float_term_value: +; in: edi - ExpressionTerm +; out: edx - FloatData +; preserves: ebx, esi, edi +; note: +; term is converted to float and the value workspace may be modified in process +; other pointers to term values may become invalidated + mov eax,[edi+ExpressionTerm.attributes] + mov edx,[edi+ExpressionTerm.value] + test eax,EXPRF_VALUE_IN_WORKSPACE + jz convert_to_float + add edx,[value_workspace.memory_start] + convert_to_float: + cmp al,EXPR_FLOAT + je value_pointer_ready + cmp al,EXPR_STRING + je convert_positive_to_float + mov eax,[edx] + test byte [edx+4+eax-1],80h + jnz convert_negative_to_float + convert_positive_to_float: + push ebx esi + mov ebx,edi + mov edx,value_workspace + mov edi,[edx+Workspace.memory_start] + add edi,[value_position] + mov ecx,sizeof.FloatData + call reserve_workspace + xchg edi,ebx + call get_term_value + mov esi,edx + lea eax,[ebx+sizeof.FloatData] + sub eax,[value_workspace.memory_start] + xchg eax,[value_position] + mov [edi+ExpressionTerm.value],eax + mov [edi+ExpressionTerm.attributes],EXPR_FLOAT + EXPRF_VALUE_IN_WORKSPACE + push edi + mov edi,ebx + call number_to_float + mov edx,edi + pop edi esi ebx + retn + convert_negative_to_float: + push ebx + call negate_term_value + pop ebx + call convert_positive_to_float + or [edx+FloatData.attributes],FLOAT_NEGATIVE + retn + +negate_term_value: +; in: +; edi - ExpressionTerm +; out: +; zf set if result is zero +; preserves: esi, edi + push esi + mov [destination_term],edi + call get_numeric_term_value + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov ecx,[esi] + add ecx,5 + mov edx,value_workspace + call reserve_workspace + jnc pointers_ready_for_negation + mov edi,[destination_term] + call get_term_value + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + pointers_ready_for_negation: + mov edx,[esi] + and edx,not 11b + mov eax,1 + xor ecx,ecx + add esi,4 + add edi,4 + negate_dwords: + cmp ecx,edx + je dwords_negated + mov ebx,[esi+ecx] + not ebx + add eax,ebx + mov [edi+ecx],eax + setc al + movzx eax,al + add ecx,4 + jmp negate_dwords + dwords_negated: + mov edx,[esi-4] + negate_bytes: + cmp ecx,edx + je bytes_negated + mov bl,[esi+ecx] + not bl + add al,bl + mov [edi+ecx],al + setc al + inc ecx + jmp negate_bytes + bytes_negated: + movsx ebx,byte [esi+ecx-1] + not bh + add al,bh + mov [edi+ecx],al + pop esi + value_calculated: + jecxz check_for_zero + optimize_value: + movsx edx,byte [edi+ecx-1] + cmp dh,[edi+ecx] + jne value_optimized + loop optimize_value + check_for_zero: + cmp byte [edi],0 + je finish_value + value_optimized: + inc ecx + finish_value: + sub edi,4 + mov [edi],ecx + value_finished: + mov edx,edi + sub edx,[value_workspace.memory_start] + lea eax,[edx+4+ecx] + mov [value_position],eax + mov edi,[destination_term] + mov [edi+ExpressionTerm.value],edx + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + EXPRF_VALUE_IN_WORKSPACE + test ecx,ecx + retn + +add_term_values: +; in: +; esi - source ExpressionTerm +; edi - destination ExpressionTerm +; out: +; zf set if result is zero +; preserves: esi, edi + call prepare_pointers_for_summation + mov edx,[ebx] + cmp edx,[esi] + jb shorter_addend_selected + mov edx,[esi] + xchg ebx,esi + shorter_addend_selected: + and edx,not 11b + add ebx,4 + add esi,4 + add edi,4 + xor al,al + xor ecx,ecx + add_dwords: + cmp ecx,edx + je dwords_added + neg al + mov eax,[esi+ecx] + adc eax,[ebx+ecx] + mov [edi+ecx],eax + setc al + add ecx,4 + jmp add_dwords + dwords_added: + mov edx,[ebx-4] + add_bytes: + cmp ecx,edx + je bytes_added + neg al + mov al,[esi+ecx] + adc al,[ebx+ecx] + mov [edi+ecx],al + setc al + inc ecx + jmp add_bytes + bytes_added: + movsx ebx,byte [ebx+ecx-1] + sar ebx,8 + mov edx,[esi-4] + sub edx,ecx + and edx,not 11b + add edx,ecx + carry_dwords: + cmp ecx,edx + je dwords_carried + neg al + mov eax,[esi+ecx] + adc eax,ebx + mov [edi+ecx],eax + setc al + add ecx,4 + jmp carry_dwords + dwords_carried: + mov edx,[esi-4] + carry_bytes: + cmp ecx,edx + je bytes_carried + neg al + mov al,[esi+ecx] + adc al,bl + mov [edi+ecx],al + setc al + inc ecx + jmp carry_bytes + bytes_carried: + movsx edx,byte [esi+ecx-1] + neg al + mov al,dh + adc al,bl + mov [edi+ecx],al + mov esi,[source_term] + jmp value_calculated + prepare_pointers_for_summation: + mov [source_term],esi + mov [destination_term],edi + call get_numeric_term_value + mov ebx,[edx] + mov edi,esi + call get_numeric_term_value + mov ecx,[edx] + cmp ecx,ebx + jae sum_length_estimated + mov ecx,ebx + sum_length_estimated: + add ecx,5 + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov edx,value_workspace + call reserve_workspace + mov edi,[destination_term] + call get_term_value + mov ebx,edx + mov edi,esi + call get_term_value + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + retn + +subtract_term_values: +; in: +; esi - source ExpressionTerm +; edi - destination ExpressionTerm +; out: +; zf set if result is zero +; preserves: esi, edi + call prepare_pointers_for_summation + mov edx,[esi] + cmp edx,[ebx] + jb shorter_length_selected + mov edx,[ebx] + shorter_length_selected: + push edx + and edx,not 11b + add ebx,4 + add esi,4 + add edi,4 + xor al,al + xor ecx,ecx + subtract_dwords: + cmp ecx,edx + je dwords_subtracted + neg al + mov eax,[ebx+ecx] + sbb eax,[esi+ecx] + mov [edi+ecx],eax + setc al + add ecx,4 + jmp subtract_dwords + dwords_subtracted: + pop edx + subtract_bytes: + cmp ecx,edx + je bytes_subtracted + neg al + mov al,[ebx+ecx] + sbb al,[esi+ecx] + mov [edi+ecx],al + setc al + inc ecx + jmp subtract_bytes + bytes_subtracted: + cmp ecx,[ebx-4] + je minuend_ended + xchg esi,ebx + movsx ebx,byte [ebx+ecx-1] + sar ebx,8 + mov edx,[esi-4] + sub edx,ecx + and edx,not 11b + add edx,ecx + borrow_dwords: + cmp ecx,edx + je dwords_borrowed + neg al + mov eax,[esi+ecx] + sbb eax,ebx + mov [edi+ecx],eax + setc al + add ecx,4 + jmp borrow_dwords + dwords_borrowed: + mov edx,[esi-4] + borrow_bytes: + cmp ecx,edx + je bytes_borrowed + neg al + mov al,[esi+ecx] + sbb al,bl + mov [edi+ecx],al + setc al + inc ecx + jmp borrow_bytes + bytes_borrowed: + movsx edx,byte [esi+ecx-1] + neg al + mov al,dh + sbb al,bl + mov [edi+ecx],al + mov esi,[source_term] + jmp value_calculated + minuend_ended: + movsx ebx,byte [ebx+ecx-1] + sar ebx,8 + mov edx,[esi-4] + sub edx,ecx + and edx,not 11b + add edx,ecx + subtract_supernumerary_dwords: + cmp ecx,edx + je supernumerary_dwords_subtracted + neg al + mov eax,ebx + sbb eax,[esi+ecx] + mov [edi+ecx],eax + setc al + add ecx,4 + jmp subtract_supernumerary_dwords + supernumerary_dwords_subtracted: + mov edx,[esi-4] + subtract_supernumerary_bytes: + cmp ecx,edx + je supernumerary_bytes_subtracted + neg al + mov al,bl + sbb al,[esi+ecx] + mov [edi+ecx],al + setc al + inc ecx + jmp subtract_supernumerary_bytes + supernumerary_bytes_subtracted: + movsx edx,byte [esi+ecx-1] + neg al + mov al,bl + sbb al,dh + mov [edi+ecx],al + mov esi,[source_term] + jmp value_calculated + +multiply_term_values: +; in: +; esi - source ExpressionTerm +; edi - destination ExpressionTerm +; out: +; zf set if result is zero +; preserves: esi, edi + mov [source_term],esi + mov [destination_term],edi + call get_numeric_term_value + mov edi,multiplier + mov ecx,4 + call fit_value + jnc multiply_by_dword + mov edi,esi + call get_numeric_term_value + mov esi,[destination_term] + mov edi,multiplier + mov ecx,4 + call fit_value + jnc multiply_by_dword + mov edi,[source_term] + call get_term_value + mov ebx,[edx] + mov edi,[destination_term] + call get_term_value + mov eax,[edx] + mov ecx,ebx + add ecx,eax + cmp ebx,eax + jae split_length_selected + xchg ebx,eax + split_length_selected: + shr ebx,1 + add ecx,18 + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov edx,value_workspace + call reserve_workspace + mov eax,edi + mov edi,[source_term] + push edi + call get_term_value + mov edi,eax + mov esi,edx + call split_value + mov eax,edi + mov edi,[destination_term] + push edi + call get_term_value + mov edi,eax + mov esi,edx + call split_value + sub edi,[value_workspace.memory_start] + mov edx,edi + mov edi,[free_temporary_terms] + add [free_temporary_terms],6*sizeof.ExpressionTerm + mov eax,EXPR_NUMBER + EXPRF_VALUE_IN_WORKSPACE + xchg edx,[value_position] + push edx + mov esi,[value_workspace.memory_start] + mov ecx,4 + create_temporary_terms: + mov [edi+ExpressionTerm.attributes],eax + mov [edi+ExpressionTerm.value],edx + add edx,[esi+edx] + add edx,4 + add edi,sizeof.ExpressionTerm + loop create_temporary_terms + mov ecx,2 + duplicate_temporary_terms: + mov [edi+ExpressionTerm.attributes],eax + mov edx,[edi-4*sizeof.ExpressionTerm+ExpressionTerm.value] + mov [edi+ExpressionTerm.value],edx + add edi,sizeof.ExpressionTerm + loop duplicate_temporary_terms + push ebx + sub edi,6*sizeof.ExpressionTerm + lea esi,[edi+2*sizeof.ExpressionTerm] + call multiply_term_values + add esi,sizeof.ExpressionTerm + add edi,sizeof.ExpressionTerm + call multiply_term_values + add edi,sizeof.ExpressionTerm + call add_term_values + add esi,2*sizeof.ExpressionTerm + add edi,2*sizeof.ExpressionTerm + call add_term_values + mov esi,edi + sub edi,2*sizeof.ExpressionTerm + call multiply_term_values + add edi,sizeof.ExpressionTerm + mov eax,[esi-3*sizeof.ExpressionTerm+ExpressionTerm.attributes] + mov edx,[esi-3*sizeof.ExpressionTerm+ExpressionTerm.value] + mov [esi+ExpressionTerm.attributes],eax + mov [esi+ExpressionTerm.value],edx + mov eax,[edi-3*sizeof.ExpressionTerm+ExpressionTerm.attributes] + mov edx,[edi-3*sizeof.ExpressionTerm+ExpressionTerm.value] + mov [edi+ExpressionTerm.attributes],eax + mov [edi+ExpressionTerm.value],edx + call add_term_values + sub edi,sizeof.ExpressionTerm + sub esi,sizeof.ExpressionTerm + call subtract_term_values + mov eax,[esp] + xor dl,dl + shld edx,eax,3 + shl eax,3 + call shift_term_value_left + mov esi,edi + sub edi,2*sizeof.ExpressionTerm + call add_term_values + mov esi,edi + add edi,sizeof.ExpressionTerm + pop eax + xor dl,dl + shld edx,eax,4 + shl eax,4 + call shift_term_value_left + pop [value_position] + mov eax,[edi+ExpressionTerm.attributes] + mov edx,[edi+ExpressionTerm.value] + pop edi + mov [edi+ExpressionTerm.attributes],eax + mov [edi+ExpressionTerm.value],edx + call add_term_values + mov [free_temporary_terms],esi + pop esi + test edi,edi + retn + split_value: + cmp ebx,[esi] + jae too_small_to_split + mov eax,ebx + inc eax + stosd + mov ecx,ebx + lodsd + rep movsb + mov ecx,eax + xor al,al + stosb + sub ecx,ebx + mov eax,ecx + stosd + rep movsb + retn + too_small_to_split: + lodsd + mov ecx,eax + stosd + rep movsb + xor eax,eax + stosd + retn + multiply_by_dword: + sets al + mov [multiplier_sign],al + movzx eax,al + or eax,[multiplier] + jz zero_product + mov ebx,esi + mov edi,esi + call get_numeric_term_value + mov esi,edx + mov ecx,[esi] + add ecx,16 + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov edx,value_workspace + call reserve_workspace + jnc pointers_ready_for_multiplication_by_dword + mov edi,ebx + call get_term_value + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + pointers_ready_for_multiplication_by_dword: + mov eax,[esi] + and eax,not 11b + mov [edi],eax + add esi,4 + add edi,4 + xor ebx,ebx + xor ecx,ecx + multiply_dwords_by_dword: + cmp ecx,[edi-4] + je dwords_multiplied_by_dword + mov eax,[esi+ecx] + mul [multiplier] + add eax,ebx + adc edx,0 + mov ebx,edx + mov [edi+ecx],eax + add ecx,4 + jmp multiply_dwords_by_dword + dwords_multiplied_by_dword: + mov edx,[esi-4] + and edx,11b + jz only_sign_in_last_dword + cmp edx,2 + jb single_byte_in_last_dword + je two_bytes_in_last_dword + movsx eax,byte [esi+ecx+2] + shl eax,16 + mov ax,[esi+ecx] + jmp last_dword_ready + two_bytes_in_last_dword: + movsx eax,word [esi+ecx] + jmp last_dword_ready + single_byte_in_last_dword: + movsx eax,byte [esi+ecx] + jmp last_dword_ready + only_sign_in_last_dword: + movsx eax,byte [esi+ecx-1] + sar eax,8 + last_dword_ready: + mov [edi-4],eax + mul [multiplier] + add eax,ebx + adc edx,0 + mov [edi+ecx],eax + xor eax,eax + mov ebx,[esi-4] + test byte [esi+ebx-1],80h + jz product_extension + sub edx,[multiplier] + sbb eax,0 + product_extension: + mov [edi+ecx+4],edx + add ecx,8 + mov [edi+ecx],eax + cmp [multiplier_sign],0 + je product_ready + mov edx,[esi-4] + and edx,not 11b + xor ecx,ecx + xor al,al + adjust_product: + cmp ecx,edx + je finish_product_adjustment + neg al + mov eax,[esi+ecx] + sbb [edi+ecx+4],eax + setc al + add ecx,4 + jmp adjust_product + finish_product_adjustment: + neg al + mov eax,[edi-4] + cdq + sbb [edi+ecx+4],eax + sbb [edi+ecx+8],edx + add ecx,8 + product_ready: + mov esi,[source_term] + jmp value_calculated + zero_product: + ; zf already set + mov esi,[source_term] + mov edi,[destination_term] + mov [edi+ExpressionTerm.value],zero_value + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + retn + +divide_term_values: +; in: +; esi - divisor ExpressionTerm, to be replaced with remainder +; edi - dividend ExpressionTerm, to be replaced with quotient +; out: +; zf set if remainder is zero +; preserves: esi, edi + mov [source_term],esi + mov [destination_term],edi + call get_numeric_term_value + mov eax,[edx] + test byte [edx+4+eax-1],80h + jnz negative_dividend + xchg edi,esi + call get_numeric_term_value + mov eax,[edx] + test byte [edx+4+eax-1],80h + jnz negative_divisor + mov edi,divisor + mov ecx,4 + call fit_value + jnc divide_by_dword + xor eax,eax + mov ebx,[edx] + find_divisor_length: + mov al,[edx+4+ebx-1] + test al,al + jnz divisor_length_ok + dec ebx + jmp find_divisor_length + divisor_length_ok: + bsr ecx,eax + inc cl + mov [long_divisor_length],ebx + mov [high_bits_count],cl + mov ebx,[edx+4+ebx-5] + shrd ebx,eax,cl + inc ebx + mov [divisor],ebx + mov eax,[source_term] + mov [long_divisor_term],eax + mov eax,[destination_term] + mov [long_dividend_term],eax + mov edi,[free_temporary_terms] + add [free_temporary_terms],4*sizeof.ExpressionTerm + mov [division_temporary_terms],edi + xor eax,eax + mov [edi+ExpressionTerm.attributes],eax + compare_dividend_with_divisor: + mov esi,edx + mov edi,[long_dividend_term] + call get_term_value + xor eax,eax + mov ebx,[edx] + find_dividend_length: + mov al,[edx+4+ebx-1] + test al,al + jnz dividend_length_ok + dec ebx + jmp find_dividend_length + dividend_length_ok: + cmp ebx,[long_divisor_length] + ja long_division + jb dividend_to_remainder + bsr ecx,eax + inc cl + cmp cl,[high_bits_count] + ja long_division + jb dividend_to_remainder + compare_with_divisor_bytes: + mov al,[edx+4+ebx-1] + cmp al,[esi+4+ebx-1] + ja subtract_divisor + jb dividend_to_remainder + dec ebx + jnz compare_with_divisor_bytes + mov esi,[long_divisor_term] + mov edi,[long_dividend_term] + mov eax,EXPR_NUMBER + mov [esi+ExpressionTerm.attributes],eax + mov [esi+ExpressionTerm.value],zero_value + mov [edi+ExpressionTerm.attributes],eax + mov [edi+ExpressionTerm.value],singular_value + jmp accomodate_quotient + dividend_to_remainder: + mov esi,[division_temporary_terms] + mov [free_temporary_terms],esi + mov eax,[esi+ExpressionTerm.attributes] + mov edx,[esi+ExpressionTerm.value] + test eax,eax + jnz quotient_ready + mov eax,EXPR_NUMBER + mov edx,zero_value + quotient_ready: + mov esi,[long_divisor_term] + mov edi,[long_dividend_term] + xchg eax,[edi+ExpressionTerm.attributes] + xchg edx,[edi+ExpressionTerm.value] + mov [esi+ExpressionTerm.attributes],eax + mov [esi+ExpressionTerm.value],edx + jmp test_remainder + subtract_divisor: + mov esi,[long_divisor_term] + mov edi,[long_dividend_term] + call subtract_term_values + mov eax,EXPR_NUMBER + mov edx,singular_value + xchg eax,[edi+ExpressionTerm.attributes] + xchg edx,[edi+ExpressionTerm.value] + mov [esi+ExpressionTerm.attributes],eax + mov [esi+ExpressionTerm.value],edx + accomodate_quotient: + mov esi,[division_temporary_terms] + mov [free_temporary_terms],esi + cmp [esi+ExpressionTerm.attributes],0 + je quotient_complete + call add_term_values + quotient_complete: + mov esi,[long_divisor_term] + test_remainder: + cmp dword [esi],0 + retn + long_division: + mov edi,[division_temporary_terms] + add edi,sizeof.ExpressionTerm + mov esi,[long_dividend_term] + mov eax,[esi+ExpressionTerm.attributes] + mov edx,[esi+ExpressionTerm.value] + mov [edi+ExpressionTerm.attributes],eax + mov [edi+ExpressionTerm.value],edx + mov ecx,8 + cmp [divisor],0 + je shift_dividend_right + add cl,32 + shift_dividend_right: + xor edx,edx + mov eax,[long_divisor_length] + shld edx,eax,3 + shl eax,3 + sub cl,[high_bits_count] + sub eax,ecx + sbb edx,0 + call shift_term_value_right + cmp [divisor],0 + je quotient_approximation_ready + mov esi,edi + mov [destination_term],esi + add edi,sizeof.ExpressionTerm + mov [source_term],edi + call divide_by_dword + quotient_approximation_ready: + mov esi,[division_temporary_terms] + cmp [esi+ExpressionTerm.attributes],0 + jne accumulate_quotient + mov eax,[edi+ExpressionTerm.attributes] + mov edx,[edi+ExpressionTerm.value] + mov [esi+ExpressionTerm.attributes],eax + mov [esi+ExpressionTerm.value],edx + jmp calculate_remainder + accumulate_quotient: + xchg esi,edi + call add_term_values + mov edi,esi + calculate_remainder: + mov esi,[long_divisor_term] + call multiply_term_values + mov esi,edi + mov edi,[long_dividend_term] + call subtract_term_values + mov edi,[long_divisor_term] + call get_term_value + jmp compare_dividend_with_divisor + negative_divisor: + call negate_term_value + xchg edi,esi + call divide_term_values + pushf + call negate_term_value + popf + retn + negative_dividend: + call negate_term_value + xchg edi,esi + call get_numeric_term_value + mov eax,[edx] + test byte [edx+4+eax-1],80h + jnz negative_dividend_and_divisor + xchg edi,esi + call divide_term_values + call negate_term_value + jmp negative_remainder + negative_dividend_and_divisor: + call negate_term_value + xchg edi,esi + call divide_term_values + negative_remainder: + xchg edi,esi + call negate_term_value + xchg edi,esi + retn + divide_by_dword: + cmp [divisor],0 + je division_by_zero + mov ebx,esi + mov edi,esi + call get_term_value + mov esi,edx + mov ecx,[esi] + add ecx,4+9 + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov edx,value_workspace + call reserve_workspace + jnc pointers_ready_for_division_by_dword + mov edi,ebx + call get_term_value + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + pointers_ready_for_division_by_dword: + mov eax,[esi] + add esi,4 + add edi,4 + mov ecx,eax + and ecx,not 11b + xor edx,edx + and eax,11b + jz first_dword_for_division_ready + cmp eax,2 + jb single_byte_in_first_dword + je two_bytes_in_first_dword + mov dl,[esi+ecx+2] + shl edx,16 + two_bytes_in_first_dword: + mov dh,[esi+ecx+1] + single_byte_in_first_dword: + mov dl,[esi+ecx] + first_dword_for_division_ready: + mov eax,edx + xor edx,edx + div [divisor] + mov [edi+ecx],eax + divide_dwords: + sub ecx,4 + jc dwords_divided + mov eax,[esi+ecx] + div [divisor] + mov [edi+ecx],eax + jmp divide_dwords + dwords_divided: + mov ecx,[esi-4] + and ecx,not 11b + add ecx,4 + call optimize_positive_value + lea ebx,[edi-4] + mov [ebx],ecx + lea edi,[edi+ecx+4] + mov ecx,5 + mov [edi],edx + mov [edi+4],ch + call optimize_positive_value + lea eax,[edi-4] + mov [eax],ecx + sub ebx,[value_workspace.memory_start] + mov edi,[destination_term] + mov [edi+ExpressionTerm.value],ebx + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + EXPRF_VALUE_IN_WORKSPACE + sub eax,[value_workspace.memory_start] + mov esi,[source_term] + mov [esi+ExpressionTerm.value],eax + mov [esi+ExpressionTerm.attributes],EXPR_NUMBER + EXPRF_VALUE_IN_WORKSPACE + add eax,4 + add eax,ecx + mov [value_position],eax + test ecx,ecx + retn + optimize_positive_value: + mov al,[edi+ecx-1] + test al,al + js zero_extension_needed + jnz positive_value_optimized + dec ecx + jnz optimize_positive_value + positive_value_optimized: + retn + zero_extension_needed: + inc ecx + retn + division_by_zero: + mov edx,_indeterminate_result + call register_error + xor eax,eax + jmp zero_product + +invert_term_value_bits: +; in: +; edi - ExpressionTerm +; out: +; zf set if result is zero +; preserves: esi, edi + mov [destination_term],edi + call get_numeric_term_value + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov ecx,[esi] + add ecx,4 + mov edx,value_workspace + call reserve_workspace + jnc pointers_ready_for_bit_inversion + mov edi,[destination_term] + call get_term_value + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + pointers_ready_for_bit_inversion: + mov edx,[esi] + xor ecx,ecx + test edx,edx + jz invert_zero + and edx,not 11b + add esi,4 + add edi,4 + invert_bits_in_dwords: + cmp ecx,edx + je bits_in_dwords_inverted + mov eax,[esi+ecx] + not eax + mov [edi+ecx],eax + add ecx,4 + jmp invert_bits_in_dwords + bits_in_dwords_inverted: + mov edx,[esi-4] + invert_bits_in_bytes: + cmp ecx,edx + je bits_in_bytes_inverted + mov al,[esi+ecx] + not al + mov [edi+ecx],al + inc ecx + jmp invert_bits_in_bytes + bits_in_bytes_inverted: + sub edi,4 + mov [edi],ecx + jmp value_finished + invert_zero: + inc ecx + mov [edi],ecx + neg cl + mov [edi+4],cl + jmp value_finished + +bitwise_add_term_values: +; in: +; esi - source ExpressionTerm +; edi - destination ExpressionTerm +; out: +; zf set if result is zero +; preserves: esi, edi + call set_up_bitwise_operation + jc zero_product + bitwise_add_dwords: + cmp ecx,edx + je dwords_added_bitwise + mov eax,[esi+ecx] + xor eax,[ebx+ecx] + mov [edi+ecx],eax + add ecx,4 + jmp bitwise_add_dwords + dwords_added_bitwise: + mov edx,[ebx-4] + bitwise_add_bytes: + cmp ecx,edx + je bytes_added_bitwise + mov al,[esi+ecx] + xor al,[ebx+ecx] + mov [edi+ecx],al + inc ecx + jmp bitwise_add_bytes + bytes_added_bitwise: + movsx ebx,byte [ebx+ecx-1] + sar ebx,8 + mov edx,[esi-4] + sub edx,ecx + and edx,not 11b + add edx,ecx + bitwise_add_supernumerary_dwords: + cmp ecx,edx + je supernumerary_dwords_added_bitwise + mov eax,[esi+ecx] + xor eax,ebx + mov [edi+ecx],eax + add ecx,4 + jmp bitwise_add_supernumerary_dwords + supernumerary_dwords_added_bitwise: + mov edx,[esi-4] + bitwise_add_supernumerary_bytes: + cmp ecx,edx + je supernumerary_bytes_added_bitwise + mov al,[esi+ecx] + xor al,bl + mov [edi+ecx],al + inc ecx + jmp bitwise_add_supernumerary_bytes + supernumerary_bytes_added_bitwise: + dec ecx + mov esi,[source_term] + jmp value_calculated + set_up_bitwise_operation: + mov [source_term],esi + mov [destination_term],edi + call get_numeric_term_value + mov ebx,[edx] + mov edi,esi + call get_numeric_term_value + mov ecx,[edx] + mov eax,ecx + or eax,ebx + jz bitwise_zero_with_zero + cmp ecx,ebx + jae bitwise_result_length_estimated + mov ecx,ebx + bitwise_result_length_estimated: + add ecx,4 + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov edx,value_workspace + call reserve_workspace + mov edi,[destination_term] + call get_term_value + mov ebx,edx + mov edi,esi + call get_term_value + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov edx,[ebx] + cmp edx,[esi] + jb shorter_value_selected + mov edx,[esi] + xchg ebx,esi + shorter_value_selected: + and edx,not 11b + add ebx,4 + add esi,4 + add edi,4 + xor al,al + xor ecx,ecx + retn + bitwise_zero_with_zero: + stc + retn + +bitwise_multiply_term_values: +; in: +; esi - source ExpressionTerm +; edi - destination ExpressionTerm +; out: +; zf set if result is zero +; preserves: esi, edi + call set_up_bitwise_operation + jc zero_product + bitwise_multiply_dwords: + cmp ecx,edx + je dwords_multiplied_bitwise + mov eax,[esi+ecx] + and eax,[ebx+ecx] + mov [edi+ecx],eax + add ecx,4 + jmp bitwise_multiply_dwords + dwords_multiplied_bitwise: + mov edx,[ebx-4] + bitwise_multiply_bytes: + cmp ecx,edx + je bytes_multiplied_bitwise + mov al,[esi+ecx] + and al,[ebx+ecx] + mov [edi+ecx],al + inc ecx + jmp bitwise_multiply_bytes + bytes_multiplied_bitwise: + movsx ebx,byte [ebx+ecx-1] + sar ebx,8 + mov edx,[esi-4] + sub edx,ecx + and edx,not 11b + add edx,ecx + bitwise_multiply_supernumerary_dwords: + cmp ecx,edx + je supernumerary_dwords_multiplied_bitwise + mov eax,[esi+ecx] + and eax,ebx + mov [edi+ecx],eax + add ecx,4 + jmp bitwise_multiply_supernumerary_dwords + supernumerary_dwords_multiplied_bitwise: + mov edx,[esi-4] + bitwise_multiply_supernumerary_bytes: + cmp ecx,edx + je supernumerary_bytes_multiplied_bitwise + mov al,[esi+ecx] + and al,bl + mov [edi+ecx],al + inc ecx + jmp bitwise_multiply_supernumerary_bytes + supernumerary_bytes_multiplied_bitwise: + dec ecx + mov esi,[source_term] + jmp value_calculated + +bitwise_inclusive_or_of_term_values: +; in: +; esi - source ExpressionTerm +; edi - destination ExpressionTerm +; out: +; zf set if result is zero +; preserves: esi, edi + call set_up_bitwise_operation + jc zero_product + inclusive_or_of_dwords: + cmp ecx,edx + je performed_inclusive_or_of_dwords + mov eax,[esi+ecx] + or eax,[ebx+ecx] + mov [edi+ecx],eax + add ecx,4 + jmp inclusive_or_of_dwords + performed_inclusive_or_of_dwords: + mov edx,[ebx-4] + inclusive_or_of_bytes: + cmp ecx,edx + je performed_inclusive_or_of_bytes + mov al,[esi+ecx] + or al,[ebx+ecx] + mov [edi+ecx],al + inc ecx + jmp inclusive_or_of_bytes + performed_inclusive_or_of_bytes: + movsx ebx,byte [ebx+ecx-1] + sar ebx,8 + mov edx,[esi-4] + sub edx,ecx + and edx,not 11b + add edx,ecx + inclusive_or_of_supernumerary_dwords: + cmp ecx,edx + je performed_inclusive_or_of_supernumerary_dwords + mov eax,[esi+ecx] + or eax,ebx + mov [edi+ecx],eax + add ecx,4 + jmp inclusive_or_of_supernumerary_dwords + performed_inclusive_or_of_supernumerary_dwords: + mov edx,[esi-4] + inclusive_or_of_supernumerary_bytes: + cmp ecx,edx + je performed_inclusive_or_of_supernumerary_bytes + mov al,[esi+ecx] + or al,bl + mov [edi+ecx],al + inc ecx + jmp inclusive_or_of_supernumerary_bytes + performed_inclusive_or_of_supernumerary_bytes: + dec ecx + mov esi,[source_term] + jmp value_calculated + +shift_term_value_left: +; in: +; edi - ExpressionTerm +; dl:eax = number of bits +; out: +; zf set if result is zero +; preserves: esi, edi + mov ebx,eax + and al,8-1 + mov [bit_shift],al + shrd ebx,edx,3 + shr dl,3 + mov [shift_overflow],dl + mov [destination_term],edi + call get_numeric_term_value + mov eax,[edx] + check_for_shifted_zero: + test eax,eax + jz shift_left_ok + cmp byte [edx+4+eax-1],0 + jne reserve_memory_for_shift_left + dec eax + jmp check_for_shifted_zero + reserve_memory_for_shift_left: + cmp [shift_overflow],0 + jne out_of_memory + push esi + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov ecx,[esi] + add ecx,ebx + jc out_of_memory + add ecx,5 + jc out_of_memory + mov edx,value_workspace + call reserve_workspace + jnc pointers_ready_for_shift_left + mov edi,[destination_term] + call get_term_value + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + pointers_ready_for_shift_left: + add edi,4 + mov ecx,ebx + push ecx + xor al,al + rep stosb + mov cl,[bit_shift] + mov edx,[esi] + add esi,4 + xor ebx,ebx + shift_bytes_left: + cmp ebx,edx + je bytes_shifted_left + mov ah,[esi+ebx] + shl eax,cl + mov [edi+ebx],ah + mov al,[esi+ebx] + inc ebx + jmp shift_bytes_left + bytes_shifted_left: + movsx eax,byte [esi+ebx-1] + shl eax,cl + mov [edi+ebx],ah + pop ecx + sub edi,ecx + add ecx,ebx + pop esi + jmp value_calculated + shift_left_ok: + retn + +shift_term_value_right: +; in: +; edi - ExpressionTerm +; dl:eax = number of bits +; out: +; zf set if result is zero +; preserves: esi, edi + push esi + mov ebx,eax + and al,8-1 + mov [bit_shift],al + shrd ebx,edx,3 + shr dl,3 + jz byte_shift_ok + or ebx,-1 + byte_shift_ok: + mov [destination_term],edi + call get_numeric_term_value + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov ecx,[esi] + sub ecx,ebx + jnc size_of_shift_result_estimated + xor ecx,ecx + size_of_shift_result_estimated: + add ecx,5 + mov edx,value_workspace + call reserve_workspace + jnc pointers_ready_for_shift_right + mov edi,[destination_term] + call get_term_value + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + pointers_ready_for_shift_right: + add edi,4 + mov cl,[bit_shift] + mov edx,[esi] + sub edx,ebx + jbe value_dissipated + lea esi,[esi+4+ebx] + xor ebx,ebx + shift_bytes_right: + inc ebx + cmp ebx,edx + je bytes_shifted_right + mov ax,[esi+ebx-1] + shr ax,cl + mov [edi+ebx-1],al + jmp shift_bytes_right + bytes_shifted_right: + dec ebx + movsx eax,byte [esi+ebx] + shr eax,cl + mov [edi+ebx],al + mov ecx,ebx + pop esi + jmp value_calculated + value_dissipated: + mov edx,[esi] + movsx eax,byte [esi+4+edx-1] + mov [edi],ah + xor ecx,ecx + pop esi + jmp value_calculated + +find_first_set_bit_in_term_value: +; in: +; esi - ExpressionTerm +; out: +; zf set when value is zero +; when zf = 0: +; dl:eax = index of first set bit +; preserves: esi, edi + xchg edi,esi + call get_numeric_term_value + xchg edi,esi + mov ebx,edx + mov edx,[ebx] + and edx,not 11b + xor ecx,ecx + add ebx,4 + find_first_set_bit_in_dwords: + cmp ecx,edx + je no_set_bit_found_in_dwords + bsf eax,[ebx+ecx] + jnz first_set_bit_found + add ecx,4 + jmp find_first_set_bit_in_dwords + no_set_bit_found_in_dwords: + mov edx,[ebx-4] + find_first_set_bit_in_bytes: + cmp ecx,edx + je no_set_bit_found + movzx eax,byte [ebx+ecx] + bsf eax,eax + jnz first_set_bit_found + inc ecx + jmp find_first_set_bit_in_bytes + no_set_bit_found: + retn + first_set_bit_found: + xor dl,dl + shld edx,ecx,3 + shl ecx,3 + add eax,ecx + adc dl,0 + inc dh + retn + +find_last_set_bit_in_term_value: +; in: +; esi - ExpressionTerm +; out: +; cf set when value is zero or negative +; when cf = 0: +; dl:eax = index of last set bit +; preserves: esi, edi + xchg edi,esi + call get_numeric_term_value + xchg edi,esi + mov ebx,edx + mov edx,[ebx] + add ebx,4 + test byte [ebx+edx-1],80h + jnz last_set_bit_unreachable + mov ecx,edx + and edx,11b + find_last_set_bit_in_dwords: + cmp ecx,edx + je find_last_set_bit_in_bytes + sub ecx,4 + bsr eax,[ebx+ecx] + jnz last_set_bit_found + jmp find_last_set_bit_in_dwords + find_last_set_bit_in_bytes: + jecxz last_set_bit_unreachable + dec ecx + movzx eax,byte [ebx+ecx] + bsr eax,eax + jnz last_set_bit_found + jmp find_last_set_bit_in_bytes + last_set_bit_unreachable: + stc + retn + last_set_bit_found: + xor dl,dl + shld edx,ecx,3 + shl ecx,3 + add eax,ecx + adc dl,0 + ; clc + retn + +truncate_term_value: +; in: +; edi - ExpressionTerm +; preserves: edi + cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT + jne get_numeric_term_value + mov [destination_term],edi + call get_term_value + mov ecx,[edx+FloatData.exponent] + cmp ecx,0 + jl no_integer_part + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + shr ecx,5 + lea ecx,[4+(ecx+1)*4] + mov edx,value_workspace + call reserve_workspace + jnc pointers_ready_for_truncation + mov edi,[destination_term] + call get_term_value + mov esi,edx + mov edi,[value_position] + add edi,[value_workspace.memory_start] + pointers_ready_for_truncation: + add edi,4 + mov ecx,32*MANTISSA_SEGMENTS + sub ecx,[esi+FloatData.exponent] + jbe integer_precision_loss + dec ecx + mov edx,ecx + and ecx,11111b + shr edx,5 + neg edx + add edx,MANTISSA_SEGMENTS + mov ebx,[esi+FloatData.mantissa+(edx-1)*4] + extract_integer_bits: + mov eax,ebx + dec edx + jz extract_highest_integer_bits + mov ebx,[esi+FloatData.mantissa+(edx-1)*4] + shrd eax,ebx,cl + stosd + jmp extract_integer_bits + extract_highest_integer_bits: + shr eax,cl + stosd + integer_part_ready: + and byte [edi],0 + dec ecx + sar ecx,3 + neg ecx + add ecx,edi + mov edi,[destination_term] + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + EXPRF_VALUE_IN_WORKSPACE + mov edx,[value_position] + mov [edi+ExpressionTerm.value],edx + sub ecx,[value_workspace.memory_start] + mov [value_position],ecx + sub ecx,edx + sub ecx,4 + add edx,[value_workspace.memory_start] + mov [edx],ecx + test [esi+FloatData.attributes],FLOAT_NEGATIVE + jnz negate_term_value + retn + integer_precision_loss: + neg ecx + inc ecx + mov edx,ecx + shr ecx,5 + xor eax,eax + rep stosd + mov ecx,edx + and ecx,11111b + mov edx,MANTISSA_SEGMENTS-1 + mov eax,[esi+FloatData.mantissa+edx*4] + shl eax,cl + stosd + extract_significant_bits: + mov eax,[esi+FloatData.mantissa+(edx-1)*4] + mov ebx,[esi+FloatData.mantissa+edx*4] + shld eax,ebx,cl + stosd + dec edx + jnz extract_significant_bits + mov eax,[esi+FloatData.mantissa+edx*4] + neg ecx + and ecx,11111b + jnz extract_highest_integer_bits + xor eax,eax + jmp integer_part_ready + no_integer_part: + mov [edi+ExpressionTerm.value],zero_value + mov [edi+ExpressionTerm.attributes],EXPR_NUMBER + retn + +reverse_term_value_bytes: +; in: +; edi - ExpressionTerm +; ebx = number of bytes +; preserves: esi, edi + push esi + mov [destination_term],edi + call get_numeric_term_value + mov edi,[value_position] + add edi,[value_workspace.memory_start] + mov ecx,ebx + add ecx,4 + mov edx,value_workspace + call reserve_workspace + mov edi,[destination_term] + call get_term_value + mov [edi+ExpressionTerm.attributes],EXPR_STRING + EXPRF_VALUE_IN_WORKSPACE + mov esi,[value_position] + mov [edi+ExpressionTerm.value],esi + lea eax,[esi+4+ebx] + mov [value_position],eax + add esi,[value_workspace.memory_start] + mov [esi],ebx + xor ecx,ecx + test ebx,ebx + jz reversed_bytes_ready + store_reversed_bytes: + cmp ecx,[edx] + jae extend_reversed_bytes + mov al,[edx+4+ecx] + mov [esi+4+ebx-1],al + inc ecx + dec ebx + jnz store_reversed_bytes + reversed_bytes_ready: + cmp ecx,[edx] + jae reversed_bytes_ok + mov al,[edx+4+ecx] + cbw + mov al,ah + lea edi,[edx+4+ecx] + neg ecx + add ecx,[edx] + repe scasb + je reversed_bytes_ok + mov edx,_value_out_of_range + call register_error + jmp reversed_bytes_ok + extend_reversed_bytes: + mov al,[edx+4+ecx-1] + cbw + mov al,ah + lea edi,[esi+4] + mov ecx,ebx + rep stosb + reversed_bytes_ok: + mov edi,[destination_term] + pop esi + retn diff --git a/toolchain/fasmg.kl0e/source/floats.inc b/toolchain/fasmg.kl0e/source/floats.inc new file mode 100644 index 0000000..c114e0d --- /dev/null +++ b/toolchain/fasmg.kl0e/source/floats.inc @@ -0,0 +1,1182 @@ + +struct FloatData + attributes dd ? ; FLOAT_# + exponent dd ? + mantissa rd MANTISSA_SEGMENTS +ends + +MANTISSA_SEGMENTS = 4 + +FLOAT_NEGATIVE = 1 +FLOAT_INFINITE = 2 +FLOAT_INDETERMINATE = 4 +FLOAT_UNDERFLOW = 8 + +number_to_float: +; in: +; esi - 32-bit length followed by binary data of that length +; edi - FloatData +; preserves: edi +; note: the number is treated as unsigned + xor eax,eax + mov [edi+FloatData.attributes],eax + lodsd + mov ecx,eax + cmp eax,10000000h + ja unsigned_too_large + shl eax,3 + dec eax + mov [edi+FloatData.exponent],eax + mov edx,MANTISSA_SEGMENTS*4 + cmp ecx,edx + ja unsigned_precision_loss + xor eax,eax + mov [mantissa_tail],eax + zero_appended_segments: + sub edx,4 + jc converted_mantissa_ready + cmp ecx,edx + ja appended_segments_zeroed + mov [edi+FloatData.mantissa+edx],eax + jmp zero_appended_segments + appended_segments_zeroed: + sub ecx,edx + jz copy_significant_dwords + read_lowest_bytes: + lodsb + ror eax,8 + loop read_lowest_bytes + mov [edi+FloatData.mantissa+edx],eax + sub edx,4 + jc converted_mantissa_ready + copy_significant_dwords: + lodsd + mov [edi+FloatData.mantissa+edx],eax + sub edx,4 + jnc copy_significant_dwords + converted_mantissa_ready: + mov esi,edi + call normalize_float + call round_float + retn + unsigned_precision_loss: + sub ecx,edx + add esi,ecx + mov eax,[esi-4] + sub ecx,4 + jz unsigned_tail_ready + jc unsigned_short_tail + xor dl,dl + lea ebx,[esi-4] + unsigned_tail_contraction: + dec ebx + or dl,[ebx] + loop unsigned_tail_contraction + setnz dl + and dl,1 + or al,dl + jmp unsigned_tail_ready + unsigned_short_tail: + neg cl + shl cl,3 + shr eax,cl + shl eax,cl + unsigned_tail_ready: + mov [mantissa_tail],eax + mov edx,(MANTISSA_SEGMENTS-1)*4 + jmp copy_significant_dwords + unsigned_too_large: + or [edi+FloatData.attributes],FLOAT_INFINITE + retn + +get_float_exponent: +; in: +; esi - FloatData +; out: +; zf set when value is zero +; eax = exponent of normalized value +; preserves: ebx, ecx, esi, edi +; note: +; when value cannot be normalized, smallest possible exponent is returned +; float attributes are ignored + xor eax,eax + find_exponent: + inc eax + bsr edx,[esi+FloatData.mantissa+(eax-1)*4] + jnz exponent_found + cmp eax,MANTISSA_SEGMENTS + jne find_exponent + xor edx,edx + minimal_exponent: + mov eax,-80000000h + test edx,edx + retn + exponent_found: + assert MANTISSA_SEGMENTS shl 5 <= 1 shl 32 + inc edx + shl eax,5 + sub edx,eax + mov eax,[esi+FloatData.exponent] + add eax,edx + jo minimal_exponent + test esi,esi + retn + +get_float_unnormalization: +; in: +; esi - FloatData +; out: +; cf set when value is zero +; when cf = 0: +; ecx = number of leading zeroes in mantissa +; preserves: ebx, edx, esi, edi + xor ecx,ecx + find_highest_set_bit: + inc ecx + bsr eax,[esi+FloatData.mantissa+(ecx-1)*4] + jnz highest_set_bit_found + cmp ecx,MANTISSA_SEGMENTS + jne find_highest_set_bit + stc + retn + highest_set_bit_found: + assert MANTISSA_SEGMENTS shl 5 <= 1 shl 32 + inc eax + shl ecx,5 + sub ecx,eax + ; clc + retn + +normalize_float: +; in: +; esi - source FloatData +; edi - destination FloatData +; [mantissa_tail] = additional bits of source mantissa, lowest bit indicating that there are set bits far down +; out: +; [mantissa_tail] = additional bits of destination mantissa, lowest bit indicating that there are set bits far down +; preserves: esi, edi +; note: float attributes are ignored + xor edx,edx + find_highest_bit: + bsr ecx,[esi+FloatData.mantissa+edx*4] + jnz highest_bit_found + inc edx + cmp edx,MANTISSA_SEGMENTS + jne find_highest_bit + bsr ecx,[mantissa_tail] + jnz highest_bit_found + call copy_float_data + mov [edi+FloatData.exponent],-80000000h + retn + copy_float_data: + cmp esi,edi + je float_data_ready + assert sizeof.FloatData and 11b = 0 + mov ecx,sizeof.FloatData shr 2 + rep movsd + sub esi,sizeof.FloatData + sub edi,sizeof.FloatData + float_data_ready: + retn + highest_bit_found: + not ecx + add ecx,32 + mov eax,edx + shl eax,5 + add eax,ecx + neg eax + jz copy_float_data + add eax,[esi+FloatData.exponent] + jo copy_float_data + mov [edi+FloatData.exponent],eax + add edi,FloatData.mantissa + shift_mantissa_up: + push edx + xor eax,eax + cmp edx,MANTISSA_SEGMENTS-1 + ja shift_mantissa_tail_up + mov eax,[esi+FloatData.mantissa+edx*4] + je shift_mantissa_tail_up + shift_mantissa_segment_up: + inc edx + mov ebx,[esi+FloatData.mantissa+edx*4] + shld eax,ebx,cl + stosd + mov eax,ebx + cmp edx,MANTISSA_SEGMENTS-1 + jne shift_mantissa_segment_up + shift_mantissa_tail_up: + mov ebx,[mantissa_tail] + and ebx,not 1 + shld eax,ebx,cl + stosd + mov eax,ebx + shl eax,cl + pop ecx + jecxz mantissa_normalized + stosd + dec ecx + xor eax,eax + rep stosd + mantissa_normalized: + and [mantissa_tail],1 + or [mantissa_tail],eax + sub edi,FloatData.mantissa + MANTISSA_SEGMENTS*4 + mov eax,[esi+FloatData.attributes] + mov [edi+FloatData.attributes],eax + retn + +unnormalize_float: +; in: +; esi - source FloatData +; edi - destination FloatData +; ecx = target exponent +; [mantissa_tail] = additional bits of source mantissa, lowest bit indicating that there are set bits far down +; out: +; [mantissa_tail] = additional bits of destination mantissa, lowest bit indicating that there are set bits far down +; preserves: esi, edi +; note: +; when target exponent is smaller than the actual one, the overflowing bits are ignored +; float attributes are ignored + mov eax,[esi+FloatData.exponent] + mov [edi+FloatData.exponent],ecx + sub ecx,eax + jz copy_float_data + js contrary_unnormalization + mov ebx,ecx + shr ebx,5 + and cl,11111b + add edi,FloatData.mantissa + (MANTISSA_SEGMENTS-1)*4 + std + mov edx,MANTISSA_SEGMENTS + sub edx,ebx + push ebx + mov ebx,edx + mov edx,MANTISSA_SEGMENTS + mov eax,[mantissa_tail] + collect_far_mantissa: + cmp edx,ebx + je far_mantissa_collected + or [mantissa_tail],eax + mov eax,[esi+FloatData.mantissa+(edx-1)*4] + dec edx + jz unnormalization_underflow + jmp collect_far_mantissa + far_mantissa_collected: + mov ebx,[esi+FloatData.mantissa+(edx-1)*4] + shrd eax,ebx,cl + xchg eax,[mantissa_tail] + test eax,eax + setnz al + and eax,1 + or [mantissa_tail],eax + dec edx + jz shift_first_mantissa_segment_down + shift_mantissa_segment_down: + mov eax,ebx + mov ebx,[esi+FloatData.mantissa+(edx-1)*4] + shrd eax,ebx,cl + stosd + dec edx + jnz shift_mantissa_segment_down + shift_first_mantissa_segment_down: + mov eax,[esi+FloatData.mantissa] + shr eax,cl + stosd + pop ecx + zero_higher_mantissa_segments: + xor eax,eax + rep stosd + sub edi,FloatData.mantissa-4 + cld + mov eax,[esi+FloatData.attributes] + mov [edi+FloatData.attributes],eax + retn + unnormalization_underflow: + cmp edx,ebx + je only_mantissa_tail + or [mantissa_tail],eax + xor eax,eax + only_mantissa_tail: + shr eax,cl + xchg eax,[mantissa_tail] + test eax,eax + setnz al + and eax,1 + or [mantissa_tail],eax + pop ebx + mov ecx,MANTISSA_SEGMENTS + jmp zero_higher_mantissa_segments + contrary_unnormalization: + add edi,FloatData.mantissa + neg ecx + mov edx,ecx + shr edx,5 + cmp edx,MANTISSA_SEGMENTS + ja unnormalization_overflow + and cl,11111b + jmp shift_mantissa_up + unnormalization_overflow: + mov ecx,MANTISSA_SEGMENTS + xor eax,eax + rep stosd + sub edi,FloatData.mantissa + MANTISSA_SEGMENTS*4 + retn + +round_float: +; in: +; edi - FloatData +; [mantissa_tail] = additional bits of mantissa, lowest bit indicating that there are set bits far down +; preserves: ebx, esi, edi + test [mantissa_tail],1 shl 31 + jz rounding_done + test [mantissa_tail],not (1 shl 31) + jnz round_up + test [edi+FloatData.mantissa+(MANTISSA_SEGMENTS-1)*4],1 + jz rounding_done + round_up: + mov edx,MANTISSA_SEGMENTS + increment_mantissa: + inc [edi+FloatData.mantissa+(edx-1)*4] + jnz rounding_done + dec edx + jnz increment_mantissa + or [edi+FloatData.mantissa],80000000h + add [edi+FloatData.exponent],1 + jo float_overflow + rounding_done: + retn + float_overflow: + or [edi+FloatData.attributes],FLOAT_INFINITE + retn + +add_floats: +; in: +; ebx - FloatData with first addend +; esi - FloatData with second addend +; edi - FloatData where sum should be stored +; preserves: edi + test [ebx+FloatData.attributes],FLOAT_NEGATIVE + setnz [first_sign] + test [esi+FloatData.attributes],FLOAT_NEGATIVE + setnz [second_sign] + float_summator: + call get_float_exponent + mov ecx,eax + xchg esi,ebx + call get_float_exponent + cmp eax,ecx + jge significant_mantissa_selected + xchg esi,ebx + mov al,[first_sign] + xchg al,[second_sign] + mov [first_sign],al + significant_mantissa_selected: + push edi + mov eax,[esi+FloatData.mantissa] + test eax,eax + js align_second_mantissa + push ebx + mov edi,[temporary_floats] + and [mantissa_tail],0 + call normalize_float + mov esi,edi + pop ebx + align_second_mantissa: + push esi + and [mantissa_tail],0 + mov ecx,[esi+FloatData.exponent] + mov esi,ebx + mov edi,[temporary_floats] + add edi,sizeof.FloatData + call unnormalize_float + mov ebx,edi + pop esi + pop edi + mov eax,[esi+FloatData.attributes] + or eax,[ebx+FloatData.attributes] + and eax,FLOAT_INFINITE or FLOAT_INDETERMINATE + mov [edi+FloatData.attributes],eax + mov ecx,[esi+FloatData.exponent] + mov [edi+FloatData.exponent],ecx + mov al,[first_sign] + xor al,[second_sign] + jnz opposite_mantissa + mov ecx,MANTISSA_SEGMENTS + clc + add_mantissa_segments: + mov eax,[esi+FloatData.mantissa+(ecx-1)*4] + adc eax,[ebx+FloatData.mantissa+(ecx-1)*4] + mov [edi+FloatData.mantissa+(ecx-1)*4],eax + loop add_mantissa_segments + jnc sum_value_ready + mov ecx,[edi+FloatData.exponent] + add ecx,1 + jo float_overflow + mov esi,edi + call unnormalize_float + or [edi+FloatData.mantissa],80000000h + jmp sum_value_ready + opposite_mantissa: + xor ecx,ecx + compare_mantissa_segments: + mov eax,[esi+FloatData.mantissa+ecx*4] + cmp eax,[ebx+FloatData.mantissa+ecx*4] + ja keep_mantissa_sources + jb switch_mantissa_sources + inc ecx + cmp ecx,MANTISSA_SEGMENTS + jne compare_mantissa_segments + switch_mantissa_sources: + xchg esi,ebx + mov al,[first_sign] + xchg al,[second_sign] + mov [first_sign],al + clc + jmp mantissa_subtraction_ready + keep_mantissa_sources: + neg [mantissa_tail] + mantissa_subtraction_ready: + mov ecx,MANTISSA_SEGMENTS + subtract_mantissa_segments: + mov eax,[esi+FloatData.mantissa+(ecx-1)*4] + sbb eax,[ebx+FloatData.mantissa+(ecx-1)*4] + mov [edi+FloatData.mantissa+(ecx-1)*4],eax + loop subtract_mantissa_segments + mov esi,edi + call normalize_float + sum_value_ready: + xor eax,eax + cmp [first_sign],0 + je round_float + or [edi+FloatData.attributes],FLOAT_NEGATIVE + jmp round_float + +subtract_floats: +; in: +; ebx - FloatData with minuend +; esi - FloatData with subtrahend +; edi - FloatData where difference should be stored +; preserves: edi + test [ebx+FloatData.attributes],FLOAT_NEGATIVE + setnz [first_sign] + test [esi+FloatData.attributes],FLOAT_NEGATIVE + setz [second_sign] + jmp float_summator + +multiply_float_by_unsigned_int: +; in: +; esi - source FloatData +; ecx = unsigned multiplier +; edi - FloatData where multipled value should be stored +; preserves: edi + mov [multiplier],ecx + cmp esi,edi + je multiply_mantissa + mov eax,[esi+FloatData.attributes] + mov edx,[esi+FloatData.exponent] + mov [edi+FloatData.attributes],eax + mov [edi+FloatData.exponent],edx + multiply_mantissa: + xor edx,edx + mov [mantissa_tail],edx + mov ecx,MANTISSA_SEGMENTS + multiply_mantissa_segments: + mov ebx,edx + mov eax,[esi+FloatData.mantissa+(ecx-1)*4] + mul [multiplier] + add eax,ebx + mov [edi+FloatData.mantissa+(ecx-1)*4],eax + loop multiply_mantissa_segments + mov esi,edi + bsr ecx,edx + jz normalize_float + inc ecx + mov eax,ecx + neg cl + add cl,32 + shl edx,cl + push edx + mov ecx,eax + add ecx,[esi+FloatData.exponent] + jo float_overflow + call unnormalize_float + pop eax + or [edi+FloatData.mantissa],eax + jmp round_float + +multiply_floats: +; in: +; ebx - FloatData with first factor +; esi - FloatData with second factor +; edi - FloatData where product should be stored +; preserves: edi + test [esi+FloatData.attributes],FLOAT_INFINITE or FLOAT_INDETERMINATE + jnz first_factor_not_zero + call get_float_exponent + jz multiply_zero_float + first_factor_not_zero: + xchg esi,ebx + test [esi+FloatData.attributes],FLOAT_INFINITE or FLOAT_INDETERMINATE + jnz second_factor_not_zero + call get_float_exponent + jz multiply_zero_float + second_factor_not_zero: + mov eax,[ebx+FloatData.attributes] + mov edx,[esi+FloatData.attributes] + xor eax,edx + and edx,FLOAT_INFINITE or FLOAT_INDETERMINATE + or eax,edx + mov [edi+FloatData.attributes],eax + mov eax,[ebx+FloatData.exponent] + add eax,[esi+FloatData.exponent] + jo exponent_overflow + inc eax + jo exponent_overflow + mov [edi+FloatData.exponent],eax + push edi + mov edi,accumulator + xor eax,eax + mov ecx,3 + rep stosd + mov [mantissa_tail],eax + mov ecx,MANTISSA_SEGMENTS-1 + mov edi,ecx + multiply_low_segments: + or [mantissa_tail],eax + mov eax,[ebx+FloatData.mantissa+ecx*4] + mul [esi+FloatData.mantissa+edi*4] + add [accumulator],eax + adc [accumulator+4],edx + adc [accumulator+8],0 + dec ecx + inc edi + cmp edi,MANTISSA_SEGMENTS + jb multiply_low_segments + dec edi + xchg ecx,edi + xor eax,eax + xchg eax,[accumulator+8] + xchg eax,[accumulator+4] + xchg eax,[accumulator] + cmp edi,0 + jge multiply_low_segments + xchg eax,[mantissa_tail] + test eax,eax + setnz al + and eax,1 + or [mantissa_tail],eax + dec ecx + inc edi + multiply_high_segments: + mov eax,[ebx+FloatData.mantissa+ecx*4] + mul [esi+FloatData.mantissa+edi*4] + add [accumulator],eax + adc [accumulator+4],edx + adc [accumulator+8],0 + dec ecx + inc edi + cmp ecx,0 + jge multiply_high_segments + inc ecx + xchg ecx,edi + xor eax,eax + xchg eax,[accumulator+8] + xchg eax,[accumulator+4] + xchg eax,[accumulator] + mov edx,[esp] + mov [edx+FloatData.mantissa+ecx*4],eax + sub ecx,2 + ja multiply_high_segments + mov eax,[ebx+FloatData.mantissa] + mul [esi+FloatData.mantissa] + add eax,[accumulator] + adc edx,[accumulator+4] + pop edi + mov [edi+FloatData.mantissa+4],eax + mov [edi+FloatData.mantissa],edx + mov esi,edi + call normalize_float + jmp round_float + multiply_zero_float: + mov eax,[ebx+FloatData.attributes] + test eax,FLOAT_INFINITE or FLOAT_INDETERMINATE + jnz indeterminate_product + mov edx,[esi+FloatData.attributes] + and edx,FLOAT_NEGATIVE + xor eax,edx + mov [edi+FloatData.attributes],eax + xor eax,eax + zero_float_result: + mov [edi+FloatData.exponent],eax + xor eax,eax + add edi,FloatData.mantissa + mov ecx,MANTISSA_SEGMENTS + rep stosd + sub edi,FloatData.mantissa + MANTISSA_SEGMENTS*4 + retn + indeterminate_product: + or [edi+FloatData.attributes],FLOAT_INDETERMINATE + retn + exponent_overflow: + js float_overflow + mov [edi+FloatData.attributes],FLOAT_UNDERFLOW + jmp zero_float_result + +multiply_float_by_power_of_ten: +; in: +; esi - FloatData with number to multiply +; ecx = signed number representing exponent +; edi - FloatData for the result +; preserves: edi + call get_float_exponent + jz copy_float_data + cmp ecx,0 + je copy_float_data + jl negative_power_of_ten + mov [exponent],ecx + mov ebx,edi + mov edi,[temporary_floats] + xor eax,eax + mov [edi+FloatData.attributes],eax + mov al,3 + mov [edi+FloatData.exponent],eax + add edi,FloatData.mantissa + mov eax,0A0000000h + stosd + xor eax,eax + mov ecx,MANTISSA_SEGMENTS-1 + rep stosd + mov edi,ebx + get_power_bit: + shr [exponent],1 + jnc square_multiplier + mov ebx,[temporary_floats] + call multiply_floats + test [edi+FloatData.attributes],FLOAT_UNDERFLOW + jnz power_exhausted + square_multiplier: + cmp [exponent],0 + je power_exhausted + push edi + mov ebx,[temporary_floats] + mov esi,ebx + mov edi,ebx + call multiply_floats + test [edi+FloatData.attributes],FLOAT_UNDERFLOW + jnz power_of_ten_underflow + pop edi + mov esi,edi + jmp get_power_bit + power_exhausted: + retn + negative_power_of_ten: + neg ecx + mov [exponent],ecx + mov ebx,edi + mov edi,[temporary_floats] + xor eax,eax + mov [edi+FloatData.attributes],eax + or eax,-4 + mov [edi+FloatData.exponent],eax + add edi,FloatData.mantissa + mov eax,0CCCCCCCCh + mov ecx,MANTISSA_SEGMENTS + dec ecx + rep stosd + inc eax + stosd + mov edi,ebx + jmp get_power_bit + power_of_ten_underflow: + pop edi + or [edi+FloatData.attributes],FLOAT_UNDERFLOW + retn + +multiplicative_inverse: +; in: +; esi - source FloatData +; edi - destination FloatData +; preserves: edi + and [mantissa_tail],0 + call normalize_float + mov eax,[edi+FloatData.attributes] + test eax,FLOAT_INFINITE + jnz reverse_of_infinity + mov ecx,[edi+FloatData.exponent] + cmp ecx,-80000000h + je float_overflow + and [edi+FloatData.attributes],0 + or [edi+FloatData.exponent],-1 + push eax ecx edi + mov [iterations],3 + bsr (MANTISSA_SEGMENTS+1) + mov ebx,edi + mov edi,[temporary_floats] + add edi,2*sizeof.FloatData + xor eax,eax + mov [edi+FloatData.attributes],eax + inc eax + mov [edi+FloatData.exponent],eax + add edi,FloatData.mantissa + mov ecx,MANTISSA_SEGMENTS + mov eax,0B4B4B4B4h + rep stosd + assert FloatData.mantissa + MANTISSA_SEGMENTS*4 = sizeof.FloatData + xor eax,eax + mov [edi+FloatData.attributes],eax + mov [edi+FloatData.exponent],eax + add edi,FloatData.mantissa + mov ecx,MANTISSA_SEGMENTS + mov eax,0F0F0F0F0h + rep stosd + sub edi,FloatData.mantissa + MANTISSA_SEGMENTS*4 + mov esi,edi + call multiply_floats + lea ebx,[edi-sizeof.FloatData] + mov esi,edi + mov edi,ebx + newton_raphson_iteration: + call subtract_floats + mov ebx,edi + mov esi,edi + add edi,sizeof.FloatData + call multiply_floats + mov ebx,[esp] + mov esi,edi + call multiply_floats + mov esi,edi + sub edi,sizeof.FloatData + inc [edi+FloatData.exponent] + mov ebx,edi + dec [iterations] + jnz newton_raphson_iteration + pop edi + call subtract_floats + pop ecx eax + not ecx + add [edi+FloatData.exponent],ecx + and [edi+FloatData.attributes],FLOAT_INFINITE or FLOAT_INDETERMINATE + or [edi+FloatData.attributes],eax + retn + reverse_of_infinity: + and eax,FLOAT_NEGATIVE or FLOAT_INDETERMINATE + mov [edi+FloatData.attributes],eax + xor eax,eax + jmp zero_float_result + +divide_floats: +; in: +; ebx - FloatData with dividend +; esi - FloatData with divisor +; edi - FloatData where quotient should be stored +; preserves: edi + push ebx + call multiplicative_inverse + pop ebx + mov esi,edi + call multiply_floats + retn + +fit_float: +; in: +; esi - FloatData +; ecx = number of bytes that the value has to fit into +; edi - buffer for the specified amount of bytes +; preserves: esi, edi + cmp ecx,2 + je half_precision + cmp ecx,4 + je single_precision + cmp ecx,8 + je double_precision + cmp ecx,10 + je extended_precision + cmp ecx,16 + je quadruple_precision + mov edx,_invalid_value + call register_error + retn + float_out_of_range: + mov edx,_value_out_of_range + call register_error + retn + zero_float: + dec ecx + xor al,al + rep stosb + test [esi+FloatData.attributes],FLOAT_NEGATIVE + setnz al + ror al,1 + stosb + retn + half_precision: + call get_float_exponent + jz zero_float + mov ebx,[esi+FloatData.exponent] + sub ebx,eax + add eax,0Fh + js half_precision_denormal + je half_precision_denormal + cmp eax,1Fh + jae float_out_of_range + mov ecx,10 + shl eax,cl + mov [edi],ax + inc ebx + call read_mantissa_bits + or [edi],ax + call get_mantissa_rounding_increment + add [edi],ax + mov dx,1Fh shl 10 + mov ax,dx + and ax,[edi] + cmp ax,dx + je float_out_of_range + half_precision_ok: + test [esi+FloatData.attributes],FLOAT_NEGATIVE + setnz al + shl ax,15 + or [edi],ax + retn + half_precision_denormal: + neg eax + mov ecx,10 + sub ecx,eax + jc float_out_of_range + call read_mantissa_bits + mov [edi],ax + call get_mantissa_rounding_increment + add [edi],ax + jz float_out_of_range + jmp half_precision_ok + single_precision: + call get_float_exponent + jz zero_float + mov ebx,[esi+FloatData.exponent] + sub ebx,eax + add eax,7Fh + js single_precision_denormal + je single_precision_denormal + cmp eax,0FFh + jae float_out_of_range + mov ecx,23 + shl eax,cl + mov [edi],eax + inc ebx + call read_mantissa_bits + or [edi],eax + call get_mantissa_rounding_increment + add [edi],eax + mov edx,0FFh shl 23 + mov eax,edx + and eax,[edi] + cmp eax,edx + je float_out_of_range + single_precision_ok: + test [esi+FloatData.attributes],FLOAT_NEGATIVE + setnz al + shl eax,31 + or [edi],eax + retn + single_precision_denormal: + neg eax + mov ecx,23 + sub ecx,eax + jc float_out_of_range + call read_mantissa_bits + mov [edi],eax + call get_mantissa_rounding_increment + add [edi],eax + jz float_out_of_range + jmp single_precision_ok + double_precision: + call get_float_exponent + jz zero_float + mov ebx,[esi+FloatData.exponent] + sub ebx,eax + add eax,3FFh + js double_precision_denormal + je double_precision_denormal + cmp eax,7FFh + jae float_out_of_range + mov ecx,20 + shl eax,cl + mov [edi+4],eax + inc ebx + call read_mantissa_bits + or [edi+4],eax + mov ecx,32 + call read_mantissa_bits + mov [edi],eax + call get_mantissa_rounding_increment + xor edx,edx + add [edi],eax + adc [edi+4],edx + mov edx,7FFh shl 20 + mov eax,edx + and eax,[edi+4] + cmp eax,edx + je float_out_of_range + double_precision_ok: + test [esi+FloatData.attributes],FLOAT_NEGATIVE + setnz al + shl eax,31 + or [edi+4],eax + retn + double_precision_denormal: + neg eax + mov ecx,52 + sub ecx,eax + jc float_out_of_range + xor eax,eax + cmp ecx,32 + jbe double_precision_denormal_high_segment_ready + sub ecx,32 + call read_mantissa_bits + mov ecx,32 + double_precision_denormal_high_segment_ready: + mov [edi+4],eax + call read_mantissa_bits + mov [edi],eax + call get_mantissa_rounding_increment + xor edx,edx + add [edi],eax + jc double_precision_denormal_carry + jnz double_precision_ok + cmp [edi+4],edx + je float_out_of_range + jmp double_precision_ok + double_precision_denormal_carry: + adc [edi+4],edx + jmp double_precision_ok + extended_precision: + call get_float_exponent + jz zero_float + mov ebx,[esi+FloatData.exponent] + sub ebx,eax + add eax,3FFFh + js extended_precision_denormal + jz extended_precision_denormal + cmp eax,7FFFh + jae float_out_of_range + mov [edi+8],ax + mov ecx,32 + call read_mantissa_bits + mov [edi+4],eax + mov ecx,32 + call read_mantissa_bits + mov [edi],eax + call get_mantissa_rounding_increment + xor edx,edx + add [edi],eax + adc [edi+4],edx + jnc extended_precision_ok + or byte [edi+7],80h + inc word [edi+8] + cmp word [edi+8],7FFFh + je float_out_of_range + extended_precision_ok: + test [esi+FloatData.attributes],FLOAT_NEGATIVE + setnz al + shl ax,15 + or [edi+8],ax + retn + extended_precision_denormal: + and word [edi+8],0 + neg eax + mov ecx,63 + sub ecx,eax + jc float_out_of_range + xor eax,eax + cmp ecx,32 + jbe extended_precision_denormal_high_segment_ready + sub ecx,32 + call read_mantissa_bits + mov ecx,32 + extended_precision_denormal_high_segment_ready: + mov [edi+4],eax + call read_mantissa_bits + mov [edi],eax + call get_mantissa_rounding_increment + xor edx,edx + add [edi],eax + jc extended_precision_denormal_carry + jnz extended_precision_ok + cmp [edi+4],edx + je float_out_of_range + jmp extended_precision_ok + extended_precision_denormal_carry: + adc [edi+4],edx + jns extended_precision_ok + inc byte [edi+8] + jmp extended_precision_ok + quadruple_precision: + call get_float_exponent + jz zero_float + mov ebx,[esi+FloatData.exponent] + sub ebx,eax + add eax,3FFFh + js quadruple_precision_denormal + je quadruple_precision_denormal + cmp eax,7FFFh + jae float_out_of_range + mov ecx,16 + shl eax,cl + mov [edi+12],eax + inc ebx + call read_mantissa_bits + or [edi+12],eax + mov ecx,32 + call read_mantissa_bits + mov [edi+8],eax + mov ecx,32 + call read_mantissa_bits + mov [edi+4],eax + mov ecx,32 + call read_mantissa_bits + mov [edi],eax + call get_mantissa_rounding_increment + xor edx,edx + add [edi],eax + adc [edi+4],edx + adc [edi+8],edx + adc [edi+12],edx + mov edx,7FFFh shl 16 + mov eax,edx + and eax,[edi+12] + cmp eax,edx + je float_out_of_range + quadruple_precision_ok: + test [esi+FloatData.attributes],FLOAT_NEGATIVE + setnz al + shl eax,31 + or [edi+12],eax + retn + quadruple_precision_denormal: + neg eax + mov ecx,112 + sub ecx,eax + jc float_out_of_range + xor eax,eax + sub ecx,96 + jbe quadruple_precision_denormal_first_segment_ready + call read_mantissa_bits + xor ecx,ecx + quadruple_precision_denormal_first_segment_ready: + mov [edi+12],eax + add ecx,96 + xor eax,eax + sub ecx,64 + jbe quadruple_precision_denormal_second_segment_ready + call read_mantissa_bits + xor ecx,ecx + quadruple_precision_denormal_second_segment_ready: + mov [edi+8],eax + add ecx,64 + xor eax,eax + sub ecx,32 + jbe quadruple_precision_denormal_third_segment_ready + call read_mantissa_bits + xor ecx,ecx + quadruple_precision_denormal_third_segment_ready: + mov [edi+4],eax + add ecx,32 + call read_mantissa_bits + mov [edi],eax + call get_mantissa_rounding_increment + xor edx,edx + add [edi],eax + jc quadruple_precision_denormal_carry + jnz quadruple_precision_ok + or edx,[edi+4] + or edx,[edi+8] + or edx,[edi+12] + jz float_out_of_range + jmp quadruple_precision_ok + quadruple_precision_denormal_carry: + adc [edi+4],edx + adc [edi+8],edx + adc [edi+12],edx + jmp quadruple_precision_ok + read_mantissa_bits: + add ebx,ecx + mov edx,ebx + dec edx + mov al,dl + shr edx,5 + and al,11111b + inc al + mov ch,cl + cmp edx,MANTISSA_SEGMENTS + ja out_of_mantissa_bits + je read_from_mantissa_border + mov cl,32 + sub cl,al + cmp al,ch + jae read_from_single_mantissa_segment + mov eax,[esi+FloatData.mantissa+edx*4] + mov edx,[esi+FloatData.mantissa+(edx-1)*4] + shrd eax,edx,cl + jmp cut_out_mantissa_bits + read_from_single_mantissa_segment: + mov eax,[esi+FloatData.mantissa+edx*4] + shr eax,cl + cut_out_mantissa_bits: + mov cl,ch + cmp cl,32 + je mantissa_bits_ok + mov edx,1 + shl edx,cl + dec edx + and eax,edx + mantissa_bits_ok: + retn + read_from_mantissa_border: + cmp al,32 + jae out_of_mantissa_bits + mov cl,al + mov eax,[esi+FloatData.mantissa+(edx-1)*4] + shl eax,cl + jmp cut_out_mantissa_bits + out_of_mantissa_bits: + xor eax,eax + retn + get_mantissa_rounding_increment: + mov al,bl + shr ebx,5 + and al,11111b + mov cl,31 + sub cl,al + cmp ebx,MANTISSA_SEGMENTS + jae no_rounding_increment + mov edx,1 + shl edx,cl + mov eax,[esi+FloatData.mantissa+ebx*4] + test eax,edx + jz no_rounding_increment + dec edx + and eax,edx + jnz rounding_increment_needed + mov edx,ebx + check_whole_mantissa: + inc edx + cmp edx,MANTISSA_SEGMENTS + jae rounding_tied + cmp dword [esi+FloatData.mantissa+edx*4],0 + je check_whole_mantissa + rounding_increment_needed: + mov eax,1 + retn + rounding_tied: + inc cl + cmp cl,32 + jb test_mantissa_parity + dec ebx + test_mantissa_parity: + mov eax,[esi+FloatData.mantissa+ebx*4] + shr eax,cl + test eax,1 + jnz rounding_increment_needed + no_rounding_increment: + xor eax,eax + retn diff --git a/toolchain/fasmg.kl0e/source/libc/ccall.inc b/toolchain/fasmg.kl0e/source/libc/ccall.inc new file mode 100644 index 0000000..4c8a0b7 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/libc/ccall.inc @@ -0,0 +1,23 @@ + +macro ccall proc*,[arg] +{ + common + local size,count + mov ebp,esp + if size + sub esp,size + end if + and esp,0FFFFFFF0h + count = 0 + if ~ arg eq + forward + mov dword [esp+count*4],arg + count = count + 1 + common + end if + size = count*4 + call proc + mov esp,ebp +} + +macro cinvoke proc*,arg& { ccall [proc],arg } diff --git a/toolchain/fasmg.kl0e/source/libc/fasmg.asm b/toolchain/fasmg.kl0e/source/libc/fasmg.asm new file mode 100644 index 0000000..27557ba --- /dev/null +++ b/toolchain/fasmg.kl0e/source/libc/fasmg.asm @@ -0,0 +1,499 @@ + +match ,{ + + include 'ccall.inc' + include 'struct.inc' + +} match -,{ +else + + include 'selfhost.inc' + +end match +_ equ } + + format ELF + public main + +include '../version.inc' + +extrn 'malloc' as libc.malloc +extrn 'realloc' as libc.realloc +extrn 'free' as libc.free +extrn 'fopen' as libc.fopen +extrn 'fclose' as libc.fclose +extrn 'fread' as libc.fread +extrn 'fwrite' as libc.fwrite +extrn 'fseek' as libc.fseek +extrn 'ftell' as libc.ftell +extrn 'time' as libc.time +extrn 'write' as libc.write + +extrn getenv +extrn gettimeofday +extrn exit + +struct timeval + time_t dd ? + suseconds_t dd ? +ends + +section '.text' executable align 16 + + main: + mov ecx,[esp+4] + mov [argc],ecx + mov ebx,[esp+8] + mov [argv],ebx + + call system_init + + call get_arguments + mov bl,al + cmp [no_logo],0 + jne logo_ok + mov esi,_logo + xor ecx,ecx + call display_string + logo_ok: + test bl,bl + jnz display_usage_information + + xor al,al + mov ecx,[verbosity_level] + jecxz init + or al,TRACE_ERROR_STACK + dec ecx + jz init + or al,TRACE_DISPLAY + init: + call assembly_init + + ccall gettimeofday,start_time,0 + + assemble: + mov esi,[initial_commands] + mov edx,[source_path] + call assembly_pass + jc assembly_done + + mov eax,[current_pass] + cmp eax,[maximum_number_of_passes] + jb assemble + + call show_display_data + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,_code_cannot_be_generated + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + jmp assembly_failed + + assembly_done: + + call show_display_data + + cmp [first_error],0 + jne assembly_failed + + cmp [no_logo],0 + jne summary_done + mov eax,[current_pass] + xor edx,edx + call itoa + call display_string + mov esi,_passes + cmp [current_pass],1 + jne display_passes_suffix + mov esi,_pass + display_passes_suffix: + xor ecx,ecx + call display_string + ccall gettimeofday,end_time,0 + mov eax,[end_time.time_t] + sub eax,[start_time.time_t] + mov ecx,1000000 + mul ecx + add eax,[end_time.suseconds_t] + adc edx,0 + sub eax,[start_time.suseconds_t] + sbb edx,0 + add eax,50000 + mov ecx,1000000 + div ecx + mov ebx,eax + mov eax,edx + xor edx,edx + mov ecx,100000 + div ecx + mov [tenths_of_second],eax + xchg eax,ebx + or ebx,eax + jz display_output_length + xor edx,edx + call itoa + call display_string + mov esi,_message_suffix + mov ecx,1 + call display_string + mov eax,[tenths_of_second] + xor edx,edx + call itoa + call display_string + mov esi,_seconds + xor ecx,ecx + call display_string + display_output_length: + call get_output_length + push eax edx + call itoa + call display_string + pop edx eax + mov esi,_bytes + cmp eax,1 + jne display_bytes_suffix + test edx,edx + jnz display_bytes_suffix + mov esi,_byte + display_bytes_suffix: + xor ecx,ecx + call display_string + mov esi,_new_line + xor ecx,ecx + call display_string + summary_done: + + mov ebx,[source_path] + mov edi,[output_path] + call write_output_file + jc write_failed + + call assembly_shutdown + call system_shutdown + + ccall exit,0 + + assembly_failed: + + call show_errors + + call assembly_shutdown + call system_shutdown + + ccall exit,2 + + write_failed: + mov ebx,_write_failed + jmp fatal_error + + out_of_memory: + mov ebx,_out_of_memory + jmp fatal_error + + fatal_error: + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,ebx + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + call assembly_shutdown + call system_shutdown + + ccall exit,3 + + display_usage_information: + + mov esi,_usage + xor ecx,ecx + call display_string + + call system_shutdown + + ccall exit,1 + + get_arguments: + xor eax,eax + mov [initial_commands],eax + mov [source_path],eax + mov [output_path],eax + mov [no_logo],al + mov [verbosity_level],eax + mov [maximum_number_of_passes],100 + mov [maximum_number_of_errors],1 + mov [maximum_depth_of_stack],10000 + mov ecx,[argc] + mov ebx,[argv] + add ebx,4 + dec ecx + jz error_in_arguments + get_argument: + mov esi,[ebx] + mov al,[esi] + cmp al,'-' + je get_option + cmp [source_path],0 + jne get_output_file + mov [source_path],esi + jmp next_argument + get_output_file: + cmp [output_path],0 + jne error_in_arguments + mov [output_path],esi + jmp next_argument + get_option: + inc esi + lodsb + cmp al,'e' + je set_errors_limit + cmp al,'E' + je set_errors_limit + cmp al,'i' + je insert_initial_command + cmp al,'I' + je insert_initial_command + cmp al,'p' + je set_passes_limit + cmp al,'P' + je set_passes_limit + cmp al,'r' + je set_recursion_limit + cmp al,'R' + je set_recursion_limit + cmp al,'v' + je set_verbose_mode + cmp al,'V' + je set_verbose_mode + cmp al,'n' + je set_no_logo + cmp al,'N' + jne error_in_arguments + set_no_logo: + or [no_logo],-1 + cmp byte [esi],0 + je next_argument + error_in_arguments: + or al,-1 + ret + set_verbose_mode: + cmp byte [esi],0 + jne get_verbose_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_verbose_setting: + call get_option_value + cmp edx,2 + ja error_in_arguments + mov [verbosity_level],edx + jmp next_argument + set_errors_limit: + cmp byte [esi],0 + jne get_errors_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_errors_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_number_of_errors],edx + jmp next_argument + set_recursion_limit: + cmp byte [esi],0 + jne get_recursion_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_recursion_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_depth_of_stack],edx + jmp next_argument + set_passes_limit: + cmp byte [esi],0 + jne get_passes_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_passes_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_number_of_passes],edx + next_argument: + add ebx,4 + dec ecx + jnz get_argument + cmp [source_path],0 + je error_in_arguments + xor al,al + ret + get_option_value: + xor eax,eax + mov edx,eax + find_option_value: + cmp byte [esi],20h + jne get_option_digit + inc esi + jmp find_option_value + get_option_digit: + lodsb + test al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + invalid_option_value: + stc + ret + insert_initial_command: + cmp byte [esi],0 + jne measure_initial_command + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + measure_initial_command: + push ebx ecx edi + mov edi,esi + or ecx,-1 + xor al,al + repne scasb + not ecx + dec ecx + mov edi,[initial_commands] + lea eax,[ecx+2] + test edi,edi + jz allocate_initial_commands_buffer + mov edx,[initial_commands_length] + add edi,edx + add eax,edx + cmp eax,[initial_commands_maximum_length] + ja grow_initial_commands_buffer + copy_initial_command: + rep movsb + mov ax,0Ah + stosw + dec edi + sub edi,[initial_commands] + mov [initial_commands_length],edi + pop edi ecx ebx + jmp next_argument + allocate_initial_commands_buffer: + push ecx + mov ecx,eax + call malloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + pop ecx + jmp copy_initial_command + grow_initial_commands_buffer: + push ecx + mov ecx,eax + mov eax,[initial_commands] + call realloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + add edi,[initial_commands_length] + pop ecx + jmp copy_initial_command + + include 'system.inc' + + include '../assembler.inc' + include '../symbols.inc' + include '../expressions.inc' + include '../conditions.inc' + include '../floats.inc' + include '../directives.inc' + include '../calm.inc' + include '../errors.inc' + include '../map.inc' + include '../reader.inc' + include '../output.inc' + include '../console.inc' + +section '.data' + + _logo db 'flat assembler version g.',VERSION,10,0 + + _usage db 'Usage: fasmg source [output]',10 + db 'Optional settings:',10 + db ' -p limit Set the maximum allowed number of passes (default 100)',10 + db ' -e limit Set the maximum number of displayed errors (default 1)',10 + db ' -r limit Set the maximum depth of the stack (default 10000)',10 + db ' -v flag Enable or disable showing all lines from the stack (default 0)',10 + db ' -i command Insert instruction at the beginning of source',13,10 + db ' -n Do not show logo nor summary',13,10 + db 0 + + _pass db ' pass, ',0 + _passes db ' passes, ',0 + _dot db '.' + _seconds db ' seconds, ',0 + _byte db ' byte.',0 + _bytes db ' bytes.',0 + + _write_failed db 'failed to write the output file',0 + _out_of_memory db 'not enough memory to complete the assembly',0 + _code_cannot_be_generated db 'could not generate code within the allowed number of passes',0 + + _open_mode db 'r',0 + _create_mode db 'w',0 + + include '../tables.inc' + include '../messages.inc' + +section '.bss' writeable align 4 + + include '../variables.inc' + + source_path dd ? + output_path dd ? + maximum_number_of_passes dd ? + + initial_commands dd ? + initial_commands_length dd ? + initial_commands_maximum_length dd ? + + argc dd ? + argv dd ? + timestamp dq ? + + start_time timeval + end_time timeval + tenths_of_second dd ? + + verbosity_level dd ? + no_logo db ? + + path_buffer rb 1000h diff --git a/toolchain/fasmg.kl0e/source/libc/selfhost.inc b/toolchain/fasmg.kl0e/source/libc/selfhost.inc new file mode 100644 index 0000000..f624753 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/libc/selfhost.inc @@ -0,0 +1,60 @@ + +include '../../examples/x86/include/80386.inc' + +macro format?.ELF? variant + match , variant + format binary as 'o' + include '../../examples/x86/include/format/elf32.inc' + use32 + else match =executable? settings, variant: + match brand =at? base:, settings + ELF.Settings.ABI = brand + ELF.Settings.BaseAddress = base + else match =at? base:, settings + ELF.Settings.BaseAddress = base + else match brand:, settings + ELF.Settings.ABI = brand + end match + include '../../examples/x86/include/format/elfexe.inc' + use32 + else + err 'invalid argument' + end match +end macro + + +macro struct? name + macro ends?! + end namespace + esc end struc + virtual at 0 + name name + sizeof.name = $ + end virtual + purge ends? + end macro + esc struc name + label . : sizeof.name + namespace . +end macro + +macro ccall? proc*,args& + local size + mov ebp,esp + if size + sub esp,size + end if + and esp,0FFFFFFF0h + match any, args + iterate arg, args + mov dword [esp+(%-1)*4],arg + if % = 1 + size := %%*4 + end if + end iterate + else + size := 0 + end match + call proc + mov esp,ebp +end macro diff --git a/toolchain/fasmg.kl0e/source/libc/struct.inc b/toolchain/fasmg.kl0e/source/libc/struct.inc new file mode 100644 index 0000000..7b0cb60 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/libc/struct.inc @@ -0,0 +1,17 @@ + +macro struct name* +{ + local body + define body struc name \{ + irp d, db,rb,dw,rw,dd,rd,dq,rq \{ struc d value& \\{ define body \\\.\\#. d value \\} \} + macro ends + \{ + define body \\} + irp d, db,rb,dw,rw,dd,rd,dq,rq \\{ restruc d \\} + irpv line, body \\{ line \\} + virtual at 0 + name name + sizeof.#name = $ + end virtual + \} +} diff --git a/toolchain/fasmg.kl0e/source/libc/system.inc b/toolchain/fasmg.kl0e/source/libc/system.inc new file mode 100644 index 0000000..0461692 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/libc/system.inc @@ -0,0 +1,225 @@ + +LINE_FEED = 0Ah + +system_init: + ccall libc.time,timestamp + retn + +system_shutdown: + retn + +malloc: +malloc_fixed: +malloc_growable: +; in: ecx = requested size +; out: eax - allocated block, ecx = allocated size, on error jumps to out_of_memory (does not return) +; preserves: ebx, esi, edi +; note: +; use of malloc_fixed hints that block will be kept as is until the end of assembly +; use of malloc_growable hints that block is likely to be resized + push ebx ecx esi edi + ccall libc.malloc,ecx + pop edi esi ecx ebx + test eax,eax + jz out_of_memory + retn +realloc: +; in: eax - memory block, ecx = requested size +; out: eax - resized block, ecx = allocated size, on error jumps to out_of_memory (does not return) +; preserves: ebx, esi, edi + push ebx ecx esi edi + ccall libc.realloc,eax,ecx + pop edi esi ecx ebx + test eax,eax + jz out_of_memory + retn +mfree: +; in: eax - memory block +; out: cf set on error +; preserves: ebx, esi, edi +; note: eax may have value 0 or -1, it should be treated as invalid input then + test eax,eax + jz interface_error + cmp eax,-1 + je interface_error + push ebx esi edi + ccall libc.free,eax + pop edi esi ebx + clc + retn + interface_error: + stc + retn + +open: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + push esi edi + call adapt_path + ccall libc.fopen,ebx,_open_mode + pop edi esi + test eax,eax + jz interface_error + mov ebx,eax + clc + retn + adapt_path: + xor ecx,ecx + mov ebx,path_buffer + copy_path: + mov al,[edx+ecx] + cmp al,'\' + jne path_char_ok + mov al,'/' + path_char_ok: + cmp ecx,1000h + jae out_of_memory + mov [ebx+ecx],al + inc ecx + test al,al + jnz copy_path + retn +create: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + push esi edi + call adapt_path + ccall libc.fopen,ebx,_create_mode + pop edi esi + test eax,eax + jz interface_error + mov ebx,eax + clc + retn +write: +; in: ebx = file handle, edx - data, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push ebx ecx esi edi + ccall libc.fwrite,edx,1,ecx,ebx + pop edi esi ecx ebx + cmp eax,ecx + jne interface_error + clc + ret +read: +; in: ebx = file handle, edx - buffer, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push ebx ecx esi edi + ccall libc.fread,edx,1,ecx,ebx + pop edi esi ecx ebx + cmp eax,ecx + jne interface_error + clc + ret +close: +; in: ebx = file handle +; preserves: ebx, esi, edi + ccall libc.fclose,ebx + ret +lseek: +; in: ebx = file handle, cl = method, edx:eax = offset +; out: edx:eax = new offset from the beginning of file, cf set on error +; preserves: ebx, esi, edi + test edx,edx + jnz interface_error + push esi edi ebx + movzx ecx,cl + ccall libc.fseek,ebx,eax,ecx + test eax,eax + jnz lseek_error + mov ebx,[esp] + ccall libc.ftell,ebx + cmp eax,-1 + je lseek_error + xor edx,edx + pop ebx edi esi + clc + ret + lseek_error: + pop ebx edi esi + stc + ret + +get_timestamp: +; out: edx:eax = timestamp +; preserves: ebx, ecx, esi, edi +; note: during the passes of a single assembly this function should always return the same value + mov eax,dword [timestamp] + mov edx,dword [timestamp+4] + retn + +display_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push ebx esi + test ecx,ecx + jnz write_string_to_stdout + xor al,al + mov edi,esi + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + write_string_to_stdout: + ccall libc.write,1,esi,ecx + pop esi ebx + retn + +display_error_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push ebx esi + test ecx,ecx + jnz write_string_to_stderr + xor al,al + mov edi,esi + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + write_string_to_stderr: + ccall libc.write,2,esi,ecx + pop esi ebx + retn + +get_environment_variable: +; in: +; esi - name +; edi - buffer for value +; ecx = size of buffer +; out: +; eax = length of value +; preserves: ebx, esi, edi + push ebx ecx esi edi + ccall getenv,esi + pop edi esi ecx ebx + test eax,eax + jz no_environment_variable + push esi + mov esi,eax + xor eax,eax + copy_environment_variable: + mov dl,[esi+eax] + cmp eax,ecx + jae next_environment_variable_character + mov [edi+eax],dl + next_environment_variable_character: + inc eax + test dl,dl + jnz copy_environment_variable + pop esi + environment_variable_ok: + ret + no_environment_variable: + mov eax,1 + jecxz environment_variable_ok + and byte [edi],0 + ret diff --git a/toolchain/fasmg.kl0e/source/linux/fasmg.asm b/toolchain/fasmg.kl0e/source/linux/fasmg.asm new file mode 100644 index 0000000..16cdf30 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/linux/fasmg.asm @@ -0,0 +1,513 @@ + +match ,{ + + include '../libc/struct.inc' + +} match -,{ +else + + include 'selfhost.inc' + +end match +_ equ } + +format ELF executable 3 +entry start + +include '../version.inc' + +struct timeval + time_t dd ? + suseconds_t dd ? +ends + +segment readable executable + + start: + + mov ecx,[esp] + mov [argc],ecx + lea ebx,[esp+4] + mov [argv],ebx + lea esi,[esp+4+ecx*4+4] + mov [env],esi + + call system_init + + call get_arguments + mov bl,al + cmp [no_logo],0 + jne logo_ok + mov esi,_logo + xor ecx,ecx + call display_string + logo_ok: + test bl,bl + jnz display_usage_information + + xor al,al + mov ecx,[verbosity_level] + jecxz init + or al,TRACE_ERROR_STACK + dec ecx + jz init + or al,TRACE_DISPLAY + init: + call assembly_init + + mov eax,78 ; sys_gettimeofday + mov ebx,start_time + xor ecx,ecx + int 0x80 + + assemble: + mov esi,[initial_commands] + mov edx,[source_path] + call assembly_pass + jc assembly_done + + mov eax,[current_pass] + cmp eax,[maximum_number_of_passes] + jb assemble + + call show_display_data + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,_code_cannot_be_generated + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + jmp assembly_failed + + assembly_done: + + call show_display_data + + cmp [first_error],0 + jne assembly_failed + + cmp [no_logo],0 + jne summary_done + mov eax,[current_pass] + xor edx,edx + call itoa + call display_string + mov esi,_passes + cmp [current_pass],1 + jne display_passes_suffix + mov esi,_pass + display_passes_suffix: + xor ecx,ecx + call display_string + mov eax,78 ; sys_gettimeofday + mov ebx,end_time + xor ecx,ecx + int 0x80 + mov eax,[end_time.time_t] + sub eax,[start_time.time_t] + mov ecx,1000000 + mul ecx + add eax,[end_time.suseconds_t] + adc edx,0 + sub eax,[start_time.suseconds_t] + sbb edx,0 + add eax,50000 + mov ecx,1000000 + div ecx + mov ebx,eax + mov eax,edx + xor edx,edx + mov ecx,100000 + div ecx + mov [tenths_of_second],eax + xchg eax,ebx + or ebx,eax + jz display_output_length + xor edx,edx + call itoa + call display_string + mov esi,_message_suffix + mov ecx,1 + call display_string + mov eax,[tenths_of_second] + xor edx,edx + call itoa + call display_string + mov esi,_seconds + xor ecx,ecx + call display_string + display_output_length: + call get_output_length + push eax edx + call itoa + call display_string + pop edx eax + mov esi,_bytes + cmp eax,1 + jne display_bytes_suffix + test edx,edx + jnz display_bytes_suffix + mov esi,_byte + display_bytes_suffix: + xor ecx,ecx + call display_string + mov esi,_new_line + xor ecx,ecx + call display_string + summary_done: + + mov ebx,[source_path] + mov edi,[output_path] + call write_output_file + jc write_failed + + call assembly_shutdown + call system_shutdown + + xor ebx,ebx + mov eax,1 ; sys_exit + int 0x80 + + assembly_failed: + + call show_errors + + call assembly_shutdown + call system_shutdown + + mov ebx,2 + mov eax,1 ; sys_exit + int 0x80 + + write_failed: + mov ebx,_write_failed + jmp fatal_error + + out_of_memory: + mov ebx,_out_of_memory + jmp fatal_error + + fatal_error: + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,ebx + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + call assembly_shutdown + call system_shutdown + + mov ebx,3 + mov eax,1 ; sys_exit + int 0x80 + + display_usage_information: + + mov esi,_usage + xor ecx,ecx + call display_string + + call system_shutdown + + mov ebx,1 + mov eax,1 ; sys_exit + int 0x80 + + get_arguments: + xor eax,eax + mov [initial_commands],eax + mov [source_path],eax + mov [output_path],eax + mov [no_logo],al + mov [verbosity_level],eax + mov [maximum_number_of_passes],100 + mov [maximum_number_of_errors],1 + mov [maximum_depth_of_stack],10000 + mov ecx,[argc] + mov ebx,[argv] + add ebx,4 + dec ecx + jz error_in_arguments + get_argument: + mov esi,[ebx] + mov al,[esi] + cmp al,'-' + je get_option + cmp [source_path],0 + jne get_output_file + mov [source_path],esi + jmp next_argument + get_output_file: + cmp [output_path],0 + jne error_in_arguments + mov [output_path],esi + jmp next_argument + get_option: + inc esi + lodsb + cmp al,'e' + je set_errors_limit + cmp al,'E' + je set_errors_limit + cmp al,'i' + je insert_initial_command + cmp al,'I' + je insert_initial_command + cmp al,'p' + je set_passes_limit + cmp al,'P' + je set_passes_limit + cmp al,'r' + je set_recursion_limit + cmp al,'R' + je set_recursion_limit + cmp al,'v' + je set_verbose_mode + cmp al,'V' + je set_verbose_mode + cmp al,'n' + je set_no_logo + cmp al,'N' + jne error_in_arguments + set_no_logo: + or [no_logo],-1 + cmp byte [esi],0 + je next_argument + error_in_arguments: + or al,-1 + ret + set_verbose_mode: + cmp byte [esi],0 + jne get_verbose_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_verbose_setting: + call get_option_value + cmp edx,2 + ja error_in_arguments + mov [verbosity_level],edx + jmp next_argument + set_errors_limit: + cmp byte [esi],0 + jne get_errors_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_errors_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_number_of_errors],edx + jmp next_argument + set_recursion_limit: + cmp byte [esi],0 + jne get_recursion_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_recursion_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_depth_of_stack],edx + jmp next_argument + set_passes_limit: + cmp byte [esi],0 + jne get_passes_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_passes_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_number_of_passes],edx + next_argument: + add ebx,4 + dec ecx + jnz get_argument + cmp [source_path],0 + je error_in_arguments + xor al,al + ret + get_option_value: + xor eax,eax + mov edx,eax + find_option_value: + cmp byte [esi],20h + jne get_option_digit + inc esi + jmp find_option_value + get_option_digit: + lodsb + test al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + invalid_option_value: + stc + ret + insert_initial_command: + cmp byte [esi],0 + jne measure_initial_command + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + measure_initial_command: + push ebx ecx edi + mov edi,esi + or ecx,-1 + xor al,al + repne scasb + not ecx + dec ecx + mov edi,[initial_commands] + lea eax,[ecx+2] + test edi,edi + jz allocate_initial_commands_buffer + mov edx,[initial_commands_length] + add edi,edx + add eax,edx + cmp eax,[initial_commands_maximum_length] + ja grow_initial_commands_buffer + copy_initial_command: + rep movsb + mov ax,0Ah + stosw + dec edi + sub edi,[initial_commands] + mov [initial_commands_length],edi + pop edi ecx ebx + jmp next_argument + allocate_initial_commands_buffer: + push ecx + mov ecx,eax + call malloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + pop ecx + jmp copy_initial_command + grow_initial_commands_buffer: + push ecx + mov ecx,eax + mov eax,[initial_commands] + call realloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + add edi,[initial_commands_length] + pop ecx + jmp copy_initial_command + + include 'system.inc' + + include '../malloc.inc' + include '../assembler.inc' + include '../symbols.inc' + include '../expressions.inc' + include '../conditions.inc' + include '../floats.inc' + include '../directives.inc' + include '../calm.inc' + include '../errors.inc' + include '../map.inc' + include '../reader.inc' + include '../output.inc' + include '../console.inc' + +segment readable + + _logo db 'flat assembler version g.',VERSION,10,0 + + _usage db 'Usage: fasmg source [output]',10 + db 'Optional settings:',10 + db ' -p limit Set the maximum allowed number of passes (default 100)',10 + db ' -e limit Set the maximum number of displayed errors (default 1)',10 + db ' -r limit Set the maximum depth of the stack (default 10000)',10 + db ' -v flag Enable or disable showing all lines from the stack (default 0)',10 + db ' -i command Insert instruction at the beginning of source',13,10 + db ' -n Do not show logo nor summary',13,10 + db 0 + + _pass db ' pass, ',0 + _passes db ' passes, ',0 + _dot db '.' + _seconds db ' seconds, ',0 + _byte db ' byte.',0 + _bytes db ' bytes.',0 + + _write_failed db 'failed to write the output file',0 + _out_of_memory db 'not enough memory to complete the assembly',0 + _code_cannot_be_generated db 'could not generate code within the allowed number of passes',0 + + _open_mode db 'r',0 + _create_mode db 'w',0 + + include '../tables.inc' + include '../messages.inc' + +segment readable writeable + + align 16 + + include '../variables.inc' + + align 16 + + timestamp dq ? + + loff dq ? + argc dd ? + argv dd ? + env dd ? + + mmap_args rd 6 + malloc_freelist dd ? + + source_path dd ? + output_path dd ? + maximum_number_of_passes dd ? + + initial_commands dd ? + initial_commands_length dd ? + initial_commands_maximum_length dd ? + + + start_time timeval + end_time timeval + tenths_of_second dd ? + + verbosity_level dd ? + no_logo db ? + + path_buffer rb 1000h + +segment readable writeable gnustack diff --git a/toolchain/fasmg.kl0e/source/linux/selfhost.inc b/toolchain/fasmg.kl0e/source/linux/selfhost.inc new file mode 100644 index 0000000..7430674 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/linux/selfhost.inc @@ -0,0 +1,59 @@ + +include '../../examples/x86/include/80386.inc' + +macro format?.ELF? variant + match , variant + format binary as 'o' + include '../../examples/x86/include/format/elf32.inc' + use32 + else match =executable? settings, variant: + match brand =at? base:, settings + ELF.Settings.ABI = brand + ELF.Settings.BaseAddress = base + else match =at? base:, settings + ELF.Settings.BaseAddress = base + else match brand:, settings + ELF.Settings.ABI = brand + end match + include '../../examples/x86/include/format/elfexe.inc' + use32 + else + err 'invalid argument' + end match +end macro + +macro struct? name + macro ends?! + end namespace + esc end struc + virtual at 0 + name name + sizeof.name = $ + end virtual + purge ends? + end macro + esc struc name + label . : sizeof.name + namespace . +end macro + +macro cinvoke? proc*,args& + local size + mov ebp,esp + if size + sub esp,size + end if + and esp,0FFFFFFF0h + match any, args + iterate arg, args + mov dword [esp+(%-1)*4],arg + if % = 1 + size := %%*4 + end if + end iterate + else + size := 0 + end match + call [proc] + mov esp,ebp +end macro diff --git a/toolchain/fasmg.kl0e/source/linux/system.inc b/toolchain/fasmg.kl0e/source/linux/system.inc new file mode 100644 index 0000000..d1b0847 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/linux/system.inc @@ -0,0 +1,298 @@ + +LINE_FEED = 0Ah + +O_ACCMODE = 0003o +O_RDONLY = 0000o +O_WRONLY = 0001o +O_RDWR = 0002o +O_CREAT = 0100o +O_EXCL = 0200o +O_NOCTTY = 0400o +O_TRUNC = 1000o +O_APPEND = 2000o +O_NONBLOCK = 4000o + +S_ISUID = 4000o +S_ISGID = 2000o +S_ISVTX = 1000o +S_IRUSR = 0400o +S_IWUSR = 0200o +S_IXUSR = 0100o +S_IRGRP = 0040o +S_IWGRP = 0020o +S_IXGRP = 0010o +S_IROTH = 0004o +S_IWOTH = 0002o +S_IXOTH = 0001o + +system_init: + mov eax,13 ; sys_time + mov ebx,timestamp + int 0x80 + retn + +system_shutdown: + retn + +open: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + push esi edi ebp + call adapt_path + mov eax,5 ; sys_open + mov ecx,O_RDONLY + xor edx,edx + int 0x80 + pop ebp edi esi + test eax,eax + js interface_error + mov ebx,eax + clc + retn + adapt_path: + xor ecx,ecx + mov ebx,path_buffer + copy_path: + mov al,[edx+ecx] + cmp al,'\' + jne path_char_ok + mov al,'/' + path_char_ok: + cmp ecx,1000h + jae out_of_memory + mov [ebx+ecx],al + inc ecx + test al,al + jnz copy_path + retn + interface_error: + stc + retn +create: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + push esi edi ebp + call adapt_path + mov eax,5 ; sys_open + mov ecx,O_CREAT+O_TRUNC+O_WRONLY + mov edx,S_IRUSR+S_IWUSR+S_IRGRP+S_IROTH + int 0x80 + pop ebp edi esi + test eax,eax + js interface_error + mov ebx,eax + clc + retn +write: +; in: ebx = file handle, edx - data, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push ebx ecx esi edi ebp + mov eax,4 ; sys_write + xchg ecx,edx + int 0x80 + pop ebp edi esi ecx ebx + test eax,eax + js interface_error + cmp eax,ecx + jne interface_error + clc + ret +read: +; in: ebx = file handle, edx - buffer, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push ebx ecx esi edi ebp + mov eax,3 ; sys_read + xchg ecx,edx + int 0x80 + pop ebp edi esi ecx ebx + test eax,eax + js interface_error + cmp eax,ecx + jne interface_error + clc + ret +close: +; in: ebx = file handle +; preserves: ebx, esi, edi + push ebx esi edi ebp + mov eax,6 ; sys_close + int 0x80 + pop ebp edi esi ebx + ret +lseek: +; in: ebx = file handle, cl = method, edx:eax = offset +; out: edx:eax = new offset from the beginning of file, cf set on error +; preserves: ebx, esi, edi + test edx,edx + jnz interface_error + push esi edi ebx ebp + movzx edi,cl + mov ecx,edx + mov edx,eax + mov eax,140 ; sys_llseek + mov esi,loff + int 0x80 + pop ebp ebx edi esi + test eax,eax + js interface_error + mov eax,dword [loff] + mov edx,dword [loff+4] + clc + ret + +get_timestamp: +; out: edx:eax = timestamp +; preserves: ebx, ecx, esi, edi +; note: during the passes of a single assembly this function should always return the same value + mov eax,dword [timestamp] + mov edx,dword [timestamp+4] + retn + +display_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push ebx esi ebp + test ecx,ecx + jnz write_string_to_stdout + xor al,al + mov edi,esi + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + write_string_to_stdout: + mov eax,4 ; sys_write + mov ebx,1 + mov edx,ecx + mov ecx,esi + int 0x80 + pop ebp esi ebx + retn + +display_error_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push ebx esi ebp + test ecx,ecx + jnz write_string_to_stderr + xor al,al + mov edi,esi + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + write_string_to_stderr: + mov eax,4 ; sys_write + mov ebx,2 + mov edx,ecx + mov ecx,esi + int 0x80 + pop ebp esi ebx + retn + +get_environment_variable: +; in: +; esi - name +; edi - buffer for value +; ecx = size of buffer +; out: +; eax = length of value +; preserves: ebx, esi, edi + push ebx ecx + mov edx,[env] + scan_environment: + mov ebx,[edx] + test ebx,ebx + jz no_environment_variable + xor ecx,ecx + compare_character: + mov al,[ebx+ecx] + mov ah,[esi+ecx] + inc ecx + cmp al,'=' + je end_of_variable_name + test ah,ah + jz next_variable + sub ah,al + je compare_character + cmp ah,20h + jne next_variable + cmp al,'A' + jb next_variable + cmp al,'Z' + jna compare_character + next_variable: + add edx,4 + jmp scan_environment + end_of_variable_name: + test ah,ah + jnz next_variable + add ebx,ecx + pop ecx + xor eax,eax + copy_environment_variable: + mov dl,[ebx+eax] + cmp eax,ecx + jae next_environment_variable_character + mov [edi+eax],dl + next_environment_variable_character: + inc eax + test dl,dl + jnz copy_environment_variable + environment_variable_ok: + pop ebx + ret + no_environment_variable: + pop ecx + mov eax,1 + jecxz environment_variable_ok + and byte [edi],0 + pop ebx + ret + +VALLOC_MINIMUM_SIZE = 100000h + +valloc: +; in: ecx = requested minimum size +; out: eax - allocated block, ecx = allocated size, zero if failed +; preserves: ebx, esi, edi + cmp ecx,VALLOC_MINIMUM_SIZE + jbe valloc_size_minimum + dec ecx + and ecx,(-1) shl 12 + add ecx,1 shl 12 + jmp valloc_size_ready + valloc_size_minimum: + mov ecx,VALLOC_MINIMUM_SIZE + valloc_size_ready: + push ebx edi + mov ebx,mmap_args + mov edi,ebx + xor eax,eax + stosd + mov eax,ecx + stosd + mov eax,3 ; PROT_READ + PROT_WRITE + stosd + mov eax,22h ; MAP_PRIVATE + MAP_ANONYMOUS + stosd + or eax,-1 + stosd + xor eax,eax + stosd + mov eax,0x5A ; old_mmap + int 0x80 + cmp eax,-1 + jne valloc_ok + xor ecx,ecx + valloc_ok: + pop edi ebx + retn diff --git a/toolchain/fasmg.kl0e/source/linux/x64/32on64.inc b/toolchain/fasmg.kl0e/source/linux/x64/32on64.inc new file mode 100644 index 0000000..898d23e --- /dev/null +++ b/toolchain/fasmg.kl0e/source/linux/x64/32on64.inc @@ -0,0 +1,124 @@ + +macro use32on64 +{ + + define esp rsp + + define promote.eax rax + define promote.ebx rbx + define promote.ecx rcx + define promote.edx rdx + define promote.esi rsi + define promote.edi rdi + define promote.ebp rbp + define promote.esp rsp + + macro push args + \{ + local list,arg,status + define list + define arg + irps sym, args \\{ + define status + match =dword, sym \\\{ + define status : + \\\} + match [any, status arg sym \\\{ + define arg [any + match [mem], arg \\\\{ + match previous, list \\\\\{ define list previous,[mem] \\\\\} + match , list \\\\\{ define list [mem] \\\\\} + define arg + \\\\} + define status : + \\\} + match [, status arg sym \\\{ + define arg [ + define status : + \\\} + match , status \\\{ + match previous, list \\\\{ define list previous,sym \\\\} + match , list \\\\{ define list sym \\\\} + \\\} + \\} + match ops,list \\{ + irp op, ops \\\{ + if op eqtype eax + push promote.\\\#op + else + mov r8d,op + push r8 + end if + \\\} + \\} + \} + + macro pop args + \{ + local list,arg,status + define list + define arg + irps sym, args \\{ + define status + match =dword, sym \\\{ + define status : + \\\} + match [any, status arg sym \\\{ + define arg [any + match [mem], arg \\\\{ + match previous, list \\\\\{ define list previous,[mem] \\\\\} + match , list \\\\\{ define list [mem] \\\\\} + define arg + \\\\} + define status : + \\\} + match [, status arg sym \\\{ + define arg [ + define status : + \\\} + match , status \\\{ + match previous, list \\\\{ define list previous,sym \\\\} + match , list \\\\{ define list sym \\\\} + \\\} + \\} + match ops,list \\{ + irp op, ops \\\{ + if op eqtype eax + pop promote.\\\#op + else + pop r8 + mov op,r8d + end if + \\\} + \\} + \} + + irp instr, jmp,call + \{ + macro instr op + \\{ + if op eqtype [0] + mov r8d,op + instr r8 + else if op eqtype 0 + instr op + else + instr promote.\\#op + end if + \\} + \} + + macro jecxz target + \{ + if target-($+1) < 80h & target-($+1) >= -80h + jecxz target + else + local j,k + jecxz j + jmp k + j: jmp target + k: + end if + \} + +} diff --git a/toolchain/fasmg.kl0e/source/linux/x64/fasmg.asm b/toolchain/fasmg.kl0e/source/linux/x64/fasmg.asm new file mode 100644 index 0000000..e9bc5f8 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/linux/x64/fasmg.asm @@ -0,0 +1,545 @@ + +match ,{ + + include '../../libc/struct.inc' + include '32on64.inc' + +} match -,{ +else + + include 'selfhost.inc' + +end match +_ equ } + +format ELF64 executable 3 +entry start + +include '../../version.inc' + +struct timeval + time_t dq ? + suseconds_t dq ? +ends + +segment readable executable + + start: + + mov rcx,[rsp] + mov [argc],rcx + lea rbx,[rsp+8] + mov [argv],rbx + lea rsi,[rsp+8+rcx*8+8] + mov [env],rsi + + call system_init + + call get_arguments + mov bl,al + cmp [no_logo],0 + jne logo_ok + mov esi,_logo + xor ecx,ecx + call display_string + logo_ok: + test bl,bl + jnz display_usage_information + + xor al,al + mov ecx,[verbosity_level] + jecxz init + or al,TRACE_ERROR_STACK + dec ecx + jz init + or al,TRACE_DISPLAY + init: + call assembly_init + + mov eax,96 ; sys_gettimeofday + mov edi,start_time + xor esi,esi + syscall + + assemble: + mov esi,[initial_commands] + mov edx,[source_path] + call assembly_pass + jc assembly_done + + mov eax,[current_pass] + cmp eax,[maximum_number_of_passes] + jb assemble + + call show_display_data + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,_code_cannot_be_generated + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + jmp assembly_failed + + assembly_done: + + call show_display_data + + cmp [first_error],0 + jne assembly_failed + + cmp [no_logo],0 + jne summary_done + mov eax,[current_pass] + xor edx,edx + call itoa + call display_string + mov esi,_passes + cmp [current_pass],1 + jne display_passes_suffix + mov esi,_pass + display_passes_suffix: + xor ecx,ecx + call display_string + mov eax,96 ; sys_gettimeofday + mov edi,end_time + xor esi,esi + syscall + mov rax,[end_time.time_t] + sub rax,[start_time.time_t] + mov rcx,1000000 + mul rcx + add rax,[end_time.suseconds_t] + adc rdx,0 + sub rax,[start_time.suseconds_t] + sbb rdx,0 + add rax,50000 + mov rcx,1000000 + div rcx + mov rbx,rax + mov rax,rdx + xor rdx,rdx + mov rcx,100000 + div rcx + mov [tenths_of_second],eax + xchg rax,rbx + or rbx,rax + jz display_output_length + mov rdx,rax + shr rdx,32 + call itoa + call display_string + mov esi,_message_suffix + mov ecx,1 + call display_string + mov eax,[tenths_of_second] + xor edx,edx + call itoa + call display_string + mov esi,_seconds + xor ecx,ecx + call display_string + display_output_length: + call get_output_length + push rax rdx + call itoa + call display_string + pop rdx rax + mov esi,_bytes + cmp eax,1 + jne display_bytes_suffix + test edx,edx + jnz display_bytes_suffix + mov esi,_byte + display_bytes_suffix: + xor ecx,ecx + call display_string + mov esi,_new_line + xor ecx,ecx + call display_string + summary_done: + + mov ebx,[source_path] + mov edi,[output_path] + call write_output_file + jc write_failed + + call assembly_shutdown + call system_shutdown + + xor edi,edi ; exit code 0 + mov eax,60 ; sys_exit + syscall + + assembly_failed: + + call show_errors + + call assembly_shutdown + call system_shutdown + + mov edi,2 + mov eax,60 ; sys_exit + syscall + + write_failed: + mov ebx,_write_failed + jmp fatal_error + + out_of_memory: + mov ebx,_out_of_memory + jmp fatal_error + + fatal_error: + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,ebx + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + call assembly_shutdown + call system_shutdown + + mov edi,3 + mov eax,60 ; sys_exit + syscall + + internal_error: + int3 + + display_usage_information: + + mov esi,_usage + xor ecx,ecx + call display_string + + call system_shutdown + + mov edi,1 + mov eax,60 ; sys_exit + syscall + + get_arguments: + xor eax,eax + mov [initial_commands],eax + mov [source_path],eax + mov [output_path],eax + mov [no_logo],al + mov [verbosity_level],eax + mov [maximum_number_of_passes],100 + mov [maximum_number_of_errors],1 + mov [maximum_depth_of_stack],10000 + mov rcx,[argc] + mov rbx,[argv] + add rbx,8 + dec ecx + jz error_in_arguments + get_argument: + mov rsi,[rbx] + mov al,[rsi] + cmp al,'-' + je get_option + cmp [source_path],0 + jne get_output_file + call strdup + mov [source_path],eax + jmp next_argument + get_output_file: + cmp [output_path],0 + jne error_in_arguments + call strdup + mov [output_path],eax + jmp next_argument + get_option: + inc rsi + lodsb + cmp al,'e' + je set_errors_limit + cmp al,'E' + je set_errors_limit + cmp al,'i' + je insert_initial_command + cmp al,'I' + je insert_initial_command + cmp al,'p' + je set_passes_limit + cmp al,'P' + je set_passes_limit + cmp al,'r' + je set_recursion_limit + cmp al,'R' + je set_recursion_limit + cmp al,'v' + je set_verbose_mode + cmp al,'V' + je set_verbose_mode + cmp al,'n' + je set_no_logo + cmp al,'N' + jne error_in_arguments + set_no_logo: + or [no_logo],-1 + cmp byte [rsi],0 + je next_argument + error_in_arguments: + or al,-1 + ret + set_verbose_mode: + cmp byte [rsi],0 + jne get_verbose_setting + dec ecx + jz error_in_arguments + add rbx,8 + mov rsi,[rbx] + get_verbose_setting: + call get_option_value + cmp edx,2 + ja error_in_arguments + mov [verbosity_level],edx + jmp next_argument + set_errors_limit: + cmp byte [rsi],0 + jne get_errors_setting + dec ecx + jz error_in_arguments + add rbx,8 + mov rsi,[rbx] + get_errors_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_number_of_errors],edx + jmp next_argument + set_recursion_limit: + cmp byte [rsi],0 + jne get_recursion_setting + dec ecx + jz error_in_arguments + add rbx,8 + mov rsi,[rbx] + get_recursion_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_depth_of_stack],edx + jmp next_argument + set_passes_limit: + cmp byte [rsi],0 + jne get_passes_setting + dec ecx + jz error_in_arguments + add rbx,8 + mov rsi,[rbx] + get_passes_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_number_of_passes],edx + next_argument: + add rbx,8 + dec ecx + jnz get_argument + cmp [source_path],0 + je error_in_arguments + xor al,al + ret + get_option_value: + xor eax,eax + mov edx,eax + find_option_value: + cmp byte [rsi],20h + jne get_option_digit + inc rsi + jmp find_option_value + get_option_digit: + lodsb + test al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec rsi + clc + ret + invalid_option_value: + stc + ret + insert_initial_command: + cmp byte [rsi],0 + jne measure_initial_command + dec ecx + jz error_in_arguments + add rbx,8 + mov rsi,[rbx] + measure_initial_command: + push rbx rcx rdi + mov rdi,rsi + or ecx,-1 + xor al,al + repne scasb + not ecx + dec ecx + mov edi,[initial_commands] + lea eax,[ecx+2] + test edi,edi + jz allocate_initial_commands_buffer + mov edx,[initial_commands_length] + add edi,edx + add eax,edx + cmp eax,[initial_commands_maximum_length] + ja grow_initial_commands_buffer + copy_initial_command: + rep movsb + mov ax,0Ah + stosw + dec edi + sub edi,[initial_commands] + mov [initial_commands_length],edi + pop rdi rcx rbx + jmp next_argument + allocate_initial_commands_buffer: + push rsi rcx + mov ecx,eax + call malloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + pop rcx rsi + jmp copy_initial_command + grow_initial_commands_buffer: + push rsi rcx + mov ecx,eax + mov eax,[initial_commands] + call realloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + add edi,[initial_commands_length] + pop rcx rsi + jmp copy_initial_command + + strdup: + ; in: rsi - ASCIIZ string + ; out: eax - copy of the string in 32-bit addressable memory + ; preserves: rbx, rcx, rsi + push rbx rcx rsi + mov rdi,rsi + or ecx,-1 + xor al,al + repne scasb + not ecx + push rsi rcx + call malloc + pop rcx rsi + mov edi,eax + rep movsb + pop rsi rcx rbx + ret + + include 'system.inc' + + use32on64 + + include '../../malloc.inc' + include '../../assembler.inc' + include '../../symbols.inc' + include '../../expressions.inc' + include '../../conditions.inc' + include '../../floats.inc' + include '../../directives.inc' + include '../../calm.inc' + include '../../errors.inc' + include '../../map.inc' + include '../../reader.inc' + include '../../output.inc' + include '../../console.inc' + +segment readable + + _logo db 'flat assembler version g.',VERSION,10,0 + + _usage db 'Usage: fasmg source [output]',10 + db 'Optional settings:',10 + db ' -p limit Set the maximum allowed number of passes (default 100)',10 + db ' -e limit Set the maximum number of displayed errors (default 1)',10 + db ' -r limit Set the maximum depth of the stack (default 10000)',10 + db ' -v flag Enable or disable showing all lines from the stack (default 0)',10 + db ' -i command Insert instruction at the beginning of source',13,10 + db ' -n Do not show logo nor summary',13,10 + db 0 + + _pass db ' pass, ',0 + _passes db ' passes, ',0 + _dot db '.' + _seconds db ' seconds, ',0 + _byte db ' byte.',0 + _bytes db ' bytes.',0 + + _write_failed db 'failed to write the output file',0 + _out_of_memory db 'not enough memory to complete the assembly',0 + _code_cannot_be_generated db 'could not generate code within the allowed number of passes',0 + + include '../../tables.inc' + include '../../messages.inc' + +segment readable writeable + + align 16 + + include '../../variables.inc' + + align 16 + + timestamp dq ? + + argc dq ? + argv dq ? + env dq ? + + mmap_hint dd ? + malloc_freelist dd ? + + source_path dd ? + output_path dd ? + maximum_number_of_passes dd ? + + initial_commands dd ? + initial_commands_length dd ? + initial_commands_maximum_length dd ? + + start_time timeval + end_time timeval + tenths_of_second dd ? + + verbosity_level dd ? + no_logo db ? + + local_heap_available db ? + + path_buffer rb 1000h + +segment readable writeable + + align 1000h + + LOCAL_HEAP_SIZE = 1000000h + + local_heap rb LOCAL_HEAP_SIZE + +segment readable writeable gnustack diff --git a/toolchain/fasmg.kl0e/source/linux/x64/selfhost.inc b/toolchain/fasmg.kl0e/source/linux/x64/selfhost.inc new file mode 100644 index 0000000..604ac42 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/linux/x64/selfhost.inc @@ -0,0 +1,120 @@ + +include '../../../examples/x86/include/x64.inc' + +macro format?.ELF64? variant + match , variant + format binary as 'o' + include '../../../examples/x86/include/format/elf64.inc' + use64 + else match =executable? settings, variant: + ELF.Settings.Class = ELFCLASS64 + ELF.Settings.Machine = EM_X86_64 + ELF.Settings.BaseAddress = 400000h + match brand =at? base:, settings + ELF.Settings.ABI = brand + ELF.Settings.BaseAddress = base + else match =at? base:, settings + ELF.Settings.BaseAddress = base + else match brand:, settings + ELF.Settings.ABI = brand + end match + include '../../../examples/x86/include/format/elfexe.inc' + use64 + else + err 'invalid argument' + end match +end macro + +macro struct? name + macro ends?! + end namespace + esc end struc + virtual at 0 + name name + sizeof.name = $ + end virtual + purge ends? + end macro + esc struc name + label . : sizeof.name + namespace . +end macro + +macro use32on64? + + define esp rsp + + define promote + + iterate , eax,rax, ebx,rbx, ecx,rcx, edx,rdx, esi,rsi, edi,rdi, esp,rsp, ebp,rbp + promote.reg32? equ reg64 + end iterate + + iterate instr, jmp,call + calminstruction instr? arg + local tmp + match [tmp], arg + jyes zero_extend + transform arg, promote + arrange tmp, =instr arg + assemble tmp + exit + zero_extend: + arrange tmp, =mov =r8d,[tmp] + assemble tmp + arrange tmp, =instr =r8 + assemble tmp + end calminstruction + end iterate + + calminstruction push? arg + local car, cdr + match car cdr?, arg + loop: + transform car, promote + jno non_reg + arrange car, =push car + assemble car + match car cdr?, cdr + jyes loop + exit + non_reg: + arrange tmp, =mov =r8d,arg + assemble tmp + arrange tmp, =push =r8 + assemble tmp + exit + end calminstruction + + calminstruction pop? arg + local car, cdr + match car cdr?, arg + loop: + transform car, promote + jno non_reg + arrange car, =pop car + assemble car + match car cdr?, cdr + jyes loop + exit + non_reg: + arrange tmp, =pop =r8 + assemble tmp + arrange tmp, =mov arg,=r8d + assemble tmp + exit + end calminstruction + + macro jecxz? target + if target-($+1) < 80h & target-($+1) >= -80h + jecxz target + else + local j,k + jecxz j + jmp k + j: jmp target + k: + end if + end macro + +end macro diff --git a/toolchain/fasmg.kl0e/source/linux/x64/system.inc b/toolchain/fasmg.kl0e/source/linux/x64/system.inc new file mode 100644 index 0000000..053d313 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/linux/x64/system.inc @@ -0,0 +1,334 @@ + +LINE_FEED = 0Ah + +O_ACCMODE = 0003o +O_RDONLY = 0000o +O_WRONLY = 0001o +O_RDWR = 0002o +O_CREAT = 0100o +O_EXCL = 0200o +O_NOCTTY = 0400o +O_TRUNC = 1000o +O_APPEND = 2000o +O_NONBLOCK = 4000o + +S_ISUID = 4000o +S_ISGID = 2000o +S_ISVTX = 1000o +S_IRUSR = 0400o +S_IWUSR = 0200o +S_IXUSR = 0100o +S_IRGRP = 0040o +S_IWGRP = 0020o +S_IXGRP = 0010o +S_IROTH = 0004o +S_IWOTH = 0002o +S_IXOTH = 0001o + +system_init: + mov eax,201 ; sys_time + mov edi,timestamp + syscall + or [local_heap_available],1 + retn + +system_shutdown: + call mcheck + retn + +open: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + push rsi rdi + call adapt_path + mov eax,2 ; sys_open + mov esi,O_RDONLY + xor edx,edx + syscall + pop rdi rsi + test eax,eax + js interface_error + mov ebx,eax + clc + ret + interface_error: + stc + ret + adapt_path: + xor ecx,ecx + mov edi,path_buffer + copy_path: + mov al,[edx+ecx] + cmp al,'\' + jne path_char_ok + mov al,'/' + path_char_ok: + cmp ecx,1000h + jae out_of_memory + mov [edi+ecx],al + inc ecx + test al,al + jnz copy_path + retn +create: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + push rsi rdi + call adapt_path + mov esi,O_CREAT+O_TRUNC+O_WRONLY + mov edx,S_IRUSR+S_IWUSR+S_IRGRP+S_IROTH + mov eax,2 ; sys_open + syscall + pop rdi rsi + test eax,eax + js interface_error + mov ebx,eax + clc + retn +write: +; in: ebx = file handle, edx - data, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push rsi rdi + mov eax,1 ; sys_write + mov edi,ebx + mov esi,edx + mov edx,ecx + syscall + pop rdi rsi + test eax,eax + js interface_error + cmp eax,edx + jne interface_error + clc + ret +read: +; in: ebx = file handle, edx - buffer, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push rsi rdi + mov eax,0 ; sys_read + mov edi,ebx + mov esi,edx + mov edx,ecx + syscall + pop rdi rsi + test eax,eax + js interface_error + cmp eax,edx + jne interface_error + clc + ret +close: +; in: ebx = file handle +; preserves: ebx, esi, edi + push rdi + mov edi,ebx + mov eax,3 ; sys_close + syscall + pop rdi + ret +lseek: +; in: ebx = file handle, cl = method, edx:eax = offset +; out: edx:eax = new offset from the beginning of file, cf set on error +; preserves: ebx, esi, edi + push rsi rdi + mov edi,ebx + mov esi,edx + mov eax,eax + shl rsi,32 + or rsi,rax + xor edx,edx + mov dl,cl + mov eax,8 ; sys_lseek + syscall + pop rdi rsi + cmp rax,-1 + je interface_error + mov rdx,rax + shr rdx,32 + clc + ret + +get_timestamp: +; out: edx:eax = timestamp +; preserves: ebx, ecx, esi, edi +; note: during the passes of a single assembly this function should always return the same value + mov eax,dword [timestamp] + mov edx,dword [timestamp+4] + retn + +display_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push rbx rsi rbp + test ecx,ecx + jnz write_string_to_stdout + xor al,al + mov edi,esi + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + write_string_to_stdout: + mov eax,1 ; sys_write + mov edi,1 + mov edx,ecx + syscall + pop rbp rsi rbx + retn + +display_error_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push rbx rsi rbp + test ecx,ecx + jnz write_string_to_stderr + xor al,al + mov edi,esi + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + write_string_to_stderr: + mov eax,1 ; sys_write + mov edi,2 + mov edx,ecx + syscall + pop rbp rsi rbx + retn + +get_environment_variable: +; in: +; esi - name +; edi - buffer for value +; ecx = size of buffer +; out: +; eax = length of value +; preserves: ebx, esi, edi + push rbx rcx + mov rdx,[env] + scan_environment: + mov rbx,[rdx] + test rbx,rbx + jz no_environment_variable + xor ecx,ecx + compare_character: + mov al,[rbx+rcx] + mov ah,[esi+ecx] + inc ecx + cmp al,'=' + je end_of_variable_name + test ah,ah + jz next_variable + sub ah,al + je compare_character + cmp ah,20h + jne next_variable + cmp al,'A' + jb next_variable + cmp al,'Z' + jna compare_character + next_variable: + add rdx,8 + jmp scan_environment + end_of_variable_name: + test ah,ah + jnz next_variable + add rbx,rcx + pop rcx + xor eax,eax + copy_environment_variable: + mov dl,[rbx+rax] + cmp eax,ecx + jae next_environment_variable_character + mov [edi+eax],dl + next_environment_variable_character: + inc eax + test dl,dl + jnz copy_environment_variable + environment_variable_ok: + pop rbx + ret + no_environment_variable: + pop rcx + mov eax,1 + jecxz environment_variable_ok + and byte [edi],0 + pop rbx + ret + +VALLOC_MINIMUM_SIZE = 100000h + +valloc: +; in: ecx = requested minimum size +; out: eax - allocated block, ecx = allocated size, zero if failed +; preserves: ebx, esi, edi + cmp ecx,VALLOC_MINIMUM_SIZE + jbe valloc_size_minimum + dec ecx + and ecx,(-1) shl 12 + add ecx,1 shl 12 + jmp valloc_size_ready + valloc_size_minimum: + mov ecx,VALLOC_MINIMUM_SIZE + valloc_size_ready: + push rbx rsi rdi + cmp [local_heap_available],0 + je valloc_mmap + cmp ecx,LOCAL_HEAP_SIZE + ja valloc_mmap + and [local_heap_available],0 + mov eax,local_heap + mov ecx,LOCAL_HEAP_SIZE + jmp valloc_ok + valloc_mmap: + xor r9d,r9d + or r8,-1 + mov r10d,62h ; MAP_PRIVATE + MAP_ANONYMOUS + MAP_32BIT + mov edx,3 ; PROT_READ + PROT_WRITE + mov esi,ecx + xor edi,edi + mov eax,9 ; sys_mmap + syscall + cmp eax,-1 + je valloc_mmap_with_hint + mov ecx,eax + cmp rcx,rax + jne valloc_mmap_unusable + add ecx,esi + jnc mmap_ok + valloc_mmap_unusable: + mov rdi,rax + mov eax,11 ; sys_munmap + syscall + valloc_mmap_with_hint: + mov r10d,22h ; MAP_PRIVATE + MAP_ANONYMOUS + mov edx,3 ; PROT_READ + PROT_WRITE + mov edi,[mmap_hint] + mov eax,9 ; sys_mmap + syscall + cmp eax,-1 + je valloc_failed + mov ecx,eax + cmp rcx,rax + jne valloc_failed + add ecx,esi + jc valloc_failed + mmap_ok: + sub ecx,eax + valloc_ok: + lea edx,[eax+ecx] + mov [mmap_hint],edx + pop rdi rsi rbx + retn + valloc_failed: + xor ecx,ecx + pop rdi rsi rbx + retn diff --git a/toolchain/fasmg.kl0e/source/macos/fasmg b/toolchain/fasmg.kl0e/source/macos/fasmg new file mode 100644 index 0000000..9a63a26 Binary files /dev/null and b/toolchain/fasmg.kl0e/source/macos/fasmg differ diff --git a/toolchain/fasmg.kl0e/source/macos/fasmg.asm b/toolchain/fasmg.kl0e/source/macos/fasmg.asm new file mode 100644 index 0000000..516af96 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/macos/fasmg.asm @@ -0,0 +1,504 @@ + +match ,{ + + err ; fasm 1 assembly not supported + +} match -,{ +else + + include 'selfhost.inc' + +end match +_ equ } + +format MachO executable +entry start + +include '../version.inc' + +interpreter '/usr/lib/dyld' +uses '/usr/lib/libSystem.B.dylib' + +import libc.malloc,'_malloc',\ + libc.realloc,'_realloc',\ + libc.free,'_free',\ + libc.fopen,'_fopen',\ + libc.fclose,'_fclose',\ + libc.fread,'_fread',\ + libc.fwrite,'_fwrite',\ + libc.fseek,'_fseek',\ + libc.ftell,'_ftell',\ + libc.time,'_time',\ + libc.write,'_write',\ + getenv,'_getenv',\ + gettimeofday,'_gettimeofday',\ + exit,'_exit' + +struct timeval + time_t dd ? + suseconds_t dd ? +ends + +segment '__TEXT' readable executable + +section '__text' align 16 + + start: + mov ecx,[esp] + mov [argc],ecx + lea ebx,[esp+4] + mov [argv],ebx + + call system_init + + call get_arguments + mov bl,al + cmp [no_logo],0 + jne logo_ok + mov esi,_logo + xor ecx,ecx + call display_string + logo_ok: + test bl,bl + jnz display_usage_information + + xor al,al + mov ecx,[verbosity_level] + jecxz init + or al,TRACE_ERROR_STACK + dec ecx + jz init + or al,TRACE_DISPLAY + init: + call assembly_init + + ccall gettimeofday,start_time,0 + + assemble: + mov esi,[initial_commands] + mov edx,[source_path] + call assembly_pass + jc assembly_done + + mov eax,[current_pass] + cmp eax,[maximum_number_of_passes] + jb assemble + + call show_display_data + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,_code_cannot_be_generated + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + jmp assembly_failed + + assembly_done: + + call show_display_data + + cmp [first_error],0 + jne assembly_failed + + cmp [no_logo],0 + jne summary_done + mov eax,[current_pass] + xor edx,edx + call itoa + call display_string + mov esi,_passes + cmp [current_pass],1 + jne display_passes_suffix + mov esi,_pass + display_passes_suffix: + xor ecx,ecx + call display_string + ccall gettimeofday,end_time,0 + mov eax,[end_time.time_t] + sub eax,[start_time.time_t] + mov ecx,1000000 + mul ecx + add eax,[end_time.suseconds_t] + adc edx,0 + sub eax,[start_time.suseconds_t] + sbb edx,0 + add eax,50000 + mov ecx,1000000 + div ecx + mov ebx,eax + mov eax,edx + xor edx,edx + mov ecx,100000 + div ecx + mov [tenths_of_second],eax + xchg eax,ebx + or ebx,eax + jz display_output_length + xor edx,edx + call itoa + call display_string + mov esi,_message_suffix + mov ecx,1 + call display_string + mov eax,[tenths_of_second] + xor edx,edx + call itoa + call display_string + mov esi,_seconds + xor ecx,ecx + call display_string + display_output_length: + call get_output_length + push eax edx + call itoa + call display_string + pop edx eax + mov esi,_bytes + cmp eax,1 + jne display_bytes_suffix + test edx,edx + jnz display_bytes_suffix + mov esi,_byte + display_bytes_suffix: + xor ecx,ecx + call display_string + mov esi,_new_line + xor ecx,ecx + call display_string + summary_done: + + mov ebx,[source_path] + mov edi,[output_path] + call write_output_file + jc write_failed + + call assembly_shutdown + call system_shutdown + + ccall exit,0 + + assembly_failed: + + call show_errors + + call assembly_shutdown + call system_shutdown + + ccall exit,2 + + write_failed: + mov ebx,_write_failed + jmp fatal_error + + out_of_memory: + mov ebx,_out_of_memory + jmp fatal_error + + fatal_error: + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,ebx + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + call assembly_shutdown + call system_shutdown + + ccall exit,3 + + display_usage_information: + + mov esi,_usage + xor ecx,ecx + call display_string + + call system_shutdown + + ccall exit,1 + + get_arguments: + xor eax,eax + mov [initial_commands],eax + mov [source_path],eax + mov [output_path],eax + mov [no_logo],al + mov [verbosity_level],eax + mov [maximum_number_of_passes],100 + mov [maximum_number_of_errors],1 + mov [maximum_depth_of_stack],10000 + mov ecx,[argc] + mov ebx,[argv] + add ebx,4 + dec ecx + jz error_in_arguments + get_argument: + mov esi,[ebx] + mov al,[esi] + cmp al,'-' + je get_option + cmp [source_path],0 + jne get_output_file + mov [source_path],esi + jmp next_argument + get_output_file: + cmp [output_path],0 + jne error_in_arguments + mov [output_path],esi + jmp next_argument + get_option: + inc esi + lodsb + cmp al,'e' + je set_errors_limit + cmp al,'E' + je set_errors_limit + cmp al,'i' + je insert_initial_command + cmp al,'I' + je insert_initial_command + cmp al,'p' + je set_passes_limit + cmp al,'P' + je set_passes_limit + cmp al,'r' + je set_recursion_limit + cmp al,'R' + je set_recursion_limit + cmp al,'v' + je set_verbose_mode + cmp al,'V' + je set_verbose_mode + cmp al,'n' + je set_no_logo + cmp al,'N' + jne error_in_arguments + set_no_logo: + or [no_logo],-1 + cmp byte [esi],0 + je next_argument + error_in_arguments: + or al,-1 + ret + set_verbose_mode: + cmp byte [esi],0 + jne get_verbose_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_verbose_setting: + call get_option_value + cmp edx,2 + ja error_in_arguments + mov [verbosity_level],edx + jmp next_argument + set_errors_limit: + cmp byte [esi],0 + jne get_errors_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_errors_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_number_of_errors],edx + jmp next_argument + set_recursion_limit: + cmp byte [esi],0 + jne get_recursion_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_recursion_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_depth_of_stack],edx + jmp next_argument + set_passes_limit: + cmp byte [esi],0 + jne get_passes_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_passes_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_number_of_passes],edx + next_argument: + add ebx,4 + dec ecx + jnz get_argument + cmp [source_path],0 + je error_in_arguments + xor al,al + ret + get_option_value: + xor eax,eax + mov edx,eax + find_option_value: + cmp byte [esi],20h + jne get_option_digit + inc esi + jmp find_option_value + get_option_digit: + lodsb + test al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + invalid_option_value: + stc + ret + insert_initial_command: + cmp byte [esi],0 + jne measure_initial_command + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + measure_initial_command: + push ebx ecx edi + mov edi,esi + or ecx,-1 + xor al,al + repne scasb + not ecx + dec ecx + mov edi,[initial_commands] + lea eax,[ecx+2] + test edi,edi + jz allocate_initial_commands_buffer + mov edx,[initial_commands_length] + add edi,edx + add eax,edx + cmp eax,[initial_commands_maximum_length] + ja grow_initial_commands_buffer + copy_initial_command: + rep movsb + mov ax,0Ah + stosw + dec edi + sub edi,[initial_commands] + mov [initial_commands_length],edi + pop edi ecx ebx + jmp next_argument + allocate_initial_commands_buffer: + push ecx + mov ecx,eax + call malloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + pop ecx + jmp copy_initial_command + grow_initial_commands_buffer: + push ecx + mov ecx,eax + mov eax,[initial_commands] + call realloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + add edi,[initial_commands_length] + pop ecx + jmp copy_initial_command + + include 'system.inc' + + include '../assembler.inc' + include '../symbols.inc' + include '../expressions.inc' + include '../conditions.inc' + include '../floats.inc' + include '../directives.inc' + include '../calm.inc' + include '../errors.inc' + include '../map.inc' + include '../reader.inc' + include '../output.inc' + include '../console.inc' + +section '__cstring' align 4 + + _logo db 'flat assembler version g.',VERSION,10,0 + + _usage db 'Usage: fasmg source [output]',10 + db 'Optional settings:',10 + db ' -p limit Set the maximum allowed number of passes (default 100)',10 + db ' -e limit Set the maximum number of displayed errors (default 1)',10 + db ' -r limit Set the maximum depth of the stack (default 10000)',10 + db ' -v flag Enable or disable showing all lines from the stack (default 0)',10 + db ' -i command Insert instruction at the beginning of source',13,10 + db ' -n Do not show logo nor summary',13,10 + db 0 + + _pass db ' pass, ',0 + _passes db ' passes, ',0 + _dot db '.' + _seconds db ' seconds, ',0 + _byte db ' byte.',0 + _bytes db ' bytes.',0 + + _write_failed db 'failed to write the output file',0 + _out_of_memory db 'not enough memory to complete the assembly',0 + _code_cannot_be_generated db 'could not generate code within the allowed number of passes',0 + + _open_mode db 'r',0 + _create_mode db 'w',0 + + include '../tables.inc' + include '../messages.inc' + +segment '__DATA' readable writable + +section '__bss' align 4 + + include '../variables.inc' + + source_path dd ? + output_path dd ? + maximum_number_of_passes dd ? + + initial_commands dd ? + initial_commands_length dd ? + initial_commands_maximum_length dd ? + + argc dd ? + argv dd ? + timestamp dq ? + + start_time timeval + end_time timeval + tenths_of_second dd ? + + verbosity_level dd ? + no_logo db ? + + path_buffer rb 1000h diff --git a/toolchain/fasmg.kl0e/source/macos/fasmg.o.asm b/toolchain/fasmg.kl0e/source/macos/fasmg.o.asm new file mode 100644 index 0000000..537be21 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/macos/fasmg.o.asm @@ -0,0 +1,498 @@ + +match ,{ + + err ; fasm 1 assembly not supported + +} match -,{ +else + + include 'selfhost.inc' + +end match +_ equ } + +format MachO +public main as '_main' + +include '../version.inc' + +extrn '_malloc' as libc.malloc +extrn '_realloc' as libc.realloc +extrn '_free' as libc.free +extrn '_fopen' as libc.fopen +extrn '_fclose' as libc.fclose +extrn '_fread' as libc.fread +extrn '_fwrite' as libc.fwrite +extrn '_fseek' as libc.fseek +extrn '_ftell' as libc.ftell +extrn '_time' as libc.time +extrn '_write' as libc.write + +extrn '_getenv' as getenv +extrn '_gettimeofday' as gettimeofday +extrn '_exit' as exit + +struct timeval + time_t dd ? + suseconds_t dd ? +ends + +section '__TEXT':'__text' align 16 + + main: + mov ecx,[esp+4] + mov [argc],ecx + mov ebx,[esp+8] + mov [argv],ebx + + call system_init + + call get_arguments + mov bl,al + cmp [no_logo],0 + jne logo_ok + mov esi,_logo + xor ecx,ecx + call display_string + logo_ok: + test bl,bl + jnz display_usage_information + + xor al,al + mov ecx,[verbosity_level] + jecxz init + or al,TRACE_ERROR_STACK + dec ecx + jz init + or al,TRACE_DISPLAY + init: + call assembly_init + + ccall gettimeofday,start_time,0 + + assemble: + mov esi,[initial_commands] + mov edx,[source_path] + call assembly_pass + jc assembly_done + + mov eax,[current_pass] + cmp eax,[maximum_number_of_passes] + jb assemble + + call show_display_data + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,_code_cannot_be_generated + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + jmp assembly_failed + + assembly_done: + + call show_display_data + + cmp [first_error],0 + jne assembly_failed + + cmp [no_logo],0 + jne summary_done + mov eax,[current_pass] + xor edx,edx + call itoa + call display_string + mov esi,_passes + cmp [current_pass],1 + jne display_passes_suffix + mov esi,_pass + display_passes_suffix: + xor ecx,ecx + call display_string + ccall gettimeofday,end_time,0 + mov eax,[end_time.time_t] + sub eax,[start_time.time_t] + mov ecx,1000000 + mul ecx + add eax,[end_time.suseconds_t] + adc edx,0 + sub eax,[start_time.suseconds_t] + sbb edx,0 + add eax,50000 + mov ecx,1000000 + div ecx + mov ebx,eax + mov eax,edx + xor edx,edx + mov ecx,100000 + div ecx + mov [tenths_of_second],eax + xchg eax,ebx + or ebx,eax + jz display_output_length + xor edx,edx + call itoa + call display_string + mov esi,_message_suffix + mov ecx,1 + call display_string + mov eax,[tenths_of_second] + xor edx,edx + call itoa + call display_string + mov esi,_seconds + xor ecx,ecx + call display_string + display_output_length: + call get_output_length + push eax edx + call itoa + call display_string + pop edx eax + mov esi,_bytes + cmp eax,1 + jne display_bytes_suffix + test edx,edx + jnz display_bytes_suffix + mov esi,_byte + display_bytes_suffix: + xor ecx,ecx + call display_string + mov esi,_new_line + xor ecx,ecx + call display_string + summary_done: + + mov ebx,[source_path] + mov edi,[output_path] + call write_output_file + jc write_failed + + call assembly_shutdown + call system_shutdown + + ccall exit,0 + + assembly_failed: + + call show_errors + + call assembly_shutdown + call system_shutdown + + ccall exit,2 + + write_failed: + mov ebx,_write_failed + jmp fatal_error + + out_of_memory: + mov ebx,_out_of_memory + jmp fatal_error + + fatal_error: + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,ebx + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + call assembly_shutdown + call system_shutdown + + ccall exit,3 + + display_usage_information: + + mov esi,_usage + xor ecx,ecx + call display_string + + call system_shutdown + + ccall exit,1 + + get_arguments: + xor eax,eax + mov [initial_commands],eax + mov [source_path],eax + mov [output_path],eax + mov [no_logo],al + mov [verbosity_level],eax + mov [maximum_number_of_passes],100 + mov [maximum_number_of_errors],1 + mov [maximum_depth_of_stack],10000 + mov ecx,[argc] + mov ebx,[argv] + add ebx,4 + dec ecx + jz error_in_arguments + get_argument: + mov esi,[ebx] + mov al,[esi] + cmp al,'-' + je get_option + cmp [source_path],0 + jne get_output_file + mov [source_path],esi + jmp next_argument + get_output_file: + cmp [output_path],0 + jne error_in_arguments + mov [output_path],esi + jmp next_argument + get_option: + inc esi + lodsb + cmp al,'e' + je set_errors_limit + cmp al,'E' + je set_errors_limit + cmp al,'i' + je insert_initial_command + cmp al,'I' + je insert_initial_command + cmp al,'p' + je set_passes_limit + cmp al,'P' + je set_passes_limit + cmp al,'r' + je set_recursion_limit + cmp al,'R' + je set_recursion_limit + cmp al,'v' + je set_verbose_mode + cmp al,'V' + je set_verbose_mode + cmp al,'n' + je set_no_logo + cmp al,'N' + jne error_in_arguments + set_no_logo: + or [no_logo],-1 + cmp byte [esi],0 + je next_argument + error_in_arguments: + or al,-1 + ret + set_verbose_mode: + cmp byte [esi],0 + jne get_verbose_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_verbose_setting: + call get_option_value + cmp edx,2 + ja error_in_arguments + mov [verbosity_level],edx + jmp next_argument + set_errors_limit: + cmp byte [esi],0 + jne get_errors_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_errors_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_number_of_errors],edx + jmp next_argument + set_recursion_limit: + cmp byte [esi],0 + jne get_recursion_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_recursion_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_depth_of_stack],edx + jmp next_argument + set_passes_limit: + cmp byte [esi],0 + jne get_passes_setting + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + get_passes_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_number_of_passes],edx + next_argument: + add ebx,4 + dec ecx + jnz get_argument + cmp [source_path],0 + je error_in_arguments + xor al,al + ret + get_option_value: + xor eax,eax + mov edx,eax + find_option_value: + cmp byte [esi],20h + jne get_option_digit + inc esi + jmp find_option_value + get_option_digit: + lodsb + test al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + invalid_option_value: + stc + ret + insert_initial_command: + cmp byte [esi],0 + jne measure_initial_command + dec ecx + jz error_in_arguments + add ebx,4 + mov esi,[ebx] + measure_initial_command: + push ebx ecx edi + mov edi,esi + or ecx,-1 + xor al,al + repne scasb + not ecx + dec ecx + mov edi,[initial_commands] + lea eax,[ecx+2] + test edi,edi + jz allocate_initial_commands_buffer + mov edx,[initial_commands_length] + add edi,edx + add eax,edx + cmp eax,[initial_commands_maximum_length] + ja grow_initial_commands_buffer + copy_initial_command: + rep movsb + mov ax,0Ah + stosw + dec edi + sub edi,[initial_commands] + mov [initial_commands_length],edi + pop edi ecx ebx + jmp next_argument + allocate_initial_commands_buffer: + push ecx + mov ecx,eax + call malloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + pop ecx + jmp copy_initial_command + grow_initial_commands_buffer: + push ecx + mov ecx,eax + mov eax,[initial_commands] + call realloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + add edi,[initial_commands_length] + pop ecx + jmp copy_initial_command + + include 'system.inc' + + include '../assembler.inc' + include '../symbols.inc' + include '../expressions.inc' + include '../conditions.inc' + include '../floats.inc' + include '../directives.inc' + include '../calm.inc' + include '../errors.inc' + include '../map.inc' + include '../reader.inc' + include '../output.inc' + include '../console.inc' + +section '__TEXT':'__cstring' align 4 + + _logo db 'flat assembler version g.',VERSION,10,0 + + _usage db 'Usage: fasmg source [output]',10 + db 'Optional settings:',10 + db ' -p limit Set the maximum allowed number of passes (default 100)',10 + db ' -e limit Set the maximum number of displayed errors (default 1)',10 + db ' -r limit Set the maximum depth of the stack (default 10000)',10 + db ' -v flag Enable or disable showing all lines from the stack (default 0)',10 + db ' -i command Insert instruction at the beginning of source',13,10 + db ' -n Do not show logo nor summary',13,10 + db 0 + + _pass db ' pass, ',0 + _passes db ' passes, ',0 + _dot db '.' + _seconds db ' seconds, ',0 + _byte db ' byte.',0 + _bytes db ' bytes.',0 + + _write_failed db 'failed to write the output file',0 + _out_of_memory db 'not enough memory to complete the assembly',0 + _code_cannot_be_generated db 'could not generate code within the allowed number of passes',0 + + _open_mode db 'r',0 + _create_mode db 'w',0 + + include '../tables.inc' + include '../messages.inc' + +section '__DATA':'__data' align 4 + + include '../variables.inc' + + source_path dd ? + output_path dd ? + maximum_number_of_passes dd ? + + initial_commands dd ? + initial_commands_length dd ? + initial_commands_maximum_length dd ? + + argc dd ? + argv dd ? + timestamp dq ? + + start_time timeval + end_time timeval + tenths_of_second dd ? + + verbosity_level dd ? + no_logo db ? + + path_buffer rb 1000h diff --git a/toolchain/fasmg.kl0e/source/macos/selfhost.inc b/toolchain/fasmg.kl0e/source/macos/selfhost.inc new file mode 100644 index 0000000..c1b1c74 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/macos/selfhost.inc @@ -0,0 +1,50 @@ + +include '../../examples/x86/include/80386.inc' + +macro format?.MachO? variant + match , variant + MachO.Settings.FileType equ MH_OBJECT + include '../../examples/x86/include/format/macho.inc' + use32 + else match =executable?, variant + MachO.Settings.BaseAddress = 0x1000 + include '../../examples/x86/include/format/macho.inc' + use32 + else + err 'invalid argument' + end match +end macro + +macro struct? name + macro ends?! + end namespace + esc end struc + virtual at 0 + name name + sizeof.name = $ + end virtual + purge ends? + end macro + esc struc name + label . : sizeof.name + namespace . +end macro + +macro ccall? proc*,args& + local size + mov ebp,esp + sub esp,size + and esp,0FFFFFFF0h + match any, args + iterate arg, args + mov dword [esp+(%-1)*4],arg + if % = 1 + size := %%*4 + end if + end iterate + else + size := 0 + end match + call proc + mov esp,ebp +end macro diff --git a/toolchain/fasmg.kl0e/source/macos/system.inc b/toolchain/fasmg.kl0e/source/macos/system.inc new file mode 100644 index 0000000..0461692 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/macos/system.inc @@ -0,0 +1,225 @@ + +LINE_FEED = 0Ah + +system_init: + ccall libc.time,timestamp + retn + +system_shutdown: + retn + +malloc: +malloc_fixed: +malloc_growable: +; in: ecx = requested size +; out: eax - allocated block, ecx = allocated size, on error jumps to out_of_memory (does not return) +; preserves: ebx, esi, edi +; note: +; use of malloc_fixed hints that block will be kept as is until the end of assembly +; use of malloc_growable hints that block is likely to be resized + push ebx ecx esi edi + ccall libc.malloc,ecx + pop edi esi ecx ebx + test eax,eax + jz out_of_memory + retn +realloc: +; in: eax - memory block, ecx = requested size +; out: eax - resized block, ecx = allocated size, on error jumps to out_of_memory (does not return) +; preserves: ebx, esi, edi + push ebx ecx esi edi + ccall libc.realloc,eax,ecx + pop edi esi ecx ebx + test eax,eax + jz out_of_memory + retn +mfree: +; in: eax - memory block +; out: cf set on error +; preserves: ebx, esi, edi +; note: eax may have value 0 or -1, it should be treated as invalid input then + test eax,eax + jz interface_error + cmp eax,-1 + je interface_error + push ebx esi edi + ccall libc.free,eax + pop edi esi ebx + clc + retn + interface_error: + stc + retn + +open: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + push esi edi + call adapt_path + ccall libc.fopen,ebx,_open_mode + pop edi esi + test eax,eax + jz interface_error + mov ebx,eax + clc + retn + adapt_path: + xor ecx,ecx + mov ebx,path_buffer + copy_path: + mov al,[edx+ecx] + cmp al,'\' + jne path_char_ok + mov al,'/' + path_char_ok: + cmp ecx,1000h + jae out_of_memory + mov [ebx+ecx],al + inc ecx + test al,al + jnz copy_path + retn +create: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + push esi edi + call adapt_path + ccall libc.fopen,ebx,_create_mode + pop edi esi + test eax,eax + jz interface_error + mov ebx,eax + clc + retn +write: +; in: ebx = file handle, edx - data, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push ebx ecx esi edi + ccall libc.fwrite,edx,1,ecx,ebx + pop edi esi ecx ebx + cmp eax,ecx + jne interface_error + clc + ret +read: +; in: ebx = file handle, edx - buffer, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push ebx ecx esi edi + ccall libc.fread,edx,1,ecx,ebx + pop edi esi ecx ebx + cmp eax,ecx + jne interface_error + clc + ret +close: +; in: ebx = file handle +; preserves: ebx, esi, edi + ccall libc.fclose,ebx + ret +lseek: +; in: ebx = file handle, cl = method, edx:eax = offset +; out: edx:eax = new offset from the beginning of file, cf set on error +; preserves: ebx, esi, edi + test edx,edx + jnz interface_error + push esi edi ebx + movzx ecx,cl + ccall libc.fseek,ebx,eax,ecx + test eax,eax + jnz lseek_error + mov ebx,[esp] + ccall libc.ftell,ebx + cmp eax,-1 + je lseek_error + xor edx,edx + pop ebx edi esi + clc + ret + lseek_error: + pop ebx edi esi + stc + ret + +get_timestamp: +; out: edx:eax = timestamp +; preserves: ebx, ecx, esi, edi +; note: during the passes of a single assembly this function should always return the same value + mov eax,dword [timestamp] + mov edx,dword [timestamp+4] + retn + +display_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push ebx esi + test ecx,ecx + jnz write_string_to_stdout + xor al,al + mov edi,esi + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + write_string_to_stdout: + ccall libc.write,1,esi,ecx + pop esi ebx + retn + +display_error_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push ebx esi + test ecx,ecx + jnz write_string_to_stderr + xor al,al + mov edi,esi + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + write_string_to_stderr: + ccall libc.write,2,esi,ecx + pop esi ebx + retn + +get_environment_variable: +; in: +; esi - name +; edi - buffer for value +; ecx = size of buffer +; out: +; eax = length of value +; preserves: ebx, esi, edi + push ebx ecx esi edi + ccall getenv,esi + pop edi esi ecx ebx + test eax,eax + jz no_environment_variable + push esi + mov esi,eax + xor eax,eax + copy_environment_variable: + mov dl,[esi+eax] + cmp eax,ecx + jae next_environment_variable_character + mov [edi+eax],dl + next_environment_variable_character: + inc eax + test dl,dl + jnz copy_environment_variable + pop esi + environment_variable_ok: + ret + no_environment_variable: + mov eax,1 + jecxz environment_variable_ok + and byte [edi],0 + ret diff --git a/toolchain/fasmg.kl0e/source/macos/x64/fasmg b/toolchain/fasmg.kl0e/source/macos/x64/fasmg new file mode 100644 index 0000000..f7e6012 Binary files /dev/null and b/toolchain/fasmg.kl0e/source/macos/x64/fasmg differ diff --git a/toolchain/fasmg.kl0e/source/macos/x64/fasmg.asm b/toolchain/fasmg.kl0e/source/macos/x64/fasmg.asm new file mode 100644 index 0000000..43677c3 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/macos/x64/fasmg.asm @@ -0,0 +1,546 @@ + +; Adapted and tested by Jacob Young (jacobly.alt@gmail.com) + +match ,{ + + err ; fasm 1 assembly not supported + +} match -,{ +else + + include 'selfhost.inc' + +end match +_ equ } + +format MachO64 executable +entry start + +include '../../version.inc' + +interpreter '/usr/lib/dyld' +uses '/usr/lib/libSystem.B.dylib' + +import libc.fopen,'_fopen',\ + libc.fclose,'_fclose',\ + libc.fread,'_fread',\ + libc.fwrite,'_fwrite',\ + libc.fseek,'_fseek',\ + libc.ftell,'_ftell',\ + libc.time,'_time',\ + libc.write,'_write',\ + mmap,'_mmap',\ + munmap,'_munmap',\ + getenv,'_getenv',\ + gettimeofday,'_gettimeofday',\ + exit,'_exit' + +struct timeval + time_t dq ? + suseconds_t dd ?,? +ends + +segment '__TEXT' readable executable + +section '__text' align 16 + + start: + mov rcx,[rsp] + mov [argc],rcx + lea rbx,[rsp+8] + mov [argv],rbx + + call system_init + + call get_arguments + mov bl,al + cmp [no_logo],0 + jne logo_ok + mov esi,_logo + xor ecx,ecx + call display_string + logo_ok: + test bl,bl + jnz display_usage_information + + xor al,al + mov ecx,[verbosity_level] + jecxz init + or al,TRACE_ERROR_STACK + dec ecx + jz init + or al,TRACE_DISPLAY + init: + call assembly_init + + ccall gettimeofday,start_time,0 + + assemble: + mov esi,[initial_commands] + mov edx,[source_path] + call assembly_pass + jc assembly_done + + mov eax,[current_pass] + cmp eax,[maximum_number_of_passes] + jb assemble + + call show_display_data + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,_code_cannot_be_generated + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + jmp assembly_failed + + assembly_done: + + call show_display_data + + cmp [first_error],0 + jne assembly_failed + + cmp [no_logo],0 + jne summary_done + mov eax,[current_pass] + xor edx,edx + call itoa + call display_string + mov esi,_passes + cmp [current_pass],1 + jne display_passes_suffix + mov esi,_pass + display_passes_suffix: + xor ecx,ecx + call display_string + ccall gettimeofday,end_time,0 + mov rax,[end_time.time_t] + sub rax,[start_time.time_t] + mov rcx,1000000 + mul rcx + mov ecx,[end_time.suseconds_t] + add ecx,50000 + add rax,rcx + adc rdx,0 + mov ecx,[start_time.suseconds_t] + sub rax,rcx + sbb rdx,0 + mov rcx,1000000 + div rcx + mov rbx,rax + mov rax,rdx + xor edx,edx + mov rcx,100000 + div rcx + mov [tenths_of_second],eax + xchg rax,rbx + or rbx,rax + jz display_output_length + mov rdx,rax + shr rdx,32 + call itoa + call display_string + mov esi,_message_suffix + mov ecx,1 + call display_string + mov eax,[tenths_of_second] + xor edx,edx + call itoa + call display_string + mov esi,_seconds + xor ecx,ecx + call display_string + display_output_length: + call get_output_length + push rax rdx + call itoa + call display_string + pop rdx rax + mov esi,_bytes + cmp eax,1 + jne display_bytes_suffix + test edx,edx + jnz display_bytes_suffix + mov esi,_byte + display_bytes_suffix: + xor ecx,ecx + call display_string + mov esi,_new_line + xor ecx,ecx + call display_string + summary_done: + + mov ebx,[source_path] + mov edi,[output_path] + call write_output_file + jc write_failed + + call assembly_shutdown + call system_shutdown + + ccall exit,0 + + assembly_failed: + + call show_errors + + call assembly_shutdown + call system_shutdown + + ccall exit,2 + + write_failed: + mov ebx,_write_failed + jmp fatal_error + + out_of_memory: + mov ebx,_out_of_memory + jmp fatal_error + + fatal_error: + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,ebx + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + call assembly_shutdown + call system_shutdown + + ccall exit,3 + + display_usage_information: + + mov esi,_usage + xor ecx,ecx + call display_string + + call system_shutdown + + ccall exit,1 + + get_arguments: + xor eax,eax + mov [initial_commands],eax + mov [source_path],eax + mov [output_path],eax + mov [no_logo],al + mov [verbosity_level],eax + mov [maximum_number_of_passes],100 + mov [maximum_number_of_errors],1 + mov [maximum_depth_of_stack],10000 + mov rcx,[argc] + mov rbx,[argv] + add rbx,8 + dec ecx + jz error_in_arguments + get_argument: + mov rsi,[rbx] + mov al,[rsi] + cmp al,'-' + je get_option + cmp [source_path],0 + jne get_output_file + call strdup + mov [source_path],eax + jmp next_argument + get_output_file: + cmp [output_path],0 + jne error_in_arguments + call strdup + mov [output_path],eax + jmp next_argument + get_option: + inc rsi + lodsb + cmp al,'e' + je set_errors_limit + cmp al,'E' + je set_errors_limit + cmp al,'i' + je insert_initial_command + cmp al,'I' + je insert_initial_command + cmp al,'p' + je set_passes_limit + cmp al,'P' + je set_passes_limit + cmp al,'r' + je set_recursion_limit + cmp al,'R' + je set_recursion_limit + cmp al,'v' + je set_verbose_mode + cmp al,'V' + je set_verbose_mode + cmp al,'n' + je set_no_logo + cmp al,'N' + jne error_in_arguments + set_no_logo: + or [no_logo],-1 + cmp byte [rsi],0 + je next_argument + error_in_arguments: + or al,-1 + ret + set_verbose_mode: + cmp byte [rsi],0 + jne get_verbose_setting + dec ecx + jz error_in_arguments + add rbx,8 + mov rsi,[rbx] + get_verbose_setting: + call get_option_value + cmp edx,2 + ja error_in_arguments + mov [verbosity_level],edx + jmp next_argument + set_errors_limit: + cmp byte [rsi],0 + jne get_errors_setting + dec ecx + jz error_in_arguments + add rbx,8 + mov rsi,[rbx] + get_errors_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_number_of_errors],edx + jmp next_argument + set_recursion_limit: + cmp byte [rsi],0 + jne get_recursion_setting + dec ecx + jz error_in_arguments + add rbx,8 + mov rsi,[rbx] + get_recursion_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_depth_of_stack],edx + jmp next_argument + set_passes_limit: + cmp byte [rsi],0 + jne get_passes_setting + dec ecx + jz error_in_arguments + add rbx,8 + mov rsi,[rbx] + get_passes_setting: + call get_option_value + test edx,edx + jz error_in_arguments + mov [maximum_number_of_passes],edx + next_argument: + add rbx,8 + dec ecx + jnz get_argument + cmp [source_path],0 + je error_in_arguments + xor al,al + ret + get_option_value: + xor eax,eax + mov edx,eax + find_option_value: + cmp byte [rsi],20h + jne get_option_digit + inc rsi + jmp find_option_value + get_option_digit: + lodsb + test al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec rsi + clc + ret + invalid_option_value: + stc + ret + insert_initial_command: + cmp byte [rsi],0 + jne measure_initial_command + dec ecx + jz error_in_arguments + add rbx,8 + mov rsi,[rbx] + measure_initial_command: + push rbx rcx rdi + mov rdi,rsi + or ecx,-1 + xor al,al + repne scasb + not ecx + dec ecx + mov edi,[initial_commands] + lea eax,[ecx+2] + test edi,edi + jz allocate_initial_commands_buffer + mov edx,[initial_commands_length] + add edi,edx + add eax,edx + cmp eax,[initial_commands_maximum_length] + ja grow_initial_commands_buffer + copy_initial_command: + rep movsb + mov ax,0Ah + stosw + dec edi + sub edi,[initial_commands] + mov [initial_commands_length],edi + pop rdi rcx rbx + jmp next_argument + allocate_initial_commands_buffer: + push rsi rcx + mov ecx,eax + call malloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + pop rcx rsi + jmp copy_initial_command + grow_initial_commands_buffer: + push rsi rcx + mov ecx,eax + mov eax,[initial_commands] + call realloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + add edi,[initial_commands_length] + pop rcx rsi + jmp copy_initial_command + + strdup: + ; in: rsi - ASCIIZ string + ; out: eax - copy of the string in 32-bit addressable memory + ; preserves: rbx, rcx, rsi + push rbx rcx rsi + mov rdi,rsi + or ecx,-1 + xor al,al + repne scasb + not ecx + push rsi rcx + call malloc + pop rcx rsi + mov edi,eax + rep movsb + pop rsi rcx rbx + ret + + include 'system.inc' + + use32on64 + + include '../../malloc.inc' + include '../../assembler.inc' + include '../../symbols.inc' + include '../../expressions.inc' + include '../../conditions.inc' + include '../../floats.inc' + include '../../directives.inc' + include '../../calm.inc' + include '../../errors.inc' + include '../../map.inc' + include '../../reader.inc' + include '../../output.inc' + include '../../console.inc' + +section '__cstring' align 4 + + _logo db 'flat assembler version g.',VERSION,10,0 + + _usage db 'Usage: fasmg source [output]',10 + db 'Optional settings:',10 + db ' -p limit Set the maximum allowed number of passes (default 100)',10 + db ' -e limit Set the maximum number of displayed errors (default 1)',10 + db ' -r limit Set the maximum depth of the stack (default 10000)',10 + db ' -v flag Enable or disable showing all lines from the stack (default 0)',10 + db ' -i command Insert instruction at the beginning of source',13,10 + db ' -n Do not show logo nor summary',13,10 + db 0 + + _pass db ' pass, ',0 + _passes db ' passes, ',0 + _dot db '.' + _seconds db ' seconds, ',0 + _byte db ' byte.',0 + _bytes db ' bytes.',0 + + _write_failed db 'failed to write the output file',0 + _out_of_memory db 'not enough memory to complete the assembly',0 + _code_cannot_be_generated db 'could not generate code within the allowed number of passes',0 + + _open_mode db 'r',0 + _create_mode db 'w',0 + + include '../../tables.inc' + include '../../messages.inc' + +segment '__DATA' readable writable + +section '__bss' align 4 + + include '../../variables.inc' + + mmap_hint dd ? + malloc_freelist dd ? + + source_path dd ? + output_path dd ? + maximum_number_of_passes dd ? + + initial_commands dd ? + initial_commands_length dd ? + initial_commands_maximum_length dd ? + + files dd ? + files_count dd ? + files_maximum_count dd ? + + argc dq ? + argv dq ? + timestamp dq ? + + start_time timeval + end_time timeval + tenths_of_second dd ? + + verbosity_level dd ? + no_logo db ? + + local_heap_available db ? + + path_buffer rb 1000h + + align 1000h + + LOCAL_HEAP_SIZE = 1000000h + + local_heap rb LOCAL_HEAP_SIZE diff --git a/toolchain/fasmg.kl0e/source/macos/x64/selfhost.inc b/toolchain/fasmg.kl0e/source/macos/x64/selfhost.inc new file mode 100644 index 0000000..f487c47 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/macos/x64/selfhost.inc @@ -0,0 +1,41 @@ + +; Adapted and tested by Jacob Young (jacobly.alt@gmail.com) + +include '../../linux/x64/selfhost.inc' + +macro format?.MachO64? variant + match , variant + MachO.Settings.ProcessorType = CPU_TYPE_X86_64 + MachO.Settings.FileType equ MH_OBJECT + include '../../../examples/x86/include/format/macho.inc' + use64 + else match =executable?, variant + MachO.Settings.ProcessorType = CPU_TYPE_X86_64 + MachO.Settings.BaseAddress = 0x1000 + include '../../../examples/x86/include/format/macho.inc' + use64 + else + err 'invalid argument' + end match +end macro + +iterate reg, rdi, rsi, rdx, rcx, r8, r9 + arguments.%? equ reg +end iterate + +macro ccall? proc*,args& + local size + mov rbp,rsp + and rsp,0FFFFFFFFFFFFFFF0h + match any, args + iterate arg, args + if sizeof (arg) + lea arguments.%,[arg] + else if ~ arg eq arguments.% + mov arguments.%,arg + end if + end iterate + end match + call proc + mov rsp,rbp +end macro diff --git a/toolchain/fasmg.kl0e/source/macos/x64/system.inc b/toolchain/fasmg.kl0e/source/macos/x64/system.inc new file mode 100644 index 0000000..55e0a92 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/macos/x64/system.inc @@ -0,0 +1,287 @@ + +; Adapted and tested by Jacob Young (jacobly.alt@gmail.com) + +LINE_FEED = 0Ah + +system_init: + ccall libc.time,timestamp + or [local_heap_available],1 + retn + +system_shutdown: + retn + +open: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + push rsi rdi + call adapt_path + ccall libc.fopen,rbx,_open_mode + put_file_entry: + pop rdi rsi + test rax,rax + jz interface_error + push rax + mov eax,[files] + mov ecx,[files_count] + mov ebx,ecx + inc ecx + mov [files_count],ecx + cmp ecx,[files_maximum_count] + ja grow_files_buffer + store_file_entry: + pop rdx + mov [eax+ebx*8],rdx + clc + retn + interface_error: + stc + retn + grow_files_buffer: + shl ecx,4 + test eax,eax + jz allocate_files_buffer + call realloc + jmp allocated_files_buffer + allocate_files_buffer: + call malloc + allocated_files_buffer: + mov [files],eax + shr ecx,3 + mov [files_maximum_count],ecx + jmp store_file_entry + adapt_path: + xor ecx,ecx + mov ebx,path_buffer + copy_path: + mov al,[edx+ecx] + cmp al,'\' + jne path_char_ok + mov al,'/' + path_char_ok: + cmp ecx,1000h + jae out_of_memory + mov [ebx+ecx],al + inc ecx + test al,al + jnz copy_path + retn +create: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + push rsi rdi + call adapt_path + ccall libc.fopen,rbx,_create_mode + jmp put_file_entry +write: +; in: ebx = file handle, edx - data, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push rbx rcx rsi rdi + mov eax,[files] + mov rax,[eax+ebx*8] + ccall libc.fwrite,rdx,1,rcx,rax + pop rdi rsi rcx rbx + cmp eax,ecx + jne interface_error + clc + ret +read: +; in: ebx = file handle, edx - buffer, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push rbx rcx rsi rdi + mov eax,[files] + mov rax,[eax+ebx*8] + ccall libc.fread,rdx,1,rcx,rax + pop rdi rsi rcx rbx + cmp eax,ecx + jne interface_error + clc + ret +close: +; in: ebx = file handle +; preserves: ebx, esi, edi + push rsi rdi + mov edi,[files] + mov rdi,[edi+ebx*8] + ccall libc.fclose,rdi + pop rdi rsi + ret +lseek: +; in: ebx = file handle, cl = method, edx:eax = offset +; out: edx:eax = new offset from the beginning of file, cf set on error +; preserves: ebx, esi, edi + push rsi rdi rbx + shl rdx,32 + or rax,rdx + movzx ecx,cl + mov edi,[files] + mov rdi,[edi+ebx*8] + push rdi + ccall libc.fseek,rdi,rax,rcx + test eax,eax + jnz lseek_error + pop rdi + ccall libc.ftell,rdi + cmp rax,-1 + je lseek_error + mov rdx,rax + shr rdx,32 + mov eax,eax + pop rbx rdi rsi + clc + ret + lseek_error: + pop rbx rdi rsi + stc + ret + +get_timestamp: +; out: edx:eax = timestamp +; preserves: ebx, ecx, esi, edi +; note: during the passes of a single assembly this function should always return the same value + mov eax,dword [timestamp] + mov edx,dword [timestamp+4] + retn + +display_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push rbx rsi + test ecx,ecx + jnz write_string_to_stdout + xor al,al + mov edi,esi + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + write_string_to_stdout: + ccall libc.write,1,rsi,rcx + pop rsi rbx + retn + +display_error_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push rbx rsi + test ecx,ecx + jnz write_string_to_stderr + xor al,al + mov edi,esi + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + write_string_to_stderr: + ccall libc.write,2,rsi,rcx + pop rsi rbx + retn + +get_environment_variable: +; in: +; esi - name +; edi - buffer for value +; ecx = size of buffer +; out: +; eax = length of value +; preserves: ebx, esi, edi + push rbx rcx rsi rdi + ccall getenv,rsi + pop rdi rsi rcx rbx + test rax,rax + jz no_environment_variable + push rsi + mov rsi,rax + xor eax,eax + copy_environment_variable: + mov dl,[rsi+rax] + cmp eax,ecx + jae next_environment_variable_character + mov [edi+eax],dl + next_environment_variable_character: + inc eax + test dl,dl + jnz copy_environment_variable + pop rsi + environment_variable_ok: + ret + no_environment_variable: + mov eax,1 + jecxz environment_variable_ok + and byte [edi],0 + ret + +VALLOC_MINIMUM_SIZE = 100000h + +valloc: +; in: ecx = requested minimum size +; out: eax - allocated block, ecx = allocated size, zero if failed +; preserves: ebx, esi, edi + cmp ecx,VALLOC_MINIMUM_SIZE + jbe valloc_size_minimum + dec ecx + and ecx,(-1) shl 12 + add ecx,1 shl 12 + jmp valloc_size_ready + valloc_size_minimum: + mov ecx,VALLOC_MINIMUM_SIZE + valloc_size_ready: + push rbx rsi rdi + cmp [local_heap_available],0 + je valloc_mmap + cmp ecx,LOCAL_HEAP_SIZE + ja valloc_mmap + and [local_heap_available],0 + mov eax,local_heap + mov ecx,LOCAL_HEAP_SIZE + jmp valloc_ok + valloc_mmap: + push rcx + ccall mmap,0,rcx, \ + 3, \ ; PROT_READ + PROT_WRITE + 9002h, \ ; MAP_PRIVATE + MAP_ANONYMOUS + MAP_32BIT + -1,0 + pop rsi + cmp eax,-1 + je valloc_mmap_with_hint + mov ecx,eax + cmp rcx,rax + jne valloc_mmap_unusable + add ecx,esi + jnc mmap_ok + valloc_mmap_unusable: + ccall munmap,rax,rsi + valloc_mmap_with_hint: + push rsi + mov edi,[mmap_hint] + ccall mmap,rdi,rsi, \ + 3, \ ; PROT_READ + PROT_WRITE + 1002h, \ ; MAP_PRIVATE + MAP_ANONYMOUS + -1,0 + pop rsi + cmp eax,-1 + je valloc_failed + mov ecx,eax + cmp rcx,rax + jne valloc_failed + add ecx,esi + jc valloc_failed + mmap_ok: + sub ecx,eax + valloc_ok: + lea edx,[eax+ecx] + mov [mmap_hint],edx + pop rdi rsi rbx + retn + valloc_failed: + xor ecx,ecx + pop rdi rsi rbx + retn \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/source/malloc.inc b/toolchain/fasmg.kl0e/source/malloc.inc new file mode 100644 index 0000000..9b99e46 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/malloc.inc @@ -0,0 +1,343 @@ + +; a very basic implementation of malloc/realloc +; for porting fasmg to systems that do not have such API natively + +struct MemoryHeader + size dd ? ; total size of this block, the lowest bit set for blocks in use + preceding_size dd ? ; total size of the block that precedes this one in memory (zero if this is an initial block of address range) +ends + +struct FreeMemory + header MemoryHeader + right dd ? ; next free block in cyclic list + left dd ? ; previous free block in cyclic list +ends + +assert defined valloc +; in: ecx = requested minimum size +; out: eax - allocated block, ecx = allocated size, zero if failed +; preserves: ebx, esi, edi +; note: +; valloc is called to request raw memory from the OS; +; it is encouraged to allocate more memory than requested (even entire available memory), +; the obtained memory is kept indefinitely in the pool for malloc +; and should be released by OS automatically when the process ends; +; if the OS does not do it automatically, additional list of the memory areas +; may need to be maintained to release them before exit + +malloc: +malloc_fixed: +malloc_growable: +; in: ecx = requested size +; out: eax - allocated block, ecx = allocated size, on error jumps to out_of_memory (does not return) +; preserves: ebx, esi, edi + add ecx,sizeof.MemoryHeader-1 + jc out_of_memory + and ecx,(-1) shl 2 + add ecx,1 shl 2 + jc out_of_memory + cmp ecx,sizeof.FreeMemory + jae malloc_size_ok + mov ecx,sizeof.FreeMemory + malloc_size_ok: + mov eax,[malloc_freelist] + test eax,eax + jz malloc_new + find_fit: + cmp ecx,[eax+MemoryHeader.size] + jbe malloc_use_block + mov eax,[eax+FreeMemory.left] + cmp eax,[malloc_freelist] + jne find_fit + malloc_new: + push ecx + add ecx,sizeof.MemoryHeader + jc out_of_memory + call valloc + test ecx,ecx + jz out_of_memory + xor edx,edx + mov [eax+MemoryHeader.preceding_size],edx + pop edx + push eax + sub ecx,edx + cmp ecx,sizeof.FreeMemory+sizeof.MemoryHeader + jb no_space_for_free_block + mov [eax+MemoryHeader.size],edx + add eax,edx + mov [eax+MemoryHeader.preceding_size],edx + mov edx,ecx + sub edx,sizeof.MemoryHeader + dec edx + and edx,(-1) shl 2 + add edx,1 shl 2 + mov [eax+MemoryHeader.size],edx + mov ecx,[malloc_freelist] + jecxz freelist_empty + mov [eax+FreeMemory.left],ecx + mov edx,eax + xchg edx,[ecx+FreeMemory.right] + mov [eax+FreeMemory.right],edx + mov [edx+FreeMemory.left],eax + mov edx,[eax+MemoryHeader.size] + jmp free_block_ready + no_space_for_free_block: + sub ecx,sizeof.MemoryHeader + add edx,ecx + mov [eax+MemoryHeader.size],edx + jmp append_limiter + freelist_empty: + mov [eax+FreeMemory.left],eax + mov [eax+FreeMemory.right],eax + free_block_ready: + mov [malloc_freelist],eax + append_limiter: + add eax,edx + mov [eax+MemoryHeader.preceding_size],edx + mov [eax+MemoryHeader.size],sizeof.MemoryHeader or 1 ; cannot be freed + pop eax + finish_malloc: + mov ecx,[eax+MemoryHeader.size] + or [eax+MemoryHeader.size],1 + add eax,sizeof.MemoryHeader + sub ecx,sizeof.MemoryHeader + retn + malloc_use_block: + mov edx,[eax+MemoryHeader.size] + sub edx,ecx + cmp edx,sizeof.FreeMemory + jb use_whole_block + mov [eax+MemoryHeader.size],ecx + mov [eax+ecx+MemoryHeader.preceding_size],ecx + add ecx,eax + mov [malloc_freelist],ecx + mov [ecx+MemoryHeader.size],edx + mov [ecx+edx+MemoryHeader.preceding_size],edx + mov edx,[eax+FreeMemory.right] + cmp edx,eax + je update_free_singleton + mov [ecx+FreeMemory.right],edx + mov [edx+FreeMemory.left],ecx + mov edx,[eax+FreeMemory.left] + mov [ecx+FreeMemory.left],edx + mov [edx+FreeMemory.right],ecx + jmp finish_malloc + update_free_singleton: + mov [ecx+FreeMemory.left],ecx + mov [ecx+FreeMemory.right],ecx + jmp finish_malloc + use_whole_block: + mov edx,[eax+FreeMemory.right] + cmp edx,eax + je depleted_freelist + mov ecx,[eax+FreeMemory.left] + mov [ecx+FreeMemory.right],edx + mov [edx+FreeMemory.left],ecx + mov [malloc_freelist],edx + jmp finish_malloc + depleted_freelist: + and [malloc_freelist],0 + jmp finish_malloc + +mfree: +; in: eax - memory block +; out: cf set on error +; preserves: ebx, esi, edi +; note: eax may have value 0 or -1, it should be treated as invalid input then + test eax,eax + jz mfree_error + cmp eax,-1 + je mfree_error + sub eax,sizeof.MemoryHeader + mov ecx,[eax+MemoryHeader.size] + btr ecx,0 + jnc mfree_error + cmp ecx,sizeof.FreeMemory + jb mfree_error + cmp [eax+ecx+MemoryHeader.preceding_size],ecx + jne mfree_error + mov [eax+MemoryHeader.size],ecx + mov edx,eax + sub edx,[eax+MemoryHeader.preceding_size] + cmp edx,eax + je no_preceding_block + test [edx+MemoryHeader.size],1 + jz coalesce_with_preceding_block + no_preceding_block: + test [eax+ecx+MemoryHeader.size],1 + jz coalesce_with_following_block + mov ecx,[malloc_freelist] + jecxz mfree_init_freelist + mov edx,[ecx+FreeMemory.right] + mov [eax+FreeMemory.left],ecx + mov [edx+FreeMemory.left],eax + mov [eax+FreeMemory.right],edx + mov [ecx+FreeMemory.right],eax + mfree_ok: + mov [malloc_freelist],eax + clc + retn + mfree_init_freelist: + mov [eax+FreeMemory.left],eax + mov [eax+FreeMemory.right],eax + jmp mfree_ok + mfree_error: + stc + retn + coalesce_with_preceding_block: + add ecx,[edx+MemoryHeader.size] + test [edx+ecx+MemoryHeader.size],1 + jz coalesce_on_both_ends + mov [edx+MemoryHeader.size],ecx + mov [edx+ecx+MemoryHeader.preceding_size],ecx + clc + retn + coalesce_on_both_ends: + lea eax,[edx+ecx] + add ecx,[eax+MemoryHeader.size] + mov [edx+MemoryHeader.size],ecx + mov [edx+ecx+MemoryHeader.preceding_size],ecx + mov [malloc_freelist],edx + mov ecx,[eax+FreeMemory.left] + mov edx,[eax+FreeMemory.right] + mov [edx+FreeMemory.left],ecx + mov [ecx+FreeMemory.right],edx + clc + retn + coalesce_with_following_block: + push ebx + lea ebx,[eax+ecx] + add ecx,[ebx+MemoryHeader.size] + mov [eax+MemoryHeader.size],ecx + mov [eax+ecx+MemoryHeader.preceding_size],ecx + mov ecx,[ebx+FreeMemory.left] + mov edx,[ebx+FreeMemory.right] + mov [ecx+FreeMemory.right],eax + mov [edx+FreeMemory.left],eax + mov ecx,[ebx+FreeMemory.left] + mov edx,[ebx+FreeMemory.right] + mov [eax+FreeMemory.left],ecx + mov [eax+FreeMemory.right],edx + pop ebx + jmp mfree_ok + +realloc: +; in: eax - memory block, ecx = requested size +; out: eax - resized block, ecx = allocated size, on error jumps to out_of_memory (does not return) +; preserves: ebx, esi, edi + add ecx,sizeof.MemoryHeader-1 + jc out_of_memory + and ecx,(-1) shl 2 + add ecx,1 shl 2 + jc out_of_memory + sub eax,sizeof.MemoryHeader + mov edx,[eax+MemoryHeader.size] + and edx,not 1 + cmp ecx,edx + jbe realloc_retain + test [eax+edx+MemoryHeader.size],1 + jnz realloc_and_copy + add edx,[eax+edx+MemoryHeader.size] + cmp ecx,edx + ja realloc_and_copy + sub edx,ecx + cmp edx,sizeof.FreeMemory + jb append_whole_block + push esi edi + push ecx edx + lea edi,[eax+ecx] + xchg ecx,[eax+MemoryHeader.size] + and ecx,not 1 + lea esi,[eax+ecx] + mov ecx,[esi+FreeMemory.left] + mov edx,[esi+FreeMemory.right] + mov [edx+FreeMemory.left],edi + mov [ecx+FreeMemory.right],edi + mov ecx,[esi+FreeMemory.left] + mov edx,[esi+FreeMemory.right] + mov [edi+FreeMemory.left],ecx + mov [edi+FreeMemory.right],edx + mov [malloc_freelist],edi + pop edx ecx + mov [edi+MemoryHeader.size],edx + mov [edi+edx+MemoryHeader.preceding_size],edx + mov [edi+MemoryHeader.preceding_size],ecx + pop edi esi + jmp finish_malloc + append_whole_block: + add edx,ecx + mov [eax+edx+MemoryHeader.preceding_size],edx + xchg edx,[eax+MemoryHeader.size] + and edx,not 1 + add edx,eax + mov ecx,[edx+FreeMemory.left] + cmp ecx,edx + je depleted_freelist + mov edx,[edx+FreeMemory.right] + mov [ecx+FreeMemory.right],edx + mov [edx+FreeMemory.left],ecx + mov [malloc_freelist],ecx + jmp finish_malloc + realloc_retain: + and [eax+MemoryHeader.size],not 1 + jmp finish_malloc + realloc_and_copy: + push esi edi + lea esi,[eax+sizeof.MemoryHeader] + call malloc_growable + push eax ecx + mov edi,eax + mov eax,esi + mov ecx,[esi-sizeof.MemoryHeader+MemoryHeader.size] + shr ecx,2 + rep movsd + call mfree + pop ecx eax + pop edi esi + retn + +if used mcheck + + mcheck: + pushf + push eax ebx ecx edx + mov eax,[malloc_freelist] + test eax,eax + jz integrity_verified + verify_freelist: + mov ebx,eax + verify_preceding_blocks: + mov ecx,[ebx+MemoryHeader.preceding_size] + jecxz preceding_blocks_ok + sub ebx,ecx + mov edx,[ebx+MemoryHeader.size] + and edx,not 1 + cmp ecx,edx + je verify_preceding_blocks + jmp internal_error + preceding_blocks_ok: + mov ebx,eax + verify_following_blocks: + mov ecx,[ebx+MemoryHeader.size] + and ecx,not 1 + cmp ecx,sizeof.MemoryHeader + je following_blocks_ok + add ebx,ecx + cmp ecx,[ebx+MemoryHeader.preceding_size] + je verify_following_blocks + jmp internal_error + following_blocks_ok: + mov edx,[eax+FreeMemory.right] + cmp eax,[edx+FreeMemory.left] + je verify_next + jmp internal_error + verify_next: + mov eax,edx + cmp eax,[malloc_freelist] + jne verify_freelist + integrity_verified: + pop edx ecx ebx eax + popf + retn + +end if diff --git a/toolchain/fasmg.kl0e/source/map.inc b/toolchain/fasmg.kl0e/source/map.inc new file mode 100644 index 0000000..a4f3579 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/map.inc @@ -0,0 +1,237 @@ + +; this is a simple map used primarily for the source cache + +struct Map + hash_mask dd ? + linked_blocks dd ? + free_space dd ? + free_space_length dd ? +ends + +struct MapEntry + name dd ? + name_length dd ? + value dd ? + next_entry dd ? +ends + +create_string_map: +; in: cl = number of hash bits +; out: ebx - new map +; preserves: esi + mov ebx,1 + shl ebx,cl + shl ebx,2 + lea ecx,[sizeof.Map+ebx*4] + call malloc_fixed + xchg ebx,eax + mov ecx,eax + dec eax + mov [ebx+Map.hash_mask],eax + lea edi,[ebx+sizeof.Map] + xor eax,eax + rep stosd + mov ecx,1000h + call malloc_fixed + mov [ebx+Map.linked_blocks],eax + xor edx,edx + mov [eax],edx + add eax,10h + mov [ebx+Map.free_space],eax + mov [ebx+Map.free_space_length],1000h-10h + retn + +destroy_string_map: +; in: ebx - map +; preserves: esi, edi + mov eax,ebx + mov ebx,[ebx+Map.linked_blocks] + call mfree + free_map_blocks: + test ebx,ebx + jz string_map_destroyed + mov eax,ebx + mov ebx,[ebx] + call mfree + jmp free_map_blocks + string_map_destroyed: + retn + +get_from_map: +; in: +; ebx - map +; esi - string +; ecx = string length, zero for ASCIIZ string +; out: +; eax = value +; cf set when no entry found +; preserves: ebx, [esi], edi +; note: when entry is found, esi is replaced with pointer to the same string in persistent storage + call get_bucket + test eax,eax + jz not_found_in_map + call find_map_entry + jc not_found_in_map + mov eax,[eax+MapEntry.value] + retn + get_bucket: + call hash_string + and edx,[ebx+Map.hash_mask] + mov eax,[ebx+sizeof.Map+edx*4] + retn + find_map_entry: + cmp [eax+MapEntry.name_length],ecx + jne next_map_entry + push edi + mov edi,[eax+MapEntry.name] + test edi,edi + jz not_this_map_entry + push ecx esi + repe cmpsb + pop esi ecx + jne not_this_map_entry + mov esi,edi + sub esi,ecx + pop edi + clc + retn + not_this_map_entry: + pop edi + next_map_entry: + mov eax,[eax+MapEntry.next_entry] + test eax,eax + jnz find_map_entry + not_found_in_map: + stc + retn + +put_into_map: +; in: +; ebx - map +; esi - string +; ecx = string length, zero for ASCIIZ string +; eax = value +; preserves: ebx, [esi], edi +; note: +; esi is replaced with pointer to the same string in persistent storage, +; an ASCIIZ string is a key with length including the terminating zero +; and when it is put into persistent storage, final zero is copied as well + push eax + call get_bucket + test eax,eax + jz new_bucket + call find_map_entry + jnc put_value_into_map_entry + mov eax,[ebx+sizeof.Map+edx*4] + find_free_map_entry: + cmp [eax+MapEntry.name],0 + je fill_map_entry + mov edx,eax + mov eax,[eax+MapEntry.next_entry] + test eax,eax + jnz find_free_map_entry + call allocate_map_entry + mov [edx+MapEntry.next_entry],eax + jmp new_map_entry + new_bucket: + call allocate_map_entry + mov [ebx+sizeof.Map+edx*4],eax + new_map_entry: + mov [eax+MapEntry.next_entry],0 + fill_map_entry: + mov [eax+MapEntry.name_length],ecx + push eax + call store_string + pop eax + mov [eax+MapEntry.name],esi + put_value_into_map_entry: + pop [eax+MapEntry.value] + retn + allocate_map_entry: + mov eax,[ebx+Map.free_space] + add [ebx+Map.free_space],sizeof.MapEntry + sub [ebx+Map.free_space_length],sizeof.MapEntry + jc map_out_of_free_space + retn + map_out_of_free_space: + push ecx edx + mov ecx,1000h + call malloc_fixed + mov edx,eax + xchg [ebx+Map.linked_blocks],edx + mov [eax],edx + add eax,10h + mov [ebx+Map.free_space],eax + mov [ebx+Map.free_space_length],1000h-10h + pop edx ecx + jmp allocate_map_entry + +remove_from_map: +; in: +; ebx - map +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, [esi], edi + call get_bucket + test eax,eax + jz not_found_in_map + call find_map_entry + jc not_found_in_map + mov dword [eax+MapEntry.name],0 + retn + +iterate_through_map: +; in: +; ebx - map +; edi - callback function +; callback: +; eax = value +; esi - string +; ecx = string length +; edx - MapEntry + mov ecx,[ebx+Map.hash_mask] + inc ecx + add ebx,sizeof.Map + iterate_through_hash_table: + mov edx,[ebx] + iterate_through_bucket: + test edx,edx + jz end_of_bucket + push ebx ecx edx edi + mov eax,[edx+MapEntry.value] + mov esi,[edx+MapEntry.name] + mov ecx,[edx+MapEntry.name_length] + call edi + pop edi edx ecx ebx + mov edx,[edx+MapEntry.next_entry] + jmp iterate_through_bucket + end_of_bucket: + add ebx,4 + loop iterate_through_hash_table + retn + +hash_string: +; in: esi - string, ecx = string length, zero for ASCIIZ string +; out: ecx = string length, edx = 32-bit hash +; preserves: ebx, esi, edi + mov edx,FNV_OFFSET + jecxz hash_asciiz + mov eax,ecx + hash_known_length: + xor dl,[esi] + inc esi + imul edx,FNV_PRIME + loop hash_known_length + mov ecx,eax + sub esi,ecx + retn + hash_asciiz: + inc ecx + lodsb + xor dl,al + imul edx,FNV_PRIME + test al,al + jnz hash_asciiz + hash_ready: + sub esi,ecx + retn diff --git a/toolchain/fasmg.kl0e/source/messages.inc b/toolchain/fasmg.kl0e/source/messages.inc new file mode 100644 index 0000000..be37c77 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/messages.inc @@ -0,0 +1,52 @@ + +_macro_source db 'macro ',0 +_preprocessed_source db 'assemble ',0 +_unnamed_source db '?',0 +_memory_source db 'eval',0 +_space db ' ',0 +_line_number_prefix db ' [',0 +_line_number_suffix db ']',0 +_line_content_prefix db ':' +_line_segment_prefix db LINE_FEED,9,0 +_calm_source db ' (CALM)',0 +_single_quote db 27h,0 +_preprocessed_text_prefix db 'Processed: ',0 +_error_prefix db 'Error: ',0 +_custom_error_prefix db 'Custom error: ',0 +_message_suffix db '.' +_new_line db LINE_FEED,0 + +_source_file_not_found db "source file '%s' not found",0 +_error_reading_file db "error reading file '%s'",0 +_missing_end_quote db "missing end quote",0 +_illegal_instruction db "illegal instruction",0 +_invalid_argument db "invalid argument",0 +_missing_argument db "missing argument",0 +_extra_characters_on_line db "extra characters on line",0 +_invalid_identifier db "invalid identifier",0 +_invalid_number db "invalid number",0 +_undefined_symbol db "symbol '%i' is undefined or out of scope",0 +_invalid_symbol_value db "the value of symbol '%i' is not valid for this use",0 +_conflicting_definition db "definition of '%i' in conflict with already defined symbol",0 +_cannot_apply_to_constant db "cannot apply this operation to constant",0 +_symbolic_self_reference db "detected a circular reference of symbolic values",0 +_unexpected_instruction db "unexpected instruction",0 +_missing_end_directive db "missing end directive",0 +_missing_closing_chevron db "missing closing chevron",0 +_invalid_value db "value of type not allowed in this context",0 +_invalid_expression db "invalid expression",0 +_missing_closing_parenthesis db "missing closing parenthesis",0 +_excess_closing_parenthesis db "excess closing parenthesis",0 +_value_out_of_range db "value out of allowed range",0 +_indeterminate_result db "expression has indeterminate, infinite, or infinitesimal result",0 +_misused_variable_term db "variable term used where not expected",0 +_nonlinear_polynomial db "cannot multiply variable terms",0 +_subdivided_variable_term db "cannot subdivide variable term",0 +_values_not_comparable db "values not comparable",0 +_assertion_failed db "assertion failed",0 +_area_overflow db "exceeded the maximum allowed length of output area",0 +_address_out_of_range db "address out of range",0 +_invalid_area db "invalid or inaccessible addressing area",0 +_stack_limit_exceeded db "exceeded the maximum allowed depth of the stack",0 +_repeated_declaration db "choice has already been declared",0 +_undefined_jump_target db "the target of the jump is not defined in this instruction",0 diff --git a/toolchain/fasmg.kl0e/source/output.inc b/toolchain/fasmg.kl0e/source/output.inc new file mode 100644 index 0000000..091c87a --- /dev/null +++ b/toolchain/fasmg.kl0e/source/output.inc @@ -0,0 +1,883 @@ + +struct OutputArea + cached_offset dq ? + definition dd ? ; pointer to ValueDefinition +ends + +struct AreaHeader + flags dd ? ; AREA_# + base_address_length dd ? + uninitialized_length dd ? +ends + +AREA_VIRTUAL = 1 +AREA_VARIABLE = 2 +AREA_SHIFT_TRACKING_DISABLED = 4 + +create_output_area: +; in: +; esi - base address in format of VALTYPE_NUMERIC value +; ecx = length of base address value +; out: +; ebx - AreaHeader +; edx - ValueDefinition + mov eax,[current_output_area_entry] + test eax,eax + jz create_first_output_area + push ecx + lea ecx,[eax+sizeof.OutputArea*2] + cmp ecx,[output_areas_list_end] + jbe get_next_output_entry + mov eax,[output_areas_list] + sub ecx,eax + sub [current_output_area_entry],eax + sub [initial_output_area_entry],eax + sub [output_areas_list_end],eax + call grow_stack + mov [output_areas_list],eax + add [current_output_area_entry],eax + add [initial_output_area_entry],eax + add eax,ecx + mov edi,eax + xchg [output_areas_list_end],eax + sub ecx,eax + sub edi,ecx + shr ecx,2 + xor eax,eax + rep stosd + mov eax,[current_output_area_entry] + get_next_output_entry: + add eax,sizeof.OutputArea + cmp [initial_output_area_entry],0 + je another_initial_output_area + mov edi,[eax-sizeof.OutputArea+OutputArea.definition] + mov ecx,[edi+ValueDefinition.value_length] + mov edi,[edi+ValueDefinition.value] + mov ebx,[edi+AreaHeader.uninitialized_length] + sub ecx,sizeof.AreaHeader + sub ecx,[edi+AreaHeader.base_address_length] + jz prior_uninitialized_length_ok + and dword [prior_uninitialized_length],0 + and dword [prior_uninitialized_length+4],0 + prior_uninitialized_length_ok: + add dword [prior_uninitialized_length],ebx + adc dword [prior_uninitialized_length+4],0 + xor edx,edx + add ecx,ebx + adc edx,0 + add ecx,dword [eax-sizeof.OutputArea+OutputArea.cached_offset] + adc edx,dword [eax-sizeof.OutputArea+OutputArea.cached_offset+4] + mov dword [eax+OutputArea.cached_offset],ecx + mov dword [eax+OutputArea.cached_offset+4],edx + pop ecx + jmp new_output_entry_ready + another_initial_output_area: + pop ecx + jmp create_initial_output_area + create_first_output_area: + mov eax,[output_areas_list] + create_initial_output_area: + mov [initial_output_area_entry],eax + and dword [eax+OutputArea.cached_offset],0 + and dword [eax+OutputArea.cached_offset+4],0 + and dword [prior_uninitialized_length],0 + and dword [prior_uninitialized_length+4],0 + new_output_entry_ready: + mov [current_output_area_entry],eax + lea ebx,[eax+OutputArea.definition] + call create_area + retn + +create_area: +; in: +; ebx - where pointer to ValueDefinition should be stored, may already hold a previously used one (should contain null otherwise) +; esi - base address in format of VALTYPE_NUMERIC value +; ecx = length of base address value +; out: +; ebx - AreaHeader +; edx - ValueDefinition + mov [address_length],ecx + mov edx,[ebx] + test edx,edx + jz current_area_definition_unusable + cmp [edx+ValueDefinition.reference_count],1 + je area_definition_ready + dec [edx+ValueDefinition.reference_count] + current_area_definition_unusable: + mov ecx,retired_definition + retrieve_retired_detached_value: + mov edx,[ecx] + test edx,edx + jz create_area_definition + cmp [edx+ValueDefinition.reference_count],0 + jne retired_detached_value_immutable + xor eax,eax + xchg eax,[edx+ValueDefinition.previous] + mov [ecx],eax + jmp adopt_area_definition + retired_detached_value_immutable: + lea ecx,[edx+ValueDefinition.previous] + jmp retrieve_retired_detached_value + create_area_definition: + mov ecx,sizeof.ValueDefinition + call create_tree_element + mov ecx,eax + xchg ecx,[value_definition_chain] + mov [eax+ValueDefinition.interlink],ecx + mov edx,eax + adopt_area_definition: + mov [ebx],edx + or [edx+ValueDefinition.flags],VAL_DETACHED + inc [edx+ValueDefinition.reference_count] + area_definition_ready: + mov ecx,[address_length] + add ecx,sizeof.AreaHeader + mov eax,[edx+ValueDefinition.block_length] + test eax,eax + jz allocate_area_block + cmp ecx,eax + jbe initialize_area_block + push ecx edx + xor eax,eax + xchg eax,[edx+ValueDefinition.value] + call mfree + pop edx ecx + allocate_area_block: + push edx + call malloc_growable + pop edx + mov [edx+ValueDefinition.value],eax + mov [edx+ValueDefinition.block_length],ecx + initialize_area_block: + mov ebx,[edx+ValueDefinition.value] + lea edi,[ebx+sizeof.AreaHeader] + mov ecx,[address_length] + mov [ebx+AreaHeader.base_address_length],ecx + rep movsb + mov [ebx+AreaHeader.uninitialized_length],ecx + mov [ebx+AreaHeader.flags],ecx + sub edi,ebx + mov [edx+ValueDefinition.value_length],edi + mov [edx+ValueDefinition.type],VALTYPE_AREA + mov ecx,[current_pass] + mov [edx+ValueDefinition.pass],ecx + retn + +initialize_output: +; in: ecx = number of bytes that should be added to output +; out: edi - output buffer to be filled with data +; preserves: esi + mov edx,[current_area] + mov ebx,[edx+ValueDefinition.value] + add ecx,[ebx+AreaHeader.uninitialized_length] + jc output_out_of_memory + mov eax,[edx+ValueDefinition.value_length] + lea edi,[ebx+eax] + add ecx,eax + jc output_out_of_memory + mov [edx+ValueDefinition.value_length],ecx + cmp ecx,[edx+ValueDefinition.block_length] + jbe area_reserve_sufficient + mov eax,[edx+ValueDefinition.value] + sub edi,eax + push edx + push ecx + bsr edx,ecx + xchg ecx,edx + dec cl + shr edx,cl + inc edx + shl edx,cl + pop ecx + cmp edx,ecx + jbe output_out_of_memory + xchg ecx,edx + call realloc + pop edx + mov ebx,eax + add edi,eax + mov [edx+ValueDefinition.value],ebx + mov [edx+ValueDefinition.block_length],ecx + area_reserve_sufficient: + mov ecx,[ebx+AreaHeader.uninitialized_length] + jecxz output_buffer_ready + xor eax,eax + rep stosb + mov [ebx+AreaHeader.uninitialized_length],eax + output_buffer_ready: + retn + output_out_of_memory: + jmp out_of_memory + +uninitialized_output: +; in: ecx = number of uninitialized bytes to be added to output +; preserves: ebx, ecx, esi, edi + mov edx,[current_area] + mov eax,[edx+ValueDefinition.value] + add [eax+AreaHeader.uninitialized_length],ecx + jc area_overflow + mov edx,[edx+ValueDefinition.value_length] + sub edx,sizeof.AreaHeader + sub edx,[eax+AreaHeader.base_address_length] + add edx,[eax+AreaHeader.uninitialized_length] + jc area_overflow + retn + area_overflow: + mov edx,_area_overflow + call register_error + mov edx,[current_area] + or ecx,-1 + mov eax,[edx+ValueDefinition.value] + sub ecx,[edx+ValueDefinition.value_length] + add ecx,sizeof.AreaHeader + add ecx,[eax+AreaHeader.base_address_length] + mov [eax+AreaHeader.uninitialized_length],ecx + retn + +trim_output: +; preserves: ecx, esi + xor eax,eax + mov dword [prior_uninitialized_length],eax + mov dword [prior_uninitialized_length+4],eax + mov edi,[current_output_area_entry] + trim_current_output_area: + mov edx,[edi+OutputArea.definition] + mov eax,[edx+ValueDefinition.value] + and [eax+AreaHeader.uninitialized_length],0 + mov ebx,[edx+ValueDefinition.value_length] + sub ebx,sizeof.AreaHeader + sub ebx,[eax+AreaHeader.base_address_length] + jnz output_trimmed + cmp edi,[initial_output_area_entry] + je output_trimmed + sub edi,sizeof.OutputArea + jmp trim_current_output_area + output_trimmed: + mov [current_output_area_entry],edi + retn + +load_from_area: +; in: +; [value_length] = length of data to load +; edi - buffer for loaded data +; edx - ValueDefinition with VALTYPE_AREA +; [data_area_symbol] - SymbolTree_Leaf linked to the same ValueDefinition with update_value_link (required only for predicted loads, can be null) +; [data_offset] = offset within the area +; out: +; cf set when data could not be loaded +; when cf = 0, buffer filled with loaded data +; preserves: esi + mov eax,[edx+ValueDefinition.value] + mov ecx,[edx+ValueDefinition.pass] + cmp ecx,[current_pass] + je area_ok + test [eax+AreaHeader.flags],AREA_VARIABLE + jnz source_area_inaccessible + area_ok: + mov ebx,[data_offset] + add ebx,[eax+AreaHeader.base_address_length] + jc area_offset_unavailable + add ebx,sizeof.AreaHeader + jc area_offset_unavailable + mov ecx,[edx+ValueDefinition.value_length] + sub ecx,ebx + jb load_out_of_initialized_data + call prepare_load_length + jc area_offset_unavailable + xchg esi,ebx + add esi,eax + rep movsb + mov esi,ebx + cmp [value_length],0 + je load_ok + mov ecx,[eax+AreaHeader.uninitialized_length] + jmp load_uninitialized_data + load_out_of_initialized_data: + add ecx,[eax+AreaHeader.uninitialized_length] + jc load_uninitialized_data + xor ecx,ecx + load_uninitialized_data: + call prepare_load_length + jc area_offset_unavailable + xor al,al + rep stosb + cmp [value_length],0 + je load_ok + xor ebx,ebx + xchg ebx,[data_area_symbol] + test ebx,ebx + jz area_offset_unavailable + mov edx,[ebx+SymbolTree_Leaf.retired_definition] + test edx,edx + jz area_with_no_history + mov ecx,[current_pass] + sub ecx,[edx+ValueDefinition.pass] + cmp ecx,1 + ja area_with_no_history + or [ebx+SymbolTree_Leaf.flags],SYM_LINK_PREDICTED + mov eax,[edx+ValueDefinition.value] + jmp load_from_area + prepare_load_length: + cmp ecx,[value_length] + jbe value_length_ok + mov ecx,[value_length] + value_length_ok: + add [data_offset],ecx + jc load_length_ready + sub [value_length],ecx + load_length_ready: + retn + source_area_inaccessible: + mov edx,_invalid_area + jmp load_failed + area_with_no_history: + or [next_pass_needed],1 + area_offset_unavailable: + mov edx,_address_out_of_range + load_failed: + call register_error + stc + retn + load_ok: + clc + retn + +prepare_area_to_write: +; in: +; [data_area] - ValueDefinition with VALTYPE_AREA +; [data_offset] = offset within the area +; [value_length] = length of data to be written +; out: +; cf set when writing specified length is not possible +; when cf = 0: +; edi - buffer for specified number of bytes directly within the area +; preserves: esi + mov edx,[data_area] + mov eax,[edx+ValueDefinition.value] + or [eax+AreaHeader.flags],AREA_VARIABLE + mov ebx,[data_offset] + xor ecx,ecx + add ebx,[eax+AreaHeader.base_address_length] + adc ecx,0 + add ebx,sizeof.AreaHeader + adc ecx,0 + add ebx,[value_length] + adc ecx,0 + jnz write_outside_initialized_area + cmp ebx,[edx+ValueDefinition.value_length] + ja write_outside_initialized_area + lea edi,[eax+ebx] + mov ecx,[value_length] + sub edi,ecx + retn + area_to_write_not_accessible: + stc + retn + write_outside_initialized_area: + sub ebx,[edx+ValueDefinition.value_length] + sbb ecx,0 + jnz write_outside_boundaries + sub [eax+AreaHeader.uninitialized_length],ebx + jnc extend_area + add [eax+AreaHeader.uninitialized_length],ebx + write_outside_boundaries: + push edx + mov edx,_address_out_of_range + call register_error + pop edx + test ecx,ecx + jnz area_to_write_not_accessible + test [eax+AreaHeader.flags],AREA_VIRTUAL + jz area_to_write_not_accessible + test [edx+ValueDefinition.flags],VAL_IN_USE + jnz area_to_write_not_accessible + and [eax+AreaHeader.uninitialized_length],0 + extend_virtual_area: + call expand_value + jmp prepare_area_to_write + extend_area: + test [eax+AreaHeader.flags],AREA_VIRTUAL + jnz extend_virtual_area + call expand_value + call update_output_offsets + jmp prepare_area_to_write + +find_output_area: +; in: +; [file_offset] = offset within the output +; out: +; cf set when not found an area that would contain a byte at specified offset +; when cf = 0: +; ebx - OutputArea +; [file_offset] = offset relative to the beginning of the found area (upper 32 bits are zero) + mov esi,[initial_output_area_entry] + mov edi,[current_output_area_entry] + add edi,sizeof.OutputArea + search_areas: + mov ebx,edi + sub ebx,esi + jz output_area_not_found + test ebx,1 shl bsf sizeof.OutputArea + jz bisect_areas_list + sub ebx,sizeof.OutputArea + bisect_areas_list: + shr ebx,1 + add ebx,esi + mov eax,dword [file_offset] + mov edx,dword [file_offset+4] + sub eax,dword [ebx+OutputArea.cached_offset] + sbb edx,dword [ebx+OutputArea.cached_offset+4] + jc search_earlier_areas + jnz search_later_areas + mov edx,[ebx+OutputArea.definition] + mov ecx,[edx+ValueDefinition.value_length] + mov edx,[edx+ValueDefinition.value] + sub ecx,sizeof.AreaHeader + sub ecx,[edx+AreaHeader.base_address_length] + add ecx,[edx+AreaHeader.uninitialized_length] + cmp eax,ecx + jae search_later_areas + output_area_found: + mov dword [file_offset],eax + and dword [file_offset+4],0 + ; clc + retn + output_area_not_found: + stc + retn + search_later_areas: + lea esi,[ebx+sizeof.OutputArea] + jmp search_areas + search_earlier_areas: + mov edi,ebx + jmp search_areas + +read_from_output: +; in: +; edi - buffer for read data +; [value_length] = length of data to read +; [file_offset] = offset within the output +; out: +; [value_length] = number of bytes that were not in the existing output and could not be read + push edi + call find_output_area + pop edi + jc output_reading_done + read_output_areas: + cmp [value_length],0 + je output_reading_done + mov edx,[ebx+OutputArea.definition] + mov ecx,[edx+ValueDefinition.value_length] + mov eax,ecx + mov edx,[edx+ValueDefinition.value] + sub ecx,sizeof.AreaHeader + sub ecx,[edx+AreaHeader.base_address_length] + sub dword [file_offset],ecx + jnc initialized_load_done + lea esi,[edx+eax] + mov ecx,dword [file_offset] + add esi,ecx + neg ecx + cmp ecx,[value_length] + jbe initialized_load_length_ok + mov ecx,[value_length] + initialized_load_length_ok: + sub [value_length],ecx + rep movsb + mov dword [file_offset],ecx + initialized_load_done: + mov ecx,[edx+AreaHeader.uninitialized_length] + sub dword [file_offset],ecx + jnc uninitialized_load_done + mov ecx,dword [file_offset] + neg ecx + cmp ecx,[value_length] + jbe uninitialized_load_length_ok + mov ecx,[value_length] + uninitialized_load_length_ok: + sub [value_length],ecx + xor al,al + rep stosb + mov dword [file_offset],ecx + uninitialized_load_done: + cmp ebx,[current_output_area_entry] + je output_reading_done + add ebx,sizeof.OutputArea + jmp read_output_areas + output_reading_done: + retn + +rewrite_output: +; in: +; esi - data to write +; [value_length] = length of data to write +; [file_offset] = offset within the output +; out: +; [value_length] = number of bytes that were not in the existing output and could not be rewritten + push esi + call find_output_area + pop esi + jc output_rewriting_done + rewrite_output_areas: + cmp [value_length],0 + je output_rewriting_done + mov edx,[ebx+OutputArea.definition] + mov ecx,[edx+ValueDefinition.value_length] + mov edx,[edx+ValueDefinition.value] + sub ecx,sizeof.AreaHeader + sub ecx,[edx+AreaHeader.base_address_length] + mov edi,[edx+AreaHeader.uninitialized_length] + add ecx,edi + sub dword [file_offset],ecx + jnc rewrite_next_area + mov eax,[value_length] + xor ecx,ecx + add eax,edi + adc ecx,ecx + add eax,dword [file_offset] + adc ecx,0 + jz rewrite_initialized_data + cmp eax,edi + jbe rewrite_uninitialized_data + mov eax,edi + rewrite_uninitialized_data: + test eax,eax + jz rewrite_initialized_data + push ebx + sub [edx+AreaHeader.uninitialized_length],eax + mov edx,[ebx+OutputArea.definition] + mov ebx,eax + call expand_value + call update_output_offsets + pop ebx + rewrite_initialized_data: + mov edx,[ebx+OutputArea.definition] + mov ecx,[edx+ValueDefinition.value_length] + mov edi,[edx+ValueDefinition.value] + or [edi+AreaHeader.flags],AREA_VARIABLE + add edi,[edi+AreaHeader.uninitialized_length] + add edi,ecx + mov ecx,dword [file_offset] + add edi,ecx + neg ecx + cmp ecx,[value_length] + jbe rewrite_length_ok + mov ecx,[value_length] + rewrite_length_ok: + sub [value_length],ecx + rep movsb + mov dword [file_offset],ecx + rewrite_next_area: + cmp ebx,[current_output_area_entry] + je output_rewriting_done + add ebx,sizeof.OutputArea + jmp rewrite_output_areas + output_rewriting_done: + retn + +update_output_offsets: +; in: +; edx - ValueDefinition of output area that had some of uninitialized data made initialized +; preserves: esi + mov eax,[current_output_area_entry] + cmp edx,[eax+OutputArea.definition] + je output_offsets_ok + and dword [prior_uninitialized_length],0 + and dword [prior_uninitialized_length+4],0 + recount_prior_uninitialized_length: + cmp eax,[initial_output_area_entry] + je output_offsets_ok + sub eax,sizeof.OutputArea + mov edi,[eax+OutputArea.definition] + mov ebx,[edi+ValueDefinition.value] + mov ecx,[ebx+AreaHeader.uninitialized_length] + add dword [prior_uninitialized_length],ecx + adc dword [prior_uninitialized_length+4],0 + cmp edx,edi + je output_offsets_ok + mov ecx,[edi+ValueDefinition.value_length] + sub ecx,sizeof.AreaHeader + sub ecx,[ebx+AreaHeader.base_address_length] + jz recount_prior_uninitialized_length + output_offsets_ok: + retn + +get_current_address_value: +; out: +; esi - address in format of VALTYPE_NUMERIC value +; ecx = length of address value +; note: the returned value is placed in assembly workspace + mov eax,[current_area] + mov esi,[eax+ValueDefinition.value] + mov ebx,[eax+ValueDefinition.value_length] + mov edx,assembly_workspace + mov edi,[edx+Workspace.memory_start] + mov ecx,[esi+AreaHeader.base_address_length] + add ecx,4 + call reserve_workspace + mov ecx,[esi+AreaHeader.base_address_length] + sub ebx,ecx + sub ebx,sizeof.AreaHeader + add ebx,[esi+AreaHeader.uninitialized_length] + ; jc internal_error + add esi,sizeof.AreaHeader + xor eax,eax + stosd + lodsd + mov ecx,eax + xor edx,edx + jecxz offset_added_to_base_address + add_offset_to_base_address: + lodsb + add al,bl + setc dl + stosb + shr ebx,8 + add ebx,edx + loop add_offset_to_base_address + offset_added_to_base_address: + mov edx,[assembly_workspace.memory_start] + add edx,4 + mov eax,ebx + cmp byte [esi-1],80h + cmc + sbb eax,0 + stosd + optimize_base_address: + movsx eax,byte [edi-2] + cmp ah,[edi-1] + jne base_address_ready + dec edi + cmp edi,edx + jne optimize_base_address + base_address_ready: + mov ecx,edi + sub ecx,edx + mov [edx-4],ecx + mov ecx,esi + measure_variable_terms: + lodsd + test eax,eax + jz variable_terms_measured + lodsd + add esi,eax + jmp measure_variable_terms + variable_terms_measured: + xchg ecx,esi + sub ecx,esi + rep movsb + mov esi,[assembly_workspace.memory_start] + mov ecx,edi + sub ecx,esi + retn + +get_output_length: +; out: +; edx:eax = length of current output (not counting uninitialized data) +; preserves: esi + mov ebx,[current_output_area_entry] + mov eax,dword [ebx+OutputArea.cached_offset] + mov edx,dword [ebx+OutputArea.cached_offset+4] + mov edi,[ebx+OutputArea.definition] + mov ecx,[edi+ValueDefinition.value_length] + mov edi,[edi+ValueDefinition.value] + sub ecx,sizeof.AreaHeader + sub ecx,[edi+AreaHeader.base_address_length] + jz current_area_entirely_uninitialized + add eax,ecx + adc edx,0 + retn + current_area_entirely_uninitialized: + sub eax,dword [prior_uninitialized_length] + sbb edx,dword [prior_uninitialized_length+4] + retn + +get_output_position: +; out: +; edx:eax = current position in the output (including uninitialized data) +; preserves: esi + mov ebx,[current_output_area_entry] + mov eax,dword [ebx+OutputArea.cached_offset] + mov edx,dword [ebx+OutputArea.cached_offset+4] + mov edi,[ebx+OutputArea.definition] + mov ecx,[edi+ValueDefinition.value_length] + mov edi,[edi+ValueDefinition.value] + sub ecx,sizeof.AreaHeader + sub ecx,[edi+AreaHeader.base_address_length] + add ecx,[edi+AreaHeader.uninitialized_length] + add eax,ecx + adc edx,0 + retn + +create_output_path: +; in: +; ebx - base path and name +; esi - file extension +; ecx = length of the extension +; out: +; edx - output path (generated in temporary storage) + push ecx + mov edi,ebx + xor al,al + or ecx,-1 + repne scasb + dec edi + mov ecx,edi + locate_extension: + cmp edi,ebx + je copy_path_name + dec edi + mov al,[edi] + cmp al,'\' + je copy_path_name + cmp al,'/' + je copy_path_name + cmp al,'.' + jne locate_extension + mov ecx,edi + copy_path_name: + sub ecx,ebx + push ecx + mov edi,[preprocessing_workspace.memory_start] + inc ecx + mov edx,preprocessing_workspace + call reserve_workspace + pop ecx + xchg esi,ebx + rep movsb + mov esi,ebx + pop ecx + mov ebx,ecx + add ecx,2 + call reserve_workspace + mov ecx,ebx + jecxz extension_attached + mov al,'.' + stosb + rep movsb + extension_attached: + xor al,al + stosb + mov edx,[preprocessing_workspace.memory_start] + retn + +write_output_file: +; in: +; ebx - source path +; edi - output path +; out: +; cf set when write failed +; note: +; when output path is null, source path is used with replaced or attached extension + mov [base_path],edi + xor eax,eax + mov [output_failures],eax + mov dword [uninitialized_length],eax + mov dword [uninitialized_length+4],eax + mov edx,edi + test edx,edx + jnz create_output_file + mov [base_path],ebx + mov esi,[output_extension] + mov ecx,[output_extension_length] + call create_output_path + create_output_file: + call create + jc output_write_failed + mov esi,[initial_output_area_entry] + write_area: + mov edx,[esi+OutputArea.definition] + mov eax,[edx+ValueDefinition.value] + mov ecx,[edx+ValueDefinition.value_length] + sub ecx,[eax+AreaHeader.base_address_length] + sub ecx,sizeof.AreaHeader + jz write_next_area + mov eax,dword [uninitialized_length] + or eax,dword [uninitialized_length+4] + jz write_initialized_data + write_uninitialized_data: + mov edi,[assembly_workspace.memory_start] + mov ecx,1000h shr 2 + xor eax,eax + rep stosd + mov ecx,1000h + cmp dword [uninitialized_length+4],0 + jne portion_length_ok + cmp ecx,dword [uninitialized_length] + jbe portion_length_ok + mov ecx,dword [uninitialized_length] + portion_length_ok: + sub dword [uninitialized_length],ecx + sbb dword [uninitialized_length+4],0 + mov edx,[assembly_workspace.memory_start] + call write + jc file_write_failed + mov eax,dword [uninitialized_length] + or eax,dword [uninitialized_length+4] + jnz write_uninitialized_data + write_initialized_data: + mov edx,[esi+OutputArea.definition] + mov eax,[edx+ValueDefinition.value] + mov ecx,[edx+ValueDefinition.value_length] + mov edx,[eax+AreaHeader.base_address_length] + add edx,sizeof.AreaHeader + sub ecx,edx + add edx,eax + call write + jc file_write_failed + write_next_area: + mov edx,[esi+OutputArea.definition] + mov eax,[edx+ValueDefinition.value] + mov eax,[eax+AreaHeader.uninitialized_length] + add dword [uninitialized_length],eax + adc dword [uninitialized_length+4],0 + cmp esi,[current_output_area_entry] + je close_output_file + add esi,sizeof.OutputArea + jmp write_area + close_output_file: + call close + mov ebx,[auxiliary_output_areas] + mov edi,write_auxiliary_output_area + call iterate_through_map + cmp [output_failures],0 + jne output_write_failed + clc + retn + file_write_failed: + call close + output_write_failed: + stc + retn + +write_auxiliary_output_area: +; in: +; eax = ValueDefinition, null for cached extension not used for auxiliary output +; esi - file extension +; ecx = length of the extension + test eax,eax + jz auxiliary_output_processed + mov ebx,[base_path] + test ebx,ebx + jz auxiliary_output_processed + push eax + call create_output_path + call create + pop edx + jc auxiliary_file_creation_failed + mov eax,[edx+ValueDefinition.value] + mov ecx,[edx+ValueDefinition.value_length] + mov edx,[eax+AreaHeader.base_address_length] + add edx,sizeof.AreaHeader + sub ecx,edx + add edx,eax + call write + jc auxiliary_file_write_failed + call close + auxiliary_output_processed: + retn + auxiliary_file_write_failed: + call close + auxiliary_file_creation_failed: + inc [output_failures] + retn diff --git a/toolchain/fasmg.kl0e/source/reader.inc b/toolchain/fasmg.kl0e/source/reader.inc new file mode 100644 index 0000000..e7f0790 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/reader.inc @@ -0,0 +1,451 @@ + +; note: +; to not interfere with code resolving, all external input must stay unchanged +; in subsequent passes of the assembly; for this reason all data read from files is +; permanently cached (source texts are cached in tokenized form) + +struct FileData + length dq ? + cache dd ? ; pointer to FileCache +ends + +struct FileCache + offset dq ? + length dd ? + next dd ? ; pointer to another FileCache +ends + +read_source: +; in: +; esi - source path +; out: +; eax - tokenized source, null when file not found +; esi - source path in persistent storage + mov ebx,[file_source_cache] + xor ecx,ecx + call get_from_map + jc read_source_file + cmp eax,-1 + je get_erroneous_source + retn + read_source_file: + mov edx,esi + call open + jc source_file_not_found + xor eax,eax + mov edx,eax + mov cl,2 + call lseek + jc error_reading_file + test edx,edx + jnz out_of_memory + push eax + xor eax,eax + mov edx,eax + mov cl,al + call lseek + jc error_reading_file + pop ecx + inc ecx + mov [source_text_length],ecx + call malloc + mov [source_text],eax + mov edx,eax + mov ecx,[source_text_length] + dec ecx + mov byte [edx+ecx],0 + call read + jc error_reading_file + call close + push esi + call tokenize_source + mov eax,[source_text] + call mfree + pop esi + mov eax,[tokenization_buffer] + xor ecx,ecx + mov ebx,[file_source_cache] + call put_into_map + mov eax,[tokenization_buffer] + retn + source_file_not_found: + xor eax,eax + xor ecx,ecx + mov ebx,[file_source_cache] + call put_into_map + xor eax,eax + retn + error_reading_file: + or eax,-1 + xor ecx,ecx + mov ebx,[file_source_cache] + call put_into_map + get_erroneous_source: + mov ebx,esi + mov edx,_error_reading_file + call register_error + mov eax,zero_value + retn + +use_source: +; in: +; esi - ASCIIZ source string +; out: +; eax - tokenized source +; esi - source text in persistent storage + mov edi,esi + xor al,al + or ecx,-1 + repne scasb + not ecx + mov [source_text_length],ecx + mov ebx,[memory_source_cache] + xor eax,eax + call get_from_map + jc adapt_memory_source + retn + adapt_memory_source: + mov [source_text],esi + call tokenize_source + mov eax,[tokenization_buffer] + mov esi,[source_text] + mov ecx,[source_text_length] + mov ebx,[memory_source_cache] + call put_into_map + mov eax,[tokenization_buffer] + retn + +tokenize_source: +; in: +; [source_text] - ASCIIZ text +; [source_text_length] = length of text (including terminating character) +; out: +; [tokenization_buffer] - tokenized source +; [tokenization_buffer_length] = length of tokenized source + mov ecx,[source_text_length] + shl ecx,1 + add ecx,18 + call malloc_growable + mov [tokenization_buffer],eax + mov [tokenization_buffer_length],ecx + add eax,ecx + sub eax,[source_text] + sub eax,[source_text_length] + mov [buffer_end_offset],eax + mov esi,[source_text] + mov edi,[tokenization_buffer] + mov [last_token],0Ah + tokenize: + mov eax,[buffer_end_offset] + add eax,esi + sub eax,edi + cmp eax,18 + jae tokenization_buffer_reserve_ok + mov ecx,esi + sub ecx,[source_text] + mov eax,[source_text_length] + mul [tokenization_buffer_length] + div ecx + mov ecx,eax + add ecx,18 + mov eax,[tokenization_buffer] + call realloc + sub edi,[tokenization_buffer] + add edi,eax + mov [tokenization_buffer],eax + mov [tokenization_buffer_length],ecx + add eax,ecx + sub eax,[source_text] + sub eax,[source_text_length] + mov [buffer_end_offset],eax + tokenization_buffer_reserve_ok: + movzx eax,byte [esi] + inc esi + mov ah,[characters+eax] + cmp ah,20h + je control_character + test ah,ah + jnz make_name_token + character_token: + stosb + mov [last_token],al + jmp tokenize + make_string_token: + mov dl,al + mov byte [edi],22h + mov [last_token],22h + add edi,5 + xor ecx,ecx + copy_string: + mov al,[esi] + cmp al,0Dh + je broken_string + cmp al,0Ah + je broken_string + cmp al,1Ah + je broken_string + test al,al + jz broken_string + inc esi + cmp al,dl + jne copy_string_character + cmp byte [esi],al + jne finish_string_token + inc esi + copy_string_character: + mov [edi+ecx],al + inc ecx + jmp copy_string + broken_string: + mov byte [edi-5],27h + finish_string_token: + mov al,[edi-5] + mov [edi-4],ecx + add edi,ecx + jmp tokenize + make_name_token: + cmp al,22h + je make_string_token + cmp al,27h + je make_string_token + mov byte [edi],1Ah + mov [last_token],1Ah + add edi,5 + xor ebx,ebx + mov ecx,FNV_OFFSET + mov edx,ecx + hash_name: + mov [edi+ebx],al + inc ebx + xor cl,al + xor dl,ah + imul ecx,FNV_PRIME + imul edx,FNV_PRIME + movzx eax,byte [esi] + inc esi + mov ah,[characters+eax] + cmp ah,20h + je finish_name_token + test ah,ah + jnz hash_name + finish_name_token: + mov [edi-4],ebx + add edi,ebx + mov [edi],ecx + mov [edi+4],edx + xor ecx,ecx + mov [edi+8],ecx + add edi,12 + cmp ah,20h + jne character_token + control_character: + cmp al,20h + je whitespace + cmp al,9 + je whitespace + cmp [last_token],20h + je mark_end_of_line + inc edi + mark_end_of_line: + mov byte [edi-1],0Ah + mov [last_token],0Ah + cmp al,0Dh + je cr + cmp al,0Ah + je lf + xor al,al + stosb + mov ecx,edi + mov eax,[tokenization_buffer] + sub ecx,eax + call realloc + mov [tokenization_buffer],eax + mov [tokenization_buffer_length],ecx + retn + cr: + cmp byte [esi],0Ah + jne tokenize + inc esi + jmp tokenize + lf: + cmp byte [esi],0Dh + jne tokenize + inc esi + jmp tokenize + whitespace: + cmp [last_token],0Ah + je tokenize + cmp [last_token],20h + je tokenize + mov al,20h + stosb + mov [last_token],al + jmp tokenize + +get_file_data: +; in: +; esi - file path +; out: +; ebx - FileData, null when file not found +; esi - file path in persistent storage +; preserves: edi + mov ebx,[file_data_cache] + xor ecx,ecx + call get_from_map + jc initialize_file_data + mov ebx,eax + retn + initialize_file_data: + mov edx,esi + call open + jc remember_file_not_found + push edi + mov ecx,sizeof.FileData + call malloc_fixed + mov edi,eax + xor eax,eax + mov edx,eax + mov cl,2 + call lseek + jc file_not_seekable + mov dword [edi+FileData.length],eax + mov dword [edi+FileData.length+4],edx + call close + mov eax,edi + xor ecx,ecx + mov [eax+FileData.cache],ecx + mov ebx,[file_data_cache] + call put_into_map + mov ebx,edi + pop edi + retn + file_not_seekable: + pop edi + remember_file_not_found: + xor eax,eax + mov ecx,eax + mov ebx,[file_data_cache] + call put_into_map + xor ebx,ebx + retn + +read_file_data: +; in: +; esi - file path +; ebx - FileData +; edi - buffer for data +; [file_offset] = offset of data +; [data_length] = length of data +; out: +; cf set when read failed +; preserves: esi + mov [file_data],ebx + lea eax,[ebx+FileData.cache] + mov [file_cache_pointer],eax + mov ebx,[eax] + read_from_file_cache: + mov ecx,[data_length] + test ecx,ecx + jz file_data_read + test ebx,ebx + jz new_trailing_file_cache_entry + mov eax,dword [file_offset] + mov edx,dword [file_offset+4] + sub eax,dword [ebx+FileCache.offset] + sbb edx,dword [ebx+FileCache.offset+4] + jc new_file_cache_entry + jnz next_entry + mov edx,[ebx+FileCache.length] + sub edx,eax + jbe next_entry + cmp ecx,edx + jbe length_to_read_ok + mov ecx,edx + length_to_read_ok: + sub [data_length],ecx + add dword [file_offset],ecx + adc dword [file_offset+4],0 + mov edx,esi + lea esi,[ebx+sizeof.FileCache+eax] + rep movsb + mov esi,edx + next_entry: + lea eax,[ebx+FileCache.next] + mov [file_cache_pointer],eax + mov ebx,[eax] + jmp read_from_file_cache + file_data_read: + clc + retn + new_trailing_file_cache_entry: + mov ebx,[file_data] + mov ecx,dword [ebx+FileData.length] + mov edx,dword [ebx+FileData.length+4] + cmp ecx,dword [file_offset] + jne measure_cache_gap + cmp edx,dword [file_offset+4] + jne measure_cache_gap + stc + retn + new_file_cache_entry: + mov ecx,dword [ebx+FileCache.offset] + mov edx,dword [ebx+FileCache.offset+4] + measure_cache_gap: + mov eax,dword [file_offset] + and eax,not 0FFFh + sub ecx,eax + sbb edx,dword [file_offset+4] + jnz compute_aligned_length + cmp ecx,[data_length] + jbe read_into_cache + compute_aligned_length: + mov eax,dword [file_offset] + and eax,0FFFh + add eax,[data_length] + dec eax + shr eax,12 + inc eax + shl eax,12 + test edx,edx + jnz use_aligned_length + cmp eax,ecx + jae read_into_cache + use_aligned_length: + mov ecx,eax + read_into_cache: + push ecx + add ecx,sizeof.FileCache + call malloc_fixed + mov ebx,eax + mov eax,[file_cache_pointer] + mov edx,ebx + xchg edx,[eax] + mov [ebx+FileCache.next],edx + pop [ebx+FileCache.length] + mov eax,dword [file_offset] + and eax,not 0FFFh + mov edx,dword [file_offset+4] + mov dword [ebx+FileCache.offset],eax + mov dword [ebx+FileCache.offset+4],edx + push ebx edi + mov edi,ebx + mov edx,esi + call open + jc file_access_error + mov eax,dword [edi+FileCache.offset] + mov edx,dword [edi+FileCache.offset+4] + xor cl,cl + call lseek + jc file_access_error + lea edx,[edi+sizeof.FileCache] + mov ecx,[edi+FileCache.length] + call read + jc file_access_error + call close + pop edi ebx + jmp read_from_file_cache + file_access_error: + pop edi ebx + stc + retn + \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/source/symbols.inc b/toolchain/fasmg.kl0e/source/symbols.inc new file mode 100644 index 0000000..9d3a243 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/symbols.inc @@ -0,0 +1,1547 @@ + +struct SymbolTree_Root + attributes db ? ; SYMTREE_# + flags db ? ; NAMESPACE_# + parameters db ? ; SPECPARM_# + reserved db ? + parent_branch dd ? ; pointer to namespace SymbolTree_Foliage + current_label dd ? ; pointer to selected SymbolTree_Foliage + chain dd ? ; pointer to another SymbolTree_Root + ; root_node SymbolTree_Node +ends + +struct SymbolTree_Node + branches rd 1 shl TREE_NODE_BITS +ends + +struct SymbolTree_LocalNode + branches rd 1 shl LOCAL_TREE_NODE_BITS +ends + +struct SymbolTree_Foliage + name_kind db ? ; NAME_# + flags db ? ; FOLIAGE_# + reserved dw ? + name_length dd ? + name_data dd ? + root dd ? ; pointer to SymbolTree_Root + next dd ? ; pointer to another SymbolTree_Foliage + child_namespace dd ? ; pointer to descendant SymbolTree_Root + ; first_leaf SymbolTree_Leaf +ends + +struct SymbolTree_Leaf + class db ? ; SYMCLASS_# + flags db ? ; SYM_# + extra_flags db ? ; SYMX_# + reserved db ? + definition dd ? ; pointer to ValueDefinition + retired_definition dd ? + last_use_pass dd ? + next dd ? ; pointer to another SymbolTree_Leaf within SymbolTree_Foliage + branch dd ? ; pointer to SymbolTree_Foliage + fallback_neighbour dd ? ; pointer to another SymbolTree_Leaf + fallback_parent dd ? ; pointer to another SymbolTree_Leaf +ends + +struct ValueDefinition + type db ? ; VALTYPE_# + flags db ? ; VAL_# + attribute db ? + reserved db ? + pass dd ? + value dd ? + value_length dd ? + block_length dd ? + reference_count dd ? ; number of distinct references to current value + previous dd ? ; pointer to another ValueDefinition + interlink dd ? +ends + +TREE_HEIGHT = 4 +TREE_NODE_BITS = 5 +LOCAL_TREE_HEIGHT = 1 +LOCAL_TREE_NODE_BITS = 6 + +FNV_PRIME = 16777619 +FNV_OFFSET = 2166136261 + +SYMTREE_LOCAL = 1 +SYMTREE_WITH_CASEINSENSITIVE_PARAMETERS = 2 + +NAMESPACE_UNATTACHED = 1 +NAMESPACE_LABEL_FORWARDING = 2 +NAMESPACE_CALM = 10h +NAMESPACE_LOCAL = 20h + +SPECPARM_COUNTER = 1 +SPECPARM_LIMIT = 2 + +FOLIAGE_WITH_TOKEN = 1 + +NAME_CASESENSITIVE = 0 +NAME_CASEINSENSITIVE = 1 +NAME_NUMERIC = 2 +NAME_ABSTRACT = 3 + +SYMCLASS_EXPRESSION = 0 +SYMCLASS_INSTRUCTION = 1 +SYMCLASS_STRUCTURE = 2 +SYMCLASS_PARAMETER = 3 +SYMCLASS_CALM_LOCATION = 10h + +SYM_CONSTANT = 1 +SYM_VARIABLE = 2 +SYM_PREDICTED = 4 +SYM_PREDICTED_DEFINED = 8 +SYM_USAGE_PREDICTED = 10h +SYM_PREDICTED_USED = 20h +SYM_LINK = 40h +SYM_LINK_PREDICTED = 80h + +SYMX_INSTRUCTION_PREDICTED = 1 + +VALTYPE_RESERVED = 0 +VALTYPE_SYMBOLIC = 1 +VALTYPE_NUMERIC = 2 +VALTYPE_STRING = 3 +VALTYPE_FLOAT = 4 +VALTYPE_ELEMENT = 5 +VALTYPE_AREA = 6 +VALTYPE_CALM = 7 +VALTYPE_SYMBOLIC_SEQUENCE = 11h +VALTYPE_NUMERIC_SEQUENCE = 12h +VALTYPE_PLAIN = 20h +VALTYPE_NATIVE_COMMAND = 40h +VALTYPE_NATIVE_COMPARATOR = 41h +VALTYPE_NATIVE_FUNCTION = 42h +VALTYPE_NATIVE_PREPOSITION = 43h + +VAL_INTERNAL = 1 +VAL_IN_USE = 2 +VAL_UNCONDITIONAL = 4 +VAL_NONRECURSIVE = 8 +VAL_SHIFTABLE = 10h +VAL_DETACHED = 20h + +RECOGNIZE_CASE_INSENSITIVE = 1 +RECOGNIZE_DEFINITION = 2 + +recognize_symbol: +; in: +; ebx - SymbolTree_Root (namespace), null for standard recognition regime +; ecx = name length +; esi - name followed by two hashes (as in name token) +; dl = SYMCLASS_# +; dh = any combination of RECOGNIZE_# flags +; [recognition_context.base_namespace] - namespace for standard recognition regime +; [name_volatile] = non-zero when name is provided in a temporary storage +; [name_token] = null or pointer to the contents of a preprocessed token +; out: +; ebx - SymbolTree_Leaf +; edx - SymbolTree_Foliage +; edi - SymbolTree_Root +; [name_volatile] zeroed when name has been moved to persistent storage +; note: +; when RECOGNIZE_DEFINITION option is not selected and no defined symbol of requested class is found, +; the provided result is as if RECOGNIZE_DEFINITION option was specified and expression class requested + mov [symbol_class],dl + test dh,RECOGNIZE_DEFINITION + setnz [symbol_expected] + or [symbol_required],1 + test dh,RECOGNIZE_CASE_INSENSITIVE + mov al,NAME_CASEINSENSITIVE + mov edx,[esi+ecx+4] + mov [case_insensitive_hash],edx + jnz name_kind_ok + mov al,NAME_CASESENSITIVE + mov edx,[esi+ecx] + mov [case_sensitive_hash],edx + name_kind_ok: + mov [name_kind],al + test ebx,ebx + jz standard_recognition + call scan_namespace + jnc symbol_recognized + mov [kept_symbol],ebx + mov [kept_symbol_flags],al + mov edi,[symbol_root] + cmp [name_kind],NAME_CASEINSENSITIVE + je no_defined_symbol + mov [current_symbol],ebx + mov ebx,[ebx+SymbolTree_Leaf.fallback_neighbour] + test ebx,ebx + jnz check_namespace_fallback + mov [name_kind],NAME_CASEINSENSITIVE + mov edx,[case_insensitive_hash] + mov ebx,edi + call scan_namespace + mov eax,[current_symbol] + mov [eax+SymbolTree_Leaf.fallback_neighbour],ebx + jc no_defined_symbol + symbol_recognized: + mov edi,[symbol_root] + retn + standard_recognition: + mov ebx,[recognition_context.base_namespace] + call scan_namespace + jnc symbol_recognized + mov [kept_symbol],ebx + mov [kept_symbol_flags],al + mov edi,[symbol_root] + find_in_wider_scope: + mov edx,[case_insensitive_hash] + mov [current_symbol],ebx + cmp [name_kind],NAME_CASEINSENSITIVE + je find_in_namespace_chain + mov ebx,[ebx+SymbolTree_Leaf.fallback_neighbour] + test ebx,ebx + jnz check_fallback_neighbour + mov [name_kind],NAME_CASEINSENSITIVE + mov ebx,[symbol_root] + call scan_namespace + mov eax,[current_symbol] + mov [eax+SymbolTree_Leaf.fallback_neighbour],ebx + jnc symbol_recognized + no_neighbour_found: + mov ebx,[current_symbol] + mov [name_kind],NAME_CASESENSITIVE + mov edx,[case_sensitive_hash] + find_in_namespace_chain: + mov ebx,[ebx+SymbolTree_Leaf.fallback_parent] + test ebx,ebx + jnz check_fallback_parent + mov edi,[symbol_root] + mov ebx,[edi+SymbolTree_Root.parent_branch] + test ebx,ebx + jz no_defined_symbol + mov ebx,[ebx+SymbolTree_Foliage.root] + call scan_namespace + mov eax,[current_symbol] + mov [eax+SymbolTree_Leaf.fallback_parent],ebx + jc find_in_wider_scope + mov edi,[symbol_root] + retn + check_fallback_neighbour: + call get_available_value + jc no_neighbour_found + fallback_neighbour_ok: + mov edx,[ebx+SymbolTree_Leaf.branch] + mov edi,[edx+SymbolTree_Foliage.root] + retn + check_fallback_parent: + call get_available_value + mov edx,[ebx+SymbolTree_Leaf.branch] + mov edi,[edx+SymbolTree_Foliage.root] + mov [symbol_root],edi + jc find_in_wider_scope + retn + check_namespace_fallback: + call get_available_value + jnc fallback_neighbour_ok + no_defined_symbol: + cmp [symbol_class],SYMCLASS_EXPRESSION + je return_kept_symbol + mov [symbol_class],SYMCLASS_EXPRESSION + or [symbol_expected],1 + mov ebx,[kept_symbol] + mov ebx,[ebx+SymbolTree_Leaf.branch] + mov edi,[ebx+SymbolTree_Foliage.root] + jmp scan_symbol_branch + return_kept_symbol: + mov ebx,[kept_symbol] + mov edx,[ebx+SymbolTree_Leaf.branch] + mov edi,[edx+SymbolTree_Foliage.root] + mov al,[kept_symbol_flags] + mov [ebx+SymbolTree_Leaf.flags],al + retn + +scan_namespace: +; in: +; ebx - SymbolTree_Root +; edx = hash +; ecx = name length +; esi - name +; [name_kind] = NAME_# +; [name_volatile] = non-zero when name is provided in a temporary storage +; [name_token] = null or pointer to the contents of a preprocessed token +; [symbol_class] = SYMCLASS_# +; [symbol_required] = non-zero when symbol needs to be added if not found +; [symbol_expected] = non-zero when symbol needs not be checked for its value availability +; out: +; ebx - SymbolTree_Leaf, null when nothing found +; edx - SymbolTree_Foliage, null when no such branch exists +; [symbol_root] - SymbolTree_Root +; [symbol_branch] - SymbolTree_Foliage +; [name_volatile] zeroed when name has been moved to persistent storage +; when [symbol_expected] = 0: +; cf set when symbol not found or has no defined value +; al = copy of symbol prediction flags before they were affected by this function +; when [symbol_expected] = 1: +; cf set when symbol not found +; preserves: ecx, [esi] + mov [symbol_root],ebx + test [ebx+SymbolTree_Root.attributes],SYMTREE_LOCAL + jnz scan_local_namespace + add ebx,sizeof.SymbolTree_Root + if TREE_HEIGHT > 1 + mov edi,TREE_HEIGHT + follow_tree: + mov eax,edx + and eax,(1 shl TREE_NODE_BITS)-1 + shr edx,TREE_NODE_BITS + lea ebx,[ebx+eax*4] + else + and edx,(1 shl TREE_NODE_BITS)-1 + lea ebx,[ebx+edx*4] + end if + mov eax,[ebx] + test eax,eax + jz unregistered_hash + mov ebx,eax + if TREE_HEIGHT > 1 + dec edi + jnz follow_tree + end if + scan_foliage_branches: + movzx eax,[name_kind] + cmp [ebx+SymbolTree_Foliage.name_kind],al + jne next_foliage_branch + cmp [ebx+SymbolTree_Foliage.name_length],ecx + jne next_foliage_branch + mov edi,[ebx+SymbolTree_Foliage.name_data] + cmp esi,edi + je scan_symbol_branch + cmp al,NAME_ABSTRACT + je next_foliage_branch + jecxz scan_symbol_branch + repe cmpsb + jne names_not_identical + mov esi,edi + mov ecx,[ebx+SymbolTree_Foliage.name_length] + sub esi,ecx + and [name_volatile],0 + mov edx,[name_token] + test edx,edx + jz scan_symbol_branch + test [ebx+SymbolTree_Foliage.flags],FOLIAGE_WITH_TOKEN + jz use_token_for_foliage + sub esi,4 + mov eax,[edx] + mov [edx],esi + mov [eax+4+ecx+8],esi + add esi,4 + jmp scan_symbol_branch + use_token_for_foliage: + mov esi,[edx] + add esi,4 + mov [ebx+SymbolTree_Foliage.name_data],esi + or [ebx+SymbolTree_Foliage.flags],FOLIAGE_WITH_TOKEN + jmp scan_symbol_branch + hash_collision: + add esi,ecx + mov ecx,[ebx+SymbolTree_Foliage.name_length] + sub esi,ecx + next_foliage_branch: + mov eax,[ebx+SymbolTree_Foliage.next] + test eax,eax + jz unregistered_name + mov ebx,eax + jmp scan_foliage_branches + names_not_identical: + cmp al,NAME_CASEINSENSITIVE + jne hash_collision + dec esi + dec edi + inc ecx + case_insensitive_compare: + lodsb + mov dl,[characters+eax] + mov al,[edi] + inc edi + dec ecx + cmp dl,[characters+eax] + jne hash_collision + test ecx,ecx + jnz case_insensitive_compare + mov ecx,[ebx+SymbolTree_Foliage.name_length] + sub esi,ecx + scan_symbol_branch: + ; in: + ; ebx - SymbolTree_Foliage + ; [symbol_class] = SYMCLASS_# + ; [symbol_required] = non-zero when symbol needs to be added if not found + ; [symbol_expected] = non-zero when symbol needs not be checked for its value availability + ; out: + ; ebx - SymbolTree_Leaf, null when nothing found + ; edx - SymbolTree_Foliage + ; [symbol_branch] - SymbolTree_Foliage + ; when [symbol_expected] = 0: + ; cf set when symbol not found or has no defined value + ; al = copy of symbol prediction flags before they were affected by this function + ; when [symbol_expected] = 1: + ; cf set when symbol not found + ; preserves: ecx, esi, edi + mov [symbol_branch],ebx + add ebx,sizeof.SymbolTree_Foliage + mov dl,[symbol_class] + scan_leaves: + mov al,[ebx+SymbolTree_Leaf.class] + cmp al,dl + je leaf_found + mov eax,[ebx+SymbolTree_Leaf.next] + test eax,eax + jz leaves_scanned + mov ebx,eax + jmp scan_leaves + leaf_found: + cmp [symbol_expected],0 + jne symbol_found + call get_available_value + jnc symbol_found + no_defined_symbol_found: + mov edx,[symbol_branch] + stc + retn + symbol_found: + mov edx,[symbol_branch] + clc + retn + leaves_scanned: + mov al,[symbol_required] + or al,[symbol_expected] + jnz attach_symbol_leaf + xor ebx,ebx + jmp no_defined_symbol_found + unregistered_name: + cmp [symbol_required],0 + je name_not_found + push ecx + lea ebx,[ebx+SymbolTree_Foliage.next] + jmp attach_foliage_branch + name_not_found: + xor ebx,ebx + xor edx,edx + stc + retn + unregistered_hash: + cmp [symbol_required],0 + je name_not_found + push ecx + if TREE_HEIGHT > 1 + expand_tree: + dec edi + jz attach_foliage_branch + mov ecx,sizeof.SymbolTree_Node + call create_tree_element + mov [ebx],eax + mov ebx,eax + mov eax,edx + and eax,(1 shl TREE_NODE_BITS)-1 + shr edx,TREE_NODE_BITS + lea ebx,[ebx+eax*4] + jmp expand_tree + end if + attach_foliage_branch: + mov ecx,sizeof.SymbolTree_Foliage + sizeof.SymbolTree_Leaf + call create_tree_element + mov [ebx],eax + mov [symbol_branch],eax + mov ebx,eax + pop ecx + mov eax,[symbol_root] + mov [ebx+SymbolTree_Foliage.root],eax + mov al,[name_kind] + mov [ebx+SymbolTree_Foliage.name_kind],al + mov [ebx+SymbolTree_Foliage.name_length],ecx + cmp al,NAME_ABSTRACT + je symbol_name_stored + mov edx,[name_token] + test edx,edx + jnz symbol_name_from_token + cmp [name_volatile],0 + je symbol_name_stored + call store_string + and [name_volatile],0 + jmp symbol_name_stored + symbol_name_from_token: + or [ebx+SymbolTree_Foliage.flags],FOLIAGE_WITH_TOKEN + mov esi,[edx] + add esi,4 + symbol_name_stored: + mov [ebx+SymbolTree_Foliage.name_data],esi + lea ebx,[ebx+sizeof.SymbolTree_Foliage] + jmp fill_new_symbol_leaf + attach_symbol_leaf: + push ecx + mov ecx,sizeof.SymbolTree_Leaf + call create_tree_element + mov [ebx+SymbolTree_Leaf.next],eax + mov ebx,eax + pop ecx + fill_new_symbol_leaf: + mov al,[symbol_class] + mov [ebx+SymbolTree_Leaf.class],al + mov edx,[symbol_branch] + cmp al,SYMCLASS_PARAMETER + jne namespace_flags_updated + cmp [name_kind],NAME_CASEINSENSITIVE + jne namespace_flags_updated + mov eax,[edx+SymbolTree_Foliage.root] + or [eax+SymbolTree_Root.attributes],SYMTREE_WITH_CASEINSENSITIVE_PARAMETERS + namespace_flags_updated: + mov [ebx+SymbolTree_Leaf.branch],edx + cmp [symbol_expected],0 + jne symbol_found + xor al,al + or [ebx+SymbolTree_Leaf.flags],SYM_PREDICTED + jmp no_defined_symbol_found + scan_local_namespace: + add ebx,sizeof.SymbolTree_Root + if LOCAL_TREE_HEIGHT > 1 + mov edi,LOCAL_TREE_HEIGHT + follow_local_tree: + mov eax,edx + and eax,(1 shl LOCAL_TREE_NODE_BITS)-1 + shr edx,LOCAL_TREE_NODE_BITS + lea ebx,[ebx+eax*4] + else + and edx,(1 shl LOCAL_TREE_NODE_BITS)-1 + lea ebx,[ebx+edx*4] + end if + mov eax,[ebx] + test eax,eax + jz local_unregistered_hash + mov ebx,eax + if LOCAL_TREE_HEIGHT > 1 + dec edi + jnz follow_local_tree + end if + jmp scan_foliage_branches + local_unregistered_hash: + cmp [symbol_required],0 + je name_not_found + push ecx + if LOCAL_TREE_HEIGHT > 1 + expand_local_tree: + dec edi + jz attach_foliage_branch + mov ecx,sizeof.SymbolTree_LocalNode + call create_tree_element + mov [ebx],eax + mov ebx,eax + mov eax,edx + and eax,(1 shl LOCAL_TREE_NODE_BITS)-1 + shr edx,LOCAL_TREE_NODE_BITS + lea ebx,[ebx+eax*4] + jmp expand_local_tree + else + jmp attach_foliage_branch + end if + +get_abstract_symbol: +; in: +; eax:ecx = symbol identifier +; ebx - SymbolTree_Root, null for local scope +; dl = SYMCLASS_# +; out: +; ebx - SymbolTree_Leaf +; edx - SymbolTree_Foliage +; edi - SymbolTree_Root + mov [symbol_class],dl + test ebx,ebx + jnz scope_selected + mov ebx,[current_context.base_namespace] + scope_selected: + mov esi,eax + mov edx,FNV_OFFSET + mov [minor_identifier],ecx + mov ecx,4 + hash_major_identifier: + xor dl,al + imul edx,FNV_PRIME + shr eax,8 + loop hash_major_identifier + mov eax,[minor_identifier] + mov ecx,4 + hash_minor_identifier: + xor dl,al + imul edx,FNV_PRIME + shr eax,8 + loop hash_minor_identifier + mov ecx,[minor_identifier] + mov [name_kind],NAME_ABSTRACT + or [symbol_required],1 + or [symbol_expected],1 + call scan_namespace + mov edi,[symbol_root] + retn + +create_tree_element: +; in: ecx = length of element +; out: eax - pointer to allocated and zeroed memory +; preserves: ebx, ecx, edx, esi, edi + sub [tree_reserve_length],ecx + jc expand_tree_reserve + mov eax,[tree_reserve] + add [tree_reserve],ecx + retn + expand_tree_reserve: + push ecx edx edi + mov ecx,10000h + call malloc_fixed + mov edx,eax + xchg edx,[tree_blocks] + mov [eax],edx + lea edi,[eax+4] + sub ecx,4 + mov [tree_reserve],edi + mov [tree_reserve_length],ecx + mov edx,eax + xor eax,eax + shr ecx,2 + rep stosd + mov eax,edx + pop edi edx ecx + jmp create_tree_element + +store_string: +; in: esi - string, ecx = length +; out: esi - stored string +; preserves: ebx, ecx, edi + cmp ecx,[storage_free_space_length] + ja expand_storage + storage_ready: + push ecx edi + mov edi,[storage_free_space] + add [storage_free_space],ecx + sub [storage_free_space_length],ecx + move_to_storage: + mov eax,edi + shr ecx,1 + jnc movsb_ok + movsb + movsb_ok: + shr ecx,1 + jnc movsw_ok + movsw + movsw_ok: + rep movsd + mov esi,eax + pop edi ecx + retn + expand_storage: + cmp ecx,100h + jae store_long_string + push ecx + mov ecx,10000h + call malloc_fixed + mov edx,eax + xchg edx,[storage_blocks] + mov [eax],edx + add eax,4 + sub ecx,4 + mov [storage_free_space],eax + mov [storage_free_space_length],ecx + pop ecx + jmp storage_ready + store_long_string: + push ecx + add ecx,4 + call malloc_fixed + mov edx,[storage_blocks] + test edx,edx + jz long_first_string + mov ecx,eax + xchg ecx,[edx] + mov [eax],ecx + long_string_storage_ready: + add eax,4 + mov ecx,[esp] + push edi + mov edi,eax + jmp move_to_storage + long_first_string: + mov [storage_blocks],eax + mov [eax],edx + jmp long_string_storage_ready + +get_symbol_namespace: +; in: +; edx - SymbolTree_Foliage +; out: +; ebx - SymbolTree_Root of child namespace +; preserves: edx, esi, edi + mov ebx,[edx+SymbolTree_Foliage.child_namespace] + test ebx,ebx + jnz symbol_namespace_ok + mov ecx,sizeof.SymbolTree_Root + sizeof.SymbolTree_Node + call create_tree_element + mov [eax+SymbolTree_Root.parent_branch],edx + mov [edx+SymbolTree_Foliage.child_namespace],eax + mov ebx,eax + symbol_namespace_ok: + retn +get_local_namespace: +; same as get_symbol_namespace + mov ebx,[edx+SymbolTree_Foliage.child_namespace] + test ebx,ebx + jnz symbol_namespace_ok + mov ecx,sizeof.SymbolTree_Root + sizeof.SymbolTree_LocalNode + call create_tree_element + or [eax+SymbolTree_Root.attributes],SYMTREE_LOCAL + or [eax+SymbolTree_Root.flags],NAMESPACE_LOCAL + mov [edx+SymbolTree_Foliage.child_namespace],eax + mov ebx,eax + retn + +get_local_anchor: +; in: +; eax = instruction identifier +; ecx = context identifier +; out: +; edx - SymbolTree_Foliage where a local namespace can be anchored + xor ebx,ebx + mov dl,SYMCLASS_PARAMETER + call get_abstract_symbol + mov eax,[ebx+SymbolTree_Leaf.definition] + test eax,eax + jz create_anchor_counter + mov ecx,[current_pass] + cmp ecx,[eax+ValueDefinition.pass] + je increment_anchor_counter + mov [eax+ValueDefinition.pass],ecx + and [eax+ValueDefinition.value],0 + jmp increment_anchor_counter + create_anchor_counter: + mov ecx,sizeof.ValueDefinition + call create_tree_element + mov [ebx+SymbolTree_Leaf.definition],eax + inc [eax+ValueDefinition.reference_count] + mov [eax+ValueDefinition.type],VALTYPE_PLAIN + mov ecx,[current_pass] + mov [eax+ValueDefinition.pass],ecx + increment_anchor_counter: + mov ecx,[eax+ValueDefinition.value] + inc [eax+ValueDefinition.value] + jecxz local_anchor_ready + mov eax,ebx + xor ebx,ebx + mov dl,SYMCLASS_PARAMETER + call get_abstract_symbol + local_anchor_ready: + retn + +get_available_value: +; in: +; ebx - SymbolTree_Leaf +; out: +; cf set if symbol is not considered defined +; edx - ValueDefinition +; al = copy of symbol prediction flags before they were affected by this function +; preserves: ebx, ecx, esi, edi + mov edx,[ebx+SymbolTree_Leaf.definition] + test [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + jnz get_variable_value + test edx,edx + jz symbol_predicted_undefined + mov al,[edx+ValueDefinition.flags] + test al,VAL_INTERNAL + jnz symbol_defined + not al + test al,VAL_IN_USE + VAL_NONRECURSIVE + jz symbol_undefined + mov eax,[current_pass] + sub eax,[edx+ValueDefinition.pass] + jz symbol_defined + cmp eax,1 + ja symbol_predicted_undefined + symbol_predicted_defined: + mov al,[ebx+SymbolTree_Leaf.flags] + or [ebx+SymbolTree_Leaf.flags],SYM_PREDICTED + SYM_PREDICTED_DEFINED + ; clc + retn + symbol_defined: + mov al,[ebx+SymbolTree_Leaf.flags] + clc + retn + symbol_predicted_undefined: + mov al,[ebx+SymbolTree_Leaf.flags] + or al,SYM_PREDICTED + and al,not SYM_PREDICTED_DEFINED + xchg [ebx+SymbolTree_Leaf.flags],al + stc + retn + get_variable_value: + test edx,edx + jz symbol_undefined + inspect_definition: + test [edx+ValueDefinition.flags],VAL_INTERNAL + jnz symbol_defined + test [edx+ValueDefinition.flags],VAL_IN_USE + jnz try_previous_definition + mov eax,[current_pass] + cmp eax,[edx+ValueDefinition.pass] + je symbol_defined + cmp edx,[ebx+SymbolTree_Leaf.definition] + je retire_outdated_definition + try_previous_definition: + mov edx,[edx+ValueDefinition.previous] + test edx,edx + jnz inspect_definition + symbol_undefined: + mov al,[ebx+SymbolTree_Leaf.flags] + stc + retn + retire_outdated_definition: + mov eax,edx + dec [edx+ValueDefinition.reference_count] + xchg edx,[ebx+SymbolTree_Leaf.retired_definition] + xchg edx,[eax+ValueDefinition.previous] + mov [ebx+SymbolTree_Leaf.definition],edx + jmp get_variable_value + +mark_symbol_as_used: +; in: +; ebx - SymbolTree_Leaf +; edx - ValueDefinition, null when value is unavailable but used nonetheless +; preserves: ebx, ecx, edx, esi, edi +; note: +; normally setting SymbolTree_Leaf.last_use_pass is enough, but this function +; improves prediction quality of USED operator; + mov eax,[current_pass] + mov [ebx+SymbolTree_Leaf.last_use_pass],eax + test edx,edx + jz mark_used_fallbacks + retn + mark_used_fallbacks: + push ebx edx + mark_fallback_neighbour: + mov edx,[ebx+SymbolTree_Leaf.fallback_neighbour] + test edx,edx + jz mark_fallback_parent + mov [edx+SymbolTree_Leaf.last_use_pass],eax + mark_fallback_parent: + mov ebx,[ebx+SymbolTree_Leaf.fallback_parent] + test ebx,ebx + jz used_fallbacks_marked + mov [ebx+SymbolTree_Leaf.last_use_pass],eax + jmp mark_fallback_neighbour + used_fallbacks_marked: + pop edx ebx + retn + +use_available_value: +; same as get_available_value, but also includes operation of mark_symbol_as_used + mov eax,[current_pass] + mov [ebx+SymbolTree_Leaf.last_use_pass],eax + call get_available_value + jc use_unavailable_value + retn + use_unavailable_value: + call mark_used_fallbacks + stc + retn + +create_constant_value_definition: +; in: +; ebx - SymbolTree_Leaf +; out: +; edx - ValueDefinition possibly containing value to update, null if definition forbidden +; preserves: ebx, esi, edi + test [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + jnz symbol_already_defined + or [ebx+SymbolTree_Leaf.flags],SYM_CONSTANT + mov eax,[ebx+SymbolTree_Leaf.definition] + test eax,eax + jz add_value_definition + test [eax+ValueDefinition.flags],VAL_INTERNAL + jnz symbol_already_defined + mov ecx,[eax+ValueDefinition.pass] + cmp ecx,[current_pass] + jne reset_value + symbol_already_defined: + mov edx,_conflicting_definition + call register_error + xor edx,edx + retn +update_value_definition: +; in: +; ebx - SymbolTree_Leaf +; out: +; edx - ValueDefinition possibly containing value to update, null if definition forbidden +; preserves: ebx, esi, edi + mov eax,[ebx+SymbolTree_Leaf.definition] + test eax,eax + jz add_value_definition + test [eax+ValueDefinition.flags],VAL_INTERNAL + jnz value_redefinition + mov ecx,[eax+ValueDefinition.pass] + cmp ecx,[current_pass] + jne reset_value + test [ebx+SymbolTree_Leaf.flags],SYM_CONSTANT or SYM_LINK + jnz constant_redefined + mov edx,eax + or [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + test [ebx+SymbolTree_Leaf.flags],SYM_PREDICTED + jz dynamic_value_definition_ready + and [ebx+SymbolTree_Leaf.flags],not SYM_PREDICTED + test [ebx+SymbolTree_Leaf.flags],SYM_PREDICTED_DEFINED + jz dynamic_value_definition_ready + or [next_pass_needed],1 + dynamic_value_definition_ready: + cmp [edx+ValueDefinition.reference_count],1 + ja dynamic_value_in_use + retn + dynamic_value_in_use: + mov eax,[edx+ValueDefinition.previous] + mov [ebx+SymbolTree_Leaf.definition],eax + dec [edx+ValueDefinition.reference_count] + mov eax,edx + xchg eax,[ebx+SymbolTree_Leaf.retired_definition] + mov [edx+ValueDefinition.previous],eax +create_value_definition: +; in: +; ebx - SymbolTree_Leaf +; out: +; edx - ValueDefinition possibly containing value to update, null if definition forbidden +; preserves: ebx, esi, edi + mov eax,[ebx+SymbolTree_Leaf.definition] + test eax,eax + jz add_value_definition + test [eax+ValueDefinition.flags],VAL_INTERNAL + jnz value_redefinition + mov ecx,[eax+ValueDefinition.pass] + cmp ecx,[current_pass] + je value_redefinition + reset_value: + test [ebx+SymbolTree_Leaf.flags],SYM_LINK + jnz reset_link_value + mov edx,[ebx+SymbolTree_Leaf.retired_definition] + retire_previous_values: + dec [eax+ValueDefinition.reference_count] + xchg edx,[eax+ValueDefinition.previous] + xchg eax,edx + test eax,eax + jz previous_values_retired + test [eax+ValueDefinition.flags],VAL_INTERNAL + jz retire_previous_values + previous_values_retired: + mov [ebx+SymbolTree_Leaf.definition],edx + xchg eax,[edx+ValueDefinition.previous] + mov [ebx+SymbolTree_Leaf.retired_definition],eax + cmp [edx+ValueDefinition.reference_count],0 + jne add_value_definition + inc [edx+ValueDefinition.reference_count] + test [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + jnz reset_value_type + retn + reset_link_value: + and [ebx+SymbolTree_Leaf.flags],not (SYM_LINK or SYM_LINK_PREDICTED) + mov eax,[ebx+SymbolTree_Leaf.last_use_pass] + cmp eax,[current_pass] + jne reset_current_link_value + or [next_pass_needed],1 + reset_current_link_value: + xor eax,eax + xchg eax,[ebx+SymbolTree_Leaf.definition] + dec [eax+ValueDefinition.reference_count] + jnz reset_previous_link_value + test [eax+ValueDefinition.flags],VAL_DETACHED + jz reset_previous_link_value + mov ecx,eax + xchg eax,[retired_definition] + mov [ecx+ValueDefinition.previous],eax + reset_previous_link_value: + xor eax,eax + xchg eax,[ebx+SymbolTree_Leaf.retired_definition] + test eax,eax + jz add_value_definition + dec [eax+ValueDefinition.reference_count] + jnz add_value_definition + test [eax+ValueDefinition.flags],VAL_DETACHED + jz add_value_definition + mov ecx,eax + xchg eax,[retired_definition] + mov [ecx+ValueDefinition.previous],eax + jmp add_value_definition + constant_redefined: + mov edx,_conflicting_definition + call register_error + xor edx,edx + retn + value_redefinition: + cmp [eax+ValueDefinition.type],VALTYPE_ELEMENT + je constant_redefined + test [ebx+SymbolTree_Leaf.flags],SYM_CONSTANT or SYM_LINK + jnz constant_redefined + test [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + jnz add_value_definition + or [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + test [ebx+SymbolTree_Leaf.flags],SYM_PREDICTED + jz add_value_definition + and [ebx+SymbolTree_Leaf.flags],not SYM_PREDICTED + test [ebx+SymbolTree_Leaf.flags],SYM_PREDICTED_DEFINED + jz add_value_definition + or [next_pass_needed],1 + add_value_definition: + lea ecx,[ebx+SymbolTree_Leaf.retired_definition] + retrieve_retired_value: + mov eax,[ecx] + test eax,eax + jz new_value_definition + cmp [eax+ValueDefinition.reference_count],0 + jne retired_value_immutable + inc [eax+ValueDefinition.reference_count] + mov edx,[eax+ValueDefinition.previous] + mov [ecx],edx + mov [eax+ValueDefinition.type],VALTYPE_RESERVED + jmp adopt_value_definition + retired_value_immutable: + lea ecx,[eax+ValueDefinition.previous] + jmp retrieve_retired_value + new_value_definition: + mov ecx,sizeof.ValueDefinition + call create_tree_element + mov ecx,eax + xchg ecx,[value_definition_chain] + mov [eax+ValueDefinition.interlink],ecx + assert VALTYPE_RESERVED = 0 + inc [eax+ValueDefinition.reference_count] + adopt_value_definition: + mov edx,eax + xchg eax,[ebx+SymbolTree_Leaf.definition] + mov [edx+ValueDefinition.previous],eax + test [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + jnz reset_value_type + test eax,eax + jz value_definition_ready + mov ecx,eax + xchg ecx,[ebx+SymbolTree_Leaf.retired_definition] + xchg ecx,[eax+ValueDefinition.previous] + mov [edx+ValueDefinition.previous],ecx + ; test ecx,ecx + ; jnz internal_error + mov ecx,[eax+ValueDefinition.pass] + mov [edx+ValueDefinition.pass],ecx + mov cl,[eax+ValueDefinition.type] + mov [edx+ValueDefinition.type],cl + mov ecx,[eax+ValueDefinition.value_length] + mov [edx+ValueDefinition.value_length],ecx + jecxz value_definition_ready + push esi edi + mov esi,[eax+ValueDefinition.value] + mov edi,[edx+ValueDefinition.value] + cmp ecx,[edx+ValueDefinition.block_length] + jbe duplicate_value + push edx + cmp [edx+ValueDefinition.block_length],0 + je reallocate_for_duplicate + push ecx + xor eax,eax + xchg eax,[edx+ValueDefinition.value] + call mfree + pop ecx + reallocate_for_duplicate: + mov edi,ecx + call malloc + pop edx + mov [edx+ValueDefinition.value],eax + mov [edx+ValueDefinition.block_length],ecx + mov ecx,edi + mov edi,eax + duplicate_value: + rep movsb + pop edi esi + value_definition_ready: + retn + reset_value_type: + mov [edx+ValueDefinition.type],VALTYPE_RESERVED + retn + +remove_value_definition: +; in: +; ebx - SymbolTree_Leaf +; edx - ValueDefinition, null to remove the present value +; edi - SymbolTree_Leaf where to move the value, null for plain remove +; out: +; cf set if there was no value to remove +; when cf = 0: +; edx - ValueDefinition that got removed +; preserves: ebx, esi, edi + test [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + jnz variable_ready + test [ebx+SymbolTree_Leaf.flags],SYM_CONSTANT or SYM_LINK + jnz cannot_apply_to_constant + or [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + test [ebx+SymbolTree_Leaf.flags],SYM_PREDICTED + jz variable_ready + and [ebx+SymbolTree_Leaf.flags],not SYM_PREDICTED + test [ebx+SymbolTree_Leaf.flags],SYM_PREDICTED_DEFINED + jz variable_ready + or [next_pass_needed],1 + variable_ready: + lea ecx,[ebx+SymbolTree_Leaf.definition] + test edx,edx + jnz find_definition_to_remove + mov edx,[ecx] + test edx,edx + jz no_definition_to_remove + test [edx+ValueDefinition.flags],VAL_INTERNAL + jnz no_definition_to_remove + cmp [edx+ValueDefinition.type],VALTYPE_RESERVED + je no_definition_to_remove + mov eax,[edx+ValueDefinition.pass] + cmp eax,[current_pass] + jne no_definition_to_remove + remove_definition: + mov eax,[edx+ValueDefinition.previous] + test edi,edi + jnz move_definition + mov [ecx],eax + mov eax,[ebx+SymbolTree_Leaf.retired_definition] + mov [edx+ValueDefinition.previous],eax + dec [edx+ValueDefinition.reference_count] + mov [ebx+SymbolTree_Leaf.retired_definition],edx + clc + retn + move_definition: + cmp edi,edx + je definition_moved + test [edi+SymbolTree_Leaf.flags],SYM_VARIABLE + jnz append_moved_definition + test [edi+SymbolTree_Leaf.flags],SYM_CONSTANT or SYM_LINK + jnz cannot_apply_to_constant + or [edi+SymbolTree_Leaf.flags],SYM_VARIABLE + test [edi+SymbolTree_Leaf.flags],SYM_PREDICTED + jz append_moved_definition + and [ebx+SymbolTree_Leaf.flags],not SYM_PREDICTED + test [ebx+SymbolTree_Leaf.flags],SYM_PREDICTED_DEFINED + jz append_moved_definition + or [next_pass_needed],1 + append_moved_definition: + mov [ecx],eax + mov eax,[edi+SymbolTree_Leaf.definition] + mov [edx+ValueDefinition.previous],eax + mov [edi+SymbolTree_Leaf.definition],edx + definition_moved: + clc + retn + find_definition_to_remove: + mov eax,[ecx] + cmp eax,edx + je remove_definition + test eax,eax + jz no_definition_to_remove + lea ecx,[eax+ValueDefinition.previous] + jmp find_definition_to_remove + cannot_apply_to_constant: + mov edx,_cannot_apply_to_constant + call register_error + no_definition_to_remove: + stc + retn + +assign_value: +; in: +; ebx - SymbolTree_Leaf +; edx - ValueDefinition prepared to receive the new value +; esi - value +; ecx = length of value +; [value_type] = VALTYPE_# +; preserves: ebx, edx +; notes: +; with VALTYPE_PLAIN ecx must be zero and esi should contain the value directly +; if esi is null, requested length is allocated but not filled + and [edx+ValueDefinition.flags],0 + mov eax,[current_pass] + sub eax,[edx+ValueDefinition.pass] + add [edx+ValueDefinition.pass],eax + test [ebx+SymbolTree_Leaf.flags],SYM_VARIABLE + jnz reuse_value_block + cmp eax,[current_pass] + je reuse_value_block + mov edi,[ebx+SymbolTree_Leaf.last_use_pass] + cmp edi,[current_pass] + jne reuse_value_block + cmp ecx,[edx+ValueDefinition.value_length] + je update_value + or [next_pass_needed],1 + reuse_value_block: + mov [edx+ValueDefinition.value_length],ecx + mov edi,[edx+ValueDefinition.value] + cmp ecx,[edx+ValueDefinition.block_length] + jbe write_value + push edx + push ecx + cmp [edx+ValueDefinition.block_length],0 + je new_value + xor eax,eax + xchg eax,[edx+ValueDefinition.value] + call mfree + new_value: + pop ecx + call malloc + pop edx + mov [edx+ValueDefinition.value],eax + mov [edx+ValueDefinition.block_length],ecx + mov edi,eax + write_value: + mov al,[value_type] + mov [edx+ValueDefinition.type],al + cmp al,VALTYPE_PLAIN + je write_plain_value + test esi,esi + jz value_written + mov ecx,[edx+ValueDefinition.value_length] + rep movsb + value_written: + retn + write_plain_value: + xchg esi,[edx+ValueDefinition.value] + cmp [edx+ValueDefinition.block_length],0 + je value_written + and [edx+ValueDefinition.block_length],0 + mov eax,esi + call mfree + jmp value_written + rewrite_value: + or [next_pass_needed],1 + jmp write_value + update_value: + mov edi,[edx+ValueDefinition.value] + cmp eax,1 + ja rewrite_value + mov al,[value_type] + cmp [edx+ValueDefinition.type],al + jne rewrite_value + jecxz value_written + test esi,esi + jz rewrite_value + cmp al,VALTYPE_SYMBOLIC + je update_symbolic_value + cmp al,VALTYPE_PLAIN + je update_plain_value + mov ecx,[edx+ValueDefinition.value_length] + repe cmpsb + je value_updated + inc ecx + dec esi + dec edi + or [next_pass_needed],1 + rep movsb + value_updated: + retn + update_symbolic_value: + mov ecx,[edx+ValueDefinition.value_length] + push edx + call compare_symbolic_values + pop edx + jecxz value_updated + value_changed: + rep movsb + changed_value_updated: + or [next_pass_needed],1 + retn + update_plain_value: + mov eax,esi + xchg eax,[edx+ValueDefinition.value] + cmp eax,esi + jne changed_value_updated + retn + +expand_value: +; in: +; edx - ValueDefinition +; ebx = number of additional zero bytes to append to the value +; preserves: ebx, edx, esi + mov eax,[edx+ValueDefinition.value_length] + mov edi,[edx+ValueDefinition.value] + add edi,eax + add eax,ebx + jc out_of_memory + cmp eax,[edx+ValueDefinition.block_length] + jbe append_zero_bytes + push eax + bsr ecx,eax + dec cl + shr eax,cl + inc eax + shl eax,cl + mov ecx,eax + pop eax + cmp ecx,eax + jbe out_of_memory + mov eax,[edx+ValueDefinition.value] + push edx + call realloc + pop edx + mov [edx+ValueDefinition.value],eax + mov [edx+ValueDefinition.block_length],ecx + mov edi,eax + add edi,[edx+ValueDefinition.value_length] + append_zero_bytes: + add [edx+ValueDefinition.value_length],ebx + xor al,al + mov ecx,ebx + rep stosb + retn + +update_value_link: +; in: +; ebx - SymbolTree_Leaf +; edx - ValueDefinition to link +; preserves: ebx, edx +; note: value must be from the current pass + mov eax,[ebx+SymbolTree_Leaf.definition] + test eax,eax + jz values_detached + mov ecx,[eax+ValueDefinition.pass] + cmp ecx,[current_pass] + je symbol_already_defined + test [ebx+SymbolTree_Leaf.flags],SYM_LINK + jnz update_established_link + detach_and_retire_values: + test eax,eax + jz values_detached + dec [eax+ValueDefinition.reference_count] + or [eax+ValueDefinition.flags],VAL_DETACHED + mov ecx,eax + xchg eax,[retired_definition] + xchg eax,[ecx+ValueDefinition.previous] + jmp detach_and_retire_values + values_detached: + mov [ebx+SymbolTree_Leaf.definition],eax + mov eax,[ebx+SymbolTree_Leaf.retired_definition] + detach_retired_values: + test eax,eax + jz retired_values_detached + or [eax+ValueDefinition.flags],VAL_DETACHED + mov ecx,eax + xchg eax,[retired_definition] + xchg eax,[ecx+ValueDefinition.previous] + jmp detach_retired_values + retired_values_detached: + mov [ebx+SymbolTree_Leaf.retired_definition],eax + or [ebx+SymbolTree_Leaf.flags],SYM_LINK + jmp link_new_value + update_established_link: + mov ecx,[current_pass] + cmp ecx,[ebx+SymbolTree_Leaf.last_use_pass] + jne link_new_value + or [ebx+SymbolTree_Leaf.flags],SYM_LINK_PREDICTED + link_new_value: + ; cmp ecx,[edx+ValueDefinition.pass] + ; jne internal_error + mov eax,edx + inc [eax+ValueDefinition.reference_count] + xchg eax,[ebx+SymbolTree_Leaf.definition] + xchg eax,[ebx+SymbolTree_Leaf.retired_definition] + test eax,eax + jz link_updated + dec [eax+ValueDefinition.reference_count] + jnz link_updated + test [eax+ValueDefinition.flags],VAL_DETACHED + jz link_updated + mov ecx,eax + xchg eax,[retired_definition] + mov [ecx+ValueDefinition.previous],eax + link_updated: + retn + +detect_mispredictions: +; in: ebx - SymbolTree_Root +; note: +; while it is looking for mispredicted definitions, it also prepares the tree for the next pass + mov edx,[tree_stack_base] + browse_from_root: + xor eax,eax + mov [ebx+SymbolTree_Root.current_label],eax + and [ebx+SymbolTree_Root.flags],not NAMESPACE_LABEL_FORWARDING + test [ebx+SymbolTree_Root.attributes],SYMTREE_LOCAL + jnz browse_local_tree + add ebx,sizeof.SymbolTree_Root + mov eax,[tree_stack_end] + sub eax,TREE_HEIGHT*8+16 + cmp edx,eax + jbe tree_stack_prepared + mov eax,[tree_stack_base] + sub edx,eax + mov ecx,[tree_stack_end] + sub ecx,eax + add ecx,TREE_HEIGHT*8+16 + push edx + call grow_stack + pop edx + add edx,eax + mov [tree_stack_base],eax + add eax,ecx + mov [tree_stack_end],eax + tree_stack_prepared: + mov ecx,TREE_HEIGHT + browse_node: + mov edi,ebx + dec cl + browse_branch: + cmp dword [edi],0 + je branch_browsed + test cl,cl + jnz deeper_node + mov esi,[edi] + browse_foliage: + mov eax,[esi+SymbolTree_Foliage.child_namespace] + test eax,eax + jz subtree_browsed + mov [edx],ebx + mov [edx+4],ecx + mov [edx+8],esi + mov [edx+12],edi + add edx,16 + mov ebx,eax + jmp browse_from_root + browse_local_tree: + add ebx,sizeof.SymbolTree_Root + mov eax,[tree_stack_end] + sub eax,LOCAL_TREE_HEIGHT*8+16 + cmp edx,eax + jbe local_tree_stack_prepared + mov eax,[tree_stack_base] + sub edx,eax + mov ecx,[tree_stack_end] + sub ecx,eax + add ecx,LOCAL_TREE_HEIGHT*8+16 + push edx + call grow_stack + pop edx + add edx,eax + mov [tree_stack_base],eax + add eax,ecx + mov [tree_stack_end],eax + local_tree_stack_prepared: + mov ecx,LOCAL_TREE_HEIGHT + 1 shl 8 + jmp browse_node + subtree_browsed: + mov eax,esi + add eax,sizeof.SymbolTree_Foliage + inspect_leaf: + test [eax+SymbolTree_Leaf.flags],SYM_LINK_PREDICTED + jz link_prediction_ok + push eax ecx edx esi edi + mov edx,[eax+SymbolTree_Leaf.definition] + mov ecx,[eax+SymbolTree_Leaf.retired_definition] + mov esi,dword [edx+ValueDefinition.type] + sub esi,dword [ecx+ValueDefinition.type] + test esi,0FFh + jnz link_value_mispredicted + mov esi,[ecx+ValueDefinition.value] + mov ecx,[ecx+ValueDefinition.value_length] + mov edi,[edx+ValueDefinition.value] + mov edx,[edx+ValueDefinition.value_length] + cmp ecx,edx + jne link_value_mispredicted + jecxz reset_link_prediction + repe cmpsb + je reset_link_prediction + link_value_mispredicted: + or [next_pass_needed],1 + reset_link_prediction: + and [eax+SymbolTree_Leaf.flags],not SYM_LINK_PREDICTED + pop edi esi edx ecx eax + link_prediction_ok: + test [eax+SymbolTree_Leaf.flags],SYM_VARIABLE + jnz inspect_next_leaf + and [eax+SymbolTree_Leaf.flags],not SYM_CONSTANT + test [eax+SymbolTree_Leaf.flags],SYM_PREDICTED or SYM_USAGE_PREDICTED + jz inspect_next_leaf + push edx + test [eax+SymbolTree_Leaf.flags],SYM_PREDICTED + jz definition_prediction_ok + mov edx,[eax+SymbolTree_Leaf.definition] + test edx,edx + jz detect_misprediction_of_undefined + test [edx+ValueDefinition.flags],VAL_INTERNAL + jnz detect_misprediction_of_defined + mov edx,[edx+ValueDefinition.pass] + cmp edx,[current_pass] + je detect_misprediction_of_defined + detect_misprediction_of_undefined: + test [eax+SymbolTree_Leaf.flags],SYM_PREDICTED_DEFINED + jz reset_prediction + or [next_pass_needed],1 + jmp reset_prediction + detect_misprediction_of_defined: + test [eax+SymbolTree_Leaf.flags],SYM_PREDICTED_DEFINED + jnz reset_prediction + or [next_pass_needed],1 + reset_prediction: + and [eax+SymbolTree_Leaf.flags],not SYM_PREDICTED + definition_prediction_ok: + test [eax+SymbolTree_Leaf.flags],SYM_USAGE_PREDICTED + jz usage_prediction_ok + mov edx,[eax+SymbolTree_Leaf.last_use_pass] + cmp edx,[current_pass] + je detect_misprediction_of_used + detect_misprediction_of_unused: + test [eax+SymbolTree_Leaf.flags],SYM_PREDICTED_USED + jz reset_usage_prediction + or [next_pass_needed],1 + jmp reset_usage_prediction + detect_misprediction_of_used: + test [eax+SymbolTree_Leaf.flags],SYM_PREDICTED_USED + jnz reset_usage_prediction + or [next_pass_needed],1 + reset_usage_prediction: + and [eax+SymbolTree_Leaf.flags],not SYM_USAGE_PREDICTED + usage_prediction_ok: + pop edx + jmp inspect_next_leaf + inspect_next_leaf: + mov eax,[eax+SymbolTree_Leaf.next] + test eax,eax + jnz inspect_leaf + mov esi,[esi+SymbolTree_Foliage.next] + test esi,esi + jnz browse_foliage + branch_browsed: + test ch,ch + jnz local_branch_browsed + add edi,4 + lea eax,[ebx+sizeof.SymbolTree_Node] + cmp edi,eax + jne browse_branch + inc cl + cmp cl,TREE_HEIGHT + je tree_browsed + sub edx,8 + mov ebx,[edx] + mov edi,[edx+4] + jmp branch_browsed + local_branch_browsed: + add edi,4 + lea eax,[ebx+sizeof.SymbolTree_LocalNode] + cmp edi,eax + jne browse_branch + inc cl + cmp cl,LOCAL_TREE_HEIGHT + je tree_browsed + sub edx,8 + mov ebx,[edx] + mov edi,[edx+4] + jmp local_branch_browsed + deeper_node: + mov [edx],ebx + mov [edx+4],edi + add edx,8 + mov ebx,[edi] + jmp browse_node + tree_browsed: + cmp edx,[tree_stack_base] + je complete_tree_browsed + sub edx,16 + mov ebx,[edx] + mov ecx,[edx+4] + mov esi,[edx+8] + mov edi,[edx+12] + jmp subtree_browsed + complete_tree_browsed: + retn diff --git a/toolchain/fasmg.kl0e/source/tables.inc b/toolchain/fasmg.kl0e/source/tables.inc new file mode 100644 index 0000000..ebb1222 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/tables.inc @@ -0,0 +1,649 @@ + +OPERATOR_PRECEDENCE_MASK = 3Fh +OPERATOR_UNARY = 40h +OPERATOR_RIGHT_ASSOCIATIVE = 80h + +SIZE_BYTE = 1 +SIZE_WORD = 2 +SIZE_DWORD = 4 +SIZE_PWORD = 6 +SIZE_QWORD = 8 +SIZE_TWORD = 10 +SIZE_DQWORD = 16 +SIZE_QQWORD = 32 +SIZE_DQQWORD = 64 + +PREPOSITION_AT = 0 +PREPOSITION_FROM = 1 +PREPOSITION_AS = 2 +PREPOSITION_DUP = 3 + +control_characters db 0,9,0Ah,0Dh,1Ah,20h +.count = $-control_characters + +syntactical_characters db '+-/*=<>()[]{}:?!,.|&~#`\;' +.count = $-syntactical_characters + +include_variable db 'INCLUDE',0 + +separating_operators: + + db '+',VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,1 + OPERATOR_UNARY + dd calculate_to_number + + db '-',VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,1 + OPERATOR_UNARY + dd calculate_neg + + db '+',VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,1 + dd calculate_add + + db '-',VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,1 + dd calculate_sub + + db '*',VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,2 + dd calculate_mul + + db '/',VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,2 + dd calculate_div + + db 0 + +symbols: + + db 3,'not',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,6 + OPERATOR_UNARY + dd calculate_not + + db 3,'mod',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,3 + dd calculate_mod + + db 3,'xor',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,4 + dd calculate_xor + + db 3,'and',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,4 + dd calculate_and + + db 2,'or',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,4 + dd calculate_or + + db 3,'shl',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,5 + dd calculate_shl + + db 3,'shr',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,5 + dd calculate_shr + + db 3,'bsf',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,6 + OPERATOR_UNARY + dd calculate_bsf + + db 3,'bsr',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,6 + OPERATOR_UNARY + dd calculate_bsr + + db 5,'bswap',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,5 + dd calculate_bswap + + db 7,'bappend',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,4 + dd calculate_bappend + + db 6,'string',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + OPERATOR_UNARY + dd calculate_to_string + + db 5,'float',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,10 + OPERATOR_UNARY + dd calculate_to_float + + db 5,'trunc',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,10 + OPERATOR_UNARY + dd extract_integer_part + + db 6,'sizeof',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,10 + OPERATOR_UNARY + dd extract_size + + db 8,'lengthof',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,10 + OPERATOR_UNARY + dd count_bytes + + db 10,'elementsof',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,10 + OPERATOR_UNARY + dd count_elements + + db 7,'element',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,7 + dd extract_element + + db 5,'scale',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,7 + dd extract_scale + + db 8,'metadata',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,7 + dd extract_metadata + + db 9,'elementof',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,8 + OPERATOR_RIGHT_ASSOCIATIVE + dd extract_element_reverse + + db 7,'scaleof',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,8 + OPERATOR_RIGHT_ASSOCIATIVE + dd extract_scale_reverse + + db 10,'metadataof',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,8 + OPERATOR_RIGHT_ASSOCIATIVE + dd extract_metadata_reverse + + db 7,'element',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd define_element + + db 3,'equ',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd define_symbolic_variable + + db 5,'reequ',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd redefine_symbolic_variable + + db 6,'define',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd define_raw_symbolic_variable + + db 8,'redefine',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd redefine_raw_symbolic_variable + + db 7,'restore',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SYMCLASS_EXPRESSION + dd restore_variables + + db 9,'namespace',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd set_namespace + + db 7,'display',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd display_data + + db 3,'err',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd custom_error + + db 7,'include',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd include_source + + db 4,'eval',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd evaluate_string + + db 6,'assert',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd assert_condition + + db 7,'defined',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMPARATOR,VAL_INTERNAL,0 + dd check_if_defined + + db 4,'used',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMPARATOR,VAL_INTERNAL,0 + dd check_if_used + + db 8,'definite',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMPARATOR,VAL_INTERNAL,0 + dd check_if_defined_earlier + + db 6,'eqtype',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMPARATOR,VAL_INTERNAL,0 + dd check_if_type_equal + + db 2,'eq',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMPARATOR,VAL_INTERNAL,0 + dd check_if_value_equal + + db 10,'relativeto',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_COMPARATOR,VAL_INTERNAL,0 + dd check_if_relative + + db 2,'if',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd conditional_block + + db 5,'match',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd match_block + + db 6,'rmatch',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd raw_match_block + + db 8,'rawmatch',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd raw_match_block + + db 5,'while',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd conditionally_repeated_block + + db 6,'repeat',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd repeated_block + + db 7,'iterate',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd iterator_block + + db 4,'rept',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd repeated_block + + db 3,'irp',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd iterator_block + + db 4,'irpv',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd variable_iterator_block + + db 4,'indx',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd set_iterator_index + + db 5,'break',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd break_directive + + db 4,'else',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd else_directive + + db 3,'end',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_directive + + db 8,'postpone',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd postponed_block + + db 5,'macro',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd define_macro + + db 5,'struc',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd define_struc + + db 3,'esc',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd escape_directive + + db 5,'local',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd local_directive + + db 8,'outscope',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd outscope_directive + + db 5,'purge',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SYMCLASS_INSTRUCTION + dd restore_variables + + db 7,'restruc',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SYMCLASS_STRUCTURE + dd restore_variables + + db 7,'mvmacro',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SYMCLASS_INSTRUCTION + dd move_variable_values + + db 7,'mvstruc',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SYMCLASS_STRUCTURE + dd move_variable_values + + db 15,'calminstruction',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd define_calm_instruction + + db 14,'removecomments',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd choose_to_remove_comments + + db 14,'retaincomments',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd choose_to_retain_comments + + db 12,'combinelines',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd choose_to_combine_lines + + db 12,'isolatelines',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd choose_to_isolate_lines + + db 3,'org',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd set_base_address + + db 7,'section',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd begin_new_section + + db 10,'restartout',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd restart_output + + db 6,'format',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd format_directive + + db 4,'emit',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd define_data + + db 4,'emit',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd define_labeled_data + + db 3,'dbx',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd define_data + + db 3,'dbx',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd define_labeled_data + + db 2,'db',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_BYTE + dd define_data + + db 2,'db',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_BYTE + dd define_labeled_data + + db 2,'dw',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_WORD + dd define_data + + db 2,'dw',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_WORD + dd define_labeled_data + + db 2,'dd',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_DWORD + dd define_data + + db 2,'dd',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_DWORD + dd define_labeled_data + + db 2,'dp',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_PWORD + dd define_data + + db 2,'dp',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_PWORD + dd define_labeled_data + + db 2,'dq',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_QWORD + dd define_data + + db 2,'dq',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_QWORD + dd define_labeled_data + + db 2,'dt',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_TWORD + dd define_data + + db 2,'dt',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_TWORD + dd define_labeled_data + + db 3,'ddq',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_DQWORD + dd define_data + + db 3,'ddq',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_DQWORD + dd define_labeled_data + + db 3,'dqq',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_QQWORD + dd define_data + + db 3,'dqq',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_QQWORD + dd define_labeled_data + + db 4,'ddqq',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_DQQWORD + dd define_data + + db 4,'ddqq',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_DQQWORD + dd define_labeled_data + + db 2,'rb',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_BYTE + dd reserve_data + + db 2,'rb',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_BYTE + dd reserve_labeled_data + + db 2,'rw',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_WORD + dd reserve_data + + db 2,'rw',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_WORD + dd reserve_labeled_data + + db 2,'rd',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_DWORD + dd reserve_data + + db 2,'rd',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_DWORD + dd reserve_labeled_data + + db 2,'rp',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_PWORD + dd reserve_data + + db 2,'rp',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_PWORD + dd reserve_labeled_data + + db 2,'rq',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_QWORD + dd reserve_data + + db 2,'rq',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_QWORD + dd reserve_labeled_data + + db 2,'rt',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_TWORD + dd reserve_data + + db 2,'rt',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_TWORD + dd reserve_labeled_data + + db 3,'rdq',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_DQWORD + dd reserve_data + + db 3,'rdq',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_DQWORD + dd reserve_labeled_data + + db 3,'rqq',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_QQWORD + dd reserve_data + + db 3,'rqq',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_QQWORD + dd reserve_labeled_data + + db 4,'rdqq',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_DQQWORD + dd reserve_data + + db 4,'rdqq',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,SIZE_DQQWORD + dd reserve_labeled_data + + db 4,'file',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd include_data + + db 4,'file',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd include_labeled_data + + db 1,'$',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_FUNCTION,VAL_INTERNAL,0 + dd current_address_value + + db 2,'$$',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_FUNCTION,VAL_INTERNAL,0 + dd base_address_value + + db 2,'$@',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_FUNCTION,VAL_INTERNAL,0 + dd truncated_address_value + + db 2,'$%',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_FUNCTION,VAL_INTERNAL,0 + dd current_position_value + + db 3,'$%%',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_FUNCTION,VAL_INTERNAL,0 + dd truncated_position_value + + db 2,'%t',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_FUNCTION,VAL_INTERNAL,0 + dd current_time_value + + db 8,'__time__',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_FUNCTION,VAL_INTERNAL,0 + dd current_time_value + + db 10,'__source__',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_FUNCTION,VAL_INTERNAL,0 + dd main_file_name_value + + db 8,'__file__',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_FUNCTION,VAL_INTERNAL,0 + dd current_file_name_value + + db 8,'__line__',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_FUNCTION,VAL_INTERNAL,0 + dd current_line_number_value + + db 4,'byte',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_BYTE + + db 4,'word',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_WORD + + db 5,'dword',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_DWORD + + db 5,'pword',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_PWORD + + db 5,'fword',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_PWORD + + db 5,'qword',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_QWORD + + db 5,'tword',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_TWORD + + db 5,'tbyte',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_TWORD + + db 6,'dqword',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_DQWORD + + db 5,'xword',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_DQWORD + + db 6,'qqword',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_QQWORD + + db 5,'yword',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_QQWORD + + db 7,'dqqword',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_DQQWORD + + db 5,'zword',SYMCLASS_EXPRESSION,VALTYPE_PLAIN,VAL_INTERNAL,0 + dd SIZE_DQQWORD + + db 5,'label',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd label_directive + + db 7,'virtual',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd virtual_block + + db 4,'load',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd load_value + + db 5,'store',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd store_value + + db 2,'at',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_PREPOSITION,VAL_INTERNAL,0 + dd PREPOSITION_AT + + db 4,'from',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_PREPOSITION,VAL_INTERNAL,0 + dd PREPOSITION_FROM + + db 2,'as',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_PREPOSITION,VAL_INTERNAL,0 + dd PREPOSITION_AS + + db 3,'dup',SYMCLASS_EXPRESSION,VALTYPE_NATIVE_PREPOSITION,VAL_INTERNAL,0 + dd PREPOSITION_DUP + + db 0 + +db 3,'end' + + db 9,'namespace',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd end_namespace + + db 2,'if',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_conditional_block + + db 5,'match',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_match_block + + db 6,'rmatch',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_raw_match_block + + db 8,'rawmatch',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_raw_match_block + + db 5,'while',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_conditionally_repeated_block + + db 6,'repeat',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_repeated_block + + db 7,'iterate',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_iterator_block + + db 4,'rept',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_repeated_block + + db 3,'irp',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_iterator_block + + db 4,'irpv',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_variable_iterator_block + + db 8,'postpone',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_postponed_block + + db 5,'macro',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_macro + + db 5,'struc',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd end_struc + + db 7,'virtual',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd end_virtual_block + + db 0 + +db 4,'else' + + db 2,'if',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd else_conditional_block + + db 5,'match',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd else_match_block + + db 6,'rmatch',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd else_raw_match_block + + db 8,'rawmatch',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd else_raw_match_block + + db 0 + +db 6,'format' + + db 6,'binary',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd format_binary + + db 0 + +db 15,'calminstruction' + + db 5,'local',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_local + + db 7,'arrange',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_arrange + + db 5,'match',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_match + + db 8,'assemble',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_assemble + + db 9,'transform',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_transform + + db 9,'stringify',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_stringify + + db 7,'publish',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_publish + + db 4,'take',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_take + + db 7,'compute',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_compute + + db 5,'check',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_check + + db 4,'emit',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_emit + + db 4,'load',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_load + + db 5,'store',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_store + + db 7,'display',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_display + + db 3,'err',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_err + + db 4,'jyes',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_jyes + + db 3,'jno',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_jno + + db 4,'jump',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_jump + + db 4,'call',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_call + + db 4,'exit',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_exit + + db 3,'end',SYMCLASS_INSTRUCTION,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL + VAL_UNCONDITIONAL,0 + dd alm_end + + db 15,'calminstruction',SYMCLASS_STRUCTURE,VALTYPE_NATIVE_COMMAND,VAL_INTERNAL,0 + dd alm_end + +db 0 + +zero_value dd 0 + dd 0 + +singular_value dd 1 + db 1 + dd 0 + +subtraction_operator dd EXPR_OPERATOR,calculate_sub + dd 0 diff --git a/toolchain/fasmg.kl0e/source/variables.inc b/toolchain/fasmg.kl0e/source/variables.inc new file mode 100644 index 0000000..922a6ac --- /dev/null +++ b/toolchain/fasmg.kl0e/source/variables.inc @@ -0,0 +1,314 @@ + +characters db 256 dup ? + +maximum_number_of_errors dd ? +maximum_depth_of_stack dd ? + +variables: + + temporary_value dd 4 dup ? + accumulator dd 3 dup ? + + source_file dd ? + + include_paths dd ? + + storage_blocks dd ? + storage_free_space dd ? + storage_free_space_length dd ? + + tree_blocks dd ? + tree_reserve dd ? + tree_reserve_length dd ? + + value_definition_chain dd ? + retired_definition dd ? + + file_source_cache dd ? + memory_source_cache dd ? + file_data_cache dd ? + + operator_table dd ? + root_namespace dd ? + root_parameter_namespace dd ? + local_parameter_namespace dd ? + interceptor_symbol dd ? + label_interceptor_symbol dd ? + other_interceptor_symbol dd ? + proxy_number dd ? + + source_context dd ? + source_context_maximum_length dd ? + current_pass dd ? + current_context RecognitionContext + local_namespace dd ? + parameter_namespace dd ? + + directives_stack dd ? + directives_stack_base dd ? + directives_stack_end dd ? + + current_counter dd ? + counters_stack_base dd ? + counters_stack_end dd ? + + first_error dd ? + + current_area dd ? + output_areas_list dd ? + output_areas_list_end dd ? + initial_output_area_entry dd ? + current_output_area_entry dd ? + prior_uninitialized_length dq ? + virtual_area dd ? + auxiliary_output_areas dd ? + void_symbol dd ? + + base_path dd ? + output_extension dd ? + output_extension_length dd ? + output_failures dd ? + + preprocessing_workspace Workspace + assembly_workspace Workspace + identifier_workspace Workspace + value_workspace Workspace + expression_workspace Workspace + calculation_workspace Workspace + auxiliary_workspace Workspace + + line_start dd ? + line_end dd ? + line_embeddings dd ? + line_embeddings_maximum_length dd ? + number_of_line_embeddings dd ? + preprocessed_context dd ? + line_context dd ? + embedded_context dd ? + number_of_enclosings dd ? + + recognition_context RecognitionContext + name_token dd ? + case_sensitive_hash dd ? + case_insensitive_hash dd ? + kept_symbol dd ? + current_symbol dd ? + tree_stack_base dd ? + tree_stack_end dd ? + symbol_root dd ? + symbol_branch dd ? + minor_identifier dd ? + + source_end dd ? + symbol_start dd ? + symbol_data dd ? + symbol_value_start dd ? + symbol_value_end dd ? + + interceptor dd ? + label_branch dd ? + label_leaf dd ? + label_interceptor dd ? + label_instruction_start dd ? + label_instruction_context dd ? + + display_buffer dd ? + display_buffer_length dd ? + display_data_length dd ? + + macro_buffer dd ? + macro_buffer_length dd ? + macro_leaf dd ? + macro_end_position dd ? + + constituent_symbol dd ? + constituent_value dd ? + constituent_whitespace dd ? + + alm_namespace dd ? + alm_adjusted_context RecognitionContext + calm_code_buffer Workspace + calm_code_cursor dd ? + calm_literals_buffer Workspace + calm_literals_cursor dd ? + calm_auxiliary_buffer Workspace + calm_auxiliary_cursor dd ? + calm_line_number dd ? + calm_instruction_number dd ? + calm_value dd ? + calm_literals dd ? + calm_source_pointer dd ? + calm_rollback_offset dd ? + + value_position dd ? + kept_value dd ? + converter_position dd ? + expression_position dd ? + expression_end dd ? + operator_stack dd ? + operator_stack_position dd ? + operator_stack_base dd ? + operator_stack_end dd ? + calculation_position dd ? + source_term dd ? + destination_term dd ? + temporary_terms dd ? + free_temporary_terms dd ? + temporary_floats dd ? + iterations dd ? + exponent dd ? + multiplier dd ? + divisor dd ? + long_dividend_term dd ? + long_divisor_term dd ? + long_divisor_length dd ? + division_temporary_terms dd ? + mantissa_tail dd ? + predicted_shift dd ? + subexpression_end dd ? + + condition_stack dd ? + condition_stack_base dd ? + condition_stack_end dd ? + initial_parentheses dd ? + comparator dd ? + outer_expression dd ? + + assembly_stack_base dd ? + assembly_stack_end dd ? + previous_symbol_end dd ? + further_whitespace dd ? + zero_digits dd ? + decimal_places dd ? + literal_exponent dd ? + update_function dd ? + argument_start dd ? + macro_parameters_context dd ? + new_local_namespace dd ? + file_name dd ? + string_end dd ? + message_end dd ? + data_area_symbol dd ? + data_area dd ? + data_offset dd ? + file_offset dq ? + data_length dd ? + local_path dd ? + + error_line_start dd ? + error_line_end dd ? + error_symbol dd ? + last_source_entry dd ? + last_file_source_entry dd ? + preprocessed_text_end dd ? + + source_text dd ? + source_text_length dd ? + tokenization_buffer dd ? + tokenization_buffer_length dd ? + buffer_end_offset dd ? + file_data dd ? + file_cache_pointer dd ? + + address_length dd ? + data_unit_length dd ? + uninitialized_length dq ? + + directive_block dd ? + number_of_iterations dd ? + number_of_parameters dd ? + number_of_values dd ? + parameter_index dd ? + value_index dd ? + value dd ? + value_length dd ? + metadata_length dd ? + sequence_header_cursor dd ? + sequence_header_length dd ? + expression_sequence_cursor dd ? + expression_sequence_end dd ? + context_boundary dd ? + whitespace_boundary dd ? + transforming_namespace dd ? + + pattern_start dd ? + pattern_end dd ? + matched_context dd ? + substitutions_end dd ? + stored_position dd ? + stored_substitution dd ? + stored_context dd ? + stored_pattern dd ? + brackets dd ? + + instruction_value dd ? + instruction_branch dd ? + instruction_body dd ? + + number_of_lines dd ? + + preprocessing_mode db ? + assembly_mode db ? + next_pass_needed db ? + shift_tracking db ? + + name_kind db ? + name_volatile db ? + symbol_class db ? + symbol_required db ? + symbol_expected db ? + kept_symbol_flags db ? + chosen_class db ? + expected_class db ? + symbol_definition db ? + symbol_independent db ? + recognizer_setting db ? + label_independent db ? + value_type db ? + waiting_for_digit db ? + literal_exponent_sign db ? + literal_fractional_part db ? + float_literal_status db ? + use_raw_values db ? + + last_token db ? + breakpoint_token db ? + current_constituent db ? + kept_value_in_workspace db ? + leave_opening_parentheses db ? + operator_argument_expected db ? + term_type db ? + bit_shift db ? + shift_overflow db ? + multiplier_sign db ? + high_bits_count db ? + first_sign db ? + second_sign db ? + comparator_priority db ? + result_type db ? + defined_element db ? + + source_context_affected db ? + raw_value db ? + substitution_active db ? + stored_substitution_activity db ? + unprocessed_matching db ? + whitespace_matching db ? + macro_definition_active db ? + macro_flags db ? + macro_greedy db ? + calm_definition_active db ? + + size_specified db ? + + message_volatile db ? + displayed_byte db ? + + alm_statement db ? + calm_result db ? + hidden_context db ? + contextless_processing db ? + +variables_end: + + trace_mode db ? diff --git a/toolchain/fasmg.kl0e/source/version.inc b/toolchain/fasmg.kl0e/source/version.inc new file mode 100644 index 0000000..213bb30 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/version.inc @@ -0,0 +1 @@ +VERSION equ "kl0e" \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/source/windows/dll/fasmg.asm b/toolchain/fasmg.kl0e/source/windows/dll/fasmg.asm new file mode 100644 index 0000000..fd81d31 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/windows/dll/fasmg.asm @@ -0,0 +1,254 @@ + +match ,{ + + include 'win32a.inc' + include 'localptr.inc' + +} match -,{ +else + + include 'selfhost.inc' + +end match +_ equ } + + format PE large NX DLL + entry DllEntryPoint + +include '../../version.inc' + +struct MEMORY_REGION + address dd ? + size dd ? +ends + +section '.text' code executable + + include '../../assembler.inc' + include '../../symbols.inc' + include '../../expressions.inc' + include '../../conditions.inc' + include '../../floats.inc' + include '../../directives.inc' + include '../../calm.inc' + include '../../errors.inc' + include '../../map.inc' + include '../../reader.inc' + include '../../output.inc' + include '../../console.inc' + + DllEntryPoint: + mov eax,1 + retn 12 + + fasmg_GetVersion: + mov eax,version_string + retn + + fasmg_Assemble: + + virtual at ebp - LOCAL_VARIABLES_SIZE + + LocalVariables: + + include '../../variables.inc' + + maximum_number_of_passes dd ? + + timestamp dq ? + systemtime SYSTEMTIME + filetime FILETIME + + memory dd ? + systmp dd ? + + rb (LocalVariables - $) and 11b + + LOCAL_VARIABLES_SIZE = $ - LocalVariables + + assert $ - ebp = 0 + + previous_frame dd ? + stored_edi dd ? + stored_esi dd ? + stored_ebx dd ? + return_address dd ? + + FunctionParameters: + + source_string dd ? + source_path dd ? + output_region dd ? + output_path dd ? + stdout dd ? + stderr dd ? + + FUNCTION_PARAMETERS_SIZE = $ - FunctionParameters + + end virtual + + push ebx esi edi + enter LOCAL_VARIABLES_SIZE,0 + + call system_init + + mov [maximum_number_of_passes],100 + mov [maximum_number_of_errors],1000 + mov [maximum_depth_of_stack],10000 + + xor al,al + call assembly_init + + assemble: + mov esi,[source_string] + mov edx,[source_path] + call assembly_pass + jc assembly_done + + mov eax,[current_pass] + cmp eax,[maximum_number_of_passes] + jb assemble + + call show_display_data + call assembly_shutdown + call system_shutdown + mov eax,-2 + leave + pop edi esi ebx + retn FUNCTION_PARAMETERS_SIZE + + assembly_done: + + call show_display_data + + cmp [first_error],0 + jne assembly_failed + + mov esi,[output_region] + test esi,esi + jz output_copied + call get_output_length + test edx,edx + jnz out_of_memory + mov [value_length],eax + xchg eax,[esi+MEMORY_REGION.size] + cmp [esi+MEMORY_REGION.address],0 + je new_region_for_output + cmp eax,[value_length] + jae copy_output + invoke VirtualAlloc,[esi+MEMORY_REGION.address],[esi+MEMORY_REGION.size],MEM_COMMIT,PAGE_READWRITE + test eax,eax + jnz copy_output + invoke VirtualFree,[esi+MEMORY_REGION.address],0,MEM_RELEASE + new_region_for_output: + invoke VirtualAlloc,0,[esi+MEMORY_REGION.size],MEM_COMMIT,PAGE_READWRITE + test eax,eax + jz out_of_memory + mov [esi+MEMORY_REGION.address],eax + copy_output: + mov edi,[esi+MEMORY_REGION.address] + xor eax,eax + mov dword [file_offset],eax + mov dword [file_offset+4],eax + call read_from_output + output_copied: + + mov ebx,[source_path] + mov edi,[output_path] + mov eax,ebx + or eax,edi + jz output_written + call write_output_file + jc write_failed + output_written: + + call assembly_shutdown + call system_shutdown + xor eax,eax + leave + pop edi esi ebx + retn FUNCTION_PARAMETERS_SIZE + + assembly_failed: + mov eax,[first_error] + xor ecx,ecx + count_errors: + inc ecx + mov eax,[eax+Error.next] + test eax,eax + jnz count_errors + push ecx + call show_errors + call assembly_shutdown + call system_shutdown + pop eax + leave + pop edi esi ebx + retn FUNCTION_PARAMETERS_SIZE + + write_failed: + call assembly_shutdown + call system_shutdown + mov eax,-3 + leave + pop edi esi ebx + retn FUNCTION_PARAMETERS_SIZE + + out_of_memory: + call assembly_shutdown + call system_shutdown + mov eax,-1 + leave + pop edi esi ebx + retn FUNCTION_PARAMETERS_SIZE + + include 'system.inc' + +section '.rdata' data readable + +data import + + library kernel32,'KERNEL32.DLL' + + import kernel32,\ + CloseHandle,'CloseHandle',\ + CreateFile,'CreateFileA',\ + ExitProcess,'ExitProcess',\ + GetCommandLine,'GetCommandLineA',\ + GetEnvironmentVariable,'GetEnvironmentVariableA',\ + GetStdHandle,'GetStdHandle',\ + GetSystemTime,'GetSystemTime',\ + GetTickCount,'GetTickCount',\ + HeapAlloc,'HeapAlloc',\ + HeapCreate,'HeapCreate',\ + HeapDestroy,'HeapDestroy',\ + HeapFree,'HeapFree',\ + HeapReAlloc,'HeapReAlloc',\ + HeapSize,'HeapSize',\ + VirtualAlloc,'VirtualAlloc',\ + VirtualFree,'VirtualFree',\ + ReadFile,'ReadFile',\ + SetFilePointer,'SetFilePointer',\ + SystemTimeToFileTime,'SystemTimeToFileTime',\ + WriteFile,'WriteFile',\ + GetLastError,'GetLastError' + +end data + +align 4 + +data export + + export 'FASMG.DLL',\ + fasmg_GetVersion,'fasmg_GetVersion',\ + fasmg_Assemble,'fasmg_Assemble' + +end data + + include '../../tables.inc' + include '../../messages.inc' + + version_string db VERSION,0 + +section '.reloc' fixups data readable discardable + \ No newline at end of file diff --git a/toolchain/fasmg.kl0e/source/windows/dll/localptr.inc b/toolchain/fasmg.kl0e/source/windows/dll/localptr.inc new file mode 100644 index 0000000..eaf63eb --- /dev/null +++ b/toolchain/fasmg.kl0e/source/windows/dll/localptr.inc @@ -0,0 +1,28 @@ + +macro pushd arg +{ + if arg eqtype +ebp & arg relativeto ebp + if arg - ebp + push eax + lea eax,[arg] + xchg eax,[esp] + else + push ebp + end if + else if ~ arg eq + pushd arg + end if +} + +macro mov dest,src +{ + if src eqtype +ebp & src relativeto ebp + if src - ebp + lea dest,[src] + else + mov dest,ebp + end if + else + mov dest,src + end if +} diff --git a/toolchain/fasmg.kl0e/source/windows/dll/selfhost.inc b/toolchain/fasmg.kl0e/source/windows/dll/selfhost.inc new file mode 100644 index 0000000..953a2b1 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/windows/dll/selfhost.inc @@ -0,0 +1,266 @@ + +include '../../../examples/x86/include/80386.inc' + +macro format?.PE? settings + PE.Settings.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_32BIT_MACHINE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_LOCAL_SYMS_STRIPPED + PE.Settings.DllCharacteristics = 0 + PE.Settings.Stamp = +VERSION + PE.Settings.LegacyHeaders = 0 + local seq + define seq settings: + while 1 + match :, seq + break + else match =DLL? more, seq + PE.Settings.Characteristics = PE.Settings.Characteristics or IMAGE_FILE_DLL + redefine seq more + else match =large? more, seq + PE.Settings.Characteristics = PE.Settings.Characteristics or IMAGE_FILE_LARGE_ADDRESS_AWARE + redefine seq more + else match =WDM? more, seq + PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_WDM_DRIVER + redefine seq more + else match =NX? more, seq + PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_NX_COMPAT + redefine seq more + else match =at? base =on? stub :, seq + PE.Settings.ImageBase = base + PE.Settings.Stub = stub + break + else match =at? base :, seq + PE.Settings.ImageBase = base + break + else match =on? stub :, seq + PE.Settings.Stub = stub + break + else + match =GUI? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI + redefine seq more + else match =console? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI + redefine seq more + else match =native? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_NATIVE + PE.Settings.SectionAlignment = 32 + PE.Settings.FileAlignment = 32 + redefine seq more + else match =EFI? more, seq + PE.Settings.Magic = 0x20B + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION + redefine seq more + else match =EFIboot? more, seq + PE.Settings.Magic = 0x20B + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER + redefine seq more + else match =EFIruntime? more, seq + PE.Settings.Magic = 0x20B + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER + redefine seq more + else + err 'invalid argument' + break + end match + match V.v more, seq + PE.Settings.MajorSubsystemVersion = V + PE.Settings.MinorSubsystemVersion = v + redefine seq more + end match + end match + end while + if PE.Settings.Characteristics and IMAGE_FILE_DLL + format binary as 'dll' + else + format binary as 'exe' + end if + include '../../../examples/x86/include/format/pe.inc' + use32 +end macro + +macro struct? name + macro ends?! + end namespace + esc end struc + virtual at 0 + name name + sizeof.name = $ + end virtual + purge ends? + end macro + esc struc name + label . : sizeof.name + namespace . +end macro + +calminstruction invoke? proc*,args& + local tmp, tmpst, stack + match , args + jyes go + collect: + match tmpst=,args, args + take stack, tmpst + jyes collect + push: + match tmp], args + jyes regular + check args relativeto ebp & args - ebp + jno regular + arrange tmp, =push =eax + assemble tmp + arrange tmp, =lea =eax,[args] + assemble tmp + arrange tmp, =xchg =eax,[=esp] + assemble tmp + jump next + regular: + arrange tmp, =pushd args + assemble tmp + next: + take args, stack + jyes push + go: + arrange tmp, =call [proc] + assemble tmp +end calminstruction + +calminstruction mov? dest*,src* + local tmp + match tmp], src + jyes regular + check src relativeto ebp & src - ebp + jno regular + arrange tmp, =lea dest,[src] + assemble tmp + exit + regular: + arrange tmp, =mov dest,src + assemble tmp +end calminstruction + +macro library? definitions& + PE.Imports: + iterate , definitions + if ~ name.redundant + dd RVA name.lookup,0,0,RVA name.str,RVA name.address + end if + name.referred = 1 + end iterate + dd 0,0,0,0,0 + iterate , definitions + if ~ name.redundant + name.str db string,0 + align 2 + end if + end iterate +end macro + +macro import? name,definitions& + align 4 + if defined name.referred + name.lookup: + iterate , definitions + if used label + if string eqtype '' + dd RVA name.label + else + dd 80000000h + string + end if + end if + end iterate + if $ > name.lookup + name.redundant = 0 + dd 0 + else + name.redundant = 1 + end if + name.address: + iterate , definitions + if used label + if string eqtype '' + label dd RVA name.label + else + label dd 80000000h + string + end if + end if + end iterate + if ~ name.redundant + dd 0 + end if + iterate , definitions + if used label & string eqtype '' + name.label dw 0 + db string,0 + align 2 + end if + end iterate + end if +end macro + +macro export dllname,exports& + iterate , exports + + local module,addresses,names,ordinal,count + count = %% + dd 0,0,0,RVA module,1 + dd count,count,RVA addresses,RVA names,RVA ordinal + addresses: + repeat count + indx % + dd RVA label + end repeat + names: + repeat count + dd RVA names.name#% + end repeat + ordinal: + repeat count + dw %-1 + end repeat + module db dllname,0 + repeat count + indx % + names.name#% db string,0 + end repeat + + local x,y,z,str1,str2,v1,v2 + x = count shr 1 + while x > 0 + y = x + while y < count + z = y + while z-x >= 0 + load v1:dword from names+z*4 + str1 = ($-(RVA $))+v1 + load v2:dword from names+(z-x)*4 + str2 = ($-(RVA $))+v2 + while v1 > 0 + load v1:byte from str1+%-1 + load v2:byte from str2+%-1 + if v1 <> v2 + break + end if + end while + if v1 < v2 + load v1:dword from names+z*4 + load v2:dword from names+(z-x)*4 + store v1:dword at names+(z-x)*4 + store v2:dword at names+z*4 + load v1:word from ordinal+z*2 + load v2:word from ordinal+(z-x)*2 + store v1:word at ordinal+(z-x)*2 + store v2:word at ordinal+z*2 + else + break + end if + z = z-x + end while + y = y+1 + end while + x = x shr 1 + end while + + break + end iterate +end macro + +include '../kernel32.inc' diff --git a/toolchain/fasmg.kl0e/source/windows/dll/system.inc b/toolchain/fasmg.kl0e/source/windows/dll/system.inc new file mode 100644 index 0000000..d4c6d40 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/windows/dll/system.inc @@ -0,0 +1,214 @@ + +LINE_FEED equ 13,10 + +system_init: + invoke HeapCreate,0,20000h,0 + mov [memory],eax + test eax,eax + jz out_of_memory + invoke GetSystemTime,systemtime + invoke SystemTimeToFileTime,systemtime,filetime + mov ebx,[filetime.dwLowDateTime] + mov eax,[filetime.dwHighDateTime] + sub ebx,116444736000000000 and 0FFFFFFFFh + sbb eax,116444736000000000 shr 32 + xor edx,edx + mov ecx,10000000 + div ecx + mov dword [timestamp+4],eax + mov eax,ebx + div ecx + mov dword [timestamp],eax + retn + +system_shutdown: + cmp [memory],0 + je memory_released + invoke HeapDestroy,[memory] + memory_released: + retn + +malloc: +malloc_fixed: +malloc_growable: +; in: ecx = requested size +; out: eax - allocated block, ecx = allocated size, on error jumps to out_of_memory (does not return) +; preserves: ebx, esi, edi +; note: +; use of malloc_fixed hints that block will be kept as is until the end of assembly +; use of malloc_growable hints that block is likely to be resized + invoke HeapAlloc,[memory],0,ecx + test eax,eax + jz out_of_memory + memory_allocated: + push eax + invoke HeapSize,[memory],0,eax + mov ecx,eax + pop eax + cmp ecx,-1 + je out_of_memory + retn +realloc: +; in: eax - memory block, ecx = requested size +; out: eax - resized block, ecx = allocated size, on error jumps to out_of_memory (does not return) +; preserves: ebx, esi, edi + invoke HeapReAlloc,[memory],0,eax,ecx + test eax,eax + jnz memory_allocated + jmp out_of_memory +mfree: +; in: eax - memory block +; out: cf set on error +; preserves: ebx, esi, edi +; note: eax may have value 0 or -1, it should be treated as invalid input then + test eax,eax + jz interface_error + cmp eax,-1 + je interface_error + invoke HeapFree,[memory],0,eax + test eax,eax + jz interface_error + clc + retn + interface_error: + stc + retn + +open: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + invoke CreateFile,edx,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0 + cmp eax,-1 + je interface_error + mov ebx,eax + clc + retn +create: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + invoke CreateFile,edx,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0 + cmp eax,-1 + je interface_error + mov ebx,eax + clc + retn +write: +; in: ebx = file handle, edx - data, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push ecx + invoke WriteFile,ebx,edx,ecx,systmp,0 + pop ecx + test eax,eax + jz interface_error + cmp ecx,[systmp] + jne interface_error + clc + retn +read: +; in: ebx = file handle, edx - buffer, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push ecx + invoke ReadFile,ebx,edx,ecx,systmp,0 + pop ecx + test eax,eax + jz interface_error + cmp ecx,[systmp] + jne interface_error + clc + retn +close: +; in: ebx = file handle +; preserves: ebx, esi, edi + invoke CloseHandle,ebx + retn +lseek: +; in: ebx = file handle, cl = method, edx:eax = offset +; out: edx:eax = new offset from the beginning of file, cf set on error +; preserves: ebx, esi, edi + movzx ecx,cl + mov [systmp],edx + invoke SetFilePointer,ebx,eax,systmp,ecx + cmp eax,-1 + jne lseek_ok + invoke GetLastError + test eax,eax + jnz interface_error + not eax + lseek_ok: + mov edx,[systmp] + clc + retn + +get_timestamp: +; out: edx:eax = timestamp +; preserves: ebx, ecx, esi, edi +; note: during the passes of a single assembly this function should always return the same value + mov eax,dword [timestamp] + mov edx,dword [timestamp+4] + retn + +display_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push ebx + mov ebx,[stdout] + jmp write_string +display_error_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push ebx + mov ebx,[stderr] + write_string: + test ebx,ebx + jz hidden_display + test ecx,ecx + jnz write_string_to_stdout + xor al,al + mov edi,esi + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + write_string_to_stdout: + mov edx,esi + write_portion_to_stdout: + mov eax,51200 + cmp ecx,eax + jbe final_write_to_stdout + sub ecx,eax + add eax,edx + push eax ecx + invoke WriteFile,ebx,edx,51200,systmp,0 + pop ecx edx + jmp write_portion_to_stdout + final_write_to_stdout: + invoke WriteFile,ebx,edx,ecx,systmp,0 + hidden_display: + pop ebx + retn + +get_environment_variable: +; in: +; esi - name +; edi - buffer for value +; ecx = size of buffer +; out: +; eax = length of value +; preserves: ebx, esi, edi + push ecx + invoke GetEnvironmentVariable,esi,edi,ecx + pop ecx + cmp eax,ecx + jae environment_variable_ready + mov byte [edi+eax],0 + environment_variable_ready: + inc eax + retn diff --git a/toolchain/fasmg.kl0e/source/windows/fasmg.asm b/toolchain/fasmg.kl0e/source/windows/fasmg.asm new file mode 100644 index 0000000..6d38202 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/windows/fasmg.asm @@ -0,0 +1,529 @@ + +match ,{ + + include 'win32a.inc' + +} match -,{ +else + + include 'selfhost.inc' + +end match +_ equ } + + + format PE large NX console 4.0 + entry start + +include '../version.inc' + +section '.text' code executable + + include 'system.inc' + + start: + + call system_init + + call get_arguments + mov bl,al + cmp [no_logo],0 + jne logo_ok + mov esi,_logo + xor ecx,ecx + call display_string + logo_ok: + test bl,bl + jnz display_usage_information + + xor al,al + movzx ecx,[verbosity_level] + jecxz init + or al,TRACE_ERROR_STACK + dec ecx + jz init + or al,TRACE_DISPLAY + init: + call assembly_init + + invoke GetTickCount + mov [timer],eax + + assemble: + mov esi,[initial_commands] + mov edx,[source_path] + call assembly_pass + jc assembly_done + + mov eax,[current_pass] + cmp eax,[maximum_number_of_passes] + jb assemble + + call show_display_data + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,_code_cannot_be_generated + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + jmp assembly_failed + + assembly_done: + + call show_display_data + + cmp [first_error],0 + jne assembly_failed + + cmp [no_logo],0 + jne summary_done + mov eax,[current_pass] + xor edx,edx + call itoa + call display_string + mov esi,_passes + cmp [current_pass],1 + jne display_passes_suffix + mov esi,_pass + display_passes_suffix: + xor ecx,ecx + call display_string + invoke GetTickCount + sub eax,[timer] + xor edx,edx + add eax,50 + mov ecx,1000 + div ecx + mov ebx,eax + mov eax,edx + xor edx,edx + mov ecx,100 + div ecx + mov [timer],eax + xchg eax,ebx + or ebx,eax + jz display_output_length + xor edx,edx + call itoa + call display_string + mov esi,_message_suffix + mov ecx,1 + call display_string + mov eax,[timer] + xor edx,edx + call itoa + call display_string + mov esi,_seconds + xor ecx,ecx + call display_string + display_output_length: + call get_output_length + push eax edx + call itoa + call display_string + pop edx eax + mov esi,_bytes + cmp eax,1 + jne display_bytes_suffix + test edx,edx + jnz display_bytes_suffix + mov esi,_byte + display_bytes_suffix: + xor ecx,ecx + call display_string + mov esi,_new_line + xor ecx,ecx + call display_string + summary_done: + + mov ebx,[source_path] + mov edi,[output_path] + call write_output_file + jc write_failed + + call assembly_shutdown + call system_shutdown + + invoke ExitProcess,0 + + assembly_failed: + + call show_errors + + call assembly_shutdown + call system_shutdown + + invoke ExitProcess,2 + + write_failed: + mov ebx,_write_failed + jmp fatal_error + + out_of_memory: + mov ebx,_out_of_memory + jmp fatal_error + + fatal_error: + + mov esi,_error_prefix + xor ecx,ecx + call display_error_string + mov esi,ebx + xor ecx,ecx + call display_error_string + mov esi,_message_suffix + xor ecx,ecx + call display_error_string + + call assembly_shutdown + call system_shutdown + + invoke ExitProcess,3 + + display_usage_information: + + mov esi,_usage + xor ecx,ecx + call display_string + + call system_shutdown + + invoke ExitProcess,1 + + get_arguments: + xor eax,eax + mov [initial_commands],eax + mov [source_path],eax + mov [output_path],eax + mov [no_logo],al + mov [verbosity_level],al + mov [maximum_number_of_passes],100 + mov [maximum_number_of_errors],1 + mov [maximum_depth_of_stack],10000 + invoke GetCommandLine + mov esi,eax + mov edi,eax + or ecx,-1 + xor al,al + repne scasb + sub edi,esi + mov ecx,edi + call malloc + mov edi,eax + get_argument: + xor ah,ah + read_character: + lodsb + test al,al + jz no_more_arguments + cmp al,22h + je switch_quote + cmp ax,20h + je end_argument + stosb + jmp read_character + end_argument: + xor al,al + stosb + find_next_argument: + mov al,[esi] + test al,al + jz no_more_arguments + cmp al,20h + jne next_argument_found + inc esi + jmp find_next_argument + switch_quote: + xor ah,1 + jmp read_character + next_argument_found: + cmp al,'-' + je get_option + cmp al,'/' + je get_option + cmp [source_path],0 + je get_source_path + cmp [output_path],0 + je get_output_path + error_in_arguments: + or al,-1 + retn + get_source_path: + mov [source_path],edi + jmp get_argument + get_output_path: + mov [output_path],edi + jmp get_argument + no_more_arguments: + cmp [source_path],0 + je error_in_arguments + xor al,al + stosb + retn + get_option: + inc esi + lodsb + cmp al,'e' + je set_errors_limit + cmp al,'E' + je set_errors_limit + cmp al,'i' + je insert_initial_command + cmp al,'I' + je insert_initial_command + cmp al,'p' + je set_passes_limit + cmp al,'P' + je set_passes_limit + cmp al,'r' + je set_recursion_limit + cmp al,'R' + je set_recursion_limit + cmp al,'v' + je set_verbose_mode + cmp al,'V' + je set_verbose_mode + cmp al,'n' + je set_no_logo + cmp al,'N' + jne error_in_arguments + set_no_logo: + or [no_logo],-1 + mov al,[esi] + cmp al,20h + je find_next_argument + test al,al + jnz error_in_arguments + jmp find_next_argument + set_verbose_mode: + call get_option_value + jc error_in_arguments + cmp edx,2 + ja error_in_arguments + mov [verbosity_level],dl + jmp find_next_argument + set_errors_limit: + call get_option_value + jc error_in_arguments + test edx,edx + jz error_in_arguments + mov [maximum_number_of_errors],edx + jmp find_next_argument + set_recursion_limit: + call get_option_value + jc error_in_arguments + test edx,edx + jz error_in_arguments + mov [maximum_depth_of_stack],edx + jmp find_next_argument + set_passes_limit: + call get_option_value + jc error_in_arguments + test edx,edx + jz error_in_arguments + mov [maximum_number_of_passes],edx + jmp find_next_argument + get_option_value: + xor eax,eax + mov edx,eax + find_option_value: + cmp byte [esi],20h + jne get_option_digit + inc esi + jmp find_option_value + get_option_digit: + lodsb + cmp al,20h + je option_value_ok + test al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + invalid_option_value: + stc + ret + insert_initial_command: + push edi + find_command_segment: + cmp byte [esi],20h + jne command_segment_found + inc esi + jmp find_command_segment + command_segment_found: + xor ah,ah + cmp byte [esi],22h + jne measure_command_segment + inc esi + inc ah + measure_command_segment: + mov ebx,esi + scan_command_segment: + mov ecx,esi + mov al,[esi] + test al,al + jz command_segment_measured + cmp ax,20h + je command_segment_measured + cmp ax,22h + je command_segment_measured + inc esi + cmp al,22h + jne scan_command_segment + command_segment_measured: + sub ecx,ebx + mov edi,[initial_commands] + lea eax,[ecx+2] + test edi,edi + jz allocate_initial_commands_buffer + mov edx,[initial_commands_length] + add edi,edx + add eax,edx + cmp eax,[initial_commands_maximum_length] + ja grow_initial_commands_buffer + copy_initial_command: + xchg esi,ebx + rep movsb + mov esi,ebx + sub edi,[initial_commands] + mov [initial_commands_length],edi + mov al,[esi] + test al,al + jz initial_command_ready + cmp al,20h + jne command_segment_found + initial_command_ready: + mov edi,[initial_commands] + add edi,[initial_commands_length] + mov ax,0Ah + stosw + inc [initial_commands_length] + pop edi + jmp find_next_argument + allocate_initial_commands_buffer: + push ecx + mov ecx,eax + call malloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + pop ecx + jmp copy_initial_command + grow_initial_commands_buffer: + push ecx + mov ecx,eax + mov eax,[initial_commands] + call realloc + mov [initial_commands],eax + mov [initial_commands_maximum_length],ecx + mov edi,eax + add edi,[initial_commands_length] + pop ecx + jmp copy_initial_command + + include '../symbols.inc' + include '../assembler.inc' + include '../expressions.inc' + include '../conditions.inc' + include '../floats.inc' + include '../directives.inc' + include '../calm.inc' + include '../errors.inc' + include '../map.inc' + include '../reader.inc' + include '../output.inc' + include '../console.inc' + +section '.bss' readable writeable + + include '../variables.inc' + + source_path dd ? + output_path dd ? + maximum_number_of_passes dd ? + + initial_commands dd ? + initial_commands_length dd ? + initial_commands_maximum_length dd ? + + stdout dd ? + stderr dd ? + memory dd ? + timestamp dq ? + systemtime SYSTEMTIME + filetime FILETIME + systmp dd ? + + timer dd ? + verbosity_level db ? + no_logo db ? + +section '.rdata' data readable + +data import + + library kernel32,'KERNEL32.DLL' + + import kernel32,\ + CloseHandle,'CloseHandle',\ + CreateFile,'CreateFileA',\ + ExitProcess,'ExitProcess',\ + GetCommandLine,'GetCommandLineA',\ + GetEnvironmentVariable,'GetEnvironmentVariableA',\ + GetStdHandle,'GetStdHandle',\ + GetSystemTime,'GetSystemTime',\ + GetTickCount,'GetTickCount',\ + HeapAlloc,'HeapAlloc',\ + HeapCreate,'HeapCreate',\ + HeapDestroy,'HeapDestroy',\ + HeapFree,'HeapFree',\ + HeapReAlloc,'HeapReAlloc',\ + HeapSize,'HeapSize',\ + ReadFile,'ReadFile',\ + SetFilePointer,'SetFilePointer',\ + SystemTimeToFileTime,'SystemTimeToFileTime',\ + WriteFile,'WriteFile',\ + GetLastError,'GetLastError' + +end data + + _logo db 'flat assembler version g.',VERSION,13,10,0 + + _usage db 'Usage: fasmg source [output]',13,10 + db 'Optional settings:',13,10 + db ' -e limit Set the maximum number of displayed errors (default 1)',13,10 + db ' -p limit Set the maximum allowed number of passes (default 100)',13,10 + db ' -r limit Set the maximum depth of the stack (default 10000)',13,10 + db ' -v flag Enable or disable showing all lines from the stack (default 0)',13,10 + db ' -i command Insert instruction at the beginning of source',13,10 + db ' -n Do not show logo nor summary',13,10 + db 0 + + _pass db ' pass, ',0 + _passes db ' passes, ',0 + _dot db '.' + _seconds db ' seconds, ',0 + _byte db ' byte.',0 + _bytes db ' bytes.',0 + + _write_failed db 'failed to write the output file',0 + _out_of_memory db 'not enough memory to complete the assembly',0 + _code_cannot_be_generated db 'could not generate code within the allowed number of passes',0 + + include '../tables.inc' + include '../messages.inc' diff --git a/toolchain/fasmg.kl0e/source/windows/kernel32.inc b/toolchain/fasmg.kl0e/source/windows/kernel32.inc new file mode 100644 index 0000000..ea728eb --- /dev/null +++ b/toolchain/fasmg.kl0e/source/windows/kernel32.inc @@ -0,0 +1,96 @@ + +struct FILETIME + dwLowDateTime dd ? + dwHighDateTime dd ? +ends + +struct SYSTEMTIME + wYear dw ? + wMonth dw ? + wDayOfWeek dw ? + wDay dw ? + wHour dw ? + wMinute dw ? + wSecond dw ? + wMilliseconds dw ? +ends + +; Page access flags + +PAGE_NOACCESS = 001h +PAGE_READONLY = 002h +PAGE_READWRITE = 004h +PAGE_WRITECOPY = 008h +PAGE_EXECUTE = 010h +PAGE_EXECUTE_READ = 020h +PAGE_EXECUTE_READWRITE = 040h +PAGE_EXECUTE_WRITECOPY = 080h +PAGE_GUARD = 100h +PAGE_NOCACHE = 200h + +; Memory allocation flags + +MEM_COMMIT = 001000h +MEM_RESERVE = 002000h +MEM_DECOMMIT = 004000h +MEM_RELEASE = 008000h +MEM_FREE = 010000h +MEM_PRIVATE = 020000h +MEM_MAPPED = 040000h +MEM_RESET = 080000h +MEM_TOP_DOWN = 100000h + +; Heap allocation flags + +HEAP_NO_SERIALIZE = 1 +HEAP_GENERATE_EXCEPTIONS = 4 +HEAP_ZERO_MEMORY = 8 + +; Device handles + +INVALID_HANDLE_VALUE = -1 +STD_INPUT_HANDLE = -10 +STD_OUTPUT_HANDLE = -11 +STD_ERROR_HANDLE = -12 + +; Access rights + +DELETE_RIGHT = 00010000h +READ_CONTROL = 00020000h +WRITE_DAC = 00040000h +WRITE_OWNER = 00080000h +SYNCHRONIZE = 00100000h +STANDARD_RIGHTS_READ = READ_CONTROL +STANDARD_RIGHTS_WRITE = READ_CONTROL +STANDARD_RIGHTS_EXECUTE = READ_CONTROL +STANDARD_RIGHTS_REQUIRED = 000F0000h +STANDARD_RIGHTS_ALL = 001F0000h +SPECIFIC_RIGHTS_ALL = 0000FFFFh +ACCESS_SYSTEM_SECURITY = 01000000h +MAXIMUM_ALLOWED = 02000000h +GENERIC_READ = 80000000h +GENERIC_WRITE = 40000000h +GENERIC_EXECUTE = 20000000h +GENERIC_ALL = 10000000h +PROCESS_TERMINATE = 00000001h +PROCESS_CREATE_THREAD = 00000002h +PROCESS_VM_OPERATION = 00000008h +PROCESS_VM_READ = 00000010h +PROCESS_VM_WRITE = 00000020h +PROCESS_DUP_HANDLE = 00000040h +PROCESS_CREATE_PROCESS = 00000080h +PROCESS_SET_QUOTA = 00000100h +PROCESS_SET_INFORMATION = 00000200h +PROCESS_QUERY_INFORMATION = 00000400h +PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or 0FFFh +FILE_SHARE_READ = 00000001h +FILE_SHARE_WRITE = 00000002h +FILE_SHARE_DELETE = 00000004h + +; CreateFile actions + +CREATE_NEW = 1 +CREATE_ALWAYS = 2 +OPEN_EXISTING = 3 +OPEN_ALWAYS = 4 +TRUNCATE_EXISTING = 5 diff --git a/toolchain/fasmg.kl0e/source/windows/selfhost.inc b/toolchain/fasmg.kl0e/source/windows/selfhost.inc new file mode 100644 index 0000000..126baef --- /dev/null +++ b/toolchain/fasmg.kl0e/source/windows/selfhost.inc @@ -0,0 +1,171 @@ + +include '../../examples/x86/include/80386.inc' + +macro format?.PE? settings + PE.Settings.Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE or IMAGE_FILE_32BIT_MACHINE or IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_LOCAL_SYMS_STRIPPED + PE.Settings.DllCharacteristics = 0 + PE.Settings.Stamp = +VERSION + local seq + define seq settings: + while 1 + match :, seq + break + else match =DLL? more, seq + PE.Settings.Characteristics = PE.Settings.Characteristics or IMAGE_FILE_DLL + redefine seq more + else match =large? more, seq + PE.Settings.Characteristics = PE.Settings.Characteristics or IMAGE_FILE_LARGE_ADDRESS_AWARE + redefine seq more + else match =WDM? more, seq + PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_WDM_DRIVER + redefine seq more + else match =NX? more, seq + PE.Settings.DllCharacteristics = PE.Settings.DllCharacteristics or IMAGE_DLLCHARACTERISTICS_NX_COMPAT + redefine seq more + else match =at? base =on? stub :, seq + PE.Settings.ImageBase = base + PE.Settings.Stub = stub + break + else match =at? base :, seq + PE.Settings.ImageBase = base + break + else match =on? stub :, seq + PE.Settings.Stub = stub + break + else + match =GUI? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI + redefine seq more + else match =console? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI + redefine seq more + else match =native? more, seq + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_NATIVE + PE.Settings.SectionAlignment = 32 + PE.Settings.FileAlignment = 32 + redefine seq more + else match =EFI? more, seq + PE.Settings.Magic = 0x20B + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_APPLICATION + redefine seq more + else match =EFIboot? more, seq + PE.Settings.Magic = 0x20B + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER + redefine seq more + else match =EFIruntime? more, seq + PE.Settings.Magic = 0x20B + PE.Settings.Subsystem = IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER + redefine seq more + else + err 'invalid argument' + break + end match + match V.v more, seq + PE.Settings.MajorSubsystemVersion = V + PE.Settings.MinorSubsystemVersion = v + redefine seq more + end match + end match + end while + if PE.Settings.Characteristics and IMAGE_FILE_DLL + format binary as 'dll' + else + format binary as 'exe' + end if + include '../../examples/x86/include/format/pe.inc' + use32 +end macro + +macro struct? name + macro ends?! + end namespace + esc end struc + virtual at 0 + name name + sizeof.name = $ + end virtual + purge ends? + end macro + esc struc name + label . : sizeof.name + namespace . +end macro + +calminstruction invoke? proc*,args& + local tmp, stack + match , args + jyes go + collect: + match tmp=,args, args + take stack, tmp + jyes collect + push: + arrange args, =pushd args + assemble args + take args, stack + jyes push + go: + arrange proc, =call [proc] + assemble proc +end calminstruction + +macro library? definitions& + PE.Imports: + iterate , definitions + if ~ name.redundant + dd RVA name.lookup,0,0,RVA name.str,RVA name.address + end if + name.referred = 1 + end iterate + dd 0,0,0,0,0 + iterate , definitions + if ~ name.redundant + name.str db string,0 + align 2 + end if + end iterate +end macro + +macro import? name,definitions& + align 4 + if defined name.referred + name.lookup: + iterate , definitions + if used label + if string eqtype '' + dd RVA name.label + else + dd 80000000h + string + end if + end if + end iterate + if $ > name.lookup + name.redundant = 0 + dd 0 + else + name.redundant = 1 + end if + name.address: + iterate , definitions + if used label + if string eqtype '' + label dd RVA name.label + else + label dd 80000000h + string + end if + end if + end iterate + if ~ name.redundant + dd 0 + end if + iterate , definitions + if used label & string eqtype '' + name.label dw 0 + db string,0 + align 2 + end if + end iterate + end if +end macro + +include 'kernel32.inc' diff --git a/toolchain/fasmg.kl0e/source/windows/system.inc b/toolchain/fasmg.kl0e/source/windows/system.inc new file mode 100644 index 0000000..79d8c41 --- /dev/null +++ b/toolchain/fasmg.kl0e/source/windows/system.inc @@ -0,0 +1,218 @@ + +LINE_FEED equ 13,10 + +system_init: + invoke GetStdHandle,STD_OUTPUT_HANDLE + mov [stdout],eax + invoke GetStdHandle,STD_ERROR_HANDLE + mov [stderr],eax + invoke HeapCreate,0,20000h,0 + mov [memory],eax + test eax,eax + jz out_of_memory + invoke GetSystemTime,systemtime + invoke SystemTimeToFileTime,systemtime,filetime + mov ebx,[filetime.dwLowDateTime] + mov eax,[filetime.dwHighDateTime] + sub ebx,116444736000000000 and 0FFFFFFFFh + sbb eax,116444736000000000 shr 32 + xor edx,edx + mov ecx,10000000 + div ecx + mov dword [timestamp+4],eax + mov eax,ebx + div ecx + mov dword [timestamp],eax + retn + +system_shutdown: + cmp [memory],0 + je memory_released + invoke HeapDestroy,[memory] + memory_released: + invoke CloseHandle,[stdout] + invoke CloseHandle,[stderr] + retn + +malloc: +malloc_fixed: +malloc_growable: +; in: ecx = requested size +; out: eax - allocated block, ecx = allocated size, on error jumps to out_of_memory (does not return) +; preserves: ebx, esi, edi +; note: +; use of malloc_fixed hints that block will be kept as is until the end of assembly +; use of malloc_growable hints that block is likely to be resized + invoke HeapAlloc,[memory],0,ecx + test eax,eax + jz out_of_memory + memory_allocated: + push eax + invoke HeapSize,[memory],0,eax + mov ecx,eax + pop eax + cmp ecx,-1 + je out_of_memory + retn +realloc: +; in: eax - memory block, ecx = requested size +; out: eax - resized block, ecx = allocated size, on error jumps to out_of_memory (does not return) +; preserves: ebx, esi, edi + invoke HeapReAlloc,[memory],0,eax,ecx + test eax,eax + jnz memory_allocated + jmp out_of_memory +mfree: +; in: eax - memory block +; out: cf set on error +; preserves: ebx, esi, edi +; note: eax may have value 0 or -1, it should be treated as invalid input then + test eax,eax + jz interface_error + cmp eax,-1 + je interface_error + invoke HeapFree,[memory],0,eax + test eax,eax + jz interface_error + clc + retn + interface_error: + stc + retn + +open: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + invoke CreateFile,edx,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0 + cmp eax,-1 + je interface_error + mov ebx,eax + clc + retn +create: +; in: edx - path to file +; out: ebx = file handle, cf set on error +; preserves: esi, edi + invoke CreateFile,edx,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0 + cmp eax,-1 + je interface_error + mov ebx,eax + clc + retn +write: +; in: ebx = file handle, edx - data, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push ecx + invoke WriteFile,ebx,edx,ecx,systmp,0 + pop ecx + test eax,eax + jz interface_error + cmp ecx,[systmp] + jne interface_error + clc + retn +read: +; in: ebx = file handle, edx - buffer, ecx = number of bytes +; out: cf set on error +; preserves: ebx, esi, edi + push ecx + invoke ReadFile,ebx,edx,ecx,systmp,0 + pop ecx + test eax,eax + jz interface_error + cmp ecx,[systmp] + jne interface_error + clc + retn +close: +; in: ebx = file handle +; preserves: ebx, esi, edi + invoke CloseHandle,ebx + retn +lseek: +; in: ebx = file handle, cl = method, edx:eax = offset +; out: edx:eax = new offset from the beginning of file, cf set on error +; preserves: ebx, esi, edi + movzx ecx,cl + mov [systmp],edx + invoke SetFilePointer,ebx,eax,systmp,ecx + cmp eax,-1 + jne lseek_ok + invoke GetLastError + test eax,eax + jnz interface_error + not eax + lseek_ok: + mov edx,[systmp] + clc + retn + +get_timestamp: +; out: edx:eax = timestamp +; preserves: ebx, ecx, esi, edi +; note: during the passes of a single assembly this function should always return the same value + mov eax,dword [timestamp] + mov edx,dword [timestamp+4] + retn + +display_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push ebx + mov ebx,[stdout] + jmp write_string +display_error_string: +; in: +; esi - string +; ecx = string length, zero for ASCIIZ string +; preserves: ebx, esi + push ebx + mov ebx,[stderr] + write_string: + test ecx,ecx + jnz write_string_to_stdout + xor al,al + mov edi,esi + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + write_string_to_stdout: + mov edx,esi + write_portion_to_stdout: + mov eax,51200 + cmp ecx,eax + jbe final_write_to_stdout + sub ecx,eax + add eax,edx + push eax ecx + invoke WriteFile,ebx,edx,51200,systmp,0 + pop ecx edx + jmp write_portion_to_stdout + final_write_to_stdout: + invoke WriteFile,ebx,edx,ecx,systmp,0 + pop ebx + retn + +get_environment_variable: +; in: +; esi - name +; edi - buffer for value +; ecx = size of buffer +; out: +; eax = length of value +; preserves: ebx, esi, edi + push ecx + invoke GetEnvironmentVariable,esi,edi,ecx + pop ecx + cmp eax,ecx + jae environment_variable_ready + mov byte [edi+eax],0 + environment_variable_ready: + inc eax + retn + diff --git a/toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.ASM b/toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.ASM new file mode 100644 index 0000000..cc3e11c --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.ASM @@ -0,0 +1,326 @@ + +; DirectDraw programming example + +format PE GUI 4.0 +entry start + +include 'win32a.inc' + +include 'ddraw.inc' + +section '.text' code readable executable + + start: + + and [DDraw],0 + and [DDSPrimary],0 + and [DDSBack],0 + and [DDPalette],0 + and [DDSPicture],0 + + invoke GetModuleHandleA,NULL + mov [hinstance],eax + + invoke LoadIconA,NULL,IDI_APPLICATION + mov [wc.hIcon],eax + + invoke LoadCursorA,NULL,IDC_ARROW + mov [wc.hCursor],eax + + mov [wc.style],0 + mov [wc.lpfnWndProc],WindowProc + mov [wc.cbClsExtra],0 + mov [wc.cbWndExtra],0 + mov eax,[hinstance] + mov [wc.hInstance],eax + mov [wc.hbrBackground],0 + mov dword [wc.lpszMenuName],NULL + mov dword [wc.lpszClassName],_class + invoke RegisterClassA,wc + test eax,eax + jz startup_error + + invoke CreateWindowExA,\ + 0,_class,_title,WS_POPUP+WS_VISIBLE,0,0,0,0,NULL,NULL,[hinstance],NULL + test eax,eax + jz startup_error + mov [hwnd],eax + + invoke DirectDrawCreate,NULL,DDraw,NULL + or eax,eax + jnz ddraw_error + + cominvk DDraw,SetCooperativeLevel,\ + [hwnd],DDSCL_EXCLUSIVE+DDSCL_FULLSCREEN + or eax,eax + jnz ddraw_error + + cominvk DDraw,SetDisplayMode,\ + 640,480,8 + or eax,eax + jnz ddraw_error + + mov [ddsd.dwSize],sizeof.DDSURFACEDESC + mov [ddsd.dwFlags],DDSD_CAPS+DDSD_BACKBUFFERCOUNT + mov [ddsd.ddsCaps.dwCaps],DDSCAPS_PRIMARYSURFACE+DDSCAPS_FLIP+DDSCAPS_COMPLEX + mov [ddsd.dwBackBufferCount],1 + cominvk DDraw,CreateSurface,\ + ddsd,DDSPrimary,NULL + or eax,eax + jnz ddraw_error + + mov [ddscaps.dwCaps],DDSCAPS_BACKBUFFER + cominvk DDSPrimary,GetAttachedSurface,\ + ddscaps,DDSBack + or eax,eax + jnz ddraw_error + + mov esi,picture + call load_picture + jc open_error + + mov esi,picture + call load_palette + jc open_error + + invoke GetTickCount + mov [last_tick],eax + + jmp paint + +main_loop: + + invoke PeekMessageA,msg,NULL,0,0,PM_NOREMOVE + or eax,eax + jz no_message + invoke GetMessageA,msg,NULL,0,0 + or eax,eax + jz end_loop + invoke TranslateMessage,msg + invoke DispatchMessageA,msg + + jmp main_loop + + no_message: + cmp [active],0 + je sleep + + cominvk DDSPrimary,IsLost + or eax,eax + jz paint + cmp eax,DDERR_SURFACELOST + jne end_loop + + cominvk DDSPrimary,Restore + +paint: + + mov [rect.top],0 + mov [rect.bottom],480 + mov [rect.left],0 + mov [rect.right],640 + + cominvk DDSBack,BltFast,\ + 0,0,[DDSPicture],rect,DDBLTFAST_SRCCOLORKEY + or eax,eax + jnz paint_done + + movzx eax,[frame] + xor edx,edx + mov ebx,10 + div ebx + + sal eax,6 + add eax,480 + mov [rect.top],eax + add eax,64 + mov [rect.bottom],eax + sal edx,6 + mov [rect.left],edx + add edx,64 + mov [rect.right],edx + + cominvk DDSBack,BltFast,\ + [x],[y],[DDSPicture],rect,DDBLTFAST_SRCCOLORKEY + + cominvk DDSPrimary,SetPalette,[DDPalette] + + cominvk DDSPrimary,Flip,0,0 + + paint_done: + + invoke GetTickCount + mov ebx,eax + sub ebx,[last_tick] + cmp ebx,20 + jb main_loop + add [last_tick],20 + + inc [frame] + cmp [frame],60 + jb main_loop + mov [frame],0 + jmp main_loop + +sleep: + invoke WaitMessage + jmp main_loop + +ddraw_error: + mov eax,_ddraw_error + jmp error +open_error: + mov eax,_open_error + error: + invoke MessageBoxA,[hwnd],eax,_error,MB_OK+MB_ICONERROR + invoke DestroyWindow,[hwnd] + invoke PostQuitMessage,1 + jmp main_loop +startup_error: + invoke MessageBoxA,[hwnd],_startup_error,_error,MB_OK+MB_ICONERROR +end_loop: + + cmp [DDSPicture],0 + je picture_released + cominvk DDSPicture,Release + picture_released: + cmp [DDPalette],0 + je palette_released + cominvk DDPalette,Release + palette_released: + cmp [DDSBack],0 + je back_surface_released + cominvk DDSPrimary,DeleteAttachedSurface,0,DDSBack + back_surface_released: + cmp [DDSPrimary],0 + je primary_surface_released + cominvk DDSPrimary,Release + primary_surface_released: + cmp [DDraw],0 + je ddraw_released + cominvk DDraw,Release + ddraw_released: + + invoke ExitProcess,[msg.wParam] + +include 'gif87a.inc' + +proc WindowProc hwnd,wmsg,wparam,lparam + push ebx esi edi + mov eax,[wmsg] + cmp eax,WM_CREATE + je .wmcreate + cmp eax,WM_DESTROY + je .wmdestroy + cmp eax,WM_ACTIVATE + je .wmactivate + cmp eax,WM_SETCURSOR + je .wmsetcursor + cmp eax,WM_MOUSEMOVE + je .wmmousemove + cmp eax,WM_KEYDOWN + je .wmkeydown + .defwindowproc: + invoke DefWindowProcA,[hwnd],[wmsg],[wparam],[lparam] + jmp .finish + .wmcreate: + xor eax,eax + jmp .finish + .wmkeydown: + cmp [wparam],VK_ESCAPE + jne .finish + .wmdestroy: + cominvk DDraw,RestoreDisplayMode + invoke PostQuitMessage,0 + xor eax,eax + jmp .finish + .wmactivate: + mov eax,[wparam] + mov [active],al + jmp .finish + .wmsetcursor: + invoke SetCursor,0 + xor eax,eax + jmp .finish + .wmmousemove: + movsx eax,word [lparam] + mov [x],eax + movsx eax,word [lparam+2] + mov [y],eax + .finish: + pop edi esi ebx + ret +endp + +section '.data' data readable writeable + + _title db 'flat assembler DirectDraw application',0 + _class db 'FDDRAW32',0 + + _error db 'Error',0 + _startup_error db 'Startup failed.',0 + _ddraw_error db 'Direct Draw initialization failed.',0 + _open_error db 'Failed opening data file.',0 + + picture db 'DDRAW.GIF',0 + +section '.bss' readable writeable + + hinstance dd ? + hwnd dd ? + wc WNDCLASS + msg MSG + + ddsd DDSURFACEDESC + ddscaps DDSCAPS + + DDraw DirectDraw + DDSPrimary DirectDrawSurface + DDSBack DirectDrawSurface + + DDSPicture DirectDrawSurface + DDPalette DirectDrawPalette + + bytes_count dd ? + last_tick dd ? + frame db ? + active db ? + LZW_bits db ? + LZW_table rd (0F00h-2)*2 + buffer rb 40000h + rect RECT + x dd ? + y dd ? + +section '.idata' import data readable + + library kernel,'KERNEL32.DLL',\ + user,'USER32.DLL',\ + ddraw,'DDRAW.DLL' + + import kernel,\ + GetModuleHandleA,'GetModuleHandleA',\ + CreateFileA,'CreateFileA',\ + ReadFile,'ReadFile',\ + CloseHandle,'CloseHandle',\ + GetTickCount,'GetTickCount',\ + ExitProcess,'ExitProcess' + + import user,\ + RegisterClassA,'RegisterClassA',\ + CreateWindowExA,'CreateWindowExA',\ + DestroyWindow,'DestroyWindow',\ + DefWindowProcA,'DefWindowProcA',\ + GetMessageA,'GetMessageA',\ + PeekMessageA,'PeekMessageA',\ + TranslateMessage,'TranslateMessage',\ + DispatchMessageA,'DispatchMessageA',\ + LoadCursorA,'LoadCursorA',\ + LoadIconA,'LoadIconA',\ + SetCursor,'SetCursor',\ + MessageBoxA,'MessageBoxA',\ + PostQuitMessage,'PostQuitMessage',\ + WaitMessage,'WaitMessage' + + import ddraw,\ + DirectDrawCreate,'DirectDrawCreate' diff --git a/toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.GIF b/toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.GIF new file mode 100644 index 0000000..96dea3a Binary files /dev/null and b/toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.GIF differ diff --git a/toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.INC b/toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.INC new file mode 100644 index 0000000..15bc638 --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.INC @@ -0,0 +1,424 @@ + +; DirectDraw interface + +interface DirectDraw,\ + QueryInterface,\ + AddRef,\ + Release,\ + Compact,\ + CreateClipper,\ + CreatePalette,\ + CreateSurface,\ + DuplicateSurface,\ + EnumDisplayModes,\ + EnumSurfaces,\ + FlipToGDISurface,\ + GetCaps,\ + GetDisplayMode,\ + GetFourCCCodes,\ + GetGDISurface,\ + GetMonitorFrequency,\ + GetScanLine,\ + GetVerticalBlankStatus,\ + Initialize,\ + RestoreDisplayMode,\ + SetCooperativeLevel,\ + SetDisplayMode,\ + WaitForVerticalBlank,\ + GetAvailableVidMem,\ + GetSurfaceFromDC,\ + RestoreAllSurfaces,\ + TestCooperativeLevel,\ + GetDeviceIdentifier,\ + StartModeTest,\ + EvaluateMode + +interface DirectDrawSurface,\ + QueryInterface,\ + AddRef,\ + Release,\ + AddAttachedSurface,\ + AddOverlayDirtyRect,\ + Blt,\ + BltBatch,\ + BltFast,\ + DeleteAttachedSurface,\ + EnumAttachedSurfaces,\ + EnumOverlayZOrders,\ + Flip,\ + GetAttachedSurface,\ + GetBltStatus,\ + GetCaps,\ + GetClipper,\ + GetColorKey,\ + GetDC,\ + GetFlipStatus,\ + GetOverlayPosition,\ + GetPalette,\ + GetPixelFormat,\ + GetSurfaceDesc,\ + Initialize,\ + IsLost,\ + Lock,\ + ReleaseDC,\ + Restore,\ + SetClipper,\ + SetColorKey,\ + SetOverlayPosition,\ + SetPalette,\ + Unlock,\ + UpdateOverlay,\ + UpdateOverlayDisplay,\ + UpdateOverlayZOrder,\ + GetDDInterface,\ + PageLock,\ + PageUnlock,\ + SetSurfaceDesc,\ + SetPrivateData,\ + GetPrivateData,\ + FreePrivateData,\ + GetUniquenessValue,\ + ChangeUniquenessValue,\ + SetPriority,\ + GetPriority,\ + SetLOD,\ + GetLOD + +interface DirectDrawPalette,\ + QueryInterface,\ + AddRef,\ + Release,\ + GetCaps,\ + GetEntries,\ + Initialize,\ + SetEntries + +interface DirectDrawClipper,\ + QueryInterface,\ + AddRef,\ + Release,\ + GetClipList,\ + GetHWnd,\ + Initialize,\ + IsClipListChanged,\ + SetClipList,\ + SetHWnd + +interface DirectDrawColorControl,\ + QueryInterface,\ + AddRef,\ + Release,\ + GetColorControls,\ + SetColorControls + +interface DirectDrawGammaControl,\ + QueryInterface,\ + AddRef,\ + Release,\ + GetGammaRamp,\ + SetGammaRamp + +struct DDCOLORKEY + dwColorSpaceLowValue dd ? + dwColorSpaceHighValue dd ? +ends + +struct DDPIXELFORMAT + dwSize dd ? + dwFlags dd ? + dwFourCC dd ? + union + dwRGBBitCount dd ? + dwYUVBitCount dd ? + dwZBufferBitDepth dd ? + dwAlphaBitDepth dd ? + dwLuminanceBitCount dd ? + dwBumpBitCount dd ? + ends + union + dwRBitMask dd ? + dwYBitMask dd ? + dwStencilBitDepth dd ? + dwLuminanceBitMask dd ? + dwBumpDuBitMask dd ? + ends + union + dwGBitMask dd ? + dwUBitMask dd ? + dwZBitMask dd ? + dwBumpDvBitMask dd ? + ends + union + dwBBitMask dd ? + dwVBitMask dd ? + dwStencilBitMask dd ? + dwBumpLuminanceBitMask dd ? + ends + union + dwRGBAlphaBitMask dd ? + dwYUVAlphaBitMask dd ? + dwLuminanceAlphaBitMask dd ? + dwRGBZBitMask dd ? + dwYUVZBitMask dd ? + ends +ends + +struct DDSCAPS + dwCaps dd ? +ends + +struct DDSURFACEDESC + dwSize dd ? + dwFlags dd ? + dwHeight dd ? + dwWidth dd ? + union + lPitch dd ? + dwLinearSize dd ? + ends + dwBackBufferCount dd ? + union + dwMipMapCount dd ? + dwZBufferBitDepth dd ? + dwRefreshRate dd ? + ends + dwAlphaBitDepth dd ? + dwReserved dd ? + lpSurface dd ? + ddckCKDestOverlay DDCOLORKEY + ddckCKDestBlt DDCOLORKEY + ddckCKSrcOverlay DDCOLORKEY + ddckCKSrcBlt DDCOLORKEY + ddpfPixelFormat DDPIXELFORMAT + ddsCaps DDSCAPS +ends + +; SetCooperativeLevel flags + +DDSCL_FULLSCREEN = 000000001h +DDSCL_ALLOWREBOOT = 000000002h +DDSCL_NOWINDOWCHANGES = 000000004h +DDSCL_NORMAL = 000000008h +DDSCL_EXCLUSIVE = 000000010h +DDSCL_ALLOWMODEX = 000000040h + +; Blt flags + +DDBLT_ALPHADEST = 000000001h +DDBLT_ALPHADESTCONSTOVERRIDE = 000000002h +DDBLT_ALPHADESTNEG = 000000004h +DDBLT_ALPHADESTSURFACEOVERRIDE = 000000008h +DDBLT_ALPHAEDGEBLEND = 000000010h +DDBLT_ALPHASRC = 000000020h +DDBLT_ALPHASRCCONSTOVERRIDE = 000000040h +DDBLT_ALPHASRCNEG = 000000080h +DDBLT_ALPHASRCSURFACEOVERRIDE = 000000100h +DDBLT_ASYNC = 000000200h +DDBLT_COLORFILL = 000000400h +DDBLT_DDFX = 000000800h +DDBLT_DDROPS = 000001000h +DDBLT_KEYDEST = 000002000h +DDBLT_KEYDESTOVERRIDE = 000004000h +DDBLT_KEYSRC = 000008000h +DDBLT_KEYSRCOVERRIDE = 000010000h +DDBLT_ROP = 000020000h +DDBLT_ROTATIONANGLE = 000040000h +DDBLT_ZBUFFER = 000080000h +DDBLT_ZBUFFERDESTCONSTOVERRIDE = 000100000h +DDBLT_ZBUFFERDESTOVERRIDE = 000200000h +DDBLT_ZBUFFERSRCCONSTOVERRIDE = 000400000h +DDBLT_ZBUFFERSRCOVERRIDE = 000800000h +DDBLT_WAIT = 001000000h +DDBLT_DEPTHFILL = 002000000h + +; BltFast flags + +DDBLTFAST_NOCOLORKEY = 000000000h +DDBLTFAST_SRCCOLORKEY = 000000001h +DDBLTFAST_DESTCOLORKEY = 000000002h +DDBLTFAST_WAIT = 000000010h + +; Flip flags + +DDFLIP_WAIT = 000000001h +DDFLIP_EVEN = 000000002h +DDFLIP_ODD = 000000004h + +; DDSURFACEDESC field flags + +DDSD_CAPS = 000000001h +DDSD_HEIGHT = 000000002h +DDSD_WIDTH = 000000004h +DDSD_PITCH = 000000008h +DDSD_BACKBUFFERCOUNT = 000000020h +DDSD_ZBUFFERBITDEPTH = 000000040h +DDSD_ALPHABITDEPTH = 000000080h +DDSD_LPSURFACE = 000000800h +DDSD_PIXELFORMAT = 000001000h +DDSD_CKDESTOVERLAY = 000002000h +DDSD_CKDESTBLT = 000004000h +DDSD_CKSRCOVERLAY = 000008000h +DDSD_CKSRCBLT = 000010000h +DDSD_MIPMAPCOUNT = 000020000h +DDSD_REFRESHRATE = 000040000h +DDSD_LINEARSIZE = 000080000h +DDSD_ALL = 0000FF9EEh + +; DirectDrawSurface capability flags + +DDSCAPS_RESERVED1 = 000000001h +DDSCAPS_ALPHA = 000000002h +DDSCAPS_BACKBUFFER = 000000004h +DDSCAPS_COMPLEX = 000000008h +DDSCAPS_FLIP = 000000010h +DDSCAPS_FRONTBUFFER = 000000020h +DDSCAPS_OFFSCREENPLAIN = 000000040h +DDSCAPS_OVERLAY = 000000080h +DDSCAPS_PALETTE = 000000100h +DDSCAPS_PRIMARYSURFACE = 000000200h +DDSCAPS_PRIMARYSURFACELEFT = 000000400h +DDSCAPS_SYSTEMMEMORY = 000000800h +DDSCAPS_TEXTURE = 000001000h +DDSCAPS_3DDEVICE = 000002000h +DDSCAPS_VIDEOMEMORY = 000004000h +DDSCAPS_VISIBLE = 000008000h +DDSCAPS_WRITEONLY = 000010000h +DDSCAPS_ZBUFFER = 000020000h +DDSCAPS_OWNDC = 000040000h +DDSCAPS_LIVEVIDEO = 000080000h +DDSCAPS_HWCODEC = 000100000h +DDSCAPS_MODEX = 000200000h +DDSCAPS_MIPMAP = 000400000h +DDSCAPS_RESERVED2 = 000800000h +DDSCAPS_ALLOCONLOAD = 004000000h +DDSCAPS_VIDEOPORT = 008000000h +DDSCAPS_LOCALVIDMEM = 010000000h +DDSCAPS_NONLOCALVIDMEM = 020000000h +DDSCAPS_STANDARDVGAMODE = 040000000h +DDSCAPS_OPTIMIZED = 080000000h + +; DirectDrawSurface lock flags + +DDLOCK_SURFACEMEMORYPTR = 000000000h +DDLOCK_WAIT = 000000001h +DDLOCK_EVENT = 000000002h +DDLOCK_READONLY = 000000010h +DDLOCK_WRITEONLY = 000000020h +DDLOCK_NOSYSLOCK = 000000800h + +; DirectDrawPalette capabilities + +DDPCAPS_4BIT = 000000001h +DDPCAPS_8BITENTRIES = 000000002h +DDPCAPS_8BIT = 000000004h +DDPCAPS_INITIALIZE = 000000008h +DDPCAPS_PRIMARYSURFACE = 000000010h +DDPCAPS_PRIMARYSURFACELEFT = 000000020h +DDPCAPS_ALLOW256 = 000000040h +DDPCAPS_VSYNC = 000000080h +DDPCAPS_1BIT = 000000100h +DDPCAPS_2BIT = 000000200h + +; DirectDraw errors + +DDERR_ALREADYINITIALIZED = 088760000h+5 +DDERR_CANNOTATTACHSURFACE = 088760000h+10 +DDERR_CANNOTDETACHSURFACE = 088760000h+20 +DDERR_CURRENTLYNOTAVAIL = 088760000h+40 +DDERR_EXCEPTION = 088760000h+55 +DDERR_HEIGHTALIGN = 088760000h+90 +DDERR_INCOMPATIBLEPRIMARY = 088760000h+95 +DDERR_INVALIDCAPS = 088760000h+100 +DDERR_INVALIDCLIPLIST = 088760000h+110 +DDERR_INVALIDMODE = 088760000h+120 +DDERR_INVALIDOBJECT = 088760000h+130 +DDERR_INVALIDPIXELFORMAT = 088760000h+145 +DDERR_INVALIDRECT = 088760000h+150 +DDERR_LOCKEDSURFACES = 088760000h+160 +DDERR_NO3D = 088760000h+170 +DDERR_NOALPHAHW = 088760000h+180 +DDERR_NOCLIPLIST = 088760000h+205 +DDERR_NOCOLORCONVHW = 088760000h+210 +DDERR_NOCOOPERATIVELEVELSET = 088760000h+212 +DDERR_NOCOLORKEY = 088760000h+215 +DDERR_NOCOLORKEYHW = 088760000h+220 +DDERR_NODIRECTDRAWSUPPORT = 088760000h+222 +DDERR_NOEXCLUSIVEMODE = 088760000h+225 +DDERR_NOFLIPHW = 088760000h+230 +DDERR_NOGDI = 088760000h+240 +DDERR_NOMIRRORHW = 088760000h+250 +DDERR_NOTFOUND = 088760000h+255 +DDERR_NOOVERLAYHW = 088760000h+260 +DDERR_NORASTEROPHW = 088760000h+280 +DDERR_NOROTATIONHW = 088760000h+290 +DDERR_NOSTRETCHHW = 088760000h+310 +DDERR_NOT4BITCOLOR = 088760000h+316 +DDERR_NOT4BITCOLORINDEX = 088760000h+317 +DDERR_NOT8BITCOLOR = 088760000h+320 +DDERR_NOTEXTUREHW = 088760000h+330 +DDERR_NOVSYNCHW = 088760000h+335 +DDERR_NOZBUFFERHW = 088760000h+340 +DDERR_NOZOVERLAYHW = 088760000h+350 +DDERR_OUTOFCAPS = 088760000h+360 +DDERR_OUTOFVIDEOMEMORY = 088760000h+380 +DDERR_OVERLAYCANTCLIP = 088760000h+382 +DDERR_OVERLAYCOLORKEYONLYONEACTI = 088760000h+384 +DDERR_PALETTEBUSY = 088760000h+387 +DDERR_COLORKEYNOTSET = 088760000h+400 +DDERR_SURFACEALREADYATTACHED = 088760000h+410 +DDERR_SURFACEALREADYDEPENDENT = 088760000h+420 +DDERR_SURFACEBUSY = 088760000h+430 +DDERR_CANTLOCKSURFACE = 088760000h+435 +DDERR_SURFACEISOBSCURED = 088760000h+440 +DDERR_SURFACELOST = 088760000h+450 +DDERR_SURFACENOTATTACHED = 088760000h+460 +DDERR_TOOBIGHEIGHT = 088760000h+470 +DDERR_TOOBIGSIZE = 088760000h+480 +DDERR_TOOBIGWIDTH = 088760000h+490 +DDERR_UNSUPPORTEDFORMAT = 088760000h+510 +DDERR_UNSUPPORTEDMASK = 088760000h+520 +DDERR_VERTICALBLANKINPROGRESS = 088760000h+537 +DDERR_WASSTILLDRAWING = 088760000h+540 +DDERR_XALIGN = 088760000h+560 +DDERR_INVALIDDIRECTDRAWGUID = 088760000h+561 +DDERR_DIRECTDRAWALREADYCREATED = 088760000h+562 +DDERR_NODIRECTDRAWHW = 088760000h+563 +DDERR_PRIMARYSURFACEALREADYEXIST = 088760000h+564 +DDERR_NOEMULATION = 088760000h+565 +DDERR_REGIONTOOSMALL = 088760000h+566 +DDERR_CLIPPERISUSINGHWND = 088760000h+567 +DDERR_NOCLIPPERATTACHED = 088760000h+568 +DDERR_NOHWND = 088760000h+569 +DDERR_HWNDSUBCLASSED = 088760000h+570 +DDERR_HWNDALREADYSET = 088760000h+571 +DDERR_NOPALETTEATTACHED = 088760000h+572 +DDERR_NOPALETTEHW = 088760000h+573 +DDERR_BLTFASTCANTCLIP = 088760000h+574 +DDERR_NOBLTHW = 088760000h+575 +DDERR_NODDROPSHW = 088760000h+576 +DDERR_OVERLAYNOTVISIBLE = 088760000h+577 +DDERR_NOOVERLAYDEST = 088760000h+578 +DDERR_INVALIDPOSITION = 088760000h+579 +DDERR_NOTAOVERLAYSURFACE = 088760000h+580 +DDERR_EXCLUSIVEMODEALREADYSET = 088760000h+581 +DDERR_NOTFLIPPABLE = 088760000h+582 +DDERR_CANTDUPLICATE = 088760000h+583 +DDERR_NOTLOCKED = 088760000h+584 +DDERR_CANTCREATEDC = 088760000h+585 +DDERR_NODC = 088760000h+586 +DDERR_WRONGMODE = 088760000h+587 +DDERR_IMPLICITLYCREATED = 088760000h+588 +DDERR_NOTPALETTIZED = 088760000h+589 +DDERR_UNSUPPORTEDMODE = 088760000h+590 +DDERR_NOMIPMAPHW = 088760000h+591 +DDERR_INVALIDSURFACETYPE = 088760000h+592 +DDERR_NOOPTIMIZEHW = 088760000h+600 +DDERR_NOTLOADED = 088760000h+601 +DDERR_DCALREADYCREATED = 088760000h+620 +DDERR_NONONLOCALVIDMEM = 088760000h+630 +DDERR_CANTPAGELOCK = 088760000h+640 +DDERR_CANTPAGEUNLOCK = 088760000h+660 +DDERR_NOTPAGELOCKED = 088760000h+680 +DDERR_MOREDATA = 088760000h+690 +DDERR_VIDEONOTACTIVE = 088760000h+695 +DDERR_DEVICEDOESNTOWNSURFACE = 088760000h+699 diff --git a/toolchain/fasmw17332/EXAMPLES/DDRAW/GIF87A.INC b/toolchain/fasmw17332/EXAMPLES/DDRAW/GIF87A.INC new file mode 100644 index 0000000..1cdd969 --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/DDRAW/GIF87A.INC @@ -0,0 +1,196 @@ + +virtual at buffer + GIFHEADER: + .ID dd ? + .ver dw ? + .width dw ? + .height dw ? + .bits db ? + .background db ? + .reserved db ? + .length = $ - GIFHEADER +end virtual + +load_picture: + + invoke CreateFileA,esi,GENERIC_READ,0,0,OPEN_EXISTING,0,0 + mov edi,eax + invoke ReadFile,edi,GIFHEADER,40000h,bytes_count,0 + invoke CloseHandle,edi + + cmp [GIFHEADER.ID],'GIF8' + jne picture_error + cmp [GIFHEADER.ver],'7a' + jne picture_error + + mov al,[GIFHEADER.bits] + and al,10000111b + cmp al,10000111b + jne picture_error + + add [bytes_count],buffer + + mov esi,buffer+GIFHEADER.length+256*3 + mov edi,esi + + xor eax,eax + find_image: + cmp esi,[bytes_count] + jae picture_error + lodsb + cmp al,',' + je image_found + cmp al,'!' + jne picture_error + inc esi + skip_application_data: + lodsb + add esi,eax + or al,al + jnz skip_application_data + jmp find_image + image_found: + add esi,4 + xor eax,eax + lodsw + mov ebx,eax + lodsw + inc esi + cmp byte [esi],8 + jne picture_error + inc esi + + mov [ddsd.dwSize],sizeof.DDSURFACEDESC + mov [ddsd.dwFlags],DDSD_CAPS+DDSD_WIDTH+DDSD_HEIGHT+DDSD_CKSRCBLT + mov [ddsd.ddsCaps.dwCaps],DDSCAPS_OFFSCREENPLAIN+DDSCAPS_SYSTEMMEMORY + mov [ddsd.dwWidth],ebx + mov [ddsd.dwHeight],eax + movzx eax,[GIFHEADER.background] + mov [ddsd.ddckCKSrcBlt.dwColorSpaceLowValue],eax + mov [ddsd.ddckCKSrcBlt.dwColorSpaceHighValue],eax + cominvk DDraw,CreateSurface,\ + ddsd,DDSPicture,0 + or eax,eax + jnz picture_error + cominvk DDSPicture,Lock,\ + 0,ddsd,DDLOCK_WAIT,0 + + mov edi,[ddsd.lpSurface] + mov ebx,esi + movzx ebp,byte [ebx] + inc ebx + add ebp,ebx + mov [LZW_bits],0 + LZW_clear: + xor edx,edx + LZW_decompress_loop: + mov ch,9 + cmp edx,(100h-2)*8 + jbe LZW_read_bits + mov ch,10 + cmp edx,(300h-2)*8 + jbe LZW_read_bits + mov ch,11 + cmp edx,(700h-2)*8 + jbe LZW_read_bits + mov ch,12 + LZW_read_bits: + mov cl,8 + sub cl,[LZW_bits] + LZW_byte_from_stream: + mov al,[ebx] + cmp ebx,ebp + jne LZW_bits_from_byte + movzx ebp,al + inc ebx + mov al,[ebx] + add ebp,ebx + LZW_bits_from_byte: + inc ebx + ror eax,8 + sub cl,ch + jz LZW_bits_ready + ja LZW_bits_with_tail + add cl,ch + add cl,8 + jmp LZW_byte_from_stream + LZW_bits_with_tail: + dec ebx + shl eax,cl + LZW_bits_ready: + neg cl + and cl,7 + mov [LZW_bits],cl + mov cl,ch + rol eax,cl + and eax,0FFFh + cmp eax,100h + jb LZW_single_byte + je LZW_clear + sub eax,102h + jc LZW_end + shl eax,3 + cmp eax,edx + ja picture_error + mov ecx,[LZW_table+eax] + mov esi,[LZW_table+eax+4] + mov [LZW_table+edx+4],edi + rep movsb + mov eax,[LZW_table+eax] + inc eax + mov [LZW_table+edx],eax + jmp LZW_decompress_next + LZW_single_byte: + mov [LZW_table+edx],2 + mov [LZW_table+edx+4],edi + stosb + LZW_decompress_next: + add edx,8 + jmp LZW_decompress_loop + LZW_end: + + cominvk DDSPicture,Unlock,0 + + mov eax,[DDSPicture] + clc + ret + + picture_error: + stc + ret + +load_palette: + + invoke CreateFileA,esi,GENERIC_READ,0,0,OPEN_EXISTING,0,0 + mov edi,eax + invoke ReadFile,edi,buffer,GIFHEADER.length+256*3,bytes_count,0 + cmp [bytes_count],GIFHEADER.length+256*3 + jne picture_error + invoke CloseHandle,edi + + cmp [GIFHEADER.ID],'GIF8' + jne picture_error + cmp [GIFHEADER.ver],'7a' + jne picture_error + mov al,[GIFHEADER.bits] + and al,111b + cmp al,111b + jne picture_error + + mov esi,buffer+GIFHEADER.length + mov edi,buffer+400h + mov ecx,256 + convert_palette: + movsw + movsb + xor al,al + stosb + loop convert_palette + + cominvk DDraw,CreatePalette,\ + DDPCAPS_8BIT+DDPCAPS_ALLOW256,buffer+400h,DDPalette,0 + or eax,eax + jnz picture_error + + clc + ret diff --git a/toolchain/fasmw17332/EXAMPLES/DIALOG/DIALOG.ASM b/toolchain/fasmw17332/EXAMPLES/DIALOG/DIALOG.ASM new file mode 100644 index 0000000..b7c8199 --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/DIALOG/DIALOG.ASM @@ -0,0 +1,130 @@ + +; DialogBox example + +format PE GUI 4.0 +entry start + +include 'win32a.inc' + +ID_CAPTION = 101 +ID_MESSAGE = 102 +ID_ICONERROR = 201 +ID_ICONINFORMATION = 202 +ID_ICONQUESTION = 203 +ID_ICONWARNING = 204 +ID_TOPMOST = 301 + +section '.text' code readable executable + + start: + + invoke GetModuleHandle,0 + invoke DialogBoxParam,eax,37,HWND_DESKTOP,DialogProc,0 + or eax,eax + jz exit + invoke MessageBox,HWND_DESKTOP,message,caption,[flags] + exit: + invoke ExitProcess,0 + +proc DialogProc hwnddlg,msg,wparam,lparam + push ebx esi edi + cmp [msg],WM_INITDIALOG + je .wminitdialog + cmp [msg],WM_COMMAND + je .wmcommand + cmp [msg],WM_CLOSE + je .wmclose + xor eax,eax + jmp .finish + .wminitdialog: + invoke CheckRadioButton,[hwnddlg],ID_ICONERROR,ID_ICONWARNING,ID_ICONINFORMATION + jmp .processed + .wmcommand: + cmp [wparam],BN_CLICKED shl 16 + IDCANCEL + je .wmclose + cmp [wparam],BN_CLICKED shl 16 + IDOK + jne .processed + invoke GetDlgItemText,[hwnddlg],ID_CAPTION,caption,40h + invoke GetDlgItemText,[hwnddlg],ID_MESSAGE,message,100h + mov [flags],MB_OK + invoke IsDlgButtonChecked,[hwnddlg],ID_ICONERROR + cmp eax,BST_CHECKED + jne .iconerror_ok + or [flags],MB_ICONERROR + .iconerror_ok: + invoke IsDlgButtonChecked,[hwnddlg],ID_ICONINFORMATION + cmp eax,BST_CHECKED + jne .iconinformation_ok + or [flags],MB_ICONINFORMATION + .iconinformation_ok: + invoke IsDlgButtonChecked,[hwnddlg],ID_ICONQUESTION + cmp eax,BST_CHECKED + jne .iconquestion_ok + or [flags],MB_ICONQUESTION + .iconquestion_ok: + invoke IsDlgButtonChecked,[hwnddlg],ID_ICONWARNING + cmp eax,BST_CHECKED + jne .iconwarning_ok + or [flags],MB_ICONWARNING + .iconwarning_ok: + invoke IsDlgButtonChecked,[hwnddlg],ID_TOPMOST + cmp eax,BST_CHECKED + jne .topmost_ok + or [flags],MB_TOPMOST + .topmost_ok: + invoke EndDialog,[hwnddlg],1 + jmp .processed + .wmclose: + invoke EndDialog,[hwnddlg],0 + .processed: + mov eax,1 + .finish: + pop edi esi ebx + ret +endp + +section '.bss' readable writeable + + flags dd ? + caption rb 40h + message rb 100h + +section '.idata' import data readable writeable + + library kernel,'KERNEL32.DLL',\ + user,'USER32.DLL' + + import kernel,\ + GetModuleHandle,'GetModuleHandleA',\ + ExitProcess,'ExitProcess' + + import user,\ + DialogBoxParam,'DialogBoxParamA',\ + CheckRadioButton,'CheckRadioButton',\ + GetDlgItemText,'GetDlgItemTextA',\ + IsDlgButtonChecked,'IsDlgButtonChecked',\ + MessageBox,'MessageBoxA',\ + EndDialog,'EndDialog' + +section '.rsrc' resource data readable + + directory RT_DIALOG,dialogs + + resource dialogs,\ + 37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration + + dialog demonstration,'Create message box',70,70,190,175,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'STATIC','&Caption:',-1,10,10,70,8,WS_VISIBLE + dialogitem 'EDIT','',ID_CAPTION,10,20,170,13,WS_VISIBLE+WS_BORDER+WS_TABSTOP + dialogitem 'STATIC','&Message:',-1,10,40,70,8,WS_VISIBLE + dialogitem 'EDIT','',ID_MESSAGE,10,50,170,13,WS_VISIBLE+WS_BORDER+WS_TABSTOP+ES_AUTOHSCROLL + dialogitem 'BUTTON','&Icon',-1,10,70,80,70,WS_VISIBLE+BS_GROUPBOX + dialogitem 'BUTTON','&Error',ID_ICONERROR,20,82,60,13,WS_VISIBLE+BS_AUTORADIOBUTTON+WS_TABSTOP+WS_GROUP + dialogitem 'BUTTON','I&nformation',ID_ICONINFORMATION,20,95,60,13,WS_VISIBLE+BS_AUTORADIOBUTTON + dialogitem 'BUTTON','&Question',ID_ICONQUESTION,20,108,60,13,WS_VISIBLE+BS_AUTORADIOBUTTON + dialogitem 'BUTTON','&Warning',ID_ICONWARNING,20,121,60,13,WS_VISIBLE+BS_AUTORADIOBUTTON + dialogitem 'BUTTON','&Style',-1,100,70,80,70,WS_VISIBLE+BS_GROUPBOX + dialogitem 'BUTTON','&Top most',ID_TOPMOST,110,82,60,13,WS_VISIBLE+WS_TABSTOP+BS_AUTOCHECKBOX + dialogitem 'BUTTON','OK',IDOK,85,150,45,15,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON + dialogitem 'BUTTON','C&ancel',IDCANCEL,135,150,45,15,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON + enddialog diff --git a/toolchain/fasmw17332/EXAMPLES/DLL/ERRORMSG.ASM b/toolchain/fasmw17332/EXAMPLES/DLL/ERRORMSG.ASM new file mode 100644 index 0000000..3ac3992 --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/DLL/ERRORMSG.ASM @@ -0,0 +1,59 @@ + +; DLL creation example + +format PE GUI 4.0 DLL +entry DllEntryPoint + +include 'win32a.inc' + +section '.text' code readable executable + +proc DllEntryPoint hinstDLL,fdwReason,lpvReserved + mov eax,TRUE + ret +endp + +; VOID ShowErrorMessage(HWND hWnd,DWORD dwError); + +proc ShowErrorMessage hWnd,dwError + local lpBuffer:DWORD + lea eax,[lpBuffer] + invoke FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER+FORMAT_MESSAGE_FROM_SYSTEM,0,[dwError],LANG_NEUTRAL,eax,0,0 + invoke MessageBox,[hWnd],[lpBuffer],NULL,MB_ICONERROR+MB_OK + invoke LocalFree,[lpBuffer] + ret +endp + +; VOID ShowLastError(HWND hWnd); + +proc ShowLastError hWnd + invoke GetLastError + stdcall ShowErrorMessage,[hWnd],eax + ret +endp + +section '.idata' import data readable writeable + + library kernel,'KERNEL32.DLL',\ + user,'USER32.DLL' + + import kernel,\ + GetLastError,'GetLastError',\ + SetLastError,'SetLastError',\ + FormatMessage,'FormatMessageA',\ + LocalFree,'LocalFree' + + import user,\ + MessageBox,'MessageBoxA' + +section '.edata' export data readable + + export 'ERRORMSG.DLL',\ + ShowErrorMessage,'ShowErrorMessage',\ + ShowLastError,'ShowLastError' + +section '.reloc' fixups data readable discardable + + if $=$$ + dd 0,8 ; if there are no fixups, generate dummy entry + end if diff --git a/toolchain/fasmw17332/EXAMPLES/DLL/LASTERR.ASM b/toolchain/fasmw17332/EXAMPLES/DLL/LASTERR.ASM new file mode 100644 index 0000000..5ada46c --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/DLL/LASTERR.ASM @@ -0,0 +1,24 @@ + +format PE GUI 4.0 +entry start + +include 'win32a.inc' + +section '.text' code readable executable + + start: + invoke SetLastError,0 + invoke ShowLastError,HWND_DESKTOP + invoke ExitProcess,0 + +section '.idata' import data readable writeable + + library kernel,'KERNEL32.DLL',\ + errormsg,'ERRORMSG.DLL' + + import kernel,\ + SetLastError,'SetLastError',\ + ExitProcess,'ExitProcess' + + import errormsg,\ + ShowLastError,'ShowLastError' diff --git a/toolchain/fasmw17332/EXAMPLES/HELLO/HELLO.ASM b/toolchain/fasmw17332/EXAMPLES/HELLO/HELLO.ASM new file mode 100644 index 0000000..341cb6d --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/HELLO/HELLO.ASM @@ -0,0 +1,18 @@ + +; example of simplified Windows programming using complex macro features + +include 'win32ax.inc' ; you can simply switch between win32ax, win32wx, win64ax and win64wx here + +.code + + start: + + invoke MessageBox,HWND_DESKTOP,"May I introduce myself?",invoke GetCommandLine,MB_YESNO + + .if eax = IDYES + invoke MessageBox,HWND_DESKTOP,"Hi! I'm the example program!","Hello!",MB_OK + .endif + + invoke ExitProcess,0 + +.end start diff --git a/toolchain/fasmw17332/EXAMPLES/MINIPAD/MINIPAD.ASM b/toolchain/fasmw17332/EXAMPLES/MINIPAD/MINIPAD.ASM new file mode 100644 index 0000000..72a89d4 --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/MINIPAD/MINIPAD.ASM @@ -0,0 +1,206 @@ + +; Simple text editor - fasm example program + +format PE GUI 4.0 +entry start + +include 'win32a.inc' + +IDR_ICON = 17 +IDR_MENU = 37 + +IDM_NEW = 101 +IDM_EXIT = 102 +IDM_ABOUT = 901 + +section '.text' code readable executable + + start: + + invoke GetModuleHandle,0 + mov [wc.hInstance],eax + + invoke LoadIcon,eax,IDR_ICON + mov [wc.hIcon],eax + invoke LoadCursor,0,IDC_ARROW + mov [wc.hCursor],eax + invoke RegisterClass,wc + test eax,eax + jz error + + invoke LoadMenu,[wc.hInstance],IDR_MENU + invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW,144,128,256,256,NULL,eax,[wc.hInstance],NULL + test eax,eax + jz error + + msg_loop: + invoke GetMessage,msg,NULL,0,0 + cmp eax,1 + jb end_loop + jne msg_loop + invoke TranslateMessage,msg + invoke DispatchMessage,msg + jmp msg_loop + + error: + invoke MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK + + end_loop: + invoke ExitProcess,[msg.wParam] + +proc WindowProc hwnd,wmsg,wparam,lparam + push ebx esi edi + mov eax,[wmsg] + cmp eax,WM_CREATE + je .wmcreate + cmp eax,WM_SIZE + je .wmsize + cmp eax,WM_SETFOCUS + je .wmsetfocus + cmp eax,WM_COMMAND + je .wmcommand + cmp eax,WM_DESTROY + je .wmdestroy + .defwndproc: + invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] + jmp .finish + .wmcreate: + invoke GetClientRect,[hwnd],client + invoke CreateWindowEx,WS_EX_CLIENTEDGE,_edit,0,WS_VISIBLE+WS_CHILD+WS_HSCROLL+WS_VSCROLL+ES_AUTOHSCROLL+ES_AUTOVSCROLL+ES_MULTILINE,[client.left],[client.top],[client.right],[client.bottom],[hwnd],0,[wc.hInstance],NULL + or eax,eax + jz .failed + mov [edithwnd],eax + invoke CreateFont,16,0,0,0,0,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_RASTER_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL + or eax,eax + jz .failed + mov [editfont],eax + invoke SendMessage,[edithwnd],WM_SETFONT,eax,FALSE + xor eax,eax + jmp .finish + .failed: + or eax,-1 + jmp .finish + .wmsize: + invoke GetClientRect,[hwnd],client + invoke MoveWindow,[edithwnd],[client.left],[client.top],[client.right],[client.bottom],TRUE + xor eax,eax + jmp .finish + .wmsetfocus: + invoke SetFocus,[edithwnd] + xor eax,eax + jmp .finish + .wmcommand: + mov eax,[wparam] + and eax,0FFFFh + cmp eax,IDM_NEW + je .new + cmp eax,IDM_ABOUT + je .about + cmp eax,IDM_EXIT + je .wmdestroy + jmp .defwndproc + .new: + invoke SendMessage,[edithwnd],WM_SETTEXT,0,0 + jmp .finish + .about: + invoke MessageBox,[hwnd],_about_text,_about_title,MB_OK + jmp .finish + .wmdestroy: + invoke DeleteObject,[editfont] + invoke PostQuitMessage,0 + xor eax,eax + .finish: + pop edi esi ebx + ret +endp + +section '.data' data readable writeable + + _title TCHAR 'MiniPad',0 + _about_title TCHAR 'About MiniPad',0 + _about_text TCHAR 'This is Win32 example program created with flat assembler.',0 + _error TCHAR 'Startup failed.',0 + + _class TCHAR 'MINIPAD32',0 + _edit TCHAR 'EDIT',0 + + wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class + + edithwnd dd ? + editfont dd ? + + msg MSG + client RECT + +section '.idata' import data readable writeable + + library kernel,'KERNEL32.DLL',\ + user,'USER32.DLL',\ + gdi,'GDI32.DLL' + + import kernel,\ + GetModuleHandle,'GetModuleHandleA',\ + ExitProcess,'ExitProcess' + + import user,\ + RegisterClass,'RegisterClassA',\ + CreateWindowEx,'CreateWindowExA',\ + DefWindowProc,'DefWindowProcA',\ + SetWindowLong,'SetWindowLongA',\ + RedrawWindow,'RedrawWindow',\ + GetMessage,'GetMessageA',\ + TranslateMessage,'TranslateMessage',\ + DispatchMessage,'DispatchMessageA',\ + SendMessage,'SendMessageA',\ + LoadCursor,'LoadCursorA',\ + LoadIcon,'LoadIconA',\ + LoadMenu,'LoadMenuA',\ + GetClientRect,'GetClientRect',\ + MoveWindow,'MoveWindow',\ + SetFocus,'SetFocus',\ + MessageBox,'MessageBoxA',\ + PostQuitMessage,'PostQuitMessage' + + import gdi,\ + CreateFont,'CreateFontA',\ + DeleteObject,'DeleteObject' + +section '.rsrc' resource data readable + + ; resource directory + + directory RT_MENU,menus,\ + RT_ICON,icons,\ + RT_GROUP_ICON,group_icons,\ + RT_VERSION,versions + + ; resource subdirectories + + resource menus,\ + IDR_MENU,LANG_ENGLISH+SUBLANG_DEFAULT,main_menu + + resource icons,\ + 1,LANG_NEUTRAL,icon_data + + resource group_icons,\ + IDR_ICON,LANG_NEUTRAL,main_icon + + resource versions,\ + 1,LANG_NEUTRAL,version + + menu main_menu + menuitem '&File',0,MFR_POPUP + menuitem '&New',IDM_NEW + menuseparator + menuitem 'E&xit',IDM_EXIT,MFR_END + menuitem '&Help',0,MFR_POPUP + MFR_END + menuitem '&About...',IDM_ABOUT,MFR_END + + icon main_icon,icon_data,'minipad.ico' + + versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,\ + 'FileDescription','MiniPad - example program',\ + 'LegalCopyright','No rights reserved.',\ + 'FileVersion','1.0',\ + 'ProductVersion','1.0',\ + 'OriginalFilename','MINIPAD.EXE' diff --git a/toolchain/fasmw17332/EXAMPLES/MINIPAD/MINIPAD.ICO b/toolchain/fasmw17332/EXAMPLES/MINIPAD/MINIPAD.ICO new file mode 100644 index 0000000..ef8e482 Binary files /dev/null and b/toolchain/fasmw17332/EXAMPLES/MINIPAD/MINIPAD.ICO differ diff --git a/toolchain/fasmw17332/EXAMPLES/MSCOFF/MSCOFF.ASM b/toolchain/fasmw17332/EXAMPLES/MSCOFF/MSCOFF.ASM new file mode 100644 index 0000000..b7810fb --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/MSCOFF/MSCOFF.ASM @@ -0,0 +1,23 @@ + +; example of making Win32 COFF object file + +format MS COFF + +extrn '__imp__MessageBoxA@16' as MessageBox:dword + +section '.text' code readable executable + + public _demo + + _demo: + push 0 + push _caption + push _message + push 0 + call [MessageBox] + ret + +section '.data' data readable writeable + + _caption db 'Win32 assembly',0 + _message db 'Coffee time!',0 diff --git a/toolchain/fasmw17332/EXAMPLES/OPENGL/OPENGL.ASM b/toolchain/fasmw17332/EXAMPLES/OPENGL/OPENGL.ASM new file mode 100644 index 0000000..0f9f298 --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/OPENGL/OPENGL.ASM @@ -0,0 +1,614 @@ + +; OpenGL programming example + +format PE GUI 4.0 +entry start + +include 'win32a.inc' + +include 'opengl.inc' + +section '.text' code readable executable + + start: + + invoke GetModuleHandle,0 + mov [wc.hInstance],eax + invoke LoadIcon,0,IDI_APPLICATION + mov [wc.hIcon],eax + invoke LoadCursor,0,IDC_ARROW + mov [wc.hCursor],eax + invoke RegisterClass,wc + invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS,16,16,432,432,NULL,NULL,[wc.hInstance],NULL + mov [hwnd],eax + + msg_loop: + invoke GetMessage,msg,NULL,0,0 + or eax,eax + jz end_loop + invoke TranslateMessage,msg + invoke DispatchMessage,msg + jmp msg_loop + + end_loop: + invoke ExitProcess,[msg.wParam] + +proc WindowProc hwnd,wmsg,wparam,lparam + push ebx esi edi + cmp [wmsg],WM_CREATE + je .wmcreate + cmp [wmsg],WM_SIZE + je .wmsize + cmp [wmsg],WM_PAINT + je .wmpaint + cmp [wmsg],WM_KEYDOWN + je .wmkeydown + cmp [wmsg],WM_DESTROY + je .wmdestroy + .defwndproc: + invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] + jmp .finish + .wmcreate: + invoke GetDC,[hwnd] + mov [hdc],eax + mov edi,pfd + mov ecx,sizeof.PIXELFORMATDESCRIPTOR shr 2 + xor eax,eax + rep stosd + mov [pfd.nSize],sizeof.PIXELFORMATDESCRIPTOR + mov [pfd.nVersion],1 + mov [pfd.dwFlags],PFD_SUPPORT_OPENGL+PFD_DOUBLEBUFFER+PFD_DRAW_TO_WINDOW + mov [pfd.iLayerType],PFD_MAIN_PLANE + mov [pfd.iPixelType],PFD_TYPE_RGBA + mov [pfd.cColorBits],16 + mov [pfd.cDepthBits],16 + mov [pfd.cAccumBits],0 + mov [pfd.cStencilBits],0 + invoke ChoosePixelFormat,[hdc],pfd + invoke SetPixelFormat,[hdc],eax,pfd + invoke wglCreateContext,[hdc] + mov [hrc],eax + invoke wglMakeCurrent,[hdc],[hrc] + invoke GetClientRect,[hwnd],rc + invoke glViewport,0,0,[rc.right],[rc.bottom] + invoke GetTickCount + mov [clock],eax + xor eax,eax + jmp .finish + .wmsize: + invoke GetClientRect,[hwnd],rc + invoke glViewport,0,0,[rc.right],[rc.bottom] + xor eax,eax + jmp .finish + .wmpaint: + invoke GetTickCount + sub eax,[clock] + cmp eax,10 + jb .animation_ok + add [clock],eax + invoke glRotatef,[theta],0.0,0.0,1.0 + .animation_ok: + invoke glClear,GL_COLOR_BUFFER_BIT + invoke glBegin,GL_QUADS + invoke glColor3f,1.0,0.1,0.1 + invoke glVertex3f,-0.6,-0.6,0.0 + invoke glColor3f,0.1,0.1,0.1 + invoke glVertex3f,0.6,-0.6,0.0 + invoke glColor3f,0.1,0.1,1.0 + invoke glVertex3f,0.6,0.6,0.0 + invoke glColor3f,1.0,0.1,1.0 + invoke glVertex3f,-0.6,0.6,0.0 + invoke glEnd + invoke SwapBuffers,[hdc] + xor eax,eax + jmp .finish + .wmkeydown: + cmp [wparam],VK_ESCAPE + jne .defwndproc + .wmdestroy: + invoke wglMakeCurrent,0,0 + invoke wglDeleteContext,[hrc] + invoke ReleaseDC,[hwnd],[hdc] + invoke PostQuitMessage,0 + xor eax,eax + .finish: + pop edi esi ebx + ret +endp + +section '.data' data readable writeable + + _title db 'OpenGL example',0 + _class db 'FASMOPENGL32',0 + + theta GLfloat 0.6 + + wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,NULL,NULL,_class + + hwnd dd ? + hdc dd ? + hrc dd ? + + msg MSG + rc RECT + pfd PIXELFORMATDESCRIPTOR + + clock dd ? + +section '.idata' import data readable writeable + + library kernel,'KERNEL32.DLL',\ + user,'USER32.DLL',\ + gdi,'GDI32.DLL',\ + opengl,'OPENGL32.DLL',\ + glu,'GLU32.DLL' + + import kernel,\ + GetModuleHandle,'GetModuleHandleA',\ + GetTickCount,'GetTickCount',\ + ExitProcess,'ExitProcess' + + import user,\ + RegisterClass,'RegisterClassA',\ + CreateWindowEx,'CreateWindowExA',\ + DefWindowProc,'DefWindowProcA',\ + GetMessage,'GetMessageA',\ + TranslateMessage,'TranslateMessage',\ + DispatchMessage,'DispatchMessageA',\ + LoadCursor,'LoadCursorA',\ + LoadIcon,'LoadIconA',\ + GetClientRect,'GetClientRect',\ + GetDC,'GetDC',\ + ReleaseDC,'ReleaseDC',\ + PostQuitMessage,'PostQuitMessage' + + import gdi,\ + ChoosePixelFormat,'ChoosePixelFormat',\ + SetPixelFormat,'SetPixelFormat',\ + SwapBuffers,'SwapBuffers' + + import opengl,\ + glAccum,'glAccum',\ + glAlphaFunc,'glAlphaFunc',\ + glAreTexturesResident,'glAreTexturesResident',\ + glArrayElement,'glArrayElement',\ + glBegin,'glBegin',\ + glBindTexture,'glBindTexture',\ + glBitmap,'glBitmap',\ + glBlendFunc,'glBlendFunc',\ + glCallList,'glCallList',\ + glCallLists,'glCallLists',\ + glClear,'glClear',\ + glClearAccum,'glClearAccum',\ + glClearColor,'glClearColor',\ + glClearDepth,'glClearDepth',\ + glClearIndex,'glClearIndex',\ + glClearStencil,'glClearStencil',\ + glClipPlane,'glClipPlane',\ + glColor3b,'glColor3b',\ + glColor3bv,'glColor3bv',\ + glColor3d,'glColor3d',\ + glColor3dv,'glColor3dv',\ + glColor3f,'glColor3f',\ + glColor3fv,'glColor3fv',\ + glColor3i,'glColor3i',\ + glColor3iv,'glColor3iv',\ + glColor3s,'glColor3s',\ + glColor3sv,'glColor3sv',\ + glColor3ub,'glColor3ub',\ + glColor3ubv,'glColor3ubv',\ + glColor3ui,'glColor3ui',\ + glColor3uiv,'glColor3uiv',\ + glColor3us,'glColor3us',\ + glColor3usv,'glColor3usv',\ + glColor4b,'glColor4b',\ + glColor4bv,'glColor4bv',\ + glColor4d,'glColor4d',\ + glColor4dv,'glColor4dv',\ + glColor4f,'glColor4f',\ + glColor4fv,'glColor4fv',\ + glColor4i,'glColor4i',\ + glColor4iv,'glColor4iv',\ + glColor4s,'glColor4s',\ + glColor4sv,'glColor4sv',\ + glColor4ub,'glColor4ub',\ + glColor4ubv,'glColor4ubv',\ + glColor4ui,'glColor4ui',\ + glColor4uiv,'glColor4uiv',\ + glColor4us,'glColor4us',\ + glColor4usv,'glColor4usv',\ + glColorMask,'glColorMask',\ + glColorMaterial,'glColorMaterial',\ + glColorPointer,'glColorPointer',\ + glCopyPixels,'glCopyPixels',\ + glCopyTexImage1D,'glCopyTexImage1D',\ + glCopyTexImage2D,'glCopyTexImage2D',\ + glCopyTexSubImage1D,'glCopyTexSubImage1D',\ + glCopyTexSubImage2D,'glCopyTexSubImage2D',\ + glCullFace,'glCullFace',\ + glDeleteLists,'glDeleteLists',\ + glDeleteTextures,'glDeleteTextures',\ + glDepthFunc,'glDepthFunc',\ + glDepthMask,'glDepthMask',\ + glDepthRange,'glDepthRange',\ + glDisable,'glDisable',\ + glDisableClientState,'glDisableClientState',\ + glDrawArrays,'glDrawArrays',\ + glDrawBuffer,'glDrawBuffer',\ + glDrawElements,'glDrawElements',\ + glDrawPixels,'glDrawPixels',\ + glEdgeFlag,'glEdgeFlag',\ + glEdgeFlagPointer,'glEdgeFlagPointer',\ + glEdgeFlagv,'glEdgeFlagv',\ + glEnable,'glEnable',\ + glEnableClientState,'glEnableClientState',\ + glEnd,'glEnd',\ + glEndList,'glEndList',\ + glEvalCoord1d,'glEvalCoord1d',\ + glEvalCoord1dv,'glEvalCoord1dv',\ + glEvalCoord1f,'glEvalCoord1f',\ + glEvalCoord1fv,'glEvalCoord1fv',\ + glEvalCoord2d,'glEvalCoord2d',\ + glEvalCoord2dv,'glEvalCoord2dv',\ + glEvalCoord2f,'glEvalCoord2f',\ + glEvalCoord2fv,'glEvalCoord2fv',\ + glEvalMesh1,'glEvalMesh1',\ + glEvalMesh2,'glEvalMesh2',\ + glEvalPoint1,'glEvalPoint1',\ + glEvalPoint2,'glEvalPoint2',\ + glFeedbackBuffer,'glFeedbackBuffer',\ + glFinish,'glFinish',\ + glFlush,'glFlush',\ + glFogf,'glFogf',\ + glFogfv,'glFogfv',\ + glFogi,'glFogi',\ + glFogiv,'glFogiv',\ + glFrontFace,'glFrontFace',\ + glFrustum,'glFrustum',\ + glGenLists,'glGenLists',\ + glGenTextures,'glGenTextures',\ + glGetBooleanv,'glGetBooleanv',\ + glGetClipPlane,'glGetClipPlane',\ + glGetDoublev,'glGetDoublev',\ + glGetError,'glGetError',\ + glGetFloatv,'glGetFloatv',\ + glGetIntegerv,'glGetIntegerv',\ + glGetLightfv,'glGetLightfv',\ + glGetLightiv,'glGetLightiv',\ + glGetMapdv,'glGetMapdv',\ + glGetMapfv,'glGetMapfv',\ + glGetMapiv,'glGetMapiv',\ + glGetMaterialfv,'glGetMaterialfv',\ + glGetMaterialiv,'glGetMaterialiv',\ + glGetPixelMapfv,'glGetPixelMapfv',\ + glGetPixelMapuiv,'glGetPixelMapuiv',\ + glGetPixelMapusv,'glGetPixelMapusv',\ + glGetPointerv,'glGetPointerv',\ + glGetPolygonStipple,'glGetPolygonStipple',\ + glGetString,'glGetString',\ + glGetTexEnvfv,'glGetTexEnvfv',\ + glGetTexEnviv,'glGetTexEnviv',\ + glGetTexGendv,'glGetTexGendv',\ + glGetTexGenfv,'glGetTexGenfv',\ + glGetTexGeniv,'glGetTexGeniv',\ + glGetTexImage,'glGetTexImage',\ + glGetTexLevelParameterfv,'glGetTexLevelParameterfv',\ + glGetTexLevelParameteriv,'glGetTexLevelParameteriv',\ + glGetTexParameterfv,'glGetTexParameterfv',\ + glGetTexParameteriv,'glGetTexParameteriv',\ + glHint,'glHint',\ + glIndexMask,'glIndexMask',\ + glIndexPointer,'glIndexPointer',\ + glIndexd,'glIndexd',\ + glIndexdv,'glIndexdv',\ + glIndexf,'glIndexf',\ + glIndexfv,'glIndexfv',\ + glIndexi,'glIndexi',\ + glIndexiv,'glIndexiv',\ + glIndexs,'glIndexs',\ + glIndexsv,'glIndexsv',\ + glIndexub,'glIndexub',\ + glIndexubv,'glIndexubv',\ + glInitNames,'glInitNames',\ + glInterleavedArrays,'glInterleavedArrays',\ + glIsEnabled,'glIsEnabled',\ + glIsList,'glIsList',\ + glIsTexture,'glIsTexture',\ + glLightModelf,'glLightModelf',\ + glLightModelfv,'glLightModelfv',\ + glLightModeli,'glLightModeli',\ + glLightModeliv,'glLightModeliv',\ + glLightf,'glLightf',\ + glLightfv,'glLightfv',\ + glLighti,'glLighti',\ + glLightiv,'glLightiv',\ + glLineStipple,'glLineStipple',\ + glLineWidth,'glLineWidth',\ + glListBase,'glListBase',\ + glLoadIdentity,'glLoadIdentity',\ + glLoadMatrixd,'glLoadMatrixd',\ + glLoadMatrixf,'glLoadMatrixf',\ + glLoadName,'glLoadName',\ + glLogicOp,'glLogicOp',\ + glMap1d,'glMap1d',\ + glMap1f,'glMap1f',\ + glMap2d,'glMap2d',\ + glMap2f,'glMap2f',\ + glMapGrid1d,'glMapGrid1d',\ + glMapGrid1f,'glMapGrid1f',\ + glMapGrid2d,'glMapGrid2d',\ + glMapGrid2f,'glMapGrid2f',\ + glMaterialf,'glMaterialf',\ + glMaterialfv,'glMaterialfv',\ + glMateriali,'glMateriali',\ + glMaterialiv,'glMaterialiv',\ + glMatrixMode,'glMatrixMode',\ + glMultMatrixd,'glMultMatrixd',\ + glMultMatrixf,'glMultMatrixf',\ + glNewList,'glNewList',\ + glNormal3b,'glNormal3b',\ + glNormal3bv,'glNormal3bv',\ + glNormal3d,'glNormal3d',\ + glNormal3dv,'glNormal3dv',\ + glNormal3f,'glNormal3f',\ + glNormal3fv,'glNormal3fv',\ + glNormal3i,'glNormal3i',\ + glNormal3iv,'glNormal3iv',\ + glNormal3s,'glNormal3s',\ + glNormal3sv,'glNormal3sv',\ + glNormalPointer,'glNormalPointer',\ + glOrtho,'glOrtho',\ + glPassThrough,'glPassThrough',\ + glPixelMapfv,'glPixelMapfv',\ + glPixelMapuiv,'glPixelMapuiv',\ + glPixelMapusv,'glPixelMapusv',\ + glPixelStoref,'glPixelStoref',\ + glPixelStorei,'glPixelStorei',\ + glPixelTransferf,'glPixelTransferf',\ + glPixelTransferi,'glPixelTransferi',\ + glPixelZoom,'glPixelZoom',\ + glPointSize,'glPointSize',\ + glPolygonMode,'glPolygonMode',\ + glPolygonOffset,'glPolygonOffset',\ + glPolygonStipple,'glPolygonStipple',\ + glPopAttrib,'glPopAttrib',\ + glPopClientAttrib,'glPopClientAttrib',\ + glPopMatrix,'glPopMatrix',\ + glPopName,'glPopName',\ + glPrioritizeTextures,'glPrioritizeTextures',\ + glPushAttrib,'glPushAttrib',\ + glPushClientAttrib,'glPushClientAttrib',\ + glPushMatrix,'glPushMatrix',\ + glPushName,'glPushName',\ + glRasterPos2d,'glRasterPos2d',\ + glRasterPos2dv,'glRasterPos2dv',\ + glRasterPos2f,'glRasterPos2f',\ + glRasterPos2fv,'glRasterPos2fv',\ + glRasterPos2i,'glRasterPos2i',\ + glRasterPos2iv,'glRasterPos2iv',\ + glRasterPos2s,'glRasterPos2s',\ + glRasterPos2sv,'glRasterPos2sv',\ + glRasterPos3d,'glRasterPos3d',\ + glRasterPos3dv,'glRasterPos3dv',\ + glRasterPos3f,'glRasterPos3f',\ + glRasterPos3fv,'glRasterPos3fv',\ + glRasterPos3i,'glRasterPos3i',\ + glRasterPos3iv,'glRasterPos3iv',\ + glRasterPos3s,'glRasterPos3s',\ + glRasterPos3sv,'glRasterPos3sv',\ + glRasterPos4d,'glRasterPos4d',\ + glRasterPos4dv,'glRasterPos4dv',\ + glRasterPos4f,'glRasterPos4f',\ + glRasterPos4fv,'glRasterPos4fv',\ + glRasterPos4i,'glRasterPos4i',\ + glRasterPos4iv,'glRasterPos4iv',\ + glRasterPos4s,'glRasterPos4s',\ + glRasterPos4sv,'glRasterPos4sv',\ + glReadBuffer,'glReadBuffer',\ + glReadPixels,'glReadPixels',\ + glRectd,'glRectd',\ + glRectdv,'glRectdv',\ + glRectf,'glRectf',\ + glRectfv,'glRectfv',\ + glRecti,'glRecti',\ + glRectiv,'glRectiv',\ + glRects,'glRects',\ + glRectsv,'glRectsv',\ + glRenderMode,'glRenderMode',\ + glRotated,'glRotated',\ + glRotatef,'glRotatef',\ + glScaled,'glScaled',\ + glScalef,'glScalef',\ + glScissor,'glScissor',\ + glSelectBuffer,'glSelectBuffer',\ + glShadeModel,'glShadeModel',\ + glStencilFunc,'glStencilFunc',\ + glStencilMask,'glStencilMask',\ + glStencilOp,'glStencilOp',\ + glTexCoord1d,'glTexCoord1d',\ + glTexCoord1dv,'glTexCoord1dv',\ + glTexCoord1f,'glTexCoord1f',\ + glTexCoord1fv,'glTexCoord1fv',\ + glTexCoord1i,'glTexCoord1i',\ + glTexCoord1iv,'glTexCoord1iv',\ + glTexCoord1s,'glTexCoord1s',\ + glTexCoord1sv,'glTexCoord1sv',\ + glTexCoord2d,'glTexCoord2d',\ + glTexCoord2dv,'glTexCoord2dv',\ + glTexCoord2f,'glTexCoord2f',\ + glTexCoord2fv,'glTexCoord2fv',\ + glTexCoord2i,'glTexCoord2i',\ + glTexCoord2iv,'glTexCoord2iv',\ + glTexCoord2s,'glTexCoord2s',\ + glTexCoord2sv,'glTexCoord2sv',\ + glTexCoord3d,'glTexCoord3d',\ + glTexCoord3dv,'glTexCoord3dv',\ + glTexCoord3f,'glTexCoord3f',\ + glTexCoord3fv,'glTexCoord3fv',\ + glTexCoord3i,'glTexCoord3i',\ + glTexCoord3iv,'glTexCoord3iv',\ + glTexCoord3s,'glTexCoord3s',\ + glTexCoord3sv,'glTexCoord3sv',\ + glTexCoord4d,'glTexCoord4d',\ + glTexCoord4dv,'glTexCoord4dv',\ + glTexCoord4f,'glTexCoord4f',\ + glTexCoord4fv,'glTexCoord4fv',\ + glTexCoord4i,'glTexCoord4i',\ + glTexCoord4iv,'glTexCoord4iv',\ + glTexCoord4s,'glTexCoord4s',\ + glTexCoord4sv,'glTexCoord4sv',\ + glTexCoordPointer,'glTexCoordPointer',\ + glTexEnvf,'glTexEnvf',\ + glTexEnvfv,'glTexEnvfv',\ + glTexEnvi,'glTexEnvi',\ + glTexEnviv,'glTexEnviv',\ + glTexGend,'glTexGend',\ + glTexGendv,'glTexGendv',\ + glTexGenf,'glTexGenf',\ + glTexGenfv,'glTexGenfv',\ + glTexGeni,'glTexGeni',\ + glTexGeniv,'glTexGeniv',\ + glTexImage1D,'glTexImage1D',\ + glTexImage2D,'glTexImage2D',\ + glTexParameterf,'glTexParameterf',\ + glTexParameterfv,'glTexParameterfv',\ + glTexParameteri,'glTexParameteri',\ + glTexParameteriv,'glTexParameteriv',\ + glTexSubImage1D,'glTexSubImage1D',\ + glTexSubImage2D,'glTexSubImage2D',\ + glTranslated,'glTranslated',\ + glTranslatef,'glTranslatef',\ + glVertex2d,'glVertex2d',\ + glVertex2dv,'glVertex2dv',\ + glVertex2f,'glVertex2f',\ + glVertex2fv,'glVertex2fv',\ + glVertex2i,'glVertex2i',\ + glVertex2iv,'glVertex2iv',\ + glVertex2s,'glVertex2s',\ + glVertex2sv,'glVertex2sv',\ + glVertex3d,'glVertex3d',\ + glVertex3dv,'glVertex3dv',\ + glVertex3f,'glVertex3f',\ + glVertex3fv,'glVertex3fv',\ + glVertex3i,'glVertex3i',\ + glVertex3iv,'glVertex3iv',\ + glVertex3s,'glVertex3s',\ + glVertex3sv,'glVertex3sv',\ + glVertex4d,'glVertex4d',\ + glVertex4dv,'glVertex4dv',\ + glVertex4f,'glVertex4f',\ + glVertex4fv,'glVertex4fv',\ + glVertex4i,'glVertex4i',\ + glVertex4iv,'glVertex4iv',\ + glVertex4s,'glVertex4s',\ + glVertex4sv,'glVertex4sv',\ + glVertexPointer,'glVertexPointer',\ + glViewport,'glViewport',\ + wglGetProcAddress,'wglGetProcAddress',\ + wglCopyContext,'wglCopyContext',\ + wglCreateContext,'wglCreateContext',\ + wglCreateLayerContext,'wglCreateLayerContext',\ + wglDeleteContext,'wglDeleteContext',\ + wglDescribeLayerPlane,'wglDescribeLayerPlane',\ + wglGetCurrentContext,'wglGetCurrentContext',\ + wglGetCurrentDC,'wglGetCurrentDC',\ + wglGetLayerPaletteEntries,'wglGetLayerPaletteEntries',\ + wglMakeCurrent,'wglMakeCurrent',\ + wglRealizeLayerPalette,'wglRealizeLayerPalette',\ + wglSetLayerPaletteEntries,'wglSetLayerPaletteEntries',\ + wglShareLists,'wglShareLists',\ + wglSwapLayerBuffers,'wglSwapLayerBuffers',\ + wglSwapMultipleBuffers,'wglSwapMultipleBuffers',\ + wglUseFontBitmapsA,'wglUseFontBitmapsA',\ + wglUseFontOutlinesA,'wglUseFontOutlinesA',\ + wglUseFontBitmapsW,'wglUseFontBitmapsW',\ + wglUseFontOutlinesW,'wglUseFontOutlinesW',\ + glDrawRangeElements,'glDrawRangeElements',\ + glTexImage3D,'glTexImage3D',\ + glBlendColor,'glBlendColor',\ + glBlendEquation,'glBlendEquation',\ + glColorSubTable,'glColorSubTable',\ + glCopyColorSubTable,'glCopyColorSubTable',\ + glColorTable,'glColorTable',\ + glCopyColorTable,'glCopyColorTable',\ + glColorTableParameteriv,'glColorTableParameteriv',\ + glColorTableParameterfv,'glColorTableParameterfv',\ + glGetColorTable,'glGetColorTable',\ + glGetColorTableParameteriv,'glGetColorTableParameteriv',\ + glGetColorTableParameterfv,'glGetColorTableParameterfv',\ + glConvolutionFilter1D,'glConvolutionFilter1D',\ + glConvolutionFilter2D,'glConvolutionFilter2D',\ + glCopyConvolutionFilter1D,'glCopyConvolutionFilter1D',\ + glCopyConvolutionFilter2D,'glCopyConvolutionFilter2D',\ + glGetConvolutionFilter,'glGetConvolutionFilter',\ + glSeparableFilter2D,'glSeparableFilter2D',\ + glGetSeparableFilter,'glGetSeparableFilter',\ + glConvolutionParameteri,'glConvolutionParameteri',\ + glConvolutionParameteriv,'glConvolutionParameteriv',\ + glConvolutionParameterf,'glConvolutionParameterf',\ + glConvolutionParameterfv,'glConvolutionParameterfv',\ + glGetConvolutionParameteriv,'glGetConvolutionParameteriv',\ + glGetConvolutionParameterfv,'glGetConvolutionParameterfv',\ + glHistogram,'glHistogram',\ + glResetHistogram,'glResetHistogram',\ + glGetHistogram,'glGetHistogram',\ + glGetHistogramParameteriv,'glGetHistogramParameteriv',\ + glGetHistogramParameterfv,'glGetHistogramParameterfv',\ + glMinmax,'glMinmax',\ + glResetMinmax,'glResetMinmax',\ + glGetMinmax,'glGetMinmax',\ + glGetMinmaxParameteriv,'glGetMinmaxParameteriv',\ + glGetMinmaxParameterfv,'glGetMinmaxParameterfv' + + import glu,\ + gluBeginCurve,'gluBeginCurve',\ + gluBeginPolygon,'gluBeginPolygon',\ + gluBeginSurface,'gluBeginSurface',\ + gluBeginTrim,'gluBeginTrim',\ + gluBuild1DMipmaps,'gluBuild1DMipmaps',\ + gluBuild2DMipmaps,'gluBuild2DMipmaps',\ + gluCylinder,'gluCylinder',\ + gluDeleteNurbsRenderer,'gluDeleteNurbsRenderer',\ + gluDeleteQuadric,'gluDeleteQuadric',\ + gluDeleteTess,'gluDeleteTess',\ + gluDisk,'gluDisk',\ + gluEndCurve,'gluEndCurve',\ + gluEndPolygon,'gluEndPolygon',\ + gluEndSurface,'gluEndSurface',\ + gluEndTrim,'gluEndTrim',\ + gluErrorString,'gluErrorString',\ + gluGetNurbsProperty,'gluGetNurbsProperty',\ + gluGetString,'gluGetString',\ + gluGetTessProperty,'gluGetTessProperty',\ + gluLoadSamplingMatrices,'gluLoadSamplingMatrices',\ + gluLookAt,'gluLookAt',\ + gluNewNurbsRenderer,'gluNewNurbsRenderer',\ + gluNewQuadric,'gluNewQuadric',\ + gluNewTess,'gluNewTess',\ + gluNextContour,'gluNextContour',\ + gluNurbsCallback,'gluNurbsCallback',\ + gluNurbsCurve,'gluNurbsCurve',\ + gluNurbsProperty,'gluNurbsProperty',\ + gluNurbsSurface,'gluNurbsSurface',\ + gluOrtho2D,'gluOrtho2D',\ + gluPartialDisk,'gluPartialDisk',\ + gluPerspective,'gluPerspective',\ + gluPickMatrix,'gluPickMatrix',\ + gluProject,'gluProject',\ + gluPwlCurve,'gluPwlCurve',\ + gluQuadricCallback,'gluQuadricCallback',\ + gluQuadricDrawStyle,'gluQuadricDrawStyle',\ + gluQuadricNormals,'gluQuadricNormals',\ + gluQuadricOrientation,'gluQuadricOrientation',\ + gluQuadricTexture,'gluQuadricTexture',\ + gluScaleImage,'gluScaleImage',\ + gluSphere,'gluSphere',\ + gluTessBeginContour,'gluTessBeginContour',\ + gluTessBeginPolygon,'gluTessBeginPolygon',\ + gluTessCallback,'gluTessCallback',\ + gluTessEndContour,'gluTessEndContour',\ + gluTessEndPolygon,'gluTessEndPolygon',\ + gluTessNormal,'gluTessNormal',\ + gluTessProperty,'gluTessProperty',\ + gluTessVertex,'gluTessVertex',\ + gluUnProject,'gluUnProject' diff --git a/toolchain/fasmw17332/EXAMPLES/OPENGL/OPENGL.INC b/toolchain/fasmw17332/EXAMPLES/OPENGL/OPENGL.INC new file mode 100644 index 0000000..05c6d08 --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/OPENGL/OPENGL.INC @@ -0,0 +1,2337 @@ + +; GL types + +GLenum fix dd +GLboolean fix db +GLbitfield fix dd +GLbyte fix db +GLshort fix dw +GLint fix dd +GLsizei fix dd +GLubyte fix db +GLushort fix dw +GLuint fix dd +GLfloat fix dd +GLclampf fix dd +GLdouble fix dq +GLclampd fix dq + +; GL errors + +GL_NO_ERROR = 0 +GL_INVALID_ENUM = $0500 +GL_INVALID_VALUE = $0501 +GL_INVALID_OPERATION = $0502 +GL_STACK_OVERFLOW = $0503 +GL_STACK_UNDERFLOW = $0504 +GL_OUT_OF_MEMORY = $0505 + +; Attribute bits + +GL_CURRENT_BIT = $00000001 +GL_POINT_BIT = $00000002 +GL_LINE_BIT = $00000004 +GL_POLYGON_BIT = $00000008 +GL_POLYGON_STIPPLE_BIT = $00000010 +GL_PIXEL_MODE_BIT = $00000020 +GL_LIGHTING_BIT = $00000040 +GL_FOG_BIT = $00000080 +GL_DEPTH_BUFFER_BIT = $00000100 +GL_ACCUM_BUFFER_BIT = $00000200 +GL_STENCIL_BUFFER_BIT = $00000400 +GL_VIEWPORT_BIT = $00000800 +GL_TRANSFORM_BIT = $00001000 +GL_ENABLE_BIT = $00002000 +GL_COLOR_BUFFER_BIT = $00004000 +GL_HINT_BIT = $00008000 +GL_EVAL_BIT = $00010000 +GL_LIST_BIT = $00020000 +GL_TEXTURE_BIT = $00040000 +GL_SCISSOR_BIT = $00080000 +GL_ALL_ATTRIB_BITS = $000FFFFF + +; Client attribute bits + +GL_CLIENT_PIXEL_STORE_BIT = $00000001 +GL_CLIENT_VERTEX_ARRAY_BIT = $00000002 +GL_CLIENT_ALL_ATTRIB_BITS = $FFFFFFFF + +; Boolean values + +GL_FALSE = 0 +GL_TRUE = 1 + +; Primitives + +GL_POINTS = $0000 +GL_LINES = $0001 +GL_LINE_LOOP = $0002 +GL_LINE_STRIP = $0003 +GL_TRIANGLES = $0004 +GL_TRIANGLE_STRIP = $0005 +GL_TRIANGLE_FAN = $0006 +GL_QUADS = $0007 +GL_QUAD_STRIP = $0008 +GL_POLYGON = $0009 + +; Blending + +GL_ZERO = 0 +GL_ONE = 1 +GL_SRC_COLOR = $0300 +GL_ONE_MINUS_SRC_COLOR = $0301 +GL_SRC_ALPHA = $0302 +GL_ONE_MINUS_SRC_ALPHA = $0303 +GL_DST_ALPHA = $0304 +GL_ONE_MINUS_DST_ALPHA = $0305 +GL_DST_COLOR = $0306 +GL_ONE_MINUS_DST_COLOR = $0307 +GL_SRC_ALPHA_SATURATE = $0308 +GL_BLEND_DST = $0BE0 +GL_BLEND_SRC = $0BE1 +GL_BLEND = $0BE2 + +; Blending (GL 1.2 ARB imaging) + +GL_BLEND_COLOR = $8005 +GL_CONSTANT_COLOR = $8001 +GL_ONE_MINUS_CONSTANT_COLOR = $8002 +GL_CONSTANT_ALPHA = $8003 +GL_ONE_MINUS_CONSTANT_ALPHA = $8004 +GL_FUNC_ADD = $8006 +GL_MIN = $8007 +GL_MAX = $8008 +GL_FUNC_SUBTRACT = $800A +GL_FUNC_REVERSE_SUBTRACT = $800B + +; Color table (GL 1.2 ARB imaging) + +GL_COLOR_TABLE = $80D0 +GL_POST_CONVOLUTION_COLOR_TABLE = $80D1 +GL_POST_COLOR_MATRIX_COLOR_TABLE = $80D2 +GL_PROXY_COLOR_TABLE = $80D3 +GL_PROXY_POST_CONVOLUTION_COLOR_TABLE = $80D4 +GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE = $80D5 +GL_COLOR_TABLE_SCALE = $80D6 +GL_COLOR_TABLE_BIAS = $80D7 +GL_COLOR_TABLE_FORMAT = $80D8 +GL_COLOR_TABLE_WIDTH = $80D9 +GL_COLOR_TABLE_RED_SIZE = $80DA +GL_COLOR_TABLE_GREEN_SIZE = $80DB +GL_COLOR_TABLE_BLUE_SIZE = $80DC +GL_COLOR_TABLE_ALPHA_SIZE = $80DD +GL_COLOR_TABLE_LUMINANCE_SIZE = $80DE +GL_COLOR_TABLE_INTENSITY_SIZE = $80DF + +; Convolutions (GL 1.2 ARB imaging) + +GL_CONVOLUTION_1D = $8010 +GL_CONVOLUTION_2D = $8011 +GL_SEPARABLE_2D = $8012 +GL_CONVOLUTION_BORDER_MODE = $8013 +GL_CONVOLUTION_FILTER_SCALE = $8014 +GL_CONVOLUTION_FILTER_BIAS = $8015 +GL_REDUCE = $8016 +GL_CONVOLUTION_FORMAT = $8017 +GL_CONVOLUTION_WIDTH = $8018 +GL_CONVOLUTION_HEIGHT = $8019 +GL_MAX_CONVOLUTION_WIDTH = $801A +GL_MAX_CONVOLUTION_HEIGHT = $801B +GL_POST_CONVOLUTION_RED_SCALE = $801C +GL_POST_CONVOLUTION_GREEN_SCALE = $801D +GL_POST_CONVOLUTION_BLUE_SCALE = $801E +GL_POST_CONVOLUTION_ALPHA_SCALE = $801F +GL_POST_CONVOLUTION_RED_BIAS = $8020 +GL_POST_CONVOLUTION_GREEN_BIAS = $8021 +GL_POST_CONVOLUTION_BLUE_BIAS = $8022 +GL_POST_CONVOLUTION_ALPHA_BIAS = $8023 + +; Histogram (GL 1.2 ARB imaging) + +GL_HISTOGRAM = $8024 +GL_PROXY_HISTOGRAM = $8025 +GL_HISTOGRAM_WIDTH = $8026 +GL_HISTOGRAM_FORMAT = $8027 +GL_HISTOGRAM_RED_SIZE = $8028 +GL_HISTOGRAM_GREEN_SIZE = $8029 +GL_HISTOGRAM_BLUE_SIZE = $802A +GL_HISTOGRAM_ALPHA_SIZE = $802B +GL_HISTOGRAM_LUMINANCE_SIZE = $802C +GL_HISTOGRAM_SINK = $802D +GL_MINMAX = $802E +GL_MINMAX_FORMAT = $802F +GL_MINMAX_SINK = $8030 + +; Buffers + +GL_NONE = 0 +GL_FRONT_LEFT = $0400 +GL_FRONT_RIGHT = $0401 +GL_BACK_LEFT = $0402 +GL_BACK_RIGHT = $0403 +GL_FRONT = $0404 +GL_BACK = $0405 +GL_LEFT = $0406 +GL_RIGHT = $0407 +GL_FRONT_AND_BACK = $0408 +GL_AUX0 = $0409 +GL_AUX1 = $040A +GL_AUX2 = $040B +GL_AUX3 = $040C +GL_AUX_BUFFERS = $0C00 +GL_DRAW_BUFFER = $0C01 +GL_READ_BUFFER = $0C02 +GL_DOUBLEBUFFER = $0C32 +GL_STEREO = $0C33 + +; Depth buffer + +GL_DEPTH_RANGE = $0B70 +GL_DEPTH_TEST = $0B71 +GL_DEPTH_WRITEMASK = $0B72 +GL_DEPTH_CLEAR_VALUE = $0B73 +GL_DEPTH_FUNC = $0B74 +GL_NEVER = $0200 +GL_LESS = $0201 +GL_EQUAL = $0202 +GL_LEQUAL = $0203 +GL_GREATER = $0204 +GL_NOTEQUAL = $0205 +GL_GEQUAL = $0206 +GL_ALWAYS = $0207 + +; Accumulation buffer + +GL_ACCUM = $0100 +GL_LOAD = $0101 +GL_RETURN = $0102 +GL_MULT = $0103 +GL_ADD = $0104 +GL_ACCUM_CLEAR_VALUE = $0B80 + +; Feedback buffer + +GL_FEEDBACK_BUFFER_POINTER = $0DF0 +GL_FEEDBACK_BUFFER_SIZE = $0DF1 +GL_FEEDBACK_BUFFER_TYPE = $0DF2 + +; Feedback types + +GL_2D = $0600 +GL_3D = $0601 +GL_3D_COLOR = $0602 +GL_3D_COLOR_TEXTURE = $0603 +GL_4D_COLOR_TEXTURE = $0604 + +; Feedback tokens + +GL_PASS_THROUGH_TOKEN = $0700 +GL_POINT_TOKEN = $0701 +GL_LINE_TOKEN = $0702 +GL_POLYGON_TOKEN = $0703 +GL_BITMAP_TOKEN = $0704 +GL_DRAW_PIXEL_TOKEN = $0705 +GL_COPY_PIXEL_TOKEN = $0706 +GL_LINE_RESET_TOKEN = $0707 + +; Fog + +GL_EXP = $0800 +GL_EXP2 = $0801 +GL_FOG = $0B60 +GL_FOG_INDEX = $0B61 +GL_FOG_DENSITY = $0B62 +GL_FOG_START = $0B63 +GL_FOG_END = $0B64 +GL_FOG_MODE = $0B65 +GL_FOG_COLOR = $0B66 + +; Pixel mode, transfer + +GL_PIXEL_MAP_I_TO_I = $0C70 +GL_PIXEL_MAP_S_TO_S = $0C71 +GL_PIXEL_MAP_I_TO_R = $0C72 +GL_PIXEL_MAP_I_TO_G = $0C73 +GL_PIXEL_MAP_I_TO_B = $0C74 +GL_PIXEL_MAP_I_TO_A = $0C75 +GL_PIXEL_MAP_R_TO_R = $0C76 +GL_PIXEL_MAP_G_TO_G = $0C77 +GL_PIXEL_MAP_B_TO_B = $0C78 +GL_PIXEL_MAP_A_TO_A = $0C79 + +; Vertex arrays + +GL_VERTEX_ARRAY_POINTER = $808E +GL_NORMAL_ARRAY_POINTER = $808F +GL_COLOR_ARRAY_POINTER = $8090 +GL_INDEX_ARRAY_POINTER = $8091 +GL_TEXTURE_COORD_ARRAY_POINTER = $8092 +GL_EDGE_FLAG_ARRAY_POINTER = $8093 + +; Stenciling + +GL_STENCIL_TEST = $0B90 +GL_STENCIL_CLEAR_VALUE = $0B91 +GL_STENCIL_FUNC = $0B92 +GL_STENCIL_VALUE_MASK = $0B93 +GL_STENCIL_FAIL = $0B94 +GL_STENCIL_PASS_DEPTH_FAIL = $0B95 +GL_STENCIL_PASS_DEPTH_PASS = $0B96 +GL_STENCIL_REF = $0B97 +GL_STENCIL_WRITEMASK = $0B98 +GL_KEEP = $1E00 +GL_REPLACE = $1E01 +GL_INCR = $1E02 +GL_DECR = $1E03 + +; Color material + +GL_COLOR_MATERIAL_FACE = $0B55 +GL_COLOR_MATERIAL_PARAMETER = $0B56 +GL_COLOR_MATERIAL = $0B57 + +; Points + +GL_POINT_SMOOTH = $0B10 +GL_POINT_SIZE = $0B11 +GL_POINT_SIZE_RANGE = $0B12 +GL_POINT_SIZE_GRANULARITY = $0B13 + +; Lines + +GL_LINE_SMOOTH = $0B20 +GL_LINE_WIDTH = $0B21 +GL_LINE_WIDTH_RANGE = $0B22 +GL_LINE_WIDTH_GRANULARITY = $0B23 +GL_LINE_STIPPLE = $0B24 +GL_LINE_STIPPLE_PATTERN = $0B25 +GL_LINE_STIPPLE_REPEAT = $0B26 + +; Polygons + +GL_POLYGON_MODE = $0B40 +GL_POLYGON_SMOOTH = $0B41 +GL_POLYGON_STIPPLE = $0B42 +GL_EDGE_FLAG = $0B43 +GL_CULL_FACE = $0B44 +GL_CULL_FACE_MODE = $0B45 +GL_FRONT_FACE = $0B46 +GL_CW = $0900 +GL_CCW = $0901 +GL_POINT = $1B00 +GL_LINE = $1B01 +GL_FILL = $1B02 + +; Display lists + +GL_LIST_MODE = $0B30 +GL_LIST_BASE = $0B32 +GL_LIST_INDEX = $0B33 +GL_COMPILE = $1300 +GL_COMPILE_AND_EXECUTE = $1301 + +; Lighting + +GL_LIGHTING = $0B50 +GL_LIGHT_MODEL_LOCAL_VIEWER = $0B51 +GL_LIGHT_MODEL_TWO_SIDE = $0B52 +GL_LIGHT_MODEL_AMBIENT = $0B53 +GL_LIGHT_MODEL_COLOR_CONTROL = $81F8 +GL_SHADE_MODEL = $0B54 +GL_NORMALIZE = $0BA1 +GL_AMBIENT = $1200 +GL_DIFFUSE = $1201 +GL_SPECULAR = $1202 +GL_POSITION = $1203 +GL_SPOT_DIRECTION = $1204 +GL_SPOT_EXPONENT = $1205 +GL_SPOT_CUTOFF = $1206 +GL_CONSTANT_ATTENUATION = $1207 +GL_LINEAR_ATTENUATION = $1208 +GL_QUADRATIC_ATTENUATION = $1209 +GL_EMISSION = $1600 +GL_SHININESS = $1601 +GL_AMBIENT_AND_DIFFUSE = $1602 +GL_COLOR_INDEXES = $1603 +GL_FLAT = $1D00 +GL_SMOOTH = $1D01 +GL_LIGHT0 = $4000 +GL_LIGHT1 = $4001 +GL_LIGHT2 = $4002 +GL_LIGHT3 = $4003 +GL_LIGHT4 = $4004 +GL_LIGHT5 = $4005 +GL_LIGHT6 = $4006 +GL_LIGHT7 = $4007 + +; Matrix modes + +GL_MATRIX_MODE = $0BA0 +GL_MODELVIEW = $1700 +GL_PROJECTION = $1701 +GL_TEXTURE = $1702 + +; Gets + +GL_CURRENT_COLOR = $0B00 +GL_CURRENT_INDEX = $0B01 +GL_CURRENT_NORMAL = $0B02 +GL_CURRENT_TEXTURE_COORDS = $0B03 +GL_CURRENT_RASTER_COLOR = $0B04 +GL_CURRENT_RASTER_INDEX = $0B05 +GL_CURRENT_RASTER_TEXTURE_COORDS = $0B06 +GL_CURRENT_RASTER_POSITION = $0B07 +GL_CURRENT_RASTER_POSITION_VALID = $0B08 +GL_CURRENT_RASTER_DISTANCE = $0B09 +GL_MAX_LIST_NESTING = $0B31 +GL_VIEWPORT = $0BA2 +GL_MODELVIEW_STACK_DEPTH = $0BA3 +GL_PROJECTION_STACK_DEPTH = $0BA4 +GL_TEXTURE_STACK_DEPTH = $0BA5 +GL_MODELVIEW_MATRIX = $0BA6 +GL_PROJECTION_MATRIX = $0BA7 +GL_TEXTURE_MATRIX = $0BA8 +GL_ATTRIB_STACK_DEPTH = $0BB0 +GL_CLIENT_ATTRIB_STACK_DEPTH = $0BB1 +GL_SINGLE_COLOR = $81F9 +GL_SEPARATE_SPECULAR_COLOR = $81FA + +; Alpha testing + +GL_ALPHA_TEST = $0BC0 +GL_ALPHA_TEST_FUNC = $0BC1 +GL_ALPHA_TEST_REF = $0BC2 + +GL_LOGIC_OP_MODE = $0BF0 +GL_INDEX_LOGIC_OP = $0BF1 +GL_LOGIC_OP = $0BF1 +GL_COLOR_LOGIC_OP = $0BF2 +GL_SCISSOR_BOX = $0C10 +GL_SCISSOR_TEST = $0C11 +GL_INDEX_CLEAR_VALUE = $0C20 +GL_INDEX_WRITEMASK = $0C21 +GL_COLOR_CLEAR_VALUE = $0C22 +GL_COLOR_WRITEMASK = $0C23 +GL_INDEX_MODE = $0C30 +GL_RGBA_MODE = $0C31 +GL_RENDER_MODE = $0C40 +GL_PERSPECTIVE_CORRECTION_HINT = $0C50 +GL_POINT_SMOOTH_HINT = $0C51 +GL_LINE_SMOOTH_HINT = $0C52 +GL_POLYGON_SMOOTH_HINT = $0C53 +GL_FOG_HINT = $0C54 +GL_TEXTURE_GEN_S = $0C60 +GL_TEXTURE_GEN_T = $0C61 +GL_TEXTURE_GEN_R = $0C62 +GL_TEXTURE_GEN_Q = $0C63 +GL_PIXEL_MAP_I_TO_I_SIZE = $0CB0 +GL_PIXEL_MAP_S_TO_S_SIZE = $0CB1 +GL_PIXEL_MAP_I_TO_R_SIZE = $0CB2 +GL_PIXEL_MAP_I_TO_G_SIZE = $0CB3 +GL_PIXEL_MAP_I_TO_B_SIZE = $0CB4 +GL_PIXEL_MAP_I_TO_A_SIZE = $0CB5 +GL_PIXEL_MAP_R_TO_R_SIZE = $0CB6 +GL_PIXEL_MAP_G_TO_G_SIZE = $0CB7 +GL_PIXEL_MAP_B_TO_B_SIZE = $0CB8 +GL_PIXEL_MAP_A_TO_A_SIZE = $0CB9 +GL_UNPACK_SWAP_BYTES = $0CF0 +GL_UNPACK_LSB_FIRST = $0CF1 +GL_UNPACK_ROW_LENGTH = $0CF2 +GL_UNPACK_SKIP_ROWS = $0CF3 +GL_UNPACK_SKIP_PIXELS = $0CF4 +GL_UNPACK_ALIGNMENT = $0CF5 +GL_PACK_SWAP_BYTES = $0D00 +GL_PACK_LSB_FIRST = $0D01 +GL_PACK_ROW_LENGTH = $0D02 +GL_PACK_SKIP_ROWS = $0D03 +GL_PACK_SKIP_PIXELS = $0D04 +GL_PACK_ALIGNMENT = $0D05 +GL_PACK_SKIP_IMAGES = $806B +GL_PACK_IMAGE_HEIGHT = $806C +GL_UNPACK_SKIP_IMAGES = $806D +GL_UNPACK_IMAGE_HEIGHT = $806E +GL_MAP_COLOR = $0D10 +GL_MAP_STENCIL = $0D11 +GL_INDEX_SHIFT = $0D12 +GL_INDEX_OFFSET = $0D13 +GL_RED_SCALE = $0D14 +GL_RED_BIAS = $0D15 +GL_ZOOM_X = $0D16 +GL_ZOOM_Y = $0D17 +GL_GREEN_SCALE = $0D18 +GL_GREEN_BIAS = $0D19 +GL_BLUE_SCALE = $0D1A +GL_BLUE_BIAS = $0D1B +GL_ALPHA_SCALE = $0D1C +GL_ALPHA_BIAS = $0D1D +GL_DEPTH_SCALE = $0D1E +GL_DEPTH_BIAS = $0D1F +GL_MAX_EVAL_ORDER = $0D30 +GL_MAX_LIGHTS = $0D31 +GL_MAX_CLIP_PLANES = $0D32 +GL_MAX_TEXTURE_SIZE = $0D33 +GL_MAX_3D_TEXTURE_SIZE = $8073 +GL_MAX_PIXEL_MAP_TABLE = $0D34 +GL_MAX_ATTRIB_STACK_DEPTH = $0D35 +GL_MAX_MODELVIEW_STACK_DEPTH = $0D36 +GL_MAX_NAME_STACK_DEPTH = $0D37 +GL_MAX_PROJECTION_STACK_DEPTH = $0D38 +GL_MAX_TEXTURE_STACK_DEPTH = $0D39 +GL_MAX_VIEWPORT_DIMS = $0D3A +GL_MAX_CLIENT_ATTRIB_STACK_DEPTH = $0D3B +GL_MAX_ELEMENTS_VERTICES = $80E8 +GL_MAX_ELEMENTS_INDICES = $80E9 +GL_RESCALE_NORMAL = $803A +GL_SUBPIXEL_BITS = $0D50 +GL_INDEX_BITS = $0D51 +GL_RED_BITS = $0D52 +GL_GREEN_BITS = $0D53 +GL_BLUE_BITS = $0D54 +GL_ALPHA_BITS = $0D55 +GL_DEPTH_BITS = $0D56 +GL_STENCIL_BITS = $0D57 +GL_ACCUM_RED_BITS = $0D58 +GL_ACCUM_GREEN_BITS = $0D59 +GL_ACCUM_BLUE_BITS = $0D5A +GL_ACCUM_ALPHA_BITS = $0D5B +GL_NAME_STACK_DEPTH = $0D70 +GL_AUTO_NORMAL = $0D80 +GL_MAP1_COLOR_4 = $0D90 +GL_MAP1_INDEX = $0D91 +GL_MAP1_NORMAL = $0D92 +GL_MAP1_TEXTURE_COORD_1 = $0D93 +GL_MAP1_TEXTURE_COORD_2 = $0D94 +GL_MAP1_TEXTURE_COORD_3 = $0D95 +GL_MAP1_TEXTURE_COORD_4 = $0D96 +GL_MAP1_VERTEX_3 = $0D97 +GL_MAP1_VERTEX_4 = $0D98 +GL_MAP2_COLOR_4 = $0DB0 +GL_MAP2_INDEX = $0DB1 +GL_MAP2_NORMAL = $0DB2 +GL_MAP2_TEXTURE_COORD_1 = $0DB3 +GL_MAP2_TEXTURE_COORD_2 = $0DB4 +GL_MAP2_TEXTURE_COORD_3 = $0DB5 +GL_MAP2_TEXTURE_COORD_4 = $0DB6 +GL_MAP2_VERTEX_3 = $0DB7 +GL_MAP2_VERTEX_4 = $0DB8 +GL_MAP1_GRID_DOMAIN = $0DD0 +GL_MAP1_GRID_SEGMENTS = $0DD1 +GL_MAP2_GRID_DOMAIN = $0DD2 +GL_MAP2_GRID_SEGMENTS = $0DD3 +GL_TEXTURE_1D = $0DE0 +GL_TEXTURE_2D = $0DE1 +GL_TEXTURE_3D = $806F +GL_SELECTION_BUFFER_POINTER = $0DF3 +GL_SELECTION_BUFFER_SIZE = $0DF4 +GL_POLYGON_OFFSET_UNITS = $2A00 +GL_POLYGON_OFFSET_POINT = $2A01 +GL_POLYGON_OFFSET_LINE = $2A02 +GL_POLYGON_OFFSET_FILL = $8037 +GL_POLYGON_OFFSET_FACTOR = $8038 +GL_TEXTURE_BINDING_1D = $8068 +GL_TEXTURE_BINDING_2D = $8069 +GL_VERTEX_ARRAY = $8074 +GL_NORMAL_ARRAY = $8075 +GL_COLOR_ARRAY = $8076 +GL_INDEX_ARRAY = $8077 +GL_TEXTURE_COORD_ARRAY = $8078 +GL_EDGE_FLAG_ARRAY = $8079 +GL_VERTEX_ARRAY_SIZE = $807A +GL_VERTEX_ARRAY_TYPE = $807B +GL_VERTEX_ARRAY_STRIDE = $807C +GL_NORMAL_ARRAY_TYPE = $807E +GL_NORMAL_ARRAY_STRIDE = $807F +GL_COLOR_ARRAY_SIZE = $8081 +GL_COLOR_ARRAY_TYPE = $8082 +GL_COLOR_ARRAY_STRIDE = $8083 +GL_INDEX_ARRAY_TYPE = $8085 +GL_INDEX_ARRAY_STRIDE = $8086 +GL_TEXTURE_COORD_ARRAY_SIZE = $8088 +GL_TEXTURE_COORD_ARRAY_TYPE = $8089 +GL_TEXTURE_COORD_ARRAY_STRIDE = $808A +GL_EDGE_FLAG_ARRAY_STRIDE = $808C +GL_COLOR_MATRIX = $80B1 +GL_COLOR_MATRIX_STACK_DEPTH = $80B2 +GL_MAX_COLOR_MATRIX_STACK_DEPTH = $80B3 +GL_POST_COLOR_MATRIX_RED_SCALE = $80B4 +GL_POST_COLOR_MATRIX_GREEN_SCALE = $80B5 +GL_POST_COLOR_MATRIX_BLUE_SCALE = $80B6 +GL_POST_COLOR_MATRIX_ALPHA_SCALE = $80B7 +GL_POST_COLOR_MATRIX_RED_BIAS = $80B8 +GL_POST_COLOR_MATRIX_GREEN_BIAS = $80B9 +GL_POST_COLOR_MATRIX_BLUE_BIAS = $80BA +GL_POST_COLOR_MATRIX_ALPHA_BIAS = $80BB + +; Evaluators + +GL_COEFF = $0A00 +GL_ORDER = $0A01 +GL_DOMAIN = $0A02 + +; Texture mapping + +GL_TEXTURE_WIDTH = $1000 +GL_TEXTURE_HEIGHT = $1001 +GL_TEXTURE_INTERNAL_FORMAT = $1003 +GL_TEXTURE_COMPONENTS = $1003 +GL_TEXTURE_BORDER_COLOR = $1004 +GL_TEXTURE_BORDER = $1005 +GL_TEXTURE_RED_SIZE = $805C +GL_TEXTURE_GREEN_SIZE = $805D +GL_TEXTURE_BLUE_SIZE = $805E +GL_TEXTURE_ALPHA_SIZE = $805F +GL_TEXTURE_LUMINANCE_SIZE = $8060 +GL_TEXTURE_INTENSITY_SIZE = $8061 +GL_TEXTURE_PRIORITY = $8066 +GL_TEXTURE_RESIDENT = $8067 +GL_BGR = $80E0 +GL_BGRA = $80E1 +GL_S = $2000 +GL_T = $2001 +GL_R = $2002 +GL_Q = $2003 +GL_MODULATE = $2100 +GL_DECAL = $2101 +GL_TEXTURE_ENV_MODE = $2200 +GL_TEXTURE_ENV_COLOR = $2201 +GL_TEXTURE_ENV = $2300 +GL_EYE_LINEAR = $2400 +GL_OBJECT_LINEAR = $2401 +GL_SPHERE_MAP = $2402 +GL_TEXTURE_GEN_MODE = $2500 +GL_OBJECT_PLANE = $2501 +GL_EYE_PLANE = $2502 +GL_NEAREST = $2600 +GL_LINEAR = $2601 +GL_NEAREST_MIPMAP_NEAREST = $2700 +GL_LINEAR_MIPMAP_NEAREST = $2701 +GL_NEAREST_MIPMAP_LINEAR = $2702 +GL_LINEAR_MIPMAP_LINEAR = $2703 +GL_TEXTURE_MAG_FILTER = $2800 +GL_TEXTURE_MIN_FILTER = $2801 +GL_TEXTURE_WRAP_R = $8072 +GL_TEXTURE_WRAP_S = $2802 +GL_TEXTURE_WRAP_T = $2803 +GL_CLAMP_TO_EDGE = $812F +GL_TEXTURE_MIN_LOD = $813A +GL_TEXTURE_MAX_LOD = $813B +GL_TEXTURE_BASE_LEVEL = $813C +GL_TEXTURE_MAX_LEVEL = $813D +GL_TEXTURE_DEPTH = $8071 +GL_PROXY_TEXTURE_1D = $8063 +GL_PROXY_TEXTURE_2D = $8064 +GL_PROXY_TEXTURE_3D = $8070 +GL_CLAMP = $2900 +GL_REPEAT = $2901 + +; Hints + +GL_DONT_CARE = $1100 +GL_FASTEST = $1101 +GL_NICEST = $1102 + +; Data types + +GL_BYTE = $1400 +GL_UNSIGNED_BYTE = $1401 +GL_SHORT = $1402 +GL_UNSIGNED_SHORT = $1403 +GL_INT = $1404 +GL_UNSIGNED_INT = $1405 +GL_FLOAT = $1406 +GL_2_BYTES = $1407 +GL_3_BYTES = $1408 +GL_4_BYTES = $1409 +GL_DOUBLE = $140A +GL_DOUBLE_EXT = $140A + +; Logic operations + +GL_CLEAR = $1500 +GL_AND = $1501 +GL_AND_REVERSE = $1502 +GL_COPY = $1503 +GL_AND_INVERTED = $1504 +GL_NOOP = $1505 +GL_XOR = $1506 +GL_OR = $1507 +GL_NOR = $1508 +GL_EQUIV = $1509 +GL_INVERT = $150A +GL_OR_REVERSE = $150B +GL_COPY_INVERTED = $150C +GL_OR_INVERTED = $150D +GL_NAND = $150E +GL_SET = $150F + +; PixelCopyType + +GL_COLOR = $1800 +GL_DEPTH = $1801 +GL_STENCIL = $1802 + +; Pixel formats + +GL_COLOR_INDEX = $1900 +GL_STENCIL_INDEX = $1901 +GL_DEPTH_COMPONENT = $1902 +GL_RED = $1903 +GL_GREEN = $1904 +GL_BLUE = $1905 +GL_ALPHA = $1906 +GL_RGB = $1907 +GL_RGBA = $1908 +GL_LUMINANCE = $1909 +GL_LUMINANCE_ALPHA = $190A + +; Pixel type + +GL_BITMAP = $1A00 + +; Rendering modes + +GL_RENDER = $1C00 +GL_FEEDBACK = $1C01 +GL_SELECT = $1C02 + +; Implementation strings + +GL_VENDOR = $1F00 +GL_RENDERER = $1F01 +GL_VERSION = $1F02 +GL_EXTENSIONS = $1F03 + +; Pixel formats + +GL_R3_G3_B2 = $2A10 +GL_ALPHA4 = $803B +GL_ALPHA8 = $803C +GL_ALPHA12 = $803D +GL_ALPHA16 = $803E +GL_LUMINANCE4 = $803F +GL_LUMINANCE8 = $8040 +GL_LUMINANCE12 = $8041 +GL_LUMINANCE16 = $8042 +GL_LUMINANCE4_ALPHA4 = $8043 +GL_LUMINANCE6_ALPHA2 = $8044 +GL_LUMINANCE8_ALPHA8 = $8045 +GL_LUMINANCE12_ALPHA4 = $8046 +GL_LUMINANCE12_ALPHA12 = $8047 +GL_LUMINANCE16_ALPHA16 = $8048 +GL_INTENSITY = $8049 +GL_INTENSITY4 = $804A +GL_INTENSITY8 = $804B +GL_INTENSITY12 = $804C +GL_INTENSITY16 = $804D +GL_RGB4 = $804F +GL_RGB5 = $8050 +GL_RGB8 = $8051 +GL_RGB10 = $8052 +GL_RGB12 = $8053 +GL_RGB16 = $8054 +GL_RGBA2 = $8055 +GL_RGBA4 = $8056 +GL_RGB5_A1 = $8057 +GL_RGBA8 = $8058 +GL_RGB10_A2 = $8059 +GL_RGBA12 = $805A +GL_RGBA16 = $805B +UNSIGNED_BYTE_3_3_2 = $8032 +UNSIGNED_BYTE_2_3_3_REV = $8362 +UNSIGNED_SHORT_5_6_5 = $8363 +UNSIGNED_SHORT_5_6_5_REV = $8364 +UNSIGNED_SHORT_4_4_4_4 = $8033 +UNSIGNED_SHORT_4_4_4_4_REV = $8365 +UNSIGNED_SHORT_5_5_5_1 = $8034 +UNSIGNED_SHORT_1_5_5_5_REV = $8366 +UNSIGNED_INT_8_8_8_8 = $8035 +UNSIGNED_INT_8_8_8_8_REV = $8367 +UNSIGNED_INT_10_10_10_2 = $8036 +UNSIGNED_INT_2_10_10_10_REV = $8368 + +; Interleaved arrays formats + +GL_V2F = $2A20 +GL_V3F = $2A21 +GL_C4UB_V2F = $2A22 +GL_C4UB_V3F = $2A23 +GL_C3F_V3F = $2A24 +GL_N3F_V3F = $2A25 +GL_C4F_N3F_V3F = $2A26 +GL_T2F_V3F = $2A27 +GL_T4F_V4F = $2A28 +GL_T2F_C4UB_V3F = $2A29 +GL_T2F_C3F_V3F = $2A2A +GL_T2F_N3F_V3F = $2A2B +GL_T2F_C4F_N3F_V3F = $2A2C +GL_T4F_C4F_N3F_V4F = $2A2D + +; Clip planes + +GL_CLIP_PLANE0 = $3000 +GL_CLIP_PLANE1 = $3001 +GL_CLIP_PLANE2 = $3002 +GL_CLIP_PLANE3 = $3003 +GL_CLIP_PLANE4 = $3004 +GL_CLIP_PLANE5 = $3005 + +; Miscellaneous + +GL_DITHER = $0BD0 + +; EXT_abgr + +GL_ABGR_EXT = $8000 + +; EXT_packed_pixels + +GL_UNSIGNED_BYTE_3_3_2_EXT = $8032 +GL_UNSIGNED_SHORT_4_4_4_4_EXT = $8033 +GL_UNSIGNED_SHORT_5_5_5_1_EXT = $8034 +GL_UNSIGNED_INT_8_8_8_8_EXT = $8035 +GL_UNSIGNED_INT_10_10_10_2_EXT = $8036 + +; EXT_vertex_array + +GL_VERTEX_ARRAY_EXT = $8074 +GL_NORMAL_ARRAY_EXT = $8075 +GL_COLOR_ARRAY_EXT = $8076 +GL_INDEX_ARRAY_EXT = $8077 +GL_TEXTURE_COORD_ARRAY_EXT = $8078 +GL_EDGE_FLAG_ARRAY_EXT = $8079 +GL_VERTEX_ARRAY_SIZE_EXT = $807A +GL_VERTEX_ARRAY_TYPE_EXT = $807B +GL_VERTEX_ARRAY_STRIDE_EXT = $807C +GL_VERTEX_ARRAY_COUNT_EXT = $807D +GL_NORMAL_ARRAY_TYPE_EXT = $807E +GL_NORMAL_ARRAY_STRIDE_EXT = $807F +GL_NORMAL_ARRAY_COUNT_EXT = $8080 +GL_COLOR_ARRAY_SIZE_EXT = $8081 +GL_COLOR_ARRAY_TYPE_EXT = $8082 +GL_COLOR_ARRAY_STRIDE_EXT = $8083 +GL_COLOR_ARRAY_COUNT_EXT = $8084 +GL_INDEX_ARRAY_TYPE_EXT = $8085 +GL_INDEX_ARRAY_STRIDE_EXT = $8086 +GL_INDEX_ARRAY_COUNT_EXT = $8087 +GL_TEXTURE_COORD_ARRAY_SIZE_EXT = $8088 +GL_TEXTURE_COORD_ARRAY_TYPE_EXT = $8089 +GL_TEXTURE_COORD_ARRAY_STRIDE_EXT = $808A +GL_TEXTURE_COORD_ARRAY_COUNT_EXT = $808B +GL_EDGE_FLAG_ARRAY_STRIDE_EXT = $808C +GL_EDGE_FLAG_ARRAY_COUNT_EXT = $808D +GL_VERTEX_ARRAY_POINTER_EXT = $808E +GL_NORMAL_ARRAY_POINTER_EXT = $808F +GL_COLOR_ARRAY_POINTER_EXT = $8090 +GL_INDEX_ARRAY_POINTER_EXT = $8091 +GL_TEXTURE_COORD_ARRAY_POINTER_EXT = $8092 +GL_EDGE_FLAG_ARRAY_POINTER_EXT = $8093 + +; EXT_color_table + +GL_TABLE_TOO_LARGE_EXT = $8031 +GL_COLOR_TABLE_EXT = $80D0 +GL_POST_CONVOLUTION_COLOR_TABLE_EXT = $80D1 +GL_POST_COLOR_MATRIX_COLOR_TABLE_EXT = $80D2 +GL_PROXY_COLOR_TABLE_EXT = $80D3 +GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_EXT = $80D4 +GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_EXT = $80D5 +GL_COLOR_TABLE_SCALE_EXT = $80D6 +GL_COLOR_TABLE_BIAS_EXT = $80D7 +GL_COLOR_TABLE_FORMAT_EXT = $80D8 +GL_COLOR_TABLE_WIDTH_EXT = $80D9 +GL_COLOR_TABLE_RED_SIZE_EXT = $80DA +GL_COLOR_TABLE_GREEN_SIZE_EXT = $80DB +GL_COLOR_TABLE_BLUE_SIZE_EXT = $80DC +GL_COLOR_TABLE_ALPHA_SIZE_EXT = $80DD +GL_COLOR_TABLE_LUMINANCE_SIZE_EXT = $80DE +GL_COLOR_TABLE_INTENSITY_SIZE_EXT = $80DF + +; EXT_bgra + +GL_BGR_EXT = $80E0 +GL_BGRA_EXT = $80E1 + +; EXT_paletted_texture + +GL_COLOR_INDEX1_EXT = $80E2 +GL_COLOR_INDEX2_EXT = $80E3 +GL_COLOR_INDEX4_EXT = $80E4 +GL_COLOR_INDEX8_EXT = $80E5 +GL_COLOR_INDEX12_EXT = $80E6 +GL_COLOR_INDEX16_EXT = $80E7 + +; EXT_blend_color + +GL_CONSTANT_COLOR_EXT = $8001 +GL_ONE_MINUS_CONSTANT_COLOR_EXT = $8002 +GL_CONSTANT_ALPHA_EXT = $8003 +GL_ONE_MINUS_CONSTANT_ALPHA_EXT = $8004 +GL_BLEND_COLOR_EXT = $8005 + +; EXT_blend_minmax + +GL_FUNC_ADD_EXT = $8006 +GL_MIN_EXT = $8007 +GL_MAX_EXT = $8008 +GL_BLEND_EQUATION_EXT = $8009 + +; EXT_blend_subtract + +GL_FUNC_SUBTRACT_EXT = $800A +GL_FUNC_REVERSE_SUBTRACT_EXT = $800B + +; EXT_convolution + +GL_CONVOLUTION_1D_EXT = $8010 +GL_CONVOLUTION_2D_EXT = $8011 +GL_SEPARABLE_2D_EXT = $8012 +GL_CONVOLUTION_BORDER_MODE_EXT = $8013 +GL_CONVOLUTION_FILTER_SCALE_EXT = $8014 +GL_CONVOLUTION_FILTER_BIAS_EXT = $8015 +GL_REDUCE_EXT = $8016 +GL_CONVOLUTION_FORMAT_EXT = $8017 +GL_CONVOLUTION_WIDTH_EXT = $8018 +GL_CONVOLUTION_HEIGHT_EXT = $8019 +GL_MAX_CONVOLUTION_WIDTH_EXT = $801A +GL_MAX_CONVOLUTION_HEIGHT_EXT = $801B +GL_POST_CONVOLUTION_RED_SCALE_EXT = $801C +GL_POST_CONVOLUTION_GREEN_SCALE_EXT = $801D +GL_POST_CONVOLUTION_BLUE_SCALE_EXT = $801E +GL_POST_CONVOLUTION_ALPHA_SCALE_EXT = $801F +GL_POST_CONVOLUTION_RED_BIAS_EXT = $8020 +GL_POST_CONVOLUTION_GREEN_BIAS_EXT = $8021 +GL_POST_CONVOLUTION_BLUE_BIAS_EXT = $8022 +GL_POST_CONVOLUTION_ALPHA_BIAS_EXT = $8023 + +; EXT_histogram + +GL_HISTOGRAM_EXT = $8024 +GL_PROXY_HISTOGRAM_EXT = $8025 +GL_HISTOGRAM_WIDTH_EXT = $8026 +GL_HISTOGRAM_FORMAT_EXT = $8027 +GL_HISTOGRAM_RED_SIZE_EXT = $8028 +GL_HISTOGRAM_GREEN_SIZE_EXT = $8029 +GL_HISTOGRAM_BLUE_SIZE_EXT = $802A +GL_HISTOGRAM_ALPHA_SIZE_EXT = $802B +GL_HISTOGRAM_LUMINANCE_SIZE_EXT = $802C +GL_HISTOGRAM_SINK_EXT = $802D +GL_MINMAX_EXT = $802E +GL_MINMAX_FORMAT_EXT = $802F +GL_MINMAX_SINK_EXT = $8030 + +; EXT_polygon_offset + +GL_POLYGON_OFFSET_EXT = $8037 +GL_POLYGON_OFFSET_FACTOR_EXT = $8038 +GL_POLYGON_OFFSET_BIAS_EXT = $8039 + +; EXT_texture + +GL_ALPHA4_EXT = $803B +GL_ALPHA8_EXT = $803C +GL_ALPHA12_EXT = $803D +GL_ALPHA16_EXT = $803E +GL_LUMINANCE4_EXT = $803F +GL_LUMINANCE8_EXT = $8040 +GL_LUMINANCE12_EXT = $8041 +GL_LUMINANCE16_EXT = $8042 +GL_LUMINANCE4_ALPHA4_EXT = $8043 +GL_LUMINANCE6_ALPHA2_EXT = $8044 +GL_LUMINANCE8_ALPHA8_EXT = $8045 +GL_LUMINANCE12_ALPHA4_EXT = $8046 +GL_LUMINANCE12_ALPHA12_EXT = $8047 +GL_LUMINANCE16_ALPHA16_EXT = $8048 +GL_INTENSITY_EXT = $8049 +GL_INTENSITY4_EXT = $804A +GL_INTENSITY8_EXT = $804B +GL_INTENSITY12_EXT = $804C +GL_INTENSITY16_EXT = $804D +GL_RGB2_EXT = $804E +GL_RGB4_EXT = $804F +GL_RGB5_EXT = $8050 +GL_RGB8_EXT = $8051 +GL_RGB10_EXT = $8052 +GL_RGB12_EXT = $8053 +GL_RGB16_EXT = $8054 +GL_RGBA2_EXT = $8055 +GL_RGBA4_EXT = $8056 +GL_RGB5_A1_EXT = $8057 +GL_RGBA8_EXT = $8058 +GL_RGB10_A2_EXT = $8059 +GL_RGBA12_EXT = $805A +GL_RGBA16_EXT = $805B +GL_TEXTURE_RED_SIZE_EXT = $805C +GL_TEXTURE_GREEN_SIZE_EXT = $805D +GL_TEXTURE_BLUE_SIZE_EXT = $805E +GL_TEXTURE_ALPHA_SIZE_EXT = $805F +GL_TEXTURE_LUMINANCE_SIZE_EXT = $8060 +GL_TEXTURE_INTENSITY_SIZE_EXT = $8061 +GL_REPLACE_EXT = $8062 +GL_PROXY_TEXTURE_1D_EXT = $8063 +GL_PROXY_TEXTURE_2D_EXT = $8064 +GL_TEXTURE_TOO_LARGE_EXT = $8065 + +; EXT_texture_object + +GL_TEXTURE_PRIORITY_EXT = $8066 +GL_TEXTURE_RESIDENT_EXT = $8067 +GL_TEXTURE_1D_BINDING_EXT = $8068 +GL_TEXTURE_2D_BINDING_EXT = $8069 +GL_TEXTURE_3D_BINDING_EXT = $806A + +; EXT_texture3D + +GL_PACK_SKIP_IMAGES_EXT = $806B +GL_PACK_IMAGE_HEIGHT_EXT = $806C +GL_UNPACK_SKIP_IMAGES_EXT = $806D +GL_UNPACK_IMAGE_HEIGHT_EXT = $806E +GL_TEXTURE_3D_EXT = $806F +GL_PROXY_TEXTURE_3D_EXT = $8070 +GL_TEXTURE_DEPTH_EXT = $8071 +GL_TEXTURE_WRAP_R_EXT = $8072 +GL_MAX_3D_TEXTURE_SIZE_EXT = $8073 + +; SGI_color_matrix + +GL_COLOR_MATRIX_SGI = $80B1 +GL_COLOR_MATRIX_STACK_DEPTH_SGI = $80B2 +GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI = $80B3 +GL_POST_COLOR_MATRIX_RED_SCALE_SGI = $80B4 +GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI = $80B5 +GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI = $80B6 +GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI = $80B7 +GL_POST_COLOR_MATRIX_RED_BIAS_SGI = $80B8 +GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI = $80B9 +GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI = $80BA +GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI = $80BB + +; SGI_texture_color_table + +GL_TEXTURE_COLOR_TABLE_SGI = $80BC +GL_PROXY_TEXTURE_COLOR_TABLE_SGI = $80BD +GL_TEXTURE_COLOR_TABLE_BIAS_SGI = $80BE +GL_TEXTURE_COLOR_TABLE_SCALE_SGI = $80BF + +; SGI_color_table + +GL_COLOR_TABLE_SGI = $80D0 +GL_POST_CONVOLUTION_COLOR_TABLE_SGI = $80D1 +GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI = $80D2 +GL_PROXY_COLOR_TABLE_SGI = $80D3 +GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI = $80D4 +GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI = $80D5 +GL_COLOR_TABLE_SCALE_SGI = $80D6 +GL_COLOR_TABLE_BIAS_SGI = $80D7 +GL_COLOR_TABLE_FORMAT_SGI = $80D8 +GL_COLOR_TABLE_WIDTH_SGI = $80D9 +GL_COLOR_TABLE_RED_SIZE_SGI = $80DA +GL_COLOR_TABLE_GREEN_SIZE_SGI = $80DB +GL_COLOR_TABLE_BLUE_SIZE_SGI = $80DC +GL_COLOR_TABLE_ALPHA_SIZE_SGI = $80DD +GL_COLOR_TABLE_LUMINANCE_SIZE_SGI = $80DE +GL_COLOR_TABLE_INTENSITY_SIZE_SGI = $80DF + +; EXT_cmyka + +GL_CMYK_EXT = $800C +GL_CMYKA_EXT = $800D +GL_PACK_CMYK_HINT_EXT = $800E +GL_UNPACK_CMYK_HINT_EXT = $800F + +; EXT_rescale_normal + +GL_RESCALE_NORMAL_EXT = $803A + +; EXT_clip_volume_hint + +GL_CLIP_VOLUME_CLIPPING_HINT_EXT = $80F0 + +; EXT_cull_vertex + +GL_CULL_VERTEX_EXT = $81AA +GL_CULL_VERTEX_EYE_POSITION_EXT = $81AB +GL_CULL_VERTEX_OBJECT_POSITION_EXT = $81AC + +; EXT_index_array_formats + +GL_IUI_V2F_EXT = $81AD +GL_IUI_V3F_EXT = $81AE +GL_IUI_N3F_V2F_EXT = $81AF +GL_IUI_N3F_V3F_EXT = $81B0 +GL_T2F_IUI_V2F_EXT = $81B1 +GL_T2F_IUI_V3F_EXT = $81B2 +GL_T2F_IUI_N3F_V2F_EXT = $81B3 +GL_T2F_IUI_N3F_V3F_EXT = $81B4 + +; EXT_index_func + +GL_INDEX_TEST_EXT = $81B5 +GL_INDEX_TEST_FUNC_EXT = $81B6 +GL_INDEX_TEST_REF_EXT = $81B7 + +; EXT_index_material + +GL_INDEX_MATERIAL_EXT = $81B8 +GL_INDEX_MATERIAL_PARAMETER_EXT = $81B9 +GL_INDEX_MATERIAL_FACE_EXT = $81BA + +; EXT_shared_texture_palette + +GL_SHARED_TEXTURE_PALETTE_EXT = $81FB + +; EXT_nurbs_tessellator + +GLU_NURBS_MODE_EXT = 100160 +GLU_NURBS_TESSELLATOR_EXT = 100161 +GLU_NURBS_RENDERER_EXT = 100162 +GLU_NURBS_BEGIN_EXT = 100164 +GLU_NURBS_VERTEX_EXT = 100165 +GLU_NURBS_NORMAL_EXT = 100166 +GLU_NURBS_COLOR_EXT = 100167 +GLU_NURBS_TEX_COORD_EXT = 100168 +GLU_NURBS_END_EXT = 100169 +GLU_NURBS_BEGIN_DATA_EXT = 100170 +GLU_NURBS_VERTEX_DATA_EXT = 100171 +GLU_NURBS_NORMAL_DATA_EXT = 100172 +GLU_NURBS_COLOR_DATA_EXT = 100173 +GLU_NURBS_TEX_COORD_DATA_EXT = 100174 +GLU_NURBS_END_DATA_EXT = 100175 + +; EXT_object_space_tess + +GLU_OBJECT_PARAMETRIC_ERROR_EXT = 100208 +GLU_OBJECT_PATH_LENGTH_EXT = 100209 + +; EXT_point_parameters + +GL_POINT_SIZE_MIN_EXT = $8126 +GL_POINT_SIZE_MAX_EXT = $8127 +GL_POINT_FADE_THRESHOLD_SIZE_EXT = $8128 +GL_DISTANCE_ATTENUATION_EXT = $8129 + +; EXT_compiled_vertex_array + +GL_ARRAY_ELEMENT_LOCK_FIRST_EXT = $81A8 +GL_ARRAY_ELEMENT_LOCK_COUNT_EXT = $81A9 + +; ARB_multitexture + +GL_ACTIVE_TEXTURE_ARB = $84E0 +GL_CLIENT_ACTIVE_TEXTURE_ARB = $84E1 +GL_MAX_TEXTURE_UNITS_ARB = $84E2 +GL_TEXTURE0_ARB = $84C0 +GL_TEXTURE1_ARB = $84C1 +GL_TEXTURE2_ARB = $84C2 +GL_TEXTURE3_ARB = $84C3 +GL_TEXTURE4_ARB = $84C4 +GL_TEXTURE5_ARB = $84C5 +GL_TEXTURE6_ARB = $84C6 +GL_TEXTURE7_ARB = $84C7 +GL_TEXTURE8_ARB = $84C8 +GL_TEXTURE9_ARB = $84C9 +GL_TEXTURE10_ARB = $84CA +GL_TEXTURE11_ARB = $84CB +GL_TEXTURE12_ARB = $84CC +GL_TEXTURE13_ARB = $84CD +GL_TEXTURE14_ARB = $84CE +GL_TEXTURE15_ARB = $84CF +GL_TEXTURE16_ARB = $84D0 +GL_TEXTURE17_ARB = $84D1 +GL_TEXTURE18_ARB = $84D2 +GL_TEXTURE19_ARB = $84D3 +GL_TEXTURE20_ARB = $84D4 +GL_TEXTURE21_ARB = $84D5 +GL_TEXTURE22_ARB = $84D6 +GL_TEXTURE23_ARB = $84D7 +GL_TEXTURE24_ARB = $84D8 +GL_TEXTURE25_ARB = $84D9 +GL_TEXTURE26_ARB = $84DA +GL_TEXTURE27_ARB = $84DB +GL_TEXTURE28_ARB = $84DC +GL_TEXTURE29_ARB = $84DD +GL_TEXTURE30_ARB = $84DE +GL_TEXTURE31_ARB = $84DF + +; EXT_stencil_wrap + +GL_INCR_WRAP_EXT = $8507 +GL_DECR_WRAP_EXT = $8508 + +; NV_texgen_reflection + +GL_NORMAL_MAP_NV = $8511 +GL_REFLECTION_MAP_NV = $8512 + +; EXT_texture_env_combine + +GL_COMBINE_EXT = $8570 +GL_COMBINE_RGB_EXT = $8571 +GL_COMBINE_ALPHA_EXT = $8572 +GL_RGB_SCALE_EXT = $8573 +GL_ADD_SIGNED_EXT = $8574 +GL_INTERPOLATE_EXT = $8575 +GL_CONSTANT_EXT = $8576 +GL_PRIMARY_COLOR_EXT = $8577 +GL_PREVIOUS_EXT = $8578 +GL_SOURCE0_RGB_EXT = $8580 +GL_SOURCE1_RGB_EXT = $8581 +GL_SOURCE2_RGB_EXT = $8582 +GL_SOURCE0_ALPHA_EXT = $8588 +GL_SOURCE1_ALPHA_EXT = $8589 +GL_SOURCE2_ALPHA_EXT = $858A +GL_OPERAND0_RGB_EXT = $8590 +GL_OPERAND1_RGB_EXT = $8591 +GL_OPERAND2_RGB_EXT = $8592 +GL_OPERAND0_ALPHA_EXT = $8598 +GL_OPERAND1_ALPHA_EXT = $8599 +GL_OPERAND2_ALPHA_EXT = $859A + +; NV_texture_env_combine4 + +GL_COMBINE4_NV = $8503 +GL_SOURCE3_RGB_NV = $8583 +GL_SOURCE3_ALPHA_NV = $858B +GL_OPERAND3_RGB_NV = $8593 +GL_OPERAND3_ALPHA_NV = $859B + +GL_BLEND_EQUATION = $8009 +GL_TABLE_TOO_LARGE = $8031 +GL_UNSIGNED_BYTE_3_3_2 = $8032 +GL_UNSIGNED_SHORT_4_4_4_4 = $8033 +GL_UNSIGNED_SHORT_5_5_5_1 = $8034 +GL_UNSIGNED_INT_8_8_8_8 = $8035 +GL_UNSIGNED_INT_10_10_10_2 = $8036 +GL_UNSIGNED_BYTE_2_3_3_REV = $8362 +GL_UNSIGNED_SHORT_5_6_5 = $8363 +GL_UNSIGNED_SHORT_5_6_5_REV = $8364 +GL_UNSIGNED_SHORT_4_4_4_4_REV = $8365 +GL_UNSIGNED_SHORT_1_5_5_5_REV = $8366 +GL_UNSIGNED_INT_8_8_8_8_REV = $8367 +GL_UNSIGNED_INT_2_10_10_10_REV = $8368 + +; GL_ARB_transpose_matrix + +GL_TRANSPOSE_MODELVIEW_MATRIX_ARB = $84E3 +GL_TRANSPOSE_PROJECTION_MATRIX_ARB = $84E4 +GL_TRANSPOSE_TEXTURE_MATRIX_ARB = $84E5 +GL_TRANSPOSE_COLOR_MATRIX_ARB = $84E6 + +; GL_ARB_multisample + +GL_MULTISAMPLE_ARB = $809D +GL_SAMPLE_ALPHA_TO_COVERAGE_ARB = $809E +GL_SAMPLE_ALPHA_TO_ONE_ARB = $809F +GL_SAMPLE_COVERAGE_ARB = $80A0 +GL_SAMPLE_BUFFERS_ARB = $80A8 +GL_SAMPLES_ARB = $80A9 +GL_SAMPLE_COVERAGE_VALUE_ARB = $80AA +GL_SAMPLE_COVERAGE_INVERT_ARB = $80AB +GL_MULTISAMPLE_BIT_ARB = $20000000 + +; GL_ARB_texture_cube_map + +GL_NORMAL_MAP_ARB = $8511 +GL_REFLECTION_MAP_ARB = $8512 +GL_TEXTURE_CUBE_MAP_ARB = $8513 +GL_TEXTURE_BINDING_CUBE_MAP_ARB = $8514 +GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB = $8515 +GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB = $8516 +GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB = $8517 +GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB = $8518 +GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB = $8519 +GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB = $851A +GL_PROXY_TEXTURE_CUBE_MAP_ARB = $851B +GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB = $851C + +; GL_ARB_texture_compression + +GL_COMPRESSED_ALPHA_ARB = $84E9 +GL_COMPRESSED_LUMINANCE_ARB = $84EA +GL_COMPRESSED_LUMINANCE_ALPHA_ARB = $84EB +GL_COMPRESSED_INTENSITY_ARB = $84EC +GL_COMPRESSED_RGB_ARB = $84ED +GL_COMPRESSED_RGBA_ARB = $84EE +GL_TEXTURE_COMPRESSION_HINT_ARB = $84EF +GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB = $86A0 +GL_TEXTURE_COMPRESSED_ARB = $86A1 +GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB = $86A2 +GL_COMPRESSED_TEXTURE_FORMATS_ARB = $86A3 + +; GL_ARB_vertex_blend + +GL_MAX_VERTEX_UNITS_ARB = $86A4 +GL_ACTIVE_VERTEX_UNITS_ARB = $86A5 +GL_WEIGHT_SUM_UNITY_ARB = $86A6 +GL_VERTEX_BLEND_ARB = $86A7 +GL_CURRENT_WEIGHT_ARB = $86A8 +GL_WEIGHT_ARRAY_TYPE_ARB = $86A9 +GL_WEIGHT_ARRAY_STRIDE_ARB = $86AA +GL_WEIGHT_ARRAY_SIZE_ARB = $86AB +GL_WEIGHT_ARRAY_POINTER_ARB = $86AC +GL_WEIGHT_ARRAY_ARB = $86AD +GL_MODELVIEW0_ARB = $1700 +GL_MODELVIEW1_ARB = $850A +GL_MODELVIEW2_ARB = $8722 +GL_MODELVIEW3_ARB = $8723 +GL_MODELVIEW4_ARB = $8724 +GL_MODELVIEW5_ARB = $8725 +GL_MODELVIEW6_ARB = $8726 +GL_MODELVIEW7_ARB = $8727 +GL_MODELVIEW8_ARB = $8728 +GL_MODELVIEW9_ARB = $8729 +GL_MODELVIEW10_ARB = $872A +GL_MODELVIEW11_ARB = $872B +GL_MODELVIEW12_ARB = $872C +GL_MODELVIEW13_ARB = $872D +GL_MODELVIEW14_ARB = $872E +GL_MODELVIEW15_ARB = $872F +GL_MODELVIEW16_ARB = $8730 +GL_MODELVIEW17_ARB = $8731 +GL_MODELVIEW18_ARB = $8732 +GL_MODELVIEW19_ARB = $8733 +GL_MODELVIEW20_ARB = $8734 +GL_MODELVIEW21_ARB = $8735 +GL_MODELVIEW22_ARB = $8736 +GL_MODELVIEW23_ARB = $8737 +GL_MODELVIEW24_ARB = $8738 +GL_MODELVIEW25_ARB = $8739 +GL_MODELVIEW26_ARB = $873A +GL_MODELVIEW27_ARB = $873B +GL_MODELVIEW28_ARB = $873C +GL_MODELVIEW29_ARB = $873D +GL_MODELVIEW30_ARB = $873E +GL_MODELVIEW31_ARB = $873F + +; GL_SGIS_texture_filter4 + +GL_FILTER4_SGIS = $8146 +GL_TEXTURE_FILTER4_SIZE_SGIS = $8147 + +; GL_SGIS_pixel_texture + +GL_PIXEL_TEXTURE_SGIS = $8353 +GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS = $8354 +GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS = $8355 +GL_PIXEL_GROUP_COLOR_SGIS = $8356 + +; GL_SGIX_pixel_texture + +GL_PIXEL_TEX_GEN_SGIX = $8139 +GL_PIXEL_TEX_GEN_MODE_SGIX = $832B + +; GL_SGIS_texture4D + +GL_PACK_SKIP_VOLUMES_SGIS = $8130 +GL_PACK_IMAGE_DEPTH_SGIS = $8131 +GL_UNPACK_SKIP_VOLUMES_SGIS = $8132 +GL_UNPACK_IMAGE_DEPTH_SGIS = $8133 +GL_TEXTURE_4D_SGIS = $8134 +GL_PROXY_TEXTURE_4D_SGIS = $8135 +GL_TEXTURE_4DSIZE_SGIS = $8136 +GL_TEXTURE_WRAP_Q_SGIS = $8137 +GL_MAX_4D_TEXTURE_SIZE_SGIS = $8138 +GL_TEXTURE_4D_BINDING_SGIS = $814F + +; GL_SGIS_detail_texture + +GL_DETAIL_TEXTURE_2D_SGIS = $8095 +GL_DETAIL_TEXTURE_2D_BINDING_SGIS = $8096 +GL_LINEAR_DETAIL_SGIS = $8097 +GL_LINEAR_DETAIL_ALPHA_SGIS = $8098 +GL_LINEAR_DETAIL_COLOR_SGIS = $8099 +GL_DETAIL_TEXTURE_LEVEL_SGIS = $809A +GL_DETAIL_TEXTURE_MODE_SGIS = $809B +GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS = $809C + +; GL_SGIS_sharpen_texture + +GL_LINEAR_SHARPEN_SGIS = $80AD +GL_LINEAR_SHARPEN_ALPHA_SGIS = $80AE +GL_LINEAR_SHARPEN_COLOR_SGIS = $80AF +GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS = $80B0 + +; GL_SGIS_texture_lod + +GL_TEXTURE_MIN_LOD_SGIS = $813A +GL_TEXTURE_MAX_LOD_SGIS = $813B +GL_TEXTURE_BASE_LEVEL_SGIS = $813C +GL_TEXTURE_MAX_LEVEL_SGIS = $813D + +; GL_SGIS_multisample + +GL_MULTISAMPLE_SGIS = $809D +GL_SAMPLE_ALPHA_TO_MASK_SGIS = $809E +GL_SAMPLE_ALPHA_TO_ONE_SGIS = $809F +GL_SAMPLE_MASK_SGIS = $80A0 +GL_1PASS_SGIS = $80A1 +GL_2PASS_0_SGIS = $80A2 +GL_2PASS_1_SGIS = $80A3 +GL_4PASS_0_SGIS = $80A4 +GL_4PASS_1_SGIS = $80A5 +GL_4PASS_2_SGIS = $80A6 +GL_4PASS_3_SGIS = $80A7 +GL_SAMPLE_BUFFERS_SGIS = $80A8 +GL_SAMPLES_SGIS = $80A9 +GL_SAMPLE_MASK_VALUE_SGIS = $80AA +GL_SAMPLE_MASK_INVERT_SGIS = $80AB +GL_SAMPLE_PATTERN_SGIS = $80AC + +; GL_SGIS_generate_mipmap + +GL_GENERATE_MIPMAP_SGIS = $8191 +GL_GENERATE_MIPMAP_HINT_SGIS = $8192 + +; GL_SGIX_clipmap + +GL_LINEAR_CLIPMAP_LINEAR_SGIX = $8170 +GL_TEXTURE_CLIPMAP_CENTER_SGIX = $8171 +GL_TEXTURE_CLIPMAP_FRAME_SGIX = $8172 +GL_TEXTURE_CLIPMAP_OFFSET_SGIX = $8173 +GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX = $8174 +GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX = $8175 +GL_TEXTURE_CLIPMAP_DEPTH_SGIX = $8176 +GL_MAX_CLIPMAP_DEPTH_SGIX = $8177 +GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX = $8178 +GL_NEAREST_CLIPMAP_NEAREST_SGIX = $844D +GL_NEAREST_CLIPMAP_LINEAR_SGIX = $844E +GL_LINEAR_CLIPMAP_NEAREST_SGIX = $844F + +; GL_SGIX_shadow + +GL_TEXTURE_COMPARE_SGIX = $819A +GL_TEXTURE_COMPARE_OPERATOR_SGIX = $819B +GL_TEXTURE_LEQUAL_R_SGIX = $819C +GL_TEXTURE_GEQUAL_R_SGIX = $819D + +; GL_SGIS_texture_edge_clamp + +GL_CLAMP_TO_EDGE_SGIS = $812F + +; GL_SGIS_texture_border_clamp + +GL_CLAMP_TO_BORDER_SGIS = $812D + +; GL_SGIX_interlace + +GL_INTERLACE_SGIX = $8094 + +; GL_SGIX_pixel_tiles + +GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX = $813E +GL_PIXEL_TILE_CACHE_INCREMENT_SGIX = $813F +GL_PIXEL_TILE_WIDTH_SGIX = $8140 +GL_PIXEL_TILE_HEIGHT_SGIX = $8141 +GL_PIXEL_TILE_GRID_WIDTH_SGIX = $8142 +GL_PIXEL_TILE_GRID_HEIGHT_SGIX = $8143 +GL_PIXEL_TILE_GRID_DEPTH_SGIX = $8144 +GL_PIXEL_TILE_CACHE_SIZE_SGIX = $8145 + +; GL_SGIS_texture_select + +GL_DUAL_ALPHA4_SGIS = $8110 +GL_DUAL_ALPHA8_SGIS = $8111 +GL_DUAL_ALPHA12_SGIS = $8112 +GL_DUAL_ALPHA16_SGIS = $8113 +GL_DUAL_LUMINANCE4_SGIS = $8114 +GL_DUAL_LUMINANCE8_SGIS = $8115 +GL_DUAL_LUMINANCE12_SGIS = $8116 +GL_DUAL_LUMINANCE16_SGIS = $8117 +GL_DUAL_INTENSITY4_SGIS = $8118 +GL_DUAL_INTENSITY8_SGIS = $8119 +GL_DUAL_INTENSITY12_SGIS = $811A +GL_DUAL_INTENSITY16_SGIS = $811B +GL_DUAL_LUMINANCE_ALPHA4_SGIS = $811C +GL_DUAL_LUMINANCE_ALPHA8_SGIS = $811D +GL_QUAD_ALPHA4_SGIS = $811E +GL_QUAD_ALPHA8_SGIS = $811F +GL_QUAD_LUMINANCE4_SGIS = $8120 +GL_QUAD_LUMINANCE8_SGIS = $8121 +GL_QUAD_INTENSITY4_SGIS = $8122 +GL_QUAD_INTENSITY8_SGIS = $8123 +GL_DUAL_TEXTURE_SELECT_SGIS = $8124 +GL_QUAD_TEXTURE_SELECT_SGIS = $8125 + +; GL_SGIX_sprite + +GL_SPRITE_SGIX = $8148 +GL_SPRITE_MODE_SGIX = $8149 +GL_SPRITE_AXIS_SGIX = $814A +GL_SPRITE_TRANSLATION_SGIX = $814B +GL_SPRITE_AXIAL_SGIX = $814C +GL_SPRITE_OBJECT_ALIGNED_SGIX = $814D +GL_SPRITE_EYE_ALIGNED_SGIX = $814E + +; GL_SGIX_texture_multi_buffer + +GL_TEXTURE_MULTI_BUFFER_HINT_SGIX = $812E + +; GL_SGIS_point_parameters + +GL_POINT_SIZE_MIN_SGIS = $8126 +GL_POINT_SIZE_MAX_SGIS = $8127 +GL_POINT_FADE_THRESHOLD_SIZE_SGIS = $8128 +GL_DISTANCE_ATTENUATION_SGIS = $8129 + +; GL_SGIX_instruments + +GL_INSTRUMENT_BUFFER_POINTER_SGIX = $8180 +GL_INSTRUMENT_MEASUREMENTS_SGIX = $8181 + +; GL_SGIX_texture_scale_bias + +GL_POST_TEXTURE_FILTER_BIAS_SGIX = $8179 +GL_POST_TEXTURE_FILTER_SCALE_SGIX = $817A +GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX = $817B +GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX = $817C + +; GL_SGIX_framezoom + +GL_FRAMEZOOM_SGIX = $818B +GL_FRAMEZOOM_FACTOR_SGIX = $818C +GL_MAX_FRAMEZOOM_FACTOR_SGIX = $818D + +; GL_FfdMaskSGIX + +GL_TEXTURE_DEFORMATION_BIT_SGIX = $00000001 +GL_GEOMETRY_DEFORMATION_BIT_SGIX = $00000002 + +; GL_SGIX_polynomial_ffd + +GL_GEOMETRY_DEFORMATION_SGIX = $8194 +GL_TEXTURE_DEFORMATION_SGIX = $8195 +GL_DEFORMATIONS_MASK_SGIX = $8196 +GL_MAX_DEFORMATION_ORDER_SGIX = $8197 + +; GL_SGIX_reference_plane + +GL_REFERENCE_PLANE_SGIX = $817D +GL_REFERENCE_PLANE_EQUATION_SGIX = $817E + +; GL_SGIX_depth_texture + +GL_DEPTH_COMPONENT16_SGIX = $81A5 +GL_DEPTH_COMPONENT24_SGIX = $81A6 +GL_DEPTH_COMPONENT32_SGIX = $81A7 + +; GL_SGIS_fog_function + +GL_FOG_FUNC_SGIS = $812A +GL_FOG_FUNC_POINTS_SGIS = $812B +GL_MAX_FOG_FUNC_POINTS_SGIS = $812C + +; GL_SGIX_fog_offset + +GL_FOG_OFFSET_SGIX = $8198 +GL_FOG_OFFSET_VALUE_SGIX = $8199 + +; GL_HP_image_transform + +GL_IMAGE_SCALE_X_HP = $8155 +GL_IMAGE_SCALE_Y_HP = $8156 +GL_IMAGE_TRANSLATE_X_HP = $8157 +GL_IMAGE_TRANSLATE_Y_HP = $8158 +GL_IMAGE_ROTATE_ANGLE_HP = $8159 +GL_IMAGE_ROTATE_ORIGIN_X_HP = $815A +GL_IMAGE_ROTATE_ORIGIN_Y_HP = $815B +GL_IMAGE_MAG_FILTER_HP = $815C +GL_IMAGE_MIN_FILTER_HP = $815D +GL_IMAGE_CUBIC_WEIGHT_HP = $815E +GL_CUBIC_HP = $815F +GL_AVERAGE_HP = $8160 +GL_IMAGE_TRANSFORM_2D_HP = $8161 +GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP = $8162 +GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP = $8163 + +; GL_HP_convolution_border_modes + +GL_IGNORE_BORDER_HP = $8150 +GL_CONSTANT_BORDER_HP = $8151 +GL_REPLICATE_BORDER_HP = $8153 +GL_CONVOLUTION_BORDER_COLOR_HP = $8154 + +; GL_SGIX_texture_add_env + +GL_TEXTURE_ENV_BIAS_SGIX = $80BE + +; GL_PGI_vertex_hints + +GL_VERTEX_DATA_HINT_PGI = $1A22A +GL_VERTEX_CONSISTENT_HINT_PGI = $1A22B +GL_MATERIAL_SIDE_HINT_PGI = $1A22C +GL_MAX_VERTEX_HINT_PGI = $1A22D +GL_COLOR3_BIT_PGI = $00010000 +GL_COLOR4_BIT_PGI = $00020000 +GL_EDGEFLAG_BIT_PGI = $00040000 +GL_INDEX_BIT_PGI = $00080000 +GL_MAT_AMBIENT_BIT_PGI = $00100000 +GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI = $00200000 +GL_MAT_DIFFUSE_BIT_PGI = $00400000 +GL_MAT_EMISSION_BIT_PGI = $00800000 +GL_MAT_COLOR_INDEXES_BIT_PGI = $01000000 +GL_MAT_SHININESS_BIT_PGI = $02000000 +GL_MAT_SPECULAR_BIT_PGI = $04000000 +GL_NORMAL_BIT_PGI = $08000000 +GL_TEXCOORD1_BIT_PGI = $10000000 +GL_TEXCOORD2_BIT_PGI = $20000000 +GL_TEXCOORD3_BIT_PGI = $40000000 +GL_TEXCOORD4_BIT_PGI = $80000000 +GL_VERTEX23_BIT_PGI = $00000004 +GL_VERTEX4_BIT_PGI = $00000008 + +; GL_PGI_misc_hints + +GL_PREFER_DOUBLEBUFFER_HINT_PGI = $1A1F8 +GL_CONSERVE_MEMORY_HINT_PGI = $1A1FD +GL_RECLAIM_MEMORY_HINT_PGI = $1A1FE +GL_NATIVE_GRAPHICS_HANDLE_PGI = $1A202 +GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI = $1A203 +GL_NATIVE_GRAPHICS_END_HINT_PGI = $1A204 +GL_ALWAYS_FAST_HINT_PGI = $1A20C +GL_ALWAYS_SOFT_HINT_PGI = $1A20D +GL_ALLOW_DRAW_OBJ_HINT_PGI = $1A20E +GL_ALLOW_DRAW_WIN_HINT_PGI = $1A20F +GL_ALLOW_DRAW_FRG_HINT_PGI = $1A210 +GL_ALLOW_DRAW_MEM_HINT_PGI = $1A211 +GL_STRICT_DEPTHFUNC_HINT_PGI = $1A216 +GL_STRICT_LIGHTING_HINT_PGI = $1A217 +GL_STRICT_SCISSOR_HINT_PGI = $1A218 +GL_FULL_STIPPLE_HINT_PGI = $1A219 +GL_CLIP_NEAR_HINT_PGI = $1A220 +GL_CLIP_FAR_HINT_PGI = $1A221 +GL_WIDE_LINE_HINT_PGI = $1A222 +GL_BACK_NORMALS_HINT_PGI = $1A223 + +; GL_EXT_paletted_texture + +GL_TEXTURE_INDEX_SIZE_EXT = $80ED + +; GL_SGIX_list_priority + +GL_LIST_PRIORITY_SGIX = $8182 + +; GL_SGIX_ir_instrument1 + +GL_IR_INSTRUMENT1_SGIX = $817F + +; GL_SGIX_calligraphic_fragment + +GL_CALLIGRAPHIC_FRAGMENT_SGIX = $8183 + +; GL_SGIX_texture_lod_bias + +GL_TEXTURE_LOD_BIAS_S_SGIX = $818E +GL_TEXTURE_LOD_BIAS_T_SGIX = $818F +GL_TEXTURE_LOD_BIAS_R_SGIX = $8190 + +; GL_SGIX_shadow_ambient + +GL_SHADOW_AMBIENT_SGIX = $80BF + +; GL_SGIX_ycrcb + +GL_YCRCB_422_SGIX = $81BB +GL_YCRCB_444_SGIX = $81BC + +; GL_SGIX_fragment_lighting + +GL_FRAGMENT_LIGHTING_SGIX = $8400 +GL_FRAGMENT_COLOR_MATERIAL_SGIX = $8401 +GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX = $8402 +GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX = $8403 +GL_MAX_FRAGMENT_LIGHTS_SGIX = $8404 +GL_MAX_ACTIVE_LIGHTS_SGIX = $8405 +GL_CURRENT_RASTER_NORMAL_SGIX = $8406 +GL_LIGHT_ENV_MODE_SGIX = $8407 +GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX = $8408 +GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX = $8409 +GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX = $840A +GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX = $840B +GL_FRAGMENT_LIGHT0_SGIX = $840C +GL_FRAGMENT_LIGHT1_SGIX = $840D +GL_FRAGMENT_LIGHT2_SGIX = $840E +GL_FRAGMENT_LIGHT3_SGIX = $840F +GL_FRAGMENT_LIGHT4_SGIX = $8410 +GL_FRAGMENT_LIGHT5_SGIX = $8411 +GL_FRAGMENT_LIGHT6_SGIX = $8412 +GL_FRAGMENT_LIGHT7_SGIX = $8413 + +; GL_IBM_rasterpos_clip + +GL_RASTER_POSITION_UNCLIPPED_IBM = $19262 + +; GL_HP_texture_lighting + +GL_TEXTURE_LIGHTING_MODE_HP = $8167 +GL_TEXTURE_POST_SPECULAR_HP = $8168 +GL_TEXTURE_PRE_SPECULAR_HP = $8169 + +; GL_EXT_draw_range_elements + +GL_MAX_ELEMENTS_VERTICES_EXT = $80E8 +GL_MAX_ELEMENTS_INDICES_EXT = $80E9 + +; GL_WIN_phong_shading + +GL_PHONG_WIN = $80EA +GL_PHONG_HINT_WIN = $80EB + +; GL_WIN_specular_fog + +GL_FOG_SPECULAR_TEXTURE_WIN = $80EC + +; GL_EXT_light_texture + +GL_FRAGMENT_MATERIAL_EXT = $8349 +GL_FRAGMENT_NORMAL_EXT = $834A +GL_FRAGMENT_COLOR_EXT = $834C +GL_ATTENUATION_EXT = $834D +GL_SHADOW_ATTENUATION_EXT = $834E +GL_TEXTURE_APPLICATION_MODE_EXT = $834F +GL_TEXTURE_LIGHT_EXT = $8350 +GL_TEXTURE_MATERIAL_FACE_EXT = $8351 +GL_TEXTURE_MATERIAL_PARAMETER_EXT = $8352 + +; GL_SGIX_blend_alpha_minmax + +GL_ALPHA_MIN_SGIX = $8320 +GL_ALPHA_MAX_SGIX = $8321 + +; GL_SGIX_async + +GL_ASYNC_MARKER_SGIX = $8329 + +; GL_SGIX_async_pixel + +GL_ASYNC_TEX_IMAGE_SGIX = $835C +GL_ASYNC_DRAW_PIXELS_SGIX = $835D +GL_ASYNC_READ_PIXELS_SGIX = $835E +GL_MAX_ASYNC_TEX_IMAGE_SGIX = $835F +GL_MAX_ASYNC_DRAW_PIXELS_SGIX = $8360 +GL_MAX_ASYNC_READ_PIXELS_SGIX = $8361 + +; GL_SGIX_async_histogram + +GL_ASYNC_HISTOGRAM_SGIX = $832C +GL_MAX_ASYNC_HISTOGRAM_SGIX = $832D + +; GL_INTEL_parallel_arrays + +GL_PARALLEL_ARRAYS_INTEL = $83F4 +GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL = $83F5 +GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL = $83F6 +GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL = $83F7 +GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL = $83F8 + +; GL_HP_occlusion_test + +GL_OCCLUSION_TEST_HP = $8165 +GL_OCCLUSION_TEST_RESULT_HP = $8166 + +; GL_EXT_pixel_transform + +GL_PIXEL_TRANSFORM_2D_EXT = $8330 +GL_PIXEL_MAG_FILTER_EXT = $8331 +GL_PIXEL_MIN_FILTER_EXT = $8332 +GL_PIXEL_CUBIC_WEIGHT_EXT = $8333 +GL_CUBIC_EXT = $8334 +GL_AVERAGE_EXT = $8335 +GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT = $8336 +GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT = $8337 +GL_PIXEL_TRANSFORM_2D_MATRIX_EXT = $8338 + +; GL_EXT_separate_specular_color + +GL_LIGHT_MODEL_COLOR_CONTROL_EXT = $81F8 +GL_SINGLE_COLOR_EXT = $81F9 +GL_SEPARATE_SPECULAR_COLOR_EXT = $81FA + +; GL_EXT_secondary_color + +GL_COLOR_SUM_EXT = $8458 +GL_CURRENT_SECONDARY_COLOR_EXT = $8459 +GL_SECONDARY_COLOR_ARRAY_SIZE_EXT = $845A +GL_SECONDARY_COLOR_ARRAY_TYPE_EXT = $845B +GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT = $845C +GL_SECONDARY_COLOR_ARRAY_POINTER_EXT = $845D +GL_SECONDARY_COLOR_ARRAY_EXT = $845E + +; GL_EXT_texture_perturb_normal + +GL_PERTURB_EXT = $85AE +GL_TEXTURE_NORMAL_EXT = $85AF + +; GL_EXT_fog_coord + +GL_FOG_COORDINATE_SOURCE_EXT = $8450 +GL_FOG_COORDINATE_EXT = $8451 +GL_FRAGMENT_DEPTH_EXT = $8452 +GL_CURRENT_FOG_COORDINATE_EXT = $8453 +GL_FOG_COORDINATE_ARRAY_TYPE_EXT = $8454 +GL_FOG_COORDINATE_ARRAY_STRIDE_EXT = $8455 +GL_FOG_COORDINATE_ARRAY_POINTER_EXT = $8456 +GL_FOG_COORDINATE_ARRAY_EXT = $8457 + +; GL_REND_screen_coordinates + +GL_SCREEN_COORDINATES_REND = $8490 +GL_INVERTED_SCREEN_W_REND = $8491 + +; GL_EXT_coordinate_frame + +GL_TANGENT_ARRAY_EXT = $8439 +GL_BINORMAL_ARRAY_EXT = $843A +GL_CURRENT_TANGENT_EXT = $843B +GL_CURRENT_BINORMAL_EXT = $843C +GL_TANGENT_ARRAY_TYPE_EXT = $843E +GL_TANGENT_ARRAY_STRIDE_EXT = $843F +GL_BINORMAL_ARRAY_TYPE_EXT = $8440 +GL_BINORMAL_ARRAY_STRIDE_EXT = $8441 +GL_TANGENT_ARRAY_POINTER_EXT = $8442 +GL_BINORMAL_ARRAY_POINTER_EXT = $8443 +GL_MAP1_TANGENT_EXT = $8444 +GL_MAP2_TANGENT_EXT = $8445 +GL_MAP1_BINORMAL_EXT = $8446 +GL_MAP2_BINORMAL_EXT = $8447 + +; GL_EXT_texture_env_combine + +GL_SOURCE3_RGB_EXT = $8583 +GL_SOURCE4_RGB_EXT = $8584 +GL_SOURCE5_RGB_EXT = $8585 +GL_SOURCE6_RGB_EXT = $8586 +GL_SOURCE7_RGB_EXT = $8587 +GL_SOURCE3_ALPHA_EXT = $858B +GL_SOURCE4_ALPHA_EXT = $858C +GL_SOURCE5_ALPHA_EXT = $858D +GL_SOURCE6_ALPHA_EXT = $858E +GL_SOURCE7_ALPHA_EXT = $858F +GL_OPERAND3_RGB_EXT = $8593 +GL_OPERAND4_RGB_EXT = $8594 +GL_OPERAND5_RGB_EXT = $8595 +GL_OPERAND6_RGB_EXT = $8596 +GL_OPERAND7_RGB_EXT = $8597 +GL_OPERAND3_ALPHA_EXT = $859B +GL_OPERAND4_ALPHA_EXT = $859C +GL_OPERAND5_ALPHA_EXT = $859D +GL_OPERAND6_ALPHA_EXT = $859E +GL_OPERAND7_ALPHA_EXT = $859F + +; GL_APPLE_specular_vector + +GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE = $85B0 + +; GL_APPLE_transform_hint + +GL_TRANSFORM_HINT_APPLE = $85B1 + +; GL_SGIX_fog_scale + +GL_FOG_SCALE_SGIX = $81FC +GL_FOG_SCALE_VALUE_SGIX = $81FD + +; GL_SUNX_constant_data + +GL_UNPACK_CONSTANT_DATA_SUNX = $81D5 +GL_TEXTURE_CONSTANT_DATA_SUNX = $81D6 + +; GL_SUN_global_alpha + +GL_GLOBAL_ALPHA_SUN = $81D9 +GL_GLOBAL_ALPHA_FACTOR_SUN = $81DA + +; GL_SUN_triangle_list + +GL_RESTART_SUN = $01 +GL_REPLACE_MIDDLE_SUN = $02 +GL_REPLACE_OLDEST_SUN = $03 +GL_TRIANGLE_LIST_SUN = $81D7 +GL_REPLACEMENT_CODE_SUN = $81D8 +GL_REPLACEMENT_CODE_ARRAY_SUN = $85C0 +GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN = $85C1 +GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN = $85C2 +GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN = $85C3 +GL_R1UI_V3F_SUN = $85C4 +GL_R1UI_C4UB_V3F_SUN = $85C5 +GL_R1UI_C3F_V3F_SUN = $85C6 +GL_R1UI_N3F_V3F_SUN = $85C7 +GL_R1UI_C4F_N3F_V3F_SUN = $85C8 +GL_R1UI_T2F_V3F_SUN = $85C9 +GL_R1UI_T2F_N3F_V3F_SUN = $85CA +GL_R1UI_T2F_C4F_N3F_V3F_SUN = $85CB + +; GL_EXT_blend_func_separate + +GL_BLEND_DST_RGB_EXT = $80C8 +GL_BLEND_SRC_RGB_EXT = $80C9 +GL_BLEND_DST_ALPHA_EXT = $80CA +GL_BLEND_SRC_ALPHA_EXT = $80CB + +; GL_INGR_color_clamp + +GL_RED_MIN_CLAMP_INGR = $8560 +GL_GREEN_MIN_CLAMP_INGR = $8561 +GL_BLUE_MIN_CLAMP_INGR = $8562 +GL_ALPHA_MIN_CLAMP_INGR = $8563 +GL_RED_MAX_CLAMP_INGR = $8564 +GL_GREEN_MAX_CLAMP_INGR = $8565 +GL_BLUE_MAX_CLAMP_INGR = $8566 +GL_ALPHA_MAX_CLAMP_INGR = $8567 + +; GL_INGR_interlace_read + +GL_INTERLACE_READ_INGR = $8568 + +; GL_EXT_422_pixels + +GL_422_EXT = $80CC +GL_422_REV_EXT = $80CD +GL_422_AVERAGE_EXT = $80CE +GL_422_REV_AVERAGE_EXT = $80CF + +; GL_EXT_texture_cube_map + +GL_NORMAL_MAP_EXT = $8511 +GL_REFLECTION_MAP_EXT = $8512 +GL_TEXTURE_CUBE_MAP_EXT = $8513 +GL_TEXTURE_BINDING_CUBE_MAP_EXT = $8514 +GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT = $8515 +GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT = $8516 +GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT = $8517 +GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT = $8518 +GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT = $8519 +GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT = $851A +GL_PROXY_TEXTURE_CUBE_MAP_EXT = $851B +GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT = $851C + +; GL_SUN_convolution_border_modes + +GL_WRAP_BORDER_SUN = $81D4 + +; GL_EXT_texture_lod_bias + +GL_MAX_TEXTURE_LOD_BIAS_EXT = $84FD +GL_TEXTURE_FILTER_CONTROL_EXT = $8500 +GL_TEXTURE_LOD_BIAS_EXT = $8501 + +; GL_EXT_texture_filter_anisotropic + +GL_TEXTURE_MAX_ANISOTROPY_EXT = $84FE +GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = $84FF + +; GL_EXT_vertex_weighting + +GL_MODELVIEW0_STACK_DEPTH_EXT = GL_MODELVIEW_STACK_DEPTH +GL_MODELVIEW1_STACK_DEPTH_EXT = $8502 +GL_MODELVIEW0_MATRIX_EXT = GL_MODELVIEW_MATRIX +GL_MODELVIEW_MATRIX1_EXT = $8506 +GL_VERTEX_WEIGHTING_EXT = $8509 +GL_MODELVIEW0_EXT = GL_MODELVIEW +GL_MODELVIEW1_EXT = $850A +GL_CURRENT_VERTEX_WEIGHT_EXT = $850B +GL_VERTEX_WEIGHT_ARRAY_EXT = $850C +GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT = $850D +GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT = $850E +GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT = $850F +GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT = $8510 + +; GL_NV_light_max_exponent + +GL_MAX_SHININESS_NV = $8504 +GL_MAX_SPOT_EXPONENT_NV = $8505 + +; GL_NV_vertex_array_range + +GL_VERTEX_ARRAY_RANGE_NV = $851D +GL_VERTEX_ARRAY_RANGE_LENGTH_NV = $851E +GL_VERTEX_ARRAY_RANGE_VALID_NV = $851F +GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV = $8520 +GL_VERTEX_ARRAY_RANGE_POINTER_NV = $8521 + +; GL_NV_register_combiners + +GL_REGISTER_COMBINERS_NV = $8522 +GL_VARIABLE_A_NV = $8523 +GL_VARIABLE_B_NV = $8524 +GL_VARIABLE_C_NV = $8525 +GL_VARIABLE_D_NV = $8526 +GL_VARIABLE_E_NV = $8527 +GL_VARIABLE_F_NV = $8528 +GL_VARIABLE_G_NV = $8529 +GL_CONSTANT_COLOR0_NV = $852A +GL_CONSTANT_COLOR1_NV = $852B +GL_PRIMARY_COLOR_NV = $852C +GL_SECONDARY_COLOR_NV = $852D +GL_SPARE0_NV = $852E +GL_SPARE1_NV = $852F +GL_DISCARD_NV = $8530 +GL_E_TIMES_F_NV = $8531 +GL_SPARE0_PLUS_SECONDARY_COLOR_NV = $8532 +GL_UNSIGNED_IDENTITY_NV = $8536 +GL_UNSIGNED_INVERT_NV = $8537 +GL_EXPAND_NORMAL_NV = $8538 +GL_EXPAND_NEGATE_NV = $8539 +GL_HALF_BIAS_NORMAL_NV = $853A +GL_HALF_BIAS_NEGATE_NV = $853B +GL_SIGNED_IDENTITY_NV = $853C +GL_SIGNED_NEGATE_NV = $853D +GL_SCALE_BY_TWO_NV = $853E +GL_SCALE_BY_FOUR_NV = $853F +GL_SCALE_BY_ONE_HALF_NV = $8540 +GL_BIAS_BY_NEGATIVE_ONE_HALF_NV = $8541 +GL_COMBINER_INPUT_NV = $8542 +GL_COMBINER_MAPPING_NV = $8543 +GL_COMBINER_COMPONENT_USAGE_NV = $8544 +GL_COMBINER_AB_DOT_PRODUCT_NV = $8545 +GL_COMBINER_CD_DOT_PRODUCT_NV = $8546 +GL_COMBINER_MUX_SUM_NV = $8547 +GL_COMBINER_SCALE_NV = $8548 +GL_COMBINER_BIAS_NV = $8549 +GL_COMBINER_AB_OUTPUT_NV = $854A +GL_COMBINER_CD_OUTPUT_NV = $854B +GL_COMBINER_SUM_OUTPUT_NV = $854C +GL_MAX_GENERAL_COMBINERS_NV = $854D +GL_NUM_GENERAL_COMBINERS_NV = $854E +GL_COLOR_SUM_CLAMP_NV = $854F +GL_COMBINER0_NV = $8550 +GL_COMBINER1_NV = $8551 +GL_COMBINER2_NV = $8552 +GL_COMBINER3_NV = $8553 +GL_COMBINER4_NV = $8554 +GL_COMBINER5_NV = $8555 +GL_COMBINER6_NV = $8556 +GL_COMBINER7_NV = $8557 + +; GL_NV_fog_distance + +GL_FOG_DISTANCE_MODE_NV = $855A +GL_EYE_RADIAL_NV = $855B +GL_EYE_PLANE_ABSOLUTE_NV = $855C + +; GL_NV_texgen_emboss + +GL_EMBOSS_LIGHT_NV = $855D +GL_EMBOSS_CONSTANT_NV = $855E +GL_EMBOSS_MAP_NV = $855F + +; GL_EXT_texture_compression_s3tc + +GL_COMPRESSED_RGB_S3TC_DXT1_EXT = $83F0 +GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = $83F1 +GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = $83F2 +GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = $83F3 + +; GL_IBM_cull_vertex + +GL_CULL_VERTEX_IBM = 103050 + +; GL_IBM_vertex_array_lists + +GL_VERTEX_ARRAY_LIST_IBM = 103070 +GL_NORMAL_ARRAY_LIST_IBM = 103071 +GL_COLOR_ARRAY_LIST_IBM = 103072 +GL_INDEX_ARRAY_LIST_IBM = 103073 +GL_TEXTURE_COORD_ARRAY_LIST_IBM = 103074 +GL_EDGE_FLAG_ARRAY_LIST_IBM = 103075 +GL_FOG_COORDINATE_ARRAY_LIST_IBM = 103076 +GL_SECONDARY_COLOR_ARRAY_LIST_IBM = 103077 +GL_VERTEX_ARRAY_LIST_STRIDE_IBM = 103080 +GL_NORMAL_ARRAY_LIST_STRIDE_IBM = 103081 +GL_COLOR_ARRAY_LIST_STRIDE_IBM = 103082 +GL_INDEX_ARRAY_LIST_STRIDE_IBM = 103083 +GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM = 103084 +GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM = 103085 +GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM = 103086 +GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM = 103087 + +; GL_SGIX_subsample + +GL_PACK_SUBSAMPLE_RATE_SGIX = $85A0 +GL_UNPACK_SUBSAMPLE_RATE_SGIX = $85A1 +GL_PIXEL_SUBSAMPLE_4444_SGIX = $85A2 +GL_PIXEL_SUBSAMPLE_2424_SGIX = $85A3 +GL_PIXEL_SUBSAMPLE_4242_SGIX = $85A4 + +; GL_SGIX_ycrcba + +GL_YCRCB_SGIX = $8318 +GL_YCRCBA_SGIX = $8319 + +; GL_SGI_depth_pass_instrument + +GL_DEPTH_PASS_INSTRUMENT_SGIX = $8310 +GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX = $8311 +GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX = $8312 + +; GL_3DFX_texture_compression_FXT1 + +GL_COMPRESSED_RGB_FXT1_3DFX = $86B0 +GL_COMPRESSED_RGBA_FXT1_3DFX = $86B1 + +; GL_3DFX_multisample + +GL_MULTISAMPLE_3DFX = $86B2 +GL_SAMPLE_BUFFERS_3DFX = $86B3 +GL_SAMPLES_3DFX = $86B4 +GL_MULTISAMPLE_BIT_3DFX = $20000000 + +; GL_EXT_multisample + +GL_MULTISAMPLE_EXT = $809D +GL_SAMPLE_ALPHA_TO_MASK_EXT = $809E +GL_SAMPLE_ALPHA_TO_ONE_EXT = $809F +GL_SAMPLE_MASK_EXT = $80A0 +GL_1PASS_EXT = $80A1 +GL_2PASS_0_EXT = $80A2 +GL_2PASS_1_EXT = $80A3 +GL_4PASS_0_EXT = $80A4 +GL_4PASS_1_EXT = $80A5 +GL_4PASS_2_EXT = $80A6 +GL_4PASS_3_EXT = $80A7 +GL_SAMPLE_BUFFERS_EXT = $80A8 +GL_SAMPLES_EXT = $80A9 +GL_SAMPLE_MASK_VALUE_EXT = $80AA +GL_SAMPLE_MASK_INVERT_EXT = $80AB +GL_SAMPLE_PATTERN_EXT = $80AC + +; GL_SGIX_vertex_preclip + +GL_VERTEX_PRECLIP_SGIX = $83EE +GL_VERTEX_PRECLIP_HINT_SGIX = $83EF + +; GL_SGIX_convolution_accuracy + +GL_CONVOLUTION_HINT_SGIX = $8316 + +; GL_SGIX_resample + +GL_PACK_RESAMPLE_SGIX = $842C +GL_UNPACK_RESAMPLE_SGIX = $842D +GL_RESAMPLE_REPLICATE_SGIX = $842E +GL_RESAMPLE_ZERO_FILL_SGIX = $842F +GL_RESAMPLE_DECIMATE_SGIX = $8430 + +; GL_SGIS_point_line_texgen + +GL_EYE_DISTANCE_TO_POINT_SGIS = $81F0 +GL_OBJECT_DISTANCE_TO_POINT_SGIS = $81F1 +GL_EYE_DISTANCE_TO_LINE_SGIS = $81F2 +GL_OBJECT_DISTANCE_TO_LINE_SGIS = $81F3 +GL_EYE_POINT_SGIS = $81F4 +GL_OBJECT_POINT_SGIS = $81F5 +GL_EYE_LINE_SGIS = $81F6 +GL_OBJECT_LINE_SGIS = $81F7 + +; GL_SGIS_texture_color_mask + +GL_TEXTURE_COLOR_WRITEMASK_SGIS = $81EF + +; GL_NV_vertex_program + +GL_VERTEX_PROGRAM_NV = $8620 +GL_VERTEX_STATE_PROGRAM_NV = $8621 +GL_ATTRIB_ARRAY_SIZE_NV = $8623 +GL_ATTRIB_ARRAY_STRIDE_NV = $8624 +GL_ATTRIB_ARRAY_TYPE_NV = $8625 +GL_CURRENT_ATTRIB_NV = $8626 +GL_PROGRAM_LENGTH_NV = $8627 +GL_PROGRAM_STRING_NV = $8628 +GL_MODELVIEW_PROJECTION_NV = $8629 +GL_IDENTITY_NV = $862A +GL_INVERSE_NV = $862B +GL_TRANSPOSE_NV = $862C +GL_INVERSE_TRANSPOSE_NV = $862D +GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV = $862E +GL_MAX_TRACK_MATRICES_NV = $862F +GL_MATRIX0_NV = $8630 +GL_MATRIX1_NV = $8631 +GL_MATRIX2_NV = $8632 +GL_MATRIX3_NV = $8633 +GL_MATRIX4_NV = $8634 +GL_MATRIX5_NV = $8635 +GL_MATRIX6_NV = $8636 +GL_MATRIX7_NV = $8637 +GL_CURRENT_MATRIX_STACK_DEPTH_NV = $8640 +GL_CURRENT_MATRIX_NV = $8641 +GL_VERTEX_PROGRAM_POINT_SIZE_NV = $8642 +GL_VERTEX_PROGRAM_TWO_SIDE_NV = $8643 +GL_PROGRAM_PARAMETER_NV = $8644 +GL_ATTRIB_ARRAY_POINTER_NV = $8645 +GL_PROGRAM_TARGET_NV = $8646 +GL_PROGRAM_RESIDENT_NV = $8647 +GL_TRACK_MATRIX_NV = $8648 +GL_TRACK_MATRIX_TRANSFORM_NV = $8649 +GL_VERTEX_PROGRAM_BINDING_NV = $864A +GL_PROGRAM_ERROR_POSITION_NV = $864B +GL_VERTEX_ATTRIB_ARRAY0_NV = $8650 +GL_VERTEX_ATTRIB_ARRAY1_NV = $8651 +GL_VERTEX_ATTRIB_ARRAY2_NV = $8652 +GL_VERTEX_ATTRIB_ARRAY3_NV = $8653 +GL_VERTEX_ATTRIB_ARRAY4_NV = $8654 +GL_VERTEX_ATTRIB_ARRAY5_NV = $8655 +GL_VERTEX_ATTRIB_ARRAY6_NV = $8656 +GL_VERTEX_ATTRIB_ARRAY7_NV = $8657 +GL_VERTEX_ATTRIB_ARRAY8_NV = $8658 +GL_VERTEX_ATTRIB_ARRAY9_NV = $8659 +GL_VERTEX_ATTRIB_ARRAY10_NV = $865A +GL_VERTEX_ATTRIB_ARRAY11_NV = $865B +GL_VERTEX_ATTRIB_ARRAY12_NV = $865C +GL_VERTEX_ATTRIB_ARRAY13_NV = $865D +GL_VERTEX_ATTRIB_ARRAY14_NV = $865E +GL_VERTEX_ATTRIB_ARRAY15_NV = $865F +GL_MAP1_VERTEX_ATTRIB0_4_NV = $8660 +GL_MAP1_VERTEX_ATTRIB1_4_NV = $8661 +GL_MAP1_VERTEX_ATTRIB2_4_NV = $8662 +GL_MAP1_VERTEX_ATTRIB3_4_NV = $8663 +GL_MAP1_VERTEX_ATTRIB4_4_NV = $8664 +GL_MAP1_VERTEX_ATTRIB5_4_NV = $8665 +GL_MAP1_VERTEX_ATTRIB6_4_NV = $8666 +GL_MAP1_VERTEX_ATTRIB7_4_NV = $8667 +GL_MAP1_VERTEX_ATTRIB8_4_NV = $8668 +GL_MAP1_VERTEX_ATTRIB9_4_NV = $8669 +GL_MAP1_VERTEX_ATTRIB10_4_NV = $866A +GL_MAP1_VERTEX_ATTRIB11_4_NV = $866B +GL_MAP1_VERTEX_ATTRIB12_4_NV = $866C +GL_MAP1_VERTEX_ATTRIB13_4_NV = $866D +GL_MAP1_VERTEX_ATTRIB14_4_NV = $866E +GL_MAP1_VERTEX_ATTRIB15_4_NV = $866F +GL_MAP2_VERTEX_ATTRIB0_4_NV = $8670 +GL_MAP2_VERTEX_ATTRIB1_4_NV = $8671 +GL_MAP2_VERTEX_ATTRIB2_4_NV = $8672 +GL_MAP2_VERTEX_ATTRIB3_4_NV = $8673 +GL_MAP2_VERTEX_ATTRIB4_4_NV = $8674 +GL_MAP2_VERTEX_ATTRIB5_4_NV = $8675 +GL_MAP2_VERTEX_ATTRIB6_4_NV = $8676 +GL_MAP2_VERTEX_ATTRIB7_4_NV = $8677 +GL_MAP2_VERTEX_ATTRIB8_4_NV = $8678 +GL_MAP2_VERTEX_ATTRIB9_4_NV = $8679 +GL_MAP2_VERTEX_ATTRIB10_4_NV = $867A +GL_MAP2_VERTEX_ATTRIB11_4_NV = $867B +GL_MAP2_VERTEX_ATTRIB12_4_NV = $867C +GL_MAP2_VERTEX_ATTRIB13_4_NV = $867D +GL_MAP2_VERTEX_ATTRIB14_4_NV = $867E +GL_MAP2_VERTEX_ATTRIB15_4_NV = $867F + +; GLU errors + +GLU_INVALID_ENUM = 100900 +GLU_INVALID_VALUE = 100901 +GLU_OUT_OF_MEMORY = 100902 +GLU_INCOMPATIBLE_GL_VERSION = 100903 + +; GLU boolean values + +GLU_TRUE = GL_TRUE +GLU_FALSE = GL_FALSE + +; Quadric constants + +GLU_SMOOTH = 100000 +GLU_FLAT = 100001 +GLU_NONE = 100002 +GLU_POINT = 100010 +GLU_LINE = 100011 +GLU_FILL = 100012 +GLU_SILHOUETTE = 100013 +GLU_OUTSIDE = 100020 +GLU_INSIDE = 100021 + +; Tesselation constants + +GLU_TESS_MAX_COORD = 1.0e150 +GLU_TESS_WINDING_RULE = 100140 +GLU_TESS_BOUNDARY_ONLY = 100141 +GLU_TESS_TOLERANCE = 100142 +GLU_TESS_WINDING_ODD = 100130 +GLU_TESS_WINDING_NONZERO = 100131 +GLU_TESS_WINDING_POSITIVE = 100132 +GLU_TESS_WINDING_NEGATIVE = 100133 +GLU_TESS_WINDING_ABS_GEQ_TWO = 100134 +GLU_TESS_BEGIN = 100100 +GLU_TESS_VERTEX = 100101 +GLU_TESS_END = 100102 +GLU_TESS_ERROR = 100103 +GLU_TESS_EDGE_FLAG = 100104 +GLU_TESS_COMBINE = 100105 +GLU_TESS_BEGIN_DATA = 100106 +GLU_TESS_VERTEX_DATA = 100107 +GLU_TESS_END_DATA = 100108 +GLU_TESS_ERROR_DATA = 100109 +GLU_TESS_EDGE_FLAG_DATA = 100110 +GLU_TESS_COMBINE_DATA = 100111 +GLU_TESS_ERROR1 = 100151 +GLU_TESS_ERROR2 = 100152 +GLU_TESS_ERROR3 = 100153 +GLU_TESS_ERROR4 = 100154 +GLU_TESS_ERROR5 = 100155 +GLU_TESS_ERROR6 = 100156 +GLU_TESS_ERROR7 = 100157 +GLU_TESS_ERROR8 = 100158 +GLU_TESS_MISSING_BEGIN_POLYGON = GLU_TESS_ERROR1 +GLU_TESS_MISSING_BEGIN_CONTOUR = GLU_TESS_ERROR2 +GLU_TESS_MISSING_END_POLYGON = GLU_TESS_ERROR3 +GLU_TESS_MISSING_END_CONTOUR = GLU_TESS_ERROR4 +GLU_TESS_COORD_TOO_LARGE = GLU_TESS_ERROR5 +GLU_TESS_NEED_COMBINE_CALLBACK = GLU_TESS_ERROR6 + +; NURBS constants + +GLU_AUTO_LOAD_MATRIX = 100200 +GLU_CULLING = 100201 +GLU_SAMPLING_TOLERANCE = 100203 +GLU_DISPLAY_MODE = 100204 +GLU_PARAMETRIC_TOLERANCE = 100202 +GLU_SAMPLING_METHOD = 100205 +GLU_U_STEP = 100206 +GLU_V_STEP = 100207 +GLU_PATH_LENGTH = 100215 +GLU_PARAMETRIC_ERROR = 100216 +GLU_DOMAIN_DISTANCE = 100217 +GLU_MAP1_TRIM_2 = 100210 +GLU_MAP1_TRIM_3 = 100211 +GLU_OUTLINE_POLYGON = 100240 +GLU_OUTLINE_PATCH = 100241 +GLU_NURBS_ERROR1 = 100251 +GLU_NURBS_ERROR2 = 100252 +GLU_NURBS_ERROR3 = 100253 +GLU_NURBS_ERROR4 = 100254 +GLU_NURBS_ERROR5 = 100255 +GLU_NURBS_ERROR6 = 100256 +GLU_NURBS_ERROR7 = 100257 +GLU_NURBS_ERROR8 = 100258 +GLU_NURBS_ERROR9 = 100259 +GLU_NURBS_ERROR10 = 100260 +GLU_NURBS_ERROR11 = 100261 +GLU_NURBS_ERROR12 = 100262 +GLU_NURBS_ERROR13 = 100263 +GLU_NURBS_ERROR14 = 100264 +GLU_NURBS_ERROR15 = 100265 +GLU_NURBS_ERROR16 = 100266 +GLU_NURBS_ERROR17 = 100267 +GLU_NURBS_ERROR18 = 100268 +GLU_NURBS_ERROR19 = 100269 +GLU_NURBS_ERROR20 = 100270 +GLU_NURBS_ERROR21 = 100271 +GLU_NURBS_ERROR22 = 100272 +GLU_NURBS_ERROR23 = 100273 +GLU_NURBS_ERROR24 = 100274 +GLU_NURBS_ERROR25 = 100275 +GLU_NURBS_ERROR26 = 100276 +GLU_NURBS_ERROR27 = 100277 +GLU_NURBS_ERROR28 = 100278 +GLU_NURBS_ERROR29 = 100279 +GLU_NURBS_ERROR30 = 100280 +GLU_NURBS_ERROR31 = 100281 +GLU_NURBS_ERROR32 = 100282 +GLU_NURBS_ERROR33 = 100283 +GLU_NURBS_ERROR34 = 100284 +GLU_NURBS_ERROR35 = 100285 +GLU_NURBS_ERROR36 = 100286 +GLU_NURBS_ERROR37 = 100287 + +; Contours types + +GLU_CW = 100120 +GLU_CCW = 100121 +GLU_INTERIOR = 100122 +GLU_EXTERIOR = 100123 +GLU_UNKNOWN = 100124 diff --git a/toolchain/fasmw17332/EXAMPLES/PEDEMO/PEDEMO.ASM b/toolchain/fasmw17332/EXAMPLES/PEDEMO/PEDEMO.ASM new file mode 100644 index 0000000..a9cfcb4 --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/PEDEMO/PEDEMO.ASM @@ -0,0 +1,46 @@ + +; Example of making 32-bit PE program as raw code and data + +format PE GUI +entry start + +section '.text' code readable executable + + start: + + push 0 + push _caption + push _message + push 0 + call [MessageBoxA] + + push 0 + call [ExitProcess] + +section '.data' data readable writeable + + _caption db 'Win32 assembly program',0 + _message db 'Hello World!',0 + +section '.idata' import data readable writeable + + dd 0,0,0,RVA kernel_name,RVA kernel_table + dd 0,0,0,RVA user_name,RVA user_table + dd 0,0,0,0,0 + + kernel_table: + ExitProcess dd RVA _ExitProcess + dd 0 + user_table: + MessageBoxA dd RVA _MessageBoxA + dd 0 + + kernel_name db 'KERNEL32.DLL',0 + user_name db 'USER32.DLL',0 + + _ExitProcess dw 0 + db 'ExitProcess',0 + _MessageBoxA dw 0 + db 'MessageBoxA',0 + +section '.reloc' fixups data readable discardable ; needed for Win32s diff --git a/toolchain/fasmw17332/EXAMPLES/TEMPLATE/TEMPLATE.ASM b/toolchain/fasmw17332/EXAMPLES/TEMPLATE/TEMPLATE.ASM new file mode 100644 index 0000000..63de34b --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/TEMPLATE/TEMPLATE.ASM @@ -0,0 +1,71 @@ + +; Template for program using standard Win32 headers + +format PE GUI 4.0 +entry start + +include 'win32w.inc' + +section '.text' code readable executable + + start: + + invoke GetModuleHandle,0 + mov [wc.hInstance],eax + invoke LoadIcon,0,IDI_APPLICATION + mov [wc.hIcon],eax + invoke LoadCursor,0,IDC_ARROW + mov [wc.hCursor],eax + invoke RegisterClass,wc + test eax,eax + jz error + + invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,256,192,NULL,NULL,[wc.hInstance],NULL + test eax,eax + jz error + + msg_loop: + invoke GetMessage,msg,NULL,0,0 + cmp eax,1 + jb end_loop + jne msg_loop + invoke TranslateMessage,msg + invoke DispatchMessage,msg + jmp msg_loop + + error: + invoke MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK + + end_loop: + invoke ExitProcess,[msg.wParam] + +proc WindowProc uses ebx esi edi, hwnd,wmsg,wparam,lparam + cmp [wmsg],WM_DESTROY + je .wmdestroy + .defwndproc: + invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] + jmp .finish + .wmdestroy: + invoke PostQuitMessage,0 + xor eax,eax + .finish: + ret +endp + +section '.data' data readable writeable + + _class TCHAR 'FASMWIN32',0 + _title TCHAR 'Win32 program template',0 + _error TCHAR 'Startup failed.',0 + + wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class + + msg MSG + +section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL',\ + user32,'USER32.DLL' + + include 'api\kernel32.inc' + include 'api\user32.inc' diff --git a/toolchain/fasmw17332/EXAMPLES/USECOM/USECOM.ASM b/toolchain/fasmw17332/EXAMPLES/USECOM/USECOM.ASM new file mode 100644 index 0000000..66d0518 --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/USECOM/USECOM.ASM @@ -0,0 +1,142 @@ + +; Component Object Model usage demonstration + +format PE GUI 4.0 +entry start + +include 'win32a.inc' + +struc GUID def + { + match d1-d2-d3-d4-d5, def + \{ + .Data1 dd 0x\#d1 + .Data2 dw 0x\#d2 + .Data3 dw 0x\#d3 + .Data4 db 0x\#d4 shr 8,0x\#d4 and 0FFh + .Data5 db 0x\#d5 shr 40,0x\#d5 shr 32 and 0FFh,0x\#d5 shr 24 and 0FFh,0x\#d5 shr 16 and 0FFh,0x\#d5 shr 8 and 0FFh,0x\#d5 and 0FFh + \} + } + +interface ITaskBarList,\ + QueryInterface,\ + AddRef,\ + Release,\ + HrInit,\ + AddTab,\ + DeleteTab,\ + ActivateTab,\ + SetActiveAlt + +CLSCTX_INPROC_SERVER = 0x1 +CLSCTX_INPROC_HANDLER = 0x2 +CLSCTX_LOCAL_SERVER = 0x4 +CLSCTX_INPROC_SERVER16 = 0x8 +CLSCTX_REMOTE_SERVER = 0x10 +CLSCTX_INPROC_HANDLER16 = 0x20 +CLSCTX_INPROC_SERVERX86 = 0x40 +CLSCTX_INPROC_HANDLERX86 = 0x80 +CLSCTX_ESERVER_HANDLER = 0x100 +CLSCTX_NO_CODE_DOWNLOAD = 0x400 +CLSCTX_NO_CUSTOM_MARSHAL = 0x1000 +CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000 +CLSCTX_NO_FAILURE_LOG = 0x4000 +CLSCTX_DISABLE_AAA = 0x8000 +CLSCTX_ENABLE_AAA = 0x10000 +CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000 + +ID_EXIT = IDCANCEL +ID_SHOW = 100 +ID_HIDE = 101 + +IDD_COMDEMO = 1 + +section '.text' code readable executable + + start: + + invoke CoInitialize,NULL + invoke CoCreateInstance,CLSID_TaskbarList,NULL,CLSCTX_INPROC_SERVER,IID_ITaskbarList,ShellTaskBar + + invoke GetModuleHandle,0 + invoke DialogBoxParam,eax,IDD_COMDEMO,HWND_DESKTOP,COMDemo,0 + + cominvk ShellTaskBar,Release + + invoke ExitProcess,0 + +proc COMDemo hwnd,msg,wparam,lparam + push ebx esi edi + cmp [msg],WM_INITDIALOG + je .wminitdialog + cmp [msg],WM_COMMAND + je .wmcommand + cmp [msg],WM_CLOSE + je .wmclose + xor eax,eax + jmp .finish + .wminitdialog: + jmp .processed + .wmcommand: + cmp [wparam],BN_CLICKED shl 16 + ID_EXIT + je .wmclose + cmp [wparam],BN_CLICKED shl 16 + ID_SHOW + je .show + cmp [wparam],BN_CLICKED shl 16 + ID_HIDE + jne .processed + .hide: + cominvk ShellTaskBar,HrInit + cominvk ShellTaskBar,DeleteTab,[hwnd] + jmp .processed + .show: + mov ebx,[ShellTaskBar] + comcall ebx,ITaskBarList,HrInit + comcall ebx,ITaskBarList,AddTab,[hwnd] + comcall ebx,ITaskBarList,ActivateTab,[hwnd] + jmp .processed + .wmclose: + invoke EndDialog,[hwnd],0 + .processed: + mov eax,1 + .finish: + pop edi esi ebx + ret +endp + +section '.data' data readable writeable + + CLSID_TaskbarList GUID 56FDF344-FD6D-11D0-958A-006097C9A090 + IID_ITaskbarList GUID 56FDF342-FD6D-11D0-958A-006097C9A090 + + ShellTaskBar ITaskBarList + +section '.idata' import data readable + + library kernel,'KERNEL32.DLL',\ + user,'USER32.DLL',\ + ole,'OLE32.DLL' + + import kernel,\ + GetModuleHandle,'GetModuleHandleA',\ + ExitProcess,'ExitProcess' + + import user,\ + DialogBoxParam,'DialogBoxParamA',\ + EndDialog,'EndDialog' + + import ole,\ + CoInitialize,'CoInitialize',\ + CoCreateInstance,'CoCreateInstance' + +section '.rsrc' resource data readable + + directory RT_DIALOG,dialogs + + resource dialogs,\ + IDD_COMDEMO,LANG_ENGLISH+SUBLANG_DEFAULT,comdemo + + dialog comdemo,'Taskbar item control',70,70,170,24,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'BUTTON','Show',ID_SHOW,4,4,45,15,WS_VISIBLE+WS_TABSTOP + dialogitem 'BUTTON','Hide',ID_HIDE,54,4,45,15,WS_VISIBLE+WS_TABSTOP + dialogitem 'BUTTON','Exit',ID_EXIT,120,4,45,15,WS_VISIBLE+WS_TABSTOP + enddialog diff --git a/toolchain/fasmw17332/EXAMPLES/WIN64/DLL/MSGDEMO.ASM b/toolchain/fasmw17332/EXAMPLES/WIN64/DLL/MSGDEMO.ASM new file mode 100644 index 0000000..aa67073 --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/WIN64/DLL/MSGDEMO.ASM @@ -0,0 +1,27 @@ +format PE64 console +entry start + +include 'win64a.inc' + +section '.text' code readable executable + +start: + sub rsp,8 + + invoke WriteMessage,message + + invoke ExitProcess,0 + +section '.data' data readable + + message db "Hi! I'm the example program!",0 + +section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL',\ + writemsg,'WRITEMSG.DLL' + + include 'api/kernel32.inc' + + import writemsg,\ + WriteMessage,'WriteMessage' \ No newline at end of file diff --git a/toolchain/fasmw17332/EXAMPLES/WIN64/DLL/WRITEMSG.ASM b/toolchain/fasmw17332/EXAMPLES/WIN64/DLL/WRITEMSG.ASM new file mode 100644 index 0000000..010a7ed --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/WIN64/DLL/WRITEMSG.ASM @@ -0,0 +1,47 @@ +format PE64 console DLL +entry DllEntryPoint + +include 'win64a.inc' + +section '.text' code readable executable + +proc DllEntryPoint hinstDLL,fdwReason,lpvReserved + mov eax,TRUE + ret +endp + +proc WriteMessage uses rbx rsi rdi, message + mov rdi,rcx ; first parameter passed in RCX + invoke GetStdHandle,STD_OUTPUT_HANDLE + mov rbx,rax + xor al,al + or rcx,-1 + repne scasb + dec rdi + mov r8,-2 + sub r8,rcx + sub rdi,r8 + invoke WriteFile,rbx,rdi,r8,bytes_count,0 + ret +endp + +section '.bss' data readable writeable + + bytes_count dd ? + +section '.edata' export data readable + + export 'WRITEMSG.DLL',\ + WriteMessage,'WriteMessage' + +section '.reloc' fixups data readable discardable + + if $=$$ + dd 0,8 ; if there are no fixups, generate dummy entry + end if + +section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL' + + include 'api/kernel32.inc' diff --git a/toolchain/fasmw17332/EXAMPLES/WIN64/MANDEL/DDRAW64.INC b/toolchain/fasmw17332/EXAMPLES/WIN64/MANDEL/DDRAW64.INC new file mode 100644 index 0000000..6c8b3af --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/WIN64/MANDEL/DDRAW64.INC @@ -0,0 +1,425 @@ + +; DirectDraw interface + +interface DirectDraw,\ + QueryInterface,\ + AddRef,\ + Release,\ + Compact,\ + CreateClipper,\ + CreatePalette,\ + CreateSurface,\ + DuplicateSurface,\ + EnumDisplayModes,\ + EnumSurfaces,\ + FlipToGDISurface,\ + GetCaps,\ + GetDisplayMode,\ + GetFourCCCodes,\ + GetGDISurface,\ + GetMonitorFrequency,\ + GetScanLine,\ + GetVerticalBlankStatus,\ + Initialize,\ + RestoreDisplayMode,\ + SetCooperativeLevel,\ + SetDisplayMode,\ + WaitForVerticalBlank,\ + GetAvailableVidMem,\ + GetSurfaceFromDC,\ + RestoreAllSurfaces,\ + TestCooperativeLevel,\ + GetDeviceIdentifier,\ + StartModeTest,\ + EvaluateMode + +interface DirectDrawSurface,\ + QueryInterface,\ + AddRef,\ + Release,\ + AddAttachedSurface,\ + AddOverlayDirtyRect,\ + Blt,\ + BltBatch,\ + BltFast,\ + DeleteAttachedSurface,\ + EnumAttachedSurfaces,\ + EnumOverlayZOrders,\ + Flip,\ + GetAttachedSurface,\ + GetBltStatus,\ + GetCaps,\ + GetClipper,\ + GetColorKey,\ + GetDC,\ + GetFlipStatus,\ + GetOverlayPosition,\ + GetPalette,\ + GetPixelFormat,\ + GetSurfaceDesc,\ + Initialize,\ + IsLost,\ + Lock,\ + ReleaseDC,\ + Restore,\ + SetClipper,\ + SetColorKey,\ + SetOverlayPosition,\ + SetPalette,\ + Unlock,\ + UpdateOverlay,\ + UpdateOverlayDisplay,\ + UpdateOverlayZOrder,\ + GetDDInterface,\ + PageLock,\ + PageUnlock,\ + SetSurfaceDesc,\ + SetPrivateData,\ + GetPrivateData,\ + FreePrivateData,\ + GetUniquenessValue,\ + ChangeUniquenessValue,\ + SetPriority,\ + GetPriority,\ + SetLOD,\ + GetLOD + +interface DirectDrawPalette,\ + QueryInterface,\ + AddRef,\ + Release,\ + GetCaps,\ + GetEntries,\ + Initialize,\ + SetEntries + +interface DirectDrawClipper,\ + QueryInterface,\ + AddRef,\ + Release,\ + GetClipList,\ + GetHWnd,\ + Initialize,\ + IsClipListChanged,\ + SetClipList,\ + SetHWnd + +interface DirectDrawColorControl,\ + QueryInterface,\ + AddRef,\ + Release,\ + GetColorControls,\ + SetColorControls + +interface DirectDrawGammaControl,\ + QueryInterface,\ + AddRef,\ + Release,\ + GetGammaRamp,\ + SetGammaRamp + +struct DDCOLORKEY + dwColorSpaceLowValue dd ? + dwColorSpaceHighValue dd ? +ends + +struct DDPIXELFORMAT + dwSize dd ? + dwFlags dd ? + dwFourCC dd ? + union + dwRGBBitCount dd ? + dwYUVBitCount dd ? + dwZBufferBitDepth dd ? + dwAlphaBitDepth dd ? + dwLuminanceBitCount dd ? + dwBumpBitCount dd ? + ends + union + dwRBitMask dd ? + dwYBitMask dd ? + dwStencilBitDepth dd ? + dwLuminanceBitMask dd ? + dwBumpDuBitMask dd ? + ends + union + dwGBitMask dd ? + dwUBitMask dd ? + dwZBitMask dd ? + dwBumpDvBitMask dd ? + ends + union + dwBBitMask dd ? + dwVBitMask dd ? + dwStencilBitMask dd ? + dwBumpLuminanceBitMask dd ? + ends + union + dwRGBAlphaBitMask dd ? + dwYUVAlphaBitMask dd ? + dwLuminanceAlphaBitMask dd ? + dwRGBZBitMask dd ? + dwYUVZBitMask dd ? + ends +ends + +struct DDSCAPS + dwCaps dd ? +ends + +struct DDSURFACEDESC + dwSize dd ? + dwFlags dd ? + dwHeight dd ? + dwWidth dd ? + union + lPitch dd ? + dwLinearSize dd ? + ends + dwBackBufferCount dd ? + union + dwMipMapCount dd ? + dwZBufferBitDepth dd ? + dwRefreshRate dd ? + ends + dwAlphaBitDepth dd ? + dwReserved dd ?,? + lpSurface dq ? + ddckCKDestOverlay DDCOLORKEY + ddckCKDestBlt DDCOLORKEY + ddckCKSrcOverlay DDCOLORKEY + ddckCKSrcBlt DDCOLORKEY + ddpfPixelFormat DDPIXELFORMAT + ddsCaps DDSCAPS + dd ? +ends + +; SetCooperativeLevel flags + +DDSCL_FULLSCREEN = 000000001h +DDSCL_ALLOWREBOOT = 000000002h +DDSCL_NOWINDOWCHANGES = 000000004h +DDSCL_NORMAL = 000000008h +DDSCL_EXCLUSIVE = 000000010h +DDSCL_ALLOWMODEX = 000000040h + +; Blt flags + +DDBLT_ALPHADEST = 000000001h +DDBLT_ALPHADESTCONSTOVERRIDE = 000000002h +DDBLT_ALPHADESTNEG = 000000004h +DDBLT_ALPHADESTSURFACEOVERRIDE = 000000008h +DDBLT_ALPHAEDGEBLEND = 000000010h +DDBLT_ALPHASRC = 000000020h +DDBLT_ALPHASRCCONSTOVERRIDE = 000000040h +DDBLT_ALPHASRCNEG = 000000080h +DDBLT_ALPHASRCSURFACEOVERRIDE = 000000100h +DDBLT_ASYNC = 000000200h +DDBLT_COLORFILL = 000000400h +DDBLT_DDFX = 000000800h +DDBLT_DDROPS = 000001000h +DDBLT_KEYDEST = 000002000h +DDBLT_KEYDESTOVERRIDE = 000004000h +DDBLT_KEYSRC = 000008000h +DDBLT_KEYSRCOVERRIDE = 000010000h +DDBLT_ROP = 000020000h +DDBLT_ROTATIONANGLE = 000040000h +DDBLT_ZBUFFER = 000080000h +DDBLT_ZBUFFERDESTCONSTOVERRIDE = 000100000h +DDBLT_ZBUFFERDESTOVERRIDE = 000200000h +DDBLT_ZBUFFERSRCCONSTOVERRIDE = 000400000h +DDBLT_ZBUFFERSRCOVERRIDE = 000800000h +DDBLT_WAIT = 001000000h +DDBLT_DEPTHFILL = 002000000h + +; BltFast flags + +DDBLTFAST_NOCOLORKEY = 000000000h +DDBLTFAST_SRCCOLORKEY = 000000001h +DDBLTFAST_DESTCOLORKEY = 000000002h +DDBLTFAST_WAIT = 000000010h + +; Flip flags + +DDFLIP_WAIT = 000000001h +DDFLIP_EVEN = 000000002h +DDFLIP_ODD = 000000004h + +; DDSURFACEDESC field flags + +DDSD_CAPS = 000000001h +DDSD_HEIGHT = 000000002h +DDSD_WIDTH = 000000004h +DDSD_PITCH = 000000008h +DDSD_BACKBUFFERCOUNT = 000000020h +DDSD_ZBUFFERBITDEPTH = 000000040h +DDSD_ALPHABITDEPTH = 000000080h +DDSD_LPSURFACE = 000000800h +DDSD_PIXELFORMAT = 000001000h +DDSD_CKDESTOVERLAY = 000002000h +DDSD_CKDESTBLT = 000004000h +DDSD_CKSRCOVERLAY = 000008000h +DDSD_CKSRCBLT = 000010000h +DDSD_MIPMAPCOUNT = 000020000h +DDSD_REFRESHRATE = 000040000h +DDSD_LINEARSIZE = 000080000h +DDSD_ALL = 0000FF9EEh + +; DirectDrawSurface capability flags + +DDSCAPS_RESERVED1 = 000000001h +DDSCAPS_ALPHA = 000000002h +DDSCAPS_BACKBUFFER = 000000004h +DDSCAPS_COMPLEX = 000000008h +DDSCAPS_FLIP = 000000010h +DDSCAPS_FRONTBUFFER = 000000020h +DDSCAPS_OFFSCREENPLAIN = 000000040h +DDSCAPS_OVERLAY = 000000080h +DDSCAPS_PALETTE = 000000100h +DDSCAPS_PRIMARYSURFACE = 000000200h +DDSCAPS_PRIMARYSURFACELEFT = 000000400h +DDSCAPS_SYSTEMMEMORY = 000000800h +DDSCAPS_TEXTURE = 000001000h +DDSCAPS_3DDEVICE = 000002000h +DDSCAPS_VIDEOMEMORY = 000004000h +DDSCAPS_VISIBLE = 000008000h +DDSCAPS_WRITEONLY = 000010000h +DDSCAPS_ZBUFFER = 000020000h +DDSCAPS_OWNDC = 000040000h +DDSCAPS_LIVEVIDEO = 000080000h +DDSCAPS_HWCODEC = 000100000h +DDSCAPS_MODEX = 000200000h +DDSCAPS_MIPMAP = 000400000h +DDSCAPS_RESERVED2 = 000800000h +DDSCAPS_ALLOCONLOAD = 004000000h +DDSCAPS_VIDEOPORT = 008000000h +DDSCAPS_LOCALVIDMEM = 010000000h +DDSCAPS_NONLOCALVIDMEM = 020000000h +DDSCAPS_STANDARDVGAMODE = 040000000h +DDSCAPS_OPTIMIZED = 080000000h + +; DirectDrawSurface lock flags + +DDLOCK_SURFACEMEMORYPTR = 000000000h +DDLOCK_WAIT = 000000001h +DDLOCK_EVENT = 000000002h +DDLOCK_READONLY = 000000010h +DDLOCK_WRITEONLY = 000000020h +DDLOCK_NOSYSLOCK = 000000800h + +; DirectDrawPalette capabilities + +DDPCAPS_4BIT = 000000001h +DDPCAPS_8BITENTRIES = 000000002h +DDPCAPS_8BIT = 000000004h +DDPCAPS_INITIALIZE = 000000008h +DDPCAPS_PRIMARYSURFACE = 000000010h +DDPCAPS_PRIMARYSURFACELEFT = 000000020h +DDPCAPS_ALLOW256 = 000000040h +DDPCAPS_VSYNC = 000000080h +DDPCAPS_1BIT = 000000100h +DDPCAPS_2BIT = 000000200h + +; DirectDraw errors + +DDERR_ALREADYINITIALIZED = 088760000h+5 +DDERR_CANNOTATTACHSURFACE = 088760000h+10 +DDERR_CANNOTDETACHSURFACE = 088760000h+20 +DDERR_CURRENTLYNOTAVAIL = 088760000h+40 +DDERR_EXCEPTION = 088760000h+55 +DDERR_HEIGHTALIGN = 088760000h+90 +DDERR_INCOMPATIBLEPRIMARY = 088760000h+95 +DDERR_INVALIDCAPS = 088760000h+100 +DDERR_INVALIDCLIPLIST = 088760000h+110 +DDERR_INVALIDMODE = 088760000h+120 +DDERR_INVALIDOBJECT = 088760000h+130 +DDERR_INVALIDPIXELFORMAT = 088760000h+145 +DDERR_INVALIDRECT = 088760000h+150 +DDERR_LOCKEDSURFACES = 088760000h+160 +DDERR_NO3D = 088760000h+170 +DDERR_NOALPHAHW = 088760000h+180 +DDERR_NOCLIPLIST = 088760000h+205 +DDERR_NOCOLORCONVHW = 088760000h+210 +DDERR_NOCOOPERATIVELEVELSET = 088760000h+212 +DDERR_NOCOLORKEY = 088760000h+215 +DDERR_NOCOLORKEYHW = 088760000h+220 +DDERR_NODIRECTDRAWSUPPORT = 088760000h+222 +DDERR_NOEXCLUSIVEMODE = 088760000h+225 +DDERR_NOFLIPHW = 088760000h+230 +DDERR_NOGDI = 088760000h+240 +DDERR_NOMIRRORHW = 088760000h+250 +DDERR_NOTFOUND = 088760000h+255 +DDERR_NOOVERLAYHW = 088760000h+260 +DDERR_NORASTEROPHW = 088760000h+280 +DDERR_NOROTATIONHW = 088760000h+290 +DDERR_NOSTRETCHHW = 088760000h+310 +DDERR_NOT4BITCOLOR = 088760000h+316 +DDERR_NOT4BITCOLORINDEX = 088760000h+317 +DDERR_NOT8BITCOLOR = 088760000h+320 +DDERR_NOTEXTUREHW = 088760000h+330 +DDERR_NOVSYNCHW = 088760000h+335 +DDERR_NOZBUFFERHW = 088760000h+340 +DDERR_NOZOVERLAYHW = 088760000h+350 +DDERR_OUTOFCAPS = 088760000h+360 +DDERR_OUTOFVIDEOMEMORY = 088760000h+380 +DDERR_OVERLAYCANTCLIP = 088760000h+382 +DDERR_OVERLAYCOLORKEYONLYONEACTI = 088760000h+384 +DDERR_PALETTEBUSY = 088760000h+387 +DDERR_COLORKEYNOTSET = 088760000h+400 +DDERR_SURFACEALREADYATTACHED = 088760000h+410 +DDERR_SURFACEALREADYDEPENDENT = 088760000h+420 +DDERR_SURFACEBUSY = 088760000h+430 +DDERR_CANTLOCKSURFACE = 088760000h+435 +DDERR_SURFACEISOBSCURED = 088760000h+440 +DDERR_SURFACELOST = 088760000h+450 +DDERR_SURFACENOTATTACHED = 088760000h+460 +DDERR_TOOBIGHEIGHT = 088760000h+470 +DDERR_TOOBIGSIZE = 088760000h+480 +DDERR_TOOBIGWIDTH = 088760000h+490 +DDERR_UNSUPPORTEDFORMAT = 088760000h+510 +DDERR_UNSUPPORTEDMASK = 088760000h+520 +DDERR_VERTICALBLANKINPROGRESS = 088760000h+537 +DDERR_WASSTILLDRAWING = 088760000h+540 +DDERR_XALIGN = 088760000h+560 +DDERR_INVALIDDIRECTDRAWGUID = 088760000h+561 +DDERR_DIRECTDRAWALREADYCREATED = 088760000h+562 +DDERR_NODIRECTDRAWHW = 088760000h+563 +DDERR_PRIMARYSURFACEALREADYEXIST = 088760000h+564 +DDERR_NOEMULATION = 088760000h+565 +DDERR_REGIONTOOSMALL = 088760000h+566 +DDERR_CLIPPERISUSINGHWND = 088760000h+567 +DDERR_NOCLIPPERATTACHED = 088760000h+568 +DDERR_NOHWND = 088760000h+569 +DDERR_HWNDSUBCLASSED = 088760000h+570 +DDERR_HWNDALREADYSET = 088760000h+571 +DDERR_NOPALETTEATTACHED = 088760000h+572 +DDERR_NOPALETTEHW = 088760000h+573 +DDERR_BLTFASTCANTCLIP = 088760000h+574 +DDERR_NOBLTHW = 088760000h+575 +DDERR_NODDROPSHW = 088760000h+576 +DDERR_OVERLAYNOTVISIBLE = 088760000h+577 +DDERR_NOOVERLAYDEST = 088760000h+578 +DDERR_INVALIDPOSITION = 088760000h+579 +DDERR_NOTAOVERLAYSURFACE = 088760000h+580 +DDERR_EXCLUSIVEMODEALREADYSET = 088760000h+581 +DDERR_NOTFLIPPABLE = 088760000h+582 +DDERR_CANTDUPLICATE = 088760000h+583 +DDERR_NOTLOCKED = 088760000h+584 +DDERR_CANTCREATEDC = 088760000h+585 +DDERR_NODC = 088760000h+586 +DDERR_WRONGMODE = 088760000h+587 +DDERR_IMPLICITLYCREATED = 088760000h+588 +DDERR_NOTPALETTIZED = 088760000h+589 +DDERR_UNSUPPORTEDMODE = 088760000h+590 +DDERR_NOMIPMAPHW = 088760000h+591 +DDERR_INVALIDSURFACETYPE = 088760000h+592 +DDERR_NOOPTIMIZEHW = 088760000h+600 +DDERR_NOTLOADED = 088760000h+601 +DDERR_DCALREADYCREATED = 088760000h+620 +DDERR_NONONLOCALVIDMEM = 088760000h+630 +DDERR_CANTPAGELOCK = 088760000h+640 +DDERR_CANTPAGEUNLOCK = 088760000h+660 +DDERR_NOTPAGELOCKED = 088760000h+680 +DDERR_MOREDATA = 088760000h+690 +DDERR_VIDEONOTACTIVE = 088760000h+695 +DDERR_DEVICEDOESNTOWNSURFACE = 088760000h+699 diff --git a/toolchain/fasmw17332/EXAMPLES/WIN64/MANDEL/MANDEL.ASM b/toolchain/fasmw17332/EXAMPLES/WIN64/MANDEL/MANDEL.ASM new file mode 100644 index 0000000..fd8acf1 --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/WIN64/MANDEL/MANDEL.ASM @@ -0,0 +1,319 @@ + +format PE64 GUI 5.0 +entry start + +include 'win64a.inc' +include 'ddraw64.inc' + +section '.text' code readable executable + + start: + + sub rsp,8 + + and [DDraw],0 + and [DDSPrimary],0 + and [DDSBack],0 + + invoke GetModuleHandle,NULL + mov [hinstance],rax + mov [wc.hInstance],rax + + invoke LoadIcon,NULL,IDI_APPLICATION + mov [wc.hIcon],rax + invoke LoadCursor,NULL,IDC_ARROW + mov [wc.hCursor],rax + invoke RegisterClassEx,wc + test rax,rax + jz startup_error + + invoke CreateWindowEx,\ + 0,_class,_title,WS_POPUP+WS_VISIBLE,0,0,0,0,NULL,NULL,[hinstance],NULL + test rax,rax + jz startup_error + mov [hwnd],rax + + invoke DirectDrawCreate,NULL,DDraw,NULL + test rax,rax + jnz ddraw_error + + cominvk DDraw,SetCooperativeLevel,\ + [hwnd],DDSCL_EXCLUSIVE+DDSCL_FULLSCREEN + test rax,rax + jnz ddraw_error + + cominvk DDraw,SetDisplayMode,\ + 640,480,32 + test rax,rax + jnz ddraw_error + + mov [ddsd.dwSize],sizeof.DDSURFACEDESC + mov [ddsd.dwFlags],DDSD_CAPS+DDSD_BACKBUFFERCOUNT + mov [ddsd.ddsCaps.dwCaps],DDSCAPS_PRIMARYSURFACE+DDSCAPS_FLIP+DDSCAPS_COMPLEX + mov [ddsd.dwBackBufferCount],1 + cominvk DDraw,CreateSurface,\ + ddsd,DDSPrimary,NULL + or eax,eax + jnz ddraw_error + + mov [ddscaps.dwCaps],DDSCAPS_BACKBUFFER + cominvk DDSPrimary,GetAttachedSurface,\ + ddscaps,DDSBack + or eax,eax + jnz ddraw_error + +refresh: + + cominvk DDSPrimary,IsLost + test rax,rax + jz paint + cmp eax,DDERR_SURFACELOST + jne end_loop + cominvk DDSPrimary,Restore + + paint: + mov [ddsd.dwSize],sizeof.DDSURFACEDESC + mov [ddsd.dwFlags],0 + cominvk DDSBack,Lock,NULL,ddsd,DDLOCK_SURFACEMEMORYPTR+DDLOCK_WAIT,NULL + test rax,rax + jnz main_loop + mov rdi,[ddsd.lpSurface] + mov r10d,[ddsd.lPitch] + xor edx,edx + movsd xmm8,[y_top] + screen: + xor ebx,ebx + movsd xmm7,[x_left] + unpcklpd xmm7,xmm8 + row: + mov rcx,255 + xorpd xmm1,xmm1 + iterate: + + movapd xmm3,xmm1 + unpckhpd xmm3,xmm3 + mulsd xmm3,xmm1 + addsd xmm3,xmm3 + + mulpd xmm1,xmm1 + movapd xmm2,xmm1 ; for SSE3-capable processor + unpckhpd xmm2,xmm2 ; these three instructions can be + subsd xmm1,xmm2 ; replaced with HSUBPD XMM1,XMM1 + unpcklpd xmm1,xmm3 + addpd xmm1,xmm7 + + movapd xmm0,xmm1 + mulpd xmm0,xmm0 + movapd xmm2,xmm0 ; for SSE3-capable processor + shufpd xmm2,xmm2,1 ; these three instructions can be + addsd xmm0,xmm2 ; replaced with HADDPD XMM0,XMM0 + sqrtpd xmm0,xmm0 + comisd xmm0,[limit] + ja over + + loop iterate + over: + xor al,al + stosb + mov al,cl + stosb + ror al,3 + stosb + stosb + + movsd xmm0,[x_step] + addpd xmm7,xmm0 + inc ebx + cmp ebx,640 + jb row + sub rdi,640*4 + add rdi,r10 + subsd xmm8,[y_step] + inc edx + cmp edx,480 + jb screen + + mov [refresh_needed],0 + cominvk DDSBack,Unlock,NULL + cominvk DDSPrimary,Flip,0,0 + +main_loop: + + invoke PeekMessage,msg,NULL,0,0,PM_NOREMOVE + or eax,eax + jz no_message + invoke GetMessage,msg,NULL,0,0 + cmp eax,1 + jb end_loop + jne no_message + invoke TranslateMessage,msg + invoke DispatchMessage,msg + + cmp [refresh_needed],0 + jne refresh + + jmp main_loop + + no_message: + invoke WaitMessage + jmp main_loop + +ddraw_error: + invoke wsprintf,buffer,_ddraw_error,rax + invoke MessageBox,[hwnd],buffer,_error,MB_OK+MB_ICONERROR + invoke DestroyWindow,[hwnd] + invoke PostQuitMessage,2 + jmp main_loop + +startup_error: + invoke MessageBox,[hwnd],_startup_error,_error,MB_OK+MB_ICONERROR + invoke ExitProcess,1 + +end_loop: + cominvk DDraw,RestoreDisplayMode + + cmp [DDSBack],0 + je back_surface_released + cominvk DDSPrimary,DeleteAttachedSurface,0,DDSBack + back_surface_released: + cmp [DDSPrimary],0 + je primary_surface_released + cominvk DDSPrimary,Release + primary_surface_released: + cmp [DDraw],0 + je ddraw_released + cominvk DDraw,Release + ddraw_released: + + invoke ExitProcess,[msg.wParam] + +proc WindowProc uses rbx rsi rdi, hwnd,wmsg,wparam,lparam + cmp edx,WM_CREATE + je .wmcreate + cmp edx,WM_DESTROY + je .wmdestroy + cmp edx,WM_LBUTTONDOWN + je .wmlbuttondown + cmp edx,WM_RBUTTONDOWN + je .wmrbuttondown + cmp edx,WM_KEYDOWN + je .wmkeydown + cmp edx,WM_ACTIVATE + je .wmactivate + .defwindowproc: + invoke DefWindowProc,rcx,rdx,r8,r9 + jmp .finish + .wmcreate: + xor eax,eax + jmp .finish + .wmactivate: + test r8,r8 + jz .finish + or [refresh_needed],1 + jmp .finish + .wmlbuttondown: + movapd xmm0,[step] + divpd xmm0,[zoom] + movapd xmm1,xmm0 + subpd xmm1,[step] + movapd [step],xmm0 + movzx eax,r9w + cvtsi2sd xmm3,eax + shr r9,16 + movzx eax,r9w + cvtsi2sd xmm4,eax + unpcklpd xmm3,xmm4 + mulpd xmm1,xmm3 + xorpd xmm1,[negate] + addpd xmm1,[origin] + movapd [origin],xmm1 + or [refresh_needed],1 + jmp .finish + .wmrbuttondown: + movapd xmm0,[step] + mulpd xmm0,[zoom] + movapd xmm1,xmm0 + subpd xmm1,[step] + movapd [step],xmm0 + movzx eax,r9w + cvtsi2sd xmm3,eax + shr r9,16 + movzx eax,r9w + cvtsi2sd xmm4,eax + unpcklpd xmm3,xmm4 + mulpd xmm1,xmm3 + xorpd xmm1,[negate] + addpd xmm1,[origin] + movapd [origin],xmm1 + or [refresh_needed],1 + jmp .finish + .wmkeydown: + cmp r8d,VK_ESCAPE + jne .finish + .wmdestroy: + invoke PostQuitMessage,0 + xor eax,eax + .finish: + ret +endp + +section '.data' data readable writeable + + wc WNDCLASSEX sizeof.WNDCLASSEX,0,WindowProc,0,0,NULL,NULL,NULL,NULL,NULL,_class,NULL + + _title db 'flat assembler DirectDraw application',0 + _class db 'FDDRAW64',0 + + _error db 'Error',0 + _startup_error db 'Startup failed',0 + _ddraw_error db 'Direct Draw initialization failed (error code 0x%x).',0 + + align 16 ; SSE data follows + + label origin dqword + x_left dq -2.2 + y_top dq 1.25 + + label step dqword + x_step dq 0.0045 + y_step dq 0.0052 + + label zoom dqword + dq 1.2,1.2 + + label negate dqword + dq 8000000000000000h,0 + + limit dq 2.5 + +section '.bss' readable writeable + + hinstance dq ? + hwnd dq ? + msg MSG + + ddsd DDSURFACEDESC + ddscaps DDSCAPS + + DDraw DirectDraw + DDSPrimary DirectDrawSurface + DDSBack DirectDrawSurface + + rect RECT + + refresh_needed dd ? + + buffer rb 100h + + +section '.idata' import data readable + + library kernel32,'KERNEL32.DLL',\ + user32,'USER32.DLL',\ + ddraw,'DDRAW.DLL' + + include 'api\kernel32.inc' + include 'api\user32.inc' + + import ddraw,\ + DirectDrawCreate,'DirectDrawCreate' diff --git a/toolchain/fasmw17332/EXAMPLES/WIN64/OPENGL/OPENGL.ASM b/toolchain/fasmw17332/EXAMPLES/WIN64/OPENGL/OPENGL.ASM new file mode 100644 index 0000000..4753c96 --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/WIN64/OPENGL/OPENGL.ASM @@ -0,0 +1,615 @@ + +; OpenGL programming example + +format PE64 GUI 5.0 +entry start + +include 'win64a.inc' + +include '..\..\opengl\opengl.inc' + +section '.text' code readable executable + + start: + sub rsp,8 ; Make stack dqword aligned + + invoke GetModuleHandle,0 + mov [wc.hInstance],rax + invoke LoadIcon,0,IDI_APPLICATION + mov [wc.hIcon],rax + invoke LoadCursor,0,IDC_ARROW + mov [wc.hCursor],rax + invoke RegisterClass,wc + invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS,16,16,432,432,NULL,NULL,[wc.hInstance],NULL + + msg_loop: + invoke GetMessage,addr msg,NULL,0,0 + cmp eax,1 + jb end_loop + jne msg_loop + invoke TranslateMessage,addr msg + invoke DispatchMessage,addr msg + jmp msg_loop + + end_loop: + invoke ExitProcess,[msg.wParam] + +proc WindowProc uses rbx rsi rdi, hwnd,wmsg,wparam,lparam + mov [hwnd],rcx + frame + cmp edx,WM_CREATE + je .wmcreate + cmp edx,WM_SIZE + je .wmsize + cmp edx,WM_PAINT + je .wmpaint + cmp edx,WM_KEYDOWN + je .wmkeydown + cmp edx,WM_DESTROY + je .wmdestroy + .defwndproc: + invoke DefWindowProc,rcx,rdx,r8,r9 + jmp .finish + .wmcreate: + invoke GetDC,rcx + mov [hdc],rax + lea rdi,[pfd] + mov rcx,sizeof.PIXELFORMATDESCRIPTOR shr 3 + xor eax,eax + rep stosq + mov [pfd.nSize],sizeof.PIXELFORMATDESCRIPTOR + mov [pfd.nVersion],1 + mov [pfd.dwFlags],PFD_SUPPORT_OPENGL+PFD_DOUBLEBUFFER+PFD_DRAW_TO_WINDOW + mov [pfd.iLayerType],PFD_MAIN_PLANE + mov [pfd.iPixelType],PFD_TYPE_RGBA + mov [pfd.cColorBits],16 + mov [pfd.cDepthBits],16 + mov [pfd.cAccumBits],0 + mov [pfd.cStencilBits],0 + invoke ChoosePixelFormat,[hdc],addr pfd + invoke SetPixelFormat,[hdc],eax,addr pfd + invoke wglCreateContext,[hdc] + mov [hrc],rax + invoke wglMakeCurrent,[hdc],[hrc] + invoke GetClientRect,[hwnd],addr rc + invoke glViewport,0,0,[rc.right],[rc.bottom] + invoke GetTickCount + mov [clock],eax + xor eax,eax + jmp .finish + .wmsize: + invoke GetClientRect,[hwnd],addr rc + invoke glViewport,0,0,[rc.right],[rc.bottom] + xor eax,eax + jmp .finish + .wmpaint: + invoke GetTickCount + sub eax,[clock] + cmp eax,10 + jb .animation_ok + add [clock],eax + invoke glRotatef,float [theta],float dword 0.0,float dword 0.0,float dword 1.0 + .animation_ok: + invoke glClear,GL_COLOR_BUFFER_BIT + invoke glBegin,GL_QUADS + invoke glColor3f,float dword 1.0,float dword 0.1,float dword 0.1 + invoke glVertex3d,float -0.6,float -0.6,float 0.0 + invoke glColor3f,float dword 0.1,float dword 0.1,float dword 0.1 + invoke glVertex3d,float 0.6,float -0.6,float 0.0 + invoke glColor3f,float dword 0.1,float dword 0.1,float dword 1.0 + invoke glVertex3d,float 0.6,float 0.6,float 0.0 + invoke glColor3f,float dword 1.0,float dword 0.1,float dword 1.0 + invoke glVertex3d,float -0.6,float 0.6,float 0.0 + invoke glEnd + invoke SwapBuffers,[hdc] + xor eax,eax + jmp .finish + .wmkeydown: + cmp r8d,VK_ESCAPE + jne .defwndproc + .wmdestroy: + invoke wglMakeCurrent,0,0 + invoke wglDeleteContext,[hrc] + invoke ReleaseDC,[hwnd],[hdc] + invoke PostQuitMessage,0 + xor eax,eax + .finish: + endf + ret +endp + +section '.data' data readable writeable + + _title db 'OpenGL example',0 + _class db 'FASMOPENGL32',0 + + theta GLfloat 0.6 + + wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,NULL,NULL,_class + + hdc dq ? + hrc dq ? + + msg MSG + rc RECT + pfd PIXELFORMATDESCRIPTOR + + clock dd ? + +section '.idata' import data readable writeable + + library kernel,'KERNEL32.DLL',\ + user,'USER32.DLL',\ + gdi,'GDI32.DLL',\ + opengl,'OPENGL32.DLL',\ + glu,'GLU32.DLL' + + import kernel,\ + GetModuleHandle,'GetModuleHandleA',\ + GetTickCount,'GetTickCount',\ + ExitProcess,'ExitProcess' + + import user,\ + RegisterClass,'RegisterClassA',\ + CreateWindowEx,'CreateWindowExA',\ + DefWindowProc,'DefWindowProcA',\ + GetMessage,'GetMessageA',\ + TranslateMessage,'TranslateMessage',\ + DispatchMessage,'DispatchMessageA',\ + LoadCursor,'LoadCursorA',\ + LoadIcon,'LoadIconA',\ + GetClientRect,'GetClientRect',\ + GetDC,'GetDC',\ + ReleaseDC,'ReleaseDC',\ + PostQuitMessage,'PostQuitMessage' + + import gdi,\ + ChoosePixelFormat,'ChoosePixelFormat',\ + SetPixelFormat,'SetPixelFormat',\ + SwapBuffers,'SwapBuffers' + + import opengl,\ + glAccum,'glAccum',\ + glAlphaFunc,'glAlphaFunc',\ + glAreTexturesResident,'glAreTexturesResident',\ + glArrayElement,'glArrayElement',\ + glBegin,'glBegin',\ + glBindTexture,'glBindTexture',\ + glBitmap,'glBitmap',\ + glBlendFunc,'glBlendFunc',\ + glCallList,'glCallList',\ + glCallLists,'glCallLists',\ + glClear,'glClear',\ + glClearAccum,'glClearAccum',\ + glClearColor,'glClearColor',\ + glClearDepth,'glClearDepth',\ + glClearIndex,'glClearIndex',\ + glClearStencil,'glClearStencil',\ + glClipPlane,'glClipPlane',\ + glColor3b,'glColor3b',\ + glColor3bv,'glColor3bv',\ + glColor3d,'glColor3d',\ + glColor3dv,'glColor3dv',\ + glColor3f,'glColor3f',\ + glColor3fv,'glColor3fv',\ + glColor3i,'glColor3i',\ + glColor3iv,'glColor3iv',\ + glColor3s,'glColor3s',\ + glColor3sv,'glColor3sv',\ + glColor3ub,'glColor3ub',\ + glColor3ubv,'glColor3ubv',\ + glColor3ui,'glColor3ui',\ + glColor3uiv,'glColor3uiv',\ + glColor3us,'glColor3us',\ + glColor3usv,'glColor3usv',\ + glColor4b,'glColor4b',\ + glColor4bv,'glColor4bv',\ + glColor4d,'glColor4d',\ + glColor4dv,'glColor4dv',\ + glColor4f,'glColor4f',\ + glColor4fv,'glColor4fv',\ + glColor4i,'glColor4i',\ + glColor4iv,'glColor4iv',\ + glColor4s,'glColor4s',\ + glColor4sv,'glColor4sv',\ + glColor4ub,'glColor4ub',\ + glColor4ubv,'glColor4ubv',\ + glColor4ui,'glColor4ui',\ + glColor4uiv,'glColor4uiv',\ + glColor4us,'glColor4us',\ + glColor4usv,'glColor4usv',\ + glColorMask,'glColorMask',\ + glColorMaterial,'glColorMaterial',\ + glColorPointer,'glColorPointer',\ + glCopyPixels,'glCopyPixels',\ + glCopyTexImage1D,'glCopyTexImage1D',\ + glCopyTexImage2D,'glCopyTexImage2D',\ + glCopyTexSubImage1D,'glCopyTexSubImage1D',\ + glCopyTexSubImage2D,'glCopyTexSubImage2D',\ + glCullFace,'glCullFace',\ + glDeleteLists,'glDeleteLists',\ + glDeleteTextures,'glDeleteTextures',\ + glDepthFunc,'glDepthFunc',\ + glDepthMask,'glDepthMask',\ + glDepthRange,'glDepthRange',\ + glDisable,'glDisable',\ + glDisableClientState,'glDisableClientState',\ + glDrawArrays,'glDrawArrays',\ + glDrawBuffer,'glDrawBuffer',\ + glDrawElements,'glDrawElements',\ + glDrawPixels,'glDrawPixels',\ + glEdgeFlag,'glEdgeFlag',\ + glEdgeFlagPointer,'glEdgeFlagPointer',\ + glEdgeFlagv,'glEdgeFlagv',\ + glEnable,'glEnable',\ + glEnableClientState,'glEnableClientState',\ + glEnd,'glEnd',\ + glEndList,'glEndList',\ + glEvalCoord1d,'glEvalCoord1d',\ + glEvalCoord1dv,'glEvalCoord1dv',\ + glEvalCoord1f,'glEvalCoord1f',\ + glEvalCoord1fv,'glEvalCoord1fv',\ + glEvalCoord2d,'glEvalCoord2d',\ + glEvalCoord2dv,'glEvalCoord2dv',\ + glEvalCoord2f,'glEvalCoord2f',\ + glEvalCoord2fv,'glEvalCoord2fv',\ + glEvalMesh1,'glEvalMesh1',\ + glEvalMesh2,'glEvalMesh2',\ + glEvalPoint1,'glEvalPoint1',\ + glEvalPoint2,'glEvalPoint2',\ + glFeedbackBuffer,'glFeedbackBuffer',\ + glFinish,'glFinish',\ + glFlush,'glFlush',\ + glFogf,'glFogf',\ + glFogfv,'glFogfv',\ + glFogi,'glFogi',\ + glFogiv,'glFogiv',\ + glFrontFace,'glFrontFace',\ + glFrustum,'glFrustum',\ + glGenLists,'glGenLists',\ + glGenTextures,'glGenTextures',\ + glGetBooleanv,'glGetBooleanv',\ + glGetClipPlane,'glGetClipPlane',\ + glGetDoublev,'glGetDoublev',\ + glGetError,'glGetError',\ + glGetFloatv,'glGetFloatv',\ + glGetIntegerv,'glGetIntegerv',\ + glGetLightfv,'glGetLightfv',\ + glGetLightiv,'glGetLightiv',\ + glGetMapdv,'glGetMapdv',\ + glGetMapfv,'glGetMapfv',\ + glGetMapiv,'glGetMapiv',\ + glGetMaterialfv,'glGetMaterialfv',\ + glGetMaterialiv,'glGetMaterialiv',\ + glGetPixelMapfv,'glGetPixelMapfv',\ + glGetPixelMapuiv,'glGetPixelMapuiv',\ + glGetPixelMapusv,'glGetPixelMapusv',\ + glGetPointerv,'glGetPointerv',\ + glGetPolygonStipple,'glGetPolygonStipple',\ + glGetString,'glGetString',\ + glGetTexEnvfv,'glGetTexEnvfv',\ + glGetTexEnviv,'glGetTexEnviv',\ + glGetTexGendv,'glGetTexGendv',\ + glGetTexGenfv,'glGetTexGenfv',\ + glGetTexGeniv,'glGetTexGeniv',\ + glGetTexImage,'glGetTexImage',\ + glGetTexLevelParameterfv,'glGetTexLevelParameterfv',\ + glGetTexLevelParameteriv,'glGetTexLevelParameteriv',\ + glGetTexParameterfv,'glGetTexParameterfv',\ + glGetTexParameteriv,'glGetTexParameteriv',\ + glHint,'glHint',\ + glIndexMask,'glIndexMask',\ + glIndexPointer,'glIndexPointer',\ + glIndexd,'glIndexd',\ + glIndexdv,'glIndexdv',\ + glIndexf,'glIndexf',\ + glIndexfv,'glIndexfv',\ + glIndexi,'glIndexi',\ + glIndexiv,'glIndexiv',\ + glIndexs,'glIndexs',\ + glIndexsv,'glIndexsv',\ + glIndexub,'glIndexub',\ + glIndexubv,'glIndexubv',\ + glInitNames,'glInitNames',\ + glInterleavedArrays,'glInterleavedArrays',\ + glIsEnabled,'glIsEnabled',\ + glIsList,'glIsList',\ + glIsTexture,'glIsTexture',\ + glLightModelf,'glLightModelf',\ + glLightModelfv,'glLightModelfv',\ + glLightModeli,'glLightModeli',\ + glLightModeliv,'glLightModeliv',\ + glLightf,'glLightf',\ + glLightfv,'glLightfv',\ + glLighti,'glLighti',\ + glLightiv,'glLightiv',\ + glLineStipple,'glLineStipple',\ + glLineWidth,'glLineWidth',\ + glListBase,'glListBase',\ + glLoadIdentity,'glLoadIdentity',\ + glLoadMatrixd,'glLoadMatrixd',\ + glLoadMatrixf,'glLoadMatrixf',\ + glLoadName,'glLoadName',\ + glLogicOp,'glLogicOp',\ + glMap1d,'glMap1d',\ + glMap1f,'glMap1f',\ + glMap2d,'glMap2d',\ + glMap2f,'glMap2f',\ + glMapGrid1d,'glMapGrid1d',\ + glMapGrid1f,'glMapGrid1f',\ + glMapGrid2d,'glMapGrid2d',\ + glMapGrid2f,'glMapGrid2f',\ + glMaterialf,'glMaterialf',\ + glMaterialfv,'glMaterialfv',\ + glMateriali,'glMateriali',\ + glMaterialiv,'glMaterialiv',\ + glMatrixMode,'glMatrixMode',\ + glMultMatrixd,'glMultMatrixd',\ + glMultMatrixf,'glMultMatrixf',\ + glNewList,'glNewList',\ + glNormal3b,'glNormal3b',\ + glNormal3bv,'glNormal3bv',\ + glNormal3d,'glNormal3d',\ + glNormal3dv,'glNormal3dv',\ + glNormal3f,'glNormal3f',\ + glNormal3fv,'glNormal3fv',\ + glNormal3i,'glNormal3i',\ + glNormal3iv,'glNormal3iv',\ + glNormal3s,'glNormal3s',\ + glNormal3sv,'glNormal3sv',\ + glNormalPointer,'glNormalPointer',\ + glOrtho,'glOrtho',\ + glPassThrough,'glPassThrough',\ + glPixelMapfv,'glPixelMapfv',\ + glPixelMapuiv,'glPixelMapuiv',\ + glPixelMapusv,'glPixelMapusv',\ + glPixelStoref,'glPixelStoref',\ + glPixelStorei,'glPixelStorei',\ + glPixelTransferf,'glPixelTransferf',\ + glPixelTransferi,'glPixelTransferi',\ + glPixelZoom,'glPixelZoom',\ + glPointSize,'glPointSize',\ + glPolygonMode,'glPolygonMode',\ + glPolygonOffset,'glPolygonOffset',\ + glPolygonStipple,'glPolygonStipple',\ + glPopAttrib,'glPopAttrib',\ + glPopClientAttrib,'glPopClientAttrib',\ + glPopMatrix,'glPopMatrix',\ + glPopName,'glPopName',\ + glPrioritizeTextures,'glPrioritizeTextures',\ + glPushAttrib,'glPushAttrib',\ + glPushClientAttrib,'glPushClientAttrib',\ + glPushMatrix,'glPushMatrix',\ + glPushName,'glPushName',\ + glRasterPos2d,'glRasterPos2d',\ + glRasterPos2dv,'glRasterPos2dv',\ + glRasterPos2f,'glRasterPos2f',\ + glRasterPos2fv,'glRasterPos2fv',\ + glRasterPos2i,'glRasterPos2i',\ + glRasterPos2iv,'glRasterPos2iv',\ + glRasterPos2s,'glRasterPos2s',\ + glRasterPos2sv,'glRasterPos2sv',\ + glRasterPos3d,'glRasterPos3d',\ + glRasterPos3dv,'glRasterPos3dv',\ + glRasterPos3f,'glRasterPos3f',\ + glRasterPos3fv,'glRasterPos3fv',\ + glRasterPos3i,'glRasterPos3i',\ + glRasterPos3iv,'glRasterPos3iv',\ + glRasterPos3s,'glRasterPos3s',\ + glRasterPos3sv,'glRasterPos3sv',\ + glRasterPos4d,'glRasterPos4d',\ + glRasterPos4dv,'glRasterPos4dv',\ + glRasterPos4f,'glRasterPos4f',\ + glRasterPos4fv,'glRasterPos4fv',\ + glRasterPos4i,'glRasterPos4i',\ + glRasterPos4iv,'glRasterPos4iv',\ + glRasterPos4s,'glRasterPos4s',\ + glRasterPos4sv,'glRasterPos4sv',\ + glReadBuffer,'glReadBuffer',\ + glReadPixels,'glReadPixels',\ + glRectd,'glRectd',\ + glRectdv,'glRectdv',\ + glRectf,'glRectf',\ + glRectfv,'glRectfv',\ + glRecti,'glRecti',\ + glRectiv,'glRectiv',\ + glRects,'glRects',\ + glRectsv,'glRectsv',\ + glRenderMode,'glRenderMode',\ + glRotated,'glRotated',\ + glRotatef,'glRotatef',\ + glScaled,'glScaled',\ + glScalef,'glScalef',\ + glScissor,'glScissor',\ + glSelectBuffer,'glSelectBuffer',\ + glShadeModel,'glShadeModel',\ + glStencilFunc,'glStencilFunc',\ + glStencilMask,'glStencilMask',\ + glStencilOp,'glStencilOp',\ + glTexCoord1d,'glTexCoord1d',\ + glTexCoord1dv,'glTexCoord1dv',\ + glTexCoord1f,'glTexCoord1f',\ + glTexCoord1fv,'glTexCoord1fv',\ + glTexCoord1i,'glTexCoord1i',\ + glTexCoord1iv,'glTexCoord1iv',\ + glTexCoord1s,'glTexCoord1s',\ + glTexCoord1sv,'glTexCoord1sv',\ + glTexCoord2d,'glTexCoord2d',\ + glTexCoord2dv,'glTexCoord2dv',\ + glTexCoord2f,'glTexCoord2f',\ + glTexCoord2fv,'glTexCoord2fv',\ + glTexCoord2i,'glTexCoord2i',\ + glTexCoord2iv,'glTexCoord2iv',\ + glTexCoord2s,'glTexCoord2s',\ + glTexCoord2sv,'glTexCoord2sv',\ + glTexCoord3d,'glTexCoord3d',\ + glTexCoord3dv,'glTexCoord3dv',\ + glTexCoord3f,'glTexCoord3f',\ + glTexCoord3fv,'glTexCoord3fv',\ + glTexCoord3i,'glTexCoord3i',\ + glTexCoord3iv,'glTexCoord3iv',\ + glTexCoord3s,'glTexCoord3s',\ + glTexCoord3sv,'glTexCoord3sv',\ + glTexCoord4d,'glTexCoord4d',\ + glTexCoord4dv,'glTexCoord4dv',\ + glTexCoord4f,'glTexCoord4f',\ + glTexCoord4fv,'glTexCoord4fv',\ + glTexCoord4i,'glTexCoord4i',\ + glTexCoord4iv,'glTexCoord4iv',\ + glTexCoord4s,'glTexCoord4s',\ + glTexCoord4sv,'glTexCoord4sv',\ + glTexCoordPointer,'glTexCoordPointer',\ + glTexEnvf,'glTexEnvf',\ + glTexEnvfv,'glTexEnvfv',\ + glTexEnvi,'glTexEnvi',\ + glTexEnviv,'glTexEnviv',\ + glTexGend,'glTexGend',\ + glTexGendv,'glTexGendv',\ + glTexGenf,'glTexGenf',\ + glTexGenfv,'glTexGenfv',\ + glTexGeni,'glTexGeni',\ + glTexGeniv,'glTexGeniv',\ + glTexImage1D,'glTexImage1D',\ + glTexImage2D,'glTexImage2D',\ + glTexParameterf,'glTexParameterf',\ + glTexParameterfv,'glTexParameterfv',\ + glTexParameteri,'glTexParameteri',\ + glTexParameteriv,'glTexParameteriv',\ + glTexSubImage1D,'glTexSubImage1D',\ + glTexSubImage2D,'glTexSubImage2D',\ + glTranslated,'glTranslated',\ + glTranslatef,'glTranslatef',\ + glVertex2d,'glVertex2d',\ + glVertex2dv,'glVertex2dv',\ + glVertex2f,'glVertex2f',\ + glVertex2fv,'glVertex2fv',\ + glVertex2i,'glVertex2i',\ + glVertex2iv,'glVertex2iv',\ + glVertex2s,'glVertex2s',\ + glVertex2sv,'glVertex2sv',\ + glVertex3d,'glVertex3d',\ + glVertex3dv,'glVertex3dv',\ + glVertex3f,'glVertex3f',\ + glVertex3fv,'glVertex3fv',\ + glVertex3i,'glVertex3i',\ + glVertex3iv,'glVertex3iv',\ + glVertex3s,'glVertex3s',\ + glVertex3sv,'glVertex3sv',\ + glVertex4d,'glVertex4d',\ + glVertex4dv,'glVertex4dv',\ + glVertex4f,'glVertex4f',\ + glVertex4fv,'glVertex4fv',\ + glVertex4i,'glVertex4i',\ + glVertex4iv,'glVertex4iv',\ + glVertex4s,'glVertex4s',\ + glVertex4sv,'glVertex4sv',\ + glVertexPointer,'glVertexPointer',\ + glViewport,'glViewport',\ + wglGetProcAddress,'wglGetProcAddress',\ + wglCopyContext,'wglCopyContext',\ + wglCreateContext,'wglCreateContext',\ + wglCreateLayerContext,'wglCreateLayerContext',\ + wglDeleteContext,'wglDeleteContext',\ + wglDescribeLayerPlane,'wglDescribeLayerPlane',\ + wglGetCurrentContext,'wglGetCurrentContext',\ + wglGetCurrentDC,'wglGetCurrentDC',\ + wglGetLayerPaletteEntries,'wglGetLayerPaletteEntries',\ + wglMakeCurrent,'wglMakeCurrent',\ + wglRealizeLayerPalette,'wglRealizeLayerPalette',\ + wglSetLayerPaletteEntries,'wglSetLayerPaletteEntries',\ + wglShareLists,'wglShareLists',\ + wglSwapLayerBuffers,'wglSwapLayerBuffers',\ + wglSwapMultipleBuffers,'wglSwapMultipleBuffers',\ + wglUseFontBitmapsA,'wglUseFontBitmapsA',\ + wglUseFontOutlinesA,'wglUseFontOutlinesA',\ + wglUseFontBitmapsW,'wglUseFontBitmapsW',\ + wglUseFontOutlinesW,'wglUseFontOutlinesW',\ + glDrawRangeElements,'glDrawRangeElements',\ + glTexImage3D,'glTexImage3D',\ + glBlendColor,'glBlendColor',\ + glBlendEquation,'glBlendEquation',\ + glColorSubTable,'glColorSubTable',\ + glCopyColorSubTable,'glCopyColorSubTable',\ + glColorTable,'glColorTable',\ + glCopyColorTable,'glCopyColorTable',\ + glColorTableParameteriv,'glColorTableParameteriv',\ + glColorTableParameterfv,'glColorTableParameterfv',\ + glGetColorTable,'glGetColorTable',\ + glGetColorTableParameteriv,'glGetColorTableParameteriv',\ + glGetColorTableParameterfv,'glGetColorTableParameterfv',\ + glConvolutionFilter1D,'glConvolutionFilter1D',\ + glConvolutionFilter2D,'glConvolutionFilter2D',\ + glCopyConvolutionFilter1D,'glCopyConvolutionFilter1D',\ + glCopyConvolutionFilter2D,'glCopyConvolutionFilter2D',\ + glGetConvolutionFilter,'glGetConvolutionFilter',\ + glSeparableFilter2D,'glSeparableFilter2D',\ + glGetSeparableFilter,'glGetSeparableFilter',\ + glConvolutionParameteri,'glConvolutionParameteri',\ + glConvolutionParameteriv,'glConvolutionParameteriv',\ + glConvolutionParameterf,'glConvolutionParameterf',\ + glConvolutionParameterfv,'glConvolutionParameterfv',\ + glGetConvolutionParameteriv,'glGetConvolutionParameteriv',\ + glGetConvolutionParameterfv,'glGetConvolutionParameterfv',\ + glHistogram,'glHistogram',\ + glResetHistogram,'glResetHistogram',\ + glGetHistogram,'glGetHistogram',\ + glGetHistogramParameteriv,'glGetHistogramParameteriv',\ + glGetHistogramParameterfv,'glGetHistogramParameterfv',\ + glMinmax,'glMinmax',\ + glResetMinmax,'glResetMinmax',\ + glGetMinmax,'glGetMinmax',\ + glGetMinmaxParameteriv,'glGetMinmaxParameteriv',\ + glGetMinmaxParameterfv,'glGetMinmaxParameterfv' + + import glu,\ + gluBeginCurve,'gluBeginCurve',\ + gluBeginPolygon,'gluBeginPolygon',\ + gluBeginSurface,'gluBeginSurface',\ + gluBeginTrim,'gluBeginTrim',\ + gluBuild1DMipmaps,'gluBuild1DMipmaps',\ + gluBuild2DMipmaps,'gluBuild2DMipmaps',\ + gluCylinder,'gluCylinder',\ + gluDeleteNurbsRenderer,'gluDeleteNurbsRenderer',\ + gluDeleteQuadric,'gluDeleteQuadric',\ + gluDeleteTess,'gluDeleteTess',\ + gluDisk,'gluDisk',\ + gluEndCurve,'gluEndCurve',\ + gluEndPolygon,'gluEndPolygon',\ + gluEndSurface,'gluEndSurface',\ + gluEndTrim,'gluEndTrim',\ + gluErrorString,'gluErrorString',\ + gluGetNurbsProperty,'gluGetNurbsProperty',\ + gluGetString,'gluGetString',\ + gluGetTessProperty,'gluGetTessProperty',\ + gluLoadSamplingMatrices,'gluLoadSamplingMatrices',\ + gluLookAt,'gluLookAt',\ + gluNewNurbsRenderer,'gluNewNurbsRenderer',\ + gluNewQuadric,'gluNewQuadric',\ + gluNewTess,'gluNewTess',\ + gluNextContour,'gluNextContour',\ + gluNurbsCallback,'gluNurbsCallback',\ + gluNurbsCurve,'gluNurbsCurve',\ + gluNurbsProperty,'gluNurbsProperty',\ + gluNurbsSurface,'gluNurbsSurface',\ + gluOrtho2D,'gluOrtho2D',\ + gluPartialDisk,'gluPartialDisk',\ + gluPerspective,'gluPerspective',\ + gluPickMatrix,'gluPickMatrix',\ + gluProject,'gluProject',\ + gluPwlCurve,'gluPwlCurve',\ + gluQuadricCallback,'gluQuadricCallback',\ + gluQuadricDrawStyle,'gluQuadricDrawStyle',\ + gluQuadricNormals,'gluQuadricNormals',\ + gluQuadricOrientation,'gluQuadricOrientation',\ + gluQuadricTexture,'gluQuadricTexture',\ + gluScaleImage,'gluScaleImage',\ + gluSphere,'gluSphere',\ + gluTessBeginContour,'gluTessBeginContour',\ + gluTessBeginPolygon,'gluTessBeginPolygon',\ + gluTessCallback,'gluTessCallback',\ + gluTessEndContour,'gluTessEndContour',\ + gluTessEndPolygon,'gluTessEndPolygon',\ + gluTessNormal,'gluTessNormal',\ + gluTessProperty,'gluTessProperty',\ + gluTessVertex,'gluTessVertex',\ + gluUnProject,'gluUnProject' diff --git a/toolchain/fasmw17332/EXAMPLES/WIN64/PE64DEMO/PE64DEMO.ASM b/toolchain/fasmw17332/EXAMPLES/WIN64/PE64DEMO/PE64DEMO.ASM new file mode 100644 index 0000000..c0b9558 --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/WIN64/PE64DEMO/PE64DEMO.ASM @@ -0,0 +1,45 @@ + +; Example of 64-bit PE program + +format PE64 GUI +entry start + +section '.text' code readable executable + + start: + sub rsp,8*5 ; reserve stack for API use and make stack dqword aligned + + mov r9d,0 + lea r8,[_caption] + lea rdx,[_message] + mov rcx,0 + call [MessageBoxA] + + mov ecx,eax + call [ExitProcess] + +section '.data' data readable writeable + + _caption db 'Win64 assembly program',0 + _message db 'Hello World!',0 + +section '.idata' import data readable writeable + + dd 0,0,0,RVA kernel_name,RVA kernel_table + dd 0,0,0,RVA user_name,RVA user_table + dd 0,0,0,0,0 + + kernel_table: + ExitProcess dq RVA _ExitProcess + dq 0 + user_table: + MessageBoxA dq RVA _MessageBoxA + dq 0 + + kernel_name db 'KERNEL32.DLL',0 + user_name db 'USER32.DLL',0 + + _ExitProcess dw 0 + db 'ExitProcess',0 + _MessageBoxA dw 0 + db 'MessageBoxA',0 diff --git a/toolchain/fasmw17332/EXAMPLES/WIN64/TEMPLATE/TEMPLATE.ASM b/toolchain/fasmw17332/EXAMPLES/WIN64/TEMPLATE/TEMPLATE.ASM new file mode 100644 index 0000000..f67bd7e --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/WIN64/TEMPLATE/TEMPLATE.ASM @@ -0,0 +1,82 @@ + +format PE64 GUI 5.0 +entry start + +include 'win64a.inc' + +section '.text' code readable executable + + start: + sub rsp,8 ; Make stack dqword aligned + + invoke GetModuleHandle,0 + mov [wc.hInstance],rax + invoke LoadIcon,0,IDI_APPLICATION + mov [wc.hIcon],rax + mov [wc.hIconSm],rax + invoke LoadCursor,0,IDC_ARROW + mov [wc.hCursor],rax + invoke RegisterClassEx,wc + test rax,rax + jz error + + invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,256,192,NULL,NULL,[wc.hInstance],NULL + test rax,rax + jz error + + msg_loop: + invoke GetMessage,msg,NULL,0,0 + cmp eax,1 + jb end_loop + jne msg_loop + invoke TranslateMessage,msg + invoke DispatchMessage,msg + jmp msg_loop + + error: + invoke MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK + + end_loop: + invoke ExitProcess,[msg.wParam] + +proc WindowProc uses rbx rsi rdi, hwnd,wmsg,wparam,lparam + +; Note that first four parameters are passed in registers, +; while names given in the declaration of procedure refer to the stack +; space reserved for them - you may store them there to be later accessible +; if the contents of registers gets destroyed. This may look like: +; mov [hwnd],rcx +; mov [wmsg],edx +; mov [wparam],r8 +; mov [lparam],r9 + + cmp edx,WM_DESTROY + je .wmdestroy + .defwndproc: + invoke DefWindowProc,rcx,rdx,r8,r9 + jmp .finish + .wmdestroy: + invoke PostQuitMessage,0 + xor eax,eax + .finish: + ret + +endp + +section '.data' data readable writeable + + _title TCHAR 'Win64 program template',0 + _class TCHAR 'FASMWIN64',0 + _error TCHAR 'Startup failed.',0 + + wc WNDCLASSEX sizeof.WNDCLASSEX,0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class,NULL + + msg MSG + +section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL',\ + user32,'USER32.DLL' + + include 'api\kernel32.inc' + include 'api\user32.inc' diff --git a/toolchain/fasmw17332/EXAMPLES/WIN64/USECOM/USECOM.ASM b/toolchain/fasmw17332/EXAMPLES/WIN64/USECOM/USECOM.ASM new file mode 100644 index 0000000..d55687a --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/WIN64/USECOM/USECOM.ASM @@ -0,0 +1,142 @@ + +; Component Object Model usage demonstration + +format PE64 GUI 5.0 +entry start + +include 'win64a.inc' + +struc GUID def + { + match d1-d2-d3-d4-d5, def + \{ + .Data1 dd 0x\#d1 + .Data2 dw 0x\#d2 + .Data3 dw 0x\#d3 + .Data4 db 0x\#d4 shr 8,0x\#d4 and 0FFh + .Data5 db 0x\#d5 shr 40,0x\#d5 shr 32 and 0FFh,0x\#d5 shr 24 and 0FFh,0x\#d5 shr 16 and 0FFh,0x\#d5 shr 8 and 0FFh,0x\#d5 and 0FFh + \} + } + +interface ITaskBarList,\ + QueryInterface,\ + AddRef,\ + Release,\ + HrInit,\ + AddTab,\ + DeleteTab,\ + ActivateTab,\ + SetActiveAlt + +CLSCTX_INPROC_SERVER = 0x1 +CLSCTX_INPROC_HANDLER = 0x2 +CLSCTX_LOCAL_SERVER = 0x4 +CLSCTX_INPROC_SERVER16 = 0x8 +CLSCTX_REMOTE_SERVER = 0x10 +CLSCTX_INPROC_HANDLER16 = 0x20 +CLSCTX_INPROC_SERVERX86 = 0x40 +CLSCTX_INPROC_HANDLERX86 = 0x80 +CLSCTX_ESERVER_HANDLER = 0x100 +CLSCTX_NO_CODE_DOWNLOAD = 0x400 +CLSCTX_NO_CUSTOM_MARSHAL = 0x1000 +CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000 +CLSCTX_NO_FAILURE_LOG = 0x4000 +CLSCTX_DISABLE_AAA = 0x8000 +CLSCTX_ENABLE_AAA = 0x10000 +CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000 + +ID_EXIT = IDCANCEL +ID_SHOW = 100 +ID_HIDE = 101 + +IDD_COMDEMO = 1 + +section '.text' code readable executable + + start: + sub rsp,8 ; Make stack dqword aligned + + invoke CoInitialize,NULL + invoke CoCreateInstance,CLSID_TaskbarList,NULL,CLSCTX_INPROC_SERVER,IID_ITaskbarList,ShellTaskBar + + invoke GetModuleHandle,0 + invoke DialogBoxParam,rax,IDD_COMDEMO,HWND_DESKTOP,COMDemo,0 + + cominvk ShellTaskBar,Release + + invoke ExitProcess,0 + +proc COMDemo uses rbx, hwnd,msg,wparam,lparam + mov [hwnd],rcx + cmp edx,WM_INITDIALOG + je .wminitdialog + cmp edx,WM_COMMAND + je .wmcommand + cmp edx,WM_CLOSE + je .wmclose + xor eax,eax + jmp .finish + .wminitdialog: + jmp .processed + .wmcommand: + cmp r8,BN_CLICKED shl 16 + ID_EXIT + je .wmclose + cmp r8,BN_CLICKED shl 16 + ID_SHOW + je .show + cmp r8,BN_CLICKED shl 16 + ID_HIDE + jne .processed + .hide: + cominvk ShellTaskBar,HrInit + cominvk ShellTaskBar,DeleteTab,[hwnd] + jmp .processed + .show: + mov rbx,[ShellTaskBar] + comcall rbx,ITaskBarList,HrInit + comcall rbx,ITaskBarList,AddTab,[hwnd] + comcall rbx,ITaskBarList,ActivateTab,[hwnd] + jmp .processed + .wmclose: + invoke EndDialog,[hwnd],0 + .processed: + mov eax,1 + .finish: + ret +endp + +section '.data' data readable writeable + + CLSID_TaskbarList GUID 56FDF344-FD6D-11D0-958A-006097C9A090 + IID_ITaskbarList GUID 56FDF342-FD6D-11D0-958A-006097C9A090 + + ShellTaskBar ITaskBarList + +section '.idata' import data readable + + library kernel,'KERNEL32.DLL',\ + user,'USER32.DLL',\ + ole,'OLE32.DLL' + + import kernel,\ + GetModuleHandle,'GetModuleHandleA',\ + ExitProcess,'ExitProcess' + + import user,\ + DialogBoxParam,'DialogBoxParamA',\ + EndDialog,'EndDialog' + + import ole,\ + CoInitialize,'CoInitialize',\ + CoCreateInstance,'CoCreateInstance' + +section '.rsrc' resource data readable + + directory RT_DIALOG,dialogs + + resource dialogs,\ + IDD_COMDEMO,LANG_ENGLISH+SUBLANG_DEFAULT,comdemo + + dialog comdemo,'Taskbar item control',70,70,170,24,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'BUTTON','Show',ID_SHOW,4,4,45,15,WS_VISIBLE+WS_TABSTOP + dialogitem 'BUTTON','Hide',ID_HIDE,54,4,45,15,WS_VISIBLE+WS_TABSTOP + dialogitem 'BUTTON','Exit',ID_EXIT,120,4,45,15,WS_VISIBLE+WS_TABSTOP + enddialog diff --git a/toolchain/fasmw17332/EXAMPLES/WIN64/WIN64AVX/WIN64AVX.ASM b/toolchain/fasmw17332/EXAMPLES/WIN64/WIN64AVX/WIN64AVX.ASM new file mode 100644 index 0000000..a6f9dda --- /dev/null +++ b/toolchain/fasmw17332/EXAMPLES/WIN64/WIN64AVX/WIN64AVX.ASM @@ -0,0 +1,98 @@ + +format PE64 NX GUI 6.0 +entry start + +include 'win64a.inc' + +section '.data' data readable writeable + + _title db 'AVX playground',0 + _error db 'AVX instructions are not supported.',0 + + x dq 3.14159265389 + + vector_output: + rept 16 i:0 + { + db 'ymm',`i,': %f,%f,%f,%f',13,10 + } + db 0 + + buffer db 1000h dup ? + +section '.text' code readable executable + + start: + + mov eax,1 + cpuid + and ecx,18000000h + cmp ecx,18000000h + jne no_AVX + xor ecx,ecx + xgetbv + and eax,110b + cmp eax,110b + jne no_AVX + + vbroadcastsd ymm0, [x] + vsqrtpd ymm1, ymm0 + + vsubpd ymm2, ymm0, ymm1 + vsubpd ymm3, ymm1, ymm2 + + vaddpd xmm4, xmm2, xmm3 + vaddpd ymm5, ymm4, ymm0 + + vperm2f128 ymm6, ymm4, ymm5, 03h + vshufpd ymm7, ymm6, ymm5, 10010011b + + vroundpd ymm8, ymm7, 0011b + vroundpd ymm9, ymm7, 0 + + sub rsp,418h + + rept 16 i:0 + { + vmovups [rsp+10h+i*32],ymm#i + } + + mov r8,[rsp+10h] + mov r9,[rsp+18h] + lea rdx,[vector_output] + lea rcx,[buffer] + call [sprintf] + + xor ecx,ecx + lea rdx,[buffer] + lea r8,[_title] + xor r9d,r9d + call [MessageBoxA] + + xor ecx,ecx + call [ExitProcess] + + no_AVX: + + sub rsp,28h + + xor ecx,ecx + lea rdx,[_error] + lea r8,[_title] + mov r9d,10h + call [MessageBoxA] + + mov ecx,1 + call [ExitProcess] + +section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL',\ + user32,'USER32.DLL',\ + msvcrt,'MSVCRT.DLL' + + include 'api\kernel32.inc' + include 'api\user32.inc' + + import msvcrt,\ + sprintf,'sprintf' diff --git a/toolchain/fasmw17332/FASM.EXE b/toolchain/fasmw17332/FASM.EXE new file mode 100644 index 0000000..ebcfecb Binary files /dev/null and b/toolchain/fasmw17332/FASM.EXE differ diff --git a/toolchain/fasmw17332/FASM.pdf b/toolchain/fasmw17332/FASM.pdf new file mode 100644 index 0000000..c5f900b Binary files /dev/null and b/toolchain/fasmw17332/FASM.pdf differ diff --git a/toolchain/fasmw17332/FASMW.EXE b/toolchain/fasmw17332/FASMW.EXE new file mode 100644 index 0000000..908b2da Binary files /dev/null and b/toolchain/fasmw17332/FASMW.EXE differ diff --git a/toolchain/fasmw17332/INCLUDE/API/ADVAPI32.INC b/toolchain/fasmw17332/INCLUDE/API/ADVAPI32.INC new file mode 100644 index 0000000..0a97a2c --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/API/ADVAPI32.INC @@ -0,0 +1,535 @@ + +; ADVAPI32 API calls + +import advapi32,\ + AbortSystemShutdownA,'AbortSystemShutdownA',\ + AbortSystemShutdownW,'AbortSystemShutdownW',\ + AccessCheck,'AccessCheck',\ + AccessCheckAndAuditAlarmA,'AccessCheckAndAuditAlarmA',\ + AccessCheckAndAuditAlarmW,'AccessCheckAndAuditAlarmW',\ + AccessCheckByType,'AccessCheckByType',\ + AccessCheckByTypeAndAuditAlarmA,'AccessCheckByTypeAndAuditAlarmA',\ + AccessCheckByTypeAndAuditAlarmW,'AccessCheckByTypeAndAuditAlarmW',\ + AccessCheckByTypeResultList,'AccessCheckByTypeResultList',\ + AccessCheckByTypeResultListAndAuditAlarmA,'AccessCheckByTypeResultListAndAuditAlarmA',\ + AccessCheckByTypeResultListAndAuditAlarmW,'AccessCheckByTypeResultListAndAuditAlarmW',\ + AddAccessAllowedAce,'AddAccessAllowedAce',\ + AddAccessAllowedAceEx,'AddAccessAllowedAceEx',\ + AddAccessAllowedObjectAce,'AddAccessAllowedObjectAce',\ + AddAccessDeniedAce,'AddAccessDeniedAce',\ + AddAccessDeniedAceEx,'AddAccessDeniedAceEx',\ + AddAccessDeniedObjectAce,'AddAccessDeniedObjectAce',\ + AddAce,'AddAce',\ + AddAuditAccessAce,'AddAuditAccessAce',\ + AddAuditAccessAceEx,'AddAuditAccessAceEx',\ + AddAuditAccessObjectAce,'AddAuditAccessObjectAce',\ + AdjustTokenGroups,'AdjustTokenGroups',\ + AdjustTokenPrivileges,'AdjustTokenPrivileges',\ + AllocateAndInitializeSid,'AllocateAndInitializeSid',\ + AllocateLocallyUniqueId,'AllocateLocallyUniqueId',\ + AreAllAccessesGranted,'AreAllAccessesGranted',\ + AreAnyAccessesGranted,'AreAnyAccessesGranted',\ + BackupEventLogA,'BackupEventLogA',\ + BackupEventLogW,'BackupEventLogW',\ + BuildExplicitAccessWithNameA,'BuildExplicitAccessWithNameA',\ + BuildExplicitAccessWithNameW,'BuildExplicitAccessWithNameW',\ + BuildImpersonateExplicitAccessWithNameA,'BuildImpersonateExplicitAccessWithNameA',\ + BuildImpersonateExplicitAccessWithNameW,'BuildImpersonateExplicitAccessWithNameW',\ + BuildImpersonateTrusteeA,'BuildImpersonateTrusteeA',\ + BuildImpersonateTrusteeW,'BuildImpersonateTrusteeW',\ + BuildSecurityDescriptorA,'BuildSecurityDescriptorA',\ + BuildSecurityDescriptorW,'BuildSecurityDescriptorW',\ + BuildTrusteeWithNameA,'BuildTrusteeWithNameA',\ + BuildTrusteeWithNameW,'BuildTrusteeWithNameW',\ + BuildTrusteeWithSidA,'BuildTrusteeWithSidA',\ + BuildTrusteeWithSidW,'BuildTrusteeWithSidW',\ + CancelOverlappedAccess,'CancelOverlappedAccess',\ + ChangeServiceConfig2A,'ChangeServiceConfig2A',\ + ChangeServiceConfig2W,'ChangeServiceConfig2W',\ + ChangeServiceConfigA,'ChangeServiceConfigA',\ + ChangeServiceConfigW,'ChangeServiceConfigW',\ + ClearEventLogA,'ClearEventLogA',\ + ClearEventLogW,'ClearEventLogW',\ + CloseEventLog,'CloseEventLog',\ + CloseRaw,'CloseRaw',\ + CloseServiceHandle,'CloseServiceHandle',\ + ControlService,'ControlService',\ + ConvertAccessToSecurityDescriptorA,'ConvertAccessToSecurityDescriptorA',\ + ConvertAccessToSecurityDescriptorW,'ConvertAccessToSecurityDescriptorW',\ + ConvertSecurityDescriptorToAccessA,'ConvertSecurityDescriptorToAccessA',\ + ConvertSecurityDescriptorToAccessW,'ConvertSecurityDescriptorToAccessW',\ + ConvertSecurityDescriptorToAccessNamedA,'ConvertSecurityDescriptorToAccessNamedA',\ + ConvertSecurityDescriptorToAccessNamedW,'ConvertSecurityDescriptorToAccessNamedW',\ + ConvertToAutoInheritPrivateObjectSecurity,'ConvertToAutoInheritPrivateObjectSecurity',\ + CopySid,'CopySid',\ + CreatePrivateObjectSecurity,'CreatePrivateObjectSecurity',\ + CreatePrivateObjectSecurityEx,'CreatePrivateObjectSecurityEx',\ + CreateProcessAsUserA,'CreateProcessAsUserA',\ + CreateProcessAsUserW,'CreateProcessAsUserW',\ + CreateRestrictedToken,'CreateRestrictedToken',\ + CreateServiceA,'CreateServiceA',\ + CreateServiceW,'CreateServiceW',\ + CryptAcquireContextA,'CryptAcquireContextA',\ + CryptAcquireContextW,'CryptAcquireContextW',\ + CryptContextAddRef,'CryptContextAddRef',\ + CryptCreateHash,'CryptCreateHash',\ + CryptDecrypt,'CryptDecrypt',\ + CryptDeriveKey,'CryptDeriveKey',\ + CryptDestroyHash,'CryptDestroyHash',\ + CryptDestroyKey,'CryptDestroyKey',\ + CryptDuplicateHash,'CryptDuplicateHash',\ + CryptDuplicateKey,'CryptDuplicateKey',\ + CryptEncrypt,'CryptEncrypt',\ + CryptEnumProviderTypesA,'CryptEnumProviderTypesA',\ + CryptEnumProviderTypesW,'CryptEnumProviderTypesW',\ + CryptEnumProvidersA,'CryptEnumProvidersA',\ + CryptEnumProvidersW,'CryptEnumProvidersW',\ + CryptExportKey,'CryptExportKey',\ + CryptGenKey,'CryptGenKey',\ + CryptGenRandom,'CryptGenRandom',\ + CryptGetDefaultProviderA,'CryptGetDefaultProviderA',\ + CryptGetDefaultProviderW,'CryptGetDefaultProviderW',\ + CryptGetHashParam,'CryptGetHashParam',\ + CryptGetKeyParam,'CryptGetKeyParam',\ + CryptGetProvParam,'CryptGetProvParam',\ + CryptGetUserKey,'CryptGetUserKey',\ + CryptHashData,'CryptHashData',\ + CryptHashSessionKey,'CryptHashSessionKey',\ + CryptImportKey,'CryptImportKey',\ + CryptReleaseContext,'CryptReleaseContext',\ + CryptSetHashParam,'CryptSetHashParam',\ + CryptSetKeyParam,'CryptSetKeyParam',\ + CryptSetProvParam,'CryptSetProvParam',\ + CryptSetProviderA,'CryptSetProviderA',\ + CryptSetProviderW,'CryptSetProviderW',\ + CryptSetProviderExA,'CryptSetProviderExA',\ + CryptSetProviderExW,'CryptSetProviderExW',\ + CryptSignHashA,'CryptSignHashA',\ + CryptSignHashW,'CryptSignHashW',\ + CryptVerifySignatureA,'CryptVerifySignatureA',\ + CryptVerifySignatureW,'CryptVerifySignatureW',\ + DecryptFileA,'DecryptFileA',\ + DecryptFileW,'DecryptFileW',\ + DeleteAce,'DeleteAce',\ + DeleteService,'DeleteService',\ + DeregisterEventSource,'DeregisterEventSource',\ + DestroyPrivateObjectSecurity,'DestroyPrivateObjectSecurity',\ + DuplicateToken,'DuplicateToken',\ + DuplicateTokenEx,'DuplicateTokenEx',\ + ElfBackupEventLogFileA,'ElfBackupEventLogFileA',\ + ElfBackupEventLogFileW,'ElfBackupEventLogFileW',\ + ElfChangeNotify,'ElfChangeNotify',\ + ElfClearEventLogFileA,'ElfClearEventLogFileA',\ + ElfClearEventLogFileW,'ElfClearEventLogFileW',\ + ElfCloseEventLog,'ElfCloseEventLog',\ + ElfDeregisterEventSource,'ElfDeregisterEventSource',\ + ElfNumberOfRecords,'ElfNumberOfRecords',\ + ElfOldestRecord,'ElfOldestRecord',\ + ElfOpenBackupEventLogA,'ElfOpenBackupEventLogA',\ + ElfOpenBackupEventLogW,'ElfOpenBackupEventLogW',\ + ElfOpenEventLogA,'ElfOpenEventLogA',\ + ElfOpenEventLogW,'ElfOpenEventLogW',\ + ElfReadEventLogA,'ElfReadEventLogA',\ + ElfReadEventLogW,'ElfReadEventLogW',\ + ElfRegisterEventSourceA,'ElfRegisterEventSourceA',\ + ElfRegisterEventSourceW,'ElfRegisterEventSourceW',\ + ElfReportEventA,'ElfReportEventA',\ + ElfReportEventW,'ElfReportEventW',\ + EncryptFileA,'EncryptFileA',\ + EncryptFileW,'EncryptFileW',\ + EnumDependentServicesA,'EnumDependentServicesA',\ + EnumDependentServicesW,'EnumDependentServicesW',\ + EnumServicesStatusA,'EnumServicesStatusA',\ + EnumServicesStatusW,'EnumServicesStatusW',\ + EqualPrefixSid,'EqualPrefixSid',\ + EqualSid,'EqualSid',\ + FindFirstFreeAce,'FindFirstFreeAce',\ + FreeSid,'FreeSid',\ + GetAccessPermissionsForObjectA,'GetAccessPermissionsForObjectA',\ + GetAccessPermissionsForObjectW,'GetAccessPermissionsForObjectW',\ + GetAce,'GetAce',\ + GetAclInformation,'GetAclInformation',\ + GetAuditedPermissionsFromAclA,'GetAuditedPermissionsFromAclA',\ + GetAuditedPermissionsFromAclW,'GetAuditedPermissionsFromAclW',\ + GetCurrentHwProfileA,'GetCurrentHwProfileA',\ + GetCurrentHwProfileW,'GetCurrentHwProfileW',\ + GetEffectiveRightsFromAclA,'GetEffectiveRightsFromAclA',\ + GetEffectiveRightsFromAclW,'GetEffectiveRightsFromAclW',\ + GetExplicitEntriesFromAclA,'GetExplicitEntriesFromAclA',\ + GetExplicitEntriesFromAclW,'GetExplicitEntriesFromAclW',\ + GetFileSecurityA,'GetFileSecurityA',\ + GetFileSecurityW,'GetFileSecurityW',\ + GetKernelObjectSecurity,'GetKernelObjectSecurity',\ + GetLengthSid,'GetLengthSid',\ + GetMultipleTrusteeA,'GetMultipleTrusteeA',\ + GetMultipleTrusteeW,'GetMultipleTrusteeW',\ + GetMultipleTrusteeOperationA,'GetMultipleTrusteeOperationA',\ + GetMultipleTrusteeOperationW,'GetMultipleTrusteeOperationW',\ + GetNamedSecurityInfoA,'GetNamedSecurityInfoA',\ + GetNamedSecurityInfoW,'GetNamedSecurityInfoW',\ + GetNamedSecurityInfoExA,'GetNamedSecurityInfoExA',\ + GetNamedSecurityInfoExW,'GetNamedSecurityInfoExW',\ + GetNumberOfEventLogRecords,'GetNumberOfEventLogRecords',\ + GetOldestEventLogRecord,'GetOldestEventLogRecord',\ + GetOverlappedAccessResults,'GetOverlappedAccessResults',\ + GetPrivateObjectSecurity,'GetPrivateObjectSecurity',\ + GetSecurityDescriptorControl,'GetSecurityDescriptorControl',\ + GetSecurityDescriptorDacl,'GetSecurityDescriptorDacl',\ + GetSecurityDescriptorGroup,'GetSecurityDescriptorGroup',\ + GetSecurityDescriptorLength,'GetSecurityDescriptorLength',\ + GetSecurityDescriptorOwner,'GetSecurityDescriptorOwner',\ + GetSecurityDescriptorSacl,'GetSecurityDescriptorSacl',\ + GetSecurityInfo,'GetSecurityInfo',\ + GetSecurityInfoExA,'GetSecurityInfoExA',\ + GetSecurityInfoExW,'GetSecurityInfoExW',\ + GetServiceDisplayNameA,'GetServiceDisplayNameA',\ + GetServiceDisplayNameW,'GetServiceDisplayNameW',\ + GetServiceKeyNameA,'GetServiceKeyNameA',\ + GetServiceKeyNameW,'GetServiceKeyNameW',\ + GetSidLengthRequiredA,'GetSidLengthRequiredA',\ + GetSidLengthRequiredW,'GetSidLengthRequiredW',\ + GetSidSubAuthority,'GetSidSubAuthority',\ + GetSidSubAuthorityCount,'GetSidSubAuthorityCount',\ + GetTokenInformation,'GetTokenInformation',\ + GetTrusteeNameA,'GetTrusteeNameA',\ + GetTrusteeNameW,'GetTrusteeNameW',\ + GetTrusteeTypeA,'GetTrusteeTypeA',\ + GetTrusteeTypeW,'GetTrusteeTypeW',\ + GetUserNameA,'GetUserNameA',\ + GetUserNameW,'GetUserNameW',\ + I_ScSetServiceBitsA,'I_ScSetServiceBitsA',\ + I_ScSetServiceBitsW,'I_ScSetServiceBitsW',\ + ImpersonateLoggedOnUser,'ImpersonateLoggedOnUser',\ + ImpersonateNamedPipeClient,'ImpersonateNamedPipeClient',\ + ImpersonateSelf,'ImpersonateSelf',\ + InitializeAcl,'InitializeAcl',\ + InitializeSecurityDescriptor,'InitializeSecurityDescriptor',\ + InitializeSid,'InitializeSid',\ + InitiateSystemShutdownA,'InitiateSystemShutdownA',\ + InitiateSystemShutdownW,'InitiateSystemShutdownW',\ + IsTextUnicode,'IsTextUnicode',\ + IsTokenRestricted,'IsTokenRestricted',\ + IsValidAcl,'IsValidAcl',\ + IsValidSecurityDescriptor,'IsValidSecurityDescriptor',\ + IsValidSid,'IsValidSid',\ + LockServiceDatabase,'LockServiceDatabase',\ + LogonUserA,'LogonUserA',\ + LogonUserW,'LogonUserW',\ + LookupAccountNameA,'LookupAccountNameA',\ + LookupAccountNameW,'LookupAccountNameW',\ + LookupAccountSidA,'LookupAccountSidA',\ + LookupAccountSidW,'LookupAccountSidW',\ + LookupPrivilegeDisplayNameA,'LookupPrivilegeDisplayNameA',\ + LookupPrivilegeDisplayNameW,'LookupPrivilegeDisplayNameW',\ + LookupPrivilegeNameA,'LookupPrivilegeNameA',\ + LookupPrivilegeNameW,'LookupPrivilegeNameW',\ + LookupPrivilegeValueA,'LookupPrivilegeValueA',\ + LookupPrivilegeValueW,'LookupPrivilegeValueW',\ + LookupSecurityDescriptorPartsA,'LookupSecurityDescriptorPartsA',\ + LookupSecurityDescriptorPartsW,'LookupSecurityDescriptorPartsW',\ + LsaAddAccountRights,'LsaAddAccountRights',\ + LsaAddPrivilegesToAccount,'LsaAddPrivilegesToAccount',\ + LsaClearAuditLog,'LsaClearAuditLog',\ + LsaClose,'LsaClose',\ + LsaCreateAccount,'LsaCreateAccount',\ + LsaCreateSecret,'LsaCreateSecret',\ + LsaCreateTrustedDomain,'LsaCreateTrustedDomain',\ + LsaCreateTrustedDomainEx,'LsaCreateTrustedDomainEx',\ + LsaDelete,'LsaDelete',\ + LsaDeleteTrustedDomain,'LsaDeleteTrustedDomain',\ + LsaEnumerateAccountRights,'LsaEnumerateAccountRights',\ + LsaEnumerateAccounts,'LsaEnumerateAccounts',\ + LsaEnumerateAccountsWithUserRight,'LsaEnumerateAccountsWithUserRight',\ + LsaEnumeratePrivileges,'LsaEnumeratePrivileges',\ + LsaEnumeratePrivilegesOfAccount,'LsaEnumeratePrivilegesOfAccount',\ + LsaEnumerateTrustedDomains,'LsaEnumerateTrustedDomains',\ + LsaEnumerateTrustedDomainsEx,'LsaEnumerateTrustedDomainsEx',\ + LsaFreeMemory,'LsaFreeMemory',\ + LsaGetQuotasForAccount,'LsaGetQuotasForAccount',\ + LsaGetSystemAccessAccount,'LsaGetSystemAccessAccount',\ + LsaGetUserName,'LsaGetUserName',\ + LsaICLookupNames,'LsaICLookupNames',\ + LsaICLookupSids,'LsaICLookupSids',\ + LsaIGetTrustedDomainAuthInfoBlobs,'LsaIGetTrustedDomainAuthInfoBlobs',\ + LsaISetTrustedDomainAuthInfoBlobs,'LsaISetTrustedDomainAuthInfoBlobs',\ + LsaLookupNames,'LsaLookupNames',\ + LsaLookupPrivilegeDisplayName,'LsaLookupPrivilegeDisplayName',\ + LsaLookupPrivilegeName,'LsaLookupPrivilegeName',\ + LsaLookupPrivilegeValue,'LsaLookupPrivilegeValue',\ + LsaLookupSids,'LsaLookupSids',\ + LsaNtStatusToWinError,'LsaNtStatusToWinError',\ + LsaOpenAccount,'LsaOpenAccount',\ + LsaOpenPolicy,'LsaOpenPolicy',\ + LsaOpenSecret,'LsaOpenSecret',\ + LsaOpenTrustedDomain,'LsaOpenTrustedDomain',\ + LsaQueryDomainInformationPolicy,'LsaQueryDomainInformationPolicy',\ + LsaQueryInfoTrustedDomain,'LsaQueryInfoTrustedDomain',\ + LsaQueryInformationPolicy,'LsaQueryInformationPolicy',\ + LsaQueryLocalInformationPolicy,'LsaQueryLocalInformationPolicy',\ + LsaQuerySecret,'LsaQuerySecret',\ + LsaQuerySecurityObject,'LsaQuerySecurityObject',\ + LsaQueryTrustedDomainInfo,'LsaQueryTrustedDomainInfo',\ + LsaQueryTrustedDomainInfoByName,'LsaQueryTrustedDomainInfoByName',\ + LsaRemoveAccountRights,'LsaRemoveAccountRights',\ + LsaRemovePrivilegesFromAccount,'LsaRemovePrivilegesFromAccount',\ + LsaRetrievePrivateData,'LsaRetrievePrivateData',\ + LsaSetDomainInformationPolicy,'LsaSetDomainInformationPolicy',\ + LsaSetInformationPolicy,'LsaSetInformationPolicy',\ + LsaSetInformationTrustedDomain,'LsaSetInformationTrustedDomain',\ + LsaSetLocalInformationPolicy,'LsaSetLocalInformationPolicy',\ + LsaSetQuotasForAccount,'LsaSetQuotasForAccount',\ + LsaSetSecret,'LsaSetSecret',\ + LsaSetSecurityObject,'LsaSetSecurityObject',\ + LsaSetSystemAccessAccount,'LsaSetSystemAccessAccount',\ + LsaSetTrustedDomainInfoByName,'LsaSetTrustedDomainInfoByName',\ + LsaSetTrustedDomainInformation,'LsaSetTrustedDomainInformation',\ + LsaStorePrivateData,'LsaStorePrivateData',\ + MakeAbsoluteSD,'MakeAbsoluteSD',\ + MakeSelfRelativeSD,'MakeSelfRelativeSD',\ + MapGenericMask,'MapGenericMask',\ + NotifyBootConfigStatus,'NotifyBootConfigStatus',\ + NotifyChangeEventLog,'NotifyChangeEventLog',\ + ObjectCloseAuditAlarmA,'ObjectCloseAuditAlarmA',\ + ObjectCloseAuditAlarmW,'ObjectCloseAuditAlarmW',\ + ObjectDeleteAuditAlarmA,'ObjectDeleteAuditAlarmA',\ + ObjectDeleteAuditAlarmW,'ObjectDeleteAuditAlarmW',\ + ObjectOpenAuditAlarmA,'ObjectOpenAuditAlarmA',\ + ObjectOpenAuditAlarmW,'ObjectOpenAuditAlarmW',\ + ObjectPrivilegeAuditAlarmA,'ObjectPrivilegeAuditAlarmA',\ + ObjectPrivilegeAuditAlarmW,'ObjectPrivilegeAuditAlarmW',\ + OpenBackupEventLogA,'OpenBackupEventLogA',\ + OpenBackupEventLogW,'OpenBackupEventLogW',\ + OpenEventLogA,'OpenEventLogA',\ + OpenEventLogW,'OpenEventLogW',\ + OpenProcessToken,'OpenProcessToken',\ + OpenRawA,'OpenRawA',\ + OpenRawW,'OpenRawW',\ + OpenSCManagerA,'OpenSCManagerA',\ + OpenSCManagerW,'OpenSCManagerW',\ + OpenServiceA,'OpenServiceA',\ + OpenServiceW,'OpenServiceW',\ + OpenThreadToken,'OpenThreadToken',\ + PrivilegeCheck,'PrivilegeCheck',\ + PrivilegedServiceAuditAlarmA,'PrivilegedServiceAuditAlarmA',\ + PrivilegedServiceAuditAlarmW,'PrivilegedServiceAuditAlarmW',\ + QueryRecoveryAgentsA,'QueryRecoveryAgentsA',\ + QueryRecoveryAgentsW,'QueryRecoveryAgentsW',\ + QueryServiceConfig2A,'QueryServiceConfig2A',\ + QueryServiceConfig2W,'QueryServiceConfig2W',\ + QueryServiceConfigA,'QueryServiceConfigA',\ + QueryServiceConfigW,'QueryServiceConfigW',\ + QueryServiceLockStatusA,'QueryServiceLockStatusA',\ + QueryServiceLockStatusW,'QueryServiceLockStatusW',\ + QueryServiceObjectSecurity,'QueryServiceObjectSecurity',\ + QueryServiceStatus,'QueryServiceStatus',\ + QueryWindows31FilesMigration,'QueryWindows31FilesMigration',\ + ReadEventLogA,'ReadEventLogA',\ + ReadEventLogW,'ReadEventLogW',\ + ReadRaw,'ReadRaw',\ + RegCloseKey,'RegCloseKey',\ + RegConnectRegistryA,'RegConnectRegistryA',\ + RegConnectRegistryW,'RegConnectRegistryW',\ + RegCreateKeyA,'RegCreateKeyA',\ + RegCreateKeyW,'RegCreateKeyW',\ + RegCreateKeyExA,'RegCreateKeyExA',\ + RegCreateKeyExW,'RegCreateKeyExW',\ + RegDeleteKeyA,'RegDeleteKeyA',\ + RegDeleteKeyW,'RegDeleteKeyW',\ + RegDeleteValueA,'RegDeleteValueA',\ + RegDeleteValueW,'RegDeleteValueW',\ + RegEnumKeyA,'RegEnumKeyA',\ + RegEnumKeyW,'RegEnumKeyW',\ + RegEnumKeyExA,'RegEnumKeyExA',\ + RegEnumKeyExW,'RegEnumKeyExW',\ + RegEnumValueA,'RegEnumValueA',\ + RegEnumValueW,'RegEnumValueW',\ + RegFlushKey,'RegFlushKey',\ + RegGetKeySecurity,'RegGetKeySecurity',\ + RegLoadKeyA,'RegLoadKeyA',\ + RegLoadKeyW,'RegLoadKeyW',\ + RegNotifyChangeKeyValue,'RegNotifyChangeKeyValue',\ + RegOpenKeyA,'RegOpenKeyA',\ + RegOpenKeyW,'RegOpenKeyW',\ + RegOpenKeyExA,'RegOpenKeyExA',\ + RegOpenKeyExW,'RegOpenKeyExW',\ + RegOverridePredefKey,'RegOverridePredefKey',\ + RegQueryInfoKeyA,'RegQueryInfoKeyA',\ + RegQueryInfoKeyW,'RegQueryInfoKeyW',\ + RegQueryMultipleValuesA,'RegQueryMultipleValuesA',\ + RegQueryMultipleValuesW,'RegQueryMultipleValuesW',\ + RegQueryValueA,'RegQueryValueA',\ + RegQueryValueW,'RegQueryValueW',\ + RegQueryValueExA,'RegQueryValueExA',\ + RegQueryValueExW,'RegQueryValueExW',\ + RegReplaceKeyA,'RegReplaceKeyA',\ + RegReplaceKeyW,'RegReplaceKeyW',\ + RegRestoreKeyA,'RegRestoreKeyA',\ + RegRestoreKeyW,'RegRestoreKeyW',\ + RegSaveKeyA,'RegSaveKeyA',\ + RegSaveKeyW,'RegSaveKeyW',\ + RegSetKeySecurity,'RegSetKeySecurity',\ + RegSetValueA,'RegSetValueA',\ + RegSetValueW,'RegSetValueW',\ + RegSetValueExA,'RegSetValueExA',\ + RegSetValueExW,'RegSetValueExW',\ + RegUnLoadKeyA,'RegUnLoadKeyA',\ + RegUnLoadKeyW,'RegUnLoadKeyW',\ + RegisterEventSourceA,'RegisterEventSourceA',\ + RegisterEventSourceW,'RegisterEventSourceW',\ + RegisterServiceCtrlHandlerA,'RegisterServiceCtrlHandlerA',\ + RegisterServiceCtrlHandlerW,'RegisterServiceCtrlHandlerW',\ + ReportEventA,'ReportEventA',\ + ReportEventW,'ReportEventW',\ + RevertToSelf,'RevertToSelf',\ + SetAclInformation,'SetAclInformation',\ + SetEntriesInAccessListA,'SetEntriesInAccessListA',\ + SetEntriesInAccessListW,'SetEntriesInAccessListW',\ + SetEntriesInAclA,'SetEntriesInAclA',\ + SetEntriesInAclW,'SetEntriesInAclW',\ + SetEntriesInAuditListA,'SetEntriesInAuditListA',\ + SetEntriesInAuditListW,'SetEntriesInAuditListW',\ + SetFileSecurityA,'SetFileSecurityA',\ + SetFileSecurityW,'SetFileSecurityW',\ + SetKernelObjectSecurity,'SetKernelObjectSecurity',\ + SetNamedSecurityInfoA,'SetNamedSecurityInfoA',\ + SetNamedSecurityInfoW,'SetNamedSecurityInfoW',\ + SetNamedSecurityInfoExA,'SetNamedSecurityInfoExA',\ + SetNamedSecurityInfoExW,'SetNamedSecurityInfoExW',\ + SetPrivateObjectSecurity,'SetPrivateObjectSecurity',\ + SetPrivateObjectSecurityEx,'SetPrivateObjectSecurityEx',\ + SetSecurityDescriptorControl,'SetSecurityDescriptorControl',\ + SetSecurityDescriptorDacl,'SetSecurityDescriptorDacl',\ + SetSecurityDescriptorGroup,'SetSecurityDescriptorGroup',\ + SetSecurityDescriptorOwner,'SetSecurityDescriptorOwner',\ + SetSecurityDescriptorSacl,'SetSecurityDescriptorSacl',\ + SetSecurityInfo,'SetSecurityInfo',\ + SetSecurityInfoExA,'SetSecurityInfoExA',\ + SetSecurityInfoExW,'SetSecurityInfoExW',\ + SetServiceBits,'SetServiceBits',\ + SetServiceObjectSecurity,'SetServiceObjectSecurity',\ + SetServiceStatus,'SetServiceStatus',\ + SetThreadToken,'SetThreadToken',\ + SetTokenInformation,'SetTokenInformation',\ + StartServiceA,'StartServiceA',\ + StartServiceW,'StartServiceW',\ + StartServiceCtrlDispatcherA,'StartServiceCtrlDispatcherA',\ + StartServiceCtrlDispatcherW,'StartServiceCtrlDispatcherW',\ + SynchronizeWindows31FilesAndWindowsNTRegistry,'SynchronizeWindows31FilesAndWindowsNTRegistry',\ + TrusteeAccessToObjectA,'TrusteeAccessToObjectA',\ + TrusteeAccessToObjectW,'TrusteeAccessToObjectW',\ + UnlockServiceDatabase,'UnlockServiceDatabase',\ + WriteRaw,'WriteRaw' + +api AbortSystemShutdown,\ + AccessCheckAndAuditAlarm,\ + AccessCheckByTypeAndAuditAlarm,\ + AccessCheckByTypeResultListAndAuditAlarm,\ + BackupEventLog,\ + BuildExplicitAccessWithName,\ + BuildImpersonateExplicitAccessWithName,\ + BuildImpersonateTrustee,\ + BuildSecurityDescriptor,\ + BuildTrusteeWithName,\ + BuildTrusteeWithSid,\ + ChangeServiceConfig2,\ + ChangeServiceConfig,\ + ClearEventLog,\ + ConvertAccessToSecurityDescriptor,\ + ConvertSecurityDescriptorToAccess,\ + ConvertSecurityDescriptorToAccessNamed,\ + CreateProcessAsUser,\ + CreateService,\ + CryptAcquireContext,\ + CryptEnumProviderTypes,\ + CryptEnumProviders,\ + CryptGetDefaultProvider,\ + CryptSetProvider,\ + CryptSetProviderEx,\ + CryptSignHash,\ + CryptVerifySignature,\ + DecryptFile,\ + ElfBackupEventLogFile,\ + ElfClearEventLogFile,\ + ElfOpenBackupEventLog,\ + ElfOpenEventLog,\ + ElfReadEventLog,\ + ElfRegisterEventSource,\ + ElfReportEvent,\ + EncryptFile,\ + EnumDependentServices,\ + EnumServicesStatus,\ + GetAccessPermissionsForObject,\ + GetAuditedPermissionsFromAcl,\ + GetCurrentHwProfile,\ + GetEffectiveRightsFromAcl,\ + GetExplicitEntriesFromAcl,\ + GetFileSecurity,\ + GetMultipleTrustee,\ + GetMultipleTrusteeOperation,\ + GetNamedSecurityInfo,\ + GetNamedSecurityInfoEx,\ + GetSecurityInfoEx,\ + GetServiceDisplayName,\ + GetServiceKeyName,\ + GetSidLengthRequired,\ + GetTrusteeName,\ + GetTrusteeType,\ + GetUserName,\ + I_ScSetServiceBits,\ + InitiateSystemShutdown,\ + LogonUser,\ + LookupAccountName,\ + LookupAccountSid,\ + LookupPrivilegeDisplayName,\ + LookupPrivilegeName,\ + LookupPrivilegeValue,\ + LookupSecurityDescriptorParts,\ + ObjectCloseAuditAlarm,\ + ObjectDeleteAuditAlarm,\ + ObjectOpenAuditAlarm,\ + ObjectPrivilegeAuditAlarm,\ + OpenBackupEventLog,\ + OpenEventLog,\ + OpenRaw,\ + OpenSCManager,\ + OpenService,\ + PrivilegedServiceAuditAlarm,\ + QueryRecoveryAgents,\ + QueryServiceConfig2,\ + QueryServiceConfig,\ + QueryServiceLockStatus,\ + ReadEventLog,\ + RegConnectRegistry,\ + RegCreateKey,\ + RegCreateKeyEx,\ + RegDeleteKey,\ + RegDeleteValue,\ + RegEnumKey,\ + RegEnumKeyEx,\ + RegEnumValue,\ + RegLoadKey,\ + RegOpenKey,\ + RegOpenKeyEx,\ + RegQueryInfoKey,\ + RegQueryMultipleValues,\ + RegQueryValue,\ + RegQueryValueEx,\ + RegReplaceKey,\ + RegRestoreKey,\ + RegSaveKey,\ + RegSetValue,\ + RegSetValueEx,\ + RegUnLoadKey,\ + RegisterEventSource,\ + RegisterServiceCtrlHandler,\ + ReportEvent,\ + SetEntriesInAccessList,\ + SetEntriesInAcl,\ + SetEntriesInAuditList,\ + SetFileSecurity,\ + SetNamedSecurityInfo,\ + SetNamedSecurityInfoEx,\ + SetSecurityInfoEx,\ + StartService,\ + StartServiceCtrlDispatcher,\ + TrusteeAccessToObject diff --git a/toolchain/fasmw17332/INCLUDE/API/COMCTL32.INC b/toolchain/fasmw17332/INCLUDE/API/COMCTL32.INC new file mode 100644 index 0000000..dc28c61 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/API/COMCTL32.INC @@ -0,0 +1,81 @@ + +; COMCTL32 API calls + +import comctl32,\ + CreateMappedBitmap,'CreateMappedBitmap',\ + CreatePropertySheetPageA,'CreatePropertySheetPageA',\ + CreatePropertySheetPageW,'CreatePropertySheetPageW',\ + CreateStatusWindowA,'CreateStatusWindowA',\ + CreateStatusWindowW,'CreateStatusWindowW',\ + CreateToolbar,'CreateToolbar',\ + CreateToolbarEx,'CreateToolbarEx',\ + CreateUpDownControl,'CreateUpDownControl',\ + DestroyPropertySheetPage,'DestroyPropertySheetPage',\ + DrawInsert,'DrawInsert',\ + DrawStatusTextA,'DrawStatusTextA',\ + DrawStatusTextW,'DrawStatusTextW',\ + FlatSB_EnableScrollBar,'FlatSB_EnableScrollBar',\ + FlatSB_GetScrollInfo,'FlatSB_GetScrollInfo',\ + FlatSB_GetScrollPos,'FlatSB_GetScrollPos',\ + FlatSB_GetScrollProp,'FlatSB_GetScrollProp',\ + FlatSB_GetScrollRange,'FlatSB_GetScrollRange',\ + FlatSB_SetScrollInfo,'FlatSB_SetScrollInfo',\ + FlatSB_SetScrollPos,'FlatSB_SetScrollPos',\ + FlatSB_SetScrollProp,'FlatSB_SetScrollProp',\ + FlatSB_SetScrollRange,'FlatSB_SetScrollRange',\ + FlatSB_ShowScrollBar,'FlatSB_ShowScrollBar',\ + GetEffectiveClientRect,'GetEffectiveClientRect',\ + ImageList_Add,'ImageList_Add',\ + ImageList_AddIcon,'ImageList_AddIcon',\ + ImageList_AddMasked,'ImageList_AddMasked',\ + ImageList_BeginDrag,'ImageList_BeginDrag',\ + ImageList_Copy,'ImageList_Copy',\ + ImageList_Create,'ImageList_Create',\ + ImageList_Destroy,'ImageList_Destroy',\ + ImageList_DragEnter,'ImageList_DragEnter',\ + ImageList_DragLeave,'ImageList_DragLeave',\ + ImageList_DragMove,'ImageList_DragMove',\ + ImageList_DragShowNolock,'ImageList_DragShowNolock',\ + ImageList_Draw,'ImageList_Draw',\ + ImageList_DrawEx,'ImageList_DrawEx',\ + ImageList_DrawIndirect,'ImageList_DrawIndirect',\ + ImageList_Duplicate,'ImageList_Duplicate',\ + ImageList_EndDrag,'ImageList_EndDrag',\ + ImageList_GetBkColor,'ImageList_GetBkColor',\ + ImageList_GetDragImage,'ImageList_GetDragImage',\ + ImageList_GetIcon,'ImageList_GetIcon',\ + ImageList_GetIconSize,'ImageList_GetIconSize',\ + ImageList_GetImageCount,'ImageList_GetImageCount',\ + ImageList_GetImageInfo,'ImageList_GetImageInfo',\ + ImageList_GetImageRect,'ImageList_GetImageRect',\ + ImageList_LoadImageA,'ImageList_LoadImageA',\ + ImageList_LoadImageW,'ImageList_LoadImageW',\ + ImageList_Merge,'ImageList_Merge',\ + ImageList_Read,'ImageList_Read',\ + ImageList_Remove,'ImageList_Remove',\ + ImageList_Replace,'ImageList_Replace',\ + ImageList_ReplaceIcon,'ImageList_ReplaceIcon',\ + ImageList_SetBkColor,'ImageList_SetBkColor',\ + ImageList_SetDragCursorImage,'ImageList_SetDragCursorImage',\ + ImageList_SetFilter,'ImageList_SetFilter',\ + ImageList_SetIconSize,'ImageList_SetIconSize',\ + ImageList_SetImageCount,'ImageList_SetImageCount',\ + ImageList_SetOverlayImage,'ImageList_SetOverlayImage',\ + ImageList_Write,'ImageList_Write',\ + InitCommonControls,'InitCommonControls',\ + InitCommonControlsEx,'InitCommonControlsEx',\ + InitializeFlatSB,'InitializeFlatSB',\ + LBItemFromPt,'LBItemFromPt',\ + MakeDragList,'MakeDragList',\ + MenuHelp,'MenuHelp',\ + PropertySheetA,'PropertySheetA',\ + PropertySheetW,'PropertySheetW',\ + ShowHideMenuCtl,'ShowHideMenuCtl',\ + UninitializeFlatSB,'UninitializeFlatSB',\ + _TrackMouseEvent,'_TrackMouseEvent' + +api CreatePropertySheetPage,\ + CreateStatusWindow,\ + DrawStatusText,\ + ImageList_LoadImage,\ + PropertySheet diff --git a/toolchain/fasmw17332/INCLUDE/API/COMDLG32.INC b/toolchain/fasmw17332/INCLUDE/API/COMDLG32.INC new file mode 100644 index 0000000..9347fbc --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/API/COMDLG32.INC @@ -0,0 +1,38 @@ + +; COMDLG32 API calls + +import comdlg32,\ + ChooseColorA,'ChooseColorA',\ + ChooseColorW,'ChooseColorW',\ + ChooseFontA,'ChooseFontA',\ + ChooseFontW,'ChooseFontW',\ + CommDlgExtendedError,'CommDlgExtendedError',\ + FindTextA,'FindTextA',\ + FindTextW,'FindTextW',\ + FormatCharDlgProc,'FormatCharDlgProc',\ + GetFileTitleA,'GetFileTitleA',\ + GetFileTitleW,'GetFileTitleW',\ + GetOpenFileNameA,'GetOpenFileNameA',\ + GetOpenFileNameW,'GetOpenFileNameW',\ + GetSaveFileNameA,'GetSaveFileNameA',\ + GetSaveFileNameW,'GetSaveFileNameW',\ + LoadAlterBitmap,'LoadAlterBitmap',\ + PageSetupDlgA,'PageSetupDlgA',\ + PageSetupDlgW,'PageSetupDlgW',\ + PrintDlgA,'PrintDlgA',\ + PrintDlgW,'PrintDlgW',\ + ReplaceTextA,'ReplaceTextA',\ + ReplaceTextW,'ReplaceTextW',\ + WantArrows,'WantArrows',\ + dwLBSubclass,'dwLBSubclass',\ + dwOKSubclass,'dwOKSubclass' + +api ChooseColor,\ + ChooseFont,\ + FindText,\ + GetFileTitle,\ + GetOpenFileName,\ + GetSaveFileName,\ + PageSetupDlg,\ + PrintDlg,\ + ReplaceText diff --git a/toolchain/fasmw17332/INCLUDE/API/GDI32.INC b/toolchain/fasmw17332/INCLUDE/API/GDI32.INC new file mode 100644 index 0000000..4cec631 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/API/GDI32.INC @@ -0,0 +1,419 @@ + +; GDI32 API calls + +import gdi32,\ + AbortDoc,'AbortDoc',\ + AbortPath,'AbortPath',\ + AddFontMemResourceEx,'AddFontMemResourceEx',\ + AddFontResourceA,'AddFontResourceA',\ + AddFontResourceW,'AddFontResourceW',\ + AddFontResourceExA,'AddFontResourceExA',\ + AddFontResourceExW,'AddFontResourceExW',\ + AngleArc,'AngleArc',\ + AnimatePalette,'AnimatePalette',\ + Arc,'Arc',\ + ArcTo,'ArcTo',\ + BeginPath,'BeginPath',\ + BitBlt,'BitBlt',\ + CancelDC,'CancelDC',\ + CheckColorsInGamut,'CheckColorsInGamut',\ + ChoosePixelFormat,'ChoosePixelFormat',\ + Chord,'Chord',\ + CloseEnhMetaFile,'CloseEnhMetaFile',\ + CloseFigure,'CloseFigure',\ + CloseMetaFile,'CloseMetaFile',\ + ColorCorrectPalette,'ColorCorrectPalette',\ + ColorMatchToTarget,'ColorMatchToTarget',\ + CombineRgn,'CombineRgn',\ + CombineTransform,'CombineTransform',\ + CopyEnhMetaFileA,'CopyEnhMetaFileA',\ + CopyEnhMetaFileW,'CopyEnhMetaFileW',\ + CopyMetaFileA,'CopyMetaFileA',\ + CopyMetaFileW,'CopyMetaFileW',\ + CreateBitmap,'CreateBitmap',\ + CreateBitmapIndirect,'CreateBitmapIndirect',\ + CreateBrushIndirect,'CreateBrushIndirect',\ + CreateColorSpaceA,'CreateColorSpaceA',\ + CreateColorSpaceW,'CreateColorSpaceW',\ + CreateCompatibleBitmap,'CreateCompatibleBitmap',\ + CreateCompatibleDC,'CreateCompatibleDC',\ + CreateDCA,'CreateDCA',\ + CreateDCW,'CreateDCW',\ + CreateDIBPatternBrush,'CreateDIBPatternBrush',\ + CreateDIBPatternBrushPt,'CreateDIBPatternBrushPt',\ + CreateDIBSection,'CreateDIBSection',\ + CreateDIBitmap,'CreateDIBitmap',\ + CreateDiscardableBitmap,'CreateDiscardableBitmap',\ + CreateEllipticRgn,'CreateEllipticRgn',\ + CreateEllipticRgnIndirect,'CreateEllipticRgnIndirect',\ + CreateEnhMetaFileA,'CreateEnhMetaFileA',\ + CreateEnhMetaFileW,'CreateEnhMetaFileW',\ + CreateFontA,'CreateFontA',\ + CreateFontW,'CreateFontW',\ + CreateFontIndirectA,'CreateFontIndirectA',\ + CreateFontIndirectW,'CreateFontIndirectW',\ + CreateFontIndirectExA,'CreateFontIndirectExA',\ + CreateFontIndirectExW,'CreateFontIndirectExW',\ + CreateHalftonePalette,'CreateHalftonePalette',\ + CreateHatchBrush,'CreateHatchBrush',\ + CreateICA,'CreateICA',\ + CreateICW,'CreateICW',\ + CreateMetaFileA,'CreateMetaFileA',\ + CreateMetaFileW,'CreateMetaFileW',\ + CreatePalette,'CreatePalette',\ + CreatePatternBrush,'CreatePatternBrush',\ + CreatePen,'CreatePen',\ + CreatePenIndirect,'CreatePenIndirect',\ + CreatePolyPolygonRgn,'CreatePolyPolygonRgn',\ + CreatePolygonRgn,'CreatePolygonRgn',\ + CreateRectRgn,'CreateRectRgn',\ + CreateRectRgnIndirect,'CreateRectRgnIndirect',\ + CreateRoundRectRgn,'CreateRoundRectRgn',\ + CreateScalableFontResourceA,'CreateScalableFontResourceA',\ + CreateScalableFontResourceW,'CreateScalableFontResourceW',\ + CreateSolidBrush,'CreateSolidBrush',\ + DPtoLP,'DPtoLP',\ + DeleteColorSpace,'DeleteColorSpace',\ + DeleteDC,'DeleteDC',\ + DeleteEnhMetaFile,'DeleteEnhMetaFile',\ + DeleteMetaFile,'DeleteMetaFile',\ + DeleteObject,'DeleteObject',\ + DescribePixelFormat,'DescribePixelFormat',\ + DeviceCapabilitiesExA,'DeviceCapabilitiesExA',\ + DeviceCapabilitiesExW,'DeviceCapabilitiesExW',\ + DrawEscape,'DrawEscape',\ + Ellipse,'Ellipse',\ + EnableEUDC,'EnableEUDC',\ + EndDoc,'EndDoc',\ + EndPage,'EndPage',\ + EndPath,'EndPath',\ + EnumEnhMetaFile,'EnumEnhMetaFile',\ + EnumFontFamiliesA,'EnumFontFamiliesA',\ + EnumFontFamiliesW,'EnumFontFamiliesW',\ + EnumFontFamiliesExA,'EnumFontFamiliesExA',\ + EnumFontFamiliesExW,'EnumFontFamiliesExW',\ + EnumFontsA,'EnumFontsA',\ + EnumFontsW,'EnumFontsW',\ + EnumICMProfilesA,'EnumICMProfilesA',\ + EnumICMProfilesW,'EnumICMProfilesW',\ + EnumMetaFile,'EnumMetaFile',\ + EnumObjects,'EnumObjects',\ + EqualRgn,'EqualRgn',\ + Escape,'Escape',\ + ExcludeClipRect,'ExcludeClipRect',\ + ExtCreatePen,'ExtCreatePen',\ + ExtCreateRegion,'ExtCreateRegion',\ + ExtEscape,'ExtEscape',\ + ExtFloodFill,'ExtFloodFill',\ + ExtSelectClipRgn,'ExtSelectClipRgn',\ + ExtTextOutA,'ExtTextOutA',\ + ExtTextOutW,'ExtTextOutW',\ + FillPath,'FillPath',\ + FillRgn,'FillRgn',\ + FixBrushOrgEx,'FixBrushOrgEx',\ + FlattenPath,'FlattenPath',\ + FloodFill,'FloodFill',\ + FrameRgn,'FrameRgn',\ + GdiComment,'GdiComment',\ + GdiDeleteSpoolFileHandle,'GdiDeleteSpoolFileHandle',\ + GdiEndDocEMF,'GdiEndDocEMF',\ + GdiEndPageEMF,'GdiEndPageEMF',\ + GdiFlush,'GdiFlush',\ + GdiGetBatchLimit,'GdiGetBatchLimit',\ + GdiGetDC,'GdiGetDC',\ + GdiGetDevmodeForPage,'GdiGetDevmodeForPage',\ + GdiGetPageCount,'GdiGetPageCount',\ + GdiGetPageHandle,'GdiGetPageHandle',\ + GdiGetSpoolFileHandle,'GdiGetSpoolFileHandle',\ + GdiPlayDCScript,'GdiPlayDCScript',\ + GdiPlayEMF,'GdiPlayEMF',\ + GdiPlayJournal,'GdiPlayJournal',\ + GdiPlayPageEMF,'GdiPlayPageEMF',\ + GdiPlayPrivatePageEMF,'GdiPlayPrivatePageEMF',\ + GdiPlayScript,'GdiPlayScript',\ + GdiResetDCEMF,'GdiResetDCEMF',\ + GdiSetBatchLimit,'GdiSetBatchLimit',\ + GdiStartDocEMF,'GdiStartDocEMF',\ + GdiStartPageEMF,'GdiStartPageEMF',\ + GetArcDirection,'GetArcDirection',\ + GetAspectRatioFilterEx,'GetAspectRatioFilterEx',\ + GetBitmapBits,'GetBitmapBits',\ + GetBitmapDimensionEx,'GetBitmapDimensionEx',\ + GetBkColor,'GetBkColor',\ + GetBkMode,'GetBkMode',\ + GetBoundsRect,'GetBoundsRect',\ + GetBrushOrgEx,'GetBrushOrgEx',\ + GetCharABCWidthsA,'GetCharABCWidthsA',\ + GetCharABCWidthsW,'GetCharABCWidthsW',\ + GetCharABCWidthsFloatA,'GetCharABCWidthsFloatA',\ + GetCharABCWidthsFloatW,'GetCharABCWidthsFloatW',\ + GetCharABCWidthsI,'GetCharABCWidthsI',\ + GetCharWidth32A,'GetCharWidth32A',\ + GetCharWidth32W,'GetCharWidth32W',\ + GetCharWidthA,'GetCharWidthA',\ + GetCharWidthW,'GetCharWidthW',\ + GetCharWidthFloatA,'GetCharWidthFloatA',\ + GetCharWidthFloatW,'GetCharWidthFloatW',\ + GetCharWidthI,'GetCharWidthI',\ + GetCharacterPlacementA,'GetCharacterPlacementA',\ + GetCharacterPlacementW,'GetCharacterPlacementW',\ + GetClipBox,'GetClipBox',\ + GetClipRgn,'GetClipRgn',\ + GetColorAdjustment,'GetColorAdjustment',\ + GetColorSpace,'GetColorSpace',\ + GetCurrentObject,'GetCurrentObject',\ + GetCurrentPositionEx,'GetCurrentPositionEx',\ + GetDCBrushColor,'GetDCBrushColor',\ + GetDCOrgEx,'GetDCOrgEx',\ + GetDCPenColor,'GetDCPenColor',\ + GetDIBColorTable,'GetDIBColorTable',\ + GetDIBits,'GetDIBits',\ + GetDeviceCaps,'GetDeviceCaps',\ + GetDeviceGammaRamp,'GetDeviceGammaRamp',\ + GetEnhMetaFileA,'GetEnhMetaFileA',\ + GetEnhMetaFileW,'GetEnhMetaFileW',\ + GetEnhMetaFileBits,'GetEnhMetaFileBits',\ + GetEnhMetaFileDescriptionA,'GetEnhMetaFileDescriptionA',\ + GetEnhMetaFileDescriptionW,'GetEnhMetaFileDescriptionW',\ + GetEnhMetaFileHeader,'GetEnhMetaFileHeader',\ + GetEnhMetaFilePaletteEntries,'GetEnhMetaFilePaletteEntries',\ + GetEnhMetaFilePixelFormat,'GetEnhMetaFilePixelFormat',\ + GetFontAssocStatus,'GetFontAssocStatus',\ + GetFontData,'GetFontData',\ + GetFontLanguageInfo,'GetFontLanguageInfo',\ + GetFontUnicodeRanges,'GetFontUnicodeRanges',\ + GetGlyphIndicesA,'GetGlyphIndicesA',\ + GetGlyphIndicesW,'GetGlyphIndicesW',\ + GetGlyphOutlineA,'GetGlyphOutlineA',\ + GetGlyphOutlineW,'GetGlyphOutlineW',\ + GetGraphicsMode,'GetGraphicsMode',\ + GetICMProfileA,'GetICMProfileA',\ + GetICMProfileW,'GetICMProfileW',\ + GetKerningPairsA,'GetKerningPairsA',\ + GetKerningPairsW,'GetKerningPairsW',\ + GetLogColorSpaceA,'GetLogColorSpaceA',\ + GetLogColorSpaceW,'GetLogColorSpaceW',\ + GetMapMode,'GetMapMode',\ + GetMetaFileA,'GetMetaFileA',\ + GetMetaFileW,'GetMetaFileW',\ + GetMetaFileBitsEx,'GetMetaFileBitsEx',\ + GetMetaRgn,'GetMetaRgn',\ + GetMiterLimit,'GetMiterLimit',\ + GetNearestColor,'GetNearestColor',\ + GetNearestPaletteIndex,'GetNearestPaletteIndex',\ + GetObjectA,'GetObjectA',\ + GetObjectW,'GetObjectW',\ + GetObjectType,'GetObjectType',\ + GetOutlineTextMetricsA,'GetOutlineTextMetricsA',\ + GetOutlineTextMetricsW,'GetOutlineTextMetricsW',\ + GetPaletteEntries,'GetPaletteEntries',\ + GetPath,'GetPath',\ + GetPixel,'GetPixel',\ + GetPixelFormat,'GetPixelFormat',\ + GetPolyFillMode,'GetPolyFillMode',\ + GetROP2,'GetROP2',\ + GetRandomRgn,'GetRandomRgn',\ + GetRasterizerCaps,'GetRasterizerCaps',\ + GetRegionData,'GetRegionData',\ + GetRelAbs,'GetRelAbs',\ + GetRgnBox,'GetRgnBox',\ + GetStockObject,'GetStockObject',\ + GetStretchBltMode,'GetStretchBltMode',\ + GetSystemPaletteEntries,'GetSystemPaletteEntries',\ + GetSystemPaletteUse,'GetSystemPaletteUse',\ + GetTextAlign,'GetTextAlign',\ + GetTextCharacterExtra,'GetTextCharacterExtra',\ + GetTextCharset,'GetTextCharset',\ + GetTextCharsetInfo,'GetTextCharsetInfo',\ + GetTextColor,'GetTextColor',\ + GetTextExtentExPointA,'GetTextExtentExPointA',\ + GetTextExtentExPointW,'GetTextExtentExPointW',\ + GetTextExtentExPointI,'GetTextExtentExPointI',\ + GetTextExtentPoint32A,'GetTextExtentPoint32A',\ + GetTextExtentPoint32W,'GetTextExtentPoint32W',\ + GetTextExtentPointA,'GetTextExtentPointA',\ + GetTextExtentPointW,'GetTextExtentPointW',\ + GetTextExtentPointI,'GetTextExtentPointI',\ + GetTextFaceA,'GetTextFaceA',\ + GetTextFaceW,'GetTextFaceW',\ + GetTextMetricsA,'GetTextMetricsA',\ + GetTextMetricsW,'GetTextMetricsW',\ + GetViewportExtEx,'GetViewportExtEx',\ + GetViewportOrgEx,'GetViewportOrgEx',\ + GetWinMetaFileBits,'GetWinMetaFileBits',\ + GetWindowExtEx,'GetWindowExtEx',\ + GetWindowOrgEx,'GetWindowOrgEx',\ + GetWorldTransform,'GetWorldTransform',\ + IntersectClipRect,'IntersectClipRect',\ + InvertRgn,'InvertRgn',\ + LPtoDP,'LPtoDP',\ + LineDDA,'LineDDA',\ + LineDDW,'LineDDW',\ + LineTo,'LineTo',\ + MaskBlt,'MaskBlt',\ + ModifyWorldTransform,'ModifyWorldTransform',\ + MoveToEx,'MoveToEx',\ + OffsetClipRgn,'OffsetClipRgn',\ + OffsetRgn,'OffsetRgn',\ + OffsetViewportOrgEx,'OffsetViewportOrgEx',\ + OffsetWindowOrgEx,'OffsetWindowOrgEx',\ + PaintRgn,'PaintRgn',\ + PatBlt,'PatBlt',\ + PathToRegion,'PathToRegion',\ + Pie,'Pie',\ + PlayEnhMetaFile,'PlayEnhMetaFile',\ + PlayEnhMetaFileRecord,'PlayEnhMetaFileRecord',\ + PlayMetaFile,'PlayMetaFile',\ + PlayMetaFileRecord,'PlayMetaFileRecord',\ + PlgBlt,'PlgBlt',\ + PolyBezier,'PolyBezier',\ + PolyBezierTo,'PolyBezierTo',\ + PolyDraw,'PolyDraw',\ + PolyPatBlt,'PolyPatBlt',\ + PolyPolygon,'PolyPolygon',\ + PolyPolyline,'PolyPolyline',\ + PolyTextOutA,'PolyTextOutA',\ + PolyTextOutW,'PolyTextOutW',\ + Polygon,'Polygon',\ + Polyline,'Polyline',\ + PolylineTo,'PolylineTo',\ + PtInRegion,'PtInRegion',\ + PtVisible,'PtVisible',\ + RealizePalette,'RealizePalette',\ + RectInRegion,'RectInRegion',\ + RectVisible,'RectVisible',\ + Rectangle,'Rectangle',\ + RemoveFontMemResourceEx,'RemoveFontMemResourceEx',\ + RemoveFontResourceA,'RemoveFontResourceA',\ + RemoveFontResourceW,'RemoveFontResourceW',\ + RemoveFontResourceExA,'RemoveFontResourceExA',\ + RemoveFontResourceExW,'RemoveFontResourceExW',\ + ResetDCA,'ResetDCA',\ + ResetDCW,'ResetDCW',\ + ResizePalette,'ResizePalette',\ + RestoreDC,'RestoreDC',\ + RoundRect,'RoundRect',\ + SaveDC,'SaveDC',\ + ScaleViewportExtEx,'ScaleViewportExtEx',\ + ScaleWindowExtEx,'ScaleWindowExtEx',\ + SelectBrushLocal,'SelectBrushLocal',\ + SelectClipPath,'SelectClipPath',\ + SelectClipRgn,'SelectClipRgn',\ + SelectFontLocal,'SelectFontLocal',\ + SelectObject,'SelectObject',\ + SelectPalette,'SelectPalette',\ + SetAbortProc,'SetAbortProc',\ + SetArcDirection,'SetArcDirection',\ + SetBitmapBits,'SetBitmapBits',\ + SetBitmapDimensionEx,'SetBitmapDimensionEx',\ + SetBkColor,'SetBkColor',\ + SetBkMode,'SetBkMode',\ + SetBoundsRect,'SetBoundsRect',\ + SetBrushOrgEx,'SetBrushOrgEx',\ + SetColorAdjustment,'SetColorAdjustment',\ + SetColorSpace,'SetColorSpace',\ + SetDCBrushColor,'SetDCBrushColor',\ + SetDCPenColor,'SetDCPenColor',\ + SetDIBColorTable,'SetDIBColorTable',\ + SetDIBits,'SetDIBits',\ + SetDIBitsToDevice,'SetDIBitsToDevice',\ + SetDeviceGammaRamp,'SetDeviceGammaRamp',\ + SetEnhMetaFileBits,'SetEnhMetaFileBits',\ + SetFontEnumeration,'SetFontEnumeration',\ + SetGraphicsMode,'SetGraphicsMode',\ + SetICMMode,'SetICMMode',\ + SetICMProfileA,'SetICMProfileA',\ + SetICMProfileW,'SetICMProfileW',\ + SetMagicColors,'SetMagicColors',\ + SetMapMode,'SetMapMode',\ + SetMapperFlags,'SetMapperFlags',\ + SetMetaFileBitsEx,'SetMetaFileBitsEx',\ + SetMetaRgn,'SetMetaRgn',\ + SetMiterLimit,'SetMiterLimit',\ + SetPaletteEntries,'SetPaletteEntries',\ + SetPixel,'SetPixel',\ + SetPixelFormat,'SetPixelFormat',\ + SetPixelV,'SetPixelV',\ + SetPolyFillMode,'SetPolyFillMode',\ + SetROP2,'SetROP2',\ + SetRectRgn,'SetRectRgn',\ + SetRelAbs,'SetRelAbs',\ + SetStretchBltMode,'SetStretchBltMode',\ + SetSystemPaletteUse,'SetSystemPaletteUse',\ + SetTextAlign,'SetTextAlign',\ + SetTextCharacterExtra,'SetTextCharacterExtra',\ + SetTextColor,'SetTextColor',\ + SetTextJustification,'SetTextJustification',\ + SetViewportExtEx,'SetViewportExtEx',\ + SetViewportOrgEx,'SetViewportOrgEx',\ + SetWinMetaFileBits,'SetWinMetaFileBits',\ + SetWindowExtEx,'SetWindowExtEx',\ + SetWindowOrgEx,'SetWindowOrgEx',\ + SetWorldTransform,'SetWorldTransform',\ + StartDocA,'StartDocA',\ + StartDocW,'StartDocW',\ + StartPage,'StartPage',\ + StretchBlt,'StretchBlt',\ + StretchDIBits,'StretchDIBits',\ + StrokeAndFillPath,'StrokeAndFillPath',\ + StrokePath,'StrokePath',\ + SwapBuffers,'SwapBuffers',\ + TextOutA,'TextOutA',\ + TextOutW,'TextOutW',\ + TranslateCharsetInfo,'TranslateCharsetInfo',\ + UnrealizeObject,'UnrealizeObject',\ + UpdateColors,'UpdateColors',\ + UpdateICMRegKeyA,'UpdateICMRegKeyA',\ + UpdateICMRegKeyW,'UpdateICMRegKeyW',\ + WidenPath,'WidenPath',\ + gdiPlaySpoolStream,'gdiPlaySpoolStream' + +api AddFontResource,\ + AddFontResourceEx,\ + CopyEnhMetaFile,\ + CopyMetaFile,\ + CreateColorSpace,\ + CreateDC,\ + CreateEnhMetaFile,\ + CreateFont,\ + CreateFontIndirect,\ + CreateFontIndirectEx,\ + CreateIC,\ + CreateMetaFile,\ + CreateScalableFontResource,\ + DeviceCapabilitiesEx,\ + EnumFontFamilies,\ + EnumFontFamiliesEx,\ + EnumFonts,\ + EnumICMProfiles,\ + ExtTextOut,\ + GetCharABCWidths,\ + GetCharABCWidthsFloat,\ + GetCharWidth32,\ + GetCharWidth,\ + GetCharWidthFloat,\ + GetCharacterPlacement,\ + GetEnhMetaFile,\ + GetEnhMetaFileDescription,\ + GetGlyphIndices,\ + GetGlyphOutline,\ + GetICMProfile,\ + GetKerningPairs,\ + GetLogColorSpace,\ + GetMetaFile,\ + GetObject,\ + GetOutlineTextMetrics,\ + GetTextExtentExPoint,\ + GetTextExtentPoint32,\ + GetTextExtentPoint,\ + GetTextFace,\ + GetTextMetrics,\ + LineDD,\ + PolyTextOut,\ + RemoveFontResource,\ + RemoveFontResourceEx,\ + ResetDC,\ + SetICMProfile,\ + StartDoc,\ + TextOut,\ + UpdateICMRegKey diff --git a/toolchain/fasmw17332/INCLUDE/API/KERNEL32.INC b/toolchain/fasmw17332/INCLUDE/API/KERNEL32.INC new file mode 100644 index 0000000..31c4672 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/API/KERNEL32.INC @@ -0,0 +1,881 @@ + +; KERNEL32 API calls + +import kernel32,\ + AddAtomA,'AddAtomA',\ + AddAtomW,'AddAtomW',\ + AddConsoleAliasA,'AddConsoleAliasA',\ + AddConsoleAliasW,'AddConsoleAliasW',\ + AllocConsole,'AllocConsole',\ + AreFileApisANSI,'AreFileApisANSI',\ + AssignProcessToJobObject,'AssignProcessToJobObject',\ + BackupRead,'BackupRead',\ + BackupSeek,'BackupSeek',\ + BackupWrite,'BackupWrite',\ + BaseAttachCompleteThunk,'BaseAttachCompleteThunk',\ + Beep,'Beep',\ + BeginUpdateResourceA,'BeginUpdateResourceA',\ + BeginUpdateResourceW,'BeginUpdateResourceW',\ + BuildCommDCBA,'BuildCommDCBA',\ + BuildCommDCBW,'BuildCommDCBW',\ + BuildCommDCBAndTimeoutsA,'BuildCommDCBAndTimeoutsA',\ + BuildCommDCBAndTimeoutsW,'BuildCommDCBAndTimeoutsW',\ + CallNamedPipeA,'CallNamedPipeA',\ + CallNamedPipeW,'CallNamedPipeW',\ + CancelIo,'CancelIo',\ + CancelWaitableTimer,'CancelWaitableTimer',\ + ClearCommBreak,'ClearCommBreak',\ + ClearCommError,'ClearCommError',\ + CloseConsoleHandle,'CloseConsoleHandle',\ + CloseHandle,'CloseHandle',\ + CloseProfileUserMapping,'CloseProfileUserMapping',\ + CmdBatNotification,'CmdBatNotification',\ + CommConfigDialogA,'CommConfigDialogA',\ + CommConfigDialogW,'CommConfigDialogW',\ + CompareFileTime,'CompareFileTime',\ + CompareStringA,'CompareStringA',\ + CompareStringW,'CompareStringW',\ + ConnectNamedPipe,'ConnectNamedPipe',\ + ConsoleMenuControl,'ConsoleMenuControl',\ + ContinueDebugEvent,'ContinueDebugEvent',\ + ConvertDefaultLocale,'ConvertDefaultLocale',\ + ConvertThreadToFiber,'ConvertThreadToFiber',\ + CopyFileA,'CopyFileA',\ + CopyFileW,'CopyFileW',\ + CopyFileExA,'CopyFileExA',\ + CopyFileExW,'CopyFileExW',\ + CreateConsoleScreenBuffer,'CreateConsoleScreenBuffer',\ + CreateDirectoryA,'CreateDirectoryA',\ + CreateDirectoryW,'CreateDirectoryW',\ + CreateDirectoryExA,'CreateDirectoryExA',\ + CreateDirectoryExW,'CreateDirectoryExW',\ + CreateEventA,'CreateEventA',\ + CreateEventW,'CreateEventW',\ + CreateFiber,'CreateFiber',\ + CreateFileA,'CreateFileA',\ + CreateFileW,'CreateFileW',\ + CreateFileMappingA,'CreateFileMappingA',\ + CreateFileMappingW,'CreateFileMappingW',\ + CreateHardLinkA,'CreateHardLinkA',\ + CreateHardLinkW,'CreateHardLinkW',\ + CreateIoCompletionPort,'CreateIoCompletionPort',\ + CreateJobObjectA,'CreateJobObjectA',\ + CreateJobObjectW,'CreateJobObjectW',\ + CreateMailslotA,'CreateMailslotA',\ + CreateMailslotW,'CreateMailslotW',\ + CreateMutexA,'CreateMutexA',\ + CreateMutexW,'CreateMutexW',\ + CreateNamedPipeA,'CreateNamedPipeA',\ + CreateNamedPipeW,'CreateNamedPipeW',\ + CreatePipe,'CreatePipe',\ + CreateProcessA,'CreateProcessA',\ + CreateProcessW,'CreateProcessW',\ + CreateRemoteThread,'CreateRemoteThread',\ + CreateSemaphoreA,'CreateSemaphoreA',\ + CreateSemaphoreW,'CreateSemaphoreW',\ + CreateTapePartition,'CreateTapePartition',\ + CreateThread,'CreateThread',\ + CreateToolhelp32Snapshot,'CreateToolhelp32Snapshot',\ + CreateVirtualBuffer,'CreateVirtualBuffer',\ + CreateWaitableTimerA,'CreateWaitableTimerA',\ + CreateWaitableTimerW,'CreateWaitableTimerW',\ + DebugActiveProcess,'DebugActiveProcess',\ + DebugBreak,'DebugBreak',\ + DefineDosDeviceA,'DefineDosDeviceA',\ + DefineDosDeviceW,'DefineDosDeviceW',\ + DeleteAtom,'DeleteAtom',\ + DeleteCriticalSection,'DeleteCriticalSection',\ + DeleteFiber,'DeleteFiber',\ + DeleteFileA,'DeleteFileA',\ + DeleteFileW,'DeleteFileW',\ + DeviceIoControl,'DeviceIoControl',\ + DisableThreadLibraryCalls,'DisableThreadLibraryCalls',\ + DisconnectNamedPipe,'DisconnectNamedPipe',\ + DosDateTimeToFileTime,'DosDateTimeToFileTime',\ + DuplicateConsoleHandle,'DuplicateConsoleHandle',\ + DuplicateHandle,'DuplicateHandle',\ + EndUpdateResourceA,'EndUpdateResourceA',\ + EndUpdateResourceW,'EndUpdateResourceW',\ + EnterCriticalSection,'EnterCriticalSection',\ + EnumCalendarInfoA,'EnumCalendarInfoA',\ + EnumCalendarInfoW,'EnumCalendarInfoW',\ + EnumCalendarInfoExA,'EnumCalendarInfoExA',\ + EnumCalendarInfoExW,'EnumCalendarInfoExW',\ + EnumDateFormatsA,'EnumDateFormatsA',\ + EnumDateFormatsW,'EnumDateFormatsW',\ + EnumDateFormatsExA,'EnumDateFormatsExA',\ + EnumDateFormatsExW,'EnumDateFormatsExW',\ + EnumResourceLanguagesA,'EnumResourceLanguagesA',\ + EnumResourceLanguagesW,'EnumResourceLanguagesW',\ + EnumResourceNamesA,'EnumResourceNamesA',\ + EnumResourceNamesW,'EnumResourceNamesW',\ + EnumResourceTypesA,'EnumResourceTypesA',\ + EnumResourceTypesW,'EnumResourceTypesW',\ + EnumSystemCodePagesA,'EnumSystemCodePagesA',\ + EnumSystemCodePagesW,'EnumSystemCodePagesW',\ + EnumSystemLocalesA,'EnumSystemLocalesA',\ + EnumSystemLocalesW,'EnumSystemLocalesW',\ + EnumTimeFormatsA,'EnumTimeFormatsA',\ + EnumTimeFormatsW,'EnumTimeFormatsW',\ + EraseTape,'EraseTape',\ + EscapeCommFunction,'EscapeCommFunction',\ + ExitProcess,'ExitProcess',\ + ExitThread,'ExitThread',\ + ExitVDM,'ExitVDM',\ + ExpandEnvironmentStringsA,'ExpandEnvironmentStringsA',\ + ExpandEnvironmentStringsW,'ExpandEnvironmentStringsW',\ + ExpungeConsoleCommandHistoryA,'ExpungeConsoleCommandHistoryA',\ + ExpungeConsoleCommandHistoryW,'ExpungeConsoleCommandHistoryW',\ + ExtendVirtualBuffer,'ExtendVirtualBuffer',\ + FatalAppExitA,'FatalAppExitA',\ + FatalAppExitW,'FatalAppExitW',\ + FatalExit,'FatalExit',\ + FileTimeToDosDateTime,'FileTimeToDosDateTime',\ + FileTimeToLocalFileTime,'FileTimeToLocalFileTime',\ + FileTimeToSystemTime,'FileTimeToSystemTime',\ + FillConsoleOutputAttribute,'FillConsoleOutputAttribute',\ + FillConsoleOutputCharacterA,'FillConsoleOutputCharacterA',\ + FillConsoleOutputCharacterW,'FillConsoleOutputCharacterW',\ + FindAtomA,'FindAtomA',\ + FindAtomW,'FindAtomW',\ + FindClose,'FindClose',\ + FindCloseChangeNotification,'FindCloseChangeNotification',\ + FindFirstChangeNotificationA,'FindFirstChangeNotificationA',\ + FindFirstChangeNotificationW,'FindFirstChangeNotificationW',\ + FindFirstFileA,'FindFirstFileA',\ + FindFirstFileW,'FindFirstFileW',\ + FindFirstFileExA,'FindFirstFileExA',\ + FindFirstFileExW,'FindFirstFileExW',\ + FindNextChangeNotification,'FindNextChangeNotification',\ + FindNextFileA,'FindNextFileA',\ + FindNextFileW,'FindNextFileW',\ + FindResourceA,'FindResourceA',\ + FindResourceW,'FindResourceW',\ + FindResourceExA,'FindResourceExA',\ + FindResourceExW,'FindResourceExW',\ + FlushConsoleInputBuffer,'FlushConsoleInputBuffer',\ + FlushFileBuffers,'FlushFileBuffers',\ + FlushInstructionCache,'FlushInstructionCache',\ + FlushViewOfFile,'FlushViewOfFile',\ + FoldStringA,'FoldStringA',\ + FoldStringW,'FoldStringW',\ + FormatMessageA,'FormatMessageA',\ + FormatMessageW,'FormatMessageW',\ + FreeConsole,'FreeConsole',\ + FreeEnvironmentStringsA,'FreeEnvironmentStringsA',\ + FreeEnvironmentStringsW,'FreeEnvironmentStringsW',\ + FreeLibrary,'FreeLibrary',\ + FreeLibraryAndExitThread,'FreeLibraryAndExitThread',\ + FreeResource,'FreeResource',\ + FreeVirtualBuffer,'FreeVirtualBuffer',\ + GenerateConsoleCtrlEvent,'GenerateConsoleCtrlEvent',\ + GetACP,'GetACP',\ + GetAtomNameA,'GetAtomNameA',\ + GetAtomNameW,'GetAtomNameW',\ + GetBinaryTypeA,'GetBinaryTypeA',\ + GetBinaryTypeW,'GetBinaryTypeW',\ + GetCPInfo,'GetCPInfo',\ + GetCPInfoExA,'GetCPInfoExA',\ + GetCPInfoExW,'GetCPInfoExW',\ + GetCommConfig,'GetCommConfig',\ + GetCommMask,'GetCommMask',\ + GetCommModemStatus,'GetCommModemStatus',\ + GetCommProperties,'GetCommProperties',\ + GetCommState,'GetCommState',\ + GetCommTimeouts,'GetCommTimeouts',\ + GetCommandLineA,'GetCommandLineA',\ + GetCommandLineW,'GetCommandLineW',\ + GetCompressedFileSizeA,'GetCompressedFileSizeA',\ + GetCompressedFileSizeW,'GetCompressedFileSizeW',\ + GetComputerNameA,'GetComputerNameA',\ + GetComputerNameW,'GetComputerNameW',\ + GetConsoleAliasA,'GetConsoleAliasA',\ + GetConsoleAliasW,'GetConsoleAliasW',\ + GetConsoleAliasExesA,'GetConsoleAliasExesA',\ + GetConsoleAliasExesW,'GetConsoleAliasExesW',\ + GetConsoleAliasExesLengthA,'GetConsoleAliasExesLengthA',\ + GetConsoleAliasExesLengthW,'GetConsoleAliasExesLengthW',\ + GetConsoleAliasesA,'GetConsoleAliasesA',\ + GetConsoleAliasesW,'GetConsoleAliasesW',\ + GetConsoleAliasesLengthA,'GetConsoleAliasesLengthA',\ + GetConsoleAliasesLengthW,'GetConsoleAliasesLengthW',\ + GetConsoleCP,'GetConsoleCP',\ + GetConsoleCommandHistoryA,'GetConsoleCommandHistoryA',\ + GetConsoleCommandHistoryW,'GetConsoleCommandHistoryW',\ + GetConsoleCommandHistoryLengthA,'GetConsoleCommandHistoryLengthA',\ + GetConsoleCommandHistoryLengthW,'GetConsoleCommandHistoryLengthW',\ + GetConsoleCursorInfo,'GetConsoleCursorInfo',\ + GetConsoleDisplayMode,'GetConsoleDisplayMode',\ + GetConsoleFontInfo,'GetConsoleFontInfo',\ + GetConsoleFontSize,'GetConsoleFontSize',\ + GetConsoleHardwareState,'GetConsoleHardwareState',\ + GetConsoleInputExeNameA,'GetConsoleInputExeNameA',\ + GetConsoleInputExeNameW,'GetConsoleInputExeNameW',\ + GetConsoleInputWaitHandle,'GetConsoleInputWaitHandle',\ + GetConsoleKeyboardLayoutNameA,'GetConsoleKeyboardLayoutNameA',\ + GetConsoleKeyboardLayoutNameW,'GetConsoleKeyboardLayoutNameW',\ + GetConsoleMode,'GetConsoleMode',\ + GetConsoleOutputCP,'GetConsoleOutputCP',\ + GetConsoleScreenBufferInfo,'GetConsoleScreenBufferInfo',\ + GetConsoleTitleA,'GetConsoleTitleA',\ + GetConsoleTitleW,'GetConsoleTitleW',\ + GetConsoleWindow,'GetConsoleWindow',\ + GetCurrencyFormatA,'GetCurrencyFormatA',\ + GetCurrencyFormatW,'GetCurrencyFormatW',\ + GetCurrentConsoleFont,'GetCurrentConsoleFont',\ + GetCurrentDirectoryA,'GetCurrentDirectoryA',\ + GetCurrentDirectoryW,'GetCurrentDirectoryW',\ + GetCurrentProcess,'GetCurrentProcess',\ + GetCurrentProcessId,'GetCurrentProcessId',\ + GetCurrentThread,'GetCurrentThread',\ + GetCurrentThreadId,'GetCurrentThreadId',\ + GetDateFormatA,'GetDateFormatA',\ + GetDateFormatW,'GetDateFormatW',\ + GetDefaultCommConfigA,'GetDefaultCommConfigA',\ + GetDefaultCommConfigW,'GetDefaultCommConfigW',\ + GetDevicePowerState,'GetDevicePowerState',\ + GetDiskFreeSpaceA,'GetDiskFreeSpaceA',\ + GetDiskFreeSpaceW,'GetDiskFreeSpaceW',\ + GetDiskFreeSpaceExA,'GetDiskFreeSpaceExA',\ + GetDiskFreeSpaceExW,'GetDiskFreeSpaceExW',\ + GetDriveTypeA,'GetDriveTypeA',\ + GetDriveTypeW,'GetDriveTypeW',\ + GetEnvironmentStringsA,'GetEnvironmentStringsA',\ + GetEnvironmentStringsW,'GetEnvironmentStringsW',\ + GetEnvironmentVariableA,'GetEnvironmentVariableA',\ + GetEnvironmentVariableW,'GetEnvironmentVariableW',\ + GetExitCodeProcess,'GetExitCodeProcess',\ + GetExitCodeThread,'GetExitCodeThread',\ + GetFileAttributesA,'GetFileAttributesA',\ + GetFileAttributesW,'GetFileAttributesW',\ + GetFileAttributesExA,'GetFileAttributesExA',\ + GetFileAttributesExW,'GetFileAttributesExW',\ + GetFileInformationByHandle,'GetFileInformationByHandle',\ + GetFileSize,'GetFileSize',\ + GetFileSizeEx,'GetFileSizeEx',\ + GetFileTime,'GetFileTime',\ + GetFileType,'GetFileType',\ + GetFullPathNameA,'GetFullPathNameA',\ + GetFullPathNameW,'GetFullPathNameW',\ + GetHandleInformation,'GetHandleInformation',\ + GetLargestConsoleWindowSize,'GetLargestConsoleWindowSize',\ + GetLastError,'GetLastError',\ + GetLocalTime,'GetLocalTime',\ + GetLocaleInfoA,'GetLocaleInfoA',\ + GetLocaleInfoW,'GetLocaleInfoW',\ + GetLogicalDriveStringsA,'GetLogicalDriveStringsA',\ + GetLogicalDriveStringsW,'GetLogicalDriveStringsW',\ + GetLogicalDrives,'GetLogicalDrives',\ + GetLongPathNameA,'GetLongPathNameA',\ + GetLongPathNameW,'GetLongPathNameW',\ + GetMailslotInfo,'GetMailslotInfo',\ + GetModuleFileNameA,'GetModuleFileNameA',\ + GetModuleFileNameW,'GetModuleFileNameW',\ + GetModuleHandleA,'GetModuleHandleA',\ + GetModuleHandleW,'GetModuleHandleW',\ + GetNamedPipeHandleStateA,'GetNamedPipeHandleStateA',\ + GetNamedPipeHandleStateW,'GetNamedPipeHandleStateW',\ + GetNamedPipeInfo,'GetNamedPipeInfo',\ + GetNextVDMCommand,'GetNextVDMCommand',\ + GetNumberFormatA,'GetNumberFormatA',\ + GetNumberFormatW,'GetNumberFormatW',\ + GetNumberOfConsoleFonts,'GetNumberOfConsoleFonts',\ + GetNumberOfConsoleInputEvents,'GetNumberOfConsoleInputEvents',\ + GetNumberOfConsoleMouseButtons,'GetNumberOfConsoleMouseButtons',\ + GetOEMCP,'GetOEMCP',\ + GetOverlappedResult,'GetOverlappedResult',\ + GetPriorityClass,'GetPriorityClass',\ + GetPrivateProfileIntA,'GetPrivateProfileIntA',\ + GetPrivateProfileIntW,'GetPrivateProfileIntW',\ + GetPrivateProfileSectionA,'GetPrivateProfileSectionA',\ + GetPrivateProfileSectionW,'GetPrivateProfileSectionW',\ + GetPrivateProfileSectionNamesA,'GetPrivateProfileSectionNamesA',\ + GetPrivateProfileSectionNamesW,'GetPrivateProfileSectionNamesW',\ + GetPrivateProfileStringA,'GetPrivateProfileStringA',\ + GetPrivateProfileStringW,'GetPrivateProfileStringW',\ + GetPrivateProfileStructA,'GetPrivateProfileStructA',\ + GetPrivateProfileStructW,'GetPrivateProfileStructW',\ + GetProcAddress,'GetProcAddress',\ + GetProcessAffinityMask,'GetProcessAffinityMask',\ + GetProcessHeap,'GetProcessHeap',\ + GetProcessHeaps,'GetProcessHeaps',\ + GetProcessPriorityBoost,'GetProcessPriorityBoost',\ + GetProcessShutdownParameters,'GetProcessShutdownParameters',\ + GetProcessTimes,'GetProcessTimes',\ + GetProcessVersion,'GetProcessVersion',\ + GetProcessWorkingSetSize,'GetProcessWorkingSetSize',\ + GetProfileIntA,'GetProfileIntA',\ + GetProfileIntW,'GetProfileIntW',\ + GetProfileSectionA,'GetProfileSectionA',\ + GetProfileSectionW,'GetProfileSectionW',\ + GetProfileStringA,'GetProfileStringA',\ + GetProfileStringW,'GetProfileStringW',\ + GetQueuedCompletionStatus,'GetQueuedCompletionStatus',\ + GetShortPathNameA,'GetShortPathNameA',\ + GetShortPathNameW,'GetShortPathNameW',\ + GetStartupInfoA,'GetStartupInfoA',\ + GetStartupInfoW,'GetStartupInfoW',\ + GetStdHandle,'GetStdHandle',\ + GetStringTypeA,'GetStringTypeA',\ + GetStringTypeW,'GetStringTypeW',\ + GetStringTypeExA,'GetStringTypeExA',\ + GetStringTypeExW,'GetStringTypeExW',\ + GetSystemDefaultLCID,'GetSystemDefaultLCID',\ + GetSystemDefaultLangID,'GetSystemDefaultLangID',\ + GetSystemDirectoryA,'GetSystemDirectoryA',\ + GetSystemDirectoryW,'GetSystemDirectoryW',\ + GetSystemInfo,'GetSystemInfo',\ + GetSystemPowerStatus,'GetSystemPowerStatus',\ + GetSystemTime,'GetSystemTime',\ + GetSystemTimeAdjustment,'GetSystemTimeAdjustment',\ + GetSystemTimeAsFileTime,'GetSystemTimeAsFileTime',\ + GetTapeParameters,'GetTapeParameters',\ + GetTapePosition,'GetTapePosition',\ + GetTapeStatus,'GetTapeStatus',\ + GetTempFileNameA,'GetTempFileNameA',\ + GetTempFileNameW,'GetTempFileNameW',\ + GetTempPathA,'GetTempPathA',\ + GetTempPathW,'GetTempPathW',\ + GetThreadContext,'GetThreadContext',\ + GetThreadLocale,'GetThreadLocale',\ + GetThreadPriority,'GetThreadPriority',\ + GetThreadPriorityBoost,'GetThreadPriorityBoost',\ + GetThreadSelectorEntry,'GetThreadSelectorEntry',\ + GetThreadTimes,'GetThreadTimes',\ + GetTickCount,'GetTickCount',\ + GetTimeFormatA,'GetTimeFormatA',\ + GetTimeFormatW,'GetTimeFormatW',\ + GetTimeZoneInformation,'GetTimeZoneInformation',\ + GetUserDefaultLCID,'GetUserDefaultLCID',\ + GetUserDefaultLangID,'GetUserDefaultLangID',\ + GetVDMCurrentDirectories,'GetVDMCurrentDirectories',\ + GetVersion,'GetVersion',\ + GetVersionExA,'GetVersionExA',\ + GetVersionExW,'GetVersionExW',\ + GetVolumeInformationA,'GetVolumeInformationA',\ + GetVolumeInformationW,'GetVolumeInformationW',\ + GetWindowsDirectoryA,'GetWindowsDirectoryA',\ + GetWindowsDirectoryW,'GetWindowsDirectoryW',\ + GlobalAddAtomA,'GlobalAddAtomA',\ + GlobalAddAtomW,'GlobalAddAtomW',\ + GlobalAlloc,'GlobalAlloc',\ + GlobalCompact,'GlobalCompact',\ + GlobalDeleteAtom,'GlobalDeleteAtom',\ + GlobalFindAtomA,'GlobalFindAtomA',\ + GlobalFindAtomW,'GlobalFindAtomW',\ + GlobalFix,'GlobalFix',\ + GlobalFlags,'GlobalFlags',\ + GlobalFree,'GlobalFree',\ + GlobalGetAtomNameA,'GlobalGetAtomNameA',\ + GlobalGetAtomNameW,'GlobalGetAtomNameW',\ + GlobalHandle,'GlobalHandle',\ + GlobalLock,'GlobalLock',\ + GlobalMemoryStatus,'GlobalMemoryStatus',\ + GlobalMemoryStatusVlm,'GlobalMemoryStatusVlm',\ + GlobalReAlloc,'GlobalReAlloc',\ + GlobalSize,'GlobalSize',\ + GlobalUnWire,'GlobalUnWire',\ + GlobalUnfix,'GlobalUnfix',\ + GlobalUnlock,'GlobalUnlock',\ + GlobalWire,'GlobalWire',\ + Heap32First,'Heap32First',\ + Heap32ListFirst,'Heap32ListFirst',\ + Heap32ListNext,'Heap32ListNext',\ + Heap32Next,'Heap32Next',\ + HeapAlloc,'HeapAlloc',\ + HeapCompact,'HeapCompact',\ + HeapCreate,'HeapCreate',\ + HeapDestroy,'HeapDestroy',\ + HeapExtend,'HeapExtend',\ + HeapFree,'HeapFree',\ + HeapLock,'HeapLock',\ + HeapReAlloc,'HeapReAlloc',\ + HeapSize,'HeapSize',\ + HeapSummary,'HeapSummary',\ + HeapUnlock,'HeapUnlock',\ + HeapUsage,'HeapUsage',\ + HeapValidate,'HeapValidate',\ + HeapWalk,'HeapWalk',\ + InitAtomTable,'InitAtomTable',\ + InitializeCriticalSection,'InitializeCriticalSection',\ + InitializeCriticalSectionAndSpinCount,'InitializeCriticalSectionAndSpinCount',\ + InterlockedCompareExchange,'InterlockedCompareExchange',\ + InterlockedDecrement,'InterlockedDecrement',\ + InterlockedExchange,'InterlockedExchange',\ + InterlockedExchangeAdd,'InterlockedExchangeAdd',\ + InterlockedIncrement,'InterlockedIncrement',\ + InvalidateConsoleDIBits,'InvalidateConsoleDIBits',\ + IsBadCodePtr,'IsBadCodePtr',\ + IsBadHugeReadPtr,'IsBadHugeReadPtr',\ + IsBadHugeWritePtr,'IsBadHugeWritePtr',\ + IsBadReadPtr,'IsBadReadPtr',\ + IsBadStringPtrA,'IsBadStringPtrA',\ + IsBadStringPtrW,'IsBadStringPtrW',\ + IsBadWritePtr,'IsBadWritePtr',\ + IsDBCSLeadByte,'IsDBCSLeadByte',\ + IsDBCSLeadByteEx,'IsDBCSLeadByteEx',\ + IsDebuggerPresent,'IsDebuggerPresent',\ + IsProcessorFeaturePresent,'IsProcessorFeaturePresent',\ + IsValidCodePage,'IsValidCodePage',\ + IsValidLocale,'IsValidLocale',\ + LCMapStringA,'LCMapStringA',\ + LCMapStringW,'LCMapStringW',\ + LeaveCriticalSection,'LeaveCriticalSection',\ + LoadLibraryA,'LoadLibraryA',\ + LoadLibraryW,'LoadLibraryW',\ + LoadLibraryExA,'LoadLibraryExA',\ + LoadLibraryExW,'LoadLibraryExW',\ + LoadModule,'LoadModule',\ + LoadResource,'LoadResource',\ + LocalAlloc,'LocalAlloc',\ + LocalCompact,'LocalCompact',\ + LocalFileTimeToFileTime,'LocalFileTimeToFileTime',\ + LocalFlags,'LocalFlags',\ + LocalFree,'LocalFree',\ + LocalHandle,'LocalHandle',\ + LocalLock,'LocalLock',\ + LocalReAlloc,'LocalReAlloc',\ + LocalShrink,'LocalShrink',\ + LocalSize,'LocalSize',\ + LocalUnlock,'LocalUnlock',\ + LockFile,'LockFile',\ + LockFileEx,'LockFileEx',\ + LockResource,'LockResource',\ + MapViewOfFile,'MapViewOfFile',\ + MapViewOfFileEx,'MapViewOfFileEx',\ + MapViewOfFileVlm,'MapViewOfFileVlm',\ + Module32First,'Module32First',\ + Module32Next,'Module32Next',\ + MoveFileA,'MoveFileA',\ + MoveFileW,'MoveFileW',\ + MoveFileExA,'MoveFileExA',\ + MoveFileExW,'MoveFileExW',\ + MoveFileWithProgressA,'MoveFileWithProgressA',\ + MoveFileWithProgressW,'MoveFileWithProgressW',\ + MulDiv,'MulDiv',\ + MultiByteToWideChar,'MultiByteToWideChar',\ + OpenEventA,'OpenEventA',\ + OpenEventW,'OpenEventW',\ + OpenFile,'OpenFile',\ + OpenFileMappingA,'OpenFileMappingA',\ + OpenFileMappingW,'OpenFileMappingW',\ + OpenJobObjectA,'OpenJobObjectA',\ + OpenJobObjectW,'OpenJobObjectW',\ + OpenMutexA,'OpenMutexA',\ + OpenMutexW,'OpenMutexW',\ + OpenProcess,'OpenProcess',\ + OpenProfileUserMapping,'OpenProfileUserMapping',\ + OpenSemaphoreA,'OpenSemaphoreA',\ + OpenSemaphoreW,'OpenSemaphoreW',\ + OpenWaitableTimerA,'OpenWaitableTimerA',\ + OpenWaitableTimerW,'OpenWaitableTimerW',\ + OutputDebugStringA,'OutputDebugStringA',\ + OutputDebugStringW,'OutputDebugStringW',\ + PeekConsoleInputA,'PeekConsoleInputA',\ + PeekConsoleInputW,'PeekConsoleInputW',\ + PeekNamedPipe,'PeekNamedPipe',\ + PostQueuedCompletionStatus,'PostQueuedCompletionStatus',\ + PrepareTape,'PrepareTape',\ + Process32First,'Process32First',\ + Process32Next,'Process32Next',\ + PulseEvent,'PulseEvent',\ + PurgeComm,'PurgeComm',\ + QueryDosDeviceA,'QueryDosDeviceA',\ + QueryDosDeviceW,'QueryDosDeviceW',\ + QueryInformationJobObject,'QueryInformationJobObject',\ + QueryPerformanceCounter,'QueryPerformanceCounter',\ + QueryPerformanceFrequency,'QueryPerformanceFrequency',\ + QueryWin31IniFilesMappedToRegistry,'QueryWin31IniFilesMappedToRegistry',\ + QueueUserAPC,'QueueUserAPC',\ + RaiseException,'RaiseException',\ + ReadConsoleA,'ReadConsoleA',\ + ReadConsoleW,'ReadConsoleW',\ + ReadConsoleInputA,'ReadConsoleInputA',\ + ReadConsoleInputW,'ReadConsoleInputW',\ + ReadConsoleInputExA,'ReadConsoleInputExA',\ + ReadConsoleInputExW,'ReadConsoleInputExW',\ + ReadConsoleOutputA,'ReadConsoleOutputA',\ + ReadConsoleOutputW,'ReadConsoleOutputW',\ + ReadConsoleOutputAttribute,'ReadConsoleOutputAttribute',\ + ReadConsoleOutputCharacterA,'ReadConsoleOutputCharacterA',\ + ReadConsoleOutputCharacterW,'ReadConsoleOutputCharacterW',\ + ReadFile,'ReadFile',\ + ReadFileEx,'ReadFileEx',\ + ReadFileScatter,'ReadFileScatter',\ + ReadFileVlm,'ReadFileVlm',\ + ReadProcessMemory,'ReadProcessMemory',\ + ReadProcessMemoryVlm,'ReadProcessMemoryVlm',\ + RegisterConsoleVDM,'RegisterConsoleVDM',\ + RegisterWaitForInputIdle,'RegisterWaitForInputIdle',\ + RegisterWowBaseHandlers,'RegisterWowBaseHandlers',\ + RegisterWowExec,'RegisterWowExec',\ + ReleaseMutex,'ReleaseMutex',\ + ReleaseSemaphore,'ReleaseSemaphore',\ + RemoveDirectoryA,'RemoveDirectoryA',\ + RemoveDirectoryW,'RemoveDirectoryW',\ + RequestWakeupLatency,'RequestWakeupLatency',\ + ResetEvent,'ResetEvent',\ + ResumeThread,'ResumeThread',\ + RtlFillMemory,'RtlFillMemory',\ + RtlMoveMemory,'RtlMoveMemory',\ + RtlUnwind,'RtlUnwind',\ + RtlZeroMemory,'RtlZeroMemory',\ + ScrollConsoleScreenBufferA,'ScrollConsoleScreenBufferA',\ + ScrollConsoleScreenBufferW,'ScrollConsoleScreenBufferW',\ + SearchPathA,'SearchPathA',\ + SearchPathW,'SearchPathW',\ + SetCommBreak,'SetCommBreak',\ + SetCommConfig,'SetCommConfig',\ + SetCommMask,'SetCommMask',\ + SetCommState,'SetCommState',\ + SetCommTimeouts,'SetCommTimeouts',\ + SetComputerNameA,'SetComputerNameA',\ + SetComputerNameW,'SetComputerNameW',\ + SetConsoleActiveScreenBuffer,'SetConsoleActiveScreenBuffer',\ + SetConsoleCP,'SetConsoleCP',\ + SetConsoleCommandHistoryMode,'SetConsoleCommandHistoryMode',\ + SetConsoleCtrlHandler,'SetConsoleCtrlHandler',\ + SetConsoleCursor,'SetConsoleCursor',\ + SetConsoleCursorInfo,'SetConsoleCursorInfo',\ + SetConsoleCursorPosition,'SetConsoleCursorPosition',\ + SetConsoleDisplayMode,'SetConsoleDisplayMode',\ + SetConsoleFont,'SetConsoleFont',\ + SetConsoleHardwareState,'SetConsoleHardwareState',\ + SetConsoleIcon,'SetConsoleIcon',\ + SetConsoleInputExeNameA,'SetConsoleInputExeNameA',\ + SetConsoleInputExeNameW,'SetConsoleInputExeNameW',\ + SetConsoleKeyShortcuts,'SetConsoleKeyShortcuts',\ + SetConsoleMaximumWindowSize,'SetConsoleMaximumWindowSize',\ + SetConsoleMenuClose,'SetConsoleMenuClose',\ + SetConsoleMode,'SetConsoleMode',\ + SetConsoleNumberOfCommandsA,'SetConsoleNumberOfCommandsA',\ + SetConsoleNumberOfCommandsW,'SetConsoleNumberOfCommandsW',\ + SetConsoleOutputCP,'SetConsoleOutputCP',\ + SetConsolePalette,'SetConsolePalette',\ + SetConsoleScreenBufferSize,'SetConsoleScreenBufferSize',\ + SetConsoleTextAttribute,'SetConsoleTextAttribute',\ + SetConsoleTitleA,'SetConsoleTitleA',\ + SetConsoleTitleW,'SetConsoleTitleW',\ + SetConsoleWindowInfo,'SetConsoleWindowInfo',\ + SetCriticalSectionSpinCount,'SetCriticalSectionSpinCount',\ + SetCurrentDirectoryA,'SetCurrentDirectoryA',\ + SetCurrentDirectoryW,'SetCurrentDirectoryW',\ + SetDefaultCommConfigA,'SetDefaultCommConfigA',\ + SetDefaultCommConfigW,'SetDefaultCommConfigW',\ + SetEndOfFile,'SetEndOfFile',\ + SetEnvironmentVariableA,'SetEnvironmentVariableA',\ + SetEnvironmentVariableW,'SetEnvironmentVariableW',\ + SetErrorMode,'SetErrorMode',\ + SetEvent,'SetEvent',\ + SetFileApisToANSI,'SetFileApisToANSI',\ + SetFileApisToOEM,'SetFileApisToOEM',\ + SetFileAttributesA,'SetFileAttributesA',\ + SetFileAttributesW,'SetFileAttributesW',\ + SetFilePointer,'SetFilePointer',\ + SetFilePointerEx,'SetFilePointerEx',\ + SetFileTime,'SetFileTime',\ + SetHandleCount,'SetHandleCount',\ + SetHandleInformation,'SetHandleInformation',\ + SetInformationJobObject,'SetInformationJobObject',\ + SetLastConsoleEventActive,'SetLastConsoleEventActive',\ + SetLastError,'SetLastError',\ + SetLocalTime,'SetLocalTime',\ + SetLocaleInfoA,'SetLocaleInfoA',\ + SetLocaleInfoW,'SetLocaleInfoW',\ + SetMailslotInfo,'SetMailslotInfo',\ + SetNamedPipeHandleState,'SetNamedPipeHandleState',\ + SetPriorityClass,'SetPriorityClass',\ + SetProcessAffinityMask,'SetProcessAffinityMask',\ + SetProcessPriorityBoost,'SetProcessPriorityBoost',\ + SetProcessShutdownParameters,'SetProcessShutdownParameters',\ + SetProcessWorkingSetSize,'SetProcessWorkingSetSize',\ + SetStdHandle,'SetStdHandle',\ + SetSystemPowerState,'SetSystemPowerState',\ + SetSystemTime,'SetSystemTime',\ + SetSystemTimeAdjustment,'SetSystemTimeAdjustment',\ + SetTapeParameters,'SetTapeParameters',\ + SetTapePosition,'SetTapePosition',\ + SetThreadAffinityMask,'SetThreadAffinityMask',\ + SetThreadContext,'SetThreadContext',\ + SetThreadExecutionState,'SetThreadExecutionState',\ + SetThreadIdealProcessor,'SetThreadIdealProcessor',\ + SetThreadLocale,'SetThreadLocale',\ + SetThreadPriority,'SetThreadPriority',\ + SetThreadPriorityBoost,'SetThreadPriorityBoost',\ + SetTimeZoneInformation,'SetTimeZoneInformation',\ + SetUnhandledExceptionFilter,'SetUnhandledExceptionFilter',\ + SetVDMCurrentDirectories,'SetVDMCurrentDirectories',\ + SetVolumeLabelA,'SetVolumeLabelA',\ + SetVolumeLabelW,'SetVolumeLabelW',\ + SetWaitableTimer,'SetWaitableTimer',\ + SetupComm,'SetupComm',\ + ShowConsoleCursor,'ShowConsoleCursor',\ + SignalObjectAndWait,'SignalObjectAndWait',\ + SizeofResource,'SizeofResource',\ + Sleep,'Sleep',\ + SleepEx,'SleepEx',\ + SuspendThread,'SuspendThread',\ + SwitchToFiber,'SwitchToFiber',\ + SwitchToThread,'SwitchToThread',\ + SystemTimeToFileTime,'SystemTimeToFileTime',\ + SystemTimeToTzSpecificLocalTime,'SystemTimeToTzSpecificLocalTime',\ + TerminateJobObject,'TerminateJobObject',\ + TerminateProcess,'TerminateProcess',\ + TerminateThread,'TerminateThread',\ + Thread32First,'Thread32First',\ + Thread32Next,'Thread32Next',\ + TlsAlloc,'TlsAlloc',\ + TlsFree,'TlsFree',\ + TlsGetValue,'TlsGetValue',\ + TlsSetValue,'TlsSetValue',\ + Toolhelp32ReadProcessMemory,'Toolhelp32ReadProcessMemory',\ + TransactNamedPipe,'TransactNamedPipe',\ + TransmitCommChar,'TransmitCommChar',\ + TrimVirtualBuffer,'TrimVirtualBuffer',\ + TryEnterCriticalSection,'TryEnterCriticalSection',\ + UnhandledExceptionFilter,'UnhandledExceptionFilter',\ + UnlockFile,'UnlockFile',\ + UnlockFileEx,'UnlockFileEx',\ + UnmapViewOfFile,'UnmapViewOfFile',\ + UnmapViewOfFileVlm,'UnmapViewOfFileVlm',\ + UpdateResourceA,'UpdateResourceA',\ + UpdateResourceW,'UpdateResourceW',\ + VDMConsoleOperation,'VDMConsoleOperation',\ + VDMOperationStarted,'VDMOperationStarted',\ + VerLanguageNameA,'VerLanguageNameA',\ + VerLanguageNameW,'VerLanguageNameW',\ + VerifyConsoleIoHandle,'VerifyConsoleIoHandle',\ + VirtualAlloc,'VirtualAlloc',\ + VirtualAllocEx,'VirtualAllocEx',\ + VirtualAllocVlm,'VirtualAllocVlm',\ + VirtualBufferExceptionHandler,'VirtualBufferExceptionHandler',\ + VirtualFree,'VirtualFree',\ + VirtualFreeEx,'VirtualFreeEx',\ + VirtualFreeVlm,'VirtualFreeVlm',\ + VirtualLock,'VirtualLock',\ + VirtualProtect,'VirtualProtect',\ + VirtualProtectEx,'VirtualProtectEx',\ + VirtualProtectVlm,'VirtualProtectVlm',\ + VirtualQuery,'VirtualQuery',\ + VirtualQueryEx,'VirtualQueryEx',\ + VirtualQueryVlm,'VirtualQueryVlm',\ + VirtualUnlock,'VirtualUnlock',\ + WaitCommEvent,'WaitCommEvent',\ + WaitForDebugEvent,'WaitForDebugEvent',\ + WaitForMultipleObjects,'WaitForMultipleObjects',\ + WaitForMultipleObjectsEx,'WaitForMultipleObjectsEx',\ + WaitForSingleObject,'WaitForSingleObject',\ + WaitForSingleObjectEx,'WaitForSingleObjectEx',\ + WaitNamedPipeA,'WaitNamedPipeA',\ + WaitNamedPipeW,'WaitNamedPipeW',\ + WideCharToMultiByte,'WideCharToMultiByte',\ + WinExec,'WinExec',\ + WriteConsoleA,'WriteConsoleA',\ + WriteConsoleW,'WriteConsoleW',\ + WriteConsoleInputA,'WriteConsoleInputA',\ + WriteConsoleInputW,'WriteConsoleInputW',\ + WriteConsoleInputVDMA,'WriteConsoleInputVDMA',\ + WriteConsoleInputVDMW,'WriteConsoleInputVDMW',\ + WriteConsoleOutputA,'WriteConsoleOutputA',\ + WriteConsoleOutputW,'WriteConsoleOutputW',\ + WriteConsoleOutputAttribute,'WriteConsoleOutputAttribute',\ + WriteConsoleOutputCharacterA,'WriteConsoleOutputCharacterA',\ + WriteConsoleOutputCharacterW,'WriteConsoleOutputCharacterW',\ + WriteFile,'WriteFile',\ + WriteFileEx,'WriteFileEx',\ + WriteFileGather,'WriteFileGather',\ + WriteFileVlm,'WriteFileVlm',\ + WritePrivateProfileSectionA,'WritePrivateProfileSectionA',\ + WritePrivateProfileSectionW,'WritePrivateProfileSectionW',\ + WritePrivateProfileStringA,'WritePrivateProfileStringA',\ + WritePrivateProfileStringW,'WritePrivateProfileStringW',\ + WritePrivateProfileStructA,'WritePrivateProfileStructA',\ + WritePrivateProfileStructW,'WritePrivateProfileStructW',\ + WriteProcessMemory,'WriteProcessMemory',\ + WriteProcessMemoryVlm,'WriteProcessMemoryVlm',\ + WriteProfileSectionA,'WriteProfileSectionA',\ + WriteProfileSectionW,'WriteProfileSectionW',\ + WriteProfileStringA,'WriteProfileStringA',\ + WriteProfileStringW,'WriteProfileStringW',\ + WriteTapemark,'WriteTapemark',\ + _hread,'_hread',\ + _hwrite,'_hwrite',\ + _lclose,'_lclose',\ + _lcreat,'_lcreat',\ + _llseek,'_llseek',\ + _lopen,'_lopen',\ + _lread,'_lread',\ + _lwrite,'_lwrite',\ + lstrcatA,'lstrcatA',\ + lstrcatW,'lstrcatW',\ + lstrcmpA,'lstrcmpA',\ + lstrcmpW,'lstrcmpW',\ + lstrcmpiA,'lstrcmpiA',\ + lstrcmpiW,'lstrcmpiW',\ + lstrcpyA,'lstrcpyA',\ + lstrcpyW,'lstrcpyW',\ + lstrcpynA,'lstrcpynA',\ + lstrcpynW,'lstrcpynW',\ + lstrlenA,'lstrlenA',\ + lstrlenW,'lstrlenW' + +api AddAtom,\ + AddConsoleAlias,\ + BeginUpdateResource,\ + BuildCommDCB,\ + BuildCommDCBAndTimeouts,\ + CallNamedPipe,\ + CommConfigDialog,\ + CompareString,\ + CopyFile,\ + CopyFileEx,\ + CreateDirectory,\ + CreateDirectoryEx,\ + CreateEvent,\ + CreateFile,\ + CreateFileMapping,\ + CreateHardLink,\ + CreateJobObject,\ + CreateMailslot,\ + CreateMutex,\ + CreateNamedPipe,\ + CreateProcess,\ + CreateSemaphore,\ + CreateWaitableTimer,\ + DefineDosDevice,\ + DeleteFile,\ + EndUpdateResource,\ + EnumCalendarInfo,\ + EnumCalendarInfoEx,\ + EnumDateFormats,\ + EnumDateFormatsEx,\ + EnumResourceLanguages,\ + EnumResourceNames,\ + EnumResourceTypes,\ + EnumSystemCodePages,\ + EnumSystemLocales,\ + EnumTimeFormats,\ + ExpandEnvironmentStrings,\ + ExpungeConsoleCommandHistory,\ + FatalAppExit,\ + FillConsoleOutputCharacter,\ + FindAtom,\ + FindFirstChangeNotification,\ + FindFirstFile,\ + FindFirstFileEx,\ + FindNextFile,\ + FindResource,\ + FindResourceEx,\ + FoldString,\ + FormatMessage,\ + FreeEnvironmentStrings,\ + GetAtomName,\ + GetBinaryType,\ + GetCPInfoEx,\ + GetCommandLine,\ + GetCompressedFileSize,\ + GetComputerName,\ + GetConsoleAlias,\ + GetConsoleAliasExes,\ + GetConsoleAliasExesLength,\ + GetConsoleAliases,\ + GetConsoleAliasesLength,\ + GetConsoleCommandHistory,\ + GetConsoleCommandHistoryLength,\ + GetConsoleInputExeName,\ + GetConsoleKeyboardLayoutName,\ + GetConsoleTitle,\ + GetCurrencyFormat,\ + GetCurrentDirectory,\ + GetDateFormat,\ + GetDefaultCommConfig,\ + GetDiskFreeSpace,\ + GetDiskFreeSpaceEx,\ + GetDriveType,\ + GetEnvironmentStrings,\ + GetEnvironmentVariable,\ + GetFileAttributes,\ + GetFileAttributesEx,\ + GetFullPathName,\ + GetLocaleInfo,\ + GetLogicalDriveStrings,\ + GetLongPathName,\ + GetModuleFileName,\ + GetModuleHandle,\ + GetNamedPipeHandleState,\ + GetNumberFormat,\ + GetPrivateProfileInt,\ + GetPrivateProfileSection,\ + GetPrivateProfileSectionNames,\ + GetPrivateProfileString,\ + GetPrivateProfileStruct,\ + GetProfileInt,\ + GetProfileSection,\ + GetProfileString,\ + GetShortPathName,\ + GetStartupInfo,\ + GetStringType,\ + GetStringTypeEx,\ + GetSystemDirectory,\ + GetTempFileName,\ + GetTempPath,\ + GetTimeFormat,\ + GetVersionEx,\ + GetVolumeInformation,\ + GetWindowsDirectory,\ + GlobalAddAtom,\ + GlobalFindAtom,\ + GlobalGetAtomName,\ + IsBadStringPtr,\ + LCMapString,\ + LoadLibrary,\ + LoadLibraryEx,\ + MoveFile,\ + MoveFileEx,\ + MoveFileWithProgress,\ + OpenEvent,\ + OpenFileMapping,\ + OpenJobObject,\ + OpenMutex,\ + OpenSemaphore,\ + OpenWaitableTimer,\ + OutputDebugString,\ + PeekConsoleInput,\ + QueryDosDevice,\ + ReadConsole,\ + ReadConsoleInput,\ + ReadConsoleInputEx,\ + ReadConsoleOutput,\ + ReadConsoleOutputCharacter,\ + RemoveDirectory,\ + ScrollConsoleScreenBuffer,\ + SearchPath,\ + SetComputerName,\ + SetConsoleInputExeName,\ + SetConsoleNumberOfCommands,\ + SetConsoleTitle,\ + SetCurrentDirectory,\ + SetDefaultCommConfig,\ + SetEnvironmentVariable,\ + SetFileAttributes,\ + SetLocaleInfo,\ + SetVolumeLabel,\ + UpdateResource,\ + VerLanguageName,\ + WaitNamedPipe,\ + WriteConsole,\ + WriteConsoleInput,\ + WriteConsoleInputVDM,\ + WriteConsoleOutput,\ + WriteConsoleOutputCharacter,\ + WritePrivateProfileSection,\ + WritePrivateProfileString,\ + WritePrivateProfileStruct,\ + WriteProfileSection,\ + WriteProfileString,\ + lstrcat,\ + lstrcmp,\ + lstrcmpi,\ + lstrcpy,\ + lstrcpyn,\ + lstrlen diff --git a/toolchain/fasmw17332/INCLUDE/API/SHELL32.INC b/toolchain/fasmw17332/INCLUDE/API/SHELL32.INC new file mode 100644 index 0000000..1ca3a14 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/API/SHELL32.INC @@ -0,0 +1,167 @@ + +; SHELL32 API calls + +import shell32,\ + CheckEscapesA,'CheckEscapesA',\ + CheckEscapesW,'CheckEscapesW',\ + DoEnvironmentSubstA,'DoEnvironmentSubstA',\ + DoEnvironmentSubstW,'DoEnvironmentSubstW',\ + DragAcceptFiles,'DragAcceptFiles',\ + DragFinish,'DragFinish',\ + DragQueryFileA,'DragQueryFileA',\ + DragQueryFileW,'DragQueryFileW',\ + DragQueryPoint,'DragQueryPoint',\ + DuplicateIcon,'DuplicateIcon',\ + ExtractAssociatedIconA,'ExtractAssociatedIconA',\ + ExtractAssociatedIconW,'ExtractAssociatedIconW',\ + ExtractAssociatedIconExA,'ExtractAssociatedIconExA',\ + ExtractAssociatedIconExW,'ExtractAssociatedIconExW',\ + ExtractIconA,'ExtractIconA',\ + ExtractIconW,'ExtractIconW',\ + ExtractIconExA,'ExtractIconExA',\ + ExtractIconExW,'ExtractIconExW',\ + ExtractIconResInfoA,'ExtractIconResInfoA',\ + ExtractIconResInfoW,'ExtractIconResInfoW',\ + FindExeDlgProc,'FindExeDlgProc',\ + FindExecutableA,'FindExecutableA',\ + FindExecutableW,'FindExecutableW',\ + FreeIconList,'FreeIconList',\ + InternalExtractIconListA,'InternalExtractIconListA',\ + InternalExtractIconListW,'InternalExtractIconListW',\ + RealShellExecuteA,'RealShellExecuteA',\ + RealShellExecuteW,'RealShellExecuteW',\ + RealShellExecuteExA,'RealShellExecuteExA',\ + RealShellExecuteExW,'RealShellExecuteExW',\ + RegenerateUserEnvironment,'RegenerateUserEnvironment',\ + SHAddToRecentDocs,'SHAddToRecentDocs',\ + SHAppBarMessage,'SHAppBarMessage',\ + SHBrowseForFolderA,'SHBrowseForFolderA',\ + SHBrowseForFolderW,'SHBrowseForFolderW',\ + SHChangeNotify,'SHChangeNotify',\ + SHEmptyRecycleBinA,'SHEmptyRecycleBinA',\ + SHEmptyRecycleBinW,'SHEmptyRecycleBinW',\ + SHFileOperationA,'SHFileOperationA',\ + SHFileOperationW,'SHFileOperationW',\ + SHFormatDrive,'SHFormatDrive',\ + SHFreeNameMappings,'SHFreeNameMappings',\ + SHGetDataFromIDListA,'SHGetDataFromIDListA',\ + SHGetDataFromIDListW,'SHGetDataFromIDListW',\ + SHGetDesktopFolder,'SHGetDesktopFolder',\ + SHGetDiskFreeSpaceA,'SHGetDiskFreeSpaceA',\ + SHGetDiskFreeSpaceW,'SHGetDiskFreeSpaceW',\ + SHGetFileInfoA,'SHGetFileInfoA',\ + SHGetFileInfoW,'SHGetFileInfoW',\ + SHGetInstanceExplorer,'SHGetInstanceExplorer',\ + SHGetMalloc,'SHGetMalloc',\ + SHGetNewLinkInfo,'SHGetNewLinkInfo',\ + SHGetPathFromIDListA,'SHGetPathFromIDListA',\ + SHGetPathFromIDListW,'SHGetPathFromIDListW',\ + SHGetSettings,'SHGetSettings',\ + SHGetSpecialFolderLocation,'SHGetSpecialFolderLocation',\ + SHGetSpecialFolderPathA,'SHGetSpecialFolderPathA',\ + SHGetSpecialFolderPathW,'SHGetSpecialFolderPathW',\ + SHInvokePrinterCommandA,'SHInvokePrinterCommandA',\ + SHInvokePrinterCommandW,'SHInvokePrinterCommandW',\ + SHLoadInProc,'SHLoadInProc',\ + SHQueryRecycleBinA,'SHQueryRecycleBinA',\ + SHQueryRecycleBinW,'SHQueryRecycleBinW',\ + SHUpdateRecycleBinIcon,'SHUpdateRecycleBinIcon',\ + SheChangeDirA,'SheChangeDirA',\ + SheChangeDirW,'SheChangeDirW',\ + SheChangeDirExA,'SheChangeDirExA',\ + SheChangeDirExW,'SheChangeDirExW',\ + SheFullPathA,'SheFullPathA',\ + SheFullPathW,'SheFullPathW',\ + SheGetCurDrive,'SheGetCurDrive',\ + SheGetDirA,'SheGetDirA',\ + SheGetDirW,'SheGetDirW',\ + SheRemoveQuotesA,'SheRemoveQuotesA',\ + SheRemoveQuotesW,'SheRemoveQuotesW',\ + SheSetCurDrive,'SheSetCurDrive',\ + SheShortenPathA,'SheShortenPathA',\ + SheShortenPathW,'SheShortenPathW',\ + ShellAboutA,'ShellAboutA',\ + ShellAboutW,'ShellAboutW',\ + ShellExecuteA,'ShellExecuteA',\ + ShellExecuteW,'ShellExecuteW',\ + ShellExecuteExA,'ShellExecuteExA',\ + ShellExecuteExW,'ShellExecuteExW',\ + ShellHookProc,'ShellHookProc',\ + Shell_NotifyIconA,'Shell_NotifyIconA',\ + Shell_NotifyIconW,'Shell_NotifyIconW',\ + StrChrA,'StrChrA',\ + StrChrW,'StrChrW',\ + StrChrIA,'StrChrIA',\ + StrChrIW,'StrChrIW',\ + StrCmpNA,'StrCmpNA',\ + StrCmpNW,'StrCmpNW',\ + StrCmpNIA,'StrCmpNIA',\ + StrCmpNIW,'StrCmpNIW',\ + StrCpyNA,'StrCpyNA',\ + StrCpyNW,'StrCpyNW',\ + StrNCmpA,'StrNCmpA',\ + StrNCmpW,'StrNCmpW',\ + StrNCmpIA,'StrNCmpIA',\ + StrNCmpIW,'StrNCmpIW',\ + StrNCpyA,'StrNCpyA',\ + StrNCpyW,'StrNCpyW',\ + StrRChrA,'StrRChrA',\ + StrRChrW,'StrRChrW',\ + StrRChrIA,'StrRChrIA',\ + StrRChrIW,'StrRChrIW',\ + StrRStrA,'StrRStrA',\ + StrRStrW,'StrRStrW',\ + StrRStrIA,'StrRStrIA',\ + StrRStrIW,'StrRStrIW',\ + StrStrA,'StrStrA',\ + StrStrW,'StrStrW',\ + StrStrIA,'StrStrIA',\ + StrStrIW,'StrStrIW',\ + WOWShellExecute,'WOWShellExecute' + +api CheckEscapes,\ + DoEnvironmentSubst,\ + DragQueryFile,\ + ExtractAssociatedIcon,\ + ExtractAssociatedIconEx,\ + ExtractIcon,\ + ExtractIconEx,\ + ExtractIconResInfo,\ + FindExecutable,\ + InternalExtractIconList,\ + RealShellExecute,\ + RealShellExecuteEx,\ + SHBrowseForFolder,\ + SHEmptyRecycleBin,\ + SHFileOperation,\ + SHGetDataFromIDList,\ + SHGetDiskFreeSpace,\ + SHGetFileInfo,\ + SHGetPathFromIDList,\ + SHGetSpecialFolderPath,\ + SHInvokePrinterCommand,\ + SHQueryRecycleBin,\ + SheChangeDir,\ + SheChangeDirEx,\ + SheFullPath,\ + SheGetDir,\ + SheRemoveQuotes,\ + SheShortenPath,\ + ShellAbout,\ + ShellExecute,\ + ShellExecuteEx,\ + Shell_NotifyIcon,\ + StrChr,\ + StrChrI,\ + StrCmpN,\ + StrCmpNI,\ + StrCpyN,\ + StrNCmp,\ + StrNCmpI,\ + StrNCpy,\ + StrRChr,\ + StrRChrI,\ + StrRStr,\ + StrRStrI,\ + StrStr,\ + StrStrI diff --git a/toolchain/fasmw17332/INCLUDE/API/USER32.INC b/toolchain/fasmw17332/INCLUDE/API/USER32.INC new file mode 100644 index 0000000..bffafa3 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/API/USER32.INC @@ -0,0 +1,756 @@ + +; USER32 API calls + +import user32,\ + ActivateKeyboardLayout,'ActivateKeyboardLayout',\ + AdjustWindowRect,'AdjustWindowRect',\ + AdjustWindowRectEx,'AdjustWindowRectEx',\ + AnimateWindow,'AnimateWindow',\ + AnyPopup,'AnyPopup',\ + AppendMenuA,'AppendMenuA',\ + AppendMenuW,'AppendMenuW',\ + ArrangeIconicWindows,'ArrangeIconicWindows',\ + AttachThreadInput,'AttachThreadInput',\ + BeginDeferWindowPos,'BeginDeferWindowPos',\ + BeginPaint,'BeginPaint',\ + BlockInput,'BlockInput',\ + BringWindowToTop,'BringWindowToTop',\ + BroadcastSystemMessageA,'BroadcastSystemMessageA',\ + BroadcastSystemMessageW,'BroadcastSystemMessageW',\ + CallMsgFilterA,'CallMsgFilterA',\ + CallMsgFilterW,'CallMsgFilterW',\ + CallNextHookEx,'CallNextHookEx',\ + CallWindowProcA,'CallWindowProcA',\ + CallWindowProcW,'CallWindowProcW',\ + CascadeChildWindows,'CascadeChildWindows',\ + CascadeWindows,'CascadeWindows',\ + ChangeClipboardChain,'ChangeClipboardChain',\ + ChangeDisplaySettingsA,'ChangeDisplaySettingsA',\ + ChangeDisplaySettingsW,'ChangeDisplaySettingsW',\ + ChangeDisplaySettingsExA,'ChangeDisplaySettingsExA',\ + ChangeDisplaySettingsExW,'ChangeDisplaySettingsExW',\ + ChangeMenuA,'ChangeMenuA',\ + ChangeMenuW,'ChangeMenuW',\ + CharLowerA,'CharLowerA',\ + CharLowerW,'CharLowerW',\ + CharLowerBuffA,'CharLowerBuffA',\ + CharLowerBuffW,'CharLowerBuffW',\ + CharNextA,'CharNextA',\ + CharNextW,'CharNextW',\ + CharNextExA,'CharNextExA',\ + CharNextExW,'CharNextExW',\ + CharPrevA,'CharPrevA',\ + CharPrevW,'CharPrevW',\ + CharPrevExA,'CharPrevExA',\ + CharPrevExW,'CharPrevExW',\ + CharToOemA,'CharToOemA',\ + CharToOemW,'CharToOemW',\ + CharToOemBuffA,'CharToOemBuffA',\ + CharToOemBuffW,'CharToOemBuffW',\ + CharUpperA,'CharUpperA',\ + CharUpperW,'CharUpperW',\ + CharUpperBuffA,'CharUpperBuffA',\ + CharUpperBuffW,'CharUpperBuffW',\ + CheckDlgButton,'CheckDlgButton',\ + CheckMenuItem,'CheckMenuItem',\ + CheckMenuRadioItem,'CheckMenuRadioItem',\ + CheckRadioButton,'CheckRadioButton',\ + ChildWindowFromPoint,'ChildWindowFromPoint',\ + ChildWindowFromPointEx,'ChildWindowFromPointEx',\ + ClientToScreen,'ClientToScreen',\ + ClipCursor,'ClipCursor',\ + CloseClipboard,'CloseClipboard',\ + CloseDesktop,'CloseDesktop',\ + CloseWindow,'CloseWindow',\ + CloseWindowStation,'CloseWindowStation',\ + CopyAcceleratorTableA,'CopyAcceleratorTableA',\ + CopyAcceleratorTableW,'CopyAcceleratorTableW',\ + CopyIcon,'CopyIcon',\ + CopyImage,'CopyImage',\ + CopyRect,'CopyRect',\ + CountClipboardFormats,'CountClipboardFormats',\ + CreateAcceleratorTableA,'CreateAcceleratorTableA',\ + CreateAcceleratorTableW,'CreateAcceleratorTableW',\ + CreateCaret,'CreateCaret',\ + CreateCursor,'CreateCursor',\ + CreateDesktopA,'CreateDesktopA',\ + CreateDesktopW,'CreateDesktopW',\ + CreateDialogIndirectParamA,'CreateDialogIndirectParamA',\ + CreateDialogIndirectParamW,'CreateDialogIndirectParamW',\ + CreateDialogParamA,'CreateDialogParamA',\ + CreateDialogParamW,'CreateDialogParamW',\ + CreateIcon,'CreateIcon',\ + CreateIconFromResource,'CreateIconFromResource',\ + CreateIconFromResourceEx,'CreateIconFromResourceEx',\ + CreateIconIndirect,'CreateIconIndirect',\ + CreateMDIWindowA,'CreateMDIWindowA',\ + CreateMDIWindowW,'CreateMDIWindowW',\ + CreateMenu,'CreateMenu',\ + CreatePopupMenu,'CreatePopupMenu',\ + CreateWindowExA,'CreateWindowExA',\ + CreateWindowExW,'CreateWindowExW',\ + CreateWindowStationA,'CreateWindowStationA',\ + CreateWindowStationW,'CreateWindowStationW',\ + DdeAbandonTransaction,'DdeAbandonTransaction',\ + DdeAccessData,'DdeAccessData',\ + DdeAddData,'DdeAddData',\ + DdeClientTransaction,'DdeClientTransaction',\ + DdeCmpStringHandles,'DdeCmpStringHandles',\ + DdeConnect,'DdeConnect',\ + DdeConnectList,'DdeConnectList',\ + DdeCreateDataHandle,'DdeCreateDataHandle',\ + DdeCreateStringHandleA,'DdeCreateStringHandleA',\ + DdeCreateStringHandleW,'DdeCreateStringHandleW',\ + DdeDisconnect,'DdeDisconnect',\ + DdeDisconnectList,'DdeDisconnectList',\ + DdeEnableCallback,'DdeEnableCallback',\ + DdeFreeDataHandle,'DdeFreeDataHandle',\ + DdeFreeStringHandle,'DdeFreeStringHandle',\ + DdeGetData,'DdeGetData',\ + DdeGetLastError,'DdeGetLastError',\ + DdeGetQualityOfService,'DdeGetQualityOfService',\ + DdeImpersonateClient,'DdeImpersonateClient',\ + DdeInitializeA,'DdeInitializeA',\ + DdeInitializeW,'DdeInitializeW',\ + DdeKeepStringHandle,'DdeKeepStringHandle',\ + DdeNameService,'DdeNameService',\ + DdePostAdvise,'DdePostAdvise',\ + DdeQueryConvInfo,'DdeQueryConvInfo',\ + DdeQueryNextServer,'DdeQueryNextServer',\ + DdeQueryStringA,'DdeQueryStringA',\ + DdeQueryStringW,'DdeQueryStringW',\ + DdeReconnect,'DdeReconnect',\ + DdeSetQualityOfService,'DdeSetQualityOfService',\ + DdeSetUserHandle,'DdeSetUserHandle',\ + DdeUnaccessData,'DdeUnaccessData',\ + DdeUninitialize,'DdeUninitialize',\ + DefDlgProcA,'DefDlgProcA',\ + DefDlgProcW,'DefDlgProcW',\ + DefFrameProcA,'DefFrameProcA',\ + DefFrameProcW,'DefFrameProcW',\ + DefMDIChildProcA,'DefMDIChildProcA',\ + DefMDIChildProcW,'DefMDIChildProcW',\ + DefWindowProcA,'DefWindowProcA',\ + DefWindowProcW,'DefWindowProcW',\ + DeferWindowPos,'DeferWindowPos',\ + DeleteMenu,'DeleteMenu',\ + DestroyAcceleratorTable,'DestroyAcceleratorTable',\ + DestroyCaret,'DestroyCaret',\ + DestroyCursor,'DestroyCursor',\ + DestroyIcon,'DestroyIcon',\ + DestroyMenu,'DestroyMenu',\ + DestroyWindow,'DestroyWindow',\ + DialogBoxIndirectParamA,'DialogBoxIndirectParamA',\ + DialogBoxIndirectParamW,'DialogBoxIndirectParamW',\ + DialogBoxParamA,'DialogBoxParamA',\ + DialogBoxParamW,'DialogBoxParamW',\ + DispatchMessageA,'DispatchMessageA',\ + DispatchMessageW,'DispatchMessageW',\ + DlgDirListA,'DlgDirListA',\ + DlgDirListW,'DlgDirListW',\ + DlgDirListComboBoxA,'DlgDirListComboBoxA',\ + DlgDirListComboBoxW,'DlgDirListComboBoxW',\ + DlgDirSelectComboBoxExA,'DlgDirSelectComboBoxExA',\ + DlgDirSelectComboBoxExW,'DlgDirSelectComboBoxExW',\ + DlgDirSelectExA,'DlgDirSelectExA',\ + DlgDirSelectExW,'DlgDirSelectExW',\ + DragDetect,'DragDetect',\ + DragObject,'DragObject',\ + DrawAnimatedRects,'DrawAnimatedRects',\ + DrawCaption,'DrawCaption',\ + DrawEdge,'DrawEdge',\ + DrawFocusRect,'DrawFocusRect',\ + DrawFrame,'DrawFrame',\ + DrawFrameControl,'DrawFrameControl',\ + DrawIcon,'DrawIcon',\ + DrawIconEx,'DrawIconEx',\ + DrawMenuBar,'DrawMenuBar',\ + DrawStateA,'DrawStateA',\ + DrawStateW,'DrawStateW',\ + DrawTextA,'DrawTextA',\ + DrawTextW,'DrawTextW',\ + DrawTextExA,'DrawTextExA',\ + DrawTextExW,'DrawTextExW',\ + EditWndProc,'EditWndProc',\ + EmptyClipboard,'EmptyClipboard',\ + EnableMenuItem,'EnableMenuItem',\ + EnableScrollBar,'EnableScrollBar',\ + EnableWindow,'EnableWindow',\ + EndDeferWindowPos,'EndDeferWindowPos',\ + EndDialog,'EndDialog',\ + EndMenu,'EndMenu',\ + EndPaint,'EndPaint',\ + EnumChildWindows,'EnumChildWindows',\ + EnumClipboardFormats,'EnumClipboardFormats',\ + EnumDesktopWindows,'EnumDesktopWindows',\ + EnumDesktopsA,'EnumDesktopsA',\ + EnumDesktopsW,'EnumDesktopsW',\ + EnumDisplayMonitors,'EnumDisplayMonitors',\ + EnumDisplaySettingsA,'EnumDisplaySettingsA',\ + EnumDisplaySettingsW,'EnumDisplaySettingsW',\ + EnumDisplaySettingsExA,'EnumDisplaySettingsExA',\ + EnumDisplaySettingsExW,'EnumDisplaySettingsExW',\ + EnumPropsA,'EnumPropsA',\ + EnumPropsW,'EnumPropsW',\ + EnumPropsExA,'EnumPropsExA',\ + EnumPropsExW,'EnumPropsExW',\ + EnumThreadWindows,'EnumThreadWindows',\ + EnumWindowStationsA,'EnumWindowStationsA',\ + EnumWindowStationsW,'EnumWindowStationsW',\ + EnumWindows,'EnumWindows',\ + EqualRect,'EqualRect',\ + ExcludeUpdateRgn,'ExcludeUpdateRgn',\ + ExitWindowsEx,'ExitWindowsEx',\ + FillRect,'FillRect',\ + FindWindowA,'FindWindowA',\ + FindWindowW,'FindWindowW',\ + FindWindowExA,'FindWindowExA',\ + FindWindowExW,'FindWindowExW',\ + FlashWindow,'FlashWindow',\ + FrameRect,'FrameRect',\ + FreeDDElParam,'FreeDDElParam',\ + GetActiveWindow,'GetActiveWindow',\ + GetAltTabInfoA,'GetAltTabInfoA',\ + GetAltTabInfoW,'GetAltTabInfoW',\ + GetAncestor,'GetAncestor',\ + GetAsyncKeyState,'GetAsyncKeyState',\ + GetCapture,'GetCapture',\ + GetCaretBlinkTime,'GetCaretBlinkTime',\ + GetCaretPos,'GetCaretPos',\ + GetClassInfoA,'GetClassInfoA',\ + GetClassInfoW,'GetClassInfoW',\ + GetClassInfoExA,'GetClassInfoExA',\ + GetClassInfoExW,'GetClassInfoExW',\ + GetClassLongA,'GetClassLongA',\ + GetClassLongW,'GetClassLongW',\ + GetClassNameA,'GetClassNameA',\ + GetClassNameW,'GetClassNameW',\ + GetClassWord,'GetClassWord',\ + GetClientRect,'GetClientRect',\ + GetClipCursor,'GetClipCursor',\ + GetClipboardData,'GetClipboardData',\ + GetClipboardFormatNameA,'GetClipboardFormatNameA',\ + GetClipboardFormatNameW,'GetClipboardFormatNameW',\ + GetClipboardSequenceNumberA,'GetClipboardSequenceNumberA',\ + GetClipboardSequenceNumberW,'GetClipboardSequenceNumberW',\ + GetClipboardViewer,'GetClipboardViewer',\ + GetComboBoxInfo,'GetComboBoxInfo',\ + GetCursor,'GetCursor',\ + GetCursorInfo,'GetCursorInfo',\ + GetCursorPos,'GetCursorPos',\ + GetDC,'GetDC',\ + GetDCEx,'GetDCEx',\ + GetDesktopWindow,'GetDesktopWindow',\ + GetDialogBaseUnits,'GetDialogBaseUnits',\ + GetDlgCtrlID,'GetDlgCtrlID',\ + GetDlgItem,'GetDlgItem',\ + GetDlgItemInt,'GetDlgItemInt',\ + GetDlgItemTextA,'GetDlgItemTextA',\ + GetDlgItemTextW,'GetDlgItemTextW',\ + GetDoubleClickTime,'GetDoubleClickTime',\ + GetFocus,'GetFocus',\ + GetForegroundWindow,'GetForegroundWindow',\ + GetGUIThreadInfo,'GetGUIThreadInfo',\ + GetGuiResources,'GetGuiResources',\ + GetIconInfo,'GetIconInfo',\ + GetInputDesktop,'GetInputDesktop',\ + GetInputState,'GetInputState',\ + GetKBCodePage,'GetKBCodePage',\ + GetKeyNameTextA,'GetKeyNameTextA',\ + GetKeyNameTextW,'GetKeyNameTextW',\ + GetKeyState,'GetKeyState',\ + GetKeyboardLayout,'GetKeyboardLayout',\ + GetKeyboardLayoutList,'GetKeyboardLayoutList',\ + GetKeyboardLayoutNameA,'GetKeyboardLayoutNameA',\ + GetKeyboardLayoutNameW,'GetKeyboardLayoutNameW',\ + GetKeyboardState,'GetKeyboardState',\ + GetKeyboardType,'GetKeyboardType',\ + GetLastActivePopup,'GetLastActivePopup',\ + GetLastInputInfo,'GetLastInputInfo',\ + GetLayeredWindowAttributes,'GetLayeredWindowAttributes',\ + GetListBoxInfo,'GetListBoxInfo',\ + GetMenu,'GetMenu',\ + GetMenuBarInfo,'GetMenuBarInfo',\ + GetMenuCheckMarkDimensions,'GetMenuCheckMarkDimensions',\ + GetMenuContextHelpId,'GetMenuContextHelpId',\ + GetMenuDefaultItem,'GetMenuDefaultItem',\ + GetMenuInfo,'GetMenuInfo',\ + GetMenuItemCount,'GetMenuItemCount',\ + GetMenuItemID,'GetMenuItemID',\ + GetMenuItemInfoA,'GetMenuItemInfoA',\ + GetMenuItemInfoW,'GetMenuItemInfoW',\ + GetMenuItemRect,'GetMenuItemRect',\ + GetMenuState,'GetMenuState',\ + GetMenuStringA,'GetMenuStringA',\ + GetMenuStringW,'GetMenuStringW',\ + GetMessageA,'GetMessageA',\ + GetMessageW,'GetMessageW',\ + GetMessageExtraInfo,'GetMessageExtraInfo',\ + GetMessagePos,'GetMessagePos',\ + GetMessageTime,'GetMessageTime',\ + GetMonitorInfoA,'GetMonitorInfoA',\ + GetMonitorInfoW,'GetMonitorInfoW',\ + GetMouseMovePoints,'GetMouseMovePoints',\ + GetNextDlgGroupItem,'GetNextDlgGroupItem',\ + GetNextDlgTabItem,'GetNextDlgTabItem',\ + GetOpenClipboardWindow,'GetOpenClipboardWindow',\ + GetParent,'GetParent',\ + GetPriorityClipboardFormat,'GetPriorityClipboardFormat',\ + GetProcessWindowStation,'GetProcessWindowStation',\ + GetPropA,'GetPropA',\ + GetPropW,'GetPropW',\ + GetQueueStatus,'GetQueueStatus',\ + GetScrollBarInfo,'GetScrollBarInfo',\ + GetScrollInfo,'GetScrollInfo',\ + GetScrollPos,'GetScrollPos',\ + GetScrollRange,'GetScrollRange',\ + GetShellWindow,'GetShellWindow',\ + GetSubMenu,'GetSubMenu',\ + GetSysColor,'GetSysColor',\ + GetSysColorBrush,'GetSysColorBrush',\ + GetSystemMenu,'GetSystemMenu',\ + GetSystemMetrics,'GetSystemMetrics',\ + GetTabbedTextExtentA,'GetTabbedTextExtentA',\ + GetTabbedTextExtentW,'GetTabbedTextExtentW',\ + GetThreadDesktop,'GetThreadDesktop',\ + GetTitleBarInfo,'GetTitleBarInfo',\ + GetTopWindow,'GetTopWindow',\ + GetUpdateRect,'GetUpdateRect',\ + GetUpdateRgn,'GetUpdateRgn',\ + GetUserObjectInformationA,'GetUserObjectInformationA',\ + GetUserObjectInformationW,'GetUserObjectInformationW',\ + GetUserObjectSecurity,'GetUserObjectSecurity',\ + GetWindow,'GetWindow',\ + GetWindowContextHelpId,'GetWindowContextHelpId',\ + GetWindowDC,'GetWindowDC',\ + GetWindowInfo,'GetWindowInfo',\ + GetWindowLongA,'GetWindowLongA',\ + GetWindowLongW,'GetWindowLongW',\ + GetWindowLongPtrA,'GetWindowLongPtrA',\ + GetWindowLongPtrW,'GetWindowLongPtrW',\ + GetWindowModuleFileNameA,'GetWindowModuleFileNameA',\ + GetWindowModuleFileNameW,'GetWindowModuleFileNameW',\ + GetWindowPlacement,'GetWindowPlacement',\ + GetWindowRect,'GetWindowRect',\ + GetWindowRgn,'GetWindowRgn',\ + GetWindowTextA,'GetWindowTextA',\ + GetWindowTextW,'GetWindowTextW',\ + GetWindowTextLengthA,'GetWindowTextLengthA',\ + GetWindowTextLengthW,'GetWindowTextLengthW',\ + GetWindowThreadProcessId,'GetWindowThreadProcessId',\ + GetWindowWord,'GetWindowWord',\ + GrayStringA,'GrayStringA',\ + GrayStringW,'GrayStringW',\ + HideCaret,'HideCaret',\ + HiliteMenuItem,'HiliteMenuItem',\ + IMPGetIMEA,'IMPGetIMEA',\ + IMPGetIMEW,'IMPGetIMEW',\ + IMPQueryIMEA,'IMPQueryIMEA',\ + IMPQueryIMEW,'IMPQueryIMEW',\ + IMPSetIMEA,'IMPSetIMEA',\ + IMPSetIMEW,'IMPSetIMEW',\ + ImpersonateDdeClientWindow,'ImpersonateDdeClientWindow',\ + InSendMessage,'InSendMessage',\ + InSendMessageEx,'InSendMessageEx',\ + InflateRect,'InflateRect',\ + InsertMenuA,'InsertMenuA',\ + InsertMenuW,'InsertMenuW',\ + InsertMenuItemA,'InsertMenuItemA',\ + InsertMenuItemW,'InsertMenuItemW',\ + IntersectRect,'IntersectRect',\ + InvalidateRect,'InvalidateRect',\ + InvalidateRgn,'InvalidateRgn',\ + InvertRect,'InvertRect',\ + IsCharAlphaA,'IsCharAlphaA',\ + IsCharAlphaW,'IsCharAlphaW',\ + IsCharAlphaNumericA,'IsCharAlphaNumericA',\ + IsCharAlphaNumericW,'IsCharAlphaNumericW',\ + IsCharLowerA,'IsCharLowerA',\ + IsCharLowerW,'IsCharLowerW',\ + IsCharUpperA,'IsCharUpperA',\ + IsCharUpperW,'IsCharUpperW',\ + IsChild,'IsChild',\ + IsClipboardFormatAvailable,'IsClipboardFormatAvailable',\ + IsDialogMessageA,'IsDialogMessageA',\ + IsDialogMessageW,'IsDialogMessageW',\ + IsDlgButtonChecked,'IsDlgButtonChecked',\ + IsIconic,'IsIconic',\ + IsMenu,'IsMenu',\ + IsRectEmpty,'IsRectEmpty',\ + IsWindow,'IsWindow',\ + IsWindowEnabled,'IsWindowEnabled',\ + IsWindowUnicode,'IsWindowUnicode',\ + IsWindowVisible,'IsWindowVisible',\ + IsZoomed,'IsZoomed',\ + KillSystemTimer,'KillSystemTimer',\ + KillTimer,'KillTimer',\ + LoadAcceleratorsA,'LoadAcceleratorsA',\ + LoadAcceleratorsW,'LoadAcceleratorsW',\ + LoadBitmapA,'LoadBitmapA',\ + LoadBitmapW,'LoadBitmapW',\ + LoadCursorA,'LoadCursorA',\ + LoadCursorW,'LoadCursorW',\ + LoadCursorFromFileA,'LoadCursorFromFileA',\ + LoadCursorFromFileW,'LoadCursorFromFileW',\ + LoadIconA,'LoadIconA',\ + LoadIconW,'LoadIconW',\ + LoadImageA,'LoadImageA',\ + LoadImageW,'LoadImageW',\ + LoadKeyboardLayoutA,'LoadKeyboardLayoutA',\ + LoadKeyboardLayoutW,'LoadKeyboardLayoutW',\ + LoadMenuA,'LoadMenuA',\ + LoadMenuW,'LoadMenuW',\ + LoadMenuIndirectA,'LoadMenuIndirectA',\ + LoadMenuIndirectW,'LoadMenuIndirectW',\ + LoadStringA,'LoadStringA',\ + LoadStringW,'LoadStringW',\ + LockWindowUpdate,'LockWindowUpdate',\ + LockWorkStation,'LockWorkStation',\ + LookupIconIdFromDirectory,'LookupIconIdFromDirectory',\ + LookupIconIdFromDirectoryEx,'LookupIconIdFromDirectoryEx',\ + MapDialogRect,'MapDialogRect',\ + MapVirtualKeyA,'MapVirtualKeyA',\ + MapVirtualKeyW,'MapVirtualKeyW',\ + MapVirtualKeyExA,'MapVirtualKeyExA',\ + MapVirtualKeyExW,'MapVirtualKeyExW',\ + MapWindowPoints,'MapWindowPoints',\ + MenuItemFromPoint,'MenuItemFromPoint',\ + MessageBeep,'MessageBeep',\ + MessageBoxA,'MessageBoxA',\ + MessageBoxW,'MessageBoxW',\ + MessageBoxExA,'MessageBoxExA',\ + MessageBoxExW,'MessageBoxExW',\ + MessageBoxIndirectA,'MessageBoxIndirectA',\ + MessageBoxIndirectW,'MessageBoxIndirectW',\ + ModifyMenuA,'ModifyMenuA',\ + ModifyMenuW,'ModifyMenuW',\ + MonitorFromPoint,'MonitorFromPoint',\ + MonitorFromRect,'MonitorFromRect',\ + MonitorFromWindow,'MonitorFromWindow',\ + MoveWindow,'MoveWindow',\ + MsgWaitForMultipleObjects,'MsgWaitForMultipleObjects',\ + MsgWaitForMultipleObjectsEx,'MsgWaitForMultipleObjectsEx',\ + NotifyWinEvent,'NotifyWinEvent',\ + OemKeyScan,'OemKeyScan',\ + OemToCharA,'OemToCharA',\ + OemToCharW,'OemToCharW',\ + OemToCharBuffA,'OemToCharBuffA',\ + OemToCharBuffW,'OemToCharBuffW',\ + OffsetRect,'OffsetRect',\ + OpenClipboard,'OpenClipboard',\ + OpenDesktopA,'OpenDesktopA',\ + OpenDesktopW,'OpenDesktopW',\ + OpenIcon,'OpenIcon',\ + OpenInputDesktop,'OpenInputDesktop',\ + OpenWindowStationA,'OpenWindowStationA',\ + OpenWindowStationW,'OpenWindowStationW',\ + PackDDElParam,'PackDDElParam',\ + PaintDesktop,'PaintDesktop',\ + PeekMessageA,'PeekMessageA',\ + PeekMessageW,'PeekMessageW',\ + PostMessageA,'PostMessageA',\ + PostMessageW,'PostMessageW',\ + PostQuitMessage,'PostQuitMessage',\ + PostThreadMessageA,'PostThreadMessageA',\ + PostThreadMessageW,'PostThreadMessageW',\ + PtInRect,'PtInRect',\ + RealChildWindowFromPoint,'RealChildWindowFromPoint',\ + RealGetWindowClassA,'RealGetWindowClassA',\ + RealGetWindowClassW,'RealGetWindowClassW',\ + RedrawWindow,'RedrawWindow',\ + RegisterClassA,'RegisterClassA',\ + RegisterClassW,'RegisterClassW',\ + RegisterClassExA,'RegisterClassExA',\ + RegisterClassExW,'RegisterClassExW',\ + RegisterClipboardFormatA,'RegisterClipboardFormatA',\ + RegisterClipboardFormatW,'RegisterClipboardFormatW',\ + RegisterDeviceNotificationA,'RegisterDeviceNotificationA',\ + RegisterDeviceNotificationW,'RegisterDeviceNotificationW',\ + RegisterHotKey,'RegisterHotKey',\ + RegisterWindowMessageA,'RegisterWindowMessageA',\ + RegisterWindowMessageW,'RegisterWindowMessageW',\ + ReleaseCapture,'ReleaseCapture',\ + ReleaseDC,'ReleaseDC',\ + RemoveMenu,'RemoveMenu',\ + RemovePropA,'RemovePropA',\ + RemovePropW,'RemovePropW',\ + ReplyMessage,'ReplyMessage',\ + ReuseDDElParam,'ReuseDDElParam',\ + ScreenToClient,'ScreenToClient',\ + ScrollChildren,'ScrollChildren',\ + ScrollDC,'ScrollDC',\ + ScrollWindow,'ScrollWindow',\ + ScrollWindowEx,'ScrollWindowEx',\ + SendDlgItemMessageA,'SendDlgItemMessageA',\ + SendDlgItemMessageW,'SendDlgItemMessageW',\ + SendIMEMessageExA,'SendIMEMessageExA',\ + SendIMEMessageExW,'SendIMEMessageExW',\ + SendInput,'SendInput',\ + SendMessageA,'SendMessageA',\ + SendMessageW,'SendMessageW',\ + SendMessageCallbackA,'SendMessageCallbackA',\ + SendMessageCallbackW,'SendMessageCallbackW',\ + SendMessageTimeoutA,'SendMessageTimeoutA',\ + SendMessageTimeoutW,'SendMessageTimeoutW',\ + SendNotifyMessageA,'SendNotifyMessageA',\ + SendNotifyMessageW,'SendNotifyMessageW',\ + SetActiveWindow,'SetActiveWindow',\ + SetCapture,'SetCapture',\ + SetCaretBlinkTime,'SetCaretBlinkTime',\ + SetCaretPos,'SetCaretPos',\ + SetClassLongA,'SetClassLongA',\ + SetClassLongW,'SetClassLongW',\ + SetClassWord,'SetClassWord',\ + SetClipboardData,'SetClipboardData',\ + SetClipboardViewer,'SetClipboardViewer',\ + SetCursor,'SetCursor',\ + SetCursorPos,'SetCursorPos',\ + SetDebugErrorLevel,'SetDebugErrorLevel',\ + SetDeskWallpaper,'SetDeskWallpaper',\ + SetDlgItemInt,'SetDlgItemInt',\ + SetDlgItemTextA,'SetDlgItemTextA',\ + SetDlgItemTextW,'SetDlgItemTextW',\ + SetDoubleClickTime,'SetDoubleClickTime',\ + SetFocus,'SetFocus',\ + SetForegroundWindow,'SetForegroundWindow',\ + SetKeyboardState,'SetKeyboardState',\ + SetLastErrorEx,'SetLastErrorEx',\ + SetLayeredWindowAttributes,'SetLayeredWindowAttributes',\ + SetMenu,'SetMenu',\ + SetMenuContextHelpId,'SetMenuContextHelpId',\ + SetMenuDefaultItem,'SetMenuDefaultItem',\ + SetMenuInfo,'SetMenuInfo',\ + SetMenuItemBitmaps,'SetMenuItemBitmaps',\ + SetMenuItemInfoA,'SetMenuItemInfoA',\ + SetMenuItemInfoW,'SetMenuItemInfoW',\ + SetMessageExtraInfo,'SetMessageExtraInfo',\ + SetMessageQueue,'SetMessageQueue',\ + SetParent,'SetParent',\ + SetProcessWindowStation,'SetProcessWindowStation',\ + SetPropA,'SetPropA',\ + SetPropW,'SetPropW',\ + SetRect,'SetRect',\ + SetRectEmpty,'SetRectEmpty',\ + SetScrollInfo,'SetScrollInfo',\ + SetScrollPos,'SetScrollPos',\ + SetScrollRange,'SetScrollRange',\ + SetShellWindow,'SetShellWindow',\ + SetSysColors,'SetSysColors',\ + SetSystemCursor,'SetSystemCursor',\ + SetSystemMenu,'SetSystemMenu',\ + SetSystemTimer,'SetSystemTimer',\ + SetThreadDesktop,'SetThreadDesktop',\ + SetTimer,'SetTimer',\ + SetUserObjectInformationA,'SetUserObjectInformationA',\ + SetUserObjectInformationW,'SetUserObjectInformationW',\ + SetUserObjectSecurity,'SetUserObjectSecurity',\ + SetWinEventHook,'SetWinEventHook',\ + SetWindowContextHelpId,'SetWindowContextHelpId',\ + SetWindowLongA,'SetWindowLongA',\ + SetWindowLongW,'SetWindowLongW',\ + SetWindowPlacement,'SetWindowPlacement',\ + SetWindowPos,'SetWindowPos',\ + SetWindowRgn,'SetWindowRgn',\ + SetWindowTextA,'SetWindowTextA',\ + SetWindowTextW,'SetWindowTextW',\ + SetWindowWord,'SetWindowWord',\ + SetWindowsHookA,'SetWindowsHookA',\ + SetWindowsHookW,'SetWindowsHookW',\ + SetWindowsHookExA,'SetWindowsHookExA',\ + SetWindowsHookExW,'SetWindowsHookExW',\ + ShowCaret,'ShowCaret',\ + ShowCursor,'ShowCursor',\ + ShowOwnedPopups,'ShowOwnedPopups',\ + ShowScrollBar,'ShowScrollBar',\ + ShowWindow,'ShowWindow',\ + ShowWindowAsync,'ShowWindowAsync',\ + SubtractRect,'SubtractRect',\ + SwapMouseButton,'SwapMouseButton',\ + SwitchDesktop,'SwitchDesktop',\ + SystemParametersInfoA,'SystemParametersInfoA',\ + SystemParametersInfoW,'SystemParametersInfoW',\ + TabbedTextOutA,'TabbedTextOutA',\ + TabbedTextOutW,'TabbedTextOutW',\ + TileChildWindows,'TileChildWindows',\ + TileWindows,'TileWindows',\ + ToAscii,'ToAscii',\ + ToAsciiEx,'ToAsciiEx',\ + ToUnicode,'ToUnicode',\ + ToUnicodeEx,'ToUnicodeEx',\ + TrackMouseEvent,'TrackMouseEvent',\ + TrackPopupMenu,'TrackPopupMenu',\ + TrackPopupMenuEx,'TrackPopupMenuEx',\ + TranslateAcceleratorA,'TranslateAcceleratorA',\ + TranslateAcceleratorW,'TranslateAcceleratorW',\ + TranslateMDISysAccel,'TranslateMDISysAccel',\ + TranslateMessage,'TranslateMessage',\ + UnhookWinEvent,'UnhookWinEvent',\ + UnhookWindowsHook,'UnhookWindowsHook',\ + UnhookWindowsHookEx,'UnhookWindowsHookEx',\ + UnionRect,'UnionRect',\ + UnloadKeyboardLayout,'UnloadKeyboardLayout',\ + UnpackDDElParam,'UnpackDDElParam',\ + UnregisterClassA,'UnregisterClassA',\ + UnregisterClassW,'UnregisterClassW',\ + UnregisterDeviceNotification,'UnregisterDeviceNotification',\ + UnregisterHotKey,'UnregisterHotKey',\ + UpdateWindow,'UpdateWindow',\ + UserHandleGrantAccess,'UserHandleGrantAccess',\ + ValidateRect,'ValidateRect',\ + ValidateRgn,'ValidateRgn',\ + VkKeyScanA,'VkKeyScanA',\ + VkKeyScanW,'VkKeyScanW',\ + VkKeyScanExA,'VkKeyScanExA',\ + VkKeyScanExW,'VkKeyScanExW',\ + WINNLSEnableIME,'WINNLSEnableIME',\ + WINNLSGetEnableStatus,'WINNLSGetEnableStatus',\ + WINNLSGetIMEHotkey,'WINNLSGetIMEHotkey',\ + WaitForInputIdle,'WaitForInputIdle',\ + WaitMessage,'WaitMessage',\ + WinHelpA,'WinHelpA',\ + WinHelpW,'WinHelpW',\ + WindowFromDC,'WindowFromDC',\ + WindowFromPoint,'WindowFromPoint',\ + keybd_event,'keybd_event',\ + mouse_event,'mouse_event',\ + wsprintfA,'wsprintfA',\ + wsprintfW,'wsprintfW',\ + wvsprintfA,'wvsprintfA',\ + wvsprintfW,'wvsprintfW' + +api AppendMenu,\ + BroadcastSystemMessage,\ + CallMsgFilter,\ + CallWindowProc,\ + ChangeDisplaySettings,\ + ChangeDisplaySettingsEx,\ + ChangeMenu,\ + CharLower,\ + CharLowerBuff,\ + CharNext,\ + CharNextEx,\ + CharPrev,\ + CharPrevEx,\ + CharToOem,\ + CharToOemBuff,\ + CharUpper,\ + CharUpperBuff,\ + CopyAcceleratorTable,\ + CreateAcceleratorTable,\ + CreateDesktop,\ + CreateDialogIndirectParam,\ + CreateDialogParam,\ + CreateMDIWindow,\ + CreateWindowEx,\ + CreateWindowStation,\ + DdeCreateStringHandle,\ + DdeInitialize,\ + DdeQueryString,\ + DefDlgProc,\ + DefFrameProc,\ + DefMDIChildProc,\ + DefWindowProc,\ + DialogBoxIndirectParam,\ + DialogBoxParam,\ + DispatchMessage,\ + DlgDirList,\ + DlgDirListComboBox,\ + DlgDirSelectComboBoxEx,\ + DlgDirSelectEx,\ + DrawState,\ + DrawText,\ + DrawTextEx,\ + EnumDesktops,\ + EnumDisplaySettings,\ + EnumDisplaySettingsEx,\ + EnumProps,\ + EnumPropsEx,\ + EnumWindowStations,\ + FindWindow,\ + FindWindowEx,\ + GetAltTabInfo,\ + GetClassInfo,\ + GetClassInfoEx,\ + GetClassLong,\ + GetClassName,\ + GetClipboardFormatName,\ + GetClipboardSequenceNumber,\ + GetDlgItemText,\ + GetKeyNameText,\ + GetKeyboardLayoutName,\ + GetMenuItemInfo,\ + GetMenuString,\ + GetMessage,\ + GetMonitorInfo,\ + GetProp,\ + GetTabbedTextExtent,\ + GetUserObjectInformation,\ + GetWindowLong,\ + GetWindowModuleFileName,\ + GetWindowText,\ + GetWindowTextLength,\ + GrayString,\ + IMPGetIME,\ + IMPQueryIME,\ + IMPSetIME,\ + InsertMenu,\ + InsertMenuItem,\ + IsCharAlpha,\ + IsCharAlphaNumeric,\ + IsCharLower,\ + IsCharUpper,\ + IsDialogMessage,\ + LoadAccelerators,\ + LoadBitmap,\ + LoadCursor,\ + LoadCursorFromFile,\ + LoadIcon,\ + LoadImage,\ + LoadKeyboardLayout,\ + LoadMenu,\ + LoadMenuIndirect,\ + LoadString,\ + MapVirtualKey,\ + MapVirtualKeyEx,\ + MessageBox,\ + MessageBoxEx,\ + MessageBoxIndirect,\ + ModifyMenu,\ + OemToChar,\ + OemToCharBuff,\ + OpenDesktop,\ + OpenWindowStation,\ + PeekMessage,\ + PostMessage,\ + PostThreadMessage,\ + RealGetWindowClass,\ + RegisterClass,\ + RegisterClassEx,\ + RegisterClipboardFormat,\ + RegisterDeviceNotification,\ + RegisterWindowMessage,\ + RemoveProp,\ + SendDlgItemMessage,\ + SendIMEMessageEx,\ + SendMessage,\ + SendMessageCallback,\ + SendMessageTimeout,\ + SendNotifyMessage,\ + SetClassLong,\ + SetDlgItemText,\ + SetMenuItemInfo,\ + SetProp,\ + SetUserObjectInformation,\ + SetWindowLong,\ + SetWindowText,\ + SetWindowsHook,\ + SetWindowsHookEx,\ + SystemParametersInfo,\ + TabbedTextOut,\ + TranslateAccelerator,\ + UnregisterClass,\ + VkKeyScan,\ + VkKeyScanEx,\ + WinHelp,\ + wsprintf,\ + wvsprintf diff --git a/toolchain/fasmw17332/INCLUDE/API/WSOCK32.INC b/toolchain/fasmw17332/INCLUDE/API/WSOCK32.INC new file mode 100644 index 0000000..8b8edb6 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/API/WSOCK32.INC @@ -0,0 +1,85 @@ + +; WSOCK32 API calls + +import wsock32,\ + AcceptEx,'AcceptEx',\ + EnumProtocolsA,'EnumProtocolsA',\ + EnumProtocolsW,'EnumProtocolsW',\ + GetAcceptExSockaddrs,'GetAcceptExSockaddrs',\ + GetAddressByNameA,'GetAddressByNameA',\ + GetAddressByNameW,'GetAddressByNameW',\ + GetNameByTypeA,'GetNameByTypeA',\ + GetNameByTypeW,'GetNameByTypeW',\ + GetServiceA,'GetServiceA',\ + GetServiceW,'GetServiceW',\ + GetTypeByNameA,'GetTypeByNameA',\ + GetTypeByNameW,'GetTypeByNameW',\ + MigrateWinsockConfiguration,'MigrateWinsockConfiguration',\ + NPLoadNameSpaces,'NPLoadNameSpaces',\ + SetServiceA,'SetServiceA',\ + SetServiceW,'SetServiceW',\ + TransmitFile,'TransmitFile',\ + WEP,'WEP',\ + WSAAsyncGetHostByAddr,'WSAAsyncGetHostByAddr',\ + WSAAsyncGetHostByName,'WSAAsyncGetHostByName',\ + WSAAsyncGetProtoByName,'WSAAsyncGetProtoByName',\ + WSAAsyncGetProtoByNumber,'WSAAsyncGetProtoByNumber',\ + WSAAsyncGetServByName,'WSAAsyncGetServByName',\ + WSAAsyncGetServByPort,'WSAAsyncGetServByPort',\ + WSAAsyncSelect,'WSAAsyncSelect',\ + WSACancelAsyncRequest,'WSACancelAsyncRequest',\ + WSACancelBlockingCall,'WSACancelBlockingCall',\ + WSACleanup,'WSACleanup',\ + WSAGetLastError,'WSAGetLastError',\ + WSAIsBlocking,'WSAIsBlocking',\ + WSARecvEx,'WSARecvEx',\ + WSASetBlockingHook,'WSASetBlockingHook',\ + WSASetLastError,'WSASetLastError',\ + WSAStartup,'WSAStartup',\ + WSAUnhookBlockingHook,'WSAUnhookBlockingHook',\ + __WSAFDIsSet,'__WSAFDIsSet',\ + accept,'accept',\ + bind,'bind',\ + closesocket,'closesocket',\ + connect,'connect',\ + dn_expand,'dn_expand',\ + gethostbyaddr,'gethostbyaddr',\ + gethostbyname,'gethostbyname',\ + gethostname,'gethostname',\ + getnetbyname,'getnetbyname',\ + getpeername,'getpeername',\ + getprotobyname,'getprotobyname',\ + getprotobynumber,'getprotobynumber',\ + getservbyname,'getservbyname',\ + getservbyport,'getservbyport',\ + getsockname,'getsockname',\ + getsockopt,'getsockopt',\ + htonl,'htonl',\ + htons,'htons',\ + inet_addr,'inet_addr',\ + inet_network,'inet_network',\ + inet_ntoa,'inet_ntoa',\ + ioctlsocket,'ioctlsocket',\ + listen,'listen',\ + ntohl,'ntohl',\ + ntohs,'ntohs',\ + rcmd,'rcmd',\ + recv,'recv',\ + recvfrom,'recvfrom',\ + rexec,'rexec',\ + rresvport,'rresvport',\ + s_perror,'s_perror',\ + select,'select',\ + send,'send',\ + sendto,'sendto',\ + sethostname,'sethostname',\ + setsockopt,'setsockopt',\ + shutdown,'shutdown',\ + socket,'socket' + +api EnumProtocols,\ + GetAddressByName,\ + GetNameByType,\ + GetService,\ + GetTypeByName,\ + SetService diff --git a/toolchain/fasmw17332/INCLUDE/ENCODING/UTF8.INC b/toolchain/fasmw17332/INCLUDE/ENCODING/UTF8.INC new file mode 100644 index 0000000..83383ff --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/ENCODING/UTF8.INC @@ -0,0 +1,77 @@ + +; UTF-8 + +macro du [arg] + { local current,..input,char + if arg eqtype '' + virtual at 0 + ..input:: + db arg + count = $ + end virtual + current = 0 + while current < count + load char byte from ..input:current + wide = char + current = current + 1 + if char > 0C0h + if char < 0E0h + wide = char and 11111b + load char byte from ..input:current + wide = wide shl 6 + (char and 111111b) + current = current + 1 + else if char < 0F0h + wide = char and 1111b + load char byte from ..input:current + wide = wide shl 6 + (char and 111111b) + load char byte from ..input:current+1 + wide = wide shl 6 + (char and 111111b) + current = current + 2 + else if char < 0F8h + wide = char and 111b + load char byte from ..input:current + wide = wide shl 6 + (char and 111111b) + load char byte from ..input:current+1 + wide = wide shl 6 + (char and 111111b) + load char byte from ..input:current+2 + wide = wide shl 6 + (char and 111111b) + current = current + 3 + else if char < 0FCh + wide = char and 11b + load char byte from ..input:current + wide = wide shl 6 + (char and 111111b) + load char byte from ..input:current+1 + wide = wide shl 6 + (char and 111111b) + load char byte from ..input:current+2 + wide = wide shl 6 + (char and 111111b) + load char byte from ..input:current+3 + wide = wide shl 6 + (char and 111111b) + current = current + 4 + else + wide = char and 1 + load char byte from ..input:current + wide = wide shl 6 + (char and 111111b) + load char byte from ..input:current+1 + wide = wide shl 6 + (char and 111111b) + load char byte from ..input:current+2 + wide = wide shl 6 + (char and 111111b) + load char byte from ..input:current+3 + wide = wide shl 6 + (char and 111111b) + load char byte from ..input:current+4 + wide = wide shl 6 + (char and 111111b) + current = current + 5 + end if + end if + if wide < 10000h + dw wide + else + dw 0D7C0h + wide shr 10,0DC00h or (wide and 3FFh) + end if + end while + else + dw arg + end if } + +struc du [args] + { common label . word + du args } diff --git a/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1250.INC b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1250.INC new file mode 100644 index 0000000..afd2b6d --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1250.INC @@ -0,0 +1,36 @@ + +; Windows 1250 + +rept 1 { local ..encoding + __encoding equ ..encoding } + +virtual at 0 + __encoding:: + times 80h dw %-1 + dw 20ACh,?,201Ah,?,201Eh,2026h,2020h,2021h,?,2030h,160h,2039h,15Ah,164h,17Dh,179h + dw ?,2018h,2019h,201Ch,201Dh,2022h,2013h,2014h,?,2122h,161h,203Ah,15Bh,165h,17Eh,17Ah + dw 0A0h,2C7h,2D8h,141h,0A4h,104h,0A6h,0A7h,0A8h,0A9h,15Eh,0ABh,0ACh,0ADh,0AEh,17Bh + dw 0B0h,0B1h,2DBh,142h,0B4h,0B5h,0B6h,0B7h,0B8h,105h,15Fh,0BBh,13Dh,2DDh,13Eh,17Ch + dw 154h,0C1h,0C2h,102h,0C4h,139h,106h,0C7h,10Ch,0C9h,118h,0CBh,11Ah,0CDh,0CEh,10Eh + dw 110h,143h,147h,0D3h,0D4h,150h,0D6h,0D7h,158h,16Eh,0DAh,170h,0DCh,0DDh,162h,0DFh + dw 155h,0E1h,0E2h,103h,0E4h,13Ah,107h,0E7h,10Dh,0E9h,119h,0EBh,11Bh,0EDh,0EEh,10Fh + dw 111h,144h,148h,0F3h,0F4h,151h,0F6h,0F7h,159h,16Fh,0FAh,171h,0FCh,0FDh,163h,2D9h +end virtual + +macro du [arg] + { local offset,char + offset = $-$$ + du arg + if arg eqtype '' + repeat ($-offset-$$)/2 + load char byte from $$+offset+(%-1)*2 + if char > 7Fh + load char word from __encoding:char*2 + store word char at $$+offset+(%-1)*2 + end if + end repeat + end if } + +struc du [args] + { common label . word + du args } diff --git a/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1251.INC b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1251.INC new file mode 100644 index 0000000..ce6766a --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1251.INC @@ -0,0 +1,33 @@ + +; Windows 1251 + +rept 1 { local ..encoding + __encoding equ ..encoding } + +virtual at 0 + __encoding:: + times 80h dw %-1 + dw 401h,403h,201Ah,453h,201Eh,2026h,2020h,2021h,20ACh,2030h,409h,2039h,40Ah,40Ch,40Bh,40Fh + dw 452h,2018h,2019h,201Ch,201Dh,2022h,2013h,2014h,?,2122h,459h,203Ah,45Ah,45Ch,45Bh,45Fh + dw 0A0h,40Eh,45Eh,408h,0A4h,490h,0A6h,0A7h,401h,0A9h,404h,0ABh,0ACh,0ADh,0AEh,407h + dw 0B0h,0B1h,406h,456h,491h,0B5h,0B6h,0B7h,451h,2116h,454h,0BBh,458h,405h,455h,457h + times 40h dw 410h+%-1 +end virtual + +macro du [arg] + { local offset,char + offset = $-$$ + du arg + if arg eqtype '' + repeat ($-offset-$$)/2 + load char byte from $$+offset+(%-1)*2 + if char > 7Fh + load char word from __encoding:char*2 + store word char at $$+offset+(%-1)*2 + end if + end repeat + end if } + +struc du [args] + { common label . word + du args } diff --git a/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1252.INC b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1252.INC new file mode 100644 index 0000000..09227f9 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1252.INC @@ -0,0 +1,31 @@ + +; Windows 1252 + +rept 1 { local ..encoding + __encoding equ ..encoding } + +virtual at 0 + __encoding:: + times 80h dw %-1 + dw 20ACh,?,201Ah,192h,201Eh,2026h,2020h,2021h,2C6h,2030h,160h,2039h,152h,?,17D,? + dw ?,2018h,2019h,201Ch,201Dh,2022h,2013h,2014h,2DCh,2122h,161h,203Ah,153h,?,17Eh,178h + times 60h dw 0A0h+%-1 +end virtual + +macro du [arg] + { local offset,char + offset = $-$$ + du arg + if arg eqtype '' + repeat ($-offset-$$)/2 + load char byte from $$+offset+(%-1)*2 + if char > 7Fh + load char word from __encoding:char*2 + store word char at $$+offset+(%-1)*2 + end if + end repeat + end if } + +struc du [args] + { common label . word + du args } diff --git a/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1253.INC b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1253.INC new file mode 100644 index 0000000..8ae3c37 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1253.INC @@ -0,0 +1,33 @@ + +; Windows 1253 + +rept 1 { local ..encoding + __encoding equ ..encoding } + +virtual at 0 + __encoding:: + times 80h dw %-1 + dw 20ACh,?,201Ah,192h,201Eh,2026h,2020h,2021h,?,2030h,?,2039h,?,?,?,? + dw ?,2018h,2019h,201Ch,201Dh,2022h,2013h,2014h,?,2122h,?,203Ah,?,?,?,? + dw 0A0h,385h,386h,0A3h,0A4h,0A5h,0A6h,0A7h,0A8h,0A9h,?,0ABh,0ACh,0ADh,0AEh,2015h + dw 0B0h,0B1h,0B2h,0B3h,384h,0B5h,0B6h,0B7h,288h,389h,38Ah,0BBh,38Ch,0BDh,38Eh,38Fh + times 40h dw 390h+%-1 +end virtual + +macro du [arg] + { local offset,char + offset = $-$$ + du arg + if arg eqtype '' + repeat ($-offset-$$)/2 + load char byte from $$+offset+(%-1)*2 + if char > 7Fh + load char word from __encoding:char*2 + store word char at $$+offset+(%-1)*2 + end if + end repeat + end if } + +struc du [args] + { common label . word + du args } diff --git a/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1254.INC b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1254.INC new file mode 100644 index 0000000..f4fd06c --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1254.INC @@ -0,0 +1,34 @@ + +; Windows 1254 + +rept 1 { local ..encoding + __encoding equ ..encoding } + +virtual at 0 + __encoding:: + times 80h dw %-1 + dw 20ACh,?,201Ah,192h,201Eh,2026h,2020h,2021h,2C6h,2030h,160h,2039h,152h,?,?,? + dw ?,2018h,2019h,201Ch,201Dh,2022h,2013h,2014h,2DCh,2122h,161h,203Ah,153h,?,?,178h + times 30h dw 0A0h+%-1 + dw 11Eh,0D1h,0D2h,0D3h,0D4h,0D5h,0D6h,0D7h,0D8h,0D9h,0DAh,0DBh,0DCh,130h,15Eh,0DFh + times 10h dw 0E0h+%-1 + dw 11Fh,0F1h,0F2h,0F3h,0F4h,0F5h,0F6h,0F7h,0F8h,0F9h,0FAh,0FBh,0FCh,131h,15Fh,0FFh +end virtual + +macro du [arg] + { local offset,char + offset = $-$$ + du arg + if arg eqtype '' + repeat ($-offset-$$)/2 + load char byte from $$+offset+(%-1)*2 + if char > 7Fh + load char word from __encoding:char*2 + store word char at $$+offset+(%-1)*2 + end if + end repeat + end if } + +struc du [args] + { common label . word + du args } diff --git a/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1255.INC b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1255.INC new file mode 100644 index 0000000..16bcdcd --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1255.INC @@ -0,0 +1,36 @@ + +; Windows 1255 + +rept 1 { local ..encoding + __encoding equ ..encoding } + +virtual at 0 + __encoding:: + times 80h dw %-1 + dw 20ACh,?,201Ah,192h,201Eh,2026h,2020h,2021h,2C6h,2030h,?,2039h,?,?,?,? + dw ?,2018h,2019h,201Ch,201Dh,2022h,2013h,2014h,2DCh,2122h,?,203Ah,?,?,?,? + dw 0A0h,0A1h,0A2h,0A3h,20AAh,0A5h,0A6h,0A7h,0A8h,0A9h,0D7h,0ABh,0ACh,0ADh,0AEh,0AFh + dw 0B0h,0B1h,0B2h,0B3h,0B4h,0B5h,0B6h,0B7h,0B8h,0B9h,0F7h,0BBh,0BCh,0BDh,0BEh,0BFh + dw 5B0h,5B1h,5B2h,5B3h,5B4h,5B5h,5B6h,5B7h,5B8h,5B9h,?,5BBh,5BCh,5BDh,5BEh,5BFh + dw 5C0h,5C1h,5C2h,5C3h,5F0h,5F1h,5F2h,5F3h,5F4h,?,?,?,?,?,?,? + dw 5D0h,5D1h,5D2h,5D3h,5D4h,5D5h,5D6h,5D7h,5D8h,5D9h,5DAh,5DBh,5DCh,5DDh,5DEh,5DFh + dw 5E0h,5E1h,5E2h,5E3h,5E4h,5E5h,5E6h,5E7h,5E8h,5E9h,5EAh,?,?,200Eh,200Fh,? +end virtual + +macro du [arg] + { local offset,char + offset = $-$$ + du arg + if arg eqtype '' + repeat ($-offset-$$)/2 + load char byte from $$+offset+(%-1)*2 + if char > 7Fh + load char word from __encoding:char*2 + store word char at $$+offset+(%-1)*2 + end if + end repeat + end if } + +struc du [args] + { common label . word + du args } diff --git a/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1256.INC b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1256.INC new file mode 100644 index 0000000..57d1738 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1256.INC @@ -0,0 +1,36 @@ + +; Windows 1256 + +rept 1 { local ..encoding + __encoding equ ..encoding } + +virtual at 0 + __encoding:: + times 80h dw %-1 + dw 20ACh,67Eh,201Ah,192h,201Eh,2026h,2020h,2021h,2C6h,2030h,679h,2039h,152h,686h,698h,688h + dw 6AFh,2018h,2019h,201Ch,201Dh,2022h,2013h,2014h,6A9h,2122h,691h,203Ah,153h,200Ch,200Dh,6BAh + dw 0A0h,60Ch,0A2h,0A3h,0A4h,0A5h,0A6h,0A7h,0A8h,0A9h,6BEh,0ABh,0ACh,0ADh,0AEh,0AFh + dw 0B0h,0B1h,0B2h,0B3h,0B4h,0B5h,0B6h,0B7h,0B8h,0B9h,0BAh,0BBh,0BCh,0BDh,0BEh,0BFh + dw 6C1h,621h,622h,623h,624h,625h,626h,627h,628h,629h,62Ah,62Bh,62Ch,62Dh,62Eh,62Fh + dw 630h,631h,632h,633h,634h,635h,636h,0D7h,637h,638h,639h,63Ah,640h,641h,642h,643h + dw 0E0h,644h,0E2h,645h,646h,647h,648h,0E7h,0E8h,0E9h,0EAh,0EBh,649h,64Ah,0EEh,0EFh + dw 64Bh,64Ch,64Dh,64Eh,0F4h,64Fh,650h,0F7h,651h,0F9h,652h,0FBh,0FCh,200Eh,200Fh,6D2h +end virtual + +macro du [arg] + { local offset,char + offset = $-$$ + du arg + if arg eqtype '' + repeat ($-offset-$$)/2 + load char byte from $$+offset+(%-1)*2 + if char > 7Fh + load char word from __encoding:char*2 + store word char at $$+offset+(%-1)*2 + end if + end repeat + end if } + +struc du [args] + { common label . word + du args } diff --git a/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1257.INC b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1257.INC new file mode 100644 index 0000000..c1bc4f9 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1257.INC @@ -0,0 +1,36 @@ + +; Windows 1257 + +rept 1 { local ..encoding + __encoding equ ..encoding } + +virtual at 0 + __encoding:: + times 80h dw %-1 + dw 20ACh,?,201Ah,?,201Eh,2026h,2020h,2021h,?,2030h,?,2039h,?,0A8h,2C7h,0B8h + dw ?,2018h,2019h,201Ch,201Dh,2022h,2013h,2014h,?,2122h,?,203Ah,?,0AFh,2DBh,? + dw 0A0h,?,0A2h,0A3h,0A4h,?,0A6h,0A7h,0D8h,0A9h,156h,0ABh,0ACh,0ADh,0AEh,0C6h + dw 0B0h,0B1h,0B2h,0B3h,0B4h,0B5h,0B6h,0B7h,0F8h,0B9h,157h,0BBh,0BCh,0BDh,0BEh,0E6h + dw 104h,12Eh,100h,106h,0C4h,0C5h,118h,112h,10Ch,0C9h,179h,116h,122h,136h,12Ah,13Bh + dw 160h,143h,145h,0D3h,14Ch,0D5h,0D6h,0D7h,172h,141h,15Ah,16Ah,0DCh,17Bh,17Dh,0DFh + dw 105h,12Fh,101h,107h,0E4h,0E5h,119h,113h,10Dh,0E9h,17Ah,117h,123h,137h,12Bh,13Ch + dw 161h,144h,146h,0F3h,14Dh,0F5h,0F6h,0F7h,173h,142h,15Bh,16Bh,0FCh,17Ch,17Eh,2D9h +end virtual + +macro du [arg] + { local offset,char + offset = $-$$ + du arg + if arg eqtype '' + repeat ($-offset-$$)/2 + load char byte from $$+offset+(%-1)*2 + if char > 7Fh + load char word from __encoding:char*2 + store word char at $$+offset+(%-1)*2 + end if + end repeat + end if } + +struc du [args] + { common label . word + du args } diff --git a/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1258.INC b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1258.INC new file mode 100644 index 0000000..c9fdb30 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN1258.INC @@ -0,0 +1,36 @@ + +; Windows 1258 + +rept 1 { local ..encoding + __encoding equ ..encoding } + +virtual at 0 + __encoding:: + times 80h dw %-1 + dw 20ACh,?,201Ah,192h,201Eh,2026h,2020h,2021h,2C6h,2030h,?,2039h,152h,?,?,? + dw ?,2018h,2019h,201Ch,201Dh,2022h,2013h,2014h,2DCh,2122h,?,203Ah,153h,?,?,178h + dw 0A0h,0A1h,0A2h,0A3h,0A4h,0A5h,0A6h,0A7h,0A8h,0A9h,0AAh,0ABh,0ACh,0ADh,0AEh,0AFh + dw 0B0h,0B1h,0B2h,0B3h,0B4h,0B5h,0B6h,0B7h,0B8h,0B9h,0BAh,0BBh,0BCh,0BDh,0BEh,0BFh + dw 0C0h,0C1h,0C2h,102h,0C4h,0C5h,0C6h,0C7h,0C8h,0C9h,0CAh,0CBh,300h,0CDh,0CEh,0CFh + dw 110h,0D1h,309h,0D3h,0D4h,1A0h,0D6h,0D7h,0D8h,0D9h,0DAh,0DBh,0DCh,1AFh,303h,0DFh + dw 0E0h,0E1h,0E2h,103h,0E4h,0E5h,0E6h,0E7h,0E8h,0E9h,0EAh,0EBh,301h,0EDh,0EEh,0EFh + dw 111h,0F1h,323h,0F3h,0F4h,1A1h,0F6h,0F7h,0F8h,0F9h,0FAh,0FBh,0FCh,1B0h,20ABh,0FFh +end virtual + +macro du [arg] + { local offset,char + offset = $-$$ + du arg + if arg eqtype '' + repeat ($-offset-$$)/2 + load char byte from $$+offset+(%-1)*2 + if char > 7Fh + load char word from __encoding:char*2 + store word char at $$+offset+(%-1)*2 + end if + end repeat + end if } + +struc du [args] + { common label . word + du args } diff --git a/toolchain/fasmw17332/INCLUDE/ENCODING/WIN874.INC b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN874.INC new file mode 100644 index 0000000..a6c5845 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/ENCODING/WIN874.INC @@ -0,0 +1,31 @@ + +; Windows 874 + +rept 1 { local ..encoding + __encoding equ ..encoding } + +virtual at 0 + __encoding:: + times 80h dw %-1 + dw 20ACh,?,?,?,?,2026h,?,?,?,?,?,?,?,?,?,? + dw ?,2018h,2019h,201Ch,201Dh,2022h,2013h,2014h,?,?,?,?,?,?,?,? + times 60h dw 0E00h+%-1 +end virtual + +macro du [arg] + { local offset,char + offset = $-$$ + du arg + if arg eqtype '' + repeat ($-offset-$$)/2 + load char byte from $$+offset+(%-1)*2 + if char > 7Fh + load char word from __encoding:char*2 + store word char at $$+offset+(%-1)*2 + end if + end repeat + end if } + +struc du [args] + { common label . word + du args } diff --git a/toolchain/fasmw17332/INCLUDE/EQUATES/COMCTL32.INC b/toolchain/fasmw17332/INCLUDE/EQUATES/COMCTL32.INC new file mode 100644 index 0000000..e1b9dda --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/EQUATES/COMCTL32.INC @@ -0,0 +1,1869 @@ + +; COMCTL32.DLL structures and constants + +struct PROPSHEETPAGE + dwSize dd ? + dwFlags dd ? + hInstance dd ? + pszTemplate dd ? + pszIcon dd ? + pszTitle dd ? + pfnDlgProc dd ? + lParam dd ? + pfnCallback dd ? + pcRefParent dd ? +ends + +struct PROPSHEETHEADER + dwSize dd ? + dwFlags dd ? + hwndParent dd ? + hInstance dd ? + pszIcon dd ? + pszCaption dd ? + nPages dd ? + pStartPage dd ? + ppsp dd ? + pfnCallback dd ? +ends + +struct IMAGEINFO + hbmImage dd ? + hbmMask dd ? + Unused1 dd ? + Unused2 dd ? + rcImage RECT +ends + +struct HD_ITEM + mask dd ? + cxy dd ? + pszText dd ? + hbm dd ? + cchTextMax dd ? + fmt dd ? + lParam dd ? +ends + +struct HD_LAYOUT + prc dd ? + pwpos dd ? +ends + +struct HD_HITTESTINFO + pt POINT + flags dd ? + iItem dd ? +ends + +struct HD_NOTIFY + hdr NMHDR + iItem dd ? + iButton dd ? + pitem dd ? +ends + +struct TBBUTTON + iBitmap dd ? + idCommand dd ? + fsState db ? + fsStyle db ? + dw ? + dwData dd ? + iString dd ? +ends + +struct COLORMAP + from dd ? + to dd ? +ends + +struct TBADDBITMAP + hInst dd ? + nID dd ? +ends + +struct TBSAVEPARAMS + hkr dd ? + pszSubKey dd ? + pszValueName dd ? +ends + +struct TBREPLACEBITMAP + hInstOld dd ? + nIDOld dd ? + hInstNew dd ? + nIDNew dd ? + nButtons dd ? +ends + +struct NMTOOLBAR + hdr NMHDR + iItem dd ? + tbButton TBBUTTON + cchText dd ? + pszText dd ? +ends + +struct REBARINFO + cbSize dd ? + fMask dd ? + himl dd ? +ends + +struct REBARBANDINFO + cbSize dd ? + fMask dd ? + fStyle dd ? + clrFore dd ? + clrBack dd ? + lpText dd ? + cch dd ? + iImage dd ? + hwndChild dd ? + cxMinChild dd ? + cyMinChild dd ? + cx dd ? + hbmBack dd ? + wID dd ? +ends + +struct TOOLINFO + cbSize dd ? + uFlags dd ? + hwnd dd ? + uId dd ? + rect RECT + hInst dd ? + lpszText dd ? +ends + +struct TTHITTESTINFO + hwnd dd ? + pt POINT + ti TOOLINFO +ends + +struct TOOLTIPTEXT + hdr NMHDR + lpszText dd ? + szText db 80 dup (?) + hinst dd ? + uFlags dd ? +ends + +struct UDACCEL + nSec dd ? + nInc dd ? +ends + +struct NM_UPDOWN + hdr NMHDR + iPos dd ? + iDelta dd ? +ends + +struct LV_ITEM + mask dd ? + iItem dd ? + iSubItem dd ? + state dd ? + stateMask dd ? + pszText dd ? + cchTextMax dd ? + iImage dd ? + lParam dd ? + iIndent dd ? +ends + +struct LV_FINDINFO + flags dd ? + psz dd ? + lParam dd ? + pt POINT + vkDirection dd ? +ends + +struct LV_HITTESTINFO + pt POINT + flags dd ? + iItem dd ? +ends + +struct LV_COLUMN + mask dd ? + fmt dd ? + cx dd ? + pszText dd ? + cchTextMax dd ? + iSubItem dd ? +ends + +struct NM_LISTVIEW + hdr NMHDR + iItem dd ? + iSubItem dd ? + uNewState dd ? + uOldState dd ? + uChanged dd ? + ptAction POINT + lParam dd ? +ends + +struct NM_CACHEHINT + hdr NMHDR + iFrom dd ? + iTo dd ? +ends + +struct NM_FINDITEM + hdr NMHDR + iStart dd ? + lvfi LV_FINDINFO +ends + +struct LV_DISPINFO + hdr NMHDR + item LV_ITEM +ends + +struct LV_KEYDOWN + hdr NMHDR + wVKey dw ? + flags dd ? +ends + +struct TV_ITEM + mask dd ? + hItem dd ? + state dd ? + stateMask dd ? + pszText dd ? + cchTextMax dd ? + iImage dd ? + iSelectedImage dd ? + cChildren dd ? + lParam dd ? +ends + +struct TV_INSERTSTRUCT + hParent dd ? + hInsertAfter dd ? + item TV_ITEM +ends + +struct TV_HITTESTINFO + pt POINT + flags dd ? + hItem dd ? +ends + +struct TV_SORTCB + hParent dd ? + lpfnCompare dd ? + lParam dd ? +ends + +struct NM_TREEVIEW + hdr NMHDR + action dd ? + itemOld TV_ITEM + itemNew TV_ITEM + ptDrag POINT +ends + +struct TV_DISPINFO + hdr NMHDR + item TV_ITEM +ends + +struct TV_KEYDOWN + hdr NMHDR + wVKey dw ? + flags dd ? +ends + +struct TC_ITEMHEADER + mask dd ? + lpReserved1 dd ? + lpReserved2 dd ? + pszText dd ? + cchTextMax dd ? + iImage dd ? +ends + +struct TC_ITEM + mask dd ? + lpReserved1 dd ? + lpReserved2 dd ? + pszText dd ? + cchTextMax dd ? + iImage dd ? + lParam dd ? +ends + +struct TC_HITTESTINFO + pt POINT + flags dd ? +ends + +struct TC_KEYDOWN + hdr NMHDR + wVKey dw ? + flags dd ? +ends + +struct MC_HITTESTINFO + cbSize dd ? + pt POINT + uHit dd ? + st SYSTEMTIME +ends + +struct NM_SELCHANGE + nmhdr NMHDR + stSelStart SYSTEMTIME + stSelEnd SYSTEMTIME +ends + +struct NM_DAYSTATE + nmhdr NMHDR + stStart SYSTEMTIME + cDayState dd ? + prgDayState dd ? +ends + +struct NM_DATETIMECHANGE + nmhdr NMHDR + dwFlags dd ? + st SYSTEMTIME +ends + +struct NM_DATETIMESTRING + nmhdr NMHDR + pszUserString dd ? + st SYSTEMTIME + dwFlags dd ? +ends + +struct NM_DATETIMEWMKEYDOWN + nmhdr NMHDR + nVirtKey dd ? + pszFormat dd ? + st SYSTEMTIME +ends + +struct NM_DATETIMEFORMAT + nmhdr NMHDR + pszFormat dd ? + st SYSTEMTIME + pszDisplay dd ? + szDisplay db 64 dup (?) +ends + +struct NM_DATETIMEFORMATQUERY + nmhdr NMHDR + pszFormat dd ? + szMax SIZE +ends + +struct INITCOMMONCONTROLSEX + dwSize dd ? + dwICC dd ? +ends + +; Common control window classes + +HOTKEY_CLASS equ 'msctls_hotkey32' +PROGRESS_CLASS equ 'msctls_progress32' +STATUS_CLASS equ 'msctls_statusbar32' +TRACKBAR_CLASS equ 'msctls_trackbar32' +UPDOWN_CLASS equ 'msctls_updown32' +TOOLTIPS_CLASS equ 'tooltips_class32' +ANIMATE_CLASS equ 'SysAnimate32' +HEADER_CLASS equ 'SysHeader32' +LISTVIEW_CLASS equ 'SysListView32' +TREEVIEW_CLASS equ 'SysTreeView32' +TABCONTROL_CLASS equ 'SysTabControl32' +MONTHCAL_CLASS equ 'SysMonthCal32' +DATETIMEPICK_CLASS equ 'SysDateTimePick32' +TOOLBAR_CLASS equ 'ToolbarWindow32' +REBAR_CLASS equ 'ReBarWindow32' + +; Ranges for control message IDs + +LVM_FIRST = 1000h +TV_FIRST = 1100h +HDM_FIRST = 1200h +TCM_FIRST = 1300h +MCM_FIRST = 1000h +DTM_FIRST = 1000h +CCM_FIRST = 2000h + +; Ranges for control notification IDs + +NM_FIRST = 0 +LVN_FIRST = -100 +PSN_FIRST = -200 +HDN_FIRST = -300 +TVN_FIRST = -400 +TTN_FIRST = -520 +TCN_FIRST = -550 +CDN_FIRST = -601 +TBN_FIRST = -700 +UDN_FIRST = -721 +MCN_FIRST = -750 +DTN_FIRST = -760 +CBEN_FIRST = -800 +RBN_FIRST = -831 + +; Generic notifications + +NM_OUTOFMEMORY = NM_FIRST - 1 +NM_CLICK = NM_FIRST - 2 +NM_DBLCLK = NM_FIRST - 3 +NM_RETURN = NM_FIRST - 4 +NM_RCLICK = NM_FIRST - 5 +NM_RDBLCLK = NM_FIRST - 6 +NM_SETFOCUS = NM_FIRST - 7 +NM_KILLFOCUS = NM_FIRST - 8 +NM_CUSTOMDRAW = NM_FIRST - 12 + +; Common control styles + +CCS_TOP = 01h +CCS_NOMOVEY = 02h +CCS_BOTTOM = 03h +CCS_NORESIZE = 04h +CCS_NOPARENTALIGN = 08h +CCS_ADJUSTABLE = 20h +CCS_NODIVIDER = 40h +CCS_VERT = 80h +CCS_LEFT = CCS_VERT or CCS_TOP +CCS_RIGHT = CCS_VERT or CCS_BOTTOM +CCS_NOMOVEX = CCS_VERT or CCS_NOMOVEY + +; Owner-drawn control types + +ODT_HEADER = 100 +ODT_TAB = 101 +ODT_LISTVIEW = 102 + +; InitCommonControlsEx classes + +ICC_ANIMATE_CLASS = 0080h +ICC_BAR_CLASSES = 0004h +ICC_COOL_CLASSES = 0400h +ICC_DATE_CLASSES = 0100h +ICC_HOTKEY_CLASS = 0040h +ICC_INTERNET_CLASSES = 0800h +ICC_LISTVIEW_CLASSES = 0001h +ICC_PAGESCROLLER_CLASS = 1000h +ICC_PROGRESS_CLASS = 0020h +ICC_TAB_CLASSES = 0008h +ICC_TREEVIEW_CLASSES = 0002h +ICC_UPDOWN_CLASS = 0010h +ICC_USEREX_CLASSES = 0200h +ICC_WIN95_CLASSES = 00FFh + +; Shared messages + +CCM_SETCOLORSCHEME = CCM_FIRST + 2 +CCM_GETCOLORSCHEME = CCM_FIRST + 3 +CCM_GETDROPTARGET = CCM_FIRST + 4 +CCM_SETUNICODEFORMAT = CCM_FIRST + 5 +CCM_GETUNICODEFORMAT = CCM_FIRST + 6 + +; Property sheet page flags + +PSP_DEFAULT = 0000h +PSP_DLGINDIRECT = 0001h +PSP_USEHICON = 0002h +PSP_USEICONID = 0004h +PSP_USETITLE = 0008h +PSP_HASHELP = 0020h +PSP_USEREFPARENT = 0040h +PSP_USECALLBACK = 0080h + +; Property sheet page actions + +PSPCB_RELEASE = 1 +PSPCB_CREATE = 2 + +; Property sheet header flags + +PSH_DEFAULT = 0000h +PSH_PROPTITLE = 0001h +PSH_USEHICON = 0002h +PSH_USEICONID = 0004h +PSH_PROPSHEETPAGE = 0008h +PSH_MULTILINETABS = 0010h +PSH_WIZARD = 0020h +PSH_USEPSTARTPAGE = 0040h +PSH_NOAPPLYNOW = 0080h +PSH_USECALLBACK = 0100h +PSH_HASHELP = 0200h +PSH_MODELESS = 0400h + +; Property sheet actions + +PSCB_INITIALIZED = 1 + +; Property sheet notifications + +PSN_SETACTIVE = PSN_FIRST - 0 +PSN_KILLACTIVE = PSN_FIRST - 1 +PSN_APPLY = PSN_FIRST - 2 +PSN_RESET = PSN_FIRST - 3 +PSN_HELP = PSN_FIRST - 5 +PSN_WIZBACK = PSN_FIRST - 6 +PSN_WIZNEXT = PSN_FIRST - 7 +PSN_WIZFINISH = PSN_FIRST - 8 +PSN_QUERYCANCEL = PSN_FIRST - 9 + +; Property sheet return values + +PSNRET_NOERROR = 0 +PSNRET_INVALID = 1 +PSNRET_INVALID_NOCHANGEPAGE = 2 + +; Property sheet messages + +PSM_SETCURSEL = WM_USER + 101 +PSM_REMOVEPAGE = WM_USER + 102 +PSM_ADDPAGE = WM_USER + 103 +PSM_CHANGED = WM_USER + 104 +PSM_RESTARTWINDOWS = WM_USER + 105 +PSM_REBOOTSYSTEM = WM_USER + 106 +PSM_CANCELTOCLOSE = WM_USER + 107 +PSM_QUERYSIBLINGS = WM_USER + 108 +PSM_UNCHANGED = WM_USER + 109 +PSM_APPLY = WM_USER + 110 +PSM_SETTITLE = WM_USER + 111 +PSM_SETTITLEW = WM_USER + 120 +PSM_SETWIZBUTTONS = WM_USER + 112 +PSM_PRESSBUTTON = WM_USER + 113 +PSM_SETCURSELID = WM_USER + 114 +PSM_SETFINISHTEXT = WM_USER + 115 +PSM_SETFINISHTEXTW = WM_USER + 121 +PSM_GETTABCONTROL = WM_USER + 116 +PSM_ISDIALOGMESSAGE = WM_USER + 117 + +; Property sheet buttons + +PSBTN_BACK = 0 +PSBTN_NEXT = 1 +PSBTN_FINISH = 2 +PSBTN_OK = 3 +PSBTN_APPLYNOW = 4 +PSBTN_CANCEL = 5 +PSBTN_HELP = 6 +PSWIZB_BACK = 1 +PSWIZB_NEXT = 2 +PSWIZB_FINISH = 4 +PSWIZB_DISABLEDFINISH = 8 +ID_PSRESTARTWINDOWS = 2 +ID_PSREBOOTSYSTEM = ID_PSRESTARTWINDOWS or 1 + +; Property sheet sizes + +PROP_SM_CXDLG = 212 +PROP_SM_CYDLG = 188 +PROP_MED_CXDLG = 227 +PROP_MED_CYDLG = 215 +PROP_LG_CXDLG = 252 +PROP_LG_CYDLG = 218 +WIZ_CXDLG = 276 +WIZ_CYDLG = 140 +WIZ_CXBMP = 80 +WIZ_BODYX = 92 +WIZ_BODYCX = 184 + +; Image list types + +ILC_MASK = 001h +ILC_COLOR = 0FEh +ILC_COLORDDB = 0FEh +ILC_COLOR4 = 004h +ILC_COLOR8 = 008h +ILC_COLOR16 = 010h +ILC_COLOR24 = 018h +ILC_COLOR32 = 020h +ILC_PALETTE = 800h + +; Image list color values + +CLR_NONE = 0FFFFFFFFh +CLR_DEFAULT = 0FF000000h +CLR_HILIGHT = CLR_DEFAULT + +; Image list drawing styles + +ILD_NORMAL = 0000h +ILD_TRANSPARENT = 0001h +ILD_MASK = 0010h +ILD_IMAGE = 0020h +ILD_BLEND25 = 0002h +ILD_BLEND50 = 0004h +ILD_OVERLAYMASK = 0F00h +ILD_SELECTED = ILD_BLEND50 +ILD_FOCUS = ILD_BLEND25 +ILD_BLEND = ILD_BLEND50 + +; Header control styles + +HDS_HORZ = 00h +HDS_BUTTONS = 02h +HDS_HOTTRACK = 04h +HDS_HIDDEN = 08h +HDS_DRAGDROP = 40h +HDS_FULLDRAG = 80h + +; Header control structure flags + +HDI_WIDTH = 01h +HDI_HEIGHT = HDI_WIDTH +HDI_TEXT = 02h +HDI_FORMAT = 04h +HDI_LPARAM = 08h +HDI_BITMAP = 10h + +; Header control flags + +HDF_LEFT = 0000h +HDF_RIGHT = 0001h +HDF_CENTER = 0002h +HDF_JUSTIFYMASK = 0003h +HDF_RTLREADING = 0004h +HDF_BITMAP = 2000h +HDF_STRING = 4000h +HDF_OWNERDRAW = 8000h + +; Header control messages + +HDM_GETITEMCOUNT = HDM_FIRST + 0 +HDM_INSERTITEMA = HDM_FIRST + 1 +HDM_DELETEITEM = HDM_FIRST + 2 +HDM_GETITEMA = HDM_FIRST + 3 +HDM_SETITEMA = HDM_FIRST + 4 +HDM_LAYOUT = HDM_FIRST + 5 +HDM_HITTEST = HDM_FIRST + 6 +HDM_INSERTITEMW = HDM_FIRST + 10 +HDM_GETITEMW = HDM_FIRST + 11 +HDM_SETITEMW = HDM_FIRST + 12 +HDM_INSERTITEM = HDM_INSERTITEMA +HDM_GETITEM = HDM_GETITEMA +HDM_SETITEM = HDM_SETITEMA + +; Hit test result flags + +HHT_NOWHERE = 001h +HHT_ONHEADER = 002h +HHT_ONDIVIDER = 004h +HHT_ONDIVOPEN = 008h +HHT_ABOVE = 100h +HHT_BELOW = 200h +HHT_TORIGHT = 400h +HHT_TOLEFT = 800h + +; Header control notifications + +HDN_ITEMCHANGINGA = HDN_FIRST - 0 +HDN_ITEMCHANGEDA = HDN_FIRST - 1 +HDN_ITEMCLICKA = HDN_FIRST - 2 +HDN_ITEMDBLCLICKA = HDN_FIRST - 3 +HDN_DIVIDERDBLCLICKA = HDN_FIRST - 5 +HDN_BEGINTRACKA = HDN_FIRST - 6 +HDN_ENDTRACKA = HDN_FIRST - 7 +HDN_TRACKA = HDN_FIRST - 8 +HDN_ITEMCHANGINGW = HDN_FIRST - 20 +HDN_ITEMCHANGEDW = HDN_FIRST - 21 +HDN_ITEMCLICKW = HDN_FIRST - 22 +HDN_ITEMDBLCLICKW = HDN_FIRST - 23 +HDN_DIVIDERDBLCLICKW = HDN_FIRST - 25 +HDN_BEGINTRACKW = HDN_FIRST - 26 +HDN_ENDTRACKW = HDN_FIRST - 27 +HDN_TRACKW = HDN_FIRST - 28 +HDN_ITEMCHANGING = HDN_ITEMCHANGINGA +HDN_ITEMCHANGED = HDN_ITEMCHANGEDA +HDN_ITEMCLICK = HDN_ITEMCLICKA +HDN_ITEMDBLCLICK = HDN_ITEMDBLCLICKA +HDN_DIVIDERDBLCLICK = HDN_DIVIDERDBLCLICKA +HDN_BEGINTRACK = HDN_BEGINTRACKA +HDN_ENDTRACK = HDN_ENDTRACKA +HDN_TRACK = HDN_TRACKA + +; Toolbar bitmap flags + +CMB_MASKED = 2 + +; Toolbar button states + +TBSTATE_CHECKED = 01h +TBSTATE_PRESSED = 02h +TBSTATE_ENABLED = 04h +TBSTATE_HIDDEN = 08h +TBSTATE_INDETERMINATE = 10h +TBSTATE_WRAP = 20h +TBSTATE_ELLIPSES = 40h + +; Toolbar button styles + +TBSTYLE_BUTTON = 0000h +TBSTYLE_SEP = 0001h +TBSTYLE_CHECK = 0002h +TBSTYLE_GROUP = 0004h +TBSTYLE_CHECKGROUP = TBSTYLE_GROUP or TBSTYLE_CHECK +TBSTYLE_DROPDOWN = 0008h +TBSTYLE_TOOLTIPS = 0100h +TBSTYLE_WRAPABLE = 0200h +TBSTYLE_ALTDRAG = 0400h +TBSTYLE_FLAT = 0800h +TBSTYLE_LIST = 1000h +TBSTYLE_CUSTOMERASE = 2000h +TBSTYLE_TRANSPARENT = 8000h + +; Toolbar button extended styles + +TBSTYLE_EX_DRAWDDARROWS = 0001h + +; Toolbar messages + +TB_ENABLEBUTTON = WM_USER + 1 +TB_CHECKBUTTON = WM_USER + 2 +TB_PRESSBUTTON = WM_USER + 3 +TB_HIDEBUTTON = WM_USER + 4 +TB_INDETERMINATE = WM_USER + 5 +TB_ISBUTTONENABLED = WM_USER + 9 +TB_ISBUTTONCHECKED = WM_USER + 10 +TB_ISBUTTONPRESSED = WM_USER + 11 +TB_ISBUTTONHIDDEN = WM_USER + 12 +TB_ISBUTTONINDETERMINATE = WM_USER + 13 +TB_SETSTATE = WM_USER + 17 +TB_GETSTATE = WM_USER + 18 +TB_ADDBITMAP = WM_USER + 19 +TB_ADDBUTTONS = WM_USER + 20 +TB_INSERTBUTTON = WM_USER + 21 +TB_DELETEBUTTON = WM_USER + 22 +TB_GETBUTTON = WM_USER + 23 +TB_BUTTONCOUNT = WM_USER + 24 +TB_COMMANDTOINDEX = WM_USER + 25 +TB_SAVERESTOREA = WM_USER + 26 +TB_ADDSTRINGA = WM_USER + 28 +TB_CUSTOMIZE = WM_USER + 27 +TB_GETITEMRECT = WM_USER + 29 +TB_BUTTONSTRUCTSIZE = WM_USER + 30 +TB_SETBUTTONSIZE = WM_USER + 31 +TB_SETBITMAPSIZE = WM_USER + 32 +TB_AUTOSIZE = WM_USER + 33 +TB_GETTOOLTIPS = WM_USER + 35 +TB_SETTOOLTIPS = WM_USER + 36 +TB_SETPARENT = WM_USER + 37 +TB_SETROWS = WM_USER + 39 +TB_GETROWS = WM_USER + 40 +TB_GETBITMAPFLAGS = WM_USER + 41 +TB_SETCMDID = WM_USER + 42 +TB_CHANGEBITMAP = WM_USER + 43 +TB_GETBITMAP = WM_USER + 44 +TB_GETBUTTONTEXTA = WM_USER + 45 +TB_REPLACEBITMAP = WM_USER + 46 +TB_SETINDENT = WM_USER + 47 +TB_SETIMAGELIST = WM_USER + 48 +TB_GETIMAGELIST = WM_USER + 49 +TB_LOADIMAGES = WM_USER + 50 +TB_GETRECT = WM_USER + 51 +TB_SETHOTIMAGELIST = WM_USER + 52 +TB_GETHOTIMAGELIST = WM_USER + 53 +TB_SETDISABLEDIMAGELIST = WM_USER + 54 +TB_GETDISABLEDIMAGELIST = WM_USER + 55 +TB_SETSTYLE = WM_USER + 56 +TB_GETSTYLE = WM_USER + 57 +TB_GETBUTTONSIZE = WM_USER + 58 +TB_SETBUTTONWIDTH = WM_USER + 59 +TB_SETMAXTEXTROWS = WM_USER + 60 +TB_GETTEXTROWS = WM_USER + 61 +TB_GETBUTTONTEXTW = WM_USER + 75 +TB_SAVERESTOREW = WM_USER + 76 +TB_ADDSTRINGW = WM_USER + 77 +TB_SETEXTENDEDSTYLE = WM_USER + 84 +TB_GETEXTENDEDSTYLE = WM_USER + 85 +TB_GETBUTTONTEXT = TB_GETBUTTONTEXTA +TB_SAVERESTORE = TB_SAVERESTOREA +TB_ADDSTRING = TB_ADDSTRINGA + +; System-defined button bitmaps + +HINST_COMMCTRL = -1 +IDB_STD_SMALL_COLOR = 0 +IDB_STD_LARGE_COLOR = 1 +IDB_VIEW_SMALL_COLOR = 4 +IDB_VIEW_LARGE_COLOR = 5 +IDB_HIST_SMALL_COLOR = 8 +IDB_HIST_LARGE_COLOR = 9 + +; Icon indexes for standard bitmap + +STD_CUT = 0 +STD_COPY = 1 +STD_PASTE = 2 +STD_UNDO = 3 +STD_REDOW = 4 +STD_DELETE = 5 +STD_FILENEW = 6 +STD_FILEOPEN = 7 +STD_FILESAVE = 8 +STD_PRINTPRE = 9 +STD_PROPERTIES = 10 +STD_HELP = 11 +STD_FIND = 12 +STD_REPLACE = 13 +STD_PRINT = 14 + +; Icon indexes for standard view bitmap + +VIEW_LARGEICONS = 0 +VIEW_SMALLICONS = 1 +VIEW_LIST = 2 +VIEW_DETAILS = 3 +VIEW_SORTNAME = 4 +VIEW_SORTSIZE = 5 +VIEW_SORTDATE = 6 +VIEW_SORTTYPE = 7 +VIEW_PARENTFOLDER = 8 +VIEW_NETCONNECT = 9 +VIEW_NETDISCONNECT = 10 +VIEW_NEWFOLDER = 11 + +; Icon indexes for history bitmap + +HIST_BACK = 0 +HIST_FORWARD = 1 +HIST_FAVORITES = 2 +HIST_ADDTOFAVORITES = 3 +HIST_VIEWTREE = 4 + +; Toolbar bitmap flags + +TBBF_LARGE = 1 + +; Toolbar notifications + +TBN_GETBUTTONINFOA = TBN_FIRST - 0 +TBN_BEGINDRAG = TBN_FIRST - 1 +TBN_ENDDRAG = TBN_FIRST - 2 +TBN_BEGINADJUST = TBN_FIRST - 3 +TBN_ENDADJUST = TBN_FIRST - 4 +TBN_RESET = TBN_FIRST - 5 +TBN_QUERYINSERT = TBN_FIRST - 6 +TBN_QUERYDELETE = TBN_FIRST - 7 +TBN_TOOLBARCHANGE = TBN_FIRST - 8 +TBN_CUSTHELP = TBN_FIRST - 9 +TBN_DROPDOWN = TBN_FIRST - 10 +TBN_CLOSEUP = TBN_FIRST - 11 +TBN_GETBUTTONINFOW = TBN_FIRST - 20 +TBN_GETBUTTONINFO = TBN_GETBUTTONINFOA + +; ReBar styles + +RBS_TOOLTIPS = 100h +RBS_VARHEIGHT = 200h +RBS_BANDBORDERS = 400h +RBS_FIXEDORDER = 800h +RBS_REGISTERDROP = 1000h +RBS_AUTOSIZE = 2000h +RBS_VERTICALGRIPPER = 4000h +RBS_DBLCLKTOGGLE = 8000h + +; ReBar band info structure flags + +RBBIM_STYLE = 001h +RBBIM_COLORS = 002h +RBBIM_TEXT = 004h +RBBIM_IMAGE = 008h +RBBIM_CHILD = 010h +RBBIM_CHILDSIZE = 020h +RBBIM_SIZE = 040h +RBBIM_BACKGROUND = 080h +RBBIM_ID = 100h +RBBIM_IDEALSIZE = 200h +RBBIM_LPARAM = 400h +RBBIM_HEADERSIZE = 800h + +; ReBar band styles + +RBBS_BREAK = 001h +RBBS_FIXEDSIZE = 002h +RBBS_CHILDEDGE = 004h +RBBS_HIDDEN = 008h +RBBS_NOVERT = 010h +RBBS_FIXEDBMP = 020h +RBBS_VARIABLEHEIGHT = 040h +RBBS_GRIPPERALWAYS = 080h +RBBS_NOGRIPPER = 100h + +; ReBar messages + +RB_INSERTBANDA = WM_USER + 1 +RB_DELETEBAND = WM_USER + 2 +RB_GETBARINFO = WM_USER + 3 +RB_SETBARINFO = WM_USER + 4 +RB_GETBANDINFO = WM_USER + 5 +RB_SETBANDINFOA = WM_USER + 6 +RB_SETPARENT = WM_USER + 7 +RB_INSERTBANDW = WM_USER + 10 +RB_SETBANDINFOW = WM_USER + 11 +RB_GETBANDCOUNT = WM_USER + 12 +RB_GETROWCOUNT = WM_USER + 13 +RB_GETROWHEIGHT = WM_USER + 14 +RB_IDTOINDEX = WM_USER + 16 +RB_GETTOOLTIPS = WM_USER + 17 +RB_SETTOOLTIPS = WM_USER + 18 +RB_SETBKCOLOR = WM_USER + 19 +RB_GETBKCOLOR = WM_USER + 20 +RB_SETTEXTCOLOR = WM_USER + 21 +RB_GETTEXTCOLOR = WM_USER + 22 +RB_SIZETORECT = WM_USER + 23 +RB_BEGINDRAG = WM_USER + 24 +RB_ENDDRAG = WM_USER + 25 +RB_DRAGMOVE = WM_USER + 26 +RB_GETBARHEIGHT = WM_USER + 27 +RB_GETBANDINFOW = WM_USER + 28 +RB_GETBANDINFOA = WM_USER + 29 +RB_MINIMIZEBAND = WM_USER + 30 +RB_MAXIMIZEBAND = WM_USER + 31 +RB_GETDROPTARGET = CCM_GETDROPTARGET +RB_GETBANDBORDERS = WM_USER + 34 +RB_SHOWBAND = WM_USER + 35 +RB_SETPALETTE = WM_USER + 37 +RB_GETPALETTE = WM_USER + 38 +RB_MOVEBAND = WM_USER + 39 +RB_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT +RB_GETUNICODEFORMAT = CCM_GETUNICODEFORMAT +RB_INSERTBAND = RB_INSERTBANDA +RB_SETBANDINFO = RB_SETBANDINFOA + +; ReBar notifications + +RBN_HEIGHTCHANGE = RBN_FIRST - 0 +RBN_GETOBJECT = RBN_FIRST - 1 +RBN_LAYOUTCHANGED = RBN_FIRST - 2 +RBN_AUTOSIZE = RBN_FIRST - 3 +RBN_BEGINDRAG = RBN_FIRST - 4 +RBN_ENDDRAG = RBN_FIRST - 5 +RBN_DELETINGBAND = RBN_FIRST - 6 +RBN_DELETEDBAND = RBN_FIRST - 7 +RBN_CHILDSIZE = RBN_FIRST - 8 + +; Tooltip styles + +TTS_ALWAYSTIP = 1 +TTS_NOPREFIX = 2 + +; Tooltip flags + +TTF_IDISHWND = 01h +TTF_CENTERTIP = 02h +TTF_RTLREADING = 04h +TTF_SUBCLASS = 10h + +; Tooltip durations + +TTDT_AUTOMATIC = 0 +TTDT_RESHOW = 1 +TTDT_AUTOPOP = 2 +TTDT_INITIAL = 3 + +; Tooltip messages + +TTM_ACTIVATE = WM_USER + 1 +TTM_SETDELAYTIME = WM_USER + 3 +TTM_ADDTOOLA = WM_USER + 4 +TTM_DELTOOLA = WM_USER + 5 +TTM_NEWTOOLRECTA = WM_USER + 6 +TTM_RELAYEVENT = WM_USER + 7 +TTM_GETTOOLINFOA = WM_USER + 8 +TTM_SETTOOLINFOA = WM_USER + 9 +TTM_HITTESTA = WM_USER + 10 +TTM_GETTEXTA = WM_USER + 11 +TTM_UPDATETIPTEXTA = WM_USER + 12 +TTM_GETTOOLCOUNT = WM_USER + 13 +TTM_ENUMTOOLSA = WM_USER + 14 +TTM_GETCURRENTTOOLA = WM_USER + 15 +TTM_WINDOWFROMPOINT = WM_USER + 16 +TTM_ADDTOOLW = WM_USER + 50 +TTM_DELTOOLW = WM_USER + 51 +TTM_NEWTOOLRECTW = WM_USER + 52 +TTM_GETTOOLINFOW = WM_USER + 53 +TTM_SETTOOLINFOW = WM_USER + 54 +TTM_HITTESTW = WM_USER + 55 +TTM_GETTEXTW = WM_USER + 56 +TTM_UPDATETIPTEXTW = WM_USER + 57 +TTM_ENUMTOOLSW = WM_USER + 58 +TTM_GETCURRENTTOOLW = WM_USER + 59 +TTM_ADDTOOL = TTM_ADDTOOLA +TTM_DELTOOL = TTM_DELTOOLA +TTM_NEWTOOLRECT = TTM_NEWTOOLRECTA +TTM_GETTOOLINFO = TTM_GETTOOLINFOA +TTM_SETTOOLINFO = TTM_SETTOOLINFOA +TTM_HITTEST = TTM_HITTESTA +TTM_GETTEXT = TTM_GETTEXTA +TTM_UPDATETIPTEXT = TTM_UPDATETIPTEXTA +TTM_ENUMTOOLS = TTM_ENUMTOOLSA +TTM_GETCURRENTTOOL = TTM_GETCURRENTTOOLA + +; Tooltip notifications + +TTN_NEEDTEXTA = TTN_FIRST - 0 +TTN_SHOW = TTN_FIRST - 1 +TTN_POP = TTN_FIRST - 2 +TTN_NEEDTEXTW = TTN_FIRST - 10 +TTN_NEEDTEXT = TTN_NEEDTEXTA + +; Status bar styles + +SBARS_SIZEGRIP = 100h + +; Status bar messages + +SB_SETTEXTA = WM_USER + 1 +SB_GETTEXTA = WM_USER + 2 +SB_GETTEXTLENGTHA = WM_USER + 3 +SB_SETPARTS = WM_USER + 4 +SB_GETPARTS = WM_USER + 6 +SB_GETBORDERS = WM_USER + 7 +SB_SETMINHEIGHT = WM_USER + 8 +SB_SIMPLE = WM_USER + 9 +SB_GETRECT = WM_USER + 10 +SB_SETTEXTW = WM_USER + 11 +SB_GETTEXTW = WM_USER + 13 +SB_GETTEXTLENGTHW = WM_USER + 12 +SB_SETTEXT = SB_SETTEXTA +SB_GETTEXT = SB_GETTEXTA +SB_GETTEXTLENGTH = SB_GETTEXTLENGTHA + +; Status bar drawing types + +SBT_OWNERDRAW = 1000h +SBT_NOBORDERS = 0100h +SBT_POPOUT = 0200h +SBT_RTLREADING = 0400h + +; Trackbar styles + +TBS_AUTOTICKS = 01h +TBS_VERT = 02h +TBS_HORZ = 00h +TBS_TOP = 04h +TBS_BOTTOM = 00h +TBS_LEFT = 04h +TBS_RIGHT = 00h +TBS_BOTH = 08h +TBS_NOTICKS = 10h +TBS_ENABLESELRANGE = 20h +TBS_FIXEDLENGTH = 40h +TBS_NOTHUMB = 80h + +; Trackbar messages + +TBM_GETPOS = WM_USER + 0 +TBM_GETRANGEMIN = WM_USER + 1 +TBM_GETRANGEMAX = WM_USER + 2 +TBM_GETTIC = WM_USER + 3 +TBM_SETTIC = WM_USER + 4 +TBM_SETPOS = WM_USER + 5 +TBM_SETRANGE = WM_USER + 6 +TBM_SETRANGEMIN = WM_USER + 7 +TBM_SETRANGEMAX = WM_USER + 8 +TBM_CLEARTICS = WM_USER + 9 +TBM_SETSEL = WM_USER + 10 +TBM_SETSELSTART = WM_USER + 11 +TBM_SETSELEND = WM_USER + 12 +TBM_GETPTICS = WM_USER + 14 +TBM_GETTICPOS = WM_USER + 15 +TBM_GETNUMTICS = WM_USER + 16 +TBM_GETSELSTART = WM_USER + 17 +TBM_GETSELEND = WM_USER + 18 +TBM_CLEARSEL = WM_USER + 19 +TBM_SETTICFREQ = WM_USER + 20 +TBM_SETPAGESIZE = WM_USER + 21 +TBM_GETPAGESIZE = WM_USER + 22 +TBM_SETLINESIZE = WM_USER + 23 +TBM_GETLINESIZE = WM_USER + 24 +TBM_GETTHUMBRECT = WM_USER + 25 +TBM_GETCHANNELRECT = WM_USER + 26 +TBM_SETTHUMBLENGTH = WM_USER + 27 +TBM_GETTHUMBLENGTH = WM_USER + 28 + +; Trackbar notifications + +TB_LINEUP = 0 +TB_LINEDOWN = 1 +TB_PAGEUP = 2 +TB_PAGEDOWN = 3 +TB_THUMBPOSITION = 4 +TB_THUMBTRACK = 5 +TB_TOP = 6 +TB_BOTTOM = 7 +TB_ENDTRACK = 8 + +; Up-down control styles + +UDS_WRAP = 01h +UDS_SETBUDDYINT = 02h +UDS_ALIGNRIGHT = 04h +UDS_ALIGNLEFT = 08h +UDS_AUTOBUDDY = 10h +UDS_ARROWKEYS = 20h +UDS_HORZ = 40h +UDS_NOTHOUSANDS = 80h + +; Up-down control messages + +UDM_SETRANGE = WM_USER + 101 +UDM_GETRANGE = WM_USER + 102 +UDM_SETPOS = WM_USER + 103 +UDM_GETPOS = WM_USER + 104 +UDM_SETBUDDY = WM_USER + 105 +UDM_GETBUDDY = WM_USER + 106 +UDM_SETACCEL = WM_USER + 107 +UDM_GETACCEL = WM_USER + 108 +UDM_SETBASE = WM_USER + 109 +UDM_GETBASE = WM_USER + 110 + +; Up-down control notifications + +UDN_DELTAPOS = UDN_FIRST - 1 + +; Progress bar messages + +PBM_SETRANGE = WM_USER + 1 +PBM_SETPOS = WM_USER + 2 +PBM_DELTAPOS = WM_USER + 3 +PBM_SETSTEP = WM_USER + 4 +PBM_STEPIT = WM_USER + 5 +PBM_SETRANGE32 = WM_USER + 6 +PBM_GETRANGE = WM_USER + 7 +PBM_GETPOS = WM_USER + 8 + +; Hot-key control messages + +HKM_SETHOTKEY = WM_USER + 1 +HKM_GETHOTKEY = WM_USER + 2 +HKM_SETRULES = WM_USER + 3 + +; Hot key flags + +HOTKEYF_SHIFT = 1 +HOTKEYF_CONTROL = 2 +HOTKEYF_ALT = 4 +HOTKEYF_EXT = 8 + +; Key combination flags + +HKCOMB_NONE = 01h +HKCOMB_S = 02h +HKCOMB_C = 04h +HKCOMB_A = 08h +HKCOMB_SC = 10h +HKCOMB_SA = 20h +HKCOMB_CA = 40h +HKCOMB_SCA = 80h + +; List view styles + +LVS_ICON = 0000h +LVS_REPORT = 0001h +LVS_SMALLICON = 0002h +LVS_LIST = 0003h +LVS_TYPEMASK = 0003h +LVS_SINGLESEL = 0004h +LVS_SHOWSELALWAYS = 0008h +LVS_SORTASCENDING = 0010h +LVS_SORTDESCENDING = 0020h +LVS_SHAREIMAGELISTS = 0040h +LVS_NOLABELWRAP = 0080h +LVS_AUTOARRANGE = 0100h +LVS_EDITLABELS = 0200h +LVS_OWNERDATA = 1000h +LVS_NOSCROLL = 2000h +LVS_ALIGNTOP = 0000h +LVS_ALIGNLEFT = 0800h +LVS_OWNERDRAWFIXED = 0400h +LVS_NOCOLUMNHEADER = 4000h +LVS_NOSORTHEADER = 8000h + +; List view extended styles + +LVS_EX_GRIDLINES = 0001h +LVS_EX_SUBITEMIMAGES = 0002h +LVS_EX_CHECKBOXES = 0004h +LVS_EX_TRACKSELECT = 0008h +LVS_EX_HEADERDRAGDROP = 0010h +LVS_EX_FULLROWSELECT = 0020h +LVS_EX_ONECLICKACTIVATE = 0040h +LVS_EX_TWOCLICKACTIVATE = 0080h +LVS_EX_FLATSB = 0100h +LVS_EX_REGIONAL = 0200h +LVS_EX_INFOTIP = 0400h +LVS_EX_UNDERLINEHOT = 0800h +LVS_EX_UNDERLINECOLD = 1000h +LVS_EX_MULTIWORKAREAS = 2000h +LVS_EX_LABELTIP = 4000h + +; List view messages + +LVM_GETBKCOLOR = LVM_FIRST + 0 +LVM_SETBKCOLOR = LVM_FIRST + 1 +LVM_GETIMAGELIST = LVM_FIRST + 2 +LVM_SETIMAGELIST = LVM_FIRST + 3 +LVM_GETITEMCOUNT = LVM_FIRST + 4 +LVM_GETITEMA = LVM_FIRST + 5 +LVM_SETITEMA = LVM_FIRST + 6 +LVM_INSERTITEMA = LVM_FIRST + 7 +LVM_DELETEITEM = LVM_FIRST + 8 +LVM_DELETEALLITEMS = LVM_FIRST + 9 +LVM_GETCALLBACKMASK = LVM_FIRST + 10 +LVM_SETCALLBACKMASK = LVM_FIRST + 11 +LVM_GETNEXTITEM = LVM_FIRST + 12 +LVM_FINDITEMA = LVM_FIRST + 13 +LVM_GETITEMRECT = LVM_FIRST + 14 +LVM_SETITEMPOSITION = LVM_FIRST + 15 +LVM_GETITEMPOSITION = LVM_FIRST + 16 +LVM_GETSTRINGWIDTHA = LVM_FIRST + 17 +LVM_HITTEST = LVM_FIRST + 18 +LVM_ENSUREVISIBLE = LVM_FIRST + 19 +LVM_SCROLL = LVM_FIRST + 20 +LVM_REDRAWITEMS = LVM_FIRST + 21 +LVM_ARRANGE = LVM_FIRST + 22 +LVM_EDITLABELA = LVM_FIRST + 23 +LVM_GETEDITCONTROL = LVM_FIRST + 24 +LVM_GETCOLUMNA = LVM_FIRST + 25 +LVM_SETCOLUMNA = LVM_FIRST + 26 +LVM_INSERTCOLUMNA = LVM_FIRST + 27 +LVM_DELETECOLUMN = LVM_FIRST + 28 +LVM_GETCOLUMNWIDTH = LVM_FIRST + 29 +LVM_SETCOLUMNWIDTH = LVM_FIRST + 30 +LVM_CREATEDRAGIMAGE = LVM_FIRST + 33 +LVM_GETVIEWRECT = LVM_FIRST + 34 +LVM_GETTEXTCOLOR = LVM_FIRST + 35 +LVM_SETTEXTCOLOR = LVM_FIRST + 36 +LVM_GETTEXTBKCOLOR = LVM_FIRST + 37 +LVM_SETTEXTBKCOLOR = LVM_FIRST + 38 +LVM_GETTOPINDEX = LVM_FIRST + 39 +LVM_GETCOUNTPERPAGE = LVM_FIRST + 40 +LVM_GETORIGIN = LVM_FIRST + 41 +LVM_UPDATE = LVM_FIRST + 42 +LVM_SETITEMSTATE = LVM_FIRST + 43 +LVM_GETITEMSTATE = LVM_FIRST + 44 +LVM_GETITEMTEXTA = LVM_FIRST + 45 +LVM_SETITEMTEXTA = LVM_FIRST + 46 +LVM_SETITEMCOUNT = LVM_FIRST + 47 +LVM_SORTITEMS = LVM_FIRST + 48 +LVM_SETITEMPOSITION32 = LVM_FIRST + 49 +LVM_GETSELECTEDCOUNT = LVM_FIRST + 50 +LVM_GETITEMSPACING = LVM_FIRST + 51 +LVM_GETISEARCHSTRINGA = LVM_FIRST + 52 +LVM_SETICONSPACING = LVM_FIRST + 53 +LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54 +LVM_GETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 55 +LVM_GETSUBITEMRECT = LVM_FIRST + 56 +LVM_SUBITEMHITTEST = LVM_FIRST + 57 +LVM_SETCOLUMNORDERARRAY = LVM_FIRST + 58 +LVM_GETCOLUMNORDERARRAY = LVM_FIRST + 59 +LVM_SETHOTITEM = LVM_FIRST + 60 +LVM_GETHOTITEM = LVM_FIRST + 61 +LVM_SETHOTCURSOR = LVM_FIRST + 62 +LVM_GETHOTCURSOR = LVM_FIRST + 63 +LVM_APPROXIMATEVIEWRECT = LVM_FIRST + 64 +LVM_SETWORKAREA = LVM_FIRST + 65 +LVM_GETITEMW = LVM_FIRST + 75 +LVM_SETITEMW = LVM_FIRST + 76 +LVM_INSERTITEMW = LVM_FIRST + 77 +LVM_FINDITEMW = LVM_FIRST + 83 +LVM_GETSTRINGWIDTHW = LVM_FIRST + 87 +LVM_GETCOLUMNW = LVM_FIRST + 95 +LVM_SETCOLUMNW = LVM_FIRST + 96 +LVM_INSERTCOLUMNW = LVM_FIRST + 97 +LVM_GETITEMTEXTW = LVM_FIRST + 115 +LVM_SETITEMTEXTW = LVM_FIRST + 116 +LVM_GETISEARCHSTRINGW = LVM_FIRST + 117 +LVM_EDITLABELW = LVM_FIRST + 118 +LVM_GETITEM = LVM_GETITEMA +LVM_SETITEM = LVM_SETITEMA +LVM_INSERTITEM = LVM_INSERTITEMA +LVM_FINDITEM = LVM_FINDITEMA +LVM_GETSTRINGWIDTH = LVM_GETSTRINGWIDTHA +LVM_GETCOLUMN = LVM_GETCOLUMNA +LVM_SETCOLUMN = LVM_SETCOLUMNA +LVM_INSERTCOLUMN = LVM_INSERTCOLUMNA +LVM_GETITEMTEXT = LVM_GETITEMTEXTA +LVM_SETITEMTEXT = LVM_SETITEMTEXTA +LVM_GETISEARCHSTRING = LVM_GETISEARCHSTRINGA +LVM_EDITLABEL = LVM_EDITLABELA + +; List view image list types + +LVSIL_NORMAL = 0 +LVSIL_SMALL = 1 +LVSIL_STATE = 2 + +; LVM_SETITEMCOUNT flags + +LVSICF_NOINVALIDATEALL = 1 +LVSICF_NOSCROLL = 2 + +; List view item structure flags + +LVIF_TEXT = 0001h +LVIF_IMAGE = 0002h +LVIF_PARAM = 0004h +LVIF_STATE = 0008h +LVIF_INDENT = 0010h +LVIF_NORECOMPUTE = 0800h +LVIF_DI_SETITEM = 1000h + +; List view item states + +LVIS_FOCUSED = 00001h +LVIS_SELECTED = 00002h +LVIS_CUT = 00004h +LVIS_DROPHILITED = 00008h +LVIS_ACTIVATING = 0020h +LVIS_OVERLAYMASK = 00F00h +LVIS_STATEIMAGEMASK = 0F000h + +; List view callback item values + +LPSTR_TEXTCALLBACK = -1 +I_IMAGECALLBACK = -1 +I_CHILDRENCALLBACK = -1 + +; List view next item relations + +LVNI_ALL = 000h +LVNI_FOCUSED = 001h +LVNI_SELECTED = 002h +LVNI_CUT = 004h +LVNI_DROPHILITED = 008h +LVNI_ABOVE = 100h +LVNI_BELOW = 200h +LVNI_TOLEFT = 400h +LVNI_TORIGHT = 800h + +; List view search types + +LVFI_PARAM = 01h +LVFI_STRING = 02h +LVFI_PARTIAL = 08h +LVFI_WRAP = 20h +LVFI_NEARESTXY = 40h + +; List view item rectangle types + +LVIR_BOUNDS = 0 +LVIR_ICON = 1 +LVIR_LABEL = 2 +LVIR_SELECTBOUNDS = 3 + +; List view hit test flags + +LVHT_NOWHERE = 01h +LVHT_ONITEMICON = 02h +LVHT_ONITEMLABEL = 04h +LVHT_ONITEMSTATEICON= 08h +LVHT_ONITEM = LVHT_ONITEMICON or LVHT_ONITEMLABEL or LVHT_ONITEMSTATEICON +LVHT_ABOVE = 08h +LVHT_BELOW = 10h +LVHT_TORIGHT = 20h +LVHT_TOLEFT = 40h + +; List view alignment values + +LVA_DEFAULT = 000h +LVA_ALIGNLEFT = 001h +LVA_ALIGNTOP = 002h +LVA_ALIGNRIGHT = 003h +LVA_ALIGNBOTTOM = 004h +LVA_SNAPTOGRID = 005h +LVA_SORTASCENDING = 100h +LVA_SORTDESCENDING = 200h + +; List view column structure flags + +LVCF_FMT = 1 +LVCF_WIDTH = 2 +LVCF_TEXT = 4 +LVCF_SUBITEM = 8 + +; List view column alignment values + +LVCFMT_LEFT = 0 +LVCFMT_RIGHT = 1 +LVCFMT_CENTER = 2 +LVCFMT_JUSTIFYMASK = 3 + +; List view column width values + +LVSCW_AUTOSIZE = -1 +LVSCW_AUTOSIZE_USEHEADER = -2 + +; List view notifications + +LVN_ITEMCHANGING = LVN_FIRST - 0 +LVN_ITEMCHANGED = LVN_FIRST - 1 +LVN_INSERTITEM = LVN_FIRST - 2 +LVN_DELETEITEM = LVN_FIRST - 3 +LVN_DELETEALLITEMS = LVN_FIRST - 4 +LVN_BEGINLABELEDITA = LVN_FIRST - 5 +LVN_ENDLABELEDITA = LVN_FIRST - 6 +LVN_COLUMNCLICK = LVN_FIRST - 8 +LVN_BEGINDRAG = LVN_FIRST - 9 +LVN_BEGINRDRAG = LVN_FIRST - 11 +LVN_ODCACHEHINT = LVN_FIRST - 13 +LVN_GETDISPINFOA = LVN_FIRST - 50 +LVN_SETDISPINFOA = LVN_FIRST - 51 +LVN_ODFINDITEMA = LVN_FIRST - 52 +LVN_KEYDOWN = LVN_FIRST - 55 +LVN_BEGINLABELEDITW = LVN_FIRST - 75 +LVN_ENDLABELEDITW = LVN_FIRST - 76 +LVN_GETDISPINFOW = LVN_FIRST - 77 +LVN_SETDISPINFOW = LVN_FIRST - 78 +LVN_ODFINDITEMW = LVN_FIRST - 79 +LVN_BEGINLABELEDIT = LVN_BEGINLABELEDITA +LVN_ENDLABELEDIT = LVN_ENDLABELEDITA +LVN_GETDISPINFO = LVN_GETDISPINFOA +LVN_SETDISPINFO = LVN_SETDISPINFOA +LVN_ODFINDITEM = LVN_ODFINDITEMA + +; Tree view styles + +TVS_HASBUTTONS = 0001h +TVS_HASLINES = 0002h +TVS_LINESATROOT = 0004h +TVS_EDITLABELS = 0008h +TVS_DISABLEDRAGDROP = 0010h +TVS_SHOWSELALWAYS = 0020h +TVS_RTLREADING = 0040h +TVS_NOTOOLTIPS = 0080h +TVS_CHECKBOXES = 0100h +TVS_TRACKSELECT = 0200h +TVS_SINGLEEXPAND = 0400h +TVS_INFOTIP = 0800h +TVS_FULLROWSELECT = 1000h +TVS_NOSCROLL = 2000h +TVS_NONEVENHEIGHT = 4000h + +; Tree view item structure flags + +TVIF_TEXT = 0001h +TVIF_IMAGE = 0002h +TVIF_PARAM = 0004h +TVIF_STATE = 0008h +TVIF_HANDLE = 0010h +TVIF_SELECTEDIMAGE = 0020h +TVIF_CHILDREN = 0040h +TVIF_DI_SETITEM = 1000h + +; Tree view item states + +TVIS_FOCUSED = 00001h +TVIS_SELECTED = 00002h +TVIS_CUT = 00004h +TVIS_DROPHILITED = 00008h +TVIS_BOLD = 00010h +TVIS_EXPANDED = 00020h +TVIS_EXPANDEDONCE = 00040h +TVIS_EXPANDPARTIAL = 00080h +TVIS_OVERLAYMASK = 00F00h +TVIS_STATEIMAGEMASK = 0F000h +TVIS_USERMASK = 0F000h + +; Tree view predefined item values + +TVI_ROOT = -10000h +TVI_FIRST = -0FFFFh +TVI_LAST = -0FFFEh +TVI_SORT = -0FFFDh + +; Tree view messages + +TVM_INSERTITEMA = TV_FIRST + 0 +TVM_DELETEITEM = TV_FIRST + 1 +TVM_EXPAND = TV_FIRST + 2 +TVM_GETITEMRECT = TV_FIRST + 4 +TVM_GETCOUNT = TV_FIRST + 5 +TVM_GETINDENT = TV_FIRST + 6 +TVM_SETINDENT = TV_FIRST + 7 +TVM_GETIMAGELIST = TV_FIRST + 8 +TVM_SETIMAGELIST = TV_FIRST + 9 +TVM_GETNEXTITEM = TV_FIRST + 10 +TVM_SELECTITEM = TV_FIRST + 11 +TVM_GETITEMA = TV_FIRST + 12 +TVM_SETITEMA = TV_FIRST + 13 +TVM_EDITLABELA = TV_FIRST + 14 +TVM_GETEDITCONTROL = TV_FIRST + 15 +TVM_GETVISIBLECOUNT = TV_FIRST + 16 +TVM_HITTEST = TV_FIRST + 17 +TVM_CREATEDRAGIMAGE = TV_FIRST + 18 +TVM_SORTCHILDREN = TV_FIRST + 19 +TVM_ENSUREVISIBLE = TV_FIRST + 20 +TVM_SORTCHILDRENCB = TV_FIRST + 21 +TVM_ENDEDITLABELNOW = TV_FIRST + 22 +TVM_GETISEARCHSTRINGA = TV_FIRST + 23 +TVM_INSERTITEMW = TV_FIRST + 50 +TVM_GETITEMW = TV_FIRST + 62 +TVM_SETITEMW = TV_FIRST + 63 +TVM_GETISEARCHSTRINGW = TV_FIRST + 64 +TVM_EDITLABELW = TV_FIRST + 65 +TVM_INSERTITEM = TVM_INSERTITEMA +TVM_GETITEM = TVM_GETITEMA +TVM_SETITEM = TVM_SETITEMA +TVM_GETISEARCHSTRING = TVM_GETISEARCHSTRINGA +TVM_EDITLABEL = TVM_EDITLABELA + +; Tree view action flags + +TVE_COLLAPSE = 0001h +TVE_EXPAND = 0002h +TVE_TOGGLE = 0003h +TVE_EXPANDPARTIAL = 4000h +TVE_COLLAPSERESET = 8000h + +; Tree view image list types + +TVSIL_NORMAL = 0 +TVSIL_STATE = 2 + +; Tree view next item types + +TVGN_ROOT = 0 +TVGN_NEXT = 1 +TVGN_PREVIOUS = 2 +TVGN_PARENT = 3 +TVGN_CHILD = 4 +TVGN_FIRSTVISIBLE = 5 +TVGN_NEXTVISIBLE = 6 +TVGN_PREVIOUSVISIBLE = 7 +TVGN_DROPHILITE = 8 +TVGN_CARET = 9 + +; Tree view hit test flags + +TVHT_NOWHERE = 001h +TVHT_ONITEMICON = 002h +TVHT_ONITEMLABEL = 004h +TVHT_ONITEMINDENT = 008h +TVHT_ONITEMBUTTON = 010h +TVHT_ONITEMRIGHT = 020h +TVHT_ONITEMSTATEICON = 040h +TVHT_ONITEM = TVHT_ONITEMICON or TVHT_ONITEMLABEL or TVHT_ONITEMSTATEICON +TVHT_ABOVE = 100h +TVHT_BELOW = 200h +TVHT_TORIGHT = 400h +TVHT_TOLEFT = 800h + +; Tree view notifications + +TVN_SELCHANGINGA = TVN_FIRST - 1 +TVN_SELCHANGEDA = TVN_FIRST - 2 +TVN_GETDISPINFOA = TVN_FIRST - 3 +TVN_SETDISPINFOA = TVN_FIRST - 4 +TVN_ITEMEXPANDINGA = TVN_FIRST - 5 +TVN_ITEMEXPANDEDA = TVN_FIRST - 6 +TVN_BEGINDRAGA = TVN_FIRST - 7 +TVN_BEGINRDRAGA = TVN_FIRST - 8 +TVN_DELETEITEMA = TVN_FIRST - 9 +TVN_BEGINLABELEDITA = TVN_FIRST - 10 +TVN_ENDLABELEDITA = TVN_FIRST - 11 +TVN_KEYDOWN = TVN_FIRST - 12 +TVN_SELCHANGINGW = TVN_FIRST - 50 +TVN_SELCHANGEDW = TVN_FIRST - 51 +TVN_GETDISPINFOW = TVN_FIRST - 52 +TVN_SETDISPINFOW = TVN_FIRST - 53 +TVN_ITEMEXPANDINGW = TVN_FIRST - 54 +TVN_ITEMEXPANDEDW = TVN_FIRST - 55 +TVN_BEGINDRAGW = TVN_FIRST - 56 +TVN_BEGINRDRAGW = TVN_FIRST - 57 +TVN_DELETEITEMW = TVN_FIRST - 58 +TVN_BEGINLABELEDITW = TVN_FIRST - 59 +TVN_ENDLABELEDITW = TVN_FIRST - 60 +TVN_SELCHANGING = TVN_SELCHANGINGA +TVN_SELCHANGED = TVN_SELCHANGEDA +TVN_GETDISPINFO = TVN_GETDISPINFOA +TVN_SETDISPINFO = TVN_SETDISPINFOA +TVN_ITEMEXPANDING = TVN_ITEMEXPANDINGA +TVN_ITEMEXPANDED = TVN_ITEMEXPANDEDA +TVN_BEGINDRAG = TVN_BEGINDRAGA +TVN_BEGINRDRAG = TVN_BEGINRDRAGA +TVN_DELETEITEM = TVN_DELETEITEMA +TVN_BEGINLABELEDIT = TVN_BEGINLABELEDITA +TVN_ENDLABELEDIT = TVN_ENDLABELEDITA + +; Tree view action flags + +TVC_UNKNOWN = 0 +TVC_BYMOUSE = 1 +TVC_BYKEYBOARD = 2 + +; Tab control styles + +TCS_SCROLLOPPOSITE = 0001h +TCS_BOTTOM = 0002h +TCS_RIGHT = 0002h +TCS_FORCEICONLEFT = 0010h +TCS_FORCELABELLEFT = 0020h +TCS_HOTTRACK = 0040h +TCS_VERTICAL = 0080h +TCS_TABS = 0000h +TCS_BUTTONS = 0100h +TCS_SINGLELINE = 0000h +TCS_MULTILINE = 0200h +TCS_RIGHTJUSTIFY = 0000h +TCS_FIXEDWIDTH = 0400h +TCS_RAGGEDRIGHT = 0800h +TCS_FOCUSONBUTTONDOWN = 1000h +TCS_OWNERDRAWFIXED = 2000h +TCS_TOOLTIPS = 4000h +TCS_FOCUSNEVER = 8000h + +; Tab control messages + +TCM_GETIMAGELIST = TCM_FIRST + 2 +TCM_SETIMAGELIST = TCM_FIRST + 3 +TCM_GETITEMCOUNT = TCM_FIRST + 4 +TCM_GETITEMA = TCM_FIRST + 5 +TCM_SETITEMA = TCM_FIRST + 6 +TCM_INSERTITEMA = TCM_FIRST + 7 +TCM_DELETEITEM = TCM_FIRST + 8 +TCM_DELETEALLITEMS = TCM_FIRST + 9 +TCM_GETITEMRECT = TCM_FIRST + 10 +TCM_GETCURSEL = TCM_FIRST + 11 +TCM_SETCURSEL = TCM_FIRST + 12 +TCM_HITTEST = TCM_FIRST + 13 +TCM_SETITEMEXTRA = TCM_FIRST + 14 +TCM_ADJUSTRECT = TCM_FIRST + 40 +TCM_SETITEMSIZE = TCM_FIRST + 41 +TCM_REMOVEIMAGE = TCM_FIRST + 42 +TCM_SETPADDING = TCM_FIRST + 43 +TCM_GETROWCOUNT = TCM_FIRST + 44 +TCM_GETTOOLTIPS = TCM_FIRST + 45 +TCM_SETTOOLTIPS = TCM_FIRST + 46 +TCM_GETCURFOCUS = TCM_FIRST + 47 +TCM_SETCURFOCUS = TCM_FIRST + 48 +TCM_GETITEMW = TCM_FIRST + 60 +TCM_SETITEMW = TCM_FIRST + 61 +TCM_INSERTITEMW = TCM_FIRST + 62 +TCM_GETITEM = TCM_GETITEMA +TCM_SETITEM = TCM_SETITEMA +TCM_INSERTITEM = TCM_INSERTITEMA + +; Tab control item structure flags + +TCIF_TEXT = 1 +TCIF_IMAGE = 2 +TCIF_RTLREADING = 4 +TCIF_PARAM = 8 + +; Tab control hit test flags + +TCHT_NOWHERE = 1 +TCHT_ONITEMICON = 2 +TCHT_ONITEMLABEL = 4 +TCHT_ONITEM = TCHT_ONITEMICON or TCHT_ONITEMLABEL + +; Tab control notifications + +TCN_KEYDOWN = TCN_FIRST - 0 +TCN_SELCHANGE = TCN_FIRST - 1 +TCN_SELCHANGING = TCN_FIRST - 2 + +; Animation control styles + +ACS_CENTER = 1 +ACS_TRANSPARENT = 2 +ACS_AUTOPLAY = 4 +ACS_TIMER = 8 + +; Animation control messages + +ACM_OPENA = WM_USER + 100 +ACM_PLAY = WM_USER + 101 +ACM_STOP = WM_USER + 102 +ACM_OPENW = WM_USER + 103 +ACM_OPEN = ACM_OPENA + +; Animation control notifications + +ACN_START = 1 +ACN_STOP = 2 + +; Month calendar styles + +MCS_DAYSTATE = 1 +MCS_MULTISELECT = 2 +MCS_WEEKNUMBERS = 4 +MCS_NOTODAY_PRE_IE4 = 8 +MCS_NOTODAYCIRCLE = 8 +MCS_NOTODAY = 16 + +; Month calendar messages + +MCM_GETCURSEL = MCM_FIRST + 1 +MCM_SETCURSEL = MCM_FIRST + 2 +MCM_GETMAXSELCOUNT = MCM_FIRST + 3 +MCM_SETMAXSELCOUNT = MCM_FIRST + 4 +MCM_GETSELRANGE = MCM_FIRST + 5 +MCM_SETSELRANGE = MCM_FIRST + 6 +MCM_GETMONTHRANGE = MCM_FIRST + 7 +MCM_SETDAYSTATE = MCM_FIRST + 8 +MCM_GETMINREQRECT = MCM_FIRST + 9 +MCM_SETCOLOR = MCM_FIRST + 10 +MCM_GETCOLOR = MCM_FIRST + 11 +MCM_SETTODAY = MCM_FIRST + 12 +MCM_GETTODAY = MCM_FIRST + 13 +MCM_HITTEST = MCM_FIRST + 14 +MCM_SETFIRSTDAYOFWEEK = MCM_FIRST + 15 +MCM_GETFIRSTDAYOFWEEK = MCM_FIRST + 16 +MCM_GETRANGE = MCM_FIRST + 17 +MCM_SETRANGE = MCM_FIRST + 18 +MCM_GETMONTHDELTA = MCM_FIRST + 19 +MCM_SETMONTHDELTA = MCM_FIRST + 20 + +; Month calendar hit test flags + +MCHT_TITLE = 0010000h +MCHT_CALENDAR = 0020000h +MCHT_TODAYLINK = 0030000h +MCHT_NEXT = 1000000h +MCHT_PREV = 2000000h +MCHT_NOWHERE = 0000000h +MCHT_TITLEBK = MCHT_TITLE +MCHT_TITLEMONTH = MCHT_TITLE or 1 +MCHT_TITLEYEAR = MCHT_TITLE or 2 +MCHT_TITLEBTNNEXT = MCHT_TITLE or MCHT_NEXT or 3 +MCHT_TITLEBTNPREV = MCHT_TITLE or MCHT_PREV or 3 +MCHT_CALENDARBK = MCHT_CALENDAR +MCHT_CALENDARDATE = MCHT_CALENDAR or 1 +MCHT_CALENDARDATENEXT = MCHT_CALENDARDATE or MCHT_NEXT +MCHT_CALENDARDATEPREV = MCHT_CALENDARDATE or MCHT_PREV +MCHT_CALENDARDAY = MCHT_CALENDAR or 2 +MCHT_CALENDARWEEKNUM = MCHT_CALENDAR or 3 + +; Month calendar color codes + +MCSC_BACKGROUND = 0 +MCSC_TEXT = 1 +MCSC_TITLEBK = 2 +MCSC_TITLETEXT = 3 +MCSC_MONTHBK = 4 +MCSC_TRAILINGTEXT = 5 + +; Month calendar notifications + +MCN_SELCHANGE = MCN_FIRST + 1 +MCN_GETDAYSTATE = MCN_FIRST + 3 +MCN_SELECT = MCN_FIRST + 4 + +; Date-time pick control messages + +DTM_GETSYSTEMTIME = DTM_FIRST + 1 +DTM_SETSYSTEMTIME = DTM_FIRST + 2 +DTM_GETRANGE = DTM_FIRST + 3 +DTM_SETRANGE = DTM_FIRST + 4 +DTM_SETFORMATA = DTM_FIRST + 5 +DTM_SETMCCOLOR = DTM_FIRST + 6 +DTM_GETMCCOLOR = DTM_FIRST + 7 +DTM_GETMONTHCAL = DTM_FIRST + 8 +DTM_SETMCFONT = DTM_FIRST + 9 +DTM_GETMCFONT = DTM_FIRST + 10 +DTM_SETFORMATW = DTM_FIRST + 50 +DTM_SETFORMAT = DTM_SETFORMATA + +; Date-time pick control styles + +DTS_UPDOWN = 01h +DTS_SHOWNONE = 02h +DTS_SHORTDATEFORMAT = 00h +DTS_LONGDATEFORMAT = 04h +DTS_TIMEFORMAT = 09h +DTS_APPCANPARSE = 10h +DTS_RIGHTALIGN = 20h + +; Date-time pick control notifications + +DTN_DATETIMECHANGE = DTN_FIRST + 1 +DTN_USERSTRINGA = DTN_FIRST + 2 +DTN_WMKEYDOWNA = DTN_FIRST + 3 +DTN_FORMATA = DTN_FIRST + 4 +DTN_FORMATQUERYA = DTN_FIRST + 5 +DTN_DROPDOWN = DTN_FIRST + 6 +DTN_CLOSEUP = DTN_FIRST + 7 +DTN_USERSTRINGW = DTN_FIRST + 15 +DTN_WMKEYDOWNW = DTN_FIRST + 16 +DTN_FORMATW = DTN_FIRST + 17 +DTN_FORMATQUERYW = DTN_FIRST + 18 +DTN_USERSTRING = DTN_USERSTRINGA +DTN_WMKEYDOWN = DTN_WMKEYDOWNA +DTN_FORMAT = DTN_FORMATA +DTN_FORMATQUERY = DTN_FORMATQUERYA + +; ImageList_LoadImage types + +IMAGE_BITMAP = 0 +IMAGE_ICON = 1 +IMAGE_CURSOR = 2 +IMAGE_ENHMETAFILE = 3 + +; ImageList_LoadImage flags + +LR_DEFAULTCOLOR = 0000h +LR_MONOCHROME = 0001h +LR_COLOR = 0002h +LR_COPYRETURNORG = 0004h +LR_COPYDELETEORG = 0008h +LR_LOADFROMFILE = 0010h +LR_LOADTRANSPARENT = 0020h +LR_DEFAULTSIZE = 0040h +LR_VGACOLOR = 0080h +LR_LOADMAP3DCOLORS = 1000h +LR_CREATEDIBSECTION = 2000h +LR_COPYFROMRESOURCE = 4000h +LR_SHARED = 8000h + +; IP control messages + +IPM_CLEARADDRESS = WM_USER + 100 +IPM_SETADDRESS = WM_USER + 101 +IPM_GETADDRESS = WM_USER + 102 +IPM_SETRANGE = WM_USER + 103 +IPM_SETFOCUS = WM_USER + 104 +IPM_ISBLANK = WM_USER + 105 + +; Custom Draw flags + +CDRF_DODEFAULT = 0 +CDRF_NEWFONT = 2 +CDRF_SKIPDEFAULT = 4 +CDRF_NOTIFYPOSTPAINT = 10h +CDRF_NOTIFYITEMDRAW = 20h +CDRF_NOTIFYSUBITEMDRAW = 20h +CDRF_NOTIFYPOSTERASE = 40h +CDDS_PREPAINT = 1 +CDDS_POSTPAINT = 2 +CDDS_PREERASE = 3 +CDDS_POSTERASE = 4 +CDDS_ITEM = 10000h +CDDS_ITEMPREPAINT = CDDS_ITEM or CDDS_PREPAINT +CDDS_ITEMPOSTPAINT = CDDS_ITEM or CDDS_POSTPAINT +CDDS_ITEMPREERASE = CDDS_ITEM or CDDS_PREERASE +CDDS_ITEMPOSTERASE = CDDS_ITEM or CDDS_POSTERASE +CDDS_SUBITEM = 20000h +CDIS_SELECTED = 1 +CDIS_GRAYED = 2 +CDIS_DISABLED = 4 +CDIS_CHECKED = 8 +CDIS_FOCUS = 10h +CDIS_DEFAULT = 20h +CDIS_HOT = 40h +CDIS_MARKED = 80h +CDIS_INDETERMINATE = 100h diff --git a/toolchain/fasmw17332/INCLUDE/EQUATES/COMCTL64.INC b/toolchain/fasmw17332/INCLUDE/EQUATES/COMCTL64.INC new file mode 100644 index 0000000..10fc113 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/EQUATES/COMCTL64.INC @@ -0,0 +1,1871 @@ + +; COMCTL32.DLL structures and constants + +struct PROPSHEETPAGE + dwSize dd ? + dwFlags dd ? + hInstance dq ? + pszTemplate dq ? + pszIcon dq ? + pszTitle dq ? + pfnDlgProc dq ? + lParam dd ?,? + pfnCallback dq ? + pcRefParent dq ? +ends + +struct PROPSHEETHEADER + dwSize dd ? + dwFlags dd ? + hwndParent dq ? + hInstance dq ? + pszIcon dq ? + pszCaption dq ? + nPages dd ?,? + pStartPage dq ? + ppsp dq ? + pfnCallback dq ? +ends + +struct IMAGEINFO + hbmImage dq ? + hbmMask dq ? + Unused1 dd ? + Unused2 dd ? + rcImage RECT +ends + +struct HD_ITEM + mask dd ? + cxy dd ? + pszText dq ? + hbm dq ? + cchTextMax dd ? + fmt dd ? + lParam dd ? +ends + +struct HD_LAYOUT + prc dq ? + pwpos dq ? +ends + +struct HD_HITTESTINFO + pt POINT + flags dd ? + iItem dd ? +ends + +struct HD_NOTIFY + hdr NMHDR + iItem dd ? + iButton dd ? + pitem dq ? +ends + +struct TBBUTTON + iBitmap dd ? + idCommand dd ? + fsState db ? + fsStyle db ?,6 dup ? + dwData dq ? + iString dq ? +ends + +struct COLORMAP + from dd ? + to dd ? +ends + +struct TBADDBITMAP + hInst dq ? + nID dd ?,? +ends + +struct TBSAVEPARAMS + hkr dq ? + pszSubKey dq ? + pszValueName dq ? +ends + +struct TBREPLACEBITMAP + hInstOld dq ? + nIDOld dq ? + hInstNew dq ? + nIDNew dq ? + nButtons dq ? +ends + +struct NMTOOLBAR + hdr NMHDR + iItem dd ?,? + tbButton TBBUTTON + cchText dd ?,? + pszText dq ? +ends + +struct REBARINFO + cbSize dd ? + fMask dd ? + himl dq ? +ends + +struct REBARBANDINFO + cbSize dd ? + fMask dd ? + fStyle dd ? + clrFore dd ? + clrBack dd ?,? + lpText dq ? + cch dd ? + iImage dd ? + hwndChild dd ? + cxMinChild dd ? + cyMinChild dd ? + cx dd ? + hbmBack dq ? + wID dd ? +ends + +struct TOOLINFO + cbSize dd ? + uFlags dd ? + hwnd dq ? + uId dq ? + rect RECT + hInst dq ? + lpszText dq ? + lParam dq ? + lpReserved dq ? +ends + +struct TTHITTESTINFO + hwnd dq ? + pt POINT + ti TOOLINFO +ends + +struct TOOLTIPTEXT + hdr NMHDR + lpszText dq ? + szText db 80 dup (?) + hinst dq ? + uFlags dd ? +ends + +struct UDACCEL + nSec dd ? + nInc dd ? +ends + +struct NM_UPDOWN + hdr NMHDR + iPos dd ? + iDelta dd ? +ends + +struct LV_ITEM + mask dd ? + iItem dd ? + iSubItem dd ? + state dd ? + stateMask dd ?,? + pszText dq ? + cchTextMax dd ? + iImage dd ? + lParam dd ? + iIndent dd ? +ends + +struct LV_FINDINFO + flags dd ?,? + psz dq ? + lParam dq ? + pt POINT + vkDirection dd ? +ends + +struct LV_HITTESTINFO + pt POINT + flags dd ? + iItem dd ? +ends + +struct LV_COLUMN + mask dd ? + fmt dd ? + cx dd ?,? + pszText dq ? + cchTextMax dd ? + iSubItem dd ? +ends + +struct NM_LISTVIEW + hdr NMHDR + iItem dd ? + iSubItem dd ? + uNewState dd ? + uOldState dd ? + uChanged dd ? + ptAction POINT + dd ? + lParam dq ? +ends + +struct NM_CACHEHINT + hdr NMHDR + iFrom dd ? + iTo dd ? +ends + +struct NM_FINDITEM + hdr NMHDR + iStart dd ?,? + lvfi LV_FINDINFO +ends + +struct LV_DISPINFO + hdr NMHDR + item LV_ITEM +ends + +struct LV_KEYDOWN + hdr NMHDR + wVKey dw ?,? + flags dd ? +ends + +struct TV_ITEM + mask dd ?,? + hItem dq ? + state dd ? + stateMask dd ? + pszText dq ? + cchTextMax dd ? + iImage dd ? + iSelectedImage dd ? + cChildren dd ? + lParam dd ?,? +ends + +struct TV_INSERTSTRUCT + hParent dq ? + hInsertAfter dq ? + item TV_ITEM +ends + +struct TV_HITTESTINFO + pt POINT + flags dd ?,? + hItem dq ? +ends + +struct TV_SORTCB + hParent dq ? + lpfnCompare dq ? + lParam dq ? +ends + +struct NM_TREEVIEW + hdr NMHDR + action dd ?,? + itemOld TV_ITEM + itemNew TV_ITEM + ptDrag POINT +ends + +struct TV_DISPINFO + hdr NMHDR + item TV_ITEM +ends + +struct TV_KEYDOWN + hdr NMHDR + wVKey dw ?,? + flags dd ? +ends + +struct TC_ITEMHEADER + mask dd ? + lpReserved1 dd ? + lpReserved2 dd ?,? + pszText dq ? + cchTextMax dd ? + iImage dd ? +ends + +struct TC_ITEM + mask dd ? + lpReserved1 dd ? + lpReserved2 dd ?,? + pszText dq ? + cchTextMax dd ? + iImage dd ? + lParam dd ? +ends + +struct TC_HITTESTINFO + pt POINT + flags dd ? +ends + +struct TC_KEYDOWN + hdr NMHDR + wVKey dw ?,? + flags dd ? +ends + +struct MC_HITTESTINFO + cbSize dd ? + pt POINT + uHit dd ? + st SYSTEMTIME +ends + +struct NM_SELCHANGE + nmhdr NMHDR + stSelStart SYSTEMTIME + stSelEnd SYSTEMTIME +ends + +struct NM_DAYSTATE + nmhdr NMHDR + stStart SYSTEMTIME + cDayState dd ? + prgDayState dd ? +ends + +struct NM_DATETIMECHANGE + nmhdr NMHDR + dwFlags dd ? + st SYSTEMTIME +ends + +struct NM_DATETIMESTRING + nmhdr NMHDR + pszUserString dq ? + st SYSTEMTIME + dwFlags dd ? +ends + +struct NM_DATETIMEWMKEYDOWN + nmhdr NMHDR + nVirtKey dd ?,? + pszFormat dq ? + st SYSTEMTIME +ends + +struct NM_DATETIMEFORMAT + nmhdr NMHDR + pszFormat dq ? + st SYSTEMTIME + pszDisplay dq ? + szDisplay db 64 dup (?) +ends + +struct NM_DATETIMEFORMATQUERY + nmhdr NMHDR + pszFormat dq ? + szMax SIZE +ends + +struct INITCOMMONCONTROLSEX + dwSize dd ? + dwICC dd ? +ends + +; Common control window classes + +HOTKEY_CLASS equ 'msctls_hotkey32' +PROGRESS_CLASS equ 'msctls_progress32' +STATUS_CLASS equ 'msctls_statusbar32' +TRACKBAR_CLASS equ 'msctls_trackbar32' +UPDOWN_CLASS equ 'msctls_updown32' +TOOLTIPS_CLASS equ 'tooltips_class32' +ANIMATE_CLASS equ 'SysAnimate32' +HEADER_CLASS equ 'SysHeader32' +LISTVIEW_CLASS equ 'SysListView32' +TREEVIEW_CLASS equ 'SysTreeView32' +TABCONTROL_CLASS equ 'SysTabControl32' +MONTHCAL_CLASS equ 'SysMonthCal32' +DATETIMEPICK_CLASS equ 'SysDateTimePick32' +TOOLBAR_CLASS equ 'ToolbarWindow32' +REBAR_CLASS equ 'ReBarWindow32' + +; Ranges for control message IDs + +LVM_FIRST = 1000h +TV_FIRST = 1100h +HDM_FIRST = 1200h +TCM_FIRST = 1300h +MCM_FIRST = 1000h +DTM_FIRST = 1000h +CCM_FIRST = 2000h + +; Ranges for control notification IDs + +NM_FIRST = 0 +LVN_FIRST = -100 +PSN_FIRST = -200 +HDN_FIRST = -300 +TVN_FIRST = -400 +TTN_FIRST = -520 +TCN_FIRST = -550 +CDN_FIRST = -601 +TBN_FIRST = -700 +UDN_FIRST = -721 +MCN_FIRST = -750 +DTN_FIRST = -760 +CBEN_FIRST = -800 +RBN_FIRST = -831 + +; Generic notifications + +NM_OUTOFMEMORY = NM_FIRST - 1 +NM_CLICK = NM_FIRST - 2 +NM_DBLCLK = NM_FIRST - 3 +NM_RETURN = NM_FIRST - 4 +NM_RCLICK = NM_FIRST - 5 +NM_RDBLCLK = NM_FIRST - 6 +NM_SETFOCUS = NM_FIRST - 7 +NM_KILLFOCUS = NM_FIRST - 8 +NM_CUSTOMDRAW = NM_FIRST - 12 + +; Common control styles + +CCS_TOP = 01h +CCS_NOMOVEY = 02h +CCS_BOTTOM = 03h +CCS_NORESIZE = 04h +CCS_NOPARENTALIGN = 08h +CCS_ADJUSTABLE = 20h +CCS_NODIVIDER = 40h +CCS_VERT = 80h +CCS_LEFT = CCS_VERT or CCS_TOP +CCS_RIGHT = CCS_VERT or CCS_BOTTOM +CCS_NOMOVEX = CCS_VERT or CCS_NOMOVEY + +; Owner-drawn control types + +ODT_HEADER = 100 +ODT_TAB = 101 +ODT_LISTVIEW = 102 + +; InitCommonControlsEx classes + +ICC_ANIMATE_CLASS = 0080h +ICC_BAR_CLASSES = 0004h +ICC_COOL_CLASSES = 0400h +ICC_DATE_CLASSES = 0100h +ICC_HOTKEY_CLASS = 0040h +ICC_INTERNET_CLASSES = 0800h +ICC_LISTVIEW_CLASSES = 0001h +ICC_PAGESCROLLER_CLASS = 1000h +ICC_PROGRESS_CLASS = 0020h +ICC_TAB_CLASSES = 0008h +ICC_TREEVIEW_CLASSES = 0002h +ICC_UPDOWN_CLASS = 0010h +ICC_USEREX_CLASSES = 0200h +ICC_WIN95_CLASSES = 00FFh + +; Shared messages + +CCM_SETCOLORSCHEME = CCM_FIRST + 2 +CCM_GETCOLORSCHEME = CCM_FIRST + 3 +CCM_GETDROPTARGET = CCM_FIRST + 4 +CCM_SETUNICODEFORMAT = CCM_FIRST + 5 +CCM_GETUNICODEFORMAT = CCM_FIRST + 6 + +; Property sheet page flags + +PSP_DEFAULT = 0000h +PSP_DLGINDIRECT = 0001h +PSP_USEHICON = 0002h +PSP_USEICONID = 0004h +PSP_USETITLE = 0008h +PSP_HASHELP = 0020h +PSP_USEREFPARENT = 0040h +PSP_USECALLBACK = 0080h + +; Property sheet page actions + +PSPCB_RELEASE = 1 +PSPCB_CREATE = 2 + +; Property sheet header flags + +PSH_DEFAULT = 0000h +PSH_PROPTITLE = 0001h +PSH_USEHICON = 0002h +PSH_USEICONID = 0004h +PSH_PROPSHEETPAGE = 0008h +PSH_MULTILINETABS = 0010h +PSH_WIZARD = 0020h +PSH_USEPSTARTPAGE = 0040h +PSH_NOAPPLYNOW = 0080h +PSH_USECALLBACK = 0100h +PSH_HASHELP = 0200h +PSH_MODELESS = 0400h + +; Property sheet actions + +PSCB_INITIALIZED = 1 + +; Property sheet notifications + +PSN_SETACTIVE = PSN_FIRST - 0 +PSN_KILLACTIVE = PSN_FIRST - 1 +PSN_APPLY = PSN_FIRST - 2 +PSN_RESET = PSN_FIRST - 3 +PSN_HELP = PSN_FIRST - 5 +PSN_WIZBACK = PSN_FIRST - 6 +PSN_WIZNEXT = PSN_FIRST - 7 +PSN_WIZFINISH = PSN_FIRST - 8 +PSN_QUERYCANCEL = PSN_FIRST - 9 + +; Property sheet return values + +PSNRET_NOERROR = 0 +PSNRET_INVALID = 1 +PSNRET_INVALID_NOCHANGEPAGE = 2 + +; Property sheet messages + +PSM_SETCURSEL = WM_USER + 101 +PSM_REMOVEPAGE = WM_USER + 102 +PSM_ADDPAGE = WM_USER + 103 +PSM_CHANGED = WM_USER + 104 +PSM_RESTARTWINDOWS = WM_USER + 105 +PSM_REBOOTSYSTEM = WM_USER + 106 +PSM_CANCELTOCLOSE = WM_USER + 107 +PSM_QUERYSIBLINGS = WM_USER + 108 +PSM_UNCHANGED = WM_USER + 109 +PSM_APPLY = WM_USER + 110 +PSM_SETTITLE = WM_USER + 111 +PSM_SETTITLEW = WM_USER + 120 +PSM_SETWIZBUTTONS = WM_USER + 112 +PSM_PRESSBUTTON = WM_USER + 113 +PSM_SETCURSELID = WM_USER + 114 +PSM_SETFINISHTEXT = WM_USER + 115 +PSM_SETFINISHTEXTW = WM_USER + 121 +PSM_GETTABCONTROL = WM_USER + 116 +PSM_ISDIALOGMESSAGE = WM_USER + 117 + +; Property sheet buttons + +PSBTN_BACK = 0 +PSBTN_NEXT = 1 +PSBTN_FINISH = 2 +PSBTN_OK = 3 +PSBTN_APPLYNOW = 4 +PSBTN_CANCEL = 5 +PSBTN_HELP = 6 +PSWIZB_BACK = 1 +PSWIZB_NEXT = 2 +PSWIZB_FINISH = 4 +PSWIZB_DISABLEDFINISH = 8 +ID_PSRESTARTWINDOWS = 2 +ID_PSREBOOTSYSTEM = ID_PSRESTARTWINDOWS or 1 + +; Property sheet sizes + +PROP_SM_CXDLG = 212 +PROP_SM_CYDLG = 188 +PROP_MED_CXDLG = 227 +PROP_MED_CYDLG = 215 +PROP_LG_CXDLG = 252 +PROP_LG_CYDLG = 218 +WIZ_CXDLG = 276 +WIZ_CYDLG = 140 +WIZ_CXBMP = 80 +WIZ_BODYX = 92 +WIZ_BODYCX = 184 + +; Image list types + +ILC_MASK = 001h +ILC_COLOR = 0FEh +ILC_COLORDDB = 0FEh +ILC_COLOR4 = 004h +ILC_COLOR8 = 008h +ILC_COLOR16 = 010h +ILC_COLOR24 = 018h +ILC_COLOR32 = 020h +ILC_PALETTE = 800h + +; Image list color values + +CLR_NONE = 0FFFFFFFFh +CLR_DEFAULT = 0FF000000h +CLR_HILIGHT = CLR_DEFAULT + +; Image list drawing styles + +ILD_NORMAL = 0000h +ILD_TRANSPARENT = 0001h +ILD_MASK = 0010h +ILD_IMAGE = 0020h +ILD_BLEND25 = 0002h +ILD_BLEND50 = 0004h +ILD_OVERLAYMASK = 0F00h +ILD_SELECTED = ILD_BLEND50 +ILD_FOCUS = ILD_BLEND25 +ILD_BLEND = ILD_BLEND50 + +; Header control styles + +HDS_HORZ = 00h +HDS_BUTTONS = 02h +HDS_HOTTRACK = 04h +HDS_HIDDEN = 08h +HDS_DRAGDROP = 40h +HDS_FULLDRAG = 80h + +; Header control structure flags + +HDI_WIDTH = 01h +HDI_HEIGHT = HDI_WIDTH +HDI_TEXT = 02h +HDI_FORMAT = 04h +HDI_LPARAM = 08h +HDI_BITMAP = 10h + +; Header control flags + +HDF_LEFT = 0000h +HDF_RIGHT = 0001h +HDF_CENTER = 0002h +HDF_JUSTIFYMASK = 0003h +HDF_RTLREADING = 0004h +HDF_BITMAP = 2000h +HDF_STRING = 4000h +HDF_OWNERDRAW = 8000h + +; Header control messages + +HDM_GETITEMCOUNT = HDM_FIRST + 0 +HDM_INSERTITEMA = HDM_FIRST + 1 +HDM_DELETEITEM = HDM_FIRST + 2 +HDM_GETITEMA = HDM_FIRST + 3 +HDM_SETITEMA = HDM_FIRST + 4 +HDM_LAYOUT = HDM_FIRST + 5 +HDM_HITTEST = HDM_FIRST + 6 +HDM_INSERTITEMW = HDM_FIRST + 10 +HDM_GETITEMW = HDM_FIRST + 11 +HDM_SETITEMW = HDM_FIRST + 12 +HDM_INSERTITEM = HDM_INSERTITEMA +HDM_GETITEM = HDM_GETITEMA +HDM_SETITEM = HDM_SETITEMA + +; Hit test result flags + +HHT_NOWHERE = 001h +HHT_ONHEADER = 002h +HHT_ONDIVIDER = 004h +HHT_ONDIVOPEN = 008h +HHT_ABOVE = 100h +HHT_BELOW = 200h +HHT_TORIGHT = 400h +HHT_TOLEFT = 800h + +; Header control notifications + +HDN_ITEMCHANGINGA = HDN_FIRST - 0 +HDN_ITEMCHANGEDA = HDN_FIRST - 1 +HDN_ITEMCLICKA = HDN_FIRST - 2 +HDN_ITEMDBLCLICKA = HDN_FIRST - 3 +HDN_DIVIDERDBLCLICKA = HDN_FIRST - 5 +HDN_BEGINTRACKA = HDN_FIRST - 6 +HDN_ENDTRACKA = HDN_FIRST - 7 +HDN_TRACKA = HDN_FIRST - 8 +HDN_ITEMCHANGINGW = HDN_FIRST - 20 +HDN_ITEMCHANGEDW = HDN_FIRST - 21 +HDN_ITEMCLICKW = HDN_FIRST - 22 +HDN_ITEMDBLCLICKW = HDN_FIRST - 23 +HDN_DIVIDERDBLCLICKW = HDN_FIRST - 25 +HDN_BEGINTRACKW = HDN_FIRST - 26 +HDN_ENDTRACKW = HDN_FIRST - 27 +HDN_TRACKW = HDN_FIRST - 28 +HDN_ITEMCHANGING = HDN_ITEMCHANGINGA +HDN_ITEMCHANGED = HDN_ITEMCHANGEDA +HDN_ITEMCLICK = HDN_ITEMCLICKA +HDN_ITEMDBLCLICK = HDN_ITEMDBLCLICKA +HDN_DIVIDERDBLCLICK = HDN_DIVIDERDBLCLICKA +HDN_BEGINTRACK = HDN_BEGINTRACKA +HDN_ENDTRACK = HDN_ENDTRACKA +HDN_TRACK = HDN_TRACKA + +; Toolbar bitmap flags + +CMB_MASKED = 2 + +; Toolbar button states + +TBSTATE_CHECKED = 01h +TBSTATE_PRESSED = 02h +TBSTATE_ENABLED = 04h +TBSTATE_HIDDEN = 08h +TBSTATE_INDETERMINATE = 10h +TBSTATE_WRAP = 20h +TBSTATE_ELLIPSES = 40h + +; Toolbar button styles + +TBSTYLE_BUTTON = 0000h +TBSTYLE_SEP = 0001h +TBSTYLE_CHECK = 0002h +TBSTYLE_GROUP = 0004h +TBSTYLE_CHECKGROUP = TBSTYLE_GROUP or TBSTYLE_CHECK +TBSTYLE_DROPDOWN = 0008h +TBSTYLE_TOOLTIPS = 0100h +TBSTYLE_WRAPABLE = 0200h +TBSTYLE_ALTDRAG = 0400h +TBSTYLE_FLAT = 0800h +TBSTYLE_LIST = 1000h +TBSTYLE_CUSTOMERASE = 2000h +TBSTYLE_TRANSPARENT = 8000h + +; Toolbar button extended styles + +TBSTYLE_EX_DRAWDDARROWS = 0001h + +; Toolbar messages + +TB_ENABLEBUTTON = WM_USER + 1 +TB_CHECKBUTTON = WM_USER + 2 +TB_PRESSBUTTON = WM_USER + 3 +TB_HIDEBUTTON = WM_USER + 4 +TB_INDETERMINATE = WM_USER + 5 +TB_ISBUTTONENABLED = WM_USER + 9 +TB_ISBUTTONCHECKED = WM_USER + 10 +TB_ISBUTTONPRESSED = WM_USER + 11 +TB_ISBUTTONHIDDEN = WM_USER + 12 +TB_ISBUTTONINDETERMINATE = WM_USER + 13 +TB_SETSTATE = WM_USER + 17 +TB_GETSTATE = WM_USER + 18 +TB_ADDBITMAP = WM_USER + 19 +TB_ADDBUTTONS = WM_USER + 20 +TB_INSERTBUTTON = WM_USER + 21 +TB_DELETEBUTTON = WM_USER + 22 +TB_GETBUTTON = WM_USER + 23 +TB_BUTTONCOUNT = WM_USER + 24 +TB_COMMANDTOINDEX = WM_USER + 25 +TB_SAVERESTOREA = WM_USER + 26 +TB_ADDSTRINGA = WM_USER + 28 +TB_CUSTOMIZE = WM_USER + 27 +TB_GETITEMRECT = WM_USER + 29 +TB_BUTTONSTRUCTSIZE = WM_USER + 30 +TB_SETBUTTONSIZE = WM_USER + 31 +TB_SETBITMAPSIZE = WM_USER + 32 +TB_AUTOSIZE = WM_USER + 33 +TB_GETTOOLTIPS = WM_USER + 35 +TB_SETTOOLTIPS = WM_USER + 36 +TB_SETPARENT = WM_USER + 37 +TB_SETROWS = WM_USER + 39 +TB_GETROWS = WM_USER + 40 +TB_GETBITMAPFLAGS = WM_USER + 41 +TB_SETCMDID = WM_USER + 42 +TB_CHANGEBITMAP = WM_USER + 43 +TB_GETBITMAP = WM_USER + 44 +TB_GETBUTTONTEXTA = WM_USER + 45 +TB_REPLACEBITMAP = WM_USER + 46 +TB_SETINDENT = WM_USER + 47 +TB_SETIMAGELIST = WM_USER + 48 +TB_GETIMAGELIST = WM_USER + 49 +TB_LOADIMAGES = WM_USER + 50 +TB_GETRECT = WM_USER + 51 +TB_SETHOTIMAGELIST = WM_USER + 52 +TB_GETHOTIMAGELIST = WM_USER + 53 +TB_SETDISABLEDIMAGELIST = WM_USER + 54 +TB_GETDISABLEDIMAGELIST = WM_USER + 55 +TB_SETSTYLE = WM_USER + 56 +TB_GETSTYLE = WM_USER + 57 +TB_GETBUTTONSIZE = WM_USER + 58 +TB_SETBUTTONWIDTH = WM_USER + 59 +TB_SETMAXTEXTROWS = WM_USER + 60 +TB_GETTEXTROWS = WM_USER + 61 +TB_GETBUTTONTEXTW = WM_USER + 75 +TB_SAVERESTOREW = WM_USER + 76 +TB_ADDSTRINGW = WM_USER + 77 +TB_SETEXTENDEDSTYLE = WM_USER + 84 +TB_GETEXTENDEDSTYLE = WM_USER + 85 +TB_GETBUTTONTEXT = TB_GETBUTTONTEXTA +TB_SAVERESTORE = TB_SAVERESTOREA +TB_ADDSTRING = TB_ADDSTRINGA + +; System-defined button bitmaps + +HINST_COMMCTRL = -1 +IDB_STD_SMALL_COLOR = 0 +IDB_STD_LARGE_COLOR = 1 +IDB_VIEW_SMALL_COLOR = 4 +IDB_VIEW_LARGE_COLOR = 5 +IDB_HIST_SMALL_COLOR = 8 +IDB_HIST_LARGE_COLOR = 9 + +; Icon indexes for standard bitmap + +STD_CUT = 0 +STD_COPY = 1 +STD_PASTE = 2 +STD_UNDO = 3 +STD_REDOW = 4 +STD_DELETE = 5 +STD_FILENEW = 6 +STD_FILEOPEN = 7 +STD_FILESAVE = 8 +STD_PRINTPRE = 9 +STD_PROPERTIES = 10 +STD_HELP = 11 +STD_FIND = 12 +STD_REPLACE = 13 +STD_PRINT = 14 + +; Icon indexes for standard view bitmap + +VIEW_LARGEICONS = 0 +VIEW_SMALLICONS = 1 +VIEW_LIST = 2 +VIEW_DETAILS = 3 +VIEW_SORTNAME = 4 +VIEW_SORTSIZE = 5 +VIEW_SORTDATE = 6 +VIEW_SORTTYPE = 7 +VIEW_PARENTFOLDER = 8 +VIEW_NETCONNECT = 9 +VIEW_NETDISCONNECT = 10 +VIEW_NEWFOLDER = 11 + +; Icon indexes for history bitmap + +HIST_BACK = 0 +HIST_FORWARD = 1 +HIST_FAVORITES = 2 +HIST_ADDTOFAVORITES = 3 +HIST_VIEWTREE = 4 + +; Toolbar bitmap flags + +TBBF_LARGE = 1 + +; Toolbar notifications + +TBN_GETBUTTONINFOA = TBN_FIRST - 0 +TBN_BEGINDRAG = TBN_FIRST - 1 +TBN_ENDDRAG = TBN_FIRST - 2 +TBN_BEGINADJUST = TBN_FIRST - 3 +TBN_ENDADJUST = TBN_FIRST - 4 +TBN_RESET = TBN_FIRST - 5 +TBN_QUERYINSERT = TBN_FIRST - 6 +TBN_QUERYDELETE = TBN_FIRST - 7 +TBN_TOOLBARCHANGE = TBN_FIRST - 8 +TBN_CUSTHELP = TBN_FIRST - 9 +TBN_DROPDOWN = TBN_FIRST - 10 +TBN_CLOSEUP = TBN_FIRST - 11 +TBN_GETBUTTONINFOW = TBN_FIRST - 20 +TBN_GETBUTTONINFO = TBN_GETBUTTONINFOA + +; ReBar styles + +RBS_TOOLTIPS = 100h +RBS_VARHEIGHT = 200h +RBS_BANDBORDERS = 400h +RBS_FIXEDORDER = 800h +RBS_REGISTERDROP = 1000h +RBS_AUTOSIZE = 2000h +RBS_VERTICALGRIPPER = 4000h +RBS_DBLCLKTOGGLE = 8000h + +; ReBar band info structure flags + +RBBIM_STYLE = 001h +RBBIM_COLORS = 002h +RBBIM_TEXT = 004h +RBBIM_IMAGE = 008h +RBBIM_CHILD = 010h +RBBIM_CHILDSIZE = 020h +RBBIM_SIZE = 040h +RBBIM_BACKGROUND = 080h +RBBIM_ID = 100h +RBBIM_IDEALSIZE = 200h +RBBIM_LPARAM = 400h +RBBIM_HEADERSIZE = 800h + +; ReBar band styles + +RBBS_BREAK = 001h +RBBS_FIXEDSIZE = 002h +RBBS_CHILDEDGE = 004h +RBBS_HIDDEN = 008h +RBBS_NOVERT = 010h +RBBS_FIXEDBMP = 020h +RBBS_VARIABLEHEIGHT = 040h +RBBS_GRIPPERALWAYS = 080h +RBBS_NOGRIPPER = 100h + +; ReBar messages + +RB_INSERTBANDA = WM_USER + 1 +RB_DELETEBAND = WM_USER + 2 +RB_GETBARINFO = WM_USER + 3 +RB_SETBARINFO = WM_USER + 4 +RB_GETBANDINFO = WM_USER + 5 +RB_SETBANDINFOA = WM_USER + 6 +RB_SETPARENT = WM_USER + 7 +RB_INSERTBANDW = WM_USER + 10 +RB_SETBANDINFOW = WM_USER + 11 +RB_GETBANDCOUNT = WM_USER + 12 +RB_GETROWCOUNT = WM_USER + 13 +RB_GETROWHEIGHT = WM_USER + 14 +RB_IDTOINDEX = WM_USER + 16 +RB_GETTOOLTIPS = WM_USER + 17 +RB_SETTOOLTIPS = WM_USER + 18 +RB_SETBKCOLOR = WM_USER + 19 +RB_GETBKCOLOR = WM_USER + 20 +RB_SETTEXTCOLOR = WM_USER + 21 +RB_GETTEXTCOLOR = WM_USER + 22 +RB_SIZETORECT = WM_USER + 23 +RB_BEGINDRAG = WM_USER + 24 +RB_ENDDRAG = WM_USER + 25 +RB_DRAGMOVE = WM_USER + 26 +RB_GETBARHEIGHT = WM_USER + 27 +RB_GETBANDINFOW = WM_USER + 28 +RB_GETBANDINFOA = WM_USER + 29 +RB_MINIMIZEBAND = WM_USER + 30 +RB_MAXIMIZEBAND = WM_USER + 31 +RB_GETDROPTARGET = CCM_GETDROPTARGET +RB_GETBANDBORDERS = WM_USER + 34 +RB_SHOWBAND = WM_USER + 35 +RB_SETPALETTE = WM_USER + 37 +RB_GETPALETTE = WM_USER + 38 +RB_MOVEBAND = WM_USER + 39 +RB_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT +RB_GETUNICODEFORMAT = CCM_GETUNICODEFORMAT +RB_INSERTBAND = RB_INSERTBANDA +RB_SETBANDINFO = RB_SETBANDINFOA + +; ReBar notifications + +RBN_HEIGHTCHANGE = RBN_FIRST - 0 +RBN_GETOBJECT = RBN_FIRST - 1 +RBN_LAYOUTCHANGED = RBN_FIRST - 2 +RBN_AUTOSIZE = RBN_FIRST - 3 +RBN_BEGINDRAG = RBN_FIRST - 4 +RBN_ENDDRAG = RBN_FIRST - 5 +RBN_DELETINGBAND = RBN_FIRST - 6 +RBN_DELETEDBAND = RBN_FIRST - 7 +RBN_CHILDSIZE = RBN_FIRST - 8 + +; Tooltip styles + +TTS_ALWAYSTIP = 1 +TTS_NOPREFIX = 2 + +; Tooltip flags + +TTF_IDISHWND = 01h +TTF_CENTERTIP = 02h +TTF_RTLREADING = 04h +TTF_SUBCLASS = 10h + +; Tooltip durations + +TTDT_AUTOMATIC = 0 +TTDT_RESHOW = 1 +TTDT_AUTOPOP = 2 +TTDT_INITIAL = 3 + +; Tooltip messages + +TTM_ACTIVATE = WM_USER + 1 +TTM_SETDELAYTIME = WM_USER + 3 +TTM_ADDTOOLA = WM_USER + 4 +TTM_DELTOOLA = WM_USER + 5 +TTM_NEWTOOLRECTA = WM_USER + 6 +TTM_RELAYEVENT = WM_USER + 7 +TTM_GETTOOLINFOA = WM_USER + 8 +TTM_SETTOOLINFOA = WM_USER + 9 +TTM_HITTESTA = WM_USER + 10 +TTM_GETTEXTA = WM_USER + 11 +TTM_UPDATETIPTEXTA = WM_USER + 12 +TTM_GETTOOLCOUNT = WM_USER + 13 +TTM_ENUMTOOLSA = WM_USER + 14 +TTM_GETCURRENTTOOLA = WM_USER + 15 +TTM_WINDOWFROMPOINT = WM_USER + 16 +TTM_ADDTOOLW = WM_USER + 50 +TTM_DELTOOLW = WM_USER + 51 +TTM_NEWTOOLRECTW = WM_USER + 52 +TTM_GETTOOLINFOW = WM_USER + 53 +TTM_SETTOOLINFOW = WM_USER + 54 +TTM_HITTESTW = WM_USER + 55 +TTM_GETTEXTW = WM_USER + 56 +TTM_UPDATETIPTEXTW = WM_USER + 57 +TTM_ENUMTOOLSW = WM_USER + 58 +TTM_GETCURRENTTOOLW = WM_USER + 59 +TTM_ADDTOOL = TTM_ADDTOOLA +TTM_DELTOOL = TTM_DELTOOLA +TTM_NEWTOOLRECT = TTM_NEWTOOLRECTA +TTM_GETTOOLINFO = TTM_GETTOOLINFOA +TTM_SETTOOLINFO = TTM_SETTOOLINFOA +TTM_HITTEST = TTM_HITTESTA +TTM_GETTEXT = TTM_GETTEXTA +TTM_UPDATETIPTEXT = TTM_UPDATETIPTEXTA +TTM_ENUMTOOLS = TTM_ENUMTOOLSA +TTM_GETCURRENTTOOL = TTM_GETCURRENTTOOLA + +; Tooltip notifications + +TTN_NEEDTEXTA = TTN_FIRST - 0 +TTN_SHOW = TTN_FIRST - 1 +TTN_POP = TTN_FIRST - 2 +TTN_NEEDTEXTW = TTN_FIRST - 10 +TTN_NEEDTEXT = TTN_NEEDTEXTA + +; Status bar styles + +SBARS_SIZEGRIP = 100h + +; Status bar messages + +SB_SETTEXTA = WM_USER + 1 +SB_GETTEXTA = WM_USER + 2 +SB_GETTEXTLENGTHA = WM_USER + 3 +SB_SETPARTS = WM_USER + 4 +SB_GETPARTS = WM_USER + 6 +SB_GETBORDERS = WM_USER + 7 +SB_SETMINHEIGHT = WM_USER + 8 +SB_SIMPLE = WM_USER + 9 +SB_GETRECT = WM_USER + 10 +SB_SETTEXTW = WM_USER + 11 +SB_GETTEXTW = WM_USER + 13 +SB_GETTEXTLENGTHW = WM_USER + 12 +SB_SETTEXT = SB_SETTEXTA +SB_GETTEXT = SB_GETTEXTA +SB_GETTEXTLENGTH = SB_GETTEXTLENGTHA + +; Status bar drawing types + +SBT_OWNERDRAW = 1000h +SBT_NOBORDERS = 0100h +SBT_POPOUT = 0200h +SBT_RTLREADING = 0400h + +; Trackbar styles + +TBS_AUTOTICKS = 01h +TBS_VERT = 02h +TBS_HORZ = 00h +TBS_TOP = 04h +TBS_BOTTOM = 00h +TBS_LEFT = 04h +TBS_RIGHT = 00h +TBS_BOTH = 08h +TBS_NOTICKS = 10h +TBS_ENABLESELRANGE = 20h +TBS_FIXEDLENGTH = 40h +TBS_NOTHUMB = 80h + +; Trackbar messages + +TBM_GETPOS = WM_USER + 0 +TBM_GETRANGEMIN = WM_USER + 1 +TBM_GETRANGEMAX = WM_USER + 2 +TBM_GETTIC = WM_USER + 3 +TBM_SETTIC = WM_USER + 4 +TBM_SETPOS = WM_USER + 5 +TBM_SETRANGE = WM_USER + 6 +TBM_SETRANGEMIN = WM_USER + 7 +TBM_SETRANGEMAX = WM_USER + 8 +TBM_CLEARTICS = WM_USER + 9 +TBM_SETSEL = WM_USER + 10 +TBM_SETSELSTART = WM_USER + 11 +TBM_SETSELEND = WM_USER + 12 +TBM_GETPTICS = WM_USER + 14 +TBM_GETTICPOS = WM_USER + 15 +TBM_GETNUMTICS = WM_USER + 16 +TBM_GETSELSTART = WM_USER + 17 +TBM_GETSELEND = WM_USER + 18 +TBM_CLEARSEL = WM_USER + 19 +TBM_SETTICFREQ = WM_USER + 20 +TBM_SETPAGESIZE = WM_USER + 21 +TBM_GETPAGESIZE = WM_USER + 22 +TBM_SETLINESIZE = WM_USER + 23 +TBM_GETLINESIZE = WM_USER + 24 +TBM_GETTHUMBRECT = WM_USER + 25 +TBM_GETCHANNELRECT = WM_USER + 26 +TBM_SETTHUMBLENGTH = WM_USER + 27 +TBM_GETTHUMBLENGTH = WM_USER + 28 + +; Trackbar notifications + +TB_LINEUP = 0 +TB_LINEDOWN = 1 +TB_PAGEUP = 2 +TB_PAGEDOWN = 3 +TB_THUMBPOSITION = 4 +TB_THUMBTRACK = 5 +TB_TOP = 6 +TB_BOTTOM = 7 +TB_ENDTRACK = 8 + +; Up-down control styles + +UDS_WRAP = 01h +UDS_SETBUDDYINT = 02h +UDS_ALIGNRIGHT = 04h +UDS_ALIGNLEFT = 08h +UDS_AUTOBUDDY = 10h +UDS_ARROWKEYS = 20h +UDS_HORZ = 40h +UDS_NOTHOUSANDS = 80h + +; Up-down control messages + +UDM_SETRANGE = WM_USER + 101 +UDM_GETRANGE = WM_USER + 102 +UDM_SETPOS = WM_USER + 103 +UDM_GETPOS = WM_USER + 104 +UDM_SETBUDDY = WM_USER + 105 +UDM_GETBUDDY = WM_USER + 106 +UDM_SETACCEL = WM_USER + 107 +UDM_GETACCEL = WM_USER + 108 +UDM_SETBASE = WM_USER + 109 +UDM_GETBASE = WM_USER + 110 + +; Up-down control notifications + +UDN_DELTAPOS = UDN_FIRST - 1 + +; Progress bar messages + +PBM_SETRANGE = WM_USER + 1 +PBM_SETPOS = WM_USER + 2 +PBM_DELTAPOS = WM_USER + 3 +PBM_SETSTEP = WM_USER + 4 +PBM_STEPIT = WM_USER + 5 +PBM_SETRANGE32 = WM_USER + 6 +PBM_GETRANGE = WM_USER + 7 +PBM_GETPOS = WM_USER + 8 + +; Hot-key control messages + +HKM_SETHOTKEY = WM_USER + 1 +HKM_GETHOTKEY = WM_USER + 2 +HKM_SETRULES = WM_USER + 3 + +; Hot key flags + +HOTKEYF_SHIFT = 1 +HOTKEYF_CONTROL = 2 +HOTKEYF_ALT = 4 +HOTKEYF_EXT = 8 + +; Key combination flags + +HKCOMB_NONE = 01h +HKCOMB_S = 02h +HKCOMB_C = 04h +HKCOMB_A = 08h +HKCOMB_SC = 10h +HKCOMB_SA = 20h +HKCOMB_CA = 40h +HKCOMB_SCA = 80h + +; List view styles + +LVS_ICON = 0000h +LVS_REPORT = 0001h +LVS_SMALLICON = 0002h +LVS_LIST = 0003h +LVS_TYPEMASK = 0003h +LVS_SINGLESEL = 0004h +LVS_SHOWSELALWAYS = 0008h +LVS_SORTASCENDING = 0010h +LVS_SORTDESCENDING = 0020h +LVS_SHAREIMAGELISTS = 0040h +LVS_NOLABELWRAP = 0080h +LVS_AUTOARRANGE = 0100h +LVS_EDITLABELS = 0200h +LVS_OWNERDATA = 1000h +LVS_NOSCROLL = 2000h +LVS_ALIGNTOP = 0000h +LVS_ALIGNLEFT = 0800h +LVS_OWNERDRAWFIXED = 0400h +LVS_NOCOLUMNHEADER = 4000h +LVS_NOSORTHEADER = 8000h + +; List view extended styles + +LVS_EX_GRIDLINES = 0001h +LVS_EX_SUBITEMIMAGES = 0002h +LVS_EX_CHECKBOXES = 0004h +LVS_EX_TRACKSELECT = 0008h +LVS_EX_HEADERDRAGDROP = 0010h +LVS_EX_FULLROWSELECT = 0020h +LVS_EX_ONECLICKACTIVATE = 0040h +LVS_EX_TWOCLICKACTIVATE = 0080h +LVS_EX_FLATSB = 0100h +LVS_EX_REGIONAL = 0200h +LVS_EX_INFOTIP = 0400h +LVS_EX_UNDERLINEHOT = 0800h +LVS_EX_UNDERLINECOLD = 1000h +LVS_EX_MULTIWORKAREAS = 2000h +LVS_EX_LABELTIP = 4000h + +; List view messages + +LVM_GETBKCOLOR = LVM_FIRST + 0 +LVM_SETBKCOLOR = LVM_FIRST + 1 +LVM_GETIMAGELIST = LVM_FIRST + 2 +LVM_SETIMAGELIST = LVM_FIRST + 3 +LVM_GETITEMCOUNT = LVM_FIRST + 4 +LVM_GETITEMA = LVM_FIRST + 5 +LVM_SETITEMA = LVM_FIRST + 6 +LVM_INSERTITEMA = LVM_FIRST + 7 +LVM_DELETEITEM = LVM_FIRST + 8 +LVM_DELETEALLITEMS = LVM_FIRST + 9 +LVM_GETCALLBACKMASK = LVM_FIRST + 10 +LVM_SETCALLBACKMASK = LVM_FIRST + 11 +LVM_GETNEXTITEM = LVM_FIRST + 12 +LVM_FINDITEMA = LVM_FIRST + 13 +LVM_GETITEMRECT = LVM_FIRST + 14 +LVM_SETITEMPOSITION = LVM_FIRST + 15 +LVM_GETITEMPOSITION = LVM_FIRST + 16 +LVM_GETSTRINGWIDTHA = LVM_FIRST + 17 +LVM_HITTEST = LVM_FIRST + 18 +LVM_ENSUREVISIBLE = LVM_FIRST + 19 +LVM_SCROLL = LVM_FIRST + 20 +LVM_REDRAWITEMS = LVM_FIRST + 21 +LVM_ARRANGE = LVM_FIRST + 22 +LVM_EDITLABELA = LVM_FIRST + 23 +LVM_GETEDITCONTROL = LVM_FIRST + 24 +LVM_GETCOLUMNA = LVM_FIRST + 25 +LVM_SETCOLUMNA = LVM_FIRST + 26 +LVM_INSERTCOLUMNA = LVM_FIRST + 27 +LVM_DELETECOLUMN = LVM_FIRST + 28 +LVM_GETCOLUMNWIDTH = LVM_FIRST + 29 +LVM_SETCOLUMNWIDTH = LVM_FIRST + 30 +LVM_CREATEDRAGIMAGE = LVM_FIRST + 33 +LVM_GETVIEWRECT = LVM_FIRST + 34 +LVM_GETTEXTCOLOR = LVM_FIRST + 35 +LVM_SETTEXTCOLOR = LVM_FIRST + 36 +LVM_GETTEXTBKCOLOR = LVM_FIRST + 37 +LVM_SETTEXTBKCOLOR = LVM_FIRST + 38 +LVM_GETTOPINDEX = LVM_FIRST + 39 +LVM_GETCOUNTPERPAGE = LVM_FIRST + 40 +LVM_GETORIGIN = LVM_FIRST + 41 +LVM_UPDATE = LVM_FIRST + 42 +LVM_SETITEMSTATE = LVM_FIRST + 43 +LVM_GETITEMSTATE = LVM_FIRST + 44 +LVM_GETITEMTEXTA = LVM_FIRST + 45 +LVM_SETITEMTEXTA = LVM_FIRST + 46 +LVM_SETITEMCOUNT = LVM_FIRST + 47 +LVM_SORTITEMS = LVM_FIRST + 48 +LVM_SETITEMPOSITION32 = LVM_FIRST + 49 +LVM_GETSELECTEDCOUNT = LVM_FIRST + 50 +LVM_GETITEMSPACING = LVM_FIRST + 51 +LVM_GETISEARCHSTRINGA = LVM_FIRST + 52 +LVM_SETICONSPACING = LVM_FIRST + 53 +LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54 +LVM_GETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 55 +LVM_GETSUBITEMRECT = LVM_FIRST + 56 +LVM_SUBITEMHITTEST = LVM_FIRST + 57 +LVM_SETCOLUMNORDERARRAY = LVM_FIRST + 58 +LVM_GETCOLUMNORDERARRAY = LVM_FIRST + 59 +LVM_SETHOTITEM = LVM_FIRST + 60 +LVM_GETHOTITEM = LVM_FIRST + 61 +LVM_SETHOTCURSOR = LVM_FIRST + 62 +LVM_GETHOTCURSOR = LVM_FIRST + 63 +LVM_APPROXIMATEVIEWRECT = LVM_FIRST + 64 +LVM_SETWORKAREA = LVM_FIRST + 65 +LVM_GETITEMW = LVM_FIRST + 75 +LVM_SETITEMW = LVM_FIRST + 76 +LVM_INSERTITEMW = LVM_FIRST + 77 +LVM_FINDITEMW = LVM_FIRST + 83 +LVM_GETSTRINGWIDTHW = LVM_FIRST + 87 +LVM_GETCOLUMNW = LVM_FIRST + 95 +LVM_SETCOLUMNW = LVM_FIRST + 96 +LVM_INSERTCOLUMNW = LVM_FIRST + 97 +LVM_GETITEMTEXTW = LVM_FIRST + 115 +LVM_SETITEMTEXTW = LVM_FIRST + 116 +LVM_GETISEARCHSTRINGW = LVM_FIRST + 117 +LVM_EDITLABELW = LVM_FIRST + 118 +LVM_GETITEM = LVM_GETITEMA +LVM_SETITEM = LVM_SETITEMA +LVM_INSERTITEM = LVM_INSERTITEMA +LVM_FINDITEM = LVM_FINDITEMA +LVM_GETSTRINGWIDTH = LVM_GETSTRINGWIDTHA +LVM_GETCOLUMN = LVM_GETCOLUMNA +LVM_SETCOLUMN = LVM_SETCOLUMNA +LVM_INSERTCOLUMN = LVM_INSERTCOLUMNA +LVM_GETITEMTEXT = LVM_GETITEMTEXTA +LVM_SETITEMTEXT = LVM_SETITEMTEXTA +LVM_GETISEARCHSTRING = LVM_GETISEARCHSTRINGA +LVM_EDITLABEL = LVM_EDITLABELA + +; List view image list types + +LVSIL_NORMAL = 0 +LVSIL_SMALL = 1 +LVSIL_STATE = 2 + +; LVM_SETITEMCOUNT flags + +LVSICF_NOINVALIDATEALL = 1 +LVSICF_NOSCROLL = 2 + +; List view item structure flags + +LVIF_TEXT = 0001h +LVIF_IMAGE = 0002h +LVIF_PARAM = 0004h +LVIF_STATE = 0008h +LVIF_INDENT = 0010h +LVIF_NORECOMPUTE = 0800h +LVIF_DI_SETITEM = 1000h + +; List view item states + +LVIS_FOCUSED = 00001h +LVIS_SELECTED = 00002h +LVIS_CUT = 00004h +LVIS_DROPHILITED = 00008h +LVIS_ACTIVATING = 0020h +LVIS_OVERLAYMASK = 00F00h +LVIS_STATEIMAGEMASK = 0F000h + +; List view callback item values + +LPSTR_TEXTCALLBACK = -1 +I_IMAGECALLBACK = -1 +I_CHILDRENCALLBACK = -1 + +; List view next item relations + +LVNI_ALL = 000h +LVNI_FOCUSED = 001h +LVNI_SELECTED = 002h +LVNI_CUT = 004h +LVNI_DROPHILITED = 008h +LVNI_ABOVE = 100h +LVNI_BELOW = 200h +LVNI_TOLEFT = 400h +LVNI_TORIGHT = 800h + +; List view search types + +LVFI_PARAM = 01h +LVFI_STRING = 02h +LVFI_PARTIAL = 08h +LVFI_WRAP = 20h +LVFI_NEARESTXY = 40h + +; List view item rectangle types + +LVIR_BOUNDS = 0 +LVIR_ICON = 1 +LVIR_LABEL = 2 +LVIR_SELECTBOUNDS = 3 + +; List view hit test flags + +LVHT_NOWHERE = 01h +LVHT_ONITEMICON = 02h +LVHT_ONITEMLABEL = 04h +LVHT_ONITEMSTATEICON= 08h +LVHT_ONITEM = LVHT_ONITEMICON or LVHT_ONITEMLABEL or LVHT_ONITEMSTATEICON +LVHT_ABOVE = 08h +LVHT_BELOW = 10h +LVHT_TORIGHT = 20h +LVHT_TOLEFT = 40h + +; List view alignment values + +LVA_DEFAULT = 000h +LVA_ALIGNLEFT = 001h +LVA_ALIGNTOP = 002h +LVA_ALIGNRIGHT = 003h +LVA_ALIGNBOTTOM = 004h +LVA_SNAPTOGRID = 005h +LVA_SORTASCENDING = 100h +LVA_SORTDESCENDING = 200h + +; List view column structure flags + +LVCF_FMT = 1 +LVCF_WIDTH = 2 +LVCF_TEXT = 4 +LVCF_SUBITEM = 8 + +; List view column alignment values + +LVCFMT_LEFT = 0 +LVCFMT_RIGHT = 1 +LVCFMT_CENTER = 2 +LVCFMT_JUSTIFYMASK = 3 + +; List view column width values + +LVSCW_AUTOSIZE = -1 +LVSCW_AUTOSIZE_USEHEADER = -2 + +; List view notifications + +LVN_ITEMCHANGING = LVN_FIRST - 0 +LVN_ITEMCHANGED = LVN_FIRST - 1 +LVN_INSERTITEM = LVN_FIRST - 2 +LVN_DELETEITEM = LVN_FIRST - 3 +LVN_DELETEALLITEMS = LVN_FIRST - 4 +LVN_BEGINLABELEDITA = LVN_FIRST - 5 +LVN_ENDLABELEDITA = LVN_FIRST - 6 +LVN_COLUMNCLICK = LVN_FIRST - 8 +LVN_BEGINDRAG = LVN_FIRST - 9 +LVN_BEGINRDRAG = LVN_FIRST - 11 +LVN_ODCACHEHINT = LVN_FIRST - 13 +LVN_GETDISPINFOA = LVN_FIRST - 50 +LVN_SETDISPINFOA = LVN_FIRST - 51 +LVN_ODFINDITEMA = LVN_FIRST - 52 +LVN_KEYDOWN = LVN_FIRST - 55 +LVN_BEGINLABELEDITW = LVN_FIRST - 75 +LVN_ENDLABELEDITW = LVN_FIRST - 76 +LVN_GETDISPINFOW = LVN_FIRST - 77 +LVN_SETDISPINFOW = LVN_FIRST - 78 +LVN_ODFINDITEMW = LVN_FIRST - 79 +LVN_BEGINLABELEDIT = LVN_BEGINLABELEDITA +LVN_ENDLABELEDIT = LVN_ENDLABELEDITA +LVN_GETDISPINFO = LVN_GETDISPINFOA +LVN_SETDISPINFO = LVN_SETDISPINFOA +LVN_ODFINDITEM = LVN_ODFINDITEMA + +; Tree view styles + +TVS_HASBUTTONS = 0001h +TVS_HASLINES = 0002h +TVS_LINESATROOT = 0004h +TVS_EDITLABELS = 0008h +TVS_DISABLEDRAGDROP = 0010h +TVS_SHOWSELALWAYS = 0020h +TVS_RTLREADING = 0040h +TVS_NOTOOLTIPS = 0080h +TVS_CHECKBOXES = 0100h +TVS_TRACKSELECT = 0200h +TVS_SINGLEEXPAND = 0400h +TVS_INFOTIP = 0800h +TVS_FULLROWSELECT = 1000h +TVS_NOSCROLL = 2000h +TVS_NONEVENHEIGHT = 4000h + +; Tree view item structure flags + +TVIF_TEXT = 0001h +TVIF_IMAGE = 0002h +TVIF_PARAM = 0004h +TVIF_STATE = 0008h +TVIF_HANDLE = 0010h +TVIF_SELECTEDIMAGE = 0020h +TVIF_CHILDREN = 0040h +TVIF_DI_SETITEM = 1000h + +; Tree view item states + +TVIS_FOCUSED = 00001h +TVIS_SELECTED = 00002h +TVIS_CUT = 00004h +TVIS_DROPHILITED = 00008h +TVIS_BOLD = 00010h +TVIS_EXPANDED = 00020h +TVIS_EXPANDEDONCE = 00040h +TVIS_EXPANDPARTIAL = 00080h +TVIS_OVERLAYMASK = 00F00h +TVIS_STATEIMAGEMASK = 0F000h +TVIS_USERMASK = 0F000h + +; Tree view predefined item values + +TVI_ROOT = -10000h +TVI_FIRST = -0FFFFh +TVI_LAST = -0FFFEh +TVI_SORT = -0FFFDh + +; Tree view messages + +TVM_INSERTITEMA = TV_FIRST + 0 +TVM_DELETEITEM = TV_FIRST + 1 +TVM_EXPAND = TV_FIRST + 2 +TVM_GETITEMRECT = TV_FIRST + 4 +TVM_GETCOUNT = TV_FIRST + 5 +TVM_GETINDENT = TV_FIRST + 6 +TVM_SETINDENT = TV_FIRST + 7 +TVM_GETIMAGELIST = TV_FIRST + 8 +TVM_SETIMAGELIST = TV_FIRST + 9 +TVM_GETNEXTITEM = TV_FIRST + 10 +TVM_SELECTITEM = TV_FIRST + 11 +TVM_GETITEMA = TV_FIRST + 12 +TVM_SETITEMA = TV_FIRST + 13 +TVM_EDITLABELA = TV_FIRST + 14 +TVM_GETEDITCONTROL = TV_FIRST + 15 +TVM_GETVISIBLECOUNT = TV_FIRST + 16 +TVM_HITTEST = TV_FIRST + 17 +TVM_CREATEDRAGIMAGE = TV_FIRST + 18 +TVM_SORTCHILDREN = TV_FIRST + 19 +TVM_ENSUREVISIBLE = TV_FIRST + 20 +TVM_SORTCHILDRENCB = TV_FIRST + 21 +TVM_ENDEDITLABELNOW = TV_FIRST + 22 +TVM_GETISEARCHSTRINGA = TV_FIRST + 23 +TVM_INSERTITEMW = TV_FIRST + 50 +TVM_GETITEMW = TV_FIRST + 62 +TVM_SETITEMW = TV_FIRST + 63 +TVM_GETISEARCHSTRINGW = TV_FIRST + 64 +TVM_EDITLABELW = TV_FIRST + 65 +TVM_INSERTITEM = TVM_INSERTITEMA +TVM_GETITEM = TVM_GETITEMA +TVM_SETITEM = TVM_SETITEMA +TVM_GETISEARCHSTRING = TVM_GETISEARCHSTRINGA +TVM_EDITLABEL = TVM_EDITLABELA + +; Tree view action flags + +TVE_COLLAPSE = 0001h +TVE_EXPAND = 0002h +TVE_TOGGLE = 0003h +TVE_EXPANDPARTIAL = 4000h +TVE_COLLAPSERESET = 8000h + +; Tree view image list types + +TVSIL_NORMAL = 0 +TVSIL_STATE = 2 + +; Tree view next item types + +TVGN_ROOT = 0 +TVGN_NEXT = 1 +TVGN_PREVIOUS = 2 +TVGN_PARENT = 3 +TVGN_CHILD = 4 +TVGN_FIRSTVISIBLE = 5 +TVGN_NEXTVISIBLE = 6 +TVGN_PREVIOUSVISIBLE = 7 +TVGN_DROPHILITE = 8 +TVGN_CARET = 9 + +; Tree view hit test flags + +TVHT_NOWHERE = 001h +TVHT_ONITEMICON = 002h +TVHT_ONITEMLABEL = 004h +TVHT_ONITEMINDENT = 008h +TVHT_ONITEMBUTTON = 010h +TVHT_ONITEMRIGHT = 020h +TVHT_ONITEMSTATEICON = 040h +TVHT_ONITEM = TVHT_ONITEMICON or TVHT_ONITEMLABEL or TVHT_ONITEMSTATEICON +TVHT_ABOVE = 100h +TVHT_BELOW = 200h +TVHT_TORIGHT = 400h +TVHT_TOLEFT = 800h + +; Tree view notifications + +TVN_SELCHANGINGA = TVN_FIRST - 1 +TVN_SELCHANGEDA = TVN_FIRST - 2 +TVN_GETDISPINFOA = TVN_FIRST - 3 +TVN_SETDISPINFOA = TVN_FIRST - 4 +TVN_ITEMEXPANDINGA = TVN_FIRST - 5 +TVN_ITEMEXPANDEDA = TVN_FIRST - 6 +TVN_BEGINDRAGA = TVN_FIRST - 7 +TVN_BEGINRDRAGA = TVN_FIRST - 8 +TVN_DELETEITEMA = TVN_FIRST - 9 +TVN_BEGINLABELEDITA = TVN_FIRST - 10 +TVN_ENDLABELEDITA = TVN_FIRST - 11 +TVN_KEYDOWN = TVN_FIRST - 12 +TVN_SELCHANGINGW = TVN_FIRST - 50 +TVN_SELCHANGEDW = TVN_FIRST - 51 +TVN_GETDISPINFOW = TVN_FIRST - 52 +TVN_SETDISPINFOW = TVN_FIRST - 53 +TVN_ITEMEXPANDINGW = TVN_FIRST - 54 +TVN_ITEMEXPANDEDW = TVN_FIRST - 55 +TVN_BEGINDRAGW = TVN_FIRST - 56 +TVN_BEGINRDRAGW = TVN_FIRST - 57 +TVN_DELETEITEMW = TVN_FIRST - 58 +TVN_BEGINLABELEDITW = TVN_FIRST - 59 +TVN_ENDLABELEDITW = TVN_FIRST - 60 +TVN_SELCHANGING = TVN_SELCHANGINGA +TVN_SELCHANGED = TVN_SELCHANGEDA +TVN_GETDISPINFO = TVN_GETDISPINFOA +TVN_SETDISPINFO = TVN_SETDISPINFOA +TVN_ITEMEXPANDING = TVN_ITEMEXPANDINGA +TVN_ITEMEXPANDED = TVN_ITEMEXPANDEDA +TVN_BEGINDRAG = TVN_BEGINDRAGA +TVN_BEGINRDRAG = TVN_BEGINRDRAGA +TVN_DELETEITEM = TVN_DELETEITEMA +TVN_BEGINLABELEDIT = TVN_BEGINLABELEDITA +TVN_ENDLABELEDIT = TVN_ENDLABELEDITA + +; Tree view action flags + +TVC_UNKNOWN = 0 +TVC_BYMOUSE = 1 +TVC_BYKEYBOARD = 2 + +; Tab control styles + +TCS_SCROLLOPPOSITE = 0001h +TCS_BOTTOM = 0002h +TCS_RIGHT = 0002h +TCS_FORCEICONLEFT = 0010h +TCS_FORCELABELLEFT = 0020h +TCS_HOTTRACK = 0040h +TCS_VERTICAL = 0080h +TCS_TABS = 0000h +TCS_BUTTONS = 0100h +TCS_SINGLELINE = 0000h +TCS_MULTILINE = 0200h +TCS_RIGHTJUSTIFY = 0000h +TCS_FIXEDWIDTH = 0400h +TCS_RAGGEDRIGHT = 0800h +TCS_FOCUSONBUTTONDOWN = 1000h +TCS_OWNERDRAWFIXED = 2000h +TCS_TOOLTIPS = 4000h +TCS_FOCUSNEVER = 8000h + +; Tab control messages + +TCM_GETIMAGELIST = TCM_FIRST + 2 +TCM_SETIMAGELIST = TCM_FIRST + 3 +TCM_GETITEMCOUNT = TCM_FIRST + 4 +TCM_GETITEMA = TCM_FIRST + 5 +TCM_SETITEMA = TCM_FIRST + 6 +TCM_INSERTITEMA = TCM_FIRST + 7 +TCM_DELETEITEM = TCM_FIRST + 8 +TCM_DELETEALLITEMS = TCM_FIRST + 9 +TCM_GETITEMRECT = TCM_FIRST + 10 +TCM_GETCURSEL = TCM_FIRST + 11 +TCM_SETCURSEL = TCM_FIRST + 12 +TCM_HITTEST = TCM_FIRST + 13 +TCM_SETITEMEXTRA = TCM_FIRST + 14 +TCM_ADJUSTRECT = TCM_FIRST + 40 +TCM_SETITEMSIZE = TCM_FIRST + 41 +TCM_REMOVEIMAGE = TCM_FIRST + 42 +TCM_SETPADDING = TCM_FIRST + 43 +TCM_GETROWCOUNT = TCM_FIRST + 44 +TCM_GETTOOLTIPS = TCM_FIRST + 45 +TCM_SETTOOLTIPS = TCM_FIRST + 46 +TCM_GETCURFOCUS = TCM_FIRST + 47 +TCM_SETCURFOCUS = TCM_FIRST + 48 +TCM_GETITEMW = TCM_FIRST + 60 +TCM_SETITEMW = TCM_FIRST + 61 +TCM_INSERTITEMW = TCM_FIRST + 62 +TCM_GETITEM = TCM_GETITEMA +TCM_SETITEM = TCM_SETITEMA +TCM_INSERTITEM = TCM_INSERTITEMA + +; Tab control item structure flags + +TCIF_TEXT = 1 +TCIF_IMAGE = 2 +TCIF_RTLREADING = 4 +TCIF_PARAM = 8 + +; Tab control hit test flags + +TCHT_NOWHERE = 1 +TCHT_ONITEMICON = 2 +TCHT_ONITEMLABEL = 4 +TCHT_ONITEM = TCHT_ONITEMICON or TCHT_ONITEMLABEL + +; Tab control notifications + +TCN_KEYDOWN = TCN_FIRST - 0 +TCN_SELCHANGE = TCN_FIRST - 1 +TCN_SELCHANGING = TCN_FIRST - 2 + +; Animation control styles + +ACS_CENTER = 1 +ACS_TRANSPARENT = 2 +ACS_AUTOPLAY = 4 +ACS_TIMER = 8 + +; Animation control messages + +ACM_OPENA = WM_USER + 100 +ACM_PLAY = WM_USER + 101 +ACM_STOP = WM_USER + 102 +ACM_OPENW = WM_USER + 103 +ACM_OPEN = ACM_OPENA + +; Animation control notifications + +ACN_START = 1 +ACN_STOP = 2 + +; Month calendar styles + +MCS_DAYSTATE = 1 +MCS_MULTISELECT = 2 +MCS_WEEKNUMBERS = 4 +MCS_NOTODAY_PRE_IE4 = 8 +MCS_NOTODAYCIRCLE = 8 +MCS_NOTODAY = 16 + +; Month calendar messages + +MCM_GETCURSEL = MCM_FIRST + 1 +MCM_SETCURSEL = MCM_FIRST + 2 +MCM_GETMAXSELCOUNT = MCM_FIRST + 3 +MCM_SETMAXSELCOUNT = MCM_FIRST + 4 +MCM_GETSELRANGE = MCM_FIRST + 5 +MCM_SETSELRANGE = MCM_FIRST + 6 +MCM_GETMONTHRANGE = MCM_FIRST + 7 +MCM_SETDAYSTATE = MCM_FIRST + 8 +MCM_GETMINREQRECT = MCM_FIRST + 9 +MCM_SETCOLOR = MCM_FIRST + 10 +MCM_GETCOLOR = MCM_FIRST + 11 +MCM_SETTODAY = MCM_FIRST + 12 +MCM_GETTODAY = MCM_FIRST + 13 +MCM_HITTEST = MCM_FIRST + 14 +MCM_SETFIRSTDAYOFWEEK = MCM_FIRST + 15 +MCM_GETFIRSTDAYOFWEEK = MCM_FIRST + 16 +MCM_GETRANGE = MCM_FIRST + 17 +MCM_SETRANGE = MCM_FIRST + 18 +MCM_GETMONTHDELTA = MCM_FIRST + 19 +MCM_SETMONTHDELTA = MCM_FIRST + 20 + +; Month calendar hit test flags + +MCHT_TITLE = 0010000h +MCHT_CALENDAR = 0020000h +MCHT_TODAYLINK = 0030000h +MCHT_NEXT = 1000000h +MCHT_PREV = 2000000h +MCHT_NOWHERE = 0000000h +MCHT_TITLEBK = MCHT_TITLE +MCHT_TITLEMONTH = MCHT_TITLE or 1 +MCHT_TITLEYEAR = MCHT_TITLE or 2 +MCHT_TITLEBTNNEXT = MCHT_TITLE or MCHT_NEXT or 3 +MCHT_TITLEBTNPREV = MCHT_TITLE or MCHT_PREV or 3 +MCHT_CALENDARBK = MCHT_CALENDAR +MCHT_CALENDARDATE = MCHT_CALENDAR or 1 +MCHT_CALENDARDATENEXT = MCHT_CALENDARDATE or MCHT_NEXT +MCHT_CALENDARDATEPREV = MCHT_CALENDARDATE or MCHT_PREV +MCHT_CALENDARDAY = MCHT_CALENDAR or 2 +MCHT_CALENDARWEEKNUM = MCHT_CALENDAR or 3 + +; Month calendar color codes + +MCSC_BACKGROUND = 0 +MCSC_TEXT = 1 +MCSC_TITLEBK = 2 +MCSC_TITLETEXT = 3 +MCSC_MONTHBK = 4 +MCSC_TRAILINGTEXT = 5 + +; Month calendar notifications + +MCN_SELCHANGE = MCN_FIRST + 1 +MCN_GETDAYSTATE = MCN_FIRST + 3 +MCN_SELECT = MCN_FIRST + 4 + +; Date-time pick control messages + +DTM_GETSYSTEMTIME = DTM_FIRST + 1 +DTM_SETSYSTEMTIME = DTM_FIRST + 2 +DTM_GETRANGE = DTM_FIRST + 3 +DTM_SETRANGE = DTM_FIRST + 4 +DTM_SETFORMATA = DTM_FIRST + 5 +DTM_SETMCCOLOR = DTM_FIRST + 6 +DTM_GETMCCOLOR = DTM_FIRST + 7 +DTM_GETMONTHCAL = DTM_FIRST + 8 +DTM_SETMCFONT = DTM_FIRST + 9 +DTM_GETMCFONT = DTM_FIRST + 10 +DTM_SETFORMATW = DTM_FIRST + 50 +DTM_SETFORMAT = DTM_SETFORMATA + +; Date-time pick control styles + +DTS_UPDOWN = 01h +DTS_SHOWNONE = 02h +DTS_SHORTDATEFORMAT = 00h +DTS_LONGDATEFORMAT = 04h +DTS_TIMEFORMAT = 09h +DTS_APPCANPARSE = 10h +DTS_RIGHTALIGN = 20h + +; Date-time pick control notifications + +DTN_DATETIMECHANGE = DTN_FIRST + 1 +DTN_USERSTRINGA = DTN_FIRST + 2 +DTN_WMKEYDOWNA = DTN_FIRST + 3 +DTN_FORMATA = DTN_FIRST + 4 +DTN_FORMATQUERYA = DTN_FIRST + 5 +DTN_DROPDOWN = DTN_FIRST + 6 +DTN_CLOSEUP = DTN_FIRST + 7 +DTN_USERSTRINGW = DTN_FIRST + 15 +DTN_WMKEYDOWNW = DTN_FIRST + 16 +DTN_FORMATW = DTN_FIRST + 17 +DTN_FORMATQUERYW = DTN_FIRST + 18 +DTN_USERSTRING = DTN_USERSTRINGA +DTN_WMKEYDOWN = DTN_WMKEYDOWNA +DTN_FORMAT = DTN_FORMATA +DTN_FORMATQUERY = DTN_FORMATQUERYA + +; ImageList_LoadImage types + +IMAGE_BITMAP = 0 +IMAGE_ICON = 1 +IMAGE_CURSOR = 2 +IMAGE_ENHMETAFILE = 3 + +; ImageList_LoadImage flags + +LR_DEFAULTCOLOR = 0000h +LR_MONOCHROME = 0001h +LR_COLOR = 0002h +LR_COPYRETURNORG = 0004h +LR_COPYDELETEORG = 0008h +LR_LOADFROMFILE = 0010h +LR_LOADTRANSPARENT = 0020h +LR_DEFAULTSIZE = 0040h +LR_VGACOLOR = 0080h +LR_LOADMAP3DCOLORS = 1000h +LR_CREATEDIBSECTION = 2000h +LR_COPYFROMRESOURCE = 4000h +LR_SHARED = 8000h + +; IP control messages + +IPM_CLEARADDRESS = WM_USER + 100 +IPM_SETADDRESS = WM_USER + 101 +IPM_GETADDRESS = WM_USER + 102 +IPM_SETRANGE = WM_USER + 103 +IPM_SETFOCUS = WM_USER + 104 +IPM_ISBLANK = WM_USER + 105 + +; Custom Draw flags + +CDRF_DODEFAULT = 0 +CDRF_NEWFONT = 2 +CDRF_SKIPDEFAULT = 4 +CDRF_NOTIFYPOSTPAINT = 10h +CDRF_NOTIFYITEMDRAW = 20h +CDRF_NOTIFYSUBITEMDRAW = 20h +CDRF_NOTIFYPOSTERASE = 40h +CDDS_PREPAINT = 1 +CDDS_POSTPAINT = 2 +CDDS_PREERASE = 3 +CDDS_POSTERASE = 4 +CDDS_ITEM = 10000h +CDDS_ITEMPREPAINT = CDDS_ITEM or CDDS_PREPAINT +CDDS_ITEMPOSTPAINT = CDDS_ITEM or CDDS_POSTPAINT +CDDS_ITEMPREERASE = CDDS_ITEM or CDDS_PREERASE +CDDS_ITEMPOSTERASE = CDDS_ITEM or CDDS_POSTERASE +CDDS_SUBITEM = 20000h +CDIS_SELECTED = 1 +CDIS_GRAYED = 2 +CDIS_DISABLED = 4 +CDIS_CHECKED = 8 +CDIS_FOCUS = 10h +CDIS_DEFAULT = 20h +CDIS_HOT = 40h +CDIS_MARKED = 80h +CDIS_INDETERMINATE = 100h diff --git a/toolchain/fasmw17332/INCLUDE/EQUATES/COMDLG32.INC b/toolchain/fasmw17332/INCLUDE/EQUATES/COMDLG32.INC new file mode 100644 index 0000000..4b27efc --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/EQUATES/COMDLG32.INC @@ -0,0 +1,333 @@ + +; COMDLG32.DLL structures and constants + +struct OPENFILENAME + lStructSize dd ? + hwndOwner dd ? + hInstance dd ? + lpstrFilter dd ? + lpstrCustomFilter dd ? + nMaxCustFilter dd ? + nFilterIndex dd ? + lpstrFile dd ? + nMaxFile dd ? + lpstrFileTitle dd ? + nMaxFileTitle dd ? + lpstrInitialDir dd ? + lpstrTitle dd ? + Flags dd ? + nFileOffset dw ? + nFileExtension dw ? + lpstrDefExt dd ? + lCustData dd ? + lpfnHook dd ? + lpTemplateName dd ? +ends + +struct CHOOSECOLOR + lStructSize dd ? + hwndOwner dd ? + hInstance dd ? + rgbResult dd ? + lpCustColors dd ? + Flags dd ? + lCustData dd ? + lpfnHook dd ? + lpTemplateName dd ? +ends + +struct FINDREPLACE + lStructSize dd ? + hwndOwner dd ? + hInstance dd ? + Flags dd ? + lpstrFindWhat dd ? + lpstrReplaceWith dd ? + wFindWhatLen dw ? + wReplaceWithLen dw ? + lCustData dd ? + lpfnHook dd ? + lpTemplateName dd ? +ends + +struct CHOOSEFONT + lStructSize dd ? + hwndOwner dd ? + hDC dd ? + lpLogFont dd ? + iPointSize dd ? + Flags dd ? + rgbColors dd ? + lCustData dd ? + lpfnHook dd ? + lpTemplateName dd ? + hInstance dd ? + lpszStyle dd ? + nFontType dw ? + wReserved dw ? + nSizeMin dd ? + nSizeMax dd ? +ends + +struct PRINTDLG + lStructSize dd ? + hwndOwner dd ? + hDevMode dd ? + hDevNames dd ? + hDC dd ? + Flags dd ? + nFromPage dw ? + nToPage dw ? + nMinPage dw ? + nMaxPage dw ? + nCopies dw ? + hInstance dd ? + lCustData dd ? + lpfnPrintHook dd ? + lpfnSetupHook dd ? + lpPrintTemplateName dd ? + lpSetupTemplateName dd ? + hPrintTemplate dd ? + hSetupTemplate dd ? +ends + +struct DEVNAMES + wDriverOffset dw ? + wDeviceOffset dw ? + wOutputOffset dw ? + wDefault dw ? +ends + +struct PAGESETUPDLG + lStructSize dd ? + hwndOwner dd ? + hDevMode dd ? + hDevNames dd ? + Flags dd ? + ptPaperSize POINT + rtMinMargin RECT + rtMargin RECT + hInstance dd ? + lCustData dd ? + lpfnPageSetupHook dd ? + lpfnPagePaintHook dd ? + lpPageSetupTemplateName dd ? + hPageSetupTemplate dd ? +ends + +; OPENFILENAME flags + +OFN_READONLY = 000001h +OFN_OVERWRITEPROMPT = 000002h +OFN_HIDEREADONLY = 000004h +OFN_NOCHANGEDIR = 000008h +OFN_SHOWHELP = 000010h +OFN_ENABLEHOOK = 000020h +OFN_ENABLETEMPLATE = 000040h +OFN_ENABLETEMPLATEHANDLE = 000080h +OFN_NOVALIDATE = 000100h +OFN_ALLOWMULTISELECT = 000200h +OFN_EXTENSIONDIFFERENT = 000400h +OFN_PATHMUSTEXIST = 000800h +OFN_FILEMUSTEXIST = 001000h +OFN_CREATEPROMPT = 002000h +OFN_SHAREAWARE = 004000h +OFN_NOREADONLYRETURN = 008000h +OFN_NOTESTFILECREATE = 010000h +OFN_NONETWORKBUTTON = 020000h +OFN_NOLONGNAMES = 040000h +OFN_EXPLORER = 080000h +OFN_NODEREFERENCELINKS = 100000h +OFN_LONGNAMES = 200000h + +; Common dialog notifications + +CDN_FIRST = -601 +CDN_LAST = -699 +CDN_INITDONE = CDN_FIRST - 0 +CDN_SELCHANGE = CDN_FIRST - 1 +CDN_FOLDERCHANGE = CDN_FIRST - 2 +CDN_SHAREVIOLATION = CDN_FIRST - 3 +CDN_HELP = CDN_FIRST - 4 +CDN_FILEOK = CDN_FIRST - 5 +CDN_TYPECHANGE = CDN_FIRST - 6 + +; Common dialog messages + +CDM_FIRST = WM_USER + 100 +CDM_LAST = WM_USER + 200 +CDM_GETSPEC = CDM_FIRST + 0 +CDM_GETFILEPATH = CDM_FIRST + 1 +CDM_GETFOLDERPATH = CDM_FIRST + 2 +CDM_GETFOLDERIDLIST = CDM_FIRST + 3 +CDM_SETCONTROLTEXT = CDM_FIRST + 4 +CDM_HIDECONTROL = CDM_FIRST + 5 +CDM_SETDEFEXT = CDM_FIRST + 6 + +; CHOOSECOLOR flags + +CC_RGBINIT = 001h +CC_FULLOPEN = 002h +CC_PREVENTFULLOPEN = 004h +CC_SHOWHELP = 008h +CC_ENABLEHOOK = 010h +CC_ENABLETEMPLATE = 020h +CC_ENABLETEMPLATEHANDLE = 040h +CC_SOLIDCOLOR = 080h +CC_ANYCOLOR = 100h + +; FINDREPLACE flags + +FR_DOWN = 00001h +FR_WHOLEWORD = 00002h +FR_MATCHCASE = 00004h +FR_FINDNEXT = 00008h +FR_REPLACE = 00010h +FR_REPLACEALL = 00020h +FR_DIALOGTERM = 00040h +FR_SHOWHELP = 00080h +FR_ENABLEHOOK = 00100h +FR_ENABLETEMPLATE = 00200h +FR_NOUPDOWN = 00400h +FR_NOMATCHCASE = 00800h +FR_NOWHOLEWORD = 01000h +FR_ENABLETEMPLATEHANDLE = 02000h +FR_HIDEUPDOWN = 04000h +FR_HIDEMATCHCASE = 08000h +FR_HIDEWHOLEWORD = 10000h + +; CHOOSEFONT flags + +CF_SCREENFONTS = 0000001h +CF_PRINTERFONTS = 0000002h +CF_BOTH = CF_SCREENFONTS or CF_PRINTERFONTS +CF_SHOWHELP = 0000004h +CF_ENABLEHOOK = 0000008h +CF_ENABLETEMPLATE = 0000010h +CF_ENABLETEMPLATEHANDLE = 0000020h +CF_INITTOLOGFONTSTRUCT = 0000040h +CF_USESTYLE = 0000080h +CF_EFFECTS = 0000100h +CF_APPLY = 0000200h +CF_ANSIONLY = 0000400h +CF_SCRIPTSONLY = CF_ANSIONLY +CF_NOVECTORFONTS = 0000800h +CF_NOOEMFONTS = CF_NOVECTORFONTS +CF_NOSIMULATIONS = 0001000h +CF_LIMITSIZE = 0002000h +CF_FIXEDPITCHONLY = 0004000h +CF_WYSIWYG = 0008000h +CF_FORCEFONTEXIST = 0010000h +CF_SCALABLEONLY = 0020000h +CF_TTONLY = 0040000h +CF_NOFACESEL = 0080000h +CF_NOSTYLESEL = 0100000h +CF_NOSIZESEL = 0200000h +CF_SELECTSCRIPT = 0400000h +CF_NOSCRIPTSEL = 0800000h +CF_NOVERTFONTS = 1000000h + +; ChooseFont messages + +WM_CHOOSEFONT_GETLOGFONT = WM_USER + 1 +WM_CHOOSEFONT_SETLOGFONT = WM_USER + 101 +WM_CHOOSEFONT_SETFLAGS = WM_USER + 102 + +; PRINTDLG flags + +PD_ALLPAGES = 000000h +PD_SELECTION = 000001h +PD_PAGENUMS = 000002h +PD_NOSELECTION = 000004h +PD_NOPAGENUMS = 000008h +PD_COLLATE = 000010h +PD_PRINTTOFILE = 000020h +PD_PRINTSETUP = 000040h +PD_NOWARNING = 000080h +PD_RETURNDC = 000100h +PD_RETURNIC = 000200h +PD_RETURNDEFAULT = 000400h +PD_SHOWHELP = 000800h +PD_ENABLEPRINTHOOK = 001000h +PD_ENABLESETUPHOOK = 002000h +PD_ENABLEPRINTTEMPLATE = 004000h +PD_ENABLESETUPTEMPLATE = 008000h +PD_ENABLEPRINTTEMPLATEHANDLE = 010000h +PD_ENABLESETUPTEMPLATEHANDLE = 020000h +PD_USEDEVMODECOPIES = 040000h +PD_USEDEVMODECOPIESANDCOLLATE = 040000h +PD_DISABLEPRINTTOFILE = 080000h +PD_HIDEPRINTTOFILE = 100000h +PD_NONETWORKBUTTON = 200000h + +; PAGESETUPDLG flags + +PSD_DEFAULTMINMARGINS = 000000h +PSD_INWININIINTLMEASURE = 000000h +PSD_MINMARGINS = 000001h +PSD_MARGINS = 000002h +PSD_INTHOUSANDTHSOFINCHES = 000004h +PSD_INHUNDREDTHSOFMILLIMETERS = 000008h +PSD_DISABLEMARGINS = 000010h +PSD_DISABLEPRINTER = 000020h +PSD_NOWARNING = 000080h +PSD_DISABLEORIENTATION = 000100h +PSD_RETURNDEFAULT = 000400h +PSD_DISABLEPAPER = 000200h +PSD_SHOWHELP = 000800h +PSD_ENABLEPAGESETUPHOOK = 002000h +PSD_ENABLEPAGESETUPTEMPLATE = 008000h +PSD_ENABLEPAGESETUPTEMPLATEHANDLE = 020000h +PSD_ENABLEPAGEPAINTHOOK = 040000h +PSD_DISABLEPAGEPAINTING = 080000h +PSD_NONETWORKBUTTON = 200000h + +; PageSetupDlg messages + +WM_PSD_PAGESETUPDLG = WM_USER +WM_PSD_FULLPAGERECT = WM_USER + 1 +WM_PSD_MINMARGINRECT = WM_USER + 2 +WM_PSD_MARGINRECT = WM_USER + 3 +WM_PSD_GREEKTEXTRECT = WM_USER + 4 +WM_PSD_ENVSTAMPRECT = WM_USER + 5 +WM_PSD_YAFULLPAGERECT = WM_USER + 6 + +; Common dialog error codes + +CDERR_DIALOGFAILURE = 0FFFFh +CDERR_GENERALCODES = 00000h +CDERR_STRUCTSIZE = 00001h +CDERR_INITIALIZATION = 00002h +CDERR_NOTEMPLATE = 00003h +CDERR_NOHINSTANCE = 00004h +CDERR_LOADSTRFAILURE = 00005h +CDERR_FINDRESFAILURE = 00006h +CDERR_LOADRESFAILURE = 00007h +CDERR_LOCKRESFAILURE = 00008h +CDERR_MEMALLOCFAILURE = 00009h +CDERR_MEMLOCKFAILURE = 0000Ah +CDERR_NOHOOK = 0000Bh +CDERR_REGISTERMSGFAIL = 0000Ch +PDERR_PRINTERCODES = 01000h +PDERR_SETUPFAILURE = 01001h +PDERR_PARSEFAILURE = 01002h +PDERR_RETDEFFAILURE = 01003h +PDERR_LOADDRVFAILURE = 01004h +PDERR_GETDEVMODEFAIL = 01005h +PDERR_INITFAILURE = 01006h +PDERR_NODEVICES = 01007h +PDERR_NODEFAULTPRN = 01008h +PDERR_DNDMMISMATCH = 01009h +PDERR_CREATEICFAILURE = 0100Ah +PDERR_PRINTERNOTFOUND = 0100Bh +PDERR_DEFAULTDIFFERENT = 0100Ch +CFERR_CHOOSEFONTCODES = 02000h +CFERR_NOFONTS = 02001h +CFERR_MAXLESSTHANMIN = 02002h +FNERR_FILENAMECODES = 03000h +FNERR_SUBCLASSFAILURE = 03001h +FNERR_INVALIDFILENAME = 03002h +FNERR_BUFFERTOOSMALL = 03003h +FRERR_FINDREPLACECODES = 04000h +FRERR_BUFFERLENGTHZERO = 04001h +CCERR_CHOOSECOLORCODES = 05000h diff --git a/toolchain/fasmw17332/INCLUDE/EQUATES/COMDLG64.INC b/toolchain/fasmw17332/INCLUDE/EQUATES/COMDLG64.INC new file mode 100644 index 0000000..64cee82 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/EQUATES/COMDLG64.INC @@ -0,0 +1,334 @@ + +; COMDLG32.DLL structures and constants + +struct OPENFILENAME + lStructSize dq ? + hwndOwner dq ? + hInstance dq ? + lpstrFilter dq ? + lpstrCustomFilter dq ? + nMaxCustFilter dd ? + nFilterIndex dd ? + lpstrFile dq ? + nMaxFile dd ?,? + lpstrFileTitle dq ? + nMaxFileTitle dd ?,? + lpstrInitialDir dq ? + lpstrTitle dq ? + Flags dd ? + nFileOffset dw ? + nFileExtension dw ? + lpstrDefExt dq ? + lCustData dq ? + lpfnHook dq ? + lpTemplateName dq ? +ends + +struct CHOOSECOLOR + lStructSize dq ? + hwndOwner dq ? + hInstance dq ? + rgbResult dd ?,? + lpCustColors dq ? + Flags dd ?,? + lCustData dq ? + lpfnHook dq ? + lpTemplateName dq ? +ends + +struct FINDREPLACE + lStructSize dq ? + hwndOwner dq ? + hInstance dq ? + Flags dd ?,? + lpstrFindWhat dq ? + lpstrReplaceWith dq ? + wFindWhatLen dw ? + wReplaceWithLen dw ?,?,? + lCustData dq ? + lpfnHook dq ? + lpTemplateName dq ? +ends + +struct CHOOSEFONT + lStructSize dq ? + hwndOwner dq ? + hDC dq ? + lpLogFont dq ? + iPointSize dd ? + Flags dd ? + rgbColors dd ?,? + lCustData dq ? + lpfnHook dq ? + lpTemplateName dq ? + hInstance dq ? + lpszStyle dq ? + nFontType dw ? + wReserved dw ? + nSizeMin dd ? + nSizeMax dd ? +ends + +struct PRINTDLG + lStructSize dq ? + hwndOwner dq ? + hDevMode dq ? + hDevNames dq ? + hDC dq ? + Flags dd ? + nFromPage dw ? + nToPage dw ? + nMinPage dw ? + nMaxPage dw ? + nCopies dw ?,? + hInstance dq ? + lCustData dq ? + lpfnPrintHook dq ? + lpfnSetupHook dq ? + lpPrintTemplateName dq ? + lpSetupTemplateName dq ? + hPrintTemplate dq ? + hSetupTemplate dq ? +ends + +struct DEVNAMES + wDriverOffset dw ? + wDeviceOffset dw ? + wOutputOffset dw ? + wDefault dw ? +ends + +struct PAGESETUPDLG + lStructSize dq ? + hwndOwner dq ? + hDevMode dq ? + hDevNames dq ? + Flags dd ? + ptPaperSize POINT + rtMinMargin RECT + rtMargin RECT + dd ? + hInstance dq ? + lCustData dq ? + lpfnPageSetupHook dq ? + lpfnPagePaintHook dq ? + lpPageSetupTemplateName dq ? + hPageSetupTemplate dq ? +ends + +; OPENFILENAME flags + +OFN_READONLY = 000001h +OFN_OVERWRITEPROMPT = 000002h +OFN_HIDEREADONLY = 000004h +OFN_NOCHANGEDIR = 000008h +OFN_SHOWHELP = 000010h +OFN_ENABLEHOOK = 000020h +OFN_ENABLETEMPLATE = 000040h +OFN_ENABLETEMPLATEHANDLE = 000080h +OFN_NOVALIDATE = 000100h +OFN_ALLOWMULTISELECT = 000200h +OFN_EXTENSIONDIFFERENT = 000400h +OFN_PATHMUSTEXIST = 000800h +OFN_FILEMUSTEXIST = 001000h +OFN_CREATEPROMPT = 002000h +OFN_SHAREAWARE = 004000h +OFN_NOREADONLYRETURN = 008000h +OFN_NOTESTFILECREATE = 010000h +OFN_NONETWORKBUTTON = 020000h +OFN_NOLONGNAMES = 040000h +OFN_EXPLORER = 080000h +OFN_NODEREFERENCELINKS = 100000h +OFN_LONGNAMES = 200000h + +; Common dialog notifications + +CDN_FIRST = -601 +CDN_LAST = -699 +CDN_INITDONE = CDN_FIRST - 0 +CDN_SELCHANGE = CDN_FIRST - 1 +CDN_FOLDERCHANGE = CDN_FIRST - 2 +CDN_SHAREVIOLATION = CDN_FIRST - 3 +CDN_HELP = CDN_FIRST - 4 +CDN_FILEOK = CDN_FIRST - 5 +CDN_TYPECHANGE = CDN_FIRST - 6 + +; Common dialog messages + +CDM_FIRST = WM_USER + 100 +CDM_LAST = WM_USER + 200 +CDM_GETSPEC = CDM_FIRST + 0 +CDM_GETFILEPATH = CDM_FIRST + 1 +CDM_GETFOLDERPATH = CDM_FIRST + 2 +CDM_GETFOLDERIDLIST = CDM_FIRST + 3 +CDM_SETCONTROLTEXT = CDM_FIRST + 4 +CDM_HIDECONTROL = CDM_FIRST + 5 +CDM_SETDEFEXT = CDM_FIRST + 6 + +; CHOOSECOLOR flags + +CC_RGBINIT = 001h +CC_FULLOPEN = 002h +CC_PREVENTFULLOPEN = 004h +CC_SHOWHELP = 008h +CC_ENABLEHOOK = 010h +CC_ENABLETEMPLATE = 020h +CC_ENABLETEMPLATEHANDLE = 040h +CC_SOLIDCOLOR = 080h +CC_ANYCOLOR = 100h + +; FINDREPLACE flags + +FR_DOWN = 00001h +FR_WHOLEWORD = 00002h +FR_MATCHCASE = 00004h +FR_FINDNEXT = 00008h +FR_REPLACE = 00010h +FR_REPLACEALL = 00020h +FR_DIALOGTERM = 00040h +FR_SHOWHELP = 00080h +FR_ENABLEHOOK = 00100h +FR_ENABLETEMPLATE = 00200h +FR_NOUPDOWN = 00400h +FR_NOMATCHCASE = 00800h +FR_NOWHOLEWORD = 01000h +FR_ENABLETEMPLATEHANDLE = 02000h +FR_HIDEUPDOWN = 04000h +FR_HIDEMATCHCASE = 08000h +FR_HIDEWHOLEWORD = 10000h + +; CHOOSEFONT flags + +CF_SCREENFONTS = 0000001h +CF_PRINTERFONTS = 0000002h +CF_BOTH = CF_SCREENFONTS or CF_PRINTERFONTS +CF_SHOWHELP = 0000004h +CF_ENABLEHOOK = 0000008h +CF_ENABLETEMPLATE = 0000010h +CF_ENABLETEMPLATEHANDLE = 0000020h +CF_INITTOLOGFONTSTRUCT = 0000040h +CF_USESTYLE = 0000080h +CF_EFFECTS = 0000100h +CF_APPLY = 0000200h +CF_ANSIONLY = 0000400h +CF_SCRIPTSONLY = CF_ANSIONLY +CF_NOVECTORFONTS = 0000800h +CF_NOOEMFONTS = CF_NOVECTORFONTS +CF_NOSIMULATIONS = 0001000h +CF_LIMITSIZE = 0002000h +CF_FIXEDPITCHONLY = 0004000h +CF_WYSIWYG = 0008000h +CF_FORCEFONTEXIST = 0010000h +CF_SCALABLEONLY = 0020000h +CF_TTONLY = 0040000h +CF_NOFACESEL = 0080000h +CF_NOSTYLESEL = 0100000h +CF_NOSIZESEL = 0200000h +CF_SELECTSCRIPT = 0400000h +CF_NOSCRIPTSEL = 0800000h +CF_NOVERTFONTS = 1000000h + +; ChooseFont messages + +WM_CHOOSEFONT_GETLOGFONT = WM_USER + 1 +WM_CHOOSEFONT_SETLOGFONT = WM_USER + 101 +WM_CHOOSEFONT_SETFLAGS = WM_USER + 102 + +; PRINTDLG flags + +PD_ALLPAGES = 000000h +PD_SELECTION = 000001h +PD_PAGENUMS = 000002h +PD_NOSELECTION = 000004h +PD_NOPAGENUMS = 000008h +PD_COLLATE = 000010h +PD_PRINTTOFILE = 000020h +PD_PRINTSETUP = 000040h +PD_NOWARNING = 000080h +PD_RETURNDC = 000100h +PD_RETURNIC = 000200h +PD_RETURNDEFAULT = 000400h +PD_SHOWHELP = 000800h +PD_ENABLEPRINTHOOK = 001000h +PD_ENABLESETUPHOOK = 002000h +PD_ENABLEPRINTTEMPLATE = 004000h +PD_ENABLESETUPTEMPLATE = 008000h +PD_ENABLEPRINTTEMPLATEHANDLE = 010000h +PD_ENABLESETUPTEMPLATEHANDLE = 020000h +PD_USEDEVMODECOPIES = 040000h +PD_USEDEVMODECOPIESANDCOLLATE = 040000h +PD_DISABLEPRINTTOFILE = 080000h +PD_HIDEPRINTTOFILE = 100000h +PD_NONETWORKBUTTON = 200000h + +; PAGESETUPDLG flags + +PSD_DEFAULTMINMARGINS = 000000h +PSD_INWININIINTLMEASURE = 000000h +PSD_MINMARGINS = 000001h +PSD_MARGINS = 000002h +PSD_INTHOUSANDTHSOFINCHES = 000004h +PSD_INHUNDREDTHSOFMILLIMETERS = 000008h +PSD_DISABLEMARGINS = 000010h +PSD_DISABLEPRINTER = 000020h +PSD_NOWARNING = 000080h +PSD_DISABLEORIENTATION = 000100h +PSD_RETURNDEFAULT = 000400h +PSD_DISABLEPAPER = 000200h +PSD_SHOWHELP = 000800h +PSD_ENABLEPAGESETUPHOOK = 002000h +PSD_ENABLEPAGESETUPTEMPLATE = 008000h +PSD_ENABLEPAGESETUPTEMPLATEHANDLE = 020000h +PSD_ENABLEPAGEPAINTHOOK = 040000h +PSD_DISABLEPAGEPAINTING = 080000h +PSD_NONETWORKBUTTON = 200000h + +; PageSetupDlg messages + +WM_PSD_PAGESETUPDLG = WM_USER +WM_PSD_FULLPAGERECT = WM_USER + 1 +WM_PSD_MINMARGINRECT = WM_USER + 2 +WM_PSD_MARGINRECT = WM_USER + 3 +WM_PSD_GREEKTEXTRECT = WM_USER + 4 +WM_PSD_ENVSTAMPRECT = WM_USER + 5 +WM_PSD_YAFULLPAGERECT = WM_USER + 6 + +; Common dialog error codes + +CDERR_DIALOGFAILURE = 0FFFFh +CDERR_GENERALCODES = 00000h +CDERR_STRUCTSIZE = 00001h +CDERR_INITIALIZATION = 00002h +CDERR_NOTEMPLATE = 00003h +CDERR_NOHINSTANCE = 00004h +CDERR_LOADSTRFAILURE = 00005h +CDERR_FINDRESFAILURE = 00006h +CDERR_LOADRESFAILURE = 00007h +CDERR_LOCKRESFAILURE = 00008h +CDERR_MEMALLOCFAILURE = 00009h +CDERR_MEMLOCKFAILURE = 0000Ah +CDERR_NOHOOK = 0000Bh +CDERR_REGISTERMSGFAIL = 0000Ch +PDERR_PRINTERCODES = 01000h +PDERR_SETUPFAILURE = 01001h +PDERR_PARSEFAILURE = 01002h +PDERR_RETDEFFAILURE = 01003h +PDERR_LOADDRVFAILURE = 01004h +PDERR_GETDEVMODEFAIL = 01005h +PDERR_INITFAILURE = 01006h +PDERR_NODEVICES = 01007h +PDERR_NODEFAULTPRN = 01008h +PDERR_DNDMMISMATCH = 01009h +PDERR_CREATEICFAILURE = 0100Ah +PDERR_PRINTERNOTFOUND = 0100Bh +PDERR_DEFAULTDIFFERENT = 0100Ch +CFERR_CHOOSEFONTCODES = 02000h +CFERR_NOFONTS = 02001h +CFERR_MAXLESSTHANMIN = 02002h +FNERR_FILENAMECODES = 03000h +FNERR_SUBCLASSFAILURE = 03001h +FNERR_INVALIDFILENAME = 03002h +FNERR_BUFFERTOOSMALL = 03003h +FRERR_FINDREPLACECODES = 04000h +FRERR_BUFFERLENGTHZERO = 04001h +CCERR_CHOOSECOLORCODES = 05000h diff --git a/toolchain/fasmw17332/INCLUDE/EQUATES/GDI32.INC b/toolchain/fasmw17332/INCLUDE/EQUATES/GDI32.INC new file mode 100644 index 0000000..77d556f --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/EQUATES/GDI32.INC @@ -0,0 +1,480 @@ + +; GDI32.DLL structures and constants + +struct SIZE + cx dd ? + cy dd ? +ends + +struct BITMAP + bmType dd ? + bmWidth dd ? + bmHeight dd ? + bmWidthBytes dd ? + bmPlanes dw ? + bmBitsPixel dw ? + bmBits dd ? +ends + +struct BITMAPCOREHEADER + bcSize dd ? + bcWidth dw ? + bcHeight dw ? + bcPlanes dw ? + bcBitCount dw ? +ends + +struct BITMAPINFOHEADER + biSize dd ? + biWidth dd ? + biHeight dd ? + biPlanes dw ? + biBitCount dw ? + biCompression dd ? + biSizeImage dd ? + biXPelsPerMeter dd ? + biYPelsPerMeter dd ? + biClrUsed dd ? + biClrImportant dd ? +ends + +struct BITMAPFILEHEADER + bfType dw ? + bfSize dd ? + bfReserved1 dw ? + bfReserved2 dw ? + bfOffBits dd ? +ends + +struct TEXTMETRIC + tmHeight dd ? + tmAscent dd ? + tmDescent dd ? + tmInternalLeading dd ? + tmExternalLeading dd ? + tmAveCharWidth dd ? + tmMaxCharWidth dd ? + tmWeight dd ? + tmOverhang dd ? + tmDigitizedAspectX dd ? + tmDigitizedAspectY dd ? + tmFirstChar TCHAR ? + tmLastChar TCHAR ? + tmDefaultChar TCHAR ? + tmBreakChar TCHAR ? + tmItalic db ? + tmUnderlined db ? + tmStruckOut db ? + tmPitchAndFamily db ? + tmCharSet db ? +ends + +struct LOGBRUSH + lbStyle dd ? + lbColor dd ? + lbHatch dd ? +ends + +struct LOGPEN + lopnStyle dd ? + lopnWidth POINT + lopnColor dd ? +ends + +struct EXTLOGPEN + elpPenStyle dd ? + elpWidth dd ? + elpBrushStyle dd ? + elpColor dd ? + elpHatch dd ? + elpNumEntries dd ? + elpStyleEntry dd ? +ends + +struct LOGFONT + lfHeight dd ? + lfWidth dd ? + lfEscapement dd ? + lfOrientation dd ? + lfWeight dd ? + lfItalic db ? + lfUnderline db ? + lfStrikeOut db ? + lfCharSet db ? + lfOutPrecision db ? + lfClipPrecision db ? + lfQuality db ? + lfPitchAndFamily db ? + lfFaceName TCHAR 32 dup (?) +ends + +struct ENUMLOGFONT + elfLogFont LOGFONT + elfFullName TCHAR 64 dup (?) + elfStyle TCHAR 32 dup (?) +ends + +struct ENUMLOGFONTEX + elfLogFont LOGFONT + elfFullName TCHAR 64 dup (?) + elfStyle TCHAR 32 dup (?) + elfScript TCHAR 32 dup (?) +ends + +struct PIXELFORMATDESCRIPTOR + nSize dw ? + nVersion dw ? + dwFlags dd ? + iPixelType db ? + cColorBits db ? + cRedBits db ? + cRedShift db ? + cGreenBits db ? + cGreenShift db ? + cBlueBits db ? + cBlueShift db ? + cAlphaBits db ? + cAlphaShift db ? + cAccumBits db ? + cAccumRedBits db ? + cAccumGreenBits db ? + cAccumBlueBits db ? + cAccumAlphaBits db ? + cDepthBits db ? + cStencilBits db ? + cAuxBuffers db ? + iLayerType db ? + bReserved db ? + dwLayerMask dd ? + dwVisibleMask dd ? + dwDamageMask dd ? +ends + +struct TRIVERTEX + x dd ? + y dd ? + Red dw ? + Green dw ? + Blue dw ? + Alpha dw ? +ends + +; General constants + +GDI_ERROR = 0FFFFFFFFh +HGDI_ERROR = 0FFFFFFFFh + +; Binary raster operations + +R2_BLACK = 1 +R2_NOTMERGEPEN = 2 +R2_MASKNOTPEN = 3 +R2_NOTCOPYPEN = 4 +R2_MASKPENNOT = 5 +R2_NOT = 6 +R2_XORPEN = 7 +R2_NOTMASKPEN = 8 +R2_MASKPEN = 9 +R2_NOTXORPEN = 10 +R2_NOP = 11 +R2_MERGENOTPEN = 12 +R2_COPYPEN = 13 +R2_MERGEPENNOT = 14 +R2_MERGEPEN = 15 +R2_WHITE = 16 + +; Raster operations + +SRCCOPY = 00CC0020h +SRCPAINT = 00EE0086h +SRCAND = 008800C6h +SRCINVERT = 00660046h +SRCERASE = 00440328h +NOTSRCCOPY = 00330008h +NOTSRCERASE = 001100A6h +MERGECOPY = 00C000CAh +MERGEPAINT = 00BB0226h +PATCOPY = 00F00021h +PATPAINT = 00FB0A09h +PATINVERT = 005A0049h +DSTINVERT = 00550009h +BLACKNESS = 00000042h +WHITENESS = 00FF0062h + +; Region flags + +ERROR = 0 +NULLREGION = 1 +SIMPLEREGION = 2 +COMPLEXREGION = 3 + +; CombineRgn styles + +RGN_AND = 1 +RGN_OR = 2 +RGN_XOR = 3 +RGN_DIFF = 4 +RGN_COPY = 5 + +; StretchBlt modes + +BLACKONWHITE = 1 +WHITEONBLACK = 2 +COLORONCOLOR = 3 +HALFTONE = 4 +STRETCH_ANDSCANS = BLACKONWHITE +STRETCH_ORSCANS = WHITEONBLACK +STRETCH_DELETESCANS = COLORONCOLOR +STRETCH_HALFTONE = HALFTONE + +; PolyFill modes + +ALTERNATE = 1 +WINDING = 2 + +; Background modes + +TRANSPARENT = 1 +OPAQUE = 2 + +; Point types + +PT_CLOSEFIGURE = 1 +PT_LINETO = 2 +PT_BEZIERTO = 4 +PT_MOVETO = 6 + +; Mapping modes + +MM_TEXT = 1 +MM_LOMETRIC = 2 +MM_HIMETRIC = 3 +MM_LOENGLISH = 4 +MM_HIENGLISH = 5 +MM_TWIPS = 6 +MM_ISOTROPIC = 7 +MM_ANISOTROPIC = 8 + +; Coordinate modes + +ABSOLUTE = 1 +RELATIVE = 2 + +; Stock logical objects + +WHITE_BRUSH = 0 +LTGRAY_BRUSH = 1 +GRAY_BRUSH = 2 +DKGRAY_BRUSH = 3 +BLACK_BRUSH = 4 +NULL_BRUSH = 5 +HOLLOW_BRUSH = NULL_BRUSH +WHITE_PEN = 6 +BLACK_PEN = 7 +NULL_PEN = 8 +OEM_FIXED_FONT = 10 +ANSI_FIXED_FONT = 11 +ANSI_VAR_FONT = 12 +SYSTEM_FONT = 13 +DEVICE_DEFAULT_FONT = 14 +DEFAULT_PALETTE = 15 +SYSTEM_FIXED_FONT = 16 +DEFAULT_GUI_FONT = 17 + +; Brush styles + +BS_SOLID = 0 +BS_NULL = 1 +BS_HOLLOW = BS_NULL +BS_HATCHED = 2 +BS_PATTERN = 3 +BS_INDEXED = 4 +BS_DIBPATTERN = 5 +BS_DIBPATTERNPT = 6 +BS_PATTERN8X8 = 7 +BS_DIBPATTERN8X8 = 8 +BS_MONOPATTERN = 9 + +; Hatch styles + +HS_HORIZONTAL = 0 +HS_VERTICAL = 1 +HS_FDIAGONAL = 2 +HS_BDIAGONAL = 3 +HS_CROSS = 4 +HS_DIAGCROSS = 5 + +; Pen styles + +PS_SOLID = 0 +PS_DASH = 1 +PS_DOT = 2 +PS_DASHDOT = 3 +PS_DASHDOTDOT = 4 +PS_NULL = 5 +PS_INSIDEFRAME = 6 +PS_USERSTYLE = 7 +PS_ALTERNATE = 8 +PS_ENDCAP_ROUND = 0 +PS_ENDCAP_SQUARE = 100h +PS_ENDCAP_FLAT = 200h +PS_JOIN_ROUND = 0 +PS_JOIN_BEVEL = 1000h +PS_JOIN_MITER = 2000h +PS_COSMETIC = 0 +PS_GEOMETRIC = 010000h + +; Arc directions + +AD_COUNTERCLOCKWISE = 1 +AD_CLOCKWISE = 2 + +; Text alignment options + +TA_NOUPDATECP = 0 +TA_UPDATECP = 1 +TA_LEFT = 0 +TA_RIGHT = 2 +TA_CENTER = 6 +TA_TOP = 0 +TA_BOTTOM = 8 +TA_BASELINE = 24 +TA_RTLREADING = 100h +VTA_BASELINE = TA_BASELINE +VTA_LEFT = TA_BOTTOM +VTA_RIGHT = TA_TOP +VTA_CENTER = TA_CENTER +VTA_BOTTOM = TA_RIGHT +VTA_TOP = TA_LEFT + +; ExtTextOut options + +ETO_OPAQUE = 0002h +ETO_CLIPPED = 0004h +ETO_GLYPH_INDEX = 0010h +ETO_RTLREADING = 0080h +ETO_IGNORELANGUAGE = 1000h + +; Bitmap compression types + +BI_RGB = 0 +BI_RLE8 = 1 +BI_RLE4 = 2 +BI_BITFIELDS = 3 + +; tmPitchAndFamily flags + +TMPF_FIXED_PITCH = 1 +TMPF_VECTOR = 2 +TMPF_TRUETYPE = 4 +TMPF_DEVICE = 8 + +; Font output precision values + +OUT_DEFAULT_PRECIS = 0 +OUT_STRING_PRECIS = 1 +OUT_CHARACTER_PRECIS = 2 +OUT_STROKE_PRECIS = 3 +OUT_TT_PRECIS = 4 +OUT_DEVICE_PRECIS = 5 +OUT_RASTER_PRECIS = 6 +OUT_TT_ONLY_PRECIS = 7 +OUT_OUTLINE_PRECIS = 8 +OUT_SCREEN_OUTLINE_PRECIS = 9 + +; Font clipping precision values + +CLIP_DEFAULT_PRECIS = 0 +CLIP_CHARACTER_PRECIS = 1 +CLIP_STROKE_PRECIS = 2 +CLIP_LH_ANGLES = 10h +CLIP_TT_ALWAYS = 20h +CLIP_EMBEDDED = 80h + +; Font output quality values + +DEFAULT_QUALITY = 0 +DRAFT_QUALITY = 1 +PROOF_QUALITY = 2 +NONANTIALIASED_QUALITY = 3 +ANTIALIASED_QUALITY = 4 + +; Font pitch values + +DEFAULT_PITCH = 0 +FIXED_PITCH = 1 +VARIABLE_PITCH = 2 +MONO_FONT = 8 + +; Font families + +FF_DONTCARE = 00h +FF_ROMAN = 10h +FF_SWISS = 20h +FF_MODERN = 30h +FF_SCRIPT = 40h +FF_DECORATIVE = 50h + +; Font weights + +FW_DONTCARE = 0 +FW_THIN = 100 +FW_EXTRALIGHT = 200 +FW_LIGHT = 300 +FW_NORMAL = 400 +FW_MEDIUM = 500 +FW_SEMIBOLD = 600 +FW_BOLD = 700 +FW_EXTRABOLD = 800 +FW_HEAVY = 900 +FW_ULTRALIGHT = FW_EXTRALIGHT +FW_REGULAR = FW_NORMAL +FW_DEMIBOLD = FW_SEMIBOLD +FW_ULTRABOLD = FW_EXTRABOLD +FW_BLACK = FW_HEAVY + +; Character set values + +ANSI_CHARSET = 0 +DEFAULT_CHARSET = 1 +SYMBOL_CHARSET = 2 +SHIFTJIS_CHARSET = 128 +HANGEUL_CHARSET = 129 +GB2312_CHARSET = 134 +CHINESEBIG5_CHARSET = 136 +OEM_CHARSET = 255 +JOHAB_CHARSET = 130 +HEBREW_CHARSET = 177 +ARABIC_CHARSET = 178 +GREEK_CHARSET = 161 +TURKISH_CHARSET = 162 +VIETNAMESE_CHARSET = 163 +THAI_CHARSET = 222 +EASTEUROPE_CHARSET = 238 +RUSSIAN_CHARSET = 204 +MAC_CHARSET = 77 +BALTIC_CHARSET = 186 + +; Pixel format constants + +PFD_TYPE_RGBA = 0 +PFD_TYPE_COLORINDEX = 1 +PFD_MAIN_PLANE = 0 +PFD_OVERLAY_PLANE = 1 +PFD_UNDERLAY_PLANE = -1 +PFD_DOUBLEBUFFER = 1 +PFD_STEREO = 2 +PFD_DRAW_TO_WINDOW = 4 +PFD_DRAW_TO_BITMAP = 8 +PFD_SUPPORT_GDI = 10h +PFD_SUPPORT_OPENGL = 20h +PFD_GENERIC_FORMAT = 40h +PFD_NEED_PALETTE = 80h +PFD_NEED_SYSTEM_PALETTE = 100h +PFD_SWAP_EXCHANGE = 200h +PFD_SWAP_COPY = 400h +PFD_SWAP_LAYER_BUFFERS = 800h +PFD_GENERIC_ACCELERATED = 1000h +PFD_DEPTH_DONTCARE = 20000000h +PFD_DOUBLEBUFFER_DONTCARE = 40000000h +PFD_STEREO_DONTCARE = 80000000h diff --git a/toolchain/fasmw17332/INCLUDE/EQUATES/GDI64.INC b/toolchain/fasmw17332/INCLUDE/EQUATES/GDI64.INC new file mode 100644 index 0000000..c611284 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/EQUATES/GDI64.INC @@ -0,0 +1,480 @@ + +; GDI32.DLL structures and constants + +struct SIZE + cx dd ? + cy dd ? +ends + +struct BITMAP + bmType dd ? + bmWidth dd ? + bmHeight dd ? + bmWidthBytes dd ? + bmPlanes dw ? + bmBitsPixel dw ?,?,? + bmBits dq ? +ends + +struct BITMAPCOREHEADER + bcSize dd ? + bcWidth dw ? + bcHeight dw ? + bcPlanes dw ? + bcBitCount dw ? +ends + +struct BITMAPINFOHEADER + biSize dd ? + biWidth dd ? + biHeight dd ? + biPlanes dw ? + biBitCount dw ? + biCompression dd ? + biSizeImage dd ? + biXPelsPerMeter dd ? + biYPelsPerMeter dd ? + biClrUsed dd ? + biClrImportant dd ? +ends + +struct BITMAPFILEHEADER + bfType dw ? + bfSize dd ? + bfReserved1 dw ? + bfReserved2 dw ? + bfOffBits dd ? +ends + +struct TEXTMETRIC + tmHeight dd ? + tmAscent dd ? + tmDescent dd ? + tmInternalLeading dd ? + tmExternalLeading dd ? + tmAveCharWidth dd ? + tmMaxCharWidth dd ? + tmWeight dd ? + tmOverhang dd ? + tmDigitizedAspectX dd ? + tmDigitizedAspectY dd ? + tmFirstChar TCHAR ? + tmLastChar TCHAR ? + tmDefaultChar TCHAR ? + tmBreakChar TCHAR ? + tmItalic db ? + tmUnderlined db ? + tmStruckOut db ? + tmPitchAndFamily db ? + tmCharSet db ? +ends + +struct LOGBRUSH + lbStyle dd ? + lbColor dd ? + lbHatch dd ? +ends + +struct LOGPEN + lopnStyle dd ? + lopnWidth POINT + lopnColor dd ? +ends + +struct EXTLOGPEN + elpPenStyle dd ? + elpWidth dd ? + elpBrushStyle dd ? + elpColor dd ? + elpHatch dd ? + elpNumEntries dd ? + elpStyleEntry dd ? +ends + +struct LOGFONT + lfHeight dd ? + lfWidth dd ? + lfEscapement dd ? + lfOrientation dd ? + lfWeight dd ? + lfItalic db ? + lfUnderline db ? + lfStrikeOut db ? + lfCharSet db ? + lfOutPrecision db ? + lfClipPrecision db ? + lfQuality db ? + lfPitchAndFamily db ? + lfFaceName TCHAR 32 dup (?) +ends + +struct ENUMLOGFONT + elfLogFont LOGFONT + elfFullName TCHAR 64 dup (?) + elfStyle TCHAR 32 dup (?) +ends + +struct ENUMLOGFONTEX + elfLogFont LOGFONT + elfFullName TCHAR 64 dup (?) + elfStyle TCHAR 32 dup (?) + elfScript TCHAR 32 dup (?) +ends + +struct PIXELFORMATDESCRIPTOR + nSize dw ? + nVersion dw ? + dwFlags dd ? + iPixelType db ? + cColorBits db ? + cRedBits db ? + cRedShift db ? + cGreenBits db ? + cGreenShift db ? + cBlueBits db ? + cBlueShift db ? + cAlphaBits db ? + cAlphaShift db ? + cAccumBits db ? + cAccumRedBits db ? + cAccumGreenBits db ? + cAccumBlueBits db ? + cAccumAlphaBits db ? + cDepthBits db ? + cStencilBits db ? + cAuxBuffers db ? + iLayerType db ? + bReserved db ? + dwLayerMask dd ? + dwVisibleMask dd ? + dwDamageMask dd ? +ends + +struct TRIVERTEX + x dd ? + y dd ? + Red dw ? + Green dw ? + Blue dw ? + Alpha dw ? +ends + +; General constants + +GDI_ERROR = 0FFFFFFFFh +HGDI_ERROR = 0FFFFFFFFh + +; Binary raster operations + +R2_BLACK = 1 +R2_NOTMERGEPEN = 2 +R2_MASKNOTPEN = 3 +R2_NOTCOPYPEN = 4 +R2_MASKPENNOT = 5 +R2_NOT = 6 +R2_XORPEN = 7 +R2_NOTMASKPEN = 8 +R2_MASKPEN = 9 +R2_NOTXORPEN = 10 +R2_NOP = 11 +R2_MERGENOTPEN = 12 +R2_COPYPEN = 13 +R2_MERGEPENNOT = 14 +R2_MERGEPEN = 15 +R2_WHITE = 16 + +; Raster operations + +SRCCOPY = 00CC0020h +SRCPAINT = 00EE0086h +SRCAND = 008800C6h +SRCINVERT = 00660046h +SRCERASE = 00440328h +NOTSRCCOPY = 00330008h +NOTSRCERASE = 001100A6h +MERGECOPY = 00C000CAh +MERGEPAINT = 00BB0226h +PATCOPY = 00F00021h +PATPAINT = 00FB0A09h +PATINVERT = 005A0049h +DSTINVERT = 00550009h +BLACKNESS = 00000042h +WHITENESS = 00FF0062h + +; Region flags + +ERROR = 0 +NULLREGION = 1 +SIMPLEREGION = 2 +COMPLEXREGION = 3 + +; CombineRgn styles + +RGN_AND = 1 +RGN_OR = 2 +RGN_XOR = 3 +RGN_DIFF = 4 +RGN_COPY = 5 + +; StretchBlt modes + +BLACKONWHITE = 1 +WHITEONBLACK = 2 +COLORONCOLOR = 3 +HALFTONE = 4 +STRETCH_ANDSCANS = BLACKONWHITE +STRETCH_ORSCANS = WHITEONBLACK +STRETCH_DELETESCANS = COLORONCOLOR +STRETCH_HALFTONE = HALFTONE + +; PolyFill modes + +ALTERNATE = 1 +WINDING = 2 + +; Background modes + +TRANSPARENT = 1 +OPAQUE = 2 + +; Point types + +PT_CLOSEFIGURE = 1 +PT_LINETO = 2 +PT_BEZIERTO = 4 +PT_MOVETO = 6 + +; Mapping modes + +MM_TEXT = 1 +MM_LOMETRIC = 2 +MM_HIMETRIC = 3 +MM_LOENGLISH = 4 +MM_HIENGLISH = 5 +MM_TWIPS = 6 +MM_ISOTROPIC = 7 +MM_ANISOTROPIC = 8 + +; Coordinate modes + +ABSOLUTE = 1 +RELATIVE = 2 + +; Stock logical objects + +WHITE_BRUSH = 0 +LTGRAY_BRUSH = 1 +GRAY_BRUSH = 2 +DKGRAY_BRUSH = 3 +BLACK_BRUSH = 4 +NULL_BRUSH = 5 +HOLLOW_BRUSH = NULL_BRUSH +WHITE_PEN = 6 +BLACK_PEN = 7 +NULL_PEN = 8 +OEM_FIXED_FONT = 10 +ANSI_FIXED_FONT = 11 +ANSI_VAR_FONT = 12 +SYSTEM_FONT = 13 +DEVICE_DEFAULT_FONT = 14 +DEFAULT_PALETTE = 15 +SYSTEM_FIXED_FONT = 16 +DEFAULT_GUI_FONT = 17 + +; Brush styles + +BS_SOLID = 0 +BS_NULL = 1 +BS_HOLLOW = BS_NULL +BS_HATCHED = 2 +BS_PATTERN = 3 +BS_INDEXED = 4 +BS_DIBPATTERN = 5 +BS_DIBPATTERNPT = 6 +BS_PATTERN8X8 = 7 +BS_DIBPATTERN8X8 = 8 +BS_MONOPATTERN = 9 + +; Hatch styles + +HS_HORIZONTAL = 0 +HS_VERTICAL = 1 +HS_FDIAGONAL = 2 +HS_BDIAGONAL = 3 +HS_CROSS = 4 +HS_DIAGCROSS = 5 + +; Pen styles + +PS_SOLID = 0 +PS_DASH = 1 +PS_DOT = 2 +PS_DASHDOT = 3 +PS_DASHDOTDOT = 4 +PS_NULL = 5 +PS_INSIDEFRAME = 6 +PS_USERSTYLE = 7 +PS_ALTERNATE = 8 +PS_ENDCAP_ROUND = 0 +PS_ENDCAP_SQUARE = 100h +PS_ENDCAP_FLAT = 200h +PS_JOIN_ROUND = 0 +PS_JOIN_BEVEL = 1000h +PS_JOIN_MITER = 2000h +PS_COSMETIC = 0 +PS_GEOMETRIC = 010000h + +; Arc directions + +AD_COUNTERCLOCKWISE = 1 +AD_CLOCKWISE = 2 + +; Text alignment options + +TA_NOUPDATECP = 0 +TA_UPDATECP = 1 +TA_LEFT = 0 +TA_RIGHT = 2 +TA_CENTER = 6 +TA_TOP = 0 +TA_BOTTOM = 8 +TA_BASELINE = 24 +TA_RTLREADING = 100h +VTA_BASELINE = TA_BASELINE +VTA_LEFT = TA_BOTTOM +VTA_RIGHT = TA_TOP +VTA_CENTER = TA_CENTER +VTA_BOTTOM = TA_RIGHT +VTA_TOP = TA_LEFT + +; ExtTextOut options + +ETO_OPAQUE = 0002h +ETO_CLIPPED = 0004h +ETO_GLYPH_INDEX = 0010h +ETO_RTLREADING = 0080h +ETO_IGNORELANGUAGE = 1000h + +; Bitmap compression types + +BI_RGB = 0 +BI_RLE8 = 1 +BI_RLE4 = 2 +BI_BITFIELDS = 3 + +; tmPitchAndFamily flags + +TMPF_FIXED_PITCH = 1 +TMPF_VECTOR = 2 +TMPF_TRUETYPE = 4 +TMPF_DEVICE = 8 + +; Font output precision values + +OUT_DEFAULT_PRECIS = 0 +OUT_STRING_PRECIS = 1 +OUT_CHARACTER_PRECIS = 2 +OUT_STROKE_PRECIS = 3 +OUT_TT_PRECIS = 4 +OUT_DEVICE_PRECIS = 5 +OUT_RASTER_PRECIS = 6 +OUT_TT_ONLY_PRECIS = 7 +OUT_OUTLINE_PRECIS = 8 +OUT_SCREEN_OUTLINE_PRECIS = 9 + +; Font clipping precision values + +CLIP_DEFAULT_PRECIS = 0 +CLIP_CHARACTER_PRECIS = 1 +CLIP_STROKE_PRECIS = 2 +CLIP_LH_ANGLES = 10h +CLIP_TT_ALWAYS = 20h +CLIP_EMBEDDED = 80h + +; Font output quality values + +DEFAULT_QUALITY = 0 +DRAFT_QUALITY = 1 +PROOF_QUALITY = 2 +NONANTIALIASED_QUALITY = 3 +ANTIALIASED_QUALITY = 4 + +; Font pitch values + +DEFAULT_PITCH = 0 +FIXED_PITCH = 1 +VARIABLE_PITCH = 2 +MONO_FONT = 8 + +; Font families + +FF_DONTCARE = 00h +FF_ROMAN = 10h +FF_SWISS = 20h +FF_MODERN = 30h +FF_SCRIPT = 40h +FF_DECORATIVE = 50h + +; Font weights + +FW_DONTCARE = 0 +FW_THIN = 100 +FW_EXTRALIGHT = 200 +FW_LIGHT = 300 +FW_NORMAL = 400 +FW_MEDIUM = 500 +FW_SEMIBOLD = 600 +FW_BOLD = 700 +FW_EXTRABOLD = 800 +FW_HEAVY = 900 +FW_ULTRALIGHT = FW_EXTRALIGHT +FW_REGULAR = FW_NORMAL +FW_DEMIBOLD = FW_SEMIBOLD +FW_ULTRABOLD = FW_EXTRABOLD +FW_BLACK = FW_HEAVY + +; Character set values + +ANSI_CHARSET = 0 +DEFAULT_CHARSET = 1 +SYMBOL_CHARSET = 2 +SHIFTJIS_CHARSET = 128 +HANGEUL_CHARSET = 129 +GB2312_CHARSET = 134 +CHINESEBIG5_CHARSET = 136 +OEM_CHARSET = 255 +JOHAB_CHARSET = 130 +HEBREW_CHARSET = 177 +ARABIC_CHARSET = 178 +GREEK_CHARSET = 161 +TURKISH_CHARSET = 162 +VIETNAMESE_CHARSET = 163 +THAI_CHARSET = 222 +EASTEUROPE_CHARSET = 238 +RUSSIAN_CHARSET = 204 +MAC_CHARSET = 77 +BALTIC_CHARSET = 186 + +; Pixel format constants + +PFD_TYPE_RGBA = 0 +PFD_TYPE_COLORINDEX = 1 +PFD_MAIN_PLANE = 0 +PFD_OVERLAY_PLANE = 1 +PFD_UNDERLAY_PLANE = -1 +PFD_DOUBLEBUFFER = 1 +PFD_STEREO = 2 +PFD_DRAW_TO_WINDOW = 4 +PFD_DRAW_TO_BITMAP = 8 +PFD_SUPPORT_GDI = 10h +PFD_SUPPORT_OPENGL = 20h +PFD_GENERIC_FORMAT = 40h +PFD_NEED_PALETTE = 80h +PFD_NEED_SYSTEM_PALETTE = 100h +PFD_SWAP_EXCHANGE = 200h +PFD_SWAP_COPY = 400h +PFD_SWAP_LAYER_BUFFERS = 800h +PFD_GENERIC_ACCELERATED = 1000h +PFD_DEPTH_DONTCARE = 20000000h +PFD_DOUBLEBUFFER_DONTCARE = 40000000h +PFD_STEREO_DONTCARE = 80000000h diff --git a/toolchain/fasmw17332/INCLUDE/EQUATES/KERNEL32.INC b/toolchain/fasmw17332/INCLUDE/EQUATES/KERNEL32.INC new file mode 100644 index 0000000..40b3569 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/EQUATES/KERNEL32.INC @@ -0,0 +1,812 @@ + +; KERNEL32.DLL structures and constants + +struct SYSTEM_INFO + wProcessorArchitecture dw ? + wReserved dw ? + dwPageSize dd ? + lpMinimumApplicationAddress dd ? + lpMaximumApplicationAddress dd ? + dwActiveProcessorMask dd ? + dwNumberOfProcessors dd ? + dwProcessorType dd ? + dwAllocationGranularity dd ? + wProcessorLevel dw ? + wProcessorRevision dw ? +ends + +struct OSVERSIONINFO + dwOSVersionInfoSize dd ? + dwMajorVersion dd ? + dwMinorVersion dd ? + dwBuildNumber dd ? + dwPlatformId dd ? + szCSDVersion TCHAR 128 dup (?) +ends + +struct OSVERSIONINFOA + dwOSVersionInfoSize dd ? + dwMajorVersion dd ? + dwMinorVersion dd ? + dwBuildNumber dd ? + dwPlatformId dd ? + szCSDVersion db 128 dup (?) +ends + +struct OSVERSIONINFOW + dwOSVersionInfoSize dd ? + dwMajorVersion dd ? + dwMinorVersion dd ? + dwBuildNumber dd ? + dwPlatformId dd ? + szCSDVersion du 128 dup (?) +ends + +struct MEMORYSTATUS + dwLength dd ? + dwMemoryLoad dd ? + dwTotalPhys dd ? + dwAvailPhys dd ? + dwTotalPageFile dd ? + dwAvailPageFile dd ? + dwTotalVirtual dd ? + dwAvailVirtual dd ? +ends + +struct STARTUPINFO + cb dd ? + lpReserved dd ? + lpDesktop dd ? + lpTitle dd ? + dwX dd ? + dwY dd ? + dwXSize dd ? + dwYSize dd ? + dwXCountChars dd ? + dwYCountChars dd ? + dwFillAttribute dd ? + dwFlags dd ? + wShowWindow dw ? + cbReserved2 dw ? + lpReserved2 dd ? + hStdInput dd ? + hStdOutput dd ? + hStdError dd ? +ends + +struct PROCESS_INFORMATION + hProcess dd ? + hThread dd ? + dwProcessId dd ? + dwThreadId dd ? +ends + +struct FILETIME + dwLowDateTime dd ? + dwHighDateTime dd ? +ends + +struct SYSTEMTIME + wYear dw ? + wMonth dw ? + wDayOfWeek dw ? + wDay dw ? + wHour dw ? + wMinute dw ? + wSecond dw ? + wMilliseconds dw ? +ends + +struct BY_HANDLE_FILE_INFORMATION + dwFileAttributes dd ? + ftCreationTime FILETIME + ftLastAccessTime FILETIME + ftLastWriteTime FILETIME + dwVolumeSerialNumber dd ? + nFileSizeHigh dd ? + nFileSizeLow dd ? + nNumberOfLinks dd ? + nFileIndexHigh dd ? + nFileIndexLow dd ? +ends + +struct WIN32_FIND_DATA + dwFileAttributes dd ? + ftCreationTime FILETIME + ftLastAccessTime FILETIME + ftLastWriteTime FILETIME + nFileSizeHigh dd ? + nFileSizeLow dd ? + dwReserved0 dd ? + dwReserved1 dd ? + cFileName TCHAR MAX_PATH dup (?) + cAlternateFileName TCHAR 14 dup (?) +ends + +struct WIN32_FIND_DATAA + dwFileAttributes dd ? + ftCreationTime FILETIME + ftLastAccessTime FILETIME + ftLastWriteTime FILETIME + nFileSizeHigh dd ? + nFileSizeLow dd ? + dwReserved0 dd ? + dwReserved1 dd ? + cFileName db MAX_PATH dup (?) + cAlternateFileName db 14 dup (?) +ends + +struct WIN32_FIND_DATAW + dwFileAttributes dd ? + ftCreationTime FILETIME + ftLastAccessTime FILETIME + ftLastWriteTime FILETIME + nFileSizeHigh dd ? + nFileSizeLow dd ? + dwReserved0 dd ? + dwReserved1 dd ? + cFileName du MAX_PATH dup (?) + cAlternateFileName du 14 dup (?) +ends + +; General constants + +NULL = 0 +TRUE = 1 +FALSE = 0 + +; Maximum path length in characters + +MAX_PATH = 260 + +; Access rights + +DELETE_RIGHT = 00010000h +READ_CONTROL = 00020000h +WRITE_DAC = 00040000h +WRITE_OWNER = 00080000h +SYNCHRONIZE = 00100000h +STANDARD_RIGHTS_READ = READ_CONTROL +STANDARD_RIGHTS_WRITE = READ_CONTROL +STANDARD_RIGHTS_EXECUTE = READ_CONTROL +STANDARD_RIGHTS_REQUIRED = 000F0000h +STANDARD_RIGHTS_ALL = 001F0000h +SPECIFIC_RIGHTS_ALL = 0000FFFFh +ACCESS_SYSTEM_SECURITY = 01000000h +MAXIMUM_ALLOWED = 02000000h +GENERIC_READ = 80000000h +GENERIC_WRITE = 40000000h +GENERIC_EXECUTE = 20000000h +GENERIC_ALL = 10000000h +PROCESS_TERMINATE = 00000001h +PROCESS_CREATE_THREAD = 00000002h +PROCESS_VM_OPERATION = 00000008h +PROCESS_VM_READ = 00000010h +PROCESS_VM_WRITE = 00000020h +PROCESS_DUP_HANDLE = 00000040h +PROCESS_CREATE_PROCESS = 00000080h +PROCESS_SET_QUOTA = 00000100h +PROCESS_SET_INFORMATION = 00000200h +PROCESS_QUERY_INFORMATION = 00000400h +PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or 0FFFh +FILE_SHARE_READ = 00000001h +FILE_SHARE_WRITE = 00000002h +FILE_SHARE_DELETE = 00000004h + +; CreateFile actions + +CREATE_NEW = 1 +CREATE_ALWAYS = 2 +OPEN_EXISTING = 3 +OPEN_ALWAYS = 4 +TRUNCATE_EXISTING = 5 + +; OpenFile modes + +OF_READ = 0000h +OF_WRITE = 0001h +OF_READWRITE = 0002h +OF_SHARE_COMPAT = 0000h +OF_SHARE_EXCLUSIVE = 0010h +OF_SHARE_DENY_WRITE = 0020h +OF_SHARE_DENY_READ = 0030h +OF_SHARE_DENY_NONE = 0040h +OF_PARSE = 0100h +OF_DELETE = 0200h +OF_VERIFY = 0400h +OF_CANCEL = 0800h +OF_CREATE = 1000h +OF_PROMPT = 2000h +OF_EXIST = 4000h +OF_REOPEN = 8000h + +; SetFilePointer methods + +FILE_BEGIN = 0 +FILE_CURRENT = 1 +FILE_END = 2 + +; File attributes + +FILE_ATTRIBUTE_READONLY = 001h +FILE_ATTRIBUTE_HIDDEN = 002h +FILE_ATTRIBUTE_SYSTEM = 004h +FILE_ATTRIBUTE_DIRECTORY = 010h +FILE_ATTRIBUTE_ARCHIVE = 020h +FILE_ATTRIBUTE_NORMAL = 080h +FILE_ATTRIBUTE_TEMPORARY = 100h +FILE_ATTRIBUTE_COMPRESSED = 800h + +; File flags + +FILE_FLAG_WRITE_THROUGH = 80000000h +FILE_FLAG_OVERLAPPED = 40000000h +FILE_FLAG_NO_BUFFERING = 20000000h +FILE_FLAG_RANDOM_ACCESS = 10000000h +FILE_FLAG_SEQUENTIAL_SCAN = 08000000h +FILE_FLAG_DELETE_ON_CLOSE = 04000000h +FILE_FLAG_BACKUP_SEMANTICS = 02000000h +FILE_FLAG_POSIX_SEMANTICS = 01000000h + +; Notify filters + +FILE_NOTIFY_CHANGE_FILE_NAME = 001h +FILE_NOTIFY_CHANGE_DIR_NAME = 002h +FILE_NOTIFY_CHANGE_ATTRIBUTES = 004h +FILE_NOTIFY_CHANGE_SIZE = 008h +FILE_NOTIFY_CHANGE_LAST_WRITE = 010h +FILE_NOTIFY_CHANGE_SECURITY = 100h + +; File types + +FILE_TYPE_UNKNOWN = 0 +FILE_TYPE_DISK = 1 +FILE_TYPE_CHAR = 2 +FILE_TYPE_PIPE = 3 +FILE_TYPE_REMOTE = 8000h + +; LockFileEx flags + +LOCKFILE_FAIL_IMMEDIATELY = 1 +LOCKFILE_EXCLUSIVE_LOCK = 2 + +; MoveFileEx flags + +MOVEFILE_REPLACE_EXISTING = 1 +MOVEFILE_COPY_ALLOWED = 2 +MOVEFILE_DELAY_UNTIL_REBOOT = 4 +MOVEFILE_WRITE_THROUGH = 8 + +; FindFirstFileEx flags + +FIND_FIRST_EX_CASE_SENSITIVE = 1 + +; Device handles + +INVALID_HANDLE_VALUE = -1 +STD_INPUT_HANDLE = -10 +STD_OUTPUT_HANDLE = -11 +STD_ERROR_HANDLE = -12 + +; DuplicateHandle options + +DUPLICATE_CLOSE_SOURCE = 1 +DUPLICATE_SAME_ACCESS = 2 + +; File mapping acccess rights + +SECTION_QUERY = 01h +SECTION_MAP_WRITE = 02h +SECTION_MAP_READ = 04h +SECTION_MAP_EXECUTE = 08h +SECTION_EXTEND_SIZE = 10h +SECTION_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or SECTION_QUERY or SECTION_MAP_WRITE or SECTION_MAP_READ or SECTION_MAP_EXECUTE or SECTION_EXTEND_SIZE +FILE_MAP_COPY = SECTION_QUERY +FILE_MAP_WRITE = SECTION_MAP_WRITE +FILE_MAP_READ = SECTION_MAP_READ +FILE_MAP_ALL_ACCESS = SECTION_ALL_ACCESS + +; File system flags + +FILE_CASE_SENSITIVE_SEARCH = 0001h +FILE_CASE_PRESERVED_NAMES = 0002h +FILE_UNICODE_ON_DISK = 0004h +FILE_PERSISTENT_ACLS = 0008h +FILE_FILE_COMPRESSION = 0010h +FILE_VOLUME_IS_COMPRESSED = 8000h +FS_CASE_IS_PRESERVED = FILE_CASE_PRESERVED_NAMES +FS_CASE_SENSITIVE = FILE_CASE_SENSITIVE_SEARCH +FS_UNICODE_STORED_ON_DISK = FILE_UNICODE_ON_DISK +FS_PERSISTENT_ACLS = FILE_PERSISTENT_ACLS + +; Drive types + +DRIVE_UNKNOWN = 0 +DRIVE_NO_ROOT_DIR = 1 +DRIVE_REMOVABLE = 2 +DRIVE_FIXED = 3 +DRIVE_REMOTE = 4 +DRIVE_CDROM = 5 +DRIVE_RAMDISK = 6 + +; Pipe modes + +PIPE_ACCESS_INBOUND = 1 +PIPE_ACCESS_OUTBOUND = 2 +PIPE_ACCESS_DUPLEX = 3 +PIPE_CLIENT_END = 0 +PIPE_SERVER_END = 1 +PIPE_WAIT = 0 +PIPE_NOWAIT = 1 +PIPE_READMODE_BYTE = 0 +PIPE_READMODE_MESSAGE = 2 +PIPE_TYPE_BYTE = 0 +PIPE_TYPE_MESSAGE = 4 +PIPE_UNLIMITED_INSTANCES = 255 + +; Global memory flags + +GMEM_FIXED = 0000h +GMEM_MOVEABLE = 0002h +GMEM_NOCOMPACT = 0010h +GMEM_NODISCARD = 0020h +GMEM_ZEROINIT = 0040h +GMEM_MODIFY = 0080h +GMEM_DISCARDABLE = 0100h +GMEM_NOT_BANKED = 1000h +GMEM_SHARE = 2000h +GMEM_DDESHARE = 2000h +GMEM_NOTIFY = 4000h +GMEM_LOWER = GMEM_NOT_BANKED +GMEM_VALID_FLAGS = 7F72h +GMEM_INVALID_HANDLE = 8000h +GMEM_DISCARDED = 4000h +GMEM_LOCKCOUNT = 0FFh +GHND = GMEM_MOVEABLE + GMEM_ZEROINIT +GPTR = GMEM_FIXED + GMEM_ZEROINIT + +; Local memory flags + +LMEM_FIXED = 0000h +LMEM_MOVEABLE = 0002h +LMEM_NOCOMPACT = 0010h +LMEM_NODISCARD = 0020h +LMEM_ZEROINIT = 0040h +LMEM_MODIFY = 0080h +LMEM_DISCARDABLE = 0F00h +LMEM_VALID_FLAGS = 0F72h +LMEM_INVALID_HANDLE = 8000h +LHND = LMEM_MOVEABLE + LMEM_ZEROINIT +LPTR = LMEM_FIXED + LMEM_ZEROINIT +LMEM_DISCARDED = 4000h +LMEM_LOCKCOUNT = 00FFh + +; Page access flags + +PAGE_NOACCESS = 001h +PAGE_READONLY = 002h +PAGE_READWRITE = 004h +PAGE_WRITECOPY = 008h +PAGE_EXECUTE = 010h +PAGE_EXECUTE_READ = 020h +PAGE_EXECUTE_READWRITE = 040h +PAGE_EXECUTE_WRITECOPY = 080h +PAGE_GUARD = 100h +PAGE_NOCACHE = 200h + +; Memory allocation flags + +MEM_COMMIT = 001000h +MEM_RESERVE = 002000h +MEM_DECOMMIT = 004000h +MEM_RELEASE = 008000h +MEM_FREE = 010000h +MEM_PRIVATE = 020000h +MEM_MAPPED = 040000h +MEM_RESET = 080000h +MEM_TOP_DOWN = 100000h + +; Heap allocation flags + +HEAP_NO_SERIALIZE = 1 +HEAP_GENERATE_EXCEPTIONS = 4 +HEAP_ZERO_MEMORY = 8 + +; Platform identifiers + +VER_PLATFORM_WIN32s = 0 +VER_PLATFORM_WIN32_WINDOWS = 1 +VER_PLATFORM_WIN32_NT = 2 + +; GetBinaryType return values + +SCS_32BIT_BINARY = 0 +SCS_DOS_BINARY = 1 +SCS_WOW_BINARY = 2 +SCS_PIF_BINARY = 3 +SCS_POSIX_BINARY = 4 +SCS_OS216_BINARY = 5 + +; CreateProcess flags + +DEBUG_PROCESS = 001h +DEBUG_ONLY_THIS_PROCESS = 002h +CREATE_SUSPENDED = 004h +DETACHED_PROCESS = 008h +CREATE_NEW_CONSOLE = 010h +NORMAL_PRIORITY_CLASS = 020h +IDLE_PRIORITY_CLASS = 040h +HIGH_PRIORITY_CLASS = 080h +REALTIME_PRIORITY_CLASS = 100h +CREATE_NEW_PROCESS_GROUP = 200h +CREATE_SEPARATE_WOW_VDM = 800h + +; Thread priority values + +THREAD_BASE_PRIORITY_MIN = -2 +THREAD_BASE_PRIORITY_MAX = 2 +THREAD_BASE_PRIORITY_LOWRT = 15 +THREAD_BASE_PRIORITY_IDLE = -15 +THREAD_PRIORITY_LOWEST = THREAD_BASE_PRIORITY_MIN +THREAD_PRIORITY_BELOW_NORMAL = THREAD_PRIORITY_LOWEST + 1 +THREAD_PRIORITY_NORMAL = 0 +THREAD_PRIORITY_HIGHEST = THREAD_BASE_PRIORITY_MAX +THREAD_PRIORITY_ABOVE_NORMAL = THREAD_PRIORITY_HIGHEST - 1 +THREAD_PRIORITY_ERROR_RETURN = 7FFFFFFFh +THREAD_PRIORITY_TIME_CRITICAL = THREAD_BASE_PRIORITY_LOWRT +THREAD_PRIORITY_IDLE = THREAD_BASE_PRIORITY_IDLE + +; Startup flags + +STARTF_USESHOWWINDOW = 001h +STARTF_USESIZE = 002h +STARTF_USEPOSITION = 004h +STARTF_USECOUNTCHARS = 008h +STARTF_USEFILLATTRIBUTE = 010h +STARTF_RUNFULLSCREEN = 020h +STARTF_FORCEONFEEDBACK = 040h +STARTF_FORCEOFFFEEDBACK = 080h +STARTF_USESTDHANDLES = 100h + +; Shutdown flags + +SHUTDOWN_NORETRY = 1h + +; LoadLibraryEx flags + +DONT_RESOLVE_DLL_REFERENCES = 1 +LOAD_LIBRARY_AS_DATAFILE = 2 +LOAD_WITH_ALTERED_SEARCH_PATH = 8 + +; DLL entry-point calls + +DLL_PROCESS_DETACH = 0 +DLL_PROCESS_ATTACH = 1 +DLL_THREAD_ATTACH = 2 +DLL_THREAD_DETACH = 3 + +; Status codes + +STATUS_WAIT_0 = 000000000h +STATUS_ABANDONED_WAIT_0 = 000000080h +STATUS_USER_APC = 0000000C0h +STATUS_TIMEOUT = 000000102h +STATUS_PENDING = 000000103h +STATUS_DATATYPE_MISALIGNMENT = 080000002h +STATUS_BREAKPOINT = 080000003h +STATUS_SINGLE_STEP = 080000004h +STATUS_ACCESS_VIOLATION = 0C0000005h +STATUS_IN_PAGE_ERROR = 0C0000006h +STATUS_NO_MEMORY = 0C0000017h +STATUS_ILLEGAL_INSTRUCTION = 0C000001Dh +STATUS_NONCONTINUABLE_EXCEPTION = 0C0000025h +STATUS_INVALID_DISPOSITION = 0C0000026h +STATUS_ARRAY_BOUNDS_EXCEEDED = 0C000008Ch +STATUS_FLOAT_DENORMAL_OPERAND = 0C000008Dh +STATUS_FLOAT_DIVIDE_BY_ZERO = 0C000008Eh +STATUS_FLOAT_INEXACT_RESULT = 0C000008Fh +STATUS_FLOAT_INVALID_OPERATION = 0C0000090h +STATUS_FLOAT_OVERFLOW = 0C0000091h +STATUS_FLOAT_STACK_CHECK = 0C0000092h +STATUS_FLOAT_UNDERFLOW = 0C0000093h +STATUS_INTEGER_DIVIDE_BY_ZERO = 0C0000094h +STATUS_INTEGER_OVERFLOW = 0C0000095h +STATUS_PRIVILEGED_INSTRUCTION = 0C0000096h +STATUS_STACK_OVERFLOW = 0C00000FDh +STATUS_CONTROL_C_EXIT = 0C000013Ah +WAIT_FAILED = -1 +WAIT_OBJECT_0 = STATUS_WAIT_0 +WAIT_ABANDONED = STATUS_ABANDONED_WAIT_0 +WAIT_ABANDONED_0 = STATUS_ABANDONED_WAIT_0 +WAIT_TIMEOUT = STATUS_TIMEOUT +WAIT_IO_COMPLETION = STATUS_USER_APC +STILL_ACTIVE = STATUS_PENDING + +; Exception codes + +EXCEPTION_CONTINUABLE = 0 +EXCEPTION_NONCONTINUABLE = 1 +EXCEPTION_ACCESS_VIOLATION = STATUS_ACCESS_VIOLATION +EXCEPTION_DATATYPE_MISALIGNMENT = STATUS_DATATYPE_MISALIGNMENT +EXCEPTION_BREAKPOINT = STATUS_BREAKPOINT +EXCEPTION_SINGLE_STEP = STATUS_SINGLE_STEP +EXCEPTION_ARRAY_BOUNDS_EXCEEDED = STATUS_ARRAY_BOUNDS_EXCEEDED +EXCEPTION_FLT_DENORMAL_OPERAND = STATUS_FLOAT_DENORMAL_OPERAND +EXCEPTION_FLT_DIVIDE_BY_ZERO = STATUS_FLOAT_DIVIDE_BY_ZERO +EXCEPTION_FLT_INEXACT_RESULT = STATUS_FLOAT_INEXACT_RESULT +EXCEPTION_FLT_INVALID_OPERATION = STATUS_FLOAT_INVALID_OPERATION +EXCEPTION_FLT_OVERFLOW = STATUS_FLOAT_OVERFLOW +EXCEPTION_FLT_STACK_CHECK = STATUS_FLOAT_STACK_CHECK +EXCEPTION_FLT_UNDERFLOW = STATUS_FLOAT_UNDERFLOW +EXCEPTION_INT_DIVIDE_BY_ZERO = STATUS_INTEGER_DIVIDE_BY_ZERO +EXCEPTION_INT_OVERFLOW = STATUS_INTEGER_OVERFLOW +EXCEPTION_ILLEGAL_INSTRUCTION = STATUS_ILLEGAL_INSTRUCTION +EXCEPTION_PRIV_INSTRUCTION = STATUS_PRIVILEGED_INSTRUCTION +EXCEPTION_IN_PAGE_ERROR = STATUS_IN_PAGE_ERROR + +; Registry options + +REG_OPTION_RESERVED = 0 +REG_OPTION_NON_VOLATILE = 0 +REG_OPTION_VOLATILE = 1 +REG_OPTION_CREATE_LINK = 2 +REG_OPTION_BACKUP_RESTORE = 4 +REG_CREATED_NEW_KEY = 1 +REG_OPENED_EXISTING_KEY = 2 +REG_WHOLE_HIVE_VOLATILE = 1 +REG_REFRESH_HIVE = 2 +REG_NOTIFY_CHANGE_NAME = 1 +REG_NOTIFY_CHANGE_ATTRIBUTES = 2 +REG_NOTIFY_CHANGE_LAST_SET = 4 +REG_NOTIFY_CHANGE_SECURITY = 8 +REG_LEGAL_CHANGE_FILTER = REG_NOTIFY_CHANGE_NAME or REG_NOTIFY_CHANGE_ATTRIBUTES or REG_NOTIFY_CHANGE_LAST_SET or REG_NOTIFY_CHANGE_SECURITY +REG_LEGAL_OPTION = REG_OPTION_RESERVED or REG_OPTION_NON_VOLATILE or REG_OPTION_VOLATILE or REG_OPTION_CREATE_LINK or REG_OPTION_BACKUP_RESTORE +REG_NONE = 0 +REG_SZ = 1 +REG_EXPAND_SZ = 2 +REG_BINARY = 3 +REG_DWORD = 4 +REG_DWORD_LITTLE_ENDIAN = 4 +REG_DWORD_BIG_ENDIAN = 5 +REG_LINK = 6 +REG_MULTI_SZ = 7 +REG_RESOURCE_LIST = 8 +REG_FULL_RESOURCE_DESCRIPTOR = 9 +REG_RESOURCE_REQUIREMENTS_LIST = 10 + +; Registry access modes + +KEY_QUERY_VALUE = 1 +KEY_SET_VALUE = 2 +KEY_CREATE_SUB_KEY = 4 +KEY_ENUMERATE_SUB_KEYS = 8 +KEY_NOTIFY = 10h +KEY_CREATE_LINK = 20h +KEY_READ = STANDARD_RIGHTS_READ or KEY_QUERY_VALUE or KEY_ENUMERATE_SUB_KEYS or KEY_NOTIFY and not SYNCHRONIZE +KEY_WRITE = STANDARD_RIGHTS_WRITE or KEY_SET_VALUE or KEY_CREATE_SUB_KEY and not SYNCHRONIZE +KEY_EXECUTE = KEY_READ +KEY_ALL_ACCESS = STANDARD_RIGHTS_ALL or KEY_QUERY_VALUE or KEY_SET_VALUE or KEY_CREATE_SUB_KEY or KEY_ENUMERATE_SUB_KEYS or KEY_NOTIFY or KEY_CREATE_LINK and not SYNCHRONIZE + +; Predefined registry keys + +HKEY_CLASSES_ROOT = 80000000h +HKEY_CURRENT_USER = 80000001h +HKEY_LOCAL_MACHINE = 80000002h +HKEY_USERS = 80000003h +HKEY_PERFORMANCE_DATA = 80000004h +HKEY_CURRENT_CONFIG = 80000005h +HKEY_DYN_DATA = 80000006h + +; FormatMessage flags + +FORMAT_MESSAGE_ALLOCATE_BUFFER = 0100h +FORMAT_MESSAGE_IGNORE_INSERTS = 0200h +FORMAT_MESSAGE_FROM_STRING = 0400h +FORMAT_MESSAGE_FROM_HMODULE = 0800h +FORMAT_MESSAGE_FROM_SYSTEM = 1000h +FORMAT_MESSAGE_ARGUMENT_ARRAY = 2000h +FORMAT_MESSAGE_MAX_WIDTH_MASK = 00FFh + +; Language identifiers + +LANG_NEUTRAL = 00h +LANG_BULGARIAN = 02h +LANG_CHINESE = 04h +LANG_CROATIAN = 1Ah +LANG_CZECH = 05h +LANG_DANISH = 06h +LANG_DUTCH = 13h +LANG_ENGLISH = 09h +LANG_FINNISH = 0Bh +LANG_FRENCH = 0Ch +LANG_GERMAN = 07h +LANG_GREEK = 08h +LANG_HUNGARIAN = 0Eh +LANG_ICELANDIC = 0Fh +LANG_ITALIAN = 10h +LANG_JAPANESE = 11h +LANG_KOREAN = 12h +LANG_NORWEGIAN = 14h +LANG_POLISH = 15h +LANG_PORTUGUESE = 16h +LANG_ROMANIAN = 18h +LANG_RUSSIAN = 19h +LANG_SLOVAK = 1Bh +LANG_SLOVENIAN = 24h +LANG_SPANISH = 0Ah +LANG_SWEDISH = 1Dh +LANG_THAI = 1Eh +LANG_TURKISH = 1Fh + +; Sublanguage identifiers + +SUBLANG_NEUTRAL = 00h shl 10 +SUBLANG_DEFAULT = 01h shl 10 +SUBLANG_SYS_DEFAULT = 02h shl 10 +SUBLANG_CHINESE_TRADITIONAL = 01h shl 10 +SUBLANG_CHINESE_SIMPLIFIED = 02h shl 10 +SUBLANG_CHINESE_HONGKONG = 03h shl 10 +SUBLANG_CHINESE_SINGAPORE = 04h shl 10 +SUBLANG_DUTCH = 01h shl 10 +SUBLANG_DUTCH_BELGIAN = 02h shl 10 +SUBLANG_ENGLISH_US = 01h shl 10 +SUBLANG_ENGLISH_UK = 02h shl 10 +SUBLANG_ENGLISH_AUS = 03h shl 10 +SUBLANG_ENGLISH_CAN = 04h shl 10 +SUBLANG_ENGLISH_NZ = 05h shl 10 +SUBLANG_ENGLISH_EIRE = 06h shl 10 +SUBLANG_FRENCH = 01h shl 10 +SUBLANG_FRENCH_BELGIAN = 02h shl 10 +SUBLANG_FRENCH_CANADIAN = 03h shl 10 +SUBLANG_FRENCH_SWISS = 04h shl 10 +SUBLANG_GERMAN = 01h shl 10 +SUBLANG_GERMAN_SWISS = 02h shl 10 +SUBLANG_GERMAN_AUSTRIAN = 03h shl 10 +SUBLANG_ITALIAN = 01h shl 10 +SUBLANG_ITALIAN_SWISS = 02h shl 10 +SUBLANG_NORWEGIAN_BOKMAL = 01h shl 10 +SUBLANG_NORWEGIAN_NYNORSK = 02h shl 10 +SUBLANG_PORTUGUESE = 02h shl 10 +SUBLANG_PORTUGUESE_BRAZILIAN = 01h shl 10 +SUBLANG_SPANISH = 01h shl 10 +SUBLANG_SPANISH_MEXICAN = 02h shl 10 +SUBLANG_SPANISH_MODERN = 03h shl 10 + +; Sorting identifiers + +SORT_DEFAULT = 0 shl 16 +SORT_JAPANESE_XJIS = 0 shl 16 +SORT_JAPANESE_UNICODE = 1 shl 16 +SORT_CHINESE_BIG5 = 0 shl 16 +SORT_CHINESE_PRCP = 0 shl 16 +SORT_CHINESE_UNICODE = 1 shl 16 +SORT_CHINESE_PRC = 2 shl 16 +SORT_CHINESE_BOPOMOFO = 3 shl 16 +SORT_KOREAN_KSC = 0 shl 16 +SORT_KOREAN_UNICODE = 1 shl 16 +SORT_GERMAN_PHONE_BOOK = 1 shl 16 +SORT_HUNGARIAN_DEFAULT = 0 shl 16 +SORT_HUNGARIAN_TECHNICAL = 1 shl 16 + +; Code pages + +CP_ACP = 0 ; default to ANSI code page +CP_OEMCP = 1 ; default to OEM code page +CP_MACCP = 2 ; default to MAC code page +CP_THREAD_ACP = 3 ; current thread's ANSI code page +CP_SYMBOL = 42 ; SYMBOL translations +CP_UTF7 = 65000 ; UTF-7 translation +CP_UTF8 = 65001 ; UTF-8 translation + +; Resource types + +RT_CURSOR = 1 +RT_BITMAP = 2 +RT_ICON = 3 +RT_MENU = 4 +RT_DIALOG = 5 +RT_STRING = 6 +RT_FONTDIR = 7 +RT_FONT = 8 +RT_ACCELERATOR = 9 +RT_RCDATA = 10 +RT_MESSAGETABLE = 11 +RT_GROUP_CURSOR = 12 +RT_GROUP_ICON = 14 +RT_VERSION = 16 +RT_DLGINCLUDE = 17 +RT_PLUGPLAY = 19 +RT_VXD = 20 +RT_ANICURSOR = 21 +RT_ANIICON = 22 +RT_HTML = 23 +RT_MANIFEST = 24 + +; Clipboard formats + +CF_TEXT = 001h +CF_BITMAP = 002h +CF_METAFILEPICT = 003h +CF_SYLK = 004h +CF_DIF = 005h +CF_TIFF = 006h +CF_OEMTEXT = 007h +CF_DIB = 008h +CF_PALETTE = 009h +CF_PENDATA = 00Ah +CF_RIFF = 00Bh +CF_WAVE = 00Ch +CF_UNICODETEXT = 00Dh +CF_ENHMETAFILE = 00Eh +CF_HDROP = 00Fh +CF_LOCALE = 010h +CF_OWNERDISPLAY = 080h +CF_DSPTEXT = 081h +CF_DSPBITMAP = 082h +CF_DSPMETAFILEPICT = 083h +CF_DSPENHMETAFILE = 08Eh +CF_PRIVATEFIRST = 200h +CF_PRIVATELAST = 2FFh +CF_GDIOBJFIRST = 300h +CF_GDIOBJLAST = 3FFh + +; OS types for version info + +VOS_UNKNOWN = 00000000h +VOS_DOS = 00010000h +VOS_OS216 = 00020000h +VOS_OS232 = 00030000h +VOS_NT = 00040000h +VOS__BASE = 00000000h +VOS__WINDOWS16 = 00000001h +VOS__PM16 = 00000002h +VOS__PM32 = 00000003h +VOS__WINDOWS32 = 00000004h +VOS_DOS_WINDOWS16 = 00010001h +VOS_DOS_WINDOWS32 = 00010004h +VOS_OS216_PM16 = 00020002h +VOS_OS232_PM32 = 00030003h +VOS_NT_WINDOWS32 = 00040004h + +; File types for version info + +VFT_UNKNOWN = 00000000h +VFT_APP = 00000001h +VFT_DLL = 00000002h +VFT_DRV = 00000003h +VFT_FONT = 00000004h +VFT_VXD = 00000005h +VFT_STATIC_LIB = 00000007h + +; File subtypes for version info + +VFT2_UNKNOWN = 00000000h +VFT2_DRV_PRINTER = 00000001h +VFT2_DRV_KEYBOARD = 00000002h +VFT2_DRV_LANGUAGE = 00000003h +VFT2_DRV_DISPLAY = 00000004h +VFT2_DRV_MOUSE = 00000005h +VFT2_DRV_NETWORK = 00000006h +VFT2_DRV_SYSTEM = 00000007h +VFT2_DRV_INSTALLABLE = 00000008h +VFT2_DRV_SOUND = 00000009h +VFT2_DRV_COMM = 0000000Ah +VFT2_DRV_INPUTMETHOD = 0000000Bh +VFT2_DRV_VERSIONED_PRINTER = 0000000Ch +VFT2_FONT_RASTER = 00000001h +VFT2_FONT_VECTOR = 00000002h +VFT2_FONT_TRUETYPE = 00000003h + +; Console control signals + +CTRL_C_EVENT = 0 +CTRL_BREAK_EVENT = 1 +CTRL_CLOSE_EVENT = 2 +CTRL_LOGOFF_EVENT = 5 +CTRL_SHUTDOWN_EVENT = 6 + +; Standard file handles + +STD_INPUT_HANDLE = 0FFFFFFF6h +STD_OUTPUT_HANDLE = 0FFFFFFF5h +STD_ERROR_HANDLE = 0FFFFFFF4h diff --git a/toolchain/fasmw17332/INCLUDE/EQUATES/KERNEL64.INC b/toolchain/fasmw17332/INCLUDE/EQUATES/KERNEL64.INC new file mode 100644 index 0000000..a0e228b --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/EQUATES/KERNEL64.INC @@ -0,0 +1,806 @@ + +; KERNEL32.DLL structures and constants + +struct SYSTEM_INFO + wProcessorArchitecture dw ? + wReserved dw ? + dwPageSize dd ? + lpMinimumApplicationAddress dq ? + lpMaximumApplicationAddress dq ? + dwActiveProcessorMask dq ? + dwNumberOfProcessors dd ? + dwProcessorType dd ? + dwAllocationGranularity dd ? + wProcessorLevel dw ? + wProcessorRevision dw ? +ends + +struct OSVERSIONINFO + dwOSVersionInfoSize dd ? + dwMajorVersion dd ? + dwMinorVersion dd ? + dwBuildNumber dd ? + dwPlatformId dd ? + szCSDVersion TCHAR 128 dup (?) +ends + +struct OSVERSIONINFOA + dwOSVersionInfoSize dd ? + dwMajorVersion dd ? + dwMinorVersion dd ? + dwBuildNumber dd ? + dwPlatformId dd ? + szCSDVersion db 128 dup (?) +ends + +struct OSVERSIONINFOW + dwOSVersionInfoSize dd ? + dwMajorVersion dd ? + dwMinorVersion dd ? + dwBuildNumber dd ? + dwPlatformId dd ? + szCSDVersion du 128 dup (?) +ends + +struct MEMORYSTATUS + dwLength dd ? + dwMemoryLoad dd ? + dwTotalPhys dq ? + dwAvailPhys dq ? + dwTotalPageFile dq ? + dwAvailPageFile dq ? + dwTotalVirtual dq ? + dwAvailVirtual dq ? +ends + +struct STARTUPINFO + cb dd ?,? + lpReserved dq ? + lpDesktop dq ? + lpTitle dq ? + dwX dd ? + dwY dd ? + dwXSize dd ? + dwYSize dd ? + dwXCountChars dd ? + dwYCountChars dd ? + dwFillAttribute dd ? + dwFlags dd ? + wShowWindow dw ? + cbReserved2 dw ?,?,? + lpReserved2 dq ? + hStdInput dq ? + hStdOutput dq ? + hStdError dq ? +ends + +struct PROCESS_INFORMATION + hProcess dq ? + hThread dq ? + dwProcessId dd ? + dwThreadId dd ? +ends + +struct FILETIME + dwLowDateTime dd ? + dwHighDateTime dd ? +ends + +struct SYSTEMTIME + wYear dw ? + wMonth dw ? + wDayOfWeek dw ? + wDay dw ? + wHour dw ? + wMinute dw ? + wSecond dw ? + wMilliseconds dw ? +ends + +struct BY_HANDLE_FILE_INFORMATION + dwFileAttributes dd ? + ftCreationTime FILETIME + ftLastAccessTime FILETIME + ftLastWriteTime FILETIME + dwVolumeSerialNumber dd ? + nFileSizeHigh dd ? + nFileSizeLow dd ? + nNumberOfLinks dd ? + nFileIndexHigh dd ? + nFileIndexLow dd ? +ends + +struct WIN32_FIND_DATA + dwFileAttributes dd ? + ftCreationTime FILETIME + ftLastAccessTime FILETIME + ftLastWriteTime FILETIME + nFileSizeHigh dd ? + nFileSizeLow dd ? + dwReserved0 dd ? + dwReserved1 dd ? + cFileName TCHAR MAX_PATH dup (?) + cAlternateFileName TCHAR 14 dup (?) +ends + +struct WIN32_FIND_DATAA + dwFileAttributes dd ? + ftCreationTime FILETIME + ftLastAccessTime FILETIME + ftLastWriteTime FILETIME + nFileSizeHigh dd ? + nFileSizeLow dd ? + dwReserved0 dd ? + dwReserved1 dd ? + cFileName db MAX_PATH dup (?) + cAlternateFileName db 14 dup (?) +ends + +struct WIN32_FIND_DATAW + dwFileAttributes dd ? + ftCreationTime FILETIME + ftLastAccessTime FILETIME + ftLastWriteTime FILETIME + nFileSizeHigh dd ? + nFileSizeLow dd ? + dwReserved0 dd ? + dwReserved1 dd ? + cFileName du MAX_PATH dup (?) + cAlternateFileName du 14 dup (?) +ends + +; General constants + +NULL = 0 +TRUE = 1 +FALSE = 0 + +; Maximum path length in characters + +MAX_PATH = 260 + +; Access rights + +DELETE_RIGHT = 00010000h +READ_CONTROL = 00020000h +WRITE_DAC = 00040000h +WRITE_OWNER = 00080000h +SYNCHRONIZE = 00100000h +STANDARD_RIGHTS_READ = READ_CONTROL +STANDARD_RIGHTS_WRITE = READ_CONTROL +STANDARD_RIGHTS_EXECUTE = READ_CONTROL +STANDARD_RIGHTS_REQUIRED = 000F0000h +STANDARD_RIGHTS_ALL = 001F0000h +SPECIFIC_RIGHTS_ALL = 0000FFFFh +ACCESS_SYSTEM_SECURITY = 01000000h +MAXIMUM_ALLOWED = 02000000h +GENERIC_READ = 80000000h +GENERIC_WRITE = 40000000h +GENERIC_EXECUTE = 20000000h +GENERIC_ALL = 10000000h +PROCESS_TERMINATE = 00000001h +PROCESS_CREATE_THREAD = 00000002h +PROCESS_VM_OPERATION = 00000008h +PROCESS_VM_READ = 00000010h +PROCESS_VM_WRITE = 00000020h +PROCESS_DUP_HANDLE = 00000040h +PROCESS_CREATE_PROCESS = 00000080h +PROCESS_SET_QUOTA = 00000100h +PROCESS_SET_INFORMATION = 00000200h +PROCESS_QUERY_INFORMATION = 00000400h +PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or 0FFFh +FILE_SHARE_READ = 00000001h +FILE_SHARE_WRITE = 00000002h +FILE_SHARE_DELETE = 00000004h + +; CreateFile actions + +CREATE_NEW = 1 +CREATE_ALWAYS = 2 +OPEN_EXISTING = 3 +OPEN_ALWAYS = 4 +TRUNCATE_EXISTING = 5 + +; OpenFile modes + +OF_READ = 0000h +OF_WRITE = 0001h +OF_READWRITE = 0002h +OF_SHARE_COMPAT = 0000h +OF_SHARE_EXCLUSIVE = 0010h +OF_SHARE_DENY_WRITE = 0020h +OF_SHARE_DENY_READ = 0030h +OF_SHARE_DENY_NONE = 0040h +OF_PARSE = 0100h +OF_DELETE = 0200h +OF_VERIFY = 0400h +OF_CANCEL = 0800h +OF_CREATE = 1000h +OF_PROMPT = 2000h +OF_EXIST = 4000h +OF_REOPEN = 8000h + +; SetFilePointer methods + +FILE_BEGIN = 0 +FILE_CURRENT = 1 +FILE_END = 2 + +; File attributes + +FILE_ATTRIBUTE_READONLY = 001h +FILE_ATTRIBUTE_HIDDEN = 002h +FILE_ATTRIBUTE_SYSTEM = 004h +FILE_ATTRIBUTE_DIRECTORY = 010h +FILE_ATTRIBUTE_ARCHIVE = 020h +FILE_ATTRIBUTE_NORMAL = 080h +FILE_ATTRIBUTE_TEMPORARY = 100h +FILE_ATTRIBUTE_COMPRESSED = 800h + +; File flags + +FILE_FLAG_WRITE_THROUGH = 80000000h +FILE_FLAG_OVERLAPPED = 40000000h +FILE_FLAG_NO_BUFFERING = 20000000h +FILE_FLAG_RANDOM_ACCESS = 10000000h +FILE_FLAG_SEQUENTIAL_SCAN = 08000000h +FILE_FLAG_DELETE_ON_CLOSE = 04000000h +FILE_FLAG_BACKUP_SEMANTICS = 02000000h +FILE_FLAG_POSIX_SEMANTICS = 01000000h + +; Notify filters + +FILE_NOTIFY_CHANGE_FILE_NAME = 001h +FILE_NOTIFY_CHANGE_DIR_NAME = 002h +FILE_NOTIFY_CHANGE_ATTRIBUTES = 004h +FILE_NOTIFY_CHANGE_SIZE = 008h +FILE_NOTIFY_CHANGE_LAST_WRITE = 010h +FILE_NOTIFY_CHANGE_SECURITY = 100h + +; File types + +FILE_TYPE_UNKNOWN = 0 +FILE_TYPE_DISK = 1 +FILE_TYPE_CHAR = 2 +FILE_TYPE_PIPE = 3 +FILE_TYPE_REMOTE = 8000h + +; LockFileEx flags + +LOCKFILE_FAIL_IMMEDIATELY = 1 +LOCKFILE_EXCLUSIVE_LOCK = 2 + +; MoveFileEx flags + +MOVEFILE_REPLACE_EXISTING = 1 +MOVEFILE_COPY_ALLOWED = 2 +MOVEFILE_DELAY_UNTIL_REBOOT = 4 +MOVEFILE_WRITE_THROUGH = 8 + +; FindFirstFileEx flags + +FIND_FIRST_EX_CASE_SENSITIVE = 1 + +; Device handles + +INVALID_HANDLE_VALUE = -1 +STD_INPUT_HANDLE = -10 +STD_OUTPUT_HANDLE = -11 +STD_ERROR_HANDLE = -12 + +; DuplicateHandle options + +DUPLICATE_CLOSE_SOURCE = 1 +DUPLICATE_SAME_ACCESS = 2 + +; File mapping acccess rights + +SECTION_QUERY = 01h +SECTION_MAP_WRITE = 02h +SECTION_MAP_READ = 04h +SECTION_MAP_EXECUTE = 08h +SECTION_EXTEND_SIZE = 10h +SECTION_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED or SECTION_QUERY or SECTION_MAP_WRITE or SECTION_MAP_READ or SECTION_MAP_EXECUTE or SECTION_EXTEND_SIZE +FILE_MAP_COPY = SECTION_QUERY +FILE_MAP_WRITE = SECTION_MAP_WRITE +FILE_MAP_READ = SECTION_MAP_READ +FILE_MAP_ALL_ACCESS = SECTION_ALL_ACCESS + +; File system flags + +FILE_CASE_SENSITIVE_SEARCH = 0001h +FILE_CASE_PRESERVED_NAMES = 0002h +FILE_UNICODE_ON_DISK = 0004h +FILE_PERSISTENT_ACLS = 0008h +FILE_FILE_COMPRESSION = 0010h +FILE_VOLUME_IS_COMPRESSED = 8000h +FS_CASE_IS_PRESERVED = FILE_CASE_PRESERVED_NAMES +FS_CASE_SENSITIVE = FILE_CASE_SENSITIVE_SEARCH +FS_UNICODE_STORED_ON_DISK = FILE_UNICODE_ON_DISK +FS_PERSISTENT_ACLS = FILE_PERSISTENT_ACLS + +; Drive types + +DRIVE_UNKNOWN = 0 +DRIVE_NO_ROOT_DIR = 1 +DRIVE_REMOVABLE = 2 +DRIVE_FIXED = 3 +DRIVE_REMOTE = 4 +DRIVE_CDROM = 5 +DRIVE_RAMDISK = 6 + +; Pipe modes + +PIPE_ACCESS_INBOUND = 1 +PIPE_ACCESS_OUTBOUND = 2 +PIPE_ACCESS_DUPLEX = 3 +PIPE_CLIENT_END = 0 +PIPE_SERVER_END = 1 +PIPE_WAIT = 0 +PIPE_NOWAIT = 1 +PIPE_READMODE_BYTE = 0 +PIPE_READMODE_MESSAGE = 2 +PIPE_TYPE_BYTE = 0 +PIPE_TYPE_MESSAGE = 4 +PIPE_UNLIMITED_INSTANCES = 255 + +; Global memory flags + +GMEM_FIXED = 0000h +GMEM_MOVEABLE = 0002h +GMEM_NOCOMPACT = 0010h +GMEM_NODISCARD = 0020h +GMEM_ZEROINIT = 0040h +GMEM_MODIFY = 0080h +GMEM_DISCARDABLE = 0100h +GMEM_NOT_BANKED = 1000h +GMEM_SHARE = 2000h +GMEM_DDESHARE = 2000h +GMEM_NOTIFY = 4000h +GMEM_LOWER = GMEM_NOT_BANKED +GMEM_VALID_FLAGS = 7F72h +GMEM_INVALID_HANDLE = 8000h +GMEM_DISCARDED = 4000h +GMEM_LOCKCOUNT = 0FFh +GHND = GMEM_MOVEABLE + GMEM_ZEROINIT +GPTR = GMEM_FIXED + GMEM_ZEROINIT + +; Local memory flags + +LMEM_FIXED = 0000h +LMEM_MOVEABLE = 0002h +LMEM_NOCOMPACT = 0010h +LMEM_NODISCARD = 0020h +LMEM_ZEROINIT = 0040h +LMEM_MODIFY = 0080h +LMEM_DISCARDABLE = 0F00h +LMEM_VALID_FLAGS = 0F72h +LMEM_INVALID_HANDLE = 8000h +LHND = LMEM_MOVEABLE + LMEM_ZEROINIT +LPTR = LMEM_FIXED + LMEM_ZEROINIT +LMEM_DISCARDED = 4000h +LMEM_LOCKCOUNT = 00FFh + +; Page access flags + +PAGE_NOACCESS = 001h +PAGE_READONLY = 002h +PAGE_READWRITE = 004h +PAGE_WRITECOPY = 008h +PAGE_EXECUTE = 010h +PAGE_EXECUTE_READ = 020h +PAGE_EXECUTE_READWRITE = 040h +PAGE_EXECUTE_WRITECOPY = 080h +PAGE_GUARD = 100h +PAGE_NOCACHE = 200h + +; Memory allocation flags + +MEM_COMMIT = 001000h +MEM_RESERVE = 002000h +MEM_DECOMMIT = 004000h +MEM_RELEASE = 008000h +MEM_FREE = 010000h +MEM_PRIVATE = 020000h +MEM_MAPPED = 040000h +MEM_RESET = 080000h +MEM_TOP_DOWN = 100000h + +; Heap allocation flags + +HEAP_NO_SERIALIZE = 1 +HEAP_GENERATE_EXCEPTIONS = 4 +HEAP_ZERO_MEMORY = 8 + +; Platform identifiers + +VER_PLATFORM_WIN32s = 0 +VER_PLATFORM_WIN32_WINDOWS = 1 +VER_PLATFORM_WIN32_NT = 2 + +; GetBinaryType return values + +SCS_32BIT_BINARY = 0 +SCS_DOS_BINARY = 1 +SCS_WOW_BINARY = 2 +SCS_PIF_BINARY = 3 +SCS_POSIX_BINARY = 4 +SCS_OS216_BINARY = 5 + +; CreateProcess flags + +DEBUG_PROCESS = 001h +DEBUG_ONLY_THIS_PROCESS = 002h +CREATE_SUSPENDED = 004h +DETACHED_PROCESS = 008h +CREATE_NEW_CONSOLE = 010h +NORMAL_PRIORITY_CLASS = 020h +IDLE_PRIORITY_CLASS = 040h +HIGH_PRIORITY_CLASS = 080h +REALTIME_PRIORITY_CLASS = 100h +CREATE_NEW_PROCESS_GROUP = 200h +CREATE_SEPARATE_WOW_VDM = 800h + +; Thread priority values + +THREAD_BASE_PRIORITY_MIN = -2 +THREAD_BASE_PRIORITY_MAX = 2 +THREAD_BASE_PRIORITY_LOWRT = 15 +THREAD_BASE_PRIORITY_IDLE = -15 +THREAD_PRIORITY_LOWEST = THREAD_BASE_PRIORITY_MIN +THREAD_PRIORITY_BELOW_NORMAL = THREAD_PRIORITY_LOWEST + 1 +THREAD_PRIORITY_NORMAL = 0 +THREAD_PRIORITY_HIGHEST = THREAD_BASE_PRIORITY_MAX +THREAD_PRIORITY_ABOVE_NORMAL = THREAD_PRIORITY_HIGHEST - 1 +THREAD_PRIORITY_ERROR_RETURN = 7FFFFFFFh +THREAD_PRIORITY_TIME_CRITICAL = THREAD_BASE_PRIORITY_LOWRT +THREAD_PRIORITY_IDLE = THREAD_BASE_PRIORITY_IDLE + +; Startup flags + +STARTF_USESHOWWINDOW = 001h +STARTF_USESIZE = 002h +STARTF_USEPOSITION = 004h +STARTF_USECOUNTCHARS = 008h +STARTF_USEFILLATTRIBUTE = 010h +STARTF_RUNFULLSCREEN = 020h +STARTF_FORCEONFEEDBACK = 040h +STARTF_FORCEOFFFEEDBACK = 080h +STARTF_USESTDHANDLES = 100h + +; Shutdown flags + +SHUTDOWN_NORETRY = 1h + +; LoadLibraryEx flags + +DONT_RESOLVE_DLL_REFERENCES = 1 +LOAD_LIBRARY_AS_DATAFILE = 2 +LOAD_WITH_ALTERED_SEARCH_PATH = 8 + +; DLL entry-point calls + +DLL_PROCESS_DETACH = 0 +DLL_PROCESS_ATTACH = 1 +DLL_THREAD_ATTACH = 2 +DLL_THREAD_DETACH = 3 + +; Status codes + +STATUS_WAIT_0 = 000000000h +STATUS_ABANDONED_WAIT_0 = 000000080h +STATUS_USER_APC = 0000000C0h +STATUS_TIMEOUT = 000000102h +STATUS_PENDING = 000000103h +STATUS_DATATYPE_MISALIGNMENT = 080000002h +STATUS_BREAKPOINT = 080000003h +STATUS_SINGLE_STEP = 080000004h +STATUS_ACCESS_VIOLATION = 0C0000005h +STATUS_IN_PAGE_ERROR = 0C0000006h +STATUS_NO_MEMORY = 0C0000017h +STATUS_ILLEGAL_INSTRUCTION = 0C000001Dh +STATUS_NONCONTINUABLE_EXCEPTION = 0C0000025h +STATUS_INVALID_DISPOSITION = 0C0000026h +STATUS_ARRAY_BOUNDS_EXCEEDED = 0C000008Ch +STATUS_FLOAT_DENORMAL_OPERAND = 0C000008Dh +STATUS_FLOAT_DIVIDE_BY_ZERO = 0C000008Eh +STATUS_FLOAT_INEXACT_RESULT = 0C000008Fh +STATUS_FLOAT_INVALID_OPERATION = 0C0000090h +STATUS_FLOAT_OVERFLOW = 0C0000091h +STATUS_FLOAT_STACK_CHECK = 0C0000092h +STATUS_FLOAT_UNDERFLOW = 0C0000093h +STATUS_INTEGER_DIVIDE_BY_ZERO = 0C0000094h +STATUS_INTEGER_OVERFLOW = 0C0000095h +STATUS_PRIVILEGED_INSTRUCTION = 0C0000096h +STATUS_STACK_OVERFLOW = 0C00000FDh +STATUS_CONTROL_C_EXIT = 0C000013Ah +WAIT_FAILED = -1 +WAIT_OBJECT_0 = STATUS_WAIT_0 +WAIT_ABANDONED = STATUS_ABANDONED_WAIT_0 +WAIT_ABANDONED_0 = STATUS_ABANDONED_WAIT_0 +WAIT_TIMEOUT = STATUS_TIMEOUT +WAIT_IO_COMPLETION = STATUS_USER_APC +STILL_ACTIVE = STATUS_PENDING + +; Exception codes + +EXCEPTION_CONTINUABLE = 0 +EXCEPTION_NONCONTINUABLE = 1 +EXCEPTION_ACCESS_VIOLATION = STATUS_ACCESS_VIOLATION +EXCEPTION_DATATYPE_MISALIGNMENT = STATUS_DATATYPE_MISALIGNMENT +EXCEPTION_BREAKPOINT = STATUS_BREAKPOINT +EXCEPTION_SINGLE_STEP = STATUS_SINGLE_STEP +EXCEPTION_ARRAY_BOUNDS_EXCEEDED = STATUS_ARRAY_BOUNDS_EXCEEDED +EXCEPTION_FLT_DENORMAL_OPERAND = STATUS_FLOAT_DENORMAL_OPERAND +EXCEPTION_FLT_DIVIDE_BY_ZERO = STATUS_FLOAT_DIVIDE_BY_ZERO +EXCEPTION_FLT_INEXACT_RESULT = STATUS_FLOAT_INEXACT_RESULT +EXCEPTION_FLT_INVALID_OPERATION = STATUS_FLOAT_INVALID_OPERATION +EXCEPTION_FLT_OVERFLOW = STATUS_FLOAT_OVERFLOW +EXCEPTION_FLT_STACK_CHECK = STATUS_FLOAT_STACK_CHECK +EXCEPTION_FLT_UNDERFLOW = STATUS_FLOAT_UNDERFLOW +EXCEPTION_INT_DIVIDE_BY_ZERO = STATUS_INTEGER_DIVIDE_BY_ZERO +EXCEPTION_INT_OVERFLOW = STATUS_INTEGER_OVERFLOW +EXCEPTION_ILLEGAL_INSTRUCTION = STATUS_ILLEGAL_INSTRUCTION +EXCEPTION_PRIV_INSTRUCTION = STATUS_PRIVILEGED_INSTRUCTION +EXCEPTION_IN_PAGE_ERROR = STATUS_IN_PAGE_ERROR + +; Registry options + +REG_OPTION_RESERVED = 0 +REG_OPTION_NON_VOLATILE = 0 +REG_OPTION_VOLATILE = 1 +REG_OPTION_CREATE_LINK = 2 +REG_OPTION_BACKUP_RESTORE = 4 +REG_CREATED_NEW_KEY = 1 +REG_OPENED_EXISTING_KEY = 2 +REG_WHOLE_HIVE_VOLATILE = 1 +REG_REFRESH_HIVE = 2 +REG_NOTIFY_CHANGE_NAME = 1 +REG_NOTIFY_CHANGE_ATTRIBUTES = 2 +REG_NOTIFY_CHANGE_LAST_SET = 4 +REG_NOTIFY_CHANGE_SECURITY = 8 +REG_LEGAL_CHANGE_FILTER = REG_NOTIFY_CHANGE_NAME or REG_NOTIFY_CHANGE_ATTRIBUTES or REG_NOTIFY_CHANGE_LAST_SET or REG_NOTIFY_CHANGE_SECURITY +REG_LEGAL_OPTION = REG_OPTION_RESERVED or REG_OPTION_NON_VOLATILE or REG_OPTION_VOLATILE or REG_OPTION_CREATE_LINK or REG_OPTION_BACKUP_RESTORE +REG_NONE = 0 +REG_SZ = 1 +REG_EXPAND_SZ = 2 +REG_BINARY = 3 +REG_DWORD = 4 +REG_DWORD_LITTLE_ENDIAN = 4 +REG_DWORD_BIG_ENDIAN = 5 +REG_LINK = 6 +REG_MULTI_SZ = 7 +REG_RESOURCE_LIST = 8 +REG_FULL_RESOURCE_DESCRIPTOR = 9 +REG_RESOURCE_REQUIREMENTS_LIST = 10 + +; Registry access modes + +KEY_QUERY_VALUE = 1 +KEY_SET_VALUE = 2 +KEY_CREATE_SUB_KEY = 4 +KEY_ENUMERATE_SUB_KEYS = 8 +KEY_NOTIFY = 10h +KEY_CREATE_LINK = 20h +KEY_READ = STANDARD_RIGHTS_READ or KEY_QUERY_VALUE or KEY_ENUMERATE_SUB_KEYS or KEY_NOTIFY and not SYNCHRONIZE +KEY_WRITE = STANDARD_RIGHTS_WRITE or KEY_SET_VALUE or KEY_CREATE_SUB_KEY and not SYNCHRONIZE +KEY_EXECUTE = KEY_READ +KEY_ALL_ACCESS = STANDARD_RIGHTS_ALL or KEY_QUERY_VALUE or KEY_SET_VALUE or KEY_CREATE_SUB_KEY or KEY_ENUMERATE_SUB_KEYS or KEY_NOTIFY or KEY_CREATE_LINK and not SYNCHRONIZE + +; Predefined registry keys + +HKEY_CLASSES_ROOT = 80000000h +HKEY_CURRENT_USER = 80000001h +HKEY_LOCAL_MACHINE = 80000002h +HKEY_USERS = 80000003h +HKEY_PERFORMANCE_DATA = 80000004h +HKEY_CURRENT_CONFIG = 80000005h +HKEY_DYN_DATA = 80000006h + +; FormatMessage flags + +FORMAT_MESSAGE_ALLOCATE_BUFFER = 0100h +FORMAT_MESSAGE_IGNORE_INSERTS = 0200h +FORMAT_MESSAGE_FROM_STRING = 0400h +FORMAT_MESSAGE_FROM_HMODULE = 0800h +FORMAT_MESSAGE_FROM_SYSTEM = 1000h +FORMAT_MESSAGE_ARGUMENT_ARRAY = 2000h +FORMAT_MESSAGE_MAX_WIDTH_MASK = 00FFh + +; Language identifiers + +LANG_NEUTRAL = 00h +LANG_BULGARIAN = 02h +LANG_CHINESE = 04h +LANG_CROATIAN = 1Ah +LANG_CZECH = 05h +LANG_DANISH = 06h +LANG_DUTCH = 13h +LANG_ENGLISH = 09h +LANG_FINNISH = 0Bh +LANG_FRENCH = 0Ch +LANG_GERMAN = 07h +LANG_GREEK = 08h +LANG_HUNGARIAN = 0Eh +LANG_ICELANDIC = 0Fh +LANG_ITALIAN = 10h +LANG_JAPANESE = 11h +LANG_KOREAN = 12h +LANG_NORWEGIAN = 14h +LANG_POLISH = 15h +LANG_PORTUGUESE = 16h +LANG_ROMANIAN = 18h +LANG_RUSSIAN = 19h +LANG_SLOVAK = 1Bh +LANG_SLOVENIAN = 24h +LANG_SPANISH = 0Ah +LANG_SWEDISH = 1Dh +LANG_THAI = 1Eh +LANG_TURKISH = 1Fh + +; Sublanguage identifiers + +SUBLANG_NEUTRAL = 00h shl 10 +SUBLANG_DEFAULT = 01h shl 10 +SUBLANG_SYS_DEFAULT = 02h shl 10 +SUBLANG_CHINESE_TRADITIONAL = 01h shl 10 +SUBLANG_CHINESE_SIMPLIFIED = 02h shl 10 +SUBLANG_CHINESE_HONGKONG = 03h shl 10 +SUBLANG_CHINESE_SINGAPORE = 04h shl 10 +SUBLANG_DUTCH = 01h shl 10 +SUBLANG_DUTCH_BELGIAN = 02h shl 10 +SUBLANG_ENGLISH_US = 01h shl 10 +SUBLANG_ENGLISH_UK = 02h shl 10 +SUBLANG_ENGLISH_AUS = 03h shl 10 +SUBLANG_ENGLISH_CAN = 04h shl 10 +SUBLANG_ENGLISH_NZ = 05h shl 10 +SUBLANG_ENGLISH_EIRE = 06h shl 10 +SUBLANG_FRENCH = 01h shl 10 +SUBLANG_FRENCH_BELGIAN = 02h shl 10 +SUBLANG_FRENCH_CANADIAN = 03h shl 10 +SUBLANG_FRENCH_SWISS = 04h shl 10 +SUBLANG_GERMAN = 01h shl 10 +SUBLANG_GERMAN_SWISS = 02h shl 10 +SUBLANG_GERMAN_AUSTRIAN = 03h shl 10 +SUBLANG_ITALIAN = 01h shl 10 +SUBLANG_ITALIAN_SWISS = 02h shl 10 +SUBLANG_NORWEGIAN_BOKMAL = 01h shl 10 +SUBLANG_NORWEGIAN_NYNORSK = 02h shl 10 +SUBLANG_PORTUGUESE = 02h shl 10 +SUBLANG_PORTUGUESE_BRAZILIAN = 01h shl 10 +SUBLANG_SPANISH = 01h shl 10 +SUBLANG_SPANISH_MEXICAN = 02h shl 10 +SUBLANG_SPANISH_MODERN = 03h shl 10 + +; Sorting identifiers + +SORT_DEFAULT = 0 shl 16 +SORT_JAPANESE_XJIS = 0 shl 16 +SORT_JAPANESE_UNICODE = 1 shl 16 +SORT_CHINESE_BIG5 = 0 shl 16 +SORT_CHINESE_PRCP = 0 shl 16 +SORT_CHINESE_UNICODE = 1 shl 16 +SORT_CHINESE_PRC = 2 shl 16 +SORT_CHINESE_BOPOMOFO = 3 shl 16 +SORT_KOREAN_KSC = 0 shl 16 +SORT_KOREAN_UNICODE = 1 shl 16 +SORT_GERMAN_PHONE_BOOK = 1 shl 16 +SORT_HUNGARIAN_DEFAULT = 0 shl 16 +SORT_HUNGARIAN_TECHNICAL = 1 shl 16 + +; Code pages + +CP_ACP = 0 ; default to ANSI code page +CP_OEMCP = 1 ; default to OEM code page +CP_MACCP = 2 ; default to MAC code page +CP_THREAD_ACP = 3 ; current thread's ANSI code page +CP_SYMBOL = 42 ; SYMBOL translations +CP_UTF7 = 65000 ; UTF-7 translation +CP_UTF8 = 65001 ; UTF-8 translation + +; Resource types + +RT_CURSOR = 1 +RT_BITMAP = 2 +RT_ICON = 3 +RT_MENU = 4 +RT_DIALOG = 5 +RT_STRING = 6 +RT_FONTDIR = 7 +RT_FONT = 8 +RT_ACCELERATOR = 9 +RT_RCDATA = 10 +RT_MESSAGETABLE = 11 +RT_GROUP_CURSOR = 12 +RT_GROUP_ICON = 14 +RT_VERSION = 16 +RT_DLGINCLUDE = 17 +RT_PLUGPLAY = 19 +RT_VXD = 20 +RT_ANICURSOR = 21 +RT_ANIICON = 22 +RT_HTML = 23 +RT_MANIFEST = 24 + +; Clipboard formats + +CF_TEXT = 001h +CF_BITMAP = 002h +CF_METAFILEPICT = 003h +CF_SYLK = 004h +CF_DIF = 005h +CF_TIFF = 006h +CF_OEMTEXT = 007h +CF_DIB = 008h +CF_PALETTE = 009h +CF_PENDATA = 00Ah +CF_RIFF = 00Bh +CF_WAVE = 00Ch +CF_UNICODETEXT = 00Dh +CF_ENHMETAFILE = 00Eh +CF_HDROP = 00Fh +CF_LOCALE = 010h +CF_OWNERDISPLAY = 080h +CF_DSPTEXT = 081h +CF_DSPBITMAP = 082h +CF_DSPMETAFILEPICT = 083h +CF_DSPENHMETAFILE = 08Eh +CF_PRIVATEFIRST = 200h +CF_PRIVATELAST = 2FFh +CF_GDIOBJFIRST = 300h +CF_GDIOBJLAST = 3FFh + +; OS types for version info + +VOS_UNKNOWN = 00000000h +VOS_DOS = 00010000h +VOS_OS216 = 00020000h +VOS_OS232 = 00030000h +VOS_NT = 00040000h +VOS__BASE = 00000000h +VOS__WINDOWS16 = 00000001h +VOS__PM16 = 00000002h +VOS__PM32 = 00000003h +VOS__WINDOWS32 = 00000004h +VOS_DOS_WINDOWS16 = 00010001h +VOS_DOS_WINDOWS32 = 00010004h +VOS_OS216_PM16 = 00020002h +VOS_OS232_PM32 = 00030003h +VOS_NT_WINDOWS32 = 00040004h + +; File types for version info + +VFT_UNKNOWN = 00000000h +VFT_APP = 00000001h +VFT_DLL = 00000002h +VFT_DRV = 00000003h +VFT_FONT = 00000004h +VFT_VXD = 00000005h +VFT_STATIC_LIB = 00000007h + +; File subtypes for version info + +VFT2_UNKNOWN = 00000000h +VFT2_DRV_PRINTER = 00000001h +VFT2_DRV_KEYBOARD = 00000002h +VFT2_DRV_LANGUAGE = 00000003h +VFT2_DRV_DISPLAY = 00000004h +VFT2_DRV_MOUSE = 00000005h +VFT2_DRV_NETWORK = 00000006h +VFT2_DRV_SYSTEM = 00000007h +VFT2_DRV_INSTALLABLE = 00000008h +VFT2_DRV_SOUND = 00000009h +VFT2_DRV_COMM = 0000000Ah +VFT2_DRV_INPUTMETHOD = 0000000Bh +VFT2_DRV_VERSIONED_PRINTER = 0000000Ch +VFT2_FONT_RASTER = 00000001h +VFT2_FONT_VECTOR = 00000002h +VFT2_FONT_TRUETYPE = 00000003h + +; Console control signals + +CTRL_C_EVENT = 0 +CTRL_BREAK_EVENT = 1 +CTRL_CLOSE_EVENT = 2 +CTRL_LOGOFF_EVENT = 5 +CTRL_SHUTDOWN_EVENT = 6 diff --git a/toolchain/fasmw17332/INCLUDE/EQUATES/SHELL32.INC b/toolchain/fasmw17332/INCLUDE/EQUATES/SHELL32.INC new file mode 100644 index 0000000..aa2b0ad --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/EQUATES/SHELL32.INC @@ -0,0 +1,128 @@ + +; SHELL32.DLL structures and constants + +struct NOTIFYICONDATA + cbSize dd ? + hWnd dd ? + uID dd ? + uFlags dd ? + uCallbackMessage dd ? + hIcon dd ? + szTip TCHAR 64 dup (?) +ends + +struct NOTIFYICONDATAA + cbSize dd ? + hWnd dd ? + uID dd ? + uFlags dd ? + uCallbackMessage dd ? + hIcon dd ? + szTip db 64 dup (?) +ends + +struct NOTIFYICONDATAW + cbSize dd ? + hWnd dd ? + uID dd ? + uFlags dd ? + uCallbackMessage dd ? + hIcon dd ? + szTip du 64 dup (?) +ends + +struct BROWSEINFO + hwndOwner dd ? + pidlRoot dd ? + pszDisplayName dd ? + lpszTitle dd ? + ulFlags dd ? + lpfn dd ? + lParam dd ? + iImage dd ? +ends + +; Taskbar icon messages + +NIM_ADD = 0 +NIM_MODIFY = 1 +NIM_DELETE = 2 +NIM_SETFOCUS = 3 +NIM_SETVERSION = 4 + +; Taskbar icon flags + +NIF_MESSAGE = 01h +NIF_ICON = 02h +NIF_TIP = 04h +NIF_STATE = 08h +NIF_INFO = 10h +NIF_GUID = 20h + +; Constant Special Item ID List + +CSIDL_DESKTOP = 0x0000 +CSIDL_INTERNET = 0x0001 +CSIDL_PROGRAMS = 0x0002 +CSIDL_CONTROLS = 0x0003 +CSIDL_PRINTERS = 0x0004 +CSIDL_PERSONAL = 0x0005 +CSIDL_FAVORITES = 0x0006 +CSIDL_STARTUP = 0x0007 +CSIDL_RECENT = 0x0008 +CSIDL_SENDTO = 0x0009 +CSIDL_BITBUCKET = 0x000A +CSIDL_STARTMENU = 0x000B +CSIDL_MYDOCUMENTS = 0x000C +CSIDL_MYMUSIC = 0x000D +CSIDL_MYVIDEO = 0x000E +CSIDL_DESKTOPDIRECTORY = 0x0010 +CSIDL_DRIVES = 0x0011 +CSIDL_NETWORK = 0x0012 +CSIDL_NETHOOD = 0x0013 +CSIDL_FONTS = 0x0014 +CSIDL_TEMPLATES = 0x0015 +CSIDL_COMMON_STARTMENU = 0x0016 +CSIDL_COMMON_PROGRAMS = 0x0017 +CSIDL_COMMON_STARTUP = 0x0018 +CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019 +CSIDL_APPDATA = 0x001A +CSIDL_PRINTHOOD = 0x001B +CSIDL_LOCAL_APPDATA = 0x001C +CSIDL_ALTSTARTUP = 0x001D +CSIDL_COMMON_ALTSTARTUP = 0x001E +CSIDL_COMMON_FAVORITES = 0x001F +CSIDL_INTERNET_CACHE = 0x0020 +CSIDL_COOKIES = 0x0021 +CSIDL_HISTORY = 0x0022 +CSIDL_COMMON_APPDATA = 0x0023 +CSIDL_WINDOWS = 0x0024 +CSIDL_SYSTEM = 0x0025 +CSIDL_PROGRAM_FILES = 0x0026 +CSIDL_MYPICTURES = 0x0027 +CSIDL_PROFILE = 0x0028 +CSIDL_SYSTEMX86 = 0x0029 +CSIDL_PROGRAM_FILESX86 = 0x002A +CSIDL_PROGRAM_FILES_COMMON = 0x002B +CSIDL_PROGRAM_FILES_COMMONX86 = 0x002C +CSIDL_COMMON_TEMPLATES = 0x002D +CSIDL_COMMON_DOCUMENTS = 0x002E +CSIDL_COMMON_ADMINTOOLS = 0x002F +CSIDL_ADMINTOOLS = 0x0030 +CSIDL_CONNECTIONS = 0x0031 +CSIDL_COMMON_MUSIC = 0x0035 +CSIDL_COMMON_PICTURES = 0x0036 +CSIDL_COMMON_VIDEO = 0x0037 +CSIDL_RESOURCES = 0x0038 +CSIDL_RESOURCES_LOCALIZED = 0x0039 +CSIDL_COMMON_OEM_LINKS = 0x003A +CSIDL_CDBURN_AREA = 0x003B +CSIDL_COMPUTERSNEARME = 0x003D +CSIDL_PROFILES = 0x003E +CSIDL_FOLDER_MASK = 0x00FF +CSIDL_FLAG_PER_USER_INIT = 0x0800 +CSIDL_FLAG_NO_ALIAS = 0x1000 +CSIDL_FLAG_DONT_VERIFY = 0x4000 +CSIDL_FLAG_CREATE = 0x8000 +CSIDL_FLAG_MASK = 0xFF00 + \ No newline at end of file diff --git a/toolchain/fasmw17332/INCLUDE/EQUATES/SHELL64.INC b/toolchain/fasmw17332/INCLUDE/EQUATES/SHELL64.INC new file mode 100644 index 0000000..79d47fb --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/EQUATES/SHELL64.INC @@ -0,0 +1,127 @@ + +; SHELL32.DLL structures and constants + +struct NOTIFYICONDATA + cbSize dd ?,? + hWnd dq ? + uID dd ? + uFlags dd ? + uCallbackMessage dd ?,? + hIcon dq ? + szTip TCHAR 64 dup (?) +ends + +struct NOTIFYICONDATAA + cbSize dd ?,? + hWnd dq ? + uID dd ? + uFlags dd ? + uCallbackMessage dd ?,? + hIcon dq ? + szTip db 64 dup (?) +ends + +struct NOTIFYICONDATAW + cbSize dd ?,? + hWnd dq ? + uID dd ? + uFlags dd ? + uCallbackMessage dd ?,? + hIcon dq ? + szTip du 64 dup (?) +ends + +struct BROWSEINFO + hwndOwner dq ? + pidlRoot dq ? + pszDisplayName dq ? + lpszTitle dq ? + ulFlags dd ?,? + lpfn dq ? + lParam dq ? + iImage dq ? +ends + +; Taskbar icon messages + +NIM_ADD = 0 +NIM_MODIFY = 1 +NIM_DELETE = 2 +NIM_SETFOCUS = 3 +NIM_SETVERSION = 4 + +; Taskbar icon flags + +NIF_MESSAGE = 01h +NIF_ICON = 02h +NIF_TIP = 04h +NIF_STATE = 08h +NIF_INFO = 10h +NIF_GUID = 20h + +; Constant Special Item ID List + +CSIDL_DESKTOP = 0x0000 +CSIDL_INTERNET = 0x0001 +CSIDL_PROGRAMS = 0x0002 +CSIDL_CONTROLS = 0x0003 +CSIDL_PRINTERS = 0x0004 +CSIDL_PERSONAL = 0x0005 +CSIDL_FAVORITES = 0x0006 +CSIDL_STARTUP = 0x0007 +CSIDL_RECENT = 0x0008 +CSIDL_SENDTO = 0x0009 +CSIDL_BITBUCKET = 0x000A +CSIDL_STARTMENU = 0x000B +CSIDL_MYDOCUMENTS = 0x000C +CSIDL_MYMUSIC = 0x000D +CSIDL_MYVIDEO = 0x000E +CSIDL_DESKTOPDIRECTORY = 0x0010 +CSIDL_DRIVES = 0x0011 +CSIDL_NETWORK = 0x0012 +CSIDL_NETHOOD = 0x0013 +CSIDL_FONTS = 0x0014 +CSIDL_TEMPLATES = 0x0015 +CSIDL_COMMON_STARTMENU = 0x0016 +CSIDL_COMMON_PROGRAMS = 0x0017 +CSIDL_COMMON_STARTUP = 0x0018 +CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019 +CSIDL_APPDATA = 0x001A +CSIDL_PRINTHOOD = 0x001B +CSIDL_LOCAL_APPDATA = 0x001C +CSIDL_ALTSTARTUP = 0x001D +CSIDL_COMMON_ALTSTARTUP = 0x001E +CSIDL_COMMON_FAVORITES = 0x001F +CSIDL_INTERNET_CACHE = 0x0020 +CSIDL_COOKIES = 0x0021 +CSIDL_HISTORY = 0x0022 +CSIDL_COMMON_APPDATA = 0x0023 +CSIDL_WINDOWS = 0x0024 +CSIDL_SYSTEM = 0x0025 +CSIDL_PROGRAM_FILES = 0x0026 +CSIDL_MYPICTURES = 0x0027 +CSIDL_PROFILE = 0x0028 +CSIDL_SYSTEMX86 = 0x0029 +CSIDL_PROGRAM_FILESX86 = 0x002A +CSIDL_PROGRAM_FILES_COMMON = 0x002B +CSIDL_PROGRAM_FILES_COMMONX86 = 0x002C +CSIDL_COMMON_TEMPLATES = 0x002D +CSIDL_COMMON_DOCUMENTS = 0x002E +CSIDL_COMMON_ADMINTOOLS = 0x002F +CSIDL_ADMINTOOLS = 0x0030 +CSIDL_CONNECTIONS = 0x0031 +CSIDL_COMMON_MUSIC = 0x0035 +CSIDL_COMMON_PICTURES = 0x0036 +CSIDL_COMMON_VIDEO = 0x0037 +CSIDL_RESOURCES = 0x0038 +CSIDL_RESOURCES_LOCALIZED = 0x0039 +CSIDL_COMMON_OEM_LINKS = 0x003A +CSIDL_CDBURN_AREA = 0x003B +CSIDL_COMPUTERSNEARME = 0x003D +CSIDL_PROFILES = 0x003E +CSIDL_FOLDER_MASK = 0x00FF +CSIDL_FLAG_PER_USER_INIT = 0x0800 +CSIDL_FLAG_NO_ALIAS = 0x1000 +CSIDL_FLAG_DONT_VERIFY = 0x4000 +CSIDL_FLAG_CREATE = 0x8000 +CSIDL_FLAG_MASK = 0xFF00 diff --git a/toolchain/fasmw17332/INCLUDE/EQUATES/USER32.INC b/toolchain/fasmw17332/INCLUDE/EQUATES/USER32.INC new file mode 100644 index 0000000..512c6d4 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/EQUATES/USER32.INC @@ -0,0 +1,1934 @@ + +; USER32.DLL structures and constants + +struct POINT + x dd ? + y dd ? +ends + +struct POINTS + x dw ? + y dw ? +ends + +struct RECT + left dd ? + top dd ? + right dd ? + bottom dd ? +ends + +struct WNDCLASS + style dd ? + lpfnWndProc dd ? + cbClsExtra dd ? + cbWndExtra dd ? + hInstance dd ? + hIcon dd ? + hCursor dd ? + hbrBackground dd ? + lpszMenuName dd ? + lpszClassName dd ? +ends + +struct WNDCLASSEX + cbSize dd ? + style dd ? + lpfnWndProc dd ? + cbClsExtra dd ? + cbWndExtra dd ? + hInstance dd ? + hIcon dd ? + hCursor dd ? + hbrBackground dd ? + lpszMenuName dd ? + lpszClassName dd ? + hIconSm dd ? +ends + +struct CREATESTRUCT + lpCreateParams dd ? + hInstance dd ? + hMenu dd ? + hwndParent dd ? + cy dd ? + cx dd ? + y dd ? + x dd ? + style dd ? + lpszName dd ? + lpszClass dd ? + dwExStyle dd ? +ends + +struct CLIENTCREATESTRUCT + hWindowMenu dd ? + idFirstChild dd ? +ends + +struct MDICREATESTRUCT + szClass dd ? + szTitle dd ? + hOwner dd ? + x dd ? + y dd ? + cx dd ? + cy dd ? + style dd ? + lParam dd ? +ends + +struct SCROLLINFO + cbSize dd ? + fMask dd ? + nMin dd ? + nMax dd ? + nPage dd ? + nPos dd ? + nTrackPos dd ? +ends + +struct MSG + hwnd dd ? + message dd ? + wParam dd ? + lParam dd ? + time dd ? + pt POINT +ends + +struct MINMAXINFO + ptReserved POINT + ptMaxSize POINT + ptMaxPosition POINT + ptMinTrackSize POINT + ptMaxTrackSize POINT +ends + +struct WINDOWPLACEMENT + length dd ? + flags dd ? + showCmd dd ? + ptMinPosition POINT + ptMaxPosition POINT + rcNormalPosition RECT +ends + +struct WINDOWPOS + hwnd dd ? + hwndInsertAfter dd ? + x dd ? + y dd ? + cx dd ? + cy dd ? + flags dd ? +ends + +struct NMHDR + hwndFrom dd ? + idFrom dd ? + code dd ? +ends + +struct COPYDATASTRUCT + dwData dd ? + cbData dd ? + lpData dd ? +ends + +struct ACCEL + fVirt dw ? + key dw ? + cmd dw ? +ends + +struct PAINTSTRUCT + hdc dd ? + fErase dd ? + rcPaint RECT + fRestore dd ? + fIncUpdate dd ? + rgbReserved db 32 dup (?) +ends + +struct DRAWTEXTPARAMS + cbSize dd ? + iTabLength dd ? + iLeftMargin dd ? + iRightMargin dd ? + uiLengthDrawn dd ? +ends + +struct DRAWITEMSTRUCT + CtlType dd ? + CtlID dd ? + itemID dd ? + itemAction dd ? + itemState dd ? + hwndItem dd ? + hDC dd ? + rcItem RECT + itemData dd ? +ends + +struct MENUITEMINFO + cbSize dd ? + fMask dd ? + fType dd ? + fState dd ? + wID dd ? + hSubMenu dd ? + hbmpChecked dd ? + hbmpUnchecked dd ? + dwItemData dd ? + dwTypeData dd ? + cch dd ? + hbmpItem dd ? +ends + +struct MEASUREITEMSTRUCT + CtlType dd ? + CtlID dd ? + itemID dd ? + itemWidth dd ? + itemHeight dd ? + itemData dd ? +ends + +struct MSGBOXPARAMS + cbSize dd ? + hwndOwner dd ? + hInstance dd ? + lpszText dd ? + lpszCaption dd ? + dwStyle dd ? + lpszIcon dd ? + dwContextHelpId dd ? + lpfnMsgBoxCallback dd ? + dwLanguageId dd ? +ends + +struct GESTURECONFIG + dwID dd ? + dwWant dd ? + dwBlock dd ? +ends + +struct GESTUREINFO + cbSize dd ? + dwFlags dd ? + dwID dd ? + hwndTarget dd ? + ptsLocation POINTS + dwInstanceID dd ? + dwSequenceID dd ?,? + ullArguments dq ? + cbExtraArgs dd ?,? +ends + +; MessageBox type flags + +MB_OK = 000000h +MB_OKCANCEL = 000001h +MB_ABORTRETRYIGNORE = 000002h +MB_YESNOCANCEL = 000003h +MB_YESNO = 000004h +MB_RETRYCANCEL = 000005h +MB_ICONHAND = 000010h +MB_ICONQUESTION = 000020h +MB_ICONEXCLAMATION = 000030h +MB_ICONASTERISK = 000040h +MB_USERICON = 000080h +MB_ICONWARNING = MB_ICONEXCLAMATION +MB_ICONERROR = MB_ICONHAND +MB_ICONINFORMATION = MB_ICONASTERISK +MB_ICONSTOP = MB_ICONHAND +MB_DEFBUTTON1 = 000000h +MB_DEFBUTTON2 = 000100h +MB_DEFBUTTON3 = 000200h +MB_DEFBUTTON4 = 000300h +MB_APPLMODAL = 000000h +MB_SYSTEMMODAL = 001000h +MB_TASKMODAL = 002000h +MB_HELP = 004000h +MB_NOFOCUS = 008000h +MB_SETFOREGROUND = 010000h +MB_DEFAULT_DESKTOP_ONLY = 020000h +MB_TOPMOST = 040000h +MB_RIGHT = 080000h +MB_RTLREADING = 100000h +MB_SERVICE_NOTIFICATION = 200000h + +; Conventional dialog box and message box command IDs + +IDOK = 1 +IDCANCEL = 2 +IDABORT = 3 +IDRETRY = 4 +IDIGNORE = 5 +IDYES = 6 +IDNO = 7 +IDCLOSE = 8 +IDHELP = 9 + +; Class styles + +CS_VREDRAW = 00001h +CS_HREDRAW = 00002h +CS_KEYCVTWINDOW = 00004h +CS_DBLCLKS = 00008h +CS_OWNDC = 00020h +CS_CLASSDC = 00040h +CS_PARENTDC = 00080h +CS_NOKEYCVT = 00100h +CS_SAVEBITS = 00800h +CS_NOCLOSE = 00200h +CS_BYTEALIGNCLIENT = 01000h +CS_BYTEALIGNWINDOW = 02000h +CS_PUBLICCLASS = 04000h +CS_GLOBALCLASS = CS_PUBLICCLASS +CS_IME = 10000h + +; Windows styles + +WS_OVERLAPPED = 000000000h +WS_ICONICPOPUP = 0C0000000h +WS_POPUP = 080000000h +WS_CHILD = 040000000h +WS_MINIMIZE = 020000000h +WS_VISIBLE = 010000000h +WS_DISABLED = 008000000h +WS_CLIPSIBLINGS = 004000000h +WS_CLIPCHILDREN = 002000000h +WS_MAXIMIZE = 001000000h +WS_CAPTION = 000C00000h +WS_BORDER = 000800000h +WS_DLGFRAME = 000400000h +WS_VSCROLL = 000200000h +WS_HSCROLL = 000100000h +WS_SYSMENU = 000080000h +WS_THICKFRAME = 000040000h +WS_HREDRAW = 000020000h +WS_VREDRAW = 000010000h +WS_GROUP = 000020000h +WS_TABSTOP = 000010000h +WS_MINIMIZEBOX = 000020000h +WS_MAXIMIZEBOX = 000010000h + +; Common Window Styles + +WS_OVERLAPPEDWINDOW = WS_OVERLAPPED or WS_CAPTION or WS_SYSMENU or WS_THICKFRAME or WS_MINIMIZEBOX or WS_MAXIMIZEBOX +WS_POPUPWINDOW = WS_POPUP or WS_BORDER or WS_SYSMENU +WS_CHILDWINDOW = WS_CHILD +WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW +WS_TILED = WS_OVERLAPPED +WS_ICONIC = WS_MINIMIZE +WS_SIZEBOX = WS_THICKFRAME + +; Extended Window Styles + +WS_EX_DLGMODALFRAME = 00001h +WS_EX_DRAGOBJECT = 00002h +WS_EX_NOPARENTNOTIFY = 00004h +WS_EX_TOPMOST = 00008h +WS_EX_ACCEPTFILES = 00010h +WS_EX_TRANSPARENT = 00020h +WS_EX_MDICHILD = 00040h +WS_EX_TOOLWINDOW = 00080h +WS_EX_WINDOWEDGE = 00100h +WS_EX_CLIENTEDGE = 00200h +WS_EX_CONTEXTHELP = 00400h +WS_EX_RIGHT = 01000h +WS_EX_LEFT = 00000h +WS_EX_RTLREADING = 02000h +WS_EX_LTRREADING = 00000h +WS_EX_LEFTSCROLLBAR = 04000h +WS_EX_RIGHTSCROLLBAR = 00000h +WS_EX_CONTROLPARENT = 10000h +WS_EX_STATICEDGE = 20000h +WS_EX_APPWINDOW = 40000h +WS_EX_LAYERED = 80000h +WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE or WS_EX_CLIENTEDGE +WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE or WS_EX_TOOLWINDOW or WS_EX_TOPMOST + +; MDI client style bits + +MDIS_ALLCHILDSTYLES = 1 + +; Special CreateWindow position value + +CW_USEDEFAULT = 80000000h + +; Predefined window handle + +HWND_DESKTOP = 0 + +; ShowWindow commands + +SW_HIDE = 0 +SW_SHOWNORMAL = 1 +SW_NORMAL = 1 +SW_SHOWMINIMIZED = 2 +SW_SHOWMAXIMIZED = 3 +SW_MAXIMIZE = 3 +SW_SHOWNOACTIVATE = 4 +SW_SHOW = 5 +SW_MINIMIZE = 6 +SW_SHOWMINNOACTIVE = 7 +SW_SHOWNA = 8 +SW_RESTORE = 9 +SW_SHOWDEFAULT = 10 + +; SetWindowPos flags + +SWP_NOSIZE = 0001h +SWP_NOMOVE = 0002h +SWP_NOZORDER = 0004h +SWP_NOREDRAW = 0008h +SWP_NOACTIVATE = 0010h +SWP_DRAWFRAME = 0020h +SWP_SHOWWINDOW = 0040h +SWP_HIDEWINDOW = 0080h +SWP_NOCOPYBITS = 0100h +SWP_NOREPOSITION = 0200h +SWP_DEFERERASE = 2000h +SWP_ASYNCWINDOWPOS = 4000h + +; SetWindowPos special handle values + +HWND_TOP = 0 +HWND_BOTTOM = 1 +HWND_TOPMOST = -1 +HWND_NOTOPMOST = -2 + +; GetWindow flags + +GW_HWNDFIRST = 0 +GW_HWNDLAST = 1 +GW_HWNDNEXT = 2 +GW_HWNDPREV = 3 +GW_OWNER = 4 +GW_CHILD = 5 + +; RedrawWindow flags + +RDW_INVALIDATE = 0001h +RDW_INTERNALPAINT = 0002h +RDW_ERASE = 0004h +RDW_VALIDATE = 0008h +RDW_NOINTERNALPAINT = 0010h +RDW_NOERASE = 0020h +RDW_NOCHILDREN = 0040h +RDW_ALLCHILDREN = 0080h +RDW_UPDATENOW = 0100h +RDW_ERASENOW = 0200h +RDW_FRAME = 0400h +RDW_NOFRAME = 0800h + +; PeekMessage Options + +PM_NOREMOVE = 0000h +PM_REMOVE = 0001h +PM_NOYIELD = 0002h + +; Window state messages + +WM_STATE = 0000h +WM_NULL = 0000h +WM_CREATE = 0001h +WM_DESTROY = 0002h +WM_MOVE = 0003h +WM_SIZE = 0005h +WM_ACTIVATE = 0006h +WM_SETFOCUS = 0007h +WM_KILLFOCUS = 0008h +WM_ENABLE = 000Ah +WM_SETREDRAW = 000Bh +WM_SETTEXT = 000Ch +WM_GETTEXT = 000Dh +WM_GETTEXTLENGTH = 000Eh +WM_PAINT = 000Fh +WM_CLOSE = 0010h +WM_QUERYENDSESSION = 0011h +WM_QUIT = 0012h +WM_QUERYOPEN = 0013h +WM_ERASEBKGND = 0014h +WM_SYSCOLORCHANGE = 0015h +WM_ENDSESSION = 0016h +WM_SYSTEMERROR = 0017h +WM_SHOWWINDOW = 0018h +WM_CTLCOLOR = 0019h +WM_WININICHANGE = 001Ah +WM_DEVMODECHANGE = 001Bh +WM_ACTIVATEAPP = 001Ch +WM_FONTCHANGE = 001Dh +WM_TIMECHANGE = 001Eh +WM_CANCELMODE = 001Fh +WM_SETCURSOR = 0020h +WM_MOUSEACTIVATE = 0021h +WM_CHILDACTIVATE = 0022h +WM_QUEUESYNC = 0023h +WM_GETMINMAXINFO = 0024h +WM_PAINTICON = 0026h +WM_ICONERASEBKGND = 0027h +WM_NEXTDLGCTL = 0028h +WM_SPOOLERSTATUS = 002Ah +WM_DRAWITEM = 002Bh +WM_MEASUREITEM = 002Ch +WM_DELETEITEM = 002Dh +WM_VKEYTOITEM = 002Eh +WM_CHARTOITEM = 002Fh +WM_SETFONT = 0030h +WM_GETFONT = 0031h +WM_SETHOTKEY = 0032h +WM_QUERYDRAGICON = 0037h +WM_COMPAREITEM = 0039h +WM_COMPACTING = 0041h +WM_COMMNOTIFY = 0044h +WM_WINDOWPOSCHANGING = 0046h +WM_WINDOWPOSCHANGED = 0047h +WM_POWER = 0048h +WM_COPYDATA = 004Ah +WM_CANCELJOURNAL = 004Bh +WM_NOTIFY = 004Eh +WM_INPUTLANGCHANGEREQUEST = 0050h +WM_INPUTLANGCHANGE = 0051h +WM_TCARD = 0052h +WM_HELP = 0053h +WM_USERCHANGED = 0054h +WM_NOTIFYFORMAT = 0055h +WM_CONTEXTMENU = 007Bh +WM_STYLECHANGING = 007Ch +WM_STYLECHANGED = 007Dh +WM_DISPLAYCHANGE = 007Eh +WM_GETICON = 007Fh +WM_SETICON = 0080h +WM_NCCREATE = 0081h +WM_NCDESTROY = 0082h +WM_NCCALCSIZE = 0083h +WM_NCHITTEST = 0084h +WM_NCPAINT = 0085h +WM_NCACTIVATE = 0086h +WM_GETDLGCODE = 0087h +WM_NCMOUSEMOVE = 00A0h +WM_NCLBUTTONDOWN = 00A1h +WM_NCLBUTTONUP = 00A2h +WM_NCLBUTTONDBLCLK = 00A3h +WM_NCRBUTTONDOWN = 00A4h +WM_NCRBUTTONUP = 00A5h +WM_NCRBUTTONDBLCLK = 00A6h +WM_NCMBUTTONDOWN = 00A7h +WM_NCMBUTTONUP = 00A8h +WM_NCMBUTTONDBLCLK = 00A9h +WM_KEYFIRST = 0100h +WM_KEYDOWN = 0100h +WM_KEYUP = 0101h +WM_CHAR = 0102h +WM_DEADCHAR = 0103h +WM_SYSKEYDOWN = 0104h +WM_SYSKEYUP = 0105h +WM_SYSCHAR = 0106h +WM_SYSDEADCHAR = 0107h +WM_KEYLAST = 0108h +WM_INITDIALOG = 0110h +WM_COMMAND = 0111h +WM_SYSCOMMAND = 0112h +WM_TIMER = 0113h +WM_HSCROLL = 0114h +WM_VSCROLL = 0115h +WM_INITMENU = 0116h +WM_INITMENUPOPUP = 0117h +WM_GESTURE = 0119h +WM_GESTURENOTIFY = 011Ah +WM_MENUSELECT = 011Fh +WM_MENUCHAR = 0120h +WM_ENTERIDLE = 0121h +WM_MENURBUTTONUP = 0122h +WM_MENUDRAG = 0123h +WM_MENUGETOBJECT = 0124h +WM_UNINITMENUPOPUP = 0125h +WM_MENUCOMMAND = 0126h +WM_CTLCOLORMSGBOX = 0132h +WM_CTLCOLOREDIT = 0133h +WM_CTLCOLORLISTBOX = 0134h +WM_CTLCOLORBTN = 0135h +WM_CTLCOLORDLG = 0136h +WM_CTLCOLORSCROLLBAR = 0137h +WM_CTLCOLORSTATIC = 0138h +WM_MOUSEFIRST = 0200h +WM_MOUSEMOVE = 0200h +WM_LBUTTONDOWN = 0201h +WM_LBUTTONUP = 0202h +WM_LBUTTONDBLCLK = 0203h +WM_RBUTTONDOWN = 0204h +WM_RBUTTONUP = 0205h +WM_RBUTTONDBLCLK = 0206h +WM_MBUTTONDOWN = 0207h +WM_MBUTTONUP = 0208h +WM_MBUTTONDBLCLK = 0209h +WM_MOUSEWHEEL = 020Ah +WM_MOUSELAST = 020Ah +WM_PARENTNOTIFY = 0210h +WM_ENTERMENULOOP = 0211h +WM_EXITMENULOOP = 0212h +WM_NEXTMENU = 0213h +WM_SIZING = 0214h +WM_CAPTURECHANGED = 0215h +WM_MOVING = 0216h +WM_POWERBROADCAST = 0218h +WM_DEVICECHANGE = 0219h +WM_MDICREATE = 0220h +WM_MDIDESTROY = 0221h +WM_MDIACTIVATE = 0222h +WM_MDIRESTORE = 0223h +WM_MDINEXT = 0224h +WM_MDIMAXIMIZE = 0225h +WM_MDITILE = 0226h +WM_MDICASCADE = 0227h +WM_MDIICONARRANGE = 0228h +WM_MDIGETACTIVE = 0229h +WM_MDISETMENU = 0230h +WM_ENTERSIZEMOVE = 0231h +WM_EXITSIZEMOVE = 0232h +WM_DROPFILES = 0233h +WM_MDIREFRESHMENU = 0234h +WM_IME_SETCONTEXT = 0281h +WM_IME_NOTIFY = 0282h +WM_IME_CONTROL = 0283h +WM_IME_COMPOSITIONFULL = 0284h +WM_IME_SELECT = 0285h +WM_IME_CHAR = 0286h +WM_IME_KEYDOWN = 0290h +WM_IME_KEYUP = 0291h +WM_MOUSEHOVER = 02A1h +WM_MOUSELEAVE = 02A3h +WM_CUT = 0300h +WM_COPY = 0301h +WM_PASTE = 0302h +WM_CLEAR = 0303h +WM_UNDO = 0304h +WM_RENDERFORMAT = 0305h +WM_RENDERALLFORMATS = 0306h +WM_DESTROYCLIPBOARD = 0307h +WM_DRAWCLIPBOARD = 0308h +WM_PAINTCLIPBOARD = 0309h +WM_VSCROLLCLIPBOARD = 030Ah +WM_SIZECLIPBOARD = 030Bh +WM_ASKCBFORMATNAME = 030Ch +WM_CHANGECBCHAIN = 030Dh +WM_HSCROLLCLIPBOARD = 030Eh +WM_QUERYNEWPALETTE = 030Fh +WM_PALETTEISCHANGING = 0310h +WM_PALETTECHANGED = 0311h +WM_HOTKEY = 0312h +WM_PRINT = 0317h +WM_PRINTCLIENT = 0318h +WM_HANDHELDFIRST = 0358h +WM_HANDHELDLAST = 035Fh +WM_AFXFIRST = 0360h +WM_AFXLAST = 037Fh +WM_PENWINFIRST = 0380h +WM_PENWINLAST = 038Fh +WM_COALESCE_FIRST = 0390h +WM_COALESCE_LAST = 039Fh +WM_USER = 0400h + +; WM_SIZE commands + +SIZE_RESTORED = 0 +SIZE_MINIMIZED = 1 +SIZE_MAXIMIZED = 2 +SIZE_MAXSHOW = 3 +SIZE_MAXHIDE = 4 + +; WM_ACTIVATE states + +WA_INACTIVE = 0 +WA_ACTIVE = 1 +WA_CLICKACTIVE = 2 + +; WM_SHOWWINDOW identifiers + +SW_PARENTCLOSING = 1 +SW_OTHERZOOM = 2 +SW_PARENTOPENING = 3 +SW_OTHERUNZOOM = 4 + +; WM_MOUSEACTIVATE return codes + +MA_ACTIVATE = 1 +MA_ACTIVATEANDEAT = 2 +MA_NOACTIVATE = 3 +MA_NOACTIVATEANDEAT = 4 + +; WM_MDITILE flags + +MDITILE_VERTICAL = 0 +MDITILE_HORIZONTAL = 1 +MDITILE_SKIPDISABLED = 2 + +; WM_NOTIFY codes + +NM_OUTOFMEMORY = -1 +NM_CLICK = -2 +NM_DBLCLICK = -3 +NM_RETURN = -4 +NM_RCLICK = -5 +NM_RDBLCLK = -6 +NM_SETFOCUS = -7 +NM_KILLFOCUS = -8 + +; WM_SETICON types + +ICON_SMALL = 0 +ICON_BIG = 1 + +; WM_HOTKEY commands + +HOTKEYF_SHIFT = 01h +HOTKEYF_CONTROL = 02h +HOTKEYF_ALT = 04h +HOTKEYF_EXT = 08h + +; Keystroke flags + +KF_EXTENDED = 0100h +KF_DLGMODE = 0800h +KF_MENUMODE = 1000h +KF_ALTDOWN = 2000h +KF_REPEAT = 4000h +KF_UP = 8000h + +; Key state masks for mouse messages + +MK_LBUTTON = 01h +MK_RBUTTON = 02h +MK_SHIFT = 04h +MK_CONTROL = 08h +MK_MBUTTON = 10h + +; WM_SIZING codes + +WMSZ_LEFT = 1 +WMSZ_RIGHT = 2 +WMSZ_TOP = 3 +WMSZ_TOPLEFT = 4 +WMSZ_TOPRIGHT = 5 +WMSZ_BOTTOM = 6 +WMSZ_BOTTOMLEFT = 7 +WMSZ_BOTTOMRIGHT = 8 + +; WM_HOTKEY modifiers + +MOD_ALT = 1 +MOD_CONTROL = 2 +MOD_SHIFT = 4 +MOD_WIN = 8 + +; WM_PRINT flags + +PRF_CHECKVISIBLE = 01h +PRF_NONCLIENT = 02h +PRF_CLIENT = 04h +PRF_ERASEBKGND = 08h +PRF_CHILDREN = 10h +PRF_OWNED = 20h + +; Virtual key codes + +VK_LBUTTON = 001h +VK_CANCEL = 003h +VK_RBUTTON = 002h +VK_MBUTTON = 004h +VK_BACK = 008h +VK_TAB = 009h +VK_CLEAR = 00Ch +VK_RETURN = 00Dh +VK_SHIFT = 010h +VK_CONTROL = 011h +VK_MENU = 012h +VK_PAUSE = 013h +VK_CAPITAL = 014h +VK_ESCAPE = 01Bh +VK_SPACE = 020h +VK_PRIOR = 021h +VK_PGUP = 021h +VK_PGDN = 022h +VK_NEXT = 022h +VK_END = 023h +VK_HOME = 024h +VK_LEFT = 025h +VK_UP = 026h +VK_RIGHT = 027h +VK_DOWN = 028h +VK_SELECT = 029h +VK_PRINT = 02Ah +VK_EXECUTE = 02Bh +VK_SNAPSHOT = 02Ch +VK_INSERT = 02Dh +VK_DELETE = 02Eh +VK_HELP = 02Fh +VK_LWIN = 05Bh +VK_RWIN = 05Ch +VK_APPS = 05Dh +VK_NUMPAD0 = 060h +VK_NUMPAD1 = 061h +VK_NUMPAD2 = 062h +VK_NUMPAD3 = 063h +VK_NUMPAD4 = 064h +VK_NUMPAD5 = 065h +VK_NUMPAD6 = 066h +VK_NUMPAD7 = 067h +VK_NUMPAD8 = 068h +VK_NUMPAD9 = 069h +VK_MULTIPLY = 06Ah +VK_ADD = 06Bh +VK_SEPARATOR = 06Ch +VK_SUBTRACT = 06Dh +VK_DECIMAL = 06Eh +VK_DIVIDE = 06Fh +VK_F1 = 070h +VK_F2 = 071h +VK_F3 = 072h +VK_F4 = 073h +VK_F5 = 074h +VK_F6 = 075h +VK_F7 = 076h +VK_F8 = 077h +VK_F9 = 078h +VK_F10 = 079h +VK_F11 = 07Ah +VK_F12 = 07Bh +VK_F13 = 07Ch +VK_F14 = 07Dh +VK_F15 = 07Eh +VK_F16 = 07Fh +VK_F17 = 080h +VK_F18 = 081h +VK_F19 = 082h +VK_F20 = 083h +VK_F21 = 084h +VK_F22 = 085h +VK_F23 = 086h +VK_F24 = 087h +VK_NUMLOCK = 090h +VK_SCROLL = 091h +VK_LSHIFT = 0A0h +VK_RSHIFT = 0A1h +VK_LCONTROL = 0A2h +VK_RCONTROL = 0A3h +VK_LMENU = 0A4h +VK_RMENU = 0A5h +VK_ATTN = 0F6h +VK_CRSEL = 0F7h +VK_EXSEL = 0F8h +VK_EREOF = 0F9h +VK_PLAY = 0FAh +VK_ZOOM = 0FBh +VK_NONAME = 0FCh +VK_PA1 = 0FDh +VK_OEM_CLEAR = 0FEh + +; Accelerator flags + +FVIRTKEY = 01h +FNOINVERT = 02h +FSHIFT = 04h +FCONTROL = 08h +FALT = 10h + +; GetClassLong offsets + +GCL_MENUNAME = -8 +GCL_HBRBACKGROUND = -10 +GCL_HCURSOR = -12 +GCL_HICON = -14 +GCL_HMODULE = -16 +GCL_CBWNDEXTRA = -18 +GCL_CBCLSEXTRA = -20 +GCL_WNDPROC = -24 +GCL_STYLE = -26 +GCW_ATOM = -32 +GCL_HICONSM = -34 + +; WNDCLASS parameters + +DLGWINDOWEXTRA = 30 + +; GetWindowLong offsets + +GWL_WNDPROC = -4 +GWL_HINSTANCE = -6 +GWL_HWNDPARENT = -8 +GWL_STYLE = -16 +GWL_EXSTYLE = -20 +GWL_USERDATA = -21 +GWL_ID = -12 +DWL_MSGRESULT = 0 +DWL_DLGPROC = 4 +DWL_USER = 8 + +; GetSystemMetrics codes + +SM_CXSCREEN = 0 +SM_CYSCREEN = 1 +SM_CXVSCROLL = 2 +SM_CYHSCROLL = 3 +SM_CYCAPTION = 4 +SM_CXBORDER = 5 +SM_CYBORDER = 6 +SM_CXDLGFRAME = 7 +SM_CYDLGFRAME = 8 +SM_CYVTHUMB = 9 +SM_CXHTHUMB = 10 +SM_CXICON = 11 +SM_CYICON = 12 +SM_CXCURSOR = 13 +SM_CYCURSOR = 14 +SM_CYMENU = 15 +SM_CXFULLSCREEN = 16 +SM_CYFULLSCREEN = 17 +SM_CYKANJIWINDOW = 18 +SM_MOUSEPRESENT = 19 +SM_CYVSCROLL = 20 +SM_CXHSCROLL = 21 +SM_DEBUG = 22 +SM_SWAPBUTTON = 23 +SM_RESERVED1 = 24 +SM_RESERVED2 = 25 +SM_RESERVED3 = 26 +SM_RESERVED4 = 27 +SM_CXMIN = 28 +SM_CYMIN = 29 +SM_CXSIZE = 30 +SM_CYSIZE = 31 +SM_CXFRAME = 32 +SM_CYFRAME = 33 +SM_CXMINTRACK = 34 +SM_CYMINTRACK = 35 +SM_CXDOUBLECLK = 36 +SM_CYDOUBLECLK = 37 +SM_CXICONSPACING = 38 +SM_CYICONSPACING = 39 +SM_MENUDROPALIGNMENT = 40 +SM_PENWINDOWS = 41 +SM_DBCSENABLED = 42 +SM_CMOUSEBUTTONS = 43 +SM_CXFIXEDFRAME = SM_CXDLGFRAME +SM_CYFIXEDFRAME = SM_CYDLGFRAME +SM_CXSIZEFRAME = SM_CXFRAME +SM_CYSIZEFRAME = SM_CYFRAME +SM_SECURE = 44 +SM_CXEDGE = 45 +SM_CYEDGE = 46 +SM_CXMINSPACING = 47 +SM_CYMINSPACING = 48 +SM_CXSMICON = 49 +SM_CYSMICON = 50 +SM_CYSMCAPTION = 51 +SM_CXSMSIZE = 52 +SM_CYSMSIZE = 53 +SM_CXMENUSIZE = 54 +SM_CYMENUSIZE = 55 +SM_ARRANGE = 56 +SM_CXMINIMIZED = 57 +SM_CYMINIMIZED = 58 +SM_CXMAXTRACK = 59 +SM_CYMAXTRACK = 60 +SM_CXMAXIMIZED = 61 +SM_CYMAXIMIZED = 62 +SM_NETWORK = 63 +SM_CLEANBOOT = 67 +SM_CXDRAG = 68 +SM_CYDRAG = 69 +SM_SHOWSOUNDS = 70 +SM_CXMENUCHECK = 71 +SM_CYMENUCHECK = 72 +SM_SLOWMACHINE = 73 +SM_MIDEASTENABLED = 74 +SM_MOUSEWHEELPRESENT = 75 +SM_CMETRICS = 76 + +; Predefined cursor identifiers + +IDC_ARROW = 32512 +IDC_IBEAM = 32513 +IDC_WAIT = 32514 +IDC_CROSS = 32515 +IDC_UPARROW = 32516 +IDC_SIZE = 32640 +IDC_ICON = 32641 +IDC_SIZENWSE = 32642 +IDC_SIZENESW = 32643 +IDC_SIZEWE = 32644 +IDC_SIZENS = 32645 +IDC_NO = 32648 +IDC_HAND = 32649 +IDC_APPSTARTING = 32650 +IDC_HELP = 32651 + +; Predefined icon identifiers + +IDI_APPLICATION = 32512 +IDI_HAND = 32513 +IDI_QUESTION = 32514 +IDI_EXCLAMATION = 32515 +IDI_ASTERISK = 32516 +IDI_WINLOGO = 32517 + +; System colors + +COLOR_SCROLLBAR = 0 +COLOR_BACKGROUND = 1 +COLOR_ACTIVECAPTION = 2 +COLOR_INACTIVECAPTION = 3 +COLOR_MENU = 4 +COLOR_WINDOW = 5 +COLOR_WINDOWFRAME = 6 +COLOR_MENUTEXT = 7 +COLOR_WINDOWTEXT = 8 +COLOR_CAPTIONTEXT = 9 +COLOR_ACTIVEBORDER = 10 +COLOR_INACTIVEBORDER = 11 +COLOR_APPWORKSPACE = 12 +COLOR_HIGHLIGHT = 13 +COLOR_HIGHLIGHTTEXT = 14 +COLOR_BTNFACE = 15 +COLOR_BTNSHADOW = 16 +COLOR_GRAYTEXT = 17 +COLOR_BTNTEXT = 18 +COLOR_INACTIVECAPTIONTEXT = 19 +COLOR_BTNHIGHLIGHT = 20 +COLOR_3DDKSHADOW = 21 +COLOR_3DLIGHT = 22 +COLOR_INFOTEXT = 23 +COLOR_INFOBK = 24 +COLOR_HOTLIGHT = 26 +COLOR_GRADIENTACTIVECAPTION = 27 +COLOR_GRADIENTINACTIVECAPTION = 28 + +; Button messages + +BM_GETCHECK = 00F0h +BM_SETCHECK = 00F1h +BM_GETSTATE = 00F2h +BM_SETSTATE = 00F3h +BM_SETSTYLE = 00F4h +BM_CLICK = 00F5h +BM_GETIMAGE = 00F6h +BM_SETIMAGE = 00F7h + +; Button notifications + +BN_CLICKED = 0 +BN_PAINT = 1 +BN_HILITE = 2 +BN_UNHILITE = 3 +BN_DISABLE = 4 +BN_DOUBLECLICKED = 5 +BN_SETFOCUS = 6 +BN_KILLFOCUS = 7 +BN_PUSHED = BN_HILITE +BN_UNPUSHED = BN_UNHILITE +BN_DBLCLK = BN_DOUBLECLICKED + +; Button styles + +BS_PUSHBUTTON = 0000h +BS_DEFPUSHBUTTON = 0001h +BS_CHECKBOX = 0002h +BS_AUTOCHECKBOX = 0003h +BS_RADIOBUTTON = 0004h +BS_3STATE = 0005h +BS_AUTO3STATE = 0006h +BS_GROUPBOX = 0007h +BS_USERBUTTON = 0008h +BS_AUTORADIOBUTTON = 0009h +BS_OWNERDRAW = 000Bh +BS_TEXT = 0000h +BS_LEFTTEXT = 0020h +BS_RIGHTBUTTON = BS_LEFTTEXT +BS_ICON = 0040h +BS_BITMAP = 0080h +BS_LEFT = 0100h +BS_RIGHT = 0200h +BS_CENTER = 0300h +BS_TOP = 0400h +BS_BOTTOM = 0800h +BS_VCENTER = 0C00h +BS_PUSHLIKE = 1000h +BS_MULTILINE = 2000h +BS_NOTIFY = 4000h +BS_FLAT = 8000h + +; Button states + +BST_UNCHECKED = 0 +BST_CHECKED = 1 +BST_INDETERMINATE = 2 +BST_PUSHED = 4 +BST_FOCUS = 8 + +; List box messages + +LB_ADDSTRING = 0180h +LB_INSERTSTRING = 0181h +LB_DELETESTRING = 0182h +LB_SELITEMRANGEEX = 0183h +LB_RESETCONTENT = 0184h +LB_SETSEL = 0185h +LB_SETCURSEL = 0186h +LB_GETSEL = 0187h +LB_GETCURSEL = 0188h +LB_GETTEXT = 0189h +LB_GETTEXTLEN = 018Ah +LB_GETCOUNT = 018Bh +LB_SELECTSTRING = 018Ch +LB_DIR = 018Dh +LB_GETTOPINDEX = 018Eh +LB_FINDSTRING = 018Fh +LB_GETSELCOUNT = 0190h +LB_GETSELITEMS = 0191h +LB_SETTABSTOPS = 0192h +LB_GETHORIZONTALEXTENT = 0193h +LB_SETHORIZONTALEXTENT = 0194h +LB_SETCOLUMNWIDTH = 0195h +LB_ADDFILE = 0196h +LB_SETTOPINDEX = 0197h +LB_GETITEMRECT = 0198h +LB_GETITEMDATA = 0199h +LB_SETITEMDATA = 019Ah +LB_SELITEMRANGE = 019Bh +LB_SETANCHORINDEX = 019Ch +LB_GETANCHORINDEX = 019Dh +LB_SETCARETINDEX = 019Eh +LB_GETCARETINDEX = 019Fh +LB_SETITEMHEIGHT = 01A0h +LB_GETITEMHEIGHT = 01A1h +LB_FINDSTRINGEXACT = 01A2h +LB_SETLOCALE = 01A5h +LB_GETLOCALE = 01A6h +LB_SETCOUNT = 01A7h +LB_INITSTORAGE = 01A8h +LB_ITEMFROMPOINT = 01A9h + +; List box notifications + +LBN_ERRSPACE = -2 +LBN_SELCHANGE = 1 +LBN_DBLCLK = 2 +LBN_SELCANCEL = 3 +LBN_SETFOCUS = 4 +LBN_KILLFOCUS = 5 + +; List box styles + +LBS_NOTIFY = 0001h +LBS_SORT = 0002h +LBS_NOREDRAW = 0004h +LBS_MULTIPLESEL = 0008h +LBS_OWNERDRAWFIXED = 0010h +LBS_OWNERDRAWVARIABLE = 0020h +LBS_HASSTRINGS = 0040h +LBS_USETABSTOPS = 0080h +LBS_NOINTEGRALHEIGHT = 0100h +LBS_MULTICOLUMN = 0200h +LBS_WANTKEYBOARDINPUT = 0400h +LBS_EXTENDEDSEL = 0800h +LBS_DISABLENOSCROLL = 1000h +LBS_NODATA = 2000h +LBS_NOSEL = 4000h +LBS_STANDARD = LBS_NOTIFY or LBS_SORT or WS_VSCROLL or WS_BORDER + +; List box return values + +LB_OKAY = 0 +LB_ERR = -1 +LB_ERRSPACE = -2 + +; Combo box messages + +CB_GETEDITSEL = 0140h +CB_LIMITTEXT = 0141h +CB_SETEDITSEL = 0142h +CB_ADDSTRING = 0143h +CB_DELETESTRING = 0144h +CB_DIR = 0145h +CB_GETCOUNT = 0146h +CB_GETCURSEL = 0147h +CB_GETLBTEXT = 0148h +CB_GETLBTEXTLEN = 0149h +CB_INSERTSTRING = 014Ah +CB_RESETCONTENT = 014Bh +CB_FINDSTRING = 014Ch +CB_SELECTSTRING = 014Dh +CB_SETCURSEL = 014Eh +CB_SHOWDROPDOWN = 014Fh +CB_GETITEMDATA = 0150h +CB_SETITEMDATA = 0151h +CB_GETDROPPEDCONTROLRECT = 0152h +CB_SETITEMHEIGHT = 0153h +CB_GETITEMHEIGHT = 0154h +CB_SETEXTENDEDUI = 0155h +CB_GETEXTENDEDUI = 0156h +CB_GETDROPPEDSTATE = 0157h +CB_FINDSTRINGEXACT = 0158h +CB_SETLOCALE = 0159h +CB_GETLOCALE = 015Ah +CB_GETTOPINDEX = 015Bh +CB_SETTOPINDEX = 015Ch +CB_GETHORIZONTALEXTENT = 015Dh +CB_SETHORIZONTALEXTENT = 015Eh +CB_GETDROPPEDWIDTH = 015Fh +CB_SETDROPPEDWIDTH = 0160h +CB_INITSTORAGE = 0161h + +; Combo box notifications + +CBN_ERRSPACE = -1 +CBN_SELCHANGE = 1 +CBN_DBLCLK = 2 +CBN_SETFOCUS = 3 +CBN_KILLFOCUS = 4 +CBN_EDITCHANGE = 5 +CBN_EDITUPDATE = 6 +CBN_DROPDOWN = 7 +CBN_CLOSEUP = 8 +CBN_SELENDOK = 9 +CBN_SELENDCANCEL = 10 + +; Combo box styles + +CBS_SIMPLE = 0001h +CBS_DROPDOWN = 0002h +CBS_DROPDOWNLIST = 0003h +CBS_OWNERDRAWFIXED = 0010h +CBS_OWNERDRAWVARIABLE = 0020h +CBS_AUTOHSCROLL = 0040h +CBS_OEMCONVERT = 0080h +CBS_SORT = 0100h +CBS_HASSTRINGS = 0200h +CBS_NOINTEGRALHEIGHT = 0400h +CBS_DISABLENOSCROLL = 0800h +CBS_UPPERCASE = 2000h +CBS_LOWERCASE = 4000h + +; Combo box return values + +CB_OKAY = 0 +CB_ERR = -1 +CB_ERRSPACE = -2 + +; Edit control messages + +EM_GETSEL = 00B0h +EM_SETSEL = 00B1h +EM_GETRECT = 00B2h +EM_SETRECT = 00B3h +EM_SETRECTNP = 00B4h +EM_SCROLL = 00B5h +EM_LINESCROLL = 00B6h +EM_SCROLLCARET = 00B7h +EM_GETMODIFY = 00B8h +EM_SETMODIFY = 00B9h +EM_GETLINECOUNT = 00BAh +EM_LINEINDEX = 00BBh +EM_SETHANDLE = 00BCh +EM_GETHANDLE = 00BDh +EM_GETTHUMB = 00BEh +EM_LINELENGTH = 00C1h +EM_REPLACESEL = 00C2h +EM_GETLINE = 00C4h +EM_LIMITTEXT = 00C5h +EM_CANUNDO = 00C6h +EM_UNDO = 00C7h +EM_FMTLINES = 00C8h +EM_LINEFROMCHAR = 00C9h +EM_SETTABSTOPS = 00CBh +EM_SETPASSWORDCHAR = 00CCh +EM_EMPTYUNDOBUFFER = 00CDh +EM_GETFIRSTVISIBLELINE = 00CEh +EM_SETREADONLY = 00CFh +EM_SETWORDBREAKPROC = 00D0h +EM_GETWORDBREAKPROC = 00D1h +EM_GETPASSWORDCHAR = 00D2h +EM_SETMARGINS = 00D3h +EM_GETMARGINS = 00D4h +EM_SETLIMITTEXT = EM_LIMITTEXT +EM_GETLIMITTEXT = 00D5h +EM_POSFROMCHAR = 00D6h +EM_CHARFROMPOS = 00D7h + +; Edit control EM_SETMARGIN parameters + +EC_LEFTMARGIN = 1 +EC_RIGHTMARGIN = 2 +EC_USEFONTINFO = 0FFFFh + +; Edit control notifications + +EN_SETFOCUS = 0100h +EN_KILLFOCUS = 0200h +EN_CHANGE = 0300h +EN_UPDATE = 0400h +EN_ERRSPACE = 0500h +EN_MAXTEXT = 0501h +EN_HSCROLL = 0601h +EN_VSCROLL = 0602h + +; Edit control styles + +ES_LEFT = 0000h +ES_CENTER = 0001h +ES_RIGHT = 0002h +ES_MULTILINE = 0004h +ES_UPPERCASE = 0008h +ES_LOWERCASE = 0010h +ES_PASSWORD = 0020h +ES_AUTOVSCROLL = 0040h +ES_AUTOHSCROLL = 0080h +ES_NOHIDESEL = 0100h +ES_OEMCONVERT = 0400h +ES_READONLY = 0800h +ES_WANTRETURN = 1000h +ES_NUMBER = 2000h + +; Static window messages + +STM_SETICON = 0170h +STM_GETICON = 0171h +STM_SETIMAGE = 0172h +STM_GETIMAGE = 0173h + +; Static window notifications + +STN_CLICKED = 0 +STN_DBLCLK = 1 +STN_ENABLE = 2 +STN_DISABLE = 3 + +; Static window styles + +SS_LEFT = 0000h +SS_CENTER = 0001h +SS_RIGHT = 0002h +SS_ICON = 0003h +SS_BLACKRECT = 0004h +SS_GRAYRECT = 0005h +SS_WHITERECT = 0006h +SS_BLACKFRAME = 0007h +SS_GRAYFRAME = 0008h +SS_WHITEFRAME = 0009h +SS_USERITEM = 000Ah +SS_SIMPLE = 000Bh +SS_LEFTNOWORDWRAP = 000Ch +SS_BITMAP = 000Eh +SS_OWNERDRAW = 000Dh +SS_ENHMETAFILE = 000Fh +SS_ETCHEDHORZ = 0010h +SS_ETCHEDVERT = 0011h +SS_ETCHEDFRAME = 0012h +SS_TYPEMASK = 001Fh +SS_NOPREFIX = 0080h +SS_NOTIFY = 0100h +SS_CENTERIMAGE = 0200h +SS_RIGHTJUST = 0400h +SS_REALSIZEIMAGE = 0800h +SS_SUNKEN = 1000h + +; Scroll bar constants + +SB_HORZ = 0 +SB_VERT = 1 +SB_CTL = 2 +SB_BOTH = 3 + +; Scroll bar messages + +SBM_SETPOS = 00E0h +SBM_GETPOS = 00E1h +SBM_SETRANGE = 00E2h +SBM_SETRANGEREDRAW = 00E6h +SBM_GETRANGE = 00E3h +SBM_ENABLE_ARROWS = 00E4h +SBM_SETSCROLLINFO = 00E9h +SBM_GETSCROLLINFO = 00EAh + +; Scroll bar commands + +SB_LINEUP = 0 +SB_LINELEFT = 0 +SB_LINEDOWN = 1 +SB_LINERIGHT = 1 +SB_PAGEUP = 2 +SB_PAGELEFT = 2 +SB_PAGEDOWN = 3 +SB_PAGERIGHT = 3 +SB_THUMBPOSITION = 4 +SB_THUMBTRACK = 5 +SB_TOP = 6 +SB_LEFT = 6 +SB_BOTTOM = 7 +SB_RIGHT = 7 +SB_ENDSCROLL = 8 + +; Scroll bar styles + +SBS_HORZ = 0000h +SBS_VERT = 0001h +SBS_TOPALIGN = 0002h +SBS_LEFTALIGN = 0002h +SBS_BOTTOMALIGN = 0004h +SBS_RIGHTALIGN = 0004h +SBS_SIZEBOXTOPLEFTALIGN = 0002h +SBS_SIZEBOXBOTTOMRIGHTALIGN = 0004h +SBS_SIZEBOX = 0008h +SBS_SIZEGRIP = 0010h + +; Scroll bar info flags + +SIF_RANGE = 0001h +SIF_PAGE = 0002h +SIF_POS = 0004h +SIF_DISABLENOSCROLL = 0008h +SIF_TRACKPOS = 0010h +SIF_ALL = SIF_RANGE or SIF_PAGE or SIF_POS or SIF_TRACKPOS + +; Dialog styles + +DS_ABSALIGN = 0001h +DS_SYSMODAL = 0002h +DS_3DLOOK = 0004h +DS_FIXEDSYS = 0008h +DS_NOFAILCREATE = 0010h +DS_LOCALEDIT = 0020h +DS_SETFONT = 0040h +DS_MODALFRAME = 0080h +DS_NOIDLEMSG = 0100h +DS_SETFOREGROUND = 0200h +DS_CONTROL = 0400h +DS_CENTER = 0800h +DS_CENTERMOUSE = 1000h +DS_CONTEXTHELP = 2000h + +; Dialog codes + +DLGC_WANTARROWS = 0001h +DLGC_WANTTAB = 0002h +DLGC_WANTALLKEYS = 0004h +DLGC_WANTMESSAGE = 0004h +DLGC_HASSETSEL = 0008h +DLGC_DEFPUSHBUTTON = 0010h +DLGC_UNDEFPUSHBUTTON = 0020h +DLGC_RADIOBUTTON = 0040h +DLGC_WANTCHARS = 0080h +DLGC_STATIC = 0100h +DLGC_BUTTON = 2000h + +; Menu flags + +MF_INSERT = 0000h +MF_CHANGE = 0080h +MF_APPEND = 0100h +MF_DELETE = 0200h +MF_REMOVE = 1000h +MF_BYCOMMAND = 0000h +MF_BYPOSITION = 0400h +MF_SEPARATOR = 0800h +MF_UNCHECKED = 0000h +MF_ENABLED = 0000h +MF_GRAYED = 0001h +MF_DISABLED = 0002h +MF_CHECKED = 0008h +MF_USECHECKBITMAPS = 0200h +MF_STRING = 0000h +MF_BITMAP = 0004h +MF_OWNERDRAW = 0100h +MF_POPUP = 0010h +MF_MENUBARBREAK = 0020h +MF_MENUBREAK = 0040h +MF_UNHILITE = 0000h +MF_HILITE = 0080h +MF_DEFAULT = 1000h +MF_SYSMENU = 2000h +MF_HELP = 4000h +MF_RIGHTJUSTIFY = 4000h +MF_MOUSESELECT = 8000h +MF_END = 0080h +MFT_STRING = MF_STRING +MFT_BITMAP = MF_BITMAP +MFT_MENUBARBREAK = MF_MENUBARBREAK +MFT_MENUBREAK = MF_MENUBREAK +MFT_OWNERDRAW = MF_OWNERDRAW +MFT_RADIOCHECK = 0200h +MFT_SEPARATOR = MF_SEPARATOR +MFT_RIGHTORDER = 2000h +MFT_RIGHTJUSTIFY = MF_RIGHTJUSTIFY +MFS_GRAYED = 0003h +MFS_DISABLED = MFS_GRAYED +MFS_CHECKED = MF_CHECKED +MFS_HILITE = MF_HILITE +MFS_ENABLED = MF_ENABLED +MFS_UNCHECKED = MF_UNCHECKED +MFS_UNHILITE = MF_UNHILITE +MFS_DEFAULT = MF_DEFAULT +MFR_POPUP = 0001h +MFR_END = MF_END + +; System menu command values + +SC_SIZE = 61440 +SC_MOVE = 61456 +SC_MINIMIZE = 61472 +SC_MAXIMIZE = 61488 +SC_NEXTWINDOW = 61504 +SC_PREVWINDOW = 61520 +SC_CLOSE = 61536 +SC_VSCROLL = 61552 +SC_HSCROLL = 61568 +SC_MOUSEMENU = 61584 +SC_KEYMENU = 61696 +SC_ARRANGE = 61712 +SC_RESTORE = 61728 +SC_TASKLIST = 61744 +SC_SCREENSAVE = 61760 +SC_HOTKEY = 61776 +SC_DEFAULT = 61792 +SC_MONITORPOWER = 61808 +SC_CONTEXTHELP = 61824 +SC_SEPARATOR = 61455 + +; Border types + +BDR_RAISEDOUTER = 01h +BDR_SUNKENOUTER = 02h +BDR_RAISEDINNER = 04h +BDR_SUNKENINNER = 08h +BDR_OUTER = 03h +BDR_INNER = 0Ch +BDR_RAISED = 05h +BDR_SUNKEN = 0Ah +EDGE_RAISED = BDR_RAISEDOUTER or BDR_RAISEDINNER +EDGE_SUNKEN = BDR_SUNKENOUTER or BDR_SUNKENINNER +EDGE_ETCHED = BDR_SUNKENOUTER or BDR_RAISEDINNER +EDGE_BUMP = BDR_RAISEDOUTER or BDR_SUNKENINNER + +; Border flags + +BF_LEFT = 0001h +BF_TOP = 0002h +BF_RIGHT = 0004h +BF_BOTTOM = 0008h +BF_TOPLEFT = BF_TOP or BF_LEFT +BF_TOPRIGHT = BF_TOP or BF_RIGHT +BF_BOTTOMLEFT = BF_BOTTOM or BF_LEFT +BF_BOTTOMRIGHT = BF_BOTTOM or BF_RIGHT +BF_RECT = BF_LEFT or BF_TOP or BF_RIGHT or BF_BOTTOM +BF_DIAGONAL = 0010h +BF_DIAGONAL_ENDTOPRIGHT = BF_DIAGONAL or BF_TOP or BF_RIGHT +BF_DIAGONAL_ENDTOPLEFT = BF_DIAGONAL or BF_TOP or BF_LEFT +BF_DIAGONAL_ENDBOTTOMLEFT = BF_DIAGONAL or BF_BOTTOM or BF_LEFT +BF_DIAGONAL_ENDBOTTOMRIGHT = BF_DIAGONAL or BF_BOTTOM or BF_RIGHT +BF_MIDDLE = 0800h +BF_SOFT = 1000h +BF_ADJUST = 2000h +BF_FLAT = 4000h +BF_MONO = 8000h + +; Frame control types + +DFC_CAPTION = 1 +DFC_MENU = 2 +DFC_SCROLL = 3 +DFC_BUTTON = 4 +DFC_POPUPMENU = 5 + +; Frame control states + +DFCS_CAPTIONCLOSE = 0000h +DFCS_CAPTIONMIN = 0001h +DFCS_CAPTIONMAX = 0002h +DFCS_CAPTIONRESTORE = 0003h +DFCS_CAPTIONHELP = 0004h +DFCS_MENUARROW = 0000h +DFCS_MENUCHECK = 0001h +DFCS_MENUBULLET = 0002h +DFCS_MENUARROWRIGHT = 0004h +DFCS_SCROLLUP = 0000h +DFCS_SCROLLDOWN = 0001h +DFCS_SCROLLLEFT = 0002h +DFCS_SCROLLRIGHT = 0003h +DFCS_SCROLLCOMBOBOX = 0005h +DFCS_SCROLLSIZEGRIP = 0008h +DFCS_SCROLLSIZEGRIPRIGHT = 0010h +DFCS_BUTTONCHECK = 0000h +DFCS_BUTTONRADIOIMAGE = 0001h +DFCS_BUTTONRADIOMASK = 0002h +DFCS_BUTTONRADIO = 0004h +DFCS_BUTTON3STATE = 0008h +DFCS_BUTTONPUSH = 0010h +DFCS_INACTIVE = 0100h +DFCS_PUSHED = 0200h +DFCS_CHECKED = 0400h +DFCS_TRANSPARENT = 0800h +DFCS_HOT = 1000h +DFCS_ADJUSTRECT = 2000h +DFCS_FLAT = 4000h +DFCS_MONO = 8000h + +; DrawCaption flags + +DC_ACTIVE = 01h +DC_SMALLCAP = 02h +DC_ICON = 04h +DC_TEXT = 08h +DC_INBUTTON = 10h + +; DrawIconEx options + +DI_MASK = 1 +DI_IMAGE = 2 +DI_NORMAL = 3 +DI_COMPAT = 4 +DI_DEFAULTSIZE = 8 + +; DrawText parameters + +DT_TOP = 00000h +DT_LEFT = 00000h +DT_CENTER = 00001h +DT_RIGHT = 00002h +DT_VCENTER = 00004h +DT_BOTTOM = 00008h +DT_WORDBREAK = 00010h +DT_SINGLELINE = 00020h +DT_EXPANDTABS = 00040h +DT_TABSTOP = 00080h +DT_NOCLIP = 00100h +DT_EXTERNALLEADING = 00200h +DT_CALCRECT = 00400h +DT_NOPREFIX = 00800h +DT_INTERNAL = 01000h +DT_EDITCONTROL = 02000h +DT_PATH_ELLIPSIS = 04000h +DT_END_ELLIPSIS = 08000h +DT_MODIFYSTRING = 10000h +DT_RTLREADING = 20000h +DT_WORD_ELLIPSIS = 40000h + +; GetDCEx flags + +DCX_WINDOW = 000001h +DCX_CACHE = 000002h +DCX_NORESETATTRS = 000004h +DCX_CLIPCHILDREN = 000008h +DCX_CLIPSIBLINGS = 000010h +DCX_PARENTCLIP = 000020h +DCX_EXCLUDERGN = 000040h +DCX_INTERSECTRGN = 000080h +DCX_EXCLUDEUPDATE = 000100h +DCX_INTERSECTUPDATE = 000200h +DCX_LOCKWINDOWUPDATE = 000400h +DCX_VALIDATE = 200000h + +; SetWindowsHook codes + +WH_MSGFILTER = -1 +WH_JOURNALRECORD = 0 +WH_JOURNALPLAYBACK = 1 +WH_KEYBOARD = 2 +WH_GETMESSAGE = 3 +WH_CALLWNDPROC = 4 +WH_CBT = 5 +WH_SYSMSGFILTER = 6 +WH_MOUSE = 7 +WH_HARDWARE = 8 +WH_DEBUG = 9 +WH_SHELL = 10 +WH_FOREGROUNDIDLE = 11 +WH_CALLWNDPROCRET = 12 +WH_KEYBOARD_LL = 13 +WH_MOUSE_LL = 14 + +; Hook codes + +HC_ACTION = 0 +HC_GETNEXT = 1 +HC_SKIP = 2 +HC_NOREMOVE = 3 +HC_SYSMODALON = 4 +HC_SYSMODALOFF = 5 + +; CBT hook codes + +HCBT_MOVESIZE = 0 +HCBT_MINMAX = 1 +HCBT_QS = 2 +HCBT_CREATEWND = 3 +HCBT_DESTROYWND = 4 +HCBT_ACTIVATE = 5 +HCBT_CLICKSKIPPED = 6 +HCBT_KEYSKIPPED = 7 +HCBT_SYSCOMMAND = 8 +HCBT_SETFOCUS = 9 + +; ExitWindowsEx flags + +EWX_LOGOFF = 0 +EWX_SHUTDOWN = 1 +EWX_REBOOT = 2 +EWX_FORCE = 4 +EWX_POWEROFF = 8 + +; WinHelp commands + +HELP_CONTEXT = 001h +HELP_QUIT = 002h +HELP_INDEX = 003h +HELP_CONTENTS = 003h +HELP_HELPONHELP = 004h +HELP_SETINDEX = 005h +HELP_SETCONTENTS = 005h +HELP_CONTEXTPOPUP = 008h +HELP_FORCEFILE = 009h +HELP_CONTEXTMENU = 00Ah +HELP_FINDER = 00Bh +HELP_WM_HELP = 00Ch +HELP_SETPOPUP_POS = 00Dh +HELP_KEY = 101h +HELP_COMMAND = 102h +HELP_PARTIALKEY = 105h +HELP_MULTIKEY = 201h +HELP_SETWINPOS = 203h + +; keybd_event flags + +KEYEVENTF_EXTENDEDKEY = 1h +KEYEVENTF_KEYUP = 2h + +; mouse_event flags + +MOUSEEVENTF_MOVE = 0001h +MOUSEEVENTF_LEFTDOWN = 0002h +MOUSEEVENTF_LEFTUP = 0004h +MOUSEEVENTF_RIGHTDOWN = 0008h +MOUSEEVENTF_RIGHTUP = 0010h +MOUSEEVENTF_MIDDLEDOWN = 0020h +MOUSEEVENTF_MIDDLEUP = 0040h +MOUSEEVENTF_WHEEL = 0800h +MOUSEEVENTF_ABSOLUTE = 8000h + +; TrackPopupMenu flags + +TPM_LEFTBUTTON = 0000h +TPM_RIGHTBUTTON = 0002h +TPM_LEFTALIGN = 0000h +TPM_CENTERALIGN = 0004h +TPM_RIGHTALIGN = 0008h +TPM_TOPALIGN = 0000h +TPM_VCENTERALIGN = 0010h +TPM_BOTTOMALIGN = 0020h +TPM_HORIZONTAL = 0000h +TPM_VERTICAL = 0040h +TPM_NONOTIFY = 0080h +TPM_RETURNCMD = 0100h +TPM_RECURSE = 0001h +TPM_HORPOSANIMATION = 0400h +TPM_HORNEGANIMATION = 0800h +TPM_VERPOSANIMATION = 1000h +TPM_VERNEGANIMATION = 2000h +TPM_NOANIMATION = 4000h +TPM_LAYOUTRTL = 8000h + +; Menu item info mask values + +MIIM_STATE = 001h +MIIM_ID = 002h +MIIM_SUBMENU = 004h +MIIM_CHECKMARKS = 008h +MIIM_TYPE = 010h +MIIM_DATA = 020h +MIIM_STRING = 040h +MIIM_BITMAP = 080h +MIIM_FTYPE = 100h + +; DRAWITEMSTRUCT control types + +ODT_MENU = 1 +ODT_LISTBOX = 2 +ODT_COMBOBOX = 3 +ODT_BUTTON = 4 +ODT_STATIC = 5 + +; DRAWITEMSTRUCT actions + +ODA_DRAWENTIRE = 1 +ODA_SELECT = 2 +ODA_FOCUS = 4 + +; DRAWITEMSTRUCT states + +ODS_SELECTED = 0001h +ODS_GRAYED = 0002h +ODS_DISABLED = 0004h +ODS_CHECKED = 0008h +ODS_FOCUS = 0010h +ODS_DEFAULT = 0020h +ODS_COMBOBOXEDIT = 1000h +ODS_HOTLIGHT = 0040h +ODS_INACTIVE = 0080h + +; WINDOWPLACEMENT flags + +WPF_SETMINPOSITION = 1 +WPF_RESTORETOMAXIMIZED = 2 + +; Layered window attributes + +LWA_COLORKEY = 1 +LWA_ALPHA = 2 + +; UpdateLayeredWindow flags + +ULW_COLORKEY = 1 +ULW_ALPHA = 2 +ULW_OPAQUE = 4 + +; SystemParametersInfo parameters + +SPI_GETACCESSTIMEOUT = 60 +SPI_GETANIMATION = 72 +SPI_GETBEEP = 1 +SPI_GETBORDER = 5 +SPI_GETDEFAULTINPUTLANG = 89 +SPI_GETDRAGFULLWINDOWS = 38 +SPI_GETFASTTASKSWITCH = 35 +SPI_GETFILTERKEYS = 50 +SPI_GETFONTSMOOTHING = 74 +SPI_GETGRIDGRANULARITY = 18 +SPI_GETHIGHCONTRAST = 66 +SPI_GETICONMETRICS = 45 +SPI_GETICONTITLELOGFONT = 31 +SPI_GETICONTITLEWRAP = 25 +SPI_GETKEYBOARDDELAY = 22 +SPI_GETKEYBOARDPREF = 68 +SPI_GETKEYBOARDSPEED = 10 +SPI_GETLOWPOWERACTIVE = 83 +SPI_GETLOWPOWERTIMEOUT = 79 +SPI_GETMENUDROPALIGNMENT = 27 +SPI_GETMINIMIZEDMETRICS = 43 +SPI_GETMOUSE = 3 +SPI_GETMOUSEKEYS = 54 +SPI_GETMOUSETRAILS = 94 +SPI_GETNONCLIENTMETRICS = 41 +SPI_GETPOWEROFFACTIVE = 84 +SPI_GETPOWEROFFTIMEOUT = 80 +SPI_GETSCREENREADER = 70 +SPI_GETSCREENSAVEACTIVE = 16 +SPI_GETSCREENSAVETIMEOUT = 14 +SPI_GETSERIALKEYS = 62 +SPI_GETSHOWSOUNDS = 56 +SPI_GETSOUNDSENTRY = 64 +SPI_GETSTICKYKEYS = 58 +SPI_GETTOGGLEKEYS = 52 +SPI_GETWINDOWSEXTENSION = 92 +SPI_GETWORKAREA = 48 +SPI_ICONHORIZONTALSPACING = 13 +SPI_ICONVERTICALSPACING = 24 +SPI_LANGDRIVER = 12 +SPI_SCREENSAVERRUNNING = 97 +SPI_SETACCESSTIMEOUT = 61 +SPI_SETANIMATION = 73 +SPI_SETBEEP = 2 +SPI_SETBORDER = 6 +SPI_SETDEFAULTINPUTLANG = 90 +SPI_SETDESKPATTERN = 21 +SPI_SETDESKWALLPAPER = 20 +SPI_SETDOUBLECLICKTIME = 32 +SPI_SETDOUBLECLKHEIGHT = 30 +SPI_SETDOUBLECLKWIDTH = 29 +SPI_SETDRAGFULLWINDOWS = 37 +SPI_SETDRAGHEIGHT = 77 +SPI_SETDRAGWIDTH = 76 +SPI_SETFASTTASKSWITCH = 36 +SPI_SETFILTERKEYS = 51 +SPI_SETFONTSMOOTHING = 75 +SPI_SETGRIDGRANULARITY = 19 +SPI_SETHANDHELD = 78 +SPI_SETHIGHCONTRAST = 67 +SPI_SETICONMETRICS = 46 +SPI_SETICONTITLELOGFONT = 34 +SPI_SETICONTITLEWRAP = 26 +SPI_SETKEYBOARDDELAY = 23 +SPI_SETKEYBOARDPREF = 69 +SPI_SETKEYBOARDSPEED = 11 +SPI_SETLANGTOGGLE = 91 +SPI_SETLOWPOWERACTIVE = 85 +SPI_SETLOWPOWERTIMEOUT = 81 +SPI_SETMENUDROPALIGNMENT = 28 +SPI_SETMINIMIZEDMETRICS = 44 +SPI_SETMOUSE = 4 +SPI_SETMOUSEBUTTONSWAP = 33 +SPI_SETMOUSEKEYS = 55 +SPI_SETMOUSETRAILS = 93 +SPI_SETNONCLIENTMETRICS = 42 +SPI_SETPENWINDOWS = 49 +SPI_SETPOWEROFFACTIVE = 86 +SPI_SETPOWEROFFTIMEOUT = 82 +SPI_SETSCREENREADER = 71 +SPI_SETSCREENSAVEACTIVE = 17 +SPI_SETSCREENSAVERRUNNING = 97 +SPI_SETSCREENSAVETIMEOUT = 15 +SPI_SETSERIALKEYS = 63 +SPI_SETSHOWSOUNDS = 57 +SPI_SETSOUNDSENTRY = 65 +SPI_SETSTICKYKEYS = 59 +SPI_SETTOGGLEKEYS = 53 +SPI_SETWORKAREA = 47 + +; SystemParametersInfo flags + +SPIF_UPDATEINIFILE = 1 +SPIF_SENDWININICHANGE = 2 + +; Gesture Information Flags + +GF_BEGIN = 1 +GF_INERTIA = 2 +GF_END = 4 + +; Gesture IDs + +GID_BEGIN = 1 +GID_END = 2 +GID_ZOOM = 3 +GID_PAN = 4 +GID_ROTATE = 5 +GID_TWOFINGERTAP = 6 +GID_PRESSANDTAP = 7 +GID_ROLLOVER = GID_PRESSANDTAP + +; Zoom Gesture Confiration Flags + +GC_ZOOM = 0x00000001 + +; Pan Gesture Configuration Flags + +GC_PAN = 0x00000001 +GC_PAN_WITH_SINGLE_FINGER_VERTICALLY = 0x00000002 +GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY = 0x00000004 +GC_PAN_WITH_GUTTER = 0x00000008 +GC_PAN_WITH_INERTIA = 0x00000010 + +; Rotate Gesture Configuration Flags + +GC_ROTATE = 0x00000001 + +; Two finger tap configuration flags + +GC_TWOFINGERTAP = 0x00000001 + +; Press and tap Configuration Flags + +GC_PRESSANDTAP = 0x00000001 +GC_ROLLOVER = GC_PRESSANDTAP diff --git a/toolchain/fasmw17332/INCLUDE/EQUATES/USER64.INC b/toolchain/fasmw17332/INCLUDE/EQUATES/USER64.INC new file mode 100644 index 0000000..8154423 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/EQUATES/USER64.INC @@ -0,0 +1,1935 @@ + +; USER32.DLL structures and constants + +struct POINT + x dd ? + y dd ? +ends + +struct POINTS + x dw ? + y dw ? +ends + +struct RECT + left dd ? + top dd ? + right dd ? + bottom dd ? +ends + +struct WNDCLASS + style dd ?,? + lpfnWndProc dq ? + cbClsExtra dd ? + cbWndExtra dd ? + hInstance dq ? + hIcon dq ? + hCursor dq ? + hbrBackground dq ? + lpszMenuName dq ? + lpszClassName dq ? +ends + +struct WNDCLASSEX + cbSize dd ? + style dd ? + lpfnWndProc dq ? + cbClsExtra dd ? + cbWndExtra dd ? + hInstance dq ? + hIcon dq ? + hCursor dq ? + hbrBackground dq ? + lpszMenuName dq ? + lpszClassName dq ? + hIconSm dq ? +ends + +struct CREATESTRUCT + lpCreateParams dq ? + hInstance dq ? + hMenu dq ? + hwndParent dq ? + cy dd ? + cx dd ? + y dd ? + x dd ? + style dd ?,? + lpszName dq ? + lpszClass dq ? + dwExStyle dd ?,? +ends + +struct CLIENTCREATESTRUCT + hWindowMenu dq ? + idFirstChild dd ? +ends + +struct MDICREATESTRUCT + szClass dq ? + szTitle dq ? + hOwner dq ? + x dd ? + y dd ? + cx dd ? + cy dd ? + style dd ? + lParam dd ? +ends + +struct SCROLLINFO + cbSize dd ? + fMask dd ? + nMin dd ? + nMax dd ? + nPage dd ? + nPos dd ? + nTrackPos dd ? +ends + +struct MSG + hwnd dq ? + message dd ?,? + wParam dq ? + lParam dq ? + time dd ? + pt POINT + dd ? +ends + +struct MINMAXINFO + ptReserved POINT + ptMaxSize POINT + ptMaxPosition POINT + ptMinTrackSize POINT + ptMaxTrackSize POINT +ends + +struct WINDOWPLACEMENT + length dd ? + flags dd ? + showCmd dd ? + ptMinPosition POINT + ptMaxPosition POINT + rcNormalPosition RECT +ends + +struct WINDOWPOS + hwnd dq ? + hwndInsertAfter dq ? + x dd ? + y dd ? + cx dd ? + cy dd ? + flags dd ?,? +ends + +struct NMHDR + hwndFrom dq ? + idFrom dq ? + code dd ?,? +ends + +struct COPYDATASTRUCT + dwData dq ? + cbData dd ?,? + lpData dq ? +ends + +struct ACCEL + fVirt dw ? + key dw ? + cmd dw ? +ends + +struct PAINTSTRUCT + hdc dq ? + fErase dd ? + rcPaint RECT + fRestore dd ? + fIncUpdate dd ? + rgbReserved db 36 dup (?) +ends + +struct DRAWTEXTPARAMS + cbSize dd ? + iTabLength dd ? + iLeftMargin dd ? + iRightMargin dd ? + uiLengthDrawn dd ?,? +ends + +struct DRAWITEMSTRUCT + CtlType dd ? + CtlID dd ? + itemID dd ? + itemAction dd ? + itemState dd ?,? + hwndItem dq ? + hDC dq ? + rcItem RECT + itemData dd ?,? +ends + +struct MENUITEMINFO + cbSize dd ? + fMask dd ? + fType dd ? + fState dd ? + wID dd ?,? + hSubMenu dq ? + hbmpChecked dq ? + hbmpUnchecked dq ? + dwItemData dq ? + dwTypeData dq ? + cch dd ?,? + hbmpItem dq ? +ends + +struct MEASUREITEMSTRUCT + CtlType dd ? + CtlID dd ? + itemID dd ? + itemWidth dd ? + itemHeight dd ?,? + itemData dq ? +ends + +struct MSGBOXPARAMS + cbSize dd ?,? + hwndOwner dq ? + hInstance dq ? + lpszText dd ? + lpszCaption dd ? + dwStyle dd ?,? + lpszIcon dq ? + dwContextHelpId dd ?,? + lpfnMsgBoxCallback dq ? + dwLanguageId dd ?,? +ends + +struct GESTURECONFIG + dwID dd ? + dwWant dd ? + dwBlock dd ? +ends + +struct GESTUREINFO + cbSize dd ? + dwFlags dd ? + dwID dd ?,? + hwndTarget dq ? + ptsLocation POINTS + dwInstanceID dd ? + dwSequenceID dd ?,? + ullArguments dq ? + cbExtraArgs dd ?,? +ends + +; MessageBox type flags + +MB_OK = 000000h +MB_OKCANCEL = 000001h +MB_ABORTRETRYIGNORE = 000002h +MB_YESNOCANCEL = 000003h +MB_YESNO = 000004h +MB_RETRYCANCEL = 000005h +MB_ICONHAND = 000010h +MB_ICONQUESTION = 000020h +MB_ICONEXCLAMATION = 000030h +MB_ICONASTERISK = 000040h +MB_USERICON = 000080h +MB_ICONWARNING = MB_ICONEXCLAMATION +MB_ICONERROR = MB_ICONHAND +MB_ICONINFORMATION = MB_ICONASTERISK +MB_ICONSTOP = MB_ICONHAND +MB_DEFBUTTON1 = 000000h +MB_DEFBUTTON2 = 000100h +MB_DEFBUTTON3 = 000200h +MB_DEFBUTTON4 = 000300h +MB_APPLMODAL = 000000h +MB_SYSTEMMODAL = 001000h +MB_TASKMODAL = 002000h +MB_HELP = 004000h +MB_NOFOCUS = 008000h +MB_SETFOREGROUND = 010000h +MB_DEFAULT_DESKTOP_ONLY = 020000h +MB_TOPMOST = 040000h +MB_RIGHT = 080000h +MB_RTLREADING = 100000h +MB_SERVICE_NOTIFICATION = 200000h + +; Conventional dialog box and message box command IDs + +IDOK = 1 +IDCANCEL = 2 +IDABORT = 3 +IDRETRY = 4 +IDIGNORE = 5 +IDYES = 6 +IDNO = 7 +IDCLOSE = 8 +IDHELP = 9 + +; Class styles + +CS_VREDRAW = 00001h +CS_HREDRAW = 00002h +CS_KEYCVTWINDOW = 00004h +CS_DBLCLKS = 00008h +CS_OWNDC = 00020h +CS_CLASSDC = 00040h +CS_PARENTDC = 00080h +CS_NOKEYCVT = 00100h +CS_SAVEBITS = 00800h +CS_NOCLOSE = 00200h +CS_BYTEALIGNCLIENT = 01000h +CS_BYTEALIGNWINDOW = 02000h +CS_PUBLICCLASS = 04000h +CS_GLOBALCLASS = CS_PUBLICCLASS +CS_IME = 10000h + +; Windows styles + +WS_OVERLAPPED = 000000000h +WS_ICONICPOPUP = 0C0000000h +WS_POPUP = 080000000h +WS_CHILD = 040000000h +WS_MINIMIZE = 020000000h +WS_VISIBLE = 010000000h +WS_DISABLED = 008000000h +WS_CLIPSIBLINGS = 004000000h +WS_CLIPCHILDREN = 002000000h +WS_MAXIMIZE = 001000000h +WS_CAPTION = 000C00000h +WS_BORDER = 000800000h +WS_DLGFRAME = 000400000h +WS_VSCROLL = 000200000h +WS_HSCROLL = 000100000h +WS_SYSMENU = 000080000h +WS_THICKFRAME = 000040000h +WS_HREDRAW = 000020000h +WS_VREDRAW = 000010000h +WS_GROUP = 000020000h +WS_TABSTOP = 000010000h +WS_MINIMIZEBOX = 000020000h +WS_MAXIMIZEBOX = 000010000h + +; Common Window Styles + +WS_OVERLAPPEDWINDOW = WS_OVERLAPPED or WS_CAPTION or WS_SYSMENU or WS_THICKFRAME or WS_MINIMIZEBOX or WS_MAXIMIZEBOX +WS_POPUPWINDOW = WS_POPUP or WS_BORDER or WS_SYSMENU +WS_CHILDWINDOW = WS_CHILD +WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW +WS_TILED = WS_OVERLAPPED +WS_ICONIC = WS_MINIMIZE +WS_SIZEBOX = WS_THICKFRAME + +; Extended Window Styles + +WS_EX_DLGMODALFRAME = 00001h +WS_EX_DRAGOBJECT = 00002h +WS_EX_NOPARENTNOTIFY = 00004h +WS_EX_TOPMOST = 00008h +WS_EX_ACCEPTFILES = 00010h +WS_EX_TRANSPARENT = 00020h +WS_EX_MDICHILD = 00040h +WS_EX_TOOLWINDOW = 00080h +WS_EX_WINDOWEDGE = 00100h +WS_EX_CLIENTEDGE = 00200h +WS_EX_CONTEXTHELP = 00400h +WS_EX_RIGHT = 01000h +WS_EX_LEFT = 00000h +WS_EX_RTLREADING = 02000h +WS_EX_LTRREADING = 00000h +WS_EX_LEFTSCROLLBAR = 04000h +WS_EX_RIGHTSCROLLBAR = 00000h +WS_EX_CONTROLPARENT = 10000h +WS_EX_STATICEDGE = 20000h +WS_EX_APPWINDOW = 40000h +WS_EX_LAYERED = 80000h +WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE or WS_EX_CLIENTEDGE +WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE or WS_EX_TOOLWINDOW or WS_EX_TOPMOST + +; MDI client style bits + +MDIS_ALLCHILDSTYLES = 1 + +; Special CreateWindow position value + +CW_USEDEFAULT = 80000000h + +; Predefined window handle + +HWND_DESKTOP = 0 + +; ShowWindow commands + +SW_HIDE = 0 +SW_SHOWNORMAL = 1 +SW_NORMAL = 1 +SW_SHOWMINIMIZED = 2 +SW_SHOWMAXIMIZED = 3 +SW_MAXIMIZE = 3 +SW_SHOWNOACTIVATE = 4 +SW_SHOW = 5 +SW_MINIMIZE = 6 +SW_SHOWMINNOACTIVE = 7 +SW_SHOWNA = 8 +SW_RESTORE = 9 +SW_SHOWDEFAULT = 10 + +; SetWindowPos flags + +SWP_NOSIZE = 0001h +SWP_NOMOVE = 0002h +SWP_NOZORDER = 0004h +SWP_NOREDRAW = 0008h +SWP_NOACTIVATE = 0010h +SWP_DRAWFRAME = 0020h +SWP_SHOWWINDOW = 0040h +SWP_HIDEWINDOW = 0080h +SWP_NOCOPYBITS = 0100h +SWP_NOREPOSITION = 0200h +SWP_DEFERERASE = 2000h +SWP_ASYNCWINDOWPOS = 4000h + +; SetWindowPos special handle values + +HWND_TOP = 0 +HWND_BOTTOM = 1 +HWND_TOPMOST = -1 +HWND_NOTOPMOST = -2 + +; GetWindow flags + +GW_HWNDFIRST = 0 +GW_HWNDLAST = 1 +GW_HWNDNEXT = 2 +GW_HWNDPREV = 3 +GW_OWNER = 4 +GW_CHILD = 5 + +; RedrawWindow flags + +RDW_INVALIDATE = 0001h +RDW_INTERNALPAINT = 0002h +RDW_ERASE = 0004h +RDW_VALIDATE = 0008h +RDW_NOINTERNALPAINT = 0010h +RDW_NOERASE = 0020h +RDW_NOCHILDREN = 0040h +RDW_ALLCHILDREN = 0080h +RDW_UPDATENOW = 0100h +RDW_ERASENOW = 0200h +RDW_FRAME = 0400h +RDW_NOFRAME = 0800h + +; PeekMessage Options + +PM_NOREMOVE = 0000h +PM_REMOVE = 0001h +PM_NOYIELD = 0002h + +; Window state messages + +WM_STATE = 0000h +WM_NULL = 0000h +WM_CREATE = 0001h +WM_DESTROY = 0002h +WM_MOVE = 0003h +WM_SIZE = 0005h +WM_ACTIVATE = 0006h +WM_SETFOCUS = 0007h +WM_KILLFOCUS = 0008h +WM_ENABLE = 000Ah +WM_SETREDRAW = 000Bh +WM_SETTEXT = 000Ch +WM_GETTEXT = 000Dh +WM_GETTEXTLENGTH = 000Eh +WM_PAINT = 000Fh +WM_CLOSE = 0010h +WM_QUERYENDSESSION = 0011h +WM_QUIT = 0012h +WM_QUERYOPEN = 0013h +WM_ERASEBKGND = 0014h +WM_SYSCOLORCHANGE = 0015h +WM_ENDSESSION = 0016h +WM_SYSTEMERROR = 0017h +WM_SHOWWINDOW = 0018h +WM_CTLCOLOR = 0019h +WM_WININICHANGE = 001Ah +WM_DEVMODECHANGE = 001Bh +WM_ACTIVATEAPP = 001Ch +WM_FONTCHANGE = 001Dh +WM_TIMECHANGE = 001Eh +WM_CANCELMODE = 001Fh +WM_SETCURSOR = 0020h +WM_MOUSEACTIVATE = 0021h +WM_CHILDACTIVATE = 0022h +WM_QUEUESYNC = 0023h +WM_GETMINMAXINFO = 0024h +WM_PAINTICON = 0026h +WM_ICONERASEBKGND = 0027h +WM_NEXTDLGCTL = 0028h +WM_SPOOLERSTATUS = 002Ah +WM_DRAWITEM = 002Bh +WM_MEASUREITEM = 002Ch +WM_DELETEITEM = 002Dh +WM_VKEYTOITEM = 002Eh +WM_CHARTOITEM = 002Fh +WM_SETFONT = 0030h +WM_GETFONT = 0031h +WM_SETHOTKEY = 0032h +WM_QUERYDRAGICON = 0037h +WM_COMPAREITEM = 0039h +WM_COMPACTING = 0041h +WM_COMMNOTIFY = 0044h +WM_WINDOWPOSCHANGING = 0046h +WM_WINDOWPOSCHANGED = 0047h +WM_POWER = 0048h +WM_COPYDATA = 004Ah +WM_CANCELJOURNAL = 004Bh +WM_NOTIFY = 004Eh +WM_INPUTLANGCHANGEREQUEST = 0050h +WM_INPUTLANGCHANGE = 0051h +WM_TCARD = 0052h +WM_HELP = 0053h +WM_USERCHANGED = 0054h +WM_NOTIFYFORMAT = 0055h +WM_CONTEXTMENU = 007Bh +WM_STYLECHANGING = 007Ch +WM_STYLECHANGED = 007Dh +WM_DISPLAYCHANGE = 007Eh +WM_GETICON = 007Fh +WM_SETICON = 0080h +WM_NCCREATE = 0081h +WM_NCDESTROY = 0082h +WM_NCCALCSIZE = 0083h +WM_NCHITTEST = 0084h +WM_NCPAINT = 0085h +WM_NCACTIVATE = 0086h +WM_GETDLGCODE = 0087h +WM_NCMOUSEMOVE = 00A0h +WM_NCLBUTTONDOWN = 00A1h +WM_NCLBUTTONUP = 00A2h +WM_NCLBUTTONDBLCLK = 00A3h +WM_NCRBUTTONDOWN = 00A4h +WM_NCRBUTTONUP = 00A5h +WM_NCRBUTTONDBLCLK = 00A6h +WM_NCMBUTTONDOWN = 00A7h +WM_NCMBUTTONUP = 00A8h +WM_NCMBUTTONDBLCLK = 00A9h +WM_KEYFIRST = 0100h +WM_KEYDOWN = 0100h +WM_KEYUP = 0101h +WM_CHAR = 0102h +WM_DEADCHAR = 0103h +WM_SYSKEYDOWN = 0104h +WM_SYSKEYUP = 0105h +WM_SYSCHAR = 0106h +WM_SYSDEADCHAR = 0107h +WM_KEYLAST = 0108h +WM_INITDIALOG = 0110h +WM_COMMAND = 0111h +WM_SYSCOMMAND = 0112h +WM_TIMER = 0113h +WM_HSCROLL = 0114h +WM_VSCROLL = 0115h +WM_INITMENU = 0116h +WM_INITMENUPOPUP = 0117h +WM_GESTURE = 0119h +WM_GESTURENOTIFY = 011Ah +WM_MENUSELECT = 011Fh +WM_MENUCHAR = 0120h +WM_ENTERIDLE = 0121h +WM_MENURBUTTONUP = 0122h +WM_MENUDRAG = 0123h +WM_MENUGETOBJECT = 0124h +WM_UNINITMENUPOPUP = 0125h +WM_MENUCOMMAND = 0126h +WM_CTLCOLORMSGBOX = 0132h +WM_CTLCOLOREDIT = 0133h +WM_CTLCOLORLISTBOX = 0134h +WM_CTLCOLORBTN = 0135h +WM_CTLCOLORDLG = 0136h +WM_CTLCOLORSCROLLBAR = 0137h +WM_CTLCOLORSTATIC = 0138h +WM_MOUSEFIRST = 0200h +WM_MOUSEMOVE = 0200h +WM_LBUTTONDOWN = 0201h +WM_LBUTTONUP = 0202h +WM_LBUTTONDBLCLK = 0203h +WM_RBUTTONDOWN = 0204h +WM_RBUTTONUP = 0205h +WM_RBUTTONDBLCLK = 0206h +WM_MBUTTONDOWN = 0207h +WM_MBUTTONUP = 0208h +WM_MBUTTONDBLCLK = 0209h +WM_MOUSEWHEEL = 020Ah +WM_MOUSELAST = 020Ah +WM_PARENTNOTIFY = 0210h +WM_ENTERMENULOOP = 0211h +WM_EXITMENULOOP = 0212h +WM_NEXTMENU = 0213h +WM_SIZING = 0214h +WM_CAPTURECHANGED = 0215h +WM_MOVING = 0216h +WM_POWERBROADCAST = 0218h +WM_DEVICECHANGE = 0219h +WM_MDICREATE = 0220h +WM_MDIDESTROY = 0221h +WM_MDIACTIVATE = 0222h +WM_MDIRESTORE = 0223h +WM_MDINEXT = 0224h +WM_MDIMAXIMIZE = 0225h +WM_MDITILE = 0226h +WM_MDICASCADE = 0227h +WM_MDIICONARRANGE = 0228h +WM_MDIGETACTIVE = 0229h +WM_MDISETMENU = 0230h +WM_ENTERSIZEMOVE = 0231h +WM_EXITSIZEMOVE = 0232h +WM_DROPFILES = 0233h +WM_MDIREFRESHMENU = 0234h +WM_IME_SETCONTEXT = 0281h +WM_IME_NOTIFY = 0282h +WM_IME_CONTROL = 0283h +WM_IME_COMPOSITIONFULL = 0284h +WM_IME_SELECT = 0285h +WM_IME_CHAR = 0286h +WM_IME_KEYDOWN = 0290h +WM_IME_KEYUP = 0291h +WM_MOUSEHOVER = 02A1h +WM_MOUSELEAVE = 02A3h +WM_CUT = 0300h +WM_COPY = 0301h +WM_PASTE = 0302h +WM_CLEAR = 0303h +WM_UNDO = 0304h +WM_RENDERFORMAT = 0305h +WM_RENDERALLFORMATS = 0306h +WM_DESTROYCLIPBOARD = 0307h +WM_DRAWCLIPBOARD = 0308h +WM_PAINTCLIPBOARD = 0309h +WM_VSCROLLCLIPBOARD = 030Ah +WM_SIZECLIPBOARD = 030Bh +WM_ASKCBFORMATNAME = 030Ch +WM_CHANGECBCHAIN = 030Dh +WM_HSCROLLCLIPBOARD = 030Eh +WM_QUERYNEWPALETTE = 030Fh +WM_PALETTEISCHANGING = 0310h +WM_PALETTECHANGED = 0311h +WM_HOTKEY = 0312h +WM_PRINT = 0317h +WM_PRINTCLIENT = 0318h +WM_HANDHELDFIRST = 0358h +WM_HANDHELDLAST = 035Fh +WM_AFXFIRST = 0360h +WM_AFXLAST = 037Fh +WM_PENWINFIRST = 0380h +WM_PENWINLAST = 038Fh +WM_COALESCE_FIRST = 0390h +WM_COALESCE_LAST = 039Fh +WM_USER = 0400h + +; WM_SIZE commands + +SIZE_RESTORED = 0 +SIZE_MINIMIZED = 1 +SIZE_MAXIMIZED = 2 +SIZE_MAXSHOW = 3 +SIZE_MAXHIDE = 4 + +; WM_ACTIVATE states + +WA_INACTIVE = 0 +WA_ACTIVE = 1 +WA_CLICKACTIVE = 2 + +; WM_SHOWWINDOW identifiers + +SW_PARENTCLOSING = 1 +SW_OTHERZOOM = 2 +SW_PARENTOPENING = 3 +SW_OTHERUNZOOM = 4 + +; WM_MOUSEACTIVATE return codes + +MA_ACTIVATE = 1 +MA_ACTIVATEANDEAT = 2 +MA_NOACTIVATE = 3 +MA_NOACTIVATEANDEAT = 4 + +; WM_MDITILE flags + +MDITILE_VERTICAL = 0 +MDITILE_HORIZONTAL = 1 +MDITILE_SKIPDISABLED = 2 + +; WM_NOTIFY codes + +NM_OUTOFMEMORY = -1 +NM_CLICK = -2 +NM_DBLCLICK = -3 +NM_RETURN = -4 +NM_RCLICK = -5 +NM_RDBLCLK = -6 +NM_SETFOCUS = -7 +NM_KILLFOCUS = -8 + +; WM_SETICON types + +ICON_SMALL = 0 +ICON_BIG = 1 + +; WM_HOTKEY commands + +HOTKEYF_SHIFT = 01h +HOTKEYF_CONTROL = 02h +HOTKEYF_ALT = 04h +HOTKEYF_EXT = 08h + +; Keystroke flags + +KF_EXTENDED = 0100h +KF_DLGMODE = 0800h +KF_MENUMODE = 1000h +KF_ALTDOWN = 2000h +KF_REPEAT = 4000h +KF_UP = 8000h + +; Key state masks for mouse messages + +MK_LBUTTON = 01h +MK_RBUTTON = 02h +MK_SHIFT = 04h +MK_CONTROL = 08h +MK_MBUTTON = 10h + +; WM_SIZING codes + +WMSZ_LEFT = 1 +WMSZ_RIGHT = 2 +WMSZ_TOP = 3 +WMSZ_TOPLEFT = 4 +WMSZ_TOPRIGHT = 5 +WMSZ_BOTTOM = 6 +WMSZ_BOTTOMLEFT = 7 +WMSZ_BOTTOMRIGHT = 8 + +; WM_HOTKEY modifiers + +MOD_ALT = 1 +MOD_CONTROL = 2 +MOD_SHIFT = 4 +MOD_WIN = 8 + +; WM_PRINT flags + +PRF_CHECKVISIBLE = 01h +PRF_NONCLIENT = 02h +PRF_CLIENT = 04h +PRF_ERASEBKGND = 08h +PRF_CHILDREN = 10h +PRF_OWNED = 20h + +; Virtual key codes + +VK_LBUTTON = 001h +VK_CANCEL = 003h +VK_RBUTTON = 002h +VK_MBUTTON = 004h +VK_BACK = 008h +VK_TAB = 009h +VK_CLEAR = 00Ch +VK_RETURN = 00Dh +VK_SHIFT = 010h +VK_CONTROL = 011h +VK_MENU = 012h +VK_PAUSE = 013h +VK_CAPITAL = 014h +VK_ESCAPE = 01Bh +VK_SPACE = 020h +VK_PRIOR = 021h +VK_PGUP = 021h +VK_PGDN = 022h +VK_NEXT = 022h +VK_END = 023h +VK_HOME = 024h +VK_LEFT = 025h +VK_UP = 026h +VK_RIGHT = 027h +VK_DOWN = 028h +VK_SELECT = 029h +VK_PRINT = 02Ah +VK_EXECUTE = 02Bh +VK_SNAPSHOT = 02Ch +VK_INSERT = 02Dh +VK_DELETE = 02Eh +VK_HELP = 02Fh +VK_LWIN = 05Bh +VK_RWIN = 05Ch +VK_APPS = 05Dh +VK_NUMPAD0 = 060h +VK_NUMPAD1 = 061h +VK_NUMPAD2 = 062h +VK_NUMPAD3 = 063h +VK_NUMPAD4 = 064h +VK_NUMPAD5 = 065h +VK_NUMPAD6 = 066h +VK_NUMPAD7 = 067h +VK_NUMPAD8 = 068h +VK_NUMPAD9 = 069h +VK_MULTIPLY = 06Ah +VK_ADD = 06Bh +VK_SEPARATOR = 06Ch +VK_SUBTRACT = 06Dh +VK_DECIMAL = 06Eh +VK_DIVIDE = 06Fh +VK_F1 = 070h +VK_F2 = 071h +VK_F3 = 072h +VK_F4 = 073h +VK_F5 = 074h +VK_F6 = 075h +VK_F7 = 076h +VK_F8 = 077h +VK_F9 = 078h +VK_F10 = 079h +VK_F11 = 07Ah +VK_F12 = 07Bh +VK_F13 = 07Ch +VK_F14 = 07Dh +VK_F15 = 07Eh +VK_F16 = 07Fh +VK_F17 = 080h +VK_F18 = 081h +VK_F19 = 082h +VK_F20 = 083h +VK_F21 = 084h +VK_F22 = 085h +VK_F23 = 086h +VK_F24 = 087h +VK_NUMLOCK = 090h +VK_SCROLL = 091h +VK_LSHIFT = 0A0h +VK_RSHIFT = 0A1h +VK_LCONTROL = 0A2h +VK_RCONTROL = 0A3h +VK_LMENU = 0A4h +VK_RMENU = 0A5h +VK_ATTN = 0F6h +VK_CRSEL = 0F7h +VK_EXSEL = 0F8h +VK_EREOF = 0F9h +VK_PLAY = 0FAh +VK_ZOOM = 0FBh +VK_NONAME = 0FCh +VK_PA1 = 0FDh +VK_OEM_CLEAR = 0FEh + +; Accelerator flags + +FVIRTKEY = 01h +FNOINVERT = 02h +FSHIFT = 04h +FCONTROL = 08h +FALT = 10h + +; GetClassLong offsets + +GCL_MENUNAME = -8 +GCL_HBRBACKGROUND = -10 +GCL_HCURSOR = -12 +GCL_HICON = -14 +GCL_HMODULE = -16 +GCL_CBWNDEXTRA = -18 +GCL_CBCLSEXTRA = -20 +GCL_WNDPROC = -24 +GCL_STYLE = -26 +GCW_ATOM = -32 +GCL_HICONSM = -34 + +; WNDCLASS parameters + +DLGWINDOWEXTRA = 30 + +; GetWindowLong offsets + +GWLP_WNDPROC = -4 +GWLP_HINSTANCE = -6 +GWLP_HWNDPARENT = -8 +GWLP_ID = -12 +GWLP_STYLE = -16 +GWLP_EXSTYLE = -20 +GWLP_USERDATA = -21 +DWLP_MSGRESULT = 0 +DWLP_DLGPROC = 8 +DWLP_USER = 16 + +; GetSystemMetrics codes + +SM_CXSCREEN = 0 +SM_CYSCREEN = 1 +SM_CXVSCROLL = 2 +SM_CYHSCROLL = 3 +SM_CYCAPTION = 4 +SM_CXBORDER = 5 +SM_CYBORDER = 6 +SM_CXDLGFRAME = 7 +SM_CYDLGFRAME = 8 +SM_CYVTHUMB = 9 +SM_CXHTHUMB = 10 +SM_CXICON = 11 +SM_CYICON = 12 +SM_CXCURSOR = 13 +SM_CYCURSOR = 14 +SM_CYMENU = 15 +SM_CXFULLSCREEN = 16 +SM_CYFULLSCREEN = 17 +SM_CYKANJIWINDOW = 18 +SM_MOUSEPRESENT = 19 +SM_CYVSCROLL = 20 +SM_CXHSCROLL = 21 +SM_DEBUG = 22 +SM_SWAPBUTTON = 23 +SM_RESERVED1 = 24 +SM_RESERVED2 = 25 +SM_RESERVED3 = 26 +SM_RESERVED4 = 27 +SM_CXMIN = 28 +SM_CYMIN = 29 +SM_CXSIZE = 30 +SM_CYSIZE = 31 +SM_CXFRAME = 32 +SM_CYFRAME = 33 +SM_CXMINTRACK = 34 +SM_CYMINTRACK = 35 +SM_CXDOUBLECLK = 36 +SM_CYDOUBLECLK = 37 +SM_CXICONSPACING = 38 +SM_CYICONSPACING = 39 +SM_MENUDROPALIGNMENT = 40 +SM_PENWINDOWS = 41 +SM_DBCSENABLED = 42 +SM_CMOUSEBUTTONS = 43 +SM_CXFIXEDFRAME = SM_CXDLGFRAME +SM_CYFIXEDFRAME = SM_CYDLGFRAME +SM_CXSIZEFRAME = SM_CXFRAME +SM_CYSIZEFRAME = SM_CYFRAME +SM_SECURE = 44 +SM_CXEDGE = 45 +SM_CYEDGE = 46 +SM_CXMINSPACING = 47 +SM_CYMINSPACING = 48 +SM_CXSMICON = 49 +SM_CYSMICON = 50 +SM_CYSMCAPTION = 51 +SM_CXSMSIZE = 52 +SM_CYSMSIZE = 53 +SM_CXMENUSIZE = 54 +SM_CYMENUSIZE = 55 +SM_ARRANGE = 56 +SM_CXMINIMIZED = 57 +SM_CYMINIMIZED = 58 +SM_CXMAXTRACK = 59 +SM_CYMAXTRACK = 60 +SM_CXMAXIMIZED = 61 +SM_CYMAXIMIZED = 62 +SM_NETWORK = 63 +SM_CLEANBOOT = 67 +SM_CXDRAG = 68 +SM_CYDRAG = 69 +SM_SHOWSOUNDS = 70 +SM_CXMENUCHECK = 71 +SM_CYMENUCHECK = 72 +SM_SLOWMACHINE = 73 +SM_MIDEASTENABLED = 74 +SM_MOUSEWHEELPRESENT = 75 +SM_CMETRICS = 76 + +; Predefined cursor identifiers + +IDC_ARROW = 32512 +IDC_IBEAM = 32513 +IDC_WAIT = 32514 +IDC_CROSS = 32515 +IDC_UPARROW = 32516 +IDC_SIZE = 32640 +IDC_ICON = 32641 +IDC_SIZENWSE = 32642 +IDC_SIZENESW = 32643 +IDC_SIZEWE = 32644 +IDC_SIZENS = 32645 +IDC_NO = 32648 +IDC_HAND = 32649 +IDC_APPSTARTING = 32650 +IDC_HELP = 32651 + +; Predefined icon identifiers + +IDI_APPLICATION = 32512 +IDI_HAND = 32513 +IDI_QUESTION = 32514 +IDI_EXCLAMATION = 32515 +IDI_ASTERISK = 32516 +IDI_WINLOGO = 32517 + +; System colors + +COLOR_SCROLLBAR = 0 +COLOR_BACKGROUND = 1 +COLOR_ACTIVECAPTION = 2 +COLOR_INACTIVECAPTION = 3 +COLOR_MENU = 4 +COLOR_WINDOW = 5 +COLOR_WINDOWFRAME = 6 +COLOR_MENUTEXT = 7 +COLOR_WINDOWTEXT = 8 +COLOR_CAPTIONTEXT = 9 +COLOR_ACTIVEBORDER = 10 +COLOR_INACTIVEBORDER = 11 +COLOR_APPWORKSPACE = 12 +COLOR_HIGHLIGHT = 13 +COLOR_HIGHLIGHTTEXT = 14 +COLOR_BTNFACE = 15 +COLOR_BTNSHADOW = 16 +COLOR_GRAYTEXT = 17 +COLOR_BTNTEXT = 18 +COLOR_INACTIVECAPTIONTEXT = 19 +COLOR_BTNHIGHLIGHT = 20 +COLOR_3DDKSHADOW = 21 +COLOR_3DLIGHT = 22 +COLOR_INFOTEXT = 23 +COLOR_INFOBK = 24 +COLOR_HOTLIGHT = 26 +COLOR_GRADIENTACTIVECAPTION = 27 +COLOR_GRADIENTINACTIVECAPTION = 28 + +; Button messages + +BM_GETCHECK = 00F0h +BM_SETCHECK = 00F1h +BM_GETSTATE = 00F2h +BM_SETSTATE = 00F3h +BM_SETSTYLE = 00F4h +BM_CLICK = 00F5h +BM_GETIMAGE = 00F6h +BM_SETIMAGE = 00F7h + +; Button notifications + +BN_CLICKED = 0 +BN_PAINT = 1 +BN_HILITE = 2 +BN_UNHILITE = 3 +BN_DISABLE = 4 +BN_DOUBLECLICKED = 5 +BN_SETFOCUS = 6 +BN_KILLFOCUS = 7 +BN_PUSHED = BN_HILITE +BN_UNPUSHED = BN_UNHILITE +BN_DBLCLK = BN_DOUBLECLICKED + +; Button styles + +BS_PUSHBUTTON = 0000h +BS_DEFPUSHBUTTON = 0001h +BS_CHECKBOX = 0002h +BS_AUTOCHECKBOX = 0003h +BS_RADIOBUTTON = 0004h +BS_3STATE = 0005h +BS_AUTO3STATE = 0006h +BS_GROUPBOX = 0007h +BS_USERBUTTON = 0008h +BS_AUTORADIOBUTTON = 0009h +BS_OWNERDRAW = 000Bh +BS_TEXT = 0000h +BS_LEFTTEXT = 0020h +BS_RIGHTBUTTON = BS_LEFTTEXT +BS_ICON = 0040h +BS_BITMAP = 0080h +BS_LEFT = 0100h +BS_RIGHT = 0200h +BS_CENTER = 0300h +BS_TOP = 0400h +BS_BOTTOM = 0800h +BS_VCENTER = 0C00h +BS_PUSHLIKE = 1000h +BS_MULTILINE = 2000h +BS_NOTIFY = 4000h +BS_FLAT = 8000h + +; Button states + +BST_UNCHECKED = 0 +BST_CHECKED = 1 +BST_INDETERMINATE = 2 +BST_PUSHED = 4 +BST_FOCUS = 8 + +; List box messages + +LB_ADDSTRING = 0180h +LB_INSERTSTRING = 0181h +LB_DELETESTRING = 0182h +LB_SELITEMRANGEEX = 0183h +LB_RESETCONTENT = 0184h +LB_SETSEL = 0185h +LB_SETCURSEL = 0186h +LB_GETSEL = 0187h +LB_GETCURSEL = 0188h +LB_GETTEXT = 0189h +LB_GETTEXTLEN = 018Ah +LB_GETCOUNT = 018Bh +LB_SELECTSTRING = 018Ch +LB_DIR = 018Dh +LB_GETTOPINDEX = 018Eh +LB_FINDSTRING = 018Fh +LB_GETSELCOUNT = 0190h +LB_GETSELITEMS = 0191h +LB_SETTABSTOPS = 0192h +LB_GETHORIZONTALEXTENT = 0193h +LB_SETHORIZONTALEXTENT = 0194h +LB_SETCOLUMNWIDTH = 0195h +LB_ADDFILE = 0196h +LB_SETTOPINDEX = 0197h +LB_GETITEMRECT = 0198h +LB_GETITEMDATA = 0199h +LB_SETITEMDATA = 019Ah +LB_SELITEMRANGE = 019Bh +LB_SETANCHORINDEX = 019Ch +LB_GETANCHORINDEX = 019Dh +LB_SETCARETINDEX = 019Eh +LB_GETCARETINDEX = 019Fh +LB_SETITEMHEIGHT = 01A0h +LB_GETITEMHEIGHT = 01A1h +LB_FINDSTRINGEXACT = 01A2h +LB_SETLOCALE = 01A5h +LB_GETLOCALE = 01A6h +LB_SETCOUNT = 01A7h +LB_INITSTORAGE = 01A8h +LB_ITEMFROMPOINT = 01A9h + +; List box notifications + +LBN_ERRSPACE = -2 +LBN_SELCHANGE = 1 +LBN_DBLCLK = 2 +LBN_SELCANCEL = 3 +LBN_SETFOCUS = 4 +LBN_KILLFOCUS = 5 + +; List box styles + +LBS_NOTIFY = 0001h +LBS_SORT = 0002h +LBS_NOREDRAW = 0004h +LBS_MULTIPLESEL = 0008h +LBS_OWNERDRAWFIXED = 0010h +LBS_OWNERDRAWVARIABLE = 0020h +LBS_HASSTRINGS = 0040h +LBS_USETABSTOPS = 0080h +LBS_NOINTEGRALHEIGHT = 0100h +LBS_MULTICOLUMN = 0200h +LBS_WANTKEYBOARDINPUT = 0400h +LBS_EXTENDEDSEL = 0800h +LBS_DISABLENOSCROLL = 1000h +LBS_NODATA = 2000h +LBS_NOSEL = 4000h +LBS_STANDARD = LBS_NOTIFY or LBS_SORT or WS_VSCROLL or WS_BORDER + +; List box return values + +LB_OKAY = 0 +LB_ERR = -1 +LB_ERRSPACE = -2 + +; Combo box messages + +CB_GETEDITSEL = 0140h +CB_LIMITTEXT = 0141h +CB_SETEDITSEL = 0142h +CB_ADDSTRING = 0143h +CB_DELETESTRING = 0144h +CB_DIR = 0145h +CB_GETCOUNT = 0146h +CB_GETCURSEL = 0147h +CB_GETLBTEXT = 0148h +CB_GETLBTEXTLEN = 0149h +CB_INSERTSTRING = 014Ah +CB_RESETCONTENT = 014Bh +CB_FINDSTRING = 014Ch +CB_SELECTSTRING = 014Dh +CB_SETCURSEL = 014Eh +CB_SHOWDROPDOWN = 014Fh +CB_GETITEMDATA = 0150h +CB_SETITEMDATA = 0151h +CB_GETDROPPEDCONTROLRECT = 0152h +CB_SETITEMHEIGHT = 0153h +CB_GETITEMHEIGHT = 0154h +CB_SETEXTENDEDUI = 0155h +CB_GETEXTENDEDUI = 0156h +CB_GETDROPPEDSTATE = 0157h +CB_FINDSTRINGEXACT = 0158h +CB_SETLOCALE = 0159h +CB_GETLOCALE = 015Ah +CB_GETTOPINDEX = 015Bh +CB_SETTOPINDEX = 015Ch +CB_GETHORIZONTALEXTENT = 015Dh +CB_SETHORIZONTALEXTENT = 015Eh +CB_GETDROPPEDWIDTH = 015Fh +CB_SETDROPPEDWIDTH = 0160h +CB_INITSTORAGE = 0161h + +; Combo box notifications + +CBN_ERRSPACE = -1 +CBN_SELCHANGE = 1 +CBN_DBLCLK = 2 +CBN_SETFOCUS = 3 +CBN_KILLFOCUS = 4 +CBN_EDITCHANGE = 5 +CBN_EDITUPDATE = 6 +CBN_DROPDOWN = 7 +CBN_CLOSEUP = 8 +CBN_SELENDOK = 9 +CBN_SELENDCANCEL = 10 + +; Combo box styles + +CBS_SIMPLE = 0001h +CBS_DROPDOWN = 0002h +CBS_DROPDOWNLIST = 0003h +CBS_OWNERDRAWFIXED = 0010h +CBS_OWNERDRAWVARIABLE = 0020h +CBS_AUTOHSCROLL = 0040h +CBS_OEMCONVERT = 0080h +CBS_SORT = 0100h +CBS_HASSTRINGS = 0200h +CBS_NOINTEGRALHEIGHT = 0400h +CBS_DISABLENOSCROLL = 0800h +CBS_UPPERCASE = 2000h +CBS_LOWERCASE = 4000h + +; Combo box return values + +CB_OKAY = 0 +CB_ERR = -1 +CB_ERRSPACE = -2 + +; Edit control messages + +EM_GETSEL = 00B0h +EM_SETSEL = 00B1h +EM_GETRECT = 00B2h +EM_SETRECT = 00B3h +EM_SETRECTNP = 00B4h +EM_SCROLL = 00B5h +EM_LINESCROLL = 00B6h +EM_SCROLLCARET = 00B7h +EM_GETMODIFY = 00B8h +EM_SETMODIFY = 00B9h +EM_GETLINECOUNT = 00BAh +EM_LINEINDEX = 00BBh +EM_SETHANDLE = 00BCh +EM_GETHANDLE = 00BDh +EM_GETTHUMB = 00BEh +EM_LINELENGTH = 00C1h +EM_REPLACESEL = 00C2h +EM_GETLINE = 00C4h +EM_LIMITTEXT = 00C5h +EM_CANUNDO = 00C6h +EM_UNDO = 00C7h +EM_FMTLINES = 00C8h +EM_LINEFROMCHAR = 00C9h +EM_SETTABSTOPS = 00CBh +EM_SETPASSWORDCHAR = 00CCh +EM_EMPTYUNDOBUFFER = 00CDh +EM_GETFIRSTVISIBLELINE = 00CEh +EM_SETREADONLY = 00CFh +EM_SETWORDBREAKPROC = 00D0h +EM_GETWORDBREAKPROC = 00D1h +EM_GETPASSWORDCHAR = 00D2h +EM_SETMARGINS = 00D3h +EM_GETMARGINS = 00D4h +EM_SETLIMITTEXT = EM_LIMITTEXT +EM_GETLIMITTEXT = 00D5h +EM_POSFROMCHAR = 00D6h +EM_CHARFROMPOS = 00D7h + +; Edit control EM_SETMARGIN parameters + +EC_LEFTMARGIN = 1 +EC_RIGHTMARGIN = 2 +EC_USEFONTINFO = 0FFFFh + +; Edit control notifications + +EN_SETFOCUS = 0100h +EN_KILLFOCUS = 0200h +EN_CHANGE = 0300h +EN_UPDATE = 0400h +EN_ERRSPACE = 0500h +EN_MAXTEXT = 0501h +EN_HSCROLL = 0601h +EN_VSCROLL = 0602h + +; Edit control styles + +ES_LEFT = 0000h +ES_CENTER = 0001h +ES_RIGHT = 0002h +ES_MULTILINE = 0004h +ES_UPPERCASE = 0008h +ES_LOWERCASE = 0010h +ES_PASSWORD = 0020h +ES_AUTOVSCROLL = 0040h +ES_AUTOHSCROLL = 0080h +ES_NOHIDESEL = 0100h +ES_OEMCONVERT = 0400h +ES_READONLY = 0800h +ES_WANTRETURN = 1000h +ES_NUMBER = 2000h + +; Static window messages + +STM_SETICON = 0170h +STM_GETICON = 0171h +STM_SETIMAGE = 0172h +STM_GETIMAGE = 0173h + +; Static window notifications + +STN_CLICKED = 0 +STN_DBLCLK = 1 +STN_ENABLE = 2 +STN_DISABLE = 3 + +; Static window styles + +SS_LEFT = 0000h +SS_CENTER = 0001h +SS_RIGHT = 0002h +SS_ICON = 0003h +SS_BLACKRECT = 0004h +SS_GRAYRECT = 0005h +SS_WHITERECT = 0006h +SS_BLACKFRAME = 0007h +SS_GRAYFRAME = 0008h +SS_WHITEFRAME = 0009h +SS_USERITEM = 000Ah +SS_SIMPLE = 000Bh +SS_LEFTNOWORDWRAP = 000Ch +SS_BITMAP = 000Eh +SS_OWNERDRAW = 000Dh +SS_ENHMETAFILE = 000Fh +SS_ETCHEDHORZ = 0010h +SS_ETCHEDVERT = 0011h +SS_ETCHEDFRAME = 0012h +SS_TYPEMASK = 001Fh +SS_NOPREFIX = 0080h +SS_NOTIFY = 0100h +SS_CENTERIMAGE = 0200h +SS_RIGHTJUST = 0400h +SS_REALSIZEIMAGE = 0800h +SS_SUNKEN = 1000h + +; Scroll bar constants + +SB_HORZ = 0 +SB_VERT = 1 +SB_CTL = 2 +SB_BOTH = 3 + +; Scroll bar messages + +SBM_SETPOS = 00E0h +SBM_GETPOS = 00E1h +SBM_SETRANGE = 00E2h +SBM_SETRANGEREDRAW = 00E6h +SBM_GETRANGE = 00E3h +SBM_ENABLE_ARROWS = 00E4h +SBM_SETSCROLLINFO = 00E9h +SBM_GETSCROLLINFO = 00EAh + +; Scroll bar commands + +SB_LINEUP = 0 +SB_LINELEFT = 0 +SB_LINEDOWN = 1 +SB_LINERIGHT = 1 +SB_PAGEUP = 2 +SB_PAGELEFT = 2 +SB_PAGEDOWN = 3 +SB_PAGERIGHT = 3 +SB_THUMBPOSITION = 4 +SB_THUMBTRACK = 5 +SB_TOP = 6 +SB_LEFT = 6 +SB_BOTTOM = 7 +SB_RIGHT = 7 +SB_ENDSCROLL = 8 + +; Scroll bar styles + +SBS_HORZ = 0000h +SBS_VERT = 0001h +SBS_TOPALIGN = 0002h +SBS_LEFTALIGN = 0002h +SBS_BOTTOMALIGN = 0004h +SBS_RIGHTALIGN = 0004h +SBS_SIZEBOXTOPLEFTALIGN = 0002h +SBS_SIZEBOXBOTTOMRIGHTALIGN = 0004h +SBS_SIZEBOX = 0008h +SBS_SIZEGRIP = 0010h + +; Scroll bar info flags + +SIF_RANGE = 0001h +SIF_PAGE = 0002h +SIF_POS = 0004h +SIF_DISABLENOSCROLL = 0008h +SIF_TRACKPOS = 0010h +SIF_ALL = SIF_RANGE or SIF_PAGE or SIF_POS or SIF_TRACKPOS + +; Dialog styles + +DS_ABSALIGN = 0001h +DS_SYSMODAL = 0002h +DS_3DLOOK = 0004h +DS_FIXEDSYS = 0008h +DS_NOFAILCREATE = 0010h +DS_LOCALEDIT = 0020h +DS_SETFONT = 0040h +DS_MODALFRAME = 0080h +DS_NOIDLEMSG = 0100h +DS_SETFOREGROUND = 0200h +DS_CONTROL = 0400h +DS_CENTER = 0800h +DS_CENTERMOUSE = 1000h +DS_CONTEXTHELP = 2000h + +; Dialog codes + +DLGC_WANTARROWS = 0001h +DLGC_WANTTAB = 0002h +DLGC_WANTALLKEYS = 0004h +DLGC_WANTMESSAGE = 0004h +DLGC_HASSETSEL = 0008h +DLGC_DEFPUSHBUTTON = 0010h +DLGC_UNDEFPUSHBUTTON = 0020h +DLGC_RADIOBUTTON = 0040h +DLGC_WANTCHARS = 0080h +DLGC_STATIC = 0100h +DLGC_BUTTON = 2000h + +; Menu flags + +MF_INSERT = 0000h +MF_CHANGE = 0080h +MF_APPEND = 0100h +MF_DELETE = 0200h +MF_REMOVE = 1000h +MF_BYCOMMAND = 0000h +MF_BYPOSITION = 0400h +MF_SEPARATOR = 0800h +MF_UNCHECKED = 0000h +MF_ENABLED = 0000h +MF_GRAYED = 0001h +MF_DISABLED = 0002h +MF_CHECKED = 0008h +MF_USECHECKBITMAPS = 0200h +MF_STRING = 0000h +MF_BITMAP = 0004h +MF_OWNERDRAW = 0100h +MF_POPUP = 0010h +MF_MENUBARBREAK = 0020h +MF_MENUBREAK = 0040h +MF_UNHILITE = 0000h +MF_HILITE = 0080h +MF_DEFAULT = 1000h +MF_SYSMENU = 2000h +MF_HELP = 4000h +MF_RIGHTJUSTIFY = 4000h +MF_MOUSESELECT = 8000h +MF_END = 0080h +MFT_STRING = MF_STRING +MFT_BITMAP = MF_BITMAP +MFT_MENUBARBREAK = MF_MENUBARBREAK +MFT_MENUBREAK = MF_MENUBREAK +MFT_OWNERDRAW = MF_OWNERDRAW +MFT_RADIOCHECK = 0200h +MFT_SEPARATOR = MF_SEPARATOR +MFT_RIGHTORDER = 2000h +MFT_RIGHTJUSTIFY = MF_RIGHTJUSTIFY +MFS_GRAYED = 0003h +MFS_DISABLED = MFS_GRAYED +MFS_CHECKED = MF_CHECKED +MFS_HILITE = MF_HILITE +MFS_ENABLED = MF_ENABLED +MFS_UNCHECKED = MF_UNCHECKED +MFS_UNHILITE = MF_UNHILITE +MFS_DEFAULT = MF_DEFAULT +MFR_POPUP = 0001h +MFR_END = MF_END + +; System menu command values + +SC_SIZE = 61440 +SC_MOVE = 61456 +SC_MINIMIZE = 61472 +SC_MAXIMIZE = 61488 +SC_NEXTWINDOW = 61504 +SC_PREVWINDOW = 61520 +SC_CLOSE = 61536 +SC_VSCROLL = 61552 +SC_HSCROLL = 61568 +SC_MOUSEMENU = 61584 +SC_KEYMENU = 61696 +SC_ARRANGE = 61712 +SC_RESTORE = 61728 +SC_TASKLIST = 61744 +SC_SCREENSAVE = 61760 +SC_HOTKEY = 61776 +SC_DEFAULT = 61792 +SC_MONITORPOWER = 61808 +SC_CONTEXTHELP = 61824 +SC_SEPARATOR = 61455 + +; Border types + +BDR_RAISEDOUTER = 01h +BDR_SUNKENOUTER = 02h +BDR_RAISEDINNER = 04h +BDR_SUNKENINNER = 08h +BDR_OUTER = 03h +BDR_INNER = 0Ch +BDR_RAISED = 05h +BDR_SUNKEN = 0Ah +EDGE_RAISED = BDR_RAISEDOUTER or BDR_RAISEDINNER +EDGE_SUNKEN = BDR_SUNKENOUTER or BDR_SUNKENINNER +EDGE_ETCHED = BDR_SUNKENOUTER or BDR_RAISEDINNER +EDGE_BUMP = BDR_RAISEDOUTER or BDR_SUNKENINNER + +; Border flags + +BF_LEFT = 0001h +BF_TOP = 0002h +BF_RIGHT = 0004h +BF_BOTTOM = 0008h +BF_TOPLEFT = BF_TOP or BF_LEFT +BF_TOPRIGHT = BF_TOP or BF_RIGHT +BF_BOTTOMLEFT = BF_BOTTOM or BF_LEFT +BF_BOTTOMRIGHT = BF_BOTTOM or BF_RIGHT +BF_RECT = BF_LEFT or BF_TOP or BF_RIGHT or BF_BOTTOM +BF_DIAGONAL = 0010h +BF_DIAGONAL_ENDTOPRIGHT = BF_DIAGONAL or BF_TOP or BF_RIGHT +BF_DIAGONAL_ENDTOPLEFT = BF_DIAGONAL or BF_TOP or BF_LEFT +BF_DIAGONAL_ENDBOTTOMLEFT = BF_DIAGONAL or BF_BOTTOM or BF_LEFT +BF_DIAGONAL_ENDBOTTOMRIGHT = BF_DIAGONAL or BF_BOTTOM or BF_RIGHT +BF_MIDDLE = 0800h +BF_SOFT = 1000h +BF_ADJUST = 2000h +BF_FLAT = 4000h +BF_MONO = 8000h + +; Frame control types + +DFC_CAPTION = 1 +DFC_MENU = 2 +DFC_SCROLL = 3 +DFC_BUTTON = 4 +DFC_POPUPMENU = 5 + +; Frame control states + +DFCS_CAPTIONCLOSE = 0000h +DFCS_CAPTIONMIN = 0001h +DFCS_CAPTIONMAX = 0002h +DFCS_CAPTIONRESTORE = 0003h +DFCS_CAPTIONHELP = 0004h +DFCS_MENUARROW = 0000h +DFCS_MENUCHECK = 0001h +DFCS_MENUBULLET = 0002h +DFCS_MENUARROWRIGHT = 0004h +DFCS_SCROLLUP = 0000h +DFCS_SCROLLDOWN = 0001h +DFCS_SCROLLLEFT = 0002h +DFCS_SCROLLRIGHT = 0003h +DFCS_SCROLLCOMBOBOX = 0005h +DFCS_SCROLLSIZEGRIP = 0008h +DFCS_SCROLLSIZEGRIPRIGHT = 0010h +DFCS_BUTTONCHECK = 0000h +DFCS_BUTTONRADIOIMAGE = 0001h +DFCS_BUTTONRADIOMASK = 0002h +DFCS_BUTTONRADIO = 0004h +DFCS_BUTTON3STATE = 0008h +DFCS_BUTTONPUSH = 0010h +DFCS_INACTIVE = 0100h +DFCS_PUSHED = 0200h +DFCS_CHECKED = 0400h +DFCS_TRANSPARENT = 0800h +DFCS_HOT = 1000h +DFCS_ADJUSTRECT = 2000h +DFCS_FLAT = 4000h +DFCS_MONO = 8000h + +; DrawCaption flags + +DC_ACTIVE = 01h +DC_SMALLCAP = 02h +DC_ICON = 04h +DC_TEXT = 08h +DC_INBUTTON = 10h + +; DrawIconEx options + +DI_MASK = 1 +DI_IMAGE = 2 +DI_NORMAL = 3 +DI_COMPAT = 4 +DI_DEFAULTSIZE = 8 + +; DrawText parameters + +DT_TOP = 00000h +DT_LEFT = 00000h +DT_CENTER = 00001h +DT_RIGHT = 00002h +DT_VCENTER = 00004h +DT_BOTTOM = 00008h +DT_WORDBREAK = 00010h +DT_SINGLELINE = 00020h +DT_EXPANDTABS = 00040h +DT_TABSTOP = 00080h +DT_NOCLIP = 00100h +DT_EXTERNALLEADING = 00200h +DT_CALCRECT = 00400h +DT_NOPREFIX = 00800h +DT_INTERNAL = 01000h +DT_EDITCONTROL = 02000h +DT_PATH_ELLIPSIS = 04000h +DT_END_ELLIPSIS = 08000h +DT_MODIFYSTRING = 10000h +DT_RTLREADING = 20000h +DT_WORD_ELLIPSIS = 40000h + +; GetDCEx flags + +DCX_WINDOW = 000001h +DCX_CACHE = 000002h +DCX_NORESETATTRS = 000004h +DCX_CLIPCHILDREN = 000008h +DCX_CLIPSIBLINGS = 000010h +DCX_PARENTCLIP = 000020h +DCX_EXCLUDERGN = 000040h +DCX_INTERSECTRGN = 000080h +DCX_EXCLUDEUPDATE = 000100h +DCX_INTERSECTUPDATE = 000200h +DCX_LOCKWINDOWUPDATE = 000400h +DCX_VALIDATE = 200000h + +; SetWindowsHook codes + +WH_MSGFILTER = -1 +WH_JOURNALRECORD = 0 +WH_JOURNALPLAYBACK = 1 +WH_KEYBOARD = 2 +WH_GETMESSAGE = 3 +WH_CALLWNDPROC = 4 +WH_CBT = 5 +WH_SYSMSGFILTER = 6 +WH_MOUSE = 7 +WH_HARDWARE = 8 +WH_DEBUG = 9 +WH_SHELL = 10 +WH_FOREGROUNDIDLE = 11 +WH_CALLWNDPROCRET = 12 +WH_KEYBOARD_LL = 13 +WH_MOUSE_LL = 14 + +; Hook codes + +HC_ACTION = 0 +HC_GETNEXT = 1 +HC_SKIP = 2 +HC_NOREMOVE = 3 +HC_SYSMODALON = 4 +HC_SYSMODALOFF = 5 + +; CBT hook codes + +HCBT_MOVESIZE = 0 +HCBT_MINMAX = 1 +HCBT_QS = 2 +HCBT_CREATEWND = 3 +HCBT_DESTROYWND = 4 +HCBT_ACTIVATE = 5 +HCBT_CLICKSKIPPED = 6 +HCBT_KEYSKIPPED = 7 +HCBT_SYSCOMMAND = 8 +HCBT_SETFOCUS = 9 + +; ExitWindowsEx flags + +EWX_LOGOFF = 0 +EWX_SHUTDOWN = 1 +EWX_REBOOT = 2 +EWX_FORCE = 4 +EWX_POWEROFF = 8 + +; WinHelp commands + +HELP_CONTEXT = 001h +HELP_QUIT = 002h +HELP_INDEX = 003h +HELP_CONTENTS = 003h +HELP_HELPONHELP = 004h +HELP_SETINDEX = 005h +HELP_SETCONTENTS = 005h +HELP_CONTEXTPOPUP = 008h +HELP_FORCEFILE = 009h +HELP_CONTEXTMENU = 00Ah +HELP_FINDER = 00Bh +HELP_WM_HELP = 00Ch +HELP_SETPOPUP_POS = 00Dh +HELP_KEY = 101h +HELP_COMMAND = 102h +HELP_PARTIALKEY = 105h +HELP_MULTIKEY = 201h +HELP_SETWINPOS = 203h + +; keybd_event flags + +KEYEVENTF_EXTENDEDKEY = 1h +KEYEVENTF_KEYUP = 2h + +; mouse_event flags + +MOUSEEVENTF_MOVE = 0001h +MOUSEEVENTF_LEFTDOWN = 0002h +MOUSEEVENTF_LEFTUP = 0004h +MOUSEEVENTF_RIGHTDOWN = 0008h +MOUSEEVENTF_RIGHTUP = 0010h +MOUSEEVENTF_MIDDLEDOWN = 0020h +MOUSEEVENTF_MIDDLEUP = 0040h +MOUSEEVENTF_WHEEL = 0800h +MOUSEEVENTF_ABSOLUTE = 8000h + +; TrackPopupMenu flags + +TPM_LEFTBUTTON = 0000h +TPM_RIGHTBUTTON = 0002h +TPM_LEFTALIGN = 0000h +TPM_CENTERALIGN = 0004h +TPM_RIGHTALIGN = 0008h +TPM_TOPALIGN = 0000h +TPM_VCENTERALIGN = 0010h +TPM_BOTTOMALIGN = 0020h +TPM_HORIZONTAL = 0000h +TPM_VERTICAL = 0040h +TPM_NONOTIFY = 0080h +TPM_RETURNCMD = 0100h +TPM_RECURSE = 0001h +TPM_HORPOSANIMATION = 0400h +TPM_HORNEGANIMATION = 0800h +TPM_VERPOSANIMATION = 1000h +TPM_VERNEGANIMATION = 2000h +TPM_NOANIMATION = 4000h +TPM_LAYOUTRTL = 8000h + +; Menu item info mask values + +MIIM_STATE = 001h +MIIM_ID = 002h +MIIM_SUBMENU = 004h +MIIM_CHECKMARKS = 008h +MIIM_TYPE = 010h +MIIM_DATA = 020h +MIIM_STRING = 040h +MIIM_BITMAP = 080h +MIIM_FTYPE = 100h + +; DRAWITEMSTRUCT control types + +ODT_MENU = 1 +ODT_LISTBOX = 2 +ODT_COMBOBOX = 3 +ODT_BUTTON = 4 +ODT_STATIC = 5 + +; DRAWITEMSTRUCT actions + +ODA_DRAWENTIRE = 1 +ODA_SELECT = 2 +ODA_FOCUS = 4 + +; DRAWITEMSTRUCT states + +ODS_SELECTED = 0001h +ODS_GRAYED = 0002h +ODS_DISABLED = 0004h +ODS_CHECKED = 0008h +ODS_FOCUS = 0010h +ODS_DEFAULT = 0020h +ODS_COMBOBOXEDIT = 1000h +ODS_HOTLIGHT = 0040h +ODS_INACTIVE = 0080h + +; WINDOWPLACEMENT flags + +WPF_SETMINPOSITION = 1 +WPF_RESTORETOMAXIMIZED = 2 + +; Layered window attributes + +LWA_COLORKEY = 1 +LWA_ALPHA = 2 + +; UpdateLayeredWindow flags + +ULW_COLORKEY = 1 +ULW_ALPHA = 2 +ULW_OPAQUE = 4 + +; SystemParametersInfo parameters + +SPI_GETACCESSTIMEOUT = 60 +SPI_GETANIMATION = 72 +SPI_GETBEEP = 1 +SPI_GETBORDER = 5 +SPI_GETDEFAULTINPUTLANG = 89 +SPI_GETDRAGFULLWINDOWS = 38 +SPI_GETFASTTASKSWITCH = 35 +SPI_GETFILTERKEYS = 50 +SPI_GETFONTSMOOTHING = 74 +SPI_GETGRIDGRANULARITY = 18 +SPI_GETHIGHCONTRAST = 66 +SPI_GETICONMETRICS = 45 +SPI_GETICONTITLELOGFONT = 31 +SPI_GETICONTITLEWRAP = 25 +SPI_GETKEYBOARDDELAY = 22 +SPI_GETKEYBOARDPREF = 68 +SPI_GETKEYBOARDSPEED = 10 +SPI_GETLOWPOWERACTIVE = 83 +SPI_GETLOWPOWERTIMEOUT = 79 +SPI_GETMENUDROPALIGNMENT = 27 +SPI_GETMINIMIZEDMETRICS = 43 +SPI_GETMOUSE = 3 +SPI_GETMOUSEKEYS = 54 +SPI_GETMOUSETRAILS = 94 +SPI_GETNONCLIENTMETRICS = 41 +SPI_GETPOWEROFFACTIVE = 84 +SPI_GETPOWEROFFTIMEOUT = 80 +SPI_GETSCREENREADER = 70 +SPI_GETSCREENSAVEACTIVE = 16 +SPI_GETSCREENSAVETIMEOUT = 14 +SPI_GETSERIALKEYS = 62 +SPI_GETSHOWSOUNDS = 56 +SPI_GETSOUNDSENTRY = 64 +SPI_GETSTICKYKEYS = 58 +SPI_GETTOGGLEKEYS = 52 +SPI_GETWINDOWSEXTENSION = 92 +SPI_GETWORKAREA = 48 +SPI_ICONHORIZONTALSPACING = 13 +SPI_ICONVERTICALSPACING = 24 +SPI_LANGDRIVER = 12 +SPI_SCREENSAVERRUNNING = 97 +SPI_SETACCESSTIMEOUT = 61 +SPI_SETANIMATION = 73 +SPI_SETBEEP = 2 +SPI_SETBORDER = 6 +SPI_SETDEFAULTINPUTLANG = 90 +SPI_SETDESKPATTERN = 21 +SPI_SETDESKWALLPAPER = 20 +SPI_SETDOUBLECLICKTIME = 32 +SPI_SETDOUBLECLKHEIGHT = 30 +SPI_SETDOUBLECLKWIDTH = 29 +SPI_SETDRAGFULLWINDOWS = 37 +SPI_SETDRAGHEIGHT = 77 +SPI_SETDRAGWIDTH = 76 +SPI_SETFASTTASKSWITCH = 36 +SPI_SETFILTERKEYS = 51 +SPI_SETFONTSMOOTHING = 75 +SPI_SETGRIDGRANULARITY = 19 +SPI_SETHANDHELD = 78 +SPI_SETHIGHCONTRAST = 67 +SPI_SETICONMETRICS = 46 +SPI_SETICONTITLELOGFONT = 34 +SPI_SETICONTITLEWRAP = 26 +SPI_SETKEYBOARDDELAY = 23 +SPI_SETKEYBOARDPREF = 69 +SPI_SETKEYBOARDSPEED = 11 +SPI_SETLANGTOGGLE = 91 +SPI_SETLOWPOWERACTIVE = 85 +SPI_SETLOWPOWERTIMEOUT = 81 +SPI_SETMENUDROPALIGNMENT = 28 +SPI_SETMINIMIZEDMETRICS = 44 +SPI_SETMOUSE = 4 +SPI_SETMOUSEBUTTONSWAP = 33 +SPI_SETMOUSEKEYS = 55 +SPI_SETMOUSETRAILS = 93 +SPI_SETNONCLIENTMETRICS = 42 +SPI_SETPENWINDOWS = 49 +SPI_SETPOWEROFFACTIVE = 86 +SPI_SETPOWEROFFTIMEOUT = 82 +SPI_SETSCREENREADER = 71 +SPI_SETSCREENSAVEACTIVE = 17 +SPI_SETSCREENSAVERRUNNING = 97 +SPI_SETSCREENSAVETIMEOUT = 15 +SPI_SETSERIALKEYS = 63 +SPI_SETSHOWSOUNDS = 57 +SPI_SETSOUNDSENTRY = 65 +SPI_SETSTICKYKEYS = 59 +SPI_SETTOGGLEKEYS = 53 +SPI_SETWORKAREA = 47 + +; SystemParametersInfo flags + +SPIF_UPDATEINIFILE = 1 +SPIF_SENDWININICHANGE = 2 + +; Gesture Information Flags + +GF_BEGIN = 1 +GF_INERTIA = 2 +GF_END = 4 + +; Gesture IDs + +GID_BEGIN = 1 +GID_END = 2 +GID_ZOOM = 3 +GID_PAN = 4 +GID_ROTATE = 5 +GID_TWOFINGERTAP = 6 +GID_PRESSANDTAP = 7 +GID_ROLLOVER = GID_PRESSANDTAP + +; Zoom Gesture Confiration Flags + +GC_ZOOM = 0x00000001 + +; Pan Gesture Configuration Flags + +GC_PAN = 0x00000001 +GC_PAN_WITH_SINGLE_FINGER_VERTICALLY = 0x00000002 +GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY = 0x00000004 +GC_PAN_WITH_GUTTER = 0x00000008 +GC_PAN_WITH_INERTIA = 0x00000010 + +; Rotate Gesture Configuration Flags + +GC_ROTATE = 0x00000001 + +; Two finger tap configuration flags + +GC_TWOFINGERTAP = 0x00000001 + +; Press and tap Configuration Flags + +GC_PRESSANDTAP = 0x00000001 +GC_ROLLOVER = GC_PRESSANDTAP diff --git a/toolchain/fasmw17332/INCLUDE/EQUATES/WSOCK32.INC b/toolchain/fasmw17332/INCLUDE/EQUATES/WSOCK32.INC new file mode 100644 index 0000000..4b16b8e --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/EQUATES/WSOCK32.INC @@ -0,0 +1,124 @@ + +; WSOCK32.DLL structures and constants + +struct WSADATA + wVersion dw ? + wHighVersion dw ? + szDescription db 256+1 dup (?) + szSystemStatus db 128+1 dup (?) + iMaxSockets dw ? + iMaxUdpDg dw ? + _padding_ db 2 dup (?) + lpVendorInfo dd ? +ends + +struct hostent + h_name dd ? + h_aliases dd ? + h_addrtype dw ? + h_length dw ? + h_addr_list dd ? +ends + +struct sockaddr_in + sin_family dw ? + sin_port dw ? + sin_addr dd ? + sin_zero db 8 dup (?) +ends + +struct sockaddr + sa_family dw ? + sa_data db 14 dup (?) +ends + +; Socket types + +SOCK_STREAM = 1 +SOCK_DGRAM = 2 +SOCK_RAW = 3 +SOCK_RDM = 4 +SOCK_SEQPACKET = 5 + +; Address formats + +AF_UNSPEC = 0 +AF_UNIX = 1 +AF_INET = 2 +AF_IMPLINK = 3 +AF_PUP = 4 +AF_CHAOS = 5 +AF_NS = 6 +AF_IPX = 6 +AF_ISO = 7 +AF_OSI = AF_ISO +AF_ECMA = 8 +AF_DATAKIT = 9 +AF_CCITT = 10 +AF_SNA = 11 +AF_DECnet = 12 +AF_DLI = 13 +AF_LAT = 14 +AF_HYLINK = 15 +AF_APPLETALK = 16 +AF_NETBIOS = 17 + +; Protocol formats + +PF_UNSPEC = 0 +PF_UNIX = 1 +PF_INET = 2 +PF_IMPLINK = 3 +PF_PUP = 4 +PF_CHAOS = 5 +PF_NS = 6 +PF_IPX = 6 +PF_ISO = 7 +PF_OSI = PF_ISO +PF_ECMA = 8 +PF_DATAKIT = 9 +PF_CCITT = 10 +PF_SNA = 11 +PF_DECnet = 12 +PF_DLI = 13 +PF_LAT = 14 +PF_HYLINK = 15 +PF_APPLETALK = 16 +PF_NETBIOS = 17 + +; IP Ports + +IPPORT_ECHO = 7 +IPPORT_DISCARD = 9 +IPPORT_SYSTAT = 11 +IPPORT_DAYTIME = 13 +IPPORT_NETSTAT = 15 +IPPORT_FTP = 21 +IPPORT_TELNET = 23 +IPPORT_SMTP = 25 +IPPORT_TIMESERVER = 37 +IPPORT_NAMESERVER = 42 +IPPORT_WHOIS = 43 +IPPORT_MTP = 57 +IPPORT_TFTP = 69 +IPPORT_RJE = 77 +IPPORT_FINGER = 79 +IPPORT_TTYLINK = 87 +IPPORT_SUPDUP = 95 +IPPORT_EXECSERVER = 512 +IPPORT_LOGINSERVER = 513 +IPPORT_CMDSERVER = 514 +IPPORT_EFSSERVER = 520 +IPPORT_BIFFUDP = 512 +IPPORT_WHOSERVER = 513 +IPPORT_ROUTESERVER = 520 +IPPORT_RESERVED = 1024 + +; Notifications + +FD_READ = 01h +FD_WRITE = 02h +FD_OOB = 04h +FD_ACCEPT = 08h +FD_CONNECT = 10h +FD_CLOSE = 20h diff --git a/toolchain/fasmw17332/INCLUDE/MACRO/COM32.INC b/toolchain/fasmw17332/INCLUDE/MACRO/COM32.INC new file mode 100644 index 0000000..55a26c6 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/MACRO/COM32.INC @@ -0,0 +1,53 @@ + +; Macroinstructions for interfacing the COM (Component Object Model) classes + +macro cominvk object,proc,[arg] + { common + if ~ arg eq + reverse + pushd arg + common + end if + assert defined object#.com.object ; must be a COM object + mov eax,[object] + push eax + mov eax,[eax] + call [eax+object#.#proc] } + +macro comcall handle,interface,proc,[arg] + { common + if ~ arg eq + reverse + pushd arg + common + end if + assert defined interface#.com.interface ; must be a COM interface + if handle eqtype eax | handle eqtype 0 + push handle + local ..handle + label ..handle at handle + mov eax,[..handle] + else + mov eax,handle + push eax + mov eax,[eax] + end if + call [eax+interface#.#proc] } + +macro interface name,[proc] + { common + struc name \{ + match , @struct \\{ define field@struct .,name, \\} + match no, @struct \\{ . dd ? + virtual at 0 + forward + .#proc dd ? + common + .\#\\.com.object = name#.com.interface + end virtual \\} \} + virtual at 0 + forward + name#.#proc dd ? + common + name#.com.interface = $ shr 2 + end virtual } diff --git a/toolchain/fasmw17332/INCLUDE/MACRO/COM64.INC b/toolchain/fasmw17332/INCLUDE/MACRO/COM64.INC new file mode 100644 index 0000000..35ca4af --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/MACRO/COM64.INC @@ -0,0 +1,39 @@ + +; Macroinstructions for interfacing the COM (Component Object Model) classes + +macro cominvk object,proc,[arg] + { common + assert defined object#.com.object ; must be a COM object + macro call dummy + \{ mov rax,[rcx] + call [rax+object#.#proc] \} + fastcall ,[object],arg + purge call } + +macro comcall handle,interface,proc,[arg] + { common + assert defined interface#.com.interface ; must be a COM interface + macro call dummy + \{ mov rax,[rcx] + call [rax+interface#.#proc] \} + fastcall ,handle,arg + purge call } + +macro interface name,[proc] + { common + struc name \{ + match , @struct \\{ define field@struct .,name, \\} + match no, @struct \\{ . dq ? + virtual at 0 + forward + .#proc dq ? + common + .\#\\.com.object = name#.com.interface + end virtual \\} \} + virtual at 0 + forward + name#.#proc dq ? + common + name#.com.interface = $ shr 3 + end virtual } + diff --git a/toolchain/fasmw17332/INCLUDE/MACRO/EXPORT.INC b/toolchain/fasmw17332/INCLUDE/MACRO/EXPORT.INC new file mode 100644 index 0000000..c0fa1c1 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/MACRO/EXPORT.INC @@ -0,0 +1,66 @@ + +; Macroinstruction for making export section + +macro export dllname,[label,string] + { common + local module,addresses,names,ordinal,count + count = 0 + forward + count = count+1 + common + dd 0,0,0,RVA module,1 + dd count,count,RVA addresses,RVA names,RVA ordinal + addresses: + forward + dd RVA label + common + names: + forward + local name + dd RVA name + common + ordinal: count = 0 + forward + dw count + count = count+1 + common + module db dllname,0 + forward + name db string,0 + common + local x,y,z,str1,str2,v1,v2 + x = count shr 1 + while x > 0 + y = x + while y < count + z = y + while z-x >= 0 + load v1 dword from names+z*4 + str1=($-RVA $)+v1 + load v2 dword from names+(z-x)*4 + str2=($-RVA $)+v2 + while v1 > 0 + load v1 from str1+%-1 + load v2 from str2+%-1 + if v1 <> v2 + break + end if + end while + if v1 +lt equ < + +macro PARSECOND parsed,cond +{ + define parsed + define neg@cond + define status@cond + define nest@cond + irps symb,cond + \{ + define symb@cond symb + match >,symb + \\{ + define symb@cond gt + \\} + match <,symb + \\{ + define symb@cond lt + \\} + current@cond equ status@cond + match ,current@cond + \\{ + match ~,symb + \\\{ + neg@cond equ neg@cond ~ + match ~~,neg@cond + \\\\{ + define neg@cond + \\\\} + define symb@cond + \\\} + match (,symb + \\\{ + parsed equ parsed neg@cond,< + define nest@cond + + define symb@cond + define neg@cond + \\\} + match any,symb@cond + \\\{ + parsed equ parsed neg@cond,symb@cond + define status@cond + + \\\} + \\} + match status,current@cond + \\{ + match &,symb + \\\{ + parsed equ parsed,&, + define status@cond + define symb@cond + define neg@cond + \\\} + match |,symb + \\\{ + parsed equ parsed,|, + define status@cond + define symb@cond + define neg@cond + \\\} + match (,symb + \\\{ + define nest@cond ( + \\\} + match ),symb + \\\{ + match +,nest@cond + \\\\{ + parsed equ parsed> + define symb@cond + \\\\} + restore nest@cond + \\\} + match any,symb@cond + \\\{ + parsed equ parsed symb@cond + \\\} + \\} + \} +} + +macro define_JNCONDEXPR +{ + macro JNCONDEXPR elabel,[mod,cond,op] + \{ + \common + \local ..t,..f + define t@cond ..t + define f@cond ..f + \forward + match ,op + \\{ + match ,mod \\\{ JNCONDEL elabel, \\\} + match ~,mod \\\{ JCONDEL elabel, \\\} + \\} + match &:flabel:tlabel, op:f@cond:t@cond + \\{ + match ,mod \\\{ JNCONDEL flabel, \\\} + match ~,mod \\\{ JCONDEL flabel, \\\} + tlabel: + \\local ..tnew + restore t@cond + define t@cond ..tnew + \\} + match |:flabel:tlabel, op:f@cond:t@cond + \\{ + match ,mod \\\{ JCONDEL tlabel, \\\} + match ~,mod \\\{ JNCONDEL tlabel, \\\} + flabel: + \\local ..fnew + restore f@cond + define f@cond ..fnew + \\} + \common + label f@cond at elabel + t@cond: + restore t@cond + restore f@cond + \} +} + +macro define_JCONDEXPR +{ + macro JCONDEXPR elabel,[mod,cond,op] + \{ + \common + \local ..t,..f + define t@cond ..t + define f@cond ..f + \forward + match ,op + \\{ + match ,mod \\\{ JCONDEL elabel, \\\} + match ~,mod \\\{ JNCONDEL elabel, \\\} + \\} + match |:flabel:tlabel, op:f@cond:t@cond + \\{ + match ,mod \\\{ JCONDEL flabel, \\\} + match ~,mod \\\{ JNCONDEL flabel, \\\} + tlabel: + \\local ..tnew + restore t@cond + define t@cond ..tnew + \\} + match &:flabel:tlabel, op:f@cond:t@cond + \\{ + match ,mod \\\{ JNCONDEL tlabel, \\\} + match ~,mod \\\{ JCONDEL tlabel, \\\} + flabel: + \\local ..fnew + restore f@cond + define f@cond ..fnew + \\} + \common + label f@cond at elabel + t@cond: + restore t@cond + restore f@cond + \} +} + +macro define_JNCONDEL +{ + macro JNCONDEL label,cond + \{ + \local COND + match car=,cdr,:cond + \\{ + define_JNCONDEXPR + define_JCONDEXPR + define_JCONDEL + define_JNCONDEL + JNCONDEXPR label,cond + purge JNCONDEXPR,JCONDEXPR,JCONDEL,JNCONDEL + define COND + \\} + match c,cond ; replace gt and lt + \\{ + match =COND =signed v1>==v2, COND c + \\\{ + cmp v1,v2 + jl label + define COND + \\\} + match =COND =signed v1<==v2, COND c + \\\{ + cmp v1,v2 + jg label + define COND + \\\} + match =COND v1>==v2, COND c + \\\{ + cmp v1,v2 + jb label + define COND + \\\} + match =COND v1<==v2, COND c + \\\{ + cmp v1,v2 + ja label + define COND + \\\} + match =COND v1==v2, COND c + \\\{ + cmp v1,v2 + jne label + define COND + \\\} + match =COND v1<>v2, COND c + \\\{ + cmp v1,v2 + je label + define COND + \\\} + match =COND =signed v1>v2, COND c + \\\{ + cmp v1,v2 + jle label + define COND + \\\} + match =COND =signed v1v2, COND c + \\\{ + cmp v1,v2 + jbe label + define COND + \\\} + match =COND v1==v2, COND c + \\\{ + cmp v1,v2 + jge label + define COND + \\\} + match =COND =signed v1<==v2, COND c + \\\{ + cmp v1,v2 + jle label + define COND + \\\} + match =COND v1>==v2, COND c + \\\{ + cmp v1,v2 + jae label + define COND + \\\} + match =COND v1<==v2, COND c + \\\{ + cmp v1,v2 + jbe label + define COND + \\\} + match =COND v1==v2, COND c + \\\{ + cmp v1,v2 + je label + define COND + \\\} + match =COND v1<>v2, COND c + \\\{ + cmp v1,v2 + jne label + define COND + \\\} + match =COND =signed v1>v2, COND c + \\\{ + cmp v1,v2 + jg label + define COND + \\\} + match =COND =signed v1v2, COND c + \\\{ + cmp v1,v2 + ja label + define COND + \\\} + match =COND v1 name#.lookup + name#.redundant = 0 + dd 0 + else + name#.redundant = 1 + end if + name#.address: + forward + if used label + if string eqtype '' + label dd RVA _label + else + label dd 80000000h + string + end if + end if + common + if ~ name#.redundant + dd 0 + end if + forward + if used label & string eqtype '' + _label dw 0 + db string,0 + rb RVA $ and 1 + end if + common + end if } + +macro api [name] {} diff --git a/toolchain/fasmw17332/INCLUDE/MACRO/IMPORT64.INC b/toolchain/fasmw17332/INCLUDE/MACRO/IMPORT64.INC new file mode 100644 index 0000000..b03da5b --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/MACRO/IMPORT64.INC @@ -0,0 +1,68 @@ + +; Macroinstructions for making import section (64-bit) + +macro library [name,string] + { common + import.data: + forward + local _label + if defined name#.redundant + if ~ name#.redundant + dd RVA name#.lookup,0,0,RVA _label,RVA name#.address + end if + end if + name#.referred = 1 + common + dd 0,0,0,0,0 + forward + if defined name#.redundant + if ~ name#.redundant + _label db string,0 + rb RVA $ and 1 + end if + end if } + +macro import name,[label,string] + { common + rb (- rva $) and 7 + if defined name#.referred + name#.lookup: + forward + if used label + if string eqtype '' + local _label + dq RVA _label + else + dq 8000000000000000h + string + end if + end if + common + if $ > name#.lookup + name#.redundant = 0 + dq 0 + else + name#.redundant = 1 + end if + name#.address: + forward + if used label + if string eqtype '' + label dq RVA _label + else + label dq 8000000000000000h + string + end if + end if + common + if ~ name#.redundant + dq 0 + end if + forward + if used label & string eqtype '' + _label dw 0 + db string,0 + rb RVA $ and 1 + end if + common + end if } + +macro api [name] {} diff --git a/toolchain/fasmw17332/INCLUDE/MACRO/MASM.INC b/toolchain/fasmw17332/INCLUDE/MACRO/MASM.INC new file mode 100644 index 0000000..b6ffe9a --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/MACRO/MASM.INC @@ -0,0 +1,66 @@ + +; Simulate MASM's syntax + +struc struct + { struct . + name@struct equ . } + +struc ends + { match =.,name@struct \{ ends \} } + +struc proc [params] + { common define@proc ., + name@proc equ . } + +struc endp + { match =.,name@proc \{ endp \} } + +macro option setting + { match =prologue:macro, setting \{ prologue@proc equ macro \} + match =epilogue:macro, setting \{ epilogue@proc equ macro \} } + +macro none procname,flag,parmbytes,localbytes,reglist { } + +macro assume params + { + local expr + define expr params + match reg:struct, expr + \{ + match assumed, reg\#@assumed \\{ irp name, assumed \\\{ restore name \\\} \\} + macro label . \\{ local def + define def . + match =reg =at label, def \\\{ define def \\\} + match name at,def \\\{ def@assumed reg,name,label at + define def \\\} + match name,def \\\{ def@assumed reg,.,: \\\} \\} + struc db [val] \\{ \common def@assumed reg,., \\} + struc dw [val] \\{ \common def@assumed reg,., \\} + struc dp [val] \\{ \common def@assumed reg,., \\} + struc dd [val] \\{ \common def@assumed reg,.,
\\} + struc dt [val] \\{ \common def@assumed reg,.,
\\} + struc dq [val] \\{ \common def@assumed reg,., \\} + struc rb cnt \\{ def@assumed reg,.,rb cnt \\} + struc rw cnt \\{ def@assumed reg,.,rw cnt \\} + struc rp cnt \\{ def@assumed reg,.,rp cnt \\} + struc rd cnt \\{ def@assumed reg,.,rd cnt \\} + struc rt cnt \\{ def@assumed reg,.,rt cnt \\} + struc rq cnt \\{ def@assumed reg,.,rq cnt \\} + reg\#@assumed equ + virtual at reg + reg struct + end virtual + purge label + restruc db,dw,dp,dd,dt,dq + restruc rb,rw,rp,rd,rt,rq \} } + +macro def@assumed reg,name,def + { match vars, reg#@assumed \{ reg#@assumed equ reg#@assumed, \} + reg#@assumed equ reg#@assumed name + local ..label + name equ ..label + ..label def } + +struc label type { label . type } + +struc none { label . } diff --git a/toolchain/fasmw17332/INCLUDE/MACRO/PROC32.INC b/toolchain/fasmw17332/INCLUDE/MACRO/PROC32.INC new file mode 100644 index 0000000..f936d98 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/MACRO/PROC32.INC @@ -0,0 +1,301 @@ + +; Macroinstructions for defining and calling procedures + +macro stdcall proc,[arg] ; directly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call proc } + +macro invoke proc,[arg] ; indirectly call STDCALL procedure + { common + if ~ arg eq + reverse + pushd arg + common + end if + call [proc] } + +macro ccall proc,[arg] ; directly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call proc + if size@ccall + add esp,size@ccall + end if } + +macro cinvoke proc,[arg] ; indirectly call CDECL procedure + { common + size@ccall = 0 + if ~ arg eq + reverse + pushd arg + size@ccall = size@ccall+4 + common + end if + call [proc] + if size@ccall + add esp,size@ccall + end if } + +macro proc [args] ; define procedure + { common + match name params, args> + \{ define@proc name, \{ prologue name,flag,parmbytes,localbytes,reglist \} + virtual at parmbase@proc + match =,args, params \{ defargs@proc args \} + match =args@proc args, args@proc params \{ defargs@proc args \} + parmbytes = $-(parmbase@proc) + end virtual + name # % = parmbytes/4 + all@vars equ + current = 0 + macro locals + \{ virtual at localbase@proc+current + macro label def \\{ match . type,def> \\\{ deflocal@proc .,label, \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} + macro finish@proc + \{ localbytes = current + match close:reglist, close@proc: \\{ close name,flag,parmbytes,localbytes,reglist \\} + end if \} } + +macro defargs@proc [arg] + { common + if ~ arg eq + forward + local ..arg,current@arg + match argname:type, arg + \{ current@arg equ argname + label ..arg type + argname equ ..arg + if qqword eq type + dd ?,?,?,?,?,?,?,? + else if dqword eq type + dd ?,?,?,? + else if tbyte eq type + dd ?,?,? + else if qword eq type | pword eq type + dd ?,? + else + dd ? + end if \} + match =current@arg,current@arg + \{ current@arg equ arg + arg equ ..arg + ..arg dd ? \} + common + args@proc equ current@arg + forward + restore current@arg + common + end if } + +macro deflocal@proc name,def,[val] { name def val } + +macro deflocal@proc name,def,[val] + { common + match vars, all@vars \{ all@vars equ all@vars, \} + all@vars equ all@vars name + forward + local ..var,..tmp + ..var def val + match =?, val \{ ..tmp equ \} + match any =?, val \{ ..tmp equ \} + match any (=?), val \{ ..tmp equ \} + match =label, def \{ ..tmp equ \} + match tmp : value, ..tmp : val + \{ tmp: end virtual + initlocal@proc ..var,def value + virtual at tmp\} + common + match first rest, ..var, \{ name equ first \} } + +struc label type { label . type } + +macro initlocal@proc name,def + { virtual at name + def + size@initlocal = $ - name + end virtual + position@initlocal = 0 + while size@initlocal > position@initlocal + virtual at name + def + if size@initlocal - position@initlocal < 2 + current@initlocal = 1 + load byte@initlocal byte from name+position@initlocal + else if size@initlocal - position@initlocal < 4 + current@initlocal = 2 + load word@initlocal word from name+position@initlocal + else + current@initlocal = 4 + load dword@initlocal dword from name+position@initlocal + end if + end virtual + if current@initlocal = 1 + mov byte [name+position@initlocal],byte@initlocal + else if current@initlocal = 2 + mov word [name+position@initlocal],word@initlocal + else + mov dword [name+position@initlocal],dword@initlocal + end if + position@initlocal = position@initlocal + current@initlocal + end while } + +macro endp + { purge ret,locals,endl + finish@proc + purge finish@proc + restore regs@proc + match all,args@proc \{ restore all \} + restore args@proc + match all,all@vars \{ restore all \} } + +macro local [var] + { common + locals + forward done@local equ + match varname[count]:vartype, var + \{ match =BYTE, vartype \\{ varname rb count + restore done@local \\} + match =WORD, vartype \\{ varname rw count + restore done@local \\} + match =DWORD, vartype \\{ varname rd count + restore done@local \\} + match =PWORD, vartype \\{ varname rp count + restore done@local \\} + match =QWORD, vartype \\{ varname rq count + restore done@local \\} + match =TBYTE, vartype \\{ varname rt count + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + rq count*2 + restore done@local \\} + match =QQWORD, vartype \\{ label varname qqword + rq count*4 + restore done@local \\} + match =XWORD, vartype \\{ label varname xword + rq count*2 + restore done@local \\} + match =YWORD, vartype \\{ label varname yword + rq count*4 + restore done@local \\} + match , done@local \\{ virtual + varname vartype + end virtual + rb count*sizeof.\#vartype + restore done@local \\} \} + match :varname:vartype, done@local:var + \{ match =BYTE, vartype \\{ varname db ? + restore done@local \\} + match =WORD, vartype \\{ varname dw ? + restore done@local \\} + match =DWORD, vartype \\{ varname dd ? + restore done@local \\} + match =PWORD, vartype \\{ varname dp ? + restore done@local \\} + match =QWORD, vartype \\{ varname dq ? + restore done@local \\} + match =TBYTE, vartype \\{ varname dt ? + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + dq ?,? + restore done@local \\} + match =QQWORD, vartype \\{ label varname qqword + dq ?,?,?,? + restore done@local \\} + match =XWORD, vartype \\{ label varname xword + dq ?,? + restore done@local \\} + match =YWORD, vartype \\{ label varname yword + dq ?,?,?,? + restore done@local \\} + match , done@local \\{ varname vartype + restore done@local \\} \} + match ,done@local + \{ var + restore done@local \} + common + endl } diff --git a/toolchain/fasmw17332/INCLUDE/MACRO/PROC64.INC b/toolchain/fasmw17332/INCLUDE/MACRO/PROC64.INC new file mode 100644 index 0000000..0fb22d0 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/MACRO/PROC64.INC @@ -0,0 +1,618 @@ + +; Macroinstructions for defining and calling procedures (x64 version) + +macro invoke proc,[arg] + { common fastcall [proc],arg } + +macro fastcall proc,[arg] + { common local stackspace,argscount,counter + if argscount < 4 + stackspace = 4*8 + else if argscount and 1 + stackspace = (argscount+1)*8 + else + stackspace = argscount*8 + end if + counter = 0 + if stackspace + if defined current@frame + if current@frame + virtual + origin = $ + inc param + load opcode byte from origin + if opcode = 67h | ( opcode > 40h & opcode < 48h ) + load opcode byte from origin+1 + end if + if opcode and 0F8h = 48h + size@param = 8 + else if opcode = 66h + size@param = 2 + else if opcode = 0FFh + size@param = 4 + else + size@param = 1 + end if + end virtual + end if + if counter = 1 + if type@param eq float + if ~ param eq xmm0 + if size@param = 4 + if param eqtype byte 0 | param eqtype byte 0f + mov eax,param + movd xmm0,eax + else + movd xmm0,param + end if + else + if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f + mov rax,param + movq xmm0,rax + else + movq xmm0,param + end if + end if + end if + if vararg@fastcall & ~ param eq rcx + movq rcx,xmm0 + end if + else if type@param eq addr + if ~ param eq rcx + lea rcx,[param] + end if + else if size@param = 8 + if ~ param eq rcx + mov rcx,param + end if + else if size@param = 4 + if ~ param eq ecx + mov ecx,param + end if + else if size@param = 2 + if ~ param eq cx + mov cx,param + end if + else if size@param = 1 + if ~ param eq cl + mov cl,param + end if + end if + else if counter = 2 + if type@param eq float + if ~ param eq xmm1 + if size@param = 4 + if param eqtype byte 0 | param eqtype byte 0f + mov eax,param + movd xmm1,eax + else + movd xmm1,param + end if + else + if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f + mov rax,param + movq xmm1,rax + else + movq xmm1,param + end if + end if + end if + if vararg@fastcall & ~ param eq rdx + movq rdx,xmm1 + end if + else if type@param eq addr + if ~ param eq rdx + lea rdx,[param] + end if + else if size@param = 8 + if ~ param eq rdx + mov rdx,param + end if + else if size@param = 4 + if ~ param eq edx + mov edx,param + end if + else if size@param = 2 + if ~ param eq dx + mov dx,param + end if + else if size@param = 1 + if ~ param eq dl + mov dl,param + end if + end if + else if counter = 3 + if type@param eq float + if ~ param eq xmm2 + if size@param = 4 + if param eqtype byte 0 | param eqtype byte 0f + mov eax,param + movd xmm2,eax + else + movd xmm2,param + end if + else + if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f + mov rax,param + movq xmm2,rax + else + movq xmm2,param + end if + end if + end if + if vararg@fastcall & ~ param eq r8 + movq r8,xmm2 + end if + else if type@param eq addr + if ~ param eq r8 + lea r8,[param] + end if + else if size@param = 8 + if ~ param eq r8 + mov r8,param + end if + else if size@param = 4 + if ~ param eq r8d + mov r8d,param + end if + else if size@param = 2 + if ~ param eq r8w + mov r8w,param + end if + else if size@param = 1 + if ~ param eq r8b + mov r8b,param + end if + end if + else if counter = 4 + if type@param eq float + if ~ param eq xmm3 + if size@param = 4 + if param eqtype byte 0 | param eqtype byte 0f + mov eax,param + movd xmm3,eax + else + movd xmm3,param + end if + else + if param eqtype 0 | param eqtype 0f | param eqtype byte 0 | param eqtype byte 0f + mov rax,param + movq xmm3,rax + else + movq xmm3,param + end if + end if + end if + if vararg@fastcall & ~ param eq r9 + movq r9,xmm3 + end if + else if type@param eq addr + if ~ param eq r9 + lea r9,[param] + end if + else if size@param = 8 + if ~ param eq r9 + mov r9,param + end if + else if size@param = 4 + if ~ param eq r9d + mov r9d,param + end if + else if size@param = 2 + if ~ param eq r9w + mov r9w,param + end if + else if size@param = 1 + if ~ param eq r9b + mov r9b,param + end if + end if + else + if type@param eq addr + lea rax,[param] + mov [rsp+(counter-1)*8],rax + else if param eqtype [0] | param eqtype byte [0] + if size@param = 8 + mov rax,param + mov [rsp+(counter-1)*8],rax + else if size@param = 4 + mov eax,param + mov [rsp+(counter-1)*8],eax + else if size@param = 2 + mov ax,param + mov [rsp+(counter-1)*8],ax + else + mov al,param + mov [rsp+(counter-1)*8],al + end if + else if size@param = 8 + virtual + origin = $ + mov rax,param + load opcode byte from origin+1 + end virtual + if opcode = 0B8h + mov rax,param + mov [rsp+(counter-1)*8],rax + else + mov qword [rsp+(counter-1)*8],param + end if + else if param in + movq [rsp+(counter-1)*8],param + else + mov [rsp+(counter-1)*8],param + end if + end if \} + common + argscount = counter + call proc + if stackspace & ~defined current@frame + add rsp,stackspace + end if } + +macro proc [args] + { common + match name params, args> + \{ define@proc name, \{ prologue name,flag,parmbytes,localbytes,reglist \} + virtual at parmbase@proc + match =,args, params \{ defargs@proc args \} + match =args@proc args, args@proc params \{ defargs@proc args \} + parmbytes = $-(parmbase@proc) + end virtual + name # % = parmbytes/8 + all@vars equ + current = 0 + macro locals + \{ virtual at localbase@proc+current + macro label def \\{ match . type,def> \\\{ deflocal@proc .,label, \\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \} + macro finish@proc + \{ localbytes = current + match close:reglist, close@proc: \\{ close name,flag,parmbytes,localbytes,reglist \\} + end if \} } + +macro defargs@proc [arg] + { common + if ~ arg eq + forward + local ..arg,current@arg + match argname:type, arg + \{ current@arg equ argname + label ..arg type + argname equ ..arg + if qqword eq type + dq ?,?,?,? + else if dqword eq type + dq ?,? + else if tbyte eq type + dq ?,? + else + dq ? + end if \} + match =current@arg,current@arg + \{ current@arg equ arg + arg equ ..arg + ..arg dq ? \} + common + args@proc equ current@arg + forward + restore current@arg + common + end if } + +macro deflocal@proc name,def,[val] { name def val } + +macro deflocal@proc name,def,[val] + { common + match vars, all@vars \{ all@vars equ all@vars, \} + all@vars equ all@vars name + forward + local ..var,..tmp + ..var def val + match =?, val \{ ..tmp equ \} + match any =?, val \{ ..tmp equ \} + match any (=?), val \{ ..tmp equ \} + match =label, def \{ ..tmp equ \} + match tmp : value, ..tmp : val + \{ tmp: end virtual + initlocal@proc ..var,def value + virtual at tmp\} + common + match first rest, ..var, \{ name equ first \} } + +struc label type { label . type } + +macro initlocal@proc name,def + { virtual at name + def + size@initlocal = $ - name + end virtual + position@initlocal = 0 + while size@initlocal > position@initlocal + virtual at name + def + if size@initlocal - position@initlocal < 2 + current@initlocal = 1 + load byte@initlocal byte from name+position@initlocal + else if size@initlocal - position@initlocal < 4 + current@initlocal = 2 + load word@initlocal word from name+position@initlocal + else if size@initlocal - position@initlocal < 8 + current@initlocal = 4 + load dword@initlocal dword from name+position@initlocal + else + load qword@initlocal qword from name+position@initlocal + if ( qword@initlocal > 0 & qword@initlocal < 80000000h ) | ( qword@initlocal < 0 & qword@initlocal >= -80000000h ) + current@initlocal = 8 + else + current@initlocal = 4 + dword@initlocal = qword@initlocal and 0FFFFFFFFh + end if + end if + end virtual + if current@initlocal = 1 + mov byte [name+position@initlocal],byte@initlocal + else if current@initlocal = 2 + mov word [name+position@initlocal],word@initlocal + else if current@initlocal = 4 + mov dword [name+position@initlocal],dword@initlocal + else + mov qword [name+position@initlocal],qword@initlocal + end if + position@initlocal = position@initlocal + current@initlocal + end while } + +macro endp + { purge ret,locals,endl + finish@proc + purge finish@proc + restore regs@proc + match all,args@proc \{ restore all \} + restore args@proc + match all,all@vars \{ restore all \} } + +macro local [var] + { common + locals + forward done@local equ + match varname[count]:vartype, var + \{ match =BYTE, vartype \\{ varname rb count + restore done@local \\} + match =WORD, vartype \\{ varname rw count + restore done@local \\} + match =DWORD, vartype \\{ varname rd count + restore done@local \\} + match =PWORD, vartype \\{ varname rp count + restore done@local \\} + match =QWORD, vartype \\{ varname rq count + restore done@local \\} + match =TBYTE, vartype \\{ varname rt count + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + rq count*2 + restore done@local \\} + match =QQWORD, vartype \\{ label varname qqword + rq count*4 + restore done@local \\} + match =XWORD, vartype \\{ label varname xword + rq count*2 + restore done@local \\} + match =YWORD, vartype \\{ label varname yword + rq count*4 + restore done@local \\} + match , done@local \\{ virtual + varname vartype + end virtual + rb count*sizeof.\#vartype + restore done@local \\} \} + match :varname:vartype, done@local:var + \{ match =BYTE, vartype \\{ varname db ? + restore done@local \\} + match =WORD, vartype \\{ varname dw ? + restore done@local \\} + match =DWORD, vartype \\{ varname dd ? + restore done@local \\} + match =PWORD, vartype \\{ varname dp ? + restore done@local \\} + match =QWORD, vartype \\{ varname dq ? + restore done@local \\} + match =TBYTE, vartype \\{ varname dt ? + restore done@local \\} + match =DQWORD, vartype \\{ label varname dqword + dq ?,? + restore done@local \\} + match =QQWORD, vartype \\{ label varname qqword + dq ?,?,?,? + restore done@local \\} + match =XWORD, vartype \\{ label varname xword + dq ?,? + restore done@local \\} + match =YWORD, vartype \\{ label varname yword + dq ?,?,?,? + restore done@local \\} + match , done@local \\{ varname vartype + restore done@local \\} \} + match ,done@local + \{ var + restore done@local \} + common + endl } + +macro frame + { local size,current + if size + sub rsp,size + end if + current = 0 + current@frame equ current + size@frame equ size } + +macro endf + { size@frame = current@frame + if size@frame + add rsp,size@frame + end if + restore size@frame,current@frame } + +macro static_rsp_prologue procname,flag,parmbytes,localbytes,reglist + { local counter,loc,frame,current + counter = 0 + irps reg, reglist \{ push reg + counter = counter+1 \} + loc = (localbytes+7) and (not 7) + if frame & (counter+loc shr 3+1) and 1 + loc = loc + 8 + end if + framebytes@proc equ frame+loc + if framebytes@proc + sub rsp,framebytes@proc + end if + localbase@proc equ rsp+frame + regsbase@proc equ rsp+frame+loc + parmbase@proc equ rsp+frame+loc+counter*8+8 + current = 0 + current@frame equ current + size@frame equ frame } + +macro static_rsp_epilogue procname,flag,parmbytes,localbytes,reglist + { if framebytes@proc + add rsp,framebytes@proc + end if + irps reg, reglist \{ reverse pop reg \} + retn } + +macro static_rsp_close procname,flag,parmbytes,localbytes,reglist + { size@frame = current@frame + restore size@frame,current@frame } + +stdcall fix fastcall + +macro cinvoke proc,[arg] + { common ccall [proc],arg } + +macro ccall proc,[arg] + { common vararg@fastcall = 1 + fastcall proc,arg + vararg@fastcall = 0 } + +vararg@fastcall = 0 \ No newline at end of file diff --git a/toolchain/fasmw17332/INCLUDE/MACRO/RESOURCE.INC b/toolchain/fasmw17332/INCLUDE/MACRO/RESOURCE.INC new file mode 100644 index 0000000..920754b --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/MACRO/RESOURCE.INC @@ -0,0 +1,334 @@ + +; Macroinstructions for making resource section + +macro directory [type,label] + { common + local max,count + count = 0 + max = 0 + forward + count = count + 1 + if type > max + max = type + end if + common + root@resource dd 0,%t,0,count shl 16 + repeat max + forward + if % = type + dd type,80000000h+label-root@resource + end if + common + end repeat } + +macro resource dir,[id,lang,label] + { common + dir: + local min,max,count,current + forward + min = id + max = id + common + count = 0 + forward + count = count + 1 + if id < min + min = id + else if id > max + max = id + end if + common + dd 0,%t,0,count shl 16 + repeat max-min+1 + current = $ + forward + if min+%-1 = id + if current = $ + dd id,80000000h+label#.directory-root@resource + end if + end if + common + end repeat + repeat max-min+1 + current = $ + forward + if min+%-1 = id + if current = $ + label#.directory dd 0,%t,0,10000h,lang,label-root@resource + count = 1 + else + dd lang,label-root@resource + count = count + 1 + end if + end if + label#.resid = id + common + local x,y,z,v1,v2 + if count > 1 + store word count at current+0Eh + x = count shr 1 + while x > 0 + y = x + while y < count + z = y + while z-x >= 0 + load v1 dword from current+10h+z*8 + load v2 dword from current+10h+(z-x)*8 + if v1 0 + dw 0FFFFh + end if + du menu+0,0,title,0 + if fontname eq + du 8,'MS Sans Serif',0 + else + du fontsize+0,fontname,0 + end if + align 4 + dialog_size equ size = $ - data + dialog_items equ items = dialog_items_counter + dialog_items_counter = 0 } + +macro dialogitem class,title,id,x,y,cx,cy,style,exstyle + { dd style or WS_CHILD,exstyle +0 + dw x,y,cx,cy,id + if class eq 'BUTTON' + dw 0FFFFh,80h + else if class eq 'EDIT' + dw 0FFFFh,81h + else if class eq 'STATIC' + dw 0FFFFh,82h + else if class eq 'LISTBOX' + dw 0FFFFh,83h + else if class eq 'SCROLLBAR' + dw 0FFFFh,84h + else if class eq 'COMBOBOX' + dw 0FFFFh,85h + else + du class,0 + end if + if title eqtype 0 + dw 0FFFFh,title + else + du title,0 + end if + dw 0 + align 4 + dialog_items_counter = dialog_items_counter + 1 } + +macro enddialog + { dialog_items + dialog_size } + +macro accelerator label,[fvirt,key,cmd] + { common + local data,size + label dd RVA data,size,0,0 + data: + accel_count = 0 + forward + accel_count = accel_count + 1 + common + size = accel_count * 8 + forward + accel_count = accel_count - 1 + if accel_count = 0 + dw fvirt or 80h,key + else + dw fvirt,key + end if + dd cmd } + +macro versioninfo label,fileos,filetype,filesubtype,lang,cp,[name,value] + { common + local data,size,vivalue,visize + label dd RVA data,size,0,0 + data dw size,visize,0 + du 'VS_VERSION_INFO',0,0 + vivalue dd 0FEEF04BDh,00010000h + local version,count,shift,char,filever,productver + filever = 0 + productver = 0 + forward + if name eq 'FileVersion' | name eq 'ProductVersion' + virtual at 0 + db value + count = $ + version = 0 + shift = 16 + repeat count + load char from %-1 + if char='.' + if shift mod 32 + shift = shift-16 + else + shift = shift+32+16 + end if + else + version = (version and not (0FFFFh shl shift)) or ((version shr shift and 0FFFFh)*10+char-'0') shl shift + end if + end repeat + end virtual + if name eq 'FileVersion' + filever = version + else if name eq 'ProductVersion' + productver = version + end if + end if + common + dq filever,productver + dd 0,0,fileos,filetype+0,filesubtype+0,0,0 + visize = $ - vivalue + local sfi_data,sfi_size + sfi_data dd sfi_size + du 1,'StringFileInfo',0 + local str_data,str_size + str_data dd str_size + du 1,'040904E4',0 + forward + local vs_data,vs_size,value_data,value_size + align 4 + vs_data dw vs_size,value_size/2 + du 1,name,0 + align 4 + value_data du value,0 + value_size = $ - value_data + vs_size = $ - vs_data + common + align 4 + str_size = $ - str_data + sfi_size = $ - sfi_data + local vfi_data,vfi_size,var_data,var_size + vfi_data dd vfi_size + du 1,'VarFileInfo',0,0 + var_data dw var_size,4 + du 0,'Translation',0,0 + dw lang,cp+0 + var_size = $ - var_data + vfi_size = $ - vfi_data + size = $ - data } + +macro resdata label +{ local data,size + label dd RVA data,size,0,0 + data = $ + ressize equ size = $ - data } + +macro endres +{ ressize + align 4 } diff --git a/toolchain/fasmw17332/INCLUDE/MACRO/STRUCT.INC b/toolchain/fasmw17332/INCLUDE/MACRO/STRUCT.INC new file mode 100644 index 0000000..0db41d9 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/MACRO/STRUCT.INC @@ -0,0 +1,221 @@ + +; Macroinstructions for defining data structures + +macro struct name + { virtual at 0 + define @struct + field@struct equ name + match child parent, name \{ restore field@struct + field@struct equ child,fields@\#parent \} + sub@struct equ + struc db [val] \{ \common define field@struct .,db, \} + struc dw [val] \{ \common define field@struct .,dw, \} + struc du [val] \{ \common define field@struct .,du, \} + struc dd [val] \{ \common define field@struct .,dd, \} + struc dp [val] \{ \common define field@struct .,dp, \} + struc dq [val] \{ \common define field@struct .,dq, \} + struc dt [val] \{ \common define field@struct .,dt, \} + struc rb count \{ define field@struct .,db,count dup (?) \} + struc rw count \{ define field@struct .,dw,count dup (?) \} + struc rd count \{ define field@struct .,dd,count dup (?) \} + struc rp count \{ define field@struct .,dp,count dup (?) \} + struc rq count \{ define field@struct .,dq,count dup (?) \} + struc rt count \{ define field@struct .,dt,count dup (?) \} + macro db [val] \{ \common \local anonymous + define field@struct anonymous,db, \} + macro dw [val] \{ \common \local anonymous + define field@struct anonymous,dw, \} + macro du [val] \{ \common \local anonymous + define field@struct anonymous,du, \} + macro dd [val] \{ \common \local anonymous + define field@struct anonymous,dd, \} + macro dp [val] \{ \common \local anonymous + define field@struct anonymous,dp, \} + macro dq [val] \{ \common \local anonymous + define field@struct anonymous,dq, \} + macro dt [val] \{ \common \local anonymous + define field@struct anonymous,dt, \} + macro rb count \{ \local anonymous + define field@struct anonymous,db,count dup (?) \} + macro rw count \{ \local anonymous + define field@struct anonymous,dw,count dup (?) \} + macro rd count \{ \local anonymous + define field@struct anonymous,dd,count dup (?) \} + macro rp count \{ \local anonymous + define field@struct anonymous,dp,count dup (?) \} + macro rq count \{ \local anonymous + define field@struct anonymous,dq,count dup (?) \} + macro rt count \{ \local anonymous + define field@struct anonymous,dt,count dup (?) \} + macro union \{ field@struct equ ,union,< + sub@struct equ union \} + macro struct \{ field@struct equ ,substruct,< + sub@struct equ substruct \} } + +macro ends + { match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt + restruc rb,rw,rd,rp,rq,rt + purge db,dw,du,dd,dp,dq,dt + purge rb,rw,rd,rp,rq,rt + purge union,struct + irpv fields,field@struct \\{ restore field@struct + \\common define fields@struct fields \\} + match name tail,fields@struct, \\{ if $ + display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah + err + end if \\} + match name=,fields,fields@struct \\{ restore @struct + make@struct name,fields + define fields@\\#name fields \\} + end virtual \} + match any, sub@struct \{ tmp@struct equ field@struct + restore field@struct + field@struct equ tmp@struct> \} + restore sub@struct } + +macro make@struct name,[field,type,def] + { common + local define + define equ name + forward + local sub + match , field \{ make@substruct type,name,sub def + define equ define,.,sub, \} + match any, field \{ define equ define,.#field,type, \} + common + match fields, define \{ define@struct fields \} } + +macro define@struct name,[field,type,def] + { common + virtual + db `name + load initial@struct byte from 0 + if initial@struct = '.' + display 'Error: name of structure should not begin with a dot.',0Dh,0Ah + err + end if + end virtual + local list + list equ + forward + if ~ field eq . + name#field type def + sizeof.#name#field = $ - name#field + else + label name#.#type + rb sizeof.#type + end if + local value + match any, list \{ list equ list, \} + list equ list + common + sizeof.#name = $ + restruc name + match values, list \{ + struc name value \\{ \\local \\..base + match , @struct \\\{ define field@struct .,name, \\\} + match no, @struct \\\{ label \\..base + forward + match , value \\\\{ field type def \\\\} + match any, value \\\\{ field type value + if ~ field eq . + rb sizeof.#name#field - ($-field) + end if \\\\} + common label . at \\..base \\\} + \\} + macro name value \\{ + match , @struct \\\{ \\\local anonymous + define field@struct anonymous,name, \\\} + match no, @struct \\\{ + forward + match , value \\\\{ type def \\\\} + match any, value \\\\{ \\\\local ..field + ..field = $ + type value + if ~ field eq . + rb sizeof.#name#field - ($-..field) + end if \\\\} + common \\\} \\} \} } + +macro enable@substruct + { macro make@substruct substruct,parent,name,[field,type,def] + \{ \common + \local define + define equ parent,name + \forward + \local sub + match , field \\{ match any, type \\\{ enable@substruct + make@substruct type,parent,sub def + purge make@substruct + define equ define,.,sub, \\\} \\} + match any, field \\{ define equ define,.\#field,type, \\} + \common + match fields, define \\{ define@\#substruct fields \\} \} } + +enable@substruct + +macro define@union parent,name,[field,type,def] + { common + virtual at parent#.#name + forward + if ~ field eq . + virtual at parent#.#name + parent#field type def + sizeof.#parent#field = $ - parent#field + end virtual + if sizeof.#parent#field > $ - parent#.#name + rb sizeof.#parent#field - ($ - parent#.#name) + end if + else + virtual at parent#.#name + label parent#.#type + type def + end virtual + label name#.#type at parent#.#name + if sizeof.#type > $ - parent#.#name + rb sizeof.#type - ($ - parent#.#name) + end if + end if + common + sizeof.#name = $ - parent#.#name + end virtual + struc name [value] \{ \common + label .\#name + last@union equ + forward + match any, last@union \\{ virtual at .\#name + field type def + end virtual \\} + match , last@union \\{ match , value \\\{ field type def \\\} + match any, value \\\{ field type value \\\} \\} + last@union equ field + common rb sizeof.#name - ($ - .\#name) \} + macro name [value] \{ \common \local ..anonymous + ..anonymous name value \} } + +macro define@substruct parent,name,[field,type,def] + { common + virtual at parent#.#name + forward + local value + if ~ field eq . + parent#field type def + sizeof.#parent#field = $ - parent#field + else + label parent#.#type + rb sizeof.#type + end if + common + sizeof.#name = $ - parent#.#name + end virtual + struc name value \{ + label .\#name + forward + match , value \\{ field type def \\} + match any, value \\{ field type value + if ~ field eq . + rb sizeof.#parent#field - ($-field) + end if \\} + common \} + macro name value \{ \local ..anonymous + ..anonymous name \} } diff --git a/toolchain/fasmw17332/INCLUDE/MACRO/proc64.bin b/toolchain/fasmw17332/INCLUDE/MACRO/proc64.bin new file mode 100644 index 0000000..e69de29 diff --git a/toolchain/fasmw17332/INCLUDE/PCOUNT/ADVAPI32.INC b/toolchain/fasmw17332/INCLUDE/PCOUNT/ADVAPI32.INC new file mode 100644 index 0000000..311655e --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/PCOUNT/ADVAPI32.INC @@ -0,0 +1,340 @@ + +; ADVAPI32 API calls parameters' count + +AbortSystemShutdown% = 1 +AccessCheck% = 8 +AccessCheckAndAuditAlarm% = 11 +AccessCheckByType% = 11 +AccessCheckByTypeAndAuditAlarm% = 16 +AccessCheckByTypeResultList% = 11 +AccessCheckByTypeResultListAndAuditAlarm% = 16 +AddAccessAllowedAce% = 4 +AddAccessAllowedAceEx% = 5 +AddAccessAllowedObjectAce% = 7 +AddAccessDeniedAce% = 4 +AddAccessDeniedAceEx% = 5 +AddAccessDeniedObjectAce% = 7 +AddAce% = 5 +AddAuditAccessAce% = 6 +AddAuditAccessAceEx% = 7 +AddAuditAccessObjectAce% = 9 +AdjustTokenGroups% = 6 +AdjustTokenPrivileges% = 6 +AllocateAndInitializeSid% = 11 +AllocateLocallyUniqueId% = 1 +AreAllAccessesGranted% = 2 +AreAnyAccessesGranted% = 2 +BackupEventLog% = 2 +BuildExplicitAccessWithName% = 5 +BuildImpersonateExplicitAccessWithName% = 6 +BuildImpersonateTrustee% = 2 +BuildSecurityDescriptor% = 9 +BuildTrusteeWithName% = 2 +BuildTrusteeWithSid% = 2 +CancelOverlappedAccess% = 1 +ChangeServiceConfig2% = 3 +ChangeServiceConfig% = 11 +ClearEventLog% = 2 +CloseEventLog% = 1 +CloseRaw% = 1 +CloseServiceHandle% = 1 +ControlService% = 3 +ConvertAccessToSecurityDescriptor% = 5 +ConvertSecurityDescriptorToAccess% = 7 +ConvertSecurityDescriptorToAccessNamed% = 7 +ConvertToAutoInheritPrivateObjectSecurity% = 6 +CopySid% = 3 +CreatePrivateObjectSecurity% = 6 +CreatePrivateObjectSecurityEx% = 8 +CreateProcessAsUser% = 11 +CreateRestrictedToken% = 9 +CreateService% = 13 +CryptAcquireContext% = 5 +CryptContextAddRef% = 3 +CryptCreateHash% = 5 +CryptDecrypt% = 6 +CryptDeriveKey% = 5 +CryptDestroyHash% = 1 +CryptDestroyKey% = 1 +CryptDuplicateHash% = 4 +CryptDuplicateKey% = 4 +CryptEncrypt% = 7 +CryptEnumProviderTypes% = 6 +CryptEnumProviders% = 6 +CryptExportKey% = 6 +CryptGenKey% = 4 +CryptGenRandom% = 3 +CryptGetDefaultProvider% = 5 +CryptGetHashParam% = 5 +CryptGetKeyParam% = 5 +CryptGetProvParam% = 5 +CryptGetUserKey% = 3 +CryptHashData% = 4 +CryptHashSessionKey% = 3 +CryptImportKey% = 6 +CryptReleaseContext% = 2 +CryptSetHashParam% = 4 +CryptSetKeyParam% = 4 +CryptSetProvParam% = 4 +CryptSetProvider% = 2 +CryptSetProviderEx% = 4 +CryptSignHash% = 6 +CryptVerifySignature% = 6 +DecryptFile% = 2 +DeleteAce% = 2 +DeleteService% = 1 +DeregisterEventSource% = 1 +DestroyPrivateObjectSecurity% = 1 +DuplicateToken% = 3 +DuplicateTokenEx% = 6 +ElfBackupEventLogFile% = 2 +ElfChangeNotify% = 2 +ElfClearEventLogFile% = 2 +ElfCloseEventLog% = 1 +ElfDeregisterEventSource% = 1 +ElfNumberOfRecords% = 2 +ElfOldestRecord% = 2 +ElfOpenBackupEventLog% = 3 +ElfOpenEventLog% = 3 +ElfReadEventLog% = 7 +ElfRegisterEventSource% = 3 +ElfReportEvent% = 12 +EncryptFile% = 1 +EnumDependentServices% = 6 +EnumServicesStatus% = 8 +EqualPrefixSid% = 2 +EqualSid% = 2 +FindFirstFreeAce% = 2 +FreeSid% = 1 +GetAccessPermissionsForObject% = 9 +GetAce% = 3 +GetAclInformation% = 4 +GetAuditedPermissionsFromAcl% = 4 +GetCurrentHwProfile% = 1 +GetEffectiveRightsFromAcl% = 3 +GetExplicitEntriesFromAcl% = 3 +GetFileSecurity% = 5 +GetKernelObjectSecurity% = 5 +GetLengthSid% = 1 +GetMultipleTrustee% = 1 +GetMultipleTrusteeOperation% = 1 +GetNamedSecurityInfo% = 8 +GetNamedSecurityInfoEx% = 9 +GetNumberOfEventLogRecords% = 2 +GetOldestEventLogRecord% = 2 +GetOverlappedAccessResults% = 4 +GetPrivateObjectSecurity% = 5 +GetSecurityDescriptorControl% = 3 +GetSecurityDescriptorDacl% = 4 +GetSecurityDescriptorGroup% = 3 +GetSecurityDescriptorLength% = 1 +GetSecurityDescriptorOwner% = 3 +GetSecurityDescriptorSacl% = 4 +GetSecurityInfo% = 8 +GetSecurityInfoEx% = 9 +GetServiceDisplayName% = 4 +GetServiceKeyName% = 4 +GetSidLengthRequired% = 1 +GetSidSubAuthority% = 2 +GetSidSubAuthorityCount% = 1 +GetTokenInformation% = 5 +GetTrusteeName% = 1 +GetTrusteeType% = 1 +GetUserName% = 2 +I_ScSetServiceBits% = 5 +ImpersonateLoggedOnUser% = 1 +ImpersonateNamedPipeClient% = 1 +ImpersonateSelf% = 1 +InitializeAcl% = 3 +InitializeSecurityDescriptor% = 2 +InitializeSid% = 3 +InitiateSystemShutdown% = 5 +IsTextUnicode% = 3 +IsTokenRestricted% = 1 +IsValidAcl% = 1 +IsValidSecurityDescriptor% = 1 +IsValidSid% = 1 +LockServiceDatabase% = 1 +LogonUser% = 6 +LookupAccountName% = 7 +LookupAccountSid% = 7 +LookupPrivilegeDisplayName% = 5 +LookupPrivilegeName% = 4 +LookupPrivilegeValue% = 3 +LookupSecurityDescriptorParts% = 7 +LsaAddAccountRights% = 4 +LsaAddPrivilegesToAccount% = 2 +LsaClearAuditLog% = 1 +LsaClose% = 1 +LsaCreateAccount% = 4 +LsaCreateSecret% = 4 +LsaCreateTrustedDomain% = 4 +LsaCreateTrustedDomainEx% = 5 +LsaDelete% = 1 +LsaDeleteTrustedDomain% = 2 +LsaEnumerateAccountRights% = 4 +LsaEnumerateAccounts% = 5 +LsaEnumerateAccountsWithUserRight% = 4 +LsaEnumeratePrivileges% = 5 +LsaEnumeratePrivilegesOfAccount% = 2 +LsaEnumerateTrustedDomains% = 5 +LsaEnumerateTrustedDomainsEx% = 6 +LsaFreeMemory% = 1 +LsaGetQuotasForAccount% = 2 +LsaGetSystemAccessAccount% = 2 +LsaGetUserName% = 2 +LsaICLookupNames% = 7 +LsaICLookupSids% = 7 +LsaIGetTrustedDomainAuthInfoBlobs% = 4 +LsaISetTrustedDomainAuthInfoBlobs% = 4 +LsaLookupNames% = 5 +LsaLookupPrivilegeDisplayName% = 4 +LsaLookupPrivilegeName% = 3 +LsaLookupPrivilegeValue% = 3 +LsaLookupSids% = 5 +LsaNtStatusToWinError% = 1 +LsaOpenAccount% = 4 +LsaOpenPolicy% = 4 +LsaOpenSecret% = 4 +LsaOpenTrustedDomain% = 4 +LsaQueryDomainInformationPolicy% = 3 +LsaQueryInfoTrustedDomain% = 3 +LsaQueryInformationPolicy% = 3 +LsaQueryLocalInformationPolicy% = 3 +LsaQuerySecret% = 5 +LsaQuerySecurityObject% = 3 +LsaQueryTrustedDomainInfo% = 4 +LsaQueryTrustedDomainInfoByName% = 4 +LsaRemoveAccountRights% = 5 +LsaRemovePrivilegesFromAccount% = 3 +LsaRetrievePrivateData% = 3 +LsaSetDomainInformationPolicy% = 3 +LsaSetInformationPolicy% = 3 +LsaSetInformationTrustedDomain% = 3 +LsaSetLocalInformationPolicy% = 3 +LsaSetQuotasForAccount% = 2 +LsaSetSecret% = 3 +LsaSetSecurityObject% = 3 +LsaSetSystemAccessAccount% = 2 +LsaSetTrustedDomainInfoByName% = 4 +LsaSetTrustedDomainInformation% = 4 +LsaStorePrivateData% = 3 +MakeAbsoluteSD% = 11 +MakeSelfRelativeSD% = 3 +MapGenericMask% = 2 +NotifyBootConfigStatus% = 1 +NotifyChangeEventLog% = 2 +ObjectCloseAuditAlarm% = 3 +ObjectDeleteAuditAlarm% = 3 +ObjectOpenAuditAlarm% = 12 +ObjectPrivilegeAuditAlarm% = 6 +OpenBackupEventLog% = 2 +OpenEventLog% = 2 +OpenProcessToken% = 3 +OpenRaw% = 3 +OpenSCManager% = 3 +OpenService% = 3 +OpenThreadToken% = 4 +PrivilegeCheck% = 3 +PrivilegedServiceAuditAlarm% = 5 +QueryRecoveryAgents% = 3 +QueryServiceConfig2% = 5 +QueryServiceConfig% = 4 +QueryServiceLockStatus% = 4 +QueryServiceObjectSecurity% = 5 +QueryServiceStatus% = 2 +QueryWindows31FilesMigration% = 1 +ReadEventLog% = 7 +ReadRaw% = 3 +RegCloseKey% = 1 +RegConnectRegistry% = 3 +RegCreateKey% = 3 +RegCreateKeyEx% = 9 +RegDeleteKey% = 2 +RegDeleteValue% = 2 +RegEnumKey% = 4 +RegEnumKeyEx% = 8 +RegEnumValue% = 8 +RegFlushKey% = 1 +RegGetKeySecurity% = 4 +RegLoadKey% = 3 +RegNotifyChangeKeyValue% = 5 +RegOpenKey% = 3 +RegOpenKeyEx% = 5 +RegOverridePredefKey% = 2 +RegQueryInfoKey% = 12 +RegQueryMultipleValues% = 5 +RegQueryValue% = 4 +RegQueryValueEx% = 6 +RegReplaceKey% = 4 +RegRestoreKey% = 3 +RegSaveKey% = 3 +RegSetKeySecurity% = 3 +RegSetValue% = 5 +RegSetValueEx% = 6 +RegUnLoadKey% = 2 +RegisterEventSource% = 2 +RegisterServiceCtrlHandler% = 2 +ReportEvent% = 9 +RevertToSelf% = 0 +SetAclInformation% = 4 +SetEntriesInAccessList% = 6 +SetEntriesInAcl% = 4 +SetEntriesInAuditList% = 6 +SetFileSecurity% = 3 +SetKernelObjectSecurity% = 3 +SetNamedSecurityInfo% = 7 +SetNamedSecurityInfoEx% = 9 +SetPrivateObjectSecurity% = 5 +SetPrivateObjectSecurityEx% = 6 +SetSecurityDescriptorControl% = 3 +SetSecurityDescriptorDacl% = 4 +SetSecurityDescriptorGroup% = 3 +SetSecurityDescriptorOwner% = 3 +SetSecurityDescriptorSacl% = 4 +SetSecurityInfo% = 7 +SetSecurityInfoEx% = 9 +SetServiceBits% = 4 +SetServiceObjectSecurity% = 3 +SetServiceStatus% = 2 +SetThreadToken% = 2 +SetTokenInformation% = 4 +StartService% = 3 +StartServiceCtrlDispatcher% = 1 +SynchronizeWindows31FilesAndWindowsNTRegistry% = 4 +SystemFunction001% = 3 +SystemFunction002% = 3 +SystemFunction003% = 2 +SystemFunction004% = 3 +SystemFunction005% = 3 +SystemFunction006% = 2 +SystemFunction007% = 2 +SystemFunction008% = 3 +SystemFunction009% = 3 +SystemFunction010% = 3 +SystemFunction011% = 3 +SystemFunction012% = 3 +SystemFunction013% = 3 +SystemFunction014% = 3 +SystemFunction015% = 3 +SystemFunction016% = 3 +SystemFunction017% = 3 +SystemFunction018% = 3 +SystemFunction019% = 3 +SystemFunction020% = 3 +SystemFunction021% = 3 +SystemFunction022% = 3 +SystemFunction023% = 3 +SystemFunction024% = 3 +SystemFunction025% = 3 +SystemFunction026% = 3 +SystemFunction027% = 3 +SystemFunction028% = 2 +SystemFunction029% = 2 +SystemFunction030% = 2 +SystemFunction031% = 2 +SystemFunction032% = 2 +SystemFunction033% = 2 +TrusteeAccessToObject% = 6 +UnlockServiceDatabase% = 1 +WriteRaw% = 3 diff --git a/toolchain/fasmw17332/INCLUDE/PCOUNT/COMCTL32.INC b/toolchain/fasmw17332/INCLUDE/PCOUNT/COMCTL32.INC new file mode 100644 index 0000000..adf4032 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/PCOUNT/COMCTL32.INC @@ -0,0 +1,69 @@ + +; COMCTL32 API calls parameters' count + +CreateMappedBitmap% = 5 +CreatePropertySheetPage% = 1 +CreateStatusWindow% = 4 +CreateToolbar% = 8 +CreateToolbarEx% = 13 +CreateUpDownControl% = 12 +DestroyPropertySheetPage% = 1 +DrawInsert% = 3 +DrawStatusText% = 4 +FlatSB_EnableScrollBar% = 3 +FlatSB_GetScrollInfo% = 3 +FlatSB_GetScrollPos% = 2 +FlatSB_GetScrollProp% = 3 +FlatSB_GetScrollRange% = 4 +FlatSB_SetScrollInfo% = 4 +FlatSB_SetScrollPos% = 4 +FlatSB_SetScrollProp% = 4 +FlatSB_SetScrollRange% = 5 +FlatSB_ShowScrollBar% = 3 +GetEffectiveClientRect% = 3 +ImageList_Add% = 3 +ImageList_AddIcon% = 2 +ImageList_AddMasked% = 3 +ImageList_BeginDrag% = 4 +ImageList_Copy% = 5 +ImageList_Create% = 5 +ImageList_Destroy% = 1 +ImageList_DragEnter% = 3 +ImageList_DragLeave% = 1 +ImageList_DragMove% = 2 +ImageList_DragShowNolock% = 1 +ImageList_Draw% = 6 +ImageList_DrawEx% = 10 +ImageList_DrawIndirect% = 1 +ImageList_Duplicate% = 1 +ImageList_EndDrag% = 0 +ImageList_GetBkColor% = 1 +ImageList_GetDragImage% = 2 +ImageList_GetIcon% = 3 +ImageList_GetIconSize% = 3 +ImageList_GetImageCount% = 1 +ImageList_GetImageInfo% = 3 +ImageList_GetImageRect% = 3 +ImageList_LoadImage% = 7 +ImageList_Merge% = 6 +ImageList_Read% = 1 +ImageList_Remove% = 2 +ImageList_Replace% = 4 +ImageList_ReplaceIcon% = 3 +ImageList_SetBkColor% = 2 +ImageList_SetDragCursorImage% = 4 +ImageList_SetFilter% = 3 +ImageList_SetIconSize% = 3 +ImageList_SetImageCount% = 2 +ImageList_SetOverlayImage% = 3 +ImageList_Write% = 2 +InitCommonControls% = 0 +InitCommonControlsEx% = 1 +InitializeFlatSB% = 1 +LBItemFromPt% = 4 +MakeDragList% = 1 +MenuHelp% = 7 +PropertySheet% = 1 +ShowHideMenuCtl% = 3 +UninitializeFlatSB% = 1 +_TrackMouseEvent% = 1 diff --git a/toolchain/fasmw17332/INCLUDE/PCOUNT/COMDLG32.INC b/toolchain/fasmw17332/INCLUDE/PCOUNT/COMDLG32.INC new file mode 100644 index 0000000..3417a8c --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/PCOUNT/COMDLG32.INC @@ -0,0 +1,18 @@ + +; COMDLG32 API calls parameters' count + +ChooseColor% = 1 +ChooseFont% = 1 +CommDlgExtendedError% = 0 +FindText% = 1 +FormatCharDlgProc% = 4 +GetFileTitle% = 3 +GetOpenFileName% = 1 +GetSaveFileName% = 1 +LoadAlterBitmap% = 3 +PageSetupDlg% = 1 +PrintDlg% = 1 +ReplaceText% = 1 +WantArrows% = 4 +dwLBSubclass% = 4 +dwOKSubclass% = 4 diff --git a/toolchain/fasmw17332/INCLUDE/PCOUNT/GDI32.INC b/toolchain/fasmw17332/INCLUDE/PCOUNT/GDI32.INC new file mode 100644 index 0000000..6d5c76b --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/PCOUNT/GDI32.INC @@ -0,0 +1,319 @@ + +; GDI32 API calls parameters' count + +AbortDoc% = 1 +AbortPath% = 1 +AddFontMemResourceEx% = 4 +AddFontResource% = 1 +AddFontResourceEx% = 3 +AngleArc% = 6 +AnimatePalette% = 4 +Arc% = 9 +ArcTo% = 9 +BeginPath% = 1 +BitBlt% = 9 +CancelDC% = 1 +CheckColorsInGamut% = 4 +ChoosePixelFormat% = 2 +Chord% = 9 +CloseEnhMetaFile% = 1 +CloseFigure% = 1 +CloseMetaFile% = 1 +ColorCorrectPalette% = 4 +ColorMatchToTarget% = 3 +CombineRgn% = 4 +CombineTransform% = 3 +CopyEnhMetaFile% = 2 +CopyMetaFile% = 2 +CreateBitmap% = 5 +CreateBitmapIndirect% = 1 +CreateBrushIndirect% = 1 +CreateColorSpace% = 1 +CreateCompatibleBitmap% = 3 +CreateCompatibleDC% = 1 +CreateDC% = 4 +CreateDIBPatternBrush% = 2 +CreateDIBPatternBrushPt% = 2 +CreateDIBSection% = 6 +CreateDIBitmap% = 6 +CreateDiscardableBitmap% = 3 +CreateEllipticRgn% = 4 +CreateEllipticRgnIndirect% = 1 +CreateEnhMetaFile% = 4 +CreateFont% = 14 +CreateFontIndirect% = 1 +CreateFontIndirectEx% = 1 +CreateHalftonePalette% = 1 +CreateHatchBrush% = 2 +CreateIC% = 4 +CreateMetaFile% = 1 +CreatePalette% = 1 +CreatePatternBrush% = 1 +CreatePen% = 3 +CreatePenIndirect% = 1 +CreatePolyPolygonRgn% = 4 +CreatePolygonRgn% = 3 +CreateRectRgn% = 4 +CreateRectRgnIndirect% = 1 +CreateRoundRectRgn% = 6 +CreateScalableFontResource% = 4 +CreateSolidBrush% = 1 +DPtoLP% = 3 +DeleteColorSpace% = 1 +DeleteDC% = 1 +DeleteEnhMetaFile% = 1 +DeleteMetaFile% = 1 +DeleteObject% = 1 +DescribePixelFormat% = 4 +DeviceCapabilitiesEx% = 6 +DrawEscape% = 4 +Ellipse% = 5 +EnableEUDC% = 1 +EndDoc% = 1 +EndPage% = 1 +EndPath% = 1 +EnumEnhMetaFile% = 5 +EnumFontFamilies% = 4 +EnumFontFamiliesEx% = 5 +EnumFonts% = 4 +EnumICMProfiles% = 3 +EnumMetaFile% = 4 +EnumObjects% = 4 +EqualRgn% = 2 +Escape% = 5 +ExcludeClipRect% = 5 +ExtCreatePen% = 5 +ExtCreateRegion% = 3 +ExtEscape% = 6 +ExtFloodFill% = 5 +ExtSelectClipRgn% = 3 +ExtTextOut% = 8 +FillPath% = 1 +FillRgn% = 3 +FixBrushOrgEx% = 4 +FlattenPath% = 1 +FloodFill% = 4 +FrameRgn% = 5 +GdiComment% = 3 +GdiDeleteSpoolFileHandle% = 1 +GdiEndDocEMF% = 1 +GdiEndPageEMF% = 2 +GdiFlush% = 0 +GdiGetBatchLimit% = 0 +GdiGetDC% = 1 +GdiGetDevmodeForPage% = 4 +GdiGetPageCount% = 1 +GdiGetPageHandle% = 3 +GdiGetSpoolFileHandle% = 3 +GdiPlayDCScript% = 6 +GdiPlayEMF% = 5 +GdiPlayJournal% = 5 +GdiPlayPageEMF% = 4 +GdiPlayPrivatePageEMF% = 3 +GdiPlayScript% = 7 +GdiResetDCEMF% = 2 +GdiSetBatchLimit% = 1 +GdiStartDocEMF% = 2 +GdiStartPageEMF% = 1 +GetArcDirection% = 1 +GetAspectRatioFilterEx% = 2 +GetBitmapBits% = 3 +GetBitmapDimensionEx% = 2 +GetBkColor% = 1 +GetBkMode% = 1 +GetBoundsRect% = 3 +GetBrushOrgEx% = 2 +GetCharABCWidths% = 4 +GetCharABCWidthsFloat% = 4 +GetCharABCWidthsI% = 5 +GetCharWidth32% = 4 +GetCharWidth% = 4 +GetCharWidthFloat% = 4 +GetCharWidthI% = 5 +GetCharacterPlacement% = 6 +GetClipBox% = 2 +GetClipRgn% = 2 +GetColorAdjustment% = 2 +GetColorSpace% = 1 +GetCurrentObject% = 2 +GetCurrentPositionEx% = 2 +GetDCBrushColor% = 1 +GetDCOrgEx% = 2 +GetDCPenColor% = 1 +GetDIBColorTable% = 4 +GetDIBits% = 7 +GetDeviceCaps% = 2 +GetDeviceGammaRamp% = 2 +GetEnhMetaFile% = 1 +GetEnhMetaFileBits% = 3 +GetEnhMetaFileDescription% = 3 +GetEnhMetaFileHeader% = 3 +GetEnhMetaFilePaletteEntries% = 3 +GetEnhMetaFilePixelFormat% = 3 +GetFontAssocStatus% = 1 +GetFontData% = 5 +GetFontLanguageInfo% = 1 +GetFontUnicodeRanges% = 2 +GetGlyphIndices% = 5 +GetGlyphOutline% = 7 +GetGraphicsMode% = 1 +GetICMProfile% = 3 +GetKerningPairs% = 3 +GetLogColorSpace% = 3 +GetMapMode% = 1 +GetMetaFile% = 1 +GetMetaFileBitsEx% = 3 +GetMetaRgn% = 2 +GetMiterLimit% = 2 +GetNearestColor% = 2 +GetNearestPaletteIndex% = 2 +GetObject% = 3 +GetObjectType% = 1 +GetOutlineTextMetrics% = 3 +GetPaletteEntries% = 4 +GetPath% = 4 +GetPixel% = 3 +GetPixelFormat% = 1 +GetPolyFillMode% = 1 +GetROP2% = 1 +GetRandomRgn% = 3 +GetRasterizerCaps% = 2 +GetRegionData% = 3 +GetRelAbs% = 2 +GetRgnBox% = 2 +GetStockObject% = 1 +GetStretchBltMode% = 1 +GetSystemPaletteEntries% = 4 +GetSystemPaletteUse% = 1 +GetTextAlign% = 1 +GetTextCharacterExtra% = 1 +GetTextCharset% = 1 +GetTextCharsetInfo% = 3 +GetTextColor% = 1 +GetTextExtentExPoint% = 7 +GetTextExtentExPointI% = 7 +GetTextExtentPoint32% = 4 +GetTextExtentPoint% = 4 +GetTextExtentPointI% = 4 +GetTextFace% = 3 +GetTextMetrics% = 2 +GetViewportExtEx% = 2 +GetViewportOrgEx% = 2 +GetWinMetaFileBits% = 5 +GetWindowExtEx% = 2 +GetWindowOrgEx% = 2 +GetWorldTransform% = 2 +IntersectClipRect% = 5 +InvertRgn% = 2 +LPtoDP% = 3 +LineDD% = 6 +LineTo% = 3 +MaskBlt% = 12 +ModifyWorldTransform% = 3 +MoveToEx% = 4 +OffsetClipRgn% = 3 +OffsetRgn% = 3 +OffsetViewportOrgEx% = 4 +OffsetWindowOrgEx% = 4 +PaintRgn% = 2 +PatBlt% = 6 +PathToRegion% = 1 +Pie% = 9 +PlayEnhMetaFile% = 3 +PlayEnhMetaFileRecord% = 4 +PlayMetaFile% = 2 +PlayMetaFileRecord% = 4 +PlgBlt% = 10 +PolyBezier% = 3 +PolyBezierTo% = 3 +PolyDraw% = 4 +PolyPatBlt% = 5 +PolyPolygon% = 4 +PolyPolyline% = 4 +PolyTextOut% = 3 +Polygon% = 3 +Polyline% = 3 +PolylineTo% = 3 +PtInRegion% = 3 +PtVisible% = 3 +RealizePalette% = 1 +RectInRegion% = 2 +RectVisible% = 2 +Rectangle% = 5 +RemoveFontMemResourceEx% = 1 +RemoveFontResource% = 1 +RemoveFontResourceEx% = 3 +ResetDC% = 2 +ResizePalette% = 2 +RestoreDC% = 2 +RoundRect% = 7 +SaveDC% = 1 +ScaleViewportExtEx% = 6 +ScaleWindowExtEx% = 6 +SelectBrushLocal% = 2 +SelectClipPath% = 2 +SelectClipRgn% = 2 +SelectFontLocal% = 2 +SelectObject% = 2 +SelectPalette% = 3 +SetAbortProc% = 2 +SetArcDirection% = 2 +SetBitmapBits% = 3 +SetBitmapDimensionEx% = 4 +SetBkColor% = 2 +SetBkMode% = 2 +SetBoundsRect% = 3 +SetBrushOrgEx% = 4 +SetColorAdjustment% = 2 +SetColorSpace% = 2 +SetDCBrushColor% = 2 +SetDCPenColor% = 2 +SetDIBColorTable% = 4 +SetDIBits% = 7 +SetDIBitsToDevice% = 12 +SetDeviceGammaRamp% = 2 +SetEnhMetaFileBits% = 2 +SetFontEnumeration% = 1 +SetGraphicsMode% = 2 +SetICMMode% = 2 +SetICMProfile% = 2 +SetMagicColors% = 3 +SetMapMode% = 2 +SetMapperFlags% = 2 +SetMetaFileBitsEx% = 2 +SetMetaRgn% = 1 +SetMiterLimit% = 3 +SetPaletteEntries% = 4 +SetPixel% = 4 +SetPixelFormat% = 3 +SetPixelV% = 4 +SetPolyFillMode% = 2 +SetROP2% = 2 +SetRectRgn% = 5 +SetRelAbs% = 2 +SetStretchBltMode% = 2 +SetSystemPaletteUse% = 2 +SetTextAlign% = 2 +SetTextCharacterExtra% = 2 +SetTextColor% = 2 +SetTextJustification% = 3 +SetViewportExtEx% = 4 +SetViewportOrgEx% = 4 +SetWinMetaFileBits% = 4 +SetWindowExtEx% = 4 +SetWindowOrgEx% = 4 +SetWorldTransform% = 2 +StartDoc% = 2 +StartPage% = 1 +StretchBlt% = 11 +StretchDIBits% = 13 +StrokeAndFillPath% = 1 +StrokePath% = 1 +SwapBuffers% = 1 +TextOut% = 5 +TranslateCharsetInfo% = 3 +UnrealizeObject% = 1 +UpdateColors% = 1 +UpdateICMRegKey% = 4 +WidenPath% = 1 +gdiPlaySpoolStream% = 6 diff --git a/toolchain/fasmw17332/INCLUDE/PCOUNT/KERNEL32.INC b/toolchain/fasmw17332/INCLUDE/PCOUNT/KERNEL32.INC new file mode 100644 index 0000000..e7fec6f --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/PCOUNT/KERNEL32.INC @@ -0,0 +1,557 @@ + +; KERNEL32 API calls parameters' count + +AddAtom% = 1 +AddConsoleAlias% = 3 +AllocConsole% = 0 +AreFileApisANSI% = 0 +AssignProcessToJobObject% = 2 +BackupRead% = 7 +BackupSeek% = 6 +BackupWrite% = 7 +BaseAttachCompleteThunk% = 0 +Beep% = 2 +BeginUpdateResource% = 2 +BuildCommDCB% = 2 +BuildCommDCBAndTimeouts% = 3 +CallNamedPipe% = 7 +CancelIo% = 1 +CancelWaitableTimer% = 1 +ClearCommBreak% = 1 +ClearCommError% = 3 +CloseConsoleHandle% = 1 +CloseHandle% = 1 +CloseProfileUserMapping% = 0 +CmdBatNotification% = 1 +CommConfigDialog% = 3 +CompareFileTime% = 2 +CompareString% = 6 +ConnectNamedPipe% = 2 +ConsoleMenuControl% = 3 +ContinueDebugEvent% = 3 +ConvertDefaultLocale% = 1 +ConvertThreadToFiber% = 1 +CopyFile% = 3 +CopyFileEx% = 6 +CreateConsoleScreenBuffer% = 5 +CreateDirectory% = 2 +CreateDirectoryEx% = 3 +CreateEvent% = 4 +CreateFiber% = 3 +CreateFile% = 7 +CreateFileMapping% = 6 +CreateHardLink% = 3 +CreateIoCompletionPort% = 4 +CreateJobObject% = 2 +CreateMailslot% = 4 +CreateMutex% = 3 +CreateNamedPipe% = 8 +CreatePipe% = 4 +CreateProcess% = 10 +CreateRemoteThread% = 7 +CreateSemaphore% = 4 +CreateTapePartition% = 4 +CreateThread% = 6 +CreateToolhelp32Snapshot% = 2 +CreateVirtualBuffer% = 3 +CreateWaitableTimer% = 3 +DebugActiveProcess% = 1 +DebugBreak% = 0 +DefineDosDevice% = 3 +DeleteAtom% = 1 +DeleteCriticalSection% = 1 +DeleteFiber% = 1 +DeleteFile% = 1 +DeviceIoControl% = 8 +DisableThreadLibraryCalls% = 1 +DisconnectNamedPipe% = 1 +DosDateTimeToFileTime% = 3 +DuplicateConsoleHandle% = 4 +DuplicateHandle% = 7 +EndUpdateResource% = 2 +EnterCriticalSection% = 1 +EnumCalendarInfo% = 4 +EnumCalendarInfoEx% = 4 +EnumDateFormats% = 3 +EnumDateFormatsEx% = 3 +EnumResourceLanguages% = 5 +EnumResourceNames% = 4 +EnumResourceTypes% = 3 +EnumSystemCodePages% = 2 +EnumSystemLocales% = 2 +EnumTimeFormats% = 3 +EraseTape% = 3 +EscapeCommFunction% = 2 +ExitProcess% = 1 +ExitThread% = 1 +ExitVDM% = 2 +ExpandEnvironmentStrings% = 3 +ExpungeConsoleCommandHistory% = 1 +ExtendVirtualBuffer% = 2 +FatalAppExit% = 2 +FatalExit% = 1 +FileTimeToDosDateTime% = 3 +FileTimeToLocalFileTime% = 2 +FileTimeToSystemTime% = 2 +FillConsoleOutputAttribute% = 5 +FillConsoleOutputCharacter% = 5 +FindAtom% = 1 +FindClose% = 1 +FindCloseChangeNotification% = 1 +FindFirstChangeNotification% = 3 +FindFirstFile% = 2 +FindFirstFileEx% = 6 +FindNextChangeNotification% = 1 +FindNextFile% = 2 +FindResource% = 3 +FindResourceEx% = 4 +FlushConsoleInputBuffer% = 1 +FlushFileBuffers% = 1 +FlushInstructionCache% = 3 +FlushViewOfFile% = 2 +FoldString% = 5 +FormatMessage% = 7 +FreeConsole% = 0 +FreeEnvironmentStrings% = 1 +FreeLibrary% = 1 +FreeLibraryAndExitThread% = 2 +FreeResource% = 1 +FreeVirtualBuffer% = 1 +GenerateConsoleCtrlEvent% = 2 +GetACP% = 0 +GetAtomName% = 3 +GetBinaryType% = 2 +GetCPInfo% = 2 +GetCPInfoEx% = 3 +GetCommConfig% = 3 +GetCommMask% = 2 +GetCommModemStatus% = 2 +GetCommProperties% = 2 +GetCommState% = 2 +GetCommTimeouts% = 2 +GetCommandLine% = 0 +GetCompressedFileSize% = 2 +GetComputerName% = 2 +GetConsoleAlias% = 4 +GetConsoleAliasExes% = 2 +GetConsoleAliasExesLength% = 0 +GetConsoleAliases% = 3 +GetConsoleAliasesLength% = 1 +GetConsoleCP% = 0 +GetConsoleCommandHistory% = 3 +GetConsoleCommandHistoryLength% = 1 +GetConsoleCursorInfo% = 2 +GetConsoleDisplayMode% = 1 +GetConsoleFontInfo% = 4 +GetConsoleFontSize% = 2 +GetConsoleHardwareState% = 3 +GetConsoleInputExeName% = 2 +GetConsoleInputWaitHandle% = 0 +GetConsoleKeyboardLayoutName% = 1 +GetConsoleMode% = 2 +GetConsoleOutputCP% = 0 +GetConsoleScreenBufferInfo% = 2 +GetConsoleTitle% = 2 +GetConsoleWindow% = 0 +GetCurrencyFormat% = 6 +GetCurrentConsoleFont% = 3 +GetCurrentDirectory% = 2 +GetCurrentProcess% = 0 +GetCurrentProcessId% = 0 +GetCurrentThread% = 0 +GetCurrentThreadId% = 0 +GetDateFormat% = 6 +GetDefaultCommConfig% = 3 +GetDevicePowerState% = 1 +GetDiskFreeSpace% = 5 +GetDiskFreeSpaceEx% = 4 +GetDriveType% = 1 +GetEnvironmentStrings% = 0 +GetEnvironmentVariable% = 3 +GetExitCodeProcess% = 2 +GetExitCodeThread% = 2 +GetFileAttributes% = 1 +GetFileAttributesEx% = 3 +GetFileInformationByHandle% = 2 +GetFileSize% = 2 +GetFileTime% = 4 +GetFileType% = 1 +GetFullPathName% = 4 +GetHandleInformation% = 2 +GetLargestConsoleWindowSize% = 1 +GetLastError% = 0 +GetLocalTime% = 1 +GetLocaleInfo% = 4 +GetLogicalDriveStrings% = 2 +GetLogicalDrives% = 0 +GetLongPathName% = 3 +GetMailslotInfo% = 5 +GetModuleFileName% = 3 +GetModuleHandle% = 1 +GetNamedPipeHandleState% = 7 +GetNamedPipeInfo% = 5 +GetNextVDMCommand% = 1 +GetNumberFormat% = 6 +GetNumberOfConsoleFonts% = 0 +GetNumberOfConsoleInputEvents% = 2 +GetNumberOfConsoleMouseButtons% = 1 +GetOEMCP% = 0 +GetOverlappedResult% = 4 +GetPriorityClass% = 1 +GetPrivateProfileInt% = 4 +GetPrivateProfileSection% = 4 +GetPrivateProfileSectionNames% = 3 +GetPrivateProfileString% = 6 +GetPrivateProfileStruct% = 5 +GetProcAddress% = 2 +GetProcessAffinityMask% = 3 +GetProcessHeap% = 0 +GetProcessHeaps% = 2 +GetProcessPriorityBoost% = 2 +GetProcessShutdownParameters% = 2 +GetProcessTimes% = 5 +GetProcessVersion% = 1 +GetProcessWorkingSetSize% = 3 +GetProfileInt% = 3 +GetProfileSection% = 3 +GetProfileString% = 5 +GetQueuedCompletionStatus% = 5 +GetShortPathName% = 3 +GetStartupInfo% = 1 +GetStdHandle% = 1 +GetStringType% = 5 +GetStringTypeEx% = 5 +GetSystemDefaultLCID% = 0 +GetSystemDefaultLangID% = 0 +GetSystemDirectory% = 2 +GetSystemInfo% = 1 +GetSystemPowerStatus% = 1 +GetSystemTime% = 1 +GetSystemTimeAdjustment% = 3 +GetSystemTimeAsFileTime% = 1 +GetTapeParameters% = 4 +GetTapePosition% = 5 +GetTapeStatus% = 1 +GetTempFileName% = 4 +GetTempPath% = 2 +GetThreadContext% = 2 +GetThreadLocale% = 0 +GetThreadPriority% = 1 +GetThreadPriorityBoost% = 2 +GetThreadSelectorEntry% = 3 +GetThreadTimes% = 5 +GetTickCount% = 0 +GetTimeFormat% = 6 +GetTimeZoneInformation% = 1 +GetUserDefaultLCID% = 0 +GetUserDefaultLangID% = 0 +GetVDMCurrentDirectories% = 2 +GetVersion% = 0 +GetVersionEx% = 1 +GetVolumeInformation% = 8 +GetWindowsDirectory% = 2 +GlobalAddAtom% = 1 +GlobalAlloc% = 2 +GlobalCompact% = 1 +GlobalDeleteAtom% = 1 +GlobalFindAtom% = 1 +GlobalFix% = 1 +GlobalFlags% = 1 +GlobalFree% = 1 +GlobalGetAtomName% = 3 +GlobalHandle% = 1 +GlobalLock% = 1 +GlobalMemoryStatus% = 1 +GlobalMemoryStatusVlm% = 1 +GlobalReAlloc% = 3 +GlobalSize% = 1 +GlobalUnWire% = 1 +GlobalUnfix% = 1 +GlobalUnlock% = 1 +GlobalWire% = 1 +Heap32First% = 3 +Heap32ListFirst% = 2 +Heap32ListNext% = 2 +Heap32Next% = 1 +HeapAlloc% = 3 +HeapCompact% = 2 +HeapCreate% = 3 +HeapDestroy% = 1 +HeapExtend% = 4 +HeapFree% = 3 +HeapLock% = 1 +HeapReAlloc% = 4 +HeapSize% = 3 +HeapSummary% = 3 +HeapUnlock% = 1 +HeapUsage% = 5 +HeapValidate% = 3 +HeapWalk% = 2 +InitAtomTable% = 1 +InitializeCriticalSection% = 1 +InitializeCriticalSectionAndSpinCount% = 2 +InterlockedCompareExchange% = 3 +InterlockedDecrement% = 1 +InterlockedExchange% = 2 +InterlockedExchangeAdd% = 2 +InterlockedIncrement% = 1 +InvalidateConsoleDIBits% = 2 +IsBadCodePtr% = 1 +IsBadHugeReadPtr% = 2 +IsBadHugeWritePtr% = 2 +IsBadReadPtr% = 2 +IsBadStringPtr% = 2 +IsBadWritePtr% = 2 +IsDBCSLeadByte% = 1 +IsDBCSLeadByteEx% = 2 +IsDebuggerPresent% = 0 +IsProcessorFeaturePresent% = 1 +IsValidCodePage% = 1 +IsValidLocale% = 2 +LCMapString% = 6 +LeaveCriticalSection% = 1 +LoadLibrary% = 1 +LoadLibraryEx% = 3 +LoadModule% = 2 +LoadResource% = 2 +LocalAlloc% = 2 +LocalCompact% = 1 +LocalFileTimeToFileTime% = 2 +LocalFlags% = 1 +LocalFree% = 1 +LocalHandle% = 1 +LocalLock% = 1 +LocalReAlloc% = 3 +LocalShrink% = 2 +LocalSize% = 1 +LocalUnlock% = 1 +LockFile% = 5 +LockFileEx% = 6 +LockResource% = 1 +MapViewOfFile% = 5 +MapViewOfFileEx% = 6 +MapViewOfFileVlm% = 7 +Module32First% = 2 +Module32Next% = 2 +MoveFile% = 2 +MoveFileEx% = 3 +MoveFileWithProgress% = 5 +MulDiv% = 3 +MultiByteToWideChar% = 6 +OpenEvent% = 3 +OpenFile% = 3 +OpenFileMapping% = 3 +OpenJobObject% = 3 +OpenMutex% = 3 +OpenProcess% = 3 +OpenProfileUserMapping% = 0 +OpenSemaphore% = 3 +OpenWaitableTimer% = 3 +OutputDebugString% = 1 +PeekConsoleInput% = 4 +PeekNamedPipe% = 6 +PostQueuedCompletionStatus% = 4 +PrepareTape% = 3 +Process32First% = 2 +Process32Next% = 2 +PulseEvent% = 1 +PurgeComm% = 2 +QueryDosDevice% = 3 +QueryInformationJobObject% = 5 +QueryPerformanceCounter% = 1 +QueryPerformanceFrequency% = 1 +QueryWin31IniFilesMappedToRegistry% = 4 +QueueUserAPC% = 3 +RaiseException% = 4 +ReadConsole% = 5 +ReadConsoleInput% = 4 +ReadConsoleInputEx% = 5 +ReadConsoleOutput% = 5 +ReadConsoleOutputAttribute% = 5 +ReadConsoleOutputCharacter% = 5 +ReadFile% = 5 +ReadFileEx% = 5 +ReadFileScatter% = 5 +ReadFileVlm% = 5 +ReadProcessMemory% = 5 +ReadProcessMemoryVlm% = 5 +RegisterConsoleVDM% = 11 +RegisterWaitForInputIdle% = 1 +RegisterWowBaseHandlers% = 1 +RegisterWowExec% = 1 +ReleaseMutex% = 1 +ReleaseSemaphore% = 3 +RemoveDirectory% = 1 +RequestWakeupLatency% = 1 +ResetEvent% = 1 +ResumeThread% = 1 +RtlFillMemory% = 3 +RtlMoveMemory% = 3 +RtlUnwind% = 4 +RtlZeroMemory% = 2 +ScrollConsoleScreenBuffer% = 5 +SearchPath% = 6 +SetCommBreak% = 1 +SetCommConfig% = 3 +SetCommMask% = 2 +SetCommState% = 2 +SetCommTimeouts% = 2 +SetComputerName% = 1 +SetConsoleActiveScreenBuffer% = 1 +SetConsoleCP% = 1 +SetConsoleCommandHistoryMode% = 1 +SetConsoleCtrlHandler% = 2 +SetConsoleCursor% = 2 +SetConsoleCursorInfo% = 2 +SetConsoleCursorPosition% = 2 +SetConsoleDisplayMode% = 3 +SetConsoleFont% = 2 +SetConsoleHardwareState% = 3 +SetConsoleIcon% = 1 +SetConsoleInputExeName% = 1 +SetConsoleKeyShortcuts% = 4 +SetConsoleMaximumWindowSize% = 2 +SetConsoleMenuClose% = 1 +SetConsoleMode% = 2 +SetConsoleNumberOfCommands% = 2 +SetConsoleOutputCP% = 1 +SetConsolePalette% = 3 +SetConsoleScreenBufferSize% = 2 +SetConsoleTextAttribute% = 2 +SetConsoleTitle% = 1 +SetConsoleWindowInfo% = 3 +SetCriticalSectionSpinCount% = 2 +SetCurrentDirectory% = 1 +SetDefaultCommConfig% = 3 +SetEndOfFile% = 1 +SetEnvironmentVariable% = 2 +SetErrorMode% = 1 +SetEvent% = 1 +SetFileApisToANSI% = 0 +SetFileApisToOEM% = 0 +SetFileAttributes% = 2 +SetFilePointer% = 4 +SetFileTime% = 4 +SetHandleCount% = 1 +SetHandleInformation% = 3 +SetInformationJobObject% = 4 +SetLastConsoleEventActive% = 0 +SetLastError% = 1 +SetLocalTime% = 1 +SetLocaleInfo% = 3 +SetMailslotInfo% = 2 +SetNamedPipeHandleState% = 4 +SetPriorityClass% = 2 +SetProcessAffinityMask% = 2 +SetProcessPriorityBoost% = 2 +SetProcessShutdownParameters% = 2 +SetProcessWorkingSetSize% = 3 +SetStdHandle% = 2 +SetSystemPowerState% = 2 +SetSystemTime% = 1 +SetSystemTimeAdjustment% = 2 +SetTapeParameters% = 3 +SetTapePosition% = 6 +SetThreadAffinityMask% = 2 +SetThreadContext% = 2 +SetThreadExecutionState% = 1 +SetThreadIdealProcessor% = 2 +SetThreadLocale% = 1 +SetThreadPriority% = 2 +SetThreadPriorityBoost% = 2 +SetTimeZoneInformation% = 1 +SetUnhandledExceptionFilter% = 1 +SetVDMCurrentDirectories% = 2 +SetVolumeLabel% = 2 +SetWaitableTimer% = 6 +SetupComm% = 3 +ShowConsoleCursor% = 2 +SignalObjectAndWait% = 4 +SizeofResource% = 2 +Sleep% = 1 +SleepEx% = 2 +SuspendThread% = 1 +SwitchToFiber% = 1 +SwitchToThread% = 0 +SystemTimeToFileTime% = 2 +SystemTimeToTzSpecificLocalTime% = 3 +TerminateJobObject% = 2 +TerminateProcess% = 2 +TerminateThread% = 2 +Thread32First% = 2 +Thread32Next% = 2 +TlsAlloc% = 0 +TlsFree% = 1 +TlsGetValue% = 1 +TlsSetValue% = 2 +Toolhelp32ReadProcessMemory% = 5 +TransactNamedPipe% = 7 +TransmitCommChar% = 2 +TrimVirtualBuffer% = 1 +TryEnterCriticalSection% = 1 +UnhandledExceptionFilter% = 1 +UnlockFile% = 5 +UnlockFileEx% = 5 +UnmapViewOfFile% = 1 +UnmapViewOfFileVlm% = 1 +UpdateResource% = 6 +VDMConsoleOperation% = 2 +VDMOperationStarted% = 1 +VerLanguageName% = 3 +VerifyConsoleIoHandle% = 1 +VirtualAlloc% = 4 +VirtualAllocEx% = 5 +VirtualAllocVlm% = 6 +VirtualBufferExceptionHandler% = 3 +VirtualFree% = 3 +VirtualFreeEx% = 4 +VirtualFreeVlm% = 5 +VirtualLock% = 2 +VirtualProtect% = 4 +VirtualProtectEx% = 5 +VirtualProtectVlm% = 6 +VirtualQuery% = 3 +VirtualQueryEx% = 4 +VirtualQueryVlm% = 4 +VirtualUnlock% = 2 +WaitCommEvent% = 3 +WaitForDebugEvent% = 2 +WaitForMultipleObjects% = 4 +WaitForMultipleObjectsEx% = 5 +WaitForSingleObject% = 2 +WaitForSingleObjectEx% = 3 +WaitNamedPipe% = 2 +WideCharToMultiByte% = 8 +WinExec% = 2 +WriteConsole% = 5 +WriteConsoleInput% = 4 +WriteConsoleInputVDM% = 4 +WriteConsoleOutput% = 5 +WriteConsoleOutputAttribute% = 5 +WriteConsoleOutputCharacter% = 5 +WriteFile% = 5 +WriteFileEx% = 5 +WriteFileGather% = 5 +WriteFileVlm% = 5 +WritePrivateProfileSection% = 3 +WritePrivateProfileString% = 4 +WritePrivateProfileStruct% = 5 +WriteProcessMemory% = 5 +WriteProcessMemoryVlm% = 5 +WriteProfileSection% = 2 +WriteProfileString% = 3 +WriteTapemark% = 4 +_hread% = 3 +_hwrite% = 3 +_lclose% = 1 +_lcreat% = 2 +_llseek% = 3 +_lopen% = 2 +_lread% = 3 +_lwrite% = 3 +lstrcat% = 2 +lstrcmp% = 2 +lstrcmpi% = 2 +lstrcpy% = 2 +lstrcpyn% = 3 +lstrlen% = 1 diff --git a/toolchain/fasmw17332/INCLUDE/PCOUNT/SHELL32.INC b/toolchain/fasmw17332/INCLUDE/PCOUNT/SHELL32.INC new file mode 100644 index 0000000..1d0528d --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/PCOUNT/SHELL32.INC @@ -0,0 +1,73 @@ + +; SHELL32 API calls parameters' count + +CheckEscapes% = 2 +DoEnvironmentSubst% = 2 +DragAcceptFiles% = 2 +DragFinish% = 1 +DragQueryFile% = 4 +DragQueryPoint% = 2 +DuplicateIcon% = 2 +ExtractAssociatedIcon% = 3 +ExtractAssociatedIconEx% = 4 +ExtractIcon% = 3 +ExtractIconEx% = 5 +ExtractIconResInfo% = 5 +FindExeDlgProc% = 4 +FindExecutable% = 3 +FreeIconList% = 2 +InternalExtractIconList% = 3 +RealShellExecute% = 10 +RealShellExecuteEx% = 11 +RegenerateUserEnvironment% = 2 +SHAddToRecentDocs% = 2 +SHAppBarMessage% = 2 +SHBrowseForFolder% = 1 +SHChangeNotify% = 4 +SHEmptyRecycleBin% = 3 +SHFileOperation% = 1 +SHFormatDrive% = 4 +SHFreeNameMappings% = 1 +SHGetDataFromIDList% = 5 +SHGetDesktopFolder% = 1 +SHGetDiskFreeSpace% = 4 +SHGetFileInfo% = 5 +SHGetInstanceExplorer% = 1 +SHGetMalloc% = 1 +SHGetNewLinkInfo% = 5 +SHGetPathFromIDList% = 2 +SHGetSettings% = 2 +SHGetSpecialFolderLocation% = 3 +SHGetSpecialFolderPath% = 4 +SHInvokePrinterCommand% = 5 +SHLoadInProc% = 1 +SHQueryRecycleBin% = 2 +SHUpdateRecycleBinIcon% = 0 +SheChangeDir% = 1 +SheChangeDirEx% = 1 +SheFullPath% = 3 +SheGetCurDrive% = 0 +SheGetDir% = 2 +SheRemoveQuotes% = 1 +SheSetCurDrive% = 1 +SheShortenPath% = 2 +ShellAbout% = 4 +ShellExecute% = 6 +ShellExecuteEx% = 1 +ShellHookProc% = 3 +Shell_NotifyIcon% = 2 +StrChr% = 2 +StrChrI% = 2 +StrCmpN% = 3 +StrCmpNI% = 3 +StrCpyN% = 3 +StrNCmp% = 3 +StrNCmpI% = 3 +StrNCpy% = 3 +StrRChr% = 3 +StrRChrI% = 3 +StrRStr% = 3 +StrRStrI% = 3 +StrStr% = 2 +StrStrI% = 2 +WOWShellExecute% = 7 diff --git a/toolchain/fasmw17332/INCLUDE/PCOUNT/USER32.INC b/toolchain/fasmw17332/INCLUDE/PCOUNT/USER32.INC new file mode 100644 index 0000000..fc4ce05 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/PCOUNT/USER32.INC @@ -0,0 +1,477 @@ + +; USER32 API calls parameters' count + +ActivateKeyboardLayout% = 2 +AdjustWindowRect% = 3 +AdjustWindowRectEx% = 4 +AnimateWindow% = 3 +AnyPopup% = 0 +AppendMenu% = 4 +ArrangeIconicWindows% = 1 +AttachThreadInput% = 3 +BeginDeferWindowPos% = 1 +BeginPaint% = 2 +BlockInput% = 1 +BringWindowToTop% = 1 +BroadcastSystemMessage% = 5 +CallMsgFilter% = 2 +CallNextHookEx% = 4 +CallWindowProc% = 5 +CascadeChildWindows% = 2 +CascadeWindows% = 5 +ChangeClipboardChain% = 2 +ChangeDisplaySettings% = 2 +ChangeDisplaySettingsEx% = 5 +ChangeMenu% = 5 +CharLower% = 1 +CharLowerBuff% = 2 +CharNext% = 1 +CharNextEx% = 3 +CharPrev% = 2 +CharPrevEx% = 4 +CharToOem% = 2 +CharToOemBuff% = 3 +CharUpper% = 1 +CharUpperBuff% = 2 +CheckDlgButton% = 3 +CheckMenuItem% = 3 +CheckMenuRadioItem% = 5 +CheckRadioButton% = 4 +ChildWindowFromPoint% = 3 +ChildWindowFromPointEx% = 4 +ClientToScreen% = 2 +ClipCursor% = 1 +CloseClipboard% = 0 +CloseDesktop% = 1 +CloseWindow% = 1 +CloseWindowStation% = 1 +CopyAcceleratorTable% = 3 +CopyIcon% = 1 +CopyImage% = 5 +CopyRect% = 2 +CountClipboardFormats% = 0 +CreateAcceleratorTable% = 2 +CreateCaret% = 4 +CreateCursor% = 7 +CreateDesktop% = 6 +CreateDialogIndirectParam% = 5 +CreateDialogParam% = 5 +CreateIcon% = 7 +CreateIconFromResource% = 4 +CreateIconFromResourceEx% = 7 +CreateIconIndirect% = 1 +CreateMDIWindow% = 10 +CreateMenu% = 0 +CreatePopupMenu% = 0 +CreateWindowEx% = 12 +CreateWindowStation% = 4 +DdeAbandonTransaction% = 3 +DdeAccessData% = 2 +DdeAddData% = 4 +DdeClientTransaction% = 8 +DdeCmpStringHandles% = 2 +DdeConnect% = 4 +DdeConnectList% = 5 +DdeCreateDataHandle% = 7 +DdeCreateStringHandle% = 3 +DdeDisconnect% = 1 +DdeDisconnectList% = 1 +DdeEnableCallback% = 3 +DdeFreeDataHandle% = 1 +DdeFreeStringHandle% = 2 +DdeGetData% = 4 +DdeGetLastError% = 1 +DdeGetQualityOfService% = 3 +DdeImpersonateClient% = 1 +DdeInitialize% = 4 +DdeKeepStringHandle% = 2 +DdeNameService% = 4 +DdePostAdvise% = 3 +DdeQueryConvInfo% = 3 +DdeQueryNextServer% = 2 +DdeQueryString% = 5 +DdeReconnect% = 1 +DdeSetQualityOfService% = 3 +DdeSetUserHandle% = 3 +DdeUnaccessData% = 1 +DdeUninitialize% = 1 +DefDlgProc% = 4 +DefFrameProc% = 5 +DefMDIChildProc% = 4 +DefWindowProc% = 4 +DeferWindowPos% = 8 +DeleteMenu% = 3 +DestroyAcceleratorTable% = 1 +DestroyCaret% = 0 +DestroyCursor% = 1 +DestroyIcon% = 1 +DestroyMenu% = 1 +DestroyWindow% = 1 +DialogBoxIndirectParam% = 5 +DialogBoxParam% = 5 +DispatchMessage% = 1 +DlgDirList% = 5 +DlgDirListComboBox% = 5 +DlgDirSelectComboBoxEx% = 4 +DlgDirSelectEx% = 4 +DragDetect% = 3 +DragObject% = 5 +DrawAnimatedRects% = 4 +DrawCaption% = 4 +DrawEdge% = 4 +DrawFocusRect% = 2 +DrawFrame% = 4 +DrawFrameControl% = 4 +DrawIcon% = 4 +DrawIconEx% = 9 +DrawMenuBar% = 1 +DrawState% = 10 +DrawText% = 5 +DrawTextEx% = 6 +EditWndProc% = 4 +EmptyClipboard% = 0 +EnableMenuItem% = 3 +EnableScrollBar% = 3 +EnableWindow% = 2 +EndDeferWindowPos% = 1 +EndDialog% = 2 +EndMenu% = 0 +EndPaint% = 2 +EnumChildWindows% = 3 +EnumClipboardFormats% = 1 +EnumDesktopWindows% = 3 +EnumDesktops% = 3 +EnumDisplayMonitors% = 4 +EnumDisplaySettings% = 3 +EnumDisplaySettingsEx% = 4 +EnumProps% = 2 +EnumPropsEx% = 3 +EnumThreadWindows% = 3 +EnumWindowStations% = 2 +EnumWindows% = 2 +EqualRect% = 2 +ExcludeUpdateRgn% = 2 +ExitWindowsEx% = 2 +FillRect% = 3 +FindWindow% = 2 +FindWindowEx% = 4 +FlashWindow% = 2 +FrameRect% = 3 +FreeDDElParam% = 2 +GetActiveWindow% = 0 +GetAltTabInfo% = 5 +GetAncestor% = 2 +GetAsyncKeyState% = 1 +GetCapture% = 0 +GetCaretBlinkTime% = 0 +GetCaretPos% = 1 +GetClassInfo% = 3 +GetClassInfoEx% = 3 +GetClassLong% = 2 +GetClassName% = 3 +GetClassWord% = 2 +GetClientRect% = 2 +GetClipCursor% = 1 +GetClipboardData% = 1 +GetClipboardFormatName% = 3 +GetClipboardSequenceNumber% = 0 +GetClipboardViewer% = 0 +GetComboBoxInfo% = 2 +GetCursor% = 0 +GetCursorInfo% = 1 +GetCursorPos% = 1 +GetDC% = 1 +GetDCEx% = 3 +GetDesktopWindow% = 0 +GetDialogBaseUnits% = 0 +GetDlgCtrlID% = 1 +GetDlgItem% = 2 +GetDlgItemInt% = 4 +GetDlgItemText% = 4 +GetDoubleClickTime% = 0 +GetFocus% = 0 +GetForegroundWindow% = 0 +GetGUIThreadInfo% = 2 +GetGuiResources% = 2 +GetIconInfo% = 2 +GetInputDesktop% = 0 +GetInputState% = 0 +GetKBCodePage% = 0 +GetKeyNameText% = 3 +GetKeyState% = 1 +GetKeyboardLayout% = 1 +GetKeyboardLayoutList% = 2 +GetKeyboardLayoutName% = 1 +GetKeyboardState% = 1 +GetKeyboardType% = 1 +GetLastActivePopup% = 1 +GetLastInputInfo% = 1 +GetListBoxInfo% = 1 +GetMenu% = 1 +GetMenuBarInfo% = 4 +GetMenuCheckMarkDimensions% = 0 +GetMenuContextHelpId% = 1 +GetMenuDefaultItem% = 3 +GetMenuInfo% = 2 +GetMenuItemCount% = 1 +GetMenuItemID% = 2 +GetMenuItemInfo% = 4 +GetMenuItemRect% = 4 +GetMenuState% = 3 +GetMenuString% = 5 +GetMessage% = 4 +GetMessageExtraInfo% = 0 +GetMessagePos% = 0 +GetMessageTime% = 0 +GetMonitorInfo% = 2 +GetMouseMovePoints% = 5 +GetNextDlgGroupItem% = 3 +GetNextDlgTabItem% = 3 +GetOpenClipboardWindow% = 0 +GetParent% = 1 +GetPriorityClipboardFormat% = 2 +GetProcessWindowStation% = 0 +GetProp% = 2 +GetQueueStatus% = 1 +GetScrollBarInfo% = 3 +GetScrollInfo% = 3 +GetScrollPos% = 2 +GetScrollRange% = 4 +GetShellWindow% = 0 +GetSubMenu% = 2 +GetSysColor% = 1 +GetSysColorBrush% = 1 +GetSystemMenu% = 2 +GetSystemMetrics% = 1 +GetTabbedTextExtent% = 5 +GetThreadDesktop% = 1 +GetTitleBarInfo% = 2 +GetTopWindow% = 1 +GetUpdateRect% = 3 +GetUpdateRgn% = 3 +GetUserObjectInformation% = 5 +GetUserObjectSecurity% = 5 +GetWindow% = 2 +GetWindowContextHelpId% = 1 +GetWindowDC% = 1 +GetWindowInfo% = 2 +GetWindowLong% = 2 +GetWindowModuleFileName% = 3 +GetWindowPlacement% = 2 +GetWindowRect% = 2 +GetWindowRgn% = 2 +GetWindowText% = 3 +GetWindowTextLength% = 1 +GetWindowThreadProcessId% = 2 +GetWindowWord% = 2 +GrayString% = 9 +HideCaret% = 1 +HiliteMenuItem% = 4 +IMPGetIME% = 2 +IMPQueryIME% = 1 +IMPSetIME% = 2 +ImpersonateDdeClientWindow% = 2 +InSendMessage% = 0 +InSendMessageEx% = 1 +InflateRect% = 3 +InsertMenu% = 5 +InsertMenuItem% = 4 +IntersectRect% = 3 +InvalidateRect% = 3 +InvalidateRgn% = 3 +InvertRect% = 2 +IsCharAlpha% = 1 +IsCharAlphaNumeric% = 1 +IsCharLower% = 1 +IsCharUpper% = 1 +IsChild% = 2 +IsClipboardFormatAvailable% = 1 +IsDialogMessage% = 2 +IsDlgButtonChecked% = 2 +IsIconic% = 1 +IsMenu% = 1 +IsRectEmpty% = 1 +IsWindow% = 1 +IsWindowEnabled% = 1 +IsWindowUnicode% = 1 +IsWindowVisible% = 1 +IsZoomed% = 1 +KillSystemTimer% = 2 +KillTimer% = 2 +LoadAccelerators% = 2 +LoadBitmap% = 2 +LoadCursor% = 2 +LoadCursorFromFile% = 1 +LoadIcon% = 2 +LoadImage% = 6 +LoadKeyboardLayout% = 2 +LoadMenu% = 2 +LoadMenuIndirect% = 1 +LoadString% = 4 +LockWindowUpdate% = 1 +LockWorkStation% = 0 +LookupIconIdFromDirectory% = 2 +LookupIconIdFromDirectoryEx% = 5 +MapDialogRect% = 2 +MapVirtualKey% = 2 +MapVirtualKeyEx% = 3 +MapWindowPoints% = 4 +MenuItemFromPoint% = 4 +MessageBeep% = 1 +MessageBox% = 4 +MessageBoxEx% = 5 +MessageBoxIndirect% = 1 +ModifyMenu% = 5 +MonitorFromPoint% = 3 +MonitorFromRect% = 2 +MonitorFromWindow% = 2 +MoveWindow% = 6 +MsgWaitForMultipleObjects% = 5 +MsgWaitForMultipleObjectsEx% = 5 +NotifyWinEvent% = 4 +OemKeyScan% = 1 +OemToChar% = 2 +OemToCharBuff% = 3 +OffsetRect% = 3 +OpenClipboard% = 1 +OpenDesktop% = 4 +OpenIcon% = 1 +OpenInputDesktop% = 3 +OpenWindowStation% = 3 +PackDDElParam% = 3 +PaintDesktop% = 1 +PeekMessage% = 5 +PostMessage% = 4 +PostQuitMessage% = 1 +PostThreadMessage% = 4 +PtInRect% = 3 +RealChildWindowFromPoint% = 3 +RealGetWindowClass% = 3 +RedrawWindow% = 4 +RegisterClass% = 1 +RegisterClassEx% = 1 +RegisterClipboardFormat% = 1 +RegisterDeviceNotification% = 3 +RegisterHotKey% = 4 +RegisterWindowMessage% = 1 +ReleaseCapture% = 0 +ReleaseDC% = 2 +RemoveMenu% = 3 +RemoveProp% = 2 +ReplyMessage% = 1 +ReuseDDElParam% = 5 +ScreenToClient% = 2 +ScrollChildren% = 3 +ScrollDC% = 7 +ScrollWindow% = 5 +ScrollWindowEx% = 8 +SendDlgItemMessage% = 5 +SendIMEMessageEx% = 2 +SendInput% = 3 +SendMessage% = 4 +SendMessageCallback% = 6 +SendMessageTimeout% = 7 +SendNotifyMessage% = 4 +SetActiveWindow% = 1 +SetCapture% = 1 +SetCaretBlinkTime% = 1 +SetCaretPos% = 2 +SetClassLong% = 3 +SetClassWord% = 3 +SetClipboardData% = 2 +SetClipboardViewer% = 1 +SetCursor% = 1 +SetCursorPos% = 2 +SetDebugErrorLevel% = 1 +SetDeskWallpaper% = 1 +SetDlgItemInt% = 4 +SetDlgItemText% = 3 +SetDoubleClickTime% = 1 +SetFocus% = 1 +SetForegroundWindow% = 1 +SetKeyboardState% = 1 +SetLastErrorEx% = 2 +SetMenu% = 2 +SetMenuContextHelpId% = 2 +SetMenuDefaultItem% = 3 +SetMenuInfo% = 2 +SetMenuItemBitmaps% = 5 +SetMenuItemInfo% = 4 +SetMessageExtraInfo% = 1 +SetMessageQueue% = 1 +SetParent% = 2 +SetProcessWindowStation% = 1 +SetProp% = 3 +SetRect% = 5 +SetRectEmpty% = 1 +SetScrollInfo% = 4 +SetScrollPos% = 4 +SetScrollRange% = 5 +SetShellWindow% = 1 +SetSysColors% = 3 +SetSystemCursor% = 2 +SetSystemMenu% = 2 +SetSystemTimer% = 4 +SetThreadDesktop% = 1 +SetTimer% = 4 +SetUserObjectInformation% = 4 +SetUserObjectSecurity% = 3 +SetWinEventHook% = 7 +SetWindowContextHelpId% = 2 +SetWindowLong% = 3 +SetWindowPlacement% = 2 +SetWindowPos% = 7 +SetWindowRgn% = 3 +SetWindowText% = 2 +SetWindowWord% = 3 +SetWindowsHook% = 2 +SetWindowsHookEx% = 4 +ShowCaret% = 1 +ShowCursor% = 1 +ShowOwnedPopups% = 2 +ShowScrollBar% = 3 +ShowWindow% = 2 +ShowWindowAsync% = 2 +SubtractRect% = 3 +SwapMouseButton% = 1 +SwitchDesktop% = 1 +SystemParametersInfo% = 4 +TabbedTextOut% = 8 +TileChildWindows% = 2 +TileWindows% = 5 +ToAscii% = 5 +ToAsciiEx% = 6 +ToUnicode% = 6 +ToUnicodeEx% = 7 +TrackMouseEvent% = 1 +TrackPopupMenu% = 7 +TrackPopupMenuEx% = 6 +TranslateAccelerator% = 3 +TranslateMDISysAccel% = 2 +TranslateMessage% = 1 +UnhookWinEvent% = 1 +UnhookWindowsHook% = 2 +UnhookWindowsHookEx% = 1 +UnionRect% = 3 +UnloadKeyboardLayout% = 1 +UnpackDDElParam% = 4 +UnregisterClass% = 2 +UnregisterDeviceNotification% = 1 +UnregisterHotKey% = 2 +UpdateWindow% = 1 +UserHandleGrantAccess% = 2 +ValidateRect% = 2 +ValidateRgn% = 2 +VkKeyScan% = 1 +VkKeyScanEx% = 2 +WINNLSEnableIME% = 2 +WINNLSGetEnableStatus% = 1 +WINNLSGetIMEHotkey% = 1 +WaitForInputIdle% = 2 +WaitMessage% = 0 +WinHelp% = 4 +WindowFromDC% = 1 +WindowFromPoint% = 2 +keybd_event% = 4 +mouse_event% = 5 +wvsprintf% = 3 diff --git a/toolchain/fasmw17332/INCLUDE/PCOUNT/WSOCK32.INC b/toolchain/fasmw17332/INCLUDE/PCOUNT/WSOCK32.INC new file mode 100644 index 0000000..ea401d3 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/PCOUNT/WSOCK32.INC @@ -0,0 +1,70 @@ + +; WSOCK32 API calls parameters' count + +AcceptEx% = 8 +EnumProtocols% = 3 +GetAcceptExSockaddrs% = 8 +GetAddressByName% = 10 +GetNameByType% = 3 +GetService% = 7 +GetTypeByName% = 2 +MigrateWinsockConfiguration% = 3 +NPLoadNameSpaces% = 3 +SetService% = 6 +TransmitFile% = 7 +WEP% = 0 +WSAAsyncGetHostByAddr% = 7 +WSAAsyncGetHostByName% = 5 +WSAAsyncGetProtoByName% = 5 +WSAAsyncGetProtoByNumber% = 5 +WSAAsyncGetServByName% = 6 +WSAAsyncGetServByPort% = 6 +WSACancelAsyncRequest% = 4 +WSACancelBlockingCall% = 0 +WSACleanup% = 0 +WSAGetLastError% = 0 +WSAIsBlocking% = 0 +WSARecvEx% = 4 +WSASetBlockingHook% = 1 +WSASetLastError% = 1 +WSAStartup% = 2 +WSAUnhookBlockingHook% = 0 +__WSAFDIsSet% = 2 +accept% = 3 +bind% = 3 +closesocket% = 1 +connect% = 3 +dn_expand% = 5 +gethostbyaddr% = 3 +gethostbyname% = 1 +gethostname% = 2 +getnetbyname% = 1 +getpeername% = 3 +getprotobyname% = 1 +getprotobynumber% = 1 +getservbyname% = 2 +getservbyport% = 2 +getsockname% = 3 +getsockopt% = 5 +htonl% = 1 +htons% = 1 +inet_addr% = 1 +inet_network% = 1 +inet_ntoa% = 1 +ioctlsocket% = 3 +listen% = 2 +ntohl% = 1 +ntohs% = 1 +rcmd% = 6 +recv% = 4 +recvfrom% = 6 +rexec% = 6 +rresvport% = 1 +s_perror% = 2 +select% = 5 +send% = 4 +sendto% = 6 +sethostname% = 2 +setsockopt% = 5 +shutdown% = 2 +socket% = 3 diff --git a/toolchain/fasmw17332/INCLUDE/WIN32A.INC b/toolchain/fasmw17332/INCLUDE/WIN32A.INC new file mode 100644 index 0000000..f3520de --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/WIN32A.INC @@ -0,0 +1,25 @@ + +; Win32 programming headers (ASCII) + +include 'macro/struct.inc' +include 'macro/proc32.inc' +include 'macro/com32.inc' +include 'macro/import32.inc' +include 'macro/export.inc' +include 'macro/resource.inc' + +struc TCHAR [val] { common match any, val \{ . db val \} + match , val \{ . db ? \} } +sizeof.TCHAR = 1 + +include 'equates/kernel32.inc' +include 'equates/user32.inc' +include 'equates/gdi32.inc' +include 'equates/comctl32.inc' +include 'equates/comdlg32.inc' +include 'equates/shell32.inc' +include 'equates/wsock32.inc' + +macro api [name] { if used name + label name dword at name#A + end if } diff --git a/toolchain/fasmw17332/INCLUDE/WIN32AX.INC b/toolchain/fasmw17332/INCLUDE/WIN32AX.INC new file mode 100644 index 0000000..2d24315 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/WIN32AX.INC @@ -0,0 +1,172 @@ + +; Extended Win32 programming headers (ASCII) + +include 'win32a.inc' + +include 'macro/if.inc' + +macro allow_nesting +{ macro pushd value + \{ match ,value \\{ + pushx equ \\} + match =pushx =invoke proc,pushx value \\{ + allow_nesting + invoke proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx =stdcall proc,pushx value \\{ + allow_nesting + stdcall proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx =cinvoke proc,pushx value \\{ + allow_nesting + cinvoke proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx =ccall proc,pushx value \\{ + allow_nesting + ccall proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx,pushx \\{ + pushd + pushx equ \\} + restore pushx \} + macro invoke proc,[arg] + \{ \reverse pushd + \common call [proc] \} + macro stdcall proc,[arg] + \{ \reverse pushd + \common call proc \} + macro cinvoke proc,[arg] + \{ \common \local size + size = 0 + if ~ arg eq + \reverse pushd + size = size+4 + match =double any,arg \\{ size = size+4 \\} + \common end if + call [proc] + if size + add esp,size + end if \} + macro ccall proc,[arg] + \{ \common \local size + size = 0 + if ~ arg eq + \reverse pushd + size = size+4 + match =double any,arg \\{ size = size+4 \\} + \common end if + call proc + if size + add esp,size + end if \} } + +macro pushd value +{ match first=,more, value \{ \local ..continue + call ..continue + db value,0 + ..continue: + pushd equ \} + match pushd =addr var,pushd value \{ \local ..opcode,..address + if +var relativeto 0 | +var relativeto $ + push var + else + lea edx,[var] + push edx + end if + pushd equ \} + match pushd =double [var],pushd value \{ + push dword [var+4] + push dword [var] + pushd equ \} + match pushd =double =ptr var,pushd value \{ + push dword [var+4] + push dword [var] + pushd equ \} + match pushd =double num,pushd value \{ \local ..high,..low + virtual at 0 + dq num + load ..low dword from 0 + load ..high dword from 4 + end virtual + push ..high + push ..low + pushd equ \} + match pushd,pushd \{ \local ..continue + if value eqtype '' + call ..continue + db value,0 + ..continue: + else + push value + end if + pushd equ \} + restore pushd } + +allow_nesting + +macro import lib,[functions] +{ common macro import_#lib \{ import lib,functions \} } + +macro api [functions] +{ common macro all_api \{ all_api + api functions \} } +macro all_api {} + +include 'api/kernel32.inc' +include 'api/user32.inc' +include 'api/gdi32.inc' +include 'api/advapi32.inc' +include 'api/comctl32.inc' +include 'api/comdlg32.inc' +include 'api/shell32.inc' +include 'api/wsock32.inc' + +purge import,api + +macro .data { section '.data' data readable writeable } + +macro .code { section '.text' code readable executable } + +macro .end label +{ + entry label + + section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL',\ + user32,'USER32.DLL',\ + gdi32,'GDI32.DLL',\ + advapi32,'ADVAPI32.DLL',\ + comctl32,'COMCTL32.DLL',\ + comdlg32,'COMDLG32.DLL',\ + shell32,'SHELL32.DLL',\ + wsock32,'WSOCK32.DLL' + + import_kernel32 + import_user32 + import_gdi32 + import_advapi32 + import_comctl32 + import_comdlg32 + import_shell32 + import_wsock32 + + all_api +} + +virtual at 0 + xchg eax,eax + detected_16bit = $-1 +end virtual + +if detected_16bit + format PE GUI 4.0 +end if diff --git a/toolchain/fasmw17332/INCLUDE/WIN32AXP.INC b/toolchain/fasmw17332/INCLUDE/WIN32AXP.INC new file mode 100644 index 0000000..13c6a9e --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/WIN32AXP.INC @@ -0,0 +1,199 @@ + +; Extended Win32 programming headers with parameters count checking (ASCII) + +include 'win32a.inc' + +include 'macro/if.inc' + +macro allow_nesting +{ macro pushd value + \{ match ,value \\{ + pushx equ \\} + match =pushx =invoke proc,pushx value \\{ + allow_nesting + invoke proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx =stdcall proc,pushx value \\{ + allow_nesting + stdcall proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx =cinvoke proc,pushx value \\{ + allow_nesting + cinvoke proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx =ccall proc,pushx value \\{ + allow_nesting + ccall proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx,pushx \\{ + pushd + pushx equ \\} + restore pushx \} + macro invoke proc,[arg] + \{ \common count@stdcall = 0 + if ~ arg eq + \forward count@stdcall = count@stdcall+1 + match =double value, arg \\{ count@stdcall = count@stdcall+1 \\} + \common end if + if proc eqtype 0 & defined proc \# % & count@stdcall <> proc \# % + display "Error: invalid count of parameters for ",\`proc,".",0Dh,0Ah + assert 0 + end if + \reverse pushd + \common call [proc] \} + macro stdcall proc,[arg] + \{ \common count@stdcall = 0 + if ~ arg eq + \forward count@stdcall = count@stdcall+1 + match =double value, arg \\{ count@stdcall = count@stdcall+1 \\} + \common end if + if proc eqtype 0 & defined proc \# % & count@stdcall <> proc \# % + display "Error: invalid count of parameters for ",\`proc,".",0Dh,0Ah + assert 0 + end if + \reverse pushd + \common call proc \} + macro cinvoke proc,[arg] + \{ \common \local size + size = 0 + if ~ arg eq + \reverse pushd + size = size+4 + match =double any,arg \\{ size = size+4 \\} + \common end if + call [proc] + if size + add esp,size + end if \} + macro ccall proc,[arg] + \{ \common \local size + size = 0 + if ~ arg eq + \reverse pushd + size = size+4 + match =double any,arg \\{ size = size+4 \\} + \common end if + call proc + if size + add esp,size + end if \} } + +macro pushd value +{ match first=,more, value \{ \local ..continue + call ..continue + db value,0 + ..continue: + pushd equ \} + match pushd =addr var,pushd value \{ \local ..opcode,..address + if +var relativeto 0 | +var relativeto $ + push var + else + lea edx,[var] + push edx + end if + pushd equ \} + match pushd =double [var],pushd value \{ + push dword [var+4] + push dword [var] + pushd equ \} + match pushd =double =ptr var,pushd value \{ + push dword [var+4] + push dword [var] + pushd equ \} + match pushd =double num,pushd value \{ \local ..high,..low + virtual at 0 + dq num + load ..low dword from 0 + load ..high dword from 4 + end virtual + push ..high + push ..low + pushd equ \} + match pushd,pushd \{ \local ..continue + if value eqtype '' + call ..continue + db value,0 + ..continue: + else + push value + end if + pushd equ \} + restore pushd } + +allow_nesting + +include 'pcount/kernel32.inc' +include 'pcount/user32.inc' +include 'pcount/gdi32.inc' +include 'pcount/advapi32.inc' +include 'pcount/comctl32.inc' +include 'pcount/comdlg32.inc' +include 'pcount/shell32.inc' +include 'pcount/wsock32.inc' + +macro import lib,[functions] +{ common macro import_#lib \{ import lib,functions \} } + +macro api [functions] +{ common macro all_api \{ all_api + api functions \} } +macro all_api {} + +include 'api/kernel32.inc' +include 'api/user32.inc' +include 'api/gdi32.inc' +include 'api/advapi32.inc' +include 'api/comctl32.inc' +include 'api/comdlg32.inc' +include 'api/shell32.inc' +include 'api/wsock32.inc' + +purge import,api + +macro .data { section '.data' data readable writeable } + +macro .code { section '.text' code readable executable } + +macro .end label +{ + entry label + + section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL',\ + user32,'USER32.DLL',\ + gdi32,'GDI32.DLL',\ + advapi32,'ADVAPI32.DLL',\ + comctl32,'COMCTL32.DLL',\ + comdlg32,'COMDLG32.DLL',\ + shell32,'SHELL32.DLL',\ + wsock32,'WSOCK32.DLL' + + import_kernel32 + import_user32 + import_gdi32 + import_advapi32 + import_comctl32 + import_comdlg32 + import_shell32 + import_wsock32 + + all_api +} + +virtual at 0 + xchg eax,eax + detected_16bit = $-1 +end virtual + +if detected_16bit + format PE GUI 4.0 +end if diff --git a/toolchain/fasmw17332/INCLUDE/WIN32W.INC b/toolchain/fasmw17332/INCLUDE/WIN32W.INC new file mode 100644 index 0000000..99e8679 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/WIN32W.INC @@ -0,0 +1,25 @@ + +; Win32 programming headers (WideChar) + +include 'macro/struct.inc' +include 'macro/proc32.inc' +include 'macro/com32.inc' +include 'macro/import32.inc' +include 'macro/export.inc' +include 'macro/resource.inc' + +struc TCHAR [val] { common match any, val \{ . du val \} + match , val \{ . du ? \} } +sizeof.TCHAR = 2 + +include 'equates/kernel32.inc' +include 'equates/user32.inc' +include 'equates/gdi32.inc' +include 'equates/comctl32.inc' +include 'equates/comdlg32.inc' +include 'equates/shell32.inc' +include 'equates/wsock32.inc' + +macro api [name] { if used name + label name dword at name#W + end if } diff --git a/toolchain/fasmw17332/INCLUDE/WIN32WX.INC b/toolchain/fasmw17332/INCLUDE/WIN32WX.INC new file mode 100644 index 0000000..8a31097 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/WIN32WX.INC @@ -0,0 +1,188 @@ + +; Extended Win32 programming headers (WideChar) + +include 'win32w.inc' + +include 'macro/if.inc' + +macro allow_nesting +{ macro pushd value + \{ match ,value \\{ + pushx equ \\} + match =pushx =invoke proc,pushx value \\{ + allow_nesting + invoke proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx =stdcall proc,pushx value \\{ + allow_nesting + stdcall proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx =cinvoke proc,pushx value \\{ + allow_nesting + cinvoke proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx =ccall proc,pushx value \\{ + allow_nesting + ccall proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx,pushx \\{ + pushd + pushx equ \\} + restore pushx \} + macro invoke proc,[arg] + \{ \reverse pushd + \common call [proc] \} + macro stdcall proc,[arg] + \{ \reverse pushd + \common call proc \} + macro cinvoke proc,[arg] + \{ \common \local size + size = 0 + if ~ arg eq + \reverse pushd + size = size+4 + match =double any,arg \\{ size = size+4 \\} + \common end if + call [proc] + if size + add esp,size + end if \} + macro ccall proc,[arg] + \{ \common \local size + size = 0 + if ~ arg eq + \reverse pushd + size = size+4 + match =double any,arg \\{ size = size+4 \\} + \common end if + call proc + if size + add esp,size + end if \} } + +macro pushd value +{ match first=,more, value \{ \local ..alignment,..continue + if sizeof.TCHAR > 1 + local ..alignment + virtual at $+5 + align sizeof.TCHAR + ..alignment = $-$$ + end virtual + times ..alignment nop + end if + call ..continue + du value,0 + ..continue: + pushd equ \} + match pushd =addr var,pushd value \{ \local ..opcode,..address + if +var relativeto 0 | +var relativeto $ + push var + else + lea edx,[var] + push edx + end if + pushd equ \} + match pushd =double [var],pushd value \{ + push dword [var+4] + push dword [var] + pushd equ \} + match pushd =double =ptr var,pushd value \{ + push dword [var+4] + push dword [var] + pushd equ \} + match pushd =double num,pushd value \{ \local ..high,..low + virtual at 0 + dq num + load ..low dword from 0 + load ..high dword from 4 + end virtual + push ..high + push ..low + pushd equ \} + match pushd,pushd \{ \local ..continue + if value eqtype '' + if sizeof.TCHAR > 1 + local ..alignment + virtual at $+5 + align sizeof.TCHAR + ..alignment = $-$$ + end virtual + times ..alignment nop + end if + call ..continue + du value,0 + ..continue: + else + push value + end if + pushd equ \} + restore pushd } + +allow_nesting + +macro import lib,[functions] +{ common macro import_#lib \{ import lib,functions \} } + +macro api [functions] +{ common macro all_api \{ all_api + api functions \} } +macro all_api {} + +include 'api/kernel32.inc' +include 'api/user32.inc' +include 'api/gdi32.inc' +include 'api/advapi32.inc' +include 'api/comctl32.inc' +include 'api/comdlg32.inc' +include 'api/shell32.inc' +include 'api/wsock32.inc' + +purge import,api + +macro .data { section '.data' data readable writeable } + +macro .code { section '.text' code readable executable } + +macro .end label +{ + entry label + + section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL',\ + user32,'USER32.DLL',\ + gdi32,'GDI32.DLL',\ + advapi32,'ADVAPI32.DLL',\ + comctl32,'COMCTL32.DLL',\ + comdlg32,'COMDLG32.DLL',\ + shell32,'SHELL32.DLL',\ + wsock32,'WSOCK32.DLL' + + import_kernel32 + import_user32 + import_gdi32 + import_advapi32 + import_comctl32 + import_comdlg32 + import_shell32 + import_wsock32 + + all_api +} + +virtual at 0 + xchg eax,eax + detected_16bit = $-1 +end virtual + +if detected_16bit + format PE GUI 4.0 +end if diff --git a/toolchain/fasmw17332/INCLUDE/WIN32WXP.INC b/toolchain/fasmw17332/INCLUDE/WIN32WXP.INC new file mode 100644 index 0000000..177fb80 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/WIN32WXP.INC @@ -0,0 +1,201 @@ + +; Extended Win32 programming headers with parameters count checking (WideChar) + +include 'win32w.inc' + +include 'macro/if.inc' + +macro allow_nesting +{ macro pushd value + \{ match ,value \\{ + pushx equ \\} + match =pushx =invoke proc,pushx value \\{ + allow_nesting + invoke proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx =stdcall proc,pushx value \\{ + allow_nesting + stdcall proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx =cinvoke proc,pushx value \\{ + allow_nesting + cinvoke proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx =ccall proc,pushx value \\{ + allow_nesting + ccall proc + purge pushd,invoke,stdcall,cinvoke,ccall + push eax + pushx equ \\} + match =pushx,pushx \\{ + pushd + pushx equ \\} + restore pushx \} + macro invoke proc,[arg] + \{ \common count@stdcall = 0 + if ~ arg eq + \forward count@stdcall = count@stdcall+1 + match =double value, arg \\{ count@stdcall = count@stdcall+1 \\} + \common end if + if proc eqtype 0 & defined proc \# % & count@stdcall <> proc \# % + display "Error: invalid count of parameters for ",\`proc,".",0Dh,0Ah + assert 0 + end if + \reverse pushd + \common call [proc] \} + macro stdcall proc,[arg] + \{ \common count@stdcall = 0 + if ~ arg eq + \forward count@stdcall = count@stdcall+1 + match =double value, arg \\{ count@stdcall = count@stdcall+1 \\} + \common end if + if proc eqtype 0 & defined proc \# % & count@stdcall <> proc \# % + display "Error: invalid count of parameters for ",\`proc,".",0Dh,0Ah + assert 0 + end if + \reverse pushd + \common call proc \} + macro cinvoke proc,[arg] + \{ \common \local size + size = 0 + if ~ arg eq + \reverse pushd + size = size+4 + match =double any,arg \\{ size = size+4 \\} + \common end if + call [proc] + if size + add esp,size + end if \} + macro ccall proc,[arg] + \{ \common \local size + size = 0 + if ~ arg eq + \reverse pushd + size = size+4 + match =double any,arg \\{ size = size+4 \\} + \common end if + call proc + if size + add esp,size + end if \} } + +macro pushd value +{ match first=,more, value \{ \local ..continue + times 1 - (rva $ and 1) nop + call ..continue + du value,0 + ..continue: + pushd equ \} + match pushd =addr var,pushd value \{ \local ..opcode,..address + if +var relativeto 0 | +var relativeto $ + push var + else + lea edx,[var] + push edx + end if + pushd equ \} + match pushd =double [var],pushd value \{ + push dword [var+4] + push dword [var] + pushd equ \} + match pushd =double =ptr var,pushd value \{ + push dword [var+4] + push dword [var] + pushd equ \} + match pushd =double num,pushd value \{ \local ..high,..low + virtual at 0 + dq num + load ..low dword from 0 + load ..high dword from 4 + end virtual + push ..high + push ..low + pushd equ \} + match pushd,pushd \{ \local ..continue + if value eqtype '' + times 1 - (rva $ and 1) nop + call ..continue + du value,0 + ..continue: + else + push value + end if + pushd equ \} + restore pushd } + +allow_nesting + +include 'pcount/kernel32.inc' +include 'pcount/user32.inc' +include 'pcount/gdi32.inc' +include 'pcount/advapi32.inc' +include 'pcount/comctl32.inc' +include 'pcount/comdlg32.inc' +include 'pcount/shell32.inc' +include 'pcount/wsock32.inc' + +macro import lib,[functions] +{ common macro import_#lib \{ import lib,functions \} } + +macro api [functions] +{ common macro all_api \{ all_api + api functions \} } +macro all_api {} + +include 'api/kernel32.inc' +include 'api/user32.inc' +include 'api/gdi32.inc' +include 'api/advapi32.inc' +include 'api/comctl32.inc' +include 'api/comdlg32.inc' +include 'api/shell32.inc' +include 'api/wsock32.inc' + +purge import,api + +macro .data { section '.data' data readable writeable } + +macro .code { section '.text' code readable executable } + +macro .end label +{ + entry label + + section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL',\ + user32,'USER32.DLL',\ + gdi32,'GDI32.DLL',\ + advapi32,'ADVAPI32.DLL',\ + comctl32,'COMCTL32.DLL',\ + comdlg32,'COMDLG32.DLL',\ + shell32,'SHELL32.DLL',\ + wsock32,'WSOCK32.DLL' + + import_kernel32 + import_user32 + import_gdi32 + import_advapi32 + import_comctl32 + import_comdlg32 + import_shell32 + import_wsock32 + + all_api +} + +virtual at 0 + xchg eax,eax + detected_16bit = $-1 +end virtual + +if detected_16bit + format PE GUI 4.0 +end if diff --git a/toolchain/fasmw17332/INCLUDE/WIN64A.INC b/toolchain/fasmw17332/INCLUDE/WIN64A.INC new file mode 100644 index 0000000..51da7fc --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/WIN64A.INC @@ -0,0 +1,25 @@ + +; Win64 programming headers (ASCII) + +include 'macro/struct.inc' +include 'macro/proc64.inc' +include 'macro/com64.inc' +include 'macro/import64.inc' +include 'macro/export.inc' +include 'macro/resource.inc' + +struc TCHAR [val] { common match any, val \{ . db val \} + match , val \{ . db ? \} } +sizeof.TCHAR = 1 + +include 'equates/kernel64.inc' +include 'equates/user64.inc' +include 'equates/gdi64.inc' +include 'equates/comctl64.inc' +include 'equates/comdlg64.inc' +include 'equates/shell64.inc' + +macro api [name] { if used name + label name qword at name#A + end if } + diff --git a/toolchain/fasmw17332/INCLUDE/WIN64AX.INC b/toolchain/fasmw17332/INCLUDE/WIN64AX.INC new file mode 100644 index 0000000..cbc21a5 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/WIN64AX.INC @@ -0,0 +1,205 @@ + +; Extended Win64 programming headers (ASCII) + +include 'win64a.inc' + +include 'macro/if.inc' + +macro allow_nesting +{ macro invoke proc,[arg] + \{ \common fastcall [proc],arg \} + macro fastcall proc,[arg] + \{ \common \local list,counter,flags,outer_frame,nested_frame,..close_nest + match =current@frame,current@frame \\{ + frame + define outer_frame \\} + define counter + define list + flags = 0 + \forward \local param,nested,isfloat,..next + match any,counter \\{ list equ list, \\} + counter equ counter+1 + define param arg + define nested + isfloat = 0 + match =invoke statement,param \\{ + nested equ param + define param \\} + match =fastcall statement,param \\{ + nested equ param + define param \\} + match =float =invoke statement,param \\{ + define nested invoke statement + define param + isfloat = 1 \\} + match =float =fastcall statement,param \\{ + define nested fastcall statement + define param + isfloat = 1 \\} + match statement,nested \\{ + match =nested_frame,nested_frame \\\{ + frame + define nested_frame \\\} + allow_nesting + statement + purge invoke_fastcall + if counter > 4 + if isfloat + movq [rsp+size@frame+(counter-1)*8],xmm0 + else + mov [rsp+size@frame+(counter-1)*8],rax + end if + else + flags = flags or 1 shl (counter-1) + if isfloat + flags = flags or 1 shl (4+counter-1) + end if + if ..close_nest > ..next + if float + movq [rsp+size@frame+(counter-1)*8],xmm0 + else + mov [rsp+size@frame+(counter-1)*8],rax + end if + else + flags = flags or 1 shl (8+counter-1) + end if + end if + ..next: \\} + list equ list + \common ..close_nest: + match ,nested_frame \\{ endf \\} + if flags and 1 + if flags and 1 shl 4 + if ~ flags and 1 shl 8 + movq xmm0,[rsp] + end if + else + if flags and 1 shl 8 + mov rcx,rax + else + mov rcx,[rsp] + end if + end if + end if + if flags and 1 shl 1 + if flags and 1 shl (4+1) + if flags and 1 shl (8+1) + movq xmm1,xmm0 + else + movq xmm1,[rsp+8] + end if + else + if flags and 1 shl (8+1) + mov rdx,rax + else + mov rdx,[rsp+8] + end if + end if + end if + if flags and 1 shl 2 + if flags and 1 shl (4+2) + if flags and 1 shl (8+2) + movq xmm2,xmm0 + else + movq xmm2,[rsp+2*8] + end if + else + if flags and 1 shl (8+2) + mov r8,rax + else + mov r8,[rsp+2*8] + end if + end if + end if + if flags and 1 shl 3 + if flags and 1 shl (4+3) + if flags and 1 shl (8+3) + movq xmm3,xmm0 + else + movq xmm3,[rsp+3*8] + end if + else + if flags and 1 shl (8+3) + mov r9,rax + else + mov r9,[rsp+3*8] + end if + end if + end if + match args,list \\{ fastcall proc,args \\} + match ,list \\{ fastcall proc \\} + match ,outer_frame \\{ endf \\} \} } + +allow_nesting + +macro import lib,[functions] +{ common macro import_#lib \{ import lib,functions \} } + +macro api [functions] +{ common macro all_api \{ all_api + api functions \} } +macro all_api {} + +include 'api/kernel32.inc' +include 'api/user32.inc' +include 'api/gdi32.inc' +include 'api/advapi32.inc' +include 'api/comctl32.inc' +include 'api/comdlg32.inc' +include 'api/shell32.inc' +include 'api/wsock32.inc' + +purge import,api + +macro .data { section '.data' data readable writeable } + +macro .code { + section '.text' code readable executable + entry $ + sub rsp,8 + local main,code + entry equ main + if main <> code + jmp main + end if + code: } + +macro .end value +{ + label entry at value + + section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL',\ + user32,'USER32.DLL',\ + gdi32,'GDI32.DLL',\ + advapi32,'ADVAPI32.DLL',\ + comctl32,'COMCTL32.DLL',\ + comdlg32,'COMDLG32.DLL',\ + shell32,'SHELL32.DLL',\ + wsock32,'WSOCK32.DLL' + + import_kernel32 + import_user32 + import_gdi32 + import_advapi32 + import_comctl32 + import_comdlg32 + import_shell32 + import_wsock32 + + all_api +} + +virtual at 0 + inc ax + if $=1 + detected_16bit = 1 + else + detected_16bit = 0 + end if +end virtual + +if detected_16bit + format PE64 GUI 5.0 +end if diff --git a/toolchain/fasmw17332/INCLUDE/WIN64AXP.INC b/toolchain/fasmw17332/INCLUDE/WIN64AXP.INC new file mode 100644 index 0000000..caa3e2b --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/WIN64AXP.INC @@ -0,0 +1,221 @@ + +; Extended Win64 programming headers with parameters count checking (ASCII) + +include 'win64a.inc' + +include 'macro/if.inc' + +macro allow_nesting +{ macro invoke proc,[arg] + \{ \common fastcall [proc],arg \} + macro fastcall proc,[arg] + \{ \common \local list,counter,flags,outer_frame,nested_frame,..close_nest + match =current@frame,current@frame \\{ + frame + define outer_frame \\} + define counter + define list + flags = 0 + \forward \local param,nested,isfloat,..next + match any,counter \\{ list equ list, \\} + counter equ counter+1 + define param arg + define nested + isfloat = 0 + match =invoke statement,param \\{ + nested equ param + define param \\} + match =fastcall statement,param \\{ + nested equ param + define param \\} + match =float =invoke statement,param \\{ + define nested invoke statement + define param + isfloat = 1 \\} + match =float =fastcall statement,param \\{ + define nested fastcall statement + define param + isfloat = 1 \\} + match statement,nested \\{ + match =nested_frame,nested_frame \\\{ + frame + define nested_frame \\\} + allow_nesting + statement + purge invoke_fastcall + if counter > 4 + if isfloat + movq [rsp+size@frame+(counter-1)*8],xmm0 + else + mov [rsp+size@frame+(counter-1)*8],rax + end if + else + flags = flags or 1 shl (counter-1) + if isfloat + flags = flags or 1 shl (4+counter-1) + end if + if ..close_nest > ..next + if float + movq [rsp+size@frame+(counter-1)*8],xmm0 + else + mov [rsp+size@frame+(counter-1)*8],rax + end if + else + flags = flags or 1 shl (8+counter-1) + end if + end if + ..next: \\} + match any,param \\{ list equ list \\} + \common ..close_nest: + match ,nested_frame \\{ endf \\} + if flags and 1 + if flags and 1 shl 4 + if ~ flags and 1 shl 8 + movq xmm0,[rsp] + end if + else + if flags and 1 shl 8 + mov rcx,rax + else + mov rcx,[rsp] + end if + end if + end if + if flags and 1 shl 1 + if flags and 1 shl (4+1) + if flags and 1 shl (8+1) + movq xmm1,xmm0 + else + movq xmm1,[rsp+8] + end if + else + if flags and 1 shl (8+1) + mov rdx,rax + else + mov rdx,[rsp+8] + end if + end if + end if + if flags and 1 shl 2 + if flags and 1 shl (4+2) + if flags and 1 shl (8+2) + movq xmm2,xmm0 + else + movq xmm2,[rsp+2*8] + end if + else + if flags and 1 shl (8+2) + mov r8,rax + else + mov r8,[rsp+2*8] + end if + end if + end if + if flags and 1 shl 3 + if flags and 1 shl (4+3) + if flags and 1 shl (8+3) + movq xmm3,xmm0 + else + movq xmm3,[rsp+3*8] + end if + else + if flags and 1 shl (8+3) + mov r9,rax + else + mov r9,[rsp+3*8] + end if + end if + end if + match args,list \\{ fastcall proc,args \\} + match ,list \\{ fastcall proc + define counter 0 \\} + match ,outer_frame \\{ endf \\} + proc@paramcheck equ proc + match [name],proc \\{ define proc@paramcheck name \\} + match name,proc@paramcheck \\{ if name eqtype 0 & defined name \\# % & counter <> name \\# % + display "Error: invalid count of parameters for ",\\`name,".",0Dh,0Ah + assert 0 + end if \\} \} } + +allow_nesting + +include 'pcount/kernel32.inc' +include 'pcount/user32.inc' +include 'pcount/gdi32.inc' +include 'pcount/advapi32.inc' +include 'pcount/comctl32.inc' +include 'pcount/comdlg32.inc' +include 'pcount/shell32.inc' +include 'pcount/wsock32.inc' + +macro import lib,[functions] +{ common macro import_#lib \{ import lib,functions \} } + +macro api [functions] +{ common macro all_api \{ all_api + api functions \} } +macro all_api {} + +include 'api/kernel32.inc' +include 'api/user32.inc' +include 'api/gdi32.inc' +include 'api/advapi32.inc' +include 'api/comctl32.inc' +include 'api/comdlg32.inc' +include 'api/shell32.inc' +include 'api/wsock32.inc' + +purge import,api + +macro .data { section '.data' data readable writeable } + +macro .code { + section '.text' code readable executable + entry $ + sub rsp,8 + local main,code + entry equ main + if main <> code + jmp main + end if + code: } + +macro .end value +{ + label entry at value + + section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL',\ + user32,'USER32.DLL',\ + gdi32,'GDI32.DLL',\ + advapi32,'ADVAPI32.DLL',\ + comctl32,'COMCTL32.DLL',\ + comdlg32,'COMDLG32.DLL',\ + shell32,'SHELL32.DLL',\ + wsock32,'WSOCK32.DLL' + + import_kernel32 + import_user32 + import_gdi32 + import_advapi32 + import_comctl32 + import_comdlg32 + import_shell32 + import_wsock32 + + all_api +} + +virtual at 0 + inc ax + if $=1 + detected_16bit = 1 + else + detected_16bit = 0 + end if +end virtual + +if detected_16bit + format PE64 GUI 5.0 +end if diff --git a/toolchain/fasmw17332/INCLUDE/WIN64W.INC b/toolchain/fasmw17332/INCLUDE/WIN64W.INC new file mode 100644 index 0000000..5f444b6 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/WIN64W.INC @@ -0,0 +1,24 @@ + +; Win64 programming headers (WideChar) + +include 'macro/struct.inc' +include 'macro/proc64.inc' +include 'macro/com64.inc' +include 'macro/import64.inc' +include 'macro/export.inc' +include 'macro/resource.inc' + +struc TCHAR [val] { common match any, val \{ . du val \} + match , val \{ . du ? \} } +sizeof.TCHAR = 2 + +include 'equates/kernel64.inc' +include 'equates/user64.inc' +include 'equates/gdi64.inc' +include 'equates/comctl64.inc' +include 'equates/comdlg64.inc' +include 'equates/shell64.inc' + +macro api [name] { if used name + label name qword at name#W + end if } \ No newline at end of file diff --git a/toolchain/fasmw17332/INCLUDE/WIN64WX.INC b/toolchain/fasmw17332/INCLUDE/WIN64WX.INC new file mode 100644 index 0000000..0aaeb31 --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/WIN64WX.INC @@ -0,0 +1,204 @@ + +; Extended Win64 programming headers (WideChar) + +include 'win64w.inc' + +include 'macro/if.inc' + +macro allow_nesting +{ macro invoke proc,[arg] + \{ \common fastcall [proc],arg \} + macro fastcall proc,[arg] + \{ \common \local list,counter,flags,outer_frame,nested_frame,..close_nest + match =current@frame,current@frame \\{ + frame + define outer_frame \\} + define counter + define list + flags = 0 + \forward \local param,nested,isfloat,..next + match any,counter \\{ list equ list, \\} + counter equ counter+1 + define param arg + define nested + isfloat = 0 + match =invoke statement,param \\{ + nested equ param + define param \\} + match =fastcall statement,param \\{ + nested equ param + define param \\} + match =float =invoke statement,param \\{ + define nested invoke statement + define param + isfloat = 1 \\} + match =float =fastcall statement,param \\{ + define nested fastcall statement + define param + isfloat = 1 \\} + match statement,nested \\{ + match =nested_frame,nested_frame \\\{ + frame + define nested_frame \\\} + allow_nesting + statement + purge invoke_fastcall + if counter > 4 + if isfloat + movq [rsp+size@frame+(counter-1)*8],xmm0 + else + mov [rsp+size@frame+(counter-1)*8],rax + end if + else + flags = flags or 1 shl (counter-1) + if isfloat + flags = flags or 1 shl (4+counter-1) + end if + if ..close_nest > ..next + if float + movq [rsp+size@frame+(counter-1)*8],xmm0 + else + mov [rsp+size@frame+(counter-1)*8],rax + end if + else + flags = flags or 1 shl (8+counter-1) + end if + end if + ..next: \\} + list equ list + \common ..close_nest: + match ,nested_frame \\{ endf \\} + if flags and 1 + if flags and 1 shl 4 + if ~ flags and 1 shl 8 + movq xmm0,[rsp] + end if + else + if flags and 1 shl 8 + mov rcx,rax + else + mov rcx,[rsp] + end if + end if + end if + if flags and 1 shl 1 + if flags and 1 shl (4+1) + if flags and 1 shl (8+1) + movq xmm1,xmm0 + else + movq xmm1,[rsp+8] + end if + else + if flags and 1 shl (8+1) + mov rdx,rax + else + mov rdx,[rsp+8] + end if + end if + end if + if flags and 1 shl 2 + if flags and 1 shl (4+2) + if flags and 1 shl (8+2) + movq xmm2,xmm0 + else + movq xmm2,[rsp+2*8] + end if + else + if flags and 1 shl (8+2) + mov r8,rax + else + mov r8,[rsp+2*8] + end if + end if + end if + if flags and 1 shl 3 + if flags and 1 shl (4+3) + if flags and 1 shl (8+3) + movq xmm3,xmm0 + else + movq xmm3,[rsp+3*8] + end if + else + if flags and 1 shl (8+3) + mov r9,rax + else + mov r9,[rsp+3*8] + end if + end if + end if + match args,list \\{ fastcall proc,args \\} + match ,list \\{ fastcall proc \\} + match ,outer_frame \\{ endf \\} \} } + +allow_nesting + +macro import lib,[functions] +{ common macro import_#lib \{ import lib,functions \} } + +macro api [functions] +{ common macro all_api \{ all_api + api functions \} } +macro all_api {} + +include 'api/kernel32.inc' +include 'api/user32.inc' +include 'api/gdi32.inc' +include 'api/advapi32.inc' +include 'api/comctl32.inc' +include 'api/comdlg32.inc' +include 'api/shell32.inc' +include 'api/wsock32.inc' + +purge import,api + +macro .data { section '.data' data readable writeable } +macro .code { + section '.text' code readable executable + entry $ + sub rsp,8 + local main,code + entry equ main + if main <> code + jmp main + end if + code: } + +macro .end value +{ + label entry at value + + section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL',\ + user32,'USER32.DLL',\ + gdi32,'GDI32.DLL',\ + advapi32,'ADVAPI32.DLL',\ + comctl32,'COMCTL32.DLL',\ + comdlg32,'COMDLG32.DLL',\ + shell32,'SHELL32.DLL',\ + wsock32,'WSOCK32.DLL' + + import_kernel32 + import_user32 + import_gdi32 + import_advapi32 + import_comctl32 + import_comdlg32 + import_shell32 + import_wsock32 + + all_api +} + +virtual at 0 + inc ax + if $=1 + detected_16bit = 1 + else + detected_16bit = 0 + end if +end virtual + +if detected_16bit + format PE64 GUI 5.0 +end if diff --git a/toolchain/fasmw17332/INCLUDE/WIN64WXP.INC b/toolchain/fasmw17332/INCLUDE/WIN64WXP.INC new file mode 100644 index 0000000..144caae --- /dev/null +++ b/toolchain/fasmw17332/INCLUDE/WIN64WXP.INC @@ -0,0 +1,221 @@ + +; Extended Win64 programming headers with parameters count checking (WideChar) + +include 'win64w.inc' + +include 'macro/if.inc' + +macro allow_nesting +{ macro invoke proc,[arg] + \{ \common fastcall [proc],arg \} + macro fastcall proc,[arg] + \{ \common \local list,counter,flags,outer_frame,nested_frame,..close_nest + match =current@frame,current@frame \\{ + frame + define outer_frame \\} + define counter + define list + flags = 0 + \forward \local param,nested,isfloat,..next + match any,counter \\{ list equ list, \\} + counter equ counter+1 + define param arg + define nested + isfloat = 0 + match =invoke statement,param \\{ + nested equ param + define param \\} + match =fastcall statement,param \\{ + nested equ param + define param \\} + match =float =invoke statement,param \\{ + define nested invoke statement + define param + isfloat = 1 \\} + match =float =fastcall statement,param \\{ + define nested fastcall statement + define param + isfloat = 1 \\} + match statement,nested \\{ + match =nested_frame,nested_frame \\\{ + frame + define nested_frame \\\} + allow_nesting + statement + purge invoke_fastcall + if counter > 4 + if isfloat + movq [rsp+size@frame+(counter-1)*8],xmm0 + else + mov [rsp+size@frame+(counter-1)*8],rax + end if + else + flags = flags or 1 shl (counter-1) + if isfloat + flags = flags or 1 shl (4+counter-1) + end if + if ..close_nest > ..next + if float + movq [rsp+size@frame+(counter-1)*8],xmm0 + else + mov [rsp+size@frame+(counter-1)*8],rax + end if + else + flags = flags or 1 shl (8+counter-1) + end if + end if + ..next: \\} + match any,param \\{ list equ list \\} + \common ..close_nest: + match ,nested_frame \\{ endf \\} + if flags and 1 + if flags and 1 shl 4 + if ~ flags and 1 shl 8 + movq xmm0,[rsp] + end if + else + if flags and 1 shl 8 + mov rcx,rax + else + mov rcx,[rsp] + end if + end if + end if + if flags and 1 shl 1 + if flags and 1 shl (4+1) + if flags and 1 shl (8+1) + movq xmm1,xmm0 + else + movq xmm1,[rsp+8] + end if + else + if flags and 1 shl (8+1) + mov rdx,rax + else + mov rdx,[rsp+8] + end if + end if + end if + if flags and 1 shl 2 + if flags and 1 shl (4+2) + if flags and 1 shl (8+2) + movq xmm2,xmm0 + else + movq xmm2,[rsp+2*8] + end if + else + if flags and 1 shl (8+2) + mov r8,rax + else + mov r8,[rsp+2*8] + end if + end if + end if + if flags and 1 shl 3 + if flags and 1 shl (4+3) + if flags and 1 shl (8+3) + movq xmm3,xmm0 + else + movq xmm3,[rsp+3*8] + end if + else + if flags and 1 shl (8+3) + mov r9,rax + else + mov r9,[rsp+3*8] + end if + end if + end if + match args,list \\{ fastcall proc,args \\} + match ,list \\{ fastcall proc + define counter 0 \\} + match ,outer_frame \\{ endf \\} + proc@paramcheck equ proc + match [name],proc \\{ define proc@paramcheck name \\} + match name,proc@paramcheck \\{ if name eqtype 0 & defined name \\# % & counter <> name \\# % + display "Error: invalid count of parameters for ",\\`name,".",0Dh,0Ah + assert 0 + end if \\} \} } + +allow_nesting + +include 'pcount/kernel32.inc' +include 'pcount/user32.inc' +include 'pcount/gdi32.inc' +include 'pcount/advapi32.inc' +include 'pcount/comctl32.inc' +include 'pcount/comdlg32.inc' +include 'pcount/shell32.inc' +include 'pcount/wsock32.inc' + +macro import lib,[functions] +{ common macro import_#lib \{ import lib,functions \} } + +macro api [functions] +{ common macro all_api \{ all_api + api functions \} } +macro all_api {} + +include 'api/kernel32.inc' +include 'api/user32.inc' +include 'api/gdi32.inc' +include 'api/advapi32.inc' +include 'api/comctl32.inc' +include 'api/comdlg32.inc' +include 'api/shell32.inc' +include 'api/wsock32.inc' + +purge import,api + +macro .data { section '.data' data readable writeable } + +macro .code { + section '.text' code readable executable + entry $ + sub rsp,8 + local main,code + entry equ main + if main <> code + jmp main + end if + code: } + +macro .end value +{ + label entry at value + + section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL',\ + user32,'USER32.DLL',\ + gdi32,'GDI32.DLL',\ + advapi32,'ADVAPI32.DLL',\ + comctl32,'COMCTL32.DLL',\ + comdlg32,'COMDLG32.DLL',\ + shell32,'SHELL32.DLL',\ + wsock32,'WSOCK32.DLL' + + import_kernel32 + import_user32 + import_gdi32 + import_advapi32 + import_comctl32 + import_comdlg32 + import_shell32 + import_wsock32 + + all_api +} + +virtual at 0 + inc ax + if $=1 + detected_16bit = 1 + else + detected_16bit = 0 + end if +end virtual + +if detected_16bit + format PE64 GUI 5.0 +end if diff --git a/toolchain/fasmw17332/LICENSE.TXT b/toolchain/fasmw17332/LICENSE.TXT new file mode 100644 index 0000000..80e0643 --- /dev/null +++ b/toolchain/fasmw17332/LICENSE.TXT @@ -0,0 +1,37 @@ + +flat assembler version 1.73 +Copyright (c) 1999-2024, Tomasz Grysztar. +All rights reserved. + +This program is free for commercial and non-commercial use as long as +the following conditions are adhered to. + +Copyright remains Tomasz Grysztar, and as such any Copyright notices +in the code are not to be removed. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The licence and distribution terms for any publically available +version or derivative of this code cannot be changed. i.e. this code +cannot simply be copied and put under another distribution licence +(including the GNU Public Licence). diff --git a/toolchain/fasmw17332/SOURCE/ASSEMBLE.INC b/toolchain/fasmw17332/SOURCE/ASSEMBLE.INC new file mode 100644 index 0000000..4ed969b --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/ASSEMBLE.INC @@ -0,0 +1,2235 @@ + +; flat assembler core +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +assembler: + xor eax,eax + mov [stub_size],eax + mov [current_pass],ax + mov [resolver_flags],eax + mov [number_of_sections],eax + mov [actual_fixups_size],eax + assembler_loop: + mov eax,[labels_list] + mov [tagged_blocks],eax + mov eax,[additional_memory] + mov [free_additional_memory],eax + mov eax,[additional_memory_end] + mov [structures_buffer],eax + mov esi,[source_start] + mov edi,[code_start] + xor eax,eax + mov dword [adjustment],eax + mov dword [adjustment+4],eax + mov [addressing_space],eax + mov [error_line],eax + mov [counter],eax + mov [format_flags],eax + mov [number_of_relocations],eax + mov [undefined_data_end],eax + mov [file_extension],eax + mov [next_pass_needed],al + mov [output_format],al + mov [adjustment_sign],al + mov [evex_mode],al + mov [code_type],16 + call init_addressing_space + pass_loop: + call assemble_line + jnc pass_loop + mov eax,[additional_memory_end] + cmp eax,[structures_buffer] + je pass_done + sub eax,18h + mov eax,[eax+4] + mov [current_line],eax + jmp missing_end_directive + pass_done: + call close_pass + mov eax,[labels_list] + check_symbols: + cmp eax,[memory_end] + jae symbols_checked + test byte [eax+8],8 + jz symbol_defined_ok + mov cx,[current_pass] + cmp cx,[eax+18] + jne symbol_defined_ok + test byte [eax+8],1 + jz symbol_defined_ok + sub cx,[eax+16] + cmp cx,1 + jne symbol_defined_ok + and byte [eax+8],not 1 + or [next_pass_needed],-1 + symbol_defined_ok: + test byte [eax+8],10h + jz use_prediction_ok + mov cx,[current_pass] + and byte [eax+8],not 10h + test byte [eax+8],20h + jnz check_use_prediction + cmp cx,[eax+18] + jne use_prediction_ok + test byte [eax+8],8 + jz use_prediction_ok + jmp use_misprediction + check_use_prediction: + test byte [eax+8],8 + jz use_misprediction + cmp cx,[eax+18] + je use_prediction_ok + use_misprediction: + or [next_pass_needed],-1 + use_prediction_ok: + test byte [eax+8],40h + jz check_next_symbol + and byte [eax+8],not 40h + test byte [eax+8],4 + jnz define_misprediction + mov cx,[current_pass] + test byte [eax+8],80h + jnz check_define_prediction + cmp cx,[eax+16] + jne check_next_symbol + test byte [eax+8],1 + jz check_next_symbol + jmp define_misprediction + check_define_prediction: + test byte [eax+8],1 + jz define_misprediction + cmp cx,[eax+16] + je check_next_symbol + define_misprediction: + or [next_pass_needed],-1 + check_next_symbol: + add eax,LABEL_STRUCTURE_SIZE + jmp check_symbols + symbols_checked: + cmp [next_pass_needed],0 + jne next_pass + mov eax,[error_line] + or eax,eax + jz assemble_ok + mov [current_line],eax + cmp [error],undefined_symbol + jne error_confirmed + mov eax,[error_info] + or eax,eax + jz error_confirmed + test byte [eax+8],1 + jnz next_pass + error_confirmed: + call error_handler + error_handler: + mov eax,[error] + sub eax,error_handler + add [esp],eax + ret + next_pass: + inc [current_pass] + mov ax,[current_pass] + cmp ax,[passes_limit] + je code_cannot_be_generated + jmp assembler_loop + assemble_ok: + ret + +create_addressing_space: + mov ebx,[addressing_space] + test ebx,ebx + jz init_addressing_space + test byte [ebx+0Ah],1 + jnz illegal_instruction + mov eax,edi + sub eax,[ebx+18h] + mov [ebx+1Ch],eax + init_addressing_space: + mov ebx,[tagged_blocks] + mov dword [ebx-4],10h + mov dword [ebx-8],24h + sub ebx,8+24h + cmp ebx,edi + jbe out_of_memory + mov [tagged_blocks],ebx + mov [addressing_space],ebx + xor eax,eax + mov [ebx],edi + mov [ebx+4],eax + mov [ebx+8],eax + mov [ebx+10h],eax + mov [ebx+14h],eax + mov [ebx+18h],edi + mov [ebx+1Ch],eax + mov [ebx+20h],eax + ret + +assemble_line: + mov eax,[tagged_blocks] + sub eax,100h + cmp edi,eax + ja out_of_memory + lods byte [esi] + cmp al,1 + je assemble_instruction + jb source_end + cmp al,3 + jb define_label + je define_constant + cmp al,4 + je label_addressing_space + cmp al,0Fh + je new_line + cmp al,13h + je code_type_setting + cmp al,10h + jne illegal_instruction + lods byte [esi] + jmp segment_prefix + code_type_setting: + lods byte [esi] + mov [code_type],al + jmp instruction_assembled + new_line: + lods dword [esi] + mov [current_line],eax + and [prefix_flags],0 + cmp [symbols_file],0 + je continue_line + cmp [next_pass_needed],0 + jne continue_line + mov ebx,[tagged_blocks] + mov dword [ebx-4],1 + mov dword [ebx-8],14h + sub ebx,8+14h + cmp ebx,edi + jbe out_of_memory + mov [tagged_blocks],ebx + mov [ebx],eax + mov [ebx+4],edi + mov eax,[addressing_space] + mov [ebx+8],eax + mov al,[code_type] + mov [ebx+10h],al + continue_line: + cmp byte [esi],0Fh + je line_assembled + jmp assemble_line + define_label: + lods dword [esi] + cmp eax,0Fh + jb invalid_use_of_symbol + je reserved_word_used_as_symbol + mov ebx,eax + lods byte [esi] + mov [label_size],al + call make_label + jmp continue_line + make_label: + mov eax,edi + xor edx,edx + xor cl,cl + mov ebp,[addressing_space] + sub eax,[ds:ebp] + sbb edx,[ds:ebp+4] + sbb cl,[ds:ebp+8] + jp label_value_ok + call recoverable_overflow + label_value_ok: + mov [address_sign],cl + test byte [ds:ebp+0Ah],1 + jnz make_virtual_label + or byte [ebx+9],1 + xchg eax,[ebx] + xchg edx,[ebx+4] + mov ch,[ebx+9] + shr ch,1 + and ch,1 + neg ch + sub eax,[ebx] + sbb edx,[ebx+4] + sbb ch,cl + mov dword [adjustment],eax + mov dword [adjustment+4],edx + mov [adjustment_sign],ch + or al,ch + or eax,edx + setnz ah + jmp finish_label + make_virtual_label: + and byte [ebx+9],not 1 + cmp eax,[ebx] + mov [ebx],eax + setne ah + cmp edx,[ebx+4] + mov [ebx+4],edx + setne al + or ah,al + finish_label: + mov ebp,[addressing_space] + mov ch,[ds:ebp+9] + mov cl,[label_size] + mov edx,[ds:ebp+14h] + mov ebp,[ds:ebp+10h] + finish_label_symbol: + mov al,[address_sign] + xor al,[ebx+9] + and al,10b + or ah,al + xor [ebx+9],al + cmp cl,[ebx+10] + mov [ebx+10],cl + setne al + or ah,al + cmp ch,[ebx+11] + mov [ebx+11],ch + setne al + or ah,al + cmp ebp,[ebx+12] + mov [ebx+12],ebp + setne al + or ah,al + or ch,ch + jz label_symbol_ok + cmp edx,[ebx+20] + mov [ebx+20],edx + setne al + or ah,al + label_symbol_ok: + mov cx,[current_pass] + xchg [ebx+16],cx + mov edx,[current_line] + mov [ebx+28],edx + and byte [ebx+8],not 2 + test byte [ebx+8],1 + jz new_label + cmp cx,[ebx+16] + je symbol_already_defined + btr dword [ebx+8],10 + jc requalified_label + inc cx + sub cx,[ebx+16] + setnz al + or ah,al + jz label_made + test byte [ebx+8],8 + jz label_made + mov cx,[current_pass] + cmp cx,[ebx+18] + jne label_made + requalified_label: + or [next_pass_needed],-1 + label_made: + ret + new_label: + or byte [ebx+8],1 + ret + define_constant: + lods dword [esi] + inc esi + cmp eax,0Fh + jb invalid_use_of_symbol + je reserved_word_used_as_symbol + push eax + or [operand_flags],1 + call get_value + pop ebx + xor cl,cl + mov ch,[value_type] + cmp ch,3 + je invalid_use_of_symbol + make_constant: + and byte [ebx+9],not 1 + cmp eax,[ebx] + mov [ebx],eax + setne ah + cmp edx,[ebx+4] + mov [ebx+4],edx + setne al + or ah,al + mov al,[value_sign] + xor al,[ebx+9] + and al,10b + or ah,al + xor [ebx+9],al + cmp cl,[ebx+10] + mov [ebx+10],cl + setne al + or ah,al + cmp ch,[ebx+11] + mov [ebx+11],ch + setne al + or ah,al + xor edx,edx + cmp edx,[ebx+12] + mov [ebx+12],edx + setne al + or ah,al + or ch,ch + jz constant_symbol_ok + mov edx,[symbol_identifier] + cmp edx,[ebx+20] + mov [ebx+20],edx + setne al + or ah,al + constant_symbol_ok: + mov cx,[current_pass] + xchg [ebx+16],cx + mov edx,[current_line] + mov [ebx+28],edx + test byte [ebx+8],1 + jz new_constant + cmp cx,[ebx+16] + jne redeclare_constant + test byte [ebx+8],2 + jz symbol_already_defined + or byte [ebx+8],4 + and byte [ebx+9],not 4 + jmp instruction_assembled + redeclare_constant: + btr dword [ebx+8],10 + jc requalified_constant + inc cx + sub cx,[ebx+16] + setnz al + or ah,al + jz instruction_assembled + test byte [ebx+8],4 + jnz instruction_assembled + test byte [ebx+8],8 + jz instruction_assembled + mov cx,[current_pass] + cmp cx,[ebx+18] + jne instruction_assembled + requalified_constant: + or [next_pass_needed],-1 + jmp instruction_assembled + new_constant: + or byte [ebx+8],1+2 + jmp instruction_assembled + label_addressing_space: + lods dword [esi] + cmp eax,0Fh + jb invalid_use_of_symbol + je reserved_word_used_as_symbol + mov cx,[current_pass] + test byte [eax+8],1 + jz make_addressing_space_label + cmp cx,[eax+16] + je symbol_already_defined + test byte [eax+9],4 + jnz make_addressing_space_label + or [next_pass_needed],-1 + make_addressing_space_label: + mov dx,[eax+8] + and dx,not (2 or 100h) + or dx,1 or 4 or 400h + mov [eax+8],dx + mov [eax+16],cx + mov edx,[current_line] + mov [eax+28],edx + mov ebx,[addressing_space] + mov [eax],ebx + or byte [ebx+0Ah],2 + jmp continue_line + assemble_instruction: +; mov [operand_size],0 +; mov [operand_flags],0 +; mov [operand_prefix],0 +; mov [rex_prefix],0 + and dword [operand_size],0 +; mov [opcode_prefix],0 +; mov [vex_required],0 +; mov [vex_register],0 +; mov [immediate_size],0 + and dword [opcode_prefix],0 + call instruction_handler + instruction_handler: + movzx ebx,word [esi] + mov al,[esi+2] + add esi,3 + add [esp],ebx + ret + instruction_assembled: + test [prefix_flags],not 1 + jnz illegal_instruction + mov al,[esi] + cmp al,0Fh + je line_assembled + or al,al + jnz extra_characters_on_line + line_assembled: + clc + ret + source_end: + dec esi + stc + ret + +org_directive: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_qword_value + mov cl,[value_type] + test cl,1 + jnz invalid_use_of_symbol + push eax + mov ebx,[addressing_space] + mov eax,edi + sub eax,[ebx+18h] + mov [ebx+1Ch],eax + test byte [ebx+0Ah],1 + jnz in_virtual + call init_addressing_space + jmp org_space_ok + in_virtual: + call close_virtual_addressing_space + call init_addressing_space + or byte [ebx+0Ah],1 + org_space_ok: + pop eax + mov [ebx+9],cl + mov cl,[value_sign] + sub [ebx],eax + sbb [ebx+4],edx + sbb byte [ebx+8],cl + jp org_value_ok + call recoverable_overflow + org_value_ok: + mov edx,[symbol_identifier] + mov [ebx+14h],edx + cmp [output_format],1 + ja instruction_assembled + cmp edi,[code_start] + jne instruction_assembled + cmp eax,100h + jne instruction_assembled + bts [format_flags],0 + jmp instruction_assembled +label_directive: + lods byte [esi] + cmp al,2 + jne invalid_argument + lods dword [esi] + cmp eax,0Fh + jb invalid_use_of_symbol + je reserved_word_used_as_symbol + inc esi + mov ebx,eax + mov [label_size],0 + lods byte [esi] + cmp al,':' + je get_label_size + dec esi + cmp al,11h + jne label_size_ok + get_label_size: + lods word [esi] + cmp al,11h + jne invalid_argument + mov [label_size],ah + label_size_ok: + cmp byte [esi],80h + je get_free_label_value + call make_label + jmp instruction_assembled + get_free_label_value: + inc esi + lods byte [esi] + cmp al,'(' + jne invalid_argument + push ebx ecx + or byte [ebx+8],4 + cmp byte [esi],'.' + je invalid_value + call get_address_value + or bh,bh + setnz ch + xchg ch,cl + mov bp,cx + shl ebp,16 + xchg bl,bh + mov bp,bx + pop ecx ebx + and byte [ebx+8],not 4 + mov ch,[value_type] + test ch,1 + jnz invalid_use_of_symbol + make_free_label: + and byte [ebx+9],not 1 + cmp eax,[ebx] + mov [ebx],eax + setne ah + cmp edx,[ebx+4] + mov [ebx+4],edx + setne al + or ah,al + mov edx,[address_symbol] + mov cl,[label_size] + call finish_label_symbol + jmp instruction_assembled +load_directive: + lods byte [esi] + cmp al,2 + jne invalid_argument + lods dword [esi] + cmp eax,0Fh + jb invalid_use_of_symbol + je reserved_word_used_as_symbol + inc esi + push eax + mov al,1 + cmp byte [esi],11h + jne load_size_ok + lods byte [esi] + lods byte [esi] + load_size_ok: + cmp al,8 + ja invalid_value + mov [operand_size],al + and dword [value],0 + and dword [value+4],0 + lods byte [esi] + cmp al,82h + jne invalid_argument + call get_data_point + jc value_loaded + push esi edi + mov esi,ebx + mov edi,value + rep movs byte [edi],[esi] + pop edi esi + value_loaded: + mov [value_sign],0 + mov eax,dword [value] + mov edx,dword [value+4] + pop ebx + xor cx,cx + jmp make_constant + get_data_point: + lods byte [esi] + cmp al,':' + je get_data_offset + cmp al,'(' + jne invalid_argument + mov ebx,[addressing_space] + mov ecx,edi + sub ecx,[ebx+18h] + mov [ebx+1Ch],ecx + cmp byte [esi],11h + jne get_data_address + cmp word [esi+1+4],'):' + jne get_data_address + inc esi + lods dword [esi] + add esi,2 + cmp byte [esi],'(' + jne invalid_argument + inc esi + cmp eax,0Fh + jbe reserved_word_used_as_symbol + mov edx,undefined_symbol + test byte [eax+8],1 + jz addressing_space_unavailable + mov edx,symbol_out_of_scope + mov cx,[eax+16] + cmp cx,[current_pass] + jne addressing_space_unavailable + test byte [eax+9],4 + jz invalid_use_of_symbol + mov ebx,eax + mov ax,[current_pass] + mov [ebx+18],ax + or byte [ebx+8],8 + call store_label_reference + get_addressing_space: + mov ebx,[ebx] + get_data_address: + push ebx + cmp byte [esi],'.' + je invalid_value + or [operand_flags],1 + call get_address_value + pop ebp + call calculate_relative_offset + cmp [next_pass_needed],0 + jne data_address_type_ok + cmp [value_type],0 + jne invalid_use_of_symbol + data_address_type_ok: + mov ebx,edi + xor ecx,ecx + add ebx,eax + adc edx,ecx + mov eax,ebx + sub eax,[ds:ebp+18h] + sbb edx,ecx + jnz bad_data_address + mov cl,[operand_size] + add eax,ecx + cmp eax,[ds:ebp+1Ch] + ja bad_data_address + clc + ret + addressing_space_unavailable: + cmp [error_line],0 + jne get_data_address + push [current_line] + pop [error_line] + mov [error],edx + mov [error_info],eax + jmp get_data_address + bad_data_address: + call recoverable_overflow + stc + ret + get_data_offset: + cmp [output_format],2 + jae invalid_operand + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_dword_value + cmp [value_type],0 + je data_offset_ok + call recoverable_invalid_address + data_offset_ok: + add eax,[code_start] + jc bad_data_address + mov ebx,eax + movzx ecx,[operand_size] + add eax,ecx + jc bad_data_address + mov edx,[addressing_space] + test byte [edx+0Ah],1 + jnz data_offset_from_virtual + cmp eax,edi + ja bad_data_address + clc + ret + data_offset_from_virtual: + cmp eax,[undefined_data_end] + ja bad_data_address + clc + ret + +store_directive: + cmp byte [esi],11h + je sized_store + lods byte [esi] + cmp al,'(' + jne invalid_argument + call get_byte_value + xor edx,edx + movzx eax,al + mov [operand_size],1 + jmp store_value_ok + sized_store: + or [operand_flags],1 + call get_value + store_value_ok: + cmp [value_type],0 + jne invalid_use_of_symbol + mov dword [value],eax + mov dword [value+4],edx + lods byte [esi] + cmp al,80h + jne invalid_argument + call get_data_point + jc instruction_assembled + push esi edi + mov esi,value + mov edi,ebx + rep movs byte [edi],[esi] + mov eax,edi + pop edi esi + cmp ebx,[undefined_data_end] + jae instruction_assembled + cmp eax,[undefined_data_start] + jbe instruction_assembled + mov [undefined_data_start],eax + jmp instruction_assembled + +display_directive: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],0 + jne display_byte + inc esi + lods dword [esi] + mov ecx,eax + push edi + mov edi,[tagged_blocks] + sub edi,8 + sub edi,eax + cmp edi,[esp] + jbe out_of_memory + mov [tagged_blocks],edi + rep movs byte [edi],[esi] + stos dword [edi] + xor eax,eax + stos dword [edi] + pop edi + inc esi + jmp display_next + display_byte: + call get_byte_value + push edi + mov edi,[tagged_blocks] + sub edi,8+1 + mov [tagged_blocks],edi + stos byte [edi] + mov eax,1 + stos dword [edi] + dec eax + stos dword [edi] + pop edi + display_next: + cmp edi,[tagged_blocks] + ja out_of_memory + lods byte [esi] + cmp al,',' + je display_directive + dec esi + jmp instruction_assembled +show_display_buffer: + mov eax,[tagged_blocks] + or eax,eax + jz display_done + mov esi,[labels_list] + cmp esi,eax + je display_done + display_messages: + sub esi,8 + mov eax,[esi+4] + mov ecx,[esi] + sub esi,ecx + cmp eax,10h + je write_addressing_space + test eax,eax + jnz skip_block + push esi + call display_block + pop esi + skip_block: + cmp esi,[tagged_blocks] + jne display_messages + display_done: + ret + write_addressing_space: + mov ecx,[esi+20h] + jecxz skip_block + push esi + mov edi,[free_additional_memory] + mov esi,[output_file] + test esi,esi + jz addressing_space_written + xor ebx,ebx + copy_output_path: + lodsb + cmp edi,[structures_buffer] + jae out_of_memory + stosb + test al,al + jz output_path_copied + cmp al,'/' + je new_path_segment + cmp al,'\' + je new_path_segment + cmp al,'.' + jne copy_output_path + mov ebx,edi + jmp copy_output_path + new_path_segment: + xor ebx,ebx + jmp copy_output_path + output_path_copied: + test ebx,ebx + jnz append_extension + mov byte [edi-1],'.' + mov ebx,edi + append_extension: + mov edi,ebx + add ebx,ecx + inc ebx + cmp ebx,[structures_buffer] + jae out_of_memory + mov esi,[esp] + mov esi,[esi+18h] + sub esi,ecx + rep movs byte [edi],[esi] + xor al,al + stos byte [edi] + mov edx,[free_additional_memory] + call create + jc write_failed + mov esi,[esp] + mov edx,[esi+18h] + mov ecx,[esi+1Ch] + call write + jc write_failed + call close + addressing_space_written: + pop esi + jmp skip_block + +times_directive: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_count_value + cmp eax,0 + je zero_times + cmp byte [esi],':' + jne times_argument_ok + inc esi + times_argument_ok: + push [counter] + push [counter_limit] + mov [counter_limit],eax + mov [counter],1 + times_loop: + mov eax,esp + sub eax,[stack_limit] + cmp eax,100h + jb stack_overflow + push esi + or [prefix_flags],1 + call continue_line + mov eax,[counter_limit] + cmp [counter],eax + je times_done + inc [counter] + pop esi + jmp times_loop + times_done: + pop eax + pop [counter_limit] + pop [counter] + jmp instruction_assembled + zero_times: + call skip_symbol + jnc zero_times + jmp instruction_assembled + +virtual_directive: + lods byte [esi] + cmp al,'(' + je continue_virtual_area + cmp al,80h + jne virtual_at_current + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_address_value + mov ebp,[address_symbol] + or bh,bh + setnz ch + jmp set_virtual + virtual_at_current: + dec esi + virtual_fallback: + mov ebp,[addressing_space] + mov al,[ds:ebp+9] + mov [value_type],al + mov eax,edi + xor edx,edx + xor cl,cl + sub eax,[ds:ebp] + sbb edx,[ds:ebp+4] + sbb cl,[ds:ebp+8] + mov [address_sign],cl + mov bx,[ds:ebp+10h] + mov cx,[ds:ebp+10h+2] + xchg bh,bl + xchg ch,cl + mov ebp,[ds:ebp+14h] + set_virtual: + xchg bl,bh + xchg cl,ch + shl ecx,16 + mov cx,bx + push ecx eax + mov ebx,[addressing_space] + test byte [ebx+0Ah],1 + jnz non_virtual_end_ok + mov eax,edi + xchg eax,[undefined_data_end] + cmp eax,edi + je non_virtual_end_ok + mov [undefined_data_start],edi + non_virtual_end_ok: + call allocate_virtual_structure_data + call init_addressing_space + or byte [ebx+0Ah],1 + cmp byte [esi],86h + jne addressing_space_extension_ok + cmp word [esi+1],'(' + jne invalid_argument + mov ecx,[esi+3] + add esi,3+4 + add [ebx+18h],ecx + mov [ebx+20h],ecx + or byte [ebx+0Ah],2 + push ebx + mov ebx,characters + get_extension: + lods byte [esi] + stos byte [edi] + xlat byte [ebx] + test al,al + jz invalid_argument + loop get_extension + inc esi + pop ebx + addressing_space_extension_ok: + pop eax + mov cl,[address_sign] + not eax + not edx + not cl + add eax,1 + adc edx,0 + adc cl,0 + add eax,edi + adc edx,0 + adc cl,0 + mov [ebx],eax + mov [ebx+4],edx + mov [ebx+8],cl + pop dword [ebx+10h] + mov [ebx+14h],ebp + mov al,[value_type] + test al,1 + jnz invalid_use_of_symbol + mov [ebx+9],al + jmp instruction_assembled + allocate_structure_data: + mov ebx,[structures_buffer] + sub ebx,18h + cmp ebx,[free_additional_memory] + jb out_of_memory + mov [structures_buffer],ebx + ret + find_structure_data: + mov ebx,[structures_buffer] + scan_structures: + cmp ebx,[additional_memory_end] + je no_such_structure + cmp ax,[ebx] + je structure_data_found + add ebx,18h + jmp scan_structures + structure_data_found: + ret + no_such_structure: + stc + ret + allocate_virtual_structure_data: + call allocate_structure_data + mov word [ebx],virtual_directive-instruction_handler + mov ecx,[addressing_space] + mov [ebx+12],ecx + mov [ebx+8],edi + mov ecx,[current_line] + mov [ebx+4],ecx + mov ebx,[addressing_space] + mov eax,edi + sub eax,[ebx+18h] + mov [ebx+1Ch],eax + ret + continue_virtual_area: + cmp byte [esi],11h + jne invalid_argument + cmp byte [esi+1+4],')' + jne invalid_argument + inc esi + lods dword [esi] + inc esi + cmp eax,0Fh + jbe reserved_word_used_as_symbol + mov edx,undefined_symbol + test byte [eax+8],1 + jz virtual_area_unavailable + mov edx,symbol_out_of_scope + mov cx,[eax+16] + cmp cx,[current_pass] + jne virtual_area_unavailable + mov edx,invalid_use_of_symbol + test byte [eax+9],4 + jz virtual_area_unavailable + mov ebx,eax + mov ax,[current_pass] + mov [ebx+18],ax + or byte [ebx+8],8 + call store_label_reference + mov ebx,[ebx] + test byte [ebx+0Ah],4 + jz virtual_area_unavailable + and byte [ebx+0Ah],not 4 + mov edx,ebx + call allocate_virtual_structure_data + mov [addressing_space],edx + push esi + mov esi,[edx+18h] + mov ecx,[edx+1Ch] + mov eax,[edx+20h] + sub esi,eax + add ecx,eax + lea eax,[edi+ecx] + cmp eax,[tagged_blocks] + jae out_of_memory + mov eax,esi + sub eax,edi + sub [edx+18h],eax + sub [edx],eax + sbb dword [edx+4],0 + sbb byte [edx+8],0 + mov al,cl + shr ecx,2 + rep movs dword [edi],[esi] + mov cl,al + and cl,11b + rep movs byte [edi],[esi] + pop esi + jmp instruction_assembled + virtual_area_unavailable: + cmp [error_line],0 + jne virtual_fallback + push [current_line] + pop [error_line] + mov [error],edx + mov [error_info],eax + jmp virtual_fallback + end_virtual: + call find_structure_data + jc unexpected_instruction + push ebx + call close_virtual_addressing_space + pop ebx + mov eax,[ebx+12] + mov [addressing_space],eax + mov edi,[ebx+8] + remove_structure_data: + push esi edi + mov ecx,ebx + sub ecx,[structures_buffer] + shr ecx,2 + lea esi,[ebx-4] + lea edi,[esi+18h] + std + rep movs dword [edi],[esi] + cld + add [structures_buffer],18h + pop edi esi + ret + close_virtual_addressing_space: + mov ebx,[addressing_space] + mov eax,edi + sub eax,[ebx+18h] + mov [ebx+1Ch],eax + add eax,[ebx+20h] + test byte [ebx+0Ah],2 + jz addressing_space_closed + or byte [ebx+0Ah],4 + push esi edi ecx edx + mov ecx,eax + mov eax,[tagged_blocks] + mov dword [eax-4],11h + mov dword [eax-8],ecx + sub eax,8 + sub eax,ecx + mov [tagged_blocks],eax + lea edi,[eax+ecx-1] + add eax,[ebx+20h] + xchg eax,[ebx+18h] + sub eax,[ebx+20h] + lea esi,[eax+ecx-1] + mov eax,edi + sub eax,esi + std + shr ecx,1 + jnc virtual_byte_ok + movs byte [edi],[esi] + virtual_byte_ok: + dec esi + dec edi + shr ecx,1 + jnc virtual_word_ok + movs word [edi],[esi] + virtual_word_ok: + sub esi,2 + sub edi,2 + rep movs dword [edi],[esi] + cld + xor edx,edx + add [ebx],eax + adc dword [ebx+4],edx + adc byte [ebx+8],dl + pop edx ecx edi esi + addressing_space_closed: + ret +repeat_directive: + test [prefix_flags],1 + jnz unexpected_instruction + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_count_value + cmp eax,0 + je zero_repeat + call allocate_structure_data + mov word [ebx],repeat_directive-instruction_handler + xchg eax,[counter_limit] + mov [ebx+10h],eax + mov eax,1 + xchg eax,[counter] + mov [ebx+14h],eax + mov [ebx+8],esi + mov eax,[current_line] + mov [ebx+4],eax + jmp instruction_assembled + end_repeat: + test [prefix_flags],1 + jnz unexpected_instruction + call find_structure_data + jc unexpected_instruction + mov eax,[counter_limit] + inc [counter] + cmp [counter],eax + jbe continue_repeating + stop_repeat: + mov eax,[ebx+10h] + mov [counter_limit],eax + mov eax,[ebx+14h] + mov [counter],eax + call remove_structure_data + jmp instruction_assembled + continue_repeating: + mov esi,[ebx+8] + jmp instruction_assembled + zero_repeat: + mov al,[esi] + or al,al + jz missing_end_directive + cmp al,0Fh + jne extra_characters_on_line + call find_end_repeat + jmp instruction_assembled + find_end_repeat: + call find_structure_end + cmp ax,repeat_directive-instruction_handler + jne unexpected_instruction + ret +while_directive: + test [prefix_flags],1 + jnz unexpected_instruction + call allocate_structure_data + mov word [ebx],while_directive-instruction_handler + mov eax,1 + xchg eax,[counter] + mov [ebx+10h],eax + mov [ebx+8],esi + mov eax,[current_line] + mov [ebx+4],eax + do_while: + push ebx + call calculate_logical_expression + or al,al + jnz while_true + mov al,[esi] + or al,al + jz missing_end_directive + cmp al,0Fh + jne extra_characters_on_line + stop_while: + call find_end_while + pop ebx + mov eax,[ebx+10h] + mov [counter],eax + call remove_structure_data + jmp instruction_assembled + while_true: + pop ebx + jmp instruction_assembled + end_while: + test [prefix_flags],1 + jnz unexpected_instruction + call find_structure_data + jc unexpected_instruction + mov eax,[ebx+4] + mov [current_line],eax + inc [counter] + jz too_many_repeats + mov esi,[ebx+8] + jmp do_while + find_end_while: + call find_structure_end + cmp ax,while_directive-instruction_handler + jne unexpected_instruction + ret +if_directive: + test [prefix_flags],1 + jnz unexpected_instruction + call calculate_logical_expression + mov dl,al + mov al,[esi] + or al,al + jz missing_end_directive + cmp al,0Fh + jne extra_characters_on_line + or dl,dl + jnz if_true + call find_else + jc instruction_assembled + mov al,[esi] + cmp al,1 + jne else_true + cmp word [esi+1],if_directive-instruction_handler + jne else_true + add esi,4 + jmp if_directive + if_true: + xor al,al + make_if_structure: + call allocate_structure_data + mov word [ebx],if_directive-instruction_handler + mov byte [ebx+2],al + mov eax,[current_line] + mov [ebx+4],eax + jmp instruction_assembled + else_true: + or al,al + jz missing_end_directive + cmp al,0Fh + jne extra_characters_on_line + or al,-1 + jmp make_if_structure + else_directive: + test [prefix_flags],1 + jnz unexpected_instruction + mov ax,if_directive-instruction_handler + call find_structure_data + jc unexpected_instruction + cmp byte [ebx+2],0 + jne unexpected_instruction + found_else: + mov al,[esi] + cmp al,1 + jne skip_else + cmp word [esi+1],if_directive-instruction_handler + jne skip_else + add esi,4 + call find_else + jnc found_else + call remove_structure_data + jmp instruction_assembled + skip_else: + or al,al + jz missing_end_directive + cmp al,0Fh + jne extra_characters_on_line + call find_end_if + call remove_structure_data + jmp instruction_assembled + end_if: + test [prefix_flags],1 + jnz unexpected_instruction + call find_structure_data + jc unexpected_instruction + call remove_structure_data + jmp instruction_assembled + find_else: + call find_structure_end + cmp ax,else_directive-instruction_handler + je else_found + cmp ax,if_directive-instruction_handler + jne unexpected_instruction + stc + ret + else_found: + clc + ret + find_end_if: + call find_structure_end + cmp ax,if_directive-instruction_handler + jne unexpected_instruction + ret + find_structure_end: + push [error_line] + mov eax,[current_line] + mov [error_line],eax + find_end_directive: + call skip_symbol + jnc find_end_directive + lods byte [esi] + cmp al,0Fh + jne no_end_directive + lods dword [esi] + mov [current_line],eax + skip_labels: + cmp byte [esi],2 + jne labels_ok + add esi,6 + jmp skip_labels + labels_ok: + cmp byte [esi],1 + jne find_end_directive + mov ax,[esi+1] + cmp ax,prefix_instruction-instruction_handler + je find_end_directive + add esi,4 + cmp ax,repeat_directive-instruction_handler + je skip_repeat + cmp ax,while_directive-instruction_handler + je skip_while + cmp ax,if_directive-instruction_handler + je skip_if + cmp ax,else_directive-instruction_handler + je structure_end + cmp ax,end_directive-instruction_handler + jne find_end_directive + cmp byte [esi],1 + jne find_end_directive + mov ax,[esi+1] + add esi,4 + cmp ax,repeat_directive-instruction_handler + je structure_end + cmp ax,while_directive-instruction_handler + je structure_end + cmp ax,if_directive-instruction_handler + jne find_end_directive + structure_end: + pop [error_line] + ret + no_end_directive: + mov eax,[error_line] + mov [current_line],eax + jmp missing_end_directive + skip_repeat: + call find_end_repeat + jmp find_end_directive + skip_while: + call find_end_while + jmp find_end_directive + skip_if: + call skip_if_block + jmp find_end_directive + skip_if_block: + call find_else + jc if_block_skipped + cmp byte [esi],1 + jne skip_after_else + cmp word [esi+1],if_directive-instruction_handler + jne skip_after_else + add esi,4 + jmp skip_if_block + skip_after_else: + call find_end_if + if_block_skipped: + ret +end_directive: + lods byte [esi] + cmp al,1 + jne invalid_argument + lods word [esi] + inc esi + cmp ax,virtual_directive-instruction_handler + je end_virtual + cmp ax,repeat_directive-instruction_handler + je end_repeat + cmp ax,while_directive-instruction_handler + je end_while + cmp ax,if_directive-instruction_handler + je end_if + cmp ax,data_directive-instruction_handler + je end_data + jmp invalid_argument +break_directive: + mov ebx,[structures_buffer] + mov al,[esi] + or al,al + jz find_breakable_structure + cmp al,0Fh + jne extra_characters_on_line + find_breakable_structure: + cmp ebx,[additional_memory_end] + je unexpected_instruction + mov ax,[ebx] + cmp ax,repeat_directive-instruction_handler + je break_repeat + cmp ax,while_directive-instruction_handler + je break_while + cmp ax,if_directive-instruction_handler + je break_if + add ebx,18h + jmp find_breakable_structure + break_if: + push [current_line] + mov eax,[ebx+4] + mov [current_line],eax + call remove_structure_data + call skip_if_block + pop [current_line] + mov ebx,[structures_buffer] + jmp find_breakable_structure + break_repeat: + push ebx + call find_end_repeat + pop ebx + jmp stop_repeat + break_while: + push ebx + jmp stop_while + +define_data: + cmp edi,[tagged_blocks] + jae out_of_memory + cmp byte [esi],'(' + jne simple_data_value + mov ebx,esi + inc esi + call skip_expression + xchg esi,ebx + cmp byte [ebx],81h + jne simple_data_value + inc esi + call get_count_value + inc esi + or eax,eax + jz duplicate_zero_times + cmp byte [esi],91h + jne duplicate_single_data_value + inc esi + duplicate_data: + push eax esi + duplicated_values: + cmp edi,[tagged_blocks] + jae out_of_memory + clc + call near dword [esp+8] + lods byte [esi] + cmp al,',' + je duplicated_values + cmp al,92h + jne invalid_argument + pop ebx eax + dec eax + jz data_defined + mov esi,ebx + jmp duplicate_data + duplicate_single_data_value: + cmp edi,[tagged_blocks] + jae out_of_memory + push eax esi + clc + call near dword [esp+8] + pop ebx eax + dec eax + jz data_defined + mov esi,ebx + jmp duplicate_single_data_value + duplicate_zero_times: + cmp byte [esi],91h + jne skip_single_data_value + inc esi + skip_data_value: + call skip_symbol + jc invalid_argument + cmp byte [esi],92h + jne skip_data_value + inc esi + jmp data_defined + skip_single_data_value: + call skip_symbol + jmp data_defined + simple_data_value: + cmp edi,[tagged_blocks] + jae out_of_memory + clc + call near dword [esp] + data_defined: + lods byte [esi] + cmp al,',' + je define_data + dec esi + stc + ret +data_bytes: + call define_data + jc instruction_assembled + lods byte [esi] + cmp al,'(' + je get_byte + cmp al,'?' + jne invalid_argument + mov eax,edi + mov byte [edi],0 + inc edi + jmp undefined_data + get_byte: + cmp byte [esi],0 + je get_string + call get_byte_value + stos byte [edi] + ret + get_string: + inc esi + lods dword [esi] + mov ecx,eax + lea eax,[edi+ecx] + cmp eax,[tagged_blocks] + ja out_of_memory + rep movs byte [edi],[esi] + inc esi + ret + undefined_data: + mov ebp,[addressing_space] + test byte [ds:ebp+0Ah],1 + jz mark_undefined_data + ret + mark_undefined_data: + cmp eax,[undefined_data_end] + je undefined_data_ok + mov [undefined_data_start],eax + undefined_data_ok: + mov [undefined_data_end],edi + ret +data_unicode: + or [base_code],-1 + jmp define_words +data_words: + mov [base_code],0 + define_words: + call define_data + jc instruction_assembled + lods byte [esi] + cmp al,'(' + je get_word + cmp al,'?' + jne invalid_argument + mov eax,edi + and word [edi],0 + scas word [edi] + jmp undefined_data + ret + get_word: + cmp [base_code],0 + je word_data_value + cmp byte [esi],0 + je word_string + word_data_value: + call get_word_value + call mark_relocation + stos word [edi] + ret + word_string: + inc esi + lods dword [esi] + mov ecx,eax + jecxz word_string_ok + lea eax,[edi+ecx*2] + cmp eax,[tagged_blocks] + ja out_of_memory + xor ah,ah + copy_word_string: + lods byte [esi] + stos word [edi] + loop copy_word_string + word_string_ok: + inc esi + ret +data_dwords: + call define_data + jc instruction_assembled + lods byte [esi] + cmp al,'(' + je get_dword + cmp al,'?' + jne invalid_argument + mov eax,edi + and dword [edi],0 + scas dword [edi] + jmp undefined_data + get_dword: + push esi + call get_dword_value + pop ebx + cmp byte [esi],':' + je complex_dword + call mark_relocation + stos dword [edi] + ret + complex_dword: + mov esi,ebx + cmp byte [esi],'.' + je invalid_value + call get_word_value + push eax + inc esi + lods byte [esi] + cmp al,'(' + jne invalid_operand + mov al,[value_type] + push eax + cmp byte [esi],'.' + je invalid_value + call get_word_value + call mark_relocation + stos word [edi] + pop eax + mov [value_type],al + pop eax + call mark_relocation + stos word [edi] + ret +data_pwords: + call define_data + jc instruction_assembled + lods byte [esi] + cmp al,'(' + je get_pword + cmp al,'?' + jne invalid_argument + mov eax,edi + and dword [edi],0 + scas dword [edi] + and word [edi],0 + scas word [edi] + jmp undefined_data + get_pword: + push esi + call get_pword_value + pop ebx + cmp byte [esi],':' + je complex_pword + call mark_relocation + stos dword [edi] + mov ax,dx + stos word [edi] + ret + complex_pword: + mov esi,ebx + cmp byte [esi],'.' + je invalid_value + call get_word_value + push eax + inc esi + lods byte [esi] + cmp al,'(' + jne invalid_operand + mov al,[value_type] + push eax + cmp byte [esi],'.' + je invalid_value + call get_dword_value + call mark_relocation + stos dword [edi] + pop eax + mov [value_type],al + pop eax + call mark_relocation + stos word [edi] + ret +data_qwords: + call define_data + jc instruction_assembled + lods byte [esi] + cmp al,'(' + je get_qword + cmp al,'?' + jne invalid_argument + mov eax,edi + and dword [edi],0 + scas dword [edi] + and dword [edi],0 + scas dword [edi] + jmp undefined_data + get_qword: + call get_qword_value + call mark_relocation + stos dword [edi] + mov eax,edx + stos dword [edi] + ret +data_twords: + call define_data + jc instruction_assembled + lods byte [esi] + cmp al,'(' + je get_tword + cmp al,'?' + jne invalid_argument + mov eax,edi + and dword [edi],0 + scas dword [edi] + and dword [edi],0 + scas dword [edi] + and word [edi],0 + scas word [edi] + jmp undefined_data + get_tword: + cmp byte [esi],'.' + jne complex_tword + inc esi + cmp word [esi+8],8000h + je fp_zero_tword + mov eax,[esi] + stos dword [edi] + mov eax,[esi+4] + stos dword [edi] + mov ax,[esi+8] + add ax,3FFFh + jo value_out_of_range + cmp ax,7FFFh + jge value_out_of_range + cmp ax,0 + jg tword_exp_ok + mov cx,ax + neg cx + inc cx + cmp cx,64 + jae value_out_of_range + cmp cx,32 + ja large_shift + mov eax,[esi] + mov edx,[esi+4] + mov ebx,edx + shr edx,cl + shrd eax,ebx,cl + jmp tword_mantissa_shift_done + large_shift: + sub cx,32 + xor edx,edx + mov eax,[esi+4] + shr eax,cl + tword_mantissa_shift_done: + jnc store_shifted_mantissa + add eax,1 + adc edx,0 + store_shifted_mantissa: + mov [edi-8],eax + mov [edi-4],edx + xor ax,ax + test edx,1 shl 31 + jz tword_exp_ok + inc ax + tword_exp_ok: + mov bl,[esi+11] + shl bx,15 + or ax,bx + stos word [edi] + add esi,13 + ret + fp_zero_tword: + xor eax,eax + stos dword [edi] + stos dword [edi] + mov al,[esi+11] + shl ax,15 + stos word [edi] + add esi,13 + ret + complex_tword: + call get_word_value + push eax + cmp byte [esi],':' + jne invalid_operand + inc esi + lods byte [esi] + cmp al,'(' + jne invalid_operand + mov al,[value_type] + push eax + cmp byte [esi],'.' + je invalid_value + call get_qword_value + call mark_relocation + stos dword [edi] + mov eax,edx + stos dword [edi] + pop eax + mov [value_type],al + pop eax + call mark_relocation + stos word [edi] + ret +data_file: + lods word [esi] + cmp ax,'(' + jne invalid_argument + add esi,4 + call open_binary_file + mov eax,[esi-4] + lea esi,[esi+eax+1] + mov al,2 + xor edx,edx + call lseek + push eax + xor edx,edx + cmp byte [esi],':' + jne position_ok + inc esi + cmp byte [esi],'(' + jne invalid_argument + inc esi + cmp byte [esi],'.' + je invalid_value + push ebx + call get_count_value + pop ebx + mov edx,eax + sub [esp],edx + jc value_out_of_range + position_ok: + cmp byte [esi],',' + jne size_ok + inc esi + cmp byte [esi],'(' + jne invalid_argument + inc esi + cmp byte [esi],'.' + je invalid_value + push ebx edx + call get_count_value + pop edx ebx + cmp eax,[esp] + ja value_out_of_range + mov [esp],eax + size_ok: + xor al,al + call lseek + pop ecx + mov edx,edi + add edi,ecx + jc out_of_memory + cmp edi,[tagged_blocks] + ja out_of_memory + call read + jc error_reading_file + call close + lods byte [esi] + cmp al,',' + je data_file + dec esi + jmp instruction_assembled + open_binary_file: + push esi + push edi + mov eax,[current_line] + find_current_source_path: + mov esi,[eax] + test byte [eax+7],80h + jz get_current_path + mov eax,[eax+8] + jmp find_current_source_path + get_current_path: + lodsb + stosb + or al,al + jnz get_current_path + cut_current_path: + cmp edi,[esp] + je current_path_ok + cmp byte [edi-1],'\' + je current_path_ok + cmp byte [edi-1],'/' + je current_path_ok + dec edi + jmp cut_current_path + current_path_ok: + mov esi,[esp+4] + call expand_path + pop edx + mov esi,edx + call open + jnc file_opened + mov edx,[include_paths] + search_in_include_paths: + push edx esi + mov edi,esi + mov esi,[esp+4] + call get_include_directory + mov [esp+4],esi + mov esi,[esp+8] + call expand_path + pop edx + mov esi,edx + call open + pop edx + jnc file_opened + cmp byte [edx],0 + jne search_in_include_paths + mov edi,esi + mov esi,[esp] + push edi + call expand_path + pop edx + mov esi,edx + call open + jc file_not_found + file_opened: + mov edi,esi + pop esi + ret +reserve_bytes: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_count_value + mov ecx,eax + mov edx,ecx + add edx,edi + jc out_of_memory + cmp edx,[tagged_blocks] + ja out_of_memory + push edi + cmp [next_pass_needed],0 + je zero_bytes + add edi,ecx + jmp reserved_data + zero_bytes: + xor eax,eax + shr ecx,1 + jnc bytes_stosb_ok + stos byte [edi] + bytes_stosb_ok: + shr ecx,1 + jnc bytes_stosw_ok + stos word [edi] + bytes_stosw_ok: + rep stos dword [edi] + reserved_data: + pop eax + call undefined_data + jmp instruction_assembled +reserve_words: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_count_value + mov ecx,eax + mov edx,ecx + shl edx,1 + jc out_of_memory + add edx,edi + jc out_of_memory + cmp edx,[tagged_blocks] + ja out_of_memory + push edi + cmp [next_pass_needed],0 + je zero_words + lea edi,[edi+ecx*2] + jmp reserved_data + zero_words: + xor eax,eax + shr ecx,1 + jnc words_stosw_ok + stos word [edi] + words_stosw_ok: + rep stos dword [edi] + jmp reserved_data +reserve_dwords: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_count_value + mov ecx,eax + mov edx,ecx + shl edx,1 + jc out_of_memory + shl edx,1 + jc out_of_memory + add edx,edi + jc out_of_memory + cmp edx,[tagged_blocks] + ja out_of_memory + push edi + cmp [next_pass_needed],0 + je zero_dwords + lea edi,[edi+ecx*4] + jmp reserved_data + zero_dwords: + xor eax,eax + rep stos dword [edi] + jmp reserved_data +reserve_pwords: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_count_value + mov ecx,eax + shl ecx,1 + jc out_of_memory + add ecx,eax + mov edx,ecx + shl edx,1 + jc out_of_memory + add edx,edi + jc out_of_memory + cmp edx,[tagged_blocks] + ja out_of_memory + push edi + cmp [next_pass_needed],0 + je zero_words + lea edi,[edi+ecx*2] + jmp reserved_data +reserve_qwords: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_count_value + mov ecx,eax + shl ecx,1 + jc out_of_memory + mov edx,ecx + shl edx,1 + jc out_of_memory + shl edx,1 + jc out_of_memory + add edx,edi + jc out_of_memory + cmp edx,[tagged_blocks] + ja out_of_memory + push edi + cmp [next_pass_needed],0 + je zero_dwords + lea edi,[edi+ecx*4] + jmp reserved_data +reserve_twords: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_count_value + mov ecx,eax + shl ecx,2 + jc out_of_memory + add ecx,eax + mov edx,ecx + shl edx,1 + jc out_of_memory + add edx,edi + jc out_of_memory + cmp edx,[tagged_blocks] + ja out_of_memory + push edi + cmp [next_pass_needed],0 + je zero_words + lea edi,[edi+ecx*2] + jmp reserved_data +align_directive: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_count_value + mov edx,eax + dec edx + test eax,edx + jnz invalid_align_value + or eax,eax + jz invalid_align_value + cmp eax,1 + je instruction_assembled + mov ecx,edi + mov ebp,[addressing_space] + sub ecx,[ds:ebp] + cmp dword [ds:ebp+10h],0 + jne section_not_aligned_enough + cmp byte [ds:ebp+9],0 + je make_alignment + cmp [output_format],3 + je pe_alignment + cmp [output_format],5 + jne object_alignment + test [format_flags],1 + jnz pe_alignment + object_alignment: + mov ebx,[ds:ebp+14h] + cmp byte [ebx],0 + jne section_not_aligned_enough + cmp eax,[ebx+10h] + jbe make_alignment + jmp section_not_aligned_enough + pe_alignment: + cmp eax,1000h + ja section_not_aligned_enough + make_alignment: + dec eax + and ecx,eax + jz instruction_assembled + neg ecx + add ecx,eax + inc ecx + mov edx,ecx + add edx,edi + jc out_of_memory + cmp edx,[tagged_blocks] + ja out_of_memory + push edi + cmp [next_pass_needed],0 + je nops + add edi,ecx + jmp reserved_data + invalid_align_value: + cmp [error_line],0 + jne instruction_assembled + mov eax,[current_line] + mov [error_line],eax + mov [error],invalid_value + jmp instruction_assembled + nops: + mov eax,90909090h + shr ecx,1 + jnc nops_stosb_ok + stos byte [edi] + nops_stosb_ok: + shr ecx,1 + jnc nops_stosw_ok + stos word [edi] + nops_stosw_ok: + rep stos dword [edi] + jmp reserved_data +err_directive: + mov al,[esi] + cmp al,0Fh + je invoked_error + or al,al + jz invoked_error + jmp extra_characters_on_line +assert_directive: + call calculate_logical_expression + or al,al + jnz instruction_assembled + cmp [error_line],0 + jne instruction_assembled + mov eax,[current_line] + mov [error_line],eax + mov [error],assertion_failed + jmp instruction_assembled diff --git a/toolchain/fasmw17332/SOURCE/AVX.INC b/toolchain/fasmw17332/SOURCE/AVX.INC new file mode 100644 index 0000000..073fc73 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/AVX.INC @@ -0,0 +1,3425 @@ + +; flat assembler core +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +avx_single_source_pd_instruction_er_evex: + or [vex_required],8 +avx_single_source_pd_instruction_er: + or [operand_flags],2+4+8 + jmp avx_pd_instruction +avx_single_source_pd_instruction_sae_evex: + or [vex_required],8 + or [operand_flags],2+4 + jmp avx_pd_instruction +avx_pd_instruction_imm8: + mov [immediate_size],1 + jmp avx_pd_instruction +avx_pd_instruction_er: + or [operand_flags],8 +avx_pd_instruction_sae: + or [operand_flags],4 +avx_pd_instruction: + mov [opcode_prefix],66h + or [rex_prefix],80h + mov cx,0800h + jmp avx_instruction_with_broadcast +avx_pd_instruction_38_evex: + or [vex_required],8 + mov [supplemental_code],al + mov al,38h + jmp avx_pd_instruction +avx_cvtps2dq_instruction: + mov [opcode_prefix],66h + jmp avx_single_source_ps_instruction_er +avx_cvtudq2ps_instruction: + mov [opcode_prefix],0F2h +avx_single_source_ps_instruction_er_evex: + or [vex_required],8 +avx_single_source_ps_instruction_er: + or [operand_flags],2+4+8 + jmp avx_ps_instruction +avx_single_source_ps_instruction_noevex: + or [operand_flags],2 + or [vex_required],2 + jmp avx_ps_instruction +avx_ps_instruction_imm8: + mov [immediate_size],1 + jmp avx_ps_instruction +avx_ps_instruction_er: + or [operand_flags],8 +avx_ps_instruction_sae: + or [operand_flags],4 +avx_ps_instruction: + mov cx,0400h + jmp avx_instruction_with_broadcast +avx_ps_instruction_66_38_evex: + or [vex_required],8 + mov [opcode_prefix],66h + mov [supplemental_code],al + mov al,38h + jmp avx_ps_instruction +avx_sd_instruction_er: + or [operand_flags],8 +avx_sd_instruction_sae: + or [operand_flags],4 +avx_sd_instruction: + mov [opcode_prefix],0F2h + or [rex_prefix],80h + mov cl,8 + jmp avx_instruction +avx_ss_instruction_er: + or [operand_flags],8 +avx_ss_instruction_sae: + or [operand_flags],4 +avx_ss_instruction: + mov [opcode_prefix],0F3h + mov cl,4 + jmp avx_instruction +avx_ss_instruction_noevex: + or [vex_required],2 + jmp avx_ss_instruction +avx_single_source_q_instruction_38_evex: + or [operand_flags],2 +avx_q_instruction_38_evex: + or [vex_required],8 +avx_q_instruction_38: + mov [supplemental_code],al + mov al,38h + jmp avx_q_instruction +avx_q_instruction_38_w1_evex: + or [vex_required],8 +avx_q_instruction_38_w1: + or [rex_prefix],8 + jmp avx_q_instruction_38 +avx_q_instruction_3a_imm8_w1: + or [rex_prefix],8 + jmp avx_q_instruction_3a_imm8 +avx_q_instruction_3a_imm8_evex: + or [vex_required],8 +avx_q_instruction_3a_imm8: + mov [immediate_size],1 + mov [supplemental_code],al + mov al,3Ah + jmp avx_q_instruction +avx_q_instruction_evex: + or [vex_required],8 +avx_q_instruction: + or [rex_prefix],80h + mov ch,8 + jmp avx_pi_instruction +avx_single_source_d_instruction_38_evex_w1: + or [rex_prefix],8 +avx_single_source_d_instruction_38_evex: + or [vex_required],8 +avx_single_source_d_instruction_38: + or [operand_flags],2 + jmp avx_d_instruction_38 +avx_d_instruction_38_evex: + or [vex_required],8 +avx_d_instruction_38: + mov [supplemental_code],al + mov al,38h + jmp avx_d_instruction +avx_d_instruction_3a_imm8_evex: + mov [immediate_size],1 + or [vex_required],8 + mov [supplemental_code],al + mov al,3Ah + jmp avx_d_instruction +avx_single_source_d_instruction_imm8: + or [operand_flags],2 + mov [immediate_size],1 + jmp avx_d_instruction +avx_d_instruction_evex: + or [vex_required],8 +avx_d_instruction: + mov ch,4 + jmp avx_pi_instruction +avx_bw_instruction_3a_imm8_w1_evex: + or [rex_prefix],8 +avx_bw_instruction_3a_imm8_evex: + mov [immediate_size],1 + or [vex_required],8 + mov [supplemental_code],al + mov al,3Ah + jmp avx_bw_instruction +avx_single_source_bw_instruction_38: + or [operand_flags],2 +avx_bw_instruction_38: + mov [supplemental_code],al + mov al,38h +avx_bw_instruction: + xor ch,ch + avx_pi_instruction: + mov [opcode_prefix],66h + xor cl,cl + jmp avx_instruction_with_broadcast +avx_bw_instruction_38_w1_evex: + or [rex_prefix],8 +avx_bw_instruction_38_evex: + or [vex_required],8 + jmp avx_bw_instruction_38 +avx_pd_instruction_noevex: + xor cl,cl + or [vex_required],2 + mov [opcode_prefix],66h + jmp avx_instruction +avx_ps_instruction_noevex: + or [vex_required],2 + mov [opcode_prefix],0F2h + xor cl,cl + jmp avx_instruction +avx_instruction: + xor ch,ch + avx_instruction_with_broadcast: + mov [mmx_size],cl + mov [broadcast_size],ch + mov [base_code],0Fh + mov [extended_code],al + avx_xop_common: + or [vex_required],1 + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + avx_reg: + lods byte [esi] + call convert_avx_register + mov [postbyte_register],al + call take_avx512_mask + avx_vex_reg: + test [operand_flags],2 + jnz avx_vex_reg_ok + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [vex_register],al + avx_vex_reg_ok: + mov al,[mmx_size] + or al,al + jz avx_regs_size_ok + mov ah,[operand_size] + or ah,ah + jz avx_regs_size_ok + cmp al,ah + je avx_regs_size_ok + ja invalid_operand_size + cmp ah,16 + jne invalid_operand_size + avx_regs_size_ok: + lods byte [esi] + cmp al,',' + jne invalid_operand + avx_regs_rm: + call take_avx_rm + jc avx_regs_reg + mov al,[immediate_size] + cmp al,1 + je mmx_imm8 + jb instruction_ready + cmp al,-4 + je sse_cmp_mem_ok + cmp byte [esi],',' + jne invalid_operand + inc esi + call take_avx_register + shl al,4 + jc invalid_operand + or byte [value],al + test al,80h + jz avx_regs_mem_reg_store + cmp [code_type],64 + jne invalid_operand + avx_regs_mem_reg_store: + call take_imm4_if_needed + call store_instruction_with_imm8 + jmp instruction_assembled + avx_regs_reg: + mov bl,al + call take_avx512_rounding + mov al,[immediate_size] + cmp al,1 + je mmx_nomem_imm8 + jb nomem_instruction_ready + cmp al,-4 + je sse_cmp_nomem_ok + lods byte [esi] + cmp al,',' + jne invalid_operand + mov al,bl + shl al,4 + jc invalid_operand + or byte [value],al + test al,80h + jz avx_regs_reg_ + cmp [code_type],64 + jne invalid_operand + avx_regs_reg_: + call take_avx_rm + jc avx_regs_reg_reg + cmp [immediate_size],-2 + jg invalid_operand + or [rex_prefix],8 + call take_imm4_if_needed + call store_instruction_with_imm8 + jmp instruction_assembled + avx_regs_reg_reg: + shl al,4 + jc invalid_operand + and byte [value],1111b + or byte [value],al + call take_imm4_if_needed + call store_nomem_instruction + mov al,byte [value] + stos byte [edi] + jmp instruction_assembled + take_avx_rm: + xor cl,cl + xchg cl,[operand_size] + lods byte [esi] + call get_size_operator + cmp al,'[' + je take_avx_mem + cmp al,10h + jne invalid_operand + mov [operand_size],cl + lods byte [esi] + call convert_avx_register + or cl,cl + jnz avx_reg_ok + or cl,[mmx_size] + jz avx_reg_ok + cmp ah,cl + je avx_reg_ok + jb invalid_operand_size + cmp ah,16 + jne invalid_operand_size + avx_reg_ok: + stc + ret + take_avx_mem: + push ecx + call get_address + cmp byte [esi],'{' + jne avx_mem_ok + inc esi + lods byte [esi] + cmp al,1Fh + jne invalid_operand + mov al,[esi] + shr al,4 + cmp al,1 + jne invalid_operand + mov al,[mmx_size] + or al,al + jnz avx_mem_broadcast_check + mov eax,[esp] + or al,al + jnz avx_mem_broadcast_check + mov al,[broadcast_size] + mov [mmx_size],al + mov ah,cl + lods byte [esi] + and al,1111b + mov cl,al + mov al,[broadcast_size] + shl al,cl + mov [esp],al + mov cl,ah + jmp avx_mem_broadcast_ok + avx_mem_broadcast_check: + bsf eax,eax + xchg al,[broadcast_size] + mov [mmx_size],al + bsf eax,eax + jz invalid_operand + mov ah,[broadcast_size] + sub ah,al + lods byte [esi] + and al,1111b + cmp al,ah + jne invalid_operand_size + avx_mem_broadcast_ok: + or [vex_required],40h + lods byte [esi] + cmp al,'}' + jne invalid_operand + avx_mem_ok: + pop eax + or al,al + jz avx_mem_size_deciding + xchg al,[operand_size] + cmp [mmx_size],0 + jne avx_mem_size_enforced + or al,al + jz avx_mem_size_ok + cmp al,[operand_size] + jne operand_sizes_do_not_match + avx_mem_size_ok: + clc + ret + avx_mem_size_deciding: + mov al,[operand_size] + cmp [mmx_size],0 + jne avx_mem_size_enforced + cmp al,16 + je avx_mem_size_ok + cmp al,32 + je avx_mem_size_ok + cmp al,64 + je avx_mem_size_ok + or al,al + jnz invalid_operand_size + call recoverable_unknown_size + avx_mem_size_enforced: + or al,al + jz avx_mem_size_ok + cmp al,[mmx_size] + je avx_mem_size_ok + jmp invalid_operand_size + take_imm4_if_needed: + cmp [immediate_size],-3 + jne imm4_ok + push ebx ecx edx + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + cmp al,'(' + jne invalid_operand + call get_byte_value + test al,11110000b + jnz value_out_of_range + or byte [value],al + pop edx ecx ebx + imm4_ok: + ret + take_avx512_mask: + cmp byte [esi],'{' + jne avx512_masking_ok + test [operand_flags],10h + jnz invalid_operand + inc esi + lods byte [esi] + cmp al,14h + jne invalid_operand + lods byte [esi] + mov ah,al + shr ah,4 + cmp ah,5 + jne invalid_operand + and al,111b + or al,al + jz invalid_operand + mov [mask_register],al + or [vex_required],20h + lods byte [esi] + cmp al,'}' + jne invalid_operand + cmp byte [esi],'{' + jne avx512_masking_ok + test [operand_flags],20h + jnz invalid_operand + inc esi + lods byte [esi] + cmp al,1Fh + jne invalid_operand + lods byte [esi] + or al,al + jnz invalid_operand + or [mask_register],80h + lods byte [esi] + cmp al,'}' + jne invalid_operand + avx512_masking_ok: + retn + take_avx512_rounding: + test [operand_flags],4+8 + jz avx512_rounding_done + test [operand_flags],8 + jz avx512_rounding_allowed + cmp [mmx_size],0 + jne avx512_rounding_allowed + cmp [operand_size],64 + jne avx512_rounding_done + avx512_rounding_allowed: + cmp byte [esi],',' + jne avx512_rounding_done + cmp byte [esi+1],'{' + jne avx512_rounding_done + add esi,2 + mov [rounding_mode],0 + or [vex_required],40h + test [operand_flags],8 + jz take_sae + or [vex_required],80h + lods byte [esi] + cmp al,1Fh + jne invalid_operand + lods byte [esi] + mov ah,al + shr ah,4 + cmp ah,2 + jne invalid_operand + and al,11b + mov [rounding_mode],al + lods byte [esi] + cmp al,'-' + jne invalid_operand + take_sae: + lods byte [esi] + cmp al,1Fh + jne invalid_operand + lods byte [esi] + cmp al,30h + jne invalid_operand + lods byte [esi] + cmp al,'}' + jne invalid_operand + avx512_rounding_done: + retn + +avx_movdqu_instruction: + mov ah,0F3h + jmp avx_movdq_instruction +avx_movdqa_instruction: + mov ah,66h + avx_movdq_instruction: + mov [opcode_prefix],ah + or [vex_required],2 + jmp avx_movps_instruction +avx512_movdqu16_instruction: + or [rex_prefix],8 +avx512_movdqu8_instruction: + mov ah,0F2h + jmp avx_movdq_instruction_evex +avx512_movdqu64_instruction: + or [rex_prefix],8 +avx512_movdqu32_instruction: + mov ah,0F3h + jmp avx_movdq_instruction_evex +avx512_movdqa64_instruction: + or [rex_prefix],8 +avx512_movdqa32_instruction: + mov ah,66h + avx_movdq_instruction_evex: + mov [opcode_prefix],ah + or [vex_required],8 + jmp avx_movps_instruction +avx_movpd_instruction: + mov [opcode_prefix],66h + or [rex_prefix],80h +avx_movps_instruction: + or [operand_flags],2 + mov [base_code],0Fh + mov [extended_code],al + or [vex_required],1 + xor al,al + mov [mmx_size],al + mov [broadcast_size],al + lods byte [esi] + call get_size_operator + cmp al,10h + je avx_reg + inc [extended_code] + test [extended_code],1 + jnz avx_mem + add [extended_code],-1+10h + avx_mem: + cmp al,'[' + jne invalid_operand + call get_address + or [operand_flags],20h + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [postbyte_register],al + jmp instruction_ready +avx_movntpd_instruction: + or [rex_prefix],80h +avx_movntdq_instruction: + mov [opcode_prefix],66h +avx_movntps_instruction: + mov [base_code],0Fh + mov [extended_code],al + or [vex_required],1 + or [operand_flags],10h + mov [mmx_size],0 + lods byte [esi] + call get_size_operator + jmp avx_mem +avx_compress_q_instruction: + or [rex_prefix],8 +avx_compress_d_instruction: + or [vex_required],8 + mov [mmx_size],0 + call setup_66_0f_38 + lods byte [esi] + call get_size_operator + cmp al,10h + jne avx_mem + lods byte [esi] + call convert_avx_register + mov bl,al + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [postbyte_register],al + jmp nomem_instruction_ready +avx_lddqu_instruction: + mov ah,0F2h + or [vex_required],2 + avx_load_instruction: + mov [opcode_prefix],ah + mov [base_code],0Fh + mov [extended_code],al + mov [mmx_size],0 + or [vex_required],1 + call take_avx_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + jmp instruction_ready +avx_movntdqa_instruction: + mov [supplemental_code],al + mov al,38h + mov ah,66h + jmp avx_load_instruction +avx_movq_instruction: + or [rex_prefix],8 + mov [mmx_size],8 + jmp avx_mov_instruction +avx_movd_instruction: + mov [mmx_size],4 + avx_mov_instruction: + or [vex_required],1 + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],7Eh + lods byte [esi] + call get_size_operator + cmp al,10h + je avx_movd_reg + cmp al,'[' + jne invalid_operand + call get_address + mov al,[mmx_size] + not al + and [operand_size],al + jnz invalid_operand_size + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_avx_register + cmp ah,16 + jne invalid_operand_size + mov [postbyte_register],al + cmp [mmx_size],8 + jne instruction_ready + and [rex_prefix],not 8 + or [rex_prefix],80h + mov [extended_code],0D6h + jmp instruction_ready + avx_movd_reg: + lods byte [esi] + cmp al,0C0h + jae avx_movd_xmmreg + call convert_register + cmp ah,[mmx_size] + jne invalid_operand_size + mov [operand_size],0 + mov bl,al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_avx_register + cmp ah,16 + jne invalid_operand_size + mov [postbyte_register],al + avx_movd_reg_ready: + test [rex_prefix],8 + jz nomem_instruction_ready + cmp [code_type],64 + jne illegal_instruction + jmp nomem_instruction_ready + avx_movd_xmmreg: + sub [extended_code],10h + call convert_avx_register + cmp ah,16 + jne invalid_operand_size + mov [postbyte_register],al + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je avx_movd_xmmreg_reg + cmp al,'[' + jne invalid_operand + call get_address + mov al,[mmx_size] + cmp al,8 + jne avx_movd_xmmreg_mem_ready + call avx_movq_xmmreg_xmmreg_opcode + avx_movd_xmmreg_mem_ready: + not al + test [operand_size],al + jnz invalid_operand_size + jmp instruction_ready + avx_movd_xmmreg_reg: + lods byte [esi] + cmp al,0C0h + jae avx_movq_xmmreg_xmmreg + call convert_register + cmp ah,[mmx_size] + jne invalid_operand_size + mov bl,al + jmp avx_movd_reg_ready + avx_movq_xmmreg_xmmreg: + cmp [mmx_size],8 + jne invalid_operand + call avx_movq_xmmreg_xmmreg_opcode + call convert_avx_register + cmp ah,16 + jne invalid_operand_size + mov bl,al + jmp nomem_instruction_ready + avx_movq_xmmreg_xmmreg_opcode: + and [rex_prefix],not 8 + or [rex_prefix],80h + add [extended_code],10h + mov [opcode_prefix],0F3h + ret +avx_movddup_instruction: + or [vex_required],1 + mov [opcode_prefix],0F2h + mov [base_code],0Fh + mov [extended_code],al + or [rex_prefix],80h + xor al,al + mov [mmx_size],al + mov [broadcast_size],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_avx_register + mov [postbyte_register],al + cmp ah,16 + ja avx_movddup_size_ok + mov [mmx_size],8 + avx_movddup_size_ok: + call take_avx512_mask + jmp avx_vex_reg_ok +avx_movlpd_instruction: + mov [opcode_prefix],66h + or [rex_prefix],80h +avx_movlps_instruction: + mov [base_code],0Fh + mov [extended_code],al + mov [mmx_size],8 + mov [broadcast_size],0 + or [vex_required],1 + lods byte [esi] + call get_size_operator + cmp al,10h + jne avx_movlps_mem + lods byte [esi] + call convert_avx_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [vex_register],al + cmp [operand_size],16 + jne invalid_operand + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_rm + jc invalid_operand + jmp instruction_ready + avx_movlps_mem: + cmp al,'[' + jne invalid_operand + call get_address + avx_movlps_mem_: + mov al,[operand_size] + or al,al + jz avx_movlps_mem_size_ok + cmp al,[mmx_size] + jne invalid_operand_size + mov [operand_size],0 + avx_movlps_mem_size_ok: + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + cmp ah,16 + jne invalid_operand + mov [postbyte_register],al + inc [extended_code] + jmp instruction_ready +avx_movhlps_instruction: + mov [base_code],0Fh + mov [extended_code],al + or [vex_required],1 + call take_avx_register + cmp ah,16 + jne invalid_operand + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [vex_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov bl,al + jmp nomem_instruction_ready +avx_movsd_instruction: + mov al,0F2h + mov cl,8 + or [rex_prefix],80h + jmp avx_movs_instruction +avx_movss_instruction: + mov al,0F3h + mov cl,4 + avx_movs_instruction: + mov [opcode_prefix],al + mov [mmx_size],cl + or [vex_required],1 + mov [base_code],0Fh + mov [extended_code],10h + lods byte [esi] + call get_size_operator + cmp al,10h + jne avx_movs_mem + lods byte [esi] + call convert_avx_register + cmp ah,16 + jne invalid_operand + mov [postbyte_register],al + call take_avx512_mask + xor cl,cl + xchg cl,[operand_size] + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne avx_movs_reg_mem + mov [operand_size],cl + lods byte [esi] + call convert_avx_register + mov [vex_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov bl,al + cmp bl,8 + jb nomem_instruction_ready + inc [extended_code] + xchg bl,[postbyte_register] + jmp nomem_instruction_ready + avx_movs_reg_mem: + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + or al,al + jz avx_movs_reg_mem_ok + cmp al,[mmx_size] + jne invalid_operand_size + avx_movs_reg_mem_ok: + jmp instruction_ready + avx_movs_mem: + cmp al,'[' + jne invalid_operand + call get_address + or [operand_flags],20h + call take_avx512_mask + jmp avx_movlps_mem_ + +avx_comiss_instruction: + or [operand_flags],2+4+10h + mov cl,4 + jmp avx_instruction +avx_comisd_instruction: + or [operand_flags],2+4+10h + mov [opcode_prefix],66h + or [rex_prefix],80h + mov cl,8 + jmp avx_instruction +avx_movshdup_instruction: + or [operand_flags],2 + mov [opcode_prefix],0F3h + xor cl,cl + jmp avx_instruction +avx_cvtqq2pd_instruction: + mov [opcode_prefix],0F3h + or [vex_required],8 + or [operand_flags],2+4+8 + or [rex_prefix],8 + mov cx,0800h + jmp avx_instruction_with_broadcast +avx_pshuf_w_instruction: + mov [opcode_prefix],al + or [operand_flags],2 + mov [immediate_size],1 + mov al,70h + xor cl,cl + jmp avx_instruction +avx_single_source_128bit_instruction_38_noevex: + or [operand_flags],2 +avx_128bit_instruction_38_noevex: + mov cl,16 + jmp avx_instruction_38_noevex +avx_single_source_instruction_38_noevex: + or [operand_flags],2 + jmp avx_pi_instruction_38_noevex +avx_pi_instruction_38_noevex: + xor cl,cl + avx_instruction_38_noevex: + or [vex_required],2 + avx_instruction_38: + mov [opcode_prefix],66h + mov [supplemental_code],al + mov al,38h + jmp avx_instruction +avx_ss_instruction_3a_imm8_noevex: + mov cl,4 + jmp avx_instruction_3a_imm8_noevex +avx_sd_instruction_3a_imm8_noevex: + mov cl,8 + jmp avx_instruction_3a_imm8_noevex +avx_single_source_128bit_instruction_3a_imm8_noevex: + or [operand_flags],2 +avx_128bit_instruction_3a_imm8_noevex: + mov cl,16 + jmp avx_instruction_3a_imm8_noevex +avx_triple_source_instruction_3a_noevex: + xor cl,cl + mov [immediate_size],-1 + mov byte [value],0 + jmp avx_instruction_3a_noevex +avx_single_source_instruction_3a_imm8_noevex: + or [operand_flags],2 +avx_pi_instruction_3a_imm8_noevex: + xor cl,cl + avx_instruction_3a_imm8_noevex: + mov [immediate_size],1 + avx_instruction_3a_noevex: + or [vex_required],2 + avx_instruction_3a: + mov [opcode_prefix],66h + mov [supplemental_code],al + mov al,3Ah + jmp avx_instruction +avx_pi_instruction_3a_imm8: + xor cl,cl + mov [immediate_size],1 + jmp avx_instruction_3a +avx_pclmulqdq_instruction: + mov byte [value],al + mov [immediate_size],-4 + xor cl,cl + mov al,44h + or [operand_flags],10h + jmp avx_instruction_3a +avx_instruction_38_nomask: + or [operand_flags],10h + xor cl,cl + jmp avx_instruction_38 + +avx512_single_source_pd_instruction_sae_imm8: + or [operand_flags],2 +avx512_pd_instruction_sae_imm8: + or [rex_prefix],8 + mov cx,0800h + jmp avx512_instruction_sae_imm8 +avx512_single_source_ps_instruction_sae_imm8: + or [operand_flags],2 +avx512_ps_instruction_sae_imm8: + mov cx,0400h + jmp avx512_instruction_sae_imm8 +avx512_sd_instruction_sae_imm8: + or [rex_prefix],8 + mov cx,0008h + jmp avx512_instruction_sae_imm8 +avx512_ss_instruction_sae_imm8: + mov cx,0004h + avx512_instruction_sae_imm8: + or [operand_flags],4 + avx512_instruction_imm8: + or [vex_required],8 + mov [opcode_prefix],66h + mov [immediate_size],1 + mov [supplemental_code],al + mov al,3Ah + jmp avx_instruction_with_broadcast +avx512_pd_instruction_er: + or [operand_flags],4+8 + jmp avx512_pd_instruction +avx512_single_source_pd_instruction_sae: + or [operand_flags],4 +avx512_single_source_pd_instruction: + or [operand_flags],2 +avx512_pd_instruction: + or [rex_prefix],8 + mov cx,0800h + jmp avx512_instruction +avx512_ps_instruction_er: + or [operand_flags],4+8 + jmp avx512_ps_instruction +avx512_single_source_ps_instruction_sae: + or [operand_flags],4 +avx512_single_source_ps_instruction: + or [operand_flags],2 +avx512_ps_instruction: + mov cx,0400h + jmp avx512_instruction +avx512_sd_instruction_er: + or [operand_flags],8 +avx512_sd_instruction_sae: + or [operand_flags],4 +avx512_sd_instruction: + or [rex_prefix],8 + mov cx,0008h + jmp avx512_instruction +avx512_ss_instruction_er: + or [operand_flags],8 +avx512_ss_instruction_sae: + or [operand_flags],4 +avx512_ss_instruction: + mov cx,0004h + avx512_instruction: + or [vex_required],8 + mov [opcode_prefix],66h + mov [supplemental_code],al + mov al,38h + jmp avx_instruction_with_broadcast +avx512_exp2pd_instruction: + or [rex_prefix],8 + or [operand_flags],2+4 + mov cx,0840h + jmp avx512_instruction +avx512_exp2ps_instruction: + or [operand_flags],2+4 + mov cx,0440h + jmp avx512_instruction + +fma_instruction_pd: + or [rex_prefix],8 + mov cx,0800h + jmp fma_instruction +fma_instruction_ps: + mov cx,0400h + jmp fma_instruction +fma_instruction_sd: + or [rex_prefix],8 + mov cx,0008h + jmp fma_instruction +fma_instruction_ss: + mov cx,0004h + fma_instruction: + or [operand_flags],4+8 + mov [opcode_prefix],66h + mov [supplemental_code],al + mov al,38h + jmp avx_instruction_with_broadcast + +fma4_instruction_p: + xor cl,cl + jmp fma4_instruction +fma4_instruction_sd: + mov cl,8 + jmp fma4_instruction +fma4_instruction_ss: + mov cl,4 + fma4_instruction: + mov [immediate_size],-2 + mov byte [value],0 + jmp avx_instruction_3a_noevex + +avx_cmp_pd_instruction: + mov [opcode_prefix],66h + or [rex_prefix],80h + mov cx,0800h + jmp avx_cmp_instruction +avx_cmp_ps_instruction: + mov cx,0400h + jmp avx_cmp_instruction +avx_cmp_sd_instruction: + mov [opcode_prefix],0F2h + or [rex_prefix],80h + mov cx,0008h + jmp avx_cmp_instruction +avx_cmp_ss_instruction: + mov [opcode_prefix],0F3h + mov cx,0004h + avx_cmp_instruction: + mov byte [value],al + mov [immediate_size],-4 + or [operand_flags],4+20h + mov al,0C2h + jmp avx_cmp_common +avx_cmpeqq_instruction: + or [rex_prefix],80h + mov ch,8 + mov [supplemental_code],al + mov al,38h + jmp avx_cmp_pi_instruction +avx_cmpeqd_instruction: + mov ch,4 + jmp avx_cmp_pi_instruction +avx_cmpeqb_instruction: + xor ch,ch + jmp avx_cmp_pi_instruction +avx512_cmp_uq_instruction: + or [rex_prefix],8 + mov ch,8 + mov ah,1Eh + jmp avx_cmp_pi_instruction_evex +avx512_cmp_ud_instruction: + mov ch,4 + mov ah,1Eh + jmp avx_cmp_pi_instruction_evex +avx512_cmp_q_instruction: + or [rex_prefix],8 + mov ch,8 + mov ah,1Fh + jmp avx_cmp_pi_instruction_evex +avx512_cmp_d_instruction: + mov ch,4 + mov ah,1Fh + jmp avx_cmp_pi_instruction_evex +avx512_cmp_uw_instruction: + or [rex_prefix],8 +avx512_cmp_ub_instruction: + xor ch,ch + mov ah,3Eh + jmp avx_cmp_pi_instruction_evex +avx512_cmp_w_instruction: + or [rex_prefix],8 +avx512_cmp_b_instruction: + xor ch,ch + mov ah,3Fh + avx_cmp_pi_instruction_evex: + mov byte [value],al + mov [immediate_size],-4 + mov [supplemental_code],ah + mov al,3Ah + or [vex_required],8 + avx_cmp_pi_instruction: + xor cl,cl + or [operand_flags],20h + mov [opcode_prefix],66h + avx_cmp_common: + mov [mmx_size],cl + mov [broadcast_size],ch + mov [extended_code],al + mov [base_code],0Fh + lods byte [esi] + call get_size_operator + cmp al,14h + je avx_maskreg + cmp al,10h + jne invalid_operand + or [vex_required],2 + jmp avx_reg + avx_maskreg: + cmp [operand_size],0 + jne invalid_operand_size + or [vex_required],8 + lods byte [esi] + call convert_mask_register + mov [postbyte_register],al + call take_avx512_mask + jmp avx_vex_reg +avx512_fpclasspd_instruction: + or [rex_prefix],8 + mov cx,0800h + jmp avx_fpclass_instruction +avx512_fpclassps_instruction: + mov cx,0400h + jmp avx_fpclass_instruction +avx512_fpclasssd_instruction: + or [rex_prefix],8 + mov cx,0008h + jmp avx_fpclass_instruction +avx512_fpclassss_instruction: + mov cx,0004h + avx_fpclass_instruction: + mov [broadcast_size],ch + mov [mmx_size],cl + or [operand_flags],2 + call setup_66_0f_3a + mov [immediate_size],1 + lods byte [esi] + cmp al,14h + je avx_maskreg + jmp invalid_operand +avx512_ptestnmd_instruction: + mov ch,4 + jmp avx512_ptestnm_instruction +avx512_ptestnmq_instruction: + or [rex_prefix],8 + mov ch,8 + jmp avx512_ptestnm_instruction +avx512_ptestnmw_instruction: + or [rex_prefix],8 +avx512_ptestnmb_instruction: + xor ch,ch + avx512_ptestnm_instruction: + mov ah,0F3h + jmp avx512_ptest_instruction +avx512_ptestmd_instruction: + mov ch,4 + jmp avx512_ptestm_instruction +avx512_ptestmq_instruction: + or [rex_prefix],8 + mov ch,8 + jmp avx512_ptestm_instruction +avx512_ptestmw_instruction: + or [rex_prefix],8 +avx512_ptestmb_instruction: + xor ch,ch + avx512_ptestm_instruction: + mov ah,66h + avx512_ptest_instruction: + xor cl,cl + mov [opcode_prefix],ah + mov [supplemental_code],al + mov al,38h + or [vex_required],8 + jmp avx_cmp_common + +mask_shift_instruction_q: + or [rex_prefix],8 +mask_shift_instruction_d: + or [operand_flags],2 + or [immediate_size],1 + mov [opcode_prefix],66h + mov [supplemental_code],al + mov al,3Ah + jmp mask_instruction +mask_instruction_single_source_b: + mov [opcode_prefix],66h + jmp mask_instruction_single_source_w +mask_instruction_single_source_d: + mov [opcode_prefix],66h +mask_instruction_single_source_q: + or [rex_prefix],8 +mask_instruction_single_source_w: + or [operand_flags],2 + jmp mask_instruction +mask_instruction_b: + mov [opcode_prefix],66h + jmp mask_instruction_w +mask_instruction_d: + mov [opcode_prefix],66h +mask_instruction_q: + or [rex_prefix],8 +mask_instruction_w: + mov [operand_size],32 +mask_instruction: + or [vex_required],1 + mov [base_code],0Fh + mov [extended_code],al + call take_mask_register + mov [postbyte_register],al + test [operand_flags],2 + jnz mask_instruction_nds_ok + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_mask_register + mov [vex_register],al + mask_instruction_nds_ok: + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_mask_register + mov bl,al + cmp [immediate_size],0 + jne mmx_nomem_imm8 + jmp nomem_instruction_ready +take_mask_register: + lods byte [esi] + cmp al,14h + jne invalid_operand + lods byte [esi] +convert_mask_register: + mov ah,al + shr ah,4 + cmp ah,5 + jne invalid_operand + and al,1111b + ret +kmov_instruction: + mov [mmx_size],al + or [vex_required],1 + mov [base_code],0Fh + mov [extended_code],90h + lods byte [esi] + cmp al,14h + je kmov_maskreg + cmp al,10h + je kmov_reg + call get_size_operator + inc [extended_code] + cmp al,'[' + jne invalid_argument + call get_address + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_mask_register + mov [postbyte_register],al + kmov_with_mem: + mov ah,[mmx_size] + mov al,[operand_size] + or al,al + jz kmov_mem_size_ok + cmp al,ah + jne invalid_operand_size + kmov_mem_size_ok: + call setup_kmov_prefix + jmp instruction_ready + setup_kmov_prefix: + cmp ah,4 + jb kmov_w_ok + or [rex_prefix],8 + kmov_w_ok: + test ah,1 or 4 + jz kmov_prefix_ok + mov [opcode_prefix],66h + kmov_prefix_ok: + ret + kmov_maskreg: + lods byte [esi] + call convert_mask_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + cmp al,14h + je kmov_maskreg_maskreg + cmp al,10h + je kmov_maskreg_reg + call get_size_operator + cmp al,'[' + jne invalid_argument + call get_address + jmp kmov_with_mem + kmov_maskreg_maskreg: + lods byte [esi] + call convert_mask_register + mov bl,al + mov ah,[mmx_size] + call setup_kmov_prefix + jmp nomem_instruction_ready + kmov_maskreg_reg: + add [extended_code],2 + lods byte [esi] + call convert_register + kmov_with_reg: + mov bl,al + mov al,[mmx_size] + mov ah,4 + cmp al,ah + jbe kmov_reg_size_check + mov ah,al + kmov_reg_size_check: + cmp ah,[operand_size] + jne invalid_operand_size + cmp al,8 + je kmov_f2_w1 + cmp al,2 + ja kmov_f2 + je nomem_instruction_ready + mov [opcode_prefix],66h + jmp nomem_instruction_ready + kmov_f2_w1: + or [rex_prefix],8 + cmp [code_type],64 + jne illegal_instruction + kmov_f2: + mov [opcode_prefix],0F2h + jmp nomem_instruction_ready + kmov_reg: + add [extended_code],3 + lods byte [esi] + call convert_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_mask_register + jmp kmov_with_reg +avx512_pmov_m2_instruction_w1: + or [rex_prefix],8 +avx512_pmov_m2_instruction: + or [vex_required],8 + call setup_f3_0f_38 + call take_avx_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_mask_register + mov bl,al + jmp nomem_instruction_ready +avx512_pmov_2m_instruction_w1: + or [rex_prefix],8 +avx512_pmov_2m_instruction: + or [vex_required],8 + call setup_f3_0f_38 + call take_mask_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov bl,al + jmp nomem_instruction_ready + setup_f3_0f_38: + mov [extended_code],38h + mov [supplemental_code],al + mov [base_code],0Fh + mov [opcode_prefix],0F3h + ret + +vzeroall_instruction: + mov [operand_size],32 +vzeroupper_instruction: + mov [base_code],0Fh + mov [extended_code],al + and [displacement_compression],0 + call store_vex_instruction_code + jmp instruction_assembled +vstmxcsr_instruction: + or [vex_required],2 + jmp stmxcsr_instruction + +avx_perm2f128_instruction: + or [vex_required],2 + xor ch,ch + avx_instruction_imm8_without_128bit: + mov [immediate_size],1 + mov ah,3Ah + jmp avx_instruction_without_128bit +avx512_shuf_q_instruction: + or [rex_prefix],8 + or [vex_required],8 + mov ch,8 + jmp avx_instruction_imm8_without_128bit +avx512_shuf_d_instruction: + or [vex_required],8 + mov ch,4 + jmp avx_instruction_imm8_without_128bit +avx_permd_instruction: + mov ah,38h + mov ch,4 + avx_instruction_without_128bit: + xor cl,cl + call setup_avx_66_supplemental + call take_avx_register + cmp ah,32 + jb invalid_operand_size + mov [postbyte_register],al + call take_avx512_mask + jmp avx_vex_reg + setup_avx_66_supplemental: + mov [opcode_prefix],66h + mov [broadcast_size],ch + mov [mmx_size],cl + mov [base_code],0Fh + mov [extended_code],ah + mov [supplemental_code],al + or [vex_required],1 + ret +avx_permq_instruction: + or [rex_prefix],8 + mov ch,8 + jmp avx_permil_instruction +avx_permilpd_instruction: + or [rex_prefix],80h + mov ch,8 + jmp avx_permil_instruction +avx_permilps_instruction: + mov ch,4 + avx_permil_instruction: + or [operand_flags],2 + xor cl,cl + mov ah,3Ah + call setup_avx_66_supplemental + call take_avx_register + cmp [supplemental_code],4 + jae avx_permil_size_ok + cmp ah,32 + jb invalid_operand_size + avx_permil_size_ok: + mov [postbyte_register],al + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_rm + jnc mmx_imm8 + mov bl,al + cmp byte [esi],',' + jne invalid_operand + mov al,[esi+1] + cmp al,11h + jne avx_permil_rm_or_imm8 + mov al,[esi+3] + avx_permil_rm_or_imm8: + cmp al,'(' + je mmx_nomem_imm8 + mov [vex_register],bl + inc esi + mov [extended_code],38h + mov al,[supplemental_code] + cmp al,4 + jb avx_permq_rm + add [supplemental_code],8 + jmp avx_regs_rm + avx_permq_rm: + or [vex_required],8 + shl al,5 + neg al + add al,36h + mov [supplemental_code],al + jmp avx_regs_rm +vpermil_2pd_instruction: + mov [immediate_size],-2 + mov byte [value],al + mov al,49h + jmp vpermil2_instruction_setup +vpermil_2ps_instruction: + mov [immediate_size],-2 + mov byte [value],al + mov al,48h + jmp vpermil2_instruction_setup +vpermil2_instruction: + mov [immediate_size],-3 + mov byte [value],0 + vpermil2_instruction_setup: + or [vex_required],2 + mov [base_code],0Fh + mov [supplemental_code],al + mov al,3Ah + xor cl,cl + jmp avx_instruction + +avx_shift_q_instruction_evex: + or [vex_required],8 +avx_shift_q_instruction: + or [rex_prefix],80h + mov cl,8 + jmp avx_shift_instruction +avx_shift_d_instruction: + mov cl,4 + jmp avx_shift_instruction +avx_shift_bw_instruction: + xor cl,cl + avx_shift_instruction: + mov [broadcast_size],cl + mov [mmx_size],0 + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],al + or [vex_required],1 + call take_avx_register + mov [postbyte_register],al + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + xor cl,cl + xchg cl,[operand_size] + lods byte [esi] + call get_size_operator + cmp al,'[' + je avx_shift_reg_mem + mov [operand_size],cl + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_avx_register + mov [vex_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + push esi + xor cl,cl + xchg cl,[operand_size] + lods byte [esi] + call get_size_operator + cmp al,10h + je avx_shift_reg_reg_reg + pop esi + cmp al,'[' + je avx_shift_reg_reg_mem + xchg cl,[operand_size] + test cl,not 1 + jnz invalid_operand_size + dec esi + call convert_avx_shift_opcode + mov bl,al + jmp mmx_nomem_imm8 + convert_avx_shift_opcode: + mov al,[extended_code] + mov ah,al + and ah,1111b + add ah,70h + mov [extended_code],ah + shr al,4 + sub al,0Ch + shl al,1 + xchg al,[postbyte_register] + xchg al,[vex_register] + ret + avx_shift_reg_reg_reg: + pop eax + lods byte [esi] + call convert_xmm_register + xchg cl,[operand_size] + mov bl,al + jmp nomem_instruction_ready + avx_shift_reg_reg_mem: + mov [mmx_size],16 + push ecx + lods byte [esi] + call get_size_operator + call get_address + pop eax + xchg al,[operand_size] + test al,al + jz instruction_ready + cmp al,16 + jne invalid_operand_size + jmp instruction_ready + avx_shift_reg_mem: + or [vex_required],8 + call take_avx_mem + call convert_avx_shift_opcode + jmp mmx_imm8 +avx_shift_dq_instruction: + mov [postbyte_register],al + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],73h + or [vex_required],1 + mov [mmx_size],0 + call take_avx_register + mov [vex_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + je avx_shift_dq_reg_mem + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_avx_register + mov bl,al + jmp mmx_nomem_imm8 + avx_shift_dq_reg_mem: + or [vex_required],8 + call get_address + jmp mmx_imm8 +avx512_rotate_q_instruction: + mov cl,8 + or [rex_prefix],cl + jmp avx512_rotate_instruction +avx512_rotate_d_instruction: + mov cl,4 + avx512_rotate_instruction: + mov [broadcast_size],cl + mov [postbyte_register],al + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],72h + or [vex_required],8 + mov [mmx_size],0 + mov [immediate_size],1 + call take_avx_register + mov [vex_register],al + call take_avx512_mask + jmp avx_vex_reg_ok + +avx_pmovsxbq_instruction: + mov cl,2 + jmp avx_pmovsx_instruction +avx_pmovsxbd_instruction: + mov cl,4 + jmp avx_pmovsx_instruction +avx_pmovsxbw_instruction: + mov cl,8 + avx_pmovsx_instruction: + mov [mmx_size],cl + or [vex_required],1 + call setup_66_0f_38 + call take_avx_register + mov [postbyte_register],al + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + xor al,al + xchg al,[operand_size] + bsf ecx,eax + sub cl,4 + shl [mmx_size],cl + push eax + lods byte [esi] + call get_size_operator + cmp al,10h + je avx_pmovsx_reg_reg + cmp al,'[' + jne invalid_operand + call get_address + pop eax + xchg al,[operand_size] + or al,al + jz instruction_ready + cmp al,[mmx_size] + jne invalid_operand_size + jmp instruction_ready + avx_pmovsx_reg_reg: + lods byte [esi] + call convert_avx_register + mov bl,al + cmp ah,[mmx_size] + je avx_pmovsx_xmmreg_reg_size_ok + jb invalid_operand_size + cmp ah,16 + jne invalid_operand_size + avx_pmovsx_xmmreg_reg_size_ok: + pop eax + mov [operand_size],al + jmp nomem_instruction_ready +avx512_pmovqb_instruction: + mov cl,2 + jmp avx512_pmov_instruction +avx512_pmovdb_instruction: + mov cl,4 + jmp avx512_pmov_instruction +avx512_pmovwb_instruction: + mov cl,8 + avx512_pmov_instruction: + mov [mmx_size],cl + or [vex_required],8 + mov [extended_code],38h + mov [supplemental_code],al + mov [base_code],0Fh + mov [opcode_prefix],0F3h + lods byte [esi] + call get_size_operator + cmp al,10h + je avx512_pmov_reg + cmp al,'[' + jne invalid_operand + call get_address + or [operand_flags],20h + call avx512_pmov_common + or al,al + jz instruction_ready + cmp al,[mmx_size] + jne invalid_operand_size + jmp instruction_ready + avx512_pmov_common: + call take_avx512_mask + xor al,al + xchg al,[operand_size] + push eax + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [postbyte_register],al + mov al,ah + mov ah,cl + bsf ecx,eax + sub cl,4 + shl [mmx_size],cl + mov cl,ah + pop eax + ret + avx512_pmov_reg: + lods byte [esi] + call convert_avx_register + mov bl,al + call avx512_pmov_common + cmp al,[mmx_size] + je nomem_instruction_ready + jb invalid_operand_size + cmp al,16 + jne invalid_operand_size + jmp nomem_instruction_ready + +avx_broadcast_128_instruction_noevex: + or [vex_required],2 + mov cl,10h + jmp avx_broadcast_instruction +avx512_broadcast_32x2_instruction: + mov cl,08h + jmp avx_broadcast_instruction_evex +avx512_broadcast_32x4_instruction: + mov cl,10h + jmp avx_broadcast_instruction_evex +avx512_broadcast_32x8_instruction: + mov cl,20h + jmp avx_broadcast_instruction_evex +avx512_broadcast_64x2_instruction: + mov cl,10h + jmp avx_broadcast_instruction_w1_evex +avx512_broadcast_64x4_instruction: + mov cl,20h + avx_broadcast_instruction_w1_evex: + or [rex_prefix],8 + avx_broadcast_instruction_evex: + or [vex_required],8 + jmp avx_broadcast_instruction +avx_broadcastss_instruction: + mov cl,4 + jmp avx_broadcast_instruction +avx_broadcastsd_instruction: + or [rex_prefix],80h + mov cl,8 + jmp avx_broadcast_instruction +avx_pbroadcastb_instruction: + mov cl,1 + jmp avx_broadcast_pi_instruction +avx_pbroadcastw_instruction: + mov cl,2 + jmp avx_broadcast_pi_instruction +avx_pbroadcastd_instruction: + mov cl,4 + jmp avx_broadcast_pi_instruction +avx_pbroadcastq_instruction: + mov cl,8 + or [rex_prefix],80h + avx_broadcast_pi_instruction: + or [operand_flags],40h + avx_broadcast_instruction: + mov [opcode_prefix],66h + mov [supplemental_code],al + mov al,38h + mov [mmx_size],cl + mov [base_code],0Fh + mov [extended_code],al + or [vex_required],1 + call take_avx_register + cmp ah,[mmx_size] + je invalid_operand_size + test [operand_flags],40h + jnz avx_broadcast_destination_size_ok + cmp [mmx_size],4 + je avx_broadcast_destination_size_ok + cmp [supplemental_code],59h + je avx_broadcast_destination_size_ok + cmp ah,16 + je invalid_operand_size + avx_broadcast_destination_size_ok: + xor ah,ah + xchg ah,[operand_size] + push eax + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je avx_broadcast_reg_reg + cmp al,'[' + jne invalid_operand + call get_address + pop eax + xchg ah,[operand_size] + mov [postbyte_register],al + mov al,[broadcast_size] + mov al,[mmx_size] + cmp al,ah + je instruction_ready + or al,al + jz instruction_ready + or ah,ah + jz instruction_ready + jmp invalid_operand_size + avx_broadcast_reg_reg: + lods byte [esi] + test [operand_flags],40h + jz avx_broadcast_reg_avx_reg + cmp al,60h + jb avx_broadcast_reg_general_reg + cmp al,80h + jb avx_broadcast_reg_avx_reg + cmp al,0C0h + jb avx_broadcast_reg_general_reg + avx_broadcast_reg_avx_reg: + call convert_avx_register + mov bl,al + mov al,[mmx_size] + or al,al + jz avx_broadcast_reg_avx_reg_size_ok + cmp ah,16 + jne invalid_operand_size + cmp al,ah + jae invalid_operand + avx_broadcast_reg_avx_reg_size_ok: + pop eax + xchg ah,[operand_size] + mov [postbyte_register],al + test [vex_required],2 + jnz invalid_operand + jmp nomem_instruction_ready + avx_broadcast_reg_general_reg: + call convert_register + mov bl,al + mov al,[mmx_size] + or al,al + jz avx_broadcast_reg_general_reg_size_ok + cmp al,ah + je avx_broadcast_reg_general_reg_size_ok + ja invalid_operand_size + cmp ah,4 + jne invalid_operand_size + avx_broadcast_reg_general_reg_size_ok: + cmp al,4 + jb avx_broadcast_reg_general_reg_ready + cmp al,8 + mov al,3 + jne avx_broadcast_reg_general_reg_ready + or [rex_prefix],8 + avx_broadcast_reg_general_reg_ready: + add al,7Ah-1 + mov [supplemental_code],al + or [vex_required],8 + pop eax + xchg ah,[operand_size] + mov [postbyte_register],al + jmp nomem_instruction_ready + +avx512_extract_64x4_instruction: + or [rex_prefix],8 +avx512_extract_32x8_instruction: + or [vex_required],8 + mov cl,32 + jmp avx_extractf_instruction +avx512_extract_64x2_instruction: + or [rex_prefix],8 +avx512_extract_32x4_instruction: + or [vex_required],8 + mov cl,16 + jmp avx_extractf_instruction +avx_extractf128_instruction: + or [vex_required],2 + mov cl,16 + avx_extractf_instruction: + mov [mmx_size],cl + call setup_66_0f_3a + lods byte [esi] + call get_size_operator + cmp al,10h + je avx_extractf_reg + cmp al,'[' + jne invalid_operand + call get_address + xor al,al + xchg al,[operand_size] + or al,al + jz avx_extractf_mem_size_ok + cmp al,[mmx_size] + jne invalid_operand_size + avx_extractf_mem_size_ok: + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + cmp ah,[mmx_size] + jbe invalid_operand_size + mov [postbyte_register],al + jmp mmx_imm8 + avx_extractf_reg: + lods byte [esi] + call convert_avx_register + cmp ah,[mmx_size] + jne invalid_operand_size + push eax + call take_avx512_mask + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + cmp ah,[mmx_size] + jbe invalid_operand_size + mov [postbyte_register],al + pop ebx + jmp mmx_nomem_imm8 +avx512_insert_64x4_instruction: + or [rex_prefix],8 +avx512_insert_32x8_instruction: + or [vex_required],8 + mov cl,32 + jmp avx_insertf_instruction +avx512_insert_64x2_instruction: + or [rex_prefix],8 +avx512_insert_32x4_instruction: + or [vex_required],8 + mov cl,16 + jmp avx_insertf_instruction +avx_insertf128_instruction: + or [vex_required],2 + mov cl,16 + avx_insertf_instruction: + mov [mmx_size],cl + mov [broadcast_size],0 + call setup_66_0f_3a + call take_avx_register + cmp ah,[mmx_size] + jbe invalid_operand + mov [postbyte_register],al + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [vex_register],al + mov al,[mmx_size] + xchg al,[operand_size] + push eax + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je avx_insertf_reg_reg_reg + cmp al,'[' + jne invalid_operand + call get_address + pop eax + mov [operand_size],al + jmp mmx_imm8 + avx_insertf_reg_reg_reg: + lods byte [esi] + call convert_avx_register + mov bl,al + pop eax + mov [operand_size],al + jmp mmx_nomem_imm8 +avx_extract_b_instruction: + mov cl,1 + jmp avx_extract_instruction +avx_extract_w_instruction: + mov cl,2 + jmp avx_extract_instruction +avx_extract_q_instruction: + or [rex_prefix],8 + mov cl,8 + jmp avx_extract_instruction +avx_extract_d_instruction: + mov cl,4 + avx_extract_instruction: + mov [mmx_size],cl + call setup_66_0f_3a + or [vex_required],1 + lods byte [esi] + call get_size_operator + cmp al,10h + je avx_extractps_reg + cmp al,'[' + jne invalid_operand + call get_address + mov al,[mmx_size] + not al + and [operand_size],al + jnz invalid_operand_size + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_avx_register + cmp ah,16 + jne invalid_operand_size + mov [postbyte_register],al + jmp mmx_imm8 + avx_extractps_reg: + lods byte [esi] + call convert_register + mov bl,al + mov al,[mmx_size] + cmp ah,al + jb invalid_operand_size + cmp ah,4 + je avx_extractps_reg_size_ok + cmp ah,8 + jne invalid_operand_size + cmp [code_type],64 + jne invalid_operand + cmp al,4 + jae avx_extractps_reg_size_ok + or [rex_prefix],8 + avx_extractps_reg_size_ok: + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_avx_register + cmp ah,16 + jne invalid_operand_size + mov [postbyte_register],al + cmp [supplemental_code],15h + jne mmx_nomem_imm8 + mov [extended_code],0C5h + xchg bl,[postbyte_register] + jmp mmx_nomem_imm8 +avx_insertps_instruction: + mov [immediate_size],1 + or [operand_flags],10h + mov [opcode_prefix],66h + mov [supplemental_code],al + mov al,3Ah + mov cl,4 + jmp avx_instruction +avx_pinsrb_instruction: + mov cl,1 + jmp avx_pinsr_instruction_3a +avx_pinsrw_instruction: + mov cl,2 + jmp avx_pinsr_instruction +avx_pinsrd_instruction: + mov cl,4 + jmp avx_pinsr_instruction_3a +avx_pinsrq_instruction: + cmp [code_type],64 + jne illegal_instruction + mov cl,8 + or [rex_prefix],8 + avx_pinsr_instruction_3a: + mov [supplemental_code],al + mov al,3Ah + avx_pinsr_instruction: + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],al + mov [mmx_size],cl + or [vex_required],1 + call take_avx_register + cmp ah,16 + jne invalid_operand_size + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [vex_register],al + jmp pinsr_xmmreg + +avx_cvtudq2pd_instruction: + or [vex_required],8 +avx_cvtdq2pd_instruction: + mov [opcode_prefix],0F3h + mov cl,4 + jmp avx_cvt_d_instruction +avx_cvtps2qq_instruction: + or [operand_flags],8 +avx_cvttps2qq_instruction: + or [operand_flags],4 + or [vex_required],8 + mov [opcode_prefix],66h + mov cl,4 + jmp avx_cvt_d_instruction +avx_cvtps2pd_instruction: + or [operand_flags],4 + mov cl,4 + avx_cvt_d_instruction: + mov [base_code],0Fh + mov [extended_code],al + or [vex_required],1 + mov [broadcast_size],cl + call take_avx_register + mov [postbyte_register],al + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + xor ecx,ecx + xchg cl,[operand_size] + mov al,cl + shr al,1 + mov [mmx_size],al + lods byte [esi] + call get_size_operator + cmp al,'[' + je avx_cvt_d_reg_mem + cmp al,10h + jne invalid_operand + mov [operand_size],0 + lods byte [esi] + call convert_avx_register + cmp ah,[mmx_size] + je avx_cvt_d_reg_reg_size_ok + jb invalid_operand_size + cmp ah,16 + jne invalid_operand_size + avx_cvt_d_reg_reg_size_ok: + mov bl,al + mov [operand_size],cl + call take_avx512_rounding + jmp nomem_instruction_ready + avx_cvt_d_reg_mem: + call take_avx_mem + jmp instruction_ready +avx_cvtpd2dq_instruction: + or [operand_flags],4+8 + mov [opcode_prefix],0F2h + jmp avx_cvt_q_instruction +avx_cvtuqq2ps_instruction: + mov [opcode_prefix],0F2h +avx_cvtpd2udq_instruction: + or [operand_flags],8 +avx_cvttpd2udq_instruction: + or [operand_flags],4 + or [vex_required],8 + jmp avx_cvt_q_instruction +avx_cvtpd2ps_instruction: + or [operand_flags],8 +avx_cvttpd2dq_instruction: + or [operand_flags],4 + mov [opcode_prefix],66h + avx_cvt_q_instruction: + mov [broadcast_size],8 + mov [base_code],0Fh + mov [extended_code],al + or [vex_required],1 + or [rex_prefix],80h + call take_avx_register + mov [postbyte_register],al + push eax + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + xor al,al + mov [operand_size],al + mov [mmx_size],al + call take_avx_rm + jnc avx_cvt_q_reg_mem + mov bl,al + pop eax + call avx_cvt_q_check_size + call take_avx512_rounding + jmp nomem_instruction_ready + avx_cvt_q_reg_mem: + pop eax + call avx_cvt_q_check_size + jmp instruction_ready + avx_cvt_q_check_size: + mov al,[operand_size] + or al,al + jz avx_cvt_q_size_not_specified + cmp al,64 + ja invalid_operand_size + shr al,1 + cmp al,ah + je avx_cvt_q_size_ok + ja invalid_operand_size + cmp ah,16 + jne invalid_operand_size + avx_cvt_q_size_ok: + ret + avx_cvt_q_size_not_specified: + cmp ah,64 shr 1 + jne recoverable_unknown_size + mov [operand_size],64 + ret +avx_cvttps2udq_instruction: + or [vex_required],8 + or [operand_flags],2+4 + mov cx,0400h + jmp avx_instruction_with_broadcast +avx_cvttps2dq_instruction: + mov [opcode_prefix],0F3h + or [operand_flags],2+4 + mov cx,0400h + jmp avx_instruction_with_broadcast +avx_cvtph2ps_instruction: + mov [opcode_prefix],66h + mov [supplemental_code],al + or [operand_flags],4 + mov al,38h + xor cl,cl + jmp avx_cvt_d_instruction +avx_cvtps2ph_instruction: + call setup_66_0f_3a + or [vex_required],1 + or [operand_flags],4 + lods byte [esi] + call get_size_operator + cmp al,10h + je vcvtps2ph_reg + cmp al,'[' + jne invalid_operand + call get_address + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + shl [operand_size],1 + call take_avx_register + mov [postbyte_register],al + shr ah,1 + mov [mmx_size],ah + jmp mmx_imm8 + vcvtps2ph_reg: + lods byte [esi] + call convert_avx_register + mov bl,al + call take_avx512_mask + xor cl,cl + xchg cl,[operand_size] + shl cl,1 + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [postbyte_register],al + or cl,cl + jz vcvtps2ph_reg_size_ok + cmp cl,ah + je vcvtps2ph_reg_size_ok + jb invalid_operand_size + cmp ah,16 + jne invalid_operand_size + vcvtps2ph_reg_size_ok: + call take_avx512_rounding + jmp mmx_nomem_imm8 + +avx_cvtsd2usi_instruction: + or [operand_flags],8 +avx_cvttsd2usi_instruction: + or [vex_required],8 + jmp avx_cvttsd2si_instruction +avx_cvtsd2si_instruction: + or [operand_flags],8 +avx_cvttsd2si_instruction: + mov ah,0F2h + mov cl,8 + jmp avx_cvt_2si_instruction +avx_cvtss2usi_instruction: + or [operand_flags],8 +avx_cvttss2usi_instruction: + or [vex_required],8 + jmp avx_cvttss2si_instruction +avx_cvtss2si_instruction: + or [operand_flags],8 +avx_cvttss2si_instruction: + mov ah,0F3h + mov cl,4 + avx_cvt_2si_instruction: + or [operand_flags],2+4 + mov [mmx_size],cl + mov [broadcast_size],0 + mov [opcode_prefix],ah + mov [base_code],0Fh + mov [extended_code],al + or [vex_required],1 + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + mov [postbyte_register],al + mov [operand_size],0 + cmp ah,4 + je avx_cvt_2si_reg + cmp ah,8 + jne invalid_operand_size + call operand_64bit + avx_cvt_2si_reg: + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_rm + jnc instruction_ready + mov bl,al + call take_avx512_rounding + jmp nomem_instruction_ready +avx_cvtusi2sd_instruction: + or [vex_required],8 +avx_cvtsi2sd_instruction: + mov ah,0F2h + mov cl,8 + jmp avx_cvtsi_instruction +avx_cvtusi2ss_instruction: + or [vex_required],8 +avx_cvtsi2ss_instruction: + mov ah,0F3h + mov cl,4 + avx_cvtsi_instruction: + or [operand_flags],2+4+8 + mov [mmx_size],cl + mov [opcode_prefix],ah + mov [base_code],0Fh + mov [extended_code],al + or [vex_required],1 + call take_avx_register + cmp ah,16 + jne invalid_operand_size + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [vex_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + mov [operand_size],0 + lods byte [esi] + call get_size_operator + cmp al,'[' + je avx_cvtsi_reg_reg_mem + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + mov bl,al + cmp ah,4 + je avx_cvtsi_reg_reg_reg32 + cmp ah,8 + jne invalid_operand_size + call operand_64bit + avx_cvtsi_rounding: + call take_avx512_rounding + jmp nomem_instruction_ready + avx_cvtsi_reg_reg_reg32: + cmp [mmx_size],8 + jne avx_cvtsi_rounding + jmp nomem_instruction_ready + avx_cvtsi_reg_reg_mem: + call get_address + mov al,[operand_size] + mov [mmx_size],al + or al,al + jz single_mem_nosize + cmp al,4 + je instruction_ready + cmp al,8 + jne invalid_operand_size + call operand_64bit + jmp instruction_ready + +avx_maskmov_w1_instruction: + or [rex_prefix],8 +avx_maskmov_instruction: + call setup_66_0f_38 + mov [mmx_size],0 + or [vex_required],2 + lods byte [esi] + call get_size_operator + cmp al,10h + jne avx_maskmov_mem + lods byte [esi] + call convert_avx_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [vex_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + jmp instruction_ready + avx_maskmov_mem: + cmp al,'[' + jne invalid_operand + call get_address + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [vex_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [postbyte_register],al + add [supplemental_code],2 + jmp instruction_ready +avx_movmskpd_instruction: + mov [opcode_prefix],66h +avx_movmskps_instruction: + mov [base_code],0Fh + mov [extended_code],50h + or [vex_required],2 + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + mov [postbyte_register],al + cmp ah,4 + je avx_movmskps_reg_ok + cmp ah,8 + jne invalid_operand_size + cmp [code_type],64 + jne invalid_operand + avx_movmskps_reg_ok: + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov bl,al + jmp nomem_instruction_ready +avx_maskmovdqu_instruction: + or [vex_required],2 + jmp maskmovdqu_instruction +avx_pmovmskb_instruction: + or [vex_required],2 + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + cmp ah,4 + je avx_pmovmskb_reg_size_ok + cmp [code_type],64 + jne invalid_operand_size + cmp ah,8 + jnz invalid_operand_size + avx_pmovmskb_reg_size_ok: + mov [postbyte_register],al + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov bl,al + jmp nomem_instruction_ready + +gather_pd_instruction: + or [rex_prefix],8 +gather_ps_instruction: + call setup_66_0f_38 + or [vex_required],4 + or [operand_flags],20h + call take_avx_register + mov [postbyte_register],al + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + xor cl,cl + xchg cl,[operand_size] + push ecx + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_argument + call get_address + pop eax + xchg al,[operand_size] + gather_mem_size_check: + mov ah,4 + test [rex_prefix],8 + jz gather_elements_size_ok + add ah,ah + gather_elements_size_ok: + mov [mmx_size],ah + test al,al + jz gather_mem_size_ok + cmp al,ah + jne invalid_operand_size + gather_mem_size_ok: + cmp byte [esi],',' + je gather_reg_mem_reg + test [vex_required],20h + jz invalid_operand + mov ah,[operand_size] + mov al,80h + jmp gather_arguments_ok + gather_reg_mem_reg: + or [vex_required],2 + inc esi + call take_avx_register + gather_arguments_ok: + mov [vex_register],al + cmp al,[postbyte_register] + je disallowed_combination_of_registers + mov al,bl + and al,11111b + cmp al,[postbyte_register] + je disallowed_combination_of_registers + cmp al,[vex_register] + je disallowed_combination_of_registers + mov al,bl + shr al,5 + cmp al,0Ch shr 1 + je gather_vr128 + mov ah,32 + cmp al,6 shr 1 + jne gather_regular + add ah,ah + gather_regular: + mov al,[rex_prefix] + shr al,3 + xor al,[supplemental_code] + test al,1 + jz gather_uniform + test [supplemental_code],1 + jz gather_double + mov al,ah + xchg al,[operand_size] + add al,al + cmp al,ah + jne invalid_operand_size + jmp instruction_ready + gather_double: + add ah,ah + gather_uniform: + cmp ah,[operand_size] + jne invalid_operand_size + jmp instruction_ready + gather_vr128: + cmp ah,16 + je instruction_ready + cmp ah,32 + jne invalid_operand_size + test [supplemental_code],1 + jnz invalid_operand_size + test [rex_prefix],8 + jz invalid_operand_size + jmp instruction_ready +scatter_pd_instruction: + or [rex_prefix],8 +scatter_ps_instruction: + call setup_66_0f_38 + or [vex_required],4+8 + or [operand_flags],20h + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_argument + call get_address + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + xor al,al + xchg al,[operand_size] + push eax + call take_avx_register + mov [postbyte_register],al + pop eax + jmp gather_mem_size_check +gatherpf_qpd_instruction: + mov ah,0C7h + jmp gatherpf_pd_instruction +gatherpf_dpd_instruction: + mov ah,0C6h + gatherpf_pd_instruction: + or [rex_prefix],8 + mov cl,8 + jmp gatherpf_instruction +gatherpf_qps_instruction: + mov ah,0C7h + jmp gatherpf_ps_instruction +gatherpf_dps_instruction: + mov ah,0C6h + gatherpf_ps_instruction: + mov cl,4 + gatherpf_instruction: + mov [mmx_size],cl + mov [postbyte_register],al + mov al,ah + call setup_66_0f_38 + or [vex_required],4+8 + or [operand_flags],20h + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_argument + call get_address + call take_avx512_mask + mov ah,[mmx_size] + mov al,[operand_size] + or al,al + jz gatherpf_mem_size_ok + cmp al,ah + jne invalid_operand_size + gatherpf_mem_size_ok: + mov [operand_size],64 + mov al,6 shr 1 + cmp ah,4 + je gatherpf_check_vsib + cmp [supplemental_code],0C6h + jne gatherpf_check_vsib + mov al,0Eh shr 1 + gatherpf_check_vsib: + mov ah,bl + shr ah,5 + cmp al,ah + jne invalid_operand + jmp instruction_ready + +bmi_instruction: + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],0F3h + mov [postbyte_register],al + bmi_reg: + or [vex_required],2 + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + mov [vex_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je bmi_reg_reg + cmp al,'[' + jne invalid_argument + call get_address + call operand_32or64 + jmp instruction_ready + bmi_reg_reg: + lods byte [esi] + call convert_register + mov bl,al + call operand_32or64 + jmp nomem_instruction_ready + operand_32or64: + mov al,[operand_size] + cmp al,4 + je operand_32or64_ok + cmp al,8 + jne invalid_operand_size + cmp [code_type],64 + jne invalid_operand + or [rex_prefix],8 + operand_32or64_ok: + ret +pdep_instruction: + mov [opcode_prefix],0F2h + jmp andn_instruction +pext_instruction: + mov [opcode_prefix],0F3h +andn_instruction: + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],al + or [vex_required],2 + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + jmp bmi_reg +sarx_instruction: + mov [opcode_prefix],0F3h + jmp bzhi_instruction +shrx_instruction: + mov [opcode_prefix],0F2h + jmp bzhi_instruction +shlx_instruction: + mov [opcode_prefix],66h +bzhi_instruction: + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],al + or [vex_required],2 + call get_reg_mem + jc bzhi_reg_reg + call get_vex_source_register + jc invalid_operand + call operand_32or64 + jmp instruction_ready + bzhi_reg_reg: + call get_vex_source_register + jc invalid_operand + call operand_32or64 + jmp nomem_instruction_ready + get_vex_source_register: + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne no_vex_source_register + lods byte [esi] + call convert_register + mov [vex_register],al + clc + ret + no_vex_source_register: + stc + ret +bextr_instruction: + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],al + or [vex_required],2 + call get_reg_mem + jc bextr_reg_reg + call get_vex_source_register + jc bextr_reg_mem_imm32 + call operand_32or64 + jmp instruction_ready + bextr_reg_reg: + call get_vex_source_register + jc bextr_reg_reg_imm32 + call operand_32or64 + jmp nomem_instruction_ready + setup_bextr_imm_opcode: + mov [xop_opcode_map],0Ah + mov [base_code],10h + call operand_32or64 + ret + bextr_reg_mem_imm32: + call get_imm32 + call setup_bextr_imm_opcode + jmp store_instruction_with_imm32 + bextr_reg_reg_imm32: + call get_imm32 + call setup_bextr_imm_opcode + store_nomem_instruction_with_imm32: + call store_nomem_instruction + mov eax,dword [value] + call mark_relocation + stos dword [edi] + jmp instruction_assembled + get_imm32: + cmp al,'(' + jne invalid_operand + push edx ebx ecx + call get_dword_value + mov dword [value],eax + pop ecx ebx edx + ret +rorx_instruction: + mov [opcode_prefix],0F2h + mov [base_code],0Fh + mov [extended_code],3Ah + mov [supplemental_code],al + or [vex_required],2 + call get_reg_mem + jc rorx_reg_reg + call operand_32or64 + jmp mmx_imm8 + rorx_reg_reg: + call operand_32or64 + jmp mmx_nomem_imm8 + +tbm_instruction: + mov [xop_opcode_map],9 + mov ah,al + shr ah,4 + and al,111b + mov [base_code],ah + mov [postbyte_register],al + jmp bmi_reg + +llwpcb_instruction: + or [vex_required],2 + mov [xop_opcode_map],9 + mov [base_code],12h + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + mov bl,al + call operand_32or64 + jmp nomem_instruction_ready +lwpins_instruction: + or [vex_required],2 + mov [xop_opcode_map],0Ah + mov [base_code],12h + mov [vex_register],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + xor cl,cl + xchg cl,[operand_size] + lods byte [esi] + call get_size_operator + cmp al,10h + je lwpins_reg_reg + cmp al,'[' + jne invalid_argument + push ecx + call get_address + pop eax + xchg al,[operand_size] + test al,al + jz lwpins_reg_mem_size_ok + cmp al,4 + jne invalid_operand_size + lwpins_reg_mem_size_ok: + call prepare_lwpins + jmp store_instruction_with_imm32 + lwpins_reg_reg: + lods byte [esi] + call convert_register + cmp ah,4 + jne invalid_operand_size + mov [operand_size],cl + mov bl,al + call prepare_lwpins + jmp store_nomem_instruction_with_imm32 + prepare_lwpins: + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_imm32 + call operand_32or64 + mov al,[vex_register] + xchg al,[postbyte_register] + mov [vex_register],al + ret + +xop_single_source_sd_instruction: + or [operand_flags],2 + mov [mmx_size],8 + jmp xop_instruction_9 +xop_single_source_ss_instruction: + or [operand_flags],2 + mov [mmx_size],4 + jmp xop_instruction_9 +xop_single_source_instruction: + or [operand_flags],2 + mov [mmx_size],0 + xop_instruction_9: + mov [base_code],al + mov [xop_opcode_map],9 + jmp avx_xop_common +xop_single_source_128bit_instruction: + or [operand_flags],2 + mov [mmx_size],16 + jmp xop_instruction_9 +xop_triple_source_128bit_instruction: + mov [immediate_size],-1 + mov byte [value],0 + mov [mmx_size],16 + jmp xop_instruction_8 +xop_128bit_instruction: + mov [immediate_size],-2 + mov byte [value],0 + mov [mmx_size],16 + xop_instruction_8: + mov [base_code],al + mov [xop_opcode_map],8 + jmp avx_xop_common +xop_pcom_b_instruction: + mov ah,0CCh + jmp xop_pcom_instruction +xop_pcom_d_instruction: + mov ah,0CEh + jmp xop_pcom_instruction +xop_pcom_q_instruction: + mov ah,0CFh + jmp xop_pcom_instruction +xop_pcom_w_instruction: + mov ah,0CDh + jmp xop_pcom_instruction +xop_pcom_ub_instruction: + mov ah,0ECh + jmp xop_pcom_instruction +xop_pcom_ud_instruction: + mov ah,0EEh + jmp xop_pcom_instruction +xop_pcom_uq_instruction: + mov ah,0EFh + jmp xop_pcom_instruction +xop_pcom_uw_instruction: + mov ah,0EDh + xop_pcom_instruction: + mov byte [value],al + mov [immediate_size],-4 + mov [mmx_size],16 + mov [base_code],ah + mov [xop_opcode_map],8 + jmp avx_xop_common +vpcmov_instruction: + or [vex_required],2 + mov [immediate_size],-2 + mov byte [value],0 + mov [mmx_size],0 + mov [base_code],al + mov [xop_opcode_map],8 + jmp avx_xop_common +xop_shift_instruction: + mov [base_code],al + or [vex_required],2 + mov [xop_opcode_map],9 + call take_avx_register + cmp ah,16 + jne invalid_operand + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + je xop_shift_reg_mem + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [vex_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + push esi + xor cl,cl + xchg cl,[operand_size] + lods byte [esi] + call get_size_operator + pop esi + xchg cl,[operand_size] + cmp al,'[' + je xop_shift_reg_reg_mem + cmp al,10h + jne xop_shift_reg_reg_imm + call take_avx_register + mov bl,al + xchg bl,[vex_register] + jmp nomem_instruction_ready + xop_shift_reg_reg_mem: + or [rex_prefix],8 + lods byte [esi] + call get_size_operator + call get_address + jmp instruction_ready + xop_shift_reg_reg_imm: + xor bl,bl + xchg bl,[vex_register] + cmp [base_code],94h + jae invalid_operand + add [base_code],30h + mov [xop_opcode_map],8 + dec esi + jmp mmx_nomem_imm8 + xop_shift_reg_mem: + call get_address + lods byte [esi] + cmp al,',' + jne invalid_operand + push esi + xor cl,cl + xchg cl,[operand_size] + lods byte [esi] + call get_size_operator + pop esi + xchg cl,[operand_size] + cmp al,10h + jne xop_shift_reg_mem_imm + call take_avx_register + mov [vex_register],al + jmp instruction_ready + xop_shift_reg_mem_imm: + cmp [base_code],94h + jae invalid_operand + add [base_code],30h + mov [xop_opcode_map],8 + dec esi + jmp mmx_imm8 + +avx512_4vnniw_instruction: + mov [opcode_prefix],0F2h + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],al + mov [mmx_size],16 + mov [broadcast_size],0 + or [vex_required],8 + call take_avx_register + mov [postbyte_register],al + call take_avx512_mask + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_register + mov [vex_register],al + cmp byte [esi],'+' + jne reg4_ok + inc esi + cmp dword [esi],29030128h + jne invalid_operand + lods dword [esi] + reg4_ok: + cmp [operand_size],64 + jne invalid_operand_size + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_avx_rm + jc invalid_operand + mov [operand_size],64 + jmp instruction_ready + +set_evex_mode: + mov [evex_mode],al + jmp instruction_assembled + +take_avx_register: + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] +convert_avx_register: + mov ah,al + and al,1Fh + and ah,0E0h + sub ah,60h + jb invalid_operand + jz avx512_register_size + sub ah,60h + jb invalid_operand + jnz avx_register_size_ok + mov ah,16 + jmp avx_register_size_ok + avx512_register_size: + mov ah,64 + avx_register_size_ok: + cmp al,8 + jb match_register_size + cmp [code_type],64 + jne invalid_operand + jmp match_register_size +store_vex_instruction_code: + test [rex_prefix],10h + jnz invalid_operand + test [vex_required],0F8h + jnz store_evex_instruction_code + test [vex_register],10000b + jnz store_evex_instruction_code + cmp [operand_size],64 + je store_evex_instruction_code + mov al,[base_code] + cmp al,0Fh + jne store_xop_instruction_code + test [vex_required],2 + jnz prepare_vex + cmp [evex_mode],0 + je prepare_vex + cmp [displacement_compression],1 + jne prepare_vex + cmp edx,80h + jb prepare_vex + cmp edx,-80h + jae prepare_vex + mov al,bl + or al,bh + shr al,4 + cmp al,2 + je prepare_vex + call compress_displacement + cmp [displacement_compression],2 + ja prepare_evex + jb prepare_vex + dec [displacement_compression] + mov edx,[uncompressed_displacement] + prepare_vex: + mov ah,[extended_code] + cmp ah,38h + je store_vex_0f38_instruction_code + cmp ah,3Ah + je store_vex_0f3a_instruction_code + test [rex_prefix],1011b + jnz store_vex_0f_instruction_code + mov [edi+2],ah + mov byte [edi],0C5h + mov al,[vex_register] + not al + shl al,3 + mov ah,[rex_prefix] + shl ah,5 + and ah,80h + xor al,ah + call get_vex_lpp_bits + mov [edi+1],al + call check_vex + add edi,3 + ret + get_vex_lpp_bits: + cmp [operand_size],32 + jne get_vex_pp_bits + or al,100b + get_vex_pp_bits: + mov ah,[opcode_prefix] + cmp ah,66h + je vex_66 + cmp ah,0F3h + je vex_f3 + cmp ah,0F2h + je vex_f2 + test ah,ah + jnz disallowed_combination_of_registers + ret + vex_f2: + or al,11b + ret + vex_f3: + or al,10b + ret + vex_66: + or al,1 + ret + store_vex_0f38_instruction_code: + mov al,11100010b + mov ah,[supplemental_code] + jmp make_c4_vex + store_vex_0f3a_instruction_code: + mov al,11100011b + mov ah,[supplemental_code] + jmp make_c4_vex + store_vex_0f_instruction_code: + mov al,11100001b + make_c4_vex: + mov [edi+3],ah + mov byte [edi],0C4h + mov ah,[rex_prefix] + shl ah,5 + xor al,ah + mov [edi+1],al + call check_vex + mov al,[vex_register] + xor al,1111b + shl al,3 + mov ah,[rex_prefix] + shl ah,4 + and ah,80h + or al,ah + call get_vex_lpp_bits + mov [edi+2],al + add edi,4 + ret + check_vex: + cmp [code_type],64 + je vex_ok + not al + test al,11000000b + jnz invalid_operand + test [rex_prefix],40h + jnz invalid_operand + vex_ok: + ret +store_xop_instruction_code: + mov [edi+3],al + mov byte [edi],8Fh + mov al,[xop_opcode_map] + mov ah,[rex_prefix] + test ah,40h + jz xop_ok + cmp [code_type],64 + jne invalid_operand + xop_ok: + not ah + shl ah,5 + xor al,ah + mov [edi+1],al + mov al,[vex_register] + xor al,1111b + shl al,3 + mov ah,[rex_prefix] + shl ah,4 + and ah,80h + or al,ah + call get_vex_lpp_bits + mov [edi+2],al + add edi,4 + ret +store_evex_instruction_code: + test [vex_required],2 + jnz invalid_operand + cmp [base_code],0Fh + jne invalid_operand + cmp [displacement_compression],1 + jne prepare_evex + call compress_displacement + prepare_evex: + mov ah,[extended_code] + cmp ah,38h + je store_evex_0f38_instruction_code + cmp ah,3Ah + je store_evex_0f3a_instruction_code + mov al,11110001b + make_evex: + mov [edi+4],ah + mov byte [edi],62h + mov ah,[rex_prefix] + shl ah,5 + xor al,ah + mov ah,[vex_required] + and ah,10h + xor al,ah + mov [edi+1],al + call check_vex + mov al,[vex_register] + not al + and al,1111b + shl al,3 + mov ah,[rex_prefix] + shl ah,4 + or ah,[rex_prefix] + and ah,80h + or al,ah + or al,100b + call get_vex_pp_bits + mov [edi+2],al + mov al,[vex_register] + not al + shr al,1 + and al,1000b + test [vex_required],80h + jne evex_rounding + mov ah,[operand_size] + cmp ah,16 + jbe evex_l_ok + or al,ah + jmp evex_l_ok + evex_rounding: + mov ah,[rounding_mode] + shl ah,5 + or al,ah + evex_l_ok: + test [vex_required],20h + jz evex_zaaa_ok + or al,[mask_register] + evex_zaaa_ok: + test [vex_required],40h + jz evex_b_ok + or al,10h + evex_b_ok: + mov [edi+3],al + add edi,5 + ret + store_evex_0f38_instruction_code: + mov al,11110010b + mov ah,[supplemental_code] + jmp make_evex + store_evex_0f3a_instruction_code: + mov al,11110011b + mov ah,[supplemental_code] + jmp make_evex +compress_displacement: + mov ebp,ecx + mov [uncompressed_displacement],edx + or edx,edx + jz displacement_compressed + xor ecx,ecx + mov cl,[mmx_size] + test cl,cl + jnz calculate_displacement_scale + mov cl,[operand_size] + calculate_displacement_scale: + bsf ecx,ecx + jz displacement_compression_ok + xor eax,eax + shrd eax,edx,cl + jnz displacement_not_compressed + sar edx,cl + cmp edx,80h + jb displacement_compressed + cmp edx,-80h + jnb displacement_compressed + shl edx,cl + displacement_not_compressed: + inc [displacement_compression] + jmp displacement_compression_ok + displacement_compressed: + add [displacement_compression],2 + displacement_compression_ok: + mov ecx,ebp + ret diff --git a/toolchain/fasmw17332/SOURCE/DOS/DPMI.INC b/toolchain/fasmw17332/SOURCE/DOS/DPMI.INC new file mode 100644 index 0000000..0195e1d --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/DOS/DPMI.INC @@ -0,0 +1,108 @@ + +; flat assembler interface for DOS +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +init_dpmi_memory: + mov ax,500h ; get free memory information + mov edi,[buffer_address] + int 31h + mov ebx,[edi] + allocate_dpmi_memory: + mov edx,[memory_setting] + shl edx,10 + jz dpmi_memory_size_ok + cmp ebx,edx + jbe dpmi_memory_size_ok + mov ebx,edx + dpmi_memory_size_ok: + mov [memory_end],ebx + mov ecx,ebx + shr ebx,16 + mov ax,501h + int 31h + jnc dpmi_memory_ok + mov ebx,[memory_end] + shr ebx,1 + cmp ebx,4000h + jb out_of_memory + jmp allocate_dpmi_memory + dpmi_memory_ok: + shl ebx,16 + mov bx,cx + sub ebx,[program_base] + jc out_of_memory + mov [memory_start],ebx + add [memory_end],ebx + mov ax,100h ; get free conventional memory size + mov bx,-1 + int 31h + movzx ecx,bx + shl ecx,4 + jecxz no_conventional_memory + mov ax,100h ; allocate all conventional memory + int 31h + movzx edi,ax + shl edi,4 + sub edi,[program_base] + jc no_conventional_memory + mov [additional_memory],edi + mov [additional_memory_end],edi + add [additional_memory_end],ecx + mov eax,[memory_end] + sub eax,[memory_start] + shr eax,2 + cmp eax,ecx + ja no_conventional_memory + ret + no_conventional_memory: + mov eax,[memory_end] + mov ebx,[memory_start] + sub eax,ebx + shr eax,2 + mov [additional_memory],ebx + add ebx,eax + mov [additional_memory_end],ebx + mov [memory_start],ebx + ret + +dpmi_dos_int: + mov [real_mode_segment],main + simulate_real_mode: + push 0 ; SS:SP (DPMI will allocate stack) + push 0 ; CS:IP (ignored) + push 0 + push [real_mode_segment] ; DS + push [real_mode_segment] ; ES + stc + pushfw + push eax + push ecx + push edx + push ebx + push 0 + push ebp + push esi + push edi + mov ax,300h + mov bx,21h + xor cx,cx + mov edi,esp + push es ss + pop es + int 31h + pop es + mov edi,[esp] + mov esi,[esp+4] + mov ebp,[esp+8] + mov ebx,[esp+10h] + mov edx,[esp+14h] + mov ecx,[esp+18h] + mov ah,[esp+20h] + sahf + mov eax,[esp+1Ch] + lea esp,[esp+32h] + ret +dpmi_dos_int_with_buffer: + mov [real_mode_segment],buffer + jmp simulate_real_mode diff --git a/toolchain/fasmw17332/SOURCE/DOS/FASM.ASM b/toolchain/fasmw17332/SOURCE/DOS/FASM.ASM new file mode 100644 index 0000000..64136cd --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/DOS/FASM.ASM @@ -0,0 +1,435 @@ + +; flat assembler interface for DOS +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + + format MZ + heap 0 + stack 8000h + entry main:start + +include 'modes.inc' + +segment main use16 + +start: + + mov ax,ds + mov dx,[2Ch] + push cs cs + pop ds es + mov [psp_segment],ax + mov [environment_segment],dx + + mov dx,_logo + mov ah,9 + int 21h + + cld + + call go32 + use32 + + call get_params + jc information + + call init_memory + + mov esi,_memory_prefix + call display_string + mov eax,[memory_end] + sub eax,[memory_start] + add eax,[additional_memory_end] + sub eax,[additional_memory] + shr eax,10 + call display_number + mov esi,_memory_suffix + call display_string + + xor ah,ah + int 1Ah + mov ax,cx + shl eax,16 + mov ax,dx + mov [start_time],eax + + cmp [mode],dpmi + je compile + jmp main+(first_segment shr 4):first_gate-first_segment + +compile: + and [preprocessing_done],0 + call preprocessor + or [preprocessing_done],-1 + call parser + call assembler + call formatter + +finish: + call display_user_messages + movzx eax,[current_pass] + inc eax + call display_number + mov esi,_passes_suffix + call display_string + xor ah,ah + int 1Ah + mov ax,cx + shl eax,16 + mov ax,dx + sub eax,[start_time] + mov ebx,100 + mul ebx + mov ebx,182 + div ebx + or eax,eax + jz display_bytes_count + xor edx,edx + mov ebx,10 + div ebx + push edx + call display_number + mov ah,2 + mov dl,'.' + int 21h + pop eax + call display_number + mov esi,_seconds_suffix + call display_string + display_bytes_count: + mov eax,[written_size] + call display_number + mov esi,_bytes_suffix + call display_string + xor al,al + jmp exit_program + +information: + mov esi,_usage + call display_string + mov al,1 + jmp exit_program + +get_params: + mov [input_file],0 + mov [output_file],0 + mov [symbols_file],0 + mov [memory_setting],0 + mov [passes_limit],100 + mov [definitions_pointer],predefinitions + push ds + mov ds,[psp_segment] + mov esi,81h + mov edi,params + find_param: + lodsb + cmp al,20h + je find_param + cmp al,'-' + je option_param + cmp al,0Dh + je all_params + or al,al + jz all_params + cmp [es:input_file],0 + jne get_output_file + mov [es:input_file],edi + jmp process_param + get_output_file: + cmp [es:output_file],0 + jne bad_params + mov [es:output_file],edi + process_param: + cmp al,22h + je string_param + copy_param: + stosb + lodsb + cmp al,20h + je param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + jmp copy_param + string_param: + lodsb + cmp al,22h + je string_param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + stosb + jmp string_param + option_param: + lodsb + cmp al,'m' + je memory_option + cmp al,'M' + je memory_option + cmp al,'p' + je passes_option + cmp al,'P' + je passes_option + cmp al,'d' + je definition_option + cmp al,'D' + je definition_option + cmp al,'s' + je symbols_option + cmp al,'S' + je symbols_option + invalid_option: + pop ds + stc + ret + get_option_value: + xor eax,eax + mov edx,eax + get_option_digit: + lodsb + cmp al,20h + je option_value_ok + cmp al,0Dh + je option_value_ok + or al,al + jz option_value_ok + sub al,30h + jc bad_params_value + cmp al,9 + ja bad_params_value + imul edx,10 + jo bad_params_value + add edx,eax + jc bad_params_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + bad_params_value: + stc + ret + memory_option: + lodsb + cmp al,20h + je memory_option + cmp al,0Dh + je invalid_option + or al,al + jz invalid_option + dec esi + call get_option_value + jc invalid_option + or edx,edx + jz invalid_option + cmp edx,1 shl (32-10) + jae invalid_option + mov [es:memory_setting],edx + jmp find_param + passes_option: + lodsb + cmp al,20h + je passes_option + cmp al,0Dh + je invalid_option + or al,al + jz invalid_option + dec esi + call get_option_value + jc bad_params + or edx,edx + jz invalid_option + cmp edx,10000h + ja invalid_option + mov [es:passes_limit],dx + jmp find_param + definition_option: + lodsb + cmp al,20h + je definition_option + cmp al,0Dh + je bad_params + or al,al + jz bad_params + dec esi + push edi + mov edi,[es:definitions_pointer] + call convert_definition_option + mov [es:definitions_pointer],edi + pop edi + jc invalid_option + jmp find_param + symbols_option: + mov [es:symbols_file],edi + find_symbols_file_name: + lodsb + cmp al,20h + jne process_param + jmp find_symbols_file_name + param_end: + dec esi + string_param_end: + xor al,al + stosb + jmp find_param + all_params: + xor al,al + stosb + pop ds + cmp [input_file],0 + je no_input_file + mov eax,[definitions_pointer] + mov byte [eax],0 + mov [initial_definitions],predefinitions + clc + ret + bad_params: + pop ds + no_input_file: + stc + ret + convert_definition_option: + mov ecx,edi + xor al,al + stosb + copy_definition_name: + lodsb + cmp al,'=' + je copy_definition_value + cmp al,20h + je bad_definition_option + cmp al,0Dh + je bad_definition_option + or al,al + jz bad_definition_option + stosb + inc byte [es:ecx] + jnz copy_definition_name + bad_definition_option: + stc + ret + copy_definition_value: + lodsb + cmp al,20h + je definition_value_end + cmp al,0Dh + je definition_value_end + or al,al + jz definition_value_end + cmp al,'\' + jne definition_value_character + cmp byte [esi],20h + jne definition_value_character + lodsb + definition_value_character: + stosb + jmp copy_definition_value + definition_value_end: + dec esi + xor al,al + stosb + clc + ret + +include '..\version.inc' + +_logo db 'flat assembler version ',VERSION_STRING,24h +_copyright db 'Copyright (c) 1999-2022, Tomasz Grysztar',0Dh,0Ah,0 + +_usage db 0Dh,0Ah + db 'usage: fasm [output]',0Dh,0Ah + db 'optional settings:',0Dh,0Ah + db ' -m set the limit in kilobytes for the available memory',0Dh,0Ah + db ' -p set the maximum allowed number of passes',0Dh,0Ah + db ' -d = define symbolic variable',0Dh,0Ah + db ' -s dump symbolic information for debugging',0Dh,0Ah + db 0 +_memory_prefix db ' (',0 +_memory_suffix db ' kilobytes memory)',0Dh,0Ah,0 +_passes_suffix db ' passes, ',0 +_seconds_suffix db ' seconds, ',0 +_bytes_suffix db ' bytes.',0Dh,0Ah,0 + +error_prefix db 'error: ',0 +error_suffix db '.' +cr_lf db 0Dh,0Ah,0 +line_number_start db ' [',0 +line_data_start db ':',0Dh,0Ah,0 +preprocessed_instruction_prefix db 'processed: ',0 + +include 'dpmi.inc' + +align 16 +first_segment: + +include '..\preproce.inc' +include '..\parser.inc' +include '..\exprpars.inc' + +align 16 +second_segment: + +include '..\exprcalc.inc' +include '..\errors.inc' +include '..\symbdump.inc' + +include 'system.inc' + +first_gate: + and [preprocessing_done],0 + call preprocessor + or [preprocessing_done],-1 + call parser + jmp main+(second_segment shr 4):second_gate-second_segment +first_segment_top = $ - first_segment + +include '..\assemble.inc' +include '..\formats.inc' +include '..\x86_64.inc' +include '..\avx.inc' + +second_gate: + call assembler + call formatter + jmp main:finish + +second_segment_top = $ - second_segment + +if first_segment_top>=10000h | second_segment_top>=10000h + if UNREAL_ENABLED>0 + UNREAL_ENABLED = -1 + else + UNREAL_ENABLED = 0 + end if +else + if UNREAL_ENABLED<0 + UNREAL_ENABLED = -1 + else + UNREAL_ENABLED = 1 + end if +end if + +include '..\tables.inc' +include '..\messages.inc' + +align 4 + +include '..\variable.inc' + +memory_setting dd ? +start_time dd ? +definitions_pointer dd ? +params rb 100h +predefinitions rb 100h + +mode dw ? +real_mode_segment dw ? +displayed_count dd ? +last_displayed rb 2 +preprocessing_done db ? + +segment buffer + +rb 1000h diff --git a/toolchain/fasmw17332/SOURCE/DOS/MODES.INC b/toolchain/fasmw17332/SOURCE/DOS/MODES.INC new file mode 100644 index 0000000..c104032 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/DOS/MODES.INC @@ -0,0 +1,539 @@ + +; flat assembler interface for DOS +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +segment modes use16 + +real32: + mov ax,7202h + push ax + popf + pushf + pop bx + cmp ax,bx + je processor_ok + call init_error + db 'required 80386 or better',24h + processor_ok: + mov eax,ds + shl eax,4 + mov [program_base],eax + mov eax,buffer + shl eax,4 + sub eax,[program_base] + mov [buffer_address],eax + +if UNREAL_ENABLED>0 + + smsw ax + test al,1 + jnz dpmi + mov eax,cs ; calculate linear address of GDT + shl eax,4 + or dword [cs:real32_GDT+10],eax + or dword [cs:real16_GDT+10],eax + add [cs:real32_GDT_address],eax + add [cs:real16_GDT_address],eax + cli + lgdt [cs:real32_GDTR] + mov eax,cr0 + or al,1 + mov cr0,eax + jmp 1 shl 3:test_pm32 + no_rm32: + sti + jmp dpmi + test_pm32: + use32 + mov eax,cr0 + and al,not 1 + mov cr0,eax + mov ebx,0FFFFh + jmp modes:test_rm32 + test_rm32: + inc ebx + jz short no_rm32 + lgdt [cs:real16_GDTR] + mov eax,cr0 + or al,1 + mov cr0,eax + jmp 1 shl 3:test_pm16 + test_pm16: + use16 + mov eax,cr0 + and al,not 1 + mov cr0,eax + jmp modes:test_rm16 + test_rm16: + sti + mov bx,(400h+(100h*interrupt.size)) shr 4 + mov ah,48h + int 21h + jc not_enough_memory + push ds es + mov es,ax + push cs + pop ds + movzx eax,ax + shl eax,4 + mov [real32_IDT_base],eax + mov dx,100h + xor bx,bx + mov di,400h + init_interrupts: + mov si,interrupt + mov [si+interrupt.vector],bx + mov word [es:bx],di + mov word [es:bx+2],es + mov cx,interrupt.size + rep movsb + add bx,4 + dec dx + jnz init_interrupts + pop es ds + call modes:switch_real32 + use32 + mov [mode],real32 + retfw + use16 + +switch_real32: + pushfw + push eax + push word ds + push word es + push word fs + push word gs + cli + mov eax,ss + mov cr3,eax + lgdt [cs:real32_GDTR] + mov eax,cr0 ; switch to protected mode + or al,1 + mov cr0,eax + jmp 1 shl 3:pm32_start + pm32_start: + use32 + mov ax,2 shl 3 ; load 32-bit data descriptor + mov ds,ax ; to all data segment registers + mov es,ax + mov fs,ax + mov gs,ax + mov ss,ax + mov eax,cr0 ; switch back to real mode + and al,not 1 + mov cr0,eax + jmp modes:pm32_end + pm32_end: + mov eax,cr3 + mov ss,ax + lidt [cs:real32_IDTR] + pop word gs + pop word fs + pop word es + pop word ds + pop eax + popfw + retfw + +switch_real16: + pushfw + push eax + cli + lgdt [cs:real16_GDTR] + mov eax,cr0 ; switch to protected mode + or al,1 + mov cr0,eax + jmp 1 shl 3:pm16_start + pm16_start: + use16 + mov eax,cr0 ; switch back to real mode + and al,not 1 + mov cr0,eax + jmp modes:pm16_end + pm16_end: + lidt [cs:real16_IDTR] + pop eax + popfw + retfd + use32 + +interrupt: + call modes:switch_real16 + use16 + movzx esp,sp + push word [esp+4] + push cs + call .real16 + pushfw + pop word [esp+4] + call modes:switch_real32 + use32 + iretw + .real16: + use16 + push eax + push ds + xor ax,ax + mov ds,ax + mov eax,[word 0] + label .vector word at $-2-interrupt + pop ds + xchg eax,[esp] + retfw + .size = $-interrupt + +label real32_GDTR pword +real32_GDT_limit dw 3*8-1 ; limit of GDT +real32_GDT_address dd real32_GDT ; linear address of GDT +real32_GDT rw 4 ; null descriptor + dw 0FFFFh,0,9A00h,0CFh ; 32-bit code descriptor + dw 0FFFFh,0,9200h,08Fh ; 4 GB data descriptor +label real16_GDTR pword +real16_GDT_limit dw 2*8-1 ; limit of GDT +real16_GDT_address dd real16_GDT ; linear address of GDT +real16_GDT rw 4 ; null descriptor + dw 0FFFFh,0,9A00h,0 ; 16-bit code descriptor + +label real32_IDTR pword +real32_IDT_limit dw 3FFh +real32_IDT_base dd ? +label real16_IDTR pword +real16_IDT_limit dw 3FFh +real16_IDT_base dd 0 + +end if + +dpmi: + mov ax,1687h + int 2Fh + or ax,ax ; DPMI installed? + jnz no_dpmi + test bl,1 ; 32-bit programs supported? + jz no_dpmi + mov word [cs:mode_switch],di + mov word [cs:mode_switch+2],es + mov bx,si ; allocate memory for DPMI data + mov ah,48h + int 21h + jc not_enough_memory + mov ds,[environment_segment] + mov es,ax + mov ax,1 + call far [cs:mode_switch] ; switch to protected mode + jc no_dpmi + mov cx,1 + xor ax,ax + int 31h ; allocate descriptor for code + mov si,ax + xor ax,ax + int 31h ; allocate descriptor for data + mov di,ax + mov dx,cs + lar cx,dx + shr cx,8 + or cx,0C000h + mov bx,si + mov ax,9 + int 31h ; set code descriptor access rights + mov dx,ds + lar cx,dx + shr cx,8 + or cx,0C000h + mov bx,di + int 31h ; set data descriptor access rights + mov ecx,main + shl ecx,4 + mov dx,cx + shr ecx,16 + mov ax,7 + int 31h ; set data descriptor base address + movzx ecx,word [esp+2] + shl ecx,4 + mov dx,cx + shr ecx,16 + mov bx,si + int 31h ; set code descriptor base address + mov cx,0FFFFh + mov dx,0FFFFh + mov ax,8 ; set segment limit to 4 GB + int 31h + mov bx,di + int 31h + mov ax,ds + mov ds,di + mov [psp_segment],es + mov [environment_segment],ax + mov es,di + mov [mode],dpmi + pop ebx + movzx ebx,bx + push esi + push ebx + retfd + +init_error: + push cs + pop ds + mov dx,init_error_prefix + mov ah,9 + int 21h + pop dx + int 21h + mov dx,init_error_suffix + int 21h + mov ax,04CFFh + int 21h + +init_error_prefix db 0Dh,0Ah,'error: ',24h +init_error_suffix db '.',0Dh,0Ah,24h + +mode_switch dd ? + + not_enough_memory: + call init_error + db 'not enough conventional memory',24h + +if UNREAL_ENABLED>0 + + no_dpmi: + smsw ax + test al,1 + jz no_real32 + call init_error + db 'system is in protected mode without 32-bit DPMI services',24h + no_real32: + call init_error + db 'processor is not able to enter 32-bit real mode',24h + +else + + no_dpmi: + call init_error + db 'no 32-bit DPMI services are available',24h + +end if + +use32 + +if UNREAL_ENABLED>0 + +init_real32_memory: + mov ax,4300h ; check for XMS + int 2Fh + cmp al,80h ; XMS present? + je xms_init + mov ax,0E801h ; check for large free extended memory + int 15h + jnc large_raw_memory + mov ah,88h ; how much extended memory free? + int 15h + or ax,ax + jz no_extended_memory + movzx eax,ax ; convert AX kilobytes to pointer + shl eax,10 + jmp use_raw_memory + large_raw_memory: + movzx ecx,cx + shl ecx,10 + movzx edx,dx + shl edx,16 + mov eax,ecx + add eax,edx + use_raw_memory: + add eax,100000h + sub eax,[program_base] + mov [memory_end],eax + push ds + push 0 ; DS := 0 + pop ds + call enable_a20 ; enable A20 + call test_a20 ; is A20 enabled? + jz a20_ok + pop ds + jmp no_extended_memory + a20_ok: + lds bx,dword [4*19h] + mov eax,100000h ; initial free extended memory base + cmp dword [bx+12h],'VDIS' ; VDISK memory allocation? + jne short no_vdisk ; if present, get base of free memory + mov eax,dword [bx+2Ch] ; get first free extended memory byte + add eax,0Fh ; align on paragraph + and eax,0FFFFF0h ; address is only 24bit + no_vdisk: + push 0FFFFh ; DS := FFFFh for ext mem addressing + pop ds + cmp dword [13h],'VDIS' ; VDISK memory allocation? + jne short vdisk_ok ; if present, get base of free memory + movzx ebx,word [2Eh] ; get first free kilobyte + shl ebx,10 + cmp eax,ebx ; pick larger of 2 addresses + ja short vdisk_ok + mov eax,ebx + vdisk_ok: + pop ds + sub eax,[program_base] + mov [memory_start],eax + mov edx,[memory_setting] + shl edx,10 + jz extended_memory_ok + mov eax,[memory_end] + sub eax,[memory_start] + sub eax,edx + jbe extended_memory_ok + sub [memory_end],eax + jmp extended_memory_ok +enable_a20: + call test_a20 ; is A20 already enabled? + jz a20_enabled ; if yes, done + in al,92h ; PS/2 A20 enable + or al,2 + out 92h,al + call test_a20 ; is A20 enabled? + jz a20_enabled ; if yes, done + call kb_wait ; AT A20 enable + jnz a20_enabled + mov al,0D1h + out 64h,al + call kb_wait + jnz a20_enabled + mov al,0DFh + out 60h,al + call kb_wait + a20_enabled: + retn + kb_wait: ; wait for safe to write to 8042 + xor cx,cx + .loop: + in al,64h ; read 8042 status + test al,2 ; buffer full? + loopnz .loop ; if yes, loop + retn + test_a20: ; test for enabled A20 + mov al,[0] ; get byte from 0:0 + mov ah,al ; preserve old byte + not al ; modify byte + xchg al,[100000h] ; put modified byte to 0FFFFh:10h + cmp ah,[0] ; set zero if byte at 0:0 not modified + mov [100000h],al ; restore byte at 0FFFFh:10h + retn ; return, zero if A20 enabled +xms_init: + push es + mov ax,4310h ; get XMS driver address + int 2Fh + mov word [cs:xms_proc],bx ; store XMS driver address + mov word [cs:xms_proc+2],es + pop es + mov ah,3 ; enable A20 + call call_xms + cmp ax,1 ; error enabling A20? + jne no_extended_memory + mov ah,88h ; get free extended memory size (XMS 3.0) + xor bl,bl + call call_xms + or bl,bl + jz xms_large_init + mov ah,8 ; get free extended memory size + xor bl,bl + call call_xms + or bl,bl + jnz no_extended_memory + mov dx,ax + movzx eax,ax + shl eax,10 + mov [memory_end],eax + mov ah,9 ; allocate largest memory block + xms_allocate: + mov ecx,[memory_setting] + shl ecx,10 + jz xms_size_ok + cmp ecx,[memory_end] + jae xms_size_ok + mov [memory_end],ecx + mov edx,[memory_setting] + xms_size_ok: + call call_xms + mov [cs:xms_handle],dx + cmp ax,1 + jne no_extended_memory + mov ah,0Ch ; lock extended memory block + call call_xms + cmp ax,1 + jne no_extended_memory + shl edx,16 + mov dx,bx + sub edx,[program_base] + mov [memory_start],edx ; store memory block address + add [memory_end],edx + jmp extended_memory_ok + xms_large_init: + mov edx,eax + shl eax,10 + mov [memory_end],eax + mov ah,89h ; allocate largest memory block (XMS 3.0) + jmp xms_allocate + call_xms: + call modes:switch_real16 + use16 + call far dword [cs:xms_proc] + call modes:switch_real32 + use32 + retn +no_extended_memory: + xor eax,eax + mov [memory_start],eax +extended_memory_ok: + mov ah,48h ; get free conventional memory size + mov bx,-1 + int 21h + movzx ecx,bx + shl ecx,4 + mov ah,48h ; allocate all conventional memory + int 21h + movzx edi,ax + shl edi,4 + sub edi,[program_base] + mov [additional_memory],edi + mov [additional_memory_end],edi + add [additional_memory_end],ecx + cmp [memory_start],0 + je only_conventional_memory + mov eax,[memory_end] + sub eax,[memory_start] + shr eax,2 + cmp eax,ecx + jbe real32_memory_ok + mov eax,[memory_end] + mov ebx,[memory_start] + sub eax,ebx + shr eax,2 + mov [additional_memory],ebx + add ebx,eax + mov [additional_memory_end],ebx + mov [memory_start],ebx + real32_memory_ok: + retf + only_conventional_memory: + shr ecx,2 ; use part of conventional memory + add edi,ecx ; as a substitute for extended memory + mov [memory_start],edi + xchg [additional_memory_end],edi + mov [memory_end],edi + retf + +free_real32_memory: + cmp [cs:xms_handle],0 + je no_xms + mov ah,0Dh ; unlock extended memory block + mov dx,[cs:xms_handle] + call call_xms + mov ah,0Ah ; free extended memory block + call call_xms + no_xms: + retf + +xms_proc dd ? ; XMS driver pointer +xms_handle dw ? ; handle of XMS memory block + +end if diff --git a/toolchain/fasmw17332/SOURCE/DOS/SYSTEM.INC b/toolchain/fasmw17332/SOURCE/DOS/SYSTEM.INC new file mode 100644 index 0000000..e191f33 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/DOS/SYSTEM.INC @@ -0,0 +1,600 @@ + +; flat assembler interface for DOS +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +go32: + use16 + call modes:real32 + use32 + retw + +program_base dd ? +buffer_address dd ? +psp_segment dw ? +environment_segment dw ? + +if UNREAL_ENABLED>0 + +init_memory: + mov [stack_limit],0 + cmp [mode],dpmi + je init_dpmi_memory + call modes:init_real32_memory + ret +dos_int: + cmp [mode],dpmi + je dpmi_dos_int + stc + int 21h + ret +dos_int_with_buffer: + cmp [mode],dpmi + je dpmi_dos_int_with_buffer + push ds buffer + pop ds + stc + int 21h + pop ds + ret +exit_program: + cmp [mode],dpmi + je exit_state_ok + push eax + call modes:free_real32_memory + pop eax + exit_state_ok: + mov ah,4Ch + int 21h + +else + +init_memory: + mov [stack_limit],0 + jmp init_dpmi_memory +dos_int: + jmp dpmi_dos_int +dos_int_with_buffer: + jmp dpmi_dos_int_with_buffer +exit_program: + mov ah,4Ch + int 21h + +end if + +get_environment_variable: + mov ebx,esi + push ds + mov ds,[environment_segment] + xor esi,esi + compare_variable_names: + mov edx,ebx + compare_character: + lodsb + mov ah,[es:edx] + inc edx + cmp al,'=' + je end_of_variable_name + or ah,ah + jz next_variable + sub ah,al + jz compare_character + cmp ah,20h + jne next_variable + cmp al,41h + jb next_variable + cmp al,5Ah + jna compare_character + next_variable: + lodsb + or al,al + jnz next_variable + cmp byte [esi],0 + jne compare_variable_names + pop ds + ret + end_of_variable_name: + or ah,ah + jnz next_variable + copy_variable_value: + lodsb + cmp edi,[es:memory_end] + jae out_of_memory + stosb + or al,al + jnz copy_variable_value + dec edi + pop ds + ret + +open: + push esi edi + call adapt_path + mov ax,716Ch + mov bx,100000b + mov dx,1 + xor cx,cx + xor si,si + call dos_int_with_buffer + jnc open_done + cmp ax,7100h + je old_open + stc + jmp open_done + old_open: + mov ax,3D00h + xor dx,dx + call dos_int_with_buffer + open_done: + mov bx,ax + pop edi esi + ret + adapt_path: + mov esi,edx + mov edi,[buffer_address] + copy_path: + lodsb + cmp al,'/' + jne path_char_ok + mov al,'\' + path_char_ok: + stosb + or al,al + jnz copy_path + ret +create: + push esi edi + call adapt_path + mov ax,716Ch + mov bx,100001b + mov dx,10010b + xor cx,cx + xor si,si + xor di,di + call dos_int_with_buffer + jnc create_done + cmp ax,7100h + je old_create + stc + jmp create_done + old_create: + mov ah,3Ch + xor cx,cx + xor dx,dx + call dos_int_with_buffer + create_done: + mov bx,ax + pop edi esi + ret +write: + push edx esi edi ebp + mov ebp,ecx + mov esi,edx + .loop: + mov ecx,1000h + sub ebp,1000h + jnc .write + add ebp,1000h + mov ecx,ebp + xor ebp,ebp + .write: + push ecx + mov edi,[buffer_address] + shr ecx,2 + rep movsd + mov ecx,[esp] + and ecx,11b + rep movsb + pop ecx + mov ah,40h + xor dx,dx + call dos_int_with_buffer + or ebp,ebp + jnz .loop + pop ebp edi esi edx + ret +read: + push edx esi edi ebp + mov ebp,ecx + mov edi,edx + .loop: + mov ecx,1000h + sub ebp,1000h + jnc .read + add ebp,1000h + mov ecx,ebp + xor ebp,ebp + .read: + push ecx + mov ah,3Fh + xor dx,dx + call dos_int_with_buffer + cmp ax,cx + jne .eof + mov esi,[buffer_address] + mov ecx,[esp] + shr ecx,2 + rep movsd + pop ecx + and ecx,11b + rep movsb + or ebp,ebp + jnz .loop + .exit: + pop ebp edi esi edx + ret + .eof: + pop ecx + stc + jmp .exit +close: + mov ah,3Eh + int 21h + ret +lseek: + mov ah,42h + mov ecx,edx + shr ecx,16 + int 21h + pushf + shl edx,16 + popf + mov dx,ax + mov eax,edx + ret + +display_string: + lods byte [esi] + or al,al + jz string_end + mov dl,al + mov ah,2 + int 21h + jmp display_string + string_end: + ret +display_number: + push ebx + mov ecx,1000000000 + xor edx,edx + xor bl,bl + display_loop: + div ecx + push edx + cmp ecx,1 + je display_digit + or bl,bl + jnz display_digit + or al,al + jz digit_ok + not bl + display_digit: + mov dl,al + add dl,30h + mov ah,2 + int 21h + digit_ok: + mov eax,ecx + xor edx,edx + mov ecx,10 + div ecx + mov ecx,eax + pop eax + or ecx,ecx + jnz display_loop + pop ebx + ret + +display_user_messages: + mov [displayed_count],0 + call show_display_buffer + cmp [displayed_count],1 + jb line_break_ok + je make_line_break + mov ax,word [last_displayed] + cmp ax,0A0Dh + je line_break_ok + cmp ax,0D0Ah + je line_break_ok + make_line_break: + mov ah,2 + mov dl,0Dh + int 21h + mov dl,0Ah + int 21h + line_break_ok: + ret +display_block: + add [displayed_count],ecx + cmp ecx,1 + ja take_last_two_characters + jb display_character + mov al,[last_displayed+1] + mov ah,[esi] + mov word [last_displayed],ax + jmp display_character + take_last_two_characters: + mov ax,[esi+ecx-2] + mov word [last_displayed],ax + display_character: + lods byte [esi] + mov dl,al + mov ah,2 + int 21h + loopd display_character + ret + +fatal_error: + mov esi,error_prefix + call display_string + pop esi + call display_string + mov esi,error_suffix + call display_string + mov al,0FFh + jmp exit_program +assembler_error: + call display_user_messages + mov ebx,[current_line] + test ebx,ebx + jz display_error_message + pushd 0 + get_error_lines: + mov eax,[ebx] + cmp byte [eax],0 + je get_next_error_line + push ebx + test byte [ebx+7],80h + jz display_error_line + mov edx,ebx + find_definition_origin: + mov edx,[edx+12] + test byte [edx+7],80h + jnz find_definition_origin + push edx + get_next_error_line: + mov ebx,[ebx+8] + jmp get_error_lines + display_error_line: + mov esi,[ebx] + call display_string + mov esi,line_number_start + call display_string + mov eax,[ebx+4] + and eax,7FFFFFFFh + call display_number + mov dl,']' + mov ah,2 + int 21h + pop esi + cmp ebx,esi + je line_number_ok + mov dl,20h + mov ah,2 + int 21h + push esi + mov esi,[esi] + movzx ecx,byte [esi] + inc esi + call display_block + mov esi,line_number_start + call display_string + pop esi + mov eax,[esi+4] + and eax,7FFFFFFFh + call display_number + mov dl,']' + mov ah,2 + int 21h + line_number_ok: + mov esi,line_data_start + call display_string + mov esi,ebx + mov edx,[esi] + call open + mov al,2 + xor edx,edx + call lseek + mov edx,[esi+8] + sub eax,edx + jz line_data_displayed + mov [counter],eax + xor al,al + call lseek + mov esi,[additional_memory] + read_line_data: + mov ecx,100h + cmp ecx,[counter] + jbe bytes_count_ok + mov ecx,[counter] + bytes_count_ok: + sub [counter],ecx + lea eax,[esi+ecx] + cmp eax,[additional_memory_end] + ja out_of_memory + push ecx + mov edx,esi + call read + pop ecx + get_line_data: + mov al,[esi] + cmp al,0Ah + je display_line_data + cmp al,0Dh + je display_line_data + cmp al,1Ah + je display_line_data + or al,al + jz display_line_data + inc esi + loop get_line_data + cmp [counter],0 + ja read_line_data + display_line_data: + call close + mov ecx,esi + mov esi,[additional_memory] + sub ecx,esi + call display_block + line_data_displayed: + mov esi,cr_lf + call display_string + pop ebx + or ebx,ebx + jnz display_error_line + cmp [preprocessing_done],0 + je display_error_message + mov esi,preprocessed_instruction_prefix + call display_string + mov esi,[current_line] + add esi,16 + mov edi,[additional_memory] + xor dl,dl + convert_instruction: + lodsb + cmp al,1Ah + je copy_symbol + cmp al,22h + je copy_symbol + cmp al,3Bh + je instruction_converted + stosb + or al,al + jz instruction_converted + xor dl,dl + jmp convert_instruction + copy_symbol: + or dl,dl + jz space_ok + mov byte [edi],20h + inc edi + space_ok: + cmp al,22h + je quoted + lodsb + movzx ecx,al + rep movsb + or dl,-1 + jmp convert_instruction + quoted: + mov al,27h + stosb + lodsd + mov ecx,eax + jecxz quoted_copied + copy_quoted: + lodsb + stosb + cmp al,27h + jne quote_ok + stosb + quote_ok: + loop copy_quoted + quoted_copied: + mov al,27h + stosb + or dl,-1 + jmp convert_instruction + instruction_converted: + xor al,al + stosb + mov esi,[additional_memory] + call display_string + mov esi,cr_lf + call display_string + display_error_message: + mov esi,error_prefix + call display_string + pop esi + call display_string + mov esi,error_suffix + call display_string + mov al,2 + jmp exit_program + +make_timestamp: + mov ah,2Ah + int 21h + push dx cx + movzx ecx,cx + mov eax,ecx + sub eax,1970 + mov ebx,365 + mul ebx + mov ebp,eax + mov eax,ecx + sub eax,1969 + shr eax,2 + add ebp,eax + mov eax,ecx + sub eax,1901 + mov ebx,100 + div ebx + sub ebp,eax + mov eax,ecx + xor edx,edx + sub eax,1601 + mov ebx,400 + div ebx + add ebp,eax + movzx ecx,byte [esp+3] + mov eax,ecx + dec eax + mov ebx,30 + mul ebx + add ebp,eax + cmp ecx,8 + jbe months_correction + mov eax,ecx + sub eax,7 + shr eax,1 + add ebp,eax + mov ecx,8 + months_correction: + mov eax,ecx + shr eax,1 + add ebp,eax + cmp ecx,2 + pop cx + jbe day_correction_ok + sub ebp,2 + test ecx,11b + jnz day_correction_ok + xor edx,edx + mov eax,ecx + mov ebx,100 + div ebx + or edx,edx + jnz day_correction + mov eax,ecx + mov ebx,400 + div ebx + or edx,edx + jnz day_correction_ok + day_correction: + inc ebp + day_correction_ok: + pop dx + movzx eax,dl + dec eax + add eax,ebp + mov ebx,24 + mul ebx + push eax + mov ah,2Ch + int 21h + pop eax + push dx + movzx ebx,ch + add eax,ebx + mov ebx,60 + mul ebx + movzx ebx,cl + add eax,ebx + mov ebx,60 + mul ebx + pop bx + movzx ebx,bh + add eax,ebx + adc edx,0 + ret diff --git a/toolchain/fasmw17332/SOURCE/ERRORS.INC b/toolchain/fasmw17332/SOURCE/ERRORS.INC new file mode 100644 index 0000000..48719fa --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/ERRORS.INC @@ -0,0 +1,191 @@ + +; flat assembler core +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +out_of_memory: + push _out_of_memory + jmp fatal_error +stack_overflow: + push _stack_overflow + jmp fatal_error +main_file_not_found: + push _main_file_not_found + jmp fatal_error +write_failed: + push _write_failed + jmp fatal_error + +code_cannot_be_generated: + push _code_cannot_be_generated + jmp general_error +format_limitations_exceeded: + push _format_limitations_exceeded + jmp general_error +invalid_definition: + push _invalid_definition + general_error: + cmp [symbols_file],0 + je fatal_error + call dump_preprocessed_source + jmp fatal_error + +file_not_found: + push _file_not_found + jmp error_with_source +error_reading_file: + push _error_reading_file + jmp error_with_source +invalid_file_format: + push _invalid_file_format + jmp error_with_source +invalid_macro_arguments: + push _invalid_macro_arguments + jmp error_with_source +incomplete_macro: + push _incomplete_macro + jmp error_with_source +unexpected_characters: + push _unexpected_characters + jmp error_with_source +invalid_argument: + push _invalid_argument + jmp error_with_source +illegal_instruction: + push _illegal_instruction + jmp error_with_source +invalid_operand: + push _invalid_operand + jmp error_with_source +invalid_operand_size: + push _invalid_operand_size + jmp error_with_source +operand_size_not_specified: + push _operand_size_not_specified + jmp error_with_source +operand_sizes_do_not_match: + push _operand_sizes_do_not_match + jmp error_with_source +invalid_address_size: + push _invalid_address_size + jmp error_with_source +address_sizes_do_not_agree: + push _address_sizes_do_not_agree + jmp error_with_source +disallowed_combination_of_registers: + push _disallowed_combination_of_registers + jmp error_with_source +long_immediate_not_encodable: + push _long_immediate_not_encodable + jmp error_with_source +relative_jump_out_of_range: + push _relative_jump_out_of_range + jmp error_with_source +invalid_expression: + push _invalid_expression + jmp error_with_source +invalid_address: + push _invalid_address + jmp error_with_source +invalid_value: + push _invalid_value + jmp error_with_source +value_out_of_range: + push _value_out_of_range + jmp error_with_source +undefined_symbol: + mov edi,message + mov esi,_undefined_symbol + call copy_asciiz + push message + cmp [error_info],0 + je error_with_source + mov esi,[error_info] + mov esi,[esi+24] + or esi,esi + jz error_with_source + mov byte [edi-1],20h + call write_quoted_symbol_name + jmp error_with_source + copy_asciiz: + lods byte [esi] + stos byte [edi] + test al,al + jnz copy_asciiz + ret + write_quoted_symbol_name: + mov al,27h + stosb + movzx ecx,byte [esi-1] + rep movs byte [edi],[esi] + mov ax,27h + stosw + ret +symbol_out_of_scope: + mov edi,message + mov esi,_symbol_out_of_scope_1 + call copy_asciiz + cmp [error_info],0 + je finish_symbol_out_of_scope_message + mov esi,[error_info] + mov esi,[esi+24] + or esi,esi + jz finish_symbol_out_of_scope_message + mov byte [edi-1],20h + call write_quoted_symbol_name + finish_symbol_out_of_scope_message: + mov byte [edi-1],20h + mov esi,_symbol_out_of_scope_2 + call copy_asciiz + push message + jmp error_with_source +invalid_use_of_symbol: + push _invalid_use_of_symbol + jmp error_with_source +name_too_long: + push _name_too_long + jmp error_with_source +invalid_name: + push _invalid_name + jmp error_with_source +reserved_word_used_as_symbol: + push _reserved_word_used_as_symbol + jmp error_with_source +symbol_already_defined: + push _symbol_already_defined + jmp error_with_source +missing_end_quote: + push _missing_end_quote + jmp error_with_source +missing_end_directive: + push _missing_end_directive + jmp error_with_source +unexpected_instruction: + push _unexpected_instruction + jmp error_with_source +extra_characters_on_line: + push _extra_characters_on_line + jmp error_with_source +section_not_aligned_enough: + push _section_not_aligned_enough + jmp error_with_source +setting_already_specified: + push _setting_already_specified + jmp error_with_source +data_already_defined: + push _data_already_defined + jmp error_with_source +too_many_repeats: + push _too_many_repeats + jmp error_with_source +assertion_failed: + push _assertion_failed + jmp error_with_source +invoked_error: + push _invoked_error + error_with_source: + cmp [symbols_file],0 + je assembler_error + call dump_preprocessed_source + call restore_preprocessed_source + jmp assembler_error diff --git a/toolchain/fasmw17332/SOURCE/EXPRCALC.INC b/toolchain/fasmw17332/SOURCE/EXPRCALC.INC new file mode 100644 index 0000000..2bb5b82 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/EXPRCALC.INC @@ -0,0 +1,2272 @@ + +; flat assembler core +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +calculate_expression: + mov [current_offset],edi + mov [value_undefined],0 + cmp byte [esi],0 + je get_string_value + cmp byte [esi],'.' + je convert_fp + calculation_loop: + mov eax,[tagged_blocks] + sub eax,0Ch + cmp eax,edi + jbe out_of_memory + lods byte [esi] + cmp al,1 + je get_byte_number + cmp al,2 + je get_word_number + cmp al,4 + je get_dword_number + cmp al,8 + je get_qword_number + cmp al,0Fh + je value_out_of_range + cmp al,10h + je get_register + cmp al,11h + je get_label + cmp al,')' + je expression_calculated + cmp al,']' + je expression_calculated + cmp al,'!' + je invalid_expression + sub edi,14h + mov ebx,edi + sub ebx,14h + cmp al,0F0h + je calculate_rva + cmp al,0F1h + je calculate_plt + cmp al,0D0h + je calculate_not + cmp al,0E0h + je calculate_bsf + cmp al,0E1h + je calculate_bsr + cmp al,083h + je calculate_neg + mov dx,[ebx+8] + or dx,[edi+8] + cmp al,80h + je calculate_add + cmp al,81h + je calculate_sub + mov ah,[ebx+12] + or ah,[edi+12] + jz absolute_values_calculation + call recoverable_misuse + absolute_values_calculation: + cmp al,90h + je calculate_mul + cmp al,91h + je calculate_div + or dx,dx + jnz invalid_expression + cmp al,0A0h + je calculate_mod + cmp al,0B0h + je calculate_and + cmp al,0B1h + je calculate_or + cmp al,0B2h + je calculate_xor + cmp al,0C0h + je calculate_shl + cmp al,0C1h + je calculate_shr + jmp invalid_expression + expression_calculated: + sub edi,14h + cmp [value_undefined],0 + je expression_value_ok + xor eax,eax + mov [edi],eax + mov [edi+4],eax + mov [edi+12],eax + expression_value_ok: + ret + get_byte_number: + xor eax,eax + lods byte [esi] + stos dword [edi] + xor al,al + stos dword [edi] + got_number: + and word [edi-8+8],0 + and word [edi-8+12],0 + and dword [edi-8+16],0 + add edi,0Ch + jmp calculation_loop + get_word_number: + xor eax,eax + lods word [esi] + stos dword [edi] + xor ax,ax + stos dword [edi] + jmp got_number + get_dword_number: + movs dword [edi],[esi] + xor eax,eax + stos dword [edi] + jmp got_number + get_qword_number: + movs dword [edi],[esi] + movs dword [edi],[esi] + jmp got_number + get_register: + mov byte [edi+9],0 + and word [edi+12],0 + lods byte [esi] + mov [edi+8],al + mov byte [edi+10],1 + xor eax,eax + mov [edi+16],eax + stos dword [edi] + stos dword [edi] + add edi,0Ch + jmp calculation_loop + get_label: + xor eax,eax + mov [edi+8],eax + mov [edi+12],eax + mov [edi+20],eax + lods dword [esi] + cmp eax,0Fh + jb predefined_label + je reserved_word_used_as_symbol + mov ebx,eax + mov ax,[current_pass] + mov [ebx+18],ax + mov cl,[ebx+9] + shr cl,1 + and cl,1 + neg cl + or byte [ebx+8],8 + test byte [ebx+8],1 + jz label_undefined + cmp ax,[ebx+16] + je unadjusted_label + test byte [ebx+8],4 + jnz label_out_of_scope + test byte [ebx+9],1 + jz unadjusted_label + mov eax,[ebx] + sub eax,dword [adjustment] + stos dword [edi] + mov eax,[ebx+4] + sbb eax,dword [adjustment+4] + stos dword [edi] + sbb cl,[adjustment_sign] + mov [edi-8+13],cl + mov eax,dword [adjustment] + or al,[adjustment_sign] + or eax,dword [adjustment+4] + jz got_label + or [next_pass_needed],-1 + jmp got_label + unadjusted_label: + mov eax,[ebx] + stos dword [edi] + mov eax,[ebx+4] + stos dword [edi] + mov [edi-8+13],cl + got_label: + test byte [ebx+9],4 + jnz invalid_use_of_symbol + call store_label_reference + mov al,[ebx+11] + mov [edi-8+12],al + mov eax,[ebx+12] + mov [edi-8+8],eax + cmp al,ah + jne labeled_registers_ok + shr eax,16 + add al,ah + jo labeled_registers_ok + xor ah,ah + mov [edi-8+10],ax + mov [edi-8+9],ah + labeled_registers_ok: + mov eax,[ebx+20] + mov [edi-8+16],eax + add edi,0Ch + mov al,[ebx+10] + or al,al + jz calculation_loop + test [operand_flags],1 + jnz calculation_loop + check_size: + xchg [operand_size],al + or al,al + jz calculation_loop + cmp al,[operand_size] + jne operand_sizes_do_not_match + jmp calculation_loop + actual_file_offset_label: + mov eax,[undefined_data_end] + mov ebp,[addressing_space] + test byte [ds:ebp+0Ah],1 + jnz use_undefined_data_offset + cmp eax,[current_offset] + jne use_current_offset + use_undefined_data_offset: + mov eax,[undefined_data_start] + jmp make_file_offset_label + current_file_offset_label: + mov ebp,[addressing_space] + test byte [ds:ebp+0Ah],1 + jz use_current_offset + mov eax,[undefined_data_end] + jmp make_file_offset_label + use_current_offset: + mov eax,[current_offset] + make_file_offset_label: + cmp [output_format],2 + jae invalid_use_of_symbol + sub eax,[code_start] + jmp make_dword_label_value + current_offset_label: + mov eax,[current_offset] + make_current_offset_label: + xor edx,edx + xor ch,ch + mov ebp,[addressing_space] + sub eax,[ds:ebp] + sbb edx,[ds:ebp+4] + sbb ch,[ds:ebp+8] + jp current_offset_label_ok + call recoverable_overflow + current_offset_label_ok: + stos dword [edi] + mov eax,edx + stos dword [edi] + mov eax,[ds:ebp+10h] + stos dword [edi] + mov cl,[ds:ebp+9] + mov [edi-12+12],cx + mov eax,[ds:ebp+14h] + mov [edi-12+16],eax + add edi,8 + jmp calculation_loop + org_origin_label: + mov eax,[addressing_space] + mov eax,[eax+18h] + jmp make_current_offset_label + counter_label: + mov eax,[counter] + make_dword_label_value: + stos dword [edi] + xor eax,eax + stos dword [edi] + add edi,0Ch + jmp calculation_loop + timestamp_label: + call make_timestamp + make_qword_label_value: + stos dword [edi] + mov eax,edx + stos dword [edi] + add edi,0Ch + jmp calculation_loop + predefined_label: + or eax,eax + jz current_offset_label + cmp eax,1 + je counter_label + cmp eax,2 + je timestamp_label + cmp eax,3 + je org_origin_label + cmp eax,4 + je current_file_offset_label + cmp eax,5 + je actual_file_offset_label + mov edx,invalid_value + jmp error_undefined + label_out_of_scope: + mov edx,symbol_out_of_scope + jmp error_undefined + label_undefined: + mov edx,undefined_symbol + error_undefined: + cmp [current_pass],1 + ja undefined_value + force_next_pass: + or [next_pass_needed],-1 + undefined_value: + or [value_undefined],-1 + and word [edi+12],0 + xor eax,eax + stos dword [edi] + stos dword [edi] + add edi,0Ch + cmp [error_line],0 + jne calculation_loop + mov eax,[current_line] + mov [error_line],eax + mov [error],edx + mov [error_info],ebx + jmp calculation_loop + calculate_add: + xor ah,ah + mov ah,[ebx+12] + mov al,[edi+12] + or al,al + jz add_values + or ah,ah + jz add_relocatable + add ah,al + jnz invalid_add + mov ecx,[edi+16] + cmp ecx,[ebx+16] + je add_values + invalid_add: + call recoverable_misuse + jmp add_values + add_relocatable: + mov ah,al + mov ecx,[edi+16] + mov [ebx+16],ecx + add_values: + mov [ebx+12],ah + mov eax,[edi] + add [ebx],eax + mov eax,[edi+4] + adc [ebx+4],eax + mov al,[edi+13] + adc [ebx+13],al + jp add_sign_ok + call recoverable_overflow + add_sign_ok: + or dx,dx + jz calculation_loop + push esi + mov esi,ebx + mov cl,[edi+10] + mov al,[edi+8] + call add_register + mov cl,[edi+11] + mov al,[edi+9] + call add_register + pop esi + jmp calculation_loop + add_register: + or al,al + jz add_register_done + add_register_start: + cmp [esi+8],al + jne add_in_second_slot + add [esi+10],cl + jo value_out_of_range + jnz add_register_done + mov byte [esi+8],0 + ret + add_in_second_slot: + cmp [esi+9],al + jne create_in_first_slot + add [esi+11],cl + jo value_out_of_range + jnz add_register_done + mov byte [esi+9],0 + ret + create_in_first_slot: + cmp byte [esi+8],0 + jne create_in_second_slot + mov [esi+8],al + mov [esi+10],cl + ret + create_in_second_slot: + cmp byte [esi+9],0 + jne invalid_expression + mov [esi+9],al + mov [esi+11],cl + add_register_done: + ret + out_of_range: + jmp calculation_loop + calculate_sub: + xor ah,ah + mov ah,[ebx+12] + mov al,[edi+12] + or al,al + jz sub_values + or ah,ah + jz negate_relocatable + cmp al,ah + jne invalid_sub + xor ah,ah + mov ecx,[edi+16] + cmp ecx,[ebx+16] + je sub_values + invalid_sub: + call recoverable_misuse + jmp sub_values + negate_relocatable: + neg al + mov ah,al + mov ecx,[edi+16] + mov [ebx+16],ecx + sub_values: + mov [ebx+12],ah + mov eax,[edi] + sub [ebx],eax + mov eax,[edi+4] + sbb [ebx+4],eax + mov al,[edi+13] + sbb [ebx+13],al + jp sub_sign_ok + cmp [error_line],0 + jne sub_sign_ok + call recoverable_overflow + sub_sign_ok: + or dx,dx + jz calculation_loop + push esi + mov esi,ebx + mov cl,[edi+10] + mov al,[edi+8] + call sub_register + mov cl,[edi+11] + mov al,[edi+9] + call sub_register + pop esi + jmp calculation_loop + sub_register: + or al,al + jz add_register_done + neg cl + jo value_out_of_range + jmp add_register_start + calculate_mul: + or dx,dx + jz mul_start + cmp word [ebx+8],0 + jne mul_start + xor ecx,ecx + swap_values: + mov eax,[ebx+ecx] + xchg eax,[edi+ecx] + mov [ebx+ecx],eax + add ecx,4 + cmp ecx,16 + jb swap_values + mul_start: + push esi edx + mov esi,ebx + xor bl,bl + cmp byte [esi+13],0 + je mul_first_sign_ok + xor bl,-1 + mov eax,[esi] + mov edx,[esi+4] + not eax + not edx + add eax,1 + adc edx,0 + mov [esi],eax + mov [esi+4],edx + or eax,edx + jz mul_overflow + mul_first_sign_ok: + cmp byte [edi+13],0 + je mul_second_sign_ok + xor bl,-1 + cmp byte [esi+8],0 + je mul_first_register_sign_ok + neg byte [esi+10] + jo invalid_expression + mul_first_register_sign_ok: + cmp byte [esi+9],0 + je mul_second_register_sign_ok + neg byte [esi+11] + jo invalid_expression + mul_second_register_sign_ok: + mov eax,[edi] + mov edx,[edi+4] + not eax + not edx + add eax,1 + adc edx,0 + mov [edi],eax + mov [edi+4],edx + or eax,edx + jz mul_overflow + mul_second_sign_ok: + cmp dword [esi+4],0 + jz mul_numbers + cmp dword [edi+4],0 + jz mul_numbers + jnz mul_overflow + mul_numbers: + mov eax,[esi+4] + mul dword [edi] + or edx,edx + jnz mul_overflow + mov ecx,eax + mov eax,[esi] + mul dword [edi+4] + or edx,edx + jnz mul_overflow + add ecx,eax + jc mul_overflow + mov eax,[esi] + mul dword [edi] + add edx,ecx + jc mul_overflow + mov [esi],eax + mov [esi+4],edx + or bl,bl + jz mul_ok + not eax + not edx + add eax,1 + adc edx,0 + mov [esi],eax + mov [esi+4],edx + or eax,edx + jnz mul_ok + not bl + mul_ok: + mov [esi+13],bl + pop edx + or dx,dx + jz mul_calculated + cmp word [edi+8],0 + jne invalid_value + cmp byte [esi+8],0 + je mul_first_register_ok + call get_byte_scale + imul byte [esi+10] + mov dl,ah + cbw + cmp ah,dl + jne value_out_of_range + mov [esi+10],al + or al,al + jnz mul_first_register_ok + mov [esi+8],al + mul_first_register_ok: + cmp byte [esi+9],0 + je mul_calculated + call get_byte_scale + imul byte [esi+11] + mov dl,ah + cbw + cmp ah,dl + jne value_out_of_range + mov [esi+11],al + or al,al + jnz mul_calculated + mov [esi+9],al + mul_calculated: + pop esi + jmp calculation_loop + mul_overflow: + pop edx esi + call recoverable_overflow + jmp calculation_loop + get_byte_scale: + mov al,[edi] + cbw + cwde + cdq + cmp edx,[edi+4] + jne value_out_of_range + cmp eax,[edi] + jne value_out_of_range + ret + calculate_div: + push esi edx + mov esi,ebx + call div_64 + pop edx + or dx,dx + jz div_calculated + cmp byte [esi+8],0 + je div_first_register_ok + call get_byte_scale + or al,al + jz value_out_of_range + mov al,[esi+10] + cbw + idiv byte [edi] + or ah,ah + jnz invalid_use_of_symbol + mov [esi+10],al + div_first_register_ok: + cmp byte [esi+9],0 + je div_calculated + call get_byte_scale + or al,al + jz value_out_of_range + mov al,[esi+11] + cbw + idiv byte [edi] + or ah,ah + jnz invalid_use_of_symbol + mov [esi+11],al + div_calculated: + pop esi + jmp calculation_loop + calculate_mod: + push esi + mov esi,ebx + call div_64 + mov [esi],eax + mov [esi+4],edx + mov [esi+13],bh + pop esi + jmp calculation_loop + calculate_and: + mov eax,[edi] + mov edx,[edi+4] + mov cl,[edi+13] + and [ebx],eax + and [ebx+4],edx + and [ebx+13],cl + jmp calculation_loop + calculate_or: + mov eax,[edi] + mov edx,[edi+4] + mov cl,[edi+13] + or [ebx],eax + or [ebx+4],edx + or [ebx+13],cl + jmp calculation_loop + calculate_xor: + mov eax,[edi] + mov edx,[edi+4] + mov cl,[edi+13] + xor [ebx],eax + xor [ebx+4],edx + xor [ebx+13],cl + jmp calculation_loop + shr_negative: + mov byte [edi+13],0 + not dword [edi] + not dword [edi+4] + add dword [edi],1 + adc dword [edi+4],0 + jc shl_over + calculate_shl: + cmp byte [edi+13],0 + jne shl_negative + mov edx,[ebx+4] + mov eax,[ebx] + cmp dword [edi+4],0 + jne shl_over + movsx ecx,byte [ebx+13] + xchg ecx,[edi] + cmp ecx,64 + je shl_max + ja shl_over + cmp ecx,32 + jae shl_high + shld [edi],edx,cl + shld edx,eax,cl + shl eax,cl + mov [ebx],eax + mov [ebx+4],edx + jmp shl_done + shl_over: + cmp byte [ebx+13],0 + jne shl_overflow + shl_max: + movsx ecx,byte [ebx+13] + cmp eax,ecx + jne shl_overflow + cmp edx,ecx + jne shl_overflow + xor eax,eax + mov [ebx],eax + mov [ebx+4],eax + jmp calculation_loop + shl_high: + sub cl,32 + shld [edi],edx,cl + shld edx,eax,cl + shl eax,cl + mov [ebx+4],eax + and dword [ebx],0 + cmp edx,[edi] + jne shl_overflow + shl_done: + movsx eax,byte [ebx+13] + cmp eax,[edi] + je calculation_loop + shl_overflow: + call recoverable_overflow + jmp calculation_loop + shl_negative: + mov byte [edi+13],0 + not dword [edi] + not dword [edi+4] + add dword [edi],1 + adc dword [edi+4],0 + jnc calculate_shr + dec dword [edi+4] + calculate_shr: + cmp byte [edi+13],0 + jne shr_negative + mov edx,[ebx+4] + mov eax,[ebx] + cmp dword [edi+4],0 + jne shr_over + mov ecx,[edi] + cmp ecx,64 + jae shr_over + push esi + movsx esi,byte [ebx+13] + cmp ecx,32 + jae shr_high + shrd eax,edx,cl + shrd edx,esi,cl + mov [ebx],eax + mov [ebx+4],edx + pop esi + jmp calculation_loop + shr_high: + sub cl,32 + shrd edx,esi,cl + mov [ebx],edx + mov [ebx+4],esi + pop esi + jmp calculation_loop + shr_over: + movsx eax,byte [ebx+13] + mov dword [ebx],eax + mov dword [ebx+4],eax + jmp calculation_loop + calculate_not: + cmp word [edi+8],0 + jne invalid_expression + cmp byte [edi+12],0 + je not_ok + call recoverable_misuse + not_ok: + not dword [edi] + not dword [edi+4] + not byte [edi+13] + add edi,14h + jmp calculation_loop + calculate_bsf: + cmp word [edi+8],0 + jne invalid_expression + cmp byte [edi+12],0 + je bsf_ok + call recoverable_misuse + bsf_ok: + xor ecx,ecx + bsf eax,[edi] + jnz finish_bs + mov ecx,32 + bsf eax,[edi+4] + jnz finish_bs + cmp byte [edi+13],0 + jne finish_bs + bs_overflow: + call recoverable_overflow + add edi,14h + jmp calculation_loop + calculate_bsr: + cmp word [edi+8],0 + jne invalid_expression + cmp byte [edi+12],0 + je bsr_ok + call recoverable_misuse + bsr_ok: + cmp byte [edi+13],0 + jne bs_overflow + mov ecx,32 + bsr eax,[edi+4] + jnz finish_bs + xor ecx,ecx + bsr eax,[edi] + jz bs_overflow + finish_bs: + add eax,ecx + xor edx,edx + mov [edi],eax + mov [edi+4],edx + mov [edi+13],dl + add edi,14h + jmp calculation_loop + calculate_neg: + cmp byte [edi+8],0 + je neg_first_register_ok + neg byte [edi+10] + jo invalid_expression + neg_first_register_ok: + cmp byte [edi+9],0 + je neg_second_register_ok + neg byte [edi+11] + jo invalid_expression + neg_second_register_ok: + neg byte [edi+12] + xor eax,eax + xor edx,edx + xor cl,cl + xchg eax,[edi] + xchg edx,[edi+4] + xchg cl,[edi+13] + sub [edi],eax + sbb [edi+4],edx + sbb [edi+13],cl + jp neg_sign_ok + call recoverable_overflow + neg_sign_ok: + add edi,14h + jmp calculation_loop + calculate_rva: + cmp word [edi+8],0 + jne invalid_expression + mov al,[output_format] + cmp al,5 + je calculate_gotoff + cmp al,4 + je calculate_coff_rva + cmp al,3 + jne invalid_expression + test [format_flags],8 + jnz pe64_rva + mov al,2 + bt [resolver_flags],0 + jc rva_type_ok + xor al,al + rva_type_ok: + cmp byte [edi+12],al + je rva_ok + call recoverable_misuse + rva_ok: + mov byte [edi+12],0 + mov eax,[code_start] + mov eax,[eax+34h] + xor edx,edx + finish_rva: + sub [edi],eax + sbb [edi+4],edx + sbb byte [edi+13],0 + jp rva_finished + call recoverable_overflow + rva_finished: + add edi,14h + jmp calculation_loop + pe64_rva: + mov al,4 + bt [resolver_flags],0 + jc pe64_rva_type_ok + xor al,al + pe64_rva_type_ok: + cmp byte [edi+12],al + je pe64_rva_ok + call recoverable_misuse + pe64_rva_ok: + mov byte [edi+12],0 + mov eax,[code_start] + mov edx,[eax+34h] + mov eax,[eax+30h] + jmp finish_rva + calculate_gotoff: + test [format_flags],1 + jnz calculate_elf_dyn_rva + test [format_flags],8 + jnz invalid_expression + calculate_coff_rva: + mov dl,5 + cmp byte [edi+12],2 + je change_value_type + incorrect_change_of_value_type: + call recoverable_misuse + change_value_type: + mov byte [edi+12],dl + add edi,14h + jmp calculation_loop + calculate_elf_dyn_rva: + xor dl,dl + test byte [edi+12],1 + jnz incorrect_change_of_value_type + jmp change_value_type + calculate_plt: + cmp word [edi+8],0 + jne invalid_expression + cmp [output_format],5 + jne invalid_expression + test [format_flags],1 + jnz invalid_expression + mov dl,6 + mov dh,2 + test [format_flags],8 + jz check_value_for_plt + mov dh,4 + check_value_for_plt: + mov eax,[edi] + or eax,[edi+4] + jnz incorrect_change_of_value_type + cmp byte [edi+12],dh + jne incorrect_change_of_value_type + mov eax,[edi+16] + cmp byte [eax],80h + jne incorrect_change_of_value_type + jmp change_value_type + div_64: + xor ebx,ebx + cmp dword [edi],0 + jne divider_ok + cmp dword [edi+4],0 + jne divider_ok + cmp [next_pass_needed],0 + je value_out_of_range + jmp div_done + divider_ok: + cmp byte [esi+13],0 + je div_first_sign_ok + mov eax,[esi] + mov edx,[esi+4] + not eax + not edx + add eax,1 + adc edx,0 + mov [esi],eax + mov [esi+4],edx + or eax,edx + jz value_out_of_range + xor bx,-1 + div_first_sign_ok: + cmp byte [edi+13],0 + je div_second_sign_ok + mov eax,[edi] + mov edx,[edi+4] + not eax + not edx + add eax,1 + adc edx,0 + mov [edi],eax + mov [edi+4],edx + or eax,edx + jz value_out_of_range + xor bl,-1 + div_second_sign_ok: + cmp dword [edi+4],0 + jne div_high + mov ecx,[edi] + mov eax,[esi+4] + xor edx,edx + div ecx + mov [esi+4],eax + mov eax,[esi] + div ecx + mov [esi],eax + mov eax,edx + xor edx,edx + jmp div_done + div_high: + push ebx + mov eax,[esi+4] + xor edx,edx + div dword [edi+4] + mov ebx,[esi] + mov [esi],eax + and dword [esi+4],0 + mov ecx,edx + mul dword [edi] + div_high_loop: + cmp ecx,edx + ja div_high_done + jb div_high_large_correction + cmp ebx,eax + jae div_high_done + div_high_correction: + dec dword [esi] + sub eax,[edi] + sbb edx,[edi+4] + jnc div_high_loop + div_high_done: + sub ebx,eax + sbb ecx,edx + mov edx,ecx + mov eax,ebx + pop ebx + jmp div_done + div_high_large_correction: + push eax edx + mov eax,edx + sub eax,ecx + xor edx,edx + div dword [edi+4] + shr eax,1 + jz div_high_small_correction + sub [esi],eax + push eax + mul dword [edi+4] + sub dword [esp+4],eax + pop eax + mul dword [edi] + sub dword [esp+4],eax + sbb dword [esp],edx + pop edx eax + jmp div_high_loop + div_high_small_correction: + pop edx eax + jmp div_high_correction + div_done: + or bh,bh + jz remainder_ok + not eax + not edx + add eax,1 + adc edx,0 + mov ecx,eax + or ecx,edx + jnz remainder_ok + not bh + remainder_ok: + or bl,bl + jz div_ok + not dword [esi] + not dword [esi+4] + add dword [esi],1 + adc dword [esi+4],0 + mov ecx,[esi] + or ecx,[esi+4] + jnz div_ok + not bl + div_ok: + mov [esi+13],bl + ret + store_label_reference: + cmp [symbols_file],0 + je label_reference_ok + cmp [next_pass_needed],0 + jne label_reference_ok + mov eax,[tagged_blocks] + mov dword [eax-4],2 + mov dword [eax-8],4 + sub eax,8+4 + cmp eax,edi + jbe out_of_memory + mov [tagged_blocks],eax + mov [eax],ebx + label_reference_ok: + ret + convert_fp: + inc esi + and word [edi+8],0 + and word [edi+12],0 + mov al,[value_size] + cmp al,2 + je convert_fp_word + cmp al,4 + je convert_fp_dword + test al,not 8 + jz convert_fp_qword + call recoverable_misuse + convert_fp_qword: + xor eax,eax + xor edx,edx + cmp word [esi+8],8000h + je fp_qword_store + mov bx,[esi+8] + mov eax,[esi] + mov edx,[esi+4] + add eax,eax + adc edx,edx + mov ecx,edx + shr edx,12 + shrd eax,ecx,12 + jnc fp_qword_ok + add eax,1 + adc edx,0 + bt edx,20 + jnc fp_qword_ok + and edx,1 shl 20 - 1 + inc bx + shr edx,1 + rcr eax,1 + fp_qword_ok: + add bx,3FFh + cmp bx,7FFh + jge value_out_of_range + cmp bx,0 + jg fp_qword_exp_ok + or edx,1 shl 20 + mov cx,bx + neg cx + inc cx + cmp cx,52+1 + ja value_out_of_range + cmp cx,32 + jb fp_qword_small_shift + sub cx,32 + mov eax,edx + xor edx,edx + shr eax,cl + jmp fp_qword_shift_done + fp_qword_small_shift: + mov ebx,edx + shr edx,cl + shrd eax,ebx,cl + fp_qword_shift_done: + mov bx,0 + jnc fp_qword_exp_ok + add eax,1 + adc edx,0 + test edx,1 shl 20 + jz fp_qword_exp_ok + and edx,1 shl 20 - 1 + inc bx + fp_qword_exp_ok: + shl ebx,20 + or edx,ebx + jnz fp_qword_store + or eax,eax + jz value_out_of_range + fp_qword_store: + mov bl,[esi+11] + shl ebx,31 + or edx,ebx + mov [edi],eax + mov [edi+4],edx + add esi,13 + ret + convert_fp_word: + xor eax,eax + cmp word [esi+8],8000h + je fp_word_store + mov bx,[esi+8] + mov ax,[esi+6] + shl ax,1 + shr ax,6 + jnc fp_word_ok + inc ax + bt ax,10 + jnc fp_word_ok + and ax,1 shl 10 - 1 + inc bx + shr ax,1 + fp_word_ok: + add bx,0Fh + cmp bx,01Fh + jge value_out_of_range + cmp bx,0 + jg fp_word_exp_ok + or ax,1 shl 10 + mov cx,bx + neg cx + inc cx + cmp cx,10+1 + ja value_out_of_range + xor bx,bx + shr ax,cl + jnc fp_word_exp_ok + inc ax + test ax,1 shl 10 + jz fp_word_exp_ok + and ax,1 shl 10 - 1 + inc bx + fp_word_exp_ok: + shl bx,10 + or ax,bx + jz value_out_of_range + fp_word_store: + mov bl,[esi+11] + shl bx,15 + or ax,bx + mov [edi],eax + xor eax,eax + mov [edi+4],eax + add esi,13 + ret + convert_fp_dword: + xor eax,eax + cmp word [esi+8],8000h + je fp_dword_store + mov bx,[esi+8] + mov eax,[esi+4] + shl eax,1 + shr eax,9 + jnc fp_dword_ok + inc eax + bt eax,23 + jnc fp_dword_ok + and eax,1 shl 23 - 1 + inc bx + shr eax,1 + fp_dword_ok: + add bx,7Fh + cmp bx,0FFh + jge value_out_of_range + cmp bx,0 + jg fp_dword_exp_ok + or eax,1 shl 23 + mov cx,bx + neg cx + inc cx + cmp cx,23+1 + ja value_out_of_range + xor bx,bx + shr eax,cl + jnc fp_dword_exp_ok + inc eax + test eax,1 shl 23 + jz fp_dword_exp_ok + and eax,1 shl 23 - 1 + inc bx + fp_dword_exp_ok: + shl ebx,23 + or eax,ebx + jz value_out_of_range + fp_dword_store: + mov bl,[esi+11] + shl ebx,31 + or eax,ebx + mov [edi],eax + xor eax,eax + mov [edi+4],eax + add esi,13 + ret + get_string_value: + inc esi + lods dword [esi] + mov ecx,eax + cmp ecx,8 + ja value_out_of_range + mov edx,edi + xor eax,eax + stos dword [edi] + stos dword [edi] + mov edi,edx + rep movs byte [edi],[esi] + mov edi,edx + inc esi + and word [edi+8],0 + and word [edi+12],0 + ret + +get_byte_value: + mov [value_size],1 + or [operand_flags],1 + call calculate_value + or al,al + jz check_byte_value + call recoverable_misuse + check_byte_value: + mov eax,[edi] + mov edx,[edi+4] + cmp byte [edi+13],0 + je byte_positive + cmp edx,-1 + jne range_exceeded + cmp eax,-100h + jb range_exceeded + ret + byte_positive: + test edx,edx + jnz range_exceeded + cmp eax,100h + jae range_exceeded + return_byte_value: + ret + range_exceeded: + xor eax,eax + xor edx,edx + recoverable_overflow: + cmp [error_line],0 + jne ignore_overflow + push [current_line] + pop [error_line] + mov [error],value_out_of_range + or [value_undefined],-1 + ignore_overflow: + ret + recoverable_misuse: + cmp [error_line],0 + jne ignore_misuse + push [current_line] + pop [error_line] + mov [error],invalid_use_of_symbol + ignore_misuse: + ret +get_word_value: + mov [value_size],2 + or [operand_flags],1 + call calculate_value + cmp al,2 + jb check_word_value + call recoverable_misuse + check_word_value: + mov eax,[edi] + mov edx,[edi+4] + cmp byte [edi+13],0 + je word_positive + cmp edx,-1 + jne range_exceeded + cmp eax,-10000h + jb range_exceeded + ret + word_positive: + test edx,edx + jnz range_exceeded + cmp eax,10000h + jae range_exceeded + ret +get_dword_value: + mov [value_size],4 + or [operand_flags],1 + call calculate_value + cmp al,4 + jne check_dword_value + mov [value_type],2 + mov eax,[edi] + cdq + cmp edx,[edi+4] + jne range_exceeded + mov ecx,edx + sar ecx,31 + cmp cl,[value_sign] + jne range_exceeded + ret + check_dword_value: + mov eax,[edi] + mov edx,[edi+4] + cmp byte [edi+13],0 + je dword_positive + cmp edx,-1 + jne range_exceeded + ret + dword_positive: + test edx,edx + jne range_exceeded + ret +get_pword_value: + mov [value_size],6 + or [operand_flags],1 + call calculate_value + cmp al,4 + jne check_pword_value + call recoverable_misuse + check_pword_value: + mov eax,[edi] + mov edx,[edi+4] + cmp byte [edi+13],0 + je pword_positive + cmp edx,-10000h + jb range_exceeded + ret + pword_positive: + cmp edx,10000h + jae range_exceeded + ret +get_qword_value: + mov [value_size],8 + or [operand_flags],1 + call calculate_value + check_qword_value: + mov eax,[edi] + mov edx,[edi+4] + ret +get_count_value: + mov [value_size],8 + or [operand_flags],1 + call calculate_expression + cmp word [edi+8],0 + jne invalid_value + mov [value_sign],0 + mov al,[edi+12] + or al,al + jz check_count_value + call recoverable_misuse + check_count_value: + cmp byte [edi+13],0 + jne invalid_count_value + mov eax,[edi] + mov edx,[edi+4] + or edx,edx + jnz invalid_count_value + ret + invalid_count_value: + cmp [error_line],0 + jne zero_count + mov eax,[current_line] + mov [error_line],eax + mov [error],invalid_value + zero_count: + xor eax,eax + ret +get_value: + mov [operand_size],0 + lods byte [esi] + call get_size_operator + cmp al,'(' + jne invalid_value + mov al,[operand_size] + cmp al,1 + je value_byte + cmp al,2 + je value_word + cmp al,4 + je value_dword + cmp al,6 + je value_pword + cmp al,8 + je value_qword + or al,al + jnz invalid_value + mov [value_size],al + call calculate_value + mov eax,[edi] + mov edx,[edi+4] + ret + calculate_value: + call calculate_expression + cmp word [edi+8],0 + jne invalid_value + mov eax,[edi+16] + mov [symbol_identifier],eax + mov al,[edi+13] + mov [value_sign],al + mov al,[edi+12] + mov [value_type],al + ret + value_qword: + call get_qword_value + truncated_value: + mov [value_sign],0 + ret + value_pword: + call get_pword_value + movzx edx,dx + jmp truncated_value + value_dword: + call get_dword_value + xor edx,edx + jmp truncated_value + value_word: + call get_word_value + xor edx,edx + movzx eax,ax + jmp truncated_value + value_byte: + call get_byte_value + xor edx,edx + movzx eax,al + jmp truncated_value +get_address_word_value: + mov [address_size],2 + mov [value_size],2 + mov [free_address_range],0 + jmp calculate_address +get_address_dword_value: + mov [address_size],4 + mov [value_size],4 + mov [free_address_range],0 + jmp calculate_address +get_address_qword_value: + mov [address_size],8 + mov [value_size],8 + mov [free_address_range],0 + jmp calculate_address +get_address_value: + mov [address_size],0 + mov [value_size],8 + or [free_address_range],-1 + calculate_address: + cmp byte [esi],'.' + je invalid_address + call calculate_expression + mov eax,[edi+16] + mov [address_symbol],eax + mov al,[edi+13] + mov [address_sign],al + mov al,[edi+12] + mov [value_type],al + cmp al,0 + je address_size_ok + jg get_address_symbol_size + neg al + get_address_symbol_size: + cmp al,6 + je special_address_type_32bit + cmp al,5 + je special_address_type_32bit + ja invalid_address_type + test al,1 + jnz invalid_address_type + shl al,5 + jmp address_symbol_ok + invalid_address_type: + call recoverable_misuse + special_address_type_32bit: + mov al,40h + address_symbol_ok: + mov ah,[address_size] + or [address_size],al + shr al,4 + or ah,ah + jz address_size_ok + cmp al,ah + je address_size_ok + cmp ax,0408h + je address_sizes_mixed + cmp ax,0804h + jne address_sizes_do_not_agree + address_sizes_mixed: + cmp [value_type],4 + jne address_sizes_mixed_type_ok + mov [value_type],2 + address_sizes_mixed_type_ok: + mov eax,[edi] + cdq + cmp edx,[edi+4] + je address_size_ok + cmp [error_line],0 + jne address_size_ok + call recoverable_overflow + address_size_ok: + xor ebx,ebx + xor ecx,ecx + mov cl,[value_type] + shl ecx,16 + mov ch,[address_size] + cmp word [edi+8],0 + je check_immediate_address + mov al,[edi+8] + mov dl,[edi+10] + call get_address_register + mov al,[edi+9] + mov dl,[edi+11] + call get_address_register + mov ax,bx + shr ah,4 + shr al,4 + or bh,bh + jz check_address_registers + or bl,bl + jz check_address_registers + cmp al,ah + jne check_vsib + check_address_registers: + or al,ah + cmp al,0Ch + jae check_vsib + cmp al,6 + je check_vsib + cmp al,7 + je check_vsib + mov ah,[address_size] + and ah,0Fh + jz address_registers_sizes_ok + cmp al,ah + jne invalid_address + address_registers_sizes_ok: + cmp al,4 + je sib_allowed + cmp al,8 + je sib_allowed + cmp al,9 + je check_ip_relative_address + cmp cl,1 + ja invalid_address + cmp [free_address_range],0 + jne check_qword_value + jmp check_word_value + address_sizes_do_not_match: + cmp al,0Fh + jne invalid_address + mov al,bh + and al,0Fh + cmp al,ah + jne invalid_address + check_ip_relative_address: + or bl,bl + jnz invalid_address + cmp bh,98h + je check_rip_relative_address + cmp bh,94h + jne invalid_address + cmp [free_address_range],0 + je check_dword_value + mov eax,[edi] + mov edx,[edi+4] + ret + check_rip_relative_address: + mov eax,[edi] + cdq + cmp edx,[edi+4] + jne range_exceeded + cmp dl,[edi+13] + jne range_exceeded + ret + get_address_register: + or al,al + jz address_register_ok + cmp dl,1 + jne scaled_register + or bh,bh + jnz scaled_register + mov bh,al + address_register_ok: + ret + scaled_register: + or bl,bl + jnz invalid_address + mov bl,al + mov cl,dl + jmp address_register_ok + sib_allowed: + or bh,bh + jnz check_index_with_base + cmp cl,3 + je special_index_scale + cmp cl,5 + je special_index_scale + cmp cl,9 + je special_index_scale + cmp cl,2 + jne check_index_scale + cmp bl,45h + jne special_index_scale + cmp [code_type],64 + je special_index_scale + cmp [segment_register],4 + jne special_index_scale + cmp [value_type],0 + jne check_index_scale + mov al,[edi] + cbw + cwde + cmp eax,[edi] + jne check_index_scale + cdq + cmp edx,[edi+4] + jne check_immediate_address + special_index_scale: + mov bh,bl + dec cl + check_immediate_address: + cmp [free_address_range],0 + jne check_qword_value + mov al,[address_size] + and al,0Fh + cmp al,2 + je check_word_value + cmp al,4 + je check_dword_value + cmp al,8 + je check_qword_value + or al,al + jnz invalid_value + cmp [code_type],64 + jne check_dword_value + jmp check_qword_value + check_index_with_base: + cmp cl,1 + jne check_index_scale + cmp bl,44h + je swap_base_with_index + cmp bl,84h + je swap_base_with_index + cmp [code_type],64 + je check_for_rbp_base + cmp bl,45h + jne check_for_ebp_base + cmp [segment_register],3 + je swap_base_with_index + jmp check_immediate_address + check_for_ebp_base: + cmp bh,45h + jne check_immediate_address + cmp [segment_register],4 + jne check_immediate_address + swap_base_with_index: + xchg bl,bh + jmp check_immediate_address + check_for_rbp_base: + cmp bh,45h + je swap_base_with_index + cmp bh,85h + je swap_base_with_index + jmp check_immediate_address + check_index_scale: + test cl,not 1111b + jnz invalid_address + mov al,cl + dec al + and al,cl + jz check_immediate_address + jmp invalid_address + check_vsib: + xor ah,ah + check_vsib_base: + test bh,bh + jz check_vsib_index + mov al,bh + shr al,4 + cmp al,4 + je check_vsib_base_size + cmp [code_type],64 + jne swap_vsib_registers + cmp al,8 + jne swap_vsib_registers + check_vsib_base_size: + mov ah,[address_size] + and ah,0Fh + jz check_vsib_index + cmp al,ah + jne invalid_address + check_vsib_index: + mov al,bl + and al,0E0h + cmp al,0C0h + jae check_index_scale + cmp al,60h + je check_index_scale + jmp invalid_address + swap_vsib_registers: + xor ah,-1 + jz invalid_address + cmp cl,1 + ja invalid_address + xchg bl,bh + mov cl,1 + jmp check_vsib_base + +calculate_relative_offset: + cmp [value_undefined],0 + jne relative_offset_ok + test bh,bh + setne ch + cmp bx,[ds:ebp+10h] + je origin_registers_ok + xchg bh,bl + xchg ch,cl + cmp bx,[ds:ebp+10h] + jne invalid_value + origin_registers_ok: + cmp cx,[ds:ebp+10h+2] + jne invalid_value + mov bl,[address_sign] + add eax,[ds:ebp] + adc edx,[ds:ebp+4] + adc bl,[ds:ebp+8] + sub eax,edi + sbb edx,0 + sbb bl,0 + mov [value_sign],bl + mov bl,[value_type] + mov ecx,[address_symbol] + mov [symbol_identifier],ecx + test bl,1 + jnz relative_offset_unallowed + cmp bl,6 + je plt_relative_offset + mov bh,[ds:ebp+9] + cmp bl,bh + je set_relative_offset_type + cmp bx,0402h + je set_relative_offset_type + relative_offset_unallowed: + call recoverable_misuse + set_relative_offset_type: + cmp [value_type],0 + je relative_offset_ok + mov [value_type],0 + cmp ecx,[ds:ebp+14h] + je relative_offset_ok + mov [value_type],3 + relative_offset_ok: + ret + plt_relative_offset: + mov [value_type],7 + cmp byte [ds:ebp+9],2 + je relative_offset_ok + cmp byte [ds:ebp+9],4 + jne recoverable_misuse + ret + +calculate_logical_expression: + xor al,al + calculate_embedded_logical_expression: + mov [logical_value_wrapping],al + call get_logical_value + logical_loop: + cmp byte [esi],'|' + je logical_or + cmp byte [esi],'&' + je logical_and + ret + logical_or: + inc esi + or al,al + jnz logical_value_already_determined + push eax + call get_logical_value + pop ebx + or al,bl + jmp logical_loop + logical_and: + inc esi + or al,al + jz logical_value_already_determined + push eax + call get_logical_value + pop ebx + and al,bl + jmp logical_loop + logical_value_already_determined: + push eax + call skip_logical_value + jc invalid_expression + pop eax + jmp logical_loop + get_value_for_comparison: + mov [value_size],8 + or [operand_flags],1 + lods byte [esi] + call calculate_expression + cmp byte [edi+8],0 + jne first_register_size_ok + mov byte [edi+10],0 + first_register_size_ok: + cmp byte [edi+9],0 + jne second_register_size_ok + mov byte [edi+11],0 + second_register_size_ok: + mov eax,[edi+16] + mov [symbol_identifier],eax + mov al,[edi+13] + mov [value_sign],al + mov bl,[edi+12] + mov eax,[edi] + mov edx,[edi+4] + mov ecx,[edi+8] + ret + get_logical_value: + xor al,al + check_for_negation: + cmp byte [esi],'~' + jne negation_ok + inc esi + xor al,-1 + jmp check_for_negation + negation_ok: + push eax + mov al,[esi] + cmp al,91h + je logical_expression + cmp al,0FFh + je invalid_expression + cmp al,88h + je check_for_defined + cmp al,8Ah + je check_for_earlier_defined + cmp al,89h + je check_for_used + cmp al,'0' + je given_false + cmp al,'1' + je given_true + cmp al,'(' + jne invalid_value + call get_value_for_comparison + mov bh,[value_sign] + push eax edx + push [symbol_identifier] + push ebx ecx + mov al,[esi] + or al,al + jz logical_number + cmp al,0Fh + je logical_number + cmp al,92h + je logical_number + cmp al,'&' + je logical_number + cmp al,'|' + je logical_number + inc esi + mov [compare_type],al + cmp byte [esi],'(' + jne invalid_value + call get_value_for_comparison + cmp bl,[esp+4] + jne values_not_relative + or bl,bl + jz check_values_registers + mov ebx,[symbol_identifier] + cmp ebx,[esp+8] + jne values_not_relative + check_values_registers: + cmp ecx,[esp] + je values_relative + ror ecx,16 + xchg ch,cl + ror ecx,16 + xchg ch,cl + cmp ecx,[esp] + je values_relative + values_not_relative: + cmp [compare_type],0F8h + jne invalid_comparison + add esp,12+8 + jmp return_false + invalid_comparison: + call recoverable_misuse + values_relative: + pop ebx + shl ebx,16 + mov bx,[esp] + add esp,8 + pop ecx ebp + cmp [compare_type],'=' + je check_equal + cmp [compare_type],0F1h + je check_not_equal + cmp [compare_type],0F8h + je return_true + test ebx,0FFFF0000h + jz check_less_or_greater + call recoverable_misuse + check_less_or_greater: + cmp [compare_type],'>' + je check_greater + cmp [compare_type],'<' + je check_less + cmp [compare_type],0F2h + je check_not_less + cmp [compare_type],0F3h + je check_not_greater + jmp invalid_expression + check_equal: + cmp bh,[value_sign] + jne return_false + cmp eax,ebp + jne return_false + cmp edx,ecx + jne return_false + jmp return_true + check_greater: + cmp bh,[value_sign] + jg return_true + jl return_false + cmp edx,ecx + jb return_true + ja return_false + cmp eax,ebp + jb return_true + jae return_false + check_less: + cmp bh,[value_sign] + jg return_false + jl return_true + cmp edx,ecx + jb return_false + ja return_true + cmp eax,ebp + jbe return_false + ja return_true + check_not_less: + cmp bh,[value_sign] + jg return_true + jl return_false + cmp edx,ecx + jb return_true + ja return_false + cmp eax,ebp + jbe return_true + ja return_false + check_not_greater: + cmp bh,[value_sign] + jg return_false + jl return_true + cmp edx,ecx + jb return_false + ja return_true + cmp eax,ebp + jb return_false + jae return_true + check_not_equal: + cmp bh,[value_sign] + jne return_true + cmp eax,ebp + jne return_true + cmp edx,ecx + jne return_true + jmp return_false + logical_number: + pop ecx ebx eax edx eax + or bl,bl + jnz invalid_logical_number + or cx,cx + jz logical_number_ok + invalid_logical_number: + call recoverable_misuse + logical_number_ok: + test bh,bh + jnz return_true + or eax,edx + jnz return_true + jmp return_false + check_for_earlier_defined: + or bh,-1 + jmp check_if_expression_defined + check_for_defined: + xor bh,bh + check_if_expression_defined: + or bl,-1 + lods word [esi] + cmp ah,'(' + jne invalid_expression + check_expression: + lods byte [esi] + or al,al + jz defined_string + cmp al,'.' + je defined_fp_value + cmp al,')' + je expression_checked + cmp al,'!' + je invalid_expression + cmp al,0Fh + je check_expression + cmp al,10h + je defined_register + cmp al,11h + je check_if_symbol_defined + cmp al,80h + jae check_expression + movzx eax,al + add esi,eax + jmp check_expression + defined_register: + inc esi + jmp check_expression + defined_fp_value: + add esi,12+1 + jmp expression_checked + defined_string: + lods dword [esi] + add esi,eax + inc esi + jmp expression_checked + check_if_symbol_defined: + lods dword [esi] + cmp eax,-1 + je invalid_expression + cmp eax,0Fh + jb check_expression + je reserved_word_used_as_symbol + test bh,bh + jnz no_prediction + test byte [eax+8],4 + jnz no_prediction + test byte [eax+8],1 + jz symbol_predicted_undefined + mov cx,[current_pass] + sub cx,[eax+16] + jz check_expression + cmp cx,1 + ja symbol_predicted_undefined + or byte [eax+8],40h+80h + jmp check_expression + no_prediction: + test byte [eax+8],1 + jz symbol_undefined + mov cx,[current_pass] + sub cx,[eax+16] + jz check_expression + jmp symbol_undefined + symbol_predicted_undefined: + or byte [eax+8],40h + and byte [eax+8],not 80h + symbol_undefined: + xor bl,bl + jmp check_expression + expression_checked: + mov al,bl + jmp logical_value_ok + check_for_used: + lods word [esi] + cmp ah,2 + jne invalid_expression + lods dword [esi] + cmp eax,0Fh + jb invalid_use_of_symbol + je reserved_word_used_as_symbol + inc esi + test byte [eax+8],8 + jz not_used + mov cx,[current_pass] + sub cx,[eax+18] + jz return_true + cmp cx,1 + ja not_used + or byte [eax+8],10h+20h + jmp return_true + not_used: + or byte [eax+8],10h + and byte [eax+8],not 20h + jmp return_false + given_false: + inc esi + return_false: + xor al,al + jmp logical_value_ok + given_true: + inc esi + return_true: + or al,-1 + jmp logical_value_ok + logical_expression: + lods byte [esi] + mov dl,[logical_value_wrapping] + push edx + call calculate_embedded_logical_expression + pop edx + mov [logical_value_wrapping],dl + push eax + lods byte [esi] + cmp al,92h + jne invalid_expression + pop eax + logical_value_ok: + pop ebx + xor al,bl + ret + +skip_symbol: + lods byte [esi] + or al,al + jz nothing_to_skip + cmp al,0Fh + je nothing_to_skip + cmp al,1 + je skip_instruction + cmp al,2 + je skip_label + cmp al,3 + je skip_label + cmp al,4 + je skip_special_label + cmp al,20h + jb skip_assembler_symbol + cmp al,'(' + je skip_expression + cmp al,'[' + je skip_address + skip_done: + clc + ret + skip_label: + add esi,2 + skip_instruction: + add esi,2 + skip_assembler_symbol: + inc esi + jmp skip_done + skip_special_label: + add esi,4 + jmp skip_done + skip_address: + mov al,[esi] + and al,11110000b + cmp al,60h + jb skip_expression + cmp al,70h + ja skip_expression + inc esi + jmp skip_address + skip_expression: + lods byte [esi] + or al,al + jz skip_string + cmp al,'.' + je skip_fp_value + cmp al,')' + je skip_done + cmp al,']' + je skip_done + cmp al,'!' + je skip_expression + cmp al,0Fh + je skip_expression + cmp al,10h + je skip_register + cmp al,11h + je skip_label_value + cmp al,80h + jae skip_expression + movzx eax,al + add esi,eax + jmp skip_expression + skip_label_value: + add esi,3 + skip_register: + inc esi + jmp skip_expression + skip_fp_value: + add esi,12 + jmp skip_done + skip_string: + lods dword [esi] + add esi,eax + inc esi + jmp skip_done + nothing_to_skip: + dec esi + stc + ret + +expand_path: + lods byte [esi] + cmp al,'%' + je environment_variable + stos byte [edi] + or al,al + jnz expand_path + cmp edi,[memory_end] + ja out_of_memory + ret + environment_variable: + mov ebx,esi + find_variable_end: + lods byte [esi] + or al,al + jz not_environment_variable + cmp al,'%' + jne find_variable_end + mov byte [esi-1],0 + push esi + mov esi,ebx + call get_environment_variable + pop esi + mov byte [esi-1],'%' + jmp expand_path + not_environment_variable: + mov al,'%' + stos byte [edi] + mov esi,ebx + jmp expand_path +get_include_directory: + lods byte [esi] + cmp al,';' + je include_directory_ok + stos byte [edi] + or al,al + jnz get_include_directory + dec esi + dec edi + include_directory_ok: + cmp byte [edi-1],'/' + je path_separator_ok + cmp byte [edi-1],'\' + je path_separator_ok + mov al,'/' + stos byte [edi] + path_separator_ok: + ret diff --git a/toolchain/fasmw17332/SOURCE/EXPRPARS.INC b/toolchain/fasmw17332/SOURCE/EXPRPARS.INC new file mode 100644 index 0000000..2863946 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/EXPRPARS.INC @@ -0,0 +1,1289 @@ + +; flat assembler core +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +convert_expression: + push ebp + call get_fp_value + jnc fp_expression + mov [current_offset],esp + expression_loop: + push edi + mov edi,single_operand_operators + call get_operator + pop edi + or al,al + jz expression_element + cmp al,82h + je expression_loop + push eax + jmp expression_loop + expression_element: + mov al,[esi] + cmp al,1Ah + je expression_number + cmp al,22h + je expression_number + cmp al,'(' + je expression_number + mov al,'!' + stos byte [edi] + jmp expression_operator + expression_number: + call convert_number + expression_operator: + push edi + mov edi,operators + call get_operator + pop edi + or al,al + jz expression_end + operators_loop: + cmp esp,[current_offset] + je push_operator + mov bl,al + and bl,0F0h + mov bh,byte [esp] + and bh,0F0h + cmp bl,bh + ja push_operator + pop ebx + mov byte [edi],bl + inc edi + jmp operators_loop + push_operator: + push eax + jmp expression_loop + expression_end: + cmp esp,[current_offset] + je expression_converted + pop eax + stos byte [edi] + jmp expression_end + expression_converted: + pop ebp + ret + fp_expression: + mov al,'.' + stos byte [edi] + mov eax,[fp_value] + stos dword [edi] + mov eax,[fp_value+4] + stos dword [edi] + mov eax,[fp_value+8] + stos dword [edi] + pop ebp + ret + +convert_number: + lea eax,[edi+20h] + mov edx,[memory_end] + cmp [source_start],0 + je check_memory_for_number + mov edx,[labels_list] + check_memory_for_number: + cmp eax,edx + jae out_of_memory + mov eax,esp + sub eax,[stack_limit] + cmp eax,100h + jb stack_overflow + cmp byte [esi],'(' + je expression_value + inc edi + call get_number + jc symbol_value + or ebp,ebp + jz valid_number + mov byte [edi-1],0Fh + ret + valid_number: + cmp dword [edi+4],0 + jne qword_number + cmp word [edi+2],0 + jne dword_number + cmp byte [edi+1],0 + jne word_number + byte_number: + mov byte [edi-1],1 + inc edi + ret + qword_number: + mov byte [edi-1],8 + add edi,8 + ret + dword_number: + mov byte [edi-1],4 + scas dword [edi] + ret + word_number: + mov byte [edi-1],2 + scas word [edi] + ret + expression_value: + inc esi + push [current_offset] + call convert_expression + pop [current_offset] + lods byte [esi] + cmp al,')' + je subexpression_closed + dec esi + mov al,'!' + stosb + subexpression_closed: + ret + symbol_value: + mov eax,[source_start] + test eax,eax + jz preprocessor_value + cmp eax,-1 + je invalid_value + push edi esi + lods word [esi] + cmp al,1Ah + jne no_address_register + movzx ecx,ah + call get_symbol + jc no_address_register + cmp al,10h + jne no_address_register + mov al,ah + shr ah,4 + cmp ah,4 + je register_value + and ah,not 1 + cmp ah,8 + je register_value + cmp ah,0Ch + jae register_value + cmp ah,6 + je register_value + cmp al,23h + je register_value + cmp al,25h + je register_value + cmp al,26h + je register_value + cmp al,27h + je register_value + no_address_register: + pop esi + mov edi,directive_operators + call get_operator + pop edi + or al,al + jnz broken_value + lods byte [esi] + cmp al,1Ah + jne invalid_value + lods byte [esi] + movzx ecx,al + call get_label_id + store_label_value: + mov byte [edi-1],11h + stos dword [edi] + ret + broken_value: + mov eax,0Fh + jmp store_label_value + register_value: + pop edx edi + mov byte [edi-1],10h + stos byte [edi] + ret + preprocessor_value: + dec edi + lods byte [esi] + cmp al,1Ah + jne invalid_value + lods byte [esi] + mov cl,al + mov ch,10b + call get_preprocessor_symbol + jc invalid_value + test edx,edx + jz special_preprocessor_value + push esi + mov esi,[edx+8] + push [current_offset] + call convert_expression + pop [current_offset] + pop esi + ret + special_preprocessor_value: + cmp eax,preprocessed_line_value + jne invalid_value + call get_current_line_from_file + mov al,4 + stos byte [edi] + mov eax,[ebx+4] + stos dword [edi] + ret + +get_number: + xor ebp,ebp + lods byte [esi] + cmp al,22h + je get_text_number + cmp al,1Ah + jne not_number + lods byte [esi] + movzx ecx,al + mov [number_start],esi + mov al,[esi] + cmp al,'$' + je number_begin + sub al,30h + cmp al,9 + ja invalid_number + number_begin: + mov ebx,esi + add esi,ecx + push esi + dec esi + mov dword [edi],0 + mov dword [edi+4],0 + cmp byte [ebx],'$' + je pascal_hex_number + cmp word [ebx],'0x' + je get_hex_number + mov al,[esi] + dec esi + cmp al,'h' + je get_hex_number + cmp al,'b' + je get_bin_number + cmp al,'d' + je get_dec_number + cmp al,'o' + je get_oct_number + cmp al,'q' + je get_oct_number + cmp al,'H' + je get_hex_number + cmp al,'B' + je get_bin_number + cmp al,'D' + je get_dec_number + cmp al,'O' + je get_oct_number + cmp al,'Q' + je get_oct_number + inc esi + get_dec_number: + mov ebx,esi + mov esi,[number_start] + get_dec_digit: + cmp esi,ebx + ja number_ok + cmp byte [esi],27h + je next_dec_digit + cmp byte [esi],'_' + je next_dec_digit + xor edx,edx + mov eax,[edi] + shld edx,eax,2 + shl eax,2 + add eax,[edi] + adc edx,0 + add eax,eax + adc edx,edx + mov [edi],eax + mov eax,[edi+4] + add eax,eax + jc dec_out_of_range + add eax,eax + jc dec_out_of_range + add eax,[edi+4] + jc dec_out_of_range + add eax,eax + jc dec_out_of_range + add eax,edx + jc dec_out_of_range + mov [edi+4],eax + movzx eax,byte [esi] + sub al,30h + jc bad_number + cmp al,9 + ja bad_number + add [edi],eax + adc dword [edi+4],0 + jc dec_out_of_range + next_dec_digit: + inc esi + jmp get_dec_digit + dec_out_of_range: + cmp esi,ebx + ja dec_out_of_range_finished + lods byte [esi] + cmp al,27h + je bad_number + cmp al,'_' + je bad_number + sub al,30h + jc bad_number + cmp al,9 + ja bad_number + jmp dec_out_of_range + dec_out_of_range_finished: + or ebp,-1 + jmp number_ok + bad_number: + pop eax + invalid_number: + mov esi,[number_start] + dec esi + not_number: + dec esi + stc + ret + get_bin_number: + xor bl,bl + get_bin_digit: + cmp esi,[number_start] + jb number_ok + movzx eax,byte [esi] + cmp al,27h + je bin_digit_skip + cmp al,'_' + je bin_digit_skip + sub al,30h + cmp al,1 + ja bad_number + xor edx,edx + mov cl,bl + dec esi + cmp bl,64 + je bin_out_of_range + inc bl + cmp cl,32 + jae bin_digit_high + shl eax,cl + or dword [edi],eax + jmp get_bin_digit + bin_digit_high: + sub cl,32 + shl eax,cl + or dword [edi+4],eax + jmp get_bin_digit + bin_out_of_range: + or al,al + jz get_bin_digit + or ebp,-1 + jmp get_bin_digit + bin_digit_skip: + dec esi + jmp get_bin_digit + pascal_hex_number: + cmp cl,1 + je bad_number + get_hex_number: + xor bl,bl + get_hex_digit: + cmp esi,[number_start] + jb number_ok + movzx eax,byte [esi] + cmp al,27h + je hex_digit_skip + cmp al,'_' + je hex_digit_skip + cmp al,'x' + je hex_number_ok + cmp al,'$' + je pascal_hex_ok + sub al,30h + cmp al,9 + jbe hex_digit_ok + sub al,7 + cmp al,15 + jbe hex_letter_digit_ok + sub al,20h + cmp al,15 + ja bad_number + hex_letter_digit_ok: + cmp al,10 + jb bad_number + hex_digit_ok: + xor edx,edx + mov cl,bl + dec esi + cmp bl,64 + je hex_out_of_range + add bl,4 + cmp cl,32 + jae hex_digit_high + shl eax,cl + or dword [edi],eax + jmp get_hex_digit + hex_digit_high: + sub cl,32 + shl eax,cl + or dword [edi+4],eax + jmp get_hex_digit + hex_out_of_range: + or al,al + jz get_hex_digit + or ebp,-1 + jmp get_hex_digit + hex_digit_skip: + dec esi + jmp get_hex_digit + get_oct_number: + xor bl,bl + get_oct_digit: + cmp esi,[number_start] + jb number_ok + movzx eax,byte [esi] + cmp al,27h + je oct_digit_skip + cmp al,'_' + je oct_digit_skip + sub al,30h + cmp al,7 + ja bad_number + oct_digit_ok: + xor edx,edx + mov cl,bl + dec esi + cmp bl,63 + ja oct_out_of_range + jne oct_range_ok + cmp al,1 + ja oct_out_of_range + oct_range_ok: + add bl,3 + cmp cl,30 + je oct_digit_wrap + ja oct_digit_high + shl eax,cl + or dword [edi],eax + jmp get_oct_digit + oct_digit_wrap: + shl eax,cl + adc dword [edi+4],0 + or dword [edi],eax + jmp get_oct_digit + oct_digit_high: + sub cl,32 + shl eax,cl + or dword [edi+4],eax + jmp get_oct_digit + oct_digit_skip: + dec esi + jmp get_oct_digit + oct_out_of_range: + or al,al + jz get_oct_digit + or ebp,-1 + jmp get_oct_digit + hex_number_ok: + dec esi + pascal_hex_ok: + cmp esi,[number_start] + jne bad_number + number_ok: + pop esi + number_done: + clc + ret + get_text_number: + lods dword [esi] + mov edx,eax + xor bl,bl + mov dword [edi],0 + mov dword [edi+4],0 + get_text_character: + sub edx,1 + jc number_done + movzx eax,byte [esi] + inc esi + mov cl,bl + cmp bl,64 + je text_out_of_range + add bl,8 + cmp cl,32 + jae text_character_high + shl eax,cl + or dword [edi],eax + jmp get_text_character + text_character_high: + sub cl,32 + shl eax,cl + or dword [edi+4],eax + jmp get_text_character + text_out_of_range: + or ebp,-1 + jmp get_text_character + +get_fp_value: + push edi esi + fp_value_start: + lods byte [esi] + cmp al,'-' + je fp_value_start + cmp al,'+' + je fp_value_start + cmp al,1Ah + jne not_fp_value + lods byte [esi] + movzx ecx,al + cmp cl,1 + jbe not_fp_value + lea edx,[esi+1] + xor ah,ah + check_fp_value: + lods byte [esi] + cmp al,'.' + je fp_character_dot + cmp al,'E' + je fp_character_exp + cmp al,'e' + je fp_character_exp + cmp al,'F' + je fp_last_character + cmp al,'f' + je fp_last_character + digit_expected: + cmp al,'0' + jb not_fp_value + cmp al,'9' + ja not_fp_value + jmp fp_character_ok + fp_character_dot: + cmp esi,edx + je not_fp_value + or ah,ah + jnz not_fp_value + or ah,1 + lods byte [esi] + loop digit_expected + not_fp_value: + pop esi edi + stc + ret + fp_last_character: + cmp cl,1 + jne not_fp_value + or ah,4 + jmp fp_character_ok + fp_character_exp: + cmp esi,edx + je not_fp_value + cmp ah,1 + ja not_fp_value + or ah,2 + cmp ecx,1 + jne fp_character_ok + cmp byte [esi],'+' + je fp_exp_sign + cmp byte [esi],'-' + jne fp_character_ok + fp_exp_sign: + inc esi + cmp byte [esi],1Ah + jne not_fp_value + inc esi + lods byte [esi] + movzx ecx,al + inc ecx + fp_character_ok: + dec ecx + jnz check_fp_value + or ah,ah + jz not_fp_value + pop esi + mov [fp_sign],0 + fp_get_sign: + lods byte [esi] + cmp al,1Ah + je fp_get + cmp al,'+' + je fp_get_sign + xor [fp_sign],1 + jmp fp_get_sign + fp_get: + lods byte [esi] + movzx ecx,al + xor edx,edx + mov edi,fp_value + mov [edi],edx + mov [edi+4],edx + mov [edi+12],edx + call fp_optimize + mov [fp_format],0 + mov al,[esi] + fp_before_dot: + lods byte [esi] + cmp al,'.' + je fp_dot + cmp al,'E' + je fp_exponent + cmp al,'e' + je fp_exponent + cmp al,'F' + je fp_done + cmp al,'f' + je fp_done + sub al,30h + mov edi,fp_value+16 + xor edx,edx + mov dword [edi+12],edx + mov dword [edi],edx + mov dword [edi+4],edx + mov [edi+7],al + mov dl,7 + mov dword [edi+8],edx + call fp_optimize + mov edi,fp_value + push ecx + mov ecx,10 + call fp_mul + pop ecx + mov ebx,fp_value+16 + call fp_add + loop fp_before_dot + fp_dot: + mov edi,fp_value+16 + xor edx,edx + mov [edi],edx + mov [edi+4],edx + mov byte [edi+7],80h + mov [edi+8],edx + mov dword [edi+12],edx + dec ecx + jz fp_done + fp_after_dot: + lods byte [esi] + cmp al,'E' + je fp_exponent + cmp al,'e' + je fp_exponent + cmp al,'F' + je fp_done + cmp al,'f' + je fp_done + inc [fp_format] + cmp [fp_format],80h + jne fp_counter_ok + mov [fp_format],7Fh + fp_counter_ok: + dec esi + mov edi,fp_value+16 + push ecx + mov ecx,10 + call fp_div + push dword [edi] + push dword [edi+4] + push dword [edi+8] + push dword [edi+12] + lods byte [esi] + sub al,30h + movzx ecx,al + call fp_mul + mov ebx,edi + mov edi,fp_value + call fp_add + mov edi,fp_value+16 + pop dword [edi+12] + pop dword [edi+8] + pop dword [edi+4] + pop dword [edi] + pop ecx + dec ecx + jnz fp_after_dot + jmp fp_done + fp_exponent: + or [fp_format],80h + xor edx,edx + xor ebp,ebp + dec ecx + jnz get_exponent + cmp byte [esi],'+' + je fp_exponent_sign + cmp byte [esi],'-' + jne fp_done + not ebp + fp_exponent_sign: + add esi,2 + lods byte [esi] + movzx ecx,al + get_exponent: + movzx eax,byte [esi] + inc esi + sub al,30h + cmp al,10 + jae exponent_ok + imul edx,10 + cmp edx,8000h + jae value_out_of_range + add edx,eax + loop get_exponent + exponent_ok: + mov edi,fp_value + or edx,edx + jz fp_done + mov ecx,edx + or ebp,ebp + jnz fp_negative_power + fp_power: + push ecx + mov ecx,10 + call fp_mul + pop ecx + loop fp_power + jmp fp_done + fp_negative_power: + push ecx + mov ecx,10 + call fp_div + pop ecx + loop fp_negative_power + fp_done: + mov edi,fp_value + mov al,[fp_format] + mov [edi+10],al + mov al,[fp_sign] + mov [edi+11],al + test byte [edi+15],80h + jz fp_ok + add dword [edi],1 + adc dword [edi+4],0 + jnc fp_ok + mov eax,[edi+4] + shrd [edi],eax,1 + shr eax,1 + or eax,80000000h + mov [edi+4],eax + inc word [edi+8] + fp_ok: + pop edi + clc + ret + fp_mul: + or ecx,ecx + jz fp_zero + mov eax,[edi+12] + mul ecx + mov [edi+12],eax + mov ebx,edx + mov eax,[edi] + mul ecx + add eax,ebx + adc edx,0 + mov [edi],eax + mov ebx,edx + mov eax,[edi+4] + mul ecx + add eax,ebx + adc edx,0 + mov [edi+4],eax + .loop: + or edx,edx + jz .done + mov eax,[edi] + shrd [edi+12],eax,1 + mov eax,[edi+4] + shrd [edi],eax,1 + shrd eax,edx,1 + mov [edi+4],eax + shr edx,1 + inc dword [edi+8] + cmp dword [edi+8],8000h + jge value_out_of_range + jmp .loop + .done: + ret + fp_div: + mov eax,[edi+4] + xor edx,edx + div ecx + mov [edi+4],eax + mov eax,[edi] + div ecx + mov [edi],eax + mov eax,[edi+12] + div ecx + mov [edi+12],eax + mov ebx,eax + or ebx,[edi] + or ebx,[edi+4] + jz fp_zero + .loop: + test byte [edi+7],80h + jnz .exp_ok + mov eax,[edi] + shld [edi+4],eax,1 + mov eax,[edi+12] + shld [edi],eax,1 + add eax,eax + mov [edi+12],eax + dec dword [edi+8] + add edx,edx + jmp .loop + .exp_ok: + mov eax,edx + xor edx,edx + div ecx + add [edi+12],eax + adc dword [edi],0 + adc dword [edi+4],0 + jnc .done + mov eax,[edi+4] + mov ebx,[edi] + shrd [edi],eax,1 + shrd [edi+12],ebx,1 + shr eax,1 + or eax,80000000h + mov [edi+4],eax + inc dword [edi+8] + .done: + ret + fp_add: + cmp dword [ebx+8],8000h + je .done + cmp dword [edi+8],8000h + je .copy + mov eax,[ebx+8] + cmp eax,[edi+8] + jge .exp_ok + mov eax,[edi+8] + .exp_ok: + call .change_exp + xchg ebx,edi + call .change_exp + xchg ebx,edi + mov edx,[ebx+12] + mov eax,[ebx] + mov ebx,[ebx+4] + add [edi+12],edx + adc [edi],eax + adc [edi+4],ebx + jnc .done + mov eax,[edi] + shrd [edi+12],eax,1 + mov eax,[edi+4] + shrd [edi],eax,1 + shr eax,1 + or eax,80000000h + mov [edi+4],eax + inc dword [edi+8] + .done: + ret + .copy: + mov eax,[ebx] + mov [edi],eax + mov eax,[ebx+4] + mov [edi+4],eax + mov eax,[ebx+8] + mov [edi+8],eax + mov eax,[ebx+12] + mov [edi+12],eax + ret + .change_exp: + push ecx + mov ecx,eax + sub ecx,[ebx+8] + mov edx,[ebx+4] + jecxz .exp_done + .exp_loop: + mov ebp,[ebx] + shrd [ebx+12],ebp,1 + shrd [ebx],edx,1 + shr edx,1 + inc dword [ebx+8] + loop .exp_loop + .exp_done: + mov [ebx+4],edx + pop ecx + ret + fp_optimize: + mov eax,[edi] + mov ebp,[edi+4] + or ebp,[edi] + or ebp,[edi+12] + jz fp_zero + .loop: + test byte [edi+7],80h + jnz .done + shld [edi+4],eax,1 + mov ebp,[edi+12] + shld eax,ebp,1 + mov [edi],eax + shl dword [edi+12],1 + dec dword [edi+8] + jmp .loop + .done: + ret + fp_zero: + mov dword [edi+8],8000h + ret + +preevaluate_logical_expression: + xor al,al + preevaluate_embedded_logical_expression: + mov [logical_value_wrapping],al + push edi + call preevaluate_logical_value + preevaluation_loop: + cmp al,0FFh + je invalid_logical_expression + mov dl,[esi] + inc esi + cmp dl,'|' + je preevaluate_or + cmp dl,'&' + je preevaluate_and + cmp dl,92h + je preevaluation_done + or dl,dl + jnz invalid_logical_expression + preevaluation_done: + pop edx + dec esi + ret + preevaluate_or: + cmp al,'1' + je quick_true + cmp al,'0' + je leave_only_following + push edi + mov al,dl + stos byte [edi] + call preevaluate_logical_value + pop ebx + cmp al,'0' + je leave_only_preceding + cmp al,'1' + jne preevaluation_loop + stos byte [edi] + xor al,al + jmp preevaluation_loop + preevaluate_and: + cmp al,'0' + je quick_false + cmp al,'1' + je leave_only_following + push edi + mov al,dl + stos byte [edi] + call preevaluate_logical_value + pop ebx + cmp al,'1' + je leave_only_preceding + cmp al,'0' + jne preevaluation_loop + stos byte [edi] + xor al,al + jmp preevaluation_loop + leave_only_following: + mov edi,[esp] + call preevaluate_logical_value + jmp preevaluation_loop + leave_only_preceding: + mov edi,ebx + xor al,al + jmp preevaluation_loop + quick_true: + call skip_logical_value + jc invalid_logical_expression + mov edi,[esp] + mov al,'1' + jmp preevaluation_loop + quick_false: + call skip_logical_value + jc invalid_logical_expression + mov edi,[esp] + mov al,'0' + jmp preevaluation_loop + invalid_logical_expression: + pop edi + mov esi,edi + mov al,0FFh + stos byte [edi] + ret + skip_logical_value: + cmp byte [esi],'~' + jne negation_skipped + inc esi + jmp skip_logical_value + negation_skipped: + mov al,[esi] + cmp al,91h + jne skip_simple_logical_value + inc esi + xchg al,[logical_value_wrapping] + push eax + skip_logical_expression: + call skip_logical_value + lods byte [esi] + or al,al + jz wrongly_structured_logical_expression + cmp al,0Fh + je wrongly_structured_logical_expression + cmp al,'|' + je skip_logical_expression + cmp al,'&' + je skip_logical_expression + cmp al,92h + jne wrongly_structured_logical_expression + pop eax + mov [logical_value_wrapping],al + logical_value_skipped: + clc + ret + wrongly_structured_logical_expression: + pop eax + stc + ret + skip_simple_logical_value: + mov [logical_value_parentheses],0 + find_simple_logical_value_end: + mov al,[esi] + or al,al + jz logical_value_skipped + cmp al,0Fh + je logical_value_skipped + cmp al,'|' + je logical_value_skipped + cmp al,'&' + je logical_value_skipped + cmp al,91h + je skip_logical_value_internal_parenthesis + cmp al,92h + jne skip_logical_value_symbol + sub [logical_value_parentheses],1 + jnc skip_logical_value_symbol + cmp [logical_value_wrapping],91h + jne skip_logical_value_symbol + jmp logical_value_skipped + skip_logical_value_internal_parenthesis: + inc [logical_value_parentheses] + skip_logical_value_symbol: + call skip_symbol + jmp find_simple_logical_value_end + preevaluate_logical_value: + mov ebp,edi + preevaluate_negation: + cmp byte [esi],'~' + jne preevaluate_negation_ok + movs byte [edi],[esi] + jmp preevaluate_negation + preevaluate_negation_ok: + mov ebx,esi + cmp byte [esi],91h + jne preevaluate_simple_logical_value + lods byte [esi] + stos byte [edi] + push ebp + mov dl,[logical_value_wrapping] + push edx + call preevaluate_embedded_logical_expression + pop edx + mov [logical_value_wrapping],dl + pop ebp + cmp al,0FFh + je invalid_logical_value + cmp byte [esi],92h + jne invalid_logical_value + or al,al + jnz preevaluated_expression_value + movs byte [edi],[esi] + ret + preevaluated_expression_value: + inc esi + lea edx,[edi-1] + sub edx,ebp + test edx,1 + jz expression_negation_ok + xor al,1 + expression_negation_ok: + mov edi,ebp + ret + invalid_logical_value: + mov edi,ebp + mov al,0FFh + ret + preevaluate_simple_logical_value: + xor edx,edx + mov [logical_value_parentheses],edx + find_logical_value_boundaries: + mov al,[esi] + or al,al + jz logical_value_boundaries_found + cmp al,91h + je logical_value_internal_parentheses + cmp al,92h + je logical_value_boundaries_parenthesis_close + cmp al,'|' + je logical_value_boundaries_found + cmp al,'&' + je logical_value_boundaries_found + or edx,edx + jnz next_symbol_in_logical_value + cmp al,0F0h + je preevaluable_logical_operator + cmp al,0F7h + je preevaluable_logical_operator + cmp al,0F6h + jne next_symbol_in_logical_value + preevaluable_logical_operator: + mov edx,esi + next_symbol_in_logical_value: + call skip_symbol + jmp find_logical_value_boundaries + logical_value_internal_parentheses: + inc [logical_value_parentheses] + jmp next_symbol_in_logical_value + logical_value_boundaries_parenthesis_close: + sub [logical_value_parentheses],1 + jnc next_symbol_in_logical_value + cmp [logical_value_wrapping],91h + jne next_symbol_in_logical_value + logical_value_boundaries_found: + or edx,edx + jz non_preevaluable_logical_value + mov al,[edx] + cmp al,0F0h + je compare_symbols + cmp al,0F7h + je compare_symbol_types + cmp al,0F6h + je scan_symbols_list + non_preevaluable_logical_value: + mov ecx,esi + mov esi,ebx + sub ecx,esi + jz invalid_logical_value + cmp esi,edi + je leave_logical_value_intact + rep movs byte [edi],[esi] + xor al,al + ret + leave_logical_value_intact: + add edi,ecx + add esi,ecx + xor al,al + ret + compare_symbols: + lea ecx,[esi-1] + sub ecx,edx + mov eax,edx + sub eax,ebx + cmp ecx,eax + jne preevaluated_false + push esi edi + mov esi,ebx + lea edi,[edx+1] + repe cmps byte [esi],[edi] + pop edi esi + je preevaluated_true + preevaluated_false: + mov eax,edi + sub eax,ebp + test eax,1 + jnz store_true + store_false: + mov edi,ebp + mov al,'0' + ret + preevaluated_true: + mov eax,edi + sub eax,ebp + test eax,1 + jnz store_false + store_true: + mov edi,ebp + mov al,'1' + ret + compare_symbol_types: + push esi + lea esi,[edx+1] + type_comparison: + cmp esi,[esp] + je types_compared + mov al,[esi] + cmp al,[ebx] + jne different_type + cmp al,'(' + jne equal_type + mov al,[esi+1] + mov ah,[ebx+1] + cmp al,ah + je equal_type + or al,al + jz different_type + or ah,ah + jz different_type + cmp al,'.' + je different_type + cmp ah,'.' + je different_type + equal_type: + call skip_symbol + xchg esi,ebx + call skip_symbol + xchg esi,ebx + jmp type_comparison + types_compared: + pop esi + cmp byte [ebx],0F7h + jne preevaluated_false + jmp preevaluated_true + different_type: + pop esi + jmp preevaluated_false + scan_symbols_list: + push edi esi + lea esi,[edx+1] + sub edx,ebx + lods byte [esi] + cmp al,'<' + jne invalid_symbols_list + get_next_from_list: + mov edi,esi + get_from_list: + cmp byte [esi],',' + je compare_in_list + cmp byte [esi],'>' + je compare_in_list + cmp esi,[esp] + jae invalid_symbols_list + call skip_symbol + jmp get_from_list + compare_in_list: + mov ecx,esi + sub ecx,edi + cmp ecx,edx + jne not_equal_length_in_list + mov esi,ebx + repe cmps byte [esi],[edi] + mov esi,edi + jne not_equal_in_list + skip_rest_of_list: + cmp byte [esi],'>' + je check_list_end + cmp esi,[esp] + jae invalid_symbols_list + call skip_symbol + jmp skip_rest_of_list + check_list_end: + inc esi + cmp esi,[esp] + jne invalid_symbols_list + pop esi edi + jmp preevaluated_true + not_equal_in_list: + add esi,ecx + not_equal_length_in_list: + lods byte [esi] + cmp al,',' + je get_next_from_list + cmp esi,[esp] + jne invalid_symbols_list + pop esi edi + jmp preevaluated_false + invalid_symbols_list: + pop esi edi + jmp invalid_logical_value diff --git a/toolchain/fasmw17332/SOURCE/FORMATS.INC b/toolchain/fasmw17332/SOURCE/FORMATS.INC new file mode 100644 index 0000000..821175f --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/FORMATS.INC @@ -0,0 +1,4195 @@ + +; flat assembler core +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +formatter: + mov [current_offset],edi + cmp [output_file],0 + jne output_path_ok + mov esi,[input_file] + mov edi,[free_additional_memory] + duplicate_output_path: + lods byte [esi] + cmp edi,[structures_buffer] + jae out_of_memory + stos byte [edi] + or al,al + jnz duplicate_output_path + dec edi + mov eax,edi + find_extension: + dec eax + cmp eax,[free_additional_memory] + jb extension_found + cmp byte [eax],'\' + je extension_found + cmp byte [eax],'/' + je extension_found + cmp byte [eax],'.' + jne find_extension + mov edi,eax + extension_found: + lea eax,[edi+9] + cmp eax,[structures_buffer] + jae out_of_memory + cmp [file_extension],0 + jne extension_specified + mov al,[output_format] + cmp al,2 + je exe_extension + jb bin_extension + cmp al,4 + je obj_extension + cmp al,5 + je o_extension + cmp al,3 + jne no_extension + cmp [subsystem],1 + je sys_extension + cmp [subsystem],10 + jae efi_extension + bt [format_flags],8 + jnc exe_extension + mov eax,'.dll' + jmp make_extension + sys_extension: + mov eax,'.sys' + jmp make_extension + efi_extension: + mov eax,'.efi' + jmp make_extension + bin_extension: + mov eax,'.bin' + bt [format_flags],0 + jnc make_extension + mov eax,'.com' + jmp make_extension + obj_extension: + mov eax,'.obj' + jmp make_extension + o_extension: + mov eax,'.o' + bt [format_flags],0 + jnc make_extension + no_extension: + xor eax,eax + jmp make_extension + exe_extension: + mov eax,'.exe' + make_extension: + xchg eax,[edi] + scas dword [edi] + mov byte [edi],0 + scas byte [edi] + mov esi,edi + stos dword [edi] + sub edi,9 + xor eax,eax + mov ebx,characters + adapt_case: + mov al,[esi] + or al,al + jz adapt_next + xlat byte [ebx] + cmp al,[esi] + je adapt_ok + sub byte [edi],20h + adapt_ok: + inc esi + adapt_next: + inc edi + cmp byte [edi],0 + jne adapt_case + jmp extension_ok + extension_specified: + mov al,'.' + stos byte [edi] + mov esi,[file_extension] + copy_extension: + lods byte [esi] + stos byte [edi] + test al,al + jnz copy_extension + dec edi + extension_ok: + mov esi,edi + lea ecx,[esi+1] + sub ecx,[free_additional_memory] + mov edi,[structures_buffer] + dec edi + std + rep movs byte [edi],[esi] + cld + inc edi + mov [structures_buffer],edi + mov [output_file],edi + output_path_ok: + cmp [symbols_file],0 + je labels_table_ok + mov ecx,[memory_end] + sub ecx,[labels_list] + mov edi,[tagged_blocks] + sub edi,8 + mov [edi],ecx + or dword [edi+4],-1 + sub edi,ecx + cmp edi,[current_offset] + jbe out_of_memory + mov [tagged_blocks],edi + mov esi,[memory_end] + copy_labels: + sub esi,32 + cmp esi,[labels_list] + jb labels_table_ok + mov ecx,32 shr 2 + rep movs dword [edi],[esi] + sub esi,32 + jmp copy_labels + labels_table_ok: + mov edi,[current_offset] + cmp [output_format],4 + je coff_formatter + cmp [output_format],5 + jne common_formatter + bt [format_flags],0 + jnc elf_formatter + common_formatter: + mov eax,edi + sub eax,[code_start] + mov [real_code_size],eax + cmp edi,[undefined_data_end] + jne calculate_code_size + mov edi,[undefined_data_start] + calculate_code_size: + mov [current_offset],edi + sub edi,[code_start] + mov [code_size],edi + and [written_size],0 + mov edx,[output_file] + call create + jc write_failed + cmp [output_format],3 + jne stub_written + mov edx,[code_start] + mov ecx,[stub_size] + sub edx,ecx + add [written_size],ecx + call write + stub_written: + cmp [output_format],2 + jne write_output + call write_mz_header + write_output: + call write_code + output_written: + call close + cmp [symbols_file],0 + jne dump_symbols + ret + write_code: + mov eax,[written_size] + mov [headers_size],eax + mov edx,[code_start] + mov ecx,[code_size] + add [written_size],ecx + lea eax,[edx+ecx] + call write + jc write_failed + ret +format_directive: + cmp edi,[code_start] + jne unexpected_instruction + mov ebp,[addressing_space] + test byte [ds:ebp+0Ah],1 + jnz unexpected_instruction + cmp [output_format],0 + jne unexpected_instruction + lods byte [esi] + cmp al,1Ch + je format_prefix + cmp al,18h + jne invalid_argument + lods byte [esi] + select_format: + mov dl,al + shr al,4 + mov [output_format],al + and edx,0Fh + or [format_flags],edx + cmp al,2 + je format_mz + cmp al,3 + je format_pe + cmp al,4 + je format_coff + cmp al,5 + je format_elf + format_defined: + cmp byte [esi],86h + jne instruction_assembled + cmp word [esi+1],'(' + jne invalid_argument + mov eax,[esi+3] + add esi,3+4 + mov [file_extension],esi + lea esi,[esi+eax+1] + jmp instruction_assembled + format_prefix: + lods byte [esi] + mov ah,al + lods byte [esi] + cmp al,18h + jne invalid_argument + lods byte [esi] + mov edx,eax + shr dl,4 + shr dh,4 + cmp dl,dh + jne invalid_argument + or al,ah + jmp select_format +entry_directive: + bts [format_flags],10h + jc setting_already_specified + mov al,[output_format] + cmp al,2 + je mz_entry + cmp al,3 + je pe_entry + cmp al,5 + jne illegal_instruction + bt [format_flags],0 + jc elf_entry + jmp illegal_instruction +stack_directive: + bts [format_flags],11h + jc setting_already_specified + mov al,[output_format] + cmp al,2 + je mz_stack + cmp al,3 + je pe_stack + jmp illegal_instruction +heap_directive: + bts [format_flags],12h + jc setting_already_specified + mov al,[output_format] + cmp al,2 + je mz_heap + cmp al,3 + je pe_heap + jmp illegal_instruction +segment_directive: + mov al,[output_format] + cmp al,2 + je mz_segment + cmp al,5 + je elf_segment + jmp illegal_instruction +section_directive: + mov al,[output_format] + cmp al,3 + je pe_section + cmp al,4 + je coff_section + cmp al,5 + je elf_section + jmp illegal_instruction +public_directive: + mov al,[output_format] + cmp al,4 + je public_allowed + cmp al,5 + jne illegal_instruction + bt [format_flags],0 + jc illegal_instruction + public_allowed: + mov [base_code],0C0h + lods byte [esi] + cmp al,2 + je public_label + cmp al,1Dh + jne invalid_argument + lods byte [esi] + and al,7 + add [base_code],al + lods byte [esi] + cmp al,2 + jne invalid_argument + public_label: + lods dword [esi] + cmp eax,0Fh + jb invalid_use_of_symbol + je reserved_word_used_as_symbol + inc esi + mov dx,[current_pass] + mov [eax+18],dx + or byte [eax+8],8 + mov ebx,eax + call store_label_reference + mov eax,ebx + mov ebx,[free_additional_memory] + lea edx,[ebx+10h] + cmp edx,[structures_buffer] + jae out_of_memory + mov [free_additional_memory],edx + mov [ebx+8],eax + mov eax,[current_line] + mov [ebx+0Ch],eax + lods byte [esi] + cmp al,86h + jne invalid_argument + lods word [esi] + cmp ax,'(' + jne invalid_argument + mov [ebx+4],esi + lods dword [esi] + lea esi,[esi+eax+1] + mov al,[base_code] + mov [ebx],al + jmp instruction_assembled +extrn_directive: + mov al,[output_format] + cmp al,4 + je extrn_allowed + cmp al,5 + jne illegal_instruction + bt [format_flags],0 + jc illegal_instruction + extrn_allowed: + lods word [esi] + cmp ax,'(' + jne invalid_argument + mov ebx,esi + lods dword [esi] + lea esi,[esi+eax+1] + mov edx,[free_additional_memory] + lea eax,[edx+0Ch] + cmp eax,[structures_buffer] + jae out_of_memory + mov [free_additional_memory],eax + mov byte [edx],80h + mov [edx+4],ebx + lods byte [esi] + cmp al,86h + jne invalid_argument + lods byte [esi] + cmp al,2 + jne invalid_argument + lods dword [esi] + cmp eax,0Fh + jb invalid_use_of_symbol + je reserved_word_used_as_symbol + inc esi + mov ebx,eax + xor ah,ah + lods byte [esi] + cmp al,':' + je get_extrn_size + dec esi + cmp al,11h + jne extrn_size_ok + get_extrn_size: + lods word [esi] + cmp al,11h + jne invalid_argument + extrn_size_ok: + mov [address_symbol],edx + mov [label_size],ah + movzx ecx,ah + mov [edx+8],ecx + xor eax,eax + xor edx,edx + xor ebp,ebp + mov [address_sign],0 + mov ch,2 + test [format_flags],8 + jz make_free_label + mov ch,4 + jmp make_free_label +mark_relocation: + cmp [value_type],0 + je relocation_ok + mov ebp,[addressing_space] + test byte [ds:ebp+0Ah],1 + jnz relocation_ok + cmp [output_format],2 + je mark_mz_relocation + cmp [output_format],3 + je mark_pe_relocation + cmp [output_format],4 + je mark_coff_relocation + cmp [output_format],5 + je mark_elf_relocation + relocation_ok: + ret +close_pass: + mov al,[output_format] + cmp al,3 + je close_pe + cmp al,4 + je close_coff + cmp al,5 + je close_elf + ret + +format_mz: + mov edx,[additional_memory] + push edi + mov edi,edx + mov ecx,1Ch shr 2 + xor eax,eax + rep stos dword [edi] + mov [free_additional_memory],edi + pop edi + mov word [edx+0Ch],0FFFFh + mov word [edx+10h],1000h + mov [code_type],16 + jmp format_defined +mark_mz_relocation: + push eax ebx + inc word [number_of_relocations] + jz format_limitations_exceeded + mov ebx,[free_additional_memory] + mov eax,edi + sub eax,[code_start] + mov [ebx],ax + shr eax,16 + shl ax,12 + mov [ebx+2],ax + cmp word [ebx],0FFFFh + jne mz_relocation_ok + inc word [ebx+2] + sub word [ebx],10h + mz_relocation_ok: + add ebx,4 + cmp ebx,[structures_buffer] + jae out_of_memory + mov [free_additional_memory],ebx + pop ebx eax + ret +mz_segment: + lods byte [esi] + cmp al,2 + jne invalid_argument + lods dword [esi] + cmp eax,0Fh + jb invalid_use_of_symbol + je reserved_word_used_as_symbol + inc esi + mov ebx,eax + mov eax,edi + sub eax,[code_start] + mov ecx,0Fh + add eax,0Fh + and eax,1111b + sub ecx,eax + mov edx,edi + xor eax,eax + rep stos byte [edi] + mov eax,edx + call undefined_data + push ebx + call create_addressing_space + pop ebx + mov eax,edi + sub eax,[code_start] + shr eax,4 + cmp eax,10000h + jae value_out_of_range + mov edx,eax + mov al,16 + cmp byte [esi],13h + jne segment_type_ok + inc esi + lods byte [esi] + segment_type_ok: + mov [code_type],al + mov eax,edx + mov ch,1 + mov [address_sign],0 + xor edx,edx + xor ebp,ebp + mov [label_size],0 + mov [address_symbol],edx + jmp make_free_label +mz_entry: + lods byte [esi] + cmp al,'(' + jne invalid_argument + call get_word_value + cmp [value_type],1 + je initial_cs_ok + call recoverable_invalid_address + initial_cs_ok: + mov edx,[additional_memory] + mov [edx+16h],ax + lods byte [esi] + cmp al,':' + jne invalid_argument + lods byte [esi] + cmp al,'(' + jne invalid_argument + ja invalid_address + call get_word_value + cmp [value_type],0 + jne invalid_use_of_symbol + mov edx,[additional_memory] + mov [edx+14h],ax + jmp instruction_assembled + recoverable_invalid_address: + cmp [error_line],0 + jne ignore_invalid_address + push [current_line] + pop [error_line] + mov [error],invalid_address + ignore_invalid_address: + ret +mz_stack: + lods byte [esi] + cmp al,'(' + jne invalid_argument + call get_word_value + cmp byte [esi],':' + je stack_pointer + cmp ax,10h + jb invalid_value + cmp [value_type],0 + jne invalid_use_of_symbol + mov edx,[additional_memory] + mov [edx+10h],ax + jmp instruction_assembled + stack_pointer: + cmp [value_type],1 + je initial_ss_ok + call recoverable_invalid_address + initial_ss_ok: + mov edx,[additional_memory] + mov [edx+0Eh],ax + lods byte [esi] + cmp al,':' + jne invalid_argument + lods byte [esi] + cmp al,'(' + jne invalid_argument + call get_word_value + cmp [value_type],0 + jne invalid_use_of_symbol + mov edx,[additional_memory] + mov [edx+10h],ax + bts [format_flags],4 + jmp instruction_assembled +mz_heap: + cmp [output_format],2 + jne illegal_instruction + lods byte [esi] + call get_size_operator + cmp ah,1 + je invalid_value + cmp ah,2 + ja invalid_value + cmp al,'(' + jne invalid_argument + call get_word_value + cmp [value_type],0 + jne invalid_use_of_symbol + mov edx,[additional_memory] + mov [edx+0Ch],ax + jmp instruction_assembled +write_mz_header: + mov edx,[additional_memory] + bt [format_flags],4 + jc mz_stack_ok + mov eax,[real_code_size] + dec eax + shr eax,4 + inc eax + mov [edx+0Eh],ax + shl eax,4 + movzx ecx,word [edx+10h] + add eax,ecx + mov [real_code_size],eax + mz_stack_ok: + mov edi,[free_additional_memory] + mov eax,[number_of_relocations] + shl eax,2 + add eax,1Ch + sub edi,eax + xchg edi,[free_additional_memory] + mov ecx,0Fh + add eax,0Fh + and eax,1111b + sub ecx,eax + xor al,al + rep stos byte [edi] + sub edi,[free_additional_memory] + mov ecx,edi + shr edi,4 + mov word [edx],'MZ' ; signature + mov [edx+8],di ; header size in paragraphs + mov eax,[number_of_relocations] + mov [edx+6],ax ; number of relocation entries + mov eax,[code_size] + add eax,ecx + mov esi,eax + shr esi,9 + and eax,1FFh + inc si + or ax,ax + jnz mz_size_ok + dec si + mz_size_ok: + mov [edx+2],ax ; number of bytes in last page + mov [edx+4],si ; number of pages + mov eax,[real_code_size] + dec eax + shr eax,4 + inc eax + mov esi,[code_size] + dec esi + shr esi,4 + inc esi + sub eax,esi + mov [edx+0Ah],ax ; minimum memory in addition to code + add [edx+0Ch],ax ; maximum memory in addition to code + salc + mov ah,al + or [edx+0Ch],ax + mov word [edx+18h],1Ch ; offset of relocation table + add [written_size],ecx + call write + jc write_failed + ret + +make_stub: + mov [stub_file],edx + or edx,edx + jnz stub_from_file + push esi + mov edx,edi + xor eax,eax + mov ecx,20h + rep stos dword [edi] + mov eax,40h+default_stub_end-default_stub + mov cx,100h+default_stub_end-default_stub + mov word [edx],'MZ' + mov byte [edx+4],1 + mov word [edx+2],ax + mov byte [edx+8],4 + mov byte [edx+0Ah],10h + mov word [edx+0Ch],0FFFFh + mov word [edx+10h],cx + mov word [edx+3Ch],ax + mov byte [edx+18h],40h + lea edi,[edx+40h] + mov esi,default_stub + mov ecx,default_stub_end-default_stub + rep movs byte [edi],[esi] + pop esi + jmp stub_ok + default_stub: + use16 + push cs + pop ds + mov dx,stub_message-default_stub + mov ah,9 + int 21h + mov ax,4C01h + int 21h + stub_message db 'This program cannot be run in DOS mode.',0Dh,0Ah,24h + rq 1 + default_stub_end: + use32 + stub_from_file: + push esi + mov esi,edx + call open_binary_file + mov edx,edi + mov ecx,1Ch + mov esi,edx + call read + jc binary_stub + cmp word [esi],'MZ' + jne binary_stub + add edi,1Ch + movzx ecx,word [esi+6] + add ecx,11b + and ecx,not 11b + add ecx,(40h-1Ch) shr 2 + lea eax,[edi+ecx*4] + cmp edi,[tagged_blocks] + jae out_of_memory + xor eax,eax + rep stos dword [edi] + mov edx,40h + xchg dx,[esi+18h] + xor al,al + call lseek + movzx ecx,word [esi+6] + shl ecx,2 + lea edx,[esi+40h] + call read + mov edx,edi + sub edx,esi + shr edx,4 + xchg dx,[esi+8] + shl edx,4 + xor al,al + call lseek + movzx ecx,word [esi+4] + dec ecx + js out_of_memory + shl ecx,9 + movzx edx,word [esi+2] + test edx,edx + jnz stub_header_size_ok + mov dx,200h + stub_header_size_ok: + add ecx,edx + mov edx,edi + sub ecx,eax + je read_stub_code + jb stub_code_ok + push ecx + dec ecx + shr ecx,3 + inc ecx + shl ecx,1 + lea eax,[edi+ecx*4] + cmp eax,[tagged_blocks] + jae out_of_memory + xor eax,eax + rep stos dword [edi] + pop ecx + read_stub_code: + call read + stub_code_ok: + call close + mov edx,edi + sub edx,esi + mov ax,dx + and ax,1FFh + mov [esi+2],ax + dec edx + shr edx,9 + inc edx + mov [esi+4],dx + mov eax,edi + sub eax,esi + mov [esi+3Ch],eax + pop esi + stub_ok: + ret + binary_stub: + mov esi,edi + mov ecx,40h shr 2 + xor eax,eax + rep stos dword [edi] + mov al,2 + xor edx,edx + call lseek + push eax + xor al,al + xor edx,edx + call lseek + mov ecx,[esp] + add ecx,40h+111b + and ecx,not 111b + mov ax,cx + and ax,1FFh + mov [esi+2],ax + lea eax,[ecx+1FFh] + shr eax,9 + mov [esi+4],ax + mov [esi+3Ch],ecx + sub ecx,40h + mov eax,10000h + sub eax,ecx + jbe binary_heap_ok + shr eax,4 + mov [esi+0Ah],ax + binary_heap_ok: + mov word [esi],'MZ' + mov byte [esi+8],4 + mov ax,0FFFFh + mov [esi+0Ch],ax + dec ax + mov [esi+10h],ax + sub ax,0Eh + mov [esi+0Eh],ax + mov [esi+16h],ax + mov word [esi+14h],100h + mov byte [esi+18h],40h + mov eax,[tagged_blocks] + sub eax,ecx + cmp edi,eax + jae out_of_memory + mov edx,edi + shr ecx,2 + xor eax,eax + rep stos dword [edi] + pop ecx + call read + call close + pop esi + ret + +format_pe: + xor edx,edx + mov [machine],14Ch + mov [subsystem],3 + mov [subsystem_version],3 + 10 shl 16 + mov [image_base],400000h + and [image_base_high],0 + test [format_flags],8 + jz pe_settings + mov [machine],8664h + mov [subsystem_version],5 + 0 shl 16 + pe_settings: + cmp byte [esi],84h + je get_stub_name + cmp byte [esi],80h + je get_pe_base + cmp byte [esi],1Bh + jne pe_settings_ok + lods byte [esi] + lods byte [esi] + test al,80h+40h + jz subsystem_setting + cmp al,80h + je dll_flag + cmp al,81h + je wdm_flag + cmp al,82h + je large_flag + cmp al,83h + je nx_flag + jmp pe_settings + dll_flag: + bts [format_flags],8 + jc setting_already_specified + jmp pe_settings + wdm_flag: + bts [format_flags],9 + jc setting_already_specified + jmp pe_settings + large_flag: + bts [format_flags],11 + jc setting_already_specified + test [format_flags],8 + jnz invalid_argument + jmp pe_settings + nx_flag: + bts [format_flags],12 + jc setting_already_specified + jmp pe_settings + subsystem_setting: + bts [format_flags],7 + jc setting_already_specified + and ax,3Fh + mov [subsystem],ax + cmp ax,10 + jb subsystem_type_ok + or [format_flags],4 + subsystem_type_ok: + cmp byte [esi],'(' + jne pe_settings + inc esi + cmp byte [esi],'.' + jne invalid_value + inc esi + push edx + cmp byte [esi+11],0 + jne invalid_value + cmp byte [esi+10],2 + ja invalid_value + mov dx,[esi+8] + cmp dx,8000h + je zero_version + mov eax,[esi+4] + cmp dx,7 + jg invalid_value + mov cx,7 + sub cx,dx + mov eax,[esi+4] + shr eax,cl + mov ebx,eax + shr ebx,24 + cmp bl,100 + jae invalid_value + and eax,0FFFFFFh + mov ecx,100 + mul ecx + shrd eax,edx,24 + jnc version_value_ok + inc eax + version_value_ok: + shl eax,16 + mov ax,bx + jmp subsystem_version_ok + zero_version: + xor eax,eax + subsystem_version_ok: + pop edx + add esi,13 + mov [subsystem_version],eax + jmp pe_settings + get_pe_base: + bts [format_flags],10 + jc setting_already_specified + lods word [esi] + cmp ah,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + push edx edi + add edi,[stub_size] + test [format_flags],4 + jnz get_peplus_base + call get_dword_value + mov [image_base],eax + jmp pe_base_ok + get_peplus_base: + call get_qword_value + mov [image_base],eax + mov [image_base_high],edx + pe_base_ok: + pop edi edx + cmp [value_type],0 + jne invalid_use_of_symbol + cmp byte [esi],84h + jne pe_settings_ok + get_stub_name: + lods byte [esi] + lods word [esi] + cmp ax,'(' + jne invalid_argument + lods dword [esi] + mov edx,esi + add esi,eax + inc esi + pe_settings_ok: + mov ebp,[stub_size] + or ebp,ebp + jz make_pe_stub + cmp edx,[stub_file] + je pe_stub_ok + sub edi,[stub_size] + mov [code_start],edi + make_pe_stub: + call make_stub + mov eax,edi + sub eax,[code_start] + mov [stub_size],eax + mov [code_start],edi + mov ebp,eax + pe_stub_ok: + mov edx,edi + mov ecx,18h+0E0h + test [format_flags],4 + jz zero_pe_header + add ecx,10h + zero_pe_header: + add ebp,ecx + shr ecx,2 + xor eax,eax + rep stos dword [edi] + mov word [edx],'PE' ; signature + mov ax,[machine] + mov word [edx+4],ax + mov byte [edx+38h+1],10h ; section alignment + mov byte [edx+3Ch+1],2 ; file alignment + mov byte [edx+40h],1 ; OS version + mov eax,[subsystem_version] + mov [edx+48h],eax + mov ax,[subsystem] + mov [edx+5Ch],ax + cmp ax,1 + jne pe_alignment_ok + mov eax,20h + mov dword [edx+38h],eax + mov dword [edx+3Ch],eax + pe_alignment_ok: + mov word [edx+1Ah],VERSION_MAJOR + VERSION_MINOR shl 8 + test [format_flags],4 + jnz init_peplus_specific + mov byte [edx+14h],0E0h ; size of optional header + mov dword [edx+16h],10B010Fh; flags and magic value + mov eax,[image_base] + mov [edx+34h],eax + mov byte [edx+60h+1],10h ; stack reserve + mov byte [edx+64h+1],10h ; stack commit + mov byte [edx+68h+2],1 ; heap reserve + mov byte [edx+74h],16 ; number of directories + jmp pe_header_ok + init_peplus_specific: + mov byte [edx+14h],0F0h ; size of optional header + mov dword [edx+16h],20B002Fh; flags and magic value + mov eax,[image_base] + mov [edx+30h],eax + mov eax,[image_base_high] + mov [edx+34h],eax + mov byte [edx+60h+1],10h ; stack reserve + mov byte [edx+68h+1],10h ; stack commit + mov byte [edx+70h+2],1 ; heap reserve + mov byte [edx+84h],16 ; number of directories + pe_header_ok: + bsf ecx,[edx+3Ch] + imul ebx,[number_of_sections],28h + or ebx,ebx + jnz reserve_space_for_section_headers + mov ebx,28h + reserve_space_for_section_headers: + add ebx,ebp + dec ebx + shr ebx,cl + inc ebx + shl ebx,cl + sub ebx,ebp + mov ecx,ebx + mov eax,[tagged_blocks] + sub eax,ecx + cmp edi,eax + jae out_of_memory + shr ecx,2 + xor eax,eax + rep stos dword [edi] + mov eax,edi + sub eax,[code_start] + add eax,[stub_size] + mov [edx+54h],eax ; size of headers + mov ecx,[edx+38h] + dec ecx + add eax,ecx + not ecx + and eax,ecx + bt [format_flags],8 + jc pe_entry_init_ok + mov [edx+28h],eax ; entry point rva + pe_entry_init_ok: + and [number_of_sections],0 + movzx ebx,word [edx+14h] + lea ebx,[edx+18h+ebx] + mov [current_section],ebx + mov dword [ebx],'.fla' + mov dword [ebx+4],'t' + mov [ebx+14h],edi + mov [ebx+0Ch],eax + mov dword [ebx+24h],0E0000060h + xor ecx,ecx + xor bl,bl + not eax + not ecx + not bl + add eax,1 + adc ecx,0 + adc bl,0 + add eax,edi + adc ecx,0 + adc bl,0 + test [format_flags],4 + jnz peplus_org + sub eax,[edx+34h] + sbb ecx,0 + sbb bl,0 + jmp pe_org_ok + peplus_org: + sub eax,[edx+30h] + sbb ecx,[edx+34h] + sbb bl,0 + pe_org_ok: + test [format_flags],8 + jnz pe64_code + mov bh,2 + mov [code_type],32 + jmp pe_code_type_ok + pe64_code: + mov bh,4 + mov [code_type],64 + pe_code_type_ok: + bt [resolver_flags],0 + jc pe_labels_type_ok + xor bh,bh + pe_labels_type_ok: + push eax ebx + call init_addressing_space + mov ebp,ebx + pop ebx eax + mov [ds:ebp],eax + mov [ds:ebp+4],ecx + mov [ds:ebp+8],bx + mov [ds:ebp+18h],edi + bt [format_flags],8 + jnc dll_flag_ok + or byte [edx+16h+1],20h + dll_flag_ok: + bt [format_flags],9 + jnc wdm_flag_ok + or byte [edx+5Eh+1],20h + wdm_flag_ok: + bt [format_flags],11 + jnc large_flag_ok + or byte [edx+16h],20h + large_flag_ok: + bt [format_flags],12 + jnc nx_ok + or byte [edx+5Eh+1],1 + nx_ok: + jmp format_defined +pe_section: + call close_pe_section + push eax ebx + call create_addressing_space + mov ebp,ebx + pop ebx eax + bts [format_flags],5 + lea ecx,[ebx+28h] + add edx,[edx+54h] + sub edx,[stub_size] + cmp ecx,edx + jbe new_section + lea ebx,[edx-28h] + or [next_pass_needed],-1 + push edi + mov edi,ebx + mov ecx,28h shr 4 + xor eax,eax + rep stos dword [edi] + pop edi + new_section: + mov [ebx+0Ch],eax + lods word [esi] + cmp ax,'(' + jne invalid_argument + lea edx,[esi+4] + mov ecx,[esi] + lea esi,[esi+4+ecx+1] + cmp ecx,8 + ja name_too_long + xor eax,eax + mov [ebx],eax + mov [ebx+4],eax + push esi edi + mov edi,ebx + mov esi,edx + rep movs byte [edi],[esi] + pop edi esi + and dword [ebx+24h],0 + mov [ebx+14h],edi + mov edx,[code_start] + mov eax,edi + xor ecx,ecx + sub eax,[ebx+0Ch] + sbb ecx,0 + sbb byte [ds:ebp+8],0 + mov byte [ds:ebp+9],2 + mov [code_type],32 + test [format_flags],8 + jz pe_section_code_type_ok + mov byte [ds:ebp+9],4 + mov [code_type],64 + pe_section_code_type_ok: + test [format_flags],4 + jnz peplus_section_org + sub eax,[edx+34h] + sbb ecx,0 + sbb byte [ds:ebp+8],0 + bt [resolver_flags],0 + jc pe_section_org_ok + mov byte [ds:ebp+9],0 + jmp pe_section_org_ok + peplus_section_org: + sub eax,[edx+30h] + sbb ecx,[edx+34h] + sbb byte [ds:ebp+8],0 + bt [resolver_flags],0 + jc pe_section_org_ok + mov byte [ds:ebp+9],0 + pe_section_org_ok: + mov [ds:ebp],eax + mov [ds:ebp+4],ecx + mov [ds:ebp+18h],edi + get_section_flags: + lods byte [esi] + cmp al,1Ah + je set_directory + cmp al,19h + je section_flag + dec esi + jmp instruction_assembled + set_directory: + movzx eax,byte [esi] + inc esi + mov ecx,ebx + test [format_flags],4 + jnz peplus_directory + xchg ecx,[edx+78h+eax*8] + mov dword [edx+78h+eax*8+4],-1 + jmp pe_directory_set + peplus_directory: + xchg ecx,[edx+88h+eax*8] + mov dword [edx+88h+eax*8+4],-1 + pe_directory_set: + or ecx,ecx + jnz data_already_defined + push ebx edx + call generate_pe_data + pop edx ebx + jmp get_section_flags + section_flag: + lods byte [esi] + cmp al,9 + je invalid_argument + cmp al,11 + je invalid_argument + mov cl,al + mov eax,1 + shl eax,cl + test dword [ebx+24h],eax + jnz setting_already_specified + or dword [ebx+24h],eax + jmp get_section_flags + close_pe_section: + mov ebx,[current_section] + mov edx,[code_start] + mov eax,edi + sub eax,[ebx+14h] + jnz finish_section + bt [format_flags],5 + jc finish_section + mov eax,[ebx+0Ch] + ret + finish_section: + mov [ebx+8],eax + cmp edi,[undefined_data_end] + jne align_section + cmp dword [edx+38h],1000h + jb align_section + mov edi,[undefined_data_start] + align_section: + and [undefined_data_end],0 + mov ebp,edi + sub ebp,[ebx+14h] + mov ecx,[edx+3Ch] + dec ecx + lea eax,[ebp+ecx] + not ecx + and eax,ecx + mov [ebx+10h],eax + sub eax,ebp + mov ecx,eax + xor al,al + rep stos byte [edi] + mov eax,[code_start] + sub eax,[stub_size] + sub [ebx+14h],eax + mov ecx,[ebx+10h] + test byte [ebx+24h],20h + jz pe_code_sum_ok + add [edx+1Ch],ecx + cmp dword [edx+2Ch],0 + jne pe_code_sum_ok + mov eax,[ebx+0Ch] + mov [edx+2Ch],eax + pe_code_sum_ok: + test byte [ebx+24h],40h + jz pe_data_sum_ok + add [edx+20h],ecx + test [format_flags],4 + jnz pe_data_sum_ok + cmp dword [edx+30h],0 + jne pe_data_sum_ok + mov eax,[ebx+0Ch] + mov [edx+30h],eax + pe_data_sum_ok: + mov eax,[ebx+8] + or eax,eax + jz udata_ok + cmp dword [ebx+10h],0 + jne udata_ok + or byte [ebx+24h],80h + add [edx+24h],ecx + udata_ok: + mov ecx,[edx+38h] + dec ecx + add eax,ecx + not ecx + and eax,ecx + add eax,[ebx+0Ch] + add ebx,28h + mov [current_section],ebx + inc word [number_of_sections] + jz format_limitations_exceeded + ret +data_directive: + cmp [output_format],3 + jne illegal_instruction + lods byte [esi] + cmp al,1Ah + je predefined_data_type + cmp al,'(' + jne invalid_argument + call get_byte_value + cmp al,16 + jb data_type_ok + jmp invalid_value + predefined_data_type: + movzx eax,byte [esi] + inc esi + data_type_ok: + mov ebx,[current_section] + mov ecx,edi + sub ecx,[ebx+14h] + add ecx,[ebx+0Ch] + mov edx,[code_start] + test [format_flags],4 + jnz peplus_data + xchg ecx,[edx+78h+eax*8] + jmp init_pe_data + peplus_data: + xchg ecx,[edx+88h+eax*8] + init_pe_data: + or ecx,ecx + jnz data_already_defined + call allocate_structure_data + mov word [ebx],data_directive-instruction_handler + mov [ebx+2],al + mov edx,[current_line] + mov [ebx+4],edx + call generate_pe_data + jmp instruction_assembled + end_data: + cmp [output_format],3 + jne illegal_instruction + call find_structure_data + jc unexpected_instruction + movzx eax,byte [ebx+2] + mov edx,[current_section] + mov ecx,edi + sub ecx,[edx+14h] + add ecx,[edx+0Ch] + mov edx,[code_start] + test [format_flags],4 + jnz end_peplus_data + sub ecx,[edx+78h+eax*8] + mov [edx+78h+eax*8+4],ecx + jmp remove_structure_data + end_peplus_data: + sub ecx,[edx+88h+eax*8] + mov [edx+88h+eax*8+4],ecx + jmp remove_structure_data +pe_entry: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + test [format_flags],8 + jnz pe64_entry + call get_dword_value + mov bl,2 + bt [resolver_flags],0 + jc check_pe_entry_label_type + xor bl,bl + check_pe_entry_label_type: + cmp [value_type],bl + je pe_entry_ok + call recoverable_invalid_address + pe_entry_ok: + cdq + test [format_flags],4 + jnz pe64_entry_type_ok + mov edx,[code_start] + sub eax,[edx+34h] + mov [edx+28h],eax + jmp instruction_assembled + pe64_entry: + call get_qword_value + mov bl,4 + bt [resolver_flags],0 + jc check_pe64_entry_label_type + xor bl,bl + check_pe64_entry_label_type: + cmp [value_type],bl + je pe64_entry_type_ok + call recoverable_invalid_address + pe64_entry_type_ok: + mov ecx,[code_start] + sub eax,[ecx+30h] + sbb edx,[ecx+34h] + jz pe64_entry_range_ok + call recoverable_overflow + pe64_entry_range_ok: + mov [ecx+28h],eax + jmp instruction_assembled +pe_stack: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + test [format_flags],4 + jnz peplus_stack + call get_count_value + mov edx,[code_start] + mov [edx+60h],eax + cmp byte [esi],',' + jne default_stack_commit + lods byte [esi] + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_count_value + mov edx,[code_start] + mov [edx+64h],eax + cmp eax,[edx+60h] + ja value_out_of_range + jmp instruction_assembled + default_stack_commit: + mov dword [edx+64h],1000h + mov eax,[edx+60h] + cmp eax,1000h + ja instruction_assembled + mov dword [edx+64h],eax + jmp instruction_assembled + peplus_stack: + call get_qword_value + cmp [value_type],0 + jne invalid_use_of_symbol + mov ecx,[code_start] + mov [ecx+60h],eax + mov [ecx+64h],edx + cmp byte [esi],',' + jne default_peplus_stack_commit + lods byte [esi] + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_qword_value + cmp [value_type],0 + jne invalid_use_of_symbol + mov ecx,[code_start] + mov [ecx+68h],eax + mov [ecx+6Ch],edx + cmp edx,[ecx+64h] + ja value_out_of_range + jb instruction_assembled + cmp eax,[ecx+60h] + ja value_out_of_range + jmp instruction_assembled + default_peplus_stack_commit: + mov dword [ecx+68h],1000h + cmp dword [ecx+64h],0 + jne instruction_assembled + mov eax,[ecx+60h] + cmp eax,1000h + ja instruction_assembled + mov dword [ecx+68h],eax + jmp instruction_assembled +pe_heap: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + test [format_flags],4 + jnz peplus_heap + call get_count_value + mov edx,[code_start] + mov [edx+68h],eax + cmp byte [esi],',' + jne instruction_assembled + lods byte [esi] + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_count_value + mov edx,[code_start] + mov [edx+6Ch],eax + cmp eax,[edx+68h] + ja value_out_of_range + jmp instruction_assembled + peplus_heap: + call get_qword_value + cmp [value_type],0 + jne invalid_use_of_symbol + mov ecx,[code_start] + mov [ecx+70h],eax + mov [ecx+74h],edx + cmp byte [esi],',' + jne instruction_assembled + lods byte [esi] + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + call get_qword_value + cmp [value_type],0 + jne invalid_use_of_symbol + mov ecx,[code_start] + mov [ecx+78h],eax + mov [ecx+7Ch],edx + cmp edx,[ecx+74h] + ja value_out_of_range + jb instruction_assembled + cmp eax,[ecx+70h] + ja value_out_of_range + jmp instruction_assembled +mark_pe_relocation: + push eax ebx + test [format_flags],4 + jz check_standard_pe_relocation_type + cmp [value_type],4 + je pe_relocation_type_ok + check_standard_pe_relocation_type: + cmp [value_type],2 + je pe_relocation_type_ok + call recoverable_misuse + pe_relocation_type_ok: + mov ebx,[current_section] + mov eax,edi + sub eax,[ebx+14h] + add eax,[ebx+0Ch] + mov ebx,[free_additional_memory] + inc [number_of_relocations] + add ebx,5 + cmp ebx,[structures_buffer] + jae out_of_memory + mov [free_additional_memory],ebx + mov [ebx-5],eax + cmp [value_type],2 + je fixup_32bit + mov byte [ebx-1],0Ah + jmp fixup_ok + fixup_32bit: + mov byte [ebx-1],3 + fixup_ok: + pop ebx eax + ret +generate_pe_data: + cmp al,2 + je make_pe_resource + cmp al,5 + je make_pe_fixups + ret +make_pe_fixups: + mov edx,[code_start] + and byte [edx+16h],not 1 + or byte [edx+5Eh],40h + bts [resolver_flags],0 + jc fixups_ready + or [next_pass_needed],-1 + fixups_ready: + and [last_fixup_base],0 + call make_fixups + xchg eax,[actual_fixups_size] + sub eax,[actual_fixups_size] + ja reserve_forward_fixups + xor eax,eax + reserve_forward_fixups: + mov [reserved_fixups],edi + add edi,eax + mov [reserved_fixups_size],eax + ret + make_fixups: + push esi + xor ecx,ecx + xchg ecx,[number_of_relocations] + mov esi,[free_additional_memory] + lea eax,[ecx*5] + sub esi,eax + mov [free_additional_memory],esi + mov edx,[last_fixup_base] + mov ebx,[last_fixup_header] + mov ebp,edi + jecxz fixups_done + make_fixup: + cmp [esi],edx + jb store_fixup + mov eax,edi + sub eax,ebp + test eax,11b + jz fixups_block + xor ax,ax + stos word [edi] + add dword [ebx],2 + fixups_block: + mov eax,edx + add edx,1000h + cmp [esi],edx + jae fixups_block + stos dword [edi] + mov ebx,edi + mov eax,8 + stos dword [edi] + store_fixup: + add dword [ebx],2 + mov ah,[esi+1] + and ah,0Fh + mov al,[esi+4] + shl al,4 + or ah,al + mov al,[esi] + stos word [edi] + add esi,5 + loop make_fixup + fixups_done: + mov [last_fixup_base],edx + mov [last_fixup_header],ebx + pop esi + mov eax,edi + sub eax,ebp + ret +make_pe_resource: + cmp byte [esi],82h + jne resource_done + inc esi + lods word [esi] + cmp ax,'(' + jne invalid_argument + lods dword [esi] + mov edx,esi + lea esi,[esi+eax+1] + cmp [next_pass_needed],0 + je resource_from_file + cmp [current_pass],0 + jne reserve_space_for_resource + and [resource_size],0 + reserve_space_for_resource: + add edi,[resource_size] + cmp edi,[tagged_blocks] + ja out_of_memory + jmp resource_done + resource_from_file: + push esi + mov esi,edx + call open_binary_file + push ebx + mov esi,[free_additional_memory] + lea eax,[esi+20h] + cmp eax,[structures_buffer] + ja out_of_memory + mov edx,esi + mov ecx,20h + call read + jc invalid_file_format + xor eax,eax + cmp [esi],eax + jne invalid_file_format + mov ax,0FFFFh + cmp [esi+8],eax + jne invalid_file_format + cmp [esi+12],eax + jne invalid_file_format + mov eax,20h + cmp [esi+4],eax + jne invalid_file_format + read_resource_headers: + test eax,11b + jz resource_file_alignment_ok + mov edx,4 + and eax,11b + sub edx,eax + mov al,1 + call lseek + jc resource_headers_ok + resource_file_alignment_ok: + mov [esi],eax + lea edx,[esi+12] + mov ecx,8 + call read + jc resource_headers_ok + mov ecx,[esi+16] + add [esi],ecx + lea edx,[esi+20] + sub ecx,8 + mov [esi+16],ecx + lea eax,[edx+ecx] + cmp eax,[structures_buffer] + ja out_of_memory + call read + jc invalid_file_format + mov edx,[esi] + add edx,[esi+12] + mov eax,[esi+16] + lea ecx,[esi+20] + lea esi,[ecx+eax] + add ecx,2 + cmp word [ecx-2],0FFFFh + je resource_header_type_ok + check_resource_header_type: + cmp ecx,esi + jae invalid_file_format + cmp word [ecx],0 + je resource_header_type_ok + add ecx,2 + jmp check_resource_header_type + resource_header_type_ok: + add ecx,2 + cmp word [ecx],0FFFFh + je resource_header_name_ok + check_resource_header_name: + cmp ecx,esi + jae invalid_file_format + cmp word [ecx],0 + je resource_header_name_ok + add ecx,2 + jmp check_resource_header_name + resource_header_name_ok: + xor al,al + call lseek + jnc read_resource_headers + resource_headers_ok: + cmp esi,[free_additional_memory] + je invalid_file_format + xor eax,eax + mov [esi],eax + mov [resource_data],edi + lea eax,[edi+16] + cmp eax,[tagged_blocks] + jae out_of_memory + xor eax,eax + stos dword [edi] + call make_timestamp + stos dword [edi] + xor eax,eax + stos dword [edi] + stos dword [edi] + xor ebx,ebx + make_type_name_directory: + mov esi,[free_additional_memory] + xor edx,edx + find_type_name: + cmp dword [esi],0 + je type_name_ok + add esi,20 + cmp word [esi],0FFFFh + je check_next_type_name + or ebx,ebx + jz check_this_type_name + xor ecx,ecx + compare_with_previous_type_name: + mov ax,[esi+ecx] + cmp ax,[ebx+ecx] + ja check_this_type_name + jb check_next_type_name + add ecx,2 + mov ax,[esi+ecx] + or ax,[ebx+ecx] + jnz compare_with_previous_type_name + jmp check_next_type_name + check_this_type_name: + or edx,edx + jz type_name_found + xor ecx,ecx + compare_with_current_type_name: + mov ax,[esi+ecx] + cmp ax,[edx+ecx] + ja check_next_type_name + jb type_name_found + add ecx,2 + mov ax,[esi+ecx] + or ax,[edx+ecx] + jnz compare_with_current_type_name + jmp same_type_name + type_name_found: + mov edx,esi + same_type_name: + mov [esi-16],edi + check_next_type_name: + mov eax,[esi-4] + add esi,eax + jmp find_type_name + type_name_ok: + or edx,edx + jz type_name_directory_done + mov ebx,edx + make_type_name_entry: + mov eax,[resource_data] + inc word [eax+12] + lea eax,[edi+8] + cmp eax,[tagged_blocks] + jae out_of_memory + mov eax,ebx + stos dword [edi] + xor eax,eax + stos dword [edi] + jmp make_type_name_directory + type_name_directory_done: + mov ebx,-1 + make_type_id_directory: + mov esi,[free_additional_memory] + mov edx,10000h + find_type_id: + cmp dword [esi],0 + je type_id_ok + add esi,20 + cmp word [esi],0FFFFh + jne check_next_type_id + movzx eax,word [esi+2] + cmp eax,ebx + jle check_next_type_id + cmp eax,edx + jg check_next_type_id + mov edx,eax + mov [esi-16],edi + check_next_type_id: + mov eax,[esi-4] + add esi,eax + jmp find_type_id + type_id_ok: + cmp edx,10000h + je type_id_directory_done + mov ebx,edx + make_type_id_entry: + mov eax,[resource_data] + inc word [eax+14] + lea eax,[edi+8] + cmp eax,[tagged_blocks] + jae out_of_memory + mov eax,ebx + stos dword [edi] + xor eax,eax + stos dword [edi] + jmp make_type_id_directory + type_id_directory_done: + mov esi,[resource_data] + add esi,10h + mov ecx,[esi-4] + or cx,cx + jz resource_directories_ok + make_resource_directories: + push ecx + push edi + mov edx,edi + sub edx,[resource_data] + bts edx,31 + mov [esi+4],edx + lea eax,[edi+16] + cmp eax,[tagged_blocks] + jae out_of_memory + xor eax,eax + stos dword [edi] + call make_timestamp + stos dword [edi] + xor eax,eax + stos dword [edi] + stos dword [edi] + mov ebp,esi + xor ebx,ebx + make_resource_name_directory: + mov esi,[free_additional_memory] + xor edx,edx + find_resource_name: + cmp dword [esi],0 + je resource_name_ok + push esi + cmp [esi+4],ebp + jne check_next_resource_name + add esi,20 + call skip_resource_name + cmp word [esi],0FFFFh + je check_next_resource_name + or ebx,ebx + jz check_this_resource_name + xor ecx,ecx + compare_with_previous_resource_name: + mov ax,[esi+ecx] + cmp ax,[ebx+ecx] + ja check_this_resource_name + jb check_next_resource_name + add ecx,2 + mov ax,[esi+ecx] + or ax,[ebx+ecx] + jnz compare_with_previous_resource_name + jmp check_next_resource_name + skip_resource_name: + cmp word [esi],0FFFFh + jne skip_unicode_string + add esi,4 + ret + skip_unicode_string: + add esi,2 + cmp word [esi-2],0 + jne skip_unicode_string + ret + check_this_resource_name: + or edx,edx + jz resource_name_found + xor ecx,ecx + compare_with_current_resource_name: + mov ax,[esi+ecx] + cmp ax,[edx+ecx] + ja check_next_resource_name + jb resource_name_found + add ecx,2 + mov ax,[esi+ecx] + or ax,[edx+ecx] + jnz compare_with_current_resource_name + jmp same_resource_name + resource_name_found: + mov edx,esi + same_resource_name: + mov eax,[esp] + mov [eax+8],edi + check_next_resource_name: + pop esi + mov eax,[esi+16] + lea esi,[esi+20+eax] + jmp find_resource_name + resource_name_ok: + or edx,edx + jz resource_name_directory_done + mov ebx,edx + make_resource_name_entry: + mov eax,[esp] + inc word [eax+12] + lea eax,[edi+8] + cmp eax,[tagged_blocks] + jae out_of_memory + mov eax,ebx + stos dword [edi] + xor eax,eax + stos dword [edi] + jmp make_resource_name_directory + resource_name_directory_done: + mov ebx,-1 + make_resource_id_directory: + mov esi,[free_additional_memory] + mov edx,10000h + find_resource_id: + cmp dword [esi],0 + je resource_id_ok + push esi + cmp [esi+4],ebp + jne check_next_resource_id + add esi,20 + call skip_resource_name + cmp word [esi],0FFFFh + jne check_next_resource_id + movzx eax,word [esi+2] + cmp eax,ebx + jle check_next_resource_id + cmp eax,edx + jg check_next_resource_id + mov edx,eax + mov eax,[esp] + mov [eax+8],edi + check_next_resource_id: + pop esi + mov eax,[esi+16] + lea esi,[esi+20+eax] + jmp find_resource_id + resource_id_ok: + cmp edx,10000h + je resource_id_directory_done + mov ebx,edx + make_resource_id_entry: + mov eax,[esp] + inc word [eax+14] + lea eax,[edi+8] + cmp eax,[tagged_blocks] + jae out_of_memory + mov eax,ebx + stos dword [edi] + xor eax,eax + stos dword [edi] + jmp make_resource_id_directory + resource_id_directory_done: + pop eax + mov esi,ebp + pop ecx + add esi,8 + dec cx + jnz make_resource_directories + resource_directories_ok: + shr ecx,16 + jnz make_resource_directories + mov esi,[resource_data] + add esi,10h + movzx eax,word [esi-4] + movzx edx,word [esi-2] + add eax,edx + lea esi,[esi+eax*8] + push edi ; address of language directories + update_resource_directories: + cmp esi,[esp] + je resource_directories_updated + add esi,10h + mov ecx,[esi-4] + or cx,cx + jz language_directories_ok + make_language_directories: + push ecx + push edi + mov edx,edi + sub edx,[resource_data] + bts edx,31 + mov [esi+4],edx + lea eax,[edi+16] + cmp eax,[tagged_blocks] + jae out_of_memory + xor eax,eax + stos dword [edi] + call make_timestamp + stos dword [edi] + xor eax,eax + stos dword [edi] + stos dword [edi] + mov ebp,esi + mov ebx,-1 + make_language_id_directory: + mov esi,[free_additional_memory] + mov edx,10000h + find_language_id: + cmp dword [esi],0 + je language_id_ok + push esi + cmp [esi+8],ebp + jne check_next_language_id + add esi,20 + mov eax,esi + call skip_resource_name + call skip_resource_name + neg eax + add eax,esi + and eax,11b + add esi,eax + get_language_id: + movzx eax,word [esi+6] + cmp eax,ebx + jle check_next_language_id + cmp eax,edx + jge check_next_language_id + mov edx,eax + mov eax,[esp] + mov dword [value],eax + check_next_language_id: + pop esi + mov eax,[esi+16] + lea esi,[esi+20+eax] + jmp find_language_id + language_id_ok: + cmp edx,10000h + je language_id_directory_done + mov ebx,edx + make_language_id_entry: + mov eax,[esp] + inc word [eax+14] + lea eax,[edi+8] + cmp eax,[tagged_blocks] + jae out_of_memory + mov eax,ebx + stos dword [edi] + mov eax,dword [value] + stos dword [edi] + jmp make_language_id_directory + language_id_directory_done: + pop eax + mov esi,ebp + pop ecx + add esi,8 + dec cx + jnz make_language_directories + language_directories_ok: + shr ecx,16 + jnz make_language_directories + jmp update_resource_directories + resource_directories_updated: + mov esi,[resource_data] + push edi + make_name_strings: + add esi,10h + movzx eax,word [esi-2] + movzx ecx,word [esi-4] + add eax,ecx + lea eax,[esi+eax*8] + push eax + or ecx,ecx + jz string_entries_processed + process_string_entries: + push ecx + mov edx,edi + sub edx,[resource_data] + bts edx,31 + xchg [esi],edx + mov ebx,edi + xor ax,ax + stos word [edi] + copy_string_data: + lea eax,[edi+2] + cmp eax,[tagged_blocks] + jae out_of_memory + mov ax,[edx] + or ax,ax + jz string_data_copied + stos word [edi] + inc word [ebx] + add edx,2 + jmp copy_string_data + string_data_copied: + add esi,8 + pop ecx + loop process_string_entries + string_entries_processed: + pop esi + cmp esi,[esp] + jb make_name_strings + mov eax,edi + sub eax,[resource_data] + test al,11b + jz resource_strings_alignment_ok + xor ax,ax + stos word [edi] + resource_strings_alignment_ok: + pop edx + pop ebx ; address of language directories + mov ebp,edi + update_language_directories: + add ebx,10h + movzx eax,word [ebx-2] + movzx ecx,word [ebx-4] + add ecx,eax + make_data_records: + push ecx + mov esi,edi + sub esi,[resource_data] + xchg esi,[ebx+4] + lea eax,[edi+16] + cmp eax,[tagged_blocks] + jae out_of_memory + mov eax,esi + stos dword [edi] + mov eax,[esi+12] + stos dword [edi] + xor eax,eax + stos dword [edi] + stos dword [edi] + pop ecx + add ebx,8 + loop make_data_records + cmp ebx,edx + jb update_language_directories + pop ebx ; file handle + mov esi,ebp + mov ebp,edi + update_data_records: + push ebp + mov ecx,edi + mov eax,[current_section] + sub ecx,[eax+14h] + add ecx,[eax+0Ch] + xchg ecx,[esi] + mov edx,[ecx] + xor al,al + call lseek + mov edx,edi + mov ecx,[esi+4] + add edi,ecx + cmp edi,[tagged_blocks] + ja out_of_memory + call read + mov eax,edi + sub eax,[resource_data] + and eax,11b + jz resource_data_alignment_ok + mov ecx,4 + sub ecx,eax + xor al,al + rep stos byte [edi] + resource_data_alignment_ok: + pop ebp + add esi,16 + cmp esi,ebp + jb update_data_records + pop esi + call close + mov eax,edi + sub eax,[resource_data] + mov [resource_size],eax + resource_done: + ret +close_pe: + call close_pe_section + mov edx,[code_start] + mov [edx+50h],eax + call make_timestamp + mov edx,[code_start] + mov [edx+8],eax + mov eax,[number_of_sections] + mov [edx+6],ax + imul eax,28h + movzx ecx,word [edx+14h] + lea eax,[eax+18h+ecx] + add eax,[stub_size] + mov ecx,[edx+3Ch] + dec ecx + add eax,ecx + not ecx + and eax,ecx + cmp eax,[edx+54h] + je pe_sections_ok + or [next_pass_needed],-1 + pe_sections_ok: + xor ecx,ecx + add edx,78h + test [format_flags],4 + jz process_directories + add edx,10h + process_directories: + mov eax,[edx+ecx*8] + or eax,eax + jz directory_ok + cmp dword [edx+ecx*8+4],-1 + jne directory_ok + section_data: + mov ebx,[edx+ecx*8] + mov eax,[ebx+0Ch] + mov [edx+ecx*8],eax ; directory rva + mov eax,[ebx+8] + mov [edx+ecx*8+4],eax ; directory size + directory_ok: + inc cl + cmp cl,10h + jb process_directories + cmp dword [edx+5*8],0 + jne finish_pe_relocations + mov eax,[number_of_relocations] + shl eax,2 + sub [free_additional_memory],eax + btr [resolver_flags],0 + jnc pe_relocations_ok + or [next_pass_needed],-1 + jmp pe_relocations_ok + finish_pe_relocations: + push edi + mov edi,[reserved_fixups] + call make_fixups + pop edi + add [actual_fixups_size],eax + cmp eax,[reserved_fixups_size] + je pe_relocations_ok + or [next_pass_needed],-1 + pe_relocations_ok: + mov ebx,[code_start] + sub ebx,[stub_size] + mov ecx,edi + sub ecx,ebx + mov ebp,ecx + shr ecx,1 + xor eax,eax + cdq + calculate_checksum: + mov dx,[ebx] + add eax,edx + mov dx,ax + shr eax,16 + add eax,edx + add ebx,2 + loop calculate_checksum + add eax,ebp + mov ebx,[code_start] + mov [ebx+58h],eax + ret + +format_coff: + mov eax,[additional_memory] + mov [symbols_stream],eax + mov ebx,eax + add eax,20h + cmp eax,[structures_buffer] + jae out_of_memory + mov [free_additional_memory],eax + xor eax,eax + mov [ebx],al + mov [ebx+4],eax + mov [ebx+8],edi + mov al,4 + mov [ebx+10h],eax + mov al,60h + bt [format_flags],0 + jnc flat_section_flags_ok + or eax,0E0000000h + flat_section_flags_ok: + mov dword [ebx+14h],eax + mov [current_section],ebx + xor eax,eax + mov [number_of_sections],eax + mov edx,ebx + call init_addressing_space + mov [ebx+14h],edx + mov byte [ebx+9],2 + mov [code_type],32 + test [format_flags],8 + jz format_defined + mov byte [ebx+9],4 + mov [code_type],64 + jmp format_defined +coff_section: + call close_coff_section + mov ebx,[free_additional_memory] + lea eax,[ebx+20h] + cmp eax,[structures_buffer] + jae out_of_memory + mov [free_additional_memory],eax + mov [current_section],ebx + inc [number_of_sections] + xor eax,eax + mov [ebx],al + mov [ebx+8],edi + mov [ebx+10h],eax + mov [ebx+14h],eax + mov edx,ebx + call create_addressing_space + xchg edx,ebx + mov [edx+14h],ebx + mov byte [edx+9],2 + test [format_flags],8 + jz coff_labels_type_ok + mov byte [edx+9],4 + coff_labels_type_ok: + lods word [esi] + cmp ax,'(' + jne invalid_argument + mov [ebx+4],esi + mov ecx,[esi] + lea esi,[esi+4+ecx+1] + cmp ecx,8 + ja name_too_long + coff_section_flags: + cmp byte [esi],8Ch + je coff_section_alignment + cmp byte [esi],19h + jne coff_section_settings_ok + inc esi + lods byte [esi] + bt [format_flags],0 + jc coff_section_flag_ok + cmp al,7 + ja invalid_argument + coff_section_flag_ok: + mov cl,al + mov eax,1 + shl eax,cl + test dword [ebx+14h],eax + jnz setting_already_specified + or dword [ebx+14h],eax + jmp coff_section_flags + coff_section_alignment: + bt [format_flags],0 + jnc invalid_argument + inc esi + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + push ebx + call get_count_value + pop ebx + mov edx,eax + dec edx + test eax,edx + jnz invalid_value + or eax,eax + jz invalid_value + cmp eax,2000h + ja invalid_value + bsf edx,eax + inc edx + shl edx,20 + or [ebx+14h],edx + xchg [ebx+10h],eax + or eax,eax + jnz setting_already_specified + jmp coff_section_flags + coff_section_settings_ok: + cmp dword [ebx+10h],0 + jne instruction_assembled + mov dword [ebx+10h],4 + bt [format_flags],0 + jnc instruction_assembled + or dword [ebx+14h],300000h + jmp instruction_assembled + close_coff_section: + mov ebx,[current_section] + mov eax,edi + mov edx,[ebx+8] + sub eax,edx + mov [ebx+0Ch],eax + xor eax,eax + xchg [undefined_data_end],eax + cmp eax,edi + jne coff_section_ok + cmp edx,[undefined_data_start] + jne coff_section_ok + mov edi,edx + or byte [ebx+14h],80h + coff_section_ok: + ret +mark_coff_relocation: + cmp [value_type],3 + je coff_relocation_relative + push ebx eax + test [format_flags],8 + jnz coff_64bit_relocation + mov al,6 + cmp [value_type],2 + je coff_relocation + cmp [value_type],5 + jne invalid_use_of_symbol + inc al + jmp coff_relocation + coff_64bit_relocation: + mov al,1 + cmp [value_type],4 + je coff_relocation + mov al,2 + cmp [value_type],2 + je coff_relocation + cmp [value_type],5 + jne invalid_use_of_symbol + inc al + jmp coff_relocation + coff_relocation_relative: + push ebx + bt [format_flags],0 + jnc relative_ok + mov ebx,[current_section] + mov ebx,[ebx+8] + sub ebx,edi + sub eax,ebx + add eax,4 + relative_ok: + mov ebx,[addressing_space] + push eax + mov al,20 + test [format_flags],8 + jnz relative_coff_64bit_relocation + cmp byte [ebx+9],2 + jne invalid_use_of_symbol + jmp coff_relocation + relative_coff_64bit_relocation: + mov al,4 + cmp byte [ebx+9],4 + jne invalid_use_of_symbol + coff_relocation: + mov ebx,[free_additional_memory] + add ebx,0Ch + cmp ebx,[structures_buffer] + jae out_of_memory + mov [free_additional_memory],ebx + mov byte [ebx-0Ch],al + mov eax,[current_section] + mov eax,[eax+8] + neg eax + add eax,edi + mov [ebx-0Ch+4],eax + mov eax,[symbol_identifier] + mov [ebx-0Ch+8],eax + pop eax ebx + ret +close_coff: + call close_coff_section + cmp [next_pass_needed],0 + je coff_closed + mov eax,[symbols_stream] + mov [free_additional_memory],eax + coff_closed: + ret +coff_formatter: + sub edi,[code_start] + mov [code_size],edi + call prepare_default_section + mov edi,[free_additional_memory] + mov ebx,edi + mov ecx,28h shr 2 + imul ecx,[number_of_sections] + add ecx,14h shr 2 + lea eax,[edi+ecx*4] + cmp eax,[structures_buffer] + jae out_of_memory + xor eax,eax + rep stos dword [edi] + mov word [ebx],14Ch + test [format_flags],8 + jz coff_magic_ok + mov word [ebx],8664h + coff_magic_ok: + mov word [ebx+12h],104h + bt [format_flags],0 + jnc coff_flags_ok + or byte [ebx+12h],80h + coff_flags_ok: + push ebx + call make_timestamp + pop ebx + mov [ebx+4],eax + mov eax,[number_of_sections] + mov [ebx+2],ax + mov esi,[symbols_stream] + xor eax,eax + xor ecx,ecx + enumerate_symbols: + cmp esi,[free_additional_memory] + je symbols_enumerated + mov dl,[esi] + or dl,dl + jz enumerate_section + cmp dl,0C0h + jae enumerate_public + cmp dl,80h + jae enumerate_extrn + add esi,0Ch + jmp enumerate_symbols + enumerate_section: + mov edx,eax + shl edx,8 + mov [esi],edx + inc eax + inc ecx + mov [esi+1Eh],cx + add esi,20h + jmp enumerate_symbols + enumerate_public: + mov edx,eax + shl edx,8 + mov dl,[esi] + mov [esi],edx + mov edx,[esi+8] + add esi,10h + inc eax + cmp byte [edx+11],0 + je enumerate_symbols + mov edx,[edx+20] + cmp byte [edx],0C0h + jae enumerate_symbols + cmp byte [edx],80h + jb enumerate_symbols + inc eax + jmp enumerate_symbols + enumerate_extrn: + mov edx,eax + shl edx,8 + mov dl,[esi] + mov [esi],edx + add esi,0Ch + inc eax + jmp enumerate_symbols + prepare_default_section: + mov ebx,[symbols_stream] + cmp dword [ebx+0Ch],0 + jne default_section_ok + cmp [number_of_sections],0 + je default_section_ok + mov edx,ebx + find_references_to_default_section: + cmp ebx,[free_additional_memory] + jne check_reference + add [symbols_stream],20h + ret + check_reference: + mov al,[ebx] + or al,al + jz skip_other_section + cmp al,0C0h + jae check_public_reference + cmp al,80h + jae next_reference + cmp edx,[ebx+8] + je default_section_ok + next_reference: + add ebx,0Ch + jmp find_references_to_default_section + check_public_reference: + mov eax,[ebx+8] + add ebx,10h + test byte [eax+8],1 + jz find_references_to_default_section + mov cx,[current_pass] + cmp cx,[eax+16] + jne find_references_to_default_section + cmp edx,[eax+20] + je default_section_ok + jmp find_references_to_default_section + skip_other_section: + add ebx,20h + jmp find_references_to_default_section + default_section_ok: + inc [number_of_sections] + ret + symbols_enumerated: + mov [ebx+0Ch],eax + mov ebp,edi + sub ebp,ebx + push ebp + lea edi,[ebx+14h] + mov esi,[symbols_stream] + find_section: + cmp esi,[free_additional_memory] + je sections_finished + mov al,[esi] + or al,al + jz section_found + add esi,0Ch + cmp al,0C0h + jb find_section + add esi,4 + jmp find_section + section_found: + push esi edi + mov esi,[esi+4] + or esi,esi + jz default_section + mov ecx,[esi] + add esi,4 + rep movs byte [edi],[esi] + jmp section_name_ok + default_section: + mov al,'.' + stos byte [edi] + mov eax,'flat' + stos dword [edi] + section_name_ok: + pop edi esi + mov eax,[esi+0Ch] + mov [edi+10h],eax + mov eax,[esi+14h] + mov [edi+24h],eax + test al,80h + jnz section_ptr_ok + mov eax,[esi+8] + sub eax,[code_start] + add eax,ebp + mov [edi+14h],eax + section_ptr_ok: + mov ebx,[code_start] + mov edx,[code_size] + add ebx,edx + add edx,ebp + xor ecx,ecx + add esi,20h + find_relocations: + cmp esi,[free_additional_memory] + je section_relocations_done + mov al,[esi] + or al,al + jz section_relocations_done + cmp al,80h + jb add_relocation + cmp al,0C0h + jb next_relocation + add esi,10h + jmp find_relocations + add_relocation: + lea eax,[ebx+0Ah] + cmp eax,[tagged_blocks] + ja out_of_memory + mov eax,[esi+4] + mov [ebx],eax + mov eax,[esi+8] + mov eax,[eax] + shr eax,8 + mov [ebx+4],eax + movzx ax,byte [esi] + mov [ebx+8],ax + add ebx,0Ah + inc ecx + next_relocation: + add esi,0Ch + jmp find_relocations + section_relocations_done: + cmp ecx,10000h + jb section_relocations_count_16bit + bt [format_flags],0 + jnc format_limitations_exceeded + mov word [edi+20h],0FFFFh + or dword [edi+24h],1000000h + mov [edi+18h],edx + push esi edi + push ecx + lea esi,[ebx-1] + add ebx,0Ah + lea edi,[ebx-1] + imul ecx,0Ah + std + rep movs byte [edi],[esi] + cld + pop ecx + inc esi + inc ecx + mov [esi],ecx + xor eax,eax + mov [esi+4],eax + mov [esi+8],ax + pop edi esi + jmp section_relocations_ok + section_relocations_count_16bit: + mov [edi+20h],cx + jcxz section_relocations_ok + mov [edi+18h],edx + section_relocations_ok: + sub ebx,[code_start] + mov [code_size],ebx + add edi,28h + jmp find_section + sections_finished: + mov edx,[free_additional_memory] + mov ebx,[code_size] + add ebp,ebx + mov [edx+8],ebp + add ebx,[code_start] + mov edi,ebx + mov ecx,[edx+0Ch] + imul ecx,12h shr 1 + xor eax,eax + shr ecx,1 + jnc zero_symbols_table + stos word [edi] + zero_symbols_table: + rep stos dword [edi] + mov edx,edi + stos dword [edi] + mov esi,[symbols_stream] + make_symbols_table: + cmp esi,[free_additional_memory] + je symbols_table_ok + mov al,[esi] + cmp al,0C0h + jae add_public_symbol + cmp al,80h + jae add_extrn_symbol + or al,al + jz add_section_symbol + add esi,0Ch + jmp make_symbols_table + add_section_symbol: + call store_symbol_name + movzx eax,word [esi+1Eh] + mov [ebx+0Ch],ax + mov byte [ebx+10h],3 + add esi,20h + add ebx,12h + jmp make_symbols_table + add_extrn_symbol: + call store_symbol_name + mov byte [ebx+10h],2 + add esi,0Ch + add ebx,12h + jmp make_symbols_table + add_public_symbol: + call store_symbol_name + mov eax,[esi+0Ch] + mov [current_line],eax + mov eax,[esi+8] + test byte [eax+8],1 + jz undefined_coff_public + mov cx,[current_pass] + cmp cx,[eax+16] + jne undefined_coff_public + mov cl,[eax+11] + or cl,cl + jz public_constant + test [format_flags],8 + jnz check_64bit_public_symbol + cmp cl,2 + je public_symbol_type_ok + jmp invalid_use_of_symbol + undefined_coff_public: + mov [error_info],eax + jmp undefined_symbol + check_64bit_public_symbol: + cmp cl,4 + jne invalid_use_of_symbol + public_symbol_type_ok: + mov ecx,[eax+20] + cmp byte [ecx],80h + je alias_symbol + cmp byte [ecx],0 + jne invalid_use_of_symbol + mov cx,[ecx+1Eh] + mov [ebx+0Ch],cx + public_symbol_section_ok: + movzx ecx,byte [eax+9] + shr cl,1 + and cl,1 + neg ecx + cmp ecx,[eax+4] + jne value_out_of_range + xor ecx,[eax] + js value_out_of_range + mov eax,[eax] + mov [ebx+8],eax + mov al,2 + cmp byte [esi],0C0h + je store_symbol_class + inc al + cmp byte [esi],0C1h + je store_symbol_class + mov al,105 + store_symbol_class: + mov byte [ebx+10h],al + add esi,10h + add ebx,12h + jmp make_symbols_table + alias_symbol: + bt [format_flags],0 + jnc invalid_use_of_symbol + mov ecx,[eax] + or ecx,[eax+4] + jnz invalid_use_of_symbol + mov byte [ebx+10h],69h + mov byte [ebx+11h],1 + add ebx,12h + mov ecx,[eax+20] + mov ecx,[ecx] + shr ecx,8 + mov [ebx],ecx + mov byte [ebx+4],3 + add esi,10h + add ebx,12h + jmp make_symbols_table + public_constant: + mov word [ebx+0Ch],0FFFFh + jmp public_symbol_section_ok + symbols_table_ok: + mov eax,edi + sub eax,edx + mov [edx],eax + sub edi,[code_start] + mov [code_size],edi + and [written_size],0 + mov edx,[output_file] + call create + jc write_failed + mov edx,[free_additional_memory] + pop ecx + add [written_size],ecx + call write + jc write_failed + jmp write_output + store_symbol_name: + push esi + mov esi,[esi+4] + or esi,esi + jz default_name + lods dword [esi] + mov ecx,eax + cmp ecx,8 + ja add_string + push edi + mov edi,ebx + rep movs byte [edi],[esi] + pop edi esi + ret + default_name: + mov dword [ebx],'.fla' + mov dword [ebx+4],'t' + pop esi + ret + add_string: + mov eax,edi + sub eax,edx + mov [ebx+4],eax + inc ecx + rep movs byte [edi],[esi] + pop esi + ret + +format_elf: + test [format_flags],8 + jnz format_elf64 + mov edx,edi + mov ecx,34h shr 2 + lea eax,[edi+ecx*4] + cmp eax,[tagged_blocks] + jae out_of_memory + xor eax,eax + rep stos dword [edi] + mov dword [edx],7Fh + 'ELF' shl 8 + mov al,1 + mov [edx+4],al + mov [edx+5],al + mov [edx+6],al + mov [edx+14h],al + mov byte [edx+12h],3 + mov byte [edx+28h],34h + mov byte [edx+2Eh],28h + mov [code_type],32 + mov byte [edx+10h],2 + cmp word [esi],1D19h + je format_elf_exe + mov byte [edx+10h],3 + cmp word [esi],021Eh + je format_elf_exe + elf_header_ok: + mov byte [edx+10h],1 + mov eax,[additional_memory] + mov [symbols_stream],eax + mov ebx,eax + add eax,20h + cmp eax,[structures_buffer] + jae out_of_memory + mov [free_additional_memory],eax + xor eax,eax + mov [current_section],ebx + mov [number_of_sections],eax + mov [ebx],al + mov [ebx+4],eax + mov [ebx+8],edi + mov al,111b + mov [ebx+14h],eax + mov al,4 + mov [ebx+10h],eax + mov edx,ebx + call init_addressing_space + xchg edx,ebx + mov [edx+14h],ebx + mov byte [edx+9],2 + test [format_flags],8 + jz format_defined + mov byte [edx+9],4 + mov byte [ebx+10h],8 + jmp format_defined + format_elf64: + mov edx,edi + mov ecx,40h shr 2 + lea eax,[edi+ecx*4] + cmp eax,[tagged_blocks] + jae out_of_memory + xor eax,eax + rep stos dword [edi] + mov dword [edx],7Fh + 'ELF' shl 8 + mov al,1 + mov [edx+5],al + mov [edx+6],al + mov [edx+14h],al + mov byte [edx+4],2 + mov byte [edx+12h],62 + mov byte [edx+34h],40h + mov byte [edx+3Ah],40h + mov [code_type],64 + mov byte [edx+10h],2 + cmp word [esi],1D19h + je format_elf64_exe + mov byte [edx+10h],3 + cmp word [esi],021Eh + je format_elf64_exe + jmp elf_header_ok +elf_section: + bt [format_flags],0 + jc illegal_instruction + call close_coff_section + mov ebx,[free_additional_memory] + lea eax,[ebx+20h] + cmp eax,[structures_buffer] + jae out_of_memory + mov [free_additional_memory],eax + mov [current_section],ebx + inc word [number_of_sections] + jz format_limitations_exceeded + xor eax,eax + mov [ebx],al + mov [ebx+8],edi + mov [ebx+10h],eax + mov al,10b + mov [ebx+14h],eax + mov edx,ebx + call create_addressing_space + xchg edx,ebx + mov [edx+14h],ebx + mov byte [edx+9],2 + test [format_flags],8 + jz elf_labels_type_ok + mov byte [edx+9],4 + elf_labels_type_ok: + lods word [esi] + cmp ax,'(' + jne invalid_argument + mov [ebx+4],esi + mov ecx,[esi] + lea esi,[esi+4+ecx+1] + elf_section_flags: + cmp byte [esi],8Ch + je elf_section_alignment + cmp byte [esi],19h + jne elf_section_settings_ok + inc esi + lods byte [esi] + sub al,28 + xor al,11b + test al,not 10b + jnz invalid_argument + mov cl,al + mov al,1 + shl al,cl + test byte [ebx+14h],al + jnz setting_already_specified + or byte [ebx+14h],al + jmp elf_section_flags + elf_section_alignment: + inc esi + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + push ebx + call get_count_value + pop ebx + mov edx,eax + dec edx + test eax,edx + jnz invalid_value + or eax,eax + jz invalid_value + xchg [ebx+10h],eax + or eax,eax + jnz setting_already_specified + jmp elf_section_flags + elf_section_settings_ok: + cmp dword [ebx+10h],0 + jne instruction_assembled + mov dword [ebx+10h],4 + test [format_flags],8 + jz instruction_assembled + mov byte [ebx+10h],8 + jmp instruction_assembled +mark_elf_relocation: + test [format_flags],1 + jnz invalid_use_of_symbol + push ebx + mov ebx,[addressing_space] + cmp [value_type],3 + je elf_relocation_relative + cmp [value_type],7 + je elf_relocation_relative + push eax + cmp [value_type],5 + je elf_gotoff_relocation + ja invalid_use_of_symbol + mov al,1 ; R_386_32 / R_AMD64_64 + test [format_flags],8 + jz coff_relocation + cmp [value_type],4 + je coff_relocation + mov al,11 ; R_AMD64_32S + jmp coff_relocation + elf_gotoff_relocation: + test [format_flags],8 + jnz invalid_use_of_symbol + mov al,9 ; R_386_GOTOFF + jmp coff_relocation + elf_relocation_relative: + cmp byte [ebx+9],0 + je invalid_use_of_symbol + mov ebx,[current_section] + mov ebx,[ebx+8] + sub ebx,edi + sub eax,ebx + push eax + mov al,2 ; R_386_PC32 / R_AMD64_PC32 + cmp [value_type],3 + je coff_relocation + mov al,4 ; R_386_PLT32 / R_AMD64_PLT32 + jmp coff_relocation +close_elf: + bt [format_flags],0 + jc close_elf_exe + call close_coff_section + cmp [next_pass_needed],0 + je elf_closed + mov eax,[symbols_stream] + mov [free_additional_memory],eax + elf_closed: + ret +elf_formatter: + mov ecx,edi + sub ecx,[code_start] + neg ecx + and ecx,111b + test [format_flags],8 + jnz align_elf_structures + and ecx,11b + align_elf_structures: + xor al,al + rep stos byte [edi] + push edi + call prepare_default_section + mov esi,[symbols_stream] + mov edi,[free_additional_memory] + xor eax,eax + mov ecx,4 + rep stos dword [edi] + test [format_flags],8 + jz find_first_section + mov ecx,2 + rep stos dword [edi] + find_first_section: + mov al,[esi] + or al,al + jz first_section_found + cmp al,0C0h + jb skip_other_symbol + add esi,4 + skip_other_symbol: + add esi,0Ch + jmp find_first_section + first_section_found: + mov ebx,esi + mov ebp,esi + add esi,20h + xor ecx,ecx + xor edx,edx + find_next_section: + cmp esi,[free_additional_memory] + je make_section_symbol + mov al,[esi] + or al,al + jz make_section_symbol + cmp al,0C0h + jae skip_public + cmp al,80h + jae skip_extrn + or byte [ebx+14h],40h + skip_extrn: + add esi,0Ch + jmp find_next_section + skip_public: + add esi,10h + jmp find_next_section + make_section_symbol: + mov eax,edi + xchg eax,[ebx+4] + stos dword [edi] + test [format_flags],8 + jnz elf64_section_symbol + xor eax,eax + stos dword [edi] + stos dword [edi] + call store_section_index + jmp section_symbol_ok + store_section_index: + inc ecx + mov eax,ecx + shl eax,8 + mov [ebx],eax + inc dx + jz format_limitations_exceeded + mov eax,edx + shl eax,16 + mov al,3 + test byte [ebx+14h],40h + jz section_index_ok + or ah,-1 + inc dx + jz format_limitations_exceeded + section_index_ok: + stos dword [edi] + ret + elf64_section_symbol: + call store_section_index + xor eax,eax + stos dword [edi] + stos dword [edi] + stos dword [edi] + stos dword [edi] + section_symbol_ok: + mov ebx,esi + add esi,20h + cmp ebx,[free_additional_memory] + jne find_next_section + inc dx + jz format_limitations_exceeded + mov [current_section],edx + mov esi,[symbols_stream] + find_other_symbols: + cmp esi,[free_additional_memory] + je elf_symbol_table_ok + mov al,[esi] + or al,al + jz skip_section + cmp al,0C0h + jae make_public_symbol + cmp al,80h + jae make_extrn_symbol + add esi,0Ch + jmp find_other_symbols + skip_section: + add esi,20h + jmp find_other_symbols + make_public_symbol: + mov eax,[esi+0Ch] + mov [current_line],eax + cmp byte [esi],0C0h + jne invalid_argument + mov ebx,[esi+8] + test byte [ebx+8],1 + jz undefined_public + mov ax,[current_pass] + cmp ax,[ebx+16] + jne undefined_public + mov dl,[ebx+11] + or dl,dl + jz public_absolute + mov eax,[ebx+20] + cmp byte [eax],0 + jne invalid_use_of_symbol + mov eax,[eax+4] + test [format_flags],8 + jnz elf64_public + cmp dl,2 + jne invalid_use_of_symbol + mov dx,[eax+0Eh] + jmp section_for_public_ok + undefined_public: + mov [error_info],ebx + jmp undefined_symbol + elf64_public: + cmp dl,4 + jne invalid_use_of_symbol + mov dx,[eax+6] + jmp section_for_public_ok + public_absolute: + mov dx,0FFF1h + section_for_public_ok: + mov eax,[esi+4] + stos dword [edi] + test [format_flags],8 + jnz elf64_public_symbol + movzx eax,byte [ebx+9] + shr al,1 + and al,1 + neg eax + cmp eax,[ebx+4] + jne value_out_of_range + xor eax,[ebx] + js value_out_of_range + mov eax,[ebx] + stos dword [edi] + xor eax,eax + mov al,[ebx+10] + stos dword [edi] + mov eax,edx + shl eax,16 + mov al,10h + cmp byte [ebx+10],0 + je elf_public_function + or al,1 + jmp store_elf_public_info + elf_public_function: + or al,2 + store_elf_public_info: + stos dword [edi] + jmp public_symbol_ok + elf64_public_symbol: + mov eax,edx + shl eax,16 + mov al,10h + cmp byte [ebx+10],0 + je elf64_public_function + or al,1 + jmp store_elf64_public_info + elf64_public_function: + or al,2 + store_elf64_public_info: + stos dword [edi] + mov al,[ebx+9] + shl eax,31-1 + xor eax,[ebx+4] + js value_out_of_range + mov eax,[ebx] + stos dword [edi] + mov eax,[ebx+4] + stos dword [edi] + mov al,[ebx+10] + stos dword [edi] + xor al,al + stos dword [edi] + public_symbol_ok: + inc ecx + mov eax,ecx + shl eax,8 + mov al,0C0h + mov [esi],eax + add esi,10h + jmp find_other_symbols + make_extrn_symbol: + mov eax,[esi+4] + stos dword [edi] + test [format_flags],8 + jnz elf64_extrn_symbol + xor eax,eax + stos dword [edi] + mov eax,[esi+8] + stos dword [edi] + mov eax,10h + stos dword [edi] + jmp extrn_symbol_ok + elf64_extrn_symbol: + mov eax,10h + stos dword [edi] + xor al,al + stos dword [edi] + stos dword [edi] + mov eax,[esi+8] + stos dword [edi] + xor eax,eax + stos dword [edi] + extrn_symbol_ok: + inc ecx + mov eax,ecx + shl eax,8 + mov al,80h + mov [esi],eax + add esi,0Ch + jmp find_other_symbols + elf_symbol_table_ok: + mov edx,edi + mov ebx,[free_additional_memory] + xor al,al + stos byte [edi] + add edi,16 + mov [edx+1],edx + add ebx,10h + test [format_flags],8 + jz make_string_table + add ebx,8 + make_string_table: + cmp ebx,edx + je elf_string_table_ok + test [format_flags],8 + jnz make_elf64_string + cmp byte [ebx+0Dh],0 + je rel_prefix_ok + mov byte [ebx+0Dh],0 + mov eax,'.rel' + stos dword [edi] + rel_prefix_ok: + mov esi,edi + sub esi,edx + xchg esi,[ebx] + add ebx,10h + make_elf_string: + or esi,esi + jz default_string + lods dword [esi] + mov ecx,eax + rep movs byte [edi],[esi] + xor al,al + stos byte [edi] + jmp make_string_table + make_elf64_string: + cmp byte [ebx+5],0 + je elf64_rel_prefix_ok + mov byte [ebx+5],0 + mov eax,'.rel' + stos dword [edi] + mov al,'a' + stos byte [edi] + elf64_rel_prefix_ok: + mov esi,edi + sub esi,edx + xchg esi,[ebx] + add ebx,18h + jmp make_elf_string + default_string: + mov eax,'.fla' + stos dword [edi] + mov ax,'t' + stos word [edi] + jmp make_string_table + elf_string_table_ok: + mov [edx+1+8],edi + mov ebx,[code_start] + mov eax,edi + sub eax,[free_additional_memory] + xor ecx,ecx + sub ecx,eax + test [format_flags],8 + jnz finish_elf64_header + and ecx,11b + add eax,ecx + mov [ebx+20h],eax + mov eax,[current_section] + inc ax + jz format_limitations_exceeded + mov [ebx+32h],ax + inc ax + jz format_limitations_exceeded + mov [ebx+30h],ax + jmp elf_header_finished + finish_elf64_header: + and ecx,111b + add eax,ecx + mov [ebx+28h],eax + mov eax,[current_section] + inc ax + jz format_limitations_exceeded + mov [ebx+3Eh],ax + inc ax + jz format_limitations_exceeded + mov [ebx+3Ch],ax + elf_header_finished: + xor eax,eax + add ecx,10*4 + rep stos byte [edi] + test [format_flags],8 + jz elf_null_section_ok + mov ecx,6*4 + rep stos byte [edi] + elf_null_section_ok: + mov esi,ebp + xor ecx,ecx + make_section_entry: + mov ebx,edi + mov eax,[esi+4] + mov eax,[eax] + stos dword [edi] + mov eax,1 + cmp dword [esi+0Ch],0 + je bss_section + test byte [esi+14h],80h + jz section_type_ok + bss_section: + mov al,8 + section_type_ok: + stos dword [edi] + mov eax,[esi+14h] + and al,3Fh + call store_elf_machine_word + xor eax,eax + call store_elf_machine_word + mov eax,[esi+8] + mov [image_base],eax + sub eax,[code_start] + call store_elf_machine_word + mov eax,[esi+0Ch] + call store_elf_machine_word + xor eax,eax + stos dword [edi] + stos dword [edi] + mov eax,[esi+10h] + call store_elf_machine_word + xor eax,eax + call store_elf_machine_word + inc ecx + add esi,20h + xchg edi,[esp] + mov ebp,edi + convert_relocations: + cmp esi,[free_additional_memory] + je relocations_converted + mov al,[esi] + or al,al + jz relocations_converted + cmp al,80h + jb make_relocation_entry + cmp al,0C0h + jb relocation_entry_ok + add esi,10h + jmp convert_relocations + make_relocation_entry: + test [format_flags],8 + jnz make_elf64_relocation_entry + mov eax,[esi+4] + stos dword [edi] + mov eax,[esi+8] + mov eax,[eax] + mov al,[esi] + stos dword [edi] + jmp relocation_entry_ok + make_elf64_relocation_entry: + mov eax,[esi+4] + stos dword [edi] + xor eax,eax + stos dword [edi] + movzx eax,byte [esi] + stos dword [edi] + mov eax,[esi+8] + mov eax,[eax] + shr eax,8 + stos dword [edi] + xor eax,eax + push edx + mov edx,[esi+4] + add edx,[image_base] + xchg eax,[edx] + stos dword [edi] + cmp byte [esi],1 + je addend_64bit + pop edx + sar eax,31 + stos dword [edi] + jmp relocation_entry_ok + addend_64bit: + xor eax,eax + xchg eax,[edx+4] + stos dword [edi] + pop edx + relocation_entry_ok: + add esi,0Ch + jmp convert_relocations + store_elf_machine_word: + stos dword [edi] + test [format_flags],8 + jz elf_machine_word_ok + and dword [edi],0 + add edi,4 + elf_machine_word_ok: + ret + relocations_converted: + cmp edi,ebp + xchg edi,[esp] + je rel_section_ok + mov eax,[ebx] + sub eax,4 + test [format_flags],8 + jz store_relocations_name_offset + dec eax + store_relocations_name_offset: + stos dword [edi] + test [format_flags],8 + jnz rela_section + mov eax,9 + jmp store_relocations_type + rela_section: + mov eax,4 + store_relocations_type: + stos dword [edi] + xor al,al + call store_elf_machine_word + call store_elf_machine_word + mov eax,ebp + sub eax,[code_start] + call store_elf_machine_word + mov eax,[esp] + sub eax,ebp + call store_elf_machine_word + mov eax,[current_section] + stos dword [edi] + mov eax,ecx + stos dword [edi] + inc ecx + test [format_flags],8 + jnz finish_elf64_rela_section + mov eax,4 + stos dword [edi] + mov al,8 + stos dword [edi] + jmp rel_section_ok + finish_elf64_rela_section: + mov eax,8 + stos dword [edi] + xor al,al + stos dword [edi] + mov al,24 + stos dword [edi] + xor al,al + stos dword [edi] + rel_section_ok: + cmp esi,[free_additional_memory] + jne make_section_entry + pop eax + mov ebx,[code_start] + sub eax,ebx + mov [code_size],eax + mov ecx,20h + test [format_flags],8 + jz adjust_elf_section_headers_offset + mov ecx,28h + adjust_elf_section_headers_offset: + add [ebx+ecx],eax + mov eax,1 + stos dword [edi] + mov al,2 + stos dword [edi] + xor al,al + call store_elf_machine_word + call store_elf_machine_word + mov eax,[code_size] + call store_elf_machine_word + mov eax,[edx+1] + sub eax,[free_additional_memory] + call store_elf_machine_word + mov eax,[current_section] + inc eax + stos dword [edi] + mov eax,[number_of_sections] + inc eax + stos dword [edi] + test [format_flags],8 + jnz finish_elf64_sym_section + mov eax,4 + stos dword [edi] + mov al,10h + stos dword [edi] + jmp sym_section_ok + finish_elf64_sym_section: + mov eax,8 + stos dword [edi] + xor al,al + stos dword [edi] + mov al,18h + stos dword [edi] + xor al,al + stos dword [edi] + sym_section_ok: + mov al,1+8 + stos dword [edi] + mov al,3 + stos dword [edi] + xor al,al + call store_elf_machine_word + call store_elf_machine_word + mov eax,[edx+1] + sub eax,[free_additional_memory] + add eax,[code_size] + call store_elf_machine_word + mov eax,[edx+1+8] + sub eax,[edx+1] + call store_elf_machine_word + xor eax,eax + stos dword [edi] + stos dword [edi] + mov al,1 + call store_elf_machine_word + xor eax,eax + call store_elf_machine_word + mov eax,'tab' + mov dword [edx+1],'.sym' + mov [edx+1+4],eax + mov dword [edx+1+8],'.str' + mov [edx+1+8+4],eax + mov [resource_data],edx + mov [written_size],0 + mov edx,[output_file] + call create + jc write_failed + call write_code + mov ecx,edi + mov edx,[free_additional_memory] + sub ecx,edx + add [written_size],ecx + call write + jc write_failed + jmp output_written + +format_elf_exe: + add esi,2 + or [format_flags],1 + cmp byte [esi],'(' + jne elf_exe_brand_ok + inc esi + cmp byte [esi],'.' + je invalid_value + push edx + call get_byte_value + cmp [value_type],0 + jne invalid_use_of_symbol + pop edx + mov [edx+7],al + elf_exe_brand_ok: + mov [image_base],8048000h + cmp byte [esi],80h + jne elf_exe_base_ok + lods word [esi] + cmp ah,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + push edx + call get_dword_value + cmp [value_type],0 + jne invalid_use_of_symbol + mov [image_base],eax + pop edx + elf_exe_base_ok: + mov byte [edx+2Ah],20h + mov ebx,edi + mov ecx,20h shr 2 + cmp [current_pass],0 + je init_elf_segments + imul ecx,[number_of_sections] + init_elf_segments: + xor eax,eax + rep stos dword [edi] + and [number_of_sections],0 + mov byte [ebx],1 + mov word [ebx+1Ch],1000h + mov byte [ebx+18h],111b + mov ebp,[image_base] + and dword [ebx+4],0 + mov [ebx+8],ebp + mov [ebx+0Ch],ebp + mov eax,edi + sub eax,[code_start] + add eax,ebp + mov [edx+18h],eax + and [image_base_high],0 + elf_exe_addressing_setup: + call init_addressing_space + call setup_elf_exe_labels_type + mov eax,[code_start] + xor edx,edx + xor cl,cl + sub eax,[image_base] + sbb edx,[image_base_high] + sbb cl,0 + mov [ebx],eax + mov [ebx+4],edx + mov [ebx+8],cl + mov [symbols_stream],edi + jmp format_defined + format_elf64_exe: + add esi,2 + or [format_flags],1 + cmp byte [esi],'(' + jne elf64_exe_brand_ok + inc esi + cmp byte [esi],'.' + je invalid_value + push edx + call get_byte_value + cmp [value_type],0 + jne invalid_use_of_symbol + pop edx + mov [edx+7],al + elf64_exe_brand_ok: + mov [image_base],400000h + and [image_base_high],0 + cmp byte [esi],80h + jne elf64_exe_base_ok + lods word [esi] + cmp ah,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + push edx + call get_qword_value + cmp [value_type],0 + jne invalid_use_of_symbol + mov [image_base],eax + mov [image_base_high],edx + pop edx + elf64_exe_base_ok: + mov byte [edx+36h],38h + mov ebx,edi + mov ecx,38h shr 2 + cmp [current_pass],0 + je init_elf64_segments + imul ecx,[number_of_sections] + init_elf64_segments: + xor eax,eax + rep stos dword [edi] + and [number_of_sections],0 + mov byte [ebx],1 + mov word [ebx+30h],1000h + mov byte [ebx+4],111b + mov ebp,[image_base] + mov ecx,[image_base_high] + and dword [ebx+8],0 + mov [ebx+10h],ebp + mov [ebx+10h+4],ecx + mov [ebx+18h],ebp + mov [ebx+18h+4],ecx + mov eax,edi + sub eax,[code_start] + add eax,ebp + adc ecx,0 + mov [edx+18h],eax + mov [edx+18h+4],ecx + jmp elf_exe_addressing_setup + setup_elf_exe_labels_type: + mov eax,[code_start] + cmp byte [eax+10h],3 + jne elf_exe_labels_type_ok + mov byte [ebx+9],2 + test [format_flags],8 + jz elf_exe_labels_type_ok + mov byte [ebx+9],4 + elf_exe_labels_type_ok: + ret +elf_entry: + lods byte [esi] + cmp al,'(' + jne invalid_argument + cmp byte [esi],'.' + je invalid_value + test [format_flags],8 + jnz elf64_entry + call get_dword_value + mov edx,[code_start] + mov [edx+18h],eax + jmp instruction_assembled + elf64_entry: + call get_qword_value + mov ebx,[code_start] + mov [ebx+18h],eax + mov [ebx+1Ch],edx + jmp instruction_assembled +elf_segment: + bt [format_flags],0 + jnc illegal_instruction + test [format_flags],8 + jnz elf64_segment + call close_elf_segment + push eax + call create_addressing_space + call setup_elf_exe_labels_type + mov ebp,ebx + mov ebx,[number_of_sections] + shl ebx,5 + add ebx,[code_start] + add ebx,34h + cmp ebx,[symbols_stream] + jb new_elf_segment + mov ebx,[symbols_stream] + sub ebx,20h + or [next_pass_needed],-1 + new_elf_segment: + mov byte [ebx],1 + and dword [ebx+18h],0 + mov word [ebx+1Ch],1000h + elf_segment_flags: + cmp byte [esi],1Eh + je elf_segment_type + cmp byte [esi],19h + jne elf_segment_flags_ok + lods word [esi] + sub ah,28 + jbe invalid_argument + cmp ah,1 + je mark_elf_segment_flag + cmp ah,3 + ja invalid_argument + xor ah,1 + cmp ah,2 + je mark_elf_segment_flag + inc ah + mark_elf_segment_flag: + test [ebx+18h],ah + jnz setting_already_specified + or [ebx+18h],ah + jmp elf_segment_flags + elf_segment_type: + cmp byte [ebx],1 + jne setting_already_specified + lods word [esi] + mov ecx,[number_of_sections] + jecxz elf_segment_type_ok + mov edx,[code_start] + add edx,34h + scan_elf_segment_types: + cmp edx,[symbols_stream] + jae elf_segment_type_ok + cmp [edx],ah + je data_already_defined + add edx,20h + loop scan_elf_segment_types + elf_segment_type_ok: + mov [ebx],ah + mov word [ebx+1Ch],1 + cmp ah,50h + jb elf_segment_flags + or dword [ebx],6474E500h + jmp elf_segment_flags + elf_segment_flags_ok: + pop edx + cmp byte [ebx],1 + jne no_elf_segment_merging + cmp [merge_segment],0 + jne merge_elf_segment + no_elf_segment_merging: + mov eax,edi + sub eax,[code_start] + mov [ebx+4],eax + and eax,0FFFh + add eax,edx + mov [ebx+8],eax + mov [ebx+0Ch],eax + xor edx,edx + elf_segment_addressing_setup: + xor cl,cl + not eax + not edx + not cl + add eax,1 + adc edx,0 + adc cl,0 + add eax,edi + adc edx,0 + adc cl,0 + mov [ds:ebp],eax + mov [ds:ebp+4],edx + mov [ds:ebp+8],cl + inc [number_of_sections] + jmp instruction_assembled + merge_elf_segment: + xor ecx,ecx + xchg ecx,[merge_segment] + cmp ecx,-1 + je merge_elf_header + mov eax,[ecx+8] + mov ecx,[ecx+4] + elf_segment_separated_base: + mov [ebx+8],eax + mov [ebx+0Ch],eax + mov [ebx+4],ecx + sub eax,ecx + add eax,edi + sub eax,[code_start] + xor edx,edx + jmp elf_segment_addressing_setup + merge_elf_header: + mov eax,[image_base] + xor ecx,ecx + jmp elf_segment_separated_base + close_elf_segment: + cmp [number_of_sections],0 + jne finish_elf_segment + cmp edi,[symbols_stream] + jne first_elf_segment_ok + or [merge_segment],-1 + mov eax,[image_base] + ret + first_elf_segment_ok: + and [merge_segment],0 + inc [number_of_sections] + finish_elf_segment: + mov ebx,[number_of_sections] + dec ebx + shl ebx,5 + add ebx,[code_start] + add ebx,34h + mov eax,edi + sub eax,[code_start] + sub eax,[ebx+4] + mov edx,edi + cmp edi,[undefined_data_end] + jne elf_segment_size_ok + cmp byte [ebx],1 + jne elf_segment_size_ok + mov edi,[undefined_data_start] + elf_segment_size_ok: + mov [ebx+14h],eax + add eax,edi + sub eax,edx + mov [ebx+10h],eax + and [undefined_data_end],0 + mov eax,[ebx+8] + cmp byte [ebx],1 + je elf_segment_position_move_and_align + cmp [merge_segment],0 + jne elf_segment_position_move + cmp byte [ebx],4 + je elf_segment_position_ok + cmp byte [ebx],51h + je elf_segment_position_ok + mov [merge_segment],ebx + elf_segment_position_move: + add eax,[ebx+14h] + jmp elf_segment_position_ok + elf_segment_position_move_and_align: + add eax,[ebx+14h] + add eax,0FFFh + elf_segment_position_ok: + and eax,not 0FFFh + ret + elf64_segment: + call close_elf64_segment + push eax edx + call create_addressing_space + call setup_elf_exe_labels_type + mov ebp,ebx + mov ebx,[number_of_sections] + imul ebx,38h + add ebx,[code_start] + add ebx,40h + cmp ebx,[symbols_stream] + jb new_elf64_segment + or [next_pass_needed],-1 + new_elf64_segment: + mov byte [ebx],1 + and dword [ebx+4],0 + mov word [ebx+30h],1000h + elf64_segment_flags: + cmp byte [esi],1Eh + je elf64_segment_type + cmp byte [esi],19h + jne elf64_segment_flags_ok + lods word [esi] + sub ah,28 + jbe invalid_argument + cmp ah,1 + je mark_elf64_segment_flag + cmp ah,3 + ja invalid_argument + xor ah,1 + cmp ah,2 + je mark_elf64_segment_flag + inc ah + mark_elf64_segment_flag: + test [ebx+4],ah + jnz setting_already_specified + or [ebx+4],ah + jmp elf64_segment_flags + elf64_segment_type: + cmp byte [ebx],1 + jne setting_already_specified + lods word [esi] + mov ecx,[number_of_sections] + jecxz elf64_segment_type_ok + mov edx,[code_start] + add edx,40h + scan_elf64_segment_types: + cmp edx,[symbols_stream] + jae elf64_segment_type_ok + cmp [edx],ah + je data_already_defined + add edx,38h + loop scan_elf64_segment_types + elf64_segment_type_ok: + mov [ebx],ah + mov word [ebx+30h],1 + cmp ah,50h + jb elf64_segment_flags + or dword [ebx],6474E500h + jmp elf64_segment_flags + elf64_segment_flags_ok: + pop edx eax + cmp byte [ebx],1 + jne no_elf64_segment_merging + cmp [merge_segment],0 + jne merge_elf64_segment + no_elf64_segment_merging: + mov ecx,edi + sub ecx,[code_start] + mov [ebx+8],ecx + and ecx,0FFFh + add eax,ecx + adc edx,0 + mov [ebx+10h],eax + mov [ebx+10h+4],edx + mov [ebx+18h],eax + mov [ebx+18h+4],edx + jmp elf_segment_addressing_setup + merge_elf64_segment: + xor ecx,ecx + xchg ecx,[merge_segment] + cmp ecx,-1 + je merge_elf64_header + mov eax,[ecx+10h] + mov edx,[ecx+10h+4] + mov ecx,[ecx+8] + elf64_segment_separated_base: + mov [ebx+10h],eax + mov [ebx+10h+4],edx + mov [ebx+18h],eax + mov [ebx+18h+4],edx + mov [ebx+8],ecx + neg ecx + add ecx,edi + sub ecx,[code_start] + add eax,ecx + adc edx,0 + jmp elf_segment_addressing_setup + merge_elf64_header: + mov eax,[image_base] + mov edx,[image_base_high] + xor ecx,ecx + jmp elf64_segment_separated_base + close_elf64_segment: + cmp [number_of_sections],0 + jne finish_elf64_segment + cmp edi,[symbols_stream] + jne first_elf64_segment_ok + or [merge_segment],-1 + mov eax,[image_base] + mov edx,[image_base_high] + ret + first_elf64_segment_ok: + and [merge_segment],0 + inc [number_of_sections] + finish_elf64_segment: + mov ebx,[number_of_sections] + dec ebx + imul ebx,38h + add ebx,[code_start] + add ebx,40h + mov eax,edi + sub eax,[code_start] + sub eax,[ebx+8] + mov edx,edi + cmp edi,[undefined_data_end] + jne elf64_segment_size_ok + cmp byte [ebx],1 + jne elf64_segment_size_ok + mov edi,[undefined_data_start] + elf64_segment_size_ok: + mov [ebx+28h],eax + add eax,edi + sub eax,edx + mov [ebx+20h],eax + and [undefined_data_end],0 + mov eax,[ebx+10h] + mov edx,[ebx+10h+4] + cmp byte [ebx],1 + je elf64_segment_position_move_and_align + cmp [merge_segment],0 + jne elf64_segment_position_move + cmp byte [ebx],4 + je elf64_segment_position_ok + cmp byte [ebx],51h + je elf64_segment_position_ok + mov [merge_segment],ebx + elf64_segment_position_move: + add eax,[ebx+28h] + adc edx,0 + jmp elf64_segment_position_ok + elf64_segment_position_move_and_align: + add eax,[ebx+28h] + adc edx,0 + add eax,0FFFh + adc edx,0 + elf64_segment_position_ok: + and eax,not 0FFFh + ret +close_elf_exe: + test [format_flags],8 + jnz close_elf64_exe + call close_elf_segment + mov edx,[code_start] + mov eax,[number_of_sections] + mov byte [edx+1Ch],34h + mov [edx+2Ch],ax + shl eax,5 + add eax,edx + add eax,34h + cmp eax,[symbols_stream] + je elf_exe_ok + or [next_pass_needed],-1 + elf_exe_ok: + ret + close_elf64_exe: + call close_elf64_segment + mov edx,[code_start] + mov eax,[number_of_sections] + mov byte [edx+20h],40h + mov [edx+38h],ax + imul eax,38h + add eax,edx + add eax,40h + cmp eax,[symbols_stream] + je elf64_exe_ok + or [next_pass_needed],-1 + elf64_exe_ok: + ret diff --git a/toolchain/fasmw17332/SOURCE/IDE/BLOCKS.INC b/toolchain/fasmw17332/SOURCE/IDE/BLOCKS.INC new file mode 100644 index 0000000..a6484bd --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/IDE/BLOCKS.INC @@ -0,0 +1,536 @@ + +; flat editor core +; Copyright (c) 1999-2015, Tomasz Grysztar. +; All rights reserved. + +insert_block: + test [editor_mode],FEMODE_VERTICALSEL + jz block_to_insert_ok + push esi + or edx,-1 + xor ecx,ecx + count_line_characters: + lodsb + cmp al,9 + je cannot_insert + cmp al,0Dh + je count_next_line + or al,al + jz end_of_line + inc ecx + jmp count_line_characters + end_of_line: + dec esi + jmp check_block_width + count_next_line: + lodsb + cmp al,0Ah + je check_block_width + dec esi + check_block_width: + cmp edx,-1 + je line_to_insert_ok + cmp edx,ecx + je line_to_insert_ok + cannot_insert: + pop esi + stc + retn + line_to_insert_ok: + mov edx,ecx + xor ecx,ecx + cmp byte [esi],0 + jne count_line_characters + pop esi + block_to_insert_ok: + mov eax,[caret_line] + mov ecx,[caret_line_number] + mov edx,[caret_position] + mov [selection_line],eax + mov [selection_line_number],ecx + mov [selection_position],edx + mov ebx,esi + get_line_to_insert: + lodsb + or al,al + jz insert_full_line + cmp al,0Dh + je insert_full_line + cmp al,0Ah + je insert_full_line + cmp al,9 + jne get_line_to_insert + push esi + dec esi + mov ecx,esi + sub ecx,ebx + mov esi,ebx + push ecx + call insert_into_line + pop ecx + add [caret_position],ecx + mov ecx,[caret_position] + and ecx,not 111b + sub ecx,[caret_position] + add ecx,8 + xor esi,esi + push ecx + call insert_into_line + pop ecx + add [caret_position],ecx + pop esi + mov ebx,esi + jmp get_line_to_insert + insert_full_line: + dec esi + push esi + mov ecx,esi + sub ecx,ebx + mov esi,ebx + push ecx + call insert_into_line + pop ecx + add [caret_position],ecx + pop esi + lodsb + or al,al + jz last_line_inserted + cmp al,0Ah + je lf_first + lodsb + cmp al,0Ah + je next_line_to_insert + dec esi + jmp next_line_to_insert + lf_first: + lodsb + cmp al,0Dh + je next_line_to_insert + dec esi + next_line_to_insert: + mov ebx,[selection_position] + test [editor_mode],FEMODE_VERTICALSEL + jnz insert_in_next_line + test [editor_mode],FEMODE_OVERWRITE + jz insert_new_line + push esi + call clear_rest_of_line + pop esi + xor ebx,ebx + insert_in_next_line: + push esi ebx + mov esi,[caret_line] + call check_line_length + pop ebx + call go_to_next_line + pop esi + mov ebx,esi + jmp get_line_to_insert + last_line_inserted: + mov esi,[caret_line] + call check_line_length + clc + retn + insert_new_line: + push esi + push [caret_line] + push [caret_line_number] + xor ebx,ebx + call break_line + pop [caret_line_number] + pop ebx esi + push [caret_line] + mov [caret_line],ebx + go_to_end_of_first_line: + test byte [ebx],1 + jz insert_full_lines + mov ebx,[ebx] + dec ebx + jmp go_to_end_of_first_line + insert_full_lines: + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + mov [ebx],eax + mov ebx,eax + mov eax,[caret_line] + mov [ebx+4],eax + mov [caret_line],ebx + inc [caret_line_number] + inc [lines_count] + call set_line + jc full_lines_inserted + jmp insert_full_lines + full_lines_inserted: + pop edi + mov eax,[caret_line] + mov [edi+4],eax + mov [ebx],edi + call cut_line_break + mov esi,[caret_line] + call check_line_length + clc + retn + set_line: + mov edi,ebx + add edi,SEGMENT_HEADER_LENGTH + mov ecx,SEGMENT_DATA_LENGTH + mov [caret_position],0 + push ebx + copy_line: + lodsb + or al,al + jz last_line_set + cmp al,0Ah + je copy_lf + cmp al,0Dh + je copy_cr + cmp al,9 + je copy_tab + set_character: + stosb + loop copy_line + extra_segment: + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + mov edi,eax + or eax,1 + mov [ebx],eax + or ebx,1 + mov [edi+4],ebx + mov ebx,edi + add edi,SEGMENT_HEADER_LENGTH + mov ecx,SEGMENT_DATA_LENGTH + add [caret_position],ecx + jmp copy_line + copy_tab: + mov al,20h + mov edx,SEGMENT_DATA_LENGTH + sub edx,ecx + add edx,[caret_position] + and edx,111b + cmp edx,111b + je set_character + dec esi + jmp set_character + copy_lf: + cmp byte [esi],0Dh + jne copy_new_line + inc esi + jmp copy_new_line + copy_cr: + cmp byte [esi],0Ah + jne copy_new_line + inc esi + copy_new_line: + pop edx + call finish_line + clc + retn + last_line_set: + pop edx + call finish_line + stc + retn + finish_line: + mov eax,SEGMENT_DATA_LENGTH + sub eax,ecx + add eax,[caret_position] + mov [caret_position],eax + mov [edx+8],eax + call register_length + mov al,20h + rep stosb + retn + +delete_block: + test [editor_mode],FEMODE_VERTICALSEL + jnz delete_vertical_block + mov eax,[caret_line_number] + cmp eax,[selection_line_number] + je delete_vertical_block + mov esi,[caret_line] + mov ecx,[caret_line_number] + mov edx,[caret_position] + cmp ecx,[selection_line_number] + jbe position_for_deleting_ok + xchg esi,[selection_line] + xchg ecx,[selection_line_number] + xchg edx,[selection_position] + mov [caret_line],esi + mov [caret_line_number],ecx + mov [caret_position],edx + position_for_deleting_ok: + test [editor_mode],FEMODE_OVERWRITE + jnz clear_block + call get_caret_segment + cmp edx,SEGMENT_DATA_LENGTH + jb first_line_of_block + call attach_empty_segments + first_line_of_block: + mov ecx,[caret_position] + sub ecx,edx + skip_rest_of_first_line: + add ecx,SEGMENT_DATA_LENGTH + mov eax,[esi] + btr eax,0 + jnc end_of_first_line + mov esi,eax + jmp skip_rest_of_first_line + end_of_first_line: + call store_segment_for_undo + mov edi,esi + mov esi,eax + remove_middle_lines: + cmp esi,[selection_line] + je middle_lines_removed + call store_freed_segment_for_undo + mov ebx,[esi] + call cancel_line + mov esi,ebx + btr esi,0 + jnc remove_middle_lines + remove_middle_line_segments: + call store_freed_segment_for_undo + mov esi,[esi] + btr esi,0 + jc remove_middle_line_segments + jmp remove_middle_lines + middle_lines_removed: + call store_segment_for_undo + mov eax,esi + or eax,1 + mov [edi],eax + mov eax,edi + or eax,1 + mov [esi+4],eax + call cancel_line + add ecx,[selection_position] + sub ecx,[caret_position] + call delete_from_line + mov esi,[caret_line] + find_following_line: + mov esi,[esi] + btr esi,0 + jc find_following_line + or esi,esi + jz following_line_ok + call store_segment_for_undo + mov eax,[caret_line] + mov [esi+4],eax + following_line_ok: + mov esi,[caret_line] + call check_line_length + block_deleted: + retn + clear_block: + push [caret_line] + push [caret_position] + clear_lines: + call clear_rest_of_line + mov [caret_line],esi + mov [caret_position],0 + cmp esi,[selection_line] + jne clear_lines + mov ecx,[selection_position] + call clear_in_line + pop [caret_position] + pop [caret_line] + retn + delete_vertical_block: + push [caret_line] + push [caret_line_number] + mov eax,[caret_position] + cmp eax,[selection_position] + jbe delete_vertical_block_line + xchg eax,[selection_position] + mov [caret_position],eax + delete_vertical_block_line: + mov ecx,[selection_position] + sub ecx,[caret_position] + call delete_from_line + mov esi,[caret_line] + call check_line_length + mov esi,[caret_line] + mov eax,[caret_line_number] + cmp eax,[selection_line_number] + je vertical_block_deleted + ja delete_in_previous_line + delete_in_next_line: + mov esi,[esi] + btr esi,0 + jc delete_in_next_line + mov [caret_line],esi + inc [caret_line_number] + jmp delete_vertical_block_line + delete_in_previous_line: + mov esi,[esi+4] + mov [caret_line],esi + dec [caret_line_number] + jmp delete_vertical_block_line + vertical_block_deleted: + pop [caret_line_number] + pop [caret_line] + mov [selection_line],0 + retn + +get_block_length: + test [editor_mode],FEMODE_VERTICALSEL + jnz get_length_of_vertical_block + mov esi,[caret_line] + mov edx,[caret_position] + mov ebx,[selection_line] + mov ecx,[selection_position] + mov eax,[caret_line_number] + cmp eax,[selection_line_number] + je get_length_of_vertical_block + jb get_length_of_standard_block + xchg esi,ebx + xchg ecx,edx + get_length_of_standard_block: + push ecx + mov ecx,[esi+8] + sub ecx,edx + jae add_length_of_line + xor ecx,ecx + add_length_of_line: + add ecx,2 + add [esp],ecx + skip_standard_block_line: + mov esi,[esi] + btr esi,0 + jc skip_standard_block_line + cmp esi,ebx + je length_of_block_ok + mov ecx,[esi+8] + jmp add_length_of_line + length_of_block_ok: + pop ecx + retn + get_length_of_vertical_block: + mov edx,[caret_line_number] + sub edx,[selection_line_number] + jae vertical_dimension_ok + neg edx + vertical_dimension_ok: + mov eax,[caret_position] + sub eax,[selection_position] + jae horizontal_dimension_ok + neg eax + horizontal_dimension_ok: + mov ecx,eax + add eax,2 + mul edx + add ecx,eax + retn + +copy_block: + test [editor_mode],FEMODE_VERTICALSEL + jnz copy_vertical_block + mov esi,[caret_line] + mov edx,[caret_position] + mov ebx,[selection_line] + mov ecx,[selection_position] + mov eax,[caret_line_number] + cmp eax,[selection_line_number] + je copy_vertical_block + jb copy_standard_block + xchg esi,ebx + xchg ecx,edx + copy_standard_block: + push ecx + push ebx + mov ecx,[esi+8] + sub ecx,edx + jb after_line_end + call copy_from_line + jmp block_line_copied + after_line_end: + mov esi,[esi] + btr esi,0 + jc after_line_end + block_line_copied: + pop ebx + copy_next_line: + mov ax,0A0Dh + stosw + cmp esi,ebx + je copy_from_last_line + push ebx + mov ecx,[esi+8] + xor edx,edx + call copy_from_line + pop ebx + jmp copy_next_line + copy_from_last_line: + pop ecx + xor edx,edx + call copy_from_line + xor al,al + stosb + retn + copy_vertical_block: + mov esi,[caret_line] + mov ebx,[selection_line] + mov edx,[caret_position] + mov ecx,[selection_position] + mov eax,[caret_line_number] + cmp eax,[selection_line_number] + jbe vertical_block_starting_line_ok + xchg esi,ebx + vertical_block_starting_line_ok: + cmp edx,ecx + jbe vertical_block_starting_position_ok + xchg edx,ecx + vertical_block_starting_position_ok: + sub ecx,edx + copy_line_from_vertical_block: + mov eax,ebx + sub eax,esi + push eax ebx ecx edx + call copy_from_line + pop edx ecx ebx eax + or eax,eax + jz vertical_block_copied + mov ax,0A0Dh + stosw + jmp copy_line_from_vertical_block + vertical_block_copied: + xor al,al + stosb + retn + copy_from_line: + mov ebx,ecx + find_copying_origin: + cmp edx,SEGMENT_DATA_LENGTH + jb copy_line_segment + mov esi,[esi] + btr esi,0 + jnc line_data_ended + sub edx,SEGMENT_DATA_LENGTH + jmp find_copying_origin + copy_line_segment: + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + cmp ebx,ecx + jae line_segment_length_ok + mov ecx,ebx + line_segment_length_ok: + sub ebx,ecx + mov eax,[esi] + lea esi,[esi+SEGMENT_HEADER_LENGTH+edx] + rep movsb + mov esi,eax + btr esi,0 + jnc line_data_ended + xor edx,edx + jmp copy_line_segment + line_data_ended: + or ebx,ebx + jz line_copy_done + mov ecx,ebx + mov al,20h + rep stosb + line_copy_done: + retn diff --git a/toolchain/fasmw17332/SOURCE/IDE/EDIT.INC b/toolchain/fasmw17332/SOURCE/IDE/EDIT.INC new file mode 100644 index 0000000..1008f04 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/IDE/EDIT.INC @@ -0,0 +1,1027 @@ + +; flat editor core +; Copyright (c) 1999-2015, Tomasz Grysztar. +; All rights reserved. + +set_text: + push esi + call reset_editor_memory + pop esi + mov ebx,[first_line] + or esi,esi + jz new_text_ok + set_text_line: + call set_line + jc new_text_ok + call allocate_segment + mov [ebx],eax + jc not_enough_memory + mov ebx,eax + mov eax,[caret_line] + mov [ebx+4],eax + mov [caret_line],ebx + inc [lines_count] + inc [caret_line_number] + jmp set_text_line + new_text_ok: + xor eax,eax + mov dword [ebx],eax + inc eax + mov [caret_line_number],eax + mov eax,[first_line] + mov [caret_line],eax + mov [caret_position],0 + retn + +put_character: + call get_caret_segment + inc [caret_position] + put_here: + cmp edx,SEGMENT_DATA_LENGTH + jae put_after_line_end + call store_segment_for_undo + test [editor_mode],FEMODE_OVERWRITE + jnz overwrite + mov ah,[esi+SEGMENT_HEADER_LENGTH+edx] + shl eax,8 + mov al,ah + insert_in_segment: + lea ebx,[esi+SEGMENT_HEADER_LENGTH+edx] + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + shift_data_right: + xchg al,[ebx] + inc ebx + loop shift_data_right + test byte [esi],1 + jnz shift_next_segment_right + cmp al,20h + je put_ok + add_segment: + push eax + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + mov edi,eax + or eax,1 + xchg eax,[esi] + stosd + mov eax,esi + or eax,1 + stosd + add edi,SEGMENT_HEADER_LENGTH - 8 + pop eax + stosb + mov ecx,SEGMENT_DATA_LENGTH - 1 + mov al,20h + rep stosb + jmp put_ok + shift_next_segment_right: + mov esi,[esi] + dec esi + call store_segment_for_undo + xor edx,edx + jmp insert_in_segment + put_after_line_end: + push eax + call attach_empty_segments + pop eax + mov [esi+SEGMENT_HEADER_LENGTH+edx],al + mov ah,20h + shl eax,8 + put_ok: + test [editor_style],FES_AUTOBRACKETS + jz insert_done + shr eax,8 + xchg ah,al + call recognize_character + jnc insert_done + cmp ah,'(' + je round + cmp ah,'[' + je square + cmp ah,'{' + je brace + insert_done: + retn + round: + mov al,')' + jmp auto_bracket + square: + mov al,']' + jmp auto_bracket + brace: + mov al,'}' + auto_bracket: + mov edx,[caret_position] + mov esi,[caret_line] + call find_segment + jmp put_here + overwrite: + mov [esi+SEGMENT_HEADER_LENGTH+edx],al + retn + attach_empty_segments: + call store_segment_for_undo + attach_segment: + push edx + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + pop edx + mov ebx,esi + mov esi,eax + mov edi,eax + or eax,1 + xchg eax,[ebx] + stosd + mov eax,ebx + or eax,1 + stosd + add edi,SEGMENT_HEADER_LENGTH - 8 + mov ecx,SEGMENT_DATA_LENGTH shr 2 + mov eax,20202020h + rep stosd + sub edx,SEGMENT_DATA_LENGTH + cmp edx,SEGMENT_DATA_LENGTH + jae attach_segment + retn + recognize_character: + cmp al,20h + jb neutral_character + cmp al,30h + jb separator_character + cmp al,3Ah + jb neutral_character + cmp al,40h + jb separator_character + cmp al,5Bh + jb neutral_character + cmp al,5Fh + jb separator_character + cmp al,7Bh + jb neutral_character + cmp al,7Fh + jb separator_character + neutral_character: + clc + retn + separator_character: + stc + retn + +delete_character: + call get_caret_segment + delete_here: + cmp edx,SEGMENT_DATA_LENGTH + jae delete_done + call store_segment_for_undo + test [editor_mode],FEMODE_OVERWRITE + jnz blank + lea ebx,[esi+SEGMENT_LENGTH] + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + mov al,20h + mov edi,[esi] + test edi,1 + jz shift_data_left + mov al,[edi-1+SEGMENT_HEADER_LENGTH] + shift_data_left: + dec ebx + xchg al,[ebx] + loop shift_data_left + lea esi,[edi-1] + xor edx,edx + test edi,1 + jnz delete_here + delete_done: + retn + blank: + mov byte [esi+SEGMENT_HEADER_LENGTH+edx],20h + retn + +tabulate: + test [editor_style],FES_SMARTTABS + jz standard_tab + mov esi,[caret_line] + mov esi,[esi+4] + or esi,esi + jz standard_tab + mov edx,[caret_position] + call find_segment + cmp edx,SEGMENT_DATA_LENGTH + jae standard_tab + push 0 + find_space: + lea edi,[esi+SEGMENT_HEADER_LENGTH+edx] + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + mov ebx,ecx + mov al,20h + repne scasb + jne no_space_in_this_segment + sub ebx,ecx + dec ebx + add edx,ebx + add [esp],ebx + call get_indent + pop ecx + or ebx,ebx + jz standard_tab + add ecx,ebx + jmp insert_tab_spaces + no_space_in_this_segment: + pop ecx + mov esi,[esi] + btr esi,0 + jnc standard_tab + add ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + xor edx,edx + push ecx + jmp find_space + standard_tab: + mov ecx,[caret_position] + and ecx,not 111b + sub ecx,[caret_position] + add ecx,8 + insert_tab_spaces: + xor esi,esi + push ecx + call insert_into_line + pop ecx + add [caret_position],ecx + retn + +carriage_return: + xor ebx,ebx + test [editor_style],FES_AUTOINDENT + jz auto_indent_ok + test [editor_mode],FEMODE_OVERWRITE + jnz auto_indent_ok + call get_caret_segment + call get_indent + add [caret_position],ebx + mov esi,[caret_line] + xor edx,edx + call get_indent + auto_indent_ok: + call break_line + retn + get_indent: + xor ebx,ebx + find_indent_origin: + cmp edx,SEGMENT_DATA_LENGTH + jb find_indent + mov esi,[esi] + btr esi,0 + jnc no_indent + sub edx,SEGMENT_DATA_LENGTH + jmp find_indent_origin + find_indent: + lea edi,[esi+SEGMENT_HEADER_LENGTH+edx] + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + add ebx,ecx + mov al,20h + repe scasb + je segment_indent + sub ebx,ecx + dec ebx + retn + segment_indent: + xor edx,edx + mov esi,[esi] + btr esi,0 + jc find_indent + no_indent: + xor ebx,ebx + retn + +break_line: + test [editor_mode],FEMODE_OVERWRITE + jnz go_to_next_line + push ebx + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + mov edi,eax + mov eax,[caret_line] + mov [edi+4],eax + mov ebx,[esp] + push edi + add edi,SEGMENT_HEADER_LENGTH + mov ecx,SEGMENT_DATA_LENGTH shr 2 + mov eax,20202020h + rep stosd + call get_caret_segment + call store_segment_for_undo + mov edi,[esp] + cmp edx,SEGMENT_DATA_LENGTH + jae empty_new_line + push esi edx + new_line_segment: + cmp ebx,SEGMENT_DATA_LENGTH + jb new_line_segments_ok + push edi ebx + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + mov esi,eax + lea edi,[esi+SEGMENT_HEADER_LENGTH] + mov ecx,SEGMENT_DATA_LENGTH shr 2 + mov eax,20202020h + rep stosd + pop ebx edi + sub ebx,SEGMENT_DATA_LENGTH + mov eax,esi + or eax,1 + mov [edi],eax + or edi,1 + mov [esi+4],edi + mov edi,esi + jmp new_line_segment + new_line_segments_ok: + pop edx esi + split_data: + cmp ebx,edx + jbe indent_data + push esi edi + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,ebx + lea esi,[esi+SEGMENT_HEADER_LENGTH+edx] + lea edi,[edi+SEGMENT_HEADER_LENGTH+ebx] + add edx,ecx + mov eax,ecx + rep movsb + mov edi,esi + sub edi,eax + mov ecx,eax + mov al,20h + rep stosb + push edx + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + pop edx edi esi + mov ebx,eax + or eax,1 + mov [edi],eax + or edi,1 + mov [ebx+4],edi + mov edi,ebx + xor ebx,ebx + jmp split_data + indent_data: + push edi + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + mov eax,ecx + lea esi,[esi+SEGMENT_HEADER_LENGTH+edx] + lea edi,[edi+SEGMENT_HEADER_LENGTH+ebx] + rep movsb + add ebx,eax + mov edi,esi + sub edi,eax + mov ecx,eax + mov al,20h + rep stosb + pop edi + mov eax,[esp] + xchg eax,[esi-SEGMENT_LENGTH] + btr eax,0 + jnc finish_new_line + shift_splitted_data: + mov esi,eax + or eax,1 + mov [edi],eax + call store_segment_for_undo + mov eax,edi + or eax,1 + mov [esi+4],eax + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,ebx + lea edi,[edi+SEGMENT_HEADER_LENGTH+ebx] + add esi,SEGMENT_HEADER_LENGTH + mov eax,esi + rep movsb + mov edi,eax + mov ecx,ebx + rep movsb + sub edi,ebx + sub edi,SEGMENT_HEADER_LENGTH + mov eax,[edi] + btr eax,0 + jc shift_splitted_data + finish_new_line: + mov esi,edi + call store_segment_for_undo + mov [edi],eax + pop esi + or eax,eax + jz new_line_pointers_ok + xchg esi,eax + call store_segment_for_undo + xchg esi,eax + mov [eax+4],esi + new_line_pointers_ok: + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,ebx + lea edi,[edi+SEGMENT_HEADER_LENGTH+ebx] + mov al,20h + rep stosb + xchg [caret_line],esi + call check_line_length + mov esi,[caret_line] + mov dword [esi+8],0 + call check_line_length + inc [caret_line_number] + inc [lines_count] + pop [caret_position] + retn + empty_new_line: + pop edi + mov eax,[esi] + mov [esi],edi + mov [edi],eax + or eax,eax + jz empty_line_pointers_ok + mov [eax+4],edi + empty_line_pointers_ok: + mov dword [edi+8],0 + mov [caret_line],edi + inc [caret_line_number] + inc [lines_count] + pop [caret_position] + retn + go_to_next_line: + mov [caret_position],ebx + mov esi,[caret_line] + skip_line_segments: + mov eax,[esi] + btr eax,0 + jnc line_segments_skipped + mov esi,eax + jmp skip_line_segments + line_segments_skipped: + or eax,eax + jz no_next_line + mov [caret_line],eax + next_line_ok: + inc [caret_line_number] + retn + no_next_line: + call store_segment_for_undo + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + mov [esi],eax + mov edi,eax + xchg eax,[caret_line] + mov [edi+4],eax + xor eax,eax + stosd + add edi,4 + stosd + add edi,SEGMENT_HEADER_LENGTH - 12 + mov ecx,SEGMENT_DATA_LENGTH shr 2 + mov eax,20202020h + rep stosd + inc [lines_count] + jmp next_line_ok + +cut_line_break: + test [editor_mode],FEMODE_OVERWRITE + jnz do_nothing + call get_caret_segment + cmp edx,SEGMENT_DATA_LENGTH + jbe segment_for_deleting_ok + call store_segment_for_undo + add_empty_segment: + push edx esi + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + pop ebx edx + mov esi,eax + mov edi,eax + or eax,1 + xchg eax,[ebx] + stosd + mov eax,ebx + or eax,1 + stosd + add edi,SEGMENT_HEADER_LENGTH - 8 + mov ecx,SEGMENT_DATA_LENGTH shr 2 + mov eax,20202020h + rep stosd + sub edx,SEGMENT_DATA_LENGTH + cmp edx,SEGMENT_DATA_LENGTH + ja add_empty_segment + segment_for_deleting_ok: + call store_segment_for_undo + mov edi,esi + mov esi,[esi] + btr esi,0 + jc append_segment + call cancel_line + append_segment: + or esi,esi + jz fill_rest_with_spaces + call store_segment_for_undo + or byte [edi],1 + lea eax,[edi+1] + mov [esi+4],eax + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + mov eax,ecx + add esi,SEGMENT_HEADER_LENGTH + lea edi,[edi+SEGMENT_HEADER_LENGTH+edx] + rep movsb + mov edi,esi + sub edi,eax + mov ecx,edx + rep movsb + sub esi,SEGMENT_LENGTH + mov edi,esi + mov esi,[esi] + btr esi,0 + jc append_segment + fill_rest_with_spaces: + lea edi,[edi+SEGMENT_HEADER_LENGTH+edx] + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + mov al,20h + rep stosb + or esi,esi + jz delete_done + call store_segment_for_undo + mov eax,[caret_line] + mov [esi+4],eax + do_nothing: + retn + +cancel_line: + dec [lines_count] + mov eax,[esi+8] + call unregister_length + cmp esi,[window_line] + jne window_line_ok + mov eax,[caret_line] + mov [window_line],eax + mov eax,[caret_line_number] + mov [window_line_number],eax + window_line_ok: + cmp esi,[first_line] + jne first_line_ok + mov eax,[caret_line] + mov [first_line],eax + first_line_ok: + retn + +insert_into_line: + or ecx,ecx + jz void_insert + push ecx esi + call get_caret_segment + test [editor_mode],FEMODE_OVERWRITE + jnz overwrite_in_line + cmp edx,SEGMENT_DATA_LENGTH + jae attach_after_line_end + mov eax,[esp+4] + push edx + xor edx,edx + mov ecx,SEGMENT_DATA_LENGTH + div ecx + mov ebx,esi + push esi + or edx,edx + jnz find_last_segment_to_shift + call store_segment_for_undo + mov esi,[esi] + btr esi,0 + jnc following_segments_shifted + call store_segment_for_undo + jmp following_segments_shifted + find_last_segment_to_shift: + test byte [ebx],1 + jz shift_following_segments + mov ebx,[ebx] + dec ebx + jmp find_last_segment_to_shift + shift_following_segments: + push edx + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + pop edx + mov edi,eax + mov esi,[ebx] + mov [edi],esi + mov eax,ebx + or eax,1 + mov [edi+4],eax + lea edi,[edi+SEGMENT_HEADER_LENGTH+edx] + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + mov al,20h + rep stosb + sub edi,SEGMENT_LENGTH + carry_to_next_segment: + mov esi,ebx + call store_segment_for_undo + mov eax,edi + or eax,1 + mov [esi],eax + add esi,SEGMENT_LENGTH + sub esi,edx + mov ecx,edx + add edi,SEGMENT_HEADER_LENGTH + rep movsb + cmp ebx,[esp] + je following_segments_shifted + mov edi,ebx + mov ebx,[edi+4] + btr ebx,0 + push edi + add edi,SEGMENT_LENGTH-1 + mov esi,edi + sub esi,edx + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + std + rep movsb + cld + pop edi + jmp carry_to_next_segment + following_segments_shifted: + pop esi edx + insert_more_segments: + mov edi,esi + mov ecx,[esp+4] + make_inserted_segment: + sub ecx,SEGMENT_DATA_LENGTH + jb fill_inserted_segments + push ecx edx + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + pop edx ecx + mov ebx,[edi] + btr ebx,0 + jnc make_attached_segment + or eax,1 + mov [edi],eax + mov [ebx+4],eax + and eax,not 1 + or ebx,1 + mov [eax],ebx + or edi,1 + mov [eax+4],edi + mov edi,eax + jmp make_inserted_segment + make_attached_segment: + or eax,1 + mov [edi],eax + and eax,not 1 + mov [eax],ebx + or edi,1 + mov [eax+4],edi + mov edi,eax + jmp make_inserted_segment + fill_inserted_segments: + mov eax,SEGMENT_DATA_LENGTH + add ecx,eax + sub eax,edx + sub eax,ecx + jbe all_shifts_done + mov ecx,eax + lea edi,[edi+SEGMENT_LENGTH-1] + push esi + lea esi,[esi+SEGMENT_HEADER_LENGTH+ecx-1] + add esi,edx + std + rep movsb + cld + pop esi + all_shifts_done: + mov edi,esi + pop esi ebx + fill_new_segment: + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + cmp ecx,ebx + jbe length_for_inserting_ok + mov ecx,ebx + length_for_inserting_ok: + sub ebx,ecx + push edi + lea edi,[edi+SEGMENT_HEADER_LENGTH+edx] + or esi,esi + jz insert_blank_string + rep movsb + jmp string_inserted + insert_blank_string: + mov al,20h + rep stosb + string_inserted: + pop edi + mov edi,[edi] + and edi,not 1 + xor edx,edx + or ebx,ebx + jnz fill_new_segment + retn + attach_after_line_end: + call attach_empty_segments + mov ebx,esi + pop esi + or esi,esi + jnz attach_string + pop ecx + retn + attach_string: + mov ecx,[esp] + mov eax,SEGMENT_DATA_LENGTH + sub eax,edx + cmp eax,ecx + jae length_to_attach_ok + mov ecx,eax + length_to_attach_ok: + sub [esp],ecx + lea edi,[ebx+SEGMENT_HEADER_LENGTH+edx] + rep movsb + mov ecx,[esp] + jecxz attach_ok + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + mov edi,eax + or eax,1 + xchg eax,[ebx] + mov [edi],eax + or ebx,1 + mov [edi+4],ebx + mov ebx,edi + xor edx,edx + jmp attach_string + attach_ok: + pop eax + lea ecx,[ebx+SEGMENT_LENGTH] + sub ecx,edi + mov al,20h + rep stosb + void_insert: + retn + overwrite_in_line: + cmp edx,SEGMENT_DATA_LENGTH + jb position_for_overwrite_ok + call attach_empty_segments + position_for_overwrite_ok: + mov edi,esi + pop esi ebx + overwrite_segment: + xchg esi,edi + call store_segment_for_undo + xchg esi,edi + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + cmp ecx,ebx + jbe length_to_overwrite_ok + mov ecx,ebx + length_to_overwrite_ok: + sub ebx,ecx + push edi + lea edi,[edi+SEGMENT_HEADER_LENGTH+edx] + or esi,esi + jz overwrite_with_blank + rep movsb + jmp overwritten_ok + overwrite_with_blank: + mov al,20h + rep stosb + overwritten_ok: + pop edi + or ebx,ebx + jz overwrite_done + push esi + mov esi,[edi] + btr esi,0 + jc overwrite_existing_segment + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + mov edx,eax + or edx,1 + mov [edi],edx + mov [eax],esi + or edi,1 + mov [eax+4],edi + mov edi,eax + pop esi + xor edx,edx + cmp ebx,SEGMENT_DATA_LENGTH + jae overwrite_segment + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,ebx + lea edi,[edi+SEGMENT_HEADER_LENGTH+ebx] + mov al,20h + rep stosb + sub edi,SEGMENT_LENGTH + jmp overwrite_segment + overwrite_existing_segment: + call store_segment_for_undo + mov edi,esi + xor edx,edx + pop esi + jmp overwrite_segment + overwrite_done: + retn + +delete_from_line: + or ecx,ecx + jz nothing_to_delete + test [editor_mode],FEMODE_OVERWRITE + jnz clear_in_line + push ecx + add [caret_position],ecx + call get_caret_segment + pop ecx + sub [caret_position],ecx + cmp edx,SEGMENT_DATA_LENGTH + jae clear_rest_of_line + push esi edx + call get_caret_segment + call store_segment_for_undo + mov edi,esi + mov ebx,edx + pop edx esi + shift_over_deleted: + mov ecx,SEGMENT_DATA_LENGTH + mov eax,ecx + sub ecx,ebx + sub eax,edx + cmp eax,ecx + jae size_to_shift_ok + mov ecx,eax + size_to_shift_ok: + push esi edi + lea esi,[esi+SEGMENT_HEADER_LENGTH+edx] + lea edi,[edi+SEGMENT_HEADER_LENGTH+ebx] + add edx,ecx + add ebx,ecx + rep movsb + pop edi + cmp ebx,SEGMENT_DATA_LENGTH + je next_destination_segment + pop esi + cmp edx,SEGMENT_DATA_LENGTH + jne shift_over_deleted + mov esi,[esi] + btr esi,0 + jnc cut_line + xor edx,edx + jmp shift_over_deleted + next_destination_segment: + mov esi,[edi] + btr esi,0 + call store_segment_for_undo + mov edi,esi + pop esi + xor ebx,ebx + jmp shift_over_deleted + cut_line: + mov esi,edi + mov edx,ebx + jmp clear_from_here + clear_in_line: + xor esi,esi + jmp insert_into_line + clear_rest_of_line: + call get_caret_segment + cmp edx,SEGMENT_DATA_LENGTH + jae no_line_tail_to_clear + call store_segment_for_undo + clear_from_here: + lea edi,[esi+SEGMENT_HEADER_LENGTH+edx] + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + mov al,20h + rep stosb + mov ebx,esi + mov esi,[ebx] + remove_following_segments: + btr esi,0 + jnc rest_of_line_cleared + call store_freed_segment_for_undo + mov esi,[esi] + jmp remove_following_segments + rest_of_line_cleared: + mov [ebx],esi + nothing_to_delete: + retn + no_line_tail_to_clear: + mov esi,[esi] + retn + +remove_line: + mov esi,[caret_line] + mov esi,[esi] + or esi,esi + jnz cut_extra_segments + mov edi,[caret_line] + add edi,SEGMENT_HEADER_LENGTH + mov ecx,SEGMENT_DATA_LENGTH + mov al,20h + repe scasb + je line_removed + cut_extra_segments: + btr esi,0 + jnc replace_with_next_line + call store_freed_segment_for_undo + mov esi,[esi] + jmp cut_extra_segments + replace_with_next_line: + or esi,esi + jz clear_current_line + call store_segment_for_undo + mov ebx,esi + xchg esi,[caret_line] + mov eax,[esi+4] + mov [ebx+4],eax + call store_freed_segment_for_undo + call cancel_line + mov esi,[esi+4] + or esi,esi + jz line_removed + find_last_segment_of_previous_line: + mov eax,[esi] + btr eax,0 + jnc link_to_new_next_line + mov esi,eax + jmp find_last_segment_of_previous_line + link_to_new_next_line: + call store_segment_for_undo + mov [esi],ebx + line_removed: + mov [caret_position],0 + mov [selection_line],0 + retn + clear_current_line: + mov esi,[caret_line] + call store_segment_for_undo + mov dword [esi],0 + lea edi,[esi+SEGMENT_HEADER_LENGTH] + mov ecx,SEGMENT_DATA_LENGTH + mov al,20h + rep stosb + jmp line_removed + +duplicate_line: + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + mov esi,[caret_line] + mov edi,eax + mov [edi+4],esi + mov eax,[esi+8] + mov [edi+8],eax + call register_length + push edi + duplicate_segment: + mov ebx,edi + add edi,SEGMENT_HEADER_LENGTH + add esi,SEGMENT_HEADER_LENGTH + mov ecx,SEGMENT_DATA_LENGTH + rep movsb + sub esi,SEGMENT_LENGTH + mov eax,[esi] + btr eax,0 + jnc all_segments_duplicated + mov esi,eax + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + mov edi,eax + or eax,1 + mov [ebx],eax + or ebx,1 + mov [edi+4],ebx + jmp duplicate_segment + all_segments_duplicated: + inc [lines_count] + call store_segment_for_undo + mov [ebx],eax + pop ebx + mov [esi],ebx + mov esi,eax + or esi,esi + jz duplicate_done + call store_segment_for_undo + mov [esi+4],ebx + duplicate_done: + retn + +finish_edit: + mov esi,[caret_line] + call check_line_length + retn diff --git a/toolchain/fasmw17332/SOURCE/IDE/FASMD/FASMD.ASM b/toolchain/fasmw17332/SOURCE/IDE/FASMD/FASMD.ASM new file mode 100644 index 0000000..81d7d16 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/IDE/FASMD/FASMD.ASM @@ -0,0 +1,6756 @@ + +; flat assembler IDE for DOS/DPMI +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + + format MZ + heap 0 + stack stack_segment:stack_top-stack_bottom + entry loader:init + +segment loader use16 + +init: + + mov ax,3301h + xor dl,dl + int 21h + push ds cs + pop ds + mov ax,2524h + mov dx,dos_error_handler + int 21h + pop ds + + mov ax,1A00h + xor bx,bx + int 10h + cmp al,1Ah + jne short no_vga + cmp bl,8 + jne short no_vga + + mov ax,1687h + int 2Fh + or ax,ax ; DPMI installed? + jnz short no_dpmi + test bl,1 ; 32-bit programs supported? + jz short no_dpmi + mov word [cs:mode_switch],di + mov word [cs:mode_switch+2],es + mov bx,si ; allocate memory for DPMI data + mov ah,48h + int 21h + jnc switch_to_protected_mode + init_failed: + call init_error + db 'DPMI initialization failed.',0Dh,0Ah,0 + no_vga: + call init_error + db 'Color VGA adapter is required.',0Dh,0Ah,0 + no_dpmi: + call init_error + db '32-bit DPMI services are not available.',0Dh,0Ah,0 + init_error: + pop si + push cs + pop ds + display_error: + lodsb + test al,al + jz short error_finish + mov dl,al + mov ah,2 + int 21h + jmp short display_error + error_finish: + mov ax,4CFFh + int 21h + dos_error_handler: + mov al,3 + iret + switch_to_protected_mode: + mov es,ax + mov ds,[ds:2Ch] + mov ax,1 + call far [cs:mode_switch] ; switch to protected mode + jc init_failed + mov cx,1 + xor ax,ax + int 31h ; allocate descriptor for code + jc init_failed + mov si,ax + xor ax,ax + int 31h ; allocate descriptor for data + jc init_failed + mov di,ax + mov dx,cs + lar cx,dx + shr cx,8 + or cx,0C000h + mov bx,si + mov ax,9 + int 31h ; set code descriptor access rights + jc init_failed + mov dx,ds + lar cx,dx + shr cx,8 + or cx,0C000h + mov bx,di + int 31h ; set data descriptor access rights + jc init_failed + mov ecx,main + shl ecx,4 + mov dx,cx + shr ecx,16 + mov ax,7 + int 31h ; set data descriptor base address + jc init_failed + mov bx,si + int 31h ; set code descriptor base address + jc init_failed + mov cx,0FFFFh + mov dx,0FFFFh + mov ax,8 ; set segment limit to 4 GB + int 31h + jc init_failed + mov bx,di + int 31h + jc init_failed + mov ax,ds + mov ds,di + mov [main_selector],di + mov [psp_selector],es + mov [environment_selector],ax + cli + mov ss,di + mov esp,stack_top + sti + mov es,di + mov cx,1 + xor ax,ax + int 31h ; allocate descriptor for BIOS data segment + jc init_failed + mov bx,ax + lar cx,[environment_selector] + shr cx,8 + mov ax,9 + int 31h ; set descriptor access rights + jc init_failed + xor cx,cx + mov dx,400h + mov ax,7 + int 31h ; set base address of BIOS data segment + jc init_failed + xor cx,cx + mov dx,0FFh + mov ax,8 + int 31h ; set limit of BIOS data segment + jc init_failed + mov fs,bx + mov [bios_selector],bx + mov cx,1 + xor ax,ax + int 31h ; allocate descriptor for video segment + jc init_failed + mov bx,ax + lar cx,[environment_selector] + shr cx,8 + mov ax,9 + int 31h ; set descriptor access rights + jc init_failed + mov cx,0Bh + mov dx,8000h + mov ax,7 + int 31h ; set base address of video segment + jc init_failed + xor cx,cx + mov dx,4000-1 + mov ax,8 + int 31h ; set limit of video segment + jc init_failed + mov gs,bx + mov [video_selector],bx + push si + push start + retf + + mode_switch dd ? + +segment main use32 + + start: + cld + + call init_video + jc startup_failed + + call init_editor_memory + jc startup_failed + + xor eax,eax + mov [next_instance],eax + mov [previous_instance],eax + mov [file_path],eax + + mov ecx,1000h + mov [line_buffer_size],ecx + call get_memory + or eax,eax + jz startup_failed + mov [line_buffer],eax + mov [line_buffer_handle],ebx + + mov [stack_limit],stack_bottom + + mov edi,upper_case_table + xor al,al + mov ecx,80h + prepare_case_table: + stosb + inc al + loop prepare_case_table + make_extended_case_table: + push eax + mov dl,al + mov ax,6520h + int 21h + mov al,[esp] + jc upper_case_character_ok + mov al,dl + upper_case_character_ok: + stosb + pop eax + inc al + jnz make_extended_case_table + mov esi,upper_case_table+'A' + mov edi,upper_case_table+'a' + mov ecx,26 + rep movsb + xor al,al + mov edi,lower_case_table + prepare_lower_case_table: + stosb + inc al + jnz prepare_lower_case_table + mov esi,lower_case_table+'a' + mov edi,lower_case_table+'A' + mov ecx,26 + rep movsb + mov eax,80h + xor edx,edx + make_lower_case_table: + mov dl,[upper_case_table+eax] + cmp al,dl + je lower_case_character_ok + cmp dl,80h + jb lower_case_character_ok + mov [lower_case_table+edx],al + lower_case_character_ok: + inc al + jnz make_lower_case_table + mov edi,characters + xor al,al + prepare_characters_table: + stosb + inc al + jnz prepare_characters_table + mov esi,characters+'a' + mov edi,characters+'A' + mov ecx,26 + rep movsb + mov edi,characters + mov esi,symbol_characters+1 + movzx ecx,byte [esi-1] + xor eax,eax + convert_table: + lodsb + mov byte [edi+eax],0 + loop convert_table + mov [selected_character],'p' + + call get_low_memory + + push ds + mov ds,[environment_selector] + xor esi,esi + mov edi,ini_path + skip_environment: + lodsb + test al,al + jnz skip_environment + lodsb + test al,al + jnz skip_environment + add esi,2 + copy_program_path: + lodsb + stosb + test al,al + jnz copy_program_path + pop ds + dec edi + mov edx,edi + find_extension_start: + cmp edi,ini_path + je attach_extension + cmp byte [edi-1],'.' + je replace_extension + cmp byte [edi-1],'/' + je attach_extension + dec edi + jmp find_extension_start + attach_extension: + mov edi,edx + mov al,'.' + stosb + replace_extension: + mov [ini_extension],edi + + xor eax,eax + mov [ini_data],eax + mov [main_project_file],eax + mov [clipboard],eax + mov [current_operation],al + mov [find_flags],eax + mov [command_flags],al + + call load_configuration + + call update_positions + call switch_to_ide_screen + + mov esi,81h + process_arguments: + push ds + mov ds,[psp_selector] + mov edi,filename_buffer + find_argument: + lodsb + cmp al,20h + je find_argument + cmp al,9 + je find_argument + cmp al,22h + je quoted_argument + dec esi + copy_argument: + lodsb + cmp al,20h + je argument_end + cmp al,9 + je argument_end + cmp al,0Dh + je argument_end + stosb + jmp copy_argument + quoted_argument: + lodsb + cmp al,0Dh + je argument_end + stosb + cmp al,22h + jne quoted_argument + lodsb + cmp al,22h + je quoted_argument + dec edi + argument_end: + dec esi + pop ds + cmp edi,filename_buffer + je main_loop + xor al,al + stosb + push esi + mov edx,filename_buffer + call load_file + pop esi + jmp process_arguments + + main_loop: + + call update_cursor + call update_screen + + xor al,al + xchg [current_operation],al + mov [last_operation],al + mov [was_selection],1 + mov eax,[selection_line] + or eax,eax + jz no_selection + cmp eax,[caret_line] + jne get_command + mov eax,[selection_position] + cmp eax,[caret_position] + jne get_command + no_selection: + mov [was_selection],0 + mov eax,[caret_line] + mov [selection_line],eax + mov eax,[caret_position] + mov [selection_position],eax + mov eax,[caret_line_number] + mov [selection_line_number],eax + get_command: + call wait_for_input + cmp ah,1 + je close_editor + jb character + cmp al,0Eh + je new_editor + cmp ah,94h + je switch_editor + cmp ah,0A5h + je switch_editor + cmp ah,3Bh + je open_help + cmp ah,3Ch + je save_current + cmp ah,55h + je save_as + cmp ah,3Eh + je open_file + cmp ah,3Fh + je goto + cmp ah,41h + je search + cmp ah,5Ah + je search_next + cmp ah,64h + je replace + cmp ah,43h + je compile_and_run + cmp ah,66h + je compile + cmp ah,65h + je build_symbols + cmp ah,5Ch + je assign_to_compiler + cmp ah,59h + je toggle_readonly + cmp ah,63h + je calculator + cmp ah,6Ch + je show_user_screen + cmp ah,44h + je options + cmp ah,3Dh + je search_next + test byte [fs:17h],1000b + jz no_alt + cmp ah,2Dh + je close_all + cmp ah,0Eh + je undo + cmp ah,0A3h + je disable_undo + cmp ah,98h + je scroll_up + cmp ah,0A0h + je scroll_down + cmp ah,9Bh + je scroll_left + cmp ah,9Dh + je scroll_right + no_alt: + or al,al + jz no_ascii + cmp al,0E0h + jne ascii + no_ascii: + cmp ah,4Bh + je left_key + cmp ah,4Dh + je right_key + cmp ah,48h + je up_key + cmp ah,50h + je down_key + cmp ah,47h + je home_key + cmp ah,4Fh + je end_key + cmp ah,77h + je screen_home + cmp ah,75h + je screen_end + cmp ah,73h + je word_left + cmp ah,74h + je word_right + cmp ah,8Dh + je word_left + cmp ah,91h + je word_right + cmp ah,49h + je pgup_key + cmp ah,51h + je pgdn_key + cmp ah,84h + je text_home + cmp ah,76h + je text_end + cmp ah,52h + je ins_key + cmp ah,0A2h + je switch_blocks + cmp ah,40h + je f6_key + cmp ah,93h + je block_delete + cmp ah,92h + je block_copy + cmp ah,53h + je del_key + cmp ah,78h + jb get_command + cmp ah,80h + ja get_command + sub ah,77h + movzx ecx,ah + jmp select_editor + ascii: + cmp al,7Fh + je word_back + cmp al,20h + jae character + cmp al,8 + je backspace_key + cmp al,9 + je tab_key + cmp al,0Dh + je enter_key + cmp al,19h + je ctrl_y_key + cmp al,1Ah + je undo + cmp al,18h + je block_cut + cmp al,3 + je block_copy + cmp al,16h + je block_paste + cmp al,0Fh + je open_file + cmp al,13h + je save_current + cmp al,6 + je search + cmp al,7 + je goto + cmp al,1 + je select_all + cmp al,2 + je ascii_table + jmp get_command + character: + test [editor_mode],FEMODE_READONLY + jnz get_command + cmp [was_selection],0 + je no_selection_to_replace + call store_status_for_undo + test [editor_style],FES_SECURESEL + jnz character_undo_ok + push eax + call delete_block + pop eax + call put_character + call finish_edit + mov [selection_line],0 + jmp text_modified + no_selection_to_replace: + mov [current_operation],20h + cmp [last_operation],20h + jne character_undopoint + mov edx,[unmodified_state] + cmp edx,[undo_data] + jne character_undo_ok + or [unmodified_state],-1 + jmp character_undo_ok + character_undopoint: + call store_status_for_undo + character_undo_ok: + call put_character + call finish_edit + mov [selection_line],0 + jmp text_modified + tab_key: + test [editor_mode],FEMODE_READONLY + jnz get_command + call store_status_for_undo + cmp [was_selection],0 + je tab_securesel + test [editor_style],FES_SECURESEL + jnz tab_securesel + call delete_block + tab_securesel: + call tabulate + mov [selection_line],0 + call finish_edit + jmp text_modified + enter_key: + test [editor_mode],FEMODE_READONLY + jnz get_command + call store_status_for_undo + cmp [was_selection],0 + je enter_secureselection_ok + test [editor_style],FES_SECURESEL + jnz enter_secureselection_ok + call delete_block + enter_secureselection_ok: + call carriage_return + mov [selection_line],0 + test [editor_mode],FEMODE_OVERWRITE + jnz text_modified + call finish_edit + jmp text_modified + backspace_key: + test [editor_mode],FEMODE_READONLY + jnz get_command + test byte [fs:17h],100b + jnz replace + cmp [was_selection],0 + je no_selection_to_clear + test [editor_style],FES_SECURESEL + jz block_delete + no_selection_to_clear: + cmp [caret_position],0 + je line_back + mov [current_operation],8 + cmp [last_operation],8 + jne backspace_undopoint + mov edx,[unmodified_state] + cmp edx,[undo_data] + jne undo_back_ok + or [unmodified_state],-1 + jmp undo_back_ok + backspace_undopoint: + call store_status_for_undo + undo_back_ok: + dec [caret_position] + call delete_character + call finish_edit + mov [selection_line],0 + jmp text_modified + line_back: + test [editor_mode],FEMODE_OVERWRITE + jnz get_command + mov esi,[caret_line] + mov esi,[esi+4] + or esi,esi + jz get_command + call store_status_for_undo + mov [caret_line],esi + dec [caret_line_number] + call check_line_length + mov [caret_position],ecx + call cut_line_break + call finish_edit + mov [selection_line],0 + jmp text_modified + word_back: + call store_status_for_undo + push [caret_position] + mov esi,[caret_line] + xor eax,eax + xchg eax,[esi+4] + push eax + call move_to_previous_word + pop eax + mov esi,[caret_line] + mov [esi+4],eax + pop ecx + sub ecx,[caret_position] + call delete_from_line + call finish_edit + jmp text_modified + del_key: + test byte [fs:17h],11b + jnz block_cut + test [editor_mode],FEMODE_READONLY + jnz get_command + cmp [was_selection],0 + je no_selection_on_del + test [editor_style],FES_SECURESEL + jz block_delete + no_selection_on_del: + mov esi,[caret_line] + test [editor_mode],FEMODE_OVERWRITE + jnz delete_char + call check_line_length + cmp ecx,[caret_position] + ja delete_char + cmp dword [esi],0 + je get_command + call store_status_for_undo + call cut_line_break + call finish_edit + mov [selection_line],0 + jmp text_modified + delete_char: + mov [current_operation],0E0h + cmp [last_operation],0E0h + je undo_delete_ok + call store_status_for_undo + undo_delete_ok: + call delete_character + call finish_edit + mov [selection_line],0 + jmp text_modified + ctrl_y_key: + test [editor_mode],FEMODE_READONLY + jnz get_command + call store_status_for_undo + call remove_line + jmp text_modified + f6_key: + test [editor_mode],FEMODE_READONLY + jnz get_command + call store_status_for_undo + call duplicate_line + jmp text_modified + left_key: + cmp [caret_position],0 + jle text_modified + dec [caret_position] + jmp moved_caret + right_key: + mov eax,[caret_position] + cmp eax,[maximum_position] + jae text_modified + inc [caret_position] + jmp moved_caret + up_key: + call move_line_up + jmp moved_caret + down_key: + call move_line_down + jmp moved_caret + home_key: + mov [caret_position],0 + jmp moved_caret + end_key: + call move_to_line_end + jmp moved_caret + screen_home: + mov eax,[window_line] + mov [caret_line],eax + mov eax,[window_line_number] + mov [caret_line_number],eax + jmp moved_caret + screen_end: + mov eax,[window_line_number] + add eax,[window_height] + dec eax + call find_line + mov [caret_line],esi + mov [caret_line_number],ecx + jmp moved_caret + pgup_key: + call move_page_up + jmp moved_caret + pgdn_key: + call move_page_down + jmp moved_caret + text_home: + mov eax,[first_line] + mov [caret_line],eax + mov [caret_line_number],1 + jmp moved_caret + text_end: + or eax,-1 + call find_line + mov [caret_line],esi + mov [caret_line_number],ecx + jmp moved_caret + word_left: + call move_to_previous_word + jmp moved_caret + word_right: + call get_caret_segment + call move_to_next_word + jmp moved_caret + scroll_left: + cmp [window_position],0 + je main_loop + dec [window_position] + jmp moved_window + scroll_right: + inc [window_position] + jmp moved_window + scroll_up: + mov esi,[window_line] + mov esi,[esi+4] + or esi,esi + jz main_loop + mov [window_line],esi + dec [window_line_number] + jmp moved_window + scroll_down: + mov esi,[window_line] + find_next_window_line: + mov esi,[esi] + btr esi,0 + jc find_next_window_line + or esi,esi + jz main_loop + mov [window_line],esi + inc [window_line_number] + jmp moved_window + ins_key: + and byte [fs:18h],not 80h + test byte [fs:17h],11b + jnz block_paste + switch_mode: + xor [editor_mode],FEMODE_OVERWRITE + jmp main_loop + switch_blocks: + xor [editor_mode],FEMODE_VERTICALSEL + jmp main_loop + block_delete: + test [editor_mode],FEMODE_READONLY + jnz get_command + cmp [was_selection],0 + je get_command + call store_status_for_undo + call delete_block + mov [selection_line],0 + jmp operation_done + block_copy: + cmp [was_selection],0 + je get_command + call copy_to_clipboard + jmp get_command + copy_to_clipboard: + cmp [clipboard],0 + je allocate_clipboard + mov ebx,[clipboard_handle] + call release_memory + allocate_clipboard: + call get_block_length + inc ecx + call get_memory + mov [clipboard],eax + mov [clipboard_handle],ebx + or eax,eax + jz not_enough_memory + mov edi,[clipboard] + call copy_block + retn + block_cut: + cmp [was_selection],0 + je get_command + call copy_to_clipboard + jmp block_delete + block_paste: + test [editor_mode],FEMODE_READONLY + jnz get_command + call store_status_for_undo + cmp [was_selection],0 + je paste_secureselection_ok + test [editor_style],FES_SECURESEL + jnz paste_secureselection_ok + call delete_block + paste_secureselection_ok: + mov esi,[clipboard] + or esi,esi + jz operation_done + call insert_block + jc paste_failed + test [editor_style],FES_SECURESEL + jz no_selection_after_paste + mov eax,[caret_line] + mov ecx,[caret_line_number] + mov edx,[caret_position] + xchg eax,[selection_line] + xchg ecx,[selection_line_number] + xchg edx,[selection_position] + mov [caret_line],eax + mov [caret_line_number],ecx + mov [caret_position],edx + jmp operation_done + no_selection_after_paste: + mov [selection_line],0 + jmp operation_done + paste_failed: + call undo_changes + jmp operation_done + undo: + test [editor_mode],FEMODE_READONLY + jnz get_command + test [editor_mode],FEMODE_NOUNDO + jnz enable_undo + test byte [fs:17h],11b + jnz redo + mov eax,[undo_data] + test eax,eax + jz get_command + call undo_changes + jmp operation_done + redo: + test [editor_mode],FEMODE_READONLY + jnz get_command + mov eax,[redo_data] + test eax,eax + jz get_command + call redo_changes + jmp operation_done + enable_undo: + and [editor_mode],not FEMODE_NOUNDO + jmp main_loop + disable_undo: + call clear_redo_data + call clear_undo_data + or [editor_mode],FEMODE_NOUNDO + jmp operation_done + toggle_readonly: + xor [editor_mode],FEMODE_READONLY + jmp main_loop + select_all: + or eax,-1 + call find_line + mov [caret_line],esi + mov [caret_line_number],ecx + call check_line_length + mov [caret_position],ecx + mov eax,1 + call find_line + mov [selection_line],esi + mov [selection_line_number],ecx + mov [selection_position],0 + jmp operation_done + ascii_table: + call ascii_table_window + jc main_loop + test al,al + jz main_loop + cmp al,1Ah + je main_loop + jmp character + + moved_caret: + test byte [fs:17h],11b + jnz operation_done + mov [selection_line],0 + jmp operation_done + text_modified: + cmp [was_selection],0 + jne operation_done + mov [selection_line],0 + operation_done: + call update_positions + call let_caret_appear + call update_window + jmp main_loop + moved_window: + call update_positions + cmp [was_selection],0 + jne main_loop + mov [selection_line],0 + jmp main_loop + + new_editor: + call create_editor_instance + jmp main_loop + close_editor: + or [command_flags],8 + jmp closing_loop + close_all: + and [command_flags],not 8 + closing_loop: + mov eax,[undo_data] + cmp eax,[unmodified_state] + je do_close + mov esi,[file_path] + call get_file_title + mov ebx,esi + mov esi,_saving_question + mov eax,2 shl 24 + mov ax,[message_box_colors] + mov [first_button],_yes + mov [second_button],_no + call message_box + cmp eax,1 + jb main_loop + ja do_close + cmp [file_path],0 + jne save_before_closing + call get_saving_path + jc main_loop + save_before_closing: + call save_file + jc main_loop + do_close: + call remove_editor_instance + jc shutdown + test [command_flags],8 + jnz main_loop + call update_cursor + call update_screen + jmp closing_loop + switch_editor: + test byte [fs:17h],11b + jnz previous_editor + mov eax,[next_instance] + or eax,eax + jnz do_switch + mov eax,[previous_instance] + or eax,eax + jz get_command + find_first_editor: + mov ebx,[eax+SEGMENT_HEADER_LENGTH+previous_instance-editor_data] + or ebx,ebx + jz do_switch + mov eax,ebx + jmp find_first_editor + do_switch: + call switch_editor_instance + jmp main_loop + previous_editor: + mov eax,[previous_instance] + or eax,eax + jnz do_switch + mov eax,[next_instance] + or eax,eax + jz get_command + find_last_editor: + mov ebx,[eax+SEGMENT_HEADER_LENGTH+next_instance-editor_data] + or ebx,ebx + jz do_switch + mov eax,ebx + jmp find_last_editor + select_editor: + mov eax,[editor_memory] + mov edx,[previous_instance] + prepare_for_editor_counting: + or edx,edx + jz find_selected_editor + mov eax,edx + mov edx,[edx+SEGMENT_HEADER_LENGTH+previous_instance-editor_data] + jmp prepare_for_editor_counting + find_selected_editor: + dec ecx + jz selected_editor_found + mov eax,[eax+SEGMENT_HEADER_LENGTH+next_instance-editor_data] + or eax,eax + jz get_command + jmp find_selected_editor + selected_editor_found: + cmp eax,[editor_memory] + je get_command + jmp do_switch + show_user_screen: + call switch_to_user_screen + mov ah,10h + int 16h + call switch_to_ide_screen + jmp main_loop + + save_current: + test [editor_mode],FEMODE_READONLY + jnz save_as + cmp [file_path],0 + jne do_save + save_as: + call get_saving_path + jc main_loop + do_save: + call save_file + jmp main_loop + open_file: + mov esi,_open + call file_open_dialog + jc main_loop + call load_file + jmp main_loop + open_help: + mov edi,[ini_extension] + mov eax,'TXT' + stosd + mov edx,ini_path + call load_file + or [editor_mode],FEMODE_READONLY + jmp main_loop + goto: + call goto_dialog + jc main_loop + or edx,edx + jz goto_position_ok + dec edx + mov [caret_position],edx + mov [selection_position],edx + goto_position_ok: + or ecx,ecx + jz goto_line_ok + mov eax,ecx + call find_line + mov [caret_line],esi + mov [selection_line],esi + mov [caret_line_number],ecx + mov [selection_line_number],ecx + goto_line_ok: + call update_positions + call let_caret_appear + call update_window + jmp main_loop + search: + call find_dialog + jc main_loop + call find_first + jc not_found + call show_found_text + jmp main_loop + not_found: + call update_screen + mov edi,buffer+1000h + push edi + call get_search_text + jc main_loop + mov edi,buffer + mov esi,_not_found_after + test [search_flags],FEFIND_BACKWARD + jz make_not_found_message + mov esi,_not_found_before + make_not_found_message: + mov ebx,esp + call sprintf + pop eax + call release_search_data + mov esi,buffer + mov ebx,_find + movzx eax,[message_box_colors] + call message_box + jmp main_loop + show_found_text: + mov eax,[caret_position] + xchg eax,[selection_position] + mov [caret_position],eax + call update_positions + call let_caret_appear + call update_window + mov eax,[caret_position] + xchg eax,[selection_position] + mov [caret_position],eax + ret + replace: + call replace_dialog + jc main_loop + mov [replaces_count],0 + push edi + call find_first + jc not_found + call store_status_for_undo + replace_loop: + test [command_flags],1 + jz do_replace + call show_found_text + call let_caret_appear + call update_window + call update_screen + mov ebx,_replace + mov esi,_replace_prompt + mov eax,2 shl 24 + mov ax,[message_box_colors] + mov [first_button],_yes + mov [second_button],_no + or [command_flags],80h + call message_box + and [command_flags],not 80h + cmp eax,1 + jb replacing_finished + ja replace_next + do_replace: + push [caret_line_number] + push [caret_position] + call delete_block + pop edx ecx + cmp ecx,[caret_line_number] + jne simple_replace + cmp edx,[caret_position] + jne simple_replace + mov esi,[esp] + call insert_block + mov esi,[caret_line] + mov ecx,[caret_line_number] + mov edx,[caret_position] + xchg esi,[selection_line] + xchg ecx,[selection_line_number] + xchg edx,[selection_position] + mov [caret_line],esi + mov [caret_line_number],ecx + mov [caret_position],edx + jmp replace_done + simple_replace: + mov esi,[esp] + call insert_block + replace_done: + inc [replaces_count] + replace_next: + call find_next + jnc replace_loop + replacing_finished: + call release_search_data + call let_caret_appear + call update_window + call update_screen + mov edi,buffer + mov esi,_replaces_made + mov ebx,replaces_count + call sprintf + mov esi,buffer + mov ebx,_find + movzx eax,[message_box_colors] + call message_box + jmp main_loop + search_next: + cmp [search_data],0 + je main_loop + call find_next + jc not_found + call show_found_text + jmp main_loop + build_symbols: + and [command_flags],not 2 + or [command_flags],4 + jmp do_compile + compile: + and [command_flags],not (2 or 4) + jmp do_compile + compile_and_run: + and [command_flags],not 4 + or [command_flags],2 + do_compile: + push [editor_memory] + mov eax,[main_project_file] + or eax,eax + jz got_main_file + call switch_editor_instance + got_main_file: + cmp [file_path],0 + jne main_file_path_ok + call update_screen + call get_saving_path + jc main_loop + call update_screen + main_file_path_ok: + mov eax,[editor_memory] + push eax + mov edx,[previous_instance] + test edx,edx + jz save_all_files + mov eax,edx + find_first_to_save: + mov edx,[eax+SEGMENT_HEADER_LENGTH+previous_instance-editor_data] + or edx,edx + jz save_all_files + mov eax,edx + jmp find_first_to_save + save_all_files: + call switch_editor_instance + cmp [file_path],0 + je save_next + mov eax,[undo_data] + cmp eax,[unmodified_state] + je save_next + call save_file + jc main_loop + save_next: + mov eax,[next_instance] + or eax,eax + jnz save_all_files + pop eax + call switch_editor_instance + mov edi,buffer+3000h + mov byte [edi],0 + call get_current_directory + mov esi,[file_path] + mov edi,buffer + mov ebx,edi + copy_directory_path: + lodsb + or al,al + jz directory_path_ok + stosb + cmp al,'\' + jne copy_directory_path + mov ebx,edi + jmp copy_directory_path + directory_path_ok: + mov byte [ebx],0 + mov esi,buffer + call go_to_directory + mov eax,[file_path] + mov [input_file],eax + mov [symbols_file],0 + test [command_flags],4 + jz symbols_file_name_ok + mov edi,buffer+2000h + mov [symbols_file],edi + mov esi,eax + xor ebx,ebx + copy_file_name: + lodsb + stosb + test al,al + jz file_name_copied + cmp al,'.' + jne copy_file_name + mov ebx,edi + jmp copy_file_name + file_name_copied: + test ebx,ebx + jz attach_fas_extension + mov edi,ebx + attach_fas_extension: + dec edi + mov eax,'.fas' + stosd + xor al,al + stosb + symbols_file_name_ok: + pop eax + call switch_editor_instance + mov cx,1000h + mov ah,1 + int 10h + mov esi,_compile + mov cx,0316h + mov ah,[window_colors] + call draw_centered_window + add edi,2 + mov [progress_offset],edi + mov eax,[memory_limit] + test eax,eax + jnz allocate_memory + mov ax,500h + mov edi,buffer + int 31h + mov eax,[edi] + allocate_memory: + mov ecx,eax + mov edx,eax + shr edx,2 + sub eax,edx + mov [memory_end],eax + mov [additional_memory_end],edx + call get_memory + or eax,eax + jnz memory_allocated + mov eax,[additional_memory_end] + shl eax,1 + cmp eax,4000h + jb not_enough_memory + jmp allocate_memory + get_current_directory: + mov ah,19h + int 21h + mov bl,al + mov dl,al + inc dl + xor esi,esi + mov ax,7147h + call dos_int + jnc got_current_directory + cmp ax,7100h + je get_current_directory_short + invalid_current_directory: + stc + ret + get_current_directory_short: + mov ah,47h + call dos_int + jc invalid_current_directory + got_current_directory: + cmp byte [buffer],0 + je drive_prefix + cmp byte [buffer+1],':' + je copy_current_directory + cmp word [buffer],'\\' + je copy_current_directory + drive_prefix: + mov al,bl + add al,'A' + mov ah,':' + stosw + mov al,'\' + stosb + copy_current_directory: + mov esi,buffer + call copy_asciiz + clc + ret + go_to_directory: + cmp esi,buffer + je directory_path_ready + mov edi,buffer + call copy_asciiz + mov esi,buffer + directory_path_ready: + mov ah,0Eh + mov dl,[buffer] + sub dl,'A' + jc current_directory_ok + cmp dl,'Z'-'A' + jbe change_current_drive + sub dl,'a'-'A' + change_current_drive: + int 21h + xor dx,dx + mov ax,713Bh + call dos_int + cmp ax,7100h + jne current_directory_ok + mov ah,3Bh + call dos_int + current_directory_ok: + ret + memory_allocated: + mov [allocated_memory],ebx + mov [memory_start],eax + add eax,[memory_end] + mov [memory_end],eax + mov [additional_memory],eax + add [additional_memory_end],eax + xor eax,eax + mov [initial_definitions],eax + mov [output_file],eax + mov [display_length],eax + mov ax,204h + mov bl,9 + int 31h + mov dword [keyboard_handler],edx + mov word [keyboard_handler+4],cx + mov ax,205h + mov bl,9 + mov cx,cs + mov edx,aborting_handler + int 31h + mov eax,[fs:6Ch] + mov [start_time],eax + call preprocessor + call draw_progress_segment + call parser + call draw_progress_segment + call assembler + call draw_progress_segment + call formatter + call draw_progress_segment + mov ax,205h + mov bl,9 + mov edx,dword [keyboard_handler] + mov cx,word [keyboard_handler+4] + int 31h + test [command_flags],2 + jnz execute + mov esi,buffer+3000h + call go_to_directory + call show_display_buffer + call update_screen + mov edi,buffer + movzx eax,[current_pass] + inc eax + call number_as_text + mov eax,' pas' + stosd + mov eax,'ses,' + stosd + mov al,20h + stosb + mov eax,[fs:6Ch] + sub eax,[start_time] + mov ebx,100 + mul ebx + mov ebx,182 + div ebx + or eax,eax + jz show_bytes_count + xor edx,edx + mov ebx,10 + div ebx + push edx + call number_as_text + mov al,'.' + stosb + pop eax + call number_as_text + mov eax,' sec' + stosd + mov eax,'onds' + stosd + mov ax,', ' + stosw + show_bytes_count: + mov eax,[written_size] + call number_as_text + mov eax,' byt' + stosd + mov eax,'es.' + stosd + mov ebx,[allocated_memory] + call release_memory + mov esi,buffer + mov ebx,_compile + movzx eax,[message_box_colors] + mov [first_button],_ok + mov [second_button],_get_display + cmp [display_length],0 + je show_compilation_summary + or eax,2 shl 24 + show_compilation_summary: + call message_box + cmp eax,2 + jb main_loop + cmp [clipboard],0 + je get_display_to_clipboard + mov ebx,[clipboard_handle] + call release_memory + get_display_to_clipboard: + mov ecx,[display_length] + inc ecx + call get_memory + mov [clipboard_handle],ebx + mov [clipboard],eax + or eax,eax + jz not_enough_memory + xor esi,esi + mov edi,eax + mov ecx,[display_length] + push ds + mov ds,[low_memory_selector] + rep movsb + pop ds + xor al,al + stosb + jmp main_loop + execute: + mov edx,[output_file] + call adapt_path + mov ebx,[allocated_memory] + call release_memory + cmp [output_format],3 + ja cannot_execute + call release_low_memory + call switch_to_user_screen + call close_video + mov edi,buffer+200h + lea edx,[edi-buffer] + mov ax,0D00h + stosw + lea esi,[edi-buffer] + xor al,al + stosb + mov al,20h + mov ecx,11 + rep stosb + xor al,al + mov ecx,25 + rep stosb + lea ebx,[edi-buffer] + xor eax,eax + stosw + mov ax,buffer_segment + shl eax,16 + mov ax,dx + stosd + mov ax,si + stosd + stosd + mov ax,4B00h + xor dx,dx + call dos_int + mov esi,buffer+3000h + call go_to_directory + call init_video + jc startup_failed + call switch_to_ide_screen + call get_low_memory + jmp main_loop + cannot_execute: + mov esi,buffer+3000h + call go_to_directory + mov esi,_not_executable + mov ebx,_error + movzx eax,[error_box_colors] + call message_box + jmp main_loop + draw_progress_segment: + mov eax,[progress_offset] + mov ecx,4 + draw_progress_filler: + mov byte [gs:eax],254 + add eax,2 + loop draw_progress_filler + mov [progress_offset],eax + ret + aborting_handler: + push eax + in al,60h + cmp al,1 + jne no_abort + mov dword [esp+4],abort_compiling + mov word [esp+4+4],cs + no_abort: + pop eax + jmp pword [cs:keyboard_handler] + abort_compiling: + cli + mov ax,[cs:main_selector] + mov esp,stack_top + mov ss,ax + mov ds,ax + mov es,ax + mov fs,[bios_selector] + mov gs,[video_selector] + mov ax,205h + mov bl,9 + mov edx,dword [keyboard_handler] + mov cx,word [keyboard_handler+4] + int 31h + sti + discard_keyboard_buffer: + mov ah,11h + int 16h + jz keyboard_buffer_ok + mov ah,10h + int 16h + jmp discard_keyboard_buffer + keyboard_buffer_ok: + mov ebx,[allocated_memory] + call release_memory + mov esi,buffer+3000h + call go_to_directory + jmp main_loop + assign_to_compiler: + mov eax,[editor_memory] + xchg eax,[main_project_file] + cmp eax,[editor_memory] + jne main_loop + mov [main_project_file],0 + jmp main_loop + calculator: + call calculator_window + jmp main_loop + options: + push [editor_style] + call options_dialog + pop eax + jnc main_loop + mov [editor_style],eax + jmp main_loop + + startup_failed: + mov esi,_startup_failed + error_message_loop: + lodsb + or al,al + jz error_message_ok + mov dl,al + mov ah,2 + int 21h + jmp error_message_loop + error_message_ok: + mov ax,4C0Fh + int 21h + + init_video: + call check_video_mode + mov bx,gs + movzx edx,byte [fs:4Ah] + mov [screen_width],edx + shl edx,1 + mov [video_pitch],edx + movzx eax,byte [fs:84h] + inc eax + mov [screen_height],eax + imul edx,eax + push edx + dec edx + shld ecx,edx,16 + mov ax,8 + int 31h + jc video_init_failed + pop ecx + call get_memory + jc video_init_failed + mov [video_storage],eax + mov [video_storage_handle],ebx + clc + ret + video_init_failed: + stc + ret + check_video_mode: + test byte [fs:65h],110b + jnz set_video_mode + cmp byte [fs:4Ah],80 + jb set_video_mode + ret + set_video_mode: + mov ax,3 + int 10h + ret + close_video: + mov ebx,[video_storage_handle] + call release_memory + ret + switch_to_ide_screen: + call check_video_mode + xor esi,esi + mov edi,[video_storage] + mov ecx,[video_pitch] + imul ecx,[screen_height] + rep movs byte [es:edi],[gs:esi] + mov ah,3 + xor bh,bh + int 10h + mov [stored_cursor],cx + mov [stored_cursor_position],dx + mov ah,0Fh + int 10h + mov [stored_page],bh + mov ax,0500h + int 10h + mov al,[fs:65h] + mov [stored_mode],al + mov ax,1003h + xor bx,bx + int 10h + mov eax,[screen_width] + mov [window_width],eax + mov eax,[screen_height] + sub eax,2 + mov [window_height],eax + call update_window + ret + switch_to_user_screen: + push es gs + pop es + mov esi,[video_storage] + xor edi,edi + mov ecx,[video_pitch] + imul ecx,[screen_height] + rep movs byte [es:edi],[ds:esi] + mov ah,1 + mov cx,[stored_cursor] + int 10h + mov ah,2 + xor bh,bh + mov dx,[stored_cursor_position] + int 10h + mov ah,5 + mov al,[stored_page] + int 10h + mov ax,1003h + xor bh,bh + mov bl,[stored_mode] + shr bl,5 + and bl,1 + int 10h + pop es + ret + + create_editor_instance: + call flush_editor_data + mov esi,[editor_memory] + find_last_instance: + mov eax,[esi+SEGMENT_HEADER_LENGTH+next_instance-editor_data] + or eax,eax + jz attach_new_instance + mov esi,eax + jmp find_last_instance + attach_new_instance: + push esi + call init_editor_memory + pop esi + jc not_enough_memory + mov eax,[editor_memory] + xchg eax,[esi+SEGMENT_HEADER_LENGTH+next_instance-editor_data] + mov [next_instance],eax + mov [previous_instance],esi + xor eax,eax + mov [file_path],eax + flush_editor_data: + mov edi,[editor_memory] + test edi,edi + jz flush_ok + add edi,SEGMENT_HEADER_LENGTH + mov esi,editor_data + mov ecx,editor_data_size + rep movsb + flush_ok: + ret + switch_editor_instance: + call flush_editor_data + cmp eax,[editor_memory] + je editor_switch_ok + mov [editor_memory],eax + lea esi,[eax+SEGMENT_HEADER_LENGTH] + mov edi,editor_data + mov ecx,editor_data_size + rep movsb + editor_switch_ok: + call update_positions + ret + remove_editor_instance: + mov eax,[editor_memory] + xor eax,[main_project_file] + jnz main_project_file_ok + mov [main_project_file],eax + main_project_file_ok: + mov esi,[previous_instance] + mov edi,[next_instance] + mov eax,edi + or edi,edi + jz next_instance_links_ok + mov [edi+SEGMENT_HEADER_LENGTH+previous_instance-editor_data],esi + next_instance_links_ok: + or esi,esi + jz previous_instance_links_ok + mov [esi+SEGMENT_HEADER_LENGTH+next_instance-editor_data],edi + mov eax,esi + previous_instance_links_ok: + push eax + call release_editor_memory + mov eax,[file_path] + or eax,eax + jz file_path_released + mov ebx,[file_path_handle] + call release_memory + file_path_released: + pop eax + or eax,eax + jz no_instance_left + call switch_editor_instance + clc + ret + no_instance_left: + stc + ret + + load_file: + push edx + push [editor_memory] + call get_full_pathname + push esi + call flush_editor_data + mov esi,[esp] + mov edx,[editor_memory] + prepare_to_scan_editors: + mov eax,[edx+SEGMENT_HEADER_LENGTH+previous_instance-editor_data] + or eax,eax + jz scan_editors + mov edx,eax + jmp prepare_to_scan_editors + scan_editors: + mov edi,[edx+SEGMENT_HEADER_LENGTH+file_path-editor_data] + or edi,edi + jz scan_next_editor + xor ecx,ecx + mov ebx,lower_case_table + compare_pathnames: + mov al,[esi+ecx] + xlatb + mov ah,al + mov al,[edi+ecx] + xlatb + cmp al,ah + jne scan_next_editor + or al,ah + jz file_found + inc ecx + jmp compare_pathnames + scan_next_editor: + mov edx,[edx+SEGMENT_HEADER_LENGTH+next_instance-editor_data] + or edx,edx + jnz scan_editors + mov eax,[undo_data] + sub eax,[unmodified_state] + or eax,[file_path] + jz open_in_current_instance + call create_editor_instance + open_in_current_instance: + pop esi + call use_pathname + mov edx,[file_path] + call open + jc load_failed + xor edx,edx + mov al,2 + call lseek + push eax ebx + lea ecx,[eax+1] + call get_memory + or eax,eax + jz not_enough_memory + mov esi,eax + mov edi,ecx + pop ebx + xor edx,edx + xor al,al + call lseek + pop ecx + mov edx,esi + mov byte [edx+ecx],0 + call read + jc load_failed + call close + push edi + call set_text + pop ebx + call release_memory + add esp,8 + ret + file_found: + mov eax,edx + call switch_editor_instance + pop esi + add esp,8 + ret + load_failed: + mov eax,[previous_instance] + or eax,[next_instance] + jnz cancel_instance + cancel_path_only: + xor ebx,ebx + xchg ebx,[file_path] + call release_memory + jmp editor_cancelled + cancel_instance: + mov eax,[editor_memory] + cmp eax,[esp] + je cancel_path_only + call remove_editor_instance + editor_cancelled: + pop eax + call switch_editor_instance + call update_screen + mov edi,buffer + mov esi,_loading_error + mov ebx,esp + call sprintf + pop eax + mov esi,buffer + mov ebx,_error + movzx eax,[error_box_colors] + call message_box + ret + get_full_pathname: + call adapt_path + sub edi,buffer + mov ax,7160h + xor cx,cx + xor si,si + stc + call dos_int + jnc got_full_pathname + mov ah,60h + call dos_int + jc full_pathname_exit + got_full_pathname: + lea esi,[buffer + edi] + cmp word [esi],'\\' + jne full_pathname_ok + cmp dword [esi+3],'.\A.' + jne full_pathname_ok + mov al,[esi+2] + mov ah,':' + add esi,5 + mov [esi],ax + full_pathname_ok: + clc + full_pathname_exit: + ret + use_pathname: + mov edi,[file_path] + or edi,edi + jnz copy_pathname + mov ecx,1000h + push esi + call get_memory + pop esi + or eax,eax + jz not_enough_memory + mov edi,eax + mov [file_path],edi + mov [file_path_handle],ebx + copy_pathname: + lodsb + stosb + or al,al + jnz copy_pathname + ret + save_file: + mov edx,[file_path] + call create + jc file_creation_error + mov [file_handle],ebx + mov esi,[first_line] + mov edi,[line_buffer] + copy_text: + mov ecx,[esi+8] + lea eax,[edi+ecx] + mov edx,[line_buffer_size] + shr edx,1 + sub eax,edx + cmp eax,[line_buffer] + ja flush_to_file + mov ebp,edi + xor edx,edx + push ecx + call copy_from_line + pop ecx + test [editor_style],FES_OPTIMALFILL + jz line_copied + cmp ecx,8 + jb line_copied + push esi edi ecx + mov esi,ebp + mov edi,[line_buffer] + mov eax,[line_buffer_size] + shr eax,1 + add edi,eax + push edi + mov ecx,[esp+4] + xor al,al + rep stosb + mov ecx,[esp+4] + mov edi,[esp] + call syntax_proc + pop ebx ecx edi + mov esi,ebp + mov edi,ebp + sub ebx,esi + xor edx,edx + optimal_fill: + lodsb + cmp al,20h + jne store_character + cmp byte [esi-1+ebx],0 + jne store_character + mov eax,esi + sub eax,ebp + test eax,111b + jz store_tab + inc edx + mov al,20h + stosb + loop optimal_fill + jmp optimal_fill_done + store_tab: + mov al,20h + or edx,edx + jz store_character + sub edi,edx + mov al,9 + store_character: + stosb + xor edx,edx + loop optimal_fill + optimal_fill_done: + pop esi + jmp line_copied + line_copied: + or esi,esi + jz flush_to_file + mov ax,0A0Dh + stosw + jmp copy_text + flush_to_file: + push esi + mov edx,[line_buffer] + mov ecx,edi + sub ecx,edx + mov ebx,[file_handle] + call write + jc file_writing_error + pop esi + mov edi,[line_buffer] + or esi,esi + jnz copy_text + mov ebx,[file_handle] + call close + mov eax,[undo_data] + mov [unmodified_state],eax + clc + ret + file_writing_error: + add esp,4 + file_creation_error: + call update_screen + mov esi,_saving_error + mov ebx,_error + movzx eax,[error_box_colors] + call message_box + stc + ret + get_saving_path: + mov esi,_save_as + call file_open_dialog + jc saving_aborted + push edx + cmp byte [edx+ecx-1],'\' + je save_in_new_directory + call open + pop edx + jc saving_allowed + push edx + call close + call update_screen + mov edi,buffer + mov esi,_overwrite_question + mov ebx,esp + call sprintf + mov esi,buffer + mov ebx,_save_as + mov eax,2 shl 24 + mov ax,[message_box_colors] + mov [first_button],_yes + mov [second_button],_no + call message_box + pop edx + cmp eax,1 + jb saving_aborted + je saving_allowed + call update_screen + jmp get_saving_path + save_in_new_directory: + mov byte [edx+ecx-1],0 + call update_screen + mov edi,buffer + mov esi,_directory_question + mov ebx,esp + call sprintf + mov esi,buffer + mov ebx,_save_as + mov eax,2 shl 24 + mov ax,[message_box_colors] + mov [first_button],_yes + mov [second_button],_no + call message_box + pop esi + cmp eax,1 + jb saving_aborted + jne saving_directory_ok + mov edi,buffer + call copy_asciiz + mov ax,7139h + xor edx,edx + call dos_int + jnc new_directory_created + cmp ax,7100h + jne error_creating_directory + mov ah,39h + call dos_int + jc error_creating_directory + new_directory_created: + mov ax,713Bh + call dos_int + jnc saving_directory_ok + cmp ax,7100h + jne error_creating_directory + mov ah,3Bh + call dos_int + jc error_creating_directory + saving_directory_ok: + call update_screen + jmp get_saving_path + error_creating_directory: + call update_screen + mov esi,_directory_error + mov ebx,_error + movzx eax,[error_box_colors] + call message_box + jmp saving_directory_ok + saving_allowed: + call get_full_pathname + jc invalid_saving_path + call use_pathname + clc + ret + invalid_saving_path: + call update_screen + mov esi,_invalid_path + mov ebx,_error + movzx eax,[error_box_colors] + call message_box + saving_aborted: + stc + ret + + load_configuration: + call load_ini_file + xor eax,eax + mov [memory_limit],eax + mov al,100 + mov [passes_limit],ax + mov ebx,_section_compiler + mov esi,_key_compiler_memory + call get_ini_int + jc memory_setting_ok + cmp eax,1 shl (32-10) + jae memory_setting_ok + shl eax,10 + mov [memory_limit],eax + memory_setting_ok: + mov esi,_key_compiler_passes + call get_ini_int + jc passes_setting_ok + test eax,eax + jz passes_setting_ok + cmp eax,10000h + ja passes_setting_ok + mov [passes_limit],ax + passes_setting_ok: + mov ebx,_section_options + mov esi,_key_options_securesel + call get_ini_int + jc securesel_init_ok + and [editor_style],not FES_SECURESEL + test eax,eax + jz securesel_init_ok + or [editor_style],FES_SECURESEL + securesel_init_ok: + mov esi,_key_options_autobrackets + call get_ini_int + jc autobrackets_init_ok + and [editor_style],not FES_AUTOBRACKETS + test eax,eax + jz autobrackets_init_ok + or [editor_style],FES_AUTOBRACKETS + autobrackets_init_ok: + mov esi,_key_options_autoindent + call get_ini_int + jc autoindent_init_ok + and [editor_style],not FES_AUTOINDENT + test eax,eax + jz autoindent_init_ok + or [editor_style],FES_AUTOINDENT + autoindent_init_ok: + mov esi,_key_options_smarttabs + call get_ini_int + jc smarttabs_init_ok + and [editor_style],not FES_SMARTTABS + test eax,eax + jz smarttabs_init_ok + or [editor_style],FES_SMARTTABS + smarttabs_init_ok: + mov esi,_key_options_optimalfill + call get_ini_int + jc optimalfill_init_ok + and [editor_style],not FES_OPTIMALFILL + test eax,eax + jz optimalfill_init_ok + or [editor_style],FES_OPTIMALFILL + optimalfill_init_ok: + mov ebx,_section_colors + mov esi,_key_color_text + call get_ini_int + jc color_text_init_ok + and al,0Fh + and [text_colors],0F0h + or [text_colors],al + color_text_init_ok: + mov esi,_key_color_background + call get_ini_int + jc color_background_init_ok + and al,0Fh + shl al,4 + and [text_colors],0Fh + or [text_colors],al + color_background_init_ok: + mov esi,_key_color_seltext + call get_ini_int + jc color_seltext_init_ok + and al,0Fh + and [selection_colors],0F0h + or [selection_colors],al + color_seltext_init_ok: + mov esi,_key_color_selbackground + call get_ini_int + jc color_selbackground_init_ok + and al,0Fh + shl al,4 + and [selection_colors],0Fh + or [selection_colors],al + color_selbackground_init_ok: + mov esi,_key_color_symbols + call get_ini_int + jc color_symbols_init_ok + mov [symbol_color],al + color_symbols_init_ok: + mov esi,_key_color_numbers + call get_ini_int + jc color_numbers_init_ok + mov [number_color],al + color_numbers_init_ok: + mov esi,_key_color_strings + call get_ini_int + jc color_strings_init_ok + mov [string_color],al + color_strings_init_ok: + mov esi,_key_color_comments + call get_ini_int + jc color_comments_init_ok + mov [comment_color],al + color_comments_init_ok: + mov esi,_key_color_statustext + call get_ini_int + jc color_statustext_init_ok + and al,0Fh + and [status_colors],0F0h + or [status_colors],al + color_statustext_init_ok: + mov esi,_key_color_statusbackground + call get_ini_int + jc color_statusbackground_init_ok + and al,0Fh + shl al,4 + and [status_colors],0Fh + or [status_colors],al + color_statusbackground_init_ok: + mov esi,_key_color_wintext + call get_ini_int + jc color_wintext_init_ok + and al,0Fh + and [window_colors],0F0h + or [window_colors],al + color_wintext_init_ok: + mov esi,_key_color_winbackground + call get_ini_int + jc color_winbackground_init_ok + and al,0Fh + shl al,4 + and [window_colors],0Fh + or [window_colors],al + color_winbackground_init_ok: + mov esi,_key_color_msgtext + call get_ini_int + jc color_msgtext_init_ok + and al,0Fh + and byte [message_box_colors+1],0F0h + or byte [message_box_colors+1],al + color_msgtext_init_ok: + mov esi,_key_color_msgbackground + call get_ini_int + jc color_msgbackground_init_ok + and al,0Fh + shl al,4 + and byte [message_box_colors+1],0Fh + or byte [message_box_colors+1],al + color_msgbackground_init_ok: + mov esi,_key_color_msgseltext + call get_ini_int + jc color_msgseltext_init_ok + and al,0Fh + and byte [message_box_colors],0F0h + or byte [message_box_colors],al + color_msgseltext_init_ok: + mov esi,_key_color_msgselbackground + call get_ini_int + jc color_msgselbackground_init_ok + and al,0Fh + shl al,4 + and byte [message_box_colors],0Fh + or byte [message_box_colors],al + color_msgselbackground_init_ok: + mov esi,_key_color_errtext + call get_ini_int + jc color_errtext_init_ok + and al,0Fh + and byte [error_box_colors+1],0F0h + or byte [error_box_colors+1],al + color_errtext_init_ok: + mov esi,_key_color_errbackground + call get_ini_int + jc color_errbackground_init_ok + and al,0Fh + shl al,4 + and byte [error_box_colors+1],0Fh + or byte [error_box_colors+1],al + color_errbackground_init_ok: + mov esi,_key_color_errseltext + call get_ini_int + jc color_errseltext_init_ok + and al,0Fh + and byte [error_box_colors],0F0h + or byte [error_box_colors],al + color_errseltext_init_ok: + mov esi,_key_color_errselbackground + call get_ini_int + jc color_errselbackground_init_ok + and al,0Fh + shl al,4 + and byte [error_box_colors],0Fh + or byte [error_box_colors],al + color_errselbackground_init_ok: + mov esi,_key_color_boxtext + call get_ini_int + jc color_boxtext_init_ok + and al,0Fh + and [box_colors],0F0h + or [box_colors],al + color_boxtext_init_ok: + mov esi,_key_color_boxbackground + call get_ini_int + jc color_boxbackground_init_ok + and al,0Fh + shl al,4 + and [box_colors],0Fh + or [box_colors],al + color_boxbackground_init_ok: + mov esi,_key_color_boxseltext + call get_ini_int + jc color_boxseltext_init_ok + and al,0Fh + and byte [box_selection_colors],0F0h + or byte [box_selection_colors],al + color_boxseltext_init_ok: + mov esi,_key_color_boxselbackground + call get_ini_int + jc color_boxselbackground_init_ok + and al,0Fh + shl al,4 + and byte [box_selection_colors],0Fh + or byte [box_selection_colors],al + color_boxselbackground_init_ok: + ret + load_ini_file: + cmp [ini_data],0 + je open_ini_file + mov ebx,[ini_data_handle] + call release_memory + open_ini_file: + mov edi,[ini_extension] + mov eax,'INI' + stosd + mov edx,ini_path + call open + jc no_ini_file + xor edx,edx + mov al,2 + call lseek + push eax + xor edx,edx + xor al,al + call lseek + mov ecx,[esp] + add ecx,800h + push ebx + call get_memory + mov [ini_data],eax + mov [ini_data_handle],ebx + pop ebx ecx + test eax,eax + jz ini_loaded + mov edx,eax + mov byte [edx+ecx],1Ah + mov [ini_data_length],ecx + call read + call close + ret + no_ini_file: + mov ecx,800h + call get_memory + mov [ini_data],eax + test eax,eax + jz ini_loaded + mov byte [eax],1Ah + mov [ini_data_length],0 + ini_loaded: + ret + get_ini_value: + mov edi,esi + mov esi,[ini_data] + test esi,esi + jz ini_value_not_found + call find_ini_block + jc ini_value_not_found + call find_ini_value + ret + ini_value_not_found: + stc + ret + find_ini_block: + lodsb + cmp al,20h + je find_ini_block + cmp al,9 + je find_ini_block + cmp al,'[' + jne look_for_ini_block_in_next_line + find_block_name: + lodsb + cmp al,20h + je find_block_name + cmp al,9 + je find_block_name + dec esi + mov edx,ebx + compare_block_name_char: + lodsb + mov ah,[edx] + inc edx + cmp al,']' + je end_of_block_name + cmp al,20h + je end_of_block_name + cmp al,9 + je end_of_block_name + cmp al,1Ah + je end_of_block_name + cmp al,0Dh + je end_of_block_name + cmp al,0Ah + je end_of_block_name + or ah,ah + jz look_for_ini_block_in_next_line + sub ah,al + jz compare_block_name_char + jns block_name_char_case_insensitive + neg ah + sub al,20h + block_name_char_case_insensitive: + cmp ah,20h + jne look_for_ini_block_in_next_line + cmp al,41h + jb look_for_ini_block_in_next_line + cmp al,5Ah + jna compare_block_name_char + look_for_ini_block_in_next_line: + dec esi + call find_next_ini_line + cmp byte [esi],1Ah + jne find_ini_block + stc + ret + end_of_block_name: + test ah,ah + jnz look_for_ini_block_in_next_line + cmp al,']' + je end_of_block_name_ok + cmp al,20h + je find_block_name_closing_bracket + cmp al,9 + jne look_for_ini_block_in_next_line + find_block_name_closing_bracket: + lodsb + jmp end_of_block_name + end_of_block_name_ok: + call find_next_ini_line + clc + ret + find_next_ini_line: + lodsb + cmp al,0Dh + je line_ending + cmp al,0Ah + je line_ending + cmp al,1Ah + jne find_next_ini_line + dec esi + ret + line_ending: + lodsb + cmp al,0Dh + je line_ending + cmp al,0Ah + je line_ending + dec esi + ret + find_ini_value: + lodsb + cmp al,20h + je find_ini_value + cmp al,9 + je find_ini_value + cmp al,0Dh + je next_ini_value + cmp al,0Ah + je next_ini_value + dec esi + cmp al,1Ah + je no_ini_value_found + cmp al,'[' + je no_ini_value_found + mov edx,edi + compare_value_name_char: + lodsb + mov ah,[edx] + inc edx + cmp al,'=' + je end_of_value_name + cmp al,20h + je end_of_value_name + cmp al,9 + je end_of_value_name + cmp al,1Ah + je end_of_value_name + cmp al,0Dh + je end_of_value_name + cmp al,0Ah + je end_of_value_name + or ah,ah + jz next_ini_value + sub ah,al + jz compare_value_name_char + jns value_name_char_case_insensitive + neg ah + sub al,20h + value_name_char_case_insensitive: + cmp ah,20h + jne next_ini_value + cmp al,41h + jb next_ini_value + cmp al,5Ah + jna compare_value_name_char + next_ini_value: + dec esi + call find_next_ini_line + cmp byte [esi],1Ah + jne find_ini_value + no_ini_value_found: + stc + ret + end_of_value_name: + test ah,ah + jnz next_ini_value + cmp al,'=' + je ini_value_found + cmp al,20h + je find_ini_value_start + cmp al,9 + jne next_ini_value + find_ini_value_start: + lodsb + jmp end_of_value_name + ini_value_found: + xor ecx,ecx + find_value_length: + cmp byte [esi+ecx],0Dh + je value_length_found + cmp byte [esi+ecx],0Ah + je value_length_found + cmp byte [esi+ecx],1Ah + je value_length_found + inc ecx + jmp find_value_length + value_length_found: + clc + ret + get_ini_int: + call get_ini_value + jc no_ini_int + push ebx + call atoi + pop ebx + ret + no_ini_int: + stc + ret + atoi: + lodsb + cmp al,20h + je atoi + cmp al,9 + je atoi + mov bl,al + xor eax,eax + xor edx,edx + cmp bl,'-' + je atoi_digit + cmp bl,'+' + je atoi_digit + dec esi + atoi_digit: + mov dl,[esi] + sub dl,30h + jc atoi_done + cmp dl,9 + ja atoi_done + mov ecx,eax + shl ecx,1 + jc atoi_overflow + shl ecx,1 + jc atoi_overflow + add eax,ecx + shl eax,1 + jc atoi_overflow + js atoi_overflow + add eax,edx + jc atoi_overflow + inc esi + jmp atoi_digit + atoi_overflow: + stc + ret + atoi_done: + cmp bl,'-' + jne atoi_sign_ok + neg eax + atoi_sign_ok: + clc + ret + update_ini_value: + mov ebp,edx + mov esi,[ini_data] + test esi,esi + jz cannot_update_ini + call find_ini_block + jc create_ini_block + call find_ini_value + jc create_ini_value + mov edi,esi + mov esi,ebp + jecxz place_for_ini_value_exhausted + copy_value_to_ini: + lodsb + test al,al + jz shift_rest_of_ini_down + stosb + loop copy_value_to_ini + place_for_ini_value_exhausted: + cmp byte [esi],0 + jne shift_rest_of_ini_up + ret + shift_rest_of_ini_down: + lea esi,[edi+ecx] + neg ecx + xchg ecx,[ini_data_length] + add [ini_data_length],ecx + inc ecx + add ecx,[ini_data] + sub ecx,esi + rep movsb + ret + shift_rest_of_ini_up: + push esi edi + mov edi,esi + xor al,al + or ecx,-1 + repne scasb + neg ecx + sub ecx,2 + mov esi,[ini_data] + add esi,[ini_data_length] + mov edi,esi + add edi,ecx + add [ini_data_length],ecx + mov ebp,ecx + mov ecx,esi + sub ecx,[esp] + inc ecx + std + rep movsb + cld + pop edi esi + mov ecx,ebp + rep movsb + ret + cannot_update_ini: + ret + create_ini_block: + push edi + mov edi,[ini_data] + mov ecx,[ini_data_length] + add edi,ecx + jecxz make_ini_block_header + mov ax,0A0Dh + stosw + make_ini_block_header: + mov al,'[' + stosb + mov esi,ebx + call copy_str + mov al,']' + stosb + mov ax,0A0Dh + stosw + pop esi + append_ini_value: + call copy_str + mov al,'=' + stosb + mov esi,ebp + call copy_str + mov ax,0A0Dh + stosw + mov ecx,edi + sub ecx,[ini_data] + mov [ini_data_length],ecx + mov al,1Ah + stosb + ret + copy_str: + lodsb + test al,al + jz str_copied + stosb + jmp copy_str + str_copied: + ret + create_ini_value: + cmp esi,[ini_data] + je ini_value_placement_ok + dec esi + mov al,[esi] + cmp al,20h + je create_ini_value + cmp al,9 + je create_ini_value + cmp al,0Dh + je create_ini_value + cmp al,0Ah + je create_ini_value + inc esi + find_place_for_ini_value: + mov al,[esi] + lodsb + cmp al,0Ah + je ini_value_placement_ok + cmp al,1Ah + je value_at_end_of_ini + cmp al,0Dh + jne find_place_for_ini_value + cmp byte [esi],0Ah + jne ini_value_placement_ok + inc esi + ini_value_placement_ok: + push edi esi + xor al,al + or ecx,-1 + repne scasb + mov edi,ebp + repne scasb + neg ecx + mov edi,ecx + mov ecx,esi + neg ecx + mov esi,[ini_data] + add esi,[ini_data_length] + add [ini_data_length],edi + add edi,esi + add ecx,esi + inc ecx + std + rep movsb + cld + pop edi esi + call copy_str + mov al,'=' + stosb + mov esi,ebp + call copy_str + mov ax,0A0Dh + stosw + ret + value_at_end_of_ini: + xchg esi,edi + mov ax,0A0Dh + stosw + jmp append_ini_value + + shutdown: + call switch_to_user_screen + call load_ini_file + cmp [ini_data],0 + je exit + mov ebx,_section_options + mov edi,_key_options_securesel + test [editor_style],FES_SECURESEL + setnz al + add al,'0' + mov edx,line_buffer + mov byte [edx+1],0 + mov [edx],al + call update_ini_value + mov edi,_key_options_autobrackets + test [editor_style],FES_AUTOBRACKETS + setnz al + add al,'0' + mov edx,line_buffer + mov [edx],al + call update_ini_value + mov edi,_key_options_autoindent + test [editor_style],FES_AUTOINDENT + setnz al + add al,'0' + mov edx,line_buffer + mov [edx],al + call update_ini_value + mov edi,_key_options_smarttabs + test [editor_style],FES_SMARTTABS + setnz al + add al,'0' + mov edx,line_buffer + mov [edx],al + call update_ini_value + mov edi,_key_options_optimalfill + test [editor_style],FES_OPTIMALFILL + setnz al + add al,'0' + mov edx,line_buffer + mov [edx],al + call update_ini_value + mov edx,ini_path + call create + jc exit + mov edx,[ini_data] + mov ecx,[ini_data_length] + call write + call close + exit: + mov ax,4C00h + int 21h + +; Positioning + + update_positions: + mov eax,[screen_width] + mov [window_width],eax + mov eax,[screen_height] + sub eax,2 + mov [window_height],eax + call update_window + ret + update_cursor: + xor bh,bh + mov edx,[caret_position] + sub edx,[window_position] + jc cursor_out_of_sight + cmp edx,[window_width] + jae cursor_out_of_sight + mov eax,[caret_line_number] + sub eax,[window_line_number] + jc cursor_out_of_sight + cmp eax,[window_height] + jae cursor_out_of_sight + inc al + mov dh,al + mov ah,2 + int 10h + test [editor_mode],FEMODE_OVERWRITE + jnz block_cursor + mov ah,1 + mov cx,0D0Eh + int 10h + ret + block_cursor: + mov ah,1 + mov cx,000Fh + int 10h + ret + cursor_out_of_sight: + mov ah,1 + mov cx,1000h + int 10h + ret + +; Text drawing + + update_screen: + call update_title_bar + mov eax,[peak_line_length] + xor edx,edx + mov ebx,SEGMENT_DATA_LENGTH + div ebx + inc eax + mul ebx + shl eax,1 + mov ecx,eax + cmp [line_buffer],0 + je line_buffer_reallocate + cmp ecx,[line_buffer_size] + jbe line_buffer_ok + mov [line_buffer],0 + push ecx + mov ebx,[line_buffer_handle] + call release_memory + pop ecx + line_buffer_reallocate: + mov [line_buffer_size],ecx + call get_memory + or eax,eax + jz memory_shortage + mov [line_buffer],eax + mov [line_buffer_handle],ebx + line_buffer_ok: + mov esi,[window_line] + mov edx,[window_line_number] + mov eax,[video_pitch] + mov [screen_offset],eax + mov edi,[line_buffer] + prepare_line: + add esi,SEGMENT_HEADER_LENGTH + mov ecx,SEGMENT_DATA_LENGTH + rep movsb + mov esi,[esi-SEGMENT_LENGTH] + btr esi,0 + jc prepare_line + push esi edx + mov ecx,edi + mov esi,[line_buffer] + sub ecx,esi + push ecx + mov al,[text_colors] + and al,0Fh + rep stosb + mov esi,[line_buffer] + mov ecx,[esp] + lea edi,[esi+ecx] + call syntax_proc + line_prepared: + mov edi,screen_row_buffer + mov ecx,[window_width] + mov al,20h + mov ah,[text_colors] + rep stosw + pop ecx + mov esi,[line_buffer] + lea ebx,[esi+ecx] + add esi,[window_position] + add ebx,[window_position] + sub ecx,[window_position] + jbe text_drawing_ok + mov edi,screen_row_buffer + cmp ecx,[window_width] + jbe draw_text + mov ecx,[window_width] + draw_text: + movsb + mov al,[text_colors] + and al,0F0h + or al,[ebx] + stosb + inc ebx + loop draw_text + text_drawing_ok: + mov edi,screen_row_buffer + cmp [selection_line],0 + je selection_marked + mov eax,[selection_line_number] + cmp eax,[caret_line_number] + jne mark_multiline_selection + cmp eax,[esp] + jne selection_marked + mark_simple_selection: + mov eax,[selection_position] + mov ecx,[caret_position] + cmp eax,ecx + jbe simple_selection_boundaries_ok + xchg eax,ecx + simple_selection_boundaries_ok: + sub ecx,[window_position] + jbe selection_marked + sub eax,[window_position] + jae simple_selection_start_ok + xor eax,eax + simple_selection_start_ok: + cmp ecx,[window_width] + jbe simple_selection_length_ok + mov ecx,[window_width] + simple_selection_length_ok: + sub ecx,eax + jbe selection_marked + lea edi,[screen_row_buffer+eax*2] + draw_selection: + inc edi + mov al,[selection_colors] + stosb + loop draw_selection + jmp selection_marked + mark_multiline_selection: + test [editor_mode],FEMODE_VERTICALSEL + jnz mark_vertical_selection + mov eax,[selection_line_number] + mov ebx,[selection_position] + mov edx,[caret_line_number] + mov ebp,[caret_position] + cmp eax,edx + jbe multiline_selection_boundaries_ok + xchg eax,edx + xchg ebx,ebp + multiline_selection_boundaries_ok: + mov edi,screen_row_buffer + mov ecx,[window_width] + cmp eax,[esp] + ja selection_marked + je mark_selection_start + cmp edx,[esp] + ja draw_selection + jb selection_marked + mark_selection_end: + cmp ebp,[window_position] + jbe selection_marked + sub ebp,[window_position] + cmp ecx,ebp + jbe draw_selection + mov ecx,ebp + jmp draw_selection + mark_selection_start: + sub ebx,[window_position] + jbe draw_selection + sub ecx,ebx + jbe selection_marked + lea edi,[edi+ebx*2] + jmp draw_selection + mark_vertical_selection: + mov eax,[selection_line_number] + mov edx,[caret_line_number] + sub eax,[esp] + jz mark_simple_selection + sub edx,[esp] + jz mark_simple_selection + xor eax,edx + js mark_simple_selection + selection_marked: + push es gs + pop es + mov esi,screen_row_buffer + mov edi,[screen_offset] + mov ecx,[window_width] + shr ecx,1 + rep movsd + setc cl + rep movsw + mov eax,[window_width] + shl eax,1 + sub edi,eax + add edi,[video_pitch] + mov [screen_offset],edi + pop es + pop edx esi + inc edx + mov eax,edx + sub eax,[window_line_number] + cmp eax,[window_height] + jae screen_ok + mov edi,[line_buffer] + or esi,esi + jnz prepare_line + push esi edx + push [window_position] + jmp line_prepared + screen_ok: + call update_status_bar + ret + + syntax_proc: + mov ebx,characters + xor edx,edx + scan_syntax: + lodsb + check_character: + cmp al,20h + je syntax_space + cmp al,3Bh + je syntax_comment + mov ah,al + xlatb + or al,al + jz syntax_symbol + or edx,edx + jnz syntax_neutral + cmp ah,27h + je syntax_string + cmp ah,22h + je syntax_string + cmp ah,24h + je syntax_pascal_hex + cmp ah,39h + ja syntax_neutral + cmp ah,30h + jae syntax_number + syntax_neutral: + or edx,-1 + inc edi + loop scan_syntax + jmp syntax_done + syntax_space: + xor edx,edx + inc edi + loop scan_syntax + jmp syntax_done + syntax_symbol: + mov al,[symbol_color] + stosb + xor edx,edx + loop scan_syntax + jmp syntax_done + syntax_pascal_hex: + cmp ecx,1 + je syntax_neutral + mov al,[esi] + mov ah,al + xlatb + or al,al + jz syntax_neutral + cmp ah,24h + jne syntax_number + cmp ecx,2 + je syntax_neutral + mov al,[esi+1] + xlatb + or al,al + jz syntax_neutral + syntax_number: + mov al,[number_color] + stosb + loop number_character + jmp syntax_done + number_character: + lodsb + mov ah,al + xlatb + xchg al,ah + or ah,ah + jz check_character + cmp al,20h + je check_character + cmp al,3Bh + je check_character + mov al,[number_color] + stosb + loop number_character + jmp syntax_done + syntax_string: + mov al,[string_color] + stosb + dec ecx + jz syntax_done + lodsb + cmp al,ah + jne syntax_string + mov al,[string_color] + stosb + dec ecx + jz syntax_done + lodsb + cmp al,ah + je syntax_string + xor edx,edx + jmp check_character + process_comment: + lodsb + cmp al,20h + jne syntax_comment + inc edi + loop process_comment + jmp syntax_done + syntax_comment: + mov al,[comment_color] + stosb + loop process_comment + syntax_done: + ret + +; Status drawing + + update_status_bar: + mov edi,screen_row_buffer + mov al,20h + mov ecx,[screen_width] + rep stosb + mov edi,screen_row_buffer+256 + mov eax,'Row ' + stosd + mov eax,[caret_line_number] + call number_as_text + mov al,'/' + stosb + mov eax,[lines_count] + call number_as_text + mov eax,', Co' + stosd + mov eax,'lumn' + stosd + mov al,' ' + stosb + mov eax,[caret_position] + inc eax + call number_as_text + mov al,'/' + stosb + mov eax,[maximum_position] + inc eax + call number_as_text + mov ecx,edi + mov esi,screen_row_buffer+256 + sub ecx,esi + mov eax,[screen_width] + lea edi,[screen_row_buffer+eax-1] + sub edi,ecx + mov byte [edi-2],0B3h + lea ebx,[edi-11] + rep movsb + mov edi,ebx + sub ebx,2 + test [editor_mode],FEMODE_READONLY + jnz readonly_status + mov eax,[undo_data] + cmp eax,[unmodified_state] + je editor_status_ok + mov eax,'Modi' + stosd + mov eax,'fied' + stosd + jmp editor_status_ok + readonly_status: + dec ebx + dec edi + mov eax,'Read' + stosd + mov al,'-' + stosb + mov eax,'only' + stosd + editor_status_ok: + mov byte [ebx],0B3h + push ebx + mov edi,screen_row_buffer+1 + xor eax,eax + mov edx,[previous_instance] + count_preceding_instances: + inc eax + or edx,edx + jz preceding_instances_count_ok + mov edx,[edx+SEGMENT_HEADER_LENGTH+previous_instance-editor_data] + jmp count_preceding_instances + preceding_instances_count_ok: + push eax + call number_as_text + mov al,'/' + stosb + pop eax + mov edx,[next_instance] + count_following_instances: + or edx,edx + jz following_instances_count_ok + inc eax + mov edx,[edx+SEGMENT_HEADER_LENGTH+next_instance-editor_data] + jmp count_following_instances + following_instances_count_ok: + call number_as_text + inc edi + mov al,'-' + stosb + inc edi + pop ecx + sub ecx,edi + mov esi,[file_path] + call get_file_title + print_file_title: + lodsb + or al,al + jz editor_title_ok + stosb + loop print_file_title + editor_title_ok: + push es gs + pop es + mov edi,[video_pitch] + mov eax,[screen_height] + dec eax + imul edi,eax + mov esi,screen_row_buffer + mov ecx,[screen_width] + mov ah,[status_colors] + draw_status_bar: + lodsb + stosw + loop draw_status_bar + pop es + ret + get_file_title: + or esi,esi + jz untitled + mov ebx,esi + find_file_name: + lodsb + or al,al + jz file_title_ok + cmp al,'\' + jne find_file_name + mov ebx,esi + jmp find_file_name + file_title_ok: + mov esi,ebx + ret + untitled: + mov esi,_untitled + ret + update_title_bar: + mov edi,screen_row_buffer + mov al,20h + mov ecx,[screen_width] + sub ecx,10+1 + rep stosb + mov al,0B3h + stosb + mov esi,_caption + mov edi,screen_row_buffer+1 + draw_caption: + lodsb + or al,al + jz caption_ok + stosb + jmp draw_caption + caption_ok: + mov edx,[main_project_file] + or edx,edx + jz main_file_title_ok + mov al,20h + stosb + mov al,'-' + stosb + mov al,20h + stosb + mov esi,[file_path] + cmp edx,[editor_memory] + je get_main_file_title + mov esi,[edx+SEGMENT_HEADER_LENGTH+file_path-editor_data] + get_main_file_title: + call get_file_title + mov ecx,[screen_width] + add ecx,screen_row_buffer-14 + sub ecx,edi + print_main_file_title: + lodsb + or al,al + jz main_file_title_ok + stosb + loop print_main_file_title + main_file_title_ok: + push es gs + pop es + xor edi,edi + mov esi,screen_row_buffer + mov ecx,[screen_width] + sub ecx,10 + mov ah,[status_colors] + draw_title_bar: + lodsb + stosw + loop draw_title_bar + pop es + call update_clock + ret + update_clock: + mov edi,[screen_width] + mov ecx,10 + sub edi,ecx + shl edi,1 + mov al,[status_colors] + prepare_clock_colors: + mov [gs:edi+(ecx-1)*2+1],al + loop prepare_clock_colors + mov ah,2Ch + int 21h + mov [gs:edi],byte 20h + mov al,ch + aam + add ax,'00' + mov [gs:edi+1*2],ah + mov [gs:edi+2*2],al + mov [gs:edi+3*2],byte ':' + mov al,cl + aam + add ax,'00' + mov [gs:edi+4*2],ah + mov [gs:edi+5*2],al + mov [gs:edi+6*2],byte ':' + mov al,dh + aam + add ax,'00' + mov [gs:edi+7*2],ah + mov [gs:edi+8*2],al + mov [gs:edi+9*2],byte 20h + ret + wait_for_input: + call update_clock + mov ah,11h + int 16h + jz wait_for_input + mov ah,10h + int 16h + test ax,ax + jz wait_for_input + ret + number_as_text: + push ebx + mov ecx,1000000000 + xor edx,edx + xor bl,bl + number_loop: + div ecx + push edx + cmp ecx,1 + je store_digit + or bl,bl + jnz store_digit + or al,al + jz digit_ok + not bl + store_digit: + add al,'0' + stosb + digit_ok: + mov eax,ecx + xor edx,edx + mov ecx,10 + div ecx + mov ecx,eax + pop eax + or ecx,ecx + jnz number_loop + pop ebx + ret + sprintf: + lodsb + cmp al,'%' + je format_parameter + stosb + or al,al + jnz sprintf + ret + format_parameter: + lodsb + mov edx,[ebx] + add ebx,4 + cmp al,'s' + je insert_string + cmp al,'d' + je insert_number + or al,al + jnz sprintf + dec esi + jmp sprintf + insert_number: + push esi + mov eax,edx + call number_as_text + pop esi + jmp sprintf + insert_string: + push esi + mov esi,edx + string_insertion_loop: + lodsb + or al,al + jz string_insertion_ok + stosb + jmp string_insertion_loop + string_insertion_ok: + pop esi + jmp sprintf + +; Windows + + message_box: + push eax ebx + xor ebp,ebp + mov edi,buffer+200h + mov dl,[esp+4+3] + or dl,dl + jnz calculate_buttons_width + mov dl,1 + mov [first_button],_ok + calculate_buttons_width: + mov [buttons_width],0 + mov eax,[first_button] + call add_button_width + dec dl + jz buttons_width_ok + add [buttons_width],2 + mov eax,[second_button] + call add_button_width + jmp buttons_width_ok + add_button_width: + push edi + mov edi,eax + xor al,al + or ecx,-1 + repne scasb + neg cl + add cl,6-2 + add [buttons_width],cl + pop edi + ret + buttons_width_ok: + mov al,[buttons_width] + mov [message_width],al + start_message_line: + mov ebx,edi + mov edx,edi + mov ecx,[screen_width] + sub ecx,14 + mov eax,[screen_height] + sub eax,7 + inc ebp + cmp ebp,eax + jae message_prepared + copy_message: + lodsb + stosb + cmp al,20h + jne message_character_ok + mov edx,edi + message_character_ok: + cmp byte [esi],0 + je message_prepared + loop copy_message + cmp edx,ebx + je split_word + lea eax,[edx-1] + mov ecx,[screen_height] + sub ecx,7 + inc ebp + cmp ebp,ecx + je cut_message + mov byte [eax],0Ah + sub eax,ebx + mov ebx,edx + mov ecx,[screen_width] + lea ecx,[ecx-14+ebx] + sub ecx,edi + cmp al,[message_width] + jbe copy_message + mov [message_width],al + jmp copy_message + cut_message: + mov edi,eax + jmp message_prepared + split_word: + mov eax,[screen_width] + sub eax,14 + mov [message_width],al + mov al,0Ah + stosb + jmp start_message_line + message_prepared: + mov eax,edi + sub eax,ebx + cmp al,[message_width] + jbe message_width_ok + mov [message_width],al + message_width_ok: + xor al,al + stosb + mov ecx,ebp + mov ch,cl + add ch,6 + mov cl,[message_width] + add cl,8 + pop esi + mov ah,[esp+1] + call draw_centered_window + mov esi,buffer+200h + add edi,2*2 + draw_message: + xor ecx,ecx + add edi,[video_pitch] + draw_message_row: + lodsb + or al,al + jz message_drawn + cmp al,0Ah + je draw_message + mov byte [gs:edi+ecx*2],al + inc ecx + jmp draw_message_row + message_drawn: + add edi,[video_pitch] + add edi,[video_pitch] + mov cx,1000h + mov ah,1 + int 10h + movzx eax,[message_width] + sub al,[buttons_width] + and al,not 1 + add edi,eax + cmp byte [esp+3],2 + jae two_button_message + pop eax + mov ah,al + mov esi,[first_button] + call draw_button + wait_for_ok: + call wait_for_input + cmp ah,1 + je message_aborted + cmp al,20h + je message_ok + cmp al,0Dh + jne wait_for_ok + message_ok: + mov eax,1 + ret + message_aborted: + xor eax,eax + ret + two_button_message: + pop edx + xor cl,cl + test edx,10000h + jnz two_button_loop + mov cl,-1 + two_button_loop: + push edi + mov al,dl + and al,cl + mov ah,cl + not ah + and ah,dh + or ah,al + mov esi,[first_button] + call draw_button + add edi,2*2 + mov al,dh + and al,cl + mov ah,cl + not ah + and ah,dl + or ah,al + mov esi,[second_button] + call draw_button + push ecx edx + call wait_for_input + pop edx ecx edi + cmp ah,1 + je message_aborted + cmp al,9 + je two_button_switch + cmp ah,0Fh + je two_button_switch + cmp ah,4Bh + je two_button_switch + cmp ah,4Dh + je two_button_switch + cmp ah,48h + je two_button_switch + cmp ah,50h + je two_button_switch + cmp al,0Dh + je button_selected + cmp al,20h + je button_selected + mov ebx,lower_case_table + xlatb + mov ah,al + mov esi,[first_button] + mov al,[esi] + xlatb + cmp al,ah + je message_ok + mov esi,[second_button] + mov al,[esi] + xlatb + cmp al,ah + je message_second_choice + jmp two_button_loop + button_selected: + or cl,cl + jnz message_ok + message_second_choice: + mov eax,2 + ret + two_button_switch: + not cl + jmp two_button_loop + draw_button: + push es gs + pop es + mov al,'[' + stosw + mov al,20h + stosw + stosw + draw_button_label: + lodsb + or al,al + jz button_label_ok + stosw + jmp draw_button_label + button_label_ok: + mov al,20h + stosw + stosw + mov al,']' + stosw + pop es + ret + draw_centered_window: + mov dl,byte [screen_width] + sub dl,cl + shr dl,1 + mov dh,byte [screen_height] + sub dh,ch + shr dh,1 + test [command_flags],80h + jz draw_window + mov ebx,[caret_line_number] + sub ebx,[window_line_number] + add ebx,3 + cmp bl,dh + jbe draw_window + mov al,dh + add al,ch + add al,3 + cmp al,bl + jb draw_window + mov dh,bl + movzx edi,ch + add edi,ebx + add edi,2 + cmp edi,[screen_height] + jb draw_window + sub dh,ch + sub dh,4 + draw_window: + push es gs + pop es + movzx edi,dh + imul edi,[video_pitch] + movzx ebx,dl + shl ebx,1 + add edi,ebx + movzx edx,ch + movzx ecx,cl + sub ecx,4 + sub edx,2 + push ecx edi + mov al,' ' + stos word [edi] + mov al,'É' + stos word [edi] + mov al,'Í' + stos word [edi] + dec ecx + mov al,' ' + stos word [edi] + dec ecx + draw_title: + lods byte [esi] + or al,al + jz title_ok + stos word [edi] + loop draw_title + jmp finish_upper_border + title_ok: + mov al,' ' + stos word [edi] + dec ecx + jz finish_upper_border + mov al,'Í' + rep stos word [edi] + finish_upper_border: + mov al,'»' + stos word [edi] + mov al,' ' + stos word [edi] + pop edi ecx + add edi,[video_pitch] + lea ebp,[edi+2*2] + draw_window_lines: + push ecx edi + mov al,' ' + stos word [edi] + mov al,'º' + stos word [edi] + mov al,' ' + rep stos word [edi] + mov al,'º' + stos word [edi] + mov al,' ' + stos word [edi] + mov byte [es:edi+1],8 + mov byte [es:edi+3],8 + pop edi ecx + add edi,[video_pitch] + dec edx + jnz draw_window_lines + push ecx edi + mov al,' ' + stos word [edi] + mov al,'È' + stos word [edi] + mov al,'Í' + rep stos word [edi] + mov al,'¼' + stos word [edi] + mov al,' ' + stos word [edi] + mov byte [es:edi+1],8 + mov byte [es:edi+3],8 + pop edi ecx + mov eax,[video_pitch] + lea edi,[edi+eax+2*2+1] + mov al,8 + add ecx,4 + finish_bottom_shadow: + stos byte [edi] + inc edi + loop finish_bottom_shadow + mov edi,ebp + mov eax,edi + cdq + idiv [video_pitch] + sar edx,1 + mov dh,al + pop es + ret + create_edit_box: + mov byte [ebx],1 + mov [ebx+1],al + mov [ebx+2],dx + mov [ebx+4],ecx + xor eax,eax + mov [ebx+8],eax + mov [ebx+12],eax + lea edi,[ebx+16] + xor ecx,ecx + or esi,esi + jz edit_box_text_ok + init_edit_box_text: + lodsb + or al,al + jz edit_box_text_ok + stosb + inc ecx + cmp cx,[ebx+6] + jb init_edit_box_text + edit_box_text_ok: + mov [ebx+8],cx + mov [ebx+12],cx + xor al,al + stosb + test byte [ebx+1],1 + jz draw_edit_box + set_edit_box_focus: + push ebx + mov ah,1 + mov cx,0D0Eh + int 10h + pop ebx + jmp draw_edit_box + kill_edit_box_focus: + mov word [ebx+10],0 + push ebx + mov ah,1 + mov cx,1000h + int 10h + pop ebx + draw_edit_box: + test byte [ebx+1],1 + jz edit_box_position_ok + mov ax,[ebx+10] + sub ax,[ebx+12] + jae edit_box_position_correction + movzx ax,byte [ebx+4] + add ax,[ebx+10] + sub ax,2 + sub ax,[ebx+12] + jae edit_box_position_ok + edit_box_position_correction: + sub [ebx+10],ax + edit_box_position_ok: + push es gs + pop es + movzx edi,byte [ebx+3] + imul edi,[video_pitch] + movzx eax,byte [ebx+2] + lea edi,[edi+eax*2] + mov al,20h + cmp word [ebx+10],0 + je edit_box_left_edge_ok + mov al,1Bh + edit_box_left_edge_ok: + mov ah,[box_colors] + stosw + movzx eax,word [ebx+10] + lea esi,[ebx+16+eax] + movzx ebp,byte [ebx+4] + sub ebp,2 + mov edx,[ebx+12] + cmp dx,[ebx+14] + jbe draw_edit_box_before_selection + ror edx,16 + draw_edit_box_before_selection: + movzx ecx,dx + sub cx,[ebx+10] + jbe draw_edit_box_selection + mov ah,[box_colors] + call draw_edit_box_part + draw_edit_box_selection: + mov ax,dx + sub ax,cx + shr edx,16 + mov cx,dx + sub cx,ax + jbe draw_edit_box_after_selection + mov ah,[box_selection_colors] + test byte [ebx+1],1 + jnz edit_box_selection_visible + mov ah,[box_colors] + edit_box_selection_visible: + call draw_edit_box_part + draw_edit_box_after_selection: + mov ah,[box_colors] + mov cx,[ebx+8] + sub cx,dx + jbe draw_edit_box_ending + call draw_edit_box_part + draw_edit_box_ending: + mov ecx,ebp + mov al,20h + rep stosw + movzx edx,word [ebx+8] + lea edx,[ebx+16+edx] + cmp esi,edx + jae edit_box_right_edge_ok + mov al,1Ah + edit_box_right_edge_ok: + stosw + test byte [ebx+1],1 + jz edit_box_cursor_ok + mov dx,[ebx+2] + inc dl + mov ax,[ebx+12] + sub ax,[ebx+10] + add dl,al + mov ah,2 + push ebx + mov bh,0 + int 10h + pop ebx + edit_box_cursor_ok: + pop es + ret + draw_edit_box_part: + or bp,bp + jz edit_box_part_ok + cmp cx,bp + jbe edit_box_part_length_ok + mov cx,bp + edit_box_part_length_ok: + sub bp,cx + draw_edit_box_character: + lodsb + stosw + loopw draw_edit_box_character + edit_box_part_ok: + ret + set_box_focus: + or byte [ebx+1],1 + mov cl,[ebx] + cmp cl,1 + jb set_check_box_focus + je set_edit_box_focus + cmp cl,2 + je draw_list_box + ret + kill_box_focus: + and byte [ebx+1],not 1 + mov cl,[ebx] + cmp cl,1 + je kill_edit_box_focus + cmp cl,2 + je draw_list_box + ret + update_box: + cmp byte [ebx],0 + je update_check_box + ret + process_box_command: + mov cl,[ebx] + cmp cl,1 + jb check_box_command + je edit_box_command + cmp cl,2 + je list_box_command + stc + ret + edit_box_command: + cmp al,0E0h + jne edit_box_ascii_code + cmp ah,4Bh + je edit_box_left_key + cmp ah,4Dh + je edit_box_right_key + cmp ah,47h + je edit_box_home_key + cmp ah,4Fh + je edit_box_end_key + cmp ah,53h + je edit_box_delete + cmp ah,52h + je edit_box_insert + cmp ah,93h + je edit_box_ctrl_delete + cmp ah,92h + je edit_box_ctrl_insert + edit_box_unknown_command: + stc + ret + edit_box_ascii_code: + cmp al,8 + je edit_box_backspace + cmp al,18h + je edit_box_cut_block + cmp al,3 + je edit_box_ctrl_insert + cmp al,16h + je edit_box_paste_block + cmp al,20h + jb edit_box_unknown_command + test byte [ebx+1],100b + jz edit_box_ascii_code_ok + cmp al,30h + jb edit_box_command_done + cmp al,39h + ja edit_box_command_done + edit_box_ascii_code_ok: + mov dx,word [ebx+12] + cmp dx,word [ebx+14] + je edit_box_character + push eax + call edit_box_delete_block + pop eax + edit_box_character: + call edit_box_insert_character + jc edit_box_command_done + jmp edit_box_no_selection + edit_box_delete: + test byte [fs:17h],11b + jnz edit_box_cut_block + mov dx,word [ebx+12] + cmp dx,word [ebx+14] + jne edit_box_ctrl_delete + cmp dx,[ebx+8] + je edit_box_command_done + inc dx + mov [ebx+14],dx + jmp edit_box_ctrl_delete + edit_box_backspace: + mov dx,[ebx+12] + cmp dx,word [ebx+14] + jne edit_box_ctrl_delete + or dx,dx + jz edit_box_command_done + dec word [ebx+12] + mov [ebx+14],dx + edit_box_ctrl_delete: + call edit_box_delete_block + jmp edit_box_no_selection + edit_box_ctrl_insert: + call edit_box_copy_block + jmp edit_box_command_done + edit_box_cut_block: + call edit_box_copy_block + call edit_box_delete_block + jmp edit_box_no_selection + edit_box_insert_character: + test byte [ebx+1],100b + jz edit_box_character_allowed + cmp al,30h + jb edit_box_disallowed_character + cmp al,39h + ja edit_box_disallowed_character + edit_box_character_allowed: + movzx ecx,word [ebx+8] + cmp cx,[ebx+6] + je edit_box_full + lea edi,[ebx+16+ecx] + lea esi,[edi-1] + sub cx,[ebx+12] + std + rep movsb + cld + stosb + inc word [ebx+8] + inc word [ebx+12] + edit_box_disallowed_character: + clc + ret + edit_box_full: + stc + ret + edit_box_delete_block: + movzx eax,word [ebx+12] + lea esi,[ebx+16+eax] + movzx eax,word [ebx+14] + lea edi,[ebx+16+eax] + movzx eax,word [ebx+8] + lea ecx,[ebx+16+eax] + cmp esi,edi + jae edit_box_shift_rest_of_line + xchg esi,edi + edit_box_shift_rest_of_line: + sub ecx,esi + mov eax,edi + rep movsb + mov ecx,esi + sub ecx,edi + sub [ebx+8],cx + sub eax,ebx + sub eax,16 + mov [ebx+12],ax + mov [ebx+14],ax + ret + edit_box_copy_block: + movzx ecx,word [ebx+12] + movzx edx,word [ebx+14] + cmp ecx,edx + je edit_box_block_copied + ja edit_box_block_start_ok + xchg ecx,edx + edit_box_block_start_ok: + sub ecx,edx + lea esi,[ebx+16+edx] + push ebx esi ecx + cmp [clipboard],0 + je edit_box_allocate_clipboard + mov ebx,[clipboard_handle] + call release_memory + edit_box_allocate_clipboard: + mov ecx,[esp] + inc ecx + call get_memory + mov [clipboard],eax + mov [clipboard_handle],ecx + or eax,eax + jz not_enough_memory + mov edi,eax + pop ecx esi ebx + rep movsb + xor al,al + stosb + edit_box_block_copied: + ret + edit_box_insert: + test byte [fs:17h],11b + jz edit_box_command_done + edit_box_paste_block: + call edit_box_delete_block + mov esi,[clipboard] + or esi,esi + jz edit_box_command_done + edit_box_insert_block: + lodsb + or al,al + jz edit_box_no_selection + cmp al,0Dh + je edit_box_no_selection + push esi + call edit_box_insert_character + pop esi + jnc edit_box_insert_block + jmp edit_box_no_selection + edit_box_left_key: + cmp word [ebx+12],0 + je edit_box_no_selection + dec word [ebx+12] + jmp edit_box_moved_cursor + edit_box_right_key: + mov ax,[ebx+8] + cmp [ebx+12],ax + je edit_box_no_selection + inc word [ebx+12] + jmp edit_box_moved_cursor + edit_box_home_key: + mov word [ebx+12],0 + jmp edit_box_moved_cursor + edit_box_end_key: + mov ax,[ebx+8] + mov [ebx+12],ax + jmp edit_box_moved_cursor + edit_box_moved_cursor: + test byte [fs:17h],11b + jnz edit_box_redraw + edit_box_no_selection: + mov ax,[ebx+12] + mov [ebx+14],ax + edit_box_redraw: + call draw_edit_box + edit_box_command_done: + movzx eax,word [ebx+8] + mov byte [ebx+16+eax],0 + clc + ret + create_list_box: + mov byte [ebx],2 + mov [ebx+1],al + mov [ebx+2],dx + mov [ebx+4],ecx + xor eax,eax + mov [ebx+8],eax + mov [ebx+12],esi + draw_list_box: + mov ax,[ebx+8] + sub ax,[ebx+10] + jb list_box_adjust_up + movzx dx,byte [ebx+5] + sub ax,dx + jb list_box_adjustments_ok + inc ax + add [ebx+10],ax + jmp list_box_adjustments_ok + list_box_adjust_up: + add [ebx+10],ax + list_box_adjustments_ok: + movzx edi,byte [ebx+3] + imul edi,[video_pitch] + movzx ecx,byte [ebx+2] + lea edi,[edi+ecx*2] + movzx edx,word [ebx+10] + push es gs + pop es + draw_list_box_row: + mov ah,[box_colors] + movzx ecx,byte [ebx+4] + cmp dx,[ebx+6] + jae draw_empty_list_box_row + mov esi,[ebx+12] + mov esi,[esi+edx*4] + test byte [ebx+1],1 + jz list_box_row_colors_ok + cmp dx,[ebx+8] + jne list_box_row_colors_ok + mov ah,[box_selection_colors] + list_box_row_colors_ok: + sub ecx,2 + mov al,20h + stosw + draw_list_box_item: + lodsb + test al,al + jnz draw_list_box_item_character + dec esi + mov al,20h + draw_list_box_item_character: + stosw + loop draw_list_box_item + mov al,20h + cmp byte [esi],0 + je list_box_item_ending + mov al,1Ah + list_box_item_ending: + stosw + jmp list_box_row_drawn + draw_empty_list_box_row: + mov al,20h + rep stosw + list_box_row_drawn: + inc edx + mov ax,dx + sub ax,[ebx+10] + cmp al,[ebx+5] + jae list_box_drawn + add edi,[video_pitch] + movzx ecx,byte [ebx+4] + shl ecx,1 + sub edi,ecx + jmp draw_list_box_row + list_box_drawn: + pop es + ret + list_box_command: + cmp ah,48h + je list_box_up_key + cmp ah,50h + je list_box_down_key + cmp ah,47h + je list_box_home_key + cmp ah,4Fh + je list_box_end_key + cmp ah,49h + je list_box_pgup_key + cmp ah,51h + je list_box_pgdn_key + stc + ret + list_box_home_key: + xor eax,eax + mov [ebx+8],ax + jmp list_box_redraw + list_box_end_key: + mov ax,[ebx+6] + dec ax + mov [ebx+8],ax + jmp list_box_redraw + list_box_pgup_key: + movzx ax,byte [ebx+5] + sub [ebx+8],ax + jae list_box_redraw + mov word [ebx+8],0 + jmp list_box_redraw + list_box_pgdn_key: + movzx ax,byte [ebx+5] + add [ebx+8],ax + mov ax,[ebx+6] + dec ax + cmp [ebx+8],ax + jbe list_box_redraw + mov [ebx+8],ax + jmp list_box_redraw + list_box_up_key: + mov ax,[ebx+8] + sub ax,1 + jc list_box_command_done + dec word [ebx+8] + jmp list_box_redraw + list_box_down_key: + mov ax,[ebx+8] + inc ax + cmp ax,[ebx+6] + jae list_box_command_done + mov [ebx+8],ax + list_box_redraw: + call draw_list_box + list_box_command_done: + clc + ret + create_check_box: + mov byte [ebx],0 + mov [ebx+1],al + mov [ebx+2],dx + mov [ebx+4],cl + mov [ebx+8],ebp + mov [ebx+12],edi + movzx edx,byte [ebx+3] + imul edx,[video_pitch] + movzx ecx,byte [ebx+2] + lea edx,[edx+ecx*2] + mov al,'[' + test byte [ebx+1],2 + jz draw_check_box_left_bracket + mov al,'(' + draw_check_box_left_bracket: + mov byte [gs:edx],al + add edx,2 + mov al,20h + test byte [ebx+1],2 + jnz set_up_radio_initial_state + test [edi],ebp + jz draw_check_box_initial_state + mov al,'+' + jmp draw_check_box_initial_state + set_up_radio_initial_state: + cmp [edi],ebp + jne draw_check_box_initial_state + mov al,7 + draw_check_box_initial_state: + mov byte [gs:edx],al + add edx,2 + mov al,']' + test byte [ebx+1],2 + jz draw_check_box_right_bracket + mov al,')' + draw_check_box_right_bracket: + mov byte [gs:edx],al + add edx,2*2 + movzx ecx,byte [ebx+4] + draw_check_box_text: + lodsb + or al,al + jz check_box_text_ok + mov [gs:edx],al + add edx,2 + loop draw_check_box_text + check_box_text_ok: + test byte [ebx+1],1 + jnz set_check_box_focus + ret + set_check_box_focus: + push ebx + mov ah,2 + mov dx,[ebx+2] + inc dl + xor bh,bh + int 10h + mov ah,1 + mov cx,0D0Eh + int 10h + pop ebx + ret + check_box_command: + cmp al,20h + je switch_check_box_state + stc + ret + switch_check_box_state: + mov edi,[ebx+12] + mov eax,[ebx+8] + test byte [ebx+1],2 + jnz set_radio_state + xor [edi],eax + call update_check_box + clc + ret + set_radio_state: + mov [edi],eax + call update_check_box + clc + ret + update_check_box: + movzx edx,byte [ebx+3] + imul edx,[video_pitch] + movzx ecx,byte [ebx+2] + lea edx,[edx+(ecx+1)*2] + mov edi,[ebx+12] + mov eax,[ebx+8] + test byte [ebx+1],2 + jnz redraw_radio + test [edi],eax + mov al,20h + jz check_box_state_ok + mov al,'+' + check_box_state_ok: + mov byte [gs:edx],al + ret + redraw_radio: + cmp [edi],eax + mov al,20h + jne radio_state_ok + mov al,7 + radio_state_ok: + mov byte [gs:edx],al + ret + + init_common_dialog: + xor eax,eax + mov [boxes_count],eax + mov [current_box],eax + ret + register_box_in_dialog: + mov eax,[boxes_count] + inc [boxes_count] + mov [boxes+eax*4],ebx + test byte [ebx+1],1 + jz box_registered + mov [current_box],eax + box_registered: + ret + common_dialog_loop: + call wait_for_input + cmp ah,1 + je common_dialog_aborted + cmp al,0Dh + je common_dialog_ok + cmp al,9 + je common_dialog_cycle_boxes + cmp ah,0Fh + je common_dialog_reverse_cycle_boxes + mov edx,[current_box] + mov ebx,[boxes+edx*4] + call process_box_command + jnc common_dialog_command_processed + cmp ah,48h + je common_dialog_previous_box + cmp ah,50h + je common_dialog_next_box + cmp ah,4Bh + je common_dialog_previous_box + cmp ah,4Dh + je common_dialog_next_box + jmp common_dialog_loop + common_dialog_command_processed: + xor edx,edx + update_boxes: + mov ebx,[boxes+edx*4] + push edx + call update_box + pop edx + inc edx + cmp edx,[boxes_count] + jb update_boxes + mov eax,[common_dialog_callback] + test eax,eax + jz common_dialog_loop + call eax + jmp common_dialog_loop + common_dialog_next_box: + mov edx,[current_box] + lea eax,[edx+1] + cmp eax,[boxes_count] + je common_dialog_loop + mov [current_box],eax + jmp common_dialog_switch_box + common_dialog_previous_box: + mov edx,[current_box] + or edx,edx + jz common_dialog_loop + dec [current_box] + jmp common_dialog_switch_box + common_dialog_cycle_boxes: + mov edx,[current_box] + inc [current_box] + mov eax,[current_box] + cmp eax,[boxes_count] + jb common_dialog_switch_box + mov [current_box],0 + jmp common_dialog_switch_box + common_dialog_reverse_cycle_boxes: + mov edx,[current_box] + sub [current_box],1 + jnc common_dialog_switch_box + mov eax,[boxes_count] + add [current_box],eax + common_dialog_switch_box: + mov ebx,[boxes+edx*4] + call kill_box_focus + mov edx,[current_box] + mov ebx,[boxes+edx*4] + call set_box_focus + jmp common_dialog_loop + common_dialog_ok: + clc + ret + common_dialog_aborted: + stc + ret + get_entered_number: + xor edx,edx + get_digit: + lodsb + or al,al + jz entered_number_ok + sub al,30h + movzx eax,al + imul edx,10 + add edx,eax + jmp get_digit + entered_number_ok: + ret + draw_static: + lodsb + or al,al + jz fill_static + mov [gs:edi],al + add edi,2 + loop draw_static + ret + fill_static: + mov byte [gs:edi],20h + add edi,2 + loop fill_static + dec esi + ret + + file_open_dialog: + push esi + mov edi,buffer+3000h + mov byte [edi],0 + call get_current_directory + cmp byte [edi-2],'\' + je browser_startup_path_ok + mov word [edi-1],'\' + browser_startup_path_ok: + xor eax,eax + mov [file_list_buffer_handle],eax + call make_list_of_files + pop esi + mov dx,0308h + mov cl,35h + mov ch,byte [screen_height] + sub ch,7 + mov ah,[window_colors] + call draw_window + push edx + mov eax,[video_pitch] + mov edx,[screen_height] + sub edx,11 + imul edx,eax + lea edx,[edi+edx+8*2] + mov [current_box],edx + lea edi,[edi+eax+2*2] + mov esi,_file + mov ecx,5 + call draw_static + mov ebx,filename_buffer + xor esi,esi + mov ecx,27h + 256 shl 16 + mov edx,[esp] + add dx,0108h + mov al,1 + call create_edit_box + mov ebx,boxes + mov esi,[file_list] + mov ecx,[file_list_buffer_top] + sub ecx,esi + shl ecx,16-2 + mov cl,27h + mov ch,byte [screen_height] + sub ch,15 + pop edx + add dx,0308h + xor al,al + call create_list_box + call draw_browser_path + file_input_loop: + call wait_for_input + cmp ah,1 + je filename_aborted + cmp al,0Dh + je filename_accepted + cmp ah,0Fh + je activate_file_browser + cmp ah,50h + je activate_file_browser + mov ebx,filename_buffer + call process_box_command + jmp file_input_loop + activate_file_browser: + mov ebx,filename_buffer + call kill_box_focus + mov ebx,boxes + call set_box_focus + call update_file_input + file_browser_loop: + call wait_for_input + cmp ah,1 + je filename_aborted + cmp al,0Dh + je filename_accepted + cmp ah,0Fh + je activate_file_input + cmp ah,4Bh + je activate_file_input + cmp al,8 + je go_to_parent_directory + mov ebx,boxes + push dword [ebx+8] + call process_box_command + pop eax + cmp ax,[ebx+8] + je file_browser_loop + call update_file_input + jmp file_browser_loop + go_to_parent_directory: + cmp byte [buffer+3000h+3],0 + je file_browser_loop + mov edi,buffer + mov eax,'..' + stosd + jmp browser_chdir + filename_accepted: + mov edx,filename_buffer+16 + movzx eax,word [edx-16+8] + test eax,eax + jz got_filename + cmp byte [edx+eax-1],'\' + je browser_path_entered + cmp byte [edx+eax-1],':' + jne got_filename + browser_path_entered: + mov esi,edx + mov edi,buffer + copy_path_to_browse: + lodsb + stosb + test al,al + jnz copy_path_to_browse + cmp word [buffer+1],':' + je browser_directory_ok + cmp byte [edi-2],'\' + jne browser_chdir + mov byte [edi-2],0 + browser_chdir: + xor dx,dx + mov ax,713Bh + call dos_int + jnc browser_directory_ok + cmp ax,7100h + jne file_list_selection_ok + mov ah,3Bh + call dos_int + jc file_list_selection_ok + browser_directory_ok: + cmp byte [buffer+1],':' + jne browser_drive_ok + mov dl,[buffer] + sub dl,'A' + cmp dl,'Z'-'A' + jbe browser_change_drive + sub dl,'a'-'A' + browser_change_drive: + mov ah,0Eh + int 21h + browser_drive_ok: + push 0 + cmp dword [buffer],'..' + jne name_to_select_ok + mov edi,buffer+3000h + mov al,'\' + or ecx,-1 + find_last_directory_name: + mov esi,edi + repne scasb + cmp byte [edi],0 + jne find_last_directory_name + lea ecx,[edi-1] + sub ecx,esi + mov edi,buffer+400h + mov [esp],ecx + mov ebx,upper_case_table + get_name_to_select: + lodsb + xlatb + stosb + loop get_name_to_select + name_to_select_ok: + mov edi,buffer+3000h + call get_current_directory + jc browser_drive_invalid + cmp byte [edi-2],'\' + je browser_new_path_ok + mov word [edi-1],'\' + browser_new_path_ok: + call make_list_of_files + call draw_browser_path + mov ebx,filename_buffer + xor eax,eax + mov [ebx+8],eax + mov [ebx+12],eax + mov [ebx+16],al + mov ebx,boxes + mov esi,[file_list] + mov [ebx+12],esi + mov ecx,[file_list_buffer_top] + sub ecx,esi + shr ecx,2 + mov [ebx+6],cx + xor eax,eax + mov [ebx+8],eax + mov eax,esi + pop edx + find_name_to_select: + cmp eax,[file_list_buffer_top] + je file_list_selection_ok + mov esi,[eax] + add esi,2 + mov edi,buffer+400h + mov ecx,edx + repe cmpsb + je select_directory + add eax,4 + jmp find_name_to_select + select_directory: + sub eax,[file_list] + shr eax,2 + mov [ebx+8],ax + file_list_selection_ok: + test byte [filename_buffer+1],1 + jnz activate_file_input + jmp activate_file_browser + browser_drive_invalid: + mov dl,[buffer+3000h] + sub dl,'A' + cmp dl,'Z'-'A' + jbe browser_restore_drive + sub dl,'a'-'A' + browser_restore_drive: + mov ah,0Eh + int 21h + pop eax + jmp file_list_selection_ok + got_filename: + cmp [filename_buffer+16],0 + je file_input_loop + call release_list_of_files + mov edx,filename_buffer+16 + movzx ecx,word [filename_buffer+8] + clc + ret + filename_aborted: + call release_list_of_files + stc + ret + activate_file_input: + mov ebx,boxes + call kill_box_focus + mov ebx,filename_buffer + call set_box_focus + jmp file_input_loop + update_file_input: + mov ebx,boxes + mov esi,[ebx+12] + movzx eax,word [ebx+8] + mov esi,[esi+eax*4] + mov ah,[esi] + add esi,2 + mov edi,filename_buffer+16 + copy_file_item: + lodsb + stosb + test al,al + jnz copy_file_item + cmp ah,[browser_symbols+2] + je file_item_copied + cmp ah,[browser_symbols+3] + je file_item_copied + mov byte [edi-1],'\' + stosb + file_item_copied: + mov ecx,edi + sub ecx,1+filename_buffer+16 + mov ebx,filename_buffer + mov [ebx+8],cx + mov [ebx+12],cx + xor eax,eax + mov [ebx+10],ax + mov [ebx+14],ax + call draw_edit_box + ret + draw_browser_path: + mov edi,[current_box] + mov esi,buffer+3000h + mov ecx,27h + call draw_static + add edi,[video_pitch] + sub edi,27h*2 + mov ecx,27h + call draw_static + ret + make_list_of_files: + cmp [file_list_buffer_handle],0 + je default_buffer_for_file_list + mov edi,[file_list_buffer_top] + mov ecx,[file_list_buffer_size] + sub edi,ecx + jmp init_file_list + default_buffer_for_file_list: + mov edi,buffer+1000h + mov ecx,2000h + init_file_list: + lea ebx,[edi+ecx] + mov [file_list_buffer_top],ebx + mov ah,1Ah + xor edx,edx + call dos_int + mov ah,19h + int 21h + mov dl,al + mov ah,0Eh + int 21h + movzx ecx,al + mov dword [buffer],'A:' + list_drives: + push ecx edi + mov ax,290Ch + xor esi,esi + mov di,10h + call dos_int + pop edi + inc al + jz try_next_drive + cmp byte [buffer],'B' + jne add_drive + test byte [fs:10h],11000000b + jz try_next_drive + add_drive: + sub ebx,4 + mov [ebx],edi + mov esi,buffer + mov ax,2004h + stosw + movsw + movsb + try_next_drive: + inc byte [buffer] + pop ecx + loop list_drives + mov [file_list],ebx + mov [file_list_buffer],edi + cmp byte [buffer+3000h],0 + je file_list_made + mov edi,buffer + mov eax,'*.*' + stosd + mov ax,714Eh + mov cx,31h + xor esi,esi + xor edx,edx + mov di,10h + call dos_int + mov ebx,eax + jnc long_file_names_list + mov ah,4Eh + mov cx,31h + xor edx,edx + call dos_int + jc file_list_made + short_file_names_list: + sub [file_list],4 + mov edx,[file_list] + mov edi,[file_list_buffer] + cmp edi,edx + jae not_enough_memory_for_list + mov [edx],edi + mov esi,buffer+1Eh + test byte [esi-1Eh+15h],10h + jnz short_directory_name + mov ebx,lower_case_table + mov ax,2003h + stosw + jmp copy_short_file_name + short_directory_name: + mov ebx,upper_case_table + cmp word [esi],'..' + je short_parent_directory + cmp byte [esi],'.' + je short_directory_to_hide + mov ax,2002h + stosw + jmp copy_short_file_name + short_parent_directory: + cmp byte [buffer+3000h+3],0 + je short_directory_to_hide + mov ax,2001h + stosw + copy_short_file_name: + lodsb + xlat byte [ebx] + cmp edi,[file_list] + jae not_enough_memory_for_list + stosb + test al,al + jnz copy_short_file_name + short_file_name_copied: + mov [file_list_buffer],edi + mov ah,4Fh + call dos_int + jnc short_file_names_list + jmp file_list_made + short_directory_to_hide: + add [file_list],4 + jmp short_file_name_copied + not_enough_memory_for_long_file_name: + pop ebx + mov ax,71A1h + call dos_int + not_enough_memory_for_list: + cmp [file_list_buffer_handle],0 + jne really_not_enough_memory_for_list + mov ax,500h + mov edi,buffer + int 31h + mov ecx,[edi] + cmp ecx,2000h + jbe really_not_enough_memory_for_list + cmp ecx,100000h + jbe allocate_buffer_for_file_list + mov ecx,100000h + allocate_buffer_for_file_list: + mov [file_list_buffer_size],ecx + call get_memory + or eax,eax + jz really_not_enough_memory_for_list + mov [file_list_buffer_handle],ebx + mov edi,eax + mov ecx,[file_list_buffer_size] + jmp init_file_list + really_not_enough_memory_for_list: + add [file_list],4 + jmp file_list_made + long_file_names_list: + push ebx + sub [file_list],4 + mov edx,[file_list] + mov edi,[file_list_buffer] + cmp edi,edx + jae not_enough_memory_for_long_file_name + mov [edx],edi + mov esi,buffer+10h+2Ch + test byte [esi-2Ch],10h + jnz long_directory_name + mov ax,2003h + stosw + mov ebx,lower_case_table + jmp copy_long_file_name + long_directory_to_hide: + add [file_list],4 + jmp long_file_name_copied + long_directory_name: + mov ebx,upper_case_table + cmp byte [esi],'.' + jne long_directory_show + cmp byte [esi+1],0 + je long_directory_to_hide + cmp word [esi+1],'.' + jne long_directory_show + cmp byte [buffer+3000h+3],0 + je long_directory_to_hide + mov ax,2001h + stosw + jmp copy_long_file_name + long_directory_show: + mov ax,2002h + stosw + copy_long_file_name: + lodsb + xlatb + cmp edi,[file_list] + jae not_enough_memory_for_long_file_name + stosb + test al,al + jnz copy_long_file_name + long_file_name_copied: + mov [file_list_buffer],edi + pop ebx + mov ax,714Fh + xor esi,esi + mov di,10h + call dos_int + jnc long_file_names_list + mov ax,71A1h + call dos_int + file_list_made: + mov edx,[file_list_buffer_top] + sub edx,[file_list] + shr edx,2 + mov ebp,edx + sort_file_list: + shr ebp,1 + jz file_list_sorted + mov ebx,ebp + sorting_iteration: + cmp ebx,edx + jae sort_file_list + mov eax,ebx + place_into_right_blocks: + cmp eax,ebp + jb sort_next_offset + push edx + mov edx,eax + sub eax,ebp + push eax + mov esi,[file_list] + lea eax,[esi+eax*4] + lea edx,[esi+edx*4] + mov esi,[eax] + mov edi,[edx] + mov ecx,257 + repe cmpsb + jbe exchange_ok + mov esi,[eax] + xchg esi,[edx] + mov [eax],esi + exchange_ok: + pop eax edx + jmp place_into_right_blocks + sort_next_offset: + inc ebx + jmp sorting_iteration + file_list_sorted: + mov esi,[file_list] + mov ebx,browser_symbols + make_browser_symbols: + cmp esi,[file_list_buffer_top] + je file_list_done + mov edx,[esi] + mov al,[edx] + dec al + xlatb + mov [edx],al + add esi,4 + jmp make_browser_symbols + file_list_done: + ret + release_list_of_files: + mov ebx,[file_list_buffer_handle] + test ebx,ebx + jz list_of_files_released + call release_memory + list_of_files_released: + ret + goto_dialog: + mov esi,_position + mov dx,080Bh + mov cx,0719h + mov ah,[window_colors] + call draw_window + push edx + push edi + mov eax,[video_pitch] + lea edi,[edi+eax+5*2] + mov esi,_row + mov ecx,4 + call draw_static + pop edi + mov eax,[video_pitch] + lea eax,[eax*3] + lea edi,[edi+eax+2*2] + mov esi,_column + mov ecx,7 + call draw_static + call init_common_dialog + mov edi,buffer+200h + mov esi,edi + mov eax,[caret_line_number] + call number_as_text + xor al,al + stosb + mov dx,[esp] + mov ebx,buffer + mov ecx,9 + 7 shl 16 + add dx,010Ah + mov al,101b + call create_edit_box + call register_box_in_dialog + mov edi,buffer+200h + mov esi,edi + mov eax,[caret_position] + inc eax + call number_as_text + xor al,al + stosb + pop edx + mov ebx,buffer+100h + mov ecx,9 + 7 shl 16 + add dx,030Ah + mov al,100b + call create_edit_box + call register_box_in_dialog + mov [common_dialog_callback],0 + call common_dialog_loop + jc goto_dialog_done + mov esi,buffer+16 + call get_entered_number + mov ecx,edx + mov esi,buffer+100h+16 + call get_entered_number + clc + goto_dialog_done: + ret + find_dialog: + push [find_flags] + mov esi,_find + mov dx,050Dh + mov cx,0A36h + mov ah,[window_colors] + call draw_window + push edx + mov eax,[video_pitch] + lea edi,[edi+eax+2*2] + mov esi,_text_to_find + mov ecx,13 + call draw_static + call init_common_dialog + call get_word_at_caret + mov edi,[line_buffer] + mov esi,[caret_line] + call copy_from_line + xor al,al + stosb + mov dx,[esp] + mov ebx,buffer + mov esi,[line_buffer] + mov ecx,32 + 1000 shl 16 + add dx,0110h + mov al,1 + call create_edit_box + call register_box_in_dialog + mov dx,[esp] + mov ebx,buffer+800h + mov esi,_case_sensitive + mov edi,find_flags + mov ebp,FEFIND_CASESENSITIVE + add dx,0310h + mov cl,18h + xor al,al + call create_check_box + call register_box_in_dialog + mov dx,[esp] + mov ebx,buffer+810h + mov esi,_whole_words + mov edi,find_flags + mov ebp,FEFIND_WHOLEWORDS + add dx,0410h + mov cl,18h + xor al,al + call create_check_box + call register_box_in_dialog + mov dx,[esp] + mov ebx,buffer+820h + mov esi,_backward + mov edi,find_flags + mov ebp,FEFIND_BACKWARD + add dx,0510h + mov cl,18h + xor al,al + call create_check_box + call register_box_in_dialog + pop edx + mov ebx,buffer+830h + mov esi,_search_in_whole_text + mov edi,find_flags + mov ebp,FEFIND_INWHOLETEXT + add dx,0610h + mov cl,18h + xor al,al + call create_check_box + call register_box_in_dialog + mov [common_dialog_callback],0 + call common_dialog_loop + pop eax + jc find_dialog_aborted + mov esi,buffer+16 + mov eax,[find_flags] + clc + ret + find_dialog_aborted: + mov [find_flags],eax + ret + replace_dialog: + push [find_flags] + mov esi,_replace + mov dx,050Dh + mov cx,0D36h + mov ah,[window_colors] + call draw_window + push edx + push edi + mov eax,[video_pitch] + lea edi,[edi+eax+2*2] + mov esi,_text_to_find + mov ecx,13 + call draw_static + pop edi + mov eax,[video_pitch] + imul eax,3 + lea edi,[edi+eax+6*2] + mov esi,_new_text + mov ecx,9 + call draw_static + call init_common_dialog + call get_word_at_caret + mov edi,[line_buffer] + mov esi,[caret_line] + call copy_from_line + xor al,al + stosb + mov dx,[esp] + mov ebx,buffer + mov esi,[line_buffer] + mov ecx,32 + 1000 shl 16 + add dx,0110h + mov al,1 + call create_edit_box + call register_box_in_dialog + mov dx,[esp] + mov ebx,buffer+400h + xor esi,esi + mov ecx,32 + 1000 shl 16 + add dx,0310h + xor al,al + call create_edit_box + call register_box_in_dialog + mov dx,[esp] + mov ebx,buffer+800h + mov esi,_case_sensitive + mov edi,find_flags + mov ebp,FEFIND_CASESENSITIVE + add dx,0510h + mov cl,18h + xor al,al + call create_check_box + call register_box_in_dialog + mov dx,[esp] + mov ebx,buffer+810h + mov esi,_whole_words + mov edi,find_flags + mov ebp,FEFIND_WHOLEWORDS + add dx,0610h + mov cl,18h + xor al,al + call create_check_box + call register_box_in_dialog + mov dx,[esp] + mov ebx,buffer+820h + mov esi,_backward + mov edi,find_flags + mov ebp,FEFIND_BACKWARD + add dx,0710h + mov cl,18h + xor al,al + call create_check_box + call register_box_in_dialog + mov dx,[esp] + mov ebx,buffer+830h + mov esi,_replace_in_whole_text + mov edi,find_flags + mov ebp,FEFIND_INWHOLETEXT + add dx,0810h + mov cl,18h + xor al,al + call create_check_box + call register_box_in_dialog + pop edx + mov ebx,buffer+840h + mov esi,_prompt + mov edi,command_flags + mov ebp,1 + add dx,0910h + mov cl,18h + xor al,al + call create_check_box + call register_box_in_dialog + mov [common_dialog_callback],0 + call common_dialog_loop + pop eax + jc replace_dialog_aborted + mov esi,buffer+16 + mov edi,buffer+400h+16 + mov eax,[find_flags] + clc + ret + replace_dialog_aborted: + mov [find_flags],eax + ret + options_dialog: + mov esi,_options + mov dx,0616h + mov cx,0922h + mov ah,[window_colors] + call draw_window + push edx + call init_common_dialog + mov ebx,buffer + mov esi,_secure_selection + mov edi,editor_style + mov ebp,FES_SECURESEL + add dx,0102h + mov cl,16h + mov al,1 + call create_check_box + call register_box_in_dialog + mov dx,[esp] + mov ebx,buffer+10h + mov esi,_auto_brackets + mov edi,editor_style + mov ebp,FES_AUTOBRACKETS + add dx,0202h + mov cl,16h + xor al,al + call create_check_box + call register_box_in_dialog + mov dx,[esp] + mov ebx,buffer+20h + mov esi,_auto_indent + mov edi,editor_style + mov ebp,FES_AUTOINDENT + add dx,0302h + mov cl,16h + xor al,al + call create_check_box + call register_box_in_dialog + mov dx,[esp] + mov ebx,buffer+30h + mov esi,_smart_tabs + mov edi,editor_style + mov ebp,FES_SMARTTABS + add dx,0402h + mov cl,16h + xor al,al + call create_check_box + call register_box_in_dialog + pop edx + mov ebx,buffer+40h + mov esi,_optimal_fill + mov edi,editor_style + mov ebp,FES_OPTIMALFILL + add dx,0502h + mov cl,16h + xor al,al + call create_check_box + call register_box_in_dialog + mov [common_dialog_callback],0 + jmp common_dialog_loop + ascii_table_window: + mov esi,_ascii_table + mov dx,0616h + mov cx,0C24h + mov ah,[window_colors] + call draw_window + push edx + mov ah,[window_colors] + xor al,al + mov edx,8 + draw_ascii_table: + mov ecx,32 + draw_ascii_row: + mov [gs:edi],ax + add edi,2 + inc al + loop draw_ascii_row + add edi,[video_pitch] + sub edi,32*2 + dec edx + jnz draw_ascii_table + mov ecx,32 + draw_ascii_table_border: + mov byte [gs:edi+(ecx-1)*2],'Ä' + loop draw_ascii_table_border + add edi,[video_pitch] + push edi + mov ah,1 + mov cx,000Fh + int 10h + ascii_table_update: + mov dl,[selected_character] + mov dh,dl + and dl,11111b + shr dh,5 + add dx,word [esp+4] + mov ah,2 + xor bh,bh + int 10h + mov edi,screen_row_buffer+10h + mov eax,'Dec:' + stosd + mov al,20h + stosb + movzx eax,[selected_character] + call number_as_text + mov al,20h + stosb + mov eax,'Hex:' + stosd + mov al,20h + stosb + mov al,[selected_character] + shr al,4 + cmp al,10 + sbb al,69h + das + stosb + mov al,[selected_character] + and al,0Fh + cmp al,10 + sbb al,69h + das + stosb + xor al,al + stosb + sub edi,30+1 + mov esi,edi + mov eax,'Char' + stosd + mov eax,'acte' + stosd + mov eax,'r: ' + stosd + mov ecx,screen_row_buffer+10h + sub ecx,edi + mov al,20h + rep stosb + mov edi,[esp] + add edi,1*2 + mov ecx,30 + call draw_static + mov edi,[esp] + mov al,[selected_character] + mov [gs:edi+12*2],al + ascii_table_loop: + call wait_for_input + or ah,ah + jz pure_ascii_char + cmp ah,48h + je ascii_table_up + cmp ah,50h + je ascii_table_down + cmp ah,4Bh + je ascii_table_left + cmp ah,4Dh + je ascii_table_right + cmp ah,1 + je ascii_table_exit + cmp al,0E0h + je ascii_table_loop + cmp al,13 + je ascii_table_done + cmp al,2 + je ascii_table_done + cmp al,20h + jb ascii_table_loop + pure_ascii_char: + mov [selected_character],al + jmp ascii_table_update + ascii_table_exit: + pop eax eax + stc + ret + ascii_table_done: + pop eax eax + mov al,[selected_character] + clc + ret + ascii_table_up: + cmp [selected_character],20h + jb ascii_table_loop + sub [selected_character],20h + jmp ascii_table_update + ascii_table_down: + cmp [selected_character],0E0h + jae ascii_table_loop + add [selected_character],20h + jmp ascii_table_update + ascii_table_left: + test [selected_character],11111b + jz ascii_table_loop + dec [selected_character] + jmp ascii_table_update + ascii_table_right: + mov al,[selected_character] + inc al + test al,11111b + jz ascii_table_loop + mov [selected_character],al + jmp ascii_table_update + calculator_window: + mov [results_selection],0 + mov esi,_calculator + mov dx,0602h + mov cx,0B4Ch + mov ah,[window_colors] + call draw_window + push edi edx + mov eax,[video_pitch] + lea edi,[edi+eax+2*2] + mov esi,_expression + mov ecx,11 + call draw_static + mov eax,[video_pitch] + lea eax,[eax*3] + mov edi,[esp+4] + lea edi,[edi+eax+2*2] + mov esi,_result + mov ecx,65 + call draw_static + call init_common_dialog + mov ebx,buffer + xor esi,esi + mov ecx,56 + 1000 shl 16 + mov dx,[esp] + add dx,010Eh + mov al,1 + call create_edit_box + call register_box_in_dialog + mov ebx,buffer+2000h + mov esi,_null + mov edi,results_selection + xor ebp,ebp + mov dx,[esp] + add dx,0402h + mov cl,18h + mov al,2 + call create_check_box + call register_box_in_dialog + mov ebx,buffer+2010h + mov esi,_null + mov edi,results_selection + mov ebp,1 + mov dx,[esp] + add dx,0502h + mov cl,18h + mov al,2 + call create_check_box + call register_box_in_dialog + mov ebx,buffer+2020h + mov esi,_null + mov edi,results_selection + mov ebp,2 + mov dx,[esp] + add dx,0602h + mov cl,18h + mov al,2 + call create_check_box + call register_box_in_dialog + mov ebx,buffer+2030h + mov esi,_null + mov edi,results_selection + mov ebp,3 + mov dx,[esp] + add dx,0702h + mov cl,18h + mov al,2 + call create_check_box + call register_box_in_dialog + pop edx edi + mov eax,[video_pitch] + lea edi,[edi+eax*4+6*2] + mov [results_offset],edi + mov [common_dialog_callback],calculate_result + calculator_loop: + call common_dialog_loop + jc close_calculator + mov esi,[results_offset] + mov eax,[results_selection] + imul eax,[video_pitch] + add esi,eax + mov edi,buffer+16 + copy_result: + lods byte [gs:esi] + cmp al,20h + je result_ready + stosb + inc esi + jmp copy_result + result_ready: + mov ecx,edi + sub ecx,buffer+16 + mov ebx,buffer + mov [ebx+8],cx + mov [ebx+12],cx + xor eax,eax + mov [ebx+10],ax + mov [ebx+14],ax + cmp [current_box],0 + jne activate_expression_box + call draw_edit_box + jmp calculator_loop + activate_expression_box: + mov edx,[current_box] + mov ebx,[boxes+edx*4] + call kill_box_focus + mov [current_box],0 + mov ebx,buffer + call set_box_focus + jmp calculator_loop + close_calculator: + ret + calculate_result: + mov esi,buffer+16 + movzx eax,word [buffer+8] + lea edi,[esi+eax] + xor eax,eax + stosb + mov [progress_offset],eax + mov [hash_tree],eax + mov [macro_status],al + mov [symbols_file],eax + not eax + mov [source_start],eax + mov eax,buffer+1000h + mov [memory_end],eax + mov [labels_list],eax + mov [resume_esp],esp + mov [resume_eip],calculator_error + call convert_line + push edi + call convert_expression + cmp byte [esi],0 + jne invalid_expression + mov al,')' + stosb + pop esi + mov [error_line],0 + mov [current_line],-1 + mov [value_size],0 + call calculate_expression + cmp [error_line],0 + je present_result + jmp [error] + present_result: + mov ebp,edi + cmp byte [ebp+13],0 + je result_in_64bit_composite_range + test byte [ebp+7],80h + jnz result_in_64bit_composite_range + mov esi,_null + mov edi,[results_offset] + add edi,[video_pitch] + mov ecx,65 + push edi + call draw_static + pop edi + add edi,[video_pitch] + mov ecx,65 + push edi + call draw_static + pop edi + add edi,[video_pitch] + mov ecx,65 + call draw_static + jmp present_decimal + result_in_64bit_composite_range: + mov eax,[ebp] + mov edx,[ebp+4] + mov edi,buffer+3000h + mov word [edi],'b' + make_binary_number: + mov bl,'0' + shrd eax,edx,1 + adc bl,0 + dec edi + mov [edi],bl + shr edx,1 + jnz make_binary_number + test eax,eax + jnz make_binary_number + mov esi,edi + mov eax,[video_pitch] + mov edi,[results_offset] + lea edi,[edi+eax*2] + mov ecx,65 + call draw_static + mov ecx,[ebp] + mov edx,[ebp+4] + mov edi,buffer+3000h + mov word [edi],'o' + make_octal_number: + mov al,cl + and al,111b + add al,'0' + dec edi + mov [edi],al + shrd ecx,edx,3 + shr edx,3 + jnz make_octal_number + test ecx,ecx + jnz make_octal_number + mov esi,edi + mov eax,[video_pitch] + mov edi,[results_offset] + lea eax,[eax*3] + add edi,eax + mov ecx,65 + call draw_static + mov ecx,[ebp] + mov edx,[ebp+4] + mov edi,buffer+3000h + mov word [edi],'h' + make_hexadecimal_number: + mov al,cl + and al,0Fh + cmp al,10 + sbb al,69h + das + dec edi + mov [edi],al + shrd ecx,edx,4 + shr edx,4 + jnz make_hexadecimal_number + test ecx,ecx + jnz make_hexadecimal_number + cmp al,'A' + jb hexadecimal_number_ok + dec edi + mov byte [edi],'0' + hexadecimal_number_ok: + mov esi,edi + mov eax,[video_pitch] + mov edi,[results_offset] + lea edi,[edi+eax] + mov ecx,65 + call draw_static + present_decimal: + mov edi,buffer+3000h + mov byte [edi],0 + mov ecx,10 + xor bl,bl + cmp byte [ebp+13],0 + je make_decimal_number + mov bl,'-' + mov eax,[ebp] + mov edx,[ebp+4] + not eax + not edx + add eax,1 + adc edx,0 + mov [ebp],eax + mov [ebp+4],edx + or eax,edx + jnz make_decimal_number + dec edi + mov byte [edi],'6' + mov dword [ebp],99999999h + mov dword [ebp+4],19999999h + make_decimal_number: + mov eax,[ebp+4] + xor edx,edx + div ecx + mov [ebp+4],eax + mov eax,[ebp] + div ecx + mov [ebp],eax + add dl,'0' + dec edi + mov [edi],dl + or eax,[ebp+4] + jnz make_decimal_number + test bl,bl + jz decimal_number_ok + dec edi + mov [edi],bl + decimal_number_ok: + mov esi,edi + mov edi,[results_offset] + mov ecx,65 + call draw_static + ret + calculator_error: + mov ebx,[video_pitch] + mov ebp,[results_offset] + mov edx,4 + clear_results: + mov ecx,65 + mov edi,ebp + call fill_static + add ebp,ebx + dec edx + jnz clear_results + ret + +; Memory allocation + + get_memory: + push esi edi + mov ebx,ecx + shr ebx,16 + mov ax,501h + int 31h + jc dpmi_allocation_failed + mov ax,bx + shl eax,16 + mov ax,cx + mov edx,main + shl edx,4 + sub eax,edx + mov bx,si + shl ebx,16 + mov bx,di + pop edi esi + ret + dpmi_allocation_failed: + xor eax,eax + pop edi esi + ret + release_memory: + push esi edi + mov esi,ebx + shr esi,16 + mov di,bx + mov ax,502h + int 31h + pop edi esi + ret + get_low_memory: + mov ax,100h + mov bx,-1 + int 31h + movzx eax,bx + shl eax,4 + mov [low_memory_size],eax + mov ax,100h + int 31h + mov [low_memory_selector],dx + jnc low_memory_ok + xor edx,edx + mov [low_memory_size],edx + low_memory_ok: + ret + release_low_memory: + cmp [low_memory_size],0 + je low_memory_ok + mov ax,101h + mov dx,[low_memory_selector] + int 31h + ret + +; File operations + + dos_int: + push 0 + push 0 + push 0 + pushw buffer_segment + pushw buffer_segment + stc + pushfw + push eax + push ecx + push edx + push ebx + push 0 + push ebp + push esi + push edi + mov ax,300h + mov bx,21h + xor cx,cx + mov edi,esp + push es ss + pop es + int 31h + pop es + mov edi,[esp] + mov esi,[esp+4] + mov ebp,[esp+8] + mov ebx,[esp+10h] + mov edx,[esp+14h] + mov ecx,[esp+18h] + mov ah,[esp+20h] + sahf + mov eax,[esp+1Ch] + lea esp,[esp+32h] + ret + open: + push esi edi + call adapt_path + mov ax,716Ch + mov bx,100000b + mov dx,1 + xor cx,cx + xor si,si + call dos_int + jnc open_done + cmp ax,7100h + je old_open + stc + jmp open_done + old_open: + mov ax,3D00h + xor dx,dx + call dos_int + open_done: + mov bx,ax + pop edi esi + ret + adapt_path: + mov esi,edx + mov edi,buffer + copy_path: + lodsb + cmp al,'/' + jne path_char_ok + mov al,'\' + path_char_ok: + stosb + or al,al + jnz copy_path + ret + create: + push esi edi + call adapt_path + mov ax,716Ch + mov bx,100001b + mov dx,10010b + xor cx,cx + xor si,si + xor di,di + call dos_int + jnc create_done + cmp ax,7100h + je old_create + stc + jmp create_done + old_create: + mov ah,3Ch + xor cx,cx + xor dx,dx + call dos_int + create_done: + mov bx,ax + pop edi esi + ret + write: + push edx esi edi ebp + mov ebp,ecx + mov esi,edx + write_loop: + mov ecx,1000h + sub ebp,1000h + jnc do_write + add ebp,1000h + mov ecx,ebp + xor ebp,ebp + do_write: + push ecx + mov edi,buffer + shr ecx,2 + rep movsd + mov ecx,[esp] + and ecx,11b + rep movsb + pop ecx + mov ah,40h + xor dx,dx + call dos_int + or ebp,ebp + jnz write_loop + pop ebp edi esi edx + ret + read: + push edx esi edi ebp + mov ebp,ecx + mov edi,edx + read_loop: + mov ecx,1000h + sub ebp,1000h + jnc do_read + add ebp,1000h + mov ecx,ebp + xor ebp,ebp + do_read: + push ecx + mov ah,3Fh + xor dx,dx + call dos_int + cmp ax,cx + jne eof + mov esi,buffer + mov ecx,[esp] + shr ecx,2 + rep movsd + pop ecx + and ecx,11b + rep movsb + or ebp,ebp + jnz read_loop + read_done: + pop ebp edi esi edx + ret + eof: + pop ecx + stc + jmp read_done + close: + mov ah,3Eh + int 21h + ret + lseek: + mov ah,42h + mov ecx,edx + shr ecx,16 + int 21h + pushf + shl edx,16 + popf + mov dx,ax + mov eax,edx + ret + +; Other functions needed by assembler core + + get_environment_variable: + push esi edi + mov ebx,_section_environment + call get_ini_value + pop edi ebx + jnc found_value_in_ini + push ds + mov ds,[environment_selector] + xor esi,esi + compare_variable_names: + mov edx,ebx + compare_name_char: + lodsb + mov ah,[es:edx] + inc edx + cmp al,'=' + je end_of_variable_name + or ah,ah + jz next_variable + sub ah,al + jz compare_name_char + cmp ah,20h + jne next_variable + cmp al,41h + jb next_variable + cmp al,5Ah + jna compare_name_char + next_variable: + lodsb + or al,al + jnz next_variable + cmp byte [esi],0 + jne compare_variable_names + pop ds + ret + end_of_variable_name: + or ah,ah + jnz next_variable + copy_variable_value: + lodsb + cmp edi,[es:memory_end] + jae out_of_memory + stosb + or al,al + jnz copy_variable_value + dec edi + pop ds + ret + found_value_in_ini: + lea eax,[edi+ecx] + cmp eax,[memory_end] + jae out_of_memory + rep movsb + ret + make_timestamp: + mov ah,2Ah + int 21h + push dx cx + movzx ecx,cx + mov eax,ecx + sub eax,1970 + mov ebx,365 + mul ebx + mov ebp,eax + mov eax,ecx + sub eax,1969 + shr eax,2 + add ebp,eax + mov eax,ecx + sub eax,1901 + mov ebx,100 + div ebx + sub ebp,eax + mov eax,ecx + xor edx,edx + sub eax,1601 + mov ebx,400 + div ebx + add ebp,eax + movzx ecx,byte [esp+3] + mov eax,ecx + dec eax + mov ebx,30 + mul ebx + add ebp,eax + cmp ecx,8 + jbe months_correction + mov eax,ecx + sub eax,7 + shr eax,1 + add ebp,eax + mov ecx,8 + months_correction: + mov eax,ecx + shr eax,1 + add ebp,eax + cmp ecx,2 + pop cx + jbe day_correction_ok + sub ebp,2 + test ecx,11b + jnz day_correction_ok + xor edx,edx + mov eax,ecx + mov ebx,100 + div ebx + or edx,edx + jnz day_correction + mov eax,ecx + mov ebx,400 + div ebx + or edx,edx + jnz day_correction_ok + day_correction: + inc ebp + day_correction_ok: + pop dx + movzx eax,dl + dec eax + add eax,ebp + mov ebx,24 + mul ebx + push eax + mov ah,2Ch + int 21h + pop eax + push dx + movzx ebx,ch + add eax,ebx + mov ebx,60 + mul ebx + movzx ebx,cl + add eax,ebx + mov ebx,60 + mul ebx + pop bx + movzx ebx,bh + add eax,ebx + adc edx,0 + ret + display_block: + mov edi,[display_length] + mov eax,[display_length] + add eax,ecx + cmp eax,[low_memory_size] + ja not_enough_memory + mov [display_length],eax + push es + mov es,[low_memory_selector] + rep movsb + pop es + ret + +; Error handling + + not_enough_memory: + call update_screen + mov esi,_memory_error + mov ebx,_error + movzx eax,[error_box_colors] + call message_box + mov esp,stack_top + jmp main_loop + + fatal_error: + cmp [progress_offset],0 + je error_outside_compiler + pop esi + mov esp,stack_top + push esi + mov ax,205h + mov bl,9 + mov edx,dword [keyboard_handler] + mov cx,word [keyboard_handler+4] + int 31h + mov ebx,[allocated_memory] + call release_memory + call update_screen + show_error_summary: + mov esi,buffer+3000h + call go_to_directory + mov esi,_assembler_error + mov edi,buffer + mov ebx,esp + call sprintf + mov esi,buffer + mov ebx,_compile + movzx eax,[error_box_colors] + mov [first_button],_ok + mov [second_button],_get_display + cmp [display_length],0 + je show_compilation_summary + or eax,2000000h + jmp show_compilation_summary + assembler_error: + cmp [progress_offset],0 + je error_outside_compiler + pop esi + mov esp,stack_top + push esi + mov ax,205h + mov bl,9 + mov edx,dword [keyboard_handler] + mov cx,word [keyboard_handler+4] + int 31h + and [output_file],0 + call show_display_buffer + call update_screen + mov ebx,[current_line] + find_error_origin: + test dword [ebx+4],80000000h + jz error_origin_found + mov ebx,[ebx+8] + jmp find_error_origin + error_origin_found: + mov esi,[ebx] + mov edi,filename_buffer + copy_error_file: + lodsb + stosb + or al,al + jnz copy_error_file + push dword [ebx+4] + mov ebx,[allocated_memory] + call release_memory + mov edx,filename_buffer + call load_file + show_error_line: + pop eax + call find_line + xor eax,eax + mov [selection_line],esi + mov [selection_line_number],ecx + mov [selection_position],eax + mov [caret_position],eax + push esi + lea edi,[esi+SEGMENT_HEADER_LENGTH] + lea ebp,[esi+SEGMENT_LENGTH] + mov ebx,characters + xor edx,edx + check_for_more_lines: + call peek_character + jc no_more_lines + cmp al,3Bh + je no_more_lines + mov ah,al + xlatb + or al,al + jz symbol + or edx,edx + jnz neutral + cmp ah,27h + je quoted + cmp ah,22h + je quoted + neutral: + or edx,-1 + jmp check_for_more_lines + peek_character: + cmp edi,ebp + je peek_next_segment + mov al,[edi] + inc edi + clc + ret + peek_next_segment: + mov esi,[esi] + btr esi,0 + lea edi,[esi+SEGMENT_HEADER_LENGTH] + lea ebp,[esi+SEGMENT_LENGTH] + jc peek_character + stc + ret + symbol: + cmp ah,'\' + je backslash + xor edx,edx + jmp check_for_more_lines + quoted: + call peek_character + jc no_more_lines + cmp al,ah + jne quoted + call peek_character + jc no_more_lines + cmp al,ah + je quoted + dec edi + xor edx,edx + jmp check_for_more_lines + backslash: + call peek_character + jc more_lines + cmp al,20h + je backslash + cmp al,3Bh + jne no_more_lines + comment: + mov esi,[esi] + btr esi,0 + jc comment + more_lines: + or esi,esi + jz last_line + inc ecx + mov [esp],esi + jmp check_for_more_lines + last_line: + pop [caret_line] + mov [caret_line_number],ecx + mov eax,[maximum_position] + mov [caret_position],eax + jmp error_line_highlighted + no_more_lines: + or esi,esi + jz last_line + pop eax + inc ecx + mov [caret_line],esi + mov [caret_line_number],ecx + error_line_highlighted: + call let_caret_appear + mov eax,[caret_line] + xchg eax,[selection_line] + mov [caret_line],eax + mov eax,[caret_line_number] + xchg eax,[selection_line_number] + mov [caret_line_number],eax + mov eax,[caret_position] + xchg eax,[selection_position] + mov [caret_position],eax + call let_caret_appear + call update_window + call update_screen + jmp show_error_summary + error_outside_compiler: + mov esp,[resume_esp] + jmp [resume_eip] + +; Assembler core + + include '..\..\errors.inc' + include '..\..\symbdump.inc' + include '..\..\preproce.inc' + include '..\..\parser.inc' + include '..\..\exprpars.inc' + include '..\..\assemble.inc' + include '..\..\exprcalc.inc' + include '..\..\formats.inc' + include '..\..\x86_64.inc' + include '..\..\avx.inc' + +; Assembler constants + + include '..\..\tables.inc' + include '..\..\messages.inc' + include '..\..\version.inc' + +; String constants + + _caption db 'flat assembler ',VERSION_STRING,0 + _copyright db 'Copyright (c) 1999-2022, Tomasz Grysztar',0 + + _null db 0 + _untitled db 'Untitled',0 + _compile db 'Compile',0 + _error db 'Error',0 + _ok db 'OK',0 + _yes db 'Yes',0 + _no db 'No',0 + _get_display db 'Get display to clipboard',0 + _open db 'Open',0 + _save_as db 'Save as',0 + _file db 'File:',0 + _position db 'Position',0 + _row db 'Row:',0 + _column db 'Column:',0 + _find db 'Find',0 + _replace db 'Replace',0 + _text_to_find db 'Text to find:',0 + _new_text db 'New text:',0 + _expression db 'Expression:',0 + _result db 'Result:',0 + _case_sensitive db 'Case sensitive',0 + _whole_words db 'Whole words',0 + _backward db 'Backward search',0 + _search_in_whole_text db 'Search in whole text',0 + _replace_in_whole_text db 'Replace in whole text',0 + _prompt db 'Prompt on replace',0 + _options db 'Editor options',0 + _secure_selection db 'Secure selection',0 + _auto_brackets db 'Automatic brackets',0 + _auto_indent db 'Automatic indents',0 + _smart_tabs db 'Smart tabulation',0 + _optimal_fill db 'Optimal fill on saving',0 + _ascii_table db 'ASCII table',0 + _calculator db 'Calculator',0 + + _startup_failed db 'Failed to allocate required memory.',0 + _memory_error db 'Not enough memory to complete this operation.',0 + _loading_error db 'Could not load file %s.',0 + _saving_error db 'Could not write file to disk.',0 + _not_executable db 'Cannot execute this kind of file.',0 + _saving_question db 'File was modified. Save it now?',0 + _overwrite_question db 'File %s already exists. Do you want to replace it?',0 + _directory_question db 'Directory %s does not exist. Do you want to create it now?',0 + _directory_error db 'Failed to create the directory.',0 + _invalid_path db 'Invalid path.',0 + _not_found_after db 'Text %s not found after current position.',0 + _not_found_before db 'Text %s not found before current position.',0 + _replace_prompt db 'Replace this occurence?',0 + _replaces_made db '%d replaces made.',0 + _assembler_error db 'Error: %s.',0 + + _section_environment db 'Environment',0 + _section_compiler db 'Compiler',0 + _key_compiler_memory db 'Memory',0 + _key_compiler_passes db 'Passes',0 + _section_options db 'Options',0 + _key_options_securesel db 'SecureSelection',0 + _key_options_autobrackets db 'AutoBrackets',0 + _key_options_autoindent db 'AutoIndent',0 + _key_options_smarttabs db 'SmartTabs',0 + _key_options_optimalfill db 'OptimalFill',0 + _section_colors db 'Colors',0 + _key_color_text db 'Text',0 + _key_color_background db 'Background',0 + _key_color_seltext db 'SelectionText',0 + _key_color_selbackground db 'SelectionBackground',0 + _key_color_symbols db 'Symbols',0 + _key_color_numbers db 'Numbers',0 + _key_color_strings db 'Strings',0 + _key_color_comments db 'Comments',0 + _key_color_statustext db 'StatusText',0 + _key_color_statusbackground db 'StatusBackground',0 + _key_color_wintext db 'WindowText',0 + _key_color_winbackground db 'WindowBackground',0 + _key_color_msgtext db 'MessageText',0 + _key_color_msgbackground db 'MessageBackground',0 + _key_color_msgseltext db 'MessageSelectionText',0 + _key_color_msgselbackground db 'MessageSelectionBackground',0 + _key_color_errtext db 'ErrorText',0 + _key_color_errbackground db 'ErrorBackground',0 + _key_color_errseltext db 'ErrorSelectionText',0 + _key_color_errselbackground db 'ErrorSelectionBackground',0 + _key_color_boxtext db 'BoxText',0 + _key_color_boxbackground db 'BoxBackground',0 + _key_color_boxseltext db 'BoxSelectionText',0 + _key_color_boxselbackground db 'BoxSelectionBackground',0 + +; Configuration + + editor_style dd FES_AUTOINDENT+FES_SMARTTABS+FES_SECURESEL+FES_OPTIMALFILL + + text_colors db 87h + selection_colors db 7Fh + symbol_color db 0Fh + number_color db 0Ah + string_color db 0Ch + comment_color db 3 + status_colors db 2Fh + window_colors db 3Fh + box_colors db 1Fh + box_selection_colors db 9Fh + message_box_colors dw 3F1Fh + error_box_colors dw 4E6Eh + +; Other constants + + browser_symbols db 18h,09h,07h,0F0h + +; Editor core + + include '..\memory.inc' + include '..\navigate.inc' + include '..\edit.inc' + include '..\blocks.inc' + include '..\search.inc' + include '..\undo.inc' + +; Editor constants + + SEGMENT_LENGTH = 160 + BLOCK_LENGTH = 1024 * SEGMENT_LENGTH + SEGMENT_HEADER_LENGTH = 16 + SEGMENT_DATA_LENGTH = SEGMENT_LENGTH - SEGMENT_HEADER_LENGTH + + FEMODE_OVERWRITE = 1 + FEMODE_VERTICALSEL = 2 + FEMODE_NOUNDO = 4 + FEMODE_READONLY = 8 + + FEFIND_CASESENSITIVE = 1 + FEFIND_WHOLEWORDS = 2 + FEFIND_BACKWARD = 4 + FEFIND_INWHOLETEXT = 8 + + FES_AUTOINDENT = 0001h + FES_AUTOBRACKETS = 0002h + FES_SMARTTABS = 0004h + FES_SECURESEL = 0008h + FES_OPTIMALFILL = 0010h + + include '..\version.inc' + +; Editor data + + editor_data: + + next_instance dd ? + previous_instance dd ? + file_path dd ? + file_path_handle dd ? + + include '..\variable.inc' + + editor_data_size = $ - editor_data + + if editor_data_size > SEGMENT_DATA_LENGTH + err + end if + + lower_case_table db 100h dup ? + upper_case_table db 100h dup ? + +; Assembler core data + + include '..\..\variable.inc' + +; Interface specific data + + psp_selector dw ? + environment_selector dw ? + main_selector dw ? + bios_selector dw ? + video_selector dw ? + + screen_width dd ? + screen_height dd ? + video_pitch dd ? + + video_storage dd ? + video_storage_handle dd ? + stored_cursor dw ? + stored_cursor_position dw ? + stored_page db ? + stored_mode db ? + + low_memory_size dd ? + low_memory_selector dw ? + + last_operation db ? + current_operation db ? + was_selection db ? + + line_buffer dd ? + line_buffer_size dd ? + line_buffer_handle dd ? + screen_offset dd ? + screen_row_buffer db 512 dup ? + + clipboard dd ? + clipboard_handle dd ? + + main_project_file dd ? + memory_limit dd ? + allocated_memory dd ? + start_time dd ? + progress_offset dd ? + keyboard_handler dp ? + display_length dd ? + + find_flags dd ? + replaces_count dd ? + selected_character db ? + command_flags db ? + message_width db ? + buttons_width db ? + first_button dd ? + second_button dd ? + + file_handle dd ? + filename_buffer db 17+256 dup ? + + ini_data dd ? + ini_data_handle dd ? + ini_data_length dd ? + ini_extension dd ? + ini_path db 260 dup ? + + file_list dd ? + file_list_buffer dd ? + file_list_buffer_top dd ? + file_list_buffer_handle dd ? + file_list_buffer_size dd ? + + current_box dd ? + boxes_count dd ? + boxes dd 16 dup ? + common_dialog_callback dd ? + + resume_esp dd ? + resume_eip dd ? + results_offset dd ? + results_selection dd ? + +segment buffer_segment + + buffer = (buffer_segment-main) shl 4 + + db 4000h dup ? + +segment stack_segment + + stack_bottom = (stack_segment-main) shl 4 + + db 4000h dup ? + + stack_top = stack_bottom + $ diff --git a/toolchain/fasmw17332/SOURCE/IDE/FASMW/FASM.INC b/toolchain/fasmw17332/SOURCE/IDE/FASMW/FASM.INC new file mode 100644 index 0000000..6667449 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/IDE/FASMW/FASM.INC @@ -0,0 +1,467 @@ + +; flat assembler interface for Win32 IDE +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +flat_assembler: + + mov [initial_definitions],0 + mov edx,[esp+4] + invoke GetFullPathName,edx,1000h,path_buffer,param_buffer + or eax,eax + jz exit_program + mov esi,path_buffer + mov [input_file],esi + mov [symbols_file],0 + test [command_flags],2 + jz symbols_file_name_ok + mov edi,path_buffer+1000h + mov [symbols_file],edi + mov ecx,eax + rep movsb + mov ecx,eax + xor al,al + stosb + sub edi,2 + mov ebx,edi + mov al,'.' + std + repne scasb + cld + je attach_fas_extension + mov edi,ebx + attach_fas_extension: + inc edi + mov eax,'.fas' + stosd + xor al,al + stosb + symbols_file_name_ok: + mov [hfile],0 + + invoke GlobalAlloc,GMEM_MOVEABLE,1 + mov [hmem_display],eax + invoke GlobalLock,[hmem_display] + mov byte [eax],0 + invoke GlobalUnlock,[hmem_display] + mov [display_size],1 + mov [error_data_size],0 + mov [allocated_memory],0 + mov eax,[compiler_memory] + shl eax,10 + jz out_of_memory + allocate_memory: + mov edx,eax + shr edx,2 + mov ecx,eax + sub ecx,edx + mov [memory_end],ecx + mov [additional_memory_end],edx + invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE + or eax,eax + jnz memory_allocated + mov eax,[additional_memory_end] + shl eax,1 + cmp eax,4000h + jb out_of_memory + jmp allocate_memory + memory_allocated: + mov [allocated_memory],eax + mov [memory_start],eax + mov [code_start],eax + add eax,[memory_end] + mov [memory_end],eax + mov [additional_memory],eax + add [additional_memory_end],eax + mov [tagged_blocks],0 + + mov eax,esp + and eax,not 0FFFh + add eax,1000h-10000h + mov [stack_limit],eax + + invoke PostMessage,[hwnd_progress],PBM_SETPOS,0,0 + invoke SetThreadPriority,[hthread],[compiler_priority] + invoke GetTickCount + mov [start_time],eax + mov [preprocessing_done],0 + call preprocessor + invoke PostMessage,[hwnd_progress],PBM_SETPOS,1,0 + or [preprocessing_done],-1 + call parser + invoke PostMessage,[hwnd_progress],PBM_SETPOS,2,0 + call assembler + invoke PostMessage,[hwnd_progress],PBM_SETPOS,3,0 + call formatter + invoke PostMessage,[hwnd_progress],PBM_SETPOS,4,0 + call show_display_buffer + invoke GetTickCount + sub eax,[start_time] + mov [total_time],eax + mov esi,[output_file] + mov edi,path_buffer + copy_executable_name: + lodsb + stosb + or al,al + jnz copy_executable_name + xor al,al + +exit_program: + movzx eax,al + push eax + mov eax,[allocated_memory] + or eax,eax + jz memory_ok + invoke VirtualFree,eax,0,MEM_RELEASE + mov [allocated_memory],0 + memory_ok: + mov eax,[hfile] + or eax,eax + jz handle_ok + invoke CloseHandle,eax + handle_ok: + invoke PostMessage,[hwnd_compiler],WM_COMMAND,IDOK,0 + call [ExitThread] + +get_environment_variable: + invoke GetEnvironmentVariable,esi,string_buffer,1000h + mov ecx,[memory_end] + sub ecx,edi + cmp ecx,1000h + jbe get_local_variable + mov ecx,1000h + get_local_variable: + invoke GetPrivateProfileString,_section_environment,esi,string_buffer,edi,ecx,ini_path + add edi,eax + cmp edi,[memory_end] + jae out_of_memory + retn + +open: + mov ebx,edx + invoke WaitForSingleObject,[mutex],-1 + invoke CreateFile,ebx,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0 + cmp eax,-1 + je file_error + mov [hfile],eax + mov ebx,eax + clc + retn + file_error: + stc + retn +create: + mov ebx,edx + invoke WaitForSingleObject,[mutex],-1 + invoke CreateFile,ebx,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0 + cmp eax,-1 + je file_error + mov ebx,eax + clc + retn +write: + invoke WriteFile,ebx,edx,ecx,bytes_count,0 + or eax,eax + jz file_error + clc + retn +read: + mov ebp,ecx + invoke ReadFile,ebx,edx,ecx,bytes_count,0 + or eax,eax + jz file_error + cmp ebp,[bytes_count] + jne file_error + clc + retn +close: + cmp ebx,[hfile] + jne close_handle + mov [hfile],0 + close_handle: + invoke CloseHandle,ebx + invoke ReleaseMutex,[mutex] + retn +lseek: + movzx eax,al + invoke SetFilePointer,ebx,edx,0,eax + cmp eax,-1 + je file_error + clc + retn + +display_block: + push edi + push ecx + add ecx,[display_size] + invoke GlobalReAlloc,[hmem_display],ecx,GMEM_MOVEABLE + or eax,eax + jz out_of_memory + mov [hmem_display],eax + invoke GlobalLock,[hmem_display] + add eax,[display_size] + lea edi,[eax-1] + pop ecx + add [display_size],ecx + rep movsb + xor al,al + stosb + invoke GlobalUnlock,[hmem_display] + pop edi + retn +fatal_error: + cmp [hthread],0 + je error_outside_compiler + pop [error_message] + error_with_no_source: + mov al,0FFh + jmp exit_program +assembler_error: + cmp [hthread],0 + je error_outside_compiler + call show_display_buffer + pop [error_message] + mov ebx,[current_line] + test ebx,ebx + jz error_with_no_source + xor ecx,ecx + get_error_lines: + mov eax,[ebx] + cmp byte [eax],0 + je get_next_error_line + test byte [ebx+7],80h + jz error_lines_ok + inc ecx + mov edx,ebx + find_definition_origin: + mov edx,[edx+12] + test byte [edx+7],80h + jnz find_definition_origin + mov eax,[edx+4] + and eax,7FFFFFFFh + push eax + mov edx,[edx] + push edx + get_next_error_line: + mov ebx,[ebx+8] + jmp get_error_lines + error_lines_ok: + inc ecx + mov eax,[ebx+4] + and eax,7FFFFFFFh + push eax + mov edx,[ebx] + push edx + mov ebx,ecx + inc ecx + shl ecx,3 + mov [error_data_size],ecx + invoke GlobalAlloc,GMEM_MOVEABLE,ecx + mov [hmem_error_data],eax + invoke GlobalLock,[hmem_error_data] + mov [eax],ebx + invoke GlobalUnlock,[hmem_error_data] + xor ebx,ebx + store_error_lines: + pop edx + invoke GetFullPathName,edx,1000h,path_buffer,param_buffer + inc eax + mov esi,eax + add eax,[error_data_size] + invoke GlobalReAlloc,[hmem_error_data],eax,GMEM_MOVEABLE + invoke GlobalLock,[hmem_error_data] + mov edi,eax + add edi,[error_data_size] + mov ecx,esi + mov esi,path_buffer + rep movsb + pop edx + mov [eax+8+ebx*8+4],edx + sub edi,eax + xchg [error_data_size],edi + mov [eax+8+ebx*8],edi + mov esi,[eax] + invoke GlobalUnlock,[hmem_error_data] + inc ebx + cmp ebx,esi + jb store_error_lines + mov edi,[additional_memory] + cmp [preprocessing_done],0 + jne error_in_preprocessed + xor al,al + stosb + jmp instruction_converted + error_in_preprocessed: + mov esi,[current_line] + add esi,16 + xor dl,dl + convert_instruction: + lodsb + cmp al,1Ah + je copy_symbol + cmp al,22h + je copy_symbol + cmp al,3Bh + je ignore_preprocessor_symbols + stosb + or al,al + jz instruction_converted + xor dl,dl + jmp convert_instruction + copy_symbol: + or dl,dl + jz space_ok + mov byte [edi],20h + inc edi + space_ok: + cmp al,22h + je quoted + lodsb + movzx ecx,al + rep movsb + or dl,-1 + jmp convert_instruction + quoted: + mov al,27h + stosb + lodsd + mov ecx,eax + jecxz quoted_copied + copy_quoted: + lodsb + stosb + cmp al,27h + jne quote_ok + stosb + quote_ok: + loop copy_quoted + quoted_copied: + mov al,27h + stosb + or dl,-1 + jmp convert_instruction + ignore_preprocessor_symbols: + xor al,al + stosb + instruction_converted: + sub edi,[additional_memory] + mov ebx,[error_data_size] + lea eax,[ebx+edi] + invoke GlobalReAlloc,[hmem_error_data],eax,GMEM_MOVEABLE + invoke GlobalLock,[hmem_error_data] + mov ecx,edi + mov [eax+4],ebx + lea edi,[eax+ebx] + mov esi,[additional_memory] + rep movsb + invoke GlobalUnlock,[hmem_error_data] + mov al,2 + jmp exit_program + error_outside_compiler: + mov esp,[resume_esp] + jmp [resume_eip] + +make_timestamp: + invoke GetSystemTime,systime + movzx ecx,[systime.wYear] + mov eax,ecx + sub eax,1970 + mov ebx,365 + mul ebx + mov ebp,eax + mov eax,ecx + sub eax,1969 + shr eax,2 + add ebp,eax + mov eax,ecx + sub eax,1901 + mov ebx,100 + div ebx + sub ebp,eax + mov eax,ecx + xor edx,edx + sub eax,1601 + mov ebx,400 + div ebx + add ebp,eax + movzx ecx,[systime.wMonth] + mov eax,ecx + dec eax + mov ebx,30 + mul ebx + add ebp,eax + cmp ecx,8 + jbe months_correction + mov eax,ecx + sub eax,7 + shr eax,1 + add ebp,eax + mov ecx,8 + months_correction: + mov eax,ecx + shr eax,1 + add ebp,eax + cmp ecx,2 + jbe day_correction_ok + sub ebp,2 + movzx ecx,word [systime.wYear] + test ecx,11b + jnz day_correction_ok + xor edx,edx + mov eax,ecx + mov ebx,100 + div ebx + or edx,edx + jnz day_correction + mov eax,ecx + mov ebx,400 + div ebx + or edx,edx + jnz day_correction_ok + day_correction: + inc ebp + day_correction_ok: + movzx eax,[systime.wDay] + dec eax + add eax,ebp + mov ebx,24 + mul ebx + movzx ecx,[systime.wHour] + add eax,ecx + mov ebx,60 + mul ebx + movzx ecx,[systime.wMinute] + add eax,ecx + mov ebx,60 + mul ebx + movzx ecx,[systime.wSecond] + add eax,ecx + adc edx,0 + retn + +include '..\..\errors.inc' +include '..\..\symbdump.inc' +include '..\..\preproce.inc' +include '..\..\parser.inc' +include '..\..\exprpars.inc' +include '..\..\assemble.inc' +include '..\..\exprcalc.inc' +include '..\..\formats.inc' +include '..\..\x86_64.inc' +include '..\..\avx.inc' + +include '..\..\tables.inc' +include '..\..\messages.inc' + +section '.bss' readable writeable + +include '..\..\variable.inc' + +allocated_memory dd ? +start_time dd ? +total_time dd ? +display_size dd ? +error_message dd ? +error_data_size dd ? +preprocessing_done db ? diff --git a/toolchain/fasmw17332/SOURCE/IDE/FASMW/FASMW.ASM b/toolchain/fasmw17332/SOURCE/IDE/FASMW/FASMW.ASM new file mode 100644 index 0000000..9d377fd --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/IDE/FASMW/FASMW.ASM @@ -0,0 +1,3812 @@ + +; flat assembler IDE for Win32 +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +format PE GUI 4.0 large NX +entry start +stack 20000h + +include 'win32ax.inc' +include 'fedit.ash' + +include '..\..\version.inc' + +struct EDITITEM + header TC_ITEMHEADER + hwnd dd ? + pszpath dd ? +ends + +FM_NEW = WM_USER + 0 +FM_OPEN = WM_USER + 1 +FM_SAVE = WM_USER + 2 +FM_COMPILE = WM_USER + 3 +FM_SELECT = WM_USER + 4 +FM_ASSIGN = WM_USER + 5 +FM_GETSELECTED = WM_USER + 6 +FM_GETASSIGNED = WM_USER + 7 +FM_GETHANDLE = WM_USER + 8 +FM_OPENREADONLY = WM_USER + 11h +FM_SAVEMODIFIED = WM_USER + 12h + +struct HH_AKLINK + cbStruct dd ? + fReserved dd ? + pszKeywords dd ? + pszUrl dd ? + pszMsgText dd ? + pszMsgTitle dd ? + pszWindow dd ? + fIndexOnFail dd ? +ends + +HH_DISPLAY_TOPIC = 0 +HH_KEYWORD_LOOKUP = 0Dh + +CP_ARGUMENTS = 0 +CP_DIRECTORY = 1 + +section '.data' data readable writeable + + _caption db 'flat assembler ',VERSION_STRING,0 + _class db 'FASMW_IDE32',0 + _fedit_class db 'FEDIT',0 + _listbox_class db 'LISTBOX',0 + _tabctrl_class db 'SysTabControl32',0 + _htmlhelp_library db 'HHCTRL.OCX',0 + _htmlhelp_api db 'HtmlHelpA',0 + _user_library db 'USER32.DLL',0 + _setgestureconfig_api db 'SetGestureConfig',0 + _getgestureinfo_api db 'GetGestureInfo',0 + _closegestureinfohandle_api db 'CloseGestureInfoHandle',0 + + _memory_error db 'Not enough memory to complete this operation.',0 + _loading_error db 'Could not load file %s.',0 + _run_object_error db 'Cannot execute object file.',0 + _saving_question db 'File was modified. Save it now?',0 + _not_found db 'Text %s not found.',0 + _not_found_after db 'Text %s not found after current position.',0 + _not_found_before db 'Text %s not found before current position.',0 + _replace_prompt db 'Replace this occurence?',0 + _replaces_made db '%d replaces made.',0 + _untitled db 'Untitled',0 + _font_face db 'Courier New',0 + _row_column db 9,'%d,' + _value db '%d' + _null db 0 + _summary db '%d passes, %d.%d seconds, %d bytes.',0 + _summary_short db '%d passes, %d bytes.',0 + _assembler_error db 'Error: %s.',0 + _line_number db '%s [%d]',0 + _color db '%d,%d,%d',0 + _modified_status db 9,'Modified',0 + _readonly_status db 9,'Read-only',0 + _pick_help db 'Pick help file',0 + _find db 'Find',0 + _replace db 'Replace',0 + + _asm_extension db 'ASM',0 + + _section_environment db 'Environment',0 + _key_environment_include db 'Include',0 + _section_compiler db 'Compiler',0 + _key_compiler_memory db 'Memory',0 + _key_compiler_priority db 'Priority',0 + _key_compiler_passes db 'Passes',0 + _section_options db 'Options',0 + _key_options_securesel db 'SecureSelection',0 + _key_options_autobrackets db 'AutoBrackets',0 + _key_options_autoindent db 'AutoIndent',0 + _key_options_smarttabs db 'SmartTabs',0 + _key_options_optimalfill db 'OptimalFill',0 + _key_options_revivedeadkeys db 'ReviveDeadKeys',0 + _key_options_consolecaret db 'ConsoleCaret',0 + _key_options_timescroll db 'TimeScroll',0 + _key_options_oneinstanceonly db 'OneInstanceOnly',0 + _section_colors db 'Colors',0 + _key_color_text db 'Text',0 + _key_color_background db 'Background',0 + _key_color_seltext db 'SelectionText',0 + _key_color_selbackground db 'SelectionBackground',0 + _key_color_symbols db 'Symbols',0 + _key_color_numbers db 'Numbers',0 + _key_color_strings db 'Strings',0 + _key_color_comments db 'Comments',0 + _section_font db 'Font',0 + _key_font_face db 'Face',0 + _key_font_height db 'Height',0 + _key_font_width db 'Width',0 + _key_font_weight db 'Weight',0 + _key_font_italic db 'Italic',0 + _key_font_charset db 'CharSet',0 + _section_window db 'Window',0 + _key_window_top db 'Top',0 + _key_window_left db 'Left',0 + _key_window_right db 'Right',0 + _key_window_bottom db 'Bottom',0 + _key_window_maximized db 'Maximized',0 + _section_help db 'Help',0 + _key_help_path db 'Path',0 + + _reg_key_desktop db 'Control Panel\Desktop',0 + _reg_value_wheelscrolllines db 'WheelScrollLines',0 + + _appearance_settings db 'Font',0 + db 'Text color',0 + db 'Background color',0 + db 'Selection text color',0 + db 'Selection background color',0 + db 'Symbols color',0 + db 'Numbers color',0 + db 'Strings color',0 + db 'Comments color',0 + db 0 + _memory_settings db '1024',0 + db '2048',0 + db '4096',0 + db '8192',0 + db '16384',0 + db '32768',0 + db '65536',0 + db '131072',0 + db '262144',0 + db '524288',0 + db 0 + _priority_settings db 'Idle',0 + db 'Low',0 + db 'Normal',0 + db 'High',0 + db 'Realtime',0 + db 0 + + fedit_style dd FES_AUTOINDENT+FES_SMARTTABS+FES_CONSOLECARET + + editor_colors rd 4 + asm_syntax_colors dd 0xF03030,0x009000,0x0000B0,0x808080 + + preview_text db 0Dh,0Ah + db ' org 100h',0Dh,0Ah + db 0Dh,0Ah + db ' mov ah,09h ',' ; write',0Dh,0Ah + db ' mov dx,text',0Dh,0Ah + db ' int 21h',0Dh,0Ah + db ' int 20h',0Dh,0Ah + db 0Dh,0Ah + db ' text db "Hello!",24h',0Dh,0Ah + db 0 + preview_selection dd 1,5,1,6 + + asm_filter db 'Assembly files',0,'*.ASM;*.INC;*.ASH',0 + db 'All files',0,'*.*',0 + db 0 + + help_filter db 'Help files',0,'*.HLP;*.CHM',0 + db 0 + + align 4 + + wheel_scroll_lines dd 3 + + HtmlHelp dd 0 + + SetGestureConfig dd 0 + GetGestureInfo dd 0 + CloseGestureInfoHandle dd 0 + + hinstance dd ? + hkey_main dd ? + hmenu_main dd ? + hmenu_edit dd ? + hmenu_tab dd ? + hacc dd ? + hfont dd ? + hwnd_main dd ? + hwnd_status dd ? + hwnd_tabctrl dd ? + hwnd_history dd ? + hwnd_fedit dd ? + hwnd_compiler dd ? + hwnd_progress dd ? + himl dd ? + hthread dd ? + hmem_display dd ? + hmem_error_data dd ? + hfile dd ? + mutex dd ? + + instance_flags dd ? + command_flags dd ? + search_settings dd ? + replaces_count dd ? + compiler_memory dd ? + compiler_priority dd ? + assigned_file dd ? + program_arguments dd ? + resume_esp dd ? + resume_eip dd ? + + param_buffer rd 10h + user_colors rd 10h + name_buffer rb 100h + search_string rb 1000h + replace_string rb 1000h + string_buffer rb 2000h + help_path rb 1000h + ini_path rb 1000h + include_path rb 1000h + path_buffer rb 4000h + + msg MSG + wc WNDCLASS + rc RECT + pt POINT + ei EDITITEM + font LOGFONT + bm BITMAP + tcht TC_HITTESTINFO + wp WINDOWPLACEMENT + fepos FEPOS + ofn OPENFILENAME + cf CHOOSEFONT + cc CHOOSECOLOR + systime SYSTEMTIME + sinfo STARTUPINFO + pinfo PROCESS_INFORMATION + cp COPYDATASTRUCT + + bytes_count dd ? + fedit_font dd ? + + tmp_colors rd 8 + tmp_font LOGFONT + backup_font LOGFONT + + hhkey HH_AKLINK + + upper_case_table rb 100h + +section '.text' code readable executable + +include 'fedit.inc' + + start: + + invoke GetModuleHandle,0 + mov [hinstance],eax + + invoke GetModuleHandle,_user_library + or eax,eax + jz gesture_api_unavailable + mov ebx,eax + invoke GetProcAddress,ebx,_setgestureconfig_api + or eax,eax + jz gesture_api_unavailable + mov esi,eax + invoke GetProcAddress,ebx,_getgestureinfo_api + or eax,eax + jz gesture_api_unavailable + mov edi,eax + invoke GetProcAddress,ebx,_closegestureinfohandle_api + or eax,eax + jz gesture_api_unavailable + mov [CloseGestureInfoHandle],eax + mov [SetGestureConfig],esi + mov [GetGestureInfo],edi + gesture_api_unavailable: + + invoke GetCommandLine + mov esi,eax + mov edi,ini_path + find_program_path: + lodsb + cmp al,20h + je find_program_path + cmp al,22h + je quoted_program_path + cmp al,0Dh + je program_path_ok + or al,al + jnz get_program_path + dec esi + jmp program_path_ok + get_program_path: + stosb + lodsb + cmp al,20h + je program_path_ok + cmp al,0Dh + je program_path_ok + or al,al + jnz get_program_path + dec esi + jmp program_path_ok + quoted_program_path: + lodsb + cmp al,22h + je program_path_ok + cmp al,0Dh + je program_path_ok + stosb + or al,al + jnz quoted_program_path + dec esi + program_path_ok: + mov [program_arguments],esi + mov ebx,edi + find_program_extension: + cmp ebx,ini_path + je make_ini_extension + dec ebx + mov al,[ebx] + cmp al,'\' + je make_ini_extension + cmp al,'/' + je make_ini_extension + cmp al,'.' + jne find_program_extension + mov edi,ebx + jmp find_program_extension + make_ini_extension: + mov eax,'.INI' + stosd + xor al,al + stosb + invoke GetFullPathName,ini_path,1000h,ini_path,param_buffer + mov esi,ini_path + mov ecx,[param_buffer] + sub ecx,esi + mov edi,include_path + rep movsb + mov eax,'INCL' + stosd + mov eax,'UDE' + stosd + invoke GetFileAttributes,ini_path + cmp eax,-1 + jne ini_ok + invoke WritePrivateProfileString,_section_environment,_key_environment_include,include_path,ini_path + ini_ok: + + mov [instance_flags],0 + stdcall GetIniBit,ini_path,_section_options,_key_options_oneinstanceonly,instance_flags,1 + cmp [instance_flags],0 + je create_new_window + invoke FindWindow,_class,NULL + or eax,eax + jnz window_already_exists + + create_new_window: + invoke LoadCursor,0,IDC_IBEAM + mov [wc.hCursor],eax + mov [wc.style],CS_GLOBALCLASS+CS_DBLCLKS + mov [wc.lpfnWndProc],FlatEditor + mov eax,[hinstance] + mov [wc.hInstance],eax + mov [wc.cbWndExtra],4 + xor eax,eax + mov [wc.hbrBackground],eax + mov [wc.cbClsExtra],eax + mov [wc.lpszMenuName],eax + mov [wc.lpszClassName],_fedit_class + invoke RegisterClass,wc + or eax,eax + jz end_loop + invoke CreateFont,0,0,0,0,0,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_RASTER_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH+FF_DONTCARE,NULL + or eax,eax + jz end_loop + mov [fedit_font],eax + + mov edi,upper_case_table + xor ebx,ebx + mov esi,100h + make_case_table: + invoke CharUpper,ebx + stosb + inc bl + dec esi + jnz make_case_table + mov edi,characters + mov ecx,100h + xor al,al + prepare_characters_table: + stosb + inc al + loop prepare_characters_table + mov esi,characters+'a' + mov edi,characters+'A' + mov ecx,26 + rep movsb + mov edi,characters + mov esi,symbol_characters+1 + movzx ecx,byte [esi-1] + xor eax,eax + convert_table: + lodsb + mov byte [edi+eax],0 + loop convert_table + + invoke LoadIcon,[hinstance],IDI_MAIN + mov [wc.hIcon],eax + invoke LoadCursor,0,IDC_ARROW + mov [wc.hCursor],eax + mov [wc.style],0 + mov [wc.lpfnWndProc],MainWindow + mov [wc.cbClsExtra],0 + mov [wc.cbWndExtra],0 + mov eax,[hinstance] + mov [wc.hInstance],eax + mov [wc.hbrBackground],COLOR_BTNFACE+1 + mov [wc.lpszMenuName],0 + mov [wc.lpszClassName],_class + invoke RegisterClass,wc + + invoke LoadMenu,[hinstance],IDM_MAIN + mov [hmenu_main],eax + invoke GetSubMenu,eax,1 + mov [hmenu_edit],eax + invoke LoadMenu,[hinstance],IDM_TAB + invoke GetSubMenu,eax,0 + mov [hmenu_tab],eax + invoke LoadAccelerators,[hinstance],IDA_MAIN + mov [hacc],eax + invoke CreateWindowEx,0,_class,_caption,WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS,96,64,384,324,NULL,[hmenu_main],[hinstance],NULL + or eax,eax + jz end_loop + mov [hwnd_main],eax + mov eax,SW_SHOW + test [wp.flags],WPF_RESTORETOMAXIMIZED + jz show_main_window + mov eax,SW_SHOWMAXIMIZED + show_main_window: + invoke ShowWindow,[hwnd_main],eax + invoke UpdateWindow,[hwnd_main] + msg_loop: + invoke GetMessage,msg,NULL,0,0 + or eax,eax + jz end_loop + invoke TranslateAccelerator,[hwnd_main],[hacc],msg + or eax,eax + jnz msg_loop + cmp [msg.message],WM_KEYDOWN + je msg_dispatch + invoke TranslateMessage,msg + msg_dispatch: + invoke DispatchMessage,msg + jmp msg_loop + + window_already_exists: + mov ebx,eax + invoke GetWindowPlacement,ebx,wp + mov eax,SW_SHOWNORMAL + cmp [wp.showCmd],SW_SHOWMAXIMIZED + jne show_existing_window + mov eax,SW_SHOWMAXIMIZED + show_existing_window: + invoke ShowWindow,ebx,eax + invoke SetForegroundWindow,ebx + invoke GetCurrentDirectory,4000h,path_buffer + inc eax + mov [cp.cbData],eax + mov [cp.lpData],path_buffer + mov [cp.dwData],CP_DIRECTORY + invoke SendMessage,ebx,WM_COPYDATA,NULL,cp + mov edi,[program_arguments] + mov [cp.lpData],edi + or ecx,-1 + xor al,al + repne scasb + neg ecx + mov [cp.cbData],ecx + mov [cp.dwData],CP_ARGUMENTS + invoke SendMessage,ebx,WM_COPYDATA,NULL,cp + end_loop: + invoke ExitProcess,[msg.wParam] + +proc MainWindow hwnd,wmsg,wparam,lparam + push ebx esi edi + cmp [wmsg],WM_CREATE + je wmcreate + cmp [wmsg],WM_COPYDATA + je wmcopydata + cmp [wmsg],WM_GETMINMAXINFO + je wmgetminmaxinfo + cmp [wmsg],WM_SIZE + je wmsize + cmp [wmsg],WM_SETFOCUS + je wmsetfocus + cmp [wmsg],FM_NEW + je fmnew + cmp [wmsg],FM_OPEN + je fmopen + cmp [wmsg],FM_OPENREADONLY + je fmopenreadonly + cmp [wmsg],FM_SAVE + je fmsave + cmp [wmsg],FM_SAVEMODIFIED + je fmsavemodified + cmp [wmsg],FM_COMPILE + je fmcompile + cmp [wmsg],FM_SELECT + je fmselect + cmp [wmsg],FM_ASSIGN + je fmassign + cmp [wmsg],FM_GETSELECTED + je fmgetselected + cmp [wmsg],FM_GETASSIGNED + je fmgetassigned + cmp [wmsg],FM_GETHANDLE + je fmgethandle + cmp [wmsg],WM_INITMENU + je wminitmenu + cmp [wmsg],WM_COMMAND + je wmcommand + cmp [wmsg],WM_NOTIFY + je wmnotify + cmp [wmsg],WM_DROPFILES + je wmdropfiles + cmp [wmsg],WM_CLOSE + je wmclose + cmp [wmsg],WM_DESTROY + je wmdestroy + invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] + jmp finish + wmcreate: + xor eax,eax + mov [search_settings],eax + mov [search_string],al + mov [replace_string],al + mov [compiler_memory],65536 + mov [compiler_priority],THREAD_PRIORITY_NORMAL + mov [assigned_file],-1 + mov [help_path],0 + mov [ofn.lStructSize],sizeof.OPENFILENAME + mov eax,[hwnd] + mov [ofn.hwndOwner],eax + mov eax,[hinstance] + mov [ofn.hInstance],eax + mov [ofn.lpstrCustomFilter],NULL + mov [ofn.nFilterIndex],1 + mov [ofn.nMaxFile],1000h + mov [ofn.lpstrFileTitle],name_buffer + mov [ofn.nMaxFileTitle],100h + mov [ofn.lpstrInitialDir],NULL + mov [ofn.lpstrDefExt],_asm_extension + mov [font.lfHeight],16 + mov [font.lfWidth],0 + mov [font.lfEscapement],0 + mov [font.lfOrientation],0 + mov [font.lfWeight],0 + mov [font.lfItalic],FALSE + mov [font.lfUnderline],FALSE + mov [font.lfStrikeOut],FALSE + mov [font.lfCharSet],DEFAULT_CHARSET + mov [font.lfOutPrecision],OUT_RASTER_PRECIS + mov [font.lfClipPrecision],CLIP_DEFAULT_PRECIS + mov [font.lfQuality],DEFAULT_QUALITY + mov [font.lfPitchAndFamily],FIXED_PITCH+FF_DONTCARE + mov edi,font.lfFaceName + mov esi,_font_face + copy_font_face: + lodsb + stosb + or al,al + jnz copy_font_face + invoke GetSysColor,COLOR_WINDOWTEXT + mov [editor_colors],eax + invoke GetSysColor,COLOR_WINDOW + mov [editor_colors+4],eax + invoke GetSysColor,COLOR_HIGHLIGHTTEXT + mov [editor_colors+8],eax + invoke GetSysColor,COLOR_HIGHLIGHT + mov [editor_colors+12],eax + mov esi,editor_colors + mov edi,user_colors + mov ecx,8 + rep movsd + mov [wp.length],sizeof.WINDOWPLACEMENT + invoke GetWindowPlacement,[hwnd],wp + invoke RegOpenKeyEx,HKEY_CURRENT_USER,_reg_key_desktop,0,KEY_READ,param_buffer + test eax,eax + jnz wheel_setting_ok + mov [bytes_count],100h + invoke RegQueryValueEx,[param_buffer],_reg_value_wheelscrolllines,0,param_buffer+4,string_buffer,bytes_count + test eax,eax + jnz no_valid_wheel_setting + cmp [param_buffer+4],REG_SZ + jne no_valid_wheel_setting + mov esi,string_buffer + cmp byte [esi],0 + je no_valid_wheel_setting + call atoi + jc no_valid_wheel_setting + mov [wheel_scroll_lines],eax + no_valid_wheel_setting: + invoke RegCloseKey,[param_buffer] + wheel_setting_ok: + stdcall GetIniInteger,ini_path,_section_compiler,_key_compiler_memory,compiler_memory + stdcall GetIniInteger,ini_path,_section_compiler,_key_compiler_priority,compiler_priority + mov eax,100 + mov [passes_limit],ax + mov [param_buffer],eax + stdcall GetIniInteger,ini_path,_section_compiler,_key_compiler_passes,param_buffer + mov eax,[param_buffer] + test eax,eax + jz passes_limit_ok + cmp eax,10000h + ja passes_limit_ok + mov [passes_limit],ax + passes_limit_ok: + stdcall GetIniBit,ini_path,_section_options,_key_options_securesel,fedit_style,FES_SECURESEL + stdcall GetIniBit,ini_path,_section_options,_key_options_autobrackets,fedit_style,FES_AUTOBRACKETS + stdcall GetIniBit,ini_path,_section_options,_key_options_autoindent,fedit_style,FES_AUTOINDENT + stdcall GetIniBit,ini_path,_section_options,_key_options_smarttabs,fedit_style,FES_SMARTTABS + stdcall GetIniBit,ini_path,_section_options,_key_options_optimalfill,fedit_style,FES_OPTIMALFILL + stdcall GetIniBit,ini_path,_section_options,_key_options_revivedeadkeys,fedit_style,FES_REVIVEDEADKEYS + stdcall GetIniBit,ini_path,_section_options,_key_options_consolecaret,fedit_style,FES_CONSOLECARET + stdcall GetIniBit,ini_path,_section_options,_key_options_timescroll,fedit_style,FES_TIMESCROLL + stdcall GetIniColor,ini_path,_section_colors,_key_color_text,editor_colors + stdcall GetIniColor,ini_path,_section_colors,_key_color_background,editor_colors+4 + stdcall GetIniColor,ini_path,_section_colors,_key_color_seltext,editor_colors+8 + stdcall GetIniColor,ini_path,_section_colors,_key_color_selbackground,editor_colors+12 + stdcall GetIniColor,ini_path,_section_colors,_key_color_symbols,asm_syntax_colors + stdcall GetIniColor,ini_path,_section_colors,_key_color_numbers,asm_syntax_colors+4 + stdcall GetIniColor,ini_path,_section_colors,_key_color_strings,asm_syntax_colors+8 + stdcall GetIniColor,ini_path,_section_colors,_key_color_comments,asm_syntax_colors+12 + invoke GetPrivateProfileString,_section_font,_key_font_face,font.lfFaceName,font.lfFaceName,32,ini_path + stdcall GetIniInteger,ini_path,_section_font,_key_font_height,font.lfHeight + stdcall GetIniInteger,ini_path,_section_font,_key_font_width,font.lfWidth + stdcall GetIniInteger,ini_path,_section_font,_key_font_weight,font.lfWeight + stdcall GetIniBit,ini_path,_section_font,_key_font_italic,font.lfItalic,1 + stdcall GetIniByte,ini_path,_section_font,_key_font_charset,font.lfCharSet + stdcall GetIniInteger,ini_path,_section_window,_key_window_top,wp.rcNormalPosition.top + stdcall GetIniInteger,ini_path,_section_window,_key_window_left,wp.rcNormalPosition.left + stdcall GetIniInteger,ini_path,_section_window,_key_window_right,wp.rcNormalPosition.right + stdcall GetIniInteger,ini_path,_section_window,_key_window_bottom,wp.rcNormalPosition.bottom + stdcall GetIniBit,ini_path,_section_window,_key_window_maximized,wp.flags,WPF_RESTORETOMAXIMIZED + invoke GetPrivateProfileString,_section_help,_key_help_path,help_path,help_path,1000h,ini_path + mov [wp.showCmd],SW_HIDE + invoke SetWindowPlacement,[hwnd],wp + invoke CreateFontIndirect,font + mov [hfont],eax + invoke CreateStatusWindow,WS_CHILD+WS_VISIBLE+SBS_SIZEGRIP,NULL,[hwnd],0 + or eax,eax + jz failed + mov [hwnd_status],eax + mov [param_buffer],48h + mov [param_buffer+4],90h + mov [param_buffer+8],-1 + invoke SendMessage,eax,SB_SETPARTS,3,param_buffer + invoke CreateWindowEx,0,_listbox_class,NULL,WS_CHILD+LBS_HASSTRINGS,0,0,0,0,[hwnd],NULL,[hinstance],NULL + or eax,eax + jz failed + mov [hwnd_history],eax + invoke CreateWindowEx,0,_tabctrl_class,NULL,WS_VISIBLE+WS_CHILD+TCS_FOCUSNEVER+TCS_BOTTOM,0,0,0,0,[hwnd],NULL,[hinstance],NULL + or eax,eax + jz failed + mov [hwnd_tabctrl],eax + invoke SendMessage,[hwnd_tabctrl],TCM_SETITEMEXTRA,sizeof.EDITITEM-sizeof.TC_ITEMHEADER,0 + invoke SendMessage,[hwnd_status],WM_GETFONT,0,0 + invoke SendMessage,[hwnd_tabctrl],WM_SETFONT,eax,FALSE + invoke LoadBitmap,[hinstance],IDB_ASSIGN + mov ebx,eax + invoke GetObject,ebx,sizeof.BITMAP,bm + invoke ImageList_Create,[bm.bmWidth],[bm.bmHeight],ILC_COLOR4,1,0 + or eax,eax + jz failed + mov [himl],eax + invoke ImageList_Add,[himl],ebx,NULL + invoke DeleteObject,ebx + invoke SendMessage,[hwnd_tabctrl],TCM_SETIMAGELIST,0,[himl] + invoke SendMessage,[hwnd],FM_NEW,_untitled,0 + cmp eax,-1 + je failed + invoke DragAcceptFiles,[hwnd],TRUE + mov esi,[program_arguments] + process_arguments: + xor ebx,ebx + ARG_ASSIGN = 1 + ARG_READONLY = 2 + find_argument: + lodsb + cmp al,20h + je find_argument + cmp al,'+' + je argument_assign + cmp al,'-' + je argument_readonly + xor ecx,ecx + cmp al,22h + je quoted_argument + cmp al,0Dh + je command_line_ok + or al,al + jz command_line_ok + lea edx,[esi-1] + find_argument_end: + inc ecx + lodsb + cmp al,20h + je argument_end + cmp al,0Dh + je argument_end + or al,al + jz argument_end + jmp find_argument_end + argument_assign: + or bl,ARG_ASSIGN + jmp find_argument + argument_readonly: + or bl,ARG_READONLY + jmp find_argument + quoted_argument: + mov edx,esi + find_quoted_argument_end: + lodsb + cmp al,22h + je quoted_argument_end + cmp al,0Dh + je quoted_argument_end + or al,al + jz quoted_argument_end + inc ecx + jmp find_quoted_argument_end + argument_end: + dec esi + quoted_argument_end: + push eax edx esi + mov esi,edx + mov edi,path_buffer + cmp ecx,1000h-1 + jae process_next_argument + rep movsb + xor al,al + stosb + mov ecx,path_buffer+4000h + sub ecx,edi + invoke GetFullPathName,path_buffer,ecx,edi,param_buffer + invoke GetFileTitle,edi,name_buffer,100h + mov eax,FM_OPEN + test bl,ARG_READONLY + jz load_from_argument + mov eax,FM_OPENREADONLY + load_from_argument: + invoke SendMessage,[hwnd],eax,name_buffer,edi + cmp eax,-1 + je loading_error + test bl,ARG_ASSIGN + jz process_next_argument + invoke SendMessage,[hwnd_tabctrl],TCM_GETCURSEL,0,0 + invoke SendMessage,[hwnd],FM_ASSIGN,eax,0 + jmp process_next_argument + loading_error: + cinvoke wsprintf,string_buffer,_loading_error,path_buffer + invoke MessageBox,[hwnd],string_buffer,_caption,MB_ICONERROR+MB_OK + process_next_argument: + pop esi edx eax + jmp process_arguments + command_line_ok: + xor eax,eax + jmp finish + wmcopydata: + mov ebx,[lparam] + virtual at ebx + cmd COPYDATASTRUCT + end virtual + mov eax,[cmd.dwData] + cmp eax,CP_ARGUMENTS + je copy_arguments + cmp eax,CP_DIRECTORY + jne failed + invoke SetCurrentDirectory,[cmd.lpData] + jmp finish + copy_arguments: + mov esi,[cmd.lpData] + jmp process_arguments + wmgetminmaxinfo: + mov ebx,[lparam] + virtual at ebx + mmi MINMAXINFO + end virtual + mov [mmi.ptMinTrackSize.x],240 + mov [mmi.ptMinTrackSize.y],160 + jmp finish + wmsize: + invoke SendMessage,[hwnd_status],WM_SIZE,0,0 + xor eax,eax + mov [rc.left],eax + mov [rc.top],eax + mov [rc.right],eax + mov [rc.bottom],eax + invoke SendMessage,[hwnd_tabctrl],TCM_ADJUSTRECT,TRUE,rc + mov esi,[rc.bottom] + sub esi,[rc.top] + invoke GetWindowRect,[hwnd_status],rc + mov ebx,[rc.bottom] + sub ebx,[rc.top] + invoke GetClientRect,[hwnd],rc + sub [rc.bottom],ebx + sub [rc.bottom],esi + invoke SetWindowPos,[hwnd_tabctrl],[hwnd_fedit],0,[rc.bottom],[rc.right],esi,0 + invoke GetSystemMetrics,SM_CYFIXEDFRAME + shl eax,1 + add [rc.bottom],eax + invoke MoveWindow,[hwnd_fedit],0,0,[rc.right],[rc.bottom],TRUE + jmp finish + wmsetfocus: + invoke SetFocus,[hwnd_fedit] + jmp finish + fmnew: + invoke CreateWindowEx,WS_EX_STATICEDGE,_fedit_class,NULL,WS_CHILD+WS_HSCROLL+WS_VSCROLL+ES_NOHIDESEL,0,0,0,0,[hwnd],NULL,[hinstance],NULL + or eax,eax + jz failed + mov [ei.header.mask],TCIF_TEXT+TCIF_PARAM + mov [ei.hwnd],eax + mov eax,[wparam] + mov [ei.header.pszText],eax + and [ei.pszpath],0 + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEMCOUNT,0,0 + invoke SendMessage,[hwnd_tabctrl],TCM_INSERTITEM,eax,ei + mov ebx,eax + invoke SendMessage,[hwnd_tabctrl],TCM_SETCURSEL,eax,0 + invoke SendMessage,[hwnd],FM_SELECT,ebx,0 + invoke SetFocus,[hwnd] + mov eax,ebx + jmp finish + fmopen: + and [command_flags],0 + allocate_path_buffer: + invoke VirtualAlloc,0,1000h,MEM_COMMIT,PAGE_READWRITE + or eax,eax + jz failed + mov edi,eax + mov esi,[lparam] + mov [lparam],edi + copy_path_for_fedit: + lodsb + stosb + or al,al + jnz copy_path_for_fedit + xor ebx,ebx + check_if_already_loaded: + mov [ei.header.mask],TCIF_PARAM + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,ebx,ei + or eax,eax + jz load_file + invoke lstrcmpi,[ei.pszpath],[lparam] + or eax,eax + jz show_already_loaded + inc ebx + jmp check_if_already_loaded + show_already_loaded: + invoke SendMessage,[hwnd_tabctrl],TCM_SETCURSEL,ebx,0 + invoke SendMessage,[hwnd],FM_SELECT,ebx,0 + jmp update_fedit_mode + load_file: + invoke CreateFile,[lparam],GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0 + cmp eax,-1 + je open_failed + mov ebx,eax + invoke GetFileSize,ebx,NULL + inc eax + push eax + invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE + or eax,eax + pop ecx + jz load_out_of_memory + dec ecx + push MEM_RELEASE + push 0 + push eax + mov byte [eax+ecx],0 + invoke ReadFile,ebx,eax,ecx,param_buffer,0 + invoke CloseHandle,ebx + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEMCOUNT,0,0 + cmp eax,1 + jne new_fedit + mov [ei.header.mask],TCIF_PARAM + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,0,ei + cmp [ei.pszpath],0 + jne new_fedit + invoke SendMessage,[ei.hwnd],FEM_ISUNMODIFIED,0,0 + or eax,eax + jz new_fedit + mov [ei.header.mask],TCIF_TEXT+TCIF_PARAM + mov eax,[wparam] + mov [ei.header.pszText],eax + mov eax,[lparam] + mov [ei.pszpath],eax + invoke SendMessage,[hwnd_tabctrl],TCM_SETITEM,0,ei + xor ebx,ebx + jmp set_fedit_text + new_fedit: + invoke SendMessage,[hwnd],FM_NEW,[wparam],0 + cmp eax,-1 + jne set_path + add esp,12 + jmp open_failed + set_path: + mov ebx,eax + mov [ei.header.mask],TCIF_PARAM + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,ebx,ei + mov eax,[lparam] + mov [ei.pszpath],eax + invoke SendMessage,[hwnd_tabctrl],TCM_SETITEM,ebx,ei + set_fedit_text: + invoke SendMessage,[hwnd_fedit],WM_SETTEXT,0,dword [esp] + call [VirtualFree] + update_fedit_mode: + invoke SendMessage,[hwnd_fedit],FEM_GETMODE,0,0 + and eax,not FEMODE_READONLY + test [command_flags],1 + jz set_fedit_mode + or eax,FEMODE_READONLY + set_fedit_mode: + invoke SendMessage,[hwnd_fedit],FEM_SETMODE,eax,0 + jmp update_status_bar + load_out_of_memory: + invoke CloseHandle,ebx + open_failed: + invoke VirtualFree,[lparam],0,MEM_RELEASE + jmp failed + fmopenreadonly: + or [command_flags],1 + jmp allocate_path_buffer + fmsavemodified: + or ebx,-1 + jmp save_single_file + fmsave: + xor ebx,ebx + save_single_file: + mov [ei.header.mask],TCIF_PARAM + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,[wparam],ei + or eax,eax + jz failed + cmp [ei.pszpath],0 + je failed + invoke SendMessage,[ei.hwnd],FEM_GETMODE,0,0 + test eax,FEMODE_READONLY + jnz ok + invoke SendMessage,[ei.hwnd],FEM_ISUNMODIFIED,0,0 + and eax,ebx + jnz ok + invoke SendMessage,[ei.hwnd],WM_GETTEXTLENGTH,0,0 + inc eax + mov [wparam],eax + invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE + or eax,eax + jz failed + mov [lparam],eax + invoke CreateFile,[ei.pszpath],GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0 + cmp eax,-1 + je save_failed + mov ebx,eax + invoke SendMessage,[ei.hwnd],WM_GETTEXT,[wparam],[lparam] + invoke WriteFile,ebx,[lparam],eax,param_buffer,0 + test eax,eax + jz save_failed + invoke CloseHandle,ebx + invoke VirtualFree,[lparam],0,MEM_RELEASE + invoke SendMessage,[ei.hwnd],FEM_MARKUNMODIFIED,0,0 + xor ebx,ebx + mov eax,[ei.hwnd] + cmp eax,[hwnd_fedit] + je update_status_bar + xor eax,eax + jmp finish + save_failed: + invoke VirtualFree,[lparam],0,MEM_RELEASE + jmp failed + fmcompile: + mov eax,[assigned_file] + push eax + cmp eax,-1 + jne assigned_ok + invoke SendMessage,[hwnd_tabctrl],TCM_GETCURSEL,0,0 + mov [assigned_file],eax + assigned_ok: + invoke SendMessage,[hwnd_main],FM_SAVEMODIFIED,eax,0 + xor ebx,ebx + or eax,eax + jz save_all + invoke SendMessage,[hwnd_tabctrl],TCM_SETCURSEL,[assigned_file],0 + invoke SendMessage,[hwnd_main],FM_SELECT,[assigned_file],0 + invoke SendMessage,[hwnd_main],WM_COMMAND,IDM_SAVEAS,0 + or eax,eax + jz save_all + or eax,-1 + jmp compile_done + save_all: + mov [ei.header.mask],TCIF_PARAM + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,ebx,ei + or eax,eax + jz do_compile + invoke SendMessage,[hwnd_main],FM_SAVEMODIFIED,ebx,0 + inc ebx + jmp save_all + do_compile: + mov eax,[wparam] + mov [output_file],eax + invoke DialogBoxParam,[hinstance],IDD_COMPILE,[hwnd],CompileDialog,[assigned_file] + cmp eax,-1 + je compile_done + push eax + cmp eax,2 + je error_details + or eax,eax + jnz make_summary + cmp [lparam],FALSE + jne make_summary + invoke GlobalFree,[hmem_display] + jmp summary_done + make_summary: + invoke DialogBoxParam,[hinstance],IDD_SUMMARY,[hwnd],SummaryDialog,eax + jmp summary_done + error_details: + invoke DialogBoxParam,[hinstance],IDD_ERRORSUMMARY,[hwnd],SummaryDialog,eax + invoke GlobalFree,[hmem_error_data] + summary_done: + pop eax + compile_done: + pop edx + cmp edx,-1 + jne finish + or [assigned_file],-1 + jmp finish + fmselect: + mov [ei.header.mask],TCIF_PARAM + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,[wparam],ei + invoke GetWindowLong,[hwnd_fedit],GWL_STYLE + and eax,not WS_VISIBLE + invoke SetWindowLong,[hwnd_fedit],GWL_STYLE,eax + mov ebx,[ei.hwnd] + mov [hwnd_fedit],ebx + mov eax,WS_CHILD+WS_HSCROLL+WS_VSCROLL+ES_NOHIDESEL + or eax,[fedit_style] + invoke SetWindowLong,ebx,GWL_STYLE,eax + invoke SendMessage,ebx,WM_SETFONT,[hfont],0 + invoke SendMessage,ebx,FEM_SETTEXTCOLOR,[editor_colors],[editor_colors+4] + invoke SendMessage,ebx,FEM_SETSELCOLOR,[editor_colors+8],[editor_colors+12] + invoke SendMessage,ebx,FEM_SETSYNTAXHIGHLIGHT,asm_syntax_colors,fasm_syntax + invoke SendMessage,ebx,FEM_SETRIGHTCLICKMENU,[hmenu_edit],[hwnd] + invoke SendMessage,[hwnd],WM_SIZE,0,0 + invoke ShowWindow,ebx,SW_SHOW + invoke UpdateWindow,ebx + invoke SetFocus,[hwnd] + jmp finish + fmassign: + mov eax,[wparam] + cmp [assigned_file],-1 + je new_assign + push eax + mov [ei.header.mask],TCIF_IMAGE + mov [ei.header.iImage],-1 + invoke SendMessage,[hwnd_tabctrl],TCM_SETITEM,[assigned_file],ei + pop eax + new_assign: + mov [assigned_file],eax + mov [ei.header.mask],TCIF_IMAGE + mov [ei.header.iImage],0 + invoke SendMessage,[hwnd_tabctrl],TCM_SETITEM,eax,ei + or eax,eax + jnz fmgetassigned + or eax,-1 + mov [assigned_file],eax + jmp finish + fmgetassigned: + mov eax,[assigned_file] + jmp finish + fmgetselected: + invoke SendMessage,[hwnd_tabctrl],TCM_GETCURSEL,0,0 + jmp finish + fmgethandle: + mov [ei.header.mask],TCIF_PARAM + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,[wparam],ei + or eax,eax + jz finish + mov eax,[ei.hwnd] + jmp finish + wminitmenu: + mov esi,[hwnd_fedit] + invoke SendMessage,esi,EM_CANUNDO,0,0 + or eax,eax + setz bl + neg bl + and ebx,MF_GRAYED + or ebx,MF_BYCOMMAND + invoke EnableMenuItem,[wparam],IDM_UNDO,ebx + invoke SendMessage,esi,FEM_CANREDO,0,0 + or eax,eax + setz bl + neg bl + and ebx,MF_GRAYED + or ebx,MF_BYCOMMAND + invoke EnableMenuItem,[wparam],IDM_REDO,ebx + invoke SendMessage,esi,FEM_GETPOS,fepos,0 + mov eax,[fepos.selectionLine] + cmp eax,[fepos.caretLine] + sete bh + mov eax,[fepos.selectionPosition] + cmp eax,[fepos.caretPosition] + sete bl + and bl,bh + neg bl + and ebx,MF_GRAYED + or ebx,MF_BYCOMMAND + invoke EnableMenuItem,[wparam],IDM_CUT,ebx + invoke EnableMenuItem,[wparam],IDM_COPY,ebx + invoke EnableMenuItem,[wparam],IDM_DELETE,ebx + invoke IsClipboardFormatAvailable,CF_TEXT + neg al + not al + and eax,MF_GRAYED + or eax,MF_BYCOMMAND + invoke EnableMenuItem,[wparam],IDM_PASTE,eax + invoke SendMessage,esi,FEM_GETMODE,0,0 + mov ebx,eax + test eax,FEMODE_VERTICALSEL + setnz al + neg al + and eax,MF_CHECKED + or eax,MF_BYCOMMAND + invoke CheckMenuItem,[wparam],IDM_VERTICAL,eax + test ebx,FEMODE_READONLY + setnz bl + and ebx,MF_GRAYED + or ebx,MF_BYCOMMAND + invoke EnableMenuItem,[wparam],IDM_CUT,ebx + invoke EnableMenuItem,[wparam],IDM_PASTE,ebx + invoke EnableMenuItem,[wparam],IDM_DELETE,ebx + invoke EnableMenuItem,[wparam],IDM_REPLACE,ebx + invoke SendMessage,esi,FEM_CANFINDNEXT,0,0 + or eax,eax + setz al + neg al + and eax,MF_GRAYED + or eax,MF_BYCOMMAND + invoke EnableMenuItem,[wparam],IDM_FINDNEXT,eax + test [fedit_style],FES_SECURESEL + setnz al + neg al + and eax,MF_CHECKED + or eax,MF_BYCOMMAND + invoke CheckMenuItem,[wparam],IDM_SECURESEL,eax + test [fedit_style],FES_AUTOBRACKETS + setnz al + neg al + and eax,MF_CHECKED + or eax,MF_BYCOMMAND + invoke CheckMenuItem,[wparam],IDM_AUTOBRACKETS,eax + test [fedit_style],FES_AUTOINDENT + setnz al + neg al + and eax,MF_CHECKED + or eax,MF_BYCOMMAND + invoke CheckMenuItem,[wparam],IDM_AUTOINDENT,eax + test [fedit_style],FES_SMARTTABS + setnz al + neg al + and eax,MF_CHECKED + or eax,MF_BYCOMMAND + invoke CheckMenuItem,[wparam],IDM_SMARTTABS,eax + test [fedit_style],FES_OPTIMALFILL + setnz al + neg al + and eax,MF_CHECKED + or eax,MF_BYCOMMAND + invoke CheckMenuItem,[wparam],IDM_OPTIMALFILL,eax + test [fedit_style],FES_REVIVEDEADKEYS + setnz al + neg al + and eax,MF_CHECKED + or eax,MF_BYCOMMAND + invoke CheckMenuItem,[wparam],IDM_REVIVEDEADKEYS,eax + test [fedit_style],FES_TIMESCROLL + setnz al + neg al + and eax,MF_CHECKED + or eax,MF_BYCOMMAND + invoke CheckMenuItem,[wparam],IDM_TIMESCROLL,eax + mov eax,[instance_flags] + neg al + and eax,MF_CHECKED + or eax,MF_BYCOMMAND + invoke CheckMenuItem,[wparam],IDM_ONEINSTANCEONLY,eax + cmp [help_path],0 + sete bl + neg bl + and ebx,MF_GRAYED + or ebx,MF_BYCOMMAND + invoke EnableMenuItem,[wparam],IDM_CONTENTS,ebx + invoke EnableMenuItem,[wparam],IDM_KEYWORD,ebx + jmp finish + wmcommand: + mov eax,[wparam] + mov ebx,[lparam] + or ebx,ebx + jz menu_command + cmp ebx,[hwnd_fedit] + jne finish + xor ebx,ebx + shr eax,16 + cmp eax,FEN_SETFOCUS + je update_status_bar + cmp eax,FEN_TEXTCHANGE + je update_status_bar + cmp eax,FEN_POSCHANGE + je update_status_bar + cmp eax,FEN_OUTOFMEMORY + je not_enough_mem + jmp finish + update_status_bar: + invoke SendMessage,[hwnd_fedit],FEM_GETPOS,fepos,0 + cinvoke wsprintf,string_buffer,_row_column,[fepos.caretLine],[fepos.caretPosition] + invoke SendMessage,[hwnd_status],SB_SETTEXT,0,string_buffer + mov esi,_null + invoke SendMessage,[hwnd_fedit],FEM_GETMODE,0,0 + test eax,FEMODE_READONLY + jnz readonly_status + invoke SendMessage,[hwnd_fedit],FEM_ISUNMODIFIED,0,0 + or eax,eax + jnz modified_status_ok + mov esi,_modified_status + jmp modified_status_ok + readonly_status: + mov esi,_readonly_status + modified_status_ok: + invoke SendMessage,[hwnd_status],SB_SETTEXT,1,esi + mov eax,ebx + jmp finish + not_enough_mem: + invoke SendMessage,[hwnd_fedit],FEM_RELEASESEARCH,0,0 + invoke MessageBox,[hwnd],_memory_error,_caption,MB_ICONERROR+MB_OK + mov eax,ebx + jmp finish + menu_command: + and eax,0FFFFh + mov ebx,[hwnd_fedit] + cmp eax,IDM_NEW + je new_file + cmp eax,IDM_OPEN + je open_file + cmp eax,IDM_SAVE + je save_file + cmp eax,IDM_SAVEAS + je save_file_as + cmp eax,IDM_NEXT + je next_file + cmp eax,IDM_PREVIOUS + je previous_file + cmp eax,IDM_OPENFOLDER + je open_folder + cmp eax,IDM_CLOSE + je close_file + cmp eax,IDM_EXIT + je exit + cmp eax,IDM_UNDO + je undo + cmp eax,IDM_REDO + je redo + cmp eax,IDM_DISCARD_UNDO + je discard_undo + cmp eax,IDM_CUT + je cut + cmp eax,IDM_COPY + je copy + cmp eax,IDM_PASTE + je paste + cmp eax,IDM_DELETE + je delete + cmp eax,IDM_SELECTALL + je select_all + cmp eax,IDM_VERTICAL + je vertical + cmp eax,IDM_READONLY + je read_only + cmp eax,IDM_POSITION + je position + cmp eax,IDM_FIND + je find + cmp eax,IDM_FINDNEXT + je findnext + cmp eax,IDM_REPLACE + je replace + cmp eax,IDM_RUN + je run + cmp eax,IDM_COMPILE + je compile + cmp eax,IDM_SYMBOLS + je build_symbols + cmp eax,IDM_ASSIGN + je assign + cmp eax,IDM_APPEARANCE + je appearance + cmp eax,IDM_COMPILERSETUP + je compiler_setup + cmp eax,IDM_SECURESEL + je option_securesel + cmp eax,IDM_AUTOBRACKETS + je option_autobrackets + cmp eax,IDM_AUTOINDENT + je option_autoindent + cmp eax,IDM_SMARTTABS + je option_smarttabs + cmp eax,IDM_OPTIMALFILL + je option_optimalfill + cmp eax,IDM_REVIVEDEADKEYS + je option_revivedeadkeys + cmp eax,IDM_TIMESCROLL + je option_timescroll + cmp eax,IDM_ONEINSTANCEONLY + je option_oneinstanceonly + cmp eax,IDM_CALCULATOR + je calculator + cmp eax,IDM_CONTENTS + je contents + cmp eax,IDM_KEYWORD + je keyword + cmp eax,IDM_PICKHELP + je pick_help + cmp eax,IDM_ABOUT + je about + sub eax,IDM_SELECTFILE + jc finish + cmp eax,9 + ja finish + mov ebx,eax + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEMCOUNT,0,0 + cmp ebx,eax + ja finish + dec ebx + invoke SendMessage,[hwnd_tabctrl],TCM_SETCURSEL,ebx,0 + invoke SendMessage,[hwnd],FM_SELECT,ebx,0 + jmp finish + new_file: + invoke SendMessage,[hwnd],FM_NEW,_untitled,0 + jmp finish + open_file: + mov [ofn.lpstrFile],path_buffer + mov [path_buffer],0 + mov [ofn.lpstrFilter],asm_filter + mov [ofn.Flags],OFN_EXPLORER+OFN_ALLOWMULTISELECT+OFN_FILEMUSTEXIST + mov [ofn.lpstrFileTitle],name_buffer + mov [ofn.lpstrTitle],NULL + invoke GetOpenFileName,ofn + or eax,eax + jz finish + mov ebx,FM_OPEN + test [ofn.Flags],OFN_READONLY + jz open_chosen_files + mov ebx,FM_OPENREADONLY + open_chosen_files: + test [ofn.Flags],OFN_ALLOWMULTISELECT + jz open_single_file + mov esi,path_buffer + movzx eax,[ofn.nFileOffset] + add esi,eax + mov byte [esi-1],'\' + mov edi,esi + open_multiple_files: + cmp byte [esi],0 + je finish + push edi + move_file_name: + lodsb + stosb + or al,al + jnz move_file_name + pop edi + invoke GetFileTitle,path_buffer,name_buffer,100h + invoke SendMessage,[hwnd],ebx,name_buffer,path_buffer + cmp eax,-1 + jne open_multiple_files + invoke wvsprintf,string_buffer,_loading_error,ofn.lpstrFile + invoke MessageBox,[hwnd],string_buffer,_caption,MB_ICONERROR+MB_OK + jmp open_multiple_files + open_single_file: + invoke SendMessage,[hwnd],ebx,name_buffer,path_buffer + cmp eax,-1 + jne finish + invoke wvsprintf,string_buffer,_loading_error,ofn.lpstrFile + invoke MessageBox,[hwnd],string_buffer,_caption,MB_ICONERROR+MB_OK + jmp finish + save_file: + invoke SendMessage,[hwnd_tabctrl],TCM_GETCURSEL,0,0 + invoke SendMessage,[hwnd],FM_SAVE,eax,0 + or eax,eax + jnz save_file_as + jmp finish + save_file_as: + invoke SendMessage,[hwnd_tabctrl],TCM_GETCURSEL,0,0 + mov ebx,eax + mov [ei.header.mask],TCIF_PARAM + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,ebx,ei + mov eax,[ei.pszpath] + or eax,eax + jnz alloc_ok + invoke VirtualAlloc,0,1000h,MEM_COMMIT,PAGE_READWRITE + mov [ei.pszpath],eax + and byte [eax],0 + alloc_ok: + mov [lparam],eax + mov [ofn.lpstrFile],eax + mov [ofn.lpstrFilter],asm_filter + mov [ofn.Flags],OFN_EXPLORER+OFN_HIDEREADONLY+OFN_OVERWRITEPROMPT + mov [ofn.lpstrTitle],NULL + invoke GetSaveFileName,ofn + or eax,eax + jz save_cancelled + mov eax,[ei.pszpath] + mov [ei.header.pszText],name_buffer + mov [ei.header.mask],TCIF_TEXT+TCIF_PARAM + invoke SendMessage,[hwnd_tabctrl],TCM_SETITEM,ebx,ei + invoke SendMessage,[hwnd],FM_SAVE,ebx,0 + xor esi,esi + check_if_overwritten: + cmp esi,ebx + je not_overwritten + mov [ei.header.mask],TCIF_PARAM + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,esi,ei + or eax,eax + jz save_ok + invoke lstrcmpi,[ei.pszpath],[lparam] + or eax,eax + jz remove_overwritten + not_overwritten: + inc esi + jmp check_if_overwritten + remove_overwritten: + invoke VirtualFree,[ei.pszpath],0,MEM_RELEASE + invoke SendMessage,[hwnd_tabctrl],TCM_DELETEITEM,esi,0 + cmp [assigned_file],-1 + je save_ok + cmp esi,[assigned_file] + ja save_ok + je assigned_overwritten + dec [assigned_file] + jmp save_ok + assigned_overwritten: + mov [assigned_file],-1 + save_ok: + xor eax,eax + jmp finish + save_cancelled: + mov eax,[ei.pszpath] + cmp byte [eax],0 + jne preserve_save_path + invoke VirtualFree,[ei.pszpath],0,MEM_RELEASE + and [ei.pszpath],0 + preserve_save_path: + invoke SendMessage,[hwnd_tabctrl],TCM_GETCURSEL,0,0 + invoke SendMessage,[hwnd_tabctrl],TCM_SETITEM,eax,ei + jmp finish + next_file: + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEMCOUNT,0,0 + mov ebx,eax + invoke SendMessage,[hwnd_tabctrl],TCM_GETCURSEL,0,0 + inc eax + cmp eax,ebx + jb select_file + xor eax,eax + select_file: + push eax + invoke SendMessage,[hwnd_tabctrl],TCM_SETCURSEL,eax,0 + pop eax + invoke SendMessage,[hwnd],FM_SELECT,eax,0 + jmp finish + previous_file: + invoke SendMessage,[hwnd_tabctrl],TCM_GETCURSEL,0,0 + sub eax,1 + jnc select_file + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEMCOUNT,0,0 + dec eax + call select_file + jmp select_file + open_folder: + invoke SendMessage,[hwnd_tabctrl],TCM_GETCURSEL,0,0 + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,eax,ei + or eax,eax + jz finish + mov eax,[ei.pszpath] + or eax,eax + jz finish + invoke GetFullPathName,eax,1000h,path_buffer,param_buffer + mov edi,[param_buffer] + xor al,al + stosb + invoke ShellExecute,HWND_DESKTOP,NULL,path_buffer,NULL,NULL,SW_SHOWNORMAL + jmp finish + close_file: + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEMCOUNT,0,0 + cmp eax,1 + jbe close_window + invoke SendMessage,[hwnd_tabctrl],TCM_GETCURSEL,0,0 + mov ebx,eax + mov [ei.header.mask],TCIF_PARAM+TCIF_TEXT + mov [ei.header.pszText],name_buffer + mov [ei.header.cchTextMax],100h + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,ebx,ei + mov eax,[ei.hwnd] + mov [wparam],eax + invoke SendMessage,eax,FEM_ISUNMODIFIED,0,0 + or eax,eax + jz close_modified + cmp [ei.pszpath],0 + jne do_close + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEMCOUNT,0,0 + cmp eax,1 + jne do_close + jmp failed + close_modified: + mov eax,MB_ICONQUESTION+MB_YESNOCANCEL + or eax,[lparam] + invoke MessageBox,[hwnd],_saving_question,[ei.header.pszText],eax + cmp eax,IDCANCEL + je failed + cmp eax,IDNO + je do_close + invoke SendMessage,[hwnd],WM_COMMAND,IDM_SAVE,0 + or eax,eax + jnz failed + do_close: + cmp [ei.pszpath],0 + je delete_tab + invoke VirtualFree,[ei.pszpath],0,MEM_RELEASE + delete_tab: + invoke SendMessage,[hwnd_tabctrl],TCM_DELETEITEM,ebx,0 + cmp ebx,[assigned_file] + jg tab_deleted + je assigned_deleted + dec [assigned_file] + jmp tab_deleted + assigned_deleted: + mov [assigned_file],-1 + tab_deleted: + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEMCOUNT,0,0 + dec eax + cmp eax,ebx + jge select_next + sub ebx,1 + jnc select_next + invoke SendMessage,[hwnd],FM_NEW,_untitled,0 + jmp destroy_fedit + select_next: + invoke SendMessage,[hwnd_tabctrl],TCM_SETCURSEL,ebx,0 + invoke SendMessage,[hwnd],FM_SELECT,ebx,0 + destroy_fedit: + invoke DestroyWindow,[wparam] + xor eax,eax + jmp finish + exit: + mov [lparam],0 + jmp close_window + undo: + invoke SendMessage,ebx,WM_UNDO,0,0 + jmp finish + redo: + invoke SendMessage,ebx,FEM_REDO,0,0 + jmp finish + cut: + invoke SendMessage,ebx,WM_CUT,0,0 + jmp finish + copy: + invoke SendMessage,ebx,WM_COPY,0,0 + jmp finish + paste: + invoke SendMessage,ebx,WM_PASTE,0,0 + jmp finish + delete: + invoke SendMessage,ebx,WM_CLEAR,0,0 + jmp finish + discard_undo: + invoke SendMessage,ebx,EM_EMPTYUNDOBUFFER,0,0 + jmp finish + select_all: + mov [fepos.selectionLine],1 + mov [fepos.selectionPosition],1 + mov [fepos.caretLine],-1 + mov [fepos.caretPosition],1 + invoke SendMessage,ebx,FEM_SETPOS,fepos,0 + invoke SendMessage,ebx,FEM_GETPOS,fepos,0 + invoke SendMessage,ebx,FEM_GETLINELENGTH,[fepos.caretLine],0 + inc eax + mov [fepos.caretPosition],eax + invoke SendMessage,ebx,FEM_SETPOS,fepos,0 + jmp finish + vertical: + invoke SendMessage,ebx,FEM_GETMODE,0,0 + xor eax,FEMODE_VERTICALSEL + invoke SendMessage,ebx,FEM_SETMODE,eax,0 + jmp finish + read_only: + invoke SendMessage,ebx,FEM_GETMODE,0,0 + xor eax,FEMODE_READONLY + invoke SendMessage,ebx,FEM_SETMODE,eax,0 + xor ebx,ebx + jmp update_status_bar + position: + invoke DialogBoxParam,[hinstance],IDD_POSITION,[hwnd],PositionDialog,0 + jmp finish + find: + invoke DialogBoxParam,[hinstance],IDD_FIND,[hwnd],FindDialog,0 + or eax,eax + jz finish + invoke SendMessage,ebx,FEM_FINDFIRST,[search_settings],search_string + or eax,eax + jnz finish + not_found: + mov [param_buffer],1000h + invoke SendMessage,[hwnd_fedit],FEM_GETSEARCHTEXT,search_string,param_buffer + invoke SendMessage,[hwnd_fedit],FEM_GETSEARCHFLAGS,0,0 + mov esi,_not_found + test eax,FEFIND_INWHOLETEXT + jnz make_not_found_message + mov esi,_not_found_after + test eax,FEFIND_BACKWARD + jz make_not_found_message + mov esi,_not_found_before + make_not_found_message: + cinvoke wsprintf,string_buffer,esi,search_string + invoke SendMessage,[hwnd_fedit],FEM_RELEASESEARCH,0,0 + invoke MessageBox,[hwnd],string_buffer,_find,MB_ICONINFORMATION+MB_OK + jmp finish + findnext: + invoke SendMessage,ebx,FEM_FINDNEXT,0,0 + or eax,eax + jz not_found + jmp finish + replace: + invoke DialogBoxParam,[hinstance],IDD_REPLACE,[hwnd],ReplaceDialog,0 + or eax,eax + jz finish + mov [replaces_count],0 + invoke SendMessage,ebx,FEM_BEGINOPERATION,0,0 + test [command_flags],1 + jz .start_replacing + invoke SendMessage,ebx,FEM_ENDOPERATION,0,0 + .start_replacing: + invoke SendMessage,ebx,FEM_FINDFIRST,[search_settings],search_string + or eax,eax + jz .not_found + invoke SendMessage,ebx,FEM_GETMODE,0,0 + push eax + and eax,not (FEMODE_VERTICALSEL + FEMODE_OVERWRITE) + invoke SendMessage,ebx,FEM_SETMODE,eax,0 + .confirm_replace: + test [command_flags],1 + jz .replace + invoke UpdateWindow,edi + invoke MessageBox,[hwnd],_replace_prompt,_replace,MB_ICONQUESTION+MB_YESNOCANCEL + cmp eax,IDCANCEL + je .replace_finish + cmp eax,IDNO + je .replace_next + .replace: + push ebx edi + invoke SendMessage,ebx,EM_REPLACESEL,FALSE,replace_string + pop edi ebx + inc [replaces_count] + .replace_next: + invoke SendMessage,ebx,FEM_FINDNEXT,0,0 + or eax,eax + jnz .confirm_replace + .replace_finish: + pop eax + invoke SendMessage,ebx,FEM_SETMODE,eax,0 + test [command_flags],1 + jnz .replace_summary + invoke SendMessage,ebx,FEM_ENDOPERATION,0,0 + .replace_summary: + invoke SendMessage,[hwnd_fedit],FEM_RELEASESEARCH,0,0 + cinvoke wsprintf,string_buffer,_replaces_made,[replaces_count] + invoke MessageBox,[hwnd],string_buffer,_find,MB_ICONINFORMATION+MB_OK + jmp finish + .not_found: + invoke SendMessage,ebx,FEM_ENDOPERATION,0,0 + jmp not_found + run: + and [command_flags],0 + invoke SendMessage,[hwnd],FM_COMPILE,0,FALSE + or eax,eax + jnz finish + mov [sinfo.cb],sizeof.STARTUPINFO + mov [sinfo.dwFlags],0 + cmp [output_format],3 + ja run_object + invoke GetFullPathName,path_buffer,1000h,path_buffer+2000h,param_buffer + mov edx,[param_buffer] + mov byte [edx-1],0 + invoke CreateProcess,path_buffer,NULL,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,path_buffer+2000h,sinfo,pinfo + invoke CloseHandle,[pinfo.hThread] + invoke CloseHandle,[pinfo.hProcess] + jmp finish + run_object: + invoke MessageBox,[hwnd],_run_object_error,_caption,MB_ICONERROR+MB_OK + jmp finish + compile: + and [command_flags],0 + invoke SendMessage,[hwnd],FM_COMPILE,0,TRUE + jmp finish + build_symbols: + mov [command_flags],2 + invoke SendMessage,[hwnd],FM_COMPILE,0,TRUE + jmp finish + assign: + invoke SendMessage,[hwnd_tabctrl],TCM_GETCURSEL,0,0 + cmp eax,[assigned_file] + jne do_assign + or eax,-1 + do_assign: + invoke SendMessage,[hwnd],FM_ASSIGN,eax,0 + jmp finish + appearance: + invoke DialogBoxParam,[hinstance],IDD_APPEARANCE,[hwnd],AppearanceSetup,0 + or eax,eax + jnz update + jmp finish + compiler_setup: + invoke DialogBoxParam,[hinstance],IDD_COMPILERSETUP,[hwnd],CompilerSetup,0 + jmp finish + option_securesel: + xor [fedit_style],FES_SECURESEL + jmp update + option_autobrackets: + xor [fedit_style],FES_AUTOBRACKETS + jmp update + option_autoindent: + xor [fedit_style],FES_AUTOINDENT + jmp update + option_smarttabs: + xor [fedit_style],FES_SMARTTABS + jmp update + option_optimalfill: + xor [fedit_style],FES_OPTIMALFILL + jmp update + option_revivedeadkeys: + xor [fedit_style],FES_REVIVEDEADKEYS + jmp update + option_timescroll: + xor [fedit_style],FES_TIMESCROLL + jmp update + option_oneinstanceonly: + xor [instance_flags],1 + stdcall WriteIniBit,ini_path,_section_options,_key_options_oneinstanceonly,[instance_flags],1 + jmp finish + calculator: + invoke DialogBoxParam,[hinstance],IDD_CALCULATOR,[hwnd],CalculatorDialog,0 + jmp finish + contents: + call get_help_file_extension + cmp eax,'.hlp' + je winhelp_contents + call check_htmlhelp + jc winhelp_contents + invoke HtmlHelp,[hwnd],help_path,HH_DISPLAY_TOPIC,0 + jmp finish + winhelp_contents: + invoke WinHelp,[hwnd],help_path,HELP_FINDER,0 + jmp finish + get_help_file_extension: + mov esi,help_path + skip_help_path: + lodsb + or al,al + jnz skip_help_path + mov ebx,characters + dec esi + mov ecx,4 + convert_extension: + dec esi + shl eax,8 + mov al,[esi] + xlatb + loop convert_extension + retn + check_htmlhelp: + cmp [HtmlHelp],0 + jne htmlhelp_ok + invoke LoadLibrary,_htmlhelp_library + or eax,eax + jz htmlhelp_unavailable + invoke GetProcAddress,eax,_htmlhelp_api + or eax,eax + jz htmlhelp_unavailable + mov [HtmlHelp],eax + htmlhelp_ok: + clc + retn + htmlhelp_unavailable: + stc + retn + keyword: + invoke SendMessage,[hwnd_fedit],FEM_GETWORDATCARET,1000h,string_buffer + call get_help_file_extension + cmp eax,'.hlp' + je winhelp_keyword + call check_htmlhelp + jc winhelp_keyword + mov [hhkey.cbStruct],sizeof.HH_AKLINK + mov [hhkey.pszKeywords],string_buffer + mov [hhkey.pszUrl],0 + mov [hhkey.fIndexOnFail],TRUE + invoke HtmlHelp,[hwnd],help_path,HH_DISPLAY_TOPIC,0 + invoke HtmlHelp,[hwnd],help_path,HH_KEYWORD_LOOKUP,hhkey + jmp finish + winhelp_keyword: + invoke WinHelp,[hwnd],help_path,HELP_KEY,string_buffer + jmp finish + pick_help: + mov [ofn.lpstrFile],help_path + mov [ofn.lpstrFilter],help_filter + mov [ofn.Flags],OFN_EXPLORER+OFN_FILEMUSTEXIST+OFN_HIDEREADONLY + mov [ofn.lpstrTitle],_pick_help + invoke GetOpenFileName,ofn + jmp finish + about: + invoke DialogBoxParam,[hinstance],IDD_ABOUT,[hwnd],AboutDialog,0 + jmp finish + failed: + or eax,-1 + jmp finish + wmnotify: + mov ebx,[lparam] + virtual at ebx + nmh NMHDR + end virtual + cmp [nmh.code],NM_RCLICK + je rclick + cmp [nmh.code],TCN_SELCHANGING + je selchanging + cmp [nmh.code],TCN_SELCHANGE + jne finish + update: + invoke SendMessage,[hwnd_tabctrl],TCM_GETCURSEL,0,0 + invoke SendMessage,[hwnd],FM_SELECT,eax,0 + jmp finish + selchanging: + xor eax,eax + jmp finish + rclick: + invoke GetCursorPos,pt + invoke GetWindowRect,[hwnd_tabctrl],rc + mov eax,[pt.x] + sub eax,[rc.left] + mov [tcht.pt.x],eax + mov eax,[pt.y] + sub eax,[rc.top] + mov [tcht.pt.y],eax + invoke SendMessage,[hwnd_tabctrl],TCM_HITTEST,0,tcht + cmp eax,-1 + je finish + mov ebx,eax + invoke SendMessage,[hwnd_tabctrl],TCM_SETCURSEL,ebx,0 + invoke SendMessage,[hwnd],FM_SELECT,ebx,0 + cmp ebx,[assigned_file] + sete al + neg al + and eax,MF_CHECKED + or eax,MF_BYCOMMAND + invoke CheckMenuItem,[hmenu_tab],IDM_ASSIGN,eax + invoke SendMessage,[hwnd_fedit],FEM_GETMODE,0,0 + test eax,FEMODE_READONLY + setnz al + neg al + and eax,MF_CHECKED + or eax,MF_BYCOMMAND + invoke CheckMenuItem,[hmenu_tab],IDM_READONLY,eax + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,ebx,ei + invoke SendMessage,[hwnd_fedit],FEM_ISUNMODIFIED,0,0 + test eax,eax + setz al + cmp [ei.pszpath],0 + setz ah + or al,ah + neg al + and eax,MF_GRAYED + or eax,MF_BYCOMMAND + invoke EnableMenuItem,[hmenu_tab],IDM_READONLY,eax + invoke TrackPopupMenu,[hmenu_tab],TPM_RIGHTBUTTON,[pt.x],[pt.y],0,[hwnd],0 + jmp finish + wmdropfiles: + invoke DragQueryFile,[wparam],-1,NULL,0 + xor ebx,ebx + drop_files: + cmp ebx,eax + je drag_finish + push eax + invoke DragQueryFile,[wparam],ebx,path_buffer,1000h + push ebx + invoke GetFileTitle,path_buffer,name_buffer,100h + invoke SendMessage,[hwnd],FM_OPEN,name_buffer,path_buffer + cmp eax,-1 + jne drop_ok + cinvoke wsprintf,string_buffer,_loading_error,path_buffer + invoke MessageBox,[hwnd],string_buffer,_caption,MB_ICONERROR+MB_OK + drop_ok: + pop ebx eax + inc ebx + jmp drop_files + drag_finish: + invoke DragFinish,[wparam] + xor eax,eax + jmp finish + wmclose: + mov [lparam],MB_DEFBUTTON2 + close_window: + mov [wparam],0 + check_before_exiting: + mov [ei.header.mask],TCIF_PARAM+TCIF_TEXT + mov [ei.header.pszText],name_buffer + mov [ei.header.cchTextMax],100h + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,[wparam],ei + or eax,eax + jz check_done + mov esi,[ei.pszpath] + invoke SendMessage,[ei.hwnd],FEM_ISUNMODIFIED,0,0 + or eax,eax + jnz check_next + invoke SendMessage,[hwnd_tabctrl],TCM_SETCURSEL,[wparam],0 + invoke SendMessage,[hwnd],FM_SELECT,[wparam],0 + mov eax,MB_ICONQUESTION+MB_YESNOCANCEL + or eax,[lparam] + invoke MessageBox,[hwnd],_saving_question,[ei.header.pszText],eax + cmp eax,IDCANCEL + je finish + cmp eax,IDNO + je check_next + invoke SendMessage,[hwnd],WM_COMMAND,IDM_SAVE,0 + or eax,eax + jnz finish + check_next: + inc [wparam] + jmp check_before_exiting + check_done: + mov [wparam],0 + release_paths: + mov [ei.header.mask],TCIF_PARAM+TCIF_TEXT + mov [ei.header.pszText],name_buffer + mov [ei.header.cchTextMax],100h + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,[wparam],ei + or eax,eax + jz quit + mov esi,[ei.pszpath] + or esi,esi + jz release_next_path + invoke VirtualFree,esi,0,MEM_RELEASE + release_next_path: + inc [wparam] + jmp release_paths + quit: + stdcall WriteIniInteger,ini_path,_section_compiler,_key_compiler_memory,[compiler_memory] + movzx eax,[passes_limit] + stdcall WriteIniInteger,ini_path,_section_compiler,_key_compiler_passes,eax + stdcall WriteIniInteger,ini_path,_section_compiler,_key_compiler_priority,[compiler_priority] + stdcall WriteIniBit,ini_path,_section_options,_key_options_securesel,[fedit_style],FES_SECURESEL + stdcall WriteIniBit,ini_path,_section_options,_key_options_autobrackets,[fedit_style],FES_AUTOBRACKETS + stdcall WriteIniBit,ini_path,_section_options,_key_options_autoindent,[fedit_style],FES_AUTOINDENT + stdcall WriteIniBit,ini_path,_section_options,_key_options_smarttabs,[fedit_style],FES_SMARTTABS + stdcall WriteIniBit,ini_path,_section_options,_key_options_optimalfill,[fedit_style],FES_OPTIMALFILL + stdcall WriteIniBit,ini_path,_section_options,_key_options_revivedeadkeys,[fedit_style],FES_REVIVEDEADKEYS + stdcall WriteIniBit,ini_path,_section_options,_key_options_consolecaret,[fedit_style],FES_CONSOLECARET + stdcall WriteIniBit,ini_path,_section_options,_key_options_timescroll,[fedit_style],FES_TIMESCROLL + stdcall WriteIniColor,ini_path,_section_colors,_key_color_text,[editor_colors] + stdcall WriteIniColor,ini_path,_section_colors,_key_color_background,[editor_colors+4] + stdcall WriteIniColor,ini_path,_section_colors,_key_color_seltext,[editor_colors+8] + stdcall WriteIniColor,ini_path,_section_colors,_key_color_selbackground,[editor_colors+12] + stdcall WriteIniColor,ini_path,_section_colors,_key_color_symbols,[asm_syntax_colors] + stdcall WriteIniColor,ini_path,_section_colors,_key_color_numbers,[asm_syntax_colors+4] + stdcall WriteIniColor,ini_path,_section_colors,_key_color_strings,[asm_syntax_colors+8] + stdcall WriteIniColor,ini_path,_section_colors,_key_color_comments,[asm_syntax_colors+12] + invoke WritePrivateProfileString,_section_font,_key_font_face,font.lfFaceName,ini_path + stdcall WriteIniInteger,ini_path,_section_font,_key_font_height,[font.lfHeight] + stdcall WriteIniInteger,ini_path,_section_font,_key_font_width,[font.lfWidth] + stdcall WriteIniInteger,ini_path,_section_font,_key_font_weight,[font.lfWeight] + stdcall WriteIniBit,ini_path,_section_font,_key_font_italic,dword [font.lfItalic],1 + movzx eax,[font.lfCharSet] + stdcall WriteIniInteger,ini_path,_section_font,_key_font_charset,eax + invoke GetWindowPlacement,[hwnd],wp + stdcall WriteIniInteger,ini_path,_section_window,_key_window_top,[wp.rcNormalPosition.top] + stdcall WriteIniInteger,ini_path,_section_window,_key_window_left,[wp.rcNormalPosition.left] + stdcall WriteIniInteger,ini_path,_section_window,_key_window_right,[wp.rcNormalPosition.right] + stdcall WriteIniInteger,ini_path,_section_window,_key_window_bottom,[wp.rcNormalPosition.bottom] + cmp [wp.showCmd],SW_SHOWMAXIMIZED + sete al + stdcall WriteIniBit,ini_path,_section_window,_key_window_maximized,eax,1 + invoke WritePrivateProfileString,_section_help,_key_help_path,help_path,ini_path + invoke DestroyWindow,[hwnd] + jmp finish + wmdestroy: + invoke WinHelp,[hwnd],0,HELP_QUIT,0 + invoke ImageList_Destroy,[himl] + invoke PostQuitMessage,0 + ok: + xor eax,eax + finish: + pop edi esi ebx + ret +endp + +proc WriteIniInteger ini,sec,key,val + cinvoke wsprintf,string_buffer,_value,[val] + invoke WritePrivateProfileString,[sec],[key],string_buffer,[ini] + ret +endp + +proc WriteIniColor ini,sec,key,color + movzx eax,byte [color] + movzx ebx,byte [color+1] + movzx ecx,byte [color+2] + cinvoke wsprintf,string_buffer,_color,eax,ebx,ecx + invoke WritePrivateProfileString,[sec],[key],string_buffer,[ini] + ret +endp + +proc WriteIniBit ini,sec,key,val,mask + mov eax,[val] + test eax,[mask] + setnz al + movzx eax,al + cinvoke wsprintf,string_buffer,_value,eax + invoke WritePrivateProfileString,[sec],[key],string_buffer,[ini] + ret +endp + +proc GetIniInteger ini,sec,key,lpval + mov [string_buffer],0 + invoke GetPrivateProfileString,[sec],[key],string_buffer,string_buffer,1000h,[ini] + mov esi,string_buffer + cmp byte [esi],0 + je .done + call atoi + jc .done + mov ebx,[lpval] + mov [ebx],eax + .done: + ret +endp + +proc atoi + lodsb + cmp al,20h + je atoi + cmp al,9 + je atoi + mov bl,al + xor eax,eax + xor edx,edx + cmp bl,'-' + je atoi_digit + cmp bl,'+' + je atoi_digit + dec esi + atoi_digit: + mov dl,[esi] + sub dl,30h + jc atoi_done + cmp dl,9 + ja atoi_done + mov ecx,eax + shl ecx,1 + jc atoi_overflow + shl ecx,1 + jc atoi_overflow + add eax,ecx + shl eax,1 + jc atoi_overflow + js atoi_overflow + add eax,edx + jc atoi_overflow + inc esi + jmp atoi_digit + atoi_overflow: + stc + ret + atoi_done: + cmp bl,'-' + jne atoi_sign_ok + neg eax + atoi_sign_ok: + clc + ret +endp + +proc GetIniColor ini,sec,key,lpcolor + mov [string_buffer],0 + invoke GetPrivateProfileString,[sec],[key],string_buffer,string_buffer,1000h,[ini] + mov esi,string_buffer + cmp byte [esi],0 + je .done + call atoi + jc .done + cmp eax,0FFh + ja .done + mov edi,eax + call .find + jne .done + call atoi + jc .done + cmp eax,0FFh + ja .done + shl eax,8 + or edi,eax + call .find + jne .done + call atoi + jc .done + cmp eax,0FFh + ja .done + shl eax,16 + or edi,eax + mov ebx,[lpcolor] + mov [ebx],edi + .done: + ret + .find: + lodsb + cmp al,20h + je .find + cmp al,9 + je .find + cmp al,',' + retn +endp + +proc GetIniByte ini,sec,key,lpval + mov [string_buffer],0 + invoke GetPrivateProfileString,[sec],[key],string_buffer,string_buffer,1000h,[ini] + mov esi,string_buffer + cmp byte [esi],0 + je .done + call atoi + jc .done + cmp eax,100h + jae .done + mov ebx,[lpval] + mov [ebx],al + .done: + ret +endp + +proc GetIniBit ini,sec,key,lpval,mask + mov [string_buffer],0 + invoke GetPrivateProfileString,[sec],[key],string_buffer,string_buffer,1000h,[ini] + mov esi,string_buffer + xor eax,eax + .find: + lodsb + cmp al,20h + je .find + cmp al,9 + je .find + sub al,30h + jc .done + cmp al,1 + ja .done + neg eax + mov ebx,[lpval] + mov edx,[mask] + not edx + and [ebx],edx + and eax,[mask] + or [ebx],eax + .done: + ret +endp + +proc fasm_syntax lpLine,uChars,lpColors + push ebx esi edi + mov esi,[lpLine] + mov edi,[lpColors] + mov ebx,characters + mov ecx,[uChars] + xor edx,edx + .scan_syntax: + lodsb + .check_character: + cmp al,20h + je .syntax_space + cmp al,3Bh + je .syntax_comment + mov ah,al + xlatb + or al,al + jz .syntax_symbol + or edx,edx + jnz .syntax_neutral + cmp ah,27h + je .syntax_string + cmp ah,22h + je .syntax_string + cmp ah,24h + je .syntax_pascal_hex + cmp ah,39h + ja .syntax_neutral + cmp ah,30h + jae .syntax_number + .syntax_neutral: + or edx,-1 + inc edi + loop .scan_syntax + jmp .done + .syntax_space: + xor edx,edx + inc edi + loop .scan_syntax + jmp .done + .syntax_symbol: + mov al,1 + stosb + xor edx,edx + loop .scan_syntax + jmp .done + .syntax_pascal_hex: + cmp ecx,1 + je .syntax_neutral + mov al,[esi] + mov ah,al + xlatb + or al,al + jz .syntax_neutral + cmp ah,24h + jne .syntax_number + cmp ecx,2 + je .syntax_neutral + mov al,[esi+1] + xlatb + or al,al + jz .syntax_neutral + .syntax_number: + mov al,2 + stosb + loop .number_character + jmp .done + .number_character: + lodsb + mov ah,al + xlatb + xchg al,ah + or ah,ah + jz .check_character + cmp al,20h + je .check_character + cmp al,3Bh + je .check_character + mov al,2 + stosb + loop .number_character + jmp .done + .syntax_string: + mov al,3 + stosb + dec ecx + jz .done + lodsb + cmp al,ah + jne .syntax_string + mov al,3 + stosb + dec ecx + jz .done + lodsb + cmp al,ah + je .syntax_string + xor edx,edx + jmp .check_character + .process_comment: + lodsb + cmp al,20h + jne .syntax_comment + inc edi + loop .process_comment + jmp .done + .syntax_comment: + mov al,4 + stosb + loop .process_comment + .done: + pop edi esi ebx + ret +endp + +proc PositionDialog hwnd_dlg,msg,wparam,lparam + push ebx esi edi + cmp [msg],WM_INITDIALOG + je .initdialog + cmp [msg],WM_COMMAND + je .command + cmp [msg],WM_CLOSE + je .close + xor eax,eax + jmp .finish + .initdialog: + invoke SendMessage,[hwnd_fedit],FEM_GETPOS,fepos,0 + cinvoke wsprintf,string_buffer,_value,[fepos.caretLine] + invoke SetDlgItemText,[hwnd_dlg],ID_ROW,string_buffer + cinvoke wsprintf,string_buffer,_value,[fepos.caretPosition] + invoke SetDlgItemText,[hwnd_dlg],ID_COLUMN,string_buffer + jmp .processed + .command: + cmp [wparam],IDCANCEL + je .close + cmp [wparam],IDOK + jne .processed + invoke GetDlgItemInt,[hwnd_dlg],ID_ROW,param_buffer,FALSE + mov [fepos.caretLine],eax + mov [fepos.selectionLine],eax + invoke GetDlgItemInt,[hwnd_dlg],ID_COLUMN,param_buffer,FALSE + mov [fepos.caretPosition],eax + mov [fepos.selectionPosition],eax + invoke IsDlgButtonChecked,[hwnd_dlg],ID_SELECT + or eax,eax + jz .position + mov [fepos.selectionLine],0 + mov [fepos.selectionPosition],0 + .position: + invoke SendMessage,[hwnd_fedit],FEM_SETPOS,fepos,0 + invoke EndDialog,[hwnd_dlg],TRUE + jmp .processed + .close: + invoke EndDialog,[hwnd_dlg],FALSE + .processed: + mov eax,1 + .finish: + pop edi esi ebx + ret +endp + +proc GetStringsFromHistory hwnd_combobox + push ebx esi + invoke SendMessage,[hwnd_history],LB_GETCOUNT,0,0 + mov esi,eax + xor ebx,ebx + .get_string: + cmp ebx,esi + je .finish + invoke SendMessage,[hwnd_history],LB_GETTEXT,ebx,string_buffer + invoke SendMessage,[hwnd_combobox],CB_ADDSTRING,0,string_buffer + inc ebx + jmp .get_string + .finish: + pop esi ebx + ret +endp + +proc AddStringToHistory lpstr + mov eax,[lpstr] + cmp byte [eax],0 + je .finish + invoke SendMessage,[hwnd_history],LB_FINDSTRINGEXACT,-1,[lpstr] + cmp eax,LB_ERR + je .insert + invoke SendMessage,[hwnd_history],LB_DELETESTRING,eax,0 + .insert: + invoke SendMessage,[hwnd_history],LB_INSERTSTRING,0,[lpstr] + cmp eax,LB_ERRSPACE + jne .finish + invoke SendMessage,[hwnd_history],LB_GETCOUNT,0,0 + sub eax,1 + jc .finish + invoke SendMessage,[hwnd_history],LB_DELETESTRING,eax,0 + jmp .insert + .finish: + ret +endp + +proc FindDialog hwnd_dlg,msg,wparam,lparam + push ebx esi edi + cmp [msg],WM_INITDIALOG + je .initdialog + cmp [msg],WM_COMMAND + je .command + cmp [msg],WM_CLOSE + je .close + xor eax,eax + jmp .finish + .initdialog: + invoke SendMessage,[hwnd_fedit],FEM_GETWORDATCARET,1000h,search_string + invoke SetDlgItemText,[hwnd_dlg],ID_TEXT,search_string + invoke GetDlgItem,[hwnd_dlg],ID_TEXT + stdcall GetStringsFromHistory,eax + xor eax,eax + test [search_settings],FEFIND_CASESENSITIVE + setnz al + invoke CheckDlgButton,[hwnd_dlg],ID_CASESENSITIVE,eax + xor eax,eax + test [search_settings],FEFIND_WHOLEWORDS + setnz al + invoke CheckDlgButton,[hwnd_dlg],ID_WHOLEWORDS,eax + xor eax,eax + test [search_settings],FEFIND_BACKWARD + setnz al + invoke CheckDlgButton,[hwnd_dlg],ID_BACKWARD,eax + xor eax,eax + test [search_settings],FEFIND_INWHOLETEXT + setnz al + invoke CheckDlgButton,[hwnd_dlg],ID_INWHOLETEXT,eax + jmp .update + .command: + cmp [wparam],ID_TEXT + CBN_EDITCHANGE shl 16 + je .update + cmp [wparam],ID_TEXT + CBN_SELCHANGE shl 16 + je .selchange + cmp [wparam],IDCANCEL + je .close + cmp [wparam],IDOK + jne .processed + xor ebx,ebx + invoke IsDlgButtonChecked,[hwnd_dlg],ID_CASESENSITIVE + or eax,eax + jz .casesensitive_ok + or ebx,FEFIND_CASESENSITIVE + .casesensitive_ok: + invoke IsDlgButtonChecked,[hwnd_dlg],ID_WHOLEWORDS + or eax,eax + jz .wholewords_ok + or ebx,FEFIND_WHOLEWORDS + .wholewords_ok: + invoke IsDlgButtonChecked,[hwnd_dlg],ID_BACKWARD + or eax,eax + jz .backward_ok + or ebx,FEFIND_BACKWARD + .backward_ok: + invoke IsDlgButtonChecked,[hwnd_dlg],ID_INWHOLETEXT + or eax,eax + jz .inwholetext_ok + or ebx,FEFIND_INWHOLETEXT + .inwholetext_ok: + mov [search_settings],ebx + stdcall AddStringToHistory,search_string + invoke EndDialog,[hwnd_dlg],TRUE + jmp .processed + .selchange: + invoke PostMessage,[hwnd_dlg],WM_COMMAND,ID_TEXT + CBN_EDITCHANGE shl 16,0 + jmp .processed + .update: + invoke GetDlgItemText,[hwnd_dlg],ID_TEXT,search_string,1000h + xor ebx,ebx + cmp [search_string],0 + setnz bl + invoke GetDlgItem,[hwnd_dlg],IDOK + invoke EnableWindow,eax,ebx + jmp .processed + .close: + invoke EndDialog,[hwnd_dlg],FALSE + .processed: + mov eax,1 + .finish: + pop edi esi ebx + ret +endp + +proc ReplaceDialog hwnd_dlg,msg,wparam,lparam + push ebx esi edi + cmp [msg],WM_INITDIALOG + je .initdialog + cmp [msg],WM_COMMAND + je .command + jmp .finish + .initdialog: + invoke SetDlgItemText,[hwnd_dlg],ID_NEWTEXT,replace_string + invoke GetDlgItem,[hwnd_dlg],ID_NEWTEXT + stdcall GetStringsFromHistory,eax + xor eax,eax + test [command_flags],1 + setnz al + invoke CheckDlgButton,[hwnd_dlg],ID_PROMPT,eax + jmp .finish + .command: + cmp [wparam],IDOK + jne .finish + invoke GetDlgItemText,[hwnd_dlg],ID_NEWTEXT,replace_string,1000h + xor ebx,ebx + invoke IsDlgButtonChecked,[hwnd_dlg],ID_PROMPT + or eax,eax + jz .prompt_ok + or ebx,1 + .prompt_ok: + mov [command_flags],ebx + stdcall AddStringToHistory,replace_string + .finish: + stdcall FindDialog,[hwnd_dlg],[msg],[wparam],[lparam] + pop edi esi ebx + ret +endp + +proc CompileDialog hwnd_dlg,msg,wparam,lparam + push ebx esi edi + cmp [msg],WM_INITDIALOG + je .initdialog + cmp [msg],WM_COMMAND + je .command + cmp [msg],WM_CLOSE + je .close + xor eax,eax + jmp .finish + .initdialog: + mov eax,[hwnd_dlg] + mov [hwnd_compiler],eax + invoke GetDlgItem,[hwnd_dlg],ID_PROGRESS + mov [hwnd_progress],eax + invoke SendMessage,eax,PBM_SETRANGE,0,40000h + mov [ei.header.mask],TCIF_PARAM + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,[lparam],ei + invoke CreateMutex,NULL,FALSE,NULL + mov [mutex],eax + invoke CreateThread,NULL,10000h,flat_assembler,[ei.pszpath],0,param_buffer + mov [hthread],eax + jmp .processed + .command: + cmp [wparam],IDCANCEL + je .close + cmp [wparam],IDOK + jne .finish + .get_exit_code: + invoke WaitForSingleObject,[hthread],-1 + invoke GetExitCodeThread,[hthread],param_buffer + invoke CloseHandle,[hthread] + invoke CloseHandle,[mutex] + invoke EndDialog,[hwnd_dlg],[param_buffer] + jmp .processed + .close: + invoke WaitForSingleObject,[mutex],-1 + cmp eax,WAIT_ABANDONED + je .processed + invoke TerminateThread,[hthread],0FFh + invoke ReleaseMutex,[mutex] + invoke CloseHandle,[hthread] + invoke CloseHandle,[mutex] + invoke GlobalFree,[hmem_display] + mov eax,[memory_start] + or eax,eax + jz .cancel + invoke VirtualFree,eax,0,MEM_RELEASE + mov [memory_start],0 + cmp [error_data_size],0 + je .cancel + invoke GlobalFree,[hmem_error_data] + .cancel: + invoke EndDialog,[hwnd_dlg],-1 + .processed: + mov eax,1 + .finish: + pop edi esi ebx + ret +endp + +proc ShowLine pszPath,nLine + mov [ei.header.mask],TCIF_PARAM + invoke SendMessage,[hwnd_tabctrl],TCM_GETCURSEL,0,0 + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,eax,ei + invoke lstrcmpi,[ei.pszpath],[pszPath] + or eax,eax + jz current_file_ok + xor ebx,ebx + find_file_window: + invoke SendMessage,[hwnd_tabctrl],TCM_GETITEM,ebx,ei + or eax,eax + jz load_for_show + invoke lstrcmpi,[ei.pszpath],[pszPath] + or eax,eax + jz show_file + inc ebx + jmp find_file_window + load_for_show: + mov esi,[pszPath] + mov edi,path_buffer + copy_path_for_show: + lodsb + stosb + or al,al + jnz copy_path_for_show + invoke GetFileTitle,path_buffer,name_buffer,100h + invoke SendMessage,[hwnd_main],FM_OPEN,name_buffer,path_buffer + cmp eax,-1 + je show_failed + jmp current_file_ok + show_file: + invoke SendMessage,[hwnd_tabctrl],TCM_SETCURSEL,ebx,0 + invoke SendMessage,[hwnd_main],FM_SELECT,ebx,0 + current_file_ok: + mov eax,[nLine] + mov [fepos.selectionLine],eax + mov [fepos.caretLine],eax + get_lines_to_show: + invoke SendMessage,[hwnd_fedit],FEM_GETLINELENGTH,[nLine],0 + mov esi,string_buffer + cmp eax,1000h + jb get_line_data + mov edi,eax + invoke VirtualAlloc,0,edi,MEM_COMMIT,PAGE_READWRITE + or eax,eax + jz show_lines + mov esi,eax + get_line_data: + invoke SendMessage,[hwnd_fedit],FEM_GETLINE,[nLine],esi + push esi + mov ecx,eax + or ecx,ecx + jz no_more_lines + mov eax,[nLine] + mov [fepos.caretLine],eax + mov ebx,characters + xor edx,edx + check_for_more_lines: + lodsb + cmp al,3Bh + je no_more_lines + mov ah,al + xlatb + or al,al + jz .symbol + or edx,edx + jnz .neutral + cmp ah,27h + je .quoted + cmp ah,22h + je .quoted + .neutral: + or edx,-1 + loop check_for_more_lines + jmp no_more_lines + .symbol: + cmp ah,'\' + je .backslash + xor edx,edx + loop check_for_more_lines + jmp no_more_lines + .quoted: + dec ecx + jz no_more_lines + lodsb + cmp al,ah + jne .quoted + dec ecx + jz no_more_lines + lodsb + cmp al,ah + je .quoted + dec esi + xor edx,edx + jmp check_for_more_lines + .backslash: + dec ecx + jz more_lines + lodsb + cmp al,20h + je .backslash + cmp al,3Bh + jne no_more_lines + more_lines: + inc [nLine] + pop esi + cmp esi,string_buffer + je get_lines_to_show + invoke VirtualFree,esi,edi,MEM_DECOMMIT + jmp get_lines_to_show + no_more_lines: + pop esi + cmp esi,string_buffer + je show_lines + invoke VirtualFree,esi,edi,MEM_DECOMMIT + show_lines: + mov [fepos.selectionPosition],1 + inc [fepos.caretLine] + mov [fepos.caretPosition],1 + invoke SendMessage,[hwnd_fedit],FEM_GETLINELENGTH,[fepos.caretLine],0 + cmp eax,-1 + jne show_ok + dec [fepos.caretLine] + invoke SendMessage,[hwnd_fedit],FEM_GETLINELENGTH,[fepos.caretLine],0 + inc eax + mov [fepos.caretPosition],eax + show_ok: + invoke SendMessage,[hwnd_fedit],FEM_SETPOS,fepos,0 + invoke SendMessage,[hwnd_fedit],FEM_GETMODE,0,0 + and eax,not FEMODE_VERTICALSEL + invoke SendMessage,[hwnd_fedit],FEM_SETMODE,eax,0 + mov eax,[fepos.selectionLine] + xchg eax,[fepos.caretLine] + mov [fepos.selectionLine],eax + mov eax,[fepos.selectionPosition] + xchg eax,[fepos.caretPosition] + mov [fepos.selectionPosition],eax + invoke SendMessage,[hwnd_fedit],FEM_SETPOS,fepos,0 + xor eax,eax + ret + show_failed: + or eax,-1 + ret +endp + +proc SummaryDialog hwnd_dlg,msg,wparam,lparam + push ebx esi edi + cmp [msg],WM_INITDIALOG + je .initdialog + cmp [msg],WM_COMMAND + je .command + cmp [msg],WM_CLOSE + je .close + xor eax,eax + jmp .finish + .initdialog: + invoke GetDlgItem,[hwnd_dlg],ID_DISPLAY + invoke SendMessage,eax,WM_SETFONT,[hfont],FALSE + invoke GlobalLock,[hmem_display] + invoke SetDlgItemText,[hwnd_dlg],ID_DISPLAY,eax + invoke GlobalUnlock,[hmem_display] + invoke GlobalFree,[hmem_display] + cmp [lparam],2 + je .error_details + cmp [lparam],0 + jne .error_message + movzx eax,[current_pass] + inc eax + mov [param_buffer],eax + mov eax,[written_size] + mov [param_buffer+4],eax + mov [param_buffer+12],eax + mov eax,[total_time] + xor edx,edx + mov ebx,100 + div ebx + mov ebx,_summary_short + or eax,eax + jz .summary_ok + xor edx,edx + mov ebx,10 + div ebx + mov [param_buffer+4],eax + mov [param_buffer+8],edx + mov ebx,_summary + .summary_ok: + invoke wvsprintf,string_buffer,ebx,param_buffer + invoke SetDlgItemText,[hwnd_dlg],ID_MESSAGE,string_buffer + cmp [lparam],2 + jne .processed + .show_line: + invoke SendDlgItemMessage,[hwnd_dlg],ID_LINES,LB_GETCURSEL,0,0 + lea ebx,[eax+1] + invoke GlobalLock,[hmem_error_data] + mov esi,[eax+ebx*8] + add esi,eax + mov eax,[eax+ebx*8+4] + stdcall ShowLine,esi,eax + invoke GlobalUnlock,[hmem_error_data] + jmp .processed + .error_details: + invoke GetDlgItem,[hwnd_dlg],ID_INSTRUCTION + invoke SendMessage,eax,WM_SETFONT,[hfont],FALSE + invoke GlobalLock,[hmem_error_data] + mov edi,eax + xor ebx,ebx + .get_error_lines: + inc ebx + mov esi,[edi+ebx*8] + add esi,edi + mov eax,[edi+ebx*8+4] + mov [param_buffer+4],eax + invoke GetFullPathName,esi,1000h,path_buffer,param_buffer + invoke wvsprintf,string_buffer,_line_number,param_buffer + invoke SendDlgItemMessage,[hwnd_dlg],ID_LINES,LB_ADDSTRING,0,string_buffer + cmp ebx,[edi] + jb .get_error_lines + mov eax,[edi+4] + add eax,edi + invoke SetDlgItemText,[hwnd_dlg],ID_INSTRUCTION,eax + invoke GlobalUnlock,[hmem_error_data] + invoke SendDlgItemMessage,[hwnd_dlg],ID_LINES,LB_SETCURSEL,0,0 + .error_message: + invoke LoadIcon,0,IDI_HAND + invoke SendDlgItemMessage,[hwnd_dlg],ID_ICON,STM_SETICON,eax,0 + mov eax,[error_message] + mov [param_buffer],eax + mov ebx,_assembler_error + jmp .summary_ok + .command: + cmp [wparam],ID_LINES + LBN_SELCHANGE shl 16 + je .show_line + cmp [wparam],IDCANCEL + je .close + cmp [wparam],IDOK + jne .finish + invoke EndDialog,[hwnd_dlg],TRUE + jmp .processed + .close: + invoke EndDialog,[hwnd_dlg],FALSE + .processed: + mov eax,1 + .finish: + pop edi esi ebx + ret +endp + +proc AddStrings hwnd_combobox,lpstrings + push ebx esi + mov esi,[lpstrings] + .add_string: + cmp byte [esi],0 + je .finish + invoke SendMessage,[hwnd_combobox],CB_ADDSTRING,0,esi + .next_string: + lodsb + or al,al + jnz .next_string + jmp .add_string + .finish: + pop esi ebx + ret +endp + +proc AppearanceSetup hwnd_dlg,msg,wparam,lparam + push ebx esi edi + cmp [msg],WM_INITDIALOG + je .initdialog + cmp [msg],WM_DESTROY + je .destroy + cmp [msg],WM_COMMAND + je .command + cmp [msg],WM_CLOSE + je .close + .notprocessed: + xor eax,eax + jmp .finish + .initdialog: + xor eax,eax + test [fedit_style],FES_CONSOLECARET + setnz al + invoke CheckDlgButton,[hwnd_dlg],ID_CONSOLECARET,eax + mov [cf.lStructSize],sizeof.CHOOSEFONT + mov eax,[hwnd_dlg] + mov [cf.hwndOwner],eax + mov [cf.Flags],CF_FIXEDPITCHONLY+CF_SCREENFONTS+CF_FORCEFONTEXIST+CF_INITTOLOGFONTSTRUCT + mov [cf.lpLogFont],tmp_font + mov [cc.lStructSize],sizeof.CHOOSECOLOR + mov eax,[hinstance] + mov [cc.hInstance],eax + mov eax,[hwnd_dlg] + mov [cc.hwndOwner],eax + mov [cc.lpCustColors],user_colors + mov [cc.Flags],CC_RGBINIT + mov esi,font + mov edi,tmp_font + mov ecx,sizeof.LOGFONT shr 2 + rep movsd + mov esi,editor_colors + mov edi,tmp_colors + mov ecx,8 + rep movsd + mov esi,editor_colors + mov edi,user_colors+20h + mov ecx,8 + rep movsd + invoke GetDlgItem,[hwnd_dlg],ID_SETTING + stdcall AddStrings,eax,_appearance_settings + invoke SendDlgItemMessage,[hwnd_dlg],ID_SETTING,CB_SETCURSEL,0,0 + invoke SendDlgItemMessage,[hwnd_dlg],ID_PREVIEW,WM_SETTEXT,0,preview_text + invoke SendDlgItemMessage,[hwnd_dlg],ID_PREVIEW,FEM_SETPOS,preview_selection,0 + invoke CreateFontIndirect,[cf.lpLogFont] + invoke SendDlgItemMessage,[hwnd_dlg],ID_PREVIEW,WM_SETFONT,eax,0 + .update_colors: + invoke SendDlgItemMessage,[hwnd_dlg],ID_PREVIEW,FEM_SETTEXTCOLOR,[tmp_colors],[tmp_colors+4] + invoke SendDlgItemMessage,[hwnd_dlg],ID_PREVIEW,FEM_SETSELCOLOR,[tmp_colors+8],[tmp_colors+12] + invoke SendDlgItemMessage,[hwnd_dlg],ID_PREVIEW,FEM_SETSYNTAXHIGHLIGHT,tmp_colors+16,fasm_syntax + jmp .processed + .destroy: + invoke SendDlgItemMessage,[hwnd_dlg],ID_PREVIEW,WM_GETFONT,0,0 + invoke DeleteObject,eax + jmp .finish + .command: + cmp [wparam],IDCANCEL + je .close + cmp [wparam],IDOK + je .ok + cmp [wparam],ID_CHANGE + jne .processed + invoke SendDlgItemMessage,[hwnd_dlg],ID_SETTING,CB_GETCURSEL,0,0 + or eax,eax + jz .change_font + cmp eax,8 + ja .processed + lea ebx,[tmp_colors+(eax-1)*4] + mov eax,[ebx] + mov [cc.rgbResult],eax + invoke ChooseColor,cc + or eax,eax + jz .processed + mov eax,[cc.rgbResult] + mov [ebx],eax + jmp .update_colors + .change_font: + mov esi,tmp_font + mov edi,backup_font + mov ecx,sizeof.LOGFONT shr 2 + rep movsd + invoke ChooseFont,cf + or eax,eax + jz .change_font_cancelled + invoke SendDlgItemMessage,[hwnd_dlg],ID_PREVIEW,WM_GETFONT,0,0 + mov ebx,eax + invoke CreateFontIndirect,[cf.lpLogFont] + invoke SendDlgItemMessage,[hwnd_dlg],ID_PREVIEW,WM_SETFONT,eax,0 + invoke DeleteObject,ebx + jmp .processed + .change_font_cancelled: + mov esi,backup_font + mov edi,tmp_font + mov ecx,sizeof.LOGFONT shr 2 + rep movsd + jmp .processed + .ok: + mov esi,tmp_colors + mov edi,editor_colors + mov ecx,8 + rep movsd + mov esi,tmp_font + mov edi,font + mov ecx,sizeof.LOGFONT shr 2 + rep movsd + invoke CreateFontIndirect,font + xchg eax,[hfont] + invoke DeleteObject,eax + invoke IsDlgButtonChecked,[hwnd_dlg],ID_CONSOLECARET + or eax,eax + setnz al + neg eax + and eax,FES_CONSOLECARET + and [fedit_style],not FES_CONSOLECARET + or [fedit_style],eax + invoke EndDialog,[hwnd_dlg],TRUE + jmp .finish + .close: + invoke EndDialog,[hwnd_dlg],FALSE + .processed: + mov eax,1 + .finish: + pop edi esi ebx + ret +endp + +proc CompilerSetup hwnd_dlg,msg,wparam,lparam + push ebx esi edi + cmp [msg],WM_INITDIALOG + je .initdialog + cmp [msg],WM_COMMAND + je .command + cmp [msg],WM_CLOSE + je .close + .notprocessed: + xor eax,eax + jmp .finish + .initdialog: + invoke SendDlgItemMessage,[hwnd_dlg],ID_INCLUDEPATH,CB_ADDSTRING,0,include_path + mov [string_buffer],0 + invoke GetEnvironmentVariable,_key_environment_include,string_buffer,1000h + invoke GetPrivateProfileString,_section_environment,_key_environment_include,string_buffer,path_buffer,4000h,ini_path + invoke SetDlgItemText,[hwnd_dlg],ID_INCLUDEPATH,path_buffer + invoke GetDlgItem,[hwnd_dlg],ID_MEMORY + stdcall AddStrings,eax,_memory_settings + invoke GetDlgItem,[hwnd_dlg],ID_PRIORITY + stdcall AddStrings,eax,_priority_settings + cinvoke wsprintf,string_buffer,_value,[compiler_memory] + invoke SendDlgItemMessage,[hwnd_dlg],ID_MEMORY,CB_FINDSTRINGEXACT,-1,string_buffer + cmp eax,CB_ERR + je .set_memory + invoke SendDlgItemMessage,[hwnd_dlg],ID_MEMORY,CB_SETCURSEL,eax,0 + jmp .memory_ok + .set_memory: + invoke SetDlgItemText,[hwnd_dlg],ID_MEMORY,string_buffer + .memory_ok: + movzx eax,[passes_limit] + invoke SetDlgItemInt,[hwnd_dlg],ID_PASSES,eax,FALSE + mov eax,[compiler_priority] + cmp eax,2 + jg .realtime + cmp eax,-2 + jl .idle + jmp .priority_ok + .idle: + mov eax,-4 + jmp .priority_ok + .realtime: + mov eax,4 + .priority_ok: + sar eax,1 + add eax,2 + invoke SendDlgItemMessage,[hwnd_dlg],ID_PRIORITY,CB_SETCURSEL,eax,0 + jmp .processed + .command: + cmp [wparam],IDCANCEL + je .close + cmp [wparam],IDOK + jne .finish + invoke GetDlgItemInt,[hwnd_dlg],ID_MEMORY,param_buffer,FALSE + mov [compiler_memory],eax + invoke GetDlgItemInt,[hwnd_dlg],ID_PASSES,param_buffer,FALSE + cmp eax,0FFFFh + jbe .set_passes + mov ax,0FFFFh + .set_passes: + mov [passes_limit],ax + invoke SendDlgItemMessage,[hwnd_dlg],ID_PRIORITY,CB_GETCURSEL,0,0 + sub eax,2 + sal eax,1 + cmp eax,4 + je .set_realtime + cmp eax,-4 + je .set_idle + jmp .set_priority + .set_idle: + mov eax,-15 + jmp .set_priority + .set_realtime: + mov eax,15 + .set_priority: + mov [compiler_priority],eax + invoke GetDlgItemText,[hwnd_dlg],ID_INCLUDEPATH,path_buffer,4000h + invoke WritePrivateProfileString,_section_environment,_key_environment_include,path_buffer,ini_path + invoke EndDialog,[hwnd_dlg],TRUE + jmp .finish + .close: + invoke EndDialog,[hwnd_dlg],FALSE + .processed: + mov eax,1 + .finish: + pop edi esi ebx + ret +endp + +proc CalculatorDialog hwnd,msg,wparam,lparam + push ebx esi edi + cmp [msg],WM_INITDIALOG + je .init + cmp [msg],WM_COMMAND + je .command + cmp [msg],WM_CLOSE + je .close + xor eax,eax + jmp .finish + .init: + invoke CheckDlgButton,[hwnd],ID_DECSELECT,BST_CHECKED + jmp .processed + .command: + cmp [wparam],IDCANCEL + je .close + cmp [wparam],IDOK + je .evaluate + cmp [wparam],ID_EXPRESSION + EN_CHANGE shl 16 + jne .processed + .calculate: + mov esi,string_buffer + invoke GetDlgItemText,[hwnd],ID_EXPRESSION,esi,400h + lea edi,[esi+eax] + xor eax,eax + stosb + mov [hthread],eax + mov [hash_tree],eax + mov [macro_status],al + mov [symbols_file],eax + not eax + mov [source_start],eax + lea eax,[esi+1000h] + mov [memory_end],eax + mov [labels_list],eax + mov eax,esp + and eax,not 0FFFh + sub eax,1000h + mov [stack_limit],eax + push ebp + mov [resume_esp],esp + mov [resume_eip],.calculator_error + call convert_line + push edi + call convert_expression + cmp byte [esi],0 + jne invalid_expression + mov al,')' + stosb + pop esi + mov [error_line],0 + or [current_line],-1 + mov [value_size],0 + call calculate_expression + cmp [error_line],0 + je .present_result + jmp [error] + .present_result: + mov esi,edi + cmp byte [esi+13],0 + je .result_in_64bit_composite_range + test byte [esi+7],80h + jnz .result_in_64bit_composite_range + invoke SetDlgItemText,[hwnd],ID_BINRESULT,_null + invoke SetDlgItemText,[hwnd],ID_OCTRESULT,_null + invoke SetDlgItemText,[hwnd],ID_HEXRESULT,_null + jmp .present_decimal + .result_in_64bit_composite_range: + mov eax,[esi] + mov edx,[esi+4] + mov edi,name_buffer+100 + mov word [edi],'b' + .make_binary: + mov bl,'0' + shrd eax,edx,1 + adc bl,0 + dec edi + mov [edi],bl + shr edx,1 + jnz .make_binary + test eax,eax + jnz .make_binary + invoke SetDlgItemText,[hwnd],ID_BINRESULT,edi + mov ecx,[esi] + mov edx,[esi+4] + mov edi,name_buffer+100 + mov word [edi],'o' + .make_octal: + mov al,cl + and al,111b + add al,'0' + dec edi + mov [edi],al + shrd ecx,edx,3 + shr edx,3 + jnz .make_octal + test ecx,ecx + jnz .make_octal + invoke SetDlgItemText,[hwnd],ID_OCTRESULT,edi + mov ecx,[esi] + mov edx,[esi+4] + mov edi,name_buffer+100 + mov word [edi],'h' + .make_hexadecimal: + mov al,cl + and al,0Fh + cmp al,10 + sbb al,69h + das + dec edi + mov [edi],al + shrd ecx,edx,4 + shr edx,4 + jnz .make_hexadecimal + test ecx,ecx + jnz .make_hexadecimal + cmp al,'A' + jb .hexadecimal_ok + dec edi + mov byte [edi],'0' + .hexadecimal_ok: + invoke SetDlgItemText,[hwnd],ID_HEXRESULT,edi + .present_decimal: + mov edi,name_buffer+100 + mov byte [edi],0 + mov ecx,10 + xor bl,bl + cmp byte [esi+13],0 + je .make_decimal + mov bl,'-' + mov eax,[esi] + mov edx,[esi+4] + not eax + not edx + add eax,1 + adc edx,0 + mov [esi],eax + mov [esi+4],edx + or eax,edx + jnz .make_decimal + dec edi + mov byte [edi],'6' + mov dword [esi],99999999h + mov dword [esi+4],19999999h + .make_decimal: + mov eax,[esi+4] + xor edx,edx + div ecx + mov [esi+4],eax + mov eax,[esi] + div ecx + mov [esi],eax + add dl,'0' + dec edi + mov [edi],dl + or eax,[esi+4] + jnz .make_decimal + test bl,bl + jz .decimal_ok + dec edi + mov [edi],bl + .decimal_ok: + invoke SetDlgItemText,[hwnd],ID_DECRESULT,edi + pop ebp + jmp .processed + .calculator_error: + pop ebp + invoke SetDlgItemText,[hwnd],ID_BINRESULT,_null + invoke SetDlgItemText,[hwnd],ID_DECRESULT,_null + invoke SetDlgItemText,[hwnd],ID_HEXRESULT,_null + invoke SetDlgItemText,[hwnd],ID_OCTRESULT,_null + jmp .processed + .evaluate: + mov ebx,ID_BINRESULT + invoke IsDlgButtonChecked,[hwnd],ID_BINSELECT + cmp eax,BST_CHECKED + je .get_result + mov ebx,ID_HEXRESULT + invoke IsDlgButtonChecked,[hwnd],ID_HEXSELECT + cmp eax,BST_CHECKED + je .get_result + mov ebx,ID_OCTRESULT + invoke IsDlgButtonChecked,[hwnd],ID_OCTSELECT + cmp eax,BST_CHECKED + je .get_result + mov ebx,ID_DECRESULT + .get_result: + invoke GetDlgItemText,[hwnd],ebx,string_buffer,100h + invoke SetDlgItemText,[hwnd],ID_EXPRESSION,string_buffer + invoke GetDlgItem,[hwnd],ID_EXPRESSION + invoke SendMessage,[hwnd],WM_NEXTDLGCTL,eax,TRUE + jmp .processed + .close: + invoke EndDialog,[hwnd],0 + .processed: + mov eax,1 + .finish: + pop edi esi ebx + ret +endp + +proc AboutDialog hwnd,msg,wparam,lparam + push ebx esi edi + cmp [msg],WM_COMMAND + je .close + cmp [msg],WM_CLOSE + je .close + xor eax,eax + jmp .finish + .close: + invoke EndDialog,[hwnd],0 + .processed: + mov eax,1 + .finish: + pop edi esi ebx + ret +endp + +include 'fasm.inc' + +section '.idata' import data readable writeable + + library kernel,'KERNEL32.DLL',\ + advapi,'ADVAPI32.DLL',\ + user,'USER32.DLL',\ + gdi,'GDI32.DLL',\ + comctl,'COMCTL32.DLL',\ + comdlg,'COMDLG32.DLL',\ + shell,'SHELL32.DLL' + + import kernel,\ + GetModuleHandle,'GetModuleHandleA',\ + LoadLibrary,'LoadLibraryA',\ + GetProcAddress,'GetProcAddress',\ + GetCommandLine,'GetCommandLineA',\ + GetFileAttributes,'GetFileAttributesA',\ + GetFullPathName,'GetFullPathNameA',\ + GetCurrentDirectory,'GetCurrentDirectoryA',\ + SetCurrentDirectory,'SetCurrentDirectoryA',\ + CreateFile,'CreateFileA',\ + GetFileSize,'GetFileSize',\ + ReadFile,'ReadFile',\ + WriteFile,'WriteFile',\ + SetFilePointer,'SetFilePointer',\ + CloseHandle,'CloseHandle',\ + lstrcmpi,'lstrcmpiA',\ + GlobalAlloc,'GlobalAlloc',\ + GlobalReAlloc,'GlobalReAlloc',\ + GlobalLock,'GlobalLock',\ + GlobalUnlock,'GlobalUnlock',\ + GlobalFree,'GlobalFree',\ + VirtualAlloc,'VirtualAlloc',\ + VirtualFree,'VirtualFree',\ + CreateThread,'CreateThread',\ + SetThreadPriority,'SetThreadPriority',\ + TerminateThread,'TerminateThread',\ + ExitThread,'ExitThread',\ + GetExitCodeThread,'GetExitCodeThread',\ + WaitForSingleObject,'WaitForSingleObject',\ + CreateMutex,'CreateMutexA',\ + ReleaseMutex,'ReleaseMutex',\ + CreateProcess,'CreateProcessA',\ + AllocConsole,'AllocConsole',\ + SetConsoleTitle,'SetConsoleTitleA',\ + FreeConsole,'FreeConsole',\ + GetEnvironmentVariable,'GetEnvironmentVariableA',\ + GetSystemTime,'GetSystemTime',\ + GetTickCount,'GetTickCount',\ + GetPrivateProfileString,'GetPrivateProfileStringA',\ + WritePrivateProfileString,'WritePrivateProfileStringA',\ + GetLastError,'GetLastError',\ + ExitProcess,'ExitProcess' + + import advapi,\ + RegOpenKeyEx,'RegOpenKeyExA',\ + RegQueryValueEx,'RegQueryValueExA',\ + RegCloseKey,'RegCloseKey' + + import user,\ + RegisterClass,'RegisterClassA',\ + CreateCaret,'CreateCaret',\ + ShowCaret,'ShowCaret',\ + HideCaret,'HideCaret',\ + SetCaretPos,'SetCaretPos',\ + DestroyCaret,'DestroyCaret',\ + BeginPaint,'BeginPaint',\ + EndPaint,'EndPaint',\ + GetDC,'GetDC',\ + GetUpdateRect,'GetUpdateRect',\ + ReleaseDC,'ReleaseDC',\ + DrawText,'DrawTextA',\ + FillRect,'FillRect',\ + InvalidateRect,'InvalidateRect',\ + GetKeyboardState,'GetKeyboardState',\ + ToAscii,'ToAscii',\ + GetScrollInfo,'GetScrollInfo',\ + SetScrollInfo,'SetScrollInfo',\ + SetCapture,'SetCapture',\ + ReleaseCapture,'ReleaseCapture',\ + GetCursorPos,'GetCursorPos',\ + ClientToScreen,'ClientToScreen',\ + OpenClipboard,'OpenClipboard',\ + CloseClipboard,'CloseClipboard',\ + EmptyClipboard,'EmptyClipboard',\ + GetClipboardData,'GetClipboardData',\ + SetClipboardData,'SetClipboardData',\ + LoadCursor,'LoadCursorA',\ + LoadIcon,'LoadIconA',\ + LoadBitmap,'LoadBitmapA',\ + LoadMenu,'LoadMenuA',\ + EnableMenuItem,'EnableMenuItem',\ + CheckMenuItem,'CheckMenuItem',\ + GetSubMenu,'GetSubMenu',\ + TrackPopupMenu,'TrackPopupMenu',\ + LoadAccelerators,'LoadAcceleratorsA',\ + IsClipboardFormatAvailable,'IsClipboardFormatAvailable',\ + CharLower,'CharLowerA',\ + CharUpper,'CharUpperA',\ + wsprintf,'wsprintfA',\ + wvsprintf,'wvsprintfA',\ + MessageBox,'MessageBoxA',\ + WinHelp,'WinHelpA',\ + DialogBoxParam,'DialogBoxParamA',\ + GetDlgItem,'GetDlgItem',\ + GetDlgItemInt,'GetDlgItemInt',\ + SetDlgItemInt,'SetDlgItemInt',\ + GetDlgItemText,'GetDlgItemTextA',\ + SetDlgItemText,'SetDlgItemTextA',\ + CheckDlgButton,'CheckDlgButton',\ + IsDlgButtonChecked,'IsDlgButtonChecked',\ + SendDlgItemMessage,'SendDlgItemMessageA',\ + EndDialog,'EndDialog',\ + FindWindow,'FindWindowA',\ + SetForegroundWindow,'SetForegroundWindow',\ + CreateWindowEx,'CreateWindowExA',\ + DestroyWindow,'DestroyWindow',\ + GetWindowLong,'GetWindowLongA',\ + SetWindowLong,'SetWindowLongA',\ + DefWindowProc,'DefWindowProcA',\ + GetClientRect,'GetClientRect',\ + GetWindowRect,'GetWindowRect',\ + MoveWindow,'MoveWindow',\ + SetWindowPos,'SetWindowPos',\ + GetWindowPlacement,'GetWindowPlacement',\ + SetWindowPlacement,'SetWindowPlacement',\ + ShowWindow,'ShowWindow',\ + EnableWindow,'EnableWindow',\ + UpdateWindow,'UpdateWindow',\ + IsZoomed,'IsZoomed',\ + SetFocus,'SetFocus',\ + GetSystemMetrics,'GetSystemMetrics',\ + GetSysColor,'GetSysColor',\ + SendMessage,'SendMessageA',\ + GetMessage,'GetMessageA',\ + TranslateAccelerator,'TranslateAccelerator',\ + TranslateMessage,'TranslateMessage',\ + DispatchMessage,'DispatchMessageA',\ + PostMessage,'PostMessageA',\ + PostQuitMessage,'PostQuitMessage' + + import gdi,\ + SetBkColor,'SetBkColor',\ + SetTextColor,'SetTextColor',\ + CreateSolidBrush,'CreateSolidBrush',\ + CreateFont,'CreateFontA',\ + CreateFontIndirect,'CreateFontIndirectA',\ + GetTextMetrics,'GetTextMetricsA',\ + GetTextExtentPoint32,'GetTextExtentPoint32A',\ + CreateCompatibleDC,'CreateCompatibleDC',\ + DeleteDC,'DeleteDC',\ + CreateBitmap,'CreateBitmap',\ + SelectObject,'SelectObject',\ + GetObject,'GetObjectA',\ + DeleteObject,'DeleteObject' + + import comctl,\ + CreateStatusWindow,'CreateStatusWindowA',\ + ImageList_Create,'ImageList_Create',\ + ImageList_Add,'ImageList_Add',\ + ImageList_Destroy,'ImageList_Destroy' + + import comdlg,\ + GetOpenFileName,'GetOpenFileNameA',\ + GetSaveFileName,'GetSaveFileNameA',\ + GetFileTitle,'GetFileTitleA',\ + ChooseFont,'ChooseFontA',\ + ChooseColor,'ChooseColorA' + + import shell,\ + DragAcceptFiles,'DragAcceptFiles',\ + DragQueryFile,'DragQueryFile',\ + DragFinish,'DragFinish',\ + ShellExecute,'ShellExecuteA' + +section '.rsrc' resource data readable + + directory RT_MENU,menus,\ + RT_ACCELERATOR,accelerators,\ + RT_DIALOG,dialogs,\ + RT_GROUP_ICON,group_icons,\ + RT_ICON,icons,\ + RT_BITMAP,bitmaps,\ + RT_VERSION,versions + + resource menus,\ + IDM_MAIN,LANG_ENGLISH+SUBLANG_DEFAULT,main_menu,\ + IDM_TAB,LANG_ENGLISH+SUBLANG_DEFAULT,popup_menu + + resource accelerators,\ + IDA_MAIN,LANG_ENGLISH+SUBLANG_DEFAULT,main_keys + + resource dialogs,\ + IDD_POSITION,LANG_ENGLISH+SUBLANG_DEFAULT,position_dialog,\ + IDD_FIND,LANG_ENGLISH+SUBLANG_DEFAULT,find_dialog,\ + IDD_REPLACE,LANG_ENGLISH+SUBLANG_DEFAULT,replace_dialog,\ + IDD_COMPILE,LANG_ENGLISH+SUBLANG_DEFAULT,compile_dialog,\ + IDD_SUMMARY,LANG_ENGLISH+SUBLANG_DEFAULT,summary_dialog,\ + IDD_ERRORSUMMARY,LANG_ENGLISH+SUBLANG_DEFAULT,error_summary_dialog,\ + IDD_APPEARANCE,LANG_ENGLISH+SUBLANG_DEFAULT,appearance_dialog,\ + IDD_COMPILERSETUP,LANG_ENGLISH+SUBLANG_DEFAULT,compiler_setup_dialog,\ + IDD_CALCULATOR,LANG_ENGLISH+SUBLANG_DEFAULT,calculator_dialog,\ + IDD_ABOUT,LANG_ENGLISH+SUBLANG_DEFAULT,about_dialog + + resource group_icons,\ + IDI_MAIN,LANG_NEUTRAL,main_icon + + resource icons,\ + 1,LANG_NEUTRAL,main_icon_data + + resource bitmaps,\ + IDB_ASSIGN,LANG_NEUTRAL,assign_bitmap + + resource versions,\ + 1,LANG_NEUTRAL,version + + IDM_MAIN = 101 + IDM_TAB = 102 + IDA_MAIN = 201 + IDD_POSITION = 301 + IDD_FIND = 302 + IDD_REPLACE = 303 + IDD_COMPILE = 304 + IDD_SUMMARY = 305 + IDD_ERRORSUMMARY = 306 + IDD_APPEARANCE = 307 + IDD_COMPILERSETUP = 308 + IDD_ABOUT = 309 + IDD_CALCULATOR = 310 + IDI_MAIN = 401 + IDB_ASSIGN = 501 + + IDM_NEW = 1101 + IDM_OPEN = 1102 + IDM_SAVE = 1103 + IDM_SAVEAS = 1104 + IDM_NEXT = 1105 + IDM_PREVIOUS = 1106 + IDM_OPENFOLDER = 1107 + IDM_CLOSE = 1108 + IDM_EXIT = 1109 + IDM_SELECTFILE = 1110 + IDM_UNDO = 1201 + IDM_REDO = 1202 + IDM_CUT = 1203 + IDM_COPY = 1204 + IDM_PASTE = 1205 + IDM_DELETE = 1206 + IDM_SELECTALL = 1207 + IDM_VERTICAL = 1208 + IDM_DISCARD_UNDO = 1209 + IDM_READONLY = 1210 + IDM_POSITION = 1301 + IDM_FIND = 1302 + IDM_FINDNEXT = 1303 + IDM_REPLACE = 1304 + IDM_RUN = 1401 + IDM_COMPILE = 1402 + IDM_DEBUG = 1403 + IDM_SYMBOLS = 1404 + IDM_ASSIGN = 1409 + IDM_APPEARANCE = 1501 + IDM_COMPILERSETUP = 1502 + IDM_SECURESEL = 1505 + IDM_AUTOBRACKETS = 1506 + IDM_AUTOINDENT = 1507 + IDM_SMARTTABS = 1508 + IDM_OPTIMALFILL = 1509 + IDM_REVIVEDEADKEYS = 1510 + IDM_TIMESCROLL = 1511 + IDM_ONEINSTANCEONLY = 1512 + IDM_CONTENTS = 1901 + IDM_KEYWORD = 1902 + IDM_PICKHELP = 1903 + IDM_CALCULATOR = 1904 + IDM_ABOUT = 1909 + + ID_CHANGE = 2001 + ID_SELECT = 2101 + ID_CASESENSITIVE = 2102 + ID_WHOLEWORDS = 2103 + ID_BACKWARD = 2104 + ID_INWHOLETEXT = 2105 + ID_PROMPT = 2106 + ID_CONSOLECARET = 2107 + ID_ROW = 2201 + ID_COLUMN = 2202 + ID_DISPLAY = 2203 + ID_INSTRUCTION = 2204 + ID_EXPRESSION = 2205 + ID_DECRESULT = 2206 + ID_HEXRESULT = 2207 + ID_BINRESULT = 2208 + ID_OCTRESULT = 2209 + ID_TEXT = 2301 + ID_NEWTEXT = 2302 + ID_SETTING = 2303 + ID_MEMORY = 2304 + ID_PRIORITY = 2305 + ID_PASSES = 2306 + ID_LINES = 2307 + ID_INCLUDEPATH = 2308 + ID_ICON = 2401 + ID_MESSAGE = 2402 + ID_DECSELECT = 2501 + ID_HEXSELECT = 2502 + ID_BINSELECT = 2503 + ID_OCTSELECT = 2504 + ID_PROGRESS = 2801 + ID_PREVIEW = 2901 + + _ equ ,09h, + + menu main_menu + menuitem '&File',0,MFR_POPUP + menuitem '&New' _ 'Ctrl+N',IDM_NEW + menuitem '&Open...' _ 'Ctrl+O',IDM_OPEN + menuitem '&Save' _ 'Ctrl+S',IDM_SAVE + menuitem 'Save &as...',IDM_SAVEAS + menuseparator + menuitem 'E&xit' _ 'Alt+X',IDM_EXIT,MFR_END + menuitem '&Edit',0,MFR_POPUP + menuitem '&Undo' _ 'Ctrl+Z',IDM_UNDO + menuitem '&Redo' _ 'Ctrl+Shift+Z',IDM_REDO + menuseparator + menuitem 'Cu&t' _ 'Ctrl+X',IDM_CUT + menuitem '&Copy' _ 'Ctrl+C',IDM_COPY + menuitem '&Paste' _ 'Ctrl+V',IDM_PASTE + menuitem '&Delete',IDM_DELETE + menuseparator + menuitem 'Select &all' _ 'Ctrl+A',IDM_SELECTALL + menuseparator + menuitem '&Vertical selection' _ 'Alt+Ins',IDM_VERTICAL,MFR_END + menuitem '&Search',0,MFR_POPUP + menuitem '&Position...' _ 'Ctrl+G',IDM_POSITION + menuseparator + menuitem '&Find...' _ 'Ctrl+F',IDM_FIND + menuitem 'Find &next' _ 'F3',IDM_FINDNEXT + menuitem '&Replace...' _ 'Ctrl+H',IDM_REPLACE,MFR_END + menuitem '&Run',0,MFR_POPUP + menuitem '&Run' _ 'F9',IDM_RUN + menuitem '&Compile' _ 'Ctrl+F9',IDM_COMPILE + menuseparator + ;menuitem '&Debug' _ 'F8',IDM_DEBUG + menuitem 'Build &symbols' _ 'Ctrl+F8',IDM_SYMBOLS,MFR_END + menuitem '&Options',0,MFR_POPUP + menuitem '&Appearance...',IDM_APPEARANCE + menuitem '&Compiler setup...',IDM_COMPILERSETUP + menuseparator + menuitem '&Secure selection',IDM_SECURESEL + menuitem 'Automatic &brackets',IDM_AUTOBRACKETS + menuitem 'Automatic &indents',IDM_AUTOINDENT + menuitem 'Smart &tabulation',IDM_SMARTTABS + menuitem '&Optimal fill on saving',IDM_OPTIMALFILL + menuitem '&Revive dead keys',IDM_REVIVEDEADKEYS + menuitem 'Ti&me scrolling',IDM_TIMESCROLL + menuitem 'O&ne instance only',IDM_ONEINSTANCEONLY,MFR_END + menuitem '&Help',0,MFR_POPUP + MFR_END + menuitem '&Contents' _ 'Alt+F1',IDM_CONTENTS + menuitem '&Keyword search' _ 'F1',IDM_KEYWORD + menuseparator + menuitem '&Pick help file...',IDM_PICKHELP + menuseparator + menuitem 'Ca&lculator...' _ 'Ctrl+F6',IDM_CALCULATOR + menuseparator + menuitem '&About...',IDM_ABOUT,MFR_END + + menu popup_menu + menuitem '',0,MFR_POPUP+MFR_END + menuitem '&Assign to compiler' _ 'Shift+F9',IDM_ASSIGN + menuitem 'Open &folder',IDM_OPENFOLDER + menuitem '&Read-only mode' _ 'Shift+F6',IDM_READONLY + menuseparator + menuitem '&Close' _ 'Esc',IDM_CLOSE,MFR_END + + accelerator main_keys,\ + FVIRTKEY+FNOINVERT+FCONTROL,'N',IDM_NEW,\ + FVIRTKEY+FNOINVERT+FCONTROL,'O',IDM_OPEN,\ + FVIRTKEY+FNOINVERT+FCONTROL,'S',IDM_SAVE,\ + FVIRTKEY+FNOINVERT+FCONTROL,'Z',IDM_UNDO,\ + FVIRTKEY+FNOINVERT+FCONTROL+FSHIFT,'Z',IDM_REDO,\ + FVIRTKEY+FNOINVERT+FCONTROL,'X',IDM_CUT,\ + FVIRTKEY+FNOINVERT+FCONTROL,'C',IDM_COPY,\ + FVIRTKEY+FNOINVERT+FCONTROL,'V',IDM_PASTE,\ + FVIRTKEY+FNOINVERT+FCONTROL,'A',IDM_SELECTALL,\ + FVIRTKEY+FNOINVERT+FCONTROL,'G',IDM_POSITION,\ + FVIRTKEY+FNOINVERT+FCONTROL,'F',IDM_FIND,\ + FVIRTKEY+FNOINVERT+FCONTROL,'H',IDM_REPLACE,\ + FVIRTKEY+FNOINVERT+FCONTROL,VK_TAB,IDM_NEXT,\ + FVIRTKEY+FNOINVERT+FCONTROL+FSHIFT,VK_TAB,IDM_PREVIOUS,\ + FVIRTKEY+FNOINVERT,VK_F1,IDM_KEYWORD,\ + FVIRTKEY+FNOINVERT+FALT,VK_F1,IDM_CONTENTS,\ + FVIRTKEY+FNOINVERT,VK_F2,IDM_SAVE,\ + FVIRTKEY+FNOINVERT+FSHIFT,VK_F2,IDM_SAVEAS,\ + FVIRTKEY+FNOINVERT,VK_F4,IDM_OPEN,\ + FVIRTKEY+FNOINVERT,VK_F3,IDM_FINDNEXT,\ + FVIRTKEY+FNOINVERT,VK_F5,IDM_POSITION,\ + FVIRTKEY+FNOINVERT+FSHIFT,VK_F6,IDM_READONLY,\ + FVIRTKEY+FNOINVERT,VK_F7,IDM_FIND,\ + FVIRTKEY+FNOINVERT+FSHIFT,VK_F7,IDM_FINDNEXT,\ + FVIRTKEY+FNOINVERT+FCONTROL,VK_F7,IDM_REPLACE,\ + FVIRTKEY+FNOINVERT,VK_F9,IDM_RUN,\ + FVIRTKEY+FNOINVERT+FCONTROL,VK_F9,IDM_COMPILE,\ + FVIRTKEY+FNOINVERT,VK_F8,IDM_DEBUG,\ + FVIRTKEY+FNOINVERT+FCONTROL,VK_F8,IDM_SYMBOLS,\ + FVIRTKEY+FNOINVERT+FSHIFT,VK_F9,IDM_ASSIGN,\ + FVIRTKEY+FNOINVERT+FCONTROL,VK_F6,IDM_CALCULATOR,\ + FVIRTKEY+FNOINVERT,VK_ESCAPE,IDM_CLOSE,\ + FVIRTKEY+FNOINVERT+FALT,VK_DELETE,IDM_DISCARD_UNDO,\ + FVIRTKEY+FNOINVERT+FALT,'X',IDM_EXIT,\ + FVIRTKEY+FNOINVERT+FALT,'1',IDM_SELECTFILE+1,\ + FVIRTKEY+FNOINVERT+FALT,'2',IDM_SELECTFILE+2,\ + FVIRTKEY+FNOINVERT+FALT,'3',IDM_SELECTFILE+3,\ + FVIRTKEY+FNOINVERT+FALT,'4',IDM_SELECTFILE+4,\ + FVIRTKEY+FNOINVERT+FALT,'5',IDM_SELECTFILE+5,\ + FVIRTKEY+FNOINVERT+FALT,'6',IDM_SELECTFILE+6,\ + FVIRTKEY+FNOINVERT+FALT,'7',IDM_SELECTFILE+7,\ + FVIRTKEY+FNOINVERT+FALT,'8',IDM_SELECTFILE+8,\ + FVIRTKEY+FNOINVERT+FALT,'9',IDM_SELECTFILE+9 + + dialog position_dialog,'Position',40,40,126,54,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'STATIC','&Row:',-1,4,8,28,8,WS_VISIBLE+SS_RIGHT + dialogitem 'EDIT','',ID_ROW,36,6,34,12,WS_VISIBLE+WS_BORDER+WS_TABSTOP+ES_NUMBER + dialogitem 'STATIC','&Column:',-1,4,26,28,8,WS_VISIBLE+SS_RIGHT + dialogitem 'EDIT','',ID_COLUMN,36,24,34,12,WS_VISIBLE+WS_BORDER+WS_TABSTOP+ES_NUMBER + dialogitem 'BUTTON','&Select',ID_SELECT,36,42,48,8,WS_VISIBLE+WS_TABSTOP+BS_AUTOCHECKBOX + dialogitem 'BUTTON','OK',IDOK,78,6,42,14,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON + dialogitem 'BUTTON','C&ancel',IDCANCEL,78,22,42,14,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON + enddialog + + dialog find_dialog,'Find',60,60,254,54,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'STATIC','&Text to find:',-1,4,8,40,8,WS_VISIBLE+SS_RIGHT + dialogitem 'COMBOBOX','',ID_TEXT,48,6,150,64,WS_VISIBLE+WS_BORDER+WS_TABSTOP+CBS_DROPDOWN+CBS_AUTOHSCROLL+WS_VSCROLL + dialogitem 'BUTTON','&Case sensitive',ID_CASESENSITIVE,48,24,70,8,WS_VISIBLE+WS_TABSTOP+BS_AUTOCHECKBOX + dialogitem 'BUTTON','&Whole words',ID_WHOLEWORDS,48,38,70,8,WS_VISIBLE+WS_TABSTOP+BS_AUTOCHECKBOX + dialogitem 'BUTTON','&Backward',ID_BACKWARD,124,24,70,8,WS_VISIBLE+WS_TABSTOP+BS_AUTOCHECKBOX + dialogitem 'BUTTON','&In whole text',ID_INWHOLETEXT,124,38,70,8,WS_VISIBLE+WS_TABSTOP+BS_AUTOCHECKBOX + dialogitem 'BUTTON','&Find first',IDOK,206,6,42,14,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON + dialogitem 'BUTTON','C&ancel',IDCANCEL,206,22,42,14,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON + enddialog + + dialog replace_dialog,'Replace',60,60,254,86,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'STATIC','&Text to find:',-1,4,8,40,8,WS_VISIBLE+SS_RIGHT + dialogitem 'COMBOBOX','',ID_TEXT,48,6,150,64,WS_VISIBLE+WS_BORDER+WS_TABSTOP+CBS_DROPDOWN+CBS_AUTOHSCROLL+WS_VSCROLL + dialogitem 'STATIC','&New text:',-1,4,26,40,8,WS_VISIBLE+SS_RIGHT + dialogitem 'COMBOBOX','',ID_NEWTEXT,48,24,150,64,WS_VISIBLE+WS_BORDER+WS_TABSTOP+CBS_DROPDOWN+CBS_AUTOHSCROLL+WS_VSCROLL + dialogitem 'BUTTON','&Case sensitive',ID_CASESENSITIVE,48,42,70,8,WS_VISIBLE+WS_TABSTOP+BS_AUTOCHECKBOX + dialogitem 'BUTTON','&Whole words',ID_WHOLEWORDS,48,56,70,8,WS_VISIBLE+WS_TABSTOP+BS_AUTOCHECKBOX + dialogitem 'BUTTON','&Backward',ID_BACKWARD,124,42,70,8,WS_VISIBLE+WS_TABSTOP+BS_AUTOCHECKBOX + dialogitem 'BUTTON','&In whole text',ID_INWHOLETEXT,124,56,70,8,WS_VISIBLE+WS_TABSTOP+BS_AUTOCHECKBOX + dialogitem 'BUTTON','&Prompt on replace',ID_PROMPT,48,70,70,8,WS_VISIBLE+WS_TABSTOP+BS_AUTOCHECKBOX + dialogitem 'BUTTON','&Replace',IDOK,206,6,42,14,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON + dialogitem 'BUTTON','C&ancel',IDCANCEL,206,22,42,14,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON + enddialog + + dialog compile_dialog,'Compile',64,64,192,42,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'msctls_progress32','',ID_PROGRESS,8,6,176,12,WS_VISIBLE + dialogitem 'BUTTON','C&ancel',IDCANCEL,75,24,42,14,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON + enddialog + + dialog summary_dialog,'Compile',48,24,192,130,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'BUTTON','OK',IDCANCEL,142,108,42,14,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON + dialogitem 'STATIC',IDI_ASTERISK,ID_ICON,8,4,0,0,WS_VISIBLE+SS_ICON + dialogitem 'STATIC','',ID_MESSAGE,36,10,148,8,WS_VISIBLE + dialogitem 'STATIC','&Display:',-1,8,28,176,8,WS_VISIBLE + dialogitem 'EDIT','',ID_DISPLAY,8,40,176,64,WS_VISIBLE+WS_BORDER+WS_TABSTOP+ES_MULTILINE+ES_READONLY+ES_AUTOHSCROLL+ES_AUTOVSCROLL+WS_VSCROLL + enddialog + + dialog error_summary_dialog,'Compile',48,24,192,144,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'STATIC','&Source:',-1,8,96,176,8,WS_VISIBLE + dialogitem 'LISTBOX','',ID_LINES,8,108,126,32,WS_VISIBLE+WS_BORDER+WS_TABSTOP+WS_VSCROLL+LBS_NOTIFY + dialogitem 'BUTTON','OK',IDCANCEL,142,108,42,14,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON + dialogitem 'STATIC',IDI_HAND,ID_ICON,8,4,0,0,WS_VISIBLE+SS_ICON + dialogitem 'STATIC','',ID_MESSAGE,36,10,148,8,WS_VISIBLE+SS_LEFTNOWORDWRAP + dialogitem 'STATIC','&Display:',-1,8,28,176,8,WS_VISIBLE + dialogitem 'EDIT','',ID_DISPLAY,8,40,176,24,WS_VISIBLE+WS_BORDER+WS_TABSTOP+ES_MULTILINE+ES_READONLY+ES_AUTOHSCROLL+ES_AUTOVSCROLL+WS_VSCROLL + dialogitem 'STATIC','&Instruction:',-1,8,68,176,8,WS_VISIBLE + dialogitem 'EDIT','',ID_INSTRUCTION,8,80,176,12,WS_VISIBLE+WS_BORDER+WS_TABSTOP+ES_READONLY+ES_AUTOHSCROLL + enddialog + + dialog appearance_dialog,'Appearance',50,20,186,166,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'COMBOBOX','',ID_SETTING,8,6,120,140,WS_VISIBLE+WS_TABSTOP+CBS_DROPDOWNLIST+WS_VSCROLL + dialogitem 'BUTTON','C&hange...',ID_CHANGE,134,6,42,13,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON + dialogitem 'FEDIT','',ID_PREVIEW,8,24,168,120,WS_VISIBLE+WS_BORDER+WS_DISABLED+ES_NOHIDESEL + dialogitem 'BUTTON','&Console caret',ID_CONSOLECARET,8,151,80,8,WS_VISIBLE+WS_TABSTOP+BS_AUTOCHECKBOX + dialogitem 'BUTTON','OK',IDOK,88,148,42,14,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON + dialogitem 'BUTTON','C&ancel',IDCANCEL,134,148,42,14,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON + enddialog + + dialog compiler_setup_dialog,'Compiler setup',54,28,200,82,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'STATIC','&Include path(s):',-1,8,4,184,8,WS_VISIBLE+SS_LEFT + dialogitem 'COMBOBOX','',ID_INCLUDEPATH,8,14,184,48,WS_VISIBLE+WS_BORDER+WS_TABSTOP+CBS_DROPDOWN+WS_VSCROLL+CBS_AUTOHSCROLL + dialogitem 'STATIC','&Memory (KB):',-1,8,30,42,8,WS_VISIBLE+SS_LEFT + dialogitem 'COMBOBOX','',ID_MEMORY,8,40,54,96,WS_VISIBLE+WS_BORDER+WS_TABSTOP+ES_NUMBER+CBS_DROPDOWN+WS_VSCROLL + dialogitem 'STATIC','&Passes limit:',-1,72,30,60,8,WS_VISIBLE+SS_LEFT + dialogitem 'EDIT','',ID_PASSES,72,40,54,12,WS_VISIBLE+WS_BORDER+WS_TABSTOP+ES_NUMBER + dialogitem 'STATIC','&Thread priority:',-1,136,30,60,8,WS_VISIBLE+SS_LEFT + dialogitem 'COMBOBOX','',ID_PRIORITY,136,40,56,96,WS_VISIBLE+WS_TABSTOP+CBS_DROPDOWNLIST+WS_VSCROLL + dialogitem 'BUTTON','OK',IDOK,104,64,42,14,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON + dialogitem 'BUTTON','C&ancel',IDCANCEL,150,64,42,14,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON + enddialog + + dialog calculator_dialog,'Calculator',48,32,380,80,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'STATIC','&Expression:',-1,4,8,44,8,WS_VISIBLE+SS_RIGHT + dialogitem 'EDIT','',ID_EXPRESSION,52,6,274,12,WS_VISIBLE+WS_BORDER+WS_TABSTOP+ES_AUTOHSCROLL + dialogitem 'BUTTON','&Decimal:',ID_DECSELECT,4,20,56,12,WS_VISIBLE+WS_TABSTOP+BS_AUTORADIOBUTTON+BS_RIGHT+BS_LEFTTEXT + dialogitem 'EDIT','',ID_DECRESULT,62,22,264,10,WS_VISIBLE+ES_READONLY+ES_AUTOHSCROLL + dialogitem 'BUTTON','&Hexadecimal:',ID_HEXSELECT,4,34,56,12,WS_VISIBLE+WS_TABSTOP+BS_AUTORADIOBUTTON+BS_RIGHT+BS_LEFTTEXT + dialogitem 'EDIT','',ID_HEXRESULT,62,36,264,10,WS_VISIBLE+ES_READONLY+ES_AUTOHSCROLL + dialogitem 'BUTTON','&Binary:',ID_BINSELECT,4,48,56,12,WS_VISIBLE+WS_TABSTOP+BS_AUTORADIOBUTTON+BS_RIGHT+BS_LEFTTEXT + dialogitem 'EDIT','',ID_BINRESULT,62,50,264,10,WS_VISIBLE+ES_READONLY+ES_AUTOHSCROLL + dialogitem 'BUTTON','&Octal:',ID_OCTSELECT,4,62,56,12,WS_VISIBLE+WS_TABSTOP+BS_AUTORADIOBUTTON+BS_RIGHT+BS_LEFTTEXT + dialogitem 'EDIT','',ID_OCTRESULT,62,64,264,10,WS_VISIBLE+ES_READONLY+ES_AUTOHSCROLL + dialogitem 'BUTTON','E&valuate',IDOK,332,6,42,14,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON + dialogitem 'BUTTON','&Close',IDCANCEL,332,22,42,14,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON + enddialog + + dialog about_dialog,'About',40,40,172,60,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'STATIC',<'flat assembler IDE for Windows',0Dh,0Ah,'Copyright ',0A9h,' 1999-2024 Tomasz Grysztar.'>,-1,27,10,144,40,WS_VISIBLE+SS_CENTER + dialogitem 'STATIC',IDI_MAIN,-1,8,8,32,32,WS_VISIBLE+SS_ICON + dialogitem 'STATIC','',-1,4,34,164,11,WS_VISIBLE+SS_ETCHEDHORZ + dialogitem 'STATIC',<'flat assembler version ',VERSION_STRING>,-1,4,38,100,20,WS_VISIBLE+SS_LEFT + dialogitem 'STATIC',<'flat editor version ',FEDIT_VERSION_STRING>,-1,4,48,100,20,WS_VISIBLE+SS_LEFT + dialogitem 'BUTTON','OK',IDOK,124,40,42,14,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON + enddialog + + icon main_icon,main_icon_data,'resource\fasmw.ico' + + bitmap assign_bitmap,'resource\assign.bmp' + + versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,\ + 'FileDescription','flat assembler',\ + 'LegalCopyright',<'Copyright ',0A9h,' 1999-2024 Tomasz Grysztar.'>,\ + 'FileVersion','1',\ + 'ProductVersion',VERSION_STRING,\ + 'OriginalFilename','FASMW.EXE' diff --git a/toolchain/fasmw17332/SOURCE/IDE/FASMW/FEDIT.ASH b/toolchain/fasmw17332/SOURCE/IDE/FASMW/FEDIT.ASH new file mode 100644 index 0000000..9d4e330 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/IDE/FASMW/FEDIT.ASH @@ -0,0 +1,69 @@ + +; flat editor mode flags + +FEMODE_OVERWRITE = 1 +FEMODE_VERTICALSEL = 2 +FEMODE_NOUNDO = 4 +FEMODE_READONLY = 8 + +; flat editor search flags + +FEFIND_CASESENSITIVE = 1 +FEFIND_WHOLEWORDS = 2 +FEFIND_BACKWARD = 4 +FEFIND_INWHOLETEXT = 8 + +; flat editor styles + +FES_AUTOINDENT = 0001h +FES_AUTOBRACKETS = 0002h +FES_SMARTTABS = 0004h +FES_SECURESEL = 0008h +FES_OPTIMALFILL = 0010h +FES_CONSOLECARET = 0020h +FES_REVIVEDEADKEYS = 0040h +FES_TIMESCROLL = 0080h + +; flat editor messages + +FEM_SETMODE = WM_USER + 0 +FEM_GETMODE = WM_USER + 1 +FEM_SETPOS = WM_USER + 2 +FEM_GETPOS = WM_USER + 3 +FEM_SETSYNTAXHIGHLIGHT = WM_USER + 4 +FEM_SETRIGHTCLICKMENU = WM_USER + 5 +FEM_SETTEXTCOLOR = WM_USER + 6 +FEM_SETSELCOLOR = WM_USER + 7 +FEM_FINDFIRST = WM_USER + 8 +FEM_FINDNEXT = WM_USER + 9 +FEM_CANFINDNEXT = WM_USER + 10 +FEM_GETLINELENGTH = WM_USER + 11 +FEM_GETLINE = WM_USER + 12 +FEM_GETWORDATCARET = WM_USER + 13 +FEM_BEGINOPERATION = WM_USER + 14 +FEM_ENDOPERATION = WM_USER + 15 +FEM_MARKUNMODIFIED = WM_USER + 16 +FEM_ISUNMODIFIED = WM_USER + 17 +FEM_GETSEARCHTEXT = WM_USER + 18 +FEM_GETSEARCHFLAGS = WM_USER + 19 +FEM_RELEASESEARCH = WM_USER + 20 +FEM_REDO = WM_USER + 84 +FEM_CANREDO = WM_USER + 85 + +; flat editor notifications + +FEN_SETFOCUS = 01h +FEN_KILLFOCUS = 02h +FEN_TEXTCHANGE = 03h +FEN_POSCHANGE = 04h +FEN_MODECHANGE = 05h +FEN_OUTOFMEMORY = 0Fh + +; flat editor position structure + +struct FEPOS + selectionPosition dd ? + selectionLine dd ? + caretPosition dd ? + caretLine dd ? +ends diff --git a/toolchain/fasmw17332/SOURCE/IDE/FASMW/FEDIT.INC b/toolchain/fasmw17332/SOURCE/IDE/FASMW/FEDIT.INC new file mode 100644 index 0000000..eea95ef --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/IDE/FASMW/FEDIT.INC @@ -0,0 +1,2279 @@ + +; flat editor interface for Win32 IDE +; Copyright (c) 2001-2014, Tomasz Grysztar. +; All rights reserved. + +SEGMENT_LENGTH = 100h +BLOCK_LENGTH = 400h * SEGMENT_LENGTH +SEGMENT_HEADER_LENGTH = 16 +SEGMENT_DATA_LENGTH = SEGMENT_LENGTH - SEGMENT_HEADER_LENGTH + +include '../version.inc' + +WM_MOUSEHWHEEL = 0x0000020E + +proc FlatEditor hwnd,wmsg,wparam,lparam + + locals + + editor_style dd ? + + label editor_data + + include '../variable.inc' + + editor_font dd ? + font_width dd ? + font_height dd ? + font_overhang dd ? + screen_base dd ? + screen_offset dd ? + screen_width dd ? + screen_height dd ? + screen_size dd ? + line_buffer dd ? + line_buffer_size dd ? + background_color dd ? + text_color dd ? + selection_background dd ? + selection_text dd ? + syntax_proc dd ? + syntax_colors dd ? + caret_x dd ? + caret_y dd ? + pan_x dw ? + pan_y dw ? + menu_handle dd ? + menu_window dd ? + current_operation db ? + last_operation db ? + was_selection db ? + mouse_select db ? + focus db ? + macro_operation db ? + + editor_data_size = $ - editor_data + + if editor_data_size > SEGMENT_DATA_LENGTH + err + end if + + return_value dd ? + background_brush dd ? + selection_brush dd ? + line_number dd ? + ps PAINTSTRUCT + tm TEXTMETRIC + sc SCROLLINFO + gestureconfig GESTURECONFIG + gestureinfo GESTUREINFO + point POINT + rect RECT + size SIZE + char dd ? + kbstate rb 100h + line_selection db ? + clipboard_opened db ? + redraw_now db ? + notification db ? + + endl + + push ebx esi edi + invoke GetWindowLong,[hwnd],GWL_STYLE + mov [editor_style],eax + cmp [wmsg],WM_CREATE + je wm_create + cmp [wmsg],WM_GETDLGCODE + je wm_getdlgcode + invoke GetWindowLong,[hwnd],0 + or eax,eax + jz defwndproc + mov [editor_memory],eax + lea esi,[eax+SEGMENT_HEADER_LENGTH] + lea edi,[editor_data] + mov ecx,editor_data_size + rep movsb + test [editor_style],ES_READONLY + jz editor_mode_ok + or [editor_mode],FEMODE_READONLY + editor_mode_ok: + mov [return_value],0 + mov [notification],0 + mov [redraw_now],0 + mov [clipboard_opened],0 + cmp [wmsg],WM_DESTROY + je wm_destroy + cmp [wmsg],WM_PAINT + je wm_paint + cmp [wmsg],WM_HSCROLL + je wm_hscroll + cmp [wmsg],WM_VSCROLL + je wm_vscroll + cmp [wmsg],WM_GESTURE + je wm_gesture + cmp [wmsg],WM_SIZE + je wm_size + mov eax,[selection_line] + or eax,eax + jz no_selection + cmp eax,[caret_line] + jne selection_present + mov eax,[selection_position] + cmp eax,[caret_position] + je no_selection + selection_present: + mov [was_selection],1 + jmp selection_status_ok + no_selection: + mov [was_selection],0 + selection_status_ok: + xor al,al + xchg [current_operation],al + mov [last_operation],al + mov eax,[wmsg] + cmp eax,WM_SETFOCUS + je wm_setfocus + cmp eax,WM_KILLFOCUS + je wm_killfocus + cmp eax,WM_KEYDOWN + je wm_keydown + cmp eax,WM_SYSKEYDOWN + je wm_syskeydown + cmp eax,WM_CHAR + je wm_char + cmp eax,WM_LBUTTONDOWN + je wm_lbuttondown + cmp eax,WM_LBUTTONUP + je wm_lbuttonup + cmp eax,WM_MOUSEMOVE + je wm_mousemove + cmp eax,WM_LBUTTONDBLCLK + je wm_lbuttondblclk + cmp eax,WM_MOUSEWHEEL + je wm_mousewheel + cmp eax,WM_MOUSEHWHEEL + je wm_mousehwheel + cmp eax,WM_RBUTTONDOWN + je wm_rbuttondown + cmp eax,WM_COPY + je wm_copy + cmp eax,WM_CUT + je wm_cut + cmp eax,WM_PASTE + je wm_paste + cmp eax,WM_CLEAR + je wm_clear + cmp eax,WM_SETTEXT + je wm_settext + cmp eax,WM_GETTEXTLENGTH + je wm_gettextlength + cmp eax,WM_GETTEXT + je wm_gettext + cmp eax,WM_SETFONT + je wm_setfont + cmp eax,WM_GETFONT + je wm_getfont + cmp eax,WM_UNDO + je wm_undo + cmp eax,EM_UNDO + je wm_undo + cmp eax,EM_CANUNDO + je em_canundo + cmp eax,FEM_REDO + je fem_redo + cmp eax,FEM_CANREDO + je fem_canredo + cmp eax,EM_EMPTYUNDOBUFFER + je em_emptyundobuffer + cmp eax,EM_REPLACESEL + je em_replacesel + cmp eax,FEM_SETMODE + je fem_setmode + cmp eax,FEM_GETMODE + je fem_getmode + cmp eax,FEM_SETSYNTAXHIGHLIGHT + je fem_setsyntaxhighlight + cmp eax,FEM_SETRIGHTCLICKMENU + je fem_setrightclickmenu + cmp eax,FEM_GETLINELENGTH + je fem_getlinelength + cmp eax,FEM_GETLINE + je fem_getline + cmp eax,FEM_SETPOS + je fem_setpos + cmp eax,FEM_GETPOS + je fem_getpos + cmp eax,FEM_FINDFIRST + je fem_findfirst + cmp eax,FEM_FINDNEXT + je fem_findnext + cmp eax,FEM_CANFINDNEXT + je fem_canfindnext + cmp eax,FEM_GETWORDATCARET + je fem_getwordatcaret + cmp eax,FEM_SETTEXTCOLOR + je fem_settextcolor + cmp eax,FEM_SETSELCOLOR + je fem_setselcolor + cmp eax,FEM_BEGINOPERATION + je fem_beginoperation + cmp eax,FEM_ENDOPERATION + je fem_endoperation + cmp eax,FEM_MARKUNMODIFIED + je fem_setunmodified + cmp eax,FEM_ISUNMODIFIED + je fem_isunmodified + cmp eax,FEM_GETSEARCHTEXT + je fem_getsearchtext + cmp eax,FEM_GETSEARCHFLAGS + je fem_getsearchflags + cmp eax,FEM_RELEASESEARCH + je fem_releasesearch +defwndproc: + invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] + jmp finish_wndproc +wm_create: + call init_editor_memory + jc create_failed + invoke SetWindowLong,[hwnd],0,[editor_memory] + mov [syntax_proc],SyntaxProc + mov [syntax_colors],0 + mov [macro_operation],0 + mov [current_operation],0 + mov [focus],0 + mov [mouse_select],0 + mov [menu_handle],0 + mov eax,SEGMENT_DATA_LENGTH*2 + mov [line_buffer_size],eax + invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE + or eax,eax + jz create_failed + mov [line_buffer],eax + mov [screen_base],0 + invoke GetSysColor,COLOR_WINDOW + mov [background_color],eax + invoke GetSysColor,COLOR_WINDOWTEXT + mov [text_color],eax + invoke GetSysColor,COLOR_HIGHLIGHT + mov [selection_background],eax + invoke GetSysColor,COLOR_HIGHLIGHTTEXT + mov [selection_text],eax + mov eax,[fedit_font] + mov [editor_font],eax + invoke GetDC,[hwnd] + mov ebx,eax + invoke SelectObject,ebx,[editor_font] + lea edi,[char] + mov byte [edi],20h + lea eax,[size] + invoke GetTextExtentPoint32,ebx,edi,1,eax + lea eax,[tm] + invoke GetTextMetrics,ebx,eax + mov eax,[size.cy] + mov [font_height],eax + mov eax,[size.cx] + mov [font_width],eax + mov ecx,[tm.tmMaxCharWidth] + sub ecx,eax + mov [font_overhang],ecx + invoke ReleaseDC,[hwnd],ebx + mov [return_value],0 + cmp [SetGestureConfig],0 + je done + mov [gestureconfig.dwID],GID_PAN + mov [gestureconfig.dwWant],GC_PAN+GC_PAN_WITH_SINGLE_FINGER_VERTICALLY+GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY+GC_PAN_WITH_INERTIA + mov [gestureconfig.dwBlock],0 + lea edx,[gestureconfig] + invoke SetGestureConfig,[hwnd],0,1,edx,sizeof.GESTURECONFIG + jmp done + create_failed: + or eax,-1 + jmp finish_wndproc +wm_destroy: + invoke VirtualFree,[line_buffer],0,MEM_RELEASE + invoke VirtualFree,[screen_base],0,MEM_RELEASE + call release_search_data + call release_editor_memory + invoke SetWindowLong,[hwnd],0,0 + xor eax,eax + jmp finish_wndproc +wm_getdlgcode: + mov eax,DLGC_WANTCHARS+DLGC_WANTARROWS + jmp finish_wndproc +wm_paint: + lea eax,[rect] + invoke GetUpdateRect,[hwnd],eax,FALSE + or eax,eax + jz finish_wndproc + cmp [screen_base],0 + je finish_wndproc + lea eax,[ps] + invoke BeginPaint,[hwnd],eax + mov ebx,eax + invoke CreateSolidBrush,[background_color] + mov [background_brush],eax + invoke CreateSolidBrush,[selection_background] + mov [selection_brush],eax + invoke SelectObject,ebx,[editor_font] + mov esi,[screen_base] + add esi,[screen_offset] + mov eax,[screen_width] + mul [screen_height] + lea edi,[esi+eax] + mov [rect.top],0 + mov eax,[font_height] + mov [rect.bottom],eax + mov ecx,[screen_height] + paint_screen: + push ecx + mov [rect.left],0 + mov ecx,[screen_width] + paint_line: + cmp byte [esi],0 + je paint_empty_block + mov edx,1 + mov al,[edi] + get_characters_block: + cmp edx,ecx + je get_color + cmp al,[edi+edx] + jne get_color + cmp byte [esi+edx],0 + je get_color + inc edx + jmp get_characters_block + paint_empty_block: + mov edx,1 + test byte [edi],80h + jnz get_empty_selection + get_empty_block: + cmp edx,ecx + je fill_empty_block + cmp byte [esi+edx],0 + jne fill_empty_block + test byte [edi+edx],80h + jnz fill_empty_block + inc edx + jmp get_empty_block + fill_empty_block: + push ecx edx + mov eax,[font_width] + mul edx + add eax,[rect.left] + mov [rect.right],eax + lea eax,[rect] + invoke FillRect,ebx,eax,[background_brush] + jmp paint_next_block + get_empty_selection: + cmp edx,ecx + je fill_empty_selection + cmp byte [esi+edx],0 + jne fill_empty_selection + test byte [edi+edx],80h + jz fill_empty_selection + inc edx + jmp get_empty_selection + fill_empty_selection: + push ecx edx + mov eax,[font_width] + mul edx + add eax,[rect.left] + mov [rect.right],eax + lea eax,[rect] + invoke FillRect,ebx,eax,[selection_brush] + jmp paint_next_block + get_color: + push ecx edx + test byte [edi],80h + jnz highlight_color + invoke SetBkColor,ebx,[background_color] + mov al,[edi] + or al,al + jnz syntax_color + default_color: + invoke SetTextColor,ebx,[text_color] + jmp color_ok + syntax_color: + movzx eax,al + mov edx,[syntax_colors] + or edx,edx + jz default_color + mov eax,[edx+(eax-1)*4] + invoke SetTextColor,ebx,eax + jmp color_ok + highlight_color: + invoke SetBkColor,ebx,[selection_background] + invoke SetTextColor,ebx,[selection_text] + color_ok: + mov ecx,[esp] + mov eax,[font_width] + mul ecx + add eax,[rect.left] + mov [rect.right],eax + lea eax,[rect] + invoke DrawText,ebx,esi,ecx,eax,DT_LEFT+DT_NOPREFIX+DT_SINGLELINE + paint_next_block: + pop edx ecx + sub ecx,edx + add esi,edx + add edi,edx + mov eax,[rect.right] + mov [rect.left],eax + or ecx,ecx + jnz paint_line + mov eax,[font_height] + add [rect.top],eax + add [rect.bottom],eax + pop ecx + dec ecx + jnz paint_screen + invoke DeleteObject,[background_brush] + invoke DeleteObject,[selection_brush] + lea eax,[ps] + invoke EndPaint,[hwnd],eax + xor eax,eax + jmp finish_wndproc +wm_setfocus: + or [focus],-1 + call create_caret + mov [notification],FEN_SETFOCUS + cmp [was_selection],0 + je done + jmp moved_window +wm_killfocus: + mov [focus],0 + invoke DestroyCaret + mov [notification],FEN_KILLFOCUS + cmp [was_selection],0 + je done + jmp moved_window +wm_hscroll: + mov [sc.cbSize],sizeof.SCROLLINFO + mov [sc.fMask],SIF_ALL + lea eax,[sc] + invoke GetScrollInfo,[hwnd],SB_HORZ,eax + movzx eax,word [wparam] + cmp eax,SB_LINEUP + je hscroll_left + cmp eax,SB_LINEDOWN + je hscroll_right + cmp eax,SB_THUMBTRACK + je hscroll_pos + cmp eax,SB_PAGEUP + je hscroll_wleft + cmp eax,SB_PAGEDOWN + je hscroll_wright + hscroll_ignore: + jmp done + hscroll_left: + cmp [window_position],0 + je hscroll_ignore + dec [window_position] + jmp moved_window + hscroll_right: + mov eax,[maximum_position] + sub eax,[sc.nPage] + cmp [window_position],eax + jge hscroll_ignore + inc [window_position] + jmp moved_window + hscroll_pos: + movzx eax,word [wparam+2] + mov [window_position],eax + jmp moved_window + hscroll_wleft: + mov eax,[sc.nPage] + sub [window_position],eax + jnc moved_window + mov [window_position],0 + jmp moved_window + hscroll_wright: + mov eax,[sc.nPage] + mov ecx,[maximum_position] + sub ecx,eax + add [window_position],eax + cmp [window_position],ecx + jbe moved_window + mov [window_position],ecx + jmp moved_window +wm_vscroll: + mov [sc.cbSize],sizeof.SCROLLINFO + mov [sc.fMask],SIF_ALL + lea eax,[sc] + invoke GetScrollInfo,[hwnd],SB_VERT,eax + movzx eax,word [wparam] + cmp eax,SB_LINEUP + je vscroll_up + cmp eax,SB_LINEDOWN + je vscroll_down + cmp eax,SB_THUMBTRACK + je vscroll_pos + cmp eax,SB_PAGEUP + je vscroll_pageup + cmp eax,SB_PAGEDOWN + je vscroll_pagedown + vscroll_ignore: + jmp done + vscroll_up: + mov esi,[window_line] + mov esi,[esi+4] + or esi,esi + jz vscroll_ignore + dec [window_line_number] + mov [window_line],esi + jmp moved_window + vscroll_down: + mov eax,[sc.nPos] + add eax,[sc.nPage] + cmp eax,[sc.nMax] + ja vscroll_ignore + mov esi,[window_line] + vscroll_skip_line: + mov esi,[esi] + btr esi,0 + jc vscroll_skip_line + or esi,esi + jz vscroll_ignore + inc [window_line_number] + mov [window_line],esi + jmp moved_window + vscroll_pos: + mov eax,[sc.nTrackPos] + call find_line + or esi,esi + jz vscroll_ignore + mov [window_line],esi + mov [window_line_number],ecx + jmp moved_window + vscroll_pageup: + mov esi,[window_line] + mov ecx,[sc.nPage] + scrolling_up: + mov eax,[esi+4] + or eax,eax + jz scroll_ok + dec [window_line_number] + mov esi,eax + loop scrolling_up + jmp scroll_ok + vscroll_pagedown: + mov esi,[window_line] + mov eax,[sc.nPos] + add eax,[sc.nPage] + mov ecx,[sc.nMax] + sub ecx,eax + inc ecx + cmp ecx,[sc.nPage] + jbe scrolling_down + mov ecx,[sc.nPage] + scrolling_down: + mov eax,esi + scroll_one_line: + mov eax,[eax] + test eax,eax + jz scroll_ok + btr eax,0 + jc scroll_one_line + or eax,eax + jz scroll_ok + inc [window_line_number] + mov esi,eax + loop scrolling_down + scroll_ok: + mov [window_line],esi + jmp moved_window +wm_gesture: + cmp [GetGestureInfo],0 + je defwndproc + mov [gestureinfo.cbSize],sizeof.GESTUREINFO + lea edx,[gestureinfo] + invoke GetGestureInfo,[lparam],edx + test eax,eax + jz defwndproc + cmp [gestureinfo.dwID],GID_PAN + jne defwndproc + invoke CloseGestureInfoHandle,[lparam] + mov eax,[gestureinfo.dwFlags] + test eax,GF_BEGIN + jnz begin_panning + mov ax,[gestureinfo.ptsLocation.x] + sub ax,[pan_x] + cwde + cdq + idiv [font_width] + sub [gestureinfo.ptsLocation.x],dx + sub [window_position],eax + cmp [window_position],0 + jl horizontal_home + jmp horizontal_pan_ok + horizontal_home: + mov [window_position],0 + horizontal_pan_ok: + mov ax,[gestureinfo.ptsLocation.y] + sub ax,[pan_y] + cwde + cdq + idiv [font_height] + sub [gestureinfo.ptsLocation.y],dx + mov ecx,eax + mov eax,dword [gestureinfo.ptsLocation] + mov dword [pan_x],eax + mov esi,[window_line] + cmp ecx,0 + jz moved_window + jg scrolling_up + neg ecx + jmp scrolling_down + begin_panning: + mov eax,dword [gestureinfo.ptsLocation] + mov dword [pan_x],eax + jmp done +wm_mousewheel: + test [editor_style],FES_TIMESCROLL + jz space_scroll + lea ebx,[kbstate] + invoke GetKeyboardState,ebx + test [kbstate+VK_MENU],80h + jz space_scroll + test [kbstate+VK_CONTROL],80h + jnz time_scroll + space_scroll: + mov esi,[window_line] + mov ecx,[wheel_scroll_lines] + cmp ecx,-1 + jne calculate_scroll + mov [sc.cbSize],sizeof.SCROLLINFO + mov [sc.fMask],SIF_PAGE + push eax + lea eax,[sc] + invoke GetScrollInfo,[hwnd],SB_VERT,eax + pop eax + mov ecx,[sc.nPage] + calculate_scroll: + mov eax,[wparam] + sar eax,16 + imul ecx + mov ecx,120 + idiv ecx + mov ecx,eax + cmp ecx,0 + jg scrolling_up + neg ecx + jnz scrolling_down + jmp done + time_scroll: + test [editor_mode],FEMODE_READONLY + jnz ignore + test [editor_mode],FEMODE_NOUNDO + jnz enable_undo + move_through_time: + cmp word [wparam+2],0 + jge backward_in_time + neg word [wparam+2] + jmp forward_in_time + backward_in_time: + sub word [wparam+2],120 + jc time_scroll_done + mov eax,[undo_data] + test eax,eax + jz time_scroll_done + call undo_changes + jmp backward_in_time + forward_in_time: + sub word [wparam+2],120 + jc time_scroll_done + mov eax,[redo_data] + test eax,eax + jz time_scroll_done + call redo_changes + jmp forward_in_time + time_scroll_done: + call create_caret + mov [last_operation],0 + jmp text_changed +wm_mousehwheel: + lea eax,[sc] + invoke GetScrollInfo,[hwnd],SB_HORZ,eax + mov esi,[window_line] + cmp [wparam],0 + jl hscroll_left + jg hscroll_right + jmp done +wm_size: + call update_positions + mov eax,[screen_width] + mul [screen_height] + mov [screen_size],eax + mov [screen_offset],0 + shl eax,2 + or eax,eax + jz screen_allocated + mov ebx,eax + mov eax,[screen_base] + or eax,eax + jz screen_released + invoke VirtualFree,eax,0,MEM_RELEASE + screen_released: + invoke VirtualAlloc,0,ebx,MEM_COMMIT,PAGE_READWRITE + screen_allocated: + mov [screen_base],eax + call update_screen + lea ebx,[rect] + invoke GetClientRect,[hwnd],ebx + invoke InvalidateRect,[hwnd],ebx,FALSE + jmp done +wm_keydown: + lea ebx,[kbstate] + invoke GetKeyboardState,ebx + cmp [was_selection],0 + jne process_key + mov eax,[caret_line] + mov [selection_line],eax + mov eax,[caret_position] + mov [selection_position],eax + mov eax,[caret_line_number] + mov [selection_line_number],eax + process_key: + mov eax,[wparam] + cmp eax,VK_LEFT + je left_key + cmp eax,VK_RIGHT + je right_key + cmp eax,VK_UP + je up_key + cmp eax,VK_DOWN + je down_key + cmp eax,VK_BACK + je backspace_key + cmp eax,VK_HOME + je home_key + cmp eax,VK_END + je end_key + cmp eax,VK_PGUP + je pgup_key + cmp eax,VK_PGDN + je pgdn_key + cmp eax,VK_APPS + je menu_key + cmp eax,VK_INSERT + je ins_key + cmp eax,VK_DELETE + je del_key + cmp eax,VK_F6 + je f6_key + test [kbstate+VK_CONTROL],80h + jz convert_to_ascii + cmp eax,'Y' + je ctrl_y_key + convert_to_ascii: + mov ax,word [lparam+2] + and eax,7Fh + lea ebx,[kbstate] + lea edx,[char] + invoke ToAscii,[wparam],eax,ebx,edx,FALSE + cmp eax,2 + je two_characters + or eax,eax + jz ignore + jg process_character + test [editor_style],FES_REVIVEDEADKEYS + je ignore + lea edx,[char] + invoke ToAscii,VK_SPACE,0,ebx,edx,FALSE + jmp process_character + two_characters: + movzx eax,byte [char+1] + invoke PostMessage,[hwnd],WM_CHAR,eax,1 shl 31 + process_character: + mov al,byte [char] + cmp al,20h + jae character + cmp al,0Dh + je character + cmp al,9 + je character + jmp ignore + left_key: + test [kbstate+VK_MENU],80h + jnz scroll_left + test [kbstate+VK_CONTROL],80h + jnz word_left + cmp [caret_position],0 + jle moved_caret + dec [caret_position] + jmp moved_caret + right_key: + test [kbstate+VK_MENU],80h + jnz scroll_right + test [kbstate+VK_CONTROL],80h + jnz word_right + mov eax,[caret_position] + cmp eax,[maximum_position] + jae moved_caret + inc [caret_position] + jmp moved_caret + up_key: + test [kbstate+VK_MENU],80h + jnz scroll_up + call move_line_up + jmp moved_caret + down_key: + test [kbstate+VK_MENU],80h + jnz scroll_down + call move_line_down + jmp moved_caret + home_key: + test [kbstate+VK_CONTROL],80h + jnz screen_home + mov [caret_position],0 + jmp moved_caret + end_key: + test [kbstate+VK_CONTROL],80h + jnz screen_end + call move_to_line_end + jmp moved_caret + screen_home: + mov eax,[window_line] + mov [caret_line],eax + mov eax,[window_line_number] + mov [caret_line_number],eax + jmp moved_caret + screen_end: + mov eax,[window_line_number] + add eax,[window_height] + dec eax + call find_line + mov [caret_line],esi + mov [caret_line_number],ecx + jmp moved_caret + pgup_key: + test [kbstate+VK_CONTROL],80h + jnz text_home + call move_page_up + jmp moved_caret + pgdn_key: + test [kbstate+VK_CONTROL],80h + jnz text_end + call move_page_down + jmp moved_caret + text_home: + mov eax,[first_line] + mov [caret_line],eax + mov [caret_line_number],1 + jmp moved_caret + text_end: + or eax,-1 + call find_line + mov [caret_line],esi + mov [caret_line_number],ecx + jmp moved_caret + word_left: + call move_to_previous_word + jmp moved_caret + word_right: + call get_caret_segment + call move_to_next_word + jmp moved_caret + scroll_left: + cmp [window_position],0 + je scroll_done + dec [window_position] + jmp scroll_done + scroll_right: + inc [window_position] + jmp scroll_done + scroll_up: + mov esi,[window_line] + mov esi,[esi+4] + or esi,esi + jz scroll_done + mov [window_line],esi + dec [window_line_number] + jmp scroll_done + scroll_down: + mov esi,[window_line] + find_next_window_line: + mov esi,[esi] + btr esi,0 + jc find_next_window_line + or esi,esi + jz scroll_done + mov [window_line],esi + inc [window_line_number] + scroll_done: + cmp [was_selection],0 + jne moved_window + mov [selection_line],0 + jmp moved_window + ins_key: + test [kbstate+VK_MENU],80h + jnz switch_blocks + test [kbstate+VK_CONTROL],80h + jnz wm_copy + test [kbstate+VK_SHIFT],80h + jnz wm_paste + xor [editor_mode],FEMODE_OVERWRITE + mov [notification],FEN_MODECHANGE + call create_caret + cmp [was_selection],1 + je done + mov [selection_line],0 + jmp done + del_key: + test [editor_mode],FEMODE_READONLY + jnz ignore + test [kbstate+VK_CONTROL],80h + jnz wm_clear + test [kbstate+VK_SHIFT],80h + jnz wm_cut + cmp [was_selection],0 + je no_selection_on_del + test [editor_style],FES_SECURESEL + jz wm_clear + no_selection_on_del: + mov esi,[caret_line] + test [editor_mode],FEMODE_OVERWRITE + jnz delete_char + call check_line_length + cmp ecx,[caret_position] + ja delete_char + cmp dword [esi],0 + je ignore + call make_undopoint + call cut_line_break + call finish_edit + jmp text_altered + delete_char: + mov [current_operation],VK_DELETE + cmp [last_operation],VK_DELETE + jne undopoint_for_delete + mov eax,[unmodified_state] + cmp eax,[undo_data] + jne undo_delete_ok + or [unmodified_state],-1 + undopoint_for_delete: + call make_undopoint + undo_delete_ok: + call delete_character + call finish_edit + jmp text_altered + backspace_key: + test [editor_mode],FEMODE_READONLY + jnz ignore + test [kbstate+VK_MENU],80h + jnz undo_key + cmp [was_selection],0 + je no_selection_to_clear + test [editor_style],FES_SECURESEL + jz wm_clear + no_selection_to_clear: + cmp [caret_position],0 + je line_back + test [kbstate+VK_CONTROL],80h + jnz word_back + mov [current_operation],VK_BACK + cmp [last_operation],VK_BACK + jne backspace_undopoint + mov eax,[unmodified_state] + cmp eax,[undo_data] + jne undo_backspace_ok + or [unmodified_state],-1 + jmp undo_backspace_ok + backspace_undopoint: + call make_undopoint + undo_backspace_ok: + dec [caret_position] + call delete_character + call finish_edit + jmp text_altered + line_back: + test [editor_mode],FEMODE_OVERWRITE + jnz ignore + mov esi,[caret_line] + mov esi,[esi+4] + or esi,esi + jz ignore + call make_undopoint + mov [caret_line],esi + dec [caret_line_number] + call check_line_length + mov [caret_position],ecx + call cut_line_break + call finish_edit + jmp text_altered + word_back: + call make_undopoint + push [caret_position] + mov esi,[caret_line] + xor eax,eax + xchg eax,[esi+4] + push eax + call move_to_previous_word + pop eax + mov esi,[caret_line] + mov [esi+4],eax + pop ecx + sub ecx,[caret_position] + call delete_from_line + call finish_edit + jmp text_altered + character: + test [editor_mode],FEMODE_READONLY + jnz ignore + cmp al,0Dh + je enter_key + cmp al,9 + je tab_key + cmp [was_selection],0 + je no_selection_to_replace + call make_undopoint + test [editor_style],FES_SECURESEL + jnz character_undo_ok + push eax + call delete_block + pop eax + call put_character + call finish_edit + jmp text_altered + no_selection_to_replace: + mov [current_operation],VK_SPACE + cmp [last_operation],VK_SPACE + jne character_undopoint + mov edx,[unmodified_state] + cmp edx,[undo_data] + jne character_undo_ok + or [unmodified_state],-1 + jmp character_undo_ok + character_undopoint: + call make_undopoint + character_undo_ok: + call put_character + call finish_edit + jmp text_altered + tab_key: + test [editor_mode],FEMODE_READONLY + jnz ignore + call make_undopoint + cmp [was_selection],0 + je tab_securesel + test [editor_style],FES_SECURESEL + jnz tab_securesel + call delete_block + tab_securesel: + call tabulate + call finish_edit + jmp text_altered + enter_key: + test [editor_mode],FEMODE_READONLY + jnz ignore + call make_undopoint + cmp [was_selection],0 + je enter_secureselection_ok + test [editor_style],FES_SECURESEL + jnz enter_secureselection_ok + call delete_block + enter_secureselection_ok: + call carriage_return + test [editor_mode],FEMODE_OVERWRITE + jnz text_altered + call finish_edit + jmp text_altered + ctrl_y_key: + test [editor_mode],FEMODE_READONLY + jnz ignore + call make_undopoint + call remove_line + jmp text_altered + f6_key: + test [editor_mode],FEMODE_READONLY + jnz ignore + call make_undopoint + call duplicate_line + jmp text_altered + menu_key: + cmp [menu_handle],0 + je ignore + lea ebx,[point] + mov eax,[caret_x] + mov [ebx+POINT.x],eax + mov eax,[caret_y] + add eax,[font_height] + mov [ebx+POINT.y],eax + invoke ClientToScreen,[hwnd],ebx + invoke TrackPopupMenu,[menu_handle],TPM_RIGHTBUTTON,[ebx+POINT.x],[ebx+POINT.y],0,[menu_window],0 + jmp ignore +wm_syskeydown: + lea ebx,[kbstate] + invoke GetKeyboardState,ebx + mov eax,[wparam] + cmp eax,VK_INSERT + je switch_blocks + cmp eax,VK_LEFT + je scroll_left + cmp eax,VK_RIGHT + je scroll_right + cmp eax,VK_UP + je scroll_up + cmp eax,VK_DOWN + je scroll_down + cmp eax,VK_BACK + je undo_key + mov al,[last_operation] + mov [current_operation],al + jmp defwndproc + switch_blocks: + xor [editor_mode],FEMODE_VERTICALSEL + mov [notification],FEN_MODECHANGE + cmp [was_selection],0 + je ignore + jmp moved_window +wm_char: + test [lparam],1 shl 31 + jz ignore + mov eax,[wparam] + jmp character +wm_lbuttondown: + cmp [focus],0 + jne focus_ok + invoke SetFocus,[hwnd] + mov esi,[editor_memory] + add esi,SEGMENT_HEADER_LENGTH + lea edi,[editor_data] + mov ecx,editor_data_size + rep movsb + focus_ok: + lea ebx,[kbstate] + invoke GetKeyboardState,ebx + cmp [was_selection],0 + jne selection_ok + mov eax,[caret_line] + mov [selection_line],eax + mov eax,[caret_position] + mov [selection_position],eax + mov eax,[caret_line_number] + mov [selection_line_number],eax + selection_ok: + call get_mouse_position + invoke SetCapture,[hwnd] + or [mouse_select],-1 + jmp moved_caret + get_mouse_position: + mov ax,word [lparam] + cwde + cdq + test [editor_style],FES_CONSOLECARET + jnz get_mouse_column + test [editor_mode],FEMODE_OVERWRITE + jnz get_mouse_column + mov ebx,[font_width] + shr ebx,1 + adc eax,ebx + get_mouse_column: + idiv [font_width] + add eax,[window_position] + cmp eax,[maximum_position] + jg mouse_out_of_line + cmp eax,0 + jge click_position_ok + xor eax,eax + jmp click_position_ok + mouse_out_of_line: + mov eax,[maximum_position] + click_position_ok: + mov [caret_position],eax + mov ax,word [lparam+2] + cwde + cdq + idiv [font_height] + add eax,[window_line_number] + cmp eax,0 + jg click_line_ok + mov eax,1 + click_line_ok: + call find_line + mov [caret_line],esi + mov [caret_line_number],ecx + retn +wm_lbuttonup: + invoke ReleaseCapture + mov [mouse_select],0 + jmp done +wm_mousemove: + cmp [mouse_select],0 + je ignore + cmp [was_selection],0 + jne select + mov eax,[caret_line] + mov ebx,[caret_line_number] + mov [selection_line],eax + mov [selection_line_number],ebx + mov eax,[caret_position] + mov [selection_position],eax + select: + call get_mouse_position + jmp moved_selection +wm_lbuttondblclk: + mov [mouse_select],0 + call get_mouse_position + call get_word_at_caret + mov [selection_position],edx + add edx,ecx + mov [caret_position],edx + mov eax,[caret_line] + mov [selection_line],eax + mov eax,[caret_line_number] + mov [selection_line_number],eax + jmp moved_selection +wm_rbuttondown: + cmp [menu_handle],0 + je ignore + lea eax,[point] + invoke GetCursorPos,eax + invoke TrackPopupMenu,[menu_handle],TPM_RIGHTBUTTON,[point.x],[point.y],0,[menu_window],0 + jmp ignore +wm_copy: + cmp [was_selection],0 + je ignore + call copy_to_clipboard + jmp ignore + copy_to_clipboard: + call get_block_length + inc ecx + invoke GlobalAlloc,GMEM_MOVEABLE+GMEM_DDESHARE,ecx + mov ebx,eax + invoke GlobalLock,ebx + mov edi,eax + push ebx + call copy_block + pop ebx + invoke GlobalUnlock,ebx + invoke OpenClipboard,[hwnd] + invoke EmptyClipboard + invoke SetClipboardData,CF_TEXT,ebx + or eax,eax + jz copy_failed + invoke CloseClipboard + retn + copy_failed: + invoke GlobalFree,ebx + retn +wm_cut: + test [editor_mode],FEMODE_READONLY + jnz ignore + cmp [was_selection],0 + je ignore + call copy_to_clipboard +wm_clear: + test [editor_mode],FEMODE_READONLY + jnz ignore + cmp [was_selection],0 + je ignore + call make_undopoint + call delete_block + mov [selection_line],0 + jmp text_changed +wm_paste: + test [editor_mode],FEMODE_READONLY + jnz ignore + call make_undopoint + cmp [was_selection],0 + je paste_secureselection_ok + test [editor_style],FES_SECURESEL + jnz paste_secureselection_ok + call delete_block + paste_secureselection_ok: + invoke OpenClipboard,NULL + invoke GetClipboardData,CF_TEXT + or eax,eax + jnz do_paste + invoke CloseClipboard + jmp ignore + do_paste: + or [clipboard_opened],-1 + push eax + invoke GlobalLock,dword [esp] + mov esi,eax + call insert_block + jc paste_failed + pop ebx + invoke GlobalUnlock,ebx + invoke CloseClipboard + mov [clipboard_opened],0 + test [editor_style],FES_SECURESEL + jz no_selection_after_paste + mov eax,[caret_line] + mov ecx,[caret_line_number] + mov edx,[caret_position] + xchg eax,[selection_line] + xchg ecx,[selection_line_number] + xchg edx,[selection_position] + mov [caret_line],eax + mov [caret_line_number],ecx + mov [caret_position],edx + jmp text_changed + no_selection_after_paste: + mov [selection_line],0 + jmp text_changed + paste_failed: + call undo_changes + pop ebx + invoke GlobalUnlock,ebx + invoke CloseClipboard + mov [clipboard_opened],0 + jmp text_changed +wm_settext: + mov esi,[lparam] + call set_text + mov [return_value],TRUE + jmp text_changed +wm_gettextlength: + mov esi,[first_line] + count_text_length: + mov eax,[esi+8] + add [return_value],eax + skip_counted_line_segments: + mov esi,[esi] + or esi,esi + jz ignore + btr esi,0 + jc skip_counted_line_segments + add [return_value],2 + jmp count_text_length +wm_gettext: + mov esi,[first_line] + mov edi,[lparam] + sub [wparam],1 + jc ignore + mov [line_number],0 + copy_text: + inc [line_number] + mov ecx,[esi+8] + test [editor_style],FES_OPTIMALFILL + jz direct_copy + cmp ecx,8 + jb direct_copy + push edi ecx + mov edi,[line_buffer] + xor edx,edx + call copy_from_line + push esi + mov esi,[line_buffer] + mov edi,[line_buffer] + add edi,[peak_line_length] + mov ebx,edi + mov ecx,[esp+4] + xor al,al + rep stosb + mov ecx,[esp+4] + invoke syntax_proc,esi,ecx,ebx + pop esi ecx edi + mov eax,[return_value] + add eax,ecx + cmp eax,[wparam] + jbe optimal_fill_size_ok + mov ecx,[wparam] + sub eax,[return_value] + optimal_fill_size_ok: + push esi edi + mov esi,[line_buffer] + mov ebx,[peak_line_length] + jecxz optimal_fill_done + xor edx,edx + optimal_fill: + lodsb + cmp al,20h + jne store_character + cmp byte [esi-1+ebx],0 + jne store_character + mov eax,esi + sub eax,[line_buffer] + test eax,111b + jz store_tab + inc edx + mov al,20h + stosb + loop optimal_fill + jmp optimal_fill_done + store_tab: + mov al,20h + or edx,edx + jz store_character + sub edi,edx + mov al,9 + store_character: + stosb + xor edx,edx + loop optimal_fill + optimal_fill_done: + pop eax + neg eax + add eax,edi + add [return_value],eax + pop esi + jmp line_copied + direct_copy: + mov eax,[return_value] + add eax,ecx + cmp eax,[wparam] + jbe direct_copy_size_ok + mov ecx,[wparam] + sub eax,[return_value] + direct_copy_size_ok: + add [return_value],ecx + xor edx,edx + call copy_from_line + line_copied: + or esi,esi + jz text_copied + mov ecx,[return_value] + add ecx,2 + cmp ecx,[wparam] + ja text_copied + mov ax,0A0Dh + stosw + mov [return_value],ecx + cmp ecx,[wparam] + jne copy_text + text_copied: + xor al,al + stosb + jmp ignore +fem_getlinelength: + mov esi,[caret_line] + mov eax,[wparam] + or eax,eax + jz return_length + call find_line + cmp ecx,[wparam] + je return_length + or [return_value],-1 + jmp ignore + return_length: + mov ecx,[esi+8] + mov [return_value],ecx + jmp ignore +fem_getline: + mov esi,[caret_line] + mov eax,[wparam] + or eax,eax + jz get_line + call find_line + cmp ecx,[wparam] + jne ignore + get_line: + mov ecx,[esi+8] + mov [return_value],ecx + mov edi,[lparam] + xor edx,edx + call copy_from_line + xor al,al + stosb + jmp ignore +wm_setfont: + mov esi,[wparam] + or esi,esi + jnz get_metrics + mov esi,[fedit_font] + get_metrics: + invoke GetDC,[hwnd] + mov ebx,eax + invoke SelectObject,ebx,esi + lea edi,[char] + mov byte [edi],20h + lea eax,[size] + invoke GetTextExtentPoint32,ebx,edi,1,eax + lea eax,[tm] + invoke GetTextMetrics,ebx,eax + invoke ReleaseDC,[hwnd],ebx + test [tm.tmPitchAndFamily],TMPF_FIXED_PITCH + jnz ignore + mov [return_value],esi + mov [editor_font],esi + mov eax,[size.cy] + mov [font_height],eax + mov eax,[size.cx] + mov [font_width],eax + mov ecx,[tm.tmMaxCharWidth] + sub ecx,eax + mov [font_overhang],ecx + mov eax,[lparam] + mov [redraw_now],al + cmp [focus],0 + je wm_size + call create_caret + jmp wm_size +wm_getfont: + mov eax,[editor_font] + cmp eax,[fedit_font] + je ignore + mov [return_value],eax + jmp ignore +wm_undo: + test [editor_mode],FEMODE_READONLY + jnz ignore + test [editor_mode],FEMODE_NOUNDO + jnz enable_undo + mov eax,[undo_data] + test eax,eax + jz ignore + call undo_changes + call create_caret + mov [last_operation],0 + jmp text_changed + enable_undo: + and [editor_mode],not FEMODE_NOUNDO + jmp ignore +em_canundo: + test [editor_mode],FEMODE_READONLY + jnz ignore + mov eax,[undo_data] + or eax,eax + jz ignore + mov [return_value],TRUE + jmp ignore + undo_key: + test [kbstate+VK_SHIFT],80h + jz wm_undo +fem_redo: + test [editor_mode],FEMODE_READONLY + jnz ignore + cmp [redo_data],0 + je ignore + call redo_changes + call create_caret + mov [last_operation],0 + jmp text_changed +fem_canredo: + test [editor_mode],FEMODE_READONLY + jnz ignore + mov eax,[redo_data] + or eax,eax + jz ignore + mov [return_value],TRUE + jmp ignore +fem_isunmodified: + mov eax,[undo_data] + cmp eax,[unmodified_state] + jne ignore + mov [return_value],TRUE + jmp ignore +em_emptyundobuffer: + call clear_redo_data + call clear_undo_data + jmp ignore +fem_setunmodified: + mov eax,[undo_data] + mov [unmodified_state],eax + jmp ignore +em_replacesel: + test [editor_mode],FEMODE_VERTICALSEL + FEMODE_OVERWRITE + FEMODE_READONLY + jnz ignore + cmp [undo_data],0 + je replacesel_undopoint + cmp [wparam],0 + je replace_undo_ok + replacesel_undopoint: + call make_undopoint + replace_undo_ok: + cmp [was_selection],0 + je simple_replace + push [caret_line_number] + push [caret_position] + call delete_block + pop edx ecx + cmp ecx,[caret_line_number] + jne simple_replace + cmp edx,[caret_position] + jne simple_replace + mov esi,[lparam] + call insert_block + mov esi,[caret_line] + mov ecx,[caret_line_number] + mov edx,[caret_position] + xchg esi,[selection_line] + xchg ecx,[selection_line_number] + xchg edx,[selection_position] + mov [caret_line],esi + mov [caret_line_number],ecx + mov [caret_position],edx + jmp text_changed + simple_replace: + mov esi,[lparam] + call insert_block + jmp text_changed +fem_setmode: + mov eax,[wparam] + xchg [editor_mode],eax + cmp eax,[editor_mode] + je ignore + mov [notification],FEN_MODECHANGE + call create_caret + cmp [was_selection],0 + jne moved_window + jmp done +fem_getmode: + mov eax,[editor_mode] + mov [return_value],eax + jmp ignore +fem_setsyntaxhighlight: + mov eax,[wparam] + mov ebx,[lparam] + mov [syntax_colors],eax + mov [syntax_proc],ebx + or eax,eax + jnz wm_size + mov [syntax_proc],SyntaxProc + jmp wm_size +fem_setrightclickmenu: + mov eax,[wparam] + mov ebx,[lparam] + mov [menu_handle],eax + mov [menu_window],ebx + jmp ignore +fem_settextcolor: + mov eax,[wparam] + mov ebx,[lparam] + mov [text_color],eax + mov [background_color],ebx + jmp wm_size +fem_setselcolor: + mov eax,[wparam] + mov ebx,[lparam] + mov [selection_text],eax + mov [selection_background],ebx + jmp wm_size +fem_setpos: + mov edi,[wparam] + virtual at edi + pos FEPOS + end virtual + cmp [selection_line],0 + jne selection_current_ok + mov eax,[caret_line] + mov [selection_line],eax + mov eax,[caret_line_number] + mov [selection_line_number],eax + mov eax,[caret_position] + mov [selection_position],eax + selection_current_ok: + mov eax,[pos.selectionLine] + or eax,eax + jz selection_line_ok + call find_line + mov [selection_line],esi + mov [selection_line_number],ecx + selection_line_ok: + mov eax,[pos.selectionPosition] + sub eax,1 + jc selection_position_set + mov [selection_position],eax + selection_position_set: + mov eax,[pos.caretLine] + or eax,eax + jz caret_line_ok + call find_line + mov [caret_line],esi + mov [caret_line_number],ecx + caret_line_ok: + mov eax,[pos.caretPosition] + sub eax,1 + jc moved_selection + mov [caret_position],eax + jmp moved_selection +fem_getpos: + mov edi,[wparam] + mov eax,[caret_line_number] + mov [pos.selectionLine],eax + mov [pos.caretLine],eax + mov eax,[caret_position] + inc eax + mov [pos.selectionPosition],eax + mov [pos.caretPosition],eax + cmp [selection_line],0 + je ignore + mov eax,[selection_line_number] + mov [pos.selectionLine],eax + mov eax,[selection_position] + inc eax + mov [pos.selectionPosition],eax + jmp ignore +fem_findfirst: + mov esi,[lparam] + mov eax,[wparam] + call find_first + jnc show_found_text + jmp ignore +fem_findnext: + call find_next + jc ignore + show_found_text: + mov [return_value],TRUE + cmp [macro_operation],0 + jne moved_selection + mov eax,[caret_position] + xchg eax,[selection_position] + mov [caret_position],eax + call update_window + call let_caret_appear + call update_positions + mov eax,[caret_position] + xchg eax,[selection_position] + mov [caret_position],eax + jmp moved_selection +fem_getsearchtext: + call get_search_text_length + mov edx,[lparam] + jc store_required_buffer_size + inc ecx + cmp ecx,[edx] + ja store_required_buffer_size + mov edi,[wparam] + call get_search_text + mov [return_value],TRUE + jmp ignore + store_required_buffer_size: + mov [edx],ecx + jmp ignore +fem_getsearchflags: + cmp [search_data],0 + je ignore + mov eax,[search_flags] + mov [return_value],eax + jmp ignore +fem_releasesearch: + call release_search_data + jmp ignore +fem_canfindnext: + cmp [search_data],0 + je ignore + mov [return_value],TRUE + jmp ignore +fem_getwordatcaret: + cmp [wparam],0 + je ignore + call get_word_at_caret + mov edi,[lparam] + mov eax,[wparam] + dec eax + jz word_copied + cmp ecx,eax + jbe copy_word + mov ecx,eax + copy_word: + mov [return_value],ecx + mov esi,[caret_line] + call copy_from_line + word_copied: + xor al,al + stosb + jmp ignore +fem_beginoperation: + test [editor_mode],FEMODE_READONLY + jnz ignore + mov [macro_operation],1 + call store_status_for_undo + jmp done +fem_endoperation: + test [editor_mode],FEMODE_READONLY + jnz ignore + xor al,al + xchg al,[macro_operation] + test al,2 + jnz text_changed + test al,4 + jz update_all + mov [notification],FEN_POSCHANGE + jmp update_all +moved_caret: + test [kbstate+VK_SHIFT],80h + jnz moved_selection + mov [selection_line],0 +moved_selection: + cmp [macro_operation],0 + jne position_changed_by_macro_operation + mov [notification],FEN_POSCHANGE + jmp update_all +moved_window: + call update_positions + jmp refresh +text_altered: + mov [selection_line],0 +text_changed: + cmp [macro_operation],0 + jne text_changed_by_macro_operation + mov [notification],FEN_TEXTCHANGE + mov eax,[peak_line_length] + xor edx,edx + mov ebx,SEGMENT_DATA_LENGTH + div ebx + inc eax + mul ebx + shl eax,1 + cmp eax,[line_buffer_size] + je update_all + mov [line_buffer_size],eax + invoke VirtualAlloc,0,[line_buffer_size],MEM_COMMIT,PAGE_READWRITE + or eax,eax + jz memory_shortage + xchg [line_buffer],eax + invoke VirtualFree,eax,0,MEM_RELEASE + update_all: + cmp [macro_operation],0 + jne done + call update_window + call let_caret_appear + call update_positions + refresh: + cmp [macro_operation],0 + jne done + cmp [screen_base],0 + je wm_size + mov eax,[screen_size] + shl eax,1 + xor [screen_offset],eax + call update_screen + mov esi,[screen_base] + mov eax,[screen_size] + lea edi,[esi+eax*2] + mov [rect.top],0 + mov edx,[font_height] + mov [rect.bottom],edx + mov ecx,[screen_height] + refresh_screen: + push ecx + mov ebx,[screen_size] + mov edx,[font_width] + xor eax,eax + mov [rect.left],eax + mov [rect.right],eax + mov ecx,[screen_width] + refresh_line: + mov al,[esi] + mov ah,[esi+ebx] + cmp al,[edi] + jne refresh_changed + cmp ah,[edi+ebx] + jne refresh_changed + inc esi + inc edi + add [rect.left],edx + add [rect.right],edx + loop refresh_line + jmp refresh_next_line + refresh_changed: + mov al,[esi] + mov ah,[esi+ebx] + inc esi + add [rect.right],edx + cmp al,[edi] + jne changed_more + cmp ah,[edi+ebx] + jne changed_more + inc edi + jmp invalidate + changed_more: + inc edi + loop refresh_changed + invalidate: + push ecx edx + push [rect.right] + mov eax,[font_overhang] + sub [rect.left],eax + add [rect.right],eax + lea edx,[rect] + invoke InvalidateRect,[hwnd],edx,FALSE + pop eax + mov [rect.left],eax + mov [rect.right],eax + pop edx ecx + jecxz refresh_next_line + loop refresh_line + refresh_next_line: + mov eax,[font_height] + add [rect.top],eax + add [rect.bottom],eax + pop ecx + dec ecx + jnz refresh_screen + jmp done + position_changed_by_macro_operation: + or [macro_operation],4 + jmp done + text_changed_by_macro_operation: + or [macro_operation],2 + jmp done +ignore: + mov dl,[last_operation] + mov [current_operation],dl + cmp [was_selection],0 + jne done + mov [selection_line],0 +done: + cmp [focus],0 + je caret_ok + call update_caret_position + caret_ok: + lea esi,[editor_data] + mov edi,[editor_memory] + add edi,SEGMENT_HEADER_LENGTH + mov ecx,editor_data_size + rep movsb + cmp [notification],0 + je notification_ok + invoke GetWindowLong,[hwnd],GWL_HWNDPARENT + mov edi,eax + invoke GetWindowLong,[hwnd],GWL_ID + movzx ebx,[notification] + shl ebx,16 + or eax,ebx + invoke SendMessage,edi,WM_COMMAND,eax,[hwnd] + notification_ok: + cmp [redraw_now],0 + je redraw_ok + invoke UpdateWindow,[hwnd] + redraw_ok: + mov eax,[return_value] +finish_wndproc: + pop edi esi ebx + ret +not_enough_memory: + lea esp,[editor_memory-10h] + mov [notification],FEN_OUTOFMEMORY + or [return_value],-1 + cmp [clipboard_opened],0 + je ignore + invoke CloseClipboard + mov [clipboard_opened],0 + jmp ignore +get_memory: + invoke VirtualAlloc,0,ecx,MEM_COMMIT,PAGE_READWRITE + mov ebx,eax + retn +release_memory: + invoke VirtualFree,ebx,0,MEM_RELEASE + retn +make_undopoint: + cmp [macro_operation],0 + jne undopoint_ok + call store_status_for_undo + undopoint_ok: + retn +update_positions: + lea eax,[rect] + invoke GetClientRect,[hwnd],eax + mov eax,[rect.right] + sub eax,[rect.left] + cdq + div [font_width] + mov [window_width],eax + add edx,-1 + adc eax,0 + mov [screen_width],eax + mov eax,[rect.bottom] + sub eax,[rect.top] + cdq + div [font_height] + mov [window_height],eax + add edx,-1 + adc eax,0 + mov [screen_height],eax + call update_window + setup_vscroll: + mov ecx,[lines_count] + mov [sc.cbSize],sizeof.SCROLLINFO + mov [sc.fMask],SIF_DISABLENOSCROLL+SIF_RANGE+SIF_PAGE+SIF_POS + mov [sc.nMin],1 + mov [sc.nMax],ecx + mov eax,[window_height] + mov [sc.nPage],eax + mov edx,[window_line_number] + mov [sc.nPos],edx + test [editor_style],WS_VSCROLL + jz setup_hscroll + lea eax,[sc] + invoke SetScrollInfo,[hwnd],SB_VERT,eax,TRUE + setup_hscroll: + mov ecx,[maximum_position] + mov [sc.nMin],0 + mov [sc.nMax],ecx + mov eax,[window_width] + mov [sc.nPage],eax + mov edx,[window_position] + mov [sc.nPos],edx + test [editor_style],WS_HSCROLL + jz setup_caret + lea eax,[sc] + invoke SetScrollInfo,[hwnd],SB_HORZ,eax,TRUE + setup_caret: + mov eax,[font_width] + mov edx,[caret_position] + sub edx,[window_position] + imul eax,edx + mov [caret_x],eax + mov eax,[font_height] + mov edx,[caret_line_number] + sub edx,[window_line_number] + imul eax,edx + mov [caret_y],eax + retn +create_caret: + xor eax,eax + test [editor_mode],FEMODE_OVERWRITE + jnz block_caret + test [editor_style],FES_CONSOLECARET + jnz console_caret + invoke CreateCaret,[hwnd],NULL,0,[font_height] + jmp show_caret + block_caret: + invoke CreateCaret,[hwnd],NULL,[font_width],[font_height] + jmp show_caret + console_caret: + invoke CreateCaret,[hwnd],NULL,[font_width],2 + show_caret: + invoke ShowCaret,[hwnd] +update_caret_position: + mov eax,[caret_y] + test [editor_mode],FEMODE_OVERWRITE + jnz set_position + test [editor_style],FES_CONSOLECARET + jz set_position + add eax,[font_height] + sub eax,2 + set_position: + invoke SetCaretPos,[caret_x],eax + retn +update_screen: + mov edi,[screen_base] + or edi,edi + jz screen_prepared + add edi,[screen_offset] + mov ebx,[screen_size] + add ebx,edi + push ebx + mov ecx,[screen_height] + mov edx,[window_line_number] + mov [line_number],edx + mov esi,[window_line] + prepare_screen: + push ecx + test byte [esi],1 + jnz prepare_long_line + push esi + add esi,SEGMENT_HEADER_LENGTH + mov ecx,SEGMENT_DATA_LENGTH + call prepare_line + pop esi + mov esi,[esi] + jmp prepare_next_line + prepare_long_line: + push edi + mov edi,[line_buffer] + xor eax,eax + combine_long_line_segments: + add esi,SEGMENT_HEADER_LENGTH + mov ecx,SEGMENT_DATA_LENGTH + rep movsb + add eax,SEGMENT_DATA_LENGTH + mov esi,[esi-SEGMENT_LENGTH] + btr esi,0 + jc combine_long_line_segments + mov ecx,eax + mov eax,esi + mov esi,edi + sub esi,ecx + pop edi + push eax + call prepare_line + pop esi + prepare_next_line: + inc [line_number] + pop ecx + dec ecx + jz prepare_selection + or esi,esi + jnz prepare_screen + prepare_empty_lines: + imul ecx,[screen_width] + xor al,al + mov edx,ecx + rep stosb + xchg edi,ebx + mov ecx,edx + rep stosb + prepare_selection: + pop ebx + test [editor_style],ES_NOHIDESEL + jnz hideselection_ok + cmp [focus],0 + je screen_prepared + hideselection_ok: + cmp [selection_line],0 + je screen_prepared + mov eax,[window_line_number] + mov esi,[selection_line_number] + mov edi,[caret_line_number] + sub esi,eax + sub edi,eax + mov ecx,[window_position] + mov eax,[selection_position] + mov edx,[caret_position] + sub eax,ecx + sub edx,ecx + cmp esi,edi + jle selection_boundaries_ok + xchg esi,edi + xchg eax,edx + selection_boundaries_ok: + mov ecx,[screen_height] + cmp edi,0 + jl screen_prepared + cmp esi,ecx + jge screen_prepared + cmp esi,edi + je prepare_vsel + test [editor_mode],FEMODE_VERTICALSEL + jz prepare_hsel + prepare_vsel: + cmp eax,edx + jle vselection_boundaries_ok + xchg eax,edx + vselection_boundaries_ok: + cmp esi,0 + jge vselection_start_ok + xor esi,esi + vselection_start_ok: + inc edi + cmp edi,ecx + jle vselection_end_ok + mov edi,ecx + vselection_end_ok: + mov ecx,[screen_width] + cmp edx,0 + jl screen_prepared + cmp eax,ecx + jge screen_prepared + cmp eax,0 + jge vselection_line_start_ok + xor eax,eax + vselection_line_start_ok: + cmp edx,ecx + jle vselection_line_end_ok + mov edx,ecx + vselection_line_end_ok: + mov ecx,edi + sub ecx,esi + imul esi,[screen_width] + add ebx,esi + prepare_vselection_line: + push eax ecx + mov edi,ebx + mov ecx,edx + sub ecx,eax + lea edi,[ebx+eax] + mov al,80h + rep stosb + add ebx,[screen_width] + pop ecx eax + loop prepare_vselection_line + jmp screen_prepared + prepare_hsel: + cmp esi,0 + jge hselection_start_ok + xor esi,esi + xor eax,eax + hselection_start_ok: + cmp edi,ecx + jl hselection_end_ok + mov edi,ecx + xor edx,edx + hselection_end_ok: + inc esi + mov ecx,edi + sub ecx,esi + imul ecx,[screen_width] + imul esi,[screen_width] + lea edi,[ebx+esi] + neg eax + add eax,[screen_width] + cmp eax,0 + jle hselection_start_line_ok + sub edi,eax + add ecx,eax + sub eax,[screen_width] + jle hselection_start_line_ok + add edi,eax + sub ecx,eax + hselection_start_line_ok: + cmp edx,0 + jle hselection_end_line_ok + add ecx,edx + sub edx,[screen_width] + jle hselection_end_line_ok + sub ecx,edx + hselection_end_line_ok: + mov al,80h + rep stosb + screen_prepared: + retn + prepare_line: + push edi ecx + mov ecx,[esp] + mov edi,[line_buffer] + add edi,ecx + shr ecx,2 + xor eax,eax + rep stosd + mov ecx,[esp] + sub edi,ecx + invoke syntax_proc,esi,ecx,edi + mov edx,edi + pop eax edi + push esi edx + mov edx,[window_position] + lea esi,[esi+edx] + sub eax,edx + jnc line_position_ok + xor eax,eax + jmp line_length_ok + line_position_ok: + cmp eax,[screen_width] + jbe line_length_ok + mov eax,[screen_width] + line_length_ok: + mov ecx,eax + rep movsb + pop esi + add esi,edx + mov ecx,eax + xchg edi,ebx + rep movsb + xchg edi,ebx + pop esi + cmp eax,[screen_width] + jb after_end_of_line + retn + after_end_of_line: + mov ecx,[screen_width] + sub ecx,eax + xor al,al + mov edx,ecx + rep stosb + xchg edi,ebx + mov ecx,edx + rep stosb + xchg edi,ebx + retn + +include '..\memory.inc' +include '..\navigate.inc' +include '..\edit.inc' +include '..\blocks.inc' +include '..\search.inc' +include '..\undo.inc' + +endp + +proc SyntaxProc lpLine,uChars,lpColors + ret +endp diff --git a/toolchain/fasmw17332/SOURCE/IDE/FASMW/RESOURCE/ASSIGN.BMP b/toolchain/fasmw17332/SOURCE/IDE/FASMW/RESOURCE/ASSIGN.BMP new file mode 100644 index 0000000..3680a6e Binary files /dev/null and b/toolchain/fasmw17332/SOURCE/IDE/FASMW/RESOURCE/ASSIGN.BMP differ diff --git a/toolchain/fasmw17332/SOURCE/IDE/FASMW/RESOURCE/FASMW.ICO b/toolchain/fasmw17332/SOURCE/IDE/FASMW/RESOURCE/FASMW.ICO new file mode 100644 index 0000000..f90f438 Binary files /dev/null and b/toolchain/fasmw17332/SOURCE/IDE/FASMW/RESOURCE/FASMW.ICO differ diff --git a/toolchain/fasmw17332/SOURCE/IDE/MEMORY.INC b/toolchain/fasmw17332/SOURCE/IDE/MEMORY.INC new file mode 100644 index 0000000..9b04370 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/IDE/MEMORY.INC @@ -0,0 +1,199 @@ + +; flat editor core +; Copyright (c) 1999-2015, Tomasz Grysztar. +; All rights reserved. + +init_editor_memory: + mov ecx,BLOCK_LENGTH + call get_memory + or eax,eax + jz memory_error + mov [editor_memory],eax + mov dword [eax],0 + mov dword [eax+4],0 + mov dword [eax+8],ebx + lea ebx,[eax+SEGMENT_LENGTH] + mov [unallocated_segments],ebx + mov [memory_search_segment],ebx + add eax,BLOCK_LENGTH + mov [unallocated_segments_end],eax + mov [memory_search_block],eax + mov [released_segments],0 + call allocate_segment + mov [first_line],eax + mov [lines_count],1 + mov [peak_line_length],0 + mov [caret_line],eax + mov [caret_line_number],1 + mov [window_line],eax + mov [window_line_number],1 + mov edi,eax + xor eax,eax + mov ecx,SEGMENT_HEADER_LENGTH shr 2 + rep stosd + mov eax,20202020h + mov ecx,SEGMENT_DATA_LENGTH shr 2 + rep stosd + call allocate_segment + jc memory_shortage + mov [lengths_table],eax + mov edi,eax + xor eax,eax + mov ecx,SEGMENT_LENGTH shr 2 + rep stosd + mov [caret_position],eax + mov [window_position],eax + mov [selection_line],eax + mov [undo_data],eax + mov [redo_data],eax + mov [search_data],eax + mov [editor_mode],eax + mov [unmodified_state],eax + clc + retn + memory_error: + stc + retn + +reset_editor_memory: + mov esi,[editor_memory] + lea eax,[esi+SEGMENT_LENGTH] + mov [unallocated_segments],eax + mov [memory_search_segment],eax + lea eax,[esi+BLOCK_LENGTH] + mov [unallocated_segments_end],eax + mov [memory_search_block],eax + mov [released_segments],0 + mov ebx,[esi] + release_blocks: + or ebx,ebx + jz release_done + push dword [ebx] + mov ebx,[ebx+8] + call release_memory + pop ebx + jmp release_blocks + release_done: + mov ebx,[editor_memory] + xor eax,eax + mov [ebx],eax + mov [undo_data],eax + mov [redo_data],eax + mov [search_data],eax + call allocate_segment + jc memory_shortage + mov [first_line],eax + mov [window_line],eax + mov [caret_line],eax + mov edi,eax + xor eax,eax + mov ecx,SEGMENT_HEADER_LENGTH shr 2 + rep stosd + mov eax,20202020h + mov ecx,SEGMENT_DATA_LENGTH shr 2 + rep stosd + xor eax,eax + mov [selection_line],eax + mov [peak_line_length],eax + mov [window_position],eax + inc eax + mov [window_line_number],eax + mov [caret_line_number],eax + mov [lines_count],eax + call allocate_segment + jc memory_shortage + mov [lengths_table],eax + mov edi,eax + xor eax,eax + mov ecx,SEGMENT_LENGTH shr 2 + rep stosd + retn + +release_editor_memory: + mov esi,[editor_memory] + release: + push dword [esi] + mov ebx,[esi+8] + call release_memory + pop esi + or esi,esi + jnz release + mov [editor_memory],0 + retn + +allocate_segment: + mov eax,[unallocated_segments] + cmp eax,[unallocated_segments_end] + je simple_allocation_failed + add [unallocated_segments],SEGMENT_LENGTH + clc + retn + simple_allocation_failed: + push ebx esi + mov ebx,[memory_search_block] + mov esi,[memory_search_segment] + cmp [released_segments],16 + jb add_new_block + find_free_segment: + cmp esi,ebx + je find_in_next_block + cmp dword [esi],-1 + je reuse_segment + add esi,SEGMENT_LENGTH + cmp esi,[memory_search_segment] + jne find_free_segment + add_new_block: + sub ebx,BLOCK_LENGTH + find_last_memory_block: + cmp dword [ebx],0 + je allocate_more_memory + mov ebx,[ebx] + jmp find_last_memory_block + allocate_more_memory: + mov ecx,BLOCK_LENGTH + push ebx + call get_memory + pop esi + or eax,eax + jz allocation_failed + mov [esi],eax + mov dword [eax],0 + mov [eax+4],esi + mov [eax+8],ebx + lea ebx,[eax+BLOCK_LENGTH] + mov [unallocated_segments_end],ebx + add eax,SEGMENT_LENGTH + lea ebx,[eax+SEGMENT_LENGTH] + mov [unallocated_segments],ebx + mov [released_segments],0 + pop esi ebx + clc + retn + allocation_failed: + xor eax,eax + pop esi ebx + stc + retn + reuse_segment: + mov eax,esi + mov [memory_search_block],ebx + add esi,SEGMENT_LENGTH + mov [memory_search_segment],esi + dec [released_segments] + pop esi ebx + clc + retn + find_in_next_block: + sub ebx,BLOCK_LENGTH + mov esi,[ebx] + lea ebx,[esi+BLOCK_LENGTH] + or esi,esi + jnz find_free_segment + mov ebx,[editor_memory] + mov esi,ebx + add ebx,BLOCK_LENGTH + jmp find_free_segment + +memory_shortage: + call undo_changes + jmp not_enough_memory diff --git a/toolchain/fasmw17332/SOURCE/IDE/NAVIGATE.INC b/toolchain/fasmw17332/SOURCE/IDE/NAVIGATE.INC new file mode 100644 index 0000000..430e127 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/IDE/NAVIGATE.INC @@ -0,0 +1,511 @@ + +; flat editor core +; Copyright (c) 1999-2015, Tomasz Grysztar. +; All rights reserved. + +find_line: + mov esi,[first_line] + mov ecx,1 + mov edx,[window_line_number] + cmp eax,edx + jae forward_from_window + sub edx,eax + cmp edx,eax + jb backward_from_window + jmp find_forward + forward_from_window: + mov esi,[window_line] + mov ecx,edx + find_forward: + cmp ecx,eax + je line_found + cmp dword [esi],0 + je line_found + mov ebx,esi + forward_skip_line: + mov ebx,[ebx] + btr ebx,0 + jc forward_skip_line + or ebx,ebx + jz line_found + mov esi,ebx + inc ecx + jmp find_forward + backward_from_window: + mov esi,[window_line] + mov ecx,[window_line_number] + find_backward: + cmp ecx,eax + je line_found + cmp dword [esi+4],0 + je line_found + mov esi,[esi+4] + dec ecx + jmp find_backward + line_found: + retn + +get_caret_segment: + mov edx,[caret_position] + mov esi,[caret_line] + find_segment: + cmp edx,SEGMENT_DATA_LENGTH + jb segment_found + test byte [esi],1 + jz segment_found + mov esi,[esi] + dec esi + sub edx,SEGMENT_DATA_LENGTH + jmp find_segment + segment_found: + retn + +check_line_length: + xor edx,edx + mov ebx,esi + count_line_segments: + test byte [esi],1 + jz last_line_segment + mov esi,[esi] + dec esi + add edx,SEGMENT_DATA_LENGTH + jmp count_line_segments + last_line_segment: + lea edi,[esi+SEGMENT_LENGTH-1] + mov al,20h + mov ecx,SEGMENT_DATA_LENGTH + std + repe scasb + cld + setne al + movzx eax,al + add ecx,eax + jnz line_segments_ok + or edx,edx + jz line_segments_ok + call store_freed_segment_for_undo + mov eax,[esi] + mov esi,[esi+4] + dec esi + call store_segment_for_undo + mov [esi],eax + sub edx,SEGMENT_DATA_LENGTH + jmp last_line_segment + line_segments_ok: + add ecx,edx + mov edx,ecx + cmp edx,[ebx+8] + je line_length_checked + mov esi,ebx + call store_segment_for_undo + xchg [ebx+8],edx + push edx + mov eax,[ebx+8] + call register_length + pop eax + call unregister_length + line_length_checked: + retn + register_length: + cmp eax,[peak_line_length] + jbe peak_length_ok + mov [peak_line_length],eax + peak_length_ok: + or eax,eax + jz ignore_zero_length + push ebx + call find_lengths_segment + inc dword [ebx+SEGMENT_HEADER_LENGTH+eax*4] + pop ebx + ignore_zero_length: + retn + find_lengths_segment: + mov ebx,[lengths_table] + try_lengths_segment: + cmp eax,SEGMENT_DATA_LENGTH/4 + jb length_entry_ok + sub eax,SEGMENT_DATA_LENGTH/4 + cmp dword [ebx],0 + je add_lengths_segment + mov ebx,[ebx] + jmp try_lengths_segment + add_lengths_segment: + push eax ecx edi + call allocate_segment + jc memory_shortage + call store_allocated_segment_for_undo + mov [ebx],eax + mov edi,eax + xor eax,eax + stosd + mov eax,ebx + stosd + mov eax,[ebx+8] + add eax,SEGMENT_DATA_LENGTH/4 + stosd + add edi,SEGMENT_HEADER_LENGTH-12 + mov ecx,SEGMENT_DATA_LENGTH shr 2 + xor eax,eax + rep stosd + lea ebx,[edi-SEGMENT_LENGTH] + pop edi ecx eax + jmp try_lengths_segment + length_entry_ok: + retn + unregister_length: + or eax,eax + jz ignore_zero_length + push ebx + cmp eax,[peak_line_length] + je unregister_peak_length + call find_lengths_segment + dec dword [ebx+SEGMENT_HEADER_LENGTH+eax*4] + length_unregistered: + pop ebx + retn + unregister_peak_length: + call find_lengths_segment + dec dword [ebx+SEGMENT_HEADER_LENGTH+eax*4] + jnz length_unregistered + find_reduced_peak: + or eax,eax + jz try_earlier_lengths_segment + dec eax + cmp dword [ebx+SEGMENT_HEADER_LENGTH+eax*4],0 + je find_reduced_peak + add eax,[ebx+8] + mov [peak_line_length],eax + jmp length_unregistered + try_earlier_lengths_segment: + mov ebx,[ebx+4] + mov eax,SEGMENT_DATA_LENGTH/4 + or ebx,ebx + jnz find_reduced_peak + mov [peak_line_length],ebx + jmp length_unregistered + +update_window: + mov edx,[window_line_number] + cmp edx,1 + je window_vertical_position_ok + add edx,[window_height] + dec edx + cmp edx,[lines_count] + jle window_vertical_position_ok + sub edx,[lines_count] + window_vertical_correction: + mov esi,[window_line] + mov esi,[esi+4] + or esi,esi + jz window_vertical_position_ok + mov [window_line],esi + dec [window_line_number] + dec edx + jnz window_vertical_correction + window_vertical_position_ok: + mov ecx,[peak_line_length] + cmp ecx,[caret_position] + jae caret_position_ok + mov ecx,[caret_position] + caret_position_ok: + cmp [selection_line],0 + je selection_position_ok + cmp ecx,[selection_position] + jae selection_position_ok + mov ecx,[selection_position] + selection_position_ok: + mov eax,[window_width] + dec eax + cmp ecx,eax + jae edit_space_width_ok + mov ecx,eax + edit_space_width_ok: + mov [maximum_position],ecx + mov edx,[window_position] + or edx,edx + jz window_horizontal_position_ok + add edx,[window_width] + inc ecx + cmp edx,ecx + jbe window_horizontal_position_ok + sub edx,ecx + sub [window_position],edx + jnc window_horizontal_position_ok + mov [window_position],0 + window_horizontal_position_ok: + retn + +let_caret_appear: + mov eax,[caret_position] + cmp eax,[window_position] + jl horizontal_correction + mov ecx,[window_width] + jecxz last_position_ok + dec ecx + last_position_ok: + add ecx,[window_position] + mov eax,[caret_position] + sub eax,ecx + jbe horizontal_ok + add eax,[window_position] + horizontal_correction: + mov [window_position],eax + horizontal_ok: + mov esi,[caret_line] + mov ecx,[caret_line_number] + cmp ecx,[window_line_number] + jl vertical_correction + mov eax,[window_height] + or eax,eax + jz vertical_check + dec eax + vertical_check: + neg eax + add eax,[caret_line_number] + cmp [window_line_number],eax + jge vertical_ok + mov esi,[window_line] + mov ecx,[window_line_number] + vertical_find: + mov esi,[esi] + btr esi,0 + jc vertical_find + inc ecx + cmp ecx,eax + jl vertical_find + vertical_correction: + mov [window_line],esi + mov [window_line_number],ecx + vertical_ok: + retn + +move_line_up: + mov esi,[caret_line] + mov eax,[esi+4] + or eax,eax + jz cannot_move + mov [caret_line],eax + dec [caret_line_number] + clc + retn + cannot_move: + stc + retn + +move_line_down: + mov esi,[caret_line] + find_next_line: + mov eax,[esi] + or eax,eax + jz cannot_move + btr eax,0 + jnc down_ok + mov esi,eax + jmp find_next_line + down_ok: + mov [caret_line],eax + inc [caret_line_number] + clc + retn + +move_page_up: + mov eax,[caret_line_number] + sub eax,[window_height] + ja pgup_caret_ok + mov eax,1 + pgup_caret_ok: + call find_line + mov [caret_line],esi + mov [caret_line_number],ecx + mov eax,[window_line_number] + sub eax,[window_height] + ja pgup_window_ok + mov eax,1 + cmp [window_line_number],eax + je moved_ok + pgup_window_ok: + call find_line + mov [window_line],esi + mov [window_line_number],ecx + retn + +move_page_down: + mov eax,[caret_line_number] + add eax,[window_height] + call find_line + mov [caret_line],esi + mov [caret_line_number],ecx + mov eax,[window_line_number] + mov ecx,[window_height] + add eax,ecx + mov ebx,[lines_count] + sub ebx,ecx + jbe moved_ok + inc ebx + cmp eax,ebx + jb pgdn_window_ok + mov eax,ebx + cmp [window_line_number],eax + je moved_ok + pgdn_window_ok: + call find_line + mov [window_line],esi + mov [window_line_number],ecx + moved_ok: + retn + +move_to_previous_word: + call get_caret_segment + mov ecx,[caret_position] + sub ecx,edx + cmp edx,SEGMENT_DATA_LENGTH + jbe find_word_to_the_left + mov edx,SEGMENT_DATA_LENGTH + find_word_to_the_left: + sub edx,1 + jc word_in_previous_segment + mov al,[esi+SEGMENT_HEADER_LENGTH+edx] + call recognize_character + jnc find_word_start + jmp find_word_to_the_left + word_in_previous_segment: + mov eax,[esi+4] + or eax,eax + jz previous_word_ok + mov esi,eax + btr esi,0 + jnc word_in_previous_line + mov edx,SEGMENT_DATA_LENGTH + sub ecx,edx + jmp find_word_to_the_left + word_in_previous_line: + mov [caret_line],esi + dec [caret_line_number] + mov edx,SEGMENT_DATA_LENGTH + xor ecx,ecx + find_last_segment: + test byte [esi],1 + jz find_word_to_the_left + mov esi,[esi] + dec esi + add ecx,SEGMENT_DATA_LENGTH + jmp find_last_segment + find_word_start: + sub edx,1 + jc word_on_segment_edge + mov al,[esi+SEGMENT_HEADER_LENGTH+edx] + call recognize_character + jc previous_word_ok + jmp find_word_start + word_on_segment_edge: + mov esi,[esi+4] + btr esi,0 + jnc previous_word_ok + mov edx,SEGMENT_DATA_LENGTH + sub ecx,edx + jmp find_word_start + previous_word_ok: + add ecx,edx + inc ecx + mov [caret_position],ecx + retn + +move_to_next_word: + mov ecx,[caret_position] + sub ecx,edx + find_word_end: + cmp edx,SEGMENT_DATA_LENGTH + jae word_wraps_segment_edge + mov al,[esi+SEGMENT_HEADER_LENGTH+edx] + call recognize_character + jc find_word_to_the_right + add edx,1 + jmp find_word_end + word_wraps_segment_edge: + mov esi,[esi] + or esi,esi + jz move_to_line_end + btr esi,0 + jnc word_in_next_line + add ecx,SEGMENT_DATA_LENGTH + sub edx,SEGMENT_DATA_LENGTH + jmp find_word_end + find_word_to_the_right: + cmp edx,SEGMENT_DATA_LENGTH + jae word_in_next_segment + mov al,[esi+SEGMENT_HEADER_LENGTH+edx] + call recognize_character + jnc next_word_ok + add edx,1 + jmp find_word_to_the_right + word_in_next_segment: + mov esi,[esi] + or esi,esi + jz move_to_line_end + btr esi,0 + jnc word_in_next_line + add ecx,SEGMENT_DATA_LENGTH + sub edx,SEGMENT_DATA_LENGTH + jmp find_word_to_the_right + word_in_next_line: + mov [caret_line],esi + inc [caret_line_number] + xor ecx,ecx + xor edx,edx + jmp find_word_to_the_right + next_word_ok: + add ecx,edx + mov [caret_position],ecx + retn + move_to_line_end: + mov esi,[caret_line] + mov eax,[esi+8] + mov [caret_position],eax + retn + +get_word_at_caret: + call get_caret_segment + mov ebx,[caret_position] + sub ebx,edx + find_left_edge: + or edx,edx + jz left_edge_in_previous_segment + cmp edx,SEGMENT_DATA_LENGTH + ja left_edge_ok + mov al,[esi+SEGMENT_HEADER_LENGTH+edx-1] + call recognize_character + jc left_edge_ok + dec edx + jmp find_left_edge + left_edge_in_previous_segment: + mov esi,[esi+4] + btr esi,0 + jnc left_edge_ok + mov edx,SEGMENT_DATA_LENGTH + sub ebx,edx + jmp find_left_edge + left_edge_ok: + add ebx,edx + call get_caret_segment + mov ecx,[caret_position] + sub ecx,edx + find_right_edge: + cmp edx,SEGMENT_DATA_LENGTH + jae right_edge_in_next_segment + mov al,[esi+SEGMENT_HEADER_LENGTH+edx] + call recognize_character + jc right_edge_ok + inc edx + jmp find_right_edge + right_edge_in_next_segment: + mov esi,[esi] + btr esi,0 + jnc right_edge_ok + xor edx,edx + add ecx,SEGMENT_DATA_LENGTH + jmp find_right_edge + right_edge_ok: + add ecx,edx + sub ecx,ebx + mov edx,ebx + retn diff --git a/toolchain/fasmw17332/SOURCE/IDE/SEARCH.INC b/toolchain/fasmw17332/SOURCE/IDE/SEARCH.INC new file mode 100644 index 0000000..6173a6f --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/IDE/SEARCH.INC @@ -0,0 +1,529 @@ + +; flat editor core +; Copyright (c) 1999-2015, Tomasz Grysztar. +; All rights reserved. + +find_first: + mov [search_flags],eax + call release_search_data + or esi,esi + jz nothing_to_search_for + mov edi,esi + xor al,al + xor ecx,ecx + sub ecx,edi + repne scasb + lea ebx,[edi-1] + sub ebx,esi + jz nothing_to_search_for + lea ecx,[(256+ebx)*4+ebx] + push ebx + call get_memory + or eax,eax + jz not_enough_memory + mov [search_data],eax + mov [search_handle],ebx + pop ebx + mov edi,eax + lea ecx,[256+ebx] + mov eax,ebx + rep stosd + mov ecx,ebx + mov ebx,[search_data] + mov edx,ecx + test [search_flags],FEFIND_BACKWARD + jnz text_for_backward_search + test [search_flags],FEFIND_CASESENSITIVE + jnz copy_search_text + push ebx + mov ebx,upper_case_table + convert_search_text: + lodsb + xlatb + stosb + loop convert_search_text + pop ebx + jmp make_character_shifts_table + copy_search_text: + rep movsb + jmp make_character_shifts_table + text_for_backward_search: + add edi,ecx + mov edx,ecx + push ebx + mov ebx,upper_case_table + reverse_search_text: + lodsb + test [search_flags],FEFIND_CASESENSITIVE + jnz reverse_store_character + xlatb + reverse_store_character: + dec edi + mov [edi],al + dec ecx + jnz reverse_search_text + pop ebx + add edi,edx + xor ecx,ecx + make_character_shifts_table: + cmp edx,ecx + je character_shifts_table_ok + dec edi + jecxz character_shift_ok + mov al,[edi] + cmp [ebx+eax*4],edx + jne character_shift_ok + mov [ebx+eax*4],ecx + character_shift_ok: + inc ecx + jmp make_character_shifts_table + character_shifts_table_ok: + lea edi,[ebx+(256+ecx)*4] + push edi + lea edi,[edi+ecx-2] + movzx eax,byte [edi+1] + mov edx,[ebx+eax*4] + mov [ebx+256*4],edx + cmp ecx,1 + je suffix_match_shifts_table_done + mov ecx,2 + mov esi,edi + sub esi,edx + make_suffix_match_shifts_table: + cmp esi,[esp] + jb store_suffix_match_shift + mov al,[esi] + cmp al,[edi] + je store_suffix_match_shift + find_suffix_match: + dec esi + inc edx + cmp esi,[esp] + jb match_part_of_suffix + push ecx esi edi + repe cmpsb + pop edi esi ecx + jne find_suffix_match + jmp store_suffix_match_shift + match_part_of_suffix: + mov eax,[esp] + push ecx esi edi + xchg eax,esi + sub eax,esi + add ecx,eax + repe cmpsb + pop edi esi ecx + jne suffix_match_shifts_table_done + store_suffix_match_shift: + mov [ebx+256*4+(ecx-1)*4],edx + dec esi + dec edi + inc ecx + cmp ecx,[ebx] + jbe make_suffix_match_shifts_table + suffix_match_shifts_table_done: + pop eax + +find_next: + mov edi,[search_data] + or edi,edi + jz nothing_to_search_for + push [caret_line] + push [caret_line_number] + push [caret_position] + push [selection_position] + test [search_flags],FEFIND_BACKWARD + jnz search_backward + test [search_flags],FEFIND_INWHOLETEXT + jz search_for_text + mov eax,[first_line] + mov [caret_line],eax + xor eax,eax + mov [caret_position],eax + inc eax + mov [caret_line_number],eax + search_for_text: + mov ecx,[edi] + dec ecx + add ecx,[caret_position] + mov esi,[caret_line] + cmp ecx,[peak_line_length] + jae text_not_in_this_line + mov [caret_position],ecx + call get_caret_segment + mov edi,[search_data] + mov eax,[edi] + lea ebx,[edi+(256+eax)*4] + mov ah,[ebx+eax-1] + mov ebx,upper_case_table + search_in_line: + cmp edx,SEGMENT_DATA_LENGTH + jae text_not_in_this_line + mov al,[esi+SEGMENT_HEADER_LENGTH+edx] + test [search_flags],FEFIND_CASESENSITIVE + jnz compare_last_character + xlatb + compare_last_character: + cmp al,ah + je partial_match + mismatch_shift: + movzx ecx,al + mov ecx,[edi+ecx*4] + shift_search_position: + add edx,ecx + add ecx,[caret_position] + cmp ecx,[peak_line_length] + jae text_not_in_this_line + mov [caret_position],ecx + check_search_position: + cmp edx,SEGMENT_DATA_LENGTH + jb search_in_line + mov ecx,[esi] + btr ecx,0 + jnc search_in_line + sub edx,SEGMENT_DATA_LENGTH + mov esi,ecx + jmp check_search_position + partial_match: + mov ecx,[edi] + dec ecx + jz text_found + push edi + lea edi,[edi+(256+ecx+1)*4] + lea edi,[edi+ecx] + compare_text: + sub edx,1 + jc compare_in_previous_segment + dec edi + mov al,20h + cmp edx,SEGMENT_DATA_LENGTH + jae compare_character + mov al,[esi+SEGMENT_HEADER_LENGTH+edx] + test [search_flags],FEFIND_CASESENSITIVE + jnz compare_character + xlatb + compare_character: + cmp al,[edi] + loope compare_text + pop edi + je text_found + neg ecx + add ecx,[edi] + dec ecx + add edx,ecx + mov ecx,[edi+(256+ecx-1)*4] + jmp shift_search_position + compare_in_previous_segment: + mov esi,[esi+4] + and esi,not 1 + mov edx,SEGMENT_DATA_LENGTH + jmp compare_text + text_not_in_this_line: + mov esi,[esi] + or esi,esi + jz text_not_found + btr esi,0 + jc text_not_in_this_line + search_in_next_line: + mov [caret_line],esi + inc [caret_line_number] + mov [caret_position],0 + mov edi,[search_data] + jmp search_for_text + text_found: + mov eax,[caret_position] + inc eax + mov [selection_position],eax + sub eax,[edi] + mov [caret_position],eax + jz left_text_edge_ok + test [search_flags],FEFIND_WHOLEWORDS + jz left_text_edge_ok + mov edi,[search_data] + mov ecx,[edi] + mov al,[edi+(256+ecx)*4] + call recognize_character + jc left_text_edge_ok + dec [caret_position] + call get_caret_segment + inc [caret_position] + cmp edx,SEGMENT_DATA_LENGTH + jae left_text_edge_ok + mov al,[esi+SEGMENT_HEADER_LENGTH+edx] + call recognize_character + jnc found_not_acceptable + left_text_edge_ok: + mov eax,[caret_position] + xchg eax,[selection_position] + mov [caret_position],eax + mov edi,[search_data] + mov ecx,[edi] + lea edi,[edi+(256+ecx)*4] + mov al,[edi+ecx-1] + cmp al,20h + je right_text_edge_blank + test [search_flags],FEFIND_WHOLEWORDS + jz right_text_edge_ok + call recognize_character + jc right_text_edge_ok + call get_caret_segment + cmp edx,SEGMENT_DATA_LENGTH + jae right_text_edge_ok + mov al,[esi+SEGMENT_HEADER_LENGTH+edx] + call recognize_character + jc right_text_edge_ok + mov eax,[selection_position] + mov [caret_position],eax + found_not_acceptable: + mov edi,[search_data] + mov ecx,[edi] + mov eax,[edi+(256+ecx-1)*4] + add [caret_position],eax + jmp search_for_text + right_text_edge_blank: + call get_caret_segment + check_for_blank_end: + mov ecx,SEGMENT_DATA_LENGTH + sub ecx,edx + jz blank_end_next_segment + push edi + mov al,20h + lea edi,[esi+SEGMENT_HEADER_LENGTH+edx] + repe scasb + pop edi + jne right_text_edge_ok + blank_end_next_segment: + mov esi,[esi] + or esi,esi + jz text_not_found + btr esi,0 + jnc search_in_next_line + xor edx,edx + jmp check_for_blank_end + right_text_edge_ok: + mov eax,[caret_line] + mov ecx,[caret_line_number] + mov [selection_line],eax + mov [selection_line_number],ecx + and [search_flags],not FEFIND_INWHOLETEXT + add esp,16 + clc + retn + text_not_found: + pop [selection_position] + pop [caret_position] + pop [caret_line_number] + pop [caret_line] + nothing_to_search_for: + stc + retn + search_backward: + test [search_flags],FEFIND_INWHOLETEXT + jz backward_search_for_text + or eax,-1 + call find_line + mov [caret_line],esi + mov [caret_line_number],ecx + call move_to_line_end + backward_search_for_text: + mov ecx,[caret_position] + sub ecx,1 + jc backward_text_not_in_this_line + mov [caret_position],ecx + mov edi,[search_data] + mov eax,[edi] + mov al,[edi+(256+eax)*4] + cmp al,20h + jne backward_search_starting_position_ok + mov esi,[caret_line] + mov ecx,[esi+8] + mov edi,[search_data] + mov eax,[edi] + sub ecx,eax + jc backward_text_not_in_this_line + cmp ecx,[caret_position] + jae backward_search_starting_position_ok + mov [caret_position],ecx + backward_search_starting_position_ok: + call get_caret_segment + mov edi,[search_data] + mov eax,[edi] + lea ebx,[edi+(256+eax)*4] + mov ah,[ebx+eax-1] + mov ebx,upper_case_table + cmp edx,SEGMENT_DATA_LENGTH + jb backward_search_in_line + mov ecx,edx + sub ecx,SEGMENT_DATA_LENGTH-1 + sub edx,ecx + sub [caret_position],ecx + backward_search_in_line: + mov al,[esi+SEGMENT_HEADER_LENGTH+edx] + test [search_flags],FEFIND_CASESENSITIVE + jnz compare_first_character + xlatb + compare_first_character: + cmp al,ah + je backward_partial_match + backward_mismatch_shift: + movzx ecx,al + mov ecx,[edi+ecx*4] + shift_backward_search_position: + sub edx,ecx + sub [caret_position],ecx + jc backward_text_not_in_this_line + check_backward_search_position: + cmp edx,0 + jge backward_search_in_line + mov esi,[esi+4] + and esi,not 1 + add edx,SEGMENT_DATA_LENGTH + jmp check_backward_search_position + backward_partial_match: + mov ecx,[edi] + dec ecx + jz backward_text_found + push edi + lea edi,[edi+(256+ecx+1)*4] + lea edi,[edi+ecx] + backward_compare_text: + inc edx + cmp edx,SEGMENT_DATA_LENGTH + jae compare_in_next_segment + dec edi + mov al,[esi+SEGMENT_HEADER_LENGTH+edx] + test [search_flags],FEFIND_CASESENSITIVE + jnz backward_compare_character + xlatb + backward_compare_character: + cmp al,[edi] + loope backward_compare_text + pop edi + je backward_text_found + neg ecx + add ecx,[edi] + dec ecx + sub edx,ecx + mov ecx,[edi+(256+ecx)*4] + jmp shift_backward_search_position + compare_in_next_segment: + sub edx,SEGMENT_DATA_LENGTH + mov esi,[esi] + btr esi,0 + jnc compare_blank_space + dec edx + jmp backward_compare_text + compare_blank_space: + pop edi + cmp ecx,[edi] + jbe backward_text_found + backward_text_not_in_this_line: + mov esi,[caret_line] + mov esi,[esi+4] + or esi,esi + jz text_not_found + mov [caret_line],esi + dec [caret_line_number] + mov ecx,[peak_line_length] + mov [caret_position],ecx + jmp backward_search_for_text + backward_text_found: + test [search_flags],FEFIND_WHOLEWORDS + jz backward_left_text_edge_ok + cmp [caret_position],0 + je backward_left_text_edge_ok + mov edi,[search_data] + mov ecx,[edi] + lea edi,[edi+(256+ecx)*4] + mov al,[edi+ecx-1] + call recognize_character + jc backward_left_text_edge_ok + dec [caret_position] + call get_caret_segment + inc [caret_position] + cmp edx,SEGMENT_DATA_LENGTH + jae backward_left_text_edge_ok + mov al,[esi+SEGMENT_HEADER_LENGTH+edx] + call recognize_character + jnc backward_found_not_acceptable + backward_left_text_edge_ok: + mov eax,[caret_position] + mov [selection_position],eax + mov edi,[search_data] + mov ecx,[edi] + add eax,ecx + mov [caret_position],eax + test [search_flags],FEFIND_WHOLEWORDS + jz backward_right_text_edge_ok + mov al,[edi+(256+ecx)*4] + call recognize_character + jc backward_right_text_edge_ok + call get_caret_segment + cmp edx,SEGMENT_DATA_LENGTH + jae backward_right_text_edge_ok + mov al,[esi+SEGMENT_HEADER_LENGTH+edx] + call recognize_character + jc backward_right_text_edge_ok + mov eax,[selection_position] + mov [caret_position],eax + backward_found_not_acceptable: + mov edi,[search_data] + mov ecx,[edi] + mov eax,[edi+(256+ecx-1)*4] + sub [caret_position],eax + jbe backward_text_not_in_this_line + jmp backward_search_for_text + backward_right_text_edge_ok: + mov eax,[caret_position] + xchg eax,[selection_position] + mov [caret_position],eax + mov eax,[caret_line] + mov ecx,[caret_line_number] + mov [selection_line],eax + mov [selection_line_number],ecx + and [search_flags],not FEFIND_INWHOLETEXT + add esp,16 + clc + retn + +get_search_text_length: + mov ecx,[search_data] + test ecx,ecx + jz no_search_text + mov ecx,[ecx] + clc + retn +get_search_text: + mov esi,[search_data] + test esi,esi + jz no_search_text + mov ecx,[esi] + lea esi,[esi+(256+ecx)*4] + test [search_flags],FEFIND_BACKWARD + jnz copy_inverted_text + rep movsb + xor al,al + stosb + clc + retn + copy_inverted_text: + mov al,[esi+ecx-1] + stosb + loop copy_inverted_text + xor al,al + stosb + clc + retn + no_search_text: + stc + retn + +release_search_data: + mov edi,[search_data] + test edi,edi + jz search_data_released + mov ebx,[search_handle] + call release_memory + mov [search_data],0 + search_data_released: + retn diff --git a/toolchain/fasmw17332/SOURCE/IDE/UNDO.INC b/toolchain/fasmw17332/SOURCE/IDE/UNDO.INC new file mode 100644 index 0000000..65e2790 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/IDE/UNDO.INC @@ -0,0 +1,339 @@ + +; flat editor core +; Copyright (c) 1999-2015, Tomasz Grysztar. +; All rights reserved. + +store_status_for_undo: + pusha + test [editor_mode],FEMODE_NOUNDO + jnz undo_disabled + call clear_redo_data + call allocate_segment + jc not_enough_memory + mov dword [eax],0 + mov edi,eax + xchg eax,[undo_data] + push eax edi + call allocate_segment + pop edi + jnc store_editor_status + xor eax,eax + stosd + jmp not_enough_memory + store_editor_status: + mov dword [eax],0 + mov dword [eax+4],0 + stosd + pop eax + stosd + lea esi,[editor_status] + mov ecx,editor_status_size shr 2 + rep movsd + mov esi,[lengths_table] + store_lengths_table: + call store_segment_for_undo + mov esi,[esi] + or esi,esi + jnz store_lengths_table + popa + store_status_for_undo_ok: + retn + undo_disabled: + call clear_redo_data + call clear_undo_data + or [unmodified_state],-1 + popa + retn + +store_segment_for_undo: + pusha + or esi,esi + jz segment_for_undo_done + call clear_redo_data + mov esi,[undo_data] + or esi,esi + jz segment_for_undo_done + mov ebx,[esi] + mov eax,[esp+4] + call prepare_slot_for_undo_storage + jc segment_for_undo_done + push edi + call allocate_segment + pop edi + mov ebx,eax + stosd + mov eax,[esp+4] + stosd + jc memory_shortage + mov esi,eax + mov edi,ebx + mov ecx,SEGMENT_LENGTH shr 2 + rep movsd + segment_for_undo_done: + popa + store_segment_for_undo_ok: + retn + prepare_slot_for_undo_storage: + mov esi,[undo_data] + mov esi,[esi] + mov ecx,[esi+4] + lea edi,[esi+8] + repne scasd + jne get_free_slot + stc + retn + get_free_slot: + mov ecx,[esi+4] + lea edi,[esi+8+ecx*8] + inc ecx + cmp ecx,SEGMENT_DATA_LENGTH/8 + jbe slot_ok + push esi + call allocate_segment + jc memory_shortage + mov esi,eax + mov ebx,[undo_data] + mov [ebx],esi + pop dword [esi] + mov ecx,1 + lea edi,[esi+8] + slot_ok: + mov [esi+4],ecx + clc + retn + +store_allocated_segment_for_undo: + pusha + call clear_redo_data + mov eax,[esp+1Ch] + xor edx,edx + mov [eax],edx + mov esi,[undo_data] + or esi,esi + jz segment_for_undo_done + call prepare_slot_for_undo_storage + jc segment_for_undo_done + xor eax,eax + stosd + mov eax,[esp+1Ch] + stosd + popa + retn + +store_freed_segment_for_undo: + pusha + call clear_redo_data + mov esi,[undo_data] + or esi,esi + jz segment_for_undo_done + call prepare_slot_for_undo_storage + jc segment_for_undo_done + mov eax,[esp+4] + stosd + xor eax,eax + stosd + popa + retn + +undo_changes: + mov esi,[undo_data] + or esi,esi + jz undo_ok + mov ebx,[esi] + mov eax,[redo_data] + xchg eax,[esi+4] + mov [undo_data],eax + mov [redo_data],esi + add esi,8 + lea edi,[editor_status] + mov ecx,editor_status_size shr 2 + call exchange_data + xor edx,edx + segments_block: + or ebx,ebx + jz undo_finished + mov esi,ebx + xchg ebx,edx + xchg ebx,[esi] + add esi,4 + lodsd + mov ecx,eax + jecxz undo_finished + lea esi,[esi+ecx*8] + restore_segments: + sub esi,8 + push esi ecx + mov edi,[esi+4] + mov esi,[esi] + or edi,edi + jz restore_next + or esi,esi + jz restore_next + mov ecx,SEGMENT_LENGTH shr 2 + call exchange_data + restore_next: + pop ecx esi + loop restore_segments + jmp segments_block + undo_finished: + mov esi,[redo_data] + mov [esi],edx + undo_ok: + retn + exchange_data: + mov eax,[esi] + xchg eax,[edi] + mov [esi],eax + add esi,4 + add edi,4 + loop exchange_data + retn + +redo_changes: + mov esi,[redo_data] + or esi,esi + jz redo_ok + mov ebx,[esi] + mov eax,[undo_data] + xchg eax,[esi+4] + mov [redo_data],eax + mov [undo_data],esi + add esi,8 + lea edi,[editor_status] + mov ecx,editor_status_size shr 2 + call exchange_data + xor edx,edx + redo_segments_block: + or ebx,ebx + jz redo_finished + mov esi,ebx + xchg ebx,edx + xchg ebx,[esi] + add esi,4 + lodsd + mov ecx,eax + jecxz redo_finished + redo_segments: + push esi ecx + mov edi,[esi+4] + mov esi,[esi] + or edi,edi + jz redo_next + or esi,esi + jz redo_next + mov ecx,SEGMENT_LENGTH shr 2 + call exchange_data + redo_next: + pop ecx esi + add esi,8 + loop redo_segments + jmp redo_segments_block + redo_finished: + mov esi,[undo_data] + mov [esi],edx + redo_ok: + retn + +clear_redo_data: + mov esi,[redo_data] + or esi,esi + jz redo_data_ok + clear_redo_block: + or ebx,-1 + xchg ebx,[esi] + inc [released_segments] + mov eax,[esi+4] + mov [redo_data],eax + clear_redo_segments: + or ebx,ebx + jz next_redo_block + mov esi,ebx + or ebx,-1 + xchg ebx,[esi] + inc [released_segments] + add esi,4 + lodsd + mov ecx,eax + jecxz next_redo_block + release_redo_segments: + push esi ecx + mov edi,[esi+4] + mov esi,[esi] + or edi,edi + jz release_next_segment + or eax,-1 + or esi,esi + jnz release_data + xchg eax,[edi] + jmp data_released + release_data: + xchg eax,[esi] + data_released: + cmp eax,-1 + je release_next_segment + inc [released_segments] + release_next_segment: + pop ecx esi + add esi,8 + loop release_redo_segments + jmp clear_redo_segments + next_redo_block: + mov esi,[redo_data] + or esi,esi + je redo_data_ok + cmp esi,[unmodified_state] + jne clear_redo_block + mov [unmodified_state],-1 + jmp clear_redo_block + redo_data_ok: + retn + +clear_undo_data: + mov esi,[undo_data] + push esi + clear_undo_block: + or esi,esi + jz undo_data_ok + or ebx,-1 + xchg ebx,[esi] + inc [released_segments] + add esi,4 + lodsd + mov [undo_data],eax + clear_undo_segments: + or ebx,ebx + jz next_undo_block + mov esi,ebx + or ebx,-1 + xchg ebx,[esi] + inc [released_segments] + add esi,4 + lodsd + mov ecx,eax + jecxz next_undo_block + lea esi,[esi+ecx*8] + release_segments: + sub esi,8 + mov edx,[esi] + or edx,edx + jz release_next + or eax,-1 + xchg [edx],eax + cmp eax,-1 + je release_next + inc [released_segments] + release_next: + loop release_segments + next_undo_block: + mov esi,[undo_data] + cmp esi,[unmodified_state] + jne clear_undo_block + or [unmodified_state],-1 + jmp clear_undo_block + undo_data_ok: + pop esi + cmp esi,[unmodified_state] + jne unmodified_ok + mov [unmodified_state],0 + unmodified_ok: + retn diff --git a/toolchain/fasmw17332/SOURCE/IDE/VARIABLE.INC b/toolchain/fasmw17332/SOURCE/IDE/VARIABLE.INC new file mode 100644 index 0000000..88661d9 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/IDE/VARIABLE.INC @@ -0,0 +1,40 @@ + +; flat editor core +; Copyright (c) 1999-2015, Tomasz Grysztar. +; All rights reserved. + +editor_memory dd ? + +label editor_status + +first_line dd ? +lines_count dd ? +peak_line_length dd ? +maximum_position dd ? +window_line dd ? +window_position dd ? +window_line_number dd ? +caret_line dd ? +caret_position dd ? +caret_line_number dd ? +selection_line dd ? +selection_position dd ? +selection_line_number dd ? +editor_mode dd ? + +editor_status_size = $ - editor_status + +window_width dd ? +window_height dd ? +unallocated_segments dd ? +unallocated_segments_end dd ? +released_segments dd ? +memory_search_block dd ? +memory_search_segment dd ? +lengths_table dd ? +undo_data dd ? +redo_data dd ? +search_data dd ? +search_flags dd ? +search_handle dd ? +unmodified_state dd ? diff --git a/toolchain/fasmw17332/SOURCE/IDE/VERSION.INC b/toolchain/fasmw17332/SOURCE/IDE/VERSION.INC new file mode 100644 index 0000000..3afe63d --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/IDE/VERSION.INC @@ -0,0 +1,39 @@ + +; flat editor version 3.12 +; Copyright (c) 1999-2015, Tomasz Grysztar. +; All rights reserved. +; +; This programs is free for commercial and non-commercial use as long as +; the following conditions are adhered to. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +; PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; The licence and distribution terms for any publically available +; version or derivative of this code cannot be changed. i.e. this code +; cannot simply be copied and put under another distribution licence +; (including the GNU Public Licence). + +FEDIT_VERSION_STRING equ "3.12" + +FEDIT_VERSION_MAJOR = 3 +FEDIT_VERSION_MINOR = 12 diff --git a/toolchain/fasmw17332/SOURCE/LIBC/FASM.ASM b/toolchain/fasmw17332/SOURCE/LIBC/FASM.ASM new file mode 100644 index 0000000..e5bc329 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/LIBC/FASM.ASM @@ -0,0 +1,362 @@ + +; flat assembler interface for Unix/libc +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + + format ELF + public main + +macro ccall proc,[arg] + { common + local size + size = 0 + mov ebp,esp + if ~ arg eq + forward + size = size + 4 + common + sub esp,size + end if + and esp,-16 + if ~ arg eq + add esp,size + reverse + pushd arg + common + end if + call proc + mov esp,ebp } + +extrn gettimeofday + +section '.text' executable align 16 + +main: + mov ecx,[esp+4] + mov [argc],ecx + mov ebx,[esp+8] + mov [argv],ebx + push ebp + mov [stack_frame],esp + + mov [con_handle],1 + mov esi,_logo + call display_string + + call get_params + jc information + + call init_memory + + mov esi,_memory_prefix + call display_string + mov eax,[memory_end] + sub eax,[memory_start] + add eax,[additional_memory_end] + sub eax,[additional_memory] + shr eax,10 + call display_number + mov esi,_memory_suffix + call display_string + + ccall gettimeofday,buffer,0 + mov eax,dword [buffer] + mov ecx,1000 + mul ecx + mov ebx,eax + mov eax,dword [buffer+4] + div ecx + add eax,ebx + mov [start_time],eax + + and [preprocessing_done],0 + call preprocessor + or [preprocessing_done],-1 + call parser + call assembler + call formatter + + call display_user_messages + movzx eax,[current_pass] + inc eax + call display_number + mov esi,_passes_suffix + call display_string + ccall gettimeofday,buffer,0 + mov eax,dword [buffer] + mov ecx,1000 + mul ecx + mov ebx,eax + mov eax,dword [buffer+4] + div ecx + add eax,ebx + sub eax,[start_time] + jnc time_ok + add eax,3600000 + time_ok: + xor edx,edx + mov ebx,100 + div ebx + or eax,eax + jz display_bytes_count + xor edx,edx + mov ebx,10 + div ebx + push edx + call display_number + mov dl,'.' + call display_character + pop eax + call display_number + mov esi,_seconds_suffix + call display_string + display_bytes_count: + mov eax,[written_size] + call display_number + mov esi,_bytes_suffix + call display_string + xor al,al + jmp exit_program + +information: + mov esi,_usage + call display_string + mov al,1 + jmp exit_program + +get_params: + mov [input_file],0 + mov [output_file],0 + mov [symbols_file],0 + mov [memory_setting],0 + mov [passes_limit],100 + + mov ecx,[argc] + mov ebx,[argv] + add ebx,4 + dec ecx + jz bad_params + mov [definitions_pointer],predefinitions + get_param: + mov esi,[ebx] + mov al,[esi] + cmp al,'-' + je option_param + cmp [input_file],0 + jne get_output_file + mov [input_file],esi + jmp next_param + get_output_file: + cmp [output_file],0 + jne bad_params + mov [output_file],esi + jmp next_param + option_param: + inc esi + lodsb + cmp al,'m' + je memory_option + cmp al,'M' + je memory_option + cmp al,'p' + je passes_option + cmp al,'P' + je passes_option + cmp al,'d' + je definition_option + cmp al,'D' + je definition_option + cmp al,'s' + je symbols_option + cmp al,'S' + je symbols_option + bad_params: + stc + ret + memory_option: + cmp byte [esi],0 + jne get_memory_setting + dec ecx + jz bad_params + add ebx,4 + mov esi,[ebx] + get_memory_setting: + call get_option_value + or edx,edx + jz bad_params + cmp edx,1 shl (32-10) + jae bad_params + mov [memory_setting],edx + jmp next_param + passes_option: + cmp byte [esi],0 + jne get_passes_setting + dec ecx + jz bad_params + add ebx,4 + mov esi,[ebx] + get_passes_setting: + call get_option_value + or edx,edx + jz bad_params + cmp edx,10000h + ja bad_params + mov [passes_limit],dx + next_param: + add ebx,4 + dec ecx + jnz get_param + cmp [input_file],0 + je bad_params + mov eax,[definitions_pointer] + mov byte [eax],0 + mov [initial_definitions],predefinitions + clc + ret + definition_option: + cmp byte [esi],0 + jne get_definition + dec ecx + jz bad_params + add ebx,4 + mov esi,[ebx] + get_definition: + push edi + mov edi,[definitions_pointer] + call convert_definition_option + mov [definitions_pointer],edi + pop edi + jc bad_params + jmp next_param + symbols_option: + cmp byte [esi],0 + jne get_symbols_setting + dec ecx + jz bad_params + add ebx,4 + mov esi,[ebx] + get_symbols_setting: + mov [symbols_file],esi + jmp next_param + get_option_value: + xor eax,eax + mov edx,eax + get_option_digit: + lodsb + cmp al,20h + je option_value_ok + cmp al,0Dh + je option_value_ok + or al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + invalid_option_value: + stc + ret + convert_definition_option: + mov edx,edi + cmp edi,predefinitions+1000h + jae bad_definition_option + xor al,al + stosb + copy_definition_name: + lodsb + cmp al,'=' + je copy_definition_value + cmp al,20h + je bad_definition_option + or al,al + jz bad_definition_option + cmp edi,predefinitions+1000h + jae bad_definition_option + stosb + inc byte [edx] + jnz copy_definition_name + bad_definition_option: + stc + ret + copy_definition_value: + lodsb + cmp al,20h + je definition_value_end + or al,al + jz definition_value_end + cmp edi,predefinitions+1000h + jae bad_definition_option + stosb + jmp copy_definition_value + definition_value_end: + dec esi + cmp edi,predefinitions+1000h + jae bad_definition_option + xor al,al + stosb + clc + ret + +include 'system.inc' + +include '..\version.inc' + +_copyright db 'Copyright (c) 1999-2022, Tomasz Grysztar',0xA,0 + +_logo db 'flat assembler version ',VERSION_STRING,0 +_usage db 0xA + db 'usage: fasm [output]',0xA + db 'optional settings:',0xA + db ' -m set the limit in kilobytes for the available memory',0xA + db ' -p set the maximum allowed number of passes',0xA + db ' -d = define symbolic variable',0xA + db ' -s dump symbolic information for debugging',0xA + db 0 +_memory_prefix db ' (',0 +_memory_suffix db ' kilobytes memory)',0xA,0 +_passes_suffix db ' passes, ',0 +_seconds_suffix db ' seconds, ',0 +_bytes_suffix db ' bytes.',0xA,0 + +include '..\errors.inc' +include '..\symbdump.inc' +include '..\preproce.inc' +include '..\parser.inc' +include '..\exprpars.inc' +include '..\assemble.inc' +include '..\exprcalc.inc' +include '..\formats.inc' +include '..\x86_64.inc' +include '..\avx.inc' + +include '..\tables.inc' +include '..\messages.inc' + +section '.bss' writeable align 4 + +include '..\variable.inc' + +argc dd ? +argv dd ? +stack_frame dd ? +memory_setting dd ? +definitions_pointer dd ? +start_time dd ? +timestamp dq ? +con_handle dd ? +displayed_count dd ? +last_displayed db ? +character db ? +preprocessing_done db ? + +predefinitions rb 1000h +buffer rb 1000h diff --git a/toolchain/fasmw17332/SOURCE/LIBC/SYSTEM.INC b/toolchain/fasmw17332/SOURCE/LIBC/SYSTEM.INC new file mode 100644 index 0000000..5cf595d --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/LIBC/SYSTEM.INC @@ -0,0 +1,410 @@ + +; flat assembler interface for Unix/libc +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +extrn malloc +extrn free +extrn getenv +extrn fopen +extrn fclose +extrn fread +extrn fwrite +extrn fseek +extrn ftell +extrn time +extrn exit + +extrn 'write' as libc_write + +init_memory: + mov eax,esp + and eax,not 0FFFh + add eax,1000h-10000h + mov [stack_limit],eax + mov ecx,[memory_setting] + shl ecx,10 + jnz allocate_memory + mov ecx,1000000h + allocate_memory: + mov [memory_setting],ecx + ccall malloc,ecx + or eax,eax + jz out_of_memory + mov [additional_memory],eax + add eax,[memory_setting] + mov [memory_end],eax + mov eax,[memory_setting] + shr eax,2 + add eax,[additional_memory] + mov [additional_memory_end],eax + mov [memory_start],eax + ret + +exit_program: + movzx eax,al + push eax + ccall free,[additional_memory] + pop eax + ccall exit,eax + mov esp,[stack_frame] + pop ebp + ret + +get_environment_variable: + ccall getenv,esi + mov esi,eax + or eax,eax + jz no_environment_variable + copy_variable_value: + lodsb + cmp edi,[memory_end] + jae out_of_memory + stosb + or al,al + jnz copy_variable_value + dec edi + ret + no_environment_variable: + stosb + dec edi + ret + +open: + push esi edi ebp + call adapt_path + ccall fopen,buffer,open_mode + pop ebp edi esi + or eax,eax + jz file_error + mov ebx,eax + clc + ret + adapt_path: + mov esi,edx + mov edi,buffer + copy_path: + lods byte [esi] + cmp al,'\' + jne path_char_ok + mov al,'/' + path_char_ok: + stos byte [edi] + or al,al + jnz copy_path + cmp edi,buffer+1000h + ja out_of_memory + ret +create: + push esi edi ebp + call adapt_path + ccall fopen,buffer,create_mode + pop ebp edi esi + or eax,eax + jz file_error + mov ebx,eax + clc + ret +close: + ccall fclose,ebx + ret +read: + push ebx ecx edx esi edi ebp + ccall fread,edx,1,ecx,ebx + pop ebp edi esi edx ecx ebx + cmp eax,ecx + jne file_error + clc + ret + file_error: + stc + ret +write: + push ebx ecx edx esi edi ebp + ccall fwrite,edx,1,ecx,ebx + pop ebp edi esi edx ecx ebx + cmp eax,ecx + jne file_error + clc + ret +lseek: + push ebx + movzx eax,al + ccall fseek,ebx,edx,eax + test eax,eax + jnz lseek_error + mov ebx,[esp] + ccall ftell,ebx + pop ebx + clc + ret + lseek_error: + pop ebx + stc + ret + +display_string: + lodsb + or al,al + jz string_displayed + mov dl,al + call display_character + jmp display_string + string_displayed: + ret +display_character: + mov [character],dl + ccall libc_write,[con_handle],character,1 + ret +display_number: + push ebx + mov ecx,1000000000 + xor edx,edx + xor bl,bl + display_loop: + div ecx + push edx + cmp ecx,1 + je display_digit + or bl,bl + jnz display_digit + or al,al + jz digit_ok + not bl + display_digit: + mov dl,al + add dl,30h + push ebx ecx + call display_character + pop ecx ebx + digit_ok: + mov eax,ecx + xor edx,edx + mov ecx,10 + div ecx + mov ecx,eax + pop eax + or ecx,ecx + jnz display_loop + pop ebx + ret + +display_user_messages: + mov [displayed_count],0 + call show_display_buffer + cmp [displayed_count],0 + je line_break_ok + cmp [last_displayed],0Ah + je line_break_ok + mov dl,0Ah + call display_character + line_break_ok: + ret +display_block: + jecxz block_displayed + add [displayed_count],ecx + mov al,[esi+ecx-1] + mov [last_displayed],al + display_characters: + lodsb + mov dl,al + push ecx esi + call display_character + pop esi ecx + loop display_characters + block_displayed: + ret + +fatal_error: + mov [con_handle],2 + mov esi,error_prefix + call display_string + pop esi + call display_string + mov esi,error_suffix + call display_string + mov al,0FFh + jmp exit_program +assembler_error: + mov [con_handle],2 + call display_user_messages + mov ebx,[current_line] + test ebx,ebx + jz display_error_message + push dword 0 + get_error_lines: + mov eax,[ebx] + cmp byte [eax],0 + je get_next_error_line + push ebx + test byte [ebx+7],80h + jz display_error_line + mov edx,ebx + find_definition_origin: + mov edx,[edx+12] + test byte [edx+7],80h + jnz find_definition_origin + push edx + get_next_error_line: + mov ebx,[ebx+8] + jmp get_error_lines + display_error_line: + mov esi,[ebx] + call display_string + mov esi,line_number_start + call display_string + mov eax,[ebx+4] + and eax,7FFFFFFFh + call display_number + mov dl,']' + call display_character + pop esi + cmp ebx,esi + je line_number_ok + mov dl,20h + call display_character + push esi + mov esi,[esi] + movzx ecx,byte [esi] + inc esi + call display_block + mov esi,line_number_start + call display_string + pop esi + mov eax,[esi+4] + and eax,7FFFFFFFh + call display_number + mov dl,']' + call display_character + line_number_ok: + mov esi,line_data_start + call display_string + mov esi,ebx + mov edx,[esi] + call open + mov al,2 + xor edx,edx + call lseek + mov edx,[esi+8] + sub eax,edx + jz line_data_displayed + push eax + xor al,al + call lseek + mov ecx,[esp] + mov edx,[additional_memory] + lea eax,[edx+ecx] + cmp eax,[additional_memory_end] + ja out_of_memory + call read + call close + pop ecx + mov esi,[additional_memory] + get_line_data: + mov al,[esi] + cmp al,0Ah + je display_line_data + cmp al,0Dh + je display_line_data + cmp al,1Ah + je display_line_data + or al,al + jz display_line_data + inc esi + loop get_line_data + display_line_data: + mov ecx,esi + mov esi,[additional_memory] + sub ecx,esi + call display_block + line_data_displayed: + mov esi,lf + call display_string + pop ebx + or ebx,ebx + jnz display_error_line + cmp [preprocessing_done],0 + je display_error_message + mov esi,preprocessed_instruction_prefix + call display_string + mov esi,[current_line] + add esi,16 + mov edi,[additional_memory] + xor dl,dl + convert_instruction: + lodsb + cmp al,1Ah + je copy_symbol + cmp al,22h + je copy_symbol + cmp al,3Bh + je instruction_converted + stosb + or al,al + jz instruction_converted + xor dl,dl + jmp convert_instruction + copy_symbol: + or dl,dl + jz space_ok + mov byte [edi],20h + inc edi + space_ok: + cmp al,22h + je quoted + lodsb + movzx ecx,al + rep movsb + or dl,-1 + jmp convert_instruction + quoted: + mov al,27h + stosb + lodsd + mov ecx,eax + jecxz quoted_copied + copy_quoted: + lodsb + stosb + cmp al,27h + jne quote_ok + stosb + quote_ok: + loop copy_quoted + quoted_copied: + mov al,27h + stosb + or dl,-1 + jmp convert_instruction + instruction_converted: + xor al,al + stosb + mov esi,[additional_memory] + call display_string + mov esi,lf + call display_string + display_error_message: + mov esi,error_prefix + call display_string + pop esi + call display_string + mov esi,error_suffix + call display_string + mov al,2 + jmp exit_program + +make_timestamp: + ccall time,timestamp + mov eax,dword [timestamp] + mov edx,dword [timestamp+4] + ret + +open_mode db 'r',0 +create_mode db 'w',0 + +error_prefix db 'error: ',0 +error_suffix db '.' +lf db 0xA,0 +line_number_start db ' [',0 +line_data_start db ':',0xA,0 +preprocessed_instruction_prefix db 'processed: ',0 diff --git a/toolchain/fasmw17332/SOURCE/LINUX/FASM.ASM b/toolchain/fasmw17332/SOURCE/LINUX/FASM.ASM new file mode 100644 index 0000000..06e65bf --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/LINUX/FASM.ASM @@ -0,0 +1,341 @@ + +; flat assembler interface for Linux +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + + format ELF executable 3 + entry start + +segment readable executable + +start: + + mov [con_handle],1 + mov esi,_logo + call display_string + + mov [command_line],esp + mov ecx,[esp] + lea ebx,[esp+4+ecx*4+4] + mov [environment],ebx + call get_params + jc information + + call init_memory + + mov esi,_memory_prefix + call display_string + mov eax,[memory_end] + sub eax,[memory_start] + add eax,[additional_memory_end] + sub eax,[additional_memory] + shr eax,10 + call display_number + mov esi,_memory_suffix + call display_string + + mov eax,78 + mov ebx,buffer + xor ecx,ecx + int 0x80 + mov eax,dword [buffer] + mov ecx,1000 + mul ecx + mov ebx,eax + mov eax,dword [buffer+4] + div ecx + add eax,ebx + mov [start_time],eax + + and [preprocessing_done],0 + call preprocessor + or [preprocessing_done],-1 + call parser + call assembler + call formatter + + call display_user_messages + movzx eax,[current_pass] + inc eax + call display_number + mov esi,_passes_suffix + call display_string + mov eax,78 + mov ebx,buffer + xor ecx,ecx + int 0x80 + mov eax,dword [buffer] + mov ecx,1000 + mul ecx + mov ebx,eax + mov eax,dword [buffer+4] + div ecx + add eax,ebx + sub eax,[start_time] + jnc time_ok + add eax,3600000 + time_ok: + xor edx,edx + mov ebx,100 + div ebx + or eax,eax + jz display_bytes_count + xor edx,edx + mov ebx,10 + div ebx + push edx + call display_number + mov dl,'.' + call display_character + pop eax + call display_number + mov esi,_seconds_suffix + call display_string + display_bytes_count: + mov eax,[written_size] + call display_number + mov esi,_bytes_suffix + call display_string + xor al,al + jmp exit_program + +information: + mov esi,_usage + call display_string + mov al,1 + jmp exit_program + +get_params: + mov ebx,[command_line] + mov [input_file],0 + mov [output_file],0 + mov [symbols_file],0 + mov [memory_setting],0 + mov [passes_limit],100 + mov ecx,[ebx] + add ebx,8 + dec ecx + jz bad_params + mov [definitions_pointer],predefinitions + get_param: + mov esi,[ebx] + mov al,[esi] + cmp al,'-' + je option_param + cmp [input_file],0 + jne get_output_file + mov [input_file],esi + jmp next_param + get_output_file: + cmp [output_file],0 + jne bad_params + mov [output_file],esi + jmp next_param + option_param: + inc esi + lodsb + cmp al,'m' + je memory_option + cmp al,'M' + je memory_option + cmp al,'p' + je passes_option + cmp al,'P' + je passes_option + cmp al,'d' + je definition_option + cmp al,'D' + je definition_option + cmp al,'s' + je symbols_option + cmp al,'S' + je symbols_option + bad_params: + stc + ret + memory_option: + cmp byte [esi],0 + jne get_memory_setting + dec ecx + jz bad_params + add ebx,4 + mov esi,[ebx] + get_memory_setting: + call get_option_value + or edx,edx + jz bad_params + cmp edx,1 shl (32-10) + jae bad_params + mov [memory_setting],edx + jmp next_param + passes_option: + cmp byte [esi],0 + jne get_passes_setting + dec ecx + jz bad_params + add ebx,4 + mov esi,[ebx] + get_passes_setting: + call get_option_value + or edx,edx + jz bad_params + cmp edx,10000h + ja bad_params + mov [passes_limit],dx + next_param: + add ebx,4 + dec ecx + jnz get_param + cmp [input_file],0 + je bad_params + mov eax,[definitions_pointer] + mov byte [eax],0 + mov [initial_definitions],predefinitions + clc + ret + definition_option: + cmp byte [esi],0 + jne get_definition + dec ecx + jz bad_params + add ebx,4 + mov esi,[ebx] + get_definition: + push edi + mov edi,[definitions_pointer] + call convert_definition_option + mov [definitions_pointer],edi + pop edi + jc bad_params + jmp next_param + symbols_option: + cmp byte [esi],0 + jne get_symbols_setting + dec ecx + jz bad_params + add ebx,4 + mov esi,[ebx] + get_symbols_setting: + mov [symbols_file],esi + jmp next_param + get_option_value: + xor eax,eax + mov edx,eax + get_option_digit: + lodsb + cmp al,20h + je option_value_ok + or al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + invalid_option_value: + stc + ret + convert_definition_option: + mov edx,edi + cmp edi,predefinitions+1000h + jae bad_definition_option + xor al,al + stosb + copy_definition_name: + lodsb + cmp al,'=' + je copy_definition_value + cmp al,20h + je bad_definition_option + or al,al + jz bad_definition_option + cmp edi,predefinitions+1000h + jae bad_definition_option + stosb + inc byte [edx] + jnz copy_definition_name + bad_definition_option: + stc + ret + copy_definition_value: + lodsb + cmp al,20h + je definition_value_end + or al,al + jz definition_value_end + cmp edi,predefinitions+1000h + jae bad_definition_option + stosb + jmp copy_definition_value + definition_value_end: + dec esi + cmp edi,predefinitions+1000h + jae bad_definition_option + xor al,al + stosb + clc + ret + +include 'system.inc' + +include '..\version.inc' + +_copyright db 'Copyright (c) 1999-2022, Tomasz Grysztar',0xA,0 + +_logo db 'flat assembler version ',VERSION_STRING,0 +_usage db 0xA + db 'usage: fasm [output]',0xA + db 'optional settings:',0xA + db ' -m set the limit in kilobytes for the available memory',0xA + db ' -p set the maximum allowed number of passes',0xA + db ' -d = define symbolic variable',0xA + db ' -s dump symbolic information for debugging',0xA + db 0 +_memory_prefix db ' (',0 +_memory_suffix db ' kilobytes memory)',0xA,0 +_passes_suffix db ' passes, ',0 +_seconds_suffix db ' seconds, ',0 +_bytes_suffix db ' bytes.',0xA,0 + +include '..\errors.inc' +include '..\symbdump.inc' +include '..\preproce.inc' +include '..\parser.inc' +include '..\exprpars.inc' +include '..\assemble.inc' +include '..\exprcalc.inc' +include '..\formats.inc' +include '..\x86_64.inc' +include '..\avx.inc' + +include '..\tables.inc' +include '..\messages.inc' + +segment readable writeable + +align 4 + +include '..\variable.inc' + +command_line dd ? +memory_setting dd ? +definitions_pointer dd ? +environment dd ? +timestamp dq ? +start_time dd ? +con_handle dd ? +displayed_count dd ? +last_displayed db ? +character db ? +preprocessing_done db ? + +predefinitions rb 1000h +buffer rb 1000h diff --git a/toolchain/fasmw17332/SOURCE/LINUX/SYSTEM.INC b/toolchain/fasmw17332/SOURCE/LINUX/SYSTEM.INC new file mode 100644 index 0000000..29c16f8 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/LINUX/SYSTEM.INC @@ -0,0 +1,470 @@ + +; flat assembler interface for Linux +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +O_ACCMODE = 0003o +O_RDONLY = 0000o +O_WRONLY = 0001o +O_RDWR = 0002o +O_CREAT = 0100o +O_EXCL = 0200o +O_NOCTTY = 0400o +O_TRUNC = 1000o +O_APPEND = 2000o +O_NONBLOCK = 4000o + +S_ISUID = 4000o +S_ISGID = 2000o +S_ISVTX = 1000o +S_IRUSR = 0400o +S_IWUSR = 0200o +S_IXUSR = 0100o +S_IRGRP = 0040o +S_IWGRP = 0020o +S_IXGRP = 0010o +S_IROTH = 0004o +S_IWOTH = 0002o +S_IXOTH = 0001o + +init_memory: + mov eax,esp + and eax,not 0FFFh + add eax,1000h-10000h + mov [stack_limit],eax + xor ebx,ebx + mov eax,45 + int 0x80 + mov [additional_memory],eax + mov ecx,[memory_setting] + shl ecx,10 + jnz allocate_memory + mov ecx,1000000h + allocate_memory: + mov ebx,[additional_memory] + add ebx,ecx + mov eax,45 + int 0x80 + mov [memory_end],eax + sub eax,[additional_memory] + shr eax,2 + add eax,[additional_memory] + mov [additional_memory_end],eax + mov [memory_start],eax + ret + +exit_program: + movzx ebx,al + mov eax,1 + int 0x80 + +get_environment_variable: + mov ecx,esi + mov ebx,[environment] + next_variable: + mov esi,[ebx] + test esi,esi + jz no_environment_variable + add ebx,4 + compare_variable_names: + mov edx,ecx + compare_character: + lodsb + mov ah,[edx] + inc edx + cmp al,'=' + je end_of_variable_name + or ah,ah + jz next_variable + sub ah,al + jz compare_character + cmp ah,20h + jne next_variable + cmp al,41h + jb next_variable + cmp al,5Ah + jna compare_character + jmp next_variable + no_environment_variable: + ret + end_of_variable_name: + or ah,ah + jnz next_variable + copy_variable_value: + lodsb + cmp edi,[memory_end] + jae out_of_memory + stosb + or al,al + jnz copy_variable_value + dec edi + ret + +open: + push esi edi ebp + call adapt_path + mov eax,5 + mov ebx,buffer + mov ecx,O_RDONLY + xor edx,edx + int 0x80 + pop ebp edi esi + test eax,eax + js file_error + mov ebx,eax + clc + ret + adapt_path: + mov esi,edx + mov edi,buffer + copy_path: + lods byte [esi] + cmp al,'\' + jne path_char_ok + mov al,'/' + path_char_ok: + stos byte [edi] + or al,al + jnz copy_path + cmp edi,buffer+1000h + ja out_of_memory + ret +create: + push esi edi ebp edx + call adapt_path + mov ebx,buffer + mov ecx,O_CREAT+O_TRUNC+O_WRONLY + mov edx,S_IRUSR+S_IWUSR+S_IRGRP+S_IROTH + pop eax + cmp eax,[output_file] + jne do_create + cmp [output_format],5 + jne do_create + bt [format_flags],0 + jnc do_create + or edx,S_IXUSR+S_IXGRP+S_IXOTH + do_create: + mov eax,5 + int 0x80 + pop ebp edi esi + test eax,eax + js file_error + mov ebx,eax + clc + ret +close: + mov eax,6 + int 0x80 + ret +read: + push ecx edx esi edi ebp + mov eax,3 + xchg ecx,edx + int 0x80 + pop ebp edi esi edx ecx + test eax,eax + js file_error + cmp eax,ecx + jne file_error + clc + ret + file_error: + stc + ret +write: + push edx esi edi ebp + mov eax,4 + xchg ecx,edx + int 0x80 + pop ebp edi esi edx + test eax,eax + js file_error + clc + ret +lseek: + mov ecx,edx + xor edx,edx + mov dl,al + mov eax,19 + int 0x80 + cmp eax,-1 + je file_error + clc + ret + +display_string: + push ebx + mov edi,esi + mov edx,esi + or ecx,-1 + xor al,al + repne scasb + neg ecx + sub ecx,2 + mov eax,4 + mov ebx,[con_handle] + xchg ecx,edx + int 0x80 + pop ebx + ret +display_character: + push ebx + mov [character],dl + mov eax,4 + mov ebx,[con_handle] + mov ecx,character + mov edx,1 + int 0x80 + pop ebx + ret +display_number: + push ebx + mov ecx,1000000000 + xor edx,edx + xor bl,bl + display_loop: + div ecx + push edx + cmp ecx,1 + je display_digit + or bl,bl + jnz display_digit + or al,al + jz digit_ok + not bl + display_digit: + mov dl,al + add dl,30h + push ebx ecx + call display_character + pop ecx ebx + digit_ok: + mov eax,ecx + xor edx,edx + mov ecx,10 + div ecx + mov ecx,eax + pop eax + or ecx,ecx + jnz display_loop + pop ebx + ret + +display_user_messages: + mov [displayed_count],0 + call show_display_buffer + cmp [displayed_count],0 + je line_break_ok + cmp [last_displayed],0Ah + je line_break_ok + mov dl,0Ah + call display_character + line_break_ok: + ret +display_block: + jecxz block_displayed + add [displayed_count],ecx + mov al,[esi+ecx-1] + mov [last_displayed],al + push ebx + mov eax,4 + mov ebx,[con_handle] + mov edx,ecx + mov ecx,esi + int 0x80 + pop ebx + block_displayed: + ret + +fatal_error: + mov [con_handle],2 + mov esi,error_prefix + call display_string + pop esi + call display_string + mov esi,error_suffix + call display_string + mov al,0FFh + jmp exit_program +assembler_error: + mov [con_handle],2 + call display_user_messages + mov ebx,[current_line] + test ebx,ebx + jz display_error_message + pushd 0 + get_error_lines: + mov eax,[ebx] + cmp byte [eax],0 + je get_next_error_line + push ebx + test byte [ebx+7],80h + jz display_error_line + mov edx,ebx + find_definition_origin: + mov edx,[edx+12] + test byte [edx+7],80h + jnz find_definition_origin + push edx + get_next_error_line: + mov ebx,[ebx+8] + jmp get_error_lines + display_error_line: + mov esi,[ebx] + call display_string + mov esi,line_number_start + call display_string + mov eax,[ebx+4] + and eax,7FFFFFFFh + call display_number + mov dl,']' + call display_character + pop esi + cmp ebx,esi + je line_number_ok + mov dl,20h + call display_character + push esi + mov esi,[esi] + movzx ecx,byte [esi] + inc esi + call display_block + mov esi,line_number_start + call display_string + pop esi + mov eax,[esi+4] + and eax,7FFFFFFFh + call display_number + mov dl,']' + call display_character + line_number_ok: + mov esi,line_data_start + call display_string + mov esi,ebx + mov edx,[esi] + call open + mov al,2 + xor edx,edx + call lseek + mov edx,[esi+8] + sub eax,edx + jz line_data_displayed + push eax + xor al,al + call lseek + mov ecx,[esp] + mov edx,[additional_memory] + lea eax,[edx+ecx] + cmp eax,[additional_memory_end] + ja out_of_memory + call read + call close + pop ecx + mov esi,[additional_memory] + get_line_data: + mov al,[esi] + cmp al,0Ah + je display_line_data + cmp al,0Dh + je display_line_data + cmp al,1Ah + je display_line_data + or al,al + jz display_line_data + inc esi + loop get_line_data + display_line_data: + mov ecx,esi + mov esi,[additional_memory] + sub ecx,esi + call display_block + line_data_displayed: + mov esi,lf + call display_string + pop ebx + or ebx,ebx + jnz display_error_line + cmp [preprocessing_done],0 + je display_error_message + mov esi,preprocessed_instruction_prefix + call display_string + mov esi,[current_line] + add esi,16 + mov edi,[additional_memory] + xor dl,dl + convert_instruction: + lodsb + cmp al,1Ah + je copy_symbol + cmp al,22h + je copy_symbol + cmp al,3Bh + je instruction_converted + stosb + or al,al + jz instruction_converted + xor dl,dl + jmp convert_instruction + copy_symbol: + or dl,dl + jz space_ok + mov byte [edi],20h + inc edi + space_ok: + cmp al,22h + je quoted + lodsb + movzx ecx,al + rep movsb + or dl,-1 + jmp convert_instruction + quoted: + mov al,27h + stosb + lodsd + mov ecx,eax + jecxz quoted_copied + copy_quoted: + lodsb + stosb + cmp al,27h + jne quote_ok + stosb + quote_ok: + loop copy_quoted + quoted_copied: + mov al,27h + stosb + or dl,-1 + jmp convert_instruction + instruction_converted: + xor al,al + stosb + mov esi,[additional_memory] + call display_string + mov esi,lf + call display_string + display_error_message: + mov esi,error_prefix + call display_string + pop esi + call display_string + mov esi,error_suffix + call display_string + mov al,2 + jmp exit_program + +make_timestamp: + mov eax,13 + mov ebx,timestamp + int 0x80 + mov eax,dword [timestamp] + mov edx,dword [timestamp+4] + ret + +error_prefix db 'error: ',0 +error_suffix db '.' +lf db 0xA,0 +line_number_start db ' [',0 +line_data_start db ':',0xA,0 +preprocessed_instruction_prefix db 'processed: ',0 diff --git a/toolchain/fasmw17332/SOURCE/LINUX/X64/FASM.ASM b/toolchain/fasmw17332/SOURCE/LINUX/X64/FASM.ASM new file mode 100644 index 0000000..8c6170c --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/LINUX/X64/FASM.ASM @@ -0,0 +1,360 @@ + +; flat assembler interface for Linux x64 +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + + format ELF64 executable 3 at 400000h + entry start + + include 'modes.inc' + +segment readable executable + +start: + + mov [con_handle],1 + mov esi,_logo + call display_string + + mov [command_line],rsp + mov rcx,[rsp] + lea rbx,[rsp+8+rcx*8+8] + mov [environment],rbx + call get_params + jc information + + call init_memory + + mov esi,_memory_prefix + call display_string + mov eax,[memory_end] + sub eax,[memory_start] + add eax,[additional_memory_end] + sub eax,[additional_memory] + shr eax,10 + call display_number + mov esi,_memory_suffix + call display_string + + mov eax,96 + mov edi,buffer + xor esi,esi + syscall + mov eax,dword [buffer] + mov ecx,1000 + mul ecx + mov ebx,eax + mov eax,dword [buffer+4] + div ecx + add eax,ebx + mov [start_time],eax + + and [preprocessing_done],0 + call preprocessor + or [preprocessing_done],-1 + call parser + call assembler + call formatter + + call display_user_messages + movzx eax,[current_pass] + inc eax + call display_number + mov esi,_passes_suffix + call display_string + mov eax,96 + mov edi,buffer + xor esi,esi + syscall + mov eax,dword [buffer] + mov ecx,1000 + mul ecx + mov ebx,eax + mov eax,dword [buffer+4] + div ecx + add eax,ebx + sub eax,[start_time] + jnc time_ok + add eax,3600000 + time_ok: + xor edx,edx + mov ebx,100 + div ebx + or eax,eax + jz display_bytes_count + xor edx,edx + mov ebx,10 + div ebx + push edx + call display_number + mov dl,'.' + call display_character + pop eax + call display_number + mov esi,_seconds_suffix + call display_string + display_bytes_count: + mov eax,[written_size] + call display_number + mov esi,_bytes_suffix + call display_string + xor al,al + jmp exit_program + +information: + mov esi,_usage + call display_string + mov al,1 + jmp exit_program + +get_params: + mov rbx,[command_line] + mov [input_file],0 + mov [output_file],0 + mov [symbols_file],0 + mov [memory_setting],0 + mov [passes_limit],100 + mov rcx,[rbx] + add rbx,8*2 + dec rcx + jz bad_params + mov [definitions_pointer],predefinitions + mov [path_pointer],paths + get_param: + mov rsi,[rbx] + mov al,[rsi] + cmp al,'-' + je option_param + cmp [input_file],0 + jne get_output_file + call collect_path + mov [input_file],edx + jmp next_param + get_output_file: + cmp [output_file],0 + jne bad_params + call collect_path + mov [output_file],edx + jmp next_param + option_param: + inc rsi + lodsb + cmp al,'m' + je memory_option + cmp al,'M' + je memory_option + cmp al,'p' + je passes_option + cmp al,'P' + je passes_option + cmp al,'d' + je definition_option + cmp al,'D' + je definition_option + cmp al,'s' + je symbols_option + cmp al,'S' + je symbols_option + bad_params: + stc + ret + memory_option: + cmp byte [rsi],0 + jne get_memory_setting + dec rcx + jz bad_params + add rbx,8 + mov rsi,[rbx] + get_memory_setting: + call get_option_value + or edx,edx + jz bad_params + cmp edx,1 shl (32-10) + jae bad_params + mov [memory_setting],edx + jmp next_param + passes_option: + cmp byte [rsi],0 + jne get_passes_setting + dec rcx + jz bad_params + add rbx,8 + mov rsi,[rbx] + get_passes_setting: + call get_option_value + or edx,edx + jz bad_params + cmp edx,10000h + ja bad_params + mov [passes_limit],dx + next_param: + add rbx,8 + dec rcx + jnz get_param + cmp [input_file],0 + je bad_params + mov eax,[definitions_pointer] + mov byte [eax],0 + mov [initial_definitions],predefinitions + clc + ret + definition_option: + cmp byte [rsi],0 + jne get_definition + dec rcx + jz bad_params + add rbx,8 + mov rsi,[rbx] + get_definition: + mov r12d,edi + mov edi,[definitions_pointer] + call convert_definition_option + mov [definitions_pointer],edi + mov edi,r12d + jc bad_params + jmp next_param + symbols_option: + cmp byte [rsi],0 + jne get_symbols_setting + dec rcx + jz bad_params + add rbx,8 + mov rsi,[rbx] + get_symbols_setting: + call collect_path + mov [symbols_file],edx + jmp next_param + get_option_value: + xor eax,eax + mov edx,eax + get_option_digit: + lodsb + cmp al,20h + je option_value_ok + or al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec rsi + clc + ret + invalid_option_value: + stc + ret + convert_definition_option: + mov edx,edi + cmp edi,predefinitions+1000h + jae bad_definition_option + xor al,al + stosb + copy_definition_name: + lodsb + cmp al,'=' + je copy_definition_value + cmp al,20h + je bad_definition_option + or al,al + jz bad_definition_option + cmp edi,predefinitions+1000h + jae bad_definition_option + stosb + inc byte [edx] + jnz copy_definition_name + bad_definition_option: + stc + ret + copy_definition_value: + lodsb + cmp al,20h + je definition_value_end + or al,al + jz definition_value_end + cmp edi,predefinitions+1000h + jae bad_definition_option + stosb + jmp copy_definition_value + definition_value_end: + dec rsi + cmp edi,predefinitions+1000h + jae bad_definition_option + xor al,al + stosb + clc + ret +collect_path: + mov edi,[path_pointer] + mov edx,edi + copy_path_to_low_memory: + lodsb + stosb + test al,al + jnz copy_path_to_low_memory + mov [path_pointer],edi + retn + +include 'system.inc' + +include '..\..\version.inc' + +_copyright db 'Copyright (c) 1999-2022, Tomasz Grysztar',0xA,0 + +_logo db 'flat assembler version ',VERSION_STRING,0 +_usage db 0xA + db 'usage: fasm [output]',0xA + db 'optional settings:',0xA + db ' -m set the limit in kilobytes for the available memory',0xA + db ' -p set the maximum allowed number of passes',0xA + db ' -d = define symbolic variable',0xA + db ' -s dump symbolic information for debugging',0xA + db 0 +_memory_prefix db ' (',0 +_memory_suffix db ' kilobytes memory, x64)',0xA,0 +_passes_suffix db ' passes, ',0 +_seconds_suffix db ' seconds, ',0 +_bytes_suffix db ' bytes.',0xA,0 +_no_low_memory db 'failed to allocate memory within 32-bit addressing range',0 + +include '..\..\errors.inc' +include '..\..\symbdump.inc' +include '..\..\preproce.inc' +include '..\..\parser.inc' +include '..\..\exprpars.inc' +include '..\..\assemble.inc' +include '..\..\exprcalc.inc' +include '..\..\x86_64.inc' +include '..\..\avx.inc' +include '..\..\formats.inc' + +include '..\..\tables.inc' +include '..\..\messages.inc' + +segment readable writeable + +align 4 + +include '..\..\variable.inc' + +command_line dq ? +memory_setting dd ? +path_pointer dd ? +definitions_pointer dd ? +environment dq ? +timestamp dq ? +start_time dd ? +con_handle dd ? +displayed_count dd ? +last_displayed db ? +character db ? +preprocessing_done db ? + +buffer rb 1000h +predefinitions rb 1000h +paths rb 10000h diff --git a/toolchain/fasmw17332/SOURCE/LINUX/X64/MODES.INC b/toolchain/fasmw17332/SOURCE/LINUX/X64/MODES.INC new file mode 100644 index 0000000..5e681f9 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/LINUX/X64/MODES.INC @@ -0,0 +1,186 @@ + +; flat assembler interface for Linux x64 +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +esp equ +rsp + +macro pushD [arg] +{ + common + local offset,total + offset = 0 + lea rsp,[rsp-total] + forward + offset = offset + 4 + if arg eqtype eax + mov dword [rsp+total-offset],arg + else + mov r8d,dword arg + mov [rsp+total-offset],r8d + end if + common + total = offset +} + +macro popD [arg] +{ + common + local offset + offset = 0 + forward + if arg eqtype [mem] + mov r8d,[rsp+offset] + mov dword arg,r8d + else + mov arg,dword [rsp+offset] + end if + offset = offset + 4 + common + lea rsp,[rsp+offset] +} + +macro add dest,src +{ + if dest eq esp + add rsp,src + else + add dest,src + end if +} + +macro mov dest,src +{ + if src eq esp + mov dest,ESP + else + mov dest,src + end if +} + +macro cmp dest,src +{ + if dest eq esp + cmp ESP,src + else + cmp dest,src + end if +} + +macro use32 +{ + + macro push args + \{ + local list,arg,status + define list + define arg + irps sym, args \\{ + define status + match =dword, sym \\\{ + define status : + \\\} + match [any, status arg sym \\\{ + define arg [any + match [mem], arg \\\\{ + match previous, list \\\\\{ define list previous,[mem] \\\\\} + match , list \\\\\{ define list [mem] \\\\\} + define arg + \\\\} + define status : + \\\} + match [, status arg sym \\\{ + define arg [ + define status : + \\\} + match , status \\\{ + match previous, list \\\\{ define list previous,sym \\\\} + match , list \\\\{ define list sym \\\\} + \\\} + \\} + match arg, list \\{ pushD arg \\} + \} + + macro pop args + \{ + local list,arg,status + define list + define arg + irps sym, args \\{ + define status + match =dword, sym \\\{ + define status : + \\\} + match [any, status arg sym \\\{ + define arg [any + match [mem], arg \\\\{ + match previous, list \\\\\{ define list previous,[mem] \\\\\} + match , list \\\\\{ define list [mem] \\\\\} + define arg + \\\\} + define status : + \\\} + match [, status arg sym \\\{ + define arg [ + define status : + \\\} + match , status \\\{ + match previous, list \\\\{ define list previous,sym \\\\} + match , list \\\\{ define list sym \\\\} + \\\} + \\} + match arg, list \\{ popD arg \\} + \} + + macro jmp arg + \{ + if arg eq near eax + jmp near rax + else if arg eq near edx + jmp near rdx + else if arg eqtype [mem] + mov r8d,arg + jmp near r8 + else + jmp arg + end if + \} + + macro call arg + \{ + if 1 + match =near =dword [mem], arg \\{ + mov r8d,[mem] + call near r8 + else + \\} + call arg + end if + \} + + macro salc ; for fasm's core it does not need to preserve flags + \{ + setc al + neg al + \} + + macro jcxz target ; for fasm's core it does not need to preserve flags + \{ + test cx,cx + jz target + \} + + use64 + +} + +macro use16 +{ + + purge push,pop,jmp,call,salc,jcxz + + use16 + +} + +use32 diff --git a/toolchain/fasmw17332/SOURCE/LINUX/X64/SYSTEM.INC b/toolchain/fasmw17332/SOURCE/LINUX/X64/SYSTEM.INC new file mode 100644 index 0000000..fd7a00e --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/LINUX/X64/SYSTEM.INC @@ -0,0 +1,548 @@ + +; flat assembler interface for Linux x64 +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +O_ACCMODE = 0003o +O_RDONLY = 0000o +O_WRONLY = 0001o +O_RDWR = 0002o +O_CREAT = 0100o +O_EXCL = 0200o +O_NOCTTY = 0400o +O_TRUNC = 1000o +O_APPEND = 2000o +O_NONBLOCK = 4000o + +S_ISUID = 4000o +S_ISGID = 2000o +S_ISVTX = 1000o +S_IRUSR = 0400o +S_IWUSR = 0200o +S_IXUSR = 0100o +S_IRGRP = 0040o +S_IWGRP = 0020o +S_IXGRP = 0010o +S_IROTH = 0004o +S_IWOTH = 0002o +S_IXOTH = 0001o + +init_memory: + mov eax,esp + and eax,not 0FFFh + add eax,1000h-10000h + mov [stack_limit],eax + xor edi,edi + mov eax,12 + syscall + mov ecx,[memory_setting] + shl ecx,10 + jnz allocate_memory + mov ecx,1000000h + allocate_memory: + mov r9d,eax + cmp rax,r9 + jne high_brk + mov [additional_memory],eax + lea edi,[eax+ecx] + mov eax,12 + syscall + mov r9d,eax + cmp rax,r9 + jne no_low_memory + mov [memory_end],eax + sub eax,[additional_memory] + shr eax,2 + add eax,[additional_memory] + mov [additional_memory_end],eax + mov [memory_start],eax + ret + high_brk: + xor r9d,r9d + or r8,-1 + mov r10d,62h ; MAP_PRIVATE + MAP_ANONYMOUS + MAP_32BIT + mov edx,3 ; PROT_READ + PROT_WRITE + mov esi,ecx + xor edi,edi + mov eax,9 ; sys_mmap + syscall + cmp eax,-1 + je mmap_with_hint + mov r9d,eax + cmp rax,r9 + jne mmap_unusable + add r9d,esi + jnc mmap_ok + mmap_unusable: + mov rdi,rax + mov eax,11 ; sys_munmap + syscall + mmap_with_hint: + mov r10d,22h ; MAP_PRIVATE + MAP_ANONYMOUS + mov edx,3 ; PROT_READ + PROT_WRITE + mov edi,480000h + mov eax,9 ; sys_mmap + syscall + cmp eax,-1 + je no_low_memory + mov r9d,eax + cmp rax,r9 + jne no_low_memory + add r9d,esi + jnc mmap_ok + no_low_memory: + mov esi,lf + call display_string + push _no_low_memory + jmp fatal_error + mmap_ok: + mov [additional_memory],eax + lea edi,[eax+esi] + mov [memory_end],edi + shr esi,2 + add eax,esi + mov [additional_memory_end],eax + mov [memory_start],eax + ret + +exit_program: + movzx edi,al + mov eax,60 + syscall + +get_environment_variable: + mov ecx,esi + mov rbx,[environment] + next_variable: + mov rsi,[rbx] + test rsi,rsi + jz no_environment_variable + add rbx,8 + compare_variable_names: + mov edx,ecx + compare_character: + lodsb + mov ah,[edx] + inc edx + cmp al,'=' + je end_of_variable_name + or ah,ah + jz next_variable + sub ah,al + jz compare_character + cmp ah,20h + jne next_variable + cmp al,41h + jb next_variable + cmp al,5Ah + jna compare_character + jmp next_variable + no_environment_variable: + ret + end_of_variable_name: + or ah,ah + jnz next_variable + copy_variable_value: + lodsb + cmp edi,[memory_end] + jae out_of_memory + stosb + or al,al + jnz copy_variable_value + dec edi + ret + +open: + mov r12d,esi + mov r13d,edi + call adapt_path + mov eax,2 + mov edi,buffer + mov esi,O_RDONLY + xor edx,edx + syscall + mov esi,r12d + mov edi,r13d + test eax,eax + js file_error + mov ebx,eax + clc + ret + adapt_path: + mov esi,edx + mov edi,buffer + copy_path: + lods byte [esi] + cmp al,'\' + jne path_char_ok + mov al,'/' + path_char_ok: + stos byte [edi] + or al,al + jnz copy_path + cmp edi,buffer+1000h + ja out_of_memory + ret +create: + mov r12d,esi + mov r13d,edi + mov r15d,edx + call adapt_path + mov edi,buffer + mov esi,O_CREAT+O_TRUNC+O_WRONLY + mov edx,S_IRUSR+S_IWUSR+S_IRGRP+S_IROTH + cmp r15d,[output_file] + jne do_create + cmp [output_format],5 + jne do_create + bt [format_flags],0 + jnc do_create + or edx,S_IXUSR+S_IXGRP+S_IXOTH + do_create: + mov eax,2 + syscall + mov esi,r12d + mov edi,r13d + test eax,eax + js file_error + mov ebx,eax + clc + ret +close: + mov r13d,edi + mov edi,ebx + mov eax,3 + syscall + mov edi,r13d + ret +read: + mov r12d,esi + mov r13d,edi + mov eax,0 + mov edi,ebx + mov esi,edx + mov edx,ecx + syscall + mov ecx,edx + mov edx,esi + mov esi,r12d + mov edi,r13d + test eax,eax + js file_error + cmp eax,ecx + jne file_error + clc + ret + file_error: + stc + ret +write: + mov r12d,esi + mov r13d,edi + mov eax,1 + mov edi,ebx + mov esi,edx + mov edx,ecx + syscall + mov ecx,edx + mov edx,esi + mov esi,r12d + mov edi,r13d + test eax,eax + js file_error + clc + ret +lseek: + mov r12d,esi + mov r13d,edi + mov edi,ebx + mov esi,edx + xor edx,edx + mov dl,al + mov eax,8 + syscall + mov esi,r12d + mov edi,r13d + cmp eax,-1 + je file_error + clc + ret + +display_string: + mov edi,esi + mov edx,esi + or ecx,-1 + xor al,al + repne scasb + neg ecx + sub ecx,2 + mov eax,1 + mov edi,[con_handle] + mov esi,edx + mov edx,ecx + syscall + ret +display_character: + mov r12d,esi + mov r13d,edi + mov [character],dl + mov eax,1 + mov edi,[con_handle] + mov esi,character + mov edx,1 + syscall + mov esi,r12d + mov edi,r13d + ret +display_number: + mov r14d,ebx + mov ecx,1000000000 + xor edx,edx + xor bl,bl + display_loop: + div ecx + mov r15d,edx + cmp ecx,1 + je display_digit + or bl,bl + jnz display_digit + or al,al + jz digit_ok + not bl + display_digit: + mov dl,al + add dl,30h + mov r10d,ecx + call display_character + mov ecx,r10d + digit_ok: + mov eax,ecx + xor edx,edx + mov ecx,10 + div ecx + mov ecx,eax + mov eax,r15d + or ecx,ecx + jnz display_loop + mov ebx,r14d + ret + +display_user_messages: + mov [displayed_count],0 + call show_display_buffer + cmp [displayed_count],0 + je line_break_ok + cmp [last_displayed],0Ah + je line_break_ok + mov dl,0Ah + call display_character + line_break_ok: + ret +display_block: + jecxz block_displayed + add [displayed_count],ecx + mov al,[esi+ecx-1] + mov [last_displayed],al + mov r13d,edi + mov eax,1 + mov edi,[con_handle] + mov edx,ecx + syscall + mov edi,r13d + block_displayed: + ret + +fatal_error: + mov [con_handle],2 + mov esi,error_prefix + call display_string + pop esi + call display_string + mov esi,error_suffix + call display_string + mov al,0FFh + jmp exit_program +assembler_error: + mov [con_handle],2 + call display_user_messages + mov ebx,[current_line] + test ebx,ebx + jz display_error_message + push dword 0 + get_error_lines: + mov eax,[ebx] + cmp byte [eax],0 + je get_next_error_line + push ebx + test byte [ebx+7],80h + jz display_error_line + mov edx,ebx + find_definition_origin: + mov edx,[edx+12] + test byte [edx+7],80h + jnz find_definition_origin + push edx + get_next_error_line: + mov ebx,[ebx+8] + jmp get_error_lines + display_error_line: + mov esi,[ebx] + call display_string + mov esi,line_number_start + call display_string + mov eax,[ebx+4] + and eax,7FFFFFFFh + call display_number + mov dl,']' + call display_character + pop esi + cmp ebx,esi + je line_number_ok + mov dl,20h + call display_character + push esi + mov esi,[esi] + movzx ecx,byte [esi] + inc esi + call display_block + mov esi,line_number_start + call display_string + pop esi + mov eax,[esi+4] + and eax,7FFFFFFFh + call display_number + mov dl,']' + call display_character + line_number_ok: + mov esi,line_data_start + call display_string + mov esi,ebx + mov edx,[esi] + call open + mov al,2 + xor edx,edx + call lseek + mov edx,[esi+8] + sub eax,edx + jz line_data_displayed + push eax + xor al,al + call lseek + mov ecx,[esp] + mov edx,[additional_memory] + lea eax,[edx+ecx] + cmp eax,[additional_memory_end] + ja out_of_memory + call read + call close + pop ecx + mov esi,[additional_memory] + get_line_data: + mov al,[esi] + cmp al,0Ah + je display_line_data + cmp al,0Dh + je display_line_data + cmp al,1Ah + je display_line_data + or al,al + jz display_line_data + inc esi + loop get_line_data + display_line_data: + mov ecx,esi + mov esi,[additional_memory] + sub ecx,esi + call display_block + line_data_displayed: + mov esi,lf + call display_string + pop ebx + or ebx,ebx + jnz display_error_line + cmp [preprocessing_done],0 + je display_error_message + mov esi,preprocessed_instruction_prefix + call display_string + mov esi,[current_line] + add esi,16 + mov edi,[additional_memory] + xor dl,dl + convert_instruction: + lodsb + cmp al,1Ah + je copy_symbol + cmp al,22h + je copy_symbol + cmp al,3Bh + je instruction_converted + stosb + or al,al + jz instruction_converted + xor dl,dl + jmp convert_instruction + copy_symbol: + or dl,dl + jz space_ok + mov byte [edi],20h + inc edi + space_ok: + cmp al,22h + je quoted + lodsb + movzx ecx,al + rep movsb + or dl,-1 + jmp convert_instruction + quoted: + mov al,27h + stosb + lodsd + mov ecx,eax + jecxz quoted_copied + copy_quoted: + lodsb + stosb + cmp al,27h + jne quote_ok + stosb + quote_ok: + loop copy_quoted + quoted_copied: + mov al,27h + stosb + or dl,-1 + jmp convert_instruction + instruction_converted: + xor al,al + stosb + mov esi,[additional_memory] + call display_string + mov esi,lf + call display_string + display_error_message: + mov esi,error_prefix + call display_string + pop esi + call display_string + mov esi,error_suffix + call display_string + mov al,2 + jmp exit_program + +make_timestamp: + mov r13d,edi + mov eax,201 + mov edi,timestamp + syscall + mov eax,dword [timestamp] + mov edx,dword [timestamp+4] + mov edi,r13d + ret + +error_prefix db 'error: ',0 +error_suffix db '.' +lf db 0xA,0 +line_number_start db ' [',0 +line_data_start db ':',0xA,0 +preprocessed_instruction_prefix db 'processed: ',0 diff --git a/toolchain/fasmw17332/SOURCE/MESSAGES.INC b/toolchain/fasmw17332/SOURCE/MESSAGES.INC new file mode 100644 index 0000000..2180421 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/MESSAGES.INC @@ -0,0 +1,51 @@ + +; flat assembler core +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +_out_of_memory db 'out of memory',0 +_stack_overflow db 'out of stack space',0 +_main_file_not_found db 'source file not found',0 +_code_cannot_be_generated db 'code cannot be generated',0 +_format_limitations_exceeded db 'format limitations exceeded',0 +_invalid_definition db 'invalid definition provided',0 +_write_failed db 'write failed',0 +_file_not_found db 'file not found',0 +_error_reading_file db 'error reading file',0 +_invalid_file_format db 'invalid file format',0 +_invalid_macro_arguments db 'invalid macro arguments',0 +_incomplete_macro db 'incomplete macro',0 +_unexpected_characters db 'unexpected characters',0 +_invalid_argument db 'invalid argument',0 +_illegal_instruction db 'illegal instruction',0 +_invalid_operand db 'invalid operand',0 +_invalid_operand_size db 'invalid size of operand',0 +_operand_size_not_specified db 'operand size not specified',0 +_operand_sizes_do_not_match db 'operand sizes do not match',0 +_invalid_address_size db 'invalid size of address value',0 +_address_sizes_do_not_agree db 'address sizes do not agree',0 +_disallowed_combination_of_registers db 'disallowed combination of registers',0 +_long_immediate_not_encodable db 'not encodable with long immediate',0 +_relative_jump_out_of_range db 'relative jump out of range',0 +_invalid_expression db 'invalid expression',0 +_invalid_address db 'invalid address',0 +_invalid_value db 'invalid value',0 +_value_out_of_range db 'value out of range',0 +_undefined_symbol db 'undefined symbol',0 +_symbol_out_of_scope_1 db 'symbol',0 +_symbol_out_of_scope_2 db 'out of scope',0 +_invalid_use_of_symbol db 'invalid use of symbol',0 +_name_too_long db 'name too long',0 +_invalid_name db 'invalid name',0 +_reserved_word_used_as_symbol db 'reserved word used as symbol',0 +_symbol_already_defined db 'symbol already defined',0 +_missing_end_quote db 'missing end quote',0 +_missing_end_directive db 'missing end directive',0 +_unexpected_instruction db 'unexpected instruction',0 +_extra_characters_on_line db 'extra characters on line',0 +_section_not_aligned_enough db 'section is not aligned enough',0 +_setting_already_specified db 'setting already specified',0 +_data_already_defined db 'data already defined',0 +_too_many_repeats db 'too many repeats',0 +_invoked_error db 'error directive encountered in source file',0 +_assertion_failed db 'assertion failed',0 diff --git a/toolchain/fasmw17332/SOURCE/PARSER.INC b/toolchain/fasmw17332/SOURCE/PARSER.INC new file mode 100644 index 0000000..a4b66b0 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/PARSER.INC @@ -0,0 +1,1470 @@ + +; flat assembler core +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +parser: + mov eax,[memory_end] + mov [labels_list],eax + mov eax,[additional_memory] + mov [free_additional_memory],eax + xor eax,eax + mov [current_locals_prefix],eax + mov [anonymous_reverse],eax + mov [anonymous_forward],eax + mov [hash_tree],eax + mov [blocks_stack],eax + mov [parsed_lines],eax + mov esi,[memory_start] + mov edi,[source_start] + parser_loop: + mov [current_line],esi + lea eax,[edi+100h] + cmp eax,[labels_list] + jae out_of_memory + cmp byte [esi+16],0 + je empty_line + cmp byte [esi+16],3Bh + je empty_line + mov al,0Fh + stos byte [edi] + mov eax,esi + stos dword [edi] + inc [parsed_lines] + add esi,16 + parse_line: + mov [formatter_symbols_allowed],0 + mov [decorator_symbols_allowed],0 + cmp byte [esi],1Ah + jne empty_instruction + push edi + add esi,2 + movzx ecx,byte [esi-1] + cmp byte [esi+ecx],':' + je simple_label + cmp byte [esi+ecx],'=' + je constant_label + call get_instruction + jnc main_instruction_identified + cmp byte [esi+ecx],1Ah + jne no_data_label + push esi ecx + lea esi,[esi+ecx+2] + movzx ecx,byte [esi-1] + call get_data_directive + jnc data_label + pop ecx esi + no_data_label: + call get_data_directive + jnc main_instruction_identified + pop edi + sub esi,2 + xor bx,bx + call parse_line_contents + jmp parse_next_line + simple_label: + pop edi + call identify_label + cmp byte [esi+1],':' + je block_label + mov byte [edi],2 + inc edi + stos dword [edi] + inc esi + xor al,al + stos byte [edi] + jmp parse_line + block_label: + mov byte [edi],4 + inc edi + stos dword [edi] + add esi,2 + jmp parse_line + constant_label: + pop edi + call get_label_id + mov byte [edi],3 + inc edi + stos dword [edi] + xor al,al + stos byte [edi] + inc esi + xor bx,bx + call parse_line_contents + jmp parse_next_line + data_label: + pop ecx edx + pop edi + push eax ebx esi + mov esi,edx + movzx ecx,byte [esi-1] + call identify_label + mov byte [edi],2 + inc edi + stos dword [edi] + pop esi ebx eax + stos byte [edi] + push edi + main_instruction_identified: + pop edi + mov dl,al + mov al,1 + stos byte [edi] + mov ax,bx + stos word [edi] + mov al,dl + stos byte [edi] + cmp bx,if_directive-instruction_handler + je parse_block + cmp bx,repeat_directive-instruction_handler + je parse_block + cmp bx,while_directive-instruction_handler + je parse_block + cmp bx,end_directive-instruction_handler + je parse_end_directive + cmp bx,else_directive-instruction_handler + je parse_else + cmp bx,assert_directive-instruction_handler + je parse_assert + common_parse: + call parse_line_contents + jmp parse_next_line + empty_instruction: + lods byte [esi] + or al,al + jz parse_next_line + cmp al,':' + je invalid_name + dec esi + mov [parenthesis_stack],0 + call parse_argument + jmp parse_next_line + empty_line: + add esi,16 + skip_rest_of_line: + call skip_foreign_line + parse_next_line: + cmp esi,[source_start] + jb parser_loop + source_parsed: + cmp [blocks_stack],0 + je blocks_stack_ok + pop eax + pop [current_line] + jmp missing_end_directive + blocks_stack_ok: + xor al,al + stos byte [edi] + add edi,0Fh + and edi,not 0Fh + mov [code_start],edi + ret + parse_block: + mov eax,esp + sub eax,[stack_limit] + cmp eax,100h + jb stack_overflow + push [current_line] + mov ax,bx + shl eax,16 + push eax + inc [blocks_stack] + cmp bx,if_directive-instruction_handler + je parse_if + cmp bx,while_directive-instruction_handler + je parse_while + call parse_line_contents + jmp parse_next_line + parse_end_directive: + cmp byte [esi],1Ah + jne common_parse + push edi + inc esi + movzx ecx,byte [esi] + inc esi + call get_instruction + pop edi + jnc parse_end_block + sub esi,2 + jmp common_parse + parse_end_block: + mov dl,al + mov al,1 + stos byte [edi] + mov ax,bx + stos word [edi] + mov al,dl + stos byte [edi] + lods byte [esi] + or al,al + jnz extra_characters_on_line + cmp bx,if_directive-instruction_handler + je close_parsing_block + cmp bx,repeat_directive-instruction_handler + je close_parsing_block + cmp bx,while_directive-instruction_handler + je close_parsing_block + jmp parse_next_line + close_parsing_block: + cmp [blocks_stack],0 + je unexpected_instruction + cmp bx,[esp+2] + jne unexpected_instruction + dec [blocks_stack] + pop eax edx + cmp bx,if_directive-instruction_handler + jne parse_next_line + test al,1100b + jz parse_next_line + test al,10000b + jnz parse_next_line + sub edi,8 + jmp parse_next_line + parse_if: + push edi + call parse_line_contents + xor al,al + stos byte [edi] + xchg esi,[esp] + mov edi,esi + call preevaluate_logical_expression + pop esi + cmp al,'0' + je parse_false_condition_block + cmp al,'1' + je parse_true_condition_block + or byte [esp],10000b + jmp parse_next_line + parse_while: + push edi + call parse_line_contents + xor al,al + stos byte [edi] + xchg esi,[esp] + mov edi,esi + call preevaluate_logical_expression + pop esi + cmp al,'0' + je parse_false_condition_block + cmp al,'1' + jne parse_next_line + stos byte [edi] + jmp parse_next_line + parse_false_condition_block: + or byte [esp],1 + sub edi,4 + jmp skip_parsing + parse_true_condition_block: + or byte [esp],100b + sub edi,4 + jmp parse_next_line + parse_else: + cmp [blocks_stack],0 + je unexpected_instruction + cmp word [esp+2],if_directive-instruction_handler + jne unexpected_instruction + lods byte [esi] + or al,al + jz parse_pure_else + cmp al,1Ah + jne extra_characters_on_line + push edi + movzx ecx,byte [esi] + inc esi + call get_instruction + jc extra_characters_on_line + pop edi + cmp bx,if_directive-instruction_handler + jne extra_characters_on_line + test byte [esp],100b + jnz skip_true_condition_else + mov dl,al + mov al,1 + stos byte [edi] + mov ax,bx + stos word [edi] + mov al,dl + stos byte [edi] + jmp parse_if + parse_assert: + push edi + call parse_line_contents + xor al,al + stos byte [edi] + xchg esi,[esp] + mov edi,esi + call preevaluate_logical_expression + pop esi + or al,al + jz parse_next_line + stos byte [edi] + jmp parse_next_line + skip_true_condition_else: + sub edi,4 + or byte [esp],1 + jmp skip_parsing_contents + parse_pure_else: + bts dword [esp],1 + jc unexpected_instruction + test byte [esp],100b + jz parse_next_line + sub edi,4 + or byte [esp],1 + jmp skip_parsing + skip_parsing: + cmp esi,[source_start] + jae source_parsed + mov [current_line],esi + add esi,16 + skip_parsing_line: + cmp byte [esi],1Ah + jne skip_parsing_contents + inc esi + movzx ecx,byte [esi] + inc esi + cmp byte [esi+ecx],':' + je skip_parsing_label + push edi + call get_instruction + pop edi + jnc skip_parsing_instruction + add esi,ecx + jmp skip_parsing_contents + skip_parsing_label: + lea esi,[esi+ecx+1] + jmp skip_parsing_line + skip_parsing_instruction: + cmp bx,if_directive-instruction_handler + je skip_parsing_block + cmp bx,repeat_directive-instruction_handler + je skip_parsing_block + cmp bx,while_directive-instruction_handler + je skip_parsing_block + cmp bx,end_directive-instruction_handler + je skip_parsing_end_directive + cmp bx,else_directive-instruction_handler + je skip_parsing_else + skip_parsing_contents: + lods byte [esi] + or al,al + jz skip_parsing + cmp al,1Ah + je skip_parsing_symbol + cmp al,3Bh + je skip_parsing_symbol + cmp al,22h + je skip_parsing_string + jmp skip_parsing_contents + skip_parsing_symbol: + lods byte [esi] + movzx eax,al + add esi,eax + jmp skip_parsing_contents + skip_parsing_string: + lods dword [esi] + add esi,eax + jmp skip_parsing_contents + skip_parsing_block: + mov eax,esp + sub eax,[stack_limit] + cmp eax,100h + jb stack_overflow + push [current_line] + mov ax,bx + shl eax,16 + push eax + inc [blocks_stack] + jmp skip_parsing_contents + skip_parsing_end_directive: + cmp byte [esi],1Ah + jne skip_parsing_contents + push edi + inc esi + movzx ecx,byte [esi] + inc esi + call get_instruction + pop edi + jnc skip_parsing_end_block + add esi,ecx + jmp skip_parsing_contents + skip_parsing_end_block: + lods byte [esi] + or al,al + jnz extra_characters_on_line + cmp bx,if_directive-instruction_handler + je close_skip_parsing_block + cmp bx,repeat_directive-instruction_handler + je close_skip_parsing_block + cmp bx,while_directive-instruction_handler + je close_skip_parsing_block + jmp skip_parsing + close_skip_parsing_block: + cmp [blocks_stack],0 + je unexpected_instruction + cmp bx,[esp+2] + jne unexpected_instruction + dec [blocks_stack] + pop eax edx + test al,1 + jz skip_parsing + cmp bx,if_directive-instruction_handler + jne parse_next_line + test al,10000b + jz parse_next_line + mov al,0Fh + stos byte [edi] + mov eax,[current_line] + stos dword [edi] + inc [parsed_lines] + mov eax,1 + (end_directive-instruction_handler) shl 8 + stos dword [edi] + mov eax,1 + (if_directive-instruction_handler) shl 8 + stos dword [edi] + jmp parse_next_line + skip_parsing_else: + cmp [blocks_stack],0 + je unexpected_instruction + cmp word [esp+2],if_directive-instruction_handler + jne unexpected_instruction + lods byte [esi] + or al,al + jz skip_parsing_pure_else + cmp al,1Ah + jne extra_characters_on_line + push edi + movzx ecx,byte [esi] + inc esi + call get_instruction + jc extra_characters_on_line + pop edi + cmp bx,if_directive-instruction_handler + jne extra_characters_on_line + mov al,[esp] + test al,1 + jz skip_parsing_contents + test al,100b + jnz skip_parsing_contents + test al,10000b + jnz parse_else_if + xor al,al + mov [esp],al + mov al,0Fh + stos byte [edi] + mov eax,[current_line] + stos dword [edi] + inc [parsed_lines] + parse_else_if: + mov eax,1 + (if_directive-instruction_handler) shl 8 + stos dword [edi] + jmp parse_if + skip_parsing_pure_else: + bts dword [esp],1 + jc unexpected_instruction + mov al,[esp] + test al,1 + jz skip_parsing + test al,100b + jnz skip_parsing + and al,not 1 + or al,1000b + mov [esp],al + jmp parse_next_line + +parse_line_contents: + mov [parenthesis_stack],0 + parse_instruction_arguments: + cmp bx,prefix_instruction-instruction_handler + je allow_embedded_instruction + cmp bx,times_directive-instruction_handler + je parse_times_directive + cmp bx,end_directive-instruction_handler + je allow_embedded_instruction + cmp bx,label_directive-instruction_handler + je parse_label_directive + cmp bx,segment_directive-instruction_handler + je parse_segment_directive + cmp bx,load_directive-instruction_handler + je parse_load_directive + cmp bx,extrn_directive-instruction_handler + je parse_extrn_directive + cmp bx,public_directive-instruction_handler + je parse_public_directive + cmp bx,section_directive-instruction_handler + je parse_formatter_argument + cmp bx,format_directive-instruction_handler + je parse_formatter_argument + cmp bx,data_directive-instruction_handler + je parse_formatter_argument + jmp parse_argument + parse_formatter_argument: + or [formatter_symbols_allowed],-1 + parse_argument: + lea eax,[edi+100h] + cmp eax,[labels_list] + jae out_of_memory + lods byte [esi] + cmp al,':' + je instruction_separator + cmp al,',' + je separator + cmp al,'=' + je expression_comparator + cmp al,'|' + je separator + cmp al,'&' + je separator + cmp al,'~' + je separator + cmp al,'>' + je greater + cmp al,'<' + je less + cmp al,')' + je close_parenthesis + or al,al + jz contents_parsed + cmp al,'[' + je address_argument + cmp al,']' + je separator + cmp al,'{' + je open_decorator + cmp al,'}' + je close_decorator + cmp al,'#' + je unallowed_character + cmp al,'`' + je unallowed_character + cmp al,3Bh + je foreign_argument + cmp [decorator_symbols_allowed],0 + je not_a_separator + cmp al,'-' + je separator + not_a_separator: + dec esi + cmp al,1Ah + jne expression_argument + push edi + mov edi,directive_operators + call get_operator + or al,al + jnz operator_argument + inc esi + movzx ecx,byte [esi] + inc esi + call get_symbol + jnc symbol_argument + cmp ecx,1 + jne check_argument + cmp byte [esi],'?' + jne check_argument + pop edi + movs byte [edi],[esi] + jmp argument_parsed + foreign_argument: + dec esi + call skip_foreign_line + jmp contents_parsed + symbol_argument: + pop edi + stos word [edi] + cmp byte [esi],'+' + jne argument_parsed + and ax,0F0FFh + cmp ax,6010h + jne argument_parsed + movs byte [edi],[esi] + jmp argument_parsed + operator_argument: + pop edi + cmp al,85h + je ptr_argument + stos byte [edi] + cmp al,8Ch + je forced_expression + cmp al,81h + je forced_parenthesis + cmp al,80h + je parse_at_operator + cmp al,82h + je parse_from_operator + cmp al,89h + je parse_label_operator + cmp al,0F8h + je forced_expression + jmp argument_parsed + instruction_separator: + stos byte [edi] + allow_embedded_instruction: + cmp byte [esi],1Ah + jne parse_argument + push edi + inc esi + movzx ecx,byte [esi] + inc esi + call get_instruction + jnc embedded_instruction + call get_data_directive + jnc embedded_instruction + pop edi + sub esi,2 + jmp parse_argument + embedded_instruction: + pop edi + mov dl,al + mov al,1 + stos byte [edi] + mov ax,bx + stos word [edi] + mov al,dl + stos byte [edi] + jmp parse_instruction_arguments + parse_times_directive: + mov al,'(' + stos byte [edi] + call convert_expression + mov al,')' + stos byte [edi] + cmp byte [esi],':' + jne allow_embedded_instruction + movs byte [edi],[esi] + jmp allow_embedded_instruction + parse_segment_directive: + or [formatter_symbols_allowed],-1 + parse_label_directive: + cmp byte [esi],1Ah + jne argument_parsed + push esi + inc esi + movzx ecx,byte [esi] + inc esi + call identify_label + pop ebx + cmp eax,0Fh + je non_label_identified + mov byte [edi],2 + inc edi + stos dword [edi] + xor al,al + stos byte [edi] + jmp argument_parsed + non_label_identified: + mov esi,ebx + jmp argument_parsed + parse_load_directive: + cmp byte [esi],1Ah + jne argument_parsed + push esi + inc esi + movzx ecx,byte [esi] + inc esi + call get_label_id + pop ebx + cmp eax,0Fh + je non_label_identified + mov byte [edi],2 + inc edi + stos dword [edi] + xor al,al + stos byte [edi] + jmp argument_parsed + parse_public_directive: + cmp byte [esi],1Ah + jne parse_argument + inc esi + push esi + movzx ecx,byte [esi] + inc esi + push esi ecx + push edi + or [formatter_symbols_allowed],-1 + call get_symbol + mov [formatter_symbols_allowed],0 + pop edi + jc parse_public_label + cmp al,1Dh + jne parse_public_label + add esp,12 + stos word [edi] + jmp parse_public_directive + parse_public_label: + pop ecx esi + mov al,2 + stos byte [edi] + call get_label_id + stos dword [edi] + mov ax,8600h + stos word [edi] + pop ebx + push ebx esi edi + mov edi,directive_operators + call get_operator + pop edi edx ebx + cmp al,86h + je argument_parsed + mov esi,edx + xchg esi,ebx + movzx ecx,byte [esi] + inc esi + mov ax,'(' + stos word [edi] + mov eax,ecx + stos dword [edi] + rep movs byte [edi],[esi] + xor al,al + stos byte [edi] + xchg esi,ebx + jmp argument_parsed + parse_extrn_directive: + cmp byte [esi],22h + je parse_quoted_extrn + cmp byte [esi],1Ah + jne parse_argument + push esi + movzx ecx,byte [esi+1] + add esi,2 + mov ax,'(' + stos word [edi] + mov eax,ecx + stos dword [edi] + rep movs byte [edi],[esi] + mov ax,8600h + stos word [edi] + pop esi + parse_label_operator: + cmp byte [esi],1Ah + jne argument_parsed + inc esi + movzx ecx,byte [esi] + inc esi + mov al,2 + stos byte [edi] + call get_label_id + stos dword [edi] + xor al,al + stos byte [edi] + jmp argument_parsed + parse_from_operator: + cmp byte [esi],22h + je argument_parsed + parse_at_operator: + cmp byte [esi],':' + je argument_parsed + jmp forced_multipart_expression + parse_quoted_extrn: + inc esi + mov ax,'(' + stos word [edi] + lods dword [esi] + mov ecx,eax + stos dword [edi] + rep movs byte [edi],[esi] + xor al,al + stos byte [edi] + push esi edi + mov edi,directive_operators + call get_operator + mov edx,esi + pop edi esi + cmp al,86h + jne argument_parsed + stos byte [edi] + mov esi,edx + jmp parse_label_operator + ptr_argument: + call parse_address + jmp address_parsed + check_argument: + push esi ecx + sub esi,2 + mov edi,single_operand_operators + call get_operator + pop ecx esi + or al,al + jnz not_instruction + call get_instruction + jnc embedded_instruction + call get_data_directive + jnc embedded_instruction + not_instruction: + pop edi + sub esi,2 + expression_argument: + cmp byte [esi],22h + jne not_string + mov eax,[esi+1] + lea ebx,[esi+5+eax] + push ebx ecx esi edi + call parse_expression + pop eax edx ecx ebx + cmp esi,ebx + jne expression_argument_parsed + mov edi,eax + mov esi,edx + string_argument: + inc esi + mov ax,'(' + stos word [edi] + lods dword [esi] + mov ecx,eax + stos dword [edi] + shr ecx,1 + jnc string_movsb_ok + movs byte [edi],[esi] + string_movsb_ok: + shr ecx,1 + jnc string_movsw_ok + movs word [edi],[esi] + string_movsw_ok: + rep movs dword [edi],[esi] + xor al,al + stos byte [edi] + jmp expression_argument_parsed + parse_expression: + mov al,'(' + stos byte [edi] + call convert_expression + mov al,')' + stos byte [edi] + ret + not_string: + cmp byte [esi],'(' + jne expression + mov eax,esp + sub eax,[stack_limit] + cmp eax,100h + jb stack_overflow + push esi edi + inc esi + mov al,91h + stos byte [edi] + inc [parenthesis_stack] + jmp parse_argument + expression_comparator: + stos byte [edi] + jmp forced_expression + greater: + cmp byte [esi],'=' + jne separator + inc esi + mov al,0F2h + jmp separator + less: + cmp byte [edi-1],0F6h + je separator + cmp byte [esi],'>' + je not_equal + cmp byte [esi],'=' + jne separator + inc esi + mov al,0F3h + jmp separator + not_equal: + inc esi + mov al,0F1h + jmp expression_comparator + expression: + call parse_expression + jmp expression_argument_parsed + forced_expression: + xor al,al + xchg al,[formatter_symbols_allowed] + push eax + call parse_expression + forced_expression_parsed: + pop eax + mov [formatter_symbols_allowed],al + jmp argument_parsed + forced_multipart_expression: + xor al,al + xchg al,[formatter_symbols_allowed] + push eax + call parse_expression + cmp byte [esi],':' + jne forced_expression_parsed + movs byte [edi],[esi] + call parse_expression + jmp forced_expression_parsed + address_argument: + call parse_address + lods byte [esi] + cmp al,']' + je address_parsed + cmp al,',' + je divided_address + dec esi + mov al,')' + stos byte [edi] + jmp argument_parsed + divided_address: + mov ax,'),' + stos word [edi] + jmp expression + address_parsed: + mov al,']' + stos byte [edi] + jmp argument_parsed + parse_address: + mov al,'[' + stos byte [edi] + cmp word [esi],021Ah + jne convert_address + push esi + add esi,4 + lea ebx,[esi+1] + cmp byte [esi],':' + pop esi + jne convert_address + add esi,2 + mov ecx,2 + push ebx edi + call get_symbol + pop edi esi + jc unknown_segment_prefix + cmp al,10h + jne unknown_segment_prefix + mov al,ah + and ah,11110000b + cmp ah,30h + jne unknown_segment_prefix + add al,30h + stos byte [edi] + jmp convert_address + unknown_segment_prefix: + sub esi,5 + convert_address: + push edi + mov edi,address_sizes + call get_operator + pop edi + or al,al + jz convert_expression + add al,70h + stos byte [edi] + jmp convert_expression + forced_parenthesis: + cmp byte [esi],'(' + jne argument_parsed + inc esi + mov al,91h + jmp separator + unallowed_character: + mov al,0FFh + jmp separator + open_decorator: + inc [decorator_symbols_allowed] + jmp separator + close_decorator: + dec [decorator_symbols_allowed] + jmp separator + close_parenthesis: + mov al,92h + separator: + stos byte [edi] + argument_parsed: + cmp [parenthesis_stack],0 + je parse_argument + dec [parenthesis_stack] + add esp,8 + jmp argument_parsed + expression_argument_parsed: + cmp [parenthesis_stack],0 + je parse_argument + cmp byte [esi],')' + jne argument_parsed + dec [parenthesis_stack] + pop edi esi + jmp expression + contents_parsed: + cmp [parenthesis_stack],0 + je contents_ok + dec [parenthesis_stack] + add esp,8 + jmp contents_parsed + contents_ok: + ret + +identify_label: + cmp byte [esi],'.' + je local_label_name + call get_label_id + cmp eax,10h + jb label_identified + or ebx,ebx + jz anonymous_label_name + dec ebx + mov [current_locals_prefix],ebx + label_identified: + ret + anonymous_label_name: + cmp byte [esi-1],'@' + je anonymous_label_name_ok + mov eax,0Fh + anonymous_label_name_ok: + ret + local_label_name: + call get_label_id + ret + +get_operator: + cmp byte [esi],1Ah + jne get_simple_operator + mov edx,esi + push ebp + inc esi + lods byte [esi] + movzx ebp,al + push edi + mov ecx,ebp + call lower_case + pop edi + check_operator: + mov esi,converted + movzx ecx,byte [edi] + jecxz no_operator + inc edi + mov ebx,edi + add ebx,ecx + cmp ecx,ebp + jne next_operator + repe cmps byte [esi],[edi] + je operator_found + jb no_operator + next_operator: + mov edi,ebx + inc edi + jmp check_operator + no_operator: + mov esi,edx + mov ecx,ebp + pop ebp + no_simple_operator: + xor al,al + ret + operator_found: + lea esi,[edx+2+ebp] + mov ecx,ebp + pop ebp + mov al,[edi] + ret + get_simple_operator: + mov al,[esi] + cmp al,22h + je no_simple_operator + simple_operator: + cmp byte [edi],1 + jb no_simple_operator + ja simple_next_operator + cmp al,[edi+1] + je simple_operator_found + simple_next_operator: + movzx ecx,byte [edi] + lea edi,[edi+1+ecx+1] + jmp simple_operator + simple_operator_found: + inc esi + mov al,[edi+2] + ret + +get_symbol: + push esi + mov ebp,ecx + call lower_case + mov ecx,ebp + cmp cl,11 + ja no_symbol + sub cl,1 + jc no_symbol + movzx ebx,word [symbols+ecx*4] + add ebx,symbols + movzx edx,word [symbols+ecx*4+2] + scan_symbols: + or edx,edx + jz no_symbol + mov eax,edx + shr eax,1 + lea edi,[ebp+2] + imul eax,edi + lea edi,[ebx+eax] + mov esi,converted + mov ecx,ebp + repe cmps byte [esi],[edi] + ja symbols_up + jb symbols_down + mov ax,[edi] + cmp al,18h + jb symbol_ok + cmp al,1Fh + je decorator_symbol + cmp [formatter_symbols_allowed],0 + je no_symbol + symbol_ok: + pop esi + add esi,ebp + clc + ret + decorator_symbol: + cmp [decorator_symbols_allowed],0 + jne symbol_ok + no_symbol: + pop esi + mov ecx,ebp + stc + ret + symbols_down: + shr edx,1 + jmp scan_symbols + symbols_up: + lea ebx,[edi+ecx+2] + shr edx,1 + adc edx,-1 + jmp scan_symbols + +get_data_directive: + push esi + mov ebp,ecx + call lower_case + mov ecx,ebp + cmp cl,4 + ja no_instruction + sub cl,2 + jc no_instruction + movzx ebx,word [data_directives+ecx*4] + add ebx,data_directives + movzx edx,word [data_directives+ecx*4+2] + jmp scan_instructions + +get_instruction: + push esi + mov ebp,ecx + call lower_case + mov ecx,ebp + cmp cl,17 + ja no_instruction + sub cl,2 + jc no_instruction + movzx ebx,word [instructions+ecx*4] + add ebx,instructions + movzx edx,word [instructions+ecx*4+2] + scan_instructions: + or edx,edx + jz no_instruction + mov eax,edx + shr eax,1 + lea edi,[ebp+3] + imul eax,edi + lea edi,[ebx+eax] + mov esi,converted + mov ecx,ebp + repe cmps byte [esi],[edi] + ja instructions_up + jb instructions_down + pop esi + add esi,ebp + mov al,[edi] + mov bx,[edi+1] + clc + ret + no_instruction: + pop esi + mov ecx,ebp + stc + ret + instructions_down: + shr edx,1 + jmp scan_instructions + instructions_up: + lea ebx,[edi+ecx+3] + shr edx,1 + adc edx,-1 + jmp scan_instructions + +get_label_id: + cmp ecx,100h + jae name_too_long + cmp byte [esi],'@' + je anonymous_label + cmp byte [esi],'.' + jne standard_label + cmp byte [esi+1],'.' + je standard_label + cmp [current_locals_prefix],0 + je standard_label + push edi + mov edi,[additional_memory_end] + sub edi,2 + sub edi,ecx + push ecx esi + mov esi,[current_locals_prefix] + lods byte [esi] + movzx ecx,al + sub edi,ecx + cmp edi,[free_additional_memory] + jb out_of_memory + mov word [edi],0 + add edi,2 + mov ebx,edi + rep movs byte [edi],[esi] + pop esi ecx + add al,cl + jc name_too_long + rep movs byte [edi],[esi] + pop edi + push ebx esi + movzx ecx,al + mov byte [ebx-1],al + mov esi,ebx + call get_label_id + pop esi ebx + cmp ebx,[eax+24] + jne composed_label_id_ok + lea edx,[ebx-2] + mov [additional_memory_end],edx + composed_label_id_ok: + ret + anonymous_label: + cmp ecx,2 + jne standard_label + mov al,[esi+1] + mov ebx,characters + xlat byte [ebx] + cmp al,'@' + je new_anonymous + cmp al,'b' + je anonymous_back + cmp al,'r' + je anonymous_back + cmp al,'f' + jne standard_label + add esi,2 + mov eax,[anonymous_forward] + or eax,eax + jnz anonymous_ok + mov eax,[current_line] + mov [error_line],eax + call allocate_label + mov [anonymous_forward],eax + anonymous_ok: + xor ebx,ebx + ret + anonymous_back: + mov eax,[anonymous_reverse] + add esi,2 + or eax,eax + jz bogus_anonymous + jmp anonymous_ok + bogus_anonymous: + call allocate_label + mov [anonymous_reverse],eax + jmp anonymous_ok + new_anonymous: + add esi,2 + mov eax,[anonymous_forward] + or eax,eax + jnz new_anonymous_ok + call allocate_label + new_anonymous_ok: + mov [anonymous_reverse],eax + mov [anonymous_forward],0 + jmp anonymous_ok + standard_label: + cmp byte [esi],'%' + je get_predefined_id + cmp byte [esi],'$' + je current_address_label + cmp byte [esi],'?' + jne find_label + cmp ecx,1 + jne find_label + inc esi + mov eax,0Fh + ret + current_address_label: + cmp ecx,3 + je current_address_label_3_characters + ja find_label + inc esi + cmp ecx,1 + jbe get_current_offset_id + inc esi + cmp byte [esi-1],'$' + je get_org_origin_id + cmp byte [esi-1],'%' + je get_file_offset_id + sub esi,2 + jmp find_label + get_current_offset_id: + xor eax,eax + ret + get_counter_id: + mov eax,1 + ret + get_timestamp_id: + mov eax,2 + ret + get_org_origin_id: + mov eax,3 + ret + get_file_offset_id: + mov eax,4 + ret + current_address_label_3_characters: + cmp word [esi+1],'%%' + jne find_label + add esi,3 + get_actual_file_offset_id: + mov eax,5 + ret + get_predefined_id: + cmp ecx,2 + ja find_label + inc esi + cmp cl,1 + je get_counter_id + lods byte [esi] + mov ebx,characters + xlat [ebx] + cmp al,'t' + je get_timestamp_id + sub esi,2 + find_label: + xor ebx,ebx + mov eax,2166136261 + mov ebp,16777619 + hash_label: + xor al,[esi+ebx] + mul ebp + inc bl + cmp bl,cl + jb hash_label + mov ebp,eax + shl eax,8 + and ebp,0FFh shl 24 + xor ebp,eax + or ebp,ebx + mov [label_hash],ebp + push edi esi + push ecx + mov ecx,32 + mov ebx,hash_tree + follow_tree: + mov edx,[ebx] + or edx,edx + jz extend_tree + xor eax,eax + shl ebp,1 + adc eax,0 + lea ebx,[edx+eax*4] + dec ecx + jnz follow_tree + mov [label_leaf],ebx + pop edx + mov eax,[ebx] + or eax,eax + jz add_label + mov ebx,esi + mov ebp,[label_hash] + compare_labels: + mov esi,ebx + mov ecx,edx + mov edi,[eax+4] + mov edi,[edi+24] + repe cmps byte [esi],[edi] + je label_found + mov eax,[eax] + or eax,eax + jnz compare_labels + jmp add_label + label_found: + add esp,4 + pop edi + mov eax,[eax+4] + ret + extend_tree: + mov edx,[free_additional_memory] + lea eax,[edx+8] + cmp eax,[additional_memory_end] + ja out_of_memory + mov [free_additional_memory],eax + xor eax,eax + mov [edx],eax + mov [edx+4],eax + shl ebp,1 + adc eax,0 + mov [ebx],edx + lea ebx,[edx+eax*4] + dec ecx + jnz extend_tree + mov [label_leaf],ebx + pop edx + add_label: + mov ecx,edx + pop esi + cmp byte [esi-2],0 + je label_name_ok + mov al,[esi] + cmp al,30h + jb name_first_char_ok + cmp al,39h + jbe numeric_name + name_first_char_ok: + cmp al,'$' + jne check_for_reserved_word + numeric_name: + add esi,ecx + reserved_word: + mov eax,0Fh + pop edi + ret + check_for_reserved_word: + call get_instruction + jnc reserved_word + call get_data_directive + jnc reserved_word + call get_symbol + jnc reserved_word + sub esi,2 + mov edi,operators + call get_operator + or al,al + jnz reserved_word + mov edi,single_operand_operators + call get_operator + or al,al + jnz reserved_word + mov edi,directive_operators + call get_operator + or al,al + jnz reserved_word + inc esi + movzx ecx,byte [esi] + inc esi + label_name_ok: + mov edx,[free_additional_memory] + lea eax,[edx+8] + cmp eax,[additional_memory_end] + ja out_of_memory + mov [free_additional_memory],eax + mov ebx,esi + add esi,ecx + mov eax,[label_leaf] + mov edi,[eax] + mov [edx],edi + mov [eax],edx + call allocate_label + mov [edx+4],eax + mov [eax+24],ebx + pop edi + ret + allocate_label: + mov eax,[labels_list] + mov ecx,LABEL_STRUCTURE_SIZE shr 2 + initialize_label: + sub eax,4 + mov dword [eax],0 + loop initialize_label + mov [labels_list],eax + ret + +LABEL_STRUCTURE_SIZE = 32 diff --git a/toolchain/fasmw17332/SOURCE/PREPROCE.INC b/toolchain/fasmw17332/SOURCE/PREPROCE.INC new file mode 100644 index 0000000..88327b2 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/PREPROCE.INC @@ -0,0 +1,2983 @@ + +; flat assembler core +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +preprocessor: + mov edi,characters + xor al,al + make_characters_table: + stosb + inc al + jnz make_characters_table + mov esi,characters+'a' + mov edi,characters+'A' + mov ecx,26 + rep movsb + mov edi,characters + mov esi,symbol_characters+1 + movzx ecx,byte [esi-1] + xor eax,eax + mark_symbol_characters: + lodsb + mov byte [edi+eax],0 + loop mark_symbol_characters + mov edi,locals_counter + mov ax,1 + '0' shl 8 + stos word [edi] + mov edi,[memory_start] + mov [include_paths],edi + mov esi,include_variable + call get_environment_variable + xor al,al + stos byte [edi] + mov [memory_start],edi + mov eax,[additional_memory] + mov [free_additional_memory],eax + mov eax,[additional_memory_end] + mov [labels_list],eax + xor eax,eax + mov [source_start],eax + mov [tagged_blocks],eax + mov [hash_tree],eax + mov [error],eax + mov [macro_status],al + mov [current_line],eax + mov esi,[initial_definitions] + test esi,esi + jz predefinitions_ok + process_predefinitions: + movzx ecx,byte [esi] + test ecx,ecx + jz predefinitions_ok + inc esi + lea eax,[esi+ecx] + push eax + mov ch,10b + call add_preprocessor_symbol + pop esi + mov edi,[memory_start] + mov [edx+8],edi + convert_predefinition: + cmp edi,[memory_end] + jae out_of_memory + lods byte [esi] + or al,al + jz predefinition_converted + cmp al,20h + je convert_predefinition + mov ah,al + mov ebx,characters + xlat byte [ebx] + or al,al + jz predefinition_separator + cmp ah,27h + je predefinition_string + cmp ah,22h + je predefinition_string + mov byte [edi],1Ah + scas word [edi] + xchg al,ah + stos byte [edi] + mov ebx,characters + xor ecx,ecx + predefinition_symbol: + lods byte [esi] + stos byte [edi] + xlat byte [ebx] + or al,al + loopnzd predefinition_symbol + neg ecx + cmp ecx,255 + ja invalid_definition + mov ebx,edi + sub ebx,ecx + mov byte [ebx-2],cl + found_predefinition_separator: + dec edi + mov ah,[esi-1] + predefinition_separator: + xchg al,ah + or al,al + jz predefinition_converted + cmp al,20h + je convert_predefinition + cmp al,3Bh + je invalid_definition + cmp al,5Ch + je predefinition_backslash + stos byte [edi] + jmp convert_predefinition + predefinition_string: + mov al,22h + stos byte [edi] + scas dword [edi] + mov ebx,edi + copy_predefinition_string: + lods byte [esi] + stos byte [edi] + or al,al + jz invalid_definition + cmp al,ah + jne copy_predefinition_string + lods byte [esi] + cmp al,ah + je copy_predefinition_string + dec esi + dec edi + mov eax,edi + sub eax,ebx + mov [ebx-4],eax + jmp convert_predefinition + predefinition_backslash: + mov byte [edi],0 + lods byte [esi] + or al,al + jz invalid_definition + cmp al,20h + je invalid_definition + cmp al,3Bh + je invalid_definition + mov al,1Ah + stos byte [edi] + mov ecx,edi + mov ax,5C01h + stos word [edi] + dec esi + group_predefinition_backslashes: + lods byte [esi] + cmp al,5Ch + jne predefinition_backslashed_symbol + stos byte [edi] + inc byte [ecx] + jmp group_predefinition_backslashes + predefinition_backslashed_symbol: + cmp al,20h + je invalid_definition + cmp al,22h + je invalid_definition + cmp al,27h + je invalid_definition + cmp al,3Bh + je invalid_definition + mov ah,al + mov ebx,characters + xlat byte [ebx] + or al,al + jz predefinition_backslashed_symbol_character + mov al,ah + convert_predefinition_backslashed_symbol: + stos byte [edi] + xlat byte [ebx] + or al,al + jz found_predefinition_separator + inc byte [ecx] + jz invalid_definition + lods byte [esi] + jmp convert_predefinition_backslashed_symbol + predefinition_backslashed_symbol_character: + mov al,ah + stos byte [edi] + inc byte [ecx] + jmp convert_predefinition + predefinition_converted: + mov [memory_start],edi + sub edi,[edx+8] + mov [edx+12],edi + jmp process_predefinitions + predefinitions_ok: + mov esi,[input_file] + mov edx,esi + call open + jc main_file_not_found + mov edi,[memory_start] + call preprocess_file + cmp [macro_status],0 + je process_postponed + mov eax,[error_line] + mov [current_line],eax + jmp incomplete_macro + process_postponed: + mov edx,hash_tree + mov ecx,32 + find_postponed_list: + mov edx,[edx] + or edx,edx + loopnz find_postponed_list + jz preprocessing_finished + process_postponed_list: + mov eax,[edx] + or eax,eax + jz preprocessing_finished + push edx + mov ebx,edx + find_earliest_postponed: + mov eax,[edx] + or eax,eax + jz earliest_postponed_found + mov ebx,edx + mov edx,eax + jmp find_earliest_postponed + earliest_postponed_found: + mov [ebx],eax + call use_postponed_macro + pop edx + cmp [macro_status],0 + je process_postponed_list + mov eax,[error_line] + mov [current_line],eax + jmp incomplete_macro + preprocessing_finished: + mov [source_start],edi + ret + use_postponed_macro: + lea esi,[edi-1] + push ecx esi + mov [struc_name],0 + jmp use_macro + +preprocess_file: + push [memory_end] + push esi + mov al,2 + xor edx,edx + call lseek + push eax + xor al,al + xor edx,edx + call lseek + pop ecx + mov edx,[memory_end] + dec edx + mov byte [edx],1Ah + sub edx,ecx + jc out_of_memory + mov esi,edx + cmp edx,edi + jbe out_of_memory + mov [memory_end],edx + call read + call close + pop edx + xor ecx,ecx + mov ebx,esi + preprocess_source: + inc ecx + mov [current_line],edi + mov eax,edx + stos dword [edi] + mov eax,ecx + stos dword [edi] + mov eax,esi + sub eax,ebx + stos dword [edi] + xor eax,eax + stos dword [edi] + push ebx edx + call convert_line + call preprocess_line + pop edx ebx + next_line: + cmp byte [esi-1],0 + je file_end + cmp byte [esi-1],1Ah + jne preprocess_source + file_end: + pop [memory_end] + clc + ret + +convert_line: + push ecx + test [macro_status],0Fh + jz convert_line_data + mov ax,3Bh + stos word [edi] + convert_line_data: + cmp edi,[memory_end] + jae out_of_memory + lods byte [esi] + cmp al,20h + je convert_line_data + cmp al,9 + je convert_line_data + mov ah,al + mov ebx,characters + xlat byte [ebx] + or al,al + jz convert_separator + cmp ah,27h + je convert_string + cmp ah,22h + je convert_string + mov byte [edi],1Ah + scas word [edi] + xchg al,ah + stos byte [edi] + mov ebx,characters + xor ecx,ecx + convert_symbol: + lods byte [esi] + stos byte [edi] + xlat byte [ebx] + or al,al + loopnzd convert_symbol + neg ecx + cmp ecx,255 + ja name_too_long + mov ebx,edi + sub ebx,ecx + mov byte [ebx-2],cl + found_separator: + dec edi + mov ah,[esi-1] + convert_separator: + xchg al,ah + cmp al,20h + jb control_character + je convert_line_data + symbol_character: + cmp al,3Bh + je ignore_comment + cmp al,5Ch + je backslash_character + stos byte [edi] + jmp convert_line_data + control_character: + cmp al,1Ah + je line_end + cmp al,0Dh + je cr_character + cmp al,0Ah + je lf_character + cmp al,9 + je convert_line_data + or al,al + jnz symbol_character + jmp line_end + lf_character: + lods byte [esi] + cmp al,0Dh + je line_end + dec esi + jmp line_end + cr_character: + lods byte [esi] + cmp al,0Ah + je line_end + dec esi + jmp line_end + convert_string: + mov al,22h + stos byte [edi] + scas dword [edi] + mov ebx,edi + copy_string: + lods byte [esi] + stos byte [edi] + cmp al,0Ah + je no_end_quote + cmp al,0Dh + je no_end_quote + or al,al + jz no_end_quote + cmp al,1Ah + je no_end_quote + cmp al,ah + jne copy_string + lods byte [esi] + cmp al,ah + je copy_string + dec esi + dec edi + mov eax,edi + sub eax,ebx + mov [ebx-4],eax + jmp convert_line_data + backslash_character: + mov byte [edi],0 + lods byte [esi] + cmp al,20h + je concatenate_lines + cmp al,9 + je concatenate_lines + cmp al,1Ah + je line_end + or al,al + jz line_end + cmp al,0Ah + je concatenate_lf + cmp al,0Dh + je concatenate_cr + cmp al,3Bh + je find_concatenated_line + mov al,1Ah + stos byte [edi] + mov ecx,edi + mov ax,5C01h + stos word [edi] + dec esi + group_backslashes: + lods byte [esi] + cmp al,5Ch + jne backslashed_symbol + stos byte [edi] + inc byte [ecx] + jz name_too_long + jmp group_backslashes + no_end_quote: + mov byte [ebx-5],0 + jmp missing_end_quote + backslashed_symbol: + cmp al,1Ah + je extra_characters_on_line + or al,al + jz extra_characters_on_line + cmp al,0Ah + je extra_characters_on_line + cmp al,0Dh + je extra_characters_on_line + cmp al,20h + je extra_characters_on_line + cmp al,9 + je extra_characters_on_line + cmp al,22h + je extra_characters_on_line + cmp al,27h + je extra_characters_on_line + cmp al,3Bh + je extra_characters_on_line + mov ah,al + mov ebx,characters + xlat byte [ebx] + or al,al + jz backslashed_symbol_character + mov al,ah + convert_backslashed_symbol: + stos byte [edi] + xlat byte [ebx] + or al,al + jz found_separator + inc byte [ecx] + jz name_too_long + lods byte [esi] + jmp convert_backslashed_symbol + backslashed_symbol_character: + mov al,ah + stos byte [edi] + inc byte [ecx] + jmp convert_line_data + concatenate_lines: + lods byte [esi] + cmp al,20h + je concatenate_lines + cmp al,9 + je concatenate_lines + cmp al,1Ah + je line_end + or al,al + jz line_end + cmp al,0Ah + je concatenate_lf + cmp al,0Dh + je concatenate_cr + cmp al,3Bh + jne extra_characters_on_line + find_concatenated_line: + lods byte [esi] + cmp al,0Ah + je concatenate_lf + cmp al,0Dh + je concatenate_cr + or al,al + jz concatenate_ok + cmp al,1Ah + jne find_concatenated_line + jmp line_end + concatenate_lf: + lods byte [esi] + cmp al,0Dh + je concatenate_ok + dec esi + jmp concatenate_ok + concatenate_cr: + lods byte [esi] + cmp al,0Ah + je concatenate_ok + dec esi + concatenate_ok: + inc dword [esp] + jmp convert_line_data + ignore_comment: + lods byte [esi] + cmp al,0Ah + je lf_character + cmp al,0Dh + je cr_character + or al,al + jz line_end + cmp al,1Ah + jne ignore_comment + line_end: + xor al,al + stos byte [edi] + pop ecx + ret + +lower_case: + mov edi,converted + mov ebx,characters + convert_case: + lods byte [esi] + xlat byte [ebx] + stos byte [edi] + loop convert_case + case_ok: + ret + +get_directive: + push edi + mov edx,esi + mov ebp,ecx + call lower_case + pop edi + scan_directives: + mov esi,converted + movzx eax,byte [edi] + or al,al + jz no_directive + mov ecx,ebp + inc edi + mov ebx,edi + add ebx,eax + mov ah,[esi] + cmp ah,[edi] + jb no_directive + ja next_directive + cmp cl,al + jne next_directive + repe cmps byte [esi],[edi] + jb no_directive + je directive_found + next_directive: + mov edi,ebx + add edi,2 + jmp scan_directives + no_directive: + mov esi,edx + mov ecx,ebp + stc + ret + directive_found: + call get_directive_handler_base + directive_handler: + lea esi,[edx+ebp] + movzx ecx,word [ebx] + add eax,ecx + clc + ret + get_directive_handler_base: + mov eax,[esp] + ret + +preprocess_line: + mov eax,esp + sub eax,[stack_limit] + cmp eax,100h + jb stack_overflow + push ecx esi + preprocess_current_line: + mov esi,[current_line] + add esi,16 + cmp word [esi],3Bh + jne line_start_ok + add esi,2 + line_start_ok: + test [macro_status],0F0h + jnz macro_preprocessing + cmp byte [esi],1Ah + jne not_fix_constant + movzx edx,byte [esi+1] + lea edx,[esi+2+edx] + cmp word [edx],031Ah + jne not_fix_constant + mov ebx,characters + movzx eax,byte [edx+2] + xlat byte [ebx] + ror eax,8 + mov al,[edx+3] + xlat byte [ebx] + ror eax,8 + mov al,[edx+4] + xlat byte [ebx] + ror eax,16 + cmp eax,'fix' + je define_fix_constant + not_fix_constant: + call process_fix_constants + jmp initial_preprocessing_ok + macro_preprocessing: + call process_macro_operators + initial_preprocessing_ok: + mov esi,[current_line] + add esi,16 + mov al,[macro_status] + test al,2 + jnz skip_macro_block + test al,1 + jnz find_macro_block + preprocess_instruction: + mov [current_offset],esi + lods byte [esi] + movzx ecx,byte [esi] + inc esi + cmp al,1Ah + jne not_preprocessor_symbol + cmp cl,3 + jb not_preprocessor_directive + push edi + mov edi,preprocessor_directives + call get_directive + pop edi + jc not_preprocessor_directive + mov byte [edx-2],3Bh + jmp near eax + not_preprocessor_directive: + xor ch,ch + call get_preprocessor_symbol + jc not_macro + mov byte [ebx-2],3Bh + mov [struc_name],0 + jmp use_macro + not_macro: + mov [struc_name],esi + add esi,ecx + lods byte [esi] + cmp al,':' + je preprocess_label + cmp al,1Ah + jne not_preprocessor_symbol + lods byte [esi] + cmp al,3 + jne not_symbolic_constant + mov ebx,characters + movzx eax,byte [esi] + xlat byte [ebx] + ror eax,8 + mov al,[esi+1] + xlat byte [ebx] + ror eax,8 + mov al,[esi+2] + xlat byte [ebx] + ror eax,16 + cmp eax,'equ' + je define_equ_constant + mov al,3 + not_symbolic_constant: + mov ch,1 + mov cl,al + call get_preprocessor_symbol + jc not_preprocessor_symbol + push edx esi + mov esi,[struc_name] + mov [struc_label],esi + sub [struc_label],2 + mov cl,[esi-1] + mov ch,10b + call get_preprocessor_symbol + jc struc_name_ok + test edx,edx + jz reserved_word_used_as_symbol + mov ecx,[edx+12] + add ecx,3 + lea ebx,[edi+ecx] + mov ecx,edi + sub ecx,[struc_label] + lea esi,[edi-1] + lea edi,[ebx-1] + std + rep movs byte [edi],[esi] + cld + mov edi,[struc_label] + mov esi,[edx+8] + mov ecx,[edx+12] + add [struc_name],ecx + add [struc_name],3 + call move_data + mov al,3Ah + stos byte [edi] + mov ax,3Bh + stos word [edi] + mov edi,ebx + pop esi + add esi,[edx+12] + add esi,3 + pop edx + jmp use_macro + struc_name_ok: + mov edx,[struc_name] + movzx eax,byte [edx-1] + add edx,eax + push edi + lea esi,[edi-1] + mov ecx,edi + sub ecx,edx + std + rep movs byte [edi],[esi] + cld + pop edi + inc edi + mov al,3Ah + mov [edx],al + inc al + mov [edx+1],al + pop esi edx + inc esi + jmp use_macro + preprocess_label: + dec esi + sub esi,ecx + lea ebp,[esi-2] + mov ch,10b + call get_preprocessor_symbol + jnc symbolic_constant_in_label + lea esi,[esi+ecx+1] + cmp byte [esi],':' + jne preprocess_instruction + inc esi + jmp preprocess_instruction + symbolic_constant_in_label: + test edx,edx + jz reserved_word_used_as_symbol + mov ebx,[edx+8] + mov ecx,[edx+12] + add ecx,ebx + check_for_broken_label: + cmp ebx,ecx + je label_broken + cmp byte [ebx],1Ah + jne label_broken + movzx eax,byte [ebx+1] + lea ebx,[ebx+2+eax] + cmp ebx,ecx + je label_constant_ok + cmp byte [ebx],':' + jne label_broken + inc ebx + cmp byte [ebx],':' + jne check_for_broken_label + inc ebx + jmp check_for_broken_label + label_broken: + call replace_symbolic_constant + jmp line_preprocessed + label_constant_ok: + mov ecx,edi + sub ecx,esi + mov edi,[edx+12] + add edi,ebp + push edi + lea eax,[edi+ecx] + push eax + cmp esi,edi + je replace_label + jb move_rest_of_line_up + rep movs byte [edi],[esi] + jmp replace_label + move_rest_of_line_up: + lea esi,[esi+ecx-1] + lea edi,[edi+ecx-1] + std + rep movs byte [edi],[esi] + cld + replace_label: + mov ecx,[edx+12] + mov edi,[esp+4] + sub edi,ecx + mov esi,[edx+8] + rep movs byte [edi],[esi] + pop edi esi + inc esi + jmp preprocess_instruction + not_preprocessor_symbol: + mov esi,[current_offset] + call process_equ_constants + line_preprocessed: + pop esi ecx + ret + +get_preprocessor_symbol: + push ebp edi esi + mov ebp,ecx + shl ebp,22 + mov al,ch + and al,11b + movzx ecx,cl + cmp al,10b + jne no_preprocessor_special_symbol + cmp cl,4 + jbe no_preprocessor_special_symbol + mov ax,'__' + cmp ax,[esi] + jne no_preprocessor_special_symbol + cmp ax,[esi+ecx-2] + jne no_preprocessor_special_symbol + add esi,2 + sub ecx,4 + push ebp + mov edi,preprocessor_special_symbols + call get_directive + pop ebp + jc preprocessor_special_symbol_not_recognized + add esi,2 + xor edx,edx + jmp preprocessor_symbol_found + preprocessor_special_symbol_not_recognized: + add ecx,4 + sub esi,2 + no_preprocessor_special_symbol: + mov ebx,hash_tree + mov edi,10 + follow_hashes_roots: + mov edx,[ebx] + or edx,edx + jz preprocessor_symbol_not_found + xor eax,eax + shl ebp,1 + adc eax,0 + lea ebx,[edx+eax*4] + dec edi + jnz follow_hashes_roots + mov edi,ebx + call calculate_hash + mov ebp,eax + and ebp,3FFh + shl ebp,10 + xor ebp,eax + mov ebx,edi + mov edi,22 + follow_hashes_tree: + mov edx,[ebx] + or edx,edx + jz preprocessor_symbol_not_found + xor eax,eax + shl ebp,1 + adc eax,0 + lea ebx,[edx+eax*4] + dec edi + jnz follow_hashes_tree + mov al,cl + mov edx,[ebx] + or edx,edx + jz preprocessor_symbol_not_found + compare_with_preprocessor_symbol: + mov edi,[edx+4] + cmp edi,1 + jbe next_equal_hash + repe cmps byte [esi],[edi] + je preprocessor_symbol_found + mov cl,al + mov esi,[esp] + next_equal_hash: + mov edx,[edx] + or edx,edx + jnz compare_with_preprocessor_symbol + preprocessor_symbol_not_found: + pop esi edi ebp + stc + ret + preprocessor_symbol_found: + pop ebx edi ebp + clc + ret + calculate_hash: + xor ebx,ebx + mov eax,2166136261 + mov ebp,16777619 + fnv1a_hash: + xor al,[esi+ebx] + mul ebp + inc bl + cmp bl,cl + jb fnv1a_hash + ret +add_preprocessor_symbol: + push edi esi + xor eax,eax + or cl,cl + jz reshape_hash + cmp ch,11b + je preprocessor_symbol_name_ok + push ecx + movzx ecx,cl + mov edi,preprocessor_directives + call get_directive + jnc reserved_word_used_as_symbol + pop ecx + preprocessor_symbol_name_ok: + call calculate_hash + reshape_hash: + mov ebp,eax + and ebp,3FFh + shr eax,10 + xor ebp,eax + shl ecx,22 + or ebp,ecx + mov ebx,hash_tree + mov ecx,32 + find_leave_for_symbol: + mov edx,[ebx] + or edx,edx + jz extend_hashes_tree + xor eax,eax + rol ebp,1 + adc eax,0 + lea ebx,[edx+eax*4] + dec ecx + jnz find_leave_for_symbol + mov edx,[ebx] + or edx,edx + jz add_symbol_entry + shr ebp,30 + cmp ebp,11b + je reuse_symbol_entry + cmp dword [edx+4],0 + jne add_symbol_entry + find_entry_to_reuse: + mov edi,[edx] + or edi,edi + jz reuse_symbol_entry + cmp dword [edi+4],0 + jne reuse_symbol_entry + mov edx,edi + jmp find_entry_to_reuse + add_symbol_entry: + mov eax,edx + mov edx,[labels_list] + sub edx,16 + cmp edx,[free_additional_memory] + jb out_of_memory + mov [labels_list],edx + mov [edx],eax + mov [ebx],edx + reuse_symbol_entry: + pop esi edi + mov [edx+4],esi + ret + extend_hashes_tree: + mov edx,[labels_list] + sub edx,8 + cmp edx,[free_additional_memory] + jb out_of_memory + mov [labels_list],edx + xor eax,eax + mov [edx],eax + mov [edx+4],eax + shl ebp,1 + adc eax,0 + mov [ebx],edx + lea ebx,[edx+eax*4] + dec ecx + jnz extend_hashes_tree + mov edx,[labels_list] + sub edx,16 + cmp edx,[free_additional_memory] + jb out_of_memory + mov [labels_list],edx + mov dword [edx],0 + mov [ebx],edx + pop esi edi + mov [edx+4],esi + ret + +define_fix_constant: + add edx,5 + add esi,2 + push edx + mov ch,11b + jmp define_preprocessor_constant +define_equ_constant: + add esi,3 + push esi + call process_equ_constants + mov esi,[struc_name] + mov ch,10b + define_preprocessor_constant: + mov byte [esi-2],3Bh + mov cl,[esi-1] + call add_preprocessor_symbol + pop ebx + mov ecx,edi + dec ecx + sub ecx,ebx + mov [edx+8],ebx + mov [edx+12],ecx + jmp line_preprocessed +define_symbolic_constant: + lods byte [esi] + cmp al,1Ah + jne invalid_name + lods byte [esi] + mov cl,al + mov ch,10b + call add_preprocessor_symbol + movzx eax,byte [esi-1] + add esi,eax + lea ecx,[edi-1] + sub ecx,esi + mov [edx+8],esi + mov [edx+12],ecx + jmp line_preprocessed + +define_struc: + mov ch,1 + jmp make_macro +define_macro: + xor ch,ch + make_macro: + lods byte [esi] + cmp al,1Ah + jne invalid_name + lods byte [esi] + mov cl,al + call add_preprocessor_symbol + mov eax,[current_line] + mov [edx+12],eax + movzx eax,byte [esi-1] + add esi,eax + mov [edx+8],esi + mov al,[macro_status] + and al,0F0h + or al,1 + mov [macro_status],al + mov eax,[current_line] + mov [error_line],eax + xor ebp,ebp + lods byte [esi] + or al,al + jz line_preprocessed + cmp al,'{' + je found_macro_block + dec esi + skip_macro_arguments: + lods byte [esi] + cmp al,1Ah + je skip_macro_argument + cmp al,'[' + jne invalid_macro_arguments + or ebp,-1 + jz invalid_macro_arguments + lods byte [esi] + cmp al,1Ah + jne invalid_macro_arguments + skip_macro_argument: + movzx eax,byte [esi] + inc esi + add esi,eax + lods byte [esi] + cmp al,':' + je macro_argument_with_default_value + cmp al,'=' + je macro_argument_with_default_value + cmp al,'*' + jne macro_argument_end + lods byte [esi] + macro_argument_end: + cmp al,',' + je skip_macro_arguments + cmp al,'&' + je macro_arguments_finisher + cmp al,']' + jne end_macro_arguments + not ebp + macro_arguments_finisher: + lods byte [esi] + end_macro_arguments: + or ebp,ebp + jnz invalid_macro_arguments + or al,al + jz line_preprocessed + cmp al,'{' + je found_macro_block + jmp invalid_macro_arguments + macro_argument_with_default_value: + or [skip_default_argument_value],-1 + call skip_macro_argument_value + inc esi + jmp macro_argument_end + skip_macro_argument_value: + cmp byte [esi],'<' + jne simple_argument + mov ecx,1 + inc esi + enclosed_argument: + lods byte [esi] + or al,al + jz invalid_macro_arguments + cmp al,1Ah + je enclosed_symbol + cmp al,22h + je enclosed_string + cmp al,'>' + je enclosed_argument_end + cmp al,'<' + jne enclosed_argument + inc ecx + jmp enclosed_argument + enclosed_symbol: + movzx eax,byte [esi] + inc esi + add esi,eax + jmp enclosed_argument + enclosed_string: + lods dword [esi] + add esi,eax + jmp enclosed_argument + enclosed_argument_end: + loop enclosed_argument + lods byte [esi] + or al,al + jz argument_value_end + cmp al,',' + je argument_value_end + cmp [skip_default_argument_value],0 + je invalid_macro_arguments + cmp al,'{' + je argument_value_end + cmp al,'&' + je argument_value_end + or ebp,ebp + jz invalid_macro_arguments + cmp al,']' + je argument_value_end + jmp invalid_macro_arguments + simple_argument: + lods byte [esi] + or al,al + jz argument_value_end + cmp al,',' + je argument_value_end + cmp al,22h + je argument_string + cmp al,1Ah + je argument_symbol + cmp [skip_default_argument_value],0 + je simple_argument + cmp al,'{' + je argument_value_end + cmp al,'&' + je argument_value_end + or ebp,ebp + jz simple_argument + cmp al,']' + je argument_value_end + argument_symbol: + movzx eax,byte [esi] + inc esi + add esi,eax + jmp simple_argument + argument_string: + lods dword [esi] + add esi,eax + jmp simple_argument + argument_value_end: + dec esi + ret + find_macro_block: + add esi,2 + lods byte [esi] + or al,al + jz line_preprocessed + cmp al,'{' + jne unexpected_characters + found_macro_block: + or [macro_status],2 + skip_macro_block: + lods byte [esi] + cmp al,1Ah + je skip_macro_symbol + cmp al,3Bh + je skip_macro_symbol + cmp al,22h + je skip_macro_string + or al,al + jz line_preprocessed + cmp al,'}' + jne skip_macro_block + mov al,[macro_status] + and [macro_status],0F0h + test al,8 + jnz use_instant_macro + cmp byte [esi],0 + je line_preprocessed + mov ecx,edi + sub ecx,esi + mov edx,esi + lea esi,[esi+ecx-1] + lea edi,[edi+1+16] + mov ebx,edi + dec edi + std + rep movs byte [edi],[esi] + cld + mov edi,edx + xor al,al + stos byte [edi] + mov esi,[current_line] + mov [current_line],edi + mov ecx,4 + rep movs dword [edi],[esi] + mov edi,ebx + jmp initial_preprocessing_ok + skip_macro_symbol: + movzx eax,byte [esi] + inc esi + add esi,eax + jmp skip_macro_block + skip_macro_string: + lods dword [esi] + add esi,eax + jmp skip_macro_block +postpone_directive: + push esi + mov esi,edx + xor ecx,ecx + call add_preprocessor_symbol + mov eax,[current_line] + mov [error_line],eax + mov [edx+12],eax + pop esi + mov [edx+8],esi + mov al,[macro_status] + and al,0F0h + or al,1 + mov [macro_status],al + lods byte [esi] + or al,al + jz line_preprocessed + cmp al,'{' + jne unexpected_characters + jmp found_macro_block +rept_directive: + mov [base_code],0 + jmp define_instant_macro +irp_directive: + mov [base_code],1 + jmp define_instant_macro +irps_directive: + mov [base_code],2 + jmp define_instant_macro +irpv_directive: + mov [base_code],3 + jmp define_instant_macro +match_directive: + mov [base_code],10h +define_instant_macro: + mov al,[macro_status] + and al,0F0h + or al,8+1 + mov [macro_status],al + mov eax,[current_line] + mov [error_line],eax + mov [instant_macro_start],esi + cmp [base_code],10h + je prepare_match + skip_parameters: + lods byte [esi] + or al,al + jz parameters_skipped + cmp al,'{' + je parameters_skipped + cmp al,22h + je skip_quoted_parameter + cmp al,1Ah + jne skip_parameters + lods byte [esi] + movzx eax,al + add esi,eax + jmp skip_parameters + skip_quoted_parameter: + lods dword [esi] + add esi,eax + jmp skip_parameters + parameters_skipped: + dec esi + mov [parameters_end],esi + lods byte [esi] + cmp al,'{' + je found_macro_block + or al,al + jnz invalid_macro_arguments + jmp line_preprocessed +prepare_match: + call skip_pattern + mov [value_type],80h+10b + call process_symbolic_constants + jmp parameters_skipped + skip_pattern: + lods byte [esi] + or al,al + jz invalid_macro_arguments + cmp al,',' + je pattern_skipped + cmp al,22h + je skip_quoted_string_in_pattern + cmp al,1Ah + je skip_symbol_in_pattern + cmp al,'=' + jne skip_pattern + mov al,[esi] + cmp al,1Ah + je skip_pattern + cmp al,22h + je skip_pattern + inc esi + jmp skip_pattern + skip_symbol_in_pattern: + lods byte [esi] + movzx eax,al + add esi,eax + jmp skip_pattern + skip_quoted_string_in_pattern: + lods dword [esi] + add esi,eax + jmp skip_pattern + pattern_skipped: + ret + +purge_macro: + xor ch,ch + jmp restore_preprocessor_symbol +purge_struc: + mov ch,1 + jmp restore_preprocessor_symbol +restore_equ_constant: + mov ch,10b + restore_preprocessor_symbol: + push ecx + lods byte [esi] + cmp al,1Ah + jne invalid_name + lods byte [esi] + mov cl,al + call get_preprocessor_symbol + jc no_symbol_to_restore + test edx,edx + jz symbol_restored + mov dword [edx+4],0 + jmp symbol_restored + no_symbol_to_restore: + add esi,ecx + symbol_restored: + pop ecx + lods byte [esi] + cmp al,',' + je restore_preprocessor_symbol + or al,al + jnz extra_characters_on_line + jmp line_preprocessed + +process_fix_constants: + mov [value_type],11b + jmp process_symbolic_constants +process_equ_constants: + mov [value_type],10b + process_symbolic_constants: + mov ebp,esi + lods byte [esi] + cmp al,1Ah + je check_symbol + cmp al,22h + je ignore_string + cmp al,'{' + je check_brace + or al,al + jnz process_symbolic_constants + ret + ignore_string: + lods dword [esi] + add esi,eax + jmp process_symbolic_constants + check_brace: + test [value_type],80h + jz process_symbolic_constants + ret + no_replacing: + movzx ecx,byte [esi-1] + add esi,ecx + jmp process_symbolic_constants + check_symbol: + mov cl,[esi] + inc esi + mov ch,[value_type] + call get_preprocessor_symbol + jc no_replacing + mov [current_section],edi + replace_symbolic_constant: + test edx,edx + jz replace_special_symbolic_constant + mov ecx,[edx+12] + mov edx,[edx+8] + xchg esi,edx + call move_data + mov esi,edx + process_after_replaced: + lods byte [esi] + cmp al,1Ah + je symbol_after_replaced + stos byte [edi] + cmp al,22h + je string_after_replaced + cmp al,'{' + je brace_after_replaced + or al,al + jnz process_after_replaced + mov ecx,edi + sub ecx,esi + mov edi,ebp + call move_data + mov esi,edi + ret + move_data: + lea eax,[edi+ecx] + cmp eax,[memory_end] + jae out_of_memory + shr ecx,1 + jnc movsb_ok + movs byte [edi],[esi] + movsb_ok: + shr ecx,1 + jnc movsw_ok + movs word [edi],[esi] + movsw_ok: + rep movs dword [edi],[esi] + ret + string_after_replaced: + lods dword [esi] + stos dword [edi] + mov ecx,eax + call move_data + jmp process_after_replaced + brace_after_replaced: + test [value_type],80h + jz process_after_replaced + mov edx,edi + mov ecx,[current_section] + sub edx,ecx + sub ecx,esi + rep movs byte [edi],[esi] + mov ecx,edi + sub ecx,esi + mov edi,ebp + call move_data + lea esi,[ebp+edx] + ret + symbol_after_replaced: + mov cl,[esi] + inc esi + mov ch,[value_type] + call get_preprocessor_symbol + jnc replace_symbolic_constant + movzx ecx,byte [esi-1] + mov al,1Ah + mov ah,cl + stos word [edi] + call move_data + jmp process_after_replaced + replace_special_symbolic_constant: + jmp near eax + preprocessed_file_value: + call get_current_line_from_file + test ebx,ebx + jz process_after_replaced + push esi edi + mov esi,[ebx] + mov edi,esi + xor al,al + or ecx,-1 + repne scas byte [edi] + add ecx,2 + neg ecx + pop edi + lea eax,[edi+1+4+ecx] + cmp eax,[memory_end] + ja out_of_memory + mov al,22h + stos byte [edi] + mov eax,ecx + stos dword [edi] + rep movs byte [edi],[esi] + pop esi + jmp process_after_replaced + preprocessed_line_value: + call get_current_line_from_file + test ebx,ebx + jz process_after_replaced + lea eax,[edi+1+4+20] + cmp eax,[memory_end] + ja out_of_memory + mov ecx,[ebx+4] + call store_number_symbol + jmp process_after_replaced + get_current_line_from_file: + mov ebx,[current_line] + find_line_from_file: + test ebx,ebx + jz line_from_file_found + test byte [ebx+7],80h + jz line_from_file_found + mov ebx,[ebx+8] + jmp find_line_from_file + line_from_file_found: + ret + +process_macro_operators: + xor dl,dl + mov ebp,edi + before_macro_operators: + mov edi,esi + lods byte [esi] + cmp al,'`' + je symbol_conversion + cmp al,'#' + je concatenation + cmp al,1Ah + je symbol_before_macro_operators + cmp al,3Bh + je no_more_macro_operators + cmp al,22h + je string_before_macro_operators + xor dl,dl + or al,al + jnz before_macro_operators + mov edi,esi + ret + no_more_macro_operators: + mov edi,ebp + ret + symbol_before_macro_operators: + mov dl,1Ah + mov ebx,esi + lods byte [esi] + movzx ecx,al + jecxz symbol_before_macro_operators_ok + mov edi,esi + cmp byte [esi],'\' + je escaped_symbol + symbol_before_macro_operators_ok: + add esi,ecx + jmp before_macro_operators + string_before_macro_operators: + mov dl,22h + mov ebx,esi + lods dword [esi] + add esi,eax + jmp before_macro_operators + escaped_symbol: + dec byte [edi-1] + dec ecx + inc esi + cmp ecx,1 + rep movs byte [edi],[esi] + jne after_macro_operators + mov al,[esi-1] + mov ecx,ebx + mov ebx,characters + xlat byte [ebx] + mov ebx,ecx + or al,al + jnz after_macro_operators + sub edi,3 + mov al,[esi-1] + stos byte [edi] + xor dl,dl + jmp after_macro_operators + reduce_symbol_conversion: + inc esi + symbol_conversion: + mov edx,esi + mov al,[esi] + cmp al,1Ah + jne symbol_character_conversion + lods word [esi] + movzx ecx,ah + lea ebx,[edi+3] + jecxz convert_to_quoted_string + cmp byte [esi],'\' + jne convert_to_quoted_string + inc esi + dec ecx + dec ebx + jmp convert_to_quoted_string + symbol_character_conversion: + cmp al,22h + je after_macro_operators + cmp al,'`' + je reduce_symbol_conversion + lea ebx,[edi+5] + xor ecx,ecx + or al,al + jz convert_to_quoted_string + cmp al,'#' + je convert_to_quoted_string + inc ecx + convert_to_quoted_string: + sub ebx,edx + ja shift_line_data + mov al,22h + mov dl,al + stos byte [edi] + mov ebx,edi + mov eax,ecx + stos dword [edi] + rep movs byte [edi],[esi] + cmp edi,esi + je before_macro_operators + jmp after_macro_operators + shift_line_data: + push ecx + mov edx,esi + lea esi,[ebp-1] + add ebp,ebx + lea edi,[ebp-1] + lea ecx,[esi+1] + sub ecx,edx + std + rep movs byte [edi],[esi] + cld + pop eax + sub edi,3 + mov dl,22h + mov [edi-1],dl + mov ebx,edi + mov [edi],eax + lea esi,[edi+4+eax] + jmp before_macro_operators + concatenation: + cmp dl,1Ah + je symbol_concatenation + cmp dl,22h + je string_concatenation + no_concatenation: + cmp esi,edi + je before_macro_operators + jmp after_macro_operators + symbol_concatenation: + cmp byte [esi],1Ah + jne no_concatenation + inc esi + lods byte [esi] + movzx ecx,al + jecxz do_symbol_concatenation + cmp byte [esi],'\' + je concatenate_escaped_symbol + do_symbol_concatenation: + add [ebx],cl + jc name_too_long + rep movs byte [edi],[esi] + jmp after_macro_operators + concatenate_escaped_symbol: + inc esi + dec ecx + jz do_symbol_concatenation + movzx eax,byte [esi] + cmp byte [characters+eax],0 + jne do_symbol_concatenation + sub esi,3 + jmp no_concatenation + string_concatenation: + cmp byte [esi],22h + je do_string_concatenation + cmp byte [esi],'`' + jne no_concatenation + concatenate_converted_symbol: + inc esi + mov al,[esi] + cmp al,'`' + je concatenate_converted_symbol + cmp al,22h + je do_string_concatenation + cmp al,1Ah + jne concatenate_converted_symbol_character + inc esi + lods byte [esi] + movzx ecx,al + jecxz finish_concatenating_converted_symbol + cmp byte [esi],'\' + jne finish_concatenating_converted_symbol + inc esi + dec ecx + finish_concatenating_converted_symbol: + add [ebx],ecx + rep movs byte [edi],[esi] + jmp after_macro_operators + concatenate_converted_symbol_character: + or al,al + jz after_macro_operators + cmp al,'#' + je after_macro_operators + inc dword [ebx] + movs byte [edi],[esi] + jmp after_macro_operators + do_string_concatenation: + inc esi + lods dword [esi] + mov ecx,eax + add [ebx],eax + rep movs byte [edi],[esi] + after_macro_operators: + lods byte [esi] + cmp al,'`' + je symbol_conversion + cmp al,'#' + je concatenation + stos byte [edi] + cmp al,1Ah + je symbol_after_macro_operators + cmp al,3Bh + je no_more_macro_operators + cmp al,22h + je string_after_macro_operators + xor dl,dl + or al,al + jnz after_macro_operators + ret + symbol_after_macro_operators: + mov dl,1Ah + mov ebx,edi + lods byte [esi] + stos byte [edi] + movzx ecx,al + jecxz symbol_after_macro_operatorss_ok + cmp byte [esi],'\' + je escaped_symbol + symbol_after_macro_operatorss_ok: + rep movs byte [edi],[esi] + jmp after_macro_operators + string_after_macro_operators: + mov dl,22h + mov ebx,edi + lods dword [esi] + stos dword [edi] + mov ecx,eax + rep movs byte [edi],[esi] + jmp after_macro_operators + +use_macro: + push [free_additional_memory] + push [macro_symbols] + mov [macro_symbols],0 + push [counter_limit] + push dword [edx+4] + mov dword [edx+4],1 + push edx + mov ebx,esi + mov esi,[edx+8] + mov eax,[edx+12] + mov [macro_line],eax + mov [counter_limit],0 + xor ebp,ebp + process_macro_arguments: + mov al,[esi] + or al,al + jz arguments_end + cmp al,'{' + je arguments_end + inc esi + cmp al,'[' + jne get_macro_arguments + mov ebp,esi + inc esi + inc [counter_limit] + get_macro_arguments: + call get_macro_argument + lods byte [esi] + cmp al,',' + je next_argument + cmp al,']' + je next_arguments_group + cmp al,'&' + je arguments_end + dec esi + jmp arguments_end + next_argument: + cmp byte [ebx],',' + jne process_macro_arguments + inc ebx + jmp process_macro_arguments + next_arguments_group: + cmp byte [ebx],',' + jne arguments_end + inc ebx + inc [counter_limit] + mov esi,ebp + jmp process_macro_arguments + get_macro_argument: + lods byte [esi] + movzx ecx,al + mov eax,[counter_limit] + call add_macro_symbol + add esi,ecx + xor eax,eax + mov [default_argument_value],eax + cmp byte [esi],'*' + je required_value + cmp byte [esi],':' + je get_default_value + cmp byte [esi],'=' + jne default_value_ok + get_default_value: + inc esi + mov [default_argument_value],esi + or [skip_default_argument_value],-1 + call skip_macro_argument_value + jmp default_value_ok + required_value: + inc esi + or [default_argument_value],-1 + default_value_ok: + xchg esi,ebx + mov [edx+12],esi + mov [skip_default_argument_value],0 + cmp byte [ebx],'&' + je greedy_macro_argument + call skip_macro_argument_value + call finish_macro_argument + jmp got_macro_argument + greedy_macro_argument: + call skip_foreign_line + dec esi + mov eax,[edx+12] + mov ecx,esi + sub ecx,eax + mov [edx+8],ecx + got_macro_argument: + xchg esi,ebx + cmp dword [edx+8],0 + jne macro_argument_ok + mov eax,[default_argument_value] + or eax,eax + jz macro_argument_ok + cmp eax,-1 + je invalid_macro_arguments + mov [edx+12],eax + call finish_macro_argument + macro_argument_ok: + ret + finish_macro_argument: + mov eax,[edx+12] + mov ecx,esi + sub ecx,eax + cmp byte [eax],'<' + jne argument_value_length_ok + inc dword [edx+12] + sub ecx,2 + or ecx,80000000h + argument_value_length_ok: + mov [edx+8],ecx + ret + arguments_end: + cmp byte [ebx],0 + jne invalid_macro_arguments + mov eax,[esp+4] + dec eax + call process_macro + pop edx + pop dword [edx+4] + pop [counter_limit] + pop [macro_symbols] + pop [free_additional_memory] + jmp line_preprocessed +use_instant_macro: + push edi + push [current_line] + push esi + mov eax,[error_line] + mov [current_line],eax + mov [macro_line],eax + mov esi,[instant_macro_start] + cmp [base_code],10h + jae do_match + cmp [base_code],0 + jne do_irp + call precalculate_value + cmp eax,0 + jl value_out_of_range + push [free_additional_memory] + push [macro_symbols] + mov [macro_symbols],0 + push [counter_limit] + mov [struc_name],0 + mov [counter_limit],eax + lods byte [esi] + or al,al + jz rept_counters_ok + cmp al,'{' + je rept_counters_ok + cmp al,1Ah + jne invalid_macro_arguments + add_rept_counter: + lods byte [esi] + movzx ecx,al + xor eax,eax + call add_macro_symbol + add esi,ecx + xor eax,eax + mov dword [edx+12],eax + inc eax + mov dword [edx+8],eax + lods byte [esi] + cmp al,':' + jne rept_counter_added + push edx + call precalculate_value + mov edx,eax + add edx,[counter_limit] + jo value_out_of_range + pop edx + mov dword [edx+8],eax + lods byte [esi] + rept_counter_added: + cmp al,',' + jne rept_counters_ok + lods byte [esi] + cmp al,1Ah + jne invalid_macro_arguments + jmp add_rept_counter + rept_counters_ok: + dec esi + cmp [counter_limit],0 + je instant_macro_finish + instant_macro_parameters_ok: + xor eax,eax + call process_macro + instant_macro_finish: + pop [counter_limit] + pop [macro_symbols] + pop [free_additional_memory] + instant_macro_done: + pop ebx esi edx + cmp byte [ebx],0 + je line_preprocessed + mov [current_line],edi + mov ecx,4 + rep movs dword [edi],[esi] + test [macro_status],0Fh + jz instant_macro_attached_line + mov ax,3Bh + stos word [edi] + instant_macro_attached_line: + mov esi,ebx + sub edx,ebx + mov ecx,edx + call move_data + jmp initial_preprocessing_ok + precalculate_value: + push edi + call convert_expression + mov al,')' + stosb + push esi + mov esi,[esp+4] + mov [error_line],0 + mov [value_size],0 + call calculate_expression + cmp [error_line],0 + je value_precalculated + jmp [error] + value_precalculated: + mov eax,[edi] + mov ecx,[edi+4] + cdq + cmp edx,ecx + jne value_out_of_range + cmp dl,[edi+13] + jne value_out_of_range + pop esi edi + ret +do_irp: + cmp byte [esi],1Ah + jne invalid_macro_arguments + movzx eax,byte [esi+1] + lea esi,[esi+2+eax] + lods byte [esi] + cmp [base_code],1 + ja irps_name_ok + cmp al,':' + je irp_with_default_value + cmp al,'=' + je irp_with_default_value + cmp al,'*' + jne irp_name_ok + lods byte [esi] + irp_name_ok: + cmp al,',' + jne invalid_macro_arguments + jmp irp_parameters_start + irp_with_default_value: + xor ebp,ebp + or [skip_default_argument_value],-1 + call skip_macro_argument_value + cmp byte [esi],',' + jne invalid_macro_arguments + inc esi + jmp irp_parameters_start + irps_name_ok: + cmp al,',' + jne invalid_macro_arguments + cmp [base_code],3 + je irp_parameters_start + mov al,[esi] + or al,al + jz instant_macro_done + cmp al,'{' + je instant_macro_done + irp_parameters_start: + xor eax,eax + push [free_additional_memory] + push [macro_symbols] + mov [macro_symbols],eax + push [counter_limit] + mov [counter_limit],eax + mov [struc_name],eax + cmp [base_code],3 + je get_irpv_parameter + mov ebx,esi + cmp [base_code],2 + je get_irps_parameter + mov edx,[parameters_end] + mov al,[edx] + push eax + mov byte [edx],0 + get_irp_parameter: + inc [counter_limit] + mov esi,[instant_macro_start] + inc esi + call get_macro_argument + cmp byte [ebx],',' + jne irp_parameters_end + inc ebx + jmp get_irp_parameter + irp_parameters_end: + mov esi,ebx + pop eax + mov [esi],al + jmp instant_macro_parameters_ok + get_irps_parameter: + mov esi,[instant_macro_start] + inc esi + lods byte [esi] + movzx ecx,al + inc [counter_limit] + mov eax,[counter_limit] + call add_macro_symbol + mov [edx+12],ebx + cmp byte [ebx],1Ah + je irps_symbol + cmp byte [ebx],22h + je irps_quoted_string + mov eax,1 + jmp irps_parameter_ok + irps_quoted_string: + mov eax,[ebx+1] + add eax,1+4 + jmp irps_parameter_ok + irps_symbol: + movzx eax,byte [ebx+1] + add eax,1+1 + irps_parameter_ok: + mov [edx+8],eax + add ebx,eax + cmp byte [ebx],0 + je irps_parameters_end + cmp byte [ebx],'{' + jne get_irps_parameter + irps_parameters_end: + mov esi,ebx + jmp instant_macro_parameters_ok + get_irpv_parameter: + lods byte [esi] + cmp al,1Ah + jne invalid_macro_arguments + lods byte [esi] + mov ebp,esi + mov cl,al + mov ch,10b + call get_preprocessor_symbol + jc instant_macro_finish + test edx,edx + jz invalid_use_of_symbol + push edx + mark_variable_value: + inc [counter_limit] + mov [edx+4],ebp + next_variable_value: + mov edx,[edx] + or edx,edx + jz variable_values_marked + mov eax,[edx+4] + cmp eax,1 + jbe next_variable_value + mov esi,ebp + movzx ecx,byte [esi-1] + xchg edi,eax + repe cmps byte [esi],[edi] + xchg edi,eax + je mark_variable_value + jmp next_variable_value + variable_values_marked: + pop edx + push [counter_limit] + add_irpv_value: + push edx + mov esi,[instant_macro_start] + inc esi + lods byte [esi] + movzx ecx,al + mov eax,[esp+4] + call add_macro_symbol + mov ebx,edx + pop edx + mov ecx,[edx+12] + mov eax,[edx+8] + mov [ebx+12],eax + mov [ebx+8],ecx + collect_next_variable_value: + mov edx,[edx] + or edx,edx + jz variable_values_collected + cmp ebp,[edx+4] + jne collect_next_variable_value + dec dword [esp] + jnz add_irpv_value + variable_values_collected: + pop eax + mov esi,ebp + movzx ecx,byte [esi-1] + add esi,ecx + cmp byte [esi],0 + je instant_macro_parameters_ok + cmp byte [esi],'{' + jne invalid_macro_arguments + jmp instant_macro_parameters_ok + +do_match: + mov ebx,esi + call skip_pattern + call exact_match + mov edx,edi + mov al,[ebx] + cmp al,1Ah + je free_match + cmp al,',' + jne instant_macro_done + cmp esi,[parameters_end] + je matched_pattern + jmp instant_macro_done + free_match: + add edx,12 + cmp edx,[memory_end] + ja out_of_memory + mov [edx-12],ebx + mov [edx-8],esi + call skip_match_element + jc try_different_matching + mov [edx-4],esi + movzx eax,byte [ebx+1] + lea ebx,[ebx+2+eax] + cmp byte [ebx],1Ah + je free_match + find_exact_match: + call exact_match + cmp esi,[parameters_end] + je end_matching + cmp byte [ebx],1Ah + je free_match + mov ebx,[edx-12] + movzx eax,byte [ebx+1] + lea ebx,[ebx+2+eax] + mov esi,[edx-4] + jmp match_more_elements + try_different_matching: + sub edx,12 + cmp edx,edi + je instant_macro_done + mov ebx,[edx-12] + movzx eax,byte [ebx+1] + lea ebx,[ebx+2+eax] + cmp byte [ebx],1Ah + je try_different_matching + mov esi,[edx-4] + match_more_elements: + call skip_match_element + jc try_different_matching + mov [edx-4],esi + jmp find_exact_match + skip_match_element: + cmp esi,[parameters_end] + je cannot_match + mov al,[esi] + cmp al,1Ah + je skip_match_symbol + cmp al,22h + je skip_match_quoted_string + add esi,1 + ret + skip_match_quoted_string: + mov eax,[esi+1] + add esi,5 + jmp skip_match_ok + skip_match_symbol: + movzx eax,byte [esi+1] + add esi,2 + skip_match_ok: + add esi,eax + ret + cannot_match: + stc + ret + exact_match: + cmp esi,[parameters_end] + je exact_match_complete + mov ah,[esi] + mov al,[ebx] + cmp al,',' + je exact_match_complete + cmp al,1Ah + je exact_match_complete + cmp al,'=' + je match_verbatim + call match_elements + je exact_match + exact_match_complete: + ret + match_verbatim: + inc ebx + call match_elements + je exact_match + dec ebx + ret + match_elements: + mov al,[ebx] + cmp al,1Ah + je match_symbols + cmp al,22h + je match_quoted_strings + cmp al,ah + je symbol_characters_matched + ret + symbol_characters_matched: + lea ebx,[ebx+1] + lea esi,[esi+1] + ret + match_quoted_strings: + mov ecx,[ebx+1] + add ecx,5 + jmp compare_elements + match_symbols: + movzx ecx,byte [ebx+1] + add ecx,2 + compare_elements: + mov eax,esi + mov ebp,edi + mov edi,ebx + repe cmps byte [esi],[edi] + jne elements_mismatch + mov ebx,edi + mov edi,ebp + ret + elements_mismatch: + mov esi,eax + mov edi,ebp + ret + end_matching: + cmp byte [ebx],',' + jne instant_macro_done + matched_pattern: + xor eax,eax + push [free_additional_memory] + push [macro_symbols] + mov [macro_symbols],eax + push [counter_limit] + mov [counter_limit],eax + mov [struc_name],eax + push esi edi edx + add_matched_symbol: + cmp edi,[esp] + je matched_symbols_ok + mov esi,[edi] + inc esi + lods byte [esi] + movzx ecx,al + xor eax,eax + call add_macro_symbol + mov eax,[edi+4] + mov dword [edx+12],eax + mov ecx,[edi+8] + sub ecx,eax + mov dword [edx+8],ecx + add edi,12 + jmp add_matched_symbol + matched_symbols_ok: + pop edx edi esi + jmp instant_macro_parameters_ok + +process_macro: + push dword [macro_status] + or [macro_status],10h + push [counter] + push [macro_block] + push [macro_block_line] + push [macro_block_line_number] + push [struc_label] + push [struc_name] + push eax + push [current_line] + lods byte [esi] + cmp al,'{' + je macro_instructions_start + or al,al + jnz unexpected_characters + find_macro_instructions: + mov [macro_line],esi + add esi,16+2 + lods byte [esi] + or al,al + jz find_macro_instructions + cmp al,'{' + je macro_instructions_start + cmp al,3Bh + jne unexpected_characters + call skip_foreign_symbol + jmp find_macro_instructions + macro_instructions_start: + mov ecx,80000000h + mov [macro_block],esi + mov eax,[macro_line] + mov [macro_block_line],eax + mov [macro_block_line_number],ecx + xor eax,eax + mov [counter],eax + cmp [counter_limit],eax + je process_macro_line + inc [counter] + process_macro_line: + lods byte [esi] + or al,al + jz process_next_line + cmp al,'}' + je macro_block_processed + dec esi + mov [current_line],edi + lea eax,[edi+10h] + cmp eax,[memory_end] + jae out_of_memory + mov eax,[esp+4] + or eax,eax + jz instant_macro_line_header + stos dword [edi] + mov eax,ecx + stos dword [edi] + mov eax,[esp] + stos dword [edi] + mov eax,[macro_line] + stos dword [edi] + jmp macro_line_header_ok + instant_macro_line_header: + mov eax,[esp] + add eax,16 + find_defining_directive: + inc eax + cmp byte [eax-1],3Bh + je defining_directive_ok + cmp byte [eax-1],1Ah + jne find_defining_directive + push eax + movzx eax,byte [eax] + inc eax + add [esp],eax + pop eax + jmp find_defining_directive + defining_directive_ok: + stos dword [edi] + mov eax,ecx + stos dword [edi] + mov eax,[macro_line] + stos dword [edi] + stos dword [edi] + macro_line_header_ok: + or [macro_status],20h + push ebx ecx + test [macro_status],0Fh + jz process_macro_line_element + mov ax,3Bh + stos word [edi] + process_macro_line_element: + lea eax,[edi+100h] + cmp eax,[memory_end] + jae out_of_memory + lods byte [esi] + cmp al,'}' + je macro_line_processed + or al,al + jz macro_line_processed + cmp al,1Ah + je process_macro_symbol + cmp al,3Bh + je macro_foreign_line + and [macro_status],not 20h + stos byte [edi] + cmp al,22h + jne process_macro_line_element + copy_macro_string: + mov ecx,[esi] + add ecx,4 + call move_data + jmp process_macro_line_element + process_macro_symbol: + push esi edi + test [macro_status],20h + jz not_macro_directive + movzx ecx,byte [esi] + inc esi + mov edi,macro_directives + call get_directive + jnc process_macro_directive + dec esi + jmp not_macro_directive + process_macro_directive: + mov edx,eax + pop edi eax + mov byte [edi],0 + inc edi + pop ecx ebx + jmp near edx + not_macro_directive: + and [macro_status],not 20h + movzx ecx,byte [esi] + inc esi + mov eax,[counter] + call get_macro_symbol + jnc group_macro_symbol + xor eax,eax + cmp [counter],eax + je multiple_macro_symbol_values + call get_macro_symbol + jc not_macro_symbol + replace_macro_symbol: + pop edi eax + mov ecx,[edx+8] + mov edx,[edx+12] + or edx,edx + jz replace_macro_counter + and ecx,not 80000000h + xchg esi,edx + call move_data + mov esi,edx + jmp process_macro_line_element + group_macro_symbol: + xor eax,eax + cmp [counter],eax + je replace_macro_symbol + push esi edx + sub esi,ecx + call get_macro_symbol + mov ebx,edx + pop edx esi + jc replace_macro_symbol + cmp edx,ebx + ja replace_macro_symbol + mov edx,ebx + jmp replace_macro_symbol + multiple_macro_symbol_values: + inc eax + push eax + call get_macro_symbol + pop eax + jc not_macro_symbol + pop edi + push ecx + mov ecx,[edx+8] + mov edx,[edx+12] + xchg esi,edx + btr ecx,31 + jc enclose_macro_symbol_value + rep movs byte [edi],[esi] + jmp macro_symbol_value_ok + enclose_macro_symbol_value: + mov byte [edi],'<' + inc edi + rep movs byte [edi],[esi] + mov byte [edi],'>' + inc edi + macro_symbol_value_ok: + cmp eax,[counter_limit] + je multiple_macro_symbol_values_ok + mov byte [edi],',' + inc edi + mov esi,edx + pop ecx + push edi + sub esi,ecx + jmp multiple_macro_symbol_values + multiple_macro_symbol_values_ok: + pop ecx eax + mov esi,edx + jmp process_macro_line_element + replace_macro_counter: + mov eax,[counter] + and eax,not 80000000h + jz group_macro_counter + add ecx,eax + dec ecx + call store_number_symbol + jmp process_macro_line_element + group_macro_counter: + mov edx,ecx + xor ecx,ecx + multiple_macro_counter_values: + push ecx edx + add ecx,edx + call store_number_symbol + pop edx ecx + inc ecx + cmp ecx,[counter_limit] + je process_macro_line_element + mov byte [edi],',' + inc edi + jmp multiple_macro_counter_values + store_number_symbol: + cmp ecx,0 + jge numer_symbol_sign_ok + neg ecx + mov al,'-' + stos byte [edi] + numer_symbol_sign_ok: + mov ax,1Ah + stos word [edi] + push edi + mov eax,ecx + mov ecx,1000000000 + xor edx,edx + xor bl,bl + store_number_digits: + div ecx + push edx + or bl,bl + jnz store_number_digit + cmp ecx,1 + je store_number_digit + or al,al + jz number_digit_ok + not bl + store_number_digit: + add al,30h + stos byte [edi] + number_digit_ok: + mov eax,ecx + xor edx,edx + mov ecx,10 + div ecx + mov ecx,eax + pop eax + or ecx,ecx + jnz store_number_digits + pop ebx + mov eax,edi + sub eax,ebx + mov [ebx-1],al + ret + not_macro_symbol: + pop edi esi + mov al,1Ah + stos byte [edi] + mov al,[esi] + inc esi + stos byte [edi] + cmp byte [esi],'.' + jne copy_raw_symbol + mov ebx,[esp+8+8] + or ebx,ebx + jz copy_raw_symbol + cmp al,1 + je copy_struc_name + xchg esi,ebx + movzx ecx,byte [esi-1] + add [edi-1],cl + jc name_too_long + rep movs byte [edi],[esi] + xchg esi,ebx + copy_raw_symbol: + movzx ecx,al + rep movs byte [edi],[esi] + jmp process_macro_line_element + copy_struc_name: + inc esi + xchg esi,ebx + movzx ecx,byte [esi-1] + mov [edi-1],cl + rep movs byte [edi],[esi] + xchg esi,ebx + mov eax,[esp+8+12] + cmp byte [eax],3Bh + je process_macro_line_element + cmp byte [eax],1Ah + jne disable_replaced_struc_name + mov byte [eax],3Bh + jmp process_macro_line_element + disable_replaced_struc_name: + mov ebx,[esp+8+8] + push esi edi + lea edi,[ebx-3] + lea esi,[edi-2] + lea ecx,[esi+1] + sub ecx,eax + std + rep movs byte [edi],[esi] + cld + mov word [eax],3Bh + pop edi esi + jmp process_macro_line_element + skip_foreign_symbol: + lods byte [esi] + movzx eax,al + add esi,eax + skip_foreign_line: + lods byte [esi] + cmp al,1Ah + je skip_foreign_symbol + cmp al,3Bh + je skip_foreign_symbol + cmp al,22h + je skip_foreign_string + or al,al + jnz skip_foreign_line + ret + skip_foreign_string: + lods dword [esi] + add esi,eax + jmp skip_foreign_line + macro_foreign_line: + call skip_foreign_symbol + macro_line_processed: + mov byte [edi],0 + inc edi + push eax + call preprocess_line + pop eax + pop ecx ebx + cmp al,'}' + je macro_block_processed + process_next_line: + inc ecx + mov [macro_line],esi + add esi,16+2 + jmp process_macro_line + macro_block_processed: + call close_macro_block + jc process_macro_line + pop [current_line] + add esp,12 + pop [macro_block_line_number] + pop [macro_block_line] + pop [macro_block] + pop [counter] + pop eax + and al,0F0h + and [macro_status],0Fh + or [macro_status],al + ret + +local_symbols: + lods byte [esi] + cmp al,1Ah + jne invalid_argument + mov byte [edi-1],3Bh + xor al,al + stos byte [edi] + make_local_symbol: + push ecx + lods byte [esi] + movzx ecx,al + mov eax,[counter] + call add_macro_symbol + mov [edx+12],edi + movzx eax,[locals_counter] + add eax,ecx + inc eax + cmp eax,100h + jae name_too_long + lea ebp,[edi+2+eax] + cmp ebp,[memory_end] + jae out_of_memory + mov ah,al + mov al,1Ah + stos word [edi] + rep movs byte [edi],[esi] + mov al,'?' + stos byte [edi] + push esi + mov esi,locals_counter+1 + movzx ecx,[locals_counter] + rep movs byte [edi],[esi] + pop esi + mov eax,edi + sub eax,[edx+12] + mov [edx+8],eax + xor al,al + stos byte [edi] + mov eax,locals_counter + movzx ecx,byte [eax] + counter_loop: + inc byte [eax+ecx] + cmp byte [eax+ecx],'9'+1 + jb counter_ok + jne letter_digit + mov byte [eax+ecx],'A' + jmp counter_ok + letter_digit: + cmp byte [eax+ecx],'Z'+1 + jb counter_ok + jne small_letter_digit + mov byte [eax+ecx],'a' + jmp counter_ok + small_letter_digit: + cmp byte [eax+ecx],'z'+1 + jb counter_ok + mov byte [eax+ecx],'0' + loop counter_loop + inc byte [eax] + movzx ecx,byte [eax] + mov byte [eax+ecx],'0' + counter_ok: + pop ecx + lods byte [esi] + cmp al,'}' + je macro_block_processed + or al,al + jz process_next_line + cmp al,',' + jne extra_characters_on_line + dec edi + lods byte [esi] + cmp al,1Ah + je make_local_symbol + jmp invalid_argument +common_block: + call close_macro_block + jc process_macro_line + mov [counter],0 + jmp new_macro_block +forward_block: + cmp [counter_limit],0 + je common_block + call close_macro_block + jc process_macro_line + mov [counter],1 + jmp new_macro_block +reverse_block: + cmp [counter_limit],0 + je common_block + call close_macro_block + jc process_macro_line + mov eax,[counter_limit] + or eax,80000000h + mov [counter],eax + new_macro_block: + mov [macro_block],esi + mov eax,[macro_line] + mov [macro_block_line],eax + mov [macro_block_line_number],ecx + jmp process_macro_line +close_macro_block: + cmp esi,[macro_block] + je block_closed + cmp [counter],0 + je block_closed + jl reverse_counter + mov eax,[counter] + cmp eax,[counter_limit] + je block_closed + inc [counter] + jmp continue_block + reverse_counter: + mov eax,[counter] + dec eax + cmp eax,80000000h + je block_closed + mov [counter],eax + continue_block: + mov esi,[macro_block] + mov eax,[macro_block_line] + mov [macro_line],eax + mov ecx,[macro_block_line_number] + stc + ret + block_closed: + clc + ret +get_macro_symbol: + push ecx + call find_macro_symbol_leaf + jc macro_symbol_not_found + mov edx,[ebx] + mov ebx,esi + try_macro_symbol: + or edx,edx + jz macro_symbol_not_found + mov ecx,[esp] + mov edi,[edx+4] + repe cmps byte [esi],[edi] + je macro_symbol_found + mov esi,ebx + mov edx,[edx] + jmp try_macro_symbol + macro_symbol_found: + pop ecx + clc + ret + macro_symbol_not_found: + pop ecx + stc + ret + find_macro_symbol_leaf: + shl eax,8 + mov al,cl + mov ebp,eax + mov ebx,macro_symbols + follow_macro_symbols_tree: + mov edx,[ebx] + or edx,edx + jz no_such_macro_symbol + xor eax,eax + shr ebp,1 + adc eax,0 + lea ebx,[edx+eax*4] + or ebp,ebp + jnz follow_macro_symbols_tree + add ebx,8 + clc + ret + no_such_macro_symbol: + stc + ret +add_macro_symbol: + push ebx ebp + call find_macro_symbol_leaf + jc extend_macro_symbol_tree + mov eax,[ebx] + make_macro_symbol: + mov edx,[free_additional_memory] + add edx,16 + cmp edx,[labels_list] + ja out_of_memory + xchg edx,[free_additional_memory] + mov [ebx],edx + mov [edx],eax + mov [edx+4],esi + pop ebp ebx + ret + extend_macro_symbol_tree: + mov edx,[free_additional_memory] + add edx,16 + cmp edx,[labels_list] + ja out_of_memory + xchg edx,[free_additional_memory] + xor eax,eax + mov [edx],eax + mov [edx+4],eax + mov [edx+8],eax + mov [edx+12],eax + shr ebp,1 + adc eax,0 + mov [ebx],edx + lea ebx,[edx+eax*4] + or ebp,ebp + jnz extend_macro_symbol_tree + add ebx,8 + xor eax,eax + jmp make_macro_symbol + +include_file: + lods byte [esi] + cmp al,22h + jne invalid_argument + lods dword [esi] + cmp byte [esi+eax],0 + jne extra_characters_on_line + push esi + push edi + mov ebx,[current_line] + find_current_file_path: + mov esi,[ebx] + test byte [ebx+7],80h + jz copy_current_file_path + mov ebx,[ebx+8] + jmp find_current_file_path + copy_current_file_path: + lods byte [esi] + stos byte [edi] + or al,al + jnz copy_current_file_path + cut_current_file_name: + cmp edi,[esp] + je current_file_path_ok + cmp byte [edi-1],'\' + je current_file_path_ok + cmp byte [edi-1],'/' + je current_file_path_ok + dec edi + jmp cut_current_file_name + current_file_path_ok: + mov esi,[esp+4] + call expand_path + pop edx + mov esi,edx + call open + jnc include_path_ok + mov ebp,[include_paths] + try_include_directories: + mov edi,esi + mov esi,ebp + cmp byte [esi],0 + je try_in_current_directory + push ebp + push edi + call get_include_directory + mov [esp+4],esi + mov esi,[esp+8] + call expand_path + pop edx + mov esi,edx + call open + pop ebp + jnc include_path_ok + jmp try_include_directories + mov edi,esi + try_in_current_directory: + mov esi,[esp] + push edi + call expand_path + pop edx + mov esi,edx + call open + jc file_not_found + include_path_ok: + mov edi,[esp] + copy_preprocessed_path: + lods byte [esi] + stos byte [edi] + or al,al + jnz copy_preprocessed_path + pop esi + lea ecx,[edi-1] + sub ecx,esi + mov [esi-4],ecx + push dword [macro_status] + and [macro_status],0Fh + call preprocess_file + pop eax + and al,0F0h + and [macro_status],0Fh + or [macro_status],al + jmp line_preprocessed diff --git a/toolchain/fasmw17332/SOURCE/SYMBDUMP.INC b/toolchain/fasmw17332/SOURCE/SYMBDUMP.INC new file mode 100644 index 0000000..c1abdad --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/SYMBDUMP.INC @@ -0,0 +1,450 @@ + +; flat assembler core +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +dump_symbols: + mov edi,[code_start] + call setup_dump_header + mov esi,[input_file] + call copy_asciiz + cmp edi,[tagged_blocks] + jae out_of_memory + mov eax,edi + sub eax,ebx + mov [ebx-40h+0Ch],eax + mov esi,[output_file] + call copy_asciiz + cmp edi,[tagged_blocks] + jae out_of_memory + mov edx,[symbols_stream] + mov ebp,[free_additional_memory] + and [number_of_sections],0 + cmp [output_format],4 + je prepare_strings_table + cmp [output_format],5 + jne strings_table_ready + bt [format_flags],0 + jc strings_table_ready + prepare_strings_table: + cmp edx,ebp + je strings_table_ready + mov al,[edx] + test al,al + jz prepare_string + cmp al,80h + je prepare_string + add edx,0Ch + cmp al,0C0h + jb prepare_strings_table + add edx,4 + jmp prepare_strings_table + prepare_string: + mov esi,edi + sub esi,ebx + xchg esi,[edx+4] + test al,al + jz prepare_section_string + or dword [edx+4],1 shl 31 + add edx,0Ch + prepare_external_string: + mov ecx,[esi] + add esi,4 + rep movs byte [edi],[esi] + mov byte [edi],0 + inc edi + cmp edi,[tagged_blocks] + jae out_of_memory + jmp prepare_strings_table + prepare_section_string: + mov ecx,[number_of_sections] + mov eax,ecx + inc eax + mov [number_of_sections],eax + xchg eax,[edx+4] + shl ecx,2 + add ecx,[free_additional_memory] + mov [ecx],eax + add edx,20h + test esi,esi + jz prepare_default_section_string + cmp [output_format],5 + jne prepare_external_string + bt [format_flags],0 + jc prepare_external_string + mov esi,[esi] + add esi,[resource_data] + copy_elf_section_name: + lods byte [esi] + cmp edi,[tagged_blocks] + jae out_of_memory + stos byte [edi] + test al,al + jnz copy_elf_section_name + jmp prepare_strings_table + prepare_default_section_string: + mov eax,'.fla' + stos dword [edi] + mov ax,'t' + stos word [edi] + cmp edi,[tagged_blocks] + jae out_of_memory + jmp prepare_strings_table + strings_table_ready: + mov edx,[tagged_blocks] + mov ebp,[memory_end] + sub ebp,[labels_list] + add ebp,edx + prepare_labels_dump: + cmp edx,ebp + je labels_dump_ok + mov eax,[edx+24] + test eax,eax + jz label_dump_name_ok + cmp eax,[memory_start] + jb label_name_outside_source + cmp eax,[source_start] + ja label_name_outside_source + sub eax,[memory_start] + dec eax + mov [edx+24],eax + jmp label_dump_name_ok + label_name_outside_source: + mov esi,eax + mov eax,edi + sub eax,ebx + or eax,1 shl 31 + mov [edx+24],eax + movzx ecx,byte [esi-1] + lea eax,[edi+ecx+1] + cmp edi,[tagged_blocks] + jae out_of_memory + rep movsb + xor al,al + stosb + label_dump_name_ok: + mov eax,[edx+28] + test eax,eax + jz label_dump_line_ok + sub eax,[memory_start] + mov [edx+28],eax + label_dump_line_ok: + test byte [edx+9],4 + jz convert_base_symbol_for_label + xor eax,eax + mov [edx],eax + mov [edx+4],eax + jmp base_symbol_for_label_ok + convert_base_symbol_for_label: + mov eax,[edx+20] + test eax,eax + jz base_symbol_for_label_ok + cmp eax,[symbols_stream] + mov eax,[eax+4] + jae base_symbol_for_label_ok + xor eax,eax + base_symbol_for_label_ok: + mov [edx+20],eax + mov ax,[current_pass] + cmp ax,[edx+16] + je label_defined_flag_ok + and byte [edx+8],not 1 + label_defined_flag_ok: + cmp ax,[edx+18] + je label_used_flag_ok + and byte [edx+8],not 8 + label_used_flag_ok: + add edx,LABEL_STRUCTURE_SIZE + jmp prepare_labels_dump + labels_dump_ok: + mov eax,edi + sub eax,ebx + mov [ebx-40h+14h],eax + add eax,40h + mov [ebx-40h+18h],eax + mov ecx,[memory_end] + sub ecx,[labels_list] + mov [ebx-40h+1Ch],ecx + add eax,ecx + mov [ebx-40h+20h],eax + mov ecx,[source_start] + sub ecx,[memory_start] + mov [ebx-40h+24h],ecx + add eax,ecx + mov [ebx-40h+28h],eax + mov eax,[number_of_sections] + shl eax,2 + mov [ebx-40h+34h],eax + call prepare_preprocessed_source + mov esi,[labels_list] + mov ebp,edi + make_lines_dump: + cmp esi,[tagged_blocks] + je lines_dump_ok + mov eax,[esi-4] + mov ecx,[esi-8] + sub esi,8 + sub esi,ecx + cmp eax,1 + je process_line_dump + cmp eax,2 + jne make_lines_dump + add dword [ebx-40h+3Ch],8 + jmp make_lines_dump + process_line_dump: + push ebx + mov ebx,[esi+8] + mov eax,[esi+4] + sub eax,[code_start] + add eax,[headers_size] + test byte [ebx+0Ah],1 + jz store_offset + xor eax,eax + store_offset: + stos dword [edi] + mov eax,[esi] + sub eax,[memory_start] + stos dword [edi] + mov eax,[esi+4] + xor edx,edx + xor cl,cl + sub eax,[ebx] + sbb edx,[ebx+4] + sbb cl,[ebx+8] + stos dword [edi] + mov eax,edx + stos dword [edi] + mov eax,[ebx+10h] + stos dword [edi] + mov eax,[ebx+14h] + test eax,eax + jz base_symbol_for_line_ok + cmp eax,[symbols_stream] + mov eax,[eax+4] + jae base_symbol_for_line_ok + xor eax,eax + base_symbol_for_line_ok: + stos dword [edi] + mov al,[ebx+9] + stos byte [edi] + mov al,[esi+10h] + stos byte [edi] + mov al,[ebx+0Ah] + and al,1 + stos byte [edi] + mov al,cl + stos byte [edi] + pop ebx + cmp edi,[tagged_blocks] + jae out_of_memory + mov eax,edi + sub eax,1Ch + sub eax,ebp + mov [esi],eax + jmp make_lines_dump + lines_dump_ok: + mov edx,edi + mov eax,[current_offset] + sub eax,[code_start] + add eax,[headers_size] + stos dword [edi] + mov ecx,edi + sub ecx,ebx + sub ecx,[ebx-40h+14h] + mov [ebx-40h+2Ch],ecx + add ecx,[ebx-40h+28h] + mov [ebx-40h+30h],ecx + add ecx,[ebx-40h+34h] + mov [ebx-40h+38h],ecx + find_inexisting_offsets: + sub edx,1Ch + cmp edx,ebp + jb write_symbols + test byte [edx+1Ah],1 + jnz find_inexisting_offsets + cmp eax,[edx] + jb correct_inexisting_offset + mov eax,[edx] + jmp find_inexisting_offsets + correct_inexisting_offset: + and dword [edx],0 + or byte [edx+1Ah],2 + jmp find_inexisting_offsets + write_symbols: + mov edx,[symbols_file] + call create + jc write_failed + mov edx,[code_start] + mov ecx,[edx+14h] + add ecx,40h + call write + jc write_failed + mov edx,[tagged_blocks] + mov ecx,[memory_end] + sub ecx,[labels_list] + call write + jc write_failed + mov edx,[memory_start] + mov ecx,[source_start] + sub ecx,edx + call write + jc write_failed + mov edx,ebp + mov ecx,edi + sub ecx,edx + call write + jc write_failed + mov edx,[free_additional_memory] + mov ecx,[number_of_sections] + shl ecx,2 + call write + jc write_failed + mov esi,[labels_list] + mov edi,[memory_start] + make_references_dump: + cmp esi,[tagged_blocks] + je references_dump_ok + mov eax,[esi-4] + mov ecx,[esi-8] + sub esi,8 + sub esi,ecx + cmp eax,2 + je dump_reference + cmp eax,1 + jne make_references_dump + mov edx,[esi] + jmp make_references_dump + dump_reference: + mov eax,[memory_end] + sub eax,[esi] + sub eax,LABEL_STRUCTURE_SIZE + stosd + mov eax,edx + stosd + cmp edi,[tagged_blocks] + jb make_references_dump + jmp out_of_memory + references_dump_ok: + mov edx,[memory_start] + mov ecx,edi + sub ecx,edx + call write + jc write_failed + call close + ret + setup_dump_header: + xor eax,eax + mov ecx,40h shr 2 + rep stos dword [edi] + mov ebx,edi + mov dword [ebx-40h],'fas'+1Ah shl 24 + mov dword [ebx-40h+4],VERSION_MAJOR + VERSION_MINOR shl 8 + 40h shl 16 + mov dword [ebx-40h+10h],40h + ret +prepare_preprocessed_source: + mov esi,[memory_start] + mov ebp,[source_start] + test ebp,ebp + jnz prepare_preprocessed_line + mov ebp,[current_line] + inc ebp + prepare_preprocessed_line: + cmp esi,ebp + jae preprocessed_source_ok + mov eax,[memory_start] + mov edx,[input_file] + cmp [esi],edx + jne line_not_from_main_input + mov [esi],eax + line_not_from_main_input: + sub [esi],eax + test byte [esi+7],1 shl 7 + jz prepare_next_preprocessed_line + sub [esi+8],eax + sub [esi+12],eax + prepare_next_preprocessed_line: + call skip_preprocessed_line + jmp prepare_preprocessed_line + preprocessed_source_ok: + ret + skip_preprocessed_line: + add esi,16 + skip_preprocessed_line_content: + lods byte [esi] + cmp al,1Ah + je skip_preprocessed_symbol + cmp al,3Bh + je skip_preprocessed_symbol + cmp al,22h + je skip_preprocessed_string + or al,al + jnz skip_preprocessed_line_content + ret + skip_preprocessed_string: + lods dword [esi] + add esi,eax + jmp skip_preprocessed_line_content + skip_preprocessed_symbol: + lods byte [esi] + movzx eax,al + add esi,eax + jmp skip_preprocessed_line_content +restore_preprocessed_source: + mov esi,[memory_start] + mov ebp,[source_start] + test ebp,ebp + jnz restore_preprocessed_line + mov ebp,[current_line] + inc ebp + restore_preprocessed_line: + cmp esi,ebp + jae preprocessed_source_restored + mov eax,[memory_start] + add [esi],eax + cmp [esi],eax + jne preprocessed_line_source_restored + mov edx,[input_file] + mov [esi],edx + preprocessed_line_source_restored: + test byte [esi+7],1 shl 7 + jz restore_next_preprocessed_line + add [esi+8],eax + add [esi+12],eax + restore_next_preprocessed_line: + call skip_preprocessed_line + jmp restore_preprocessed_line + preprocessed_source_restored: + ret +dump_preprocessed_source: + mov edi,[free_additional_memory] + call setup_dump_header + mov esi,[input_file] + call copy_asciiz + cmp edi,[additional_memory_end] + jae out_of_memory + mov eax,edi + sub eax,ebx + dec eax + mov [ebx-40h+0Ch],eax + mov eax,edi + sub eax,ebx + mov [ebx-40h+14h],eax + add eax,40h + mov [ebx-40h+20h],eax + call prepare_preprocessed_source + sub esi,[memory_start] + mov [ebx-40h+24h],esi + mov edx,[symbols_file] + call create + jc write_failed + mov edx,[free_additional_memory] + mov ecx,[edx+14h] + add ecx,40h + call write + jc write_failed + mov edx,[memory_start] + mov ecx,esi + call write + jc write_failed + call close + ret diff --git a/toolchain/fasmw17332/SOURCE/TABLES.INC b/toolchain/fasmw17332/SOURCE/TABLES.INC new file mode 100644 index 0000000..bc104a0 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/TABLES.INC @@ -0,0 +1,4393 @@ + +; flat assembler core +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +include_variable db 'INCLUDE',0 + +symbol_characters db 27 + db 9,0Ah,0Dh,1Ah,20h,'+-/*=<>()[]{}:,|&~#`;\' + +preprocessor_directives: + db 6,'define' + dw define_symbolic_constant-directive_handler + db 7,'include' + dw include_file-directive_handler + db 3,'irp' + dw irp_directive-directive_handler + db 4,'irps' + dw irps_directive-directive_handler + db 4,'irpv' + dw irpv_directive-directive_handler + db 5,'macro' + dw define_macro-directive_handler + db 5,'match' + dw match_directive-directive_handler + db 8,'postpone' + dw postpone_directive-directive_handler + db 5,'purge' + dw purge_macro-directive_handler + db 4,'rept' + dw rept_directive-directive_handler + db 7,'restore' + dw restore_equ_constant-directive_handler + db 7,'restruc' + dw purge_struc-directive_handler + db 5,'struc' + dw define_struc-directive_handler + db 0 + +macro_directives: + db 6,'common' + dw common_block-directive_handler + db 7,'forward' + dw forward_block-directive_handler + db 5,'local' + dw local_symbols-directive_handler + db 7,'reverse' + dw reverse_block-directive_handler + db 0 + +preprocessor_special_symbols: + db 4,'file' + dw preprocessed_file_value-directive_handler + db 4,'line' + dw preprocessed_line_value-directive_handler + db 0 + +operators: + db 1,'+',80h + db 1,'-',81h + db 1,'*',90h + db 1,'/',91h + db 3,'and',0B0h + db 3,'mod',0A0h + db 2,'or',0B1h + db 3,'shl',0C0h + db 3,'shr',0C1h + db 3,'xor',0B2h + db 0 + +single_operand_operators: + db 1,'+',82h + db 1,'-',83h + db 3,'bsf',0E0h + db 3,'bsr',0E1h + db 3,'not',0D0h + db 3,'plt',0F1h + db 3,'rva',0F0h + db 0 + +directive_operators: + db 5,'align',8Ch + db 2,'as',86h + db 2,'at',80h + db 7,'defined',88h + db 8,'definite',8Ah + db 3,'dup',81h + db 2,'eq',0F0h + db 6,'eqtype',0F7h + db 4,'from',82h + db 2,'in',0F6h + db 2,'on',84h + db 3,'ptr',85h + db 10,'relativeto',0F8h + db 4,'used',89h + db 0 + +address_sizes: + db 4,'byte',1 + db 5,'dword',4 + db 5,'qword',8 + db 4,'word',2 + db 0 + +symbols: + dw symbols_1-symbols,(symbols_2-symbols_1)/(1+2) + dw symbols_2-symbols,(symbols_3-symbols_2)/(2+2) + dw symbols_3-symbols,(symbols_4-symbols_3)/(3+2) + dw symbols_4-symbols,(symbols_5-symbols_4)/(4+2) + dw symbols_5-symbols,(symbols_6-symbols_5)/(5+2) + dw symbols_6-symbols,(symbols_7-symbols_6)/(6+2) + dw symbols_7-symbols,(symbols_8-symbols_7)/(7+2) + dw symbols_8-symbols,(symbols_9-symbols_8)/(8+2) + dw symbols_9-symbols,(symbols_10-symbols_9)/(9+2) + dw symbols_10-symbols,(symbols_11-symbols_10)/(10+2) + dw symbols_11-symbols,(symbols_end-symbols_11)/(11+2) + +symbols_1: + db 'z',1Fh,0 +symbols_2: + db 'ah',10h,04h + db 'al',10h,10h + db 'ax',10h,20h + db 'bh',10h,07h + db 'bl',10h,13h + db 'bp',10h,25h + db 'bx',10h,23h + db 'ch',10h,05h + db 'cl',10h,11h + db 'cs',10h,32h + db 'cx',10h,21h + db 'dh',10h,06h + db 'di',10h,27h + db 'dl',10h,12h + db 'ds',10h,34h + db 'dx',10h,22h + db 'es',10h,31h + db 'fs',10h,35h + db 'gs',10h,36h + db 'k0',14h,50h + db 'k1',14h,51h + db 'k2',14h,52h + db 'k3',14h,53h + db 'k4',14h,54h + db 'k5',14h,55h + db 'k6',14h,56h + db 'k7',14h,57h + db 'ms',1Ch,41h + db 'mz',18h,20h + db 'nx',1Bh,83h + db 'pe',18h,30h + db 'r8',10h,88h + db 'r9',10h,89h + db 'rd',1Fh,21h + db 'rn',1Fh,20h + db 'ru',1Fh,22h + db 'rz',1Fh,23h + db 'si',10h,26h + db 'sp',10h,24h + db 'ss',10h,33h + db 'st',10h,0A0h +symbols_3: + db 'bpl',10h,15h + db 'cr0',14h,00h + db 'cr1',14h,01h + db 'cr2',14h,02h + db 'cr3',14h,03h + db 'cr4',14h,04h + db 'cr5',14h,05h + db 'cr6',14h,06h + db 'cr7',14h,07h + db 'cr8',14h,08h + db 'cr9',14h,09h + db 'dil',10h,17h + db 'dll',1Bh,80h + db 'dr0',14h,10h + db 'dr1',14h,11h + db 'dr2',14h,12h + db 'dr3',14h,13h + db 'dr4',14h,14h + db 'dr5',14h,15h + db 'dr6',14h,16h + db 'dr7',14h,17h + db 'dr8',14h,18h + db 'dr9',14h,19h + db 'eax',10h,40h + db 'ebp',10h,45h + db 'ebx',10h,43h + db 'ecx',10h,41h + db 'edi',10h,47h + db 'edx',10h,42h + db 'efi',1Bh,10 + db 'eip',10h,94h + db 'elf',18h,50h + db 'esi',10h,46h + db 'esp',10h,44h + db 'far',12h,3 + db 'gui',1Bh,2 + db 'mm0',10h,0B0h + db 'mm1',10h,0B1h + db 'mm2',10h,0B2h + db 'mm3',10h,0B3h + db 'mm4',10h,0B4h + db 'mm5',10h,0B5h + db 'mm6',10h,0B6h + db 'mm7',10h,0B7h + db 'r10',10h,8Ah + db 'r11',10h,8Bh + db 'r12',10h,8Ch + db 'r13',10h,8Dh + db 'r14',10h,8Eh + db 'r15',10h,8Fh + db 'r8b',10h,18h + db 'r8d',10h,48h + db 'r8l',10h,18h + db 'r8w',10h,28h + db 'r9b',10h,19h + db 'r9d',10h,49h + db 'r9l',10h,19h + db 'r9w',10h,29h + db 'rax',10h,80h + db 'rbp',10h,85h + db 'rbx',10h,83h + db 'rcx',10h,81h + db 'rdi',10h,87h + db 'rdx',10h,82h + db 'rip',10h,98h + db 'rsi',10h,86h + db 'rsp',10h,84h + db 'sae',1Fh,30h + db 'sil',10h,16h + db 'spl',10h,14h + db 'st0',10h,0A0h + db 'st1',10h,0A1h + db 'st2',10h,0A2h + db 'st3',10h,0A3h + db 'st4',10h,0A4h + db 'st5',10h,0A5h + db 'st6',10h,0A6h + db 'st7',10h,0A7h + db 'tr0',14h,40h + db 'tr1',14h,41h + db 'tr2',14h,42h + db 'tr3',14h,43h + db 'tr4',14h,44h + db 'tr5',14h,45h + db 'tr6',14h,46h + db 'tr7',14h,47h + db 'wdm',1Bh,81h +symbols_4: + db '1to2',1Fh,11h + db '1to4',1Fh,12h + db '1to8',1Fh,13h + db 'bnd0',14h,60h + db 'bnd1',14h,61h + db 'bnd2',14h,62h + db 'bnd3',14h,63h + db 'byte',11h,1 + db 'code',19h,5 + db 'coff',18h,40h + db 'cr10',14h,0Ah + db 'cr11',14h,0Bh + db 'cr12',14h,0Ch + db 'cr13',14h,0Dh + db 'cr14',14h,0Eh + db 'cr15',14h,0Fh + db 'data',19h,6 + db 'dr10',14h,1Ah + db 'dr11',14h,1Bh + db 'dr12',14h,1Ch + db 'dr13',14h,1Dh + db 'dr14',14h,1Eh + db 'dr15',14h,1Fh + db 'ms64',1Ch,49h + db 'near',12h,2 + db 'note',1Eh,4 + db 'pe64',18h,3Ch + db 'r10b',10h,1Ah + db 'r10d',10h,4Ah + db 'r10l',10h,1Ah + db 'r10w',10h,2Ah + db 'r11b',10h,1Bh + db 'r11d',10h,4Bh + db 'r11l',10h,1Bh + db 'r11w',10h,2Bh + db 'r12b',10h,1Ch + db 'r12d',10h,4Ch + db 'r12l',10h,1Ch + db 'r12w',10h,2Ch + db 'r13b',10h,1Dh + db 'r13d',10h,4Dh + db 'r13l',10h,1Dh + db 'r13w',10h,2Dh + db 'r14b',10h,1Eh + db 'r14d',10h,4Eh + db 'r14l',10h,1Eh + db 'r14w',10h,2Eh + db 'r15b',10h,1Fh + db 'r15d',10h,4Fh + db 'r15l',10h,1Fh + db 'r15w',10h,2Fh + db 'word',11h,2 + db 'xmm0',10h,0C0h + db 'xmm1',10h,0C1h + db 'xmm2',10h,0C2h + db 'xmm3',10h,0C3h + db 'xmm4',10h,0C4h + db 'xmm5',10h,0C5h + db 'xmm6',10h,0C6h + db 'xmm7',10h,0C7h + db 'xmm8',10h,0C8h + db 'xmm9',10h,0C9h + db 'ymm0',10h,0E0h + db 'ymm1',10h,0E1h + db 'ymm2',10h,0E2h + db 'ymm3',10h,0E3h + db 'ymm4',10h,0E4h + db 'ymm5',10h,0E5h + db 'ymm6',10h,0E6h + db 'ymm7',10h,0E7h + db 'ymm8',10h,0E8h + db 'ymm9',10h,0E9h + db 'zmm0',10h,60h + db 'zmm1',10h,61h + db 'zmm2',10h,62h + db 'zmm3',10h,63h + db 'zmm4',10h,64h + db 'zmm5',10h,65h + db 'zmm6',10h,66h + db 'zmm7',10h,67h + db 'zmm8',10h,68h + db 'zmm9',10h,69h +symbols_5: + db '1to16',1Fh,14h + db 'dword',11h,4 + db 'elf64',18h,58h + db 'fword',11h,6 + db 'large',1Bh,82h + db 'pword',11h,6 + db 'qword',11h,8 + db 'short',12h,1 + db 'tbyte',11h,0Ah + db 'tword',11h,0Ah + db 'use16',13h,16 + db 'use32',13h,32 + db 'use64',13h,64 + db 'xmm10',10h,0CAh + db 'xmm11',10h,0CBh + db 'xmm12',10h,0CCh + db 'xmm13',10h,0CDh + db 'xmm14',10h,0CEh + db 'xmm15',10h,0CFh + db 'xmm16',10h,0D0h + db 'xmm17',10h,0D1h + db 'xmm18',10h,0D2h + db 'xmm19',10h,0D3h + db 'xmm20',10h,0D4h + db 'xmm21',10h,0D5h + db 'xmm22',10h,0D6h + db 'xmm23',10h,0D7h + db 'xmm24',10h,0D8h + db 'xmm25',10h,0D9h + db 'xmm26',10h,0DAh + db 'xmm27',10h,0DBh + db 'xmm28',10h,0DCh + db 'xmm29',10h,0DDh + db 'xmm30',10h,0DEh + db 'xmm31',10h,0DFh + db 'xword',11h,16 + db 'ymm10',10h,0EAh + db 'ymm11',10h,0EBh + db 'ymm12',10h,0ECh + db 'ymm13',10h,0EDh + db 'ymm14',10h,0EEh + db 'ymm15',10h,0EFh + db 'ymm16',10h,0F0h + db 'ymm17',10h,0F1h + db 'ymm18',10h,0F2h + db 'ymm19',10h,0F3h + db 'ymm20',10h,0F4h + db 'ymm21',10h,0F5h + db 'ymm22',10h,0F6h + db 'ymm23',10h,0F7h + db 'ymm24',10h,0F8h + db 'ymm25',10h,0F9h + db 'ymm26',10h,0FAh + db 'ymm27',10h,0FBh + db 'ymm28',10h,0FCh + db 'ymm29',10h,0FDh + db 'ymm30',10h,0FEh + db 'ymm31',10h,0FFh + db 'yword',11h,32 + db 'zmm10',10h,6Ah + db 'zmm11',10h,6Bh + db 'zmm12',10h,6Ch + db 'zmm13',10h,6Dh + db 'zmm14',10h,6Eh + db 'zmm15',10h,6Fh + db 'zmm16',10h,70h + db 'zmm17',10h,71h + db 'zmm18',10h,72h + db 'zmm19',10h,73h + db 'zmm20',10h,74h + db 'zmm21',10h,75h + db 'zmm22',10h,76h + db 'zmm23',10h,77h + db 'zmm24',10h,78h + db 'zmm25',10h,79h + db 'zmm26',10h,7Ah + db 'zmm27',10h,7Bh + db 'zmm28',10h,7Ch + db 'zmm29',10h,7Dh + db 'zmm30',10h,7Eh + db 'zmm31',10h,7Fh + db 'zword',11h,64 +symbols_6: + db 'binary',18h,10h + db 'dqword',11h,16 + db 'export',1Ah,0 + db 'fixups',1Ah,5 + db 'import',1Ah,1 + db 'native',1Bh,1 + db 'qqword',11h,32 + db 'static',1Dh,1 +symbols_7: + db 'console',1Bh,3 + db 'dqqword',11h,64 + db 'dynamic',1Eh,2 + db 'efiboot',1Bh,11 +symbols_8: + db 'gnurelro',1Eh,52h + db 'gnustack',1Eh,51h + db 'linkinfo',19h,9 + db 'readable',19h,30 + db 'resource',1Ah,2 + db 'writable',19h,31 +symbols_9: + db 'shareable',19h,28 + db 'writeable',19h,31 +symbols_10: + db 'efiruntime',1Bh,12 + db 'executable',19h,29 + db 'gnuehframe',1Eh,50h + db 'linkremove',19h,11 +symbols_11: + db 'discardable',19h,25 + db 'interpreter',1Eh,3 + db 'notpageable',19h,27 +symbols_end: + +instructions: + dw instructions_2-instructions,(instructions_3-instructions_2)/(2+3) + dw instructions_3-instructions,(instructions_4-instructions_3)/(3+3) + dw instructions_4-instructions,(instructions_5-instructions_4)/(4+3) + dw instructions_5-instructions,(instructions_6-instructions_5)/(5+3) + dw instructions_6-instructions,(instructions_7-instructions_6)/(6+3) + dw instructions_7-instructions,(instructions_8-instructions_7)/(7+3) + dw instructions_8-instructions,(instructions_9-instructions_8)/(8+3) + dw instructions_9-instructions,(instructions_10-instructions_9)/(9+3) + dw instructions_10-instructions,(instructions_11-instructions_10)/(10+3) + dw instructions_11-instructions,(instructions_12-instructions_11)/(11+3) + dw instructions_12-instructions,(instructions_13-instructions_12)/(12+3) + dw instructions_13-instructions,(instructions_14-instructions_13)/(13+3) + dw instructions_14-instructions,(instructions_15-instructions_14)/(14+3) + dw instructions_15-instructions,(instructions_16-instructions_15)/(15+3) + dw instructions_16-instructions,(instructions_17-instructions_16)/(16+3) + dw instructions_17-instructions,(instructions_end-instructions_17)/(17+3) + +instructions_2: + db 'bt',4 + dw bt_instruction-instruction_handler + db 'if',0 + dw if_directive-instruction_handler + db 'in',0 + dw in_instruction-instruction_handler + db 'ja',77h + dw conditional_jump-instruction_handler + db 'jb',72h + dw conditional_jump-instruction_handler + db 'jc',72h + dw conditional_jump-instruction_handler + db 'je',74h + dw conditional_jump-instruction_handler + db 'jg',7Fh + dw conditional_jump-instruction_handler + db 'jl',7Ch + dw conditional_jump-instruction_handler + db 'jo',70h + dw conditional_jump-instruction_handler + db 'jp',7Ah + dw conditional_jump-instruction_handler + db 'js',78h + dw conditional_jump-instruction_handler + db 'jz',74h + dw conditional_jump-instruction_handler + db 'or',08h + dw basic_instruction-instruction_handler +instructions_3: + db 'aaa',37h + dw simple_instruction_except64-instruction_handler + db 'aad',0D5h + dw aa_instruction-instruction_handler + db 'aam',0D4h + dw aa_instruction-instruction_handler + db 'aas',3Fh + dw simple_instruction_except64-instruction_handler + db 'adc',10h + dw basic_instruction-instruction_handler + db 'add',00h + dw basic_instruction-instruction_handler + db 'and',20h + dw basic_instruction-instruction_handler + db 'bnd',0F2h + dw bnd_prefix_instruction-instruction_handler + db 'bsf',0BCh + dw bs_instruction-instruction_handler + db 'bsr',0BDh + dw bs_instruction-instruction_handler + db 'btc',7 + dw bt_instruction-instruction_handler + db 'btr',6 + dw bt_instruction-instruction_handler + db 'bts',5 + dw bt_instruction-instruction_handler + db 'cbw',98h + dw simple_instruction_16bit-instruction_handler + db 'cdq',99h + dw simple_instruction_32bit-instruction_handler + db 'clc',0F8h + dw simple_instruction-instruction_handler + db 'cld',0FCh + dw simple_instruction-instruction_handler + db 'cli',0FAh + dw simple_instruction-instruction_handler + db 'cmc',0F5h + dw simple_instruction-instruction_handler + db 'cmp',38h + dw basic_instruction-instruction_handler + db 'cqo',99h + dw simple_instruction_64bit-instruction_handler + db 'cwd',99h + dw simple_instruction_16bit-instruction_handler + db 'daa',27h + dw simple_instruction_except64-instruction_handler + db 'das',2Fh + dw simple_instruction_except64-instruction_handler + db 'dec',1 + dw inc_instruction-instruction_handler + db 'div',6 + dw single_operand_instruction-instruction_handler + db 'end',0 + dw end_directive-instruction_handler + db 'err',0 + dw err_directive-instruction_handler + db 'fld',0 + dw fld_instruction-instruction_handler + db 'fst',2 + dw fld_instruction-instruction_handler + db 'hlt',0F4h + dw simple_instruction-instruction_handler + db 'inc',0 + dw inc_instruction-instruction_handler + db 'ins',6Ch + dw ins_instruction-instruction_handler + db 'int',0CDh + dw int_instruction-instruction_handler + db 'jae',73h + dw conditional_jump-instruction_handler + db 'jbe',76h + dw conditional_jump-instruction_handler + db 'jge',7Dh + dw conditional_jump-instruction_handler + db 'jle',7Eh + dw conditional_jump-instruction_handler + db 'jmp',0 + dw jmp_instruction-instruction_handler + db 'jna',76h + dw conditional_jump-instruction_handler + db 'jnb',73h + dw conditional_jump-instruction_handler + db 'jnc',73h + dw conditional_jump-instruction_handler + db 'jne',75h + dw conditional_jump-instruction_handler + db 'jng',7Eh + dw conditional_jump-instruction_handler + db 'jnl',7Dh + dw conditional_jump-instruction_handler + db 'jno',71h + dw conditional_jump-instruction_handler + db 'jnp',7Bh + dw conditional_jump-instruction_handler + db 'jns',79h + dw conditional_jump-instruction_handler + db 'jnz',75h + dw conditional_jump-instruction_handler + db 'jpe',7Ah + dw conditional_jump-instruction_handler + db 'jpo',7Bh + dw conditional_jump-instruction_handler + db 'lar',2 + dw lar_instruction-instruction_handler + db 'lds',3 + dw ls_instruction-instruction_handler + db 'lea',0 + dw lea_instruction-instruction_handler + db 'les',0 + dw ls_instruction-instruction_handler + db 'lfs',4 + dw ls_instruction-instruction_handler + db 'lgs',5 + dw ls_instruction-instruction_handler + db 'lsl',3 + dw lar_instruction-instruction_handler + db 'lss',2 + dw ls_instruction-instruction_handler + db 'ltr',3 + dw pm_word_instruction-instruction_handler + db 'mov',0 + dw mov_instruction-instruction_handler + db 'mul',4 + dw single_operand_instruction-instruction_handler + db 'neg',3 + dw single_operand_instruction-instruction_handler + db 'nop',90h + dw nop_instruction-instruction_handler + db 'not',2 + dw single_operand_instruction-instruction_handler + db 'org',0 + dw org_directive-instruction_handler + db 'out',0 + dw out_instruction-instruction_handler + db 'pop',0 + dw pop_instruction-instruction_handler + db 'por',0EBh + dw basic_mmx_instruction-instruction_handler + db 'rcl',2 + dw sh_instruction-instruction_handler + db 'rcr',3 + dw sh_instruction-instruction_handler + db 'rep',0F3h + dw prefix_instruction-instruction_handler + db 'ret',0C2h + dw ret_instruction-instruction_handler + db 'rol',0 + dw sh_instruction-instruction_handler + db 'ror',1 + dw sh_instruction-instruction_handler + db 'rsm',0AAh + dw simple_extended_instruction-instruction_handler + db 'sal',4 + dw sh_instruction-instruction_handler + db 'sar',7 + dw sh_instruction-instruction_handler + db 'sbb',18h + dw basic_instruction-instruction_handler + db 'shl',4 + dw sh_instruction-instruction_handler + db 'shr',5 + dw sh_instruction-instruction_handler + db 'stc',0F9h + dw simple_instruction-instruction_handler + db 'std',0FDh + dw simple_instruction-instruction_handler + db 'sti',0FBh + dw simple_instruction-instruction_handler + db 'str',1 + dw pm_store_word_instruction-instruction_handler + db 'sub',28h + dw basic_instruction-instruction_handler + db 'ud0',0FFh + dw ud_instruction-instruction_handler + db 'ud1',0B9h + dw ud_instruction-instruction_handler + db 'ud2',0Bh + dw simple_extended_instruction-instruction_handler + db 'xor',30h + dw basic_instruction-instruction_handler +instructions_4: + db 'adcx',66h + dw adx_instruction-instruction_handler + db 'adox',0F3h + dw adx_instruction-instruction_handler + db 'andn',0F2h + dw andn_instruction-instruction_handler + db 'arpl',0 + dw arpl_instruction-instruction_handler + db 'blci',26h + dw tbm_instruction-instruction_handler + db 'blcs',13h + dw tbm_instruction-instruction_handler + db 'blsi',3 + dw bmi_instruction-instruction_handler + db 'blsr',1 + dw bmi_instruction-instruction_handler + db 'bzhi',0F5h + dw bzhi_instruction-instruction_handler + db 'call',0 + dw call_instruction-instruction_handler + db 'cdqe',98h + dw simple_instruction_64bit-instruction_handler + db 'clac',0CAh + dw simple_instruction_0f_01-instruction_handler + db 'clgi',0DDh + dw simple_instruction_0f_01-instruction_handler + db 'clts',6 + dw simple_extended_instruction-instruction_handler + db 'clwb',6 + dw clflushopt_instruction-instruction_handler + db 'cmps',0A6h + dw cmps_instruction-instruction_handler + db 'cwde',98h + dw simple_instruction_32bit-instruction_handler + db 'data',0 + dw data_directive-instruction_handler + db 'dppd',41h + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'dpps',40h + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'else',0 + dw else_directive-instruction_handler + db 'emms',77h + dw simple_extended_instruction-instruction_handler + db 'fabs',100001b + dw simple_fpu_instruction-instruction_handler + db 'fadd',0 + dw basic_fpu_instruction-instruction_handler + db 'fbld',4 + dw fbld_instruction-instruction_handler + db 'fchs',100000b + dw simple_fpu_instruction-instruction_handler + db 'fcom',2 + dw basic_fpu_instruction-instruction_handler + db 'fcos',111111b + dw simple_fpu_instruction-instruction_handler + db 'fdiv',6 + dw basic_fpu_instruction-instruction_handler + db 'feni',0E0h + dw finit_instruction-instruction_handler + db 'fild',0 + dw fild_instruction-instruction_handler + db 'fist',2 + dw fild_instruction-instruction_handler + db 'fld1',101000b + dw simple_fpu_instruction-instruction_handler + db 'fldz',101110b + dw simple_fpu_instruction-instruction_handler + db 'fmul',1 + dw basic_fpu_instruction-instruction_handler + db 'fnop',010000b + dw simple_fpu_instruction-instruction_handler + db 'fsin',111110b + dw simple_fpu_instruction-instruction_handler + db 'fstp',3 + dw fld_instruction-instruction_handler + db 'fsub',4 + dw basic_fpu_instruction-instruction_handler + db 'ftst',100100b + dw simple_fpu_instruction-instruction_handler + db 'fxam',100101b + dw simple_fpu_instruction-instruction_handler + db 'fxch',0 + dw fxch_instruction-instruction_handler + db 'heap',0 + dw heap_directive-instruction_handler + db 'idiv',7 + dw single_operand_instruction-instruction_handler + db 'imul',0 + dw imul_instruction-instruction_handler + db 'insb',6Ch + dw simple_instruction-instruction_handler + db 'insd',6Dh + dw simple_instruction_32bit-instruction_handler + db 'insw',6Dh + dw simple_instruction_16bit-instruction_handler + db 'int1',0F1h + dw simple_instruction-instruction_handler + db 'int3',0CCh + dw simple_instruction-instruction_handler + db 'into',0CEh + dw simple_instruction_except64-instruction_handler + db 'invd',8 + dw simple_extended_instruction-instruction_handler + db 'iret',0CFh + dw iret_instruction-instruction_handler + db 'jcxz',0E3h + dw loop_instruction_16bit-instruction_handler + db 'jnae',72h + dw conditional_jump-instruction_handler + db 'jnbe',77h + dw conditional_jump-instruction_handler + db 'jnge',7Ch + dw conditional_jump-instruction_handler + db 'jnle',7Fh + dw conditional_jump-instruction_handler + db 'korb',45h + dw mask_instruction_b-instruction_handler + db 'kord',45h + dw mask_instruction_d-instruction_handler + db 'korq',45h + dw mask_instruction_q-instruction_handler + db 'korw',45h + dw mask_instruction_w-instruction_handler + db 'lahf',9Fh + dw simple_instruction-instruction_handler + db 'lgdt',2 + dw lgdt_instruction-instruction_handler + db 'lidt',3 + dw lgdt_instruction-instruction_handler + db 'lldt',2 + dw pm_word_instruction-instruction_handler + db 'lmsw',16h + dw pm_word_instruction-instruction_handler + db 'load',0 + dw load_directive-instruction_handler + db 'lock',0F0h + dw prefix_instruction-instruction_handler + db 'lods',0ACh + dw lods_instruction-instruction_handler + db 'loop',0E2h + dw loop_instruction-instruction_handler + db 'movd',0 + dw movd_instruction-instruction_handler + db 'movq',0 + dw movq_instruction-instruction_handler + db 'movs',0A4h + dw movs_instruction-instruction_handler + db 'mulx',0F6h + dw pdep_instruction-instruction_handler + db 'orpd',56h + dw sse_pd_instruction-instruction_handler + db 'orps',56h + dw sse_ps_instruction-instruction_handler + db 'outs',6Eh + dw outs_instruction-instruction_handler + db 'pand',0DBh + dw basic_mmx_instruction-instruction_handler + db 'pdep',0F5h + dw pdep_instruction-instruction_handler + db 'pext',0F5h + dw pext_instruction-instruction_handler + db 'popa',61h + dw simple_instruction_except64-instruction_handler + db 'popd',4 + dw pop_instruction-instruction_handler + db 'popf',9Dh + dw simple_instruction-instruction_handler + db 'popq',8 + dw pop_instruction-instruction_handler + db 'popw',2 + dw pop_instruction-instruction_handler + db 'push',0 + dw push_instruction-instruction_handler + db 'pxor',0EFh + dw basic_mmx_instruction-instruction_handler + db 'repe',0F3h + dw prefix_instruction-instruction_handler + db 'repz',0F3h + dw prefix_instruction-instruction_handler + db 'retd',0C2h + dw ret_instruction_32bit_except64-instruction_handler + db 'retf',0CAh + dw retf_instruction-instruction_handler + db 'retn',0C2h + dw ret_instruction-instruction_handler + db 'retq',0C2h + dw ret_instruction_only64-instruction_handler + db 'retw',0C2h + dw ret_instruction_16bit-instruction_handler + db 'rorx',0F0h + dw rorx_instruction-instruction_handler + db 'sahf',9Eh + dw simple_instruction-instruction_handler + db 'salc',0D6h + dw simple_instruction_except64-instruction_handler + db 'sarx',0F7h + dw sarx_instruction-instruction_handler + db 'scas',0AEh + dw stos_instruction-instruction_handler + db 'seta',97h + dw set_instruction-instruction_handler + db 'setb',92h + dw set_instruction-instruction_handler + db 'setc',92h + dw set_instruction-instruction_handler + db 'sete',94h + dw set_instruction-instruction_handler + db 'setg',9Fh + dw set_instruction-instruction_handler + db 'setl',9Ch + dw set_instruction-instruction_handler + db 'seto',90h + dw set_instruction-instruction_handler + db 'setp',9Ah + dw set_instruction-instruction_handler + db 'sets',98h + dw set_instruction-instruction_handler + db 'setz',94h + dw set_instruction-instruction_handler + db 'sgdt',0 + dw lgdt_instruction-instruction_handler + db 'shld',0A4h + dw shd_instruction-instruction_handler + db 'shlx',0F7h + dw shlx_instruction-instruction_handler + db 'shrd',0ACh + dw shd_instruction-instruction_handler + db 'shrx',0F7h + dw shrx_instruction-instruction_handler + db 'sidt',1 + dw lgdt_instruction-instruction_handler + db 'sldt',0 + dw pm_store_word_instruction-instruction_handler + db 'smsw',14h + dw pm_store_word_instruction-instruction_handler + db 'stac',0CBh + dw simple_instruction_0f_01-instruction_handler + db 'stgi',0DCh + dw simple_instruction_0f_01-instruction_handler + db 'stos',0AAh + dw stos_instruction-instruction_handler + db 'test',0 + dw test_instruction-instruction_handler + db 'verr',4 + dw pm_word_instruction-instruction_handler + db 'verw',5 + dw pm_word_instruction-instruction_handler + db 'vpor',0EBh + dw avx_pd_instruction_noevex-instruction_handler + db 'wait',9Bh + dw simple_instruction-instruction_handler + db 'xadd',0C0h + dw basic_486_instruction-instruction_handler + db 'xchg',0 + dw xchg_instruction-instruction_handler + db 'xend',0D5h + dw simple_instruction_0f_01-instruction_handler + db 'xlat',0D7h + dw xlat_instruction-instruction_handler +instructions_5: + db 'addpd',58h + dw sse_pd_instruction-instruction_handler + db 'addps',58h + dw sse_ps_instruction-instruction_handler + db 'addsd',58h + dw sse_sd_instruction-instruction_handler + db 'addss',58h + dw sse_ss_instruction-instruction_handler + db 'align',0 + dw align_directive-instruction_handler + db 'andpd',54h + dw sse_pd_instruction-instruction_handler + db 'andps',54h + dw sse_ps_instruction-instruction_handler + db 'bextr',0F7h + dw bextr_instruction-instruction_handler + db 'blcic',15h + dw tbm_instruction-instruction_handler + db 'blsic',16h + dw tbm_instruction-instruction_handler + db 'bndcl',1Ah + dw bndcl_instruction-instruction_handler + db 'bndcn',1Bh + dw bndcu_instruction-instruction_handler + db 'bndcu',1Ah + dw bndcu_instruction-instruction_handler + db 'bndmk',1Bh + dw bndmk_instruction-instruction_handler + db 'bound',0 + dw bound_instruction-instruction_handler + db 'break',0 + dw break_directive-instruction_handler + db 'bswap',0 + dw bswap_instruction-instruction_handler + db 'cmova',47h + dw bs_instruction-instruction_handler + db 'cmovb',42h + dw bs_instruction-instruction_handler + db 'cmovc',42h + dw bs_instruction-instruction_handler + db 'cmove',44h + dw bs_instruction-instruction_handler + db 'cmovg',4Fh + dw bs_instruction-instruction_handler + db 'cmovl',4Ch + dw bs_instruction-instruction_handler + db 'cmovo',40h + dw bs_instruction-instruction_handler + db 'cmovp',4Ah + dw bs_instruction-instruction_handler + db 'cmovs',48h + dw bs_instruction-instruction_handler + db 'cmovz',44h + dw bs_instruction-instruction_handler + db 'cmppd',-1 + dw cmp_pd_instruction-instruction_handler + db 'cmpps',-1 + dw cmp_ps_instruction-instruction_handler + db 'cmpsb',0A6h + dw simple_instruction-instruction_handler + db 'cmpsd',-1 + dw cmpsd_instruction-instruction_handler + db 'cmpsq',0A7h + dw simple_instruction_64bit-instruction_handler + db 'cmpss',-1 + dw cmp_ss_instruction-instruction_handler + db 'cmpsw',0A7h + dw simple_instruction_16bit-instruction_handler + db 'cpuid',0A2h + dw simple_extended_instruction-instruction_handler + db 'crc32',0 + dw crc32_instruction-instruction_handler + db 'divpd',5Eh + dw sse_pd_instruction-instruction_handler + db 'divps',5Eh + dw sse_ps_instruction-instruction_handler + db 'divsd',5Eh + dw sse_sd_instruction-instruction_handler + db 'divss',5Eh + dw sse_ss_instruction-instruction_handler + db 'enter',0 + dw enter_instruction-instruction_handler + db 'entry',0 + dw entry_directive-instruction_handler + db 'extrn',0 + dw extrn_directive-instruction_handler + db 'extrq',0 + dw extrq_instruction-instruction_handler + db 'f2xm1',110000b + dw simple_fpu_instruction-instruction_handler + db 'faddp',0 + dw faddp_instruction-instruction_handler + db 'fbstp',6 + dw fbld_instruction-instruction_handler + db 'fclex',0E2h + dw finit_instruction-instruction_handler + db 'fcomi',0F0h + dw fcomi_instruction-instruction_handler + db 'fcomp',3 + dw basic_fpu_instruction-instruction_handler + db 'fdisi',0E1h + dw finit_instruction-instruction_handler + db 'fdivp',7 + dw faddp_instruction-instruction_handler + db 'fdivr',7 + dw basic_fpu_instruction-instruction_handler + db 'femms',0Eh + dw simple_extended_instruction-instruction_handler + db 'ffree',0 + dw ffree_instruction-instruction_handler + db 'fiadd',0 + dw fi_instruction-instruction_handler + db 'ficom',2 + dw fi_instruction-instruction_handler + db 'fidiv',6 + dw fi_instruction-instruction_handler + db 'fimul',1 + dw fi_instruction-instruction_handler + db 'finit',0E3h + dw finit_instruction-instruction_handler + db 'fistp',3 + dw fild_instruction-instruction_handler + db 'fisub',4 + dw fi_instruction-instruction_handler + db 'fldcw',5 + dw fldcw_instruction-instruction_handler + db 'fldpi',101011b + dw simple_fpu_instruction-instruction_handler + db 'fmulp',1 + dw faddp_instruction-instruction_handler + db 'fneni',0E0h + dw fninit_instruction-instruction_handler + db 'fprem',111000b + dw simple_fpu_instruction-instruction_handler + db 'fptan',110010b + dw simple_fpu_instruction-instruction_handler + db 'fsave',6 + dw fsave_instruction-instruction_handler + db 'fsqrt',111010b + dw simple_fpu_instruction-instruction_handler + db 'fstcw',7 + dw fstcw_instruction-instruction_handler + db 'fstsw',0 + dw fstsw_instruction-instruction_handler + db 'fsubp',5 + dw faddp_instruction-instruction_handler + db 'fsubr',5 + dw basic_fpu_instruction-instruction_handler + db 'fucom',4 + dw ffree_instruction-instruction_handler + db 'fwait',9Bh + dw simple_instruction-instruction_handler + db 'fyl2x',110001b + dw simple_fpu_instruction-instruction_handler + db 'icebp',0F1h + dw simple_instruction-instruction_handler + db 'iretd',0CFh + dw simple_instruction_32bit-instruction_handler + db 'iretq',0CFh + dw simple_instruction_64bit-instruction_handler + db 'iretw',0CFh + dw simple_instruction_16bit-instruction_handler + db 'jecxz',0E3h + dw loop_instruction_32bit-instruction_handler + db 'jrcxz',0E3h + dw loop_instruction_64bit-instruction_handler + db 'kaddb',4Ah + dw mask_instruction_b-instruction_handler + db 'kaddd',4Ah + dw mask_instruction_d-instruction_handler + db 'kaddq',4Ah + dw mask_instruction_q-instruction_handler + db 'kaddw',4Ah + dw mask_instruction_w-instruction_handler + db 'kandb',41h + dw mask_instruction_b-instruction_handler + db 'kandd',41h + dw mask_instruction_d-instruction_handler + db 'kandq',41h + dw mask_instruction_q-instruction_handler + db 'kandw',41h + dw mask_instruction_w-instruction_handler + db 'kmovb',1 + dw kmov_instruction-instruction_handler + db 'kmovd',4 + dw kmov_instruction-instruction_handler + db 'kmovq',8 + dw kmov_instruction-instruction_handler + db 'kmovw',2 + dw kmov_instruction-instruction_handler + db 'knotb',44h + dw mask_instruction_single_source_b-instruction_handler + db 'knotd',44h + dw mask_instruction_single_source_d-instruction_handler + db 'knotq',44h + dw mask_instruction_single_source_q-instruction_handler + db 'knotw',44h + dw mask_instruction_single_source_w-instruction_handler + db 'kxorb',47h + dw mask_instruction_b-instruction_handler + db 'kxord',47h + dw mask_instruction_d-instruction_handler + db 'kxorq',47h + dw mask_instruction_q-instruction_handler + db 'kxorw',47h + dw mask_instruction_w-instruction_handler + db 'label',0 + dw label_directive-instruction_handler + db 'lddqu',0 + dw lddqu_instruction-instruction_handler + db 'leave',0C9h + dw simple_instruction-instruction_handler + db 'lodsb',0ACh + dw simple_instruction-instruction_handler + db 'lodsd',0ADh + dw simple_instruction_32bit-instruction_handler + db 'lodsq',0ADh + dw simple_instruction_64bit-instruction_handler + db 'lodsw',0ADh + dw simple_instruction_16bit-instruction_handler + db 'loopd',0E2h + dw loop_instruction_32bit-instruction_handler + db 'loope',0E1h + dw loop_instruction-instruction_handler + db 'loopq',0E2h + dw loop_instruction_64bit-instruction_handler + db 'loopw',0E2h + dw loop_instruction_16bit-instruction_handler + db 'loopz',0E1h + dw loop_instruction-instruction_handler + db 'lzcnt',0BDh + dw popcnt_instruction-instruction_handler + db 'maxpd',5Fh + dw sse_pd_instruction-instruction_handler + db 'maxps',5Fh + dw sse_ps_instruction-instruction_handler + db 'maxsd',5Fh + dw sse_sd_instruction-instruction_handler + db 'maxss',5Fh + dw sse_ss_instruction-instruction_handler + db 'minpd',5Dh + dw sse_pd_instruction-instruction_handler + db 'minps',5Dh + dw sse_ps_instruction-instruction_handler + db 'minsd',5Dh + dw sse_sd_instruction-instruction_handler + db 'minss',5Dh + dw sse_ss_instruction-instruction_handler + db 'movbe',0F0h + dw movbe_instruction-instruction_handler + db 'movsb',0A4h + dw simple_instruction-instruction_handler + db 'movsd',0 + dw movsd_instruction-instruction_handler + db 'movsq',0A5h + dw simple_instruction_64bit-instruction_handler + db 'movss',0 + dw movss_instruction-instruction_handler + db 'movsw',0A5h + dw simple_instruction_16bit-instruction_handler + db 'movsx',0BEh + dw movx_instruction-instruction_handler + db 'movzx',0B6h + dw movx_instruction-instruction_handler + db 'mulpd',59h + dw sse_pd_instruction-instruction_handler + db 'mulps',59h + dw sse_ps_instruction-instruction_handler + db 'mulsd',59h + dw sse_sd_instruction-instruction_handler + db 'mulss',59h + dw sse_ss_instruction-instruction_handler + db 'mwait',0C9h + dw monitor_instruction-instruction_handler + db 'outsb',6Eh + dw simple_instruction-instruction_handler + db 'outsd',6Fh + dw simple_instruction_32bit-instruction_handler + db 'outsw',6Fh + dw simple_instruction_16bit-instruction_handler + db 'pabsb',1Ch + dw ssse3_instruction-instruction_handler + db 'pabsd',1Eh + dw ssse3_instruction-instruction_handler + db 'pabsw',1Dh + dw ssse3_instruction-instruction_handler + db 'paddb',0FCh + dw basic_mmx_instruction-instruction_handler + db 'paddd',0FEh + dw basic_mmx_instruction-instruction_handler + db 'paddq',0D4h + dw basic_mmx_instruction-instruction_handler + db 'paddw',0FDh + dw basic_mmx_instruction-instruction_handler + db 'pandn',0DFh + dw basic_mmx_instruction-instruction_handler + db 'pause',0 + dw pause_instruction-instruction_handler + db 'pavgb',0E0h + dw basic_mmx_instruction-instruction_handler + db 'pavgw',0E3h + dw basic_mmx_instruction-instruction_handler + db 'pf2id',1Dh + dw amd3dnow_instruction-instruction_handler + db 'pf2iw',1Ch + dw amd3dnow_instruction-instruction_handler + db 'pfacc',0AEh + dw amd3dnow_instruction-instruction_handler + db 'pfadd',9Eh + dw amd3dnow_instruction-instruction_handler + db 'pfmax',0A4h + dw amd3dnow_instruction-instruction_handler + db 'pfmin',94h + dw amd3dnow_instruction-instruction_handler + db 'pfmul',0B4h + dw amd3dnow_instruction-instruction_handler + db 'pfrcp',96h + dw amd3dnow_instruction-instruction_handler + db 'pfsub',9Ah + dw amd3dnow_instruction-instruction_handler + db 'pi2fd',0Dh + dw amd3dnow_instruction-instruction_handler + db 'pi2fw',0Ch + dw amd3dnow_instruction-instruction_handler + db 'popad',61h + dw simple_instruction_32bit_except64-instruction_handler + db 'popaw',61h + dw simple_instruction_16bit_except64-instruction_handler + db 'popfd',9Dh + dw simple_instruction_32bit_except64-instruction_handler + db 'popfq',9Dh + dw simple_instruction_only64-instruction_handler + db 'popfw',9Dh + dw simple_instruction_16bit-instruction_handler + db 'pslld',0F2h + dw mmx_bit_shift_instruction-instruction_handler + db 'psllq',0F3h + dw mmx_bit_shift_instruction-instruction_handler + db 'psllw',0F1h + dw mmx_bit_shift_instruction-instruction_handler + db 'psrad',0E2h + dw mmx_bit_shift_instruction-instruction_handler + db 'psraw',0E1h + dw mmx_bit_shift_instruction-instruction_handler + db 'psrld',0D2h + dw mmx_bit_shift_instruction-instruction_handler + db 'psrlq',0D3h + dw mmx_bit_shift_instruction-instruction_handler + db 'psrlw',0D1h + dw mmx_bit_shift_instruction-instruction_handler + db 'psubb',0F8h + dw basic_mmx_instruction-instruction_handler + db 'psubd',0FAh + dw basic_mmx_instruction-instruction_handler + db 'psubq',0FBh + dw basic_mmx_instruction-instruction_handler + db 'psubw',0F9h + dw basic_mmx_instruction-instruction_handler + db 'ptest',17h + dw sse4_instruction_66_38-instruction_handler + db 'pusha',60h + dw simple_instruction_except64-instruction_handler + db 'pushd',4 + dw push_instruction-instruction_handler + db 'pushf',9Ch + dw simple_instruction-instruction_handler + db 'pushq',8 + dw push_instruction-instruction_handler + db 'pushw',2 + dw push_instruction-instruction_handler + db 'rcpps',53h + dw sse_ps_instruction-instruction_handler + db 'rcpss',53h + dw sse_ss_instruction-instruction_handler + db 'rdmsr',32h + dw simple_extended_instruction-instruction_handler + db 'rdpid',7 + dw rdpid_instruction-instruction_handler + db 'rdpmc',33h + dw simple_extended_instruction-instruction_handler + db 'rdpru',0FDh + dw simple_instruction_0f_01-instruction_handler + db 'rdtsc',31h + dw simple_extended_instruction-instruction_handler + db 'repne',0F2h + dw prefix_instruction-instruction_handler + db 'repnz',0F2h + dw prefix_instruction-instruction_handler + db 'retfd',0CAh + dw retf_instruction_32bit-instruction_handler + db 'retfq',0CAh + dw retf_instruction_64bit-instruction_handler + db 'retfw',0CAh + dw retf_instruction_16bit-instruction_handler + db 'retnd',0C2h + dw ret_instruction_32bit_except64-instruction_handler + db 'retnq',0C2h + dw ret_instruction_only64-instruction_handler + db 'retnw',0C2h + dw ret_instruction_16bit-instruction_handler + db 'scasb',0AEh + dw simple_instruction-instruction_handler + db 'scasd',0AFh + dw simple_instruction_32bit-instruction_handler + db 'scasq',0AFh + dw simple_instruction_64bit-instruction_handler + db 'scasw',0AFh + dw simple_instruction_16bit-instruction_handler + db 'setae',93h + dw set_instruction-instruction_handler + db 'setbe',96h + dw set_instruction-instruction_handler + db 'setge',9Dh + dw set_instruction-instruction_handler + db 'setle',9Eh + dw set_instruction-instruction_handler + db 'setna',96h + dw set_instruction-instruction_handler + db 'setnb',93h + dw set_instruction-instruction_handler + db 'setnc',93h + dw set_instruction-instruction_handler + db 'setne',95h + dw set_instruction-instruction_handler + db 'setng',9Eh + dw set_instruction-instruction_handler + db 'setnl',9Dh + dw set_instruction-instruction_handler + db 'setno',91h + dw set_instruction-instruction_handler + db 'setnp',9Bh + dw set_instruction-instruction_handler + db 'setns',99h + dw set_instruction-instruction_handler + db 'setnz',95h + dw set_instruction-instruction_handler + db 'setpe',9Ah + dw set_instruction-instruction_handler + db 'setpo',9Bh + dw set_instruction-instruction_handler + db 'stack',0 + dw stack_directive-instruction_handler + db 'store',0 + dw store_directive-instruction_handler + db 'stosb',0AAh + dw simple_instruction-instruction_handler + db 'stosd',0ABh + dw simple_instruction_32bit-instruction_handler + db 'stosq',0ABh + dw simple_instruction_64bit-instruction_handler + db 'stosw',0ABh + dw simple_instruction_16bit-instruction_handler + db 'subpd',5Ch + dw sse_pd_instruction-instruction_handler + db 'subps',5Ch + dw sse_ps_instruction-instruction_handler + db 'subsd',5Ch + dw sse_sd_instruction-instruction_handler + db 'subss',5Ch + dw sse_ss_instruction-instruction_handler + db 'times',0 + dw times_directive-instruction_handler + db 'tzcnt',0BCh + dw popcnt_instruction-instruction_handler + db 'tzmsk',14h + dw tbm_instruction-instruction_handler + db 'vdppd',41h + dw avx_128bit_instruction_3a_imm8_noevex-instruction_handler + db 'vdpps',40h + dw avx_pi_instruction_3a_imm8_noevex-instruction_handler + db 'vmovd',0 + dw avx_movd_instruction-instruction_handler + db 'vmovq',0 + dw avx_movq_instruction-instruction_handler + db 'vmrun',0D8h + dw simple_svm_instruction-instruction_handler + db 'vmxon',6 + dw vmxon_instruction-instruction_handler + db 'vorpd',56h + dw avx_pd_instruction-instruction_handler + db 'vorps',56h + dw avx_ps_instruction-instruction_handler + db 'vpand',0DBh + dw avx_pd_instruction_noevex-instruction_handler + db 'vpord',0EBh + dw avx_d_instruction_evex-instruction_handler + db 'vporq',0EBh + dw avx_q_instruction_evex-instruction_handler + db 'vpxor',0EFh + dw avx_pd_instruction_noevex-instruction_handler + db 'while',0 + dw while_directive-instruction_handler + db 'wrmsr',30h + dw simple_extended_instruction-instruction_handler + db 'wrssd',0F6h + dw wrssd_instruction-instruction_handler + db 'wrssq',0F6h + dw wrssq_instruction-instruction_handler + db 'xlatb',0D7h + dw simple_instruction-instruction_handler + db 'xorpd',57h + dw sse_pd_instruction-instruction_handler + db 'xorps',57h + dw sse_ps_instruction-instruction_handler + db 'xsave',100b + dw fxsave_instruction-instruction_handler + db 'xtest',0D6h + dw simple_instruction_0f_01-instruction_handler +instructions_6: + db 'aesdec',0DEh + dw sse4_instruction_66_38-instruction_handler + db 'aesenc',0DCh + dw sse4_instruction_66_38-instruction_handler + db 'aesimc',0DBh + dw sse4_instruction_66_38-instruction_handler + db 'andnpd',55h + dw sse_pd_instruction-instruction_handler + db 'andnps',55h + dw sse_ps_instruction-instruction_handler + db 'assert',0 + dw assert_directive-instruction_handler + db 'blcmsk',21h + dw tbm_instruction-instruction_handler + db 'blsmsk',2 + dw bmi_instruction-instruction_handler + db 'bndldx',1Ah + dw bndldx_instruction-instruction_handler + db 'bndmov',1Ah + dw bndmov_instruction-instruction_handler + db 'bndstx',1Bh + dw bndstx_instruction-instruction_handler + db 'clzero',0 + dw clzero_instruction-instruction_handler + db 'cmovae',43h + dw bs_instruction-instruction_handler + db 'cmovbe',46h + dw bs_instruction-instruction_handler + db 'cmovge',4Dh + dw bs_instruction-instruction_handler + db 'cmovle',4Eh + dw bs_instruction-instruction_handler + db 'cmovna',46h + dw bs_instruction-instruction_handler + db 'cmovnb',43h + dw bs_instruction-instruction_handler + db 'cmovnc',43h + dw bs_instruction-instruction_handler + db 'cmovne',45h + dw bs_instruction-instruction_handler + db 'cmovng',4Eh + dw bs_instruction-instruction_handler + db 'cmovnl',4Dh + dw bs_instruction-instruction_handler + db 'cmovno',41h + dw bs_instruction-instruction_handler + db 'cmovnp',4Bh + dw bs_instruction-instruction_handler + db 'cmovns',49h + dw bs_instruction-instruction_handler + db 'cmovnz',45h + dw bs_instruction-instruction_handler + db 'cmovpe',4Ah + dw bs_instruction-instruction_handler + db 'cmovpo',4Bh + dw bs_instruction-instruction_handler + db 'comisd',2Fh + dw comisd_instruction-instruction_handler + db 'comiss',2Fh + dw comiss_instruction-instruction_handler + db 'fcmovb',0C0h + dw fcmov_instruction-instruction_handler + db 'fcmove',0C8h + dw fcmov_instruction-instruction_handler + db 'fcmovu',0D8h + dw fcmov_instruction-instruction_handler + db 'fcomip',0F0h + dw fcomip_instruction-instruction_handler + db 'fcompp',0 + dw fcompp_instruction-instruction_handler + db 'fdivrp',6 + dw faddp_instruction-instruction_handler + db 'ffreep',0 + dw ffreep_instruction-instruction_handler + db 'ficomp',3 + dw fi_instruction-instruction_handler + db 'fidivr',7 + dw fi_instruction-instruction_handler + db 'fisttp',1 + dw fild_instruction-instruction_handler + db 'fisubr',5 + dw fi_instruction-instruction_handler + db 'fldenv',4 + dw fldenv_instruction-instruction_handler + db 'fldl2e',101010b + dw simple_fpu_instruction-instruction_handler + db 'fldl2t',101001b + dw simple_fpu_instruction-instruction_handler + db 'fldlg2',101100b + dw simple_fpu_instruction-instruction_handler + db 'fldln2',101101b + dw simple_fpu_instruction-instruction_handler + db 'fnclex',0E2h + dw fninit_instruction-instruction_handler + db 'fndisi',0E1h + dw fninit_instruction-instruction_handler + db 'fninit',0E3h + dw fninit_instruction-instruction_handler + db 'fnsave',6 + dw fnsave_instruction-instruction_handler + db 'fnstcw',7 + dw fldcw_instruction-instruction_handler + db 'fnstsw',0 + dw fnstsw_instruction-instruction_handler + db 'format',0 + dw format_directive-instruction_handler + db 'fpatan',110011b + dw simple_fpu_instruction-instruction_handler + db 'fprem1',110101b + dw simple_fpu_instruction-instruction_handler + db 'frstor',4 + dw fnsave_instruction-instruction_handler + db 'frstpm',0E5h + dw fninit_instruction-instruction_handler + db 'fsaved',6 + dw fsave_instruction_32bit-instruction_handler + db 'fsavew',6 + dw fsave_instruction_16bit-instruction_handler + db 'fscale',111101b + dw simple_fpu_instruction-instruction_handler + db 'fsetpm',0E4h + dw fninit_instruction-instruction_handler + db 'fstenv',6 + dw fstenv_instruction-instruction_handler + db 'fsubrp',4 + dw faddp_instruction-instruction_handler + db 'fucomi',0E8h + dw fcomi_instruction-instruction_handler + db 'fucomp',5 + dw ffree_instruction-instruction_handler + db 'fxsave',0 + dw fxsave_instruction-instruction_handler + db 'getsec',37h + dw simple_extended_instruction-instruction_handler + db 'haddpd',07Ch + dw sse_pd_instruction-instruction_handler + db 'haddps',07Ch + dw cvtpd2dq_instruction-instruction_handler + db 'hsubpd',07Dh + dw sse_pd_instruction-instruction_handler + db 'hsubps',07Dh + dw cvtpd2dq_instruction-instruction_handler + db 'invept',80h + dw vmx_inv_instruction-instruction_handler + db 'invlpg',0 + dw invlpg_instruction-instruction_handler + db 'kandnb',42h + dw mask_instruction_b-instruction_handler + db 'kandnd',42h + dw mask_instruction_d-instruction_handler + db 'kandnq',42h + dw mask_instruction_q-instruction_handler + db 'kandnw',42h + dw mask_instruction_w-instruction_handler + db 'ktestb',99h + dw mask_instruction_single_source_b-instruction_handler + db 'ktestd',99h + dw mask_instruction_single_source_d-instruction_handler + db 'ktestq',99h + dw mask_instruction_single_source_q-instruction_handler + db 'ktestw',99h + dw mask_instruction_single_source_w-instruction_handler + db 'kxnorb',46h + dw mask_instruction_b-instruction_handler + db 'kxnord',46h + dw mask_instruction_d-instruction_handler + db 'kxnorq',46h + dw mask_instruction_q-instruction_handler + db 'kxnorw',46h + dw mask_instruction_w-instruction_handler + db 'lfence',0E8h + dw fence_instruction-instruction_handler + db 'llwpcb',0 + dw llwpcb_instruction-instruction_handler + db 'looped',0E1h + dw loop_instruction_32bit-instruction_handler + db 'loopeq',0E1h + dw loop_instruction_64bit-instruction_handler + db 'loopew',0E1h + dw loop_instruction_16bit-instruction_handler + db 'loopne',0E0h + dw loop_instruction-instruction_handler + db 'loopnz',0E0h + dw loop_instruction-instruction_handler + db 'loopzd',0E1h + dw loop_instruction_32bit-instruction_handler + db 'loopzq',0E1h + dw loop_instruction_64bit-instruction_handler + db 'loopzw',0E1h + dw loop_instruction_16bit-instruction_handler + db 'lwpins',0 + dw lwpins_instruction-instruction_handler + db 'lwpval',1 + dw lwpins_instruction-instruction_handler + db 'mfence',0F0h + dw fence_instruction-instruction_handler + db 'movapd',28h + dw movpd_instruction-instruction_handler + db 'movaps',28h + dw movps_instruction-instruction_handler + db 'movdqa',66h + dw movdq_instruction-instruction_handler + db 'movdqu',0F3h + dw movdq_instruction-instruction_handler + db 'movhpd',16h + dw movlpd_instruction-instruction_handler + db 'movhps',16h + dw movlps_instruction-instruction_handler + db 'movlpd',12h + dw movlpd_instruction-instruction_handler + db 'movlps',12h + dw movlps_instruction-instruction_handler + db 'movnti',0C3h + dw movnti_instruction-instruction_handler + db 'movntq',0E7h + dw movntq_instruction-instruction_handler + db 'movsxd',63h + dw movsxd_instruction-instruction_handler + db 'movupd',10h + dw movpd_instruction-instruction_handler + db 'movups',10h + dw movps_instruction-instruction_handler + db 'mwaitx',0FBh + dw monitor_instruction-instruction_handler + db 'paddsb',0ECh + dw basic_mmx_instruction-instruction_handler + db 'paddsw',0EDh + dw basic_mmx_instruction-instruction_handler + db 'pextrb',14h + dw pextrb_instruction-instruction_handler + db 'pextrd',16h + dw pextrd_instruction-instruction_handler + db 'pextrq',16h + dw pextrq_instruction-instruction_handler + db 'pextrw',15h + dw pextrw_instruction-instruction_handler + db 'pfnacc',8Ah + dw amd3dnow_instruction-instruction_handler + db 'pfsubr',0AAh + dw amd3dnow_instruction-instruction_handler + db 'phaddd',2 + dw ssse3_instruction-instruction_handler + db 'phaddw',1 + dw ssse3_instruction-instruction_handler + db 'phsubd',6 + dw ssse3_instruction-instruction_handler + db 'phsubw',5 + dw ssse3_instruction-instruction_handler + db 'pinsrb',20h + dw pinsrb_instruction-instruction_handler + db 'pinsrd',22h + dw pinsrd_instruction-instruction_handler + db 'pinsrq',22h + dw pinsrq_instruction-instruction_handler + db 'pinsrw',0C4h + dw pinsrw_instruction-instruction_handler + db 'pmaxsb',3Ch + dw sse4_instruction_66_38-instruction_handler + db 'pmaxsd',3Dh + dw sse4_instruction_66_38-instruction_handler + db 'pmaxsw',0EEh + dw basic_mmx_instruction-instruction_handler + db 'pmaxub',0DEh + dw basic_mmx_instruction-instruction_handler + db 'pmaxud',3Fh + dw sse4_instruction_66_38-instruction_handler + db 'pmaxuw',3Eh + dw sse4_instruction_66_38-instruction_handler + db 'pminsb',38h + dw sse4_instruction_66_38-instruction_handler + db 'pminsd',39h + dw sse4_instruction_66_38-instruction_handler + db 'pminsw',0EAh + dw basic_mmx_instruction-instruction_handler + db 'pminub',0DAh + dw basic_mmx_instruction-instruction_handler + db 'pminud',3Bh + dw sse4_instruction_66_38-instruction_handler + db 'pminuw',3Ah + dw sse4_instruction_66_38-instruction_handler + db 'pmuldq',28h + dw sse4_instruction_66_38-instruction_handler + db 'pmulhw',0E5h + dw basic_mmx_instruction-instruction_handler + db 'pmulld',40h + dw sse4_instruction_66_38-instruction_handler + db 'pmullw',0D5h + dw basic_mmx_instruction-instruction_handler + db 'popcnt',0B8h + dw popcnt_instruction-instruction_handler + db 'psadbw',0F6h + dw basic_mmx_instruction-instruction_handler + db 'pshufb',0 + dw ssse3_instruction-instruction_handler + db 'pshufd',66h + dw pshufd_instruction-instruction_handler + db 'pshufw',0 + dw pshufw_instruction-instruction_handler + db 'psignb',8 + dw ssse3_instruction-instruction_handler + db 'psignd',0Ah + dw ssse3_instruction-instruction_handler + db 'psignw',9 + dw ssse3_instruction-instruction_handler + db 'pslldq',111b + dw pslldq_instruction-instruction_handler + db 'psmash',0FFh + dw simple_instruction_f3_0f_01-instruction_handler + db 'psrldq',011b + dw pslldq_instruction-instruction_handler + db 'psubsb',0E8h + dw basic_mmx_instruction-instruction_handler + db 'psubsw',0E9h + dw basic_mmx_instruction-instruction_handler + db 'pswapd',0BBh + dw amd3dnow_instruction-instruction_handler + db 'public',0 + dw public_directive-instruction_handler + db 'pushad',60h + dw simple_instruction_32bit_except64-instruction_handler + db 'pushaw',60h + dw simple_instruction_16bit_except64-instruction_handler + db 'pushfd',9Ch + dw simple_instruction_32bit_except64-instruction_handler + db 'pushfq',9Ch + dw simple_instruction_only64-instruction_handler + db 'pushfw',9Ch + dw simple_instruction_16bit-instruction_handler + db 'rdmsrq',32h + dw simple_extended_instruction_64bit-instruction_handler + db 'rdpkru',0EEh + dw simple_instruction_0f_01-instruction_handler + db 'rdrand',110b + dw rdrand_instruction-instruction_handler + db 'rdseed',111b + dw rdrand_instruction-instruction_handler + db 'rdsspd',1 + dw rdsspd_instruction-instruction_handler + db 'rdsspq',1 + dw rdsspq_instruction-instruction_handler + db 'rdtscp',0F9h + dw simple_instruction_0f_01-instruction_handler + db 'repeat',0 + dw repeat_directive-instruction_handler + db 'setalc',0D6h + dw simple_instruction_except64-instruction_handler + db 'setnae',92h + dw set_instruction-instruction_handler + db 'setnbe',97h + dw set_instruction-instruction_handler + db 'setnge',9Ch + dw set_instruction-instruction_handler + db 'setnle',9Fh + dw set_instruction-instruction_handler + db 'sfence',0F8h + dw fence_instruction-instruction_handler + db 'shufpd',0C6h + dw sse_pd_instruction_imm8-instruction_handler + db 'shufps',0C6h + dw sse_ps_instruction_imm8-instruction_handler + db 'skinit',0 + dw skinit_instruction-instruction_handler + db 'slwpcb',1 + dw llwpcb_instruction-instruction_handler + db 'sqrtpd',51h + dw sse_pd_instruction-instruction_handler + db 'sqrtps',51h + dw sse_ps_instruction-instruction_handler + db 'sqrtsd',51h + dw sse_sd_instruction-instruction_handler + db 'sqrtss',51h + dw sse_ss_instruction-instruction_handler + db 'swapgs',0F8h + dw swapgs_instruction-instruction_handler + db 'sysret',07h + dw simple_extended_instruction-instruction_handler + db 't1mskc',17h + dw tbm_instruction-instruction_handler + db 'tpause',66h + dw tpause_instruction-instruction_handler + db 'umwait',0F2h + dw tpause_instruction-instruction_handler + db 'vaddpd',58h + dw avx_pd_instruction_er-instruction_handler + db 'vaddps',58h + dw avx_ps_instruction_er-instruction_handler + db 'vaddsd',58h + dw avx_sd_instruction_er-instruction_handler + db 'vaddss',58h + dw avx_ss_instruction_er-instruction_handler + db 'vandpd',54h + dw avx_pd_instruction-instruction_handler + db 'vandps',54h + dw avx_ps_instruction-instruction_handler + db 'vcmppd',-1 + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpps',-1 + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpsd',-1 + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpss',-1 + dw avx_cmp_ss_instruction-instruction_handler + db 'vdivpd',5Eh + dw avx_pd_instruction_er-instruction_handler + db 'vdivps',5Eh + dw avx_ps_instruction_er-instruction_handler + db 'vdivsd',5Eh + dw avx_sd_instruction_er-instruction_handler + db 'vdivss',5Eh + dw avx_ss_instruction_er-instruction_handler + db 'vlddqu',0F0h + dw avx_lddqu_instruction-instruction_handler + db 'vmaxpd',5Fh + dw avx_pd_instruction_sae-instruction_handler + db 'vmaxps',5Fh + dw avx_ps_instruction_sae-instruction_handler + db 'vmaxsd',5Fh + dw avx_sd_instruction_sae-instruction_handler + db 'vmaxss',5Fh + dw avx_ss_instruction_sae-instruction_handler + db 'vmcall',0C1h + dw simple_instruction_0f_01-instruction_handler + db 'vmfunc',0D4h + dw simple_instruction_0f_01-instruction_handler + db 'vminpd',5Dh + dw avx_pd_instruction_sae-instruction_handler + db 'vminps',5Dh + dw avx_ps_instruction_sae-instruction_handler + db 'vminsd',5Dh + dw avx_sd_instruction_sae-instruction_handler + db 'vminss',5Dh + dw avx_ss_instruction_sae-instruction_handler + db 'vmload',0DAh + dw simple_svm_instruction-instruction_handler + db 'vmovsd',0 + dw avx_movsd_instruction-instruction_handler + db 'vmovss',0 + dw avx_movss_instruction-instruction_handler + db 'vmread',0 + dw vmread_instruction-instruction_handler + db 'vmsave',0DBh + dw simple_svm_instruction-instruction_handler + db 'vmulpd',59h + dw avx_pd_instruction_er-instruction_handler + db 'vmulps',59h + dw avx_ps_instruction_er-instruction_handler + db 'vmulsd',59h + dw avx_sd_instruction_er-instruction_handler + db 'vmulss',59h + dw avx_ss_instruction_er-instruction_handler + db 'vmxoff',0C4h + dw simple_instruction_0f_01-instruction_handler + db 'vpabsb',1Ch + dw avx_single_source_bw_instruction_38-instruction_handler + db 'vpabsd',1Eh + dw avx_single_source_d_instruction_38-instruction_handler + db 'vpabsq',1Fh + dw avx_single_source_q_instruction_38_evex-instruction_handler + db 'vpabsw',1Dh + dw avx_single_source_bw_instruction_38-instruction_handler + db 'vpaddb',0FCh + dw avx_bw_instruction-instruction_handler + db 'vpaddd',0FEh + dw avx_d_instruction-instruction_handler + db 'vpaddq',0D4h + dw avx_q_instruction-instruction_handler + db 'vpaddw',0FDh + dw avx_bw_instruction-instruction_handler + db 'vpandd',0DBh + dw avx_d_instruction_evex-instruction_handler + db 'vpandn',0DFh + dw avx_pd_instruction_noevex-instruction_handler + db 'vpandq',0DBh + dw avx_q_instruction_evex-instruction_handler + db 'vpavgb',0E0h + dw avx_bw_instruction-instruction_handler + db 'vpavgw',0E3h + dw avx_bw_instruction-instruction_handler + db 'vpcmov',0A2h + dw vpcmov_instruction-instruction_handler + db 'vpcmpb',-1 + dw avx512_cmp_b_instruction-instruction_handler + db 'vpcmpd',-1 + dw avx512_cmp_d_instruction-instruction_handler + db 'vpcmpq',-1 + dw avx512_cmp_q_instruction-instruction_handler + db 'vpcmpw',-1 + dw avx512_cmp_w_instruction-instruction_handler + db 'vpcomb',-1 + dw xop_pcom_b_instruction-instruction_handler + db 'vpcomd',-1 + dw xop_pcom_d_instruction-instruction_handler + db 'vpcomq',-1 + dw xop_pcom_q_instruction-instruction_handler + db 'vpcomw',-1 + dw xop_pcom_w_instruction-instruction_handler + db 'vpermb',8Dh + dw avx_bw_instruction_38_evex-instruction_handler + db 'vpermd',36h + dw avx_permd_instruction-instruction_handler + db 'vpermq',0 + dw avx_permq_instruction-instruction_handler + db 'vpermw',8Dh + dw avx_bw_instruction_38_w1_evex-instruction_handler + db 'vpperm',0A3h + dw xop_128bit_instruction-instruction_handler + db 'vprold',1 + dw avx512_rotate_d_instruction-instruction_handler + db 'vprolq',1 + dw avx512_rotate_q_instruction-instruction_handler + db 'vprord',0 + dw avx512_rotate_d_instruction-instruction_handler + db 'vprorq',0 + dw avx512_rotate_q_instruction-instruction_handler + db 'vprotb',90h + dw xop_shift_instruction-instruction_handler + db 'vprotd',92h + dw xop_shift_instruction-instruction_handler + db 'vprotq',93h + dw xop_shift_instruction-instruction_handler + db 'vprotw',91h + dw xop_shift_instruction-instruction_handler + db 'vpshab',98h + dw xop_shift_instruction-instruction_handler + db 'vpshad',9Ah + dw xop_shift_instruction-instruction_handler + db 'vpshaq',9Bh + dw xop_shift_instruction-instruction_handler + db 'vpshaw',99h + dw xop_shift_instruction-instruction_handler + db 'vpshlb',94h + dw xop_shift_instruction-instruction_handler + db 'vpshld',96h + dw xop_shift_instruction-instruction_handler + db 'vpshlq',97h + dw xop_shift_instruction-instruction_handler + db 'vpshlw',95h + dw xop_shift_instruction-instruction_handler + db 'vpslld',0F2h + dw avx_shift_d_instruction-instruction_handler + db 'vpsllq',0F3h + dw avx_shift_q_instruction-instruction_handler + db 'vpsllw',0F1h + dw avx_shift_bw_instruction-instruction_handler + db 'vpsrad',0E2h + dw avx_shift_d_instruction-instruction_handler + db 'vpsraq',0E2h + dw avx_shift_q_instruction_evex-instruction_handler + db 'vpsraw',0E1h + dw avx_shift_bw_instruction-instruction_handler + db 'vpsrld',0D2h + dw avx_shift_d_instruction-instruction_handler + db 'vpsrlq',0D3h + dw avx_shift_q_instruction-instruction_handler + db 'vpsrlw',0D1h + dw avx_shift_bw_instruction-instruction_handler + db 'vpsubb',0F8h + dw avx_bw_instruction-instruction_handler + db 'vpsubd',0FAh + dw avx_d_instruction-instruction_handler + db 'vpsubq',0FBh + dw avx_q_instruction-instruction_handler + db 'vpsubw',0F9h + dw avx_bw_instruction-instruction_handler + db 'vptest',17h + dw avx_single_source_instruction_38_noevex-instruction_handler + db 'vpxord',0EFh + dw avx_d_instruction_evex-instruction_handler + db 'vpxorq',0EFh + dw avx_q_instruction_evex-instruction_handler + db 'vrcpps',53h + dw avx_single_source_ps_instruction_noevex-instruction_handler + db 'vrcpss',53h + dw avx_ss_instruction_noevex-instruction_handler + db 'vsubpd',5Ch + dw avx_pd_instruction_er-instruction_handler + db 'vsubps',5Ch + dw avx_ps_instruction_er-instruction_handler + db 'vsubsd',5Ch + dw avx_sd_instruction_er-instruction_handler + db 'vsubss',5Ch + dw avx_ss_instruction_er-instruction_handler + db 'vxorpd',57h + dw avx_pd_instruction-instruction_handler + db 'vxorps',57h + dw avx_ps_instruction-instruction_handler + db 'wbinvd',9 + dw simple_extended_instruction-instruction_handler + db 'wrmsrq',30h + dw simple_extended_instruction_64bit-instruction_handler + db 'wrpkru',0EFh + dw simple_instruction_0f_01-instruction_handler + db 'wrussd',0F5h + dw wrussd_instruction-instruction_handler + db 'wrussq',0F5h + dw wrussq_instruction-instruction_handler + db 'xabort',0 + dw xabort_instruction-instruction_handler + db 'xbegin',0 + dw xbegin_instruction-instruction_handler + db 'xgetbv',0D0h + dw simple_instruction_0f_01-instruction_handler + db 'xrstor',101b + dw fxsave_instruction-instruction_handler + db 'xsavec',4 + dw xsaves_instruction-instruction_handler + db 'xsaves',5 + dw xsaves_instruction-instruction_handler + db 'xsetbv',0D1h + dw simple_instruction_0f_01-instruction_handler +instructions_7: + db 'blcfill',11h + dw tbm_instruction-instruction_handler + db 'blendpd',0Dh + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'blendps',0Ch + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'blsfill',12h + dw tbm_instruction-instruction_handler + db 'clflush',111b + dw clflush_instruction-instruction_handler + db 'cmovnae',42h + dw bs_instruction-instruction_handler + db 'cmovnbe',47h + dw bs_instruction-instruction_handler + db 'cmovnge',4Ch + dw bs_instruction-instruction_handler + db 'cmovnle',4Fh + dw bs_instruction-instruction_handler + db 'cmpeqpd',0 + dw cmp_pd_instruction-instruction_handler + db 'cmpeqps',0 + dw cmp_ps_instruction-instruction_handler + db 'cmpeqsd',0 + dw cmp_sd_instruction-instruction_handler + db 'cmpeqss',0 + dw cmp_ss_instruction-instruction_handler + db 'cmplepd',2 + dw cmp_pd_instruction-instruction_handler + db 'cmpleps',2 + dw cmp_ps_instruction-instruction_handler + db 'cmplesd',2 + dw cmp_sd_instruction-instruction_handler + db 'cmpless',2 + dw cmp_ss_instruction-instruction_handler + db 'cmpltpd',1 + dw cmp_pd_instruction-instruction_handler + db 'cmpltps',1 + dw cmp_ps_instruction-instruction_handler + db 'cmpltsd',1 + dw cmp_sd_instruction-instruction_handler + db 'cmpltss',1 + dw cmp_ss_instruction-instruction_handler + db 'cmpxchg',0B0h + dw basic_486_instruction-instruction_handler + db 'display',0 + dw display_directive-instruction_handler + db 'endbr32',0FBh + dw endbr_instruction-instruction_handler + db 'endbr64',0FAh + dw endbr_instruction-instruction_handler + db 'fcmovbe',0D0h + dw fcmov_instruction-instruction_handler + db 'fcmovnb',0C0h + dw fcomi_instruction-instruction_handler + db 'fcmovne',0C8h + dw fcomi_instruction-instruction_handler + db 'fcmovnu',0D8h + dw fcomi_instruction-instruction_handler + db 'fdecstp',110110b + dw simple_fpu_instruction-instruction_handler + db 'fincstp',110111b + dw simple_fpu_instruction-instruction_handler + db 'fldenvd',4 + dw fldenv_instruction_32bit-instruction_handler + db 'fldenvw',4 + dw fldenv_instruction_16bit-instruction_handler + db 'fnsaved',6 + dw fnsave_instruction_32bit-instruction_handler + db 'fnsavew',6 + dw fnsave_instruction_16bit-instruction_handler + db 'fnstenv',6 + dw fldenv_instruction-instruction_handler + db 'frndint',111100b + dw simple_fpu_instruction-instruction_handler + db 'frstord',4 + dw fnsave_instruction_32bit-instruction_handler + db 'frstorw',4 + dw fnsave_instruction_16bit-instruction_handler + db 'fsincos',111011b + dw simple_fpu_instruction-instruction_handler + db 'fstenvd',6 + dw fstenv_instruction_32bit-instruction_handler + db 'fstenvw',6 + dw fstenv_instruction_16bit-instruction_handler + db 'fucomip',0E8h + dw fcomip_instruction-instruction_handler + db 'fucompp',0 + dw fucompp_instruction-instruction_handler + db 'fxrstor',1 + dw fxsave_instruction-instruction_handler + db 'fxtract',110100b + dw simple_fpu_instruction-instruction_handler + db 'fyl2xp1',111001b + dw simple_fpu_instruction-instruction_handler + db 'incsspd',5 + dw incsspd_instruction-instruction_handler + db 'incsspq',5 + dw incsspq_instruction-instruction_handler + db 'insertq',0 + dw insertq_instruction-instruction_handler + db 'invlpga',0DFh + dw invlpga_instruction-instruction_handler + db 'invlpgb',0FEh + dw simple_instruction_0f_01-instruction_handler + db 'invpcid',82h + dw vmx_inv_instruction-instruction_handler + db 'invvpid',81h + dw vmx_inv_instruction-instruction_handler + db 'ldmxcsr',10b + dw stmxcsr_instruction-instruction_handler + db 'loopned',0E0h + dw loop_instruction_32bit-instruction_handler + db 'loopneq',0E0h + dw loop_instruction_64bit-instruction_handler + db 'loopnew',0E0h + dw loop_instruction_16bit-instruction_handler + db 'loopnzd',0E0h + dw loop_instruction_32bit-instruction_handler + db 'loopnzq',0E0h + dw loop_instruction_64bit-instruction_handler + db 'loopnzw',0E0h + dw loop_instruction_16bit-instruction_handler + db 'mcommit',0FAh + dw simple_instruction_f3_0f_01-instruction_handler + db 'monitor',0C8h + dw monitor_instruction-instruction_handler + db 'movddup',12h + dw sse_sd_instruction-instruction_handler + db 'movdiri',0F9h + dw movdiri_instruction-instruction_handler + db 'movdq2q',0 + dw movdq2q_instruction-instruction_handler + db 'movhlps',12h + dw movhlps_instruction-instruction_handler + db 'movlhps',16h + dw movhlps_instruction-instruction_handler + db 'movntdq',0E7h + dw movntpd_instruction-instruction_handler + db 'movntpd',2Bh + dw movntpd_instruction-instruction_handler + db 'movntps',2Bh + dw movntps_instruction-instruction_handler + db 'movntsd',2Bh + dw movntsd_instruction-instruction_handler + db 'movntss',2Bh + dw movntss_instruction-instruction_handler + db 'movq2dq',0 + dw movq2dq_instruction-instruction_handler + db 'mpsadbw',42h + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'paddusb',0DCh + dw basic_mmx_instruction-instruction_handler + db 'paddusw',0DDh + dw basic_mmx_instruction-instruction_handler + db 'palignr',0 + dw palignr_instruction-instruction_handler + db 'pavgusb',0BFh + dw amd3dnow_instruction-instruction_handler + db 'pblendw',0Eh + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'pcmpeqb',74h + dw basic_mmx_instruction-instruction_handler + db 'pcmpeqd',76h + dw basic_mmx_instruction-instruction_handler + db 'pcmpeqq',29h + dw sse4_instruction_66_38-instruction_handler + db 'pcmpeqw',75h + dw basic_mmx_instruction-instruction_handler + db 'pcmpgtb',64h + dw basic_mmx_instruction-instruction_handler + db 'pcmpgtd',66h + dw basic_mmx_instruction-instruction_handler + db 'pcmpgtq',37h + dw sse4_instruction_66_38-instruction_handler + db 'pcmpgtw',65h + dw basic_mmx_instruction-instruction_handler + db 'pcommit',0F8h + dw pcommit_instruction-instruction_handler + db 'pconfig',0C5h + dw pconfig_instruction-instruction_handler + db 'pfcmpeq',0B0h + dw amd3dnow_instruction-instruction_handler + db 'pfcmpge',90h + dw amd3dnow_instruction-instruction_handler + db 'pfcmpgt',0A0h + dw amd3dnow_instruction-instruction_handler + db 'pfpnacc',8Eh + dw amd3dnow_instruction-instruction_handler + db 'pfrsqrt',97h + dw amd3dnow_instruction-instruction_handler + db 'phaddsw',3 + dw ssse3_instruction-instruction_handler + db 'phsubsw',7 + dw ssse3_instruction-instruction_handler + db 'pmaddwd',0F5h + dw basic_mmx_instruction-instruction_handler + db 'pmulhrw',0B7h + dw amd3dnow_instruction-instruction_handler + db 'pmulhuw',0E4h + dw basic_mmx_instruction-instruction_handler + db 'pmuludq',0F4h + dw basic_mmx_instruction-instruction_handler + db 'pshufhw',0F3h + dw pshufd_instruction-instruction_handler + db 'pshuflw',0F2h + dw pshufd_instruction-instruction_handler + db 'psubusb',0D8h + dw basic_mmx_instruction-instruction_handler + db 'psubusw',0D9h + dw basic_mmx_instruction-instruction_handler + db 'ptwrite',4 + dw ptwrite_instruction-instruction_handler + db 'roundpd',9 + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'roundps',8 + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'roundsd',0Bh + dw sse4_sd_instruction_66_3a_imm8-instruction_handler + db 'roundss',0Ah + dw sse4_ss_instruction_66_3a_imm8-instruction_handler + db 'rsqrtps',52h + dw sse_ps_instruction-instruction_handler + db 'rsqrtss',52h + dw sse_ss_instruction-instruction_handler + db 'section',0 + dw section_directive-instruction_handler + db 'segment',0 + dw segment_directive-instruction_handler + db 'stmxcsr',11b + dw stmxcsr_instruction-instruction_handler + db 'syscall',05h + dw simple_extended_instruction-instruction_handler + db 'sysexit',35h + dw simple_extended_instruction-instruction_handler + db 'sysretq',07h + dw simple_extended_instruction_64bit-instruction_handler + db 'tlbsync',0FFh + dw simple_instruction_0f_01-instruction_handler + db 'ucomisd',2Eh + dw comisd_instruction-instruction_handler + db 'ucomiss',2Eh + dw comiss_instruction-instruction_handler + db 'vaesdec',0DEh + dw avx_instruction_38_nomask-instruction_handler + db 'vaesenc',0DCh + dw avx_instruction_38_nomask-instruction_handler + db 'vaesimc',0DBh + dw avx_single_source_128bit_instruction_38_noevex-instruction_handler + db 'valignd',3 + dw avx_d_instruction_3a_imm8_evex-instruction_handler + db 'valignq',3 + dw avx_q_instruction_3a_imm8_evex-instruction_handler + db 'vandnpd',55h + dw avx_pd_instruction-instruction_handler + db 'vandnps',55h + dw avx_ps_instruction-instruction_handler + db 'vcomisd',2Fh + dw avx_comisd_instruction-instruction_handler + db 'vcomiss',2Fh + dw avx_comiss_instruction-instruction_handler + db 'vexp2pd',0C8h + dw avx512_exp2pd_instruction-instruction_handler + db 'vexp2ps',0C8h + dw avx512_exp2ps_instruction-instruction_handler + db 'vfrczpd',81h + dw xop_single_source_instruction-instruction_handler + db 'vfrczps',80h + dw xop_single_source_instruction-instruction_handler + db 'vfrczsd',83h + dw xop_single_source_sd_instruction-instruction_handler + db 'vfrczss',82h + dw xop_single_source_ss_instruction-instruction_handler + db 'vhaddpd',07Ch + dw avx_pd_instruction_noevex-instruction_handler + db 'vhaddps',07Ch + dw avx_ps_instruction_noevex-instruction_handler + db 'vhsubpd',07Dh + dw avx_pd_instruction_noevex-instruction_handler + db 'vhsubps',07Dh + dw avx_ps_instruction_noevex-instruction_handler + db 'virtual',0 + dw virtual_directive-instruction_handler + db 'vmclear',6 + dw vmclear_instruction-instruction_handler + db 'vmmcall',0D9h + dw simple_instruction_0f_01-instruction_handler + db 'vmovapd',28h + dw avx_movpd_instruction-instruction_handler + db 'vmovaps',28h + dw avx_movps_instruction-instruction_handler + db 'vmovdqa',6Fh + dw avx_movdqa_instruction-instruction_handler + db 'vmovdqu',6Fh + dw avx_movdqu_instruction-instruction_handler + db 'vmovhpd',16h + dw avx_movlpd_instruction-instruction_handler + db 'vmovhps',16h + dw avx_movlps_instruction-instruction_handler + db 'vmovlpd',12h + dw avx_movlpd_instruction-instruction_handler + db 'vmovlps',12h + dw avx_movlps_instruction-instruction_handler + db 'vmovupd',10h + dw avx_movpd_instruction-instruction_handler + db 'vmovups',10h + dw avx_movps_instruction-instruction_handler + db 'vmptrld',6 + dw vmx_instruction-instruction_handler + db 'vmptrst',7 + dw vmx_instruction-instruction_handler + db 'vmwrite',0 + dw vmwrite_instruction-instruction_handler + db 'vpaddsb',0ECh + dw avx_bw_instruction-instruction_handler + db 'vpaddsw',0EDh + dw avx_bw_instruction-instruction_handler + db 'vpandnd',0DFh + dw avx_d_instruction_evex-instruction_handler + db 'vpandnq',0DFh + dw avx_q_instruction_evex-instruction_handler + db 'vpcmpub',-1 + dw avx512_cmp_ub_instruction-instruction_handler + db 'vpcmpud',-1 + dw avx512_cmp_ud_instruction-instruction_handler + db 'vpcmpuq',-1 + dw avx512_cmp_uq_instruction-instruction_handler + db 'vpcmpuw',-1 + dw avx512_cmp_uw_instruction-instruction_handler + db 'vpcomub',-1 + dw xop_pcom_ub_instruction-instruction_handler + db 'vpcomud',-1 + dw xop_pcom_ud_instruction-instruction_handler + db 'vpcomuq',-1 + dw xop_pcom_uq_instruction-instruction_handler + db 'vpcomuw',-1 + dw xop_pcom_uw_instruction-instruction_handler + db 'vpermpd',1 + dw avx_permq_instruction-instruction_handler + db 'vpermps',16h + dw avx_permd_instruction-instruction_handler + db 'vpextrb',14h + dw avx_extract_b_instruction-instruction_handler + db 'vpextrd',16h + dw avx_extract_d_instruction-instruction_handler + db 'vpextrq',16h + dw avx_extract_q_instruction-instruction_handler + db 'vpextrw',15h + dw avx_extract_w_instruction-instruction_handler + db 'vphaddd',2 + dw avx_pi_instruction_38_noevex-instruction_handler + db 'vphaddw',1 + dw avx_pi_instruction_38_noevex-instruction_handler + db 'vphsubd',6 + dw avx_pi_instruction_38_noevex-instruction_handler + db 'vphsubw',5 + dw avx_pi_instruction_38_noevex-instruction_handler + db 'vpinsrb',20h + dw avx_pinsrb_instruction-instruction_handler + db 'vpinsrd',22h + dw avx_pinsrd_instruction-instruction_handler + db 'vpinsrq',22h + dw avx_pinsrq_instruction-instruction_handler + db 'vpinsrw',0C4h + dw avx_pinsrw_instruction-instruction_handler + db 'vpmaxsb',3Ch + dw avx_bw_instruction_38-instruction_handler + db 'vpmaxsd',3Dh + dw avx_d_instruction_38-instruction_handler + db 'vpmaxsq',3Dh + dw avx_q_instruction_38_evex-instruction_handler + db 'vpmaxsw',0EEh + dw avx_bw_instruction-instruction_handler + db 'vpmaxub',0DEh + dw avx_bw_instruction-instruction_handler + db 'vpmaxud',3Fh + dw avx_d_instruction_38-instruction_handler + db 'vpmaxuq',3Fh + dw avx_q_instruction_38_evex-instruction_handler + db 'vpmaxuw',3Eh + dw avx_bw_instruction_38-instruction_handler + db 'vpminsb',38h + dw avx_bw_instruction_38-instruction_handler + db 'vpminsd',39h + dw avx_d_instruction_38-instruction_handler + db 'vpminsq',39h + dw avx_q_instruction_38_evex-instruction_handler + db 'vpminsw',0EAh + dw avx_bw_instruction-instruction_handler + db 'vpminub',0DAh + dw avx_bw_instruction-instruction_handler + db 'vpminud',3Bh + dw avx_d_instruction_38-instruction_handler + db 'vpminuq',3Bh + dw avx_q_instruction_38_evex-instruction_handler + db 'vpminuw',3Ah + dw avx_bw_instruction_38-instruction_handler + db 'vpmovdb',31h + dw avx512_pmovdb_instruction-instruction_handler + db 'vpmovdw',33h + dw avx512_pmovwb_instruction-instruction_handler + db 'vpmovqb',32h + dw avx512_pmovqb_instruction-instruction_handler + db 'vpmovqd',35h + dw avx512_pmovwb_instruction-instruction_handler + db 'vpmovqw',34h + dw avx512_pmovdb_instruction-instruction_handler + db 'vpmovwb',30h + dw avx512_pmovwb_instruction-instruction_handler + db 'vpmuldq',28h + dw avx_q_instruction_38-instruction_handler + db 'vpmulhw',0E5h + dw avx_bw_instruction-instruction_handler + db 'vpmulld',40h + dw avx_d_instruction_38-instruction_handler + db 'vpmullq',40h + dw avx_q_instruction_38_evex-instruction_handler + db 'vpmullw',0D5h + dw avx_bw_instruction-instruction_handler + db 'vprolvd',15h + dw avx_d_instruction_38_evex-instruction_handler + db 'vprolvq',15h + dw avx_q_instruction_38_evex-instruction_handler + db 'vprorvd',14h + dw avx_d_instruction_38_evex-instruction_handler + db 'vprorvq',14h + dw avx_q_instruction_38_evex-instruction_handler + db 'vpsadbw',0F6h + dw avx_bw_instruction-instruction_handler + db 'vpshldd',71h + dw avx_d_instruction_3a_imm8_evex-instruction_handler + db 'vpshldq',71h + dw avx_q_instruction_3a_imm8_evex-instruction_handler + db 'vpshldw',70h + dw avx_bw_instruction_3a_imm8_w1_evex-instruction_handler + db 'vpshrdd',73h + dw avx_d_instruction_3a_imm8_evex-instruction_handler + db 'vpshrdq',73h + dw avx_q_instruction_3a_imm8_evex-instruction_handler + db 'vpshrdw',72h + dw avx_bw_instruction_3a_imm8_w1_evex-instruction_handler + db 'vpshufb',0 + dw avx_bw_instruction_38-instruction_handler + db 'vpshufd',70h + dw avx_single_source_d_instruction_imm8-instruction_handler + db 'vpsignb',8 + dw avx_pi_instruction_38_noevex-instruction_handler + db 'vpsignd',0Ah + dw avx_pi_instruction_38_noevex-instruction_handler + db 'vpsignw',9 + dw avx_pi_instruction_38_noevex-instruction_handler + db 'vpslldq',111b + dw avx_shift_dq_instruction-instruction_handler + db 'vpsllvd',47h + dw avx_d_instruction_38-instruction_handler + db 'vpsllvq',47h + dw avx_q_instruction_38_w1-instruction_handler + db 'vpsllvw',12h + dw avx_bw_instruction_38_w1_evex-instruction_handler + db 'vpsravd',46h + dw avx_d_instruction_38-instruction_handler + db 'vpsravq',46h + dw avx_q_instruction_38_w1_evex-instruction_handler + db 'vpsravw',11h + dw avx_bw_instruction_38_w1_evex-instruction_handler + db 'vpsrldq',011b + dw avx_shift_dq_instruction-instruction_handler + db 'vpsrlvd',45h + dw avx_d_instruction_38-instruction_handler + db 'vpsrlvq',45h + dw avx_q_instruction_38_w1-instruction_handler + db 'vpsrlvw',10h + dw avx_bw_instruction_38_w1_evex-instruction_handler + db 'vpsubsb',0E8h + dw avx_bw_instruction-instruction_handler + db 'vpsubsw',0E9h + dw avx_bw_instruction-instruction_handler + db 'vshufpd',0C6h + dw avx_pd_instruction_imm8-instruction_handler + db 'vshufps',0C6h + dw avx_ps_instruction_imm8-instruction_handler + db 'vsqrtpd',51h + dw avx_single_source_pd_instruction_er-instruction_handler + db 'vsqrtps',51h + dw avx_single_source_ps_instruction_er-instruction_handler + db 'vsqrtsd',51h + dw avx_sd_instruction_er-instruction_handler + db 'vsqrtss',51h + dw avx_ss_instruction_er-instruction_handler + db 'vtestpd',0Fh + dw avx_single_source_instruction_38_noevex-instruction_handler + db 'vtestps',0Eh + dw avx_single_source_instruction_38_noevex-instruction_handler + db 'xrstors',3 + dw xsaves_instruction-instruction_handler + db 'xsave64',100b + dw fxsave_instruction_64bit-instruction_handler +instructions_8: + db 'addsubpd',0D0h + dw sse_pd_instruction-instruction_handler + db 'addsubps',0D0h + dw cvtpd2dq_instruction-instruction_handler + db 'blendvpd',15h + dw sse4_instruction_66_38_xmm0-instruction_handler + db 'blendvps',14h + dw sse4_instruction_66_38_xmm0-instruction_handler + db 'cldemote',0 + dw cldemote_instruction-instruction_handler + db 'clrssbsy',6 + dw clrssbsy_instruction-instruction_handler + db 'cmpneqpd',4 + dw cmp_pd_instruction-instruction_handler + db 'cmpneqps',4 + dw cmp_ps_instruction-instruction_handler + db 'cmpneqsd',4 + dw cmp_sd_instruction-instruction_handler + db 'cmpneqss',4 + dw cmp_ss_instruction-instruction_handler + db 'cmpnlepd',6 + dw cmp_pd_instruction-instruction_handler + db 'cmpnleps',6 + dw cmp_ps_instruction-instruction_handler + db 'cmpnlesd',6 + dw cmp_sd_instruction-instruction_handler + db 'cmpnless',6 + dw cmp_ss_instruction-instruction_handler + db 'cmpnltpd',5 + dw cmp_pd_instruction-instruction_handler + db 'cmpnltps',5 + dw cmp_ps_instruction-instruction_handler + db 'cmpnltsd',5 + dw cmp_sd_instruction-instruction_handler + db 'cmpnltss',5 + dw cmp_ss_instruction-instruction_handler + db 'cmpordpd',7 + dw cmp_pd_instruction-instruction_handler + db 'cmpordps',7 + dw cmp_ps_instruction-instruction_handler + db 'cmpordsd',7 + dw cmp_sd_instruction-instruction_handler + db 'cmpordss',7 + dw cmp_ss_instruction-instruction_handler + db 'cvtdq2pd',0E6h + dw cvtdq2pd_instruction-instruction_handler + db 'cvtdq2ps',5Bh + dw sse_ps_instruction-instruction_handler + db 'cvtpd2dq',0E6h + dw cvtpd2dq_instruction-instruction_handler + db 'cvtpd2pi',2Dh + dw cvtpd2pi_instruction-instruction_handler + db 'cvtpd2ps',5Ah + dw sse_pd_instruction-instruction_handler + db 'cvtpi2pd',2Ah + dw cvtpi2pd_instruction-instruction_handler + db 'cvtpi2ps',2Ah + dw cvtpi2ps_instruction-instruction_handler + db 'cvtps2dq',5Bh + dw sse_pd_instruction-instruction_handler + db 'cvtps2pd',5Ah + dw cvtps2pd_instruction-instruction_handler + db 'cvtps2pi',2Dh + dw cvtps2pi_instruction-instruction_handler + db 'cvtsd2si',2Dh + dw cvtsd2si_instruction-instruction_handler + db 'cvtsd2ss',5Ah + dw sse_sd_instruction-instruction_handler + db 'cvtsi2sd',2Ah + dw cvtsi2sd_instruction-instruction_handler + db 'cvtsi2ss',2Ah + dw cvtsi2ss_instruction-instruction_handler + db 'cvtss2sd',5Ah + dw sse_ss_instruction-instruction_handler + db 'cvtss2si',2Dh + dw cvtss2si_instruction-instruction_handler + db 'fcmovnbe',0D0h + dw fcomi_instruction-instruction_handler + db 'fnstenvd',6 + dw fldenv_instruction_32bit-instruction_handler + db 'fnstenvw',6 + dw fldenv_instruction_16bit-instruction_handler + db 'fxsave64',0 + dw fxsave_instruction_64bit-instruction_handler + db 'insertps',21h + dw insertps_instruction-instruction_handler + db 'kortestb',98h + dw mask_instruction_single_source_b-instruction_handler + db 'kortestd',98h + dw mask_instruction_single_source_d-instruction_handler + db 'kortestq',98h + dw mask_instruction_single_source_q-instruction_handler + db 'kortestw',98h + dw mask_instruction_single_source_w-instruction_handler + db 'kshiftlb',32h + dw mask_shift_instruction_d-instruction_handler + db 'kshiftld',33h + dw mask_shift_instruction_d-instruction_handler + db 'kshiftlq',33h + dw mask_shift_instruction_q-instruction_handler + db 'kshiftlw',32h + dw mask_shift_instruction_q-instruction_handler + db 'kshiftrb',30h + dw mask_shift_instruction_d-instruction_handler + db 'kshiftrd',31h + dw mask_shift_instruction_d-instruction_handler + db 'kshiftrq',31h + dw mask_shift_instruction_q-instruction_handler + db 'kshiftrw',30h + dw mask_shift_instruction_q-instruction_handler + db 'kunpckbw',4Bh + dw mask_instruction_b-instruction_handler + db 'kunpckdq',4Bh + dw mask_instruction_q-instruction_handler + db 'kunpckwd',4Bh + dw mask_instruction_w-instruction_handler + db 'maskmovq',0 + dw maskmovq_instruction-instruction_handler + db 'monitorx',0FAh + dw monitor_instruction-instruction_handler + db 'movmskpd',0 + dw movmskpd_instruction-instruction_handler + db 'movmskps',0 + dw movmskps_instruction-instruction_handler + db 'movntdqa',2Ah + dw movntdqa_instruction-instruction_handler + db 'movshdup',16h + dw movshdup_instruction-instruction_handler + db 'movsldup',12h + dw movshdup_instruction-instruction_handler + db 'packssdw',6Bh + dw basic_mmx_instruction-instruction_handler + db 'packsswb',63h + dw basic_mmx_instruction-instruction_handler + db 'packusdw',2Bh + dw sse4_instruction_66_38-instruction_handler + db 'packuswb',67h + dw basic_mmx_instruction-instruction_handler + db 'pblendvb',10h + dw sse4_instruction_66_38_xmm0-instruction_handler + db 'pfrcpit1',0A6h + dw amd3dnow_instruction-instruction_handler + db 'pfrcpit2',0B6h + dw amd3dnow_instruction-instruction_handler + db 'pfrsqit1',0A7h + dw amd3dnow_instruction-instruction_handler + db 'pmovmskb',0D7h + dw pmovmskb_instruction-instruction_handler + db 'pmovsxbd',21h + dw pmovsxbd_instruction-instruction_handler + db 'pmovsxbq',22h + dw pmovsxbq_instruction-instruction_handler + db 'pmovsxbw',20h + dw pmovsxbw_instruction-instruction_handler + db 'pmovsxdq',25h + dw pmovsxdq_instruction-instruction_handler + db 'pmovsxwd',23h + dw pmovsxwd_instruction-instruction_handler + db 'pmovsxwq',24h + dw pmovsxwq_instruction-instruction_handler + db 'pmovzxbd',31h + dw pmovsxbd_instruction-instruction_handler + db 'pmovzxbq',32h + dw pmovsxbq_instruction-instruction_handler + db 'pmovzxbw',30h + dw pmovsxbw_instruction-instruction_handler + db 'pmovzxdq',35h + dw pmovsxdq_instruction-instruction_handler + db 'pmovzxwd',33h + dw pmovsxwd_instruction-instruction_handler + db 'pmovzxwq',34h + dw pmovsxwq_instruction-instruction_handler + db 'pmulhrsw',0Bh + dw ssse3_instruction-instruction_handler + db 'prefetch',0 + dw amd_prefetch_instruction-instruction_handler + db 'rdfsbase',0 + dw rdfsbase_instruction-instruction_handler + db 'rdgsbase',1 + dw rdfsbase_instruction-instruction_handler + db 'rstorssp',5 + dw rstorssp_instruction-instruction_handler + db 'setssbsy',0E8h + dw setssbsy_instruction-instruction_handler + db 'sha1msg1',0C9h + dw sse4_instruction_38-instruction_handler + db 'sha1msg2',0CAh + dw sse4_instruction_38-instruction_handler + db 'sysenter',34h + dw simple_extended_instruction-instruction_handler + db 'sysexitq',35h + dw simple_extended_instruction_64bit-instruction_handler + db 'umonitor',0 + dw umonitor_instruction-instruction_handler + db 'unpckhpd',15h + dw sse_pd_instruction-instruction_handler + db 'unpckhps',15h + dw sse_ps_instruction-instruction_handler + db 'unpcklpd',14h + dw sse_pd_instruction-instruction_handler + db 'unpcklps',14h + dw sse_ps_instruction-instruction_handler + db 'vblendpd',0Dh + dw avx_pi_instruction_3a_imm8_noevex-instruction_handler + db 'vblendps',0Ch + dw avx_pi_instruction_3a_imm8_noevex-instruction_handler + db 'vcmpeqpd',0 + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpeqps',0 + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpeqsd',0 + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpeqss',0 + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpgepd',0Dh + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpgeps',0Dh + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpgesd',0Dh + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpgess',0Dh + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpgtpd',0Eh + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpgtps',0Eh + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpgtsd',0Eh + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpgtss',0Eh + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmplepd',2 + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpleps',2 + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmplesd',2 + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpless',2 + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpltpd',1 + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpltps',1 + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpltsd',1 + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpltss',1 + dw avx_cmp_ss_instruction-instruction_handler + db 'vfmaddpd',69h + dw fma4_instruction_p-instruction_handler + db 'vfmaddps',68h + dw fma4_instruction_p-instruction_handler + db 'vfmaddsd',6Bh + dw fma4_instruction_sd-instruction_handler + db 'vfmaddss',6Ah + dw fma4_instruction_ss-instruction_handler + db 'vfmsubpd',6Dh + dw fma4_instruction_p-instruction_handler + db 'vfmsubps',6Ch + dw fma4_instruction_p-instruction_handler + db 'vfmsubsd',6Fh + dw fma4_instruction_sd-instruction_handler + db 'vfmsubss',6Eh + dw fma4_instruction_ss-instruction_handler + db 'vldmxcsr',10b + dw vstmxcsr_instruction-instruction_handler + db 'vmlaunch',0C2h + dw simple_instruction_0f_01-instruction_handler + db 'vmovddup',12h + dw avx_movddup_instruction-instruction_handler + db 'vmovdqu8',6Fh + dw avx512_movdqu8_instruction-instruction_handler + db 'vmovhlps',12h + dw avx_movhlps_instruction-instruction_handler + db 'vmovlhps',16h + dw avx_movhlps_instruction-instruction_handler + db 'vmovntdq',0E7h + dw avx_movntdq_instruction-instruction_handler + db 'vmovntpd',2Bh + dw avx_movntpd_instruction-instruction_handler + db 'vmovntps',2Bh + dw avx_movntps_instruction-instruction_handler + db 'vmpsadbw',42h + dw avx_pi_instruction_3a_imm8_noevex-instruction_handler + db 'vmresume',0C3h + dw simple_instruction_0f_01-instruction_handler + db 'vpaddusb',0DCh + dw avx_bw_instruction-instruction_handler + db 'vpaddusw',0DDh + dw avx_bw_instruction-instruction_handler + db 'vpalignr',0Fh + dw avx_pi_instruction_3a_imm8-instruction_handler + db 'vpblendd',2 + dw avx_pi_instruction_3a_imm8_noevex-instruction_handler + db 'vpblendw',0Eh + dw avx_pi_instruction_3a_imm8_noevex-instruction_handler + db 'vpcmpeqb',74h + dw avx_cmpeqb_instruction-instruction_handler + db 'vpcmpeqd',76h + dw avx_cmpeqd_instruction-instruction_handler + db 'vpcmpeqq',29h + dw avx_cmpeqq_instruction-instruction_handler + db 'vpcmpeqw',75h + dw avx_cmpeqb_instruction-instruction_handler + db 'vpcmpgtb',64h + dw avx_cmpeqb_instruction-instruction_handler + db 'vpcmpgtd',66h + dw avx_cmpeqd_instruction-instruction_handler + db 'vpcmpgtq',37h + dw avx_cmpeqq_instruction-instruction_handler + db 'vpcmpgtw',65h + dw avx_cmpeqb_instruction-instruction_handler + db 'vpcmpleb',2 + dw avx512_cmp_b_instruction-instruction_handler + db 'vpcmpled',2 + dw avx512_cmp_d_instruction-instruction_handler + db 'vpcmpleq',2 + dw avx512_cmp_q_instruction-instruction_handler + db 'vpcmplew',2 + dw avx512_cmp_w_instruction-instruction_handler + db 'vpcmpltb',1 + dw avx512_cmp_b_instruction-instruction_handler + db 'vpcmpltd',1 + dw avx512_cmp_d_instruction-instruction_handler + db 'vpcmpltq',1 + dw avx512_cmp_q_instruction-instruction_handler + db 'vpcmpltw',1 + dw avx512_cmp_w_instruction-instruction_handler + db 'vpcomeqb',4 + dw xop_pcom_b_instruction-instruction_handler + db 'vpcomeqd',4 + dw xop_pcom_d_instruction-instruction_handler + db 'vpcomeqq',4 + dw xop_pcom_q_instruction-instruction_handler + db 'vpcomeqw',4 + dw xop_pcom_w_instruction-instruction_handler + db 'vpcomgeb',3 + dw xop_pcom_b_instruction-instruction_handler + db 'vpcomged',3 + dw xop_pcom_d_instruction-instruction_handler + db 'vpcomgeq',3 + dw xop_pcom_q_instruction-instruction_handler + db 'vpcomgew',3 + dw xop_pcom_w_instruction-instruction_handler + db 'vpcomgtb',2 + dw xop_pcom_b_instruction-instruction_handler + db 'vpcomgtd',2 + dw xop_pcom_d_instruction-instruction_handler + db 'vpcomgtq',2 + dw xop_pcom_q_instruction-instruction_handler + db 'vpcomgtw',2 + dw xop_pcom_w_instruction-instruction_handler + db 'vpcomleb',1 + dw xop_pcom_b_instruction-instruction_handler + db 'vpcomled',1 + dw xop_pcom_d_instruction-instruction_handler + db 'vpcomleq',1 + dw xop_pcom_q_instruction-instruction_handler + db 'vpcomlew',1 + dw xop_pcom_w_instruction-instruction_handler + db 'vpcomltb',0 + dw xop_pcom_b_instruction-instruction_handler + db 'vpcomltd',0 + dw xop_pcom_d_instruction-instruction_handler + db 'vpcomltq',0 + dw xop_pcom_q_instruction-instruction_handler + db 'vpcomltw',0 + dw xop_pcom_w_instruction-instruction_handler + db 'vpdpbusd',50h + dw avx_d_instruction_38_evex-instruction_handler + db 'vpdpwssd',52h + dw avx_d_instruction_38_evex-instruction_handler + db 'vpermi2b',75h + dw avx_bw_instruction_38_evex-instruction_handler + db 'vpermi2d',76h + dw avx_d_instruction_38_evex-instruction_handler + db 'vpermi2q',76h + dw avx_q_instruction_38_evex-instruction_handler + db 'vpermi2w',75h + dw avx_bw_instruction_38_w1_evex-instruction_handler + db 'vpermt2b',7Dh + dw avx_bw_instruction_38_evex-instruction_handler + db 'vpermt2d',7Eh + dw avx_d_instruction_38_evex-instruction_handler + db 'vpermt2q',7Eh + dw avx_q_instruction_38_evex-instruction_handler + db 'vpermt2w',7Dh + dw avx_bw_instruction_38_w1_evex-instruction_handler + db 'vphaddbd',0C2h + dw xop_single_source_128bit_instruction-instruction_handler + db 'vphaddbq',0C3h + dw xop_single_source_128bit_instruction-instruction_handler + db 'vphaddbw',0C1h + dw xop_single_source_128bit_instruction-instruction_handler + db 'vphadddq',0CBh + dw xop_single_source_128bit_instruction-instruction_handler + db 'vphaddsw',3 + dw avx_pi_instruction_38_noevex-instruction_handler + db 'vphaddwd',0C6h + dw xop_single_source_128bit_instruction-instruction_handler + db 'vphaddwq',0C7h + dw xop_single_source_128bit_instruction-instruction_handler + db 'vphsubbw',0E1h + dw xop_single_source_128bit_instruction-instruction_handler + db 'vphsubdq',0E3h + dw xop_single_source_128bit_instruction-instruction_handler + db 'vphsubsw',7 + dw avx_pi_instruction_38_noevex-instruction_handler + db 'vphsubwd',0E2h + dw xop_single_source_128bit_instruction-instruction_handler + db 'vplzcntd',44h + dw avx_single_source_d_instruction_38_evex-instruction_handler + db 'vplzcntq',44h + dw avx_single_source_q_instruction_38_evex-instruction_handler + db 'vpmacsdd',9Eh + dw xop_triple_source_128bit_instruction-instruction_handler + db 'vpmacswd',96h + dw xop_triple_source_128bit_instruction-instruction_handler + db 'vpmacsww',95h + dw xop_triple_source_128bit_instruction-instruction_handler + db 'vpmaddwd',0F5h + dw avx_bw_instruction-instruction_handler + db 'vpmovb2m',29h + dw avx512_pmov_2m_instruction-instruction_handler + db 'vpmovd2m',39h + dw avx512_pmov_2m_instruction-instruction_handler + db 'vpmovm2b',28h + dw avx512_pmov_m2_instruction-instruction_handler + db 'vpmovm2d',38h + dw avx512_pmov_m2_instruction-instruction_handler + db 'vpmovm2q',38h + dw avx512_pmov_m2_instruction_w1-instruction_handler + db 'vpmovm2w',28h + dw avx512_pmov_m2_instruction_w1-instruction_handler + db 'vpmovq2m',39h + dw avx512_pmov_2m_instruction_w1-instruction_handler + db 'vpmovsdb',21h + dw avx512_pmovdb_instruction-instruction_handler + db 'vpmovsdw',23h + dw avx512_pmovwb_instruction-instruction_handler + db 'vpmovsqb',22h + dw avx512_pmovqb_instruction-instruction_handler + db 'vpmovsqd',25h + dw avx512_pmovwb_instruction-instruction_handler + db 'vpmovsqw',24h + dw avx512_pmovdb_instruction-instruction_handler + db 'vpmovswb',20h + dw avx512_pmovwb_instruction-instruction_handler + db 'vpmovw2m',29h + dw avx512_pmov_2m_instruction_w1-instruction_handler + db 'vpmulhuw',0E4h + dw avx_bw_instruction-instruction_handler + db 'vpmuludq',0F4h + dw avx_q_instruction-instruction_handler + db 'vpopcntb',54h + dw avx_single_source_d_instruction_38_evex-instruction_handler + db 'vpopcntd',55h + dw avx512_single_source_ps_instruction-instruction_handler + db 'vpopcntq',55h + dw avx512_single_source_pd_instruction-instruction_handler + db 'vpopcntw',54h + dw avx_single_source_d_instruction_38_evex_w1-instruction_handler + db 'vpshldvd',71h + dw avx_d_instruction_38_evex-instruction_handler + db 'vpshldvq',71h + dw avx_q_instruction_38_evex-instruction_handler + db 'vpshldvw',70h + dw avx_bw_instruction_38_w1_evex-instruction_handler + db 'vpshrdvd',73h + dw avx_d_instruction_38_evex-instruction_handler + db 'vpshrdvq',73h + dw avx_q_instruction_38_evex-instruction_handler + db 'vpshrdvw',72 + dw avx_bw_instruction_38_w1_evex-instruction_handler + db 'vpshufhw',0F3h + dw avx_pshuf_w_instruction-instruction_handler + db 'vpshuflw',0F2h + dw avx_pshuf_w_instruction-instruction_handler + db 'vpsubusb',0D8h + dw avx_bw_instruction-instruction_handler + db 'vpsubusw',0D9h + dw avx_bw_instruction-instruction_handler + db 'vptestmb',26h + dw avx512_ptestmb_instruction-instruction_handler + db 'vptestmd',27h + dw avx512_ptestmd_instruction-instruction_handler + db 'vptestmq',27h + dw avx512_ptestmq_instruction-instruction_handler + db 'vptestmw',26h + dw avx512_ptestmw_instruction-instruction_handler + db 'vrangepd',50h + dw avx512_pd_instruction_sae_imm8-instruction_handler + db 'vrangeps',50h + dw avx512_ps_instruction_sae_imm8-instruction_handler + db 'vrangesd',51h + dw avx512_sd_instruction_sae_imm8-instruction_handler + db 'vrangess',51h + dw avx512_ss_instruction_sae_imm8-instruction_handler + db 'vrcp14pd',4Ch + dw avx512_single_source_pd_instruction-instruction_handler + db 'vrcp14ps',4Ch + dw avx512_single_source_ps_instruction-instruction_handler + db 'vrcp14sd',4Dh + dw avx512_sd_instruction-instruction_handler + db 'vrcp14ss',4Dh + dw avx512_ss_instruction-instruction_handler + db 'vrcp28pd',0CAh + dw avx512_exp2pd_instruction-instruction_handler + db 'vrcp28ps',0CAh + dw avx512_exp2ps_instruction-instruction_handler + db 'vrcp28sd',0CBh + dw avx512_sd_instruction_sae-instruction_handler + db 'vrcp28ss',0CBh + dw avx512_ss_instruction_sae-instruction_handler + db 'vroundpd',9 + dw avx_single_source_instruction_3a_imm8_noevex-instruction_handler + db 'vroundps',8 + dw avx_single_source_instruction_3a_imm8_noevex-instruction_handler + db 'vroundsd',0Bh + dw avx_sd_instruction_3a_imm8_noevex-instruction_handler + db 'vroundss',0Ah + dw avx_ss_instruction_3a_imm8_noevex-instruction_handler + db 'vrsqrtps',52h + dw avx_single_source_ps_instruction_noevex-instruction_handler + db 'vrsqrtss',52h + dw avx_ss_instruction_noevex-instruction_handler + db 'vstmxcsr',11b + dw vstmxcsr_instruction-instruction_handler + db 'vucomisd',2Eh + dw avx_comisd_instruction-instruction_handler + db 'vucomiss',2Eh + dw avx_comiss_instruction-instruction_handler + db 'vzeroall',77h + dw vzeroall_instruction-instruction_handler + db 'wbnoinvd',9 + dw simple_extended_instruction_f3-instruction_handler + db 'wrfsbase',2 + dw rdfsbase_instruction-instruction_handler + db 'wrgsbase',3 + dw rdfsbase_instruction-instruction_handler + db 'xacquire',0F2h + dw prefix_instruction-instruction_handler + db 'xrelease',0F3h + dw prefix_instruction-instruction_handler + db 'xrstor64',101b + dw fxsave_instruction_64bit-instruction_handler + db 'xsavec64',4 + dw xsaves_instruction_64bit-instruction_handler + db 'xsaveopt',110b + dw fxsave_instruction-instruction_handler + db 'xsaves64',5 + dw xsaves_instruction_64bit-instruction_handler +instructions_9: + db 'cmpxchg8b',8 + dw cmpxchgx_instruction-instruction_handler + db 'cvttpd2dq',0E6h + dw sse_pd_instruction-instruction_handler + db 'cvttpd2pi',2Ch + dw cvtpd2pi_instruction-instruction_handler + db 'cvttps2dq',5Bh + dw movshdup_instruction-instruction_handler + db 'cvttps2pi',2Ch + dw cvtps2pi_instruction-instruction_handler + db 'cvttsd2si',2Ch + dw cvtsd2si_instruction-instruction_handler + db 'cvttss2si',2Ch + dw cvtss2si_instruction-instruction_handler + db 'extractps',17h + dw extractps_instruction-instruction_handler + db 'fxrstor64',1 + dw fxsave_instruction_64bit-instruction_handler + db 'gf2p8mulb',0CFh + dw sse4_instruction_66_38-instruction_handler + db 'movdir64b',0F8h + dw movdir64b_instruction-instruction_handler + db 'pclmulqdq',-1 + dw pclmulqdq_instruction-instruction_handler + db 'pcmpestri',61h + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'pcmpestrm',60h + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'pcmpistri',63h + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'pcmpistrm',62h + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'pmaddubsw',4 + dw ssse3_instruction-instruction_handler + db 'prefetchw',1 + dw amd_prefetch_instruction-instruction_handler + db 'punpckhbw',68h + dw basic_mmx_instruction-instruction_handler + db 'punpckhdq',6Ah + dw basic_mmx_instruction-instruction_handler + db 'punpckhwd',69h + dw basic_mmx_instruction-instruction_handler + db 'punpcklbw',60h + dw basic_mmx_instruction-instruction_handler + db 'punpckldq',62h + dw basic_mmx_instruction-instruction_handler + db 'punpcklwd',61h + dw basic_mmx_instruction-instruction_handler + db 'pvalidate',0FFh + dw simple_instruction_f2_0f_01-instruction_handler + db 'rmpadjust',0FEh + dw simple_instruction_f3_0f_01-instruction_handler + db 'rmpupdate',0FEh + dw simple_instruction_f2_0f_01-instruction_handler + db 'sha1nexte',0C8h + dw sse4_instruction_38-instruction_handler + db 'sha1rnds4',0CCh + dw sse4_instruction_3a_imm8-instruction_handler + db 'useavx256',0 + dw set_evex_mode-instruction_handler + db 'useavx512',1 + dw set_evex_mode-instruction_handler + db 'vaddsubpd',0D0h + dw avx_pd_instruction_noevex-instruction_handler + db 'vaddsubps',0D0h + dw avx_ps_instruction_noevex-instruction_handler + db 'vblendmpd',65h + dw avx_pd_instruction_38_evex-instruction_handler + db 'vblendmps',65h + dw avx_ps_instruction_66_38_evex-instruction_handler + db 'vblendvpd',4Bh + dw avx_triple_source_instruction_3a_noevex-instruction_handler + db 'vblendvps',4Ah + dw avx_triple_source_instruction_3a_noevex-instruction_handler + db 'vcmpneqpd',4 + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpneqps',4 + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpneqsd',4 + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpneqss',4 + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpngepd',9 + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpngeps',9 + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpngesd',9 + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpngess',9 + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpngtpd',0Ah + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpngtps',0Ah + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpngtsd',0Ah + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpngtss',0Ah + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpnlepd',6 + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpnleps',6 + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpnlesd',6 + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpnless',6 + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpnltpd',5 + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpnltps',5 + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpnltsd',5 + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpnltss',5 + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpordpd',7 + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpordps',7 + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpordsd',7 + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpordss',7 + dw avx_cmp_ss_instruction-instruction_handler + db 'vcvtdq2pd',0E6h + dw avx_cvtdq2pd_instruction-instruction_handler + db 'vcvtdq2ps',5Bh + dw avx_single_source_ps_instruction_er-instruction_handler + db 'vcvtpd2dq',0E6h + dw avx_cvtpd2dq_instruction-instruction_handler + db 'vcvtpd2ps',5Ah + dw avx_cvtpd2ps_instruction-instruction_handler + db 'vcvtpd2qq',7Bh + dw avx_single_source_pd_instruction_er_evex-instruction_handler + db 'vcvtph2ps',13h + dw avx_cvtph2ps_instruction-instruction_handler + db 'vcvtps2dq',5Bh + dw avx_cvtps2dq_instruction-instruction_handler + db 'vcvtps2pd',5Ah + dw avx_cvtps2pd_instruction-instruction_handler + db 'vcvtps2ph',1Dh + dw avx_cvtps2ph_instruction-instruction_handler + db 'vcvtps2qq',7Bh + dw avx_cvtps2qq_instruction-instruction_handler + db 'vcvtqq2pd',0E6h + dw avx_cvtqq2pd_instruction-instruction_handler + db 'vcvtqq2ps',5Bh + dw avx_cvtpd2udq_instruction-instruction_handler + db 'vcvtsd2si',2Dh + dw avx_cvtsd2si_instruction-instruction_handler + db 'vcvtsd2ss',5Ah + dw avx_sd_instruction_er-instruction_handler + db 'vcvtsi2sd',2Ah + dw avx_cvtsi2sd_instruction-instruction_handler + db 'vcvtsi2ss',2Ah + dw avx_cvtsi2ss_instruction-instruction_handler + db 'vcvtss2sd',5Ah + dw avx_ss_instruction_sae-instruction_handler + db 'vcvtss2si',2Dh + dw avx_cvtss2si_instruction-instruction_handler + db 'vdbpsadbw',42h + dw avx_bw_instruction_3a_imm8_evex-instruction_handler + db 'vexpandpd',88h + dw avx_single_source_q_instruction_38_evex-instruction_handler + db 'vexpandps',88h + dw avx_single_source_d_instruction_38_evex-instruction_handler + db 'vfnmaddpd',79h + dw fma4_instruction_p-instruction_handler + db 'vfnmaddps',78h + dw fma4_instruction_p-instruction_handler + db 'vfnmaddsd',7Bh + dw fma4_instruction_sd-instruction_handler + db 'vfnmaddss',7Ah + dw fma4_instruction_ss-instruction_handler + db 'vfnmsubpd',7Dh + dw fma4_instruction_p-instruction_handler + db 'vfnmsubps',7Ch + dw fma4_instruction_p-instruction_handler + db 'vfnmsubsd',7Fh + dw fma4_instruction_sd-instruction_handler + db 'vfnmsubss',7Eh + dw fma4_instruction_ss-instruction_handler + db 'vgetexppd',42h + dw avx512_single_source_pd_instruction_sae-instruction_handler + db 'vgetexpps',42h + dw avx512_single_source_ps_instruction_sae-instruction_handler + db 'vgetexpsd',43h + dw avx512_sd_instruction_sae-instruction_handler + db 'vgetexpss',43h + dw avx512_ss_instruction_sae-instruction_handler + db 'vinsertps',21h + dw avx_insertps_instruction-instruction_handler + db 'vmovdqa32',6Fh + dw avx512_movdqa32_instruction-instruction_handler + db 'vmovdqa64',6Fh + dw avx512_movdqa64_instruction-instruction_handler + db 'vmovdqu16',6Fh + dw avx512_movdqu16_instruction-instruction_handler + db 'vmovdqu32',6Fh + dw avx512_movdqu32_instruction-instruction_handler + db 'vmovdqu64',6Fh + dw avx512_movdqu64_instruction-instruction_handler + db 'vmovmskpd',0 + dw avx_movmskpd_instruction-instruction_handler + db 'vmovmskps',0 + dw avx_movmskps_instruction-instruction_handler + db 'vmovntdqa',2Ah + dw avx_movntdqa_instruction-instruction_handler + db 'vmovshdup',16h + dw avx_movshdup_instruction-instruction_handler + db 'vmovsldup',12h + dw avx_movshdup_instruction-instruction_handler + db 'vp4dpwssd',52h + dw avx512_4vnniw_instruction-instruction_handler + db 'vpackssdw',6Bh + dw avx_d_instruction-instruction_handler + db 'vpacksswb',63h + dw avx_bw_instruction-instruction_handler + db 'vpackusdw',2Bh + dw avx_d_instruction_38-instruction_handler + db 'vpackuswb',67h + dw avx_bw_instruction-instruction_handler + db 'vpblendmb',66h + dw avx_bw_instruction_38_evex-instruction_handler + db 'vpblendmd',64h + dw avx_d_instruction_38_evex-instruction_handler + db 'vpblendmq',64h + dw avx_q_instruction_38_evex-instruction_handler + db 'vpblendmw',66h + dw avx_bw_instruction_38_w1_evex-instruction_handler + db 'vpblendvb',4Ch + dw avx_triple_source_instruction_3a_noevex-instruction_handler + db 'vpcmpleub',2 + dw avx512_cmp_ub_instruction-instruction_handler + db 'vpcmpleud',2 + dw avx512_cmp_ud_instruction-instruction_handler + db 'vpcmpleuq',2 + dw avx512_cmp_uq_instruction-instruction_handler + db 'vpcmpleuw',2 + dw avx512_cmp_uw_instruction-instruction_handler + db 'vpcmpltub',1 + dw avx512_cmp_ub_instruction-instruction_handler + db 'vpcmpltud',1 + dw avx512_cmp_ud_instruction-instruction_handler + db 'vpcmpltuq',1 + dw avx512_cmp_uq_instruction-instruction_handler + db 'vpcmpltuw',1 + dw avx512_cmp_uw_instruction-instruction_handler + db 'vpcmpneqb',4 + dw avx512_cmp_b_instruction-instruction_handler + db 'vpcmpneqd',4 + dw avx512_cmp_d_instruction-instruction_handler + db 'vpcmpneqq',4 + dw avx512_cmp_q_instruction-instruction_handler + db 'vpcmpneqw',4 + dw avx512_cmp_b_instruction-instruction_handler + db 'vpcmpnleb',6 + dw avx512_cmp_b_instruction-instruction_handler + db 'vpcmpnled',6 + dw avx512_cmp_d_instruction-instruction_handler + db 'vpcmpnleq',6 + dw avx512_cmp_q_instruction-instruction_handler + db 'vpcmpnlew',6 + dw avx512_cmp_b_instruction-instruction_handler + db 'vpcmpnltb',5 + dw avx512_cmp_b_instruction-instruction_handler + db 'vpcmpnltd',5 + dw avx512_cmp_d_instruction-instruction_handler + db 'vpcmpnltq',5 + dw avx512_cmp_q_instruction-instruction_handler + db 'vpcmpnltw',5 + dw avx512_cmp_b_instruction-instruction_handler + db 'vpcomequb',4 + dw xop_pcom_ub_instruction-instruction_handler + db 'vpcomequd',4 + dw xop_pcom_ud_instruction-instruction_handler + db 'vpcomequq',4 + dw xop_pcom_uq_instruction-instruction_handler + db 'vpcomequw',4 + dw xop_pcom_uw_instruction-instruction_handler + db 'vpcomgeub',3 + dw xop_pcom_ub_instruction-instruction_handler + db 'vpcomgeud',3 + dw xop_pcom_ud_instruction-instruction_handler + db 'vpcomgeuq',3 + dw xop_pcom_uq_instruction-instruction_handler + db 'vpcomgeuw',3 + dw xop_pcom_uw_instruction-instruction_handler + db 'vpcomgtub',2 + dw xop_pcom_ub_instruction-instruction_handler + db 'vpcomgtud',2 + dw xop_pcom_ud_instruction-instruction_handler + db 'vpcomgtuq',2 + dw xop_pcom_uq_instruction-instruction_handler + db 'vpcomgtuw',2 + dw xop_pcom_uw_instruction-instruction_handler + db 'vpcomleub',1 + dw xop_pcom_ub_instruction-instruction_handler + db 'vpcomleud',1 + dw xop_pcom_ud_instruction-instruction_handler + db 'vpcomleuq',1 + dw xop_pcom_uq_instruction-instruction_handler + db 'vpcomleuw',1 + dw xop_pcom_uw_instruction-instruction_handler + db 'vpcomltub',0 + dw xop_pcom_ub_instruction-instruction_handler + db 'vpcomltud',0 + dw xop_pcom_ud_instruction-instruction_handler + db 'vpcomltuq',0 + dw xop_pcom_uq_instruction-instruction_handler + db 'vpcomltuw',0 + dw xop_pcom_uw_instruction-instruction_handler + db 'vpcomneqb',5 + dw xop_pcom_b_instruction-instruction_handler + db 'vpcomneqd',5 + dw xop_pcom_d_instruction-instruction_handler + db 'vpcomneqq',5 + dw xop_pcom_q_instruction-instruction_handler + db 'vpcomneqw',5 + dw xop_pcom_w_instruction-instruction_handler + db 'vpdpbusds',51h + dw avx_d_instruction_38_evex-instruction_handler + db 'vpdpwssds',53h + dw avx_d_instruction_38_evex-instruction_handler + db 'vpermi2pd',77h + dw avx_q_instruction_38_evex-instruction_handler + db 'vpermi2ps',77h + dw avx_d_instruction_38_evex-instruction_handler + db 'vpermilpd',5 + dw avx_permilpd_instruction-instruction_handler + db 'vpermilps',4 + dw avx_permilps_instruction-instruction_handler + db 'vpermt2pd',7Fh + dw avx_q_instruction_38_evex-instruction_handler + db 'vpermt2ps',7Fh + dw avx_d_instruction_38_evex-instruction_handler + db 'vpexpandb',62h + dw avx_single_source_d_instruction_38_evex-instruction_handler + db 'vpexpandd',89h + dw avx_single_source_d_instruction_38_evex-instruction_handler + db 'vpexpandq',89h + dw avx_single_source_q_instruction_38_evex-instruction_handler + db 'vpexpandw',62h + dw avx_single_source_q_instruction_38_evex-instruction_handler + db 'vphaddubd',0D2h + dw xop_single_source_128bit_instruction-instruction_handler + db 'vphaddubq',0D3h + dw xop_single_source_128bit_instruction-instruction_handler + db 'vphaddubw',0D1h + dw xop_single_source_128bit_instruction-instruction_handler + db 'vphaddudq',0DBh + dw xop_single_source_128bit_instruction-instruction_handler + db 'vphadduwd',0D6h + dw xop_single_source_128bit_instruction-instruction_handler + db 'vphadduwq',0D7h + dw xop_single_source_128bit_instruction-instruction_handler + db 'vpmacsdqh',9Fh + dw xop_triple_source_128bit_instruction-instruction_handler + db 'vpmacsdql',97h + dw xop_triple_source_128bit_instruction-instruction_handler + db 'vpmacssdd',8Eh + dw xop_triple_source_128bit_instruction-instruction_handler + db 'vpmacsswd',86h + dw xop_triple_source_128bit_instruction-instruction_handler + db 'vpmacssww',85h + dw xop_triple_source_128bit_instruction-instruction_handler + db 'vpmadcswd',0B6h + dw xop_triple_source_128bit_instruction-instruction_handler + db 'vpmovmskb',0D7h + dw avx_pmovmskb_instruction-instruction_handler + db 'vpmovsxbd',21h + dw avx_pmovsxbd_instruction-instruction_handler + db 'vpmovsxbq',22h + dw avx_pmovsxbq_instruction-instruction_handler + db 'vpmovsxbw',20h + dw avx_pmovsxbw_instruction-instruction_handler + db 'vpmovsxdq',25h + dw avx_pmovsxbw_instruction-instruction_handler + db 'vpmovsxwd',23h + dw avx_pmovsxbw_instruction-instruction_handler + db 'vpmovsxwq',24h + dw avx_pmovsxbd_instruction-instruction_handler + db 'vpmovusdb',11h + dw avx512_pmovdb_instruction-instruction_handler + db 'vpmovusdw',13h + dw avx512_pmovwb_instruction-instruction_handler + db 'vpmovusqb',12h + dw avx512_pmovqb_instruction-instruction_handler + db 'vpmovusqd',15h + dw avx512_pmovwb_instruction-instruction_handler + db 'vpmovusqw',14h + dw avx512_pmovdb_instruction-instruction_handler + db 'vpmovuswb',10h + dw avx512_pmovwb_instruction-instruction_handler + db 'vpmovzxbd',31h + dw avx_pmovsxbd_instruction-instruction_handler + db 'vpmovzxbq',32h + dw avx_pmovsxbq_instruction-instruction_handler + db 'vpmovzxbw',30h + dw avx_pmovsxbw_instruction-instruction_handler + db 'vpmovzxdq',35h + dw avx_pmovsxbw_instruction-instruction_handler + db 'vpmovzxwd',33h + dw avx_pmovsxbw_instruction-instruction_handler + db 'vpmovzxwq',34h + dw avx_pmovsxbd_instruction-instruction_handler + db 'vpmulhrsw',0Bh + dw avx_bw_instruction_38-instruction_handler + db 'vptestnmb',26h + dw avx512_ptestnmb_instruction-instruction_handler + db 'vptestnmd',27h + dw avx512_ptestnmd_instruction-instruction_handler + db 'vptestnmq',27h + dw avx512_ptestnmq_instruction-instruction_handler + db 'vptestnmw',26h + dw avx512_ptestnmw_instruction-instruction_handler + db 'vreducepd',56h + dw avx512_single_source_pd_instruction_sae_imm8-instruction_handler + db 'vreduceps',56h + dw avx512_single_source_ps_instruction_sae_imm8-instruction_handler + db 'vreducesd',57h + dw avx512_sd_instruction_sae_imm8-instruction_handler + db 'vreducess',57h + dw avx512_ss_instruction_sae_imm8-instruction_handler + db 'vscalefpd',2Ch + dw avx512_pd_instruction_er-instruction_handler + db 'vscalefps',2Ch + dw avx512_ps_instruction_er-instruction_handler + db 'vscalefsd',2Dh + dw avx512_sd_instruction_er-instruction_handler + db 'vscalefss',2Dh + dw avx512_ss_instruction_er-instruction_handler + db 'vunpckhpd',15h + dw avx_pd_instruction-instruction_handler + db 'vunpckhps',15h + dw avx_ps_instruction-instruction_handler + db 'vunpcklpd',14h + dw avx_pd_instruction-instruction_handler + db 'vunpcklps',14h + dw avx_ps_instruction-instruction_handler + db 'xrstors64',3 + dw xsaves_instruction_64bit-instruction_handler +instructions_10: + db 'aesdeclast',0DFh + dw sse4_instruction_66_38-instruction_handler + db 'aesenclast',0DDh + dw sse4_instruction_66_38-instruction_handler + db 'clflushopt',7 + dw clflushopt_instruction-instruction_handler + db 'cmpunordpd',3 + dw cmp_pd_instruction-instruction_handler + db 'cmpunordps',3 + dw cmp_ps_instruction-instruction_handler + db 'cmpunordsd',3 + dw cmp_sd_instruction-instruction_handler + db 'cmpunordss',3 + dw cmp_ss_instruction-instruction_handler + db 'cmpxchg16b',16 + dw cmpxchgx_instruction-instruction_handler + db 'loadall286',5 + dw simple_extended_instruction-instruction_handler + db 'loadall386',7 + dw simple_extended_instruction-instruction_handler + db 'maskmovdqu',0 + dw maskmovdqu_instruction-instruction_handler + db 'phminposuw',41h + dw sse4_instruction_66_38-instruction_handler + db 'prefetcht0',1 + dw prefetch_instruction-instruction_handler + db 'prefetcht1',2 + dw prefetch_instruction-instruction_handler + db 'prefetcht2',3 + dw prefetch_instruction-instruction_handler + db 'punpckhqdq',6Dh + dw sse_pd_instruction-instruction_handler + db 'punpcklqdq',6Ch + dw sse_pd_instruction-instruction_handler + db 'sha256msg1',0CCh + dw sse4_instruction_38-instruction_handler + db 'sha256msg2',0CDh + dw sse4_instruction_38-instruction_handler + db 'vcmptruepd',0Fh + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmptrueps',0Fh + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmptruesd',0Fh + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmptruess',0Fh + dw avx_cmp_ss_instruction-instruction_handler + db 'vcvtpd2udq',79h + dw avx_cvtpd2udq_instruction-instruction_handler + db 'vcvtpd2uqq',79h + dw avx_single_source_pd_instruction_er_evex-instruction_handler + db 'vcvtps2udq',79h + dw avx_single_source_ps_instruction_er_evex-instruction_handler + db 'vcvtps2uqq',79h + dw avx_cvtps2qq_instruction-instruction_handler + db 'vcvtsd2usi',79h + dw avx_cvtsd2usi_instruction-instruction_handler + db 'vcvtss2usi',79h + dw avx_cvtss2usi_instruction-instruction_handler + db 'vcvttpd2dq',0E6h + dw avx_cvttpd2dq_instruction-instruction_handler + db 'vcvttpd2qq',7Ah + dw avx_single_source_pd_instruction_sae_evex-instruction_handler + db 'vcvttps2dq',5Bh + dw avx_cvttps2dq_instruction-instruction_handler + db 'vcvttps2qq',7Ah + dw avx_cvttps2qq_instruction-instruction_handler + db 'vcvttsd2si',2Ch + dw avx_cvttsd2si_instruction-instruction_handler + db 'vcvttss2si',2Ch + dw avx_cvttss2si_instruction-instruction_handler + db 'vcvtudq2pd',7Ah + dw avx_cvtudq2pd_instruction-instruction_handler + db 'vcvtudq2ps',7Ah + dw avx_cvtudq2ps_instruction-instruction_handler + db 'vcvtuqq2pd',7Ah + dw avx_cvtqq2pd_instruction-instruction_handler + db 'vcvtuqq2ps',7Ah + dw avx_cvtuqq2ps_instruction-instruction_handler + db 'vcvtusi2sd',7Bh + dw avx_cvtusi2sd_instruction-instruction_handler + db 'vcvtusi2ss',7Bh + dw avx_cvtusi2ss_instruction-instruction_handler + db 'vextractps',17h + dw avx_extract_d_instruction-instruction_handler + db 'vfpclasspd',66h + dw avx512_fpclasspd_instruction-instruction_handler + db 'vfpclassps',66h + dw avx512_fpclassps_instruction-instruction_handler + db 'vfpclasssd',67h + dw avx512_fpclasssd_instruction-instruction_handler + db 'vfpclassss',67h + dw avx512_fpclassss_instruction-instruction_handler + db 'vgatherdpd',92h + dw gather_pd_instruction-instruction_handler + db 'vgatherdps',92h + dw gather_ps_instruction-instruction_handler + db 'vgatherqpd',93h + dw gather_pd_instruction-instruction_handler + db 'vgatherqps',93h + dw gather_ps_instruction-instruction_handler + db 'vgetmantpd',26h + dw avx512_single_source_pd_instruction_sae_imm8-instruction_handler + db 'vgetmantps',26h + dw avx512_single_source_ps_instruction_sae_imm8-instruction_handler + db 'vgetmantsd',27h + dw avx512_sd_instruction_sae_imm8-instruction_handler + db 'vgetmantss',27h + dw avx512_ss_instruction_sae_imm8-instruction_handler + db 'vgf2p8mulb',0CFh + dw avx_bw_instruction_38-instruction_handler + db 'vmaskmovpd',2Dh + dw avx_maskmov_instruction-instruction_handler + db 'vmaskmovps',2Ch + dw avx_maskmov_instruction-instruction_handler + db 'vp4dpwssds',53h + dw avx512_4vnniw_instruction-instruction_handler + db 'vpclmulqdq',-1 + dw avx_pclmulqdq_instruction-instruction_handler + db 'vpcmpestri',61h + dw avx_single_source_128bit_instruction_3a_imm8_noevex-instruction_handler + db 'vpcmpestrm',60h + dw avx_single_source_128bit_instruction_3a_imm8_noevex-instruction_handler + db 'vpcmpistri',63h + dw avx_single_source_128bit_instruction_3a_imm8_noevex-instruction_handler + db 'vpcmpistrm',62h + dw avx_single_source_128bit_instruction_3a_imm8_noevex-instruction_handler + db 'vpcmpnequb',4 + dw avx512_cmp_ub_instruction-instruction_handler + db 'vpcmpnequd',4 + dw avx512_cmp_ud_instruction-instruction_handler + db 'vpcmpnequq',4 + dw avx512_cmp_uq_instruction-instruction_handler + db 'vpcmpnequw',4 + dw avx512_cmp_uw_instruction-instruction_handler + db 'vpcmpnleub',6 + dw avx512_cmp_ub_instruction-instruction_handler + db 'vpcmpnleud',6 + dw avx512_cmp_ud_instruction-instruction_handler + db 'vpcmpnleuq',6 + dw avx512_cmp_uq_instruction-instruction_handler + db 'vpcmpnleuw',6 + dw avx512_cmp_uw_instruction-instruction_handler + db 'vpcmpnltub',5 + dw avx512_cmp_ub_instruction-instruction_handler + db 'vpcmpnltud',5 + dw avx512_cmp_ud_instruction-instruction_handler + db 'vpcmpnltuq',5 + dw avx512_cmp_uq_instruction-instruction_handler + db 'vpcmpnltuw',5 + dw avx512_cmp_uw_instruction-instruction_handler + db 'vpcomnequb',5 + dw xop_pcom_ub_instruction-instruction_handler + db 'vpcomnequd',5 + dw xop_pcom_ud_instruction-instruction_handler + db 'vpcomnequq',5 + dw xop_pcom_uq_instruction-instruction_handler + db 'vpcomnequw',5 + dw xop_pcom_uw_instruction-instruction_handler + db 'vpcomtrueb',7 + dw xop_pcom_b_instruction-instruction_handler + db 'vpcomtrued',7 + dw xop_pcom_d_instruction-instruction_handler + db 'vpcomtrueq',7 + dw xop_pcom_q_instruction-instruction_handler + db 'vpcomtruew',7 + dw xop_pcom_w_instruction-instruction_handler + db 'vperm2f128',6 + dw avx_perm2f128_instruction-instruction_handler + db 'vperm2i128',46h + dw avx_perm2f128_instruction-instruction_handler + db 'vpermil2pd',49h + dw vpermil2_instruction-instruction_handler + db 'vpermil2ps',48h + dw vpermil2_instruction-instruction_handler + db 'vpgatherdd',90h + dw gather_ps_instruction-instruction_handler + db 'vpgatherdq',90h + dw gather_pd_instruction-instruction_handler + db 'vpgatherqd',91h + dw gather_ps_instruction-instruction_handler + db 'vpgatherqq',91h + dw gather_pd_instruction-instruction_handler + db 'vpmacssdqh',8Fh + dw xop_triple_source_128bit_instruction-instruction_handler + db 'vpmacssdql',87h + dw xop_triple_source_128bit_instruction-instruction_handler + db 'vpmadcsswd',0A6h + dw xop_triple_source_128bit_instruction-instruction_handler + db 'vpmaddubsw',4 + dw avx_bw_instruction_38-instruction_handler + db 'vpmaskmovd',8Ch + dw avx_maskmov_instruction-instruction_handler + db 'vpmaskmovq',8Ch + dw avx_maskmov_w1_instruction-instruction_handler + db 'vpternlogd',25h + dw avx_d_instruction_3a_imm8_evex-instruction_handler + db 'vpternlogq',25h + dw avx_q_instruction_3a_imm8_evex-instruction_handler + db 'vpunpckhbw',68h + dw avx_bw_instruction-instruction_handler + db 'vpunpckhdq',6Ah + dw avx_d_instruction-instruction_handler + db 'vpunpckhwd',69h + dw avx_bw_instruction-instruction_handler + db 'vpunpcklbw',60h + dw avx_bw_instruction-instruction_handler + db 'vpunpckldq',62h + dw avx_d_instruction-instruction_handler + db 'vpunpcklwd',61h + dw avx_bw_instruction-instruction_handler + db 'vrsqrt14pd',4Eh + dw avx512_single_source_pd_instruction-instruction_handler + db 'vrsqrt14ps',4Eh + dw avx512_single_source_ps_instruction-instruction_handler + db 'vrsqrt14sd',4Fh + dw avx512_sd_instruction-instruction_handler + db 'vrsqrt14ss',4Fh + dw avx512_ss_instruction-instruction_handler + db 'vrsqrt28pd',0CCh + dw avx512_exp2pd_instruction-instruction_handler + db 'vrsqrt28ps',0CCh + dw avx512_exp2ps_instruction-instruction_handler + db 'vrsqrt28sd',0CDh + dw avx512_sd_instruction_sae-instruction_handler + db 'vrsqrt28ss',0CDh + dw avx512_ss_instruction_sae-instruction_handler + db 'vshuff32x4',23h + dw avx512_shuf_d_instruction-instruction_handler + db 'vshuff64x2',23h + dw avx512_shuf_q_instruction-instruction_handler + db 'vshufi32x4',43h + dw avx512_shuf_d_instruction-instruction_handler + db 'vshufi64x2',43h + dw avx512_shuf_q_instruction-instruction_handler + db 'vzeroupper',77h + dw vzeroupper_instruction-instruction_handler + db 'xsaveopt64',110b + dw fxsave_instruction_64bit-instruction_handler +instructions_11: + db 'pclmulhqhdq',10001b + dw pclmulqdq_instruction-instruction_handler + db 'pclmullqhdq',10000b + dw pclmulqdq_instruction-instruction_handler + db 'prefetchnta',0 + dw prefetch_instruction-instruction_handler + db 'prefetchwt1',2 + dw amd_prefetch_instruction-instruction_handler + db 'saveprevssp',0EAh + dw setssbsy_instruction-instruction_handler + db 'sha256rnds2',0CBh + dw sse4_instruction_38_xmm0-instruction_handler + db 'vaesdeclast',0DFh + dw avx_instruction_38_nomask-instruction_handler + db 'vaesenclast',0DDh + dw avx_instruction_38_nomask-instruction_handler + db 'vcmpeq_ospd',10h + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpeq_osps',10h + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpeq_ossd',10h + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpeq_osss',10h + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpeq_uqpd',8 + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpeq_uqps',8 + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpeq_uqsd',8 + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpeq_uqss',8 + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpeq_uspd',18h + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpeq_usps',18h + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpeq_ussd',18h + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpeq_usss',18h + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpfalsepd',0Bh + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpfalseps',0Bh + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpfalsesd',0Bh + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpfalsess',0Bh + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpge_oqpd',1Dh + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpge_oqps',1Dh + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpge_oqsd',1Dh + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpge_oqss',1Dh + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpgt_oqpd',1Eh + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpgt_oqps',1Eh + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpgt_oqsd',1Eh + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpgt_oqss',1Eh + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmple_oqpd',12h + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmple_oqps',12h + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmple_oqsd',12h + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmple_oqss',12h + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmplt_oqpd',11h + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmplt_oqps',11h + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmplt_oqsd',11h + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmplt_oqss',11h + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpord_spd',17h + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpord_sps',17h + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpord_ssd',17h + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpord_sss',17h + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpunordpd',3 + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpunordps',3 + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpunordsd',3 + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpunordss',3 + dw avx_cmp_ss_instruction-instruction_handler + db 'vcompresspd',8Ah + dw avx_compress_q_instruction-instruction_handler + db 'vcompressps',8Ah + dw avx_compress_d_instruction-instruction_handler + db 'vcvttpd2udq',78h + dw avx_cvttpd2udq_instruction-instruction_handler + db 'vcvttpd2uqq',78h + dw avx_single_source_pd_instruction_sae_evex-instruction_handler + db 'vcvttps2udq',78h + dw avx_cvttps2udq_instruction-instruction_handler + db 'vcvttps2uqq',78h + dw avx_cvttps2qq_instruction-instruction_handler + db 'vcvttsd2usi',78h + dw avx_cvttsd2usi_instruction-instruction_handler + db 'vcvttss2usi',78h + dw avx_cvttss2usi_instruction-instruction_handler + db 'vfixupimmpd',54h + dw avx512_pd_instruction_sae_imm8-instruction_handler + db 'vfixupimmps',54h + dw avx512_ps_instruction_sae_imm8-instruction_handler + db 'vfixupimmsd',55h + dw avx512_sd_instruction_sae_imm8-instruction_handler + db 'vfixupimmss',55h + dw avx512_ss_instruction_sae_imm8-instruction_handler + db 'vfmadd132pd',98h + dw fma_instruction_pd-instruction_handler + db 'vfmadd132ps',98h + dw fma_instruction_ps-instruction_handler + db 'vfmadd132sd',99h + dw fma_instruction_sd-instruction_handler + db 'vfmadd132ss',99h + dw fma_instruction_ss-instruction_handler + db 'vfmadd213pd',0A8h + dw fma_instruction_pd-instruction_handler + db 'vfmadd213ps',0A8h + dw fma_instruction_ps-instruction_handler + db 'vfmadd213sd',0A9h + dw fma_instruction_sd-instruction_handler + db 'vfmadd213ss',0A9h + dw fma_instruction_ss-instruction_handler + db 'vfmadd231pd',0B8h + dw fma_instruction_pd-instruction_handler + db 'vfmadd231ps',0B8h + dw fma_instruction_ps-instruction_handler + db 'vfmadd231sd',0B9h + dw fma_instruction_sd-instruction_handler + db 'vfmadd231ss',0B9h + dw fma_instruction_ss-instruction_handler + db 'vfmaddsubpd',5Dh + dw fma4_instruction_p-instruction_handler + db 'vfmaddsubps',5Ch + dw fma4_instruction_p-instruction_handler + db 'vfmsub132pd',9Ah + dw fma_instruction_pd-instruction_handler + db 'vfmsub132ps',9Ah + dw fma_instruction_ps-instruction_handler + db 'vfmsub132sd',9Bh + dw fma_instruction_sd-instruction_handler + db 'vfmsub132ss',9Bh + dw fma_instruction_ss-instruction_handler + db 'vfmsub213pd',0AAh + dw fma_instruction_pd-instruction_handler + db 'vfmsub213ps',0AAh + dw fma_instruction_ps-instruction_handler + db 'vfmsub213sd',0ABh + dw fma_instruction_sd-instruction_handler + db 'vfmsub213ss',0ABh + dw fma_instruction_ss-instruction_handler + db 'vfmsub231pd',0BAh + dw fma_instruction_pd-instruction_handler + db 'vfmsub231ps',0BAh + dw fma_instruction_ps-instruction_handler + db 'vfmsub231sd',0BBh + dw fma_instruction_sd-instruction_handler + db 'vfmsub231ss',0BBh + dw fma_instruction_ss-instruction_handler + db 'vfmsubaddpd',5Fh + dw fma4_instruction_p-instruction_handler + db 'vfmsubaddps',5Eh + dw fma4_instruction_p-instruction_handler + db 'vinsertf128',18h + dw avx_insertf128_instruction-instruction_handler + db 'vinserti128',38h + dw avx_insertf128_instruction-instruction_handler + db 'vmaskmovdqu',0 + dw avx_maskmovdqu_instruction-instruction_handler + db 'vpcomfalseb',6 + dw xop_pcom_b_instruction-instruction_handler + db 'vpcomfalsed',6 + dw xop_pcom_d_instruction-instruction_handler + db 'vpcomfalseq',6 + dw xop_pcom_q_instruction-instruction_handler + db 'vpcomfalsew',6 + dw xop_pcom_w_instruction-instruction_handler + db 'vpcompressb',63h + dw avx_compress_d_instruction-instruction_handler + db 'vpcompressd',8Bh + dw avx_compress_d_instruction-instruction_handler + db 'vpcompressq',8Bh + dw avx_compress_q_instruction-instruction_handler + db 'vpcompressw',63h + dw avx_compress_q_instruction-instruction_handler + db 'vpcomtrueub',7 + dw xop_pcom_ub_instruction-instruction_handler + db 'vpcomtrueud',7 + dw xop_pcom_ud_instruction-instruction_handler + db 'vpcomtrueuq',7 + dw xop_pcom_uq_instruction-instruction_handler + db 'vpcomtrueuw',7 + dw xop_pcom_uw_instruction-instruction_handler + db 'vpconflictd',0C4h + dw avx_single_source_d_instruction_38_evex-instruction_handler + db 'vpconflictq',0C4h + dw avx_single_source_q_instruction_38_evex-instruction_handler + db 'vphminposuw',41h + dw avx_single_source_instruction_38_noevex-instruction_handler + db 'vpmadd52huq',0B5h + dw avx_q_instruction_38_evex-instruction_handler + db 'vpmadd52luq',0B4h + dw avx_q_instruction_38_evex-instruction_handler + db 'vpscatterdd',0A0h + dw scatter_ps_instruction-instruction_handler + db 'vpscatterdq',0A0h + dw scatter_pd_instruction-instruction_handler + db 'vpscatterqd',0A1h + dw scatter_ps_instruction-instruction_handler + db 'vpscatterqq',0A1h + dw scatter_pd_instruction-instruction_handler + db 'vpunpckhqdq',6Dh + dw avx_q_instruction-instruction_handler + db 'vpunpcklqdq',6Ch + dw avx_q_instruction-instruction_handler + db 'vrndscalepd',9 + dw avx512_single_source_pd_instruction_sae_imm8-instruction_handler + db 'vrndscaleps',8 + dw avx512_single_source_ps_instruction_sae_imm8-instruction_handler + db 'vrndscalesd',0Bh + dw avx512_sd_instruction_sae_imm8-instruction_handler + db 'vrndscaless',0Ah + dw avx512_ss_instruction_sae_imm8-instruction_handler + db 'vscatterdpd',0A2h + dw scatter_pd_instruction-instruction_handler + db 'vscatterdps',0A2h + dw scatter_ps_instruction-instruction_handler + db 'vscatterqpd',0A3h + dw scatter_pd_instruction-instruction_handler + db 'vscatterqps',0A3h + dw scatter_ps_instruction-instruction_handler +instructions_12: + db 'pclmulhqhqdq',10001b + dw pclmulqdq_instruction-instruction_handler + db 'pclmulhqlqdq',1 + dw pclmulqdq_instruction-instruction_handler + db 'pclmullqhqdq',10000b + dw pclmulqdq_instruction-instruction_handler + db 'pclmullqlqdq',0 + dw pclmulqdq_instruction-instruction_handler + db 'vbroadcastsd',19h + dw avx_broadcastsd_instruction-instruction_handler + db 'vbroadcastss',18h + dw avx_broadcastss_instruction-instruction_handler + db 'vcmpneq_oqpd',0Ch + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpneq_oqps',0Ch + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpneq_oqsd',0Ch + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpneq_oqss',0Ch + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpneq_ospd',1Ch + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpneq_osps',1Ch + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpneq_ossd',1Ch + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpneq_osss',1Ch + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpneq_uspd',14h + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpneq_usps',14h + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpneq_ussd',14h + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpneq_usss',14h + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpnge_uqpd',19h + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpnge_uqps',19h + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpnge_uqsd',19h + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpnge_uqss',19h + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpngt_uqpd',1Ah + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpngt_uqps',1Ah + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpngt_uqsd',1Ah + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpngt_uqss',1Ah + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpnle_uqpd',16h + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpnle_uqps',16h + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpnle_uqsd',16h + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpnle_uqss',16h + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpnlt_uqpd',15h + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpnlt_uqps',15h + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpnlt_uqsd',15h + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpnlt_uqss',15h + dw avx_cmp_ss_instruction-instruction_handler + db 'vextractf128',19h + dw avx_extractf128_instruction-instruction_handler + db 'vextracti128',39h + dw avx_extractf128_instruction-instruction_handler + db 'vfnmadd132pd',9Ch + dw fma_instruction_pd-instruction_handler + db 'vfnmadd132ps',9Ch + dw fma_instruction_ps-instruction_handler + db 'vfnmadd132sd',9Dh + dw fma_instruction_sd-instruction_handler + db 'vfnmadd132ss',9Dh + dw fma_instruction_ss-instruction_handler + db 'vfnmadd213pd',0ACh + dw fma_instruction_pd-instruction_handler + db 'vfnmadd213ps',0ACh + dw fma_instruction_ps-instruction_handler + db 'vfnmadd213sd',0ADh + dw fma_instruction_sd-instruction_handler + db 'vfnmadd213ss',0ADh + dw fma_instruction_ss-instruction_handler + db 'vfnmadd231pd',0BCh + dw fma_instruction_pd-instruction_handler + db 'vfnmadd231ps',0BCh + dw fma_instruction_ps-instruction_handler + db 'vfnmadd231sd',0BDh + dw fma_instruction_sd-instruction_handler + db 'vfnmadd231ss',0BDh + dw fma_instruction_ss-instruction_handler + db 'vfnmsub132pd',9Eh + dw fma_instruction_pd-instruction_handler + db 'vfnmsub132ps',9Eh + dw fma_instruction_ps-instruction_handler + db 'vfnmsub132sd',9Fh + dw fma_instruction_sd-instruction_handler + db 'vfnmsub132ss',9Fh + dw fma_instruction_ss-instruction_handler + db 'vfnmsub213pd',0AEh + dw fma_instruction_pd-instruction_handler + db 'vfnmsub213ps',0AEh + dw fma_instruction_ps-instruction_handler + db 'vfnmsub213sd',0AFh + dw fma_instruction_sd-instruction_handler + db 'vfnmsub213ss',0AFh + dw fma_instruction_ss-instruction_handler + db 'vfnmsub231pd',0BEh + dw fma_instruction_pd-instruction_handler + db 'vfnmsub231ps',0BEh + dw fma_instruction_ps-instruction_handler + db 'vfnmsub231sd',0BFh + dw fma_instruction_sd-instruction_handler + db 'vfnmsub231ss',0BFh + dw fma_instruction_ss-instruction_handler + db 'vinsertf32x4',18h + dw avx512_insert_32x4_instruction-instruction_handler + db 'vinsertf32x8',1Ah + dw avx512_insert_32x8_instruction-instruction_handler + db 'vinsertf64x2',18h + dw avx512_insert_64x2_instruction-instruction_handler + db 'vinsertf64x4',1Ah + dw avx512_insert_64x4_instruction-instruction_handler + db 'vinserti32x4',38h + dw avx512_insert_32x4_instruction-instruction_handler + db 'vinserti32x8',3Ah + dw avx512_insert_32x8_instruction-instruction_handler + db 'vinserti64x2',38h + dw avx512_insert_64x2_instruction-instruction_handler + db 'vinserti64x4',3Ah + dw avx512_insert_64x4_instruction-instruction_handler + db 'vpbroadcastb',78h + dw avx_pbroadcastb_instruction-instruction_handler + db 'vpbroadcastd',58h + dw avx_pbroadcastd_instruction-instruction_handler + db 'vpbroadcastq',59h + dw avx_pbroadcastq_instruction-instruction_handler + db 'vpbroadcastw',79h + dw avx_pbroadcastw_instruction-instruction_handler + db 'vpclmulhqhdq',10001b + dw avx_pclmulqdq_instruction-instruction_handler + db 'vpclmullqhdq',10000b + dw avx_pclmulqdq_instruction-instruction_handler + db 'vpcomfalseub',6 + dw xop_pcom_ub_instruction-instruction_handler + db 'vpcomfalseud',6 + dw xop_pcom_ud_instruction-instruction_handler + db 'vpcomfalseuq',6 + dw xop_pcom_uq_instruction-instruction_handler + db 'vpcomfalseuw',6 + dw xop_pcom_uw_instruction-instruction_handler + db 'vpermilmo2pd',10b + dw vpermil_2pd_instruction-instruction_handler + db 'vpermilmo2ps',10b + dw vpermil_2ps_instruction-instruction_handler + db 'vpermilmz2pd',11b + dw vpermil_2pd_instruction-instruction_handler + db 'vpermilmz2ps',11b + dw vpermil_2ps_instruction-instruction_handler + db 'vpermiltd2pd',0 + dw vpermil_2pd_instruction-instruction_handler + db 'vpermiltd2ps',0 + dw vpermil_2ps_instruction-instruction_handler + db 'vpshufbitqmb',8Fh + dw avx512_ptestmb_instruction-instruction_handler +instructions_13: + db 'gf2p8affineqb',0CEh + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'vcmptrue_uspd',1Fh + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmptrue_usps',1Fh + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmptrue_ussd',1Fh + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmptrue_usss',1Fh + dw avx_cmp_ss_instruction-instruction_handler + db 'vcmpunord_spd',13h + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpunord_sps',13h + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpunord_ssd',13h + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpunord_sss',13h + dw avx_cmp_ss_instruction-instruction_handler + db 'vextractf32x4',19h + dw avx512_extract_32x4_instruction-instruction_handler + db 'vextractf32x8',1Bh + dw avx512_extract_32x8_instruction-instruction_handler + db 'vextractf64x2',19h + dw avx512_extract_64x2_instruction-instruction_handler + db 'vextractf64x4',1Bh + dw avx512_extract_64x4_instruction-instruction_handler + db 'vextracti32x4',39h + dw avx512_extract_32x4_instruction-instruction_handler + db 'vextracti32x8',3Bh + dw avx512_extract_32x8_instruction-instruction_handler + db 'vextracti64x2',39h + dw avx512_extract_64x2_instruction-instruction_handler + db 'vextracti64x4',3Bh + dw avx512_extract_64x4_instruction-instruction_handler + db 'vgatherpf0dpd',1 + dw gatherpf_dpd_instruction-instruction_handler + db 'vgatherpf0dps',1 + dw gatherpf_dps_instruction-instruction_handler + db 'vgatherpf0qpd',1 + dw gatherpf_qpd_instruction-instruction_handler + db 'vgatherpf0qps',1 + dw gatherpf_qps_instruction-instruction_handler + db 'vgatherpf1dpd',2 + dw gatherpf_dpd_instruction-instruction_handler + db 'vgatherpf1dps',2 + dw gatherpf_dps_instruction-instruction_handler + db 'vgatherpf1qpd',2 + dw gatherpf_qpd_instruction-instruction_handler + db 'vgatherpf1qps',2 + dw gatherpf_qps_instruction-instruction_handler + db 'vpclmulhqlqdq',1 + dw avx_pclmulqdq_instruction-instruction_handler + db 'vpclmullqlqdq',0 + dw avx_pclmulqdq_instruction-instruction_handler +instructions_14: + db 'vbroadcastf128',1Ah + dw avx_broadcast_128_instruction_noevex-instruction_handler + db 'vbroadcasti128',5Ah + dw avx_broadcast_128_instruction_noevex-instruction_handler + db 'vcmpfalse_ospd',1Bh + dw avx_cmp_pd_instruction-instruction_handler + db 'vcmpfalse_osps',1Bh + dw avx_cmp_ps_instruction-instruction_handler + db 'vcmpfalse_ossd',1Bh + dw avx_cmp_sd_instruction-instruction_handler + db 'vcmpfalse_osss',1Bh + dw avx_cmp_ss_instruction-instruction_handler + db 'vfmaddsub132pd',96h + dw fma_instruction_pd-instruction_handler + db 'vfmaddsub132ps',96h + dw fma_instruction_ps-instruction_handler + db 'vfmaddsub213pd',0A6h + dw fma_instruction_pd-instruction_handler + db 'vfmaddsub213ps',0A6h + dw fma_instruction_ps-instruction_handler + db 'vfmaddsub231pd',0B6h + dw fma_instruction_pd-instruction_handler + db 'vfmaddsub231ps',0B6h + dw fma_instruction_ps-instruction_handler + db 'vfmsubadd132pd',97h + dw fma_instruction_pd-instruction_handler + db 'vfmsubadd132ps',97h + dw fma_instruction_ps-instruction_handler + db 'vfmsubadd213pd',0A7h + dw fma_instruction_pd-instruction_handler + db 'vfmsubadd213ps',0A7h + dw fma_instruction_ps-instruction_handler + db 'vfmsubadd231pd',0B7h + dw fma_instruction_pd-instruction_handler + db 'vfmsubadd231ps',0B7h + dw fma_instruction_ps-instruction_handler + db 'vgf2p8affineqb',0CEh + dw avx_q_instruction_3a_imm8_w1-instruction_handler + db 'vpmultishiftqb',83h + dw avx_q_instruction_38_evex-instruction_handler + db 'vscatterpf0dpd',5 + dw gatherpf_dpd_instruction-instruction_handler + db 'vscatterpf0dps',5 + dw gatherpf_dps_instruction-instruction_handler + db 'vscatterpf0qpd',5 + dw gatherpf_qpd_instruction-instruction_handler + db 'vscatterpf0qps',5 + dw gatherpf_qps_instruction-instruction_handler + db 'vscatterpf1dpd',6 + dw gatherpf_dpd_instruction-instruction_handler + db 'vscatterpf1dps',6 + dw gatherpf_dps_instruction-instruction_handler + db 'vscatterpf1qpd',6 + dw gatherpf_qpd_instruction-instruction_handler + db 'vscatterpf1qps',6 + dw gatherpf_qps_instruction-instruction_handler +instructions_15: + db 'aeskeygenassist',0DFh + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'vbroadcastf32x2',19h + dw avx512_broadcast_32x2_instruction-instruction_handler + db 'vbroadcastf32x4',1Ah + dw avx512_broadcast_32x4_instruction-instruction_handler + db 'vbroadcastf32x8',1Bh + dw avx512_broadcast_32x8_instruction-instruction_handler + db 'vbroadcastf64x2',1Ah + dw avx512_broadcast_64x2_instruction-instruction_handler + db 'vbroadcastf64x4',1Bh + dw avx512_broadcast_64x4_instruction-instruction_handler + db 'vbroadcasti32x2',59h + dw avx512_broadcast_32x2_instruction-instruction_handler + db 'vbroadcasti32x4',5Ah + dw avx512_broadcast_32x4_instruction-instruction_handler + db 'vbroadcasti32x8',5Bh + dw avx512_broadcast_32x8_instruction-instruction_handler + db 'vbroadcasti64x2',5Ah + dw avx512_broadcast_64x2_instruction-instruction_handler + db 'vbroadcasti64x4',5Bh + dw avx512_broadcast_64x4_instruction-instruction_handler + db 'vpbroadcastmb2q',2Ah + dw avx512_pmov_m2_instruction_w1-instruction_handler + db 'vpbroadcastmw2d',3Ah + dw avx512_pmov_m2_instruction-instruction_handler +instructions_16: + db 'gf2p8affineinvqb',0CFh + dw sse4_instruction_66_3a_imm8-instruction_handler + db 'vaeskeygenassist',0DFh + dw avx_single_source_128bit_instruction_3a_imm8_noevex-instruction_handler +instructions_17: + db 'vgf2p8affineinvqb',0CFh + dw avx_q_instruction_3a_imm8_w1-instruction_handler +instructions_end: + +data_directives: + dw data_directives_2-data_directives,(data_directives_3-data_directives_2)/(2+3) + dw data_directives_3-data_directives,(data_directives_4-data_directives_3)/(3+3) + dw data_directives_4-data_directives,(data_directives_end-data_directives_4)/(4+3) + +data_directives_2: + db 'db',1 + dw data_bytes-instruction_handler + db 'dd',4 + dw data_dwords-instruction_handler + db 'df',6 + dw data_pwords-instruction_handler + db 'dp',6 + dw data_pwords-instruction_handler + db 'dq',8 + dw data_qwords-instruction_handler + db 'dt',10 + dw data_twords-instruction_handler + db 'du',2 + dw data_unicode-instruction_handler + db 'dw',2 + dw data_words-instruction_handler + db 'rb',1 + dw reserve_bytes-instruction_handler + db 'rd',4 + dw reserve_dwords-instruction_handler + db 'rf',6 + dw reserve_pwords-instruction_handler + db 'rp',6 + dw reserve_pwords-instruction_handler + db 'rq',8 + dw reserve_qwords-instruction_handler + db 'rt',10 + dw reserve_twords-instruction_handler + db 'rw',2 + dw reserve_words-instruction_handler +data_directives_3: +data_directives_4: + db 'file',1 + dw data_file-instruction_handler +data_directives_end: diff --git a/toolchain/fasmw17332/SOURCE/VARIABLE.INC b/toolchain/fasmw17332/SOURCE/VARIABLE.INC new file mode 100644 index 0000000..d4f0357 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/VARIABLE.INC @@ -0,0 +1,155 @@ + +; flat assembler core variables +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +; Variables which have to be set up by interface: + +memory_start dd ? +memory_end dd ? + +additional_memory dd ? +additional_memory_end dd ? + +stack_limit dd ? + +initial_definitions dd ? +input_file dd ? +output_file dd ? +symbols_file dd ? + +passes_limit dw ? + +; Internal core variables: + +current_pass dw ? + +include_paths dd ? +free_additional_memory dd ? +source_start dd ? +code_start dd ? +code_size dd ? +real_code_size dd ? +written_size dd ? +headers_size dd ? + +current_line dd ? +macro_line dd ? +macro_block dd ? +macro_block_line dd ? +macro_block_line_number dd ? +macro_symbols dd ? +struc_name dd ? +struc_label dd ? +instant_macro_start dd ? +parameters_end dd ? +default_argument_value dd ? +locals_counter rb 8 +current_locals_prefix dd ? +anonymous_reverse dd ? +anonymous_forward dd ? +labels_list dd ? +label_hash dd ? +label_leaf dd ? +hash_tree dd ? +addressing_space dd ? +undefined_data_start dd ? +undefined_data_end dd ? +counter dd ? +counter_limit dd ? +error_info dd ? +error_line dd ? +error dd ? +tagged_blocks dd ? +structures_buffer dd ? +number_start dd ? +current_offset dd ? +value dq ? +fp_value rd 8 +adjustment dq ? +symbol_identifier dd ? +address_symbol dd ? +address_high dd ? +uncompressed_displacement dd ? +format_flags dd ? +resolver_flags dd ? +symbols_stream dd ? +number_of_relocations dd ? +number_of_sections dd ? +stub_size dd ? +stub_file dd ? +current_section dd ? +machine dw ? +subsystem dw ? +subsystem_version dd ? +image_base dd ? +image_base_high dd ? +merge_segment dd ? +resource_data dd ? +resource_size dd ? +actual_fixups_size dd ? +reserved_fixups dd ? +reserved_fixups_size dd ? +last_fixup_base dd ? +last_fixup_header dd ? +parenthesis_stack dd ? +blocks_stack dd ? +parsed_lines dd ? +logical_value_parentheses dd ? +file_extension dd ? + +operand_size db ? +operand_flags db ? +operand_prefix db ? +rex_prefix db ? +opcode_prefix db ? +vex_required db ? +vex_register db ? +immediate_size db ? +mask_register db ? +broadcast_size db ? +rounding_mode db ? + +base_code db ? +extended_code db ? +supplemental_code db ? +postbyte_register db ? +segment_register db ? +xop_opcode_map db ? + +mmx_size db ? +jump_type db ? +push_size db ? +value_size db ? +address_size db ? +label_size db ? +size_declared db ? +address_size_declared db ? +displacement_compression db ? + +value_undefined db ? +value_constant db ? +value_type db ? +value_sign db ? +fp_sign db ? +fp_format db ? +address_sign db ? +address_register db ? +compare_type db ? +logical_value_wrapping db ? +next_pass_needed db ? +output_format db ? +code_type db ? +adjustment_sign db ? +evex_mode db ? + +macro_status db ? +skip_default_argument_value db ? +prefix_flags db ? +formatter_symbols_allowed db ? +decorator_symbols_allowed db ? +free_address_range db ? + +characters rb 100h +converted rb 100h +message rb 180h diff --git a/toolchain/fasmw17332/SOURCE/VERSION.INC b/toolchain/fasmw17332/SOURCE/VERSION.INC new file mode 100644 index 0000000..f160acd --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/VERSION.INC @@ -0,0 +1,39 @@ + +; flat assembler version 1.73 +; Copyright (c) 1999-2024, Tomasz Grysztar. +; All rights reserved. +; +; This programs is free for commercial and non-commercial use as long as +; the following conditions are adhered to. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are +; met: +; +; 1. Redistributions of source code must retain the above copyright notice, +; this list of conditions and the following disclaimer. +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +; PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR +; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +; +; The licence and distribution terms for any publically available +; version or derivative of this code cannot be changed. i.e. this code +; cannot simply be copied and put under another distribution licence +; (including the GNU Public Licence). + +VERSION_STRING equ "1.73.32" + +VERSION_MAJOR = 1 +VERSION_MINOR = 73 diff --git a/toolchain/fasmw17332/SOURCE/WIN32/FASM.ASM b/toolchain/fasmw17332/SOURCE/WIN32/FASM.ASM new file mode 100644 index 0000000..4001387 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/WIN32/FASM.ASM @@ -0,0 +1,436 @@ + +; flat assembler interface for Win32 +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + + format PE console + +section '.text' code readable executable + +start: + + mov [con_handle],STD_OUTPUT_HANDLE + mov esi,_logo + call display_string + + call get_params + jc information + + call init_memory + + mov esi,_memory_prefix + call display_string + mov eax,[memory_end] + sub eax,[memory_start] + add eax,[additional_memory_end] + sub eax,[additional_memory] + shr eax,10 + call display_number + mov esi,_memory_suffix + call display_string + + call [GetTickCount] + mov [start_time],eax + + and [preprocessing_done],0 + call preprocessor + or [preprocessing_done],-1 + call parser + call assembler + call formatter + + call display_user_messages + movzx eax,[current_pass] + inc eax + call display_number + mov esi,_passes_suffix + call display_string + call [GetTickCount] + sub eax,[start_time] + xor edx,edx + mov ebx,100 + div ebx + or eax,eax + jz display_bytes_count + xor edx,edx + mov ebx,10 + div ebx + push edx + call display_number + mov dl,'.' + call display_character + pop eax + call display_number + mov esi,_seconds_suffix + call display_string + display_bytes_count: + mov eax,[written_size] + call display_number + mov esi,_bytes_suffix + call display_string + xor al,al + jmp exit_program + +information: + mov esi,_usage + call display_string + mov al,1 + jmp exit_program + +get_params: + mov [input_file],0 + mov [output_file],0 + mov [symbols_file],0 + mov [memory_setting],0 + mov [passes_limit],100 + call [GetCommandLine] + mov [definitions_pointer],predefinitions + mov esi,eax + mov edi,params + find_command_start: + lodsb + cmp al,20h + je find_command_start + cmp al,22h + je skip_quoted_name + skip_name: + lodsb + cmp al,20h + je find_param + or al,al + jz all_params + jmp skip_name + skip_quoted_name: + lodsb + cmp al,22h + je find_param + or al,al + jz all_params + jmp skip_quoted_name + find_param: + lodsb + cmp al,20h + je find_param + cmp al,'-' + je option_param + cmp al,0Dh + je all_params + or al,al + jz all_params + cmp [input_file],0 + jne get_output_file + mov [input_file],edi + jmp process_param + get_output_file: + cmp [output_file],0 + jne bad_params + mov [output_file],edi + process_param: + cmp al,22h + je string_param + copy_param: + cmp edi,params+1000h + jae bad_params + stosb + lodsb + cmp al,20h + je param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + jmp copy_param + string_param: + lodsb + cmp al,22h + je string_param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + cmp edi,params+1000h + jae bad_params + stosb + jmp string_param + option_param: + lodsb + cmp al,'m' + je memory_option + cmp al,'M' + je memory_option + cmp al,'p' + je passes_option + cmp al,'P' + je passes_option + cmp al,'d' + je definition_option + cmp al,'D' + je definition_option + cmp al,'s' + je symbols_option + cmp al,'S' + je symbols_option + bad_params: + stc + ret + get_option_value: + xor eax,eax + mov edx,eax + get_option_digit: + lodsb + cmp al,20h + je option_value_ok + cmp al,0Dh + je option_value_ok + or al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + invalid_option_value: + stc + ret + memory_option: + lodsb + cmp al,20h + je memory_option + cmp al,0Dh + je bad_params + or al,al + jz bad_params + dec esi + call get_option_value + or edx,edx + jz bad_params + cmp edx,1 shl (32-10) + jae bad_params + mov [memory_setting],edx + jmp find_param + passes_option: + lodsb + cmp al,20h + je passes_option + cmp al,0Dh + je bad_params + or al,al + jz bad_params + dec esi + call get_option_value + or edx,edx + jz bad_params + cmp edx,10000h + ja bad_params + mov [passes_limit],dx + jmp find_param + definition_option: + lodsb + cmp al,20h + je definition_option + cmp al,0Dh + je bad_params + or al,al + jz bad_params + dec esi + push edi + mov edi,[definitions_pointer] + call convert_definition_option + mov [definitions_pointer],edi + pop edi + jc bad_params + jmp find_param + symbols_option: + mov [symbols_file],edi + find_symbols_file_name: + lodsb + cmp al,20h + jne process_param + jmp find_symbols_file_name + param_end: + dec esi + string_param_end: + cmp edi,params+1000h + jae bad_params + xor al,al + stosb + jmp find_param + all_params: + cmp [input_file],0 + je bad_params + mov eax,[definitions_pointer] + mov byte [eax],0 + mov [initial_definitions],predefinitions + clc + ret + convert_definition_option: + mov ecx,edi + cmp edi,predefinitions+1000h + jae bad_definition_option + xor al,al + stosb + copy_definition_name: + lodsb + cmp al,'=' + je copy_definition_value + cmp al,20h + je bad_definition_option + cmp al,0Dh + je bad_definition_option + or al,al + jz bad_definition_option + cmp edi,predefinitions+1000h + jae bad_definition_option + stosb + inc byte [ecx] + jnz copy_definition_name + bad_definition_option: + stc + ret + copy_definition_value: + lodsb + cmp al,20h + je definition_value_end + cmp al,0Dh + je definition_value_end + or al,al + jz definition_value_end + cmp al,'\' + jne definition_value_character + cmp byte [esi],20h + jne definition_value_character + lodsb + definition_value_character: + cmp edi,predefinitions+1000h + jae bad_definition_option + stosb + jmp copy_definition_value + definition_value_end: + dec esi + cmp edi,predefinitions+1000h + jae bad_definition_option + xor al,al + stosb + clc + ret + +include 'system.inc' + +include '..\errors.inc' +include '..\symbdump.inc' +include '..\preproce.inc' +include '..\parser.inc' +include '..\exprpars.inc' +include '..\assemble.inc' +include '..\exprcalc.inc' +include '..\formats.inc' +include '..\x86_64.inc' +include '..\avx.inc' + +include '..\tables.inc' +include '..\messages.inc' + +section '.data' data readable writeable + +include '..\version.inc' + +_copyright db 'Copyright (c) 1999-2022, Tomasz Grysztar',0Dh,0Ah,0 + +_logo db 'flat assembler version ',VERSION_STRING,0 +_usage db 0Dh,0Ah + db 'usage: fasm [output]',0Dh,0Ah + db 'optional settings:',0Dh,0Ah + db ' -m set the limit in kilobytes for the available memory',0Dh,0Ah + db ' -p set the maximum allowed number of passes',0Dh,0Ah + db ' -d = define symbolic variable',0Dh,0Ah + db ' -s dump symbolic information for debugging',0Dh,0Ah + db 0 +_memory_prefix db ' (',0 +_memory_suffix db ' kilobytes memory)',0Dh,0Ah,0 +_passes_suffix db ' passes, ',0 +_seconds_suffix db ' seconds, ',0 +_bytes_suffix db ' bytes.',0Dh,0Ah,0 + +align 4 + +include '..\variable.inc' + +con_handle dd ? +memory_setting dd ? +start_time dd ? +definitions_pointer dd ? +bytes_count dd ? +displayed_count dd ? +character db ? +last_displayed rb 2 +preprocessing_done db ? + +params rb 1000h +options rb 1000h +predefinitions rb 1000h +buffer rb 4000h + +stack 10000h + +section '.idata' import data readable writeable + + dd 0,0,0,rva kernel_name,rva kernel_table + dd 0,0,0,0,0 + + kernel_table: + ExitProcess dd rva _ExitProcess + CreateFile dd rva _CreateFileA + ReadFile dd rva _ReadFile + WriteFile dd rva _WriteFile + CloseHandle dd rva _CloseHandle + SetFilePointer dd rva _SetFilePointer + GetCommandLine dd rva _GetCommandLineA + GetEnvironmentVariable dd rva _GetEnvironmentVariable + GetStdHandle dd rva _GetStdHandle + VirtualAlloc dd rva _VirtualAlloc + VirtualFree dd rva _VirtualFree + GetTickCount dd rva _GetTickCount + GetSystemTime dd rva _GetSystemTime + GlobalMemoryStatus dd rva _GlobalMemoryStatus + dd 0 + + kernel_name db 'KERNEL32.DLL',0 + + _ExitProcess dw 0 + db 'ExitProcess',0 + _CreateFileA dw 0 + db 'CreateFileA',0 + _ReadFile dw 0 + db 'ReadFile',0 + _WriteFile dw 0 + db 'WriteFile',0 + _CloseHandle dw 0 + db 'CloseHandle',0 + _SetFilePointer dw 0 + db 'SetFilePointer',0 + _GetCommandLineA dw 0 + db 'GetCommandLineA',0 + _GetEnvironmentVariable dw 0 + db 'GetEnvironmentVariableA',0 + _GetStdHandle dw 0 + db 'GetStdHandle',0 + _VirtualAlloc dw 0 + db 'VirtualAlloc',0 + _VirtualFree dw 0 + db 'VirtualFree',0 + _GetTickCount dw 0 + db 'GetTickCount',0 + _GetSystemTime dw 0 + db 'GetSystemTime',0 + _GlobalMemoryStatus dw 0 + db 'GlobalMemoryStatus',0 + +section '.reloc' fixups data readable discardable diff --git a/toolchain/fasmw17332/SOURCE/WIN32/SYSTEM.INC b/toolchain/fasmw17332/SOURCE/WIN32/SYSTEM.INC new file mode 100644 index 0000000..3afc0aa --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/WIN32/SYSTEM.INC @@ -0,0 +1,570 @@ + +; flat assembler interface for Win32 +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +CREATE_NEW = 1 +CREATE_ALWAYS = 2 +OPEN_EXISTING = 3 +OPEN_ALWAYS = 4 +TRUNCATE_EXISTING = 5 + +FILE_SHARE_READ = 1 +FILE_SHARE_WRITE = 2 +FILE_SHARE_DELETE = 4 + +GENERIC_READ = 80000000h +GENERIC_WRITE = 40000000h + +STD_INPUT_HANDLE = 0FFFFFFF6h +STD_OUTPUT_HANDLE = 0FFFFFFF5h +STD_ERROR_HANDLE = 0FFFFFFF4h + +MEM_COMMIT = 1000h +MEM_RESERVE = 2000h +MEM_DECOMMIT = 4000h +MEM_RELEASE = 8000h +MEM_FREE = 10000h +MEM_PRIVATE = 20000h +MEM_MAPPED = 40000h +MEM_RESET = 80000h +MEM_TOP_DOWN = 100000h + +PAGE_NOACCESS = 1 +PAGE_READONLY = 2 +PAGE_READWRITE = 4 +PAGE_WRITECOPY = 8 +PAGE_EXECUTE = 10h +PAGE_EXECUTE_READ = 20h +PAGE_EXECUTE_READWRITE = 40h +PAGE_EXECUTE_WRITECOPY = 80h +PAGE_GUARD = 100h +PAGE_NOCACHE = 200h + +init_memory: + xor eax,eax + mov [memory_start],eax + mov eax,esp + and eax,not 0FFFh + add eax,1000h-10000h + mov [stack_limit],eax + mov eax,[memory_setting] + shl eax,10 + jnz allocate_memory + push buffer + call [GlobalMemoryStatus] + mov eax,dword [buffer+20] + mov edx,dword [buffer+12] + cmp eax,0 + jl large_memory + cmp edx,0 + jl large_memory + shr eax,2 + add eax,edx + jmp allocate_memory + large_memory: + mov eax,80000000h + allocate_memory: + mov edx,eax + shr edx,2 + mov ecx,eax + sub ecx,edx + mov [memory_end],ecx + mov [additional_memory_end],edx + push PAGE_READWRITE + push MEM_COMMIT + push eax + push 0 + call [VirtualAlloc] + or eax,eax + jz not_enough_memory + mov [memory_start],eax + add eax,[memory_end] + mov [memory_end],eax + mov [additional_memory],eax + add [additional_memory_end],eax + ret + not_enough_memory: + mov eax,[additional_memory_end] + shl eax,1 + cmp eax,4000h + jb out_of_memory + jmp allocate_memory + +exit_program: + movzx eax,al + push eax + mov eax,[memory_start] + test eax,eax + jz do_exit + push MEM_RELEASE + push 0 + push eax + call [VirtualFree] + do_exit: + call [ExitProcess] + +get_environment_variable: + mov ecx,[memory_end] + sub ecx,edi + cmp ecx,4000h + jbe buffer_for_variable_ok + mov ecx,4000h + buffer_for_variable_ok: + push ecx + push edi + push esi + call [GetEnvironmentVariable] + add edi,eax + cmp edi,[memory_end] + jae out_of_memory + ret + +open: + push 0 + push 0 + push OPEN_EXISTING + push 0 + push FILE_SHARE_READ + push GENERIC_READ + push edx + call [CreateFile] + cmp eax,-1 + je file_error + mov ebx,eax + clc + ret + file_error: + stc + ret +create: + push 0 + push 0 + push CREATE_ALWAYS + push 0 + push FILE_SHARE_READ + push GENERIC_WRITE + push edx + call [CreateFile] + cmp eax,-1 + je file_error + mov ebx,eax + clc + ret +write: + push 0 + push bytes_count + push ecx + push edx + push ebx + call [WriteFile] + or eax,eax + jz file_error + clc + ret +read: + mov ebp,ecx + push 0 + push bytes_count + push ecx + push edx + push ebx + call [ReadFile] + or eax,eax + jz file_error + cmp ebp,[bytes_count] + jne file_error + clc + ret +close: + push ebx + call [CloseHandle] + ret +lseek: + movzx eax,al + push eax + push 0 + push edx + push ebx + call [SetFilePointer] + cmp eax,-1 + je file_error + clc + ret + +display_string: + push [con_handle] + call [GetStdHandle] + mov ebp,eax + mov edi,esi + or ecx,-1 + xor al,al + repne scasb + neg ecx + sub ecx,2 + push 0 + push bytes_count + push ecx + push esi + push ebp + call [WriteFile] + ret +display_character: + push ebx + mov [character],dl + push [con_handle] + call [GetStdHandle] + mov ebx,eax + push 0 + push bytes_count + push 1 + push character + push ebx + call [WriteFile] + pop ebx + ret +display_number: + push ebx + mov ecx,1000000000 + xor edx,edx + xor bl,bl + display_loop: + div ecx + push edx + cmp ecx,1 + je display_digit + or bl,bl + jnz display_digit + or al,al + jz digit_ok + not bl + display_digit: + mov dl,al + add dl,30h + push ecx + call display_character + pop ecx + digit_ok: + mov eax,ecx + xor edx,edx + mov ecx,10 + div ecx + mov ecx,eax + pop eax + or ecx,ecx + jnz display_loop + pop ebx + ret + +display_user_messages: + mov [displayed_count],0 + call show_display_buffer + cmp [displayed_count],1 + jb line_break_ok + je make_line_break + mov ax,word [last_displayed] + cmp ax,0A0Dh + je line_break_ok + cmp ax,0D0Ah + je line_break_ok + make_line_break: + mov word [buffer],0A0Dh + push [con_handle] + call [GetStdHandle] + push 0 + push bytes_count + push 2 + push buffer + push eax + call [WriteFile] + line_break_ok: + ret +display_block: + add [displayed_count],ecx + cmp ecx,1 + ja take_last_two_characters + jb block_displayed + mov al,[last_displayed+1] + mov ah,[esi] + mov word [last_displayed],ax + jmp block_ok + take_last_two_characters: + mov ax,[esi+ecx-2] + mov word [last_displayed],ax + block_ok: + push ecx + push [con_handle] + call [GetStdHandle] + pop ecx + push 0 + push bytes_count + push ecx + push esi + push eax + call [WriteFile] + block_displayed: + ret + +fatal_error: + mov [con_handle],STD_ERROR_HANDLE + mov esi,error_prefix + call display_string + pop esi + call display_string + mov esi,error_suffix + call display_string + mov al,0FFh + jmp exit_program +assembler_error: + mov [con_handle],STD_ERROR_HANDLE + call display_user_messages + mov ebx,[current_line] + test ebx,ebx + jz display_error_message + push dword 0 + get_error_lines: + mov eax,[ebx] + cmp byte [eax],0 + je get_next_error_line + push ebx + test byte [ebx+7],80h + jz display_error_line + mov edx,ebx + find_definition_origin: + mov edx,[edx+12] + test byte [edx+7],80h + jnz find_definition_origin + push edx + get_next_error_line: + mov ebx,[ebx+8] + jmp get_error_lines + display_error_line: + mov esi,[ebx] + call display_string + mov esi,line_number_start + call display_string + mov eax,[ebx+4] + and eax,7FFFFFFFh + call display_number + mov dl,']' + call display_character + pop esi + cmp ebx,esi + je line_number_ok + mov dl,20h + call display_character + push esi + mov esi,[esi] + movzx ecx,byte [esi] + inc esi + call display_block + mov esi,line_number_start + call display_string + pop esi + mov eax,[esi+4] + and eax,7FFFFFFFh + call display_number + mov dl,']' + call display_character + line_number_ok: + mov esi,line_data_start + call display_string + mov esi,ebx + mov edx,[esi] + call open + mov al,2 + xor edx,edx + call lseek + mov edx,[esi+8] + sub eax,edx + jz line_data_displayed + push eax + xor al,al + call lseek + mov ecx,[esp] + mov edx,[additional_memory] + lea eax,[edx+ecx] + cmp eax,[additional_memory_end] + ja out_of_memory + call read + call close + pop ecx + mov esi,[additional_memory] + get_line_data: + mov al,[esi] + cmp al,0Ah + je display_line_data + cmp al,0Dh + je display_line_data + cmp al,1Ah + je display_line_data + or al,al + jz display_line_data + inc esi + loop get_line_data + display_line_data: + mov ecx,esi + mov esi,[additional_memory] + sub ecx,esi + call display_block + line_data_displayed: + mov esi,cr_lf + call display_string + pop ebx + or ebx,ebx + jnz display_error_line + cmp [preprocessing_done],0 + je display_error_message + mov esi,preprocessed_instruction_prefix + call display_string + mov esi,[current_line] + add esi,16 + mov edi,[additional_memory] + xor dl,dl + convert_instruction: + lodsb + cmp al,1Ah + je copy_symbol + cmp al,22h + je copy_symbol + cmp al,3Bh + je instruction_converted + stosb + or al,al + jz instruction_converted + xor dl,dl + jmp convert_instruction + copy_symbol: + or dl,dl + jz space_ok + mov byte [edi],20h + inc edi + space_ok: + cmp al,22h + je quoted + lodsb + movzx ecx,al + rep movsb + or dl,-1 + jmp convert_instruction + quoted: + mov al,27h + stosb + lodsd + mov ecx,eax + jecxz quoted_copied + copy_quoted: + lodsb + stosb + cmp al,27h + jne quote_ok + stosb + quote_ok: + loop copy_quoted + quoted_copied: + mov al,27h + stosb + or dl,-1 + jmp convert_instruction + instruction_converted: + xor al,al + stosb + mov esi,[additional_memory] + call display_string + mov esi,cr_lf + call display_string + display_error_message: + mov esi,error_prefix + call display_string + pop esi + call display_string + mov esi,error_suffix + call display_string + mov al,2 + jmp exit_program + +make_timestamp: + push buffer + call [GetSystemTime] + movzx ecx,word [buffer] + mov eax,ecx + sub eax,1970 + mov ebx,365 + mul ebx + mov ebp,eax + mov eax,ecx + sub eax,1969 + shr eax,2 + add ebp,eax + mov eax,ecx + sub eax,1901 + mov ebx,100 + div ebx + sub ebp,eax + mov eax,ecx + xor edx,edx + sub eax,1601 + mov ebx,400 + div ebx + add ebp,eax + movzx ecx,word [buffer+2] + mov eax,ecx + dec eax + mov ebx,30 + mul ebx + add ebp,eax + cmp ecx,8 + jbe months_correction + mov eax,ecx + sub eax,7 + shr eax,1 + add ebp,eax + mov ecx,8 + months_correction: + mov eax,ecx + shr eax,1 + add ebp,eax + cmp ecx,2 + jbe day_correction_ok + sub ebp,2 + movzx ecx,word [buffer] + test ecx,11b + jnz day_correction_ok + xor edx,edx + mov eax,ecx + mov ebx,100 + div ebx + or edx,edx + jnz day_correction + mov eax,ecx + mov ebx,400 + div ebx + or edx,edx + jnz day_correction_ok + day_correction: + inc ebp + day_correction_ok: + movzx eax,word [buffer+6] + dec eax + add eax,ebp + mov ebx,24 + mul ebx + movzx ecx,word [buffer+8] + add eax,ecx + mov ebx,60 + mul ebx + movzx ecx,word [buffer+10] + add eax,ecx + mov ebx,60 + mul ebx + movzx ecx,word [buffer+12] + add eax,ecx + adc edx,0 + ret + +error_prefix db 'error: ',0 +error_suffix db '.' +cr_lf db 0Dh,0Ah,0 +line_number_start db ' [',0 +line_data_start db ':',0Dh,0Ah,0 +preprocessed_instruction_prefix db 'processed: ',0 diff --git a/toolchain/fasmw17332/SOURCE/X86_64.INC b/toolchain/fasmw17332/SOURCE/X86_64.INC new file mode 100644 index 0000000..bfb9327 --- /dev/null +++ b/toolchain/fasmw17332/SOURCE/X86_64.INC @@ -0,0 +1,7391 @@ + +; flat assembler core +; Copyright (c) 1999-2022, Tomasz Grysztar. +; All rights reserved. + +simple_instruction_except64: + cmp [code_type],64 + je illegal_instruction +simple_instruction: + stos byte [edi] + jmp instruction_assembled +simple_instruction_only64: + cmp [code_type],64 + jne illegal_instruction + jmp simple_instruction +simple_instruction_16bit_except64: + cmp [code_type],64 + je illegal_instruction +simple_instruction_16bit: + cmp [code_type],16 + jne size_prefix + stos byte [edi] + jmp instruction_assembled + size_prefix: + mov ah,al + mov al,66h + stos word [edi] + jmp instruction_assembled +simple_instruction_32bit_except64: + cmp [code_type],64 + je illegal_instruction +simple_instruction_32bit: + cmp [code_type],16 + je size_prefix + stos byte [edi] + jmp instruction_assembled +iret_instruction: + cmp [code_type],64 + jne simple_instruction +simple_instruction_64bit: + cmp [code_type],64 + jne illegal_instruction + mov ah,al + mov al,48h + stos word [edi] + jmp instruction_assembled +simple_extended_instruction_64bit: + cmp [code_type],64 + jne illegal_instruction + mov byte [edi],48h + inc edi +simple_extended_instruction: + mov ah,al + mov al,0Fh + stos word [edi] + jmp instruction_assembled +simple_extended_instruction_f3: + mov byte [edi],0F3h + inc edi + jmp simple_extended_instruction +prefix_instruction: + stos byte [edi] + or [prefix_flags],1 + jmp continue_line +segment_prefix: + mov ah,al + shr ah,4 + cmp ah,3 + jne illegal_instruction + and al,1111b + mov [segment_register],al + call store_segment_prefix + or [prefix_flags],1 + jmp continue_line +bnd_prefix_instruction: + stos byte [edi] + or [prefix_flags],1 + 10h + jmp continue_line +int_instruction: + lods byte [esi] + call get_size_operator + cmp ah,1 + ja invalid_operand_size + cmp al,'(' + jne invalid_operand + call get_byte_value + test eax,eax + jns int_imm_ok + call recoverable_overflow + int_imm_ok: + mov ah,al + mov al,0CDh + stos word [edi] + jmp instruction_assembled +aa_instruction: + cmp [code_type],64 + je illegal_instruction + push eax + mov bl,10 + cmp byte [esi],'(' + jne aa_store + inc esi + xor al,al + xchg al,[operand_size] + cmp al,1 + ja invalid_operand_size + call get_byte_value + mov bl,al + aa_store: + cmp [operand_size],0 + jne invalid_operand + pop eax + mov ah,bl + stos word [edi] + jmp instruction_assembled + +basic_instruction: + mov [base_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + je basic_reg + cmp al,'[' + jne invalid_operand + basic_mem: + call get_address + push edx ebx ecx + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'(' + je basic_mem_imm + cmp al,10h + jne invalid_operand + basic_mem_reg: + lods byte [esi] + call convert_register + mov [postbyte_register],al + pop ecx ebx edx + mov al,ah + cmp al,1 + je instruction_ready + call operand_autodetect + inc [base_code] + instruction_ready: + call store_instruction + jmp instruction_assembled + basic_mem_imm: + mov al,[operand_size] + cmp al,1 + jb basic_mem_imm_nosize + je basic_mem_imm_8bit + cmp al,2 + je basic_mem_imm_16bit + cmp al,4 + je basic_mem_imm_32bit + cmp al,8 + jne invalid_operand_size + basic_mem_imm_64bit: + cmp [size_declared],0 + jne long_immediate_not_encodable + call operand_64bit + call get_simm32 + cmp [value_type],4 + jae long_immediate_not_encodable + jmp basic_mem_imm_32bit_ok + basic_mem_imm_nosize: + call recoverable_unknown_size + basic_mem_imm_8bit: + call get_byte_value + mov byte [value],al + mov al,[base_code] + shr al,3 + mov [postbyte_register],al + pop ecx ebx edx + mov [base_code],80h + call store_instruction_with_imm8 + jmp instruction_assembled + basic_mem_imm_16bit: + call operand_16bit + call get_word_value + mov word [value],ax + mov al,[base_code] + shr al,3 + mov [postbyte_register],al + pop ecx ebx edx + cmp [value_type],0 + jne basic_mem_imm_16bit_store + cmp [size_declared],0 + jne basic_mem_imm_16bit_store + cmp word [value],80h + jb basic_mem_simm_8bit + cmp word [value],-80h + jae basic_mem_simm_8bit + basic_mem_imm_16bit_store: + mov [base_code],81h + call store_instruction_with_imm16 + jmp instruction_assembled + basic_mem_simm_8bit: + mov [base_code],83h + call store_instruction_with_imm8 + jmp instruction_assembled + basic_mem_imm_32bit: + call operand_32bit + call get_dword_value + basic_mem_imm_32bit_ok: + mov dword [value],eax + mov al,[base_code] + shr al,3 + mov [postbyte_register],al + pop ecx ebx edx + cmp [value_type],0 + jne basic_mem_imm_32bit_store + cmp [size_declared],0 + jne basic_mem_imm_32bit_store + cmp dword [value],80h + jb basic_mem_simm_8bit + cmp dword [value],-80h + jae basic_mem_simm_8bit + basic_mem_imm_32bit_store: + mov [base_code],81h + call store_instruction_with_imm32 + jmp instruction_assembled + get_simm32: + call get_qword_value + mov ecx,edx + cdq + cmp ecx,edx + je simm32_range_ok + call recoverable_overflow + simm32_range_ok: + cmp [value_type],4 + jne get_simm32_ok + mov [value_type],2 + get_simm32_ok: + ret + basic_reg: + lods byte [esi] + call convert_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je basic_reg_reg + cmp al,'(' + je basic_reg_imm + cmp al,'[' + jne invalid_operand + basic_reg_mem: + call get_address + mov al,[operand_size] + cmp al,1 + je basic_reg_mem_8bit + call operand_autodetect + add [base_code],3 + jmp instruction_ready + basic_reg_mem_8bit: + add [base_code],2 + jmp instruction_ready + basic_reg_reg: + lods byte [esi] + call convert_register + mov bl,[postbyte_register] + mov [postbyte_register],al + mov al,ah + cmp al,1 + je nomem_instruction_ready + call operand_autodetect + inc [base_code] + nomem_instruction_ready: + call store_nomem_instruction + jmp instruction_assembled + basic_reg_imm: + mov al,[operand_size] + cmp al,1 + je basic_reg_imm_8bit + cmp al,2 + je basic_reg_imm_16bit + cmp al,4 + je basic_reg_imm_32bit + cmp al,8 + jne invalid_operand_size + basic_reg_imm_64bit: + cmp [size_declared],0 + jne long_immediate_not_encodable + call operand_64bit + call get_simm32 + cmp [value_type],4 + jae long_immediate_not_encodable + jmp basic_reg_imm_32bit_ok + basic_reg_imm_8bit: + call get_byte_value + mov dl,al + mov bl,[base_code] + shr bl,3 + xchg bl,[postbyte_register] + or bl,bl + jz basic_al_imm + mov [base_code],80h + call store_nomem_instruction + mov al,dl + stos byte [edi] + jmp instruction_assembled + basic_al_imm: + mov al,[base_code] + add al,4 + stos byte [edi] + mov al,dl + stos byte [edi] + jmp instruction_assembled + basic_reg_imm_16bit: + call operand_16bit + call get_word_value + mov dx,ax + mov bl,[base_code] + shr bl,3 + xchg bl,[postbyte_register] + cmp [value_type],0 + jne basic_reg_imm_16bit_store + cmp [size_declared],0 + jne basic_reg_imm_16bit_store + cmp dx,80h + jb basic_reg_simm_8bit + cmp dx,-80h + jae basic_reg_simm_8bit + basic_reg_imm_16bit_store: + or bl,bl + jz basic_ax_imm + mov [base_code],81h + call store_nomem_instruction + basic_store_imm_16bit: + mov ax,dx + call mark_relocation + stos word [edi] + jmp instruction_assembled + basic_reg_simm_8bit: + mov [base_code],83h + call store_nomem_instruction + mov al,dl + stos byte [edi] + jmp instruction_assembled + basic_ax_imm: + add [base_code],5 + call store_classic_instruction_code + jmp basic_store_imm_16bit + basic_reg_imm_32bit: + call operand_32bit + call get_dword_value + basic_reg_imm_32bit_ok: + mov edx,eax + mov bl,[base_code] + shr bl,3 + xchg bl,[postbyte_register] + cmp [value_type],0 + jne basic_reg_imm_32bit_store + cmp [size_declared],0 + jne basic_reg_imm_32bit_store + cmp edx,80h + jb basic_reg_simm_8bit + cmp edx,-80h + jae basic_reg_simm_8bit + basic_reg_imm_32bit_store: + or bl,bl + jz basic_eax_imm + mov [base_code],81h + call store_nomem_instruction + basic_store_imm_32bit: + mov eax,edx + call mark_relocation + stos dword [edi] + jmp instruction_assembled + basic_eax_imm: + add [base_code],5 + call store_classic_instruction_code + jmp basic_store_imm_32bit + recoverable_unknown_size: + cmp [error_line],0 + jne ignore_unknown_size + push [current_line] + pop [error_line] + mov [error],operand_size_not_specified + ignore_unknown_size: + ret +single_operand_instruction: + mov [base_code],0F6h + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,10h + je single_reg + cmp al,'[' + jne invalid_operand + single_mem: + call get_address + mov al,[operand_size] + cmp al,1 + je single_mem_8bit + jb single_mem_nosize + call operand_autodetect + inc [base_code] + jmp instruction_ready + single_mem_nosize: + call recoverable_unknown_size + single_mem_8bit: + jmp instruction_ready + single_reg: + lods byte [esi] + call convert_register + mov bl,al + mov al,ah + cmp al,1 + je single_reg_8bit + call operand_autodetect + inc [base_code] + single_reg_8bit: + jmp nomem_instruction_ready +mov_instruction: + mov [base_code],88h + lods byte [esi] + call get_size_operator + cmp al,10h + je mov_reg + cmp al,14h + je mov_creg + cmp al,'[' + jne invalid_operand + mov_mem: + call get_address + push edx ebx ecx + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'(' + je mov_mem_imm + cmp al,10h + jne invalid_operand + mov_mem_reg: + lods byte [esi] + cmp al,30h + jb mov_mem_general_reg + cmp al,40h + jb mov_mem_sreg + mov_mem_general_reg: + call convert_register + mov [postbyte_register],al + pop ecx ebx edx + cmp ah,1 + je mov_mem_reg_8bit + inc [base_code] + mov al,ah + call operand_autodetect + mov al,[postbyte_register] + or al,bl + or al,bh + jz mov_mem_ax + jmp instruction_ready + mov_mem_reg_8bit: + or al,bl + or al,bh + jnz instruction_ready + mov_mem_al: + test ch,22h + jnz mov_mem_address16_al + test ch,44h + jnz mov_mem_address32_al + test ch,not 88h + jnz invalid_address_size + call check_mov_address64 + cmp al,0 + jg mov_mem_address64_al + jl instruction_ready + cmp [code_type],16 + jne mov_mem_address32_al + cmp edx,10000h + jb mov_mem_address16_al + mov_mem_address32_al: + call store_segment_prefix_if_necessary + call address_32bit_prefix + mov [base_code],0A2h + store_mov_address32: + call store_classic_instruction_code + call store_address_32bit_value + jmp instruction_assembled + mov_mem_address16_al: + call store_segment_prefix_if_necessary + call address_16bit_prefix + mov [base_code],0A2h + store_mov_address16: + cmp [code_type],64 + je invalid_address + call store_classic_instruction_code + mov eax,edx + stos word [edi] + cmp edx,10000h + jge value_out_of_range + jmp instruction_assembled + check_mov_address64: + cmp [code_type],64 + jne no_address64 + test ch,88h + jnz address64_required + mov eax,[address_high] + or eax,eax + jz no_address64 + bt edx,31 + adc eax,0 + jz address64_simm32 + address64_required: + mov al,1 + ret + address64_simm32: + mov al,-1 + ret + no_address64: + test ch,08h + jnz invalid_address_size + xor al,al + ret + mov_mem_address64_al: + call store_segment_prefix_if_necessary + mov [base_code],0A2h + store_mov_address64: + call store_classic_instruction_code + call store_address_64bit_value + jmp instruction_assembled + mov_mem_ax: + test ch,22h + jnz mov_mem_address16_ax + test ch,44h + jnz mov_mem_address32_ax + test ch,not 88h + jnz invalid_address_size + call check_mov_address64 + cmp al,0 + jg mov_mem_address64_ax + jl instruction_ready + cmp [code_type],16 + jne mov_mem_address32_ax + cmp edx,10000h + jb mov_mem_address16_ax + mov_mem_address32_ax: + call store_segment_prefix_if_necessary + call address_32bit_prefix + mov [base_code],0A3h + jmp store_mov_address32 + mov_mem_address16_ax: + call store_segment_prefix_if_necessary + call address_16bit_prefix + mov [base_code],0A3h + jmp store_mov_address16 + mov_mem_address64_ax: + call store_segment_prefix_if_necessary + mov [base_code],0A3h + jmp store_mov_address64 + mov_mem_sreg: + sub al,31h + mov [postbyte_register],al + pop ecx ebx edx + mov ah,[operand_size] + or ah,ah + jz mov_mem_sreg_store + cmp ah,2 + jne invalid_operand_size + mov_mem_sreg_store: + mov [base_code],8Ch + jmp instruction_ready + mov_mem_imm: + mov al,[operand_size] + cmp al,1 + jb mov_mem_imm_nosize + je mov_mem_imm_8bit + cmp al,2 + je mov_mem_imm_16bit + cmp al,4 + je mov_mem_imm_32bit + cmp al,8 + jne invalid_operand_size + mov_mem_imm_64bit: + cmp [size_declared],0 + jne long_immediate_not_encodable + call operand_64bit + call get_simm32 + cmp [value_type],4 + jae long_immediate_not_encodable + jmp mov_mem_imm_32bit_store + mov_mem_imm_nosize: + call recoverable_unknown_size + mov_mem_imm_8bit: + call get_byte_value + mov byte [value],al + mov [postbyte_register],0 + mov [base_code],0C6h + pop ecx ebx edx + call store_instruction_with_imm8 + jmp instruction_assembled + mov_mem_imm_16bit: + call operand_16bit + call get_word_value + mov word [value],ax + mov [postbyte_register],0 + mov [base_code],0C7h + pop ecx ebx edx + call store_instruction_with_imm16 + jmp instruction_assembled + mov_mem_imm_32bit: + call operand_32bit + call get_dword_value + mov_mem_imm_32bit_store: + mov dword [value],eax + mov [postbyte_register],0 + mov [base_code],0C7h + pop ecx ebx edx + call store_instruction_with_imm32 + jmp instruction_assembled + mov_reg: + lods byte [esi] + mov ah,al + sub ah,10h + and ah,al + test ah,0F0h + jnz mov_sreg + call convert_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + je mov_reg_mem + cmp al,'(' + je mov_reg_imm + cmp al,14h + je mov_reg_creg + cmp al,10h + jne invalid_operand + mov_reg_reg: + lods byte [esi] + mov ah,al + sub ah,10h + and ah,al + test ah,0F0h + jnz mov_reg_sreg + call convert_register + mov bl,[postbyte_register] + mov [postbyte_register],al + mov al,ah + cmp al,1 + je mov_reg_reg_8bit + call operand_autodetect + inc [base_code] + mov_reg_reg_8bit: + jmp nomem_instruction_ready + mov_reg_sreg: + mov bl,[postbyte_register] + mov ah,al + and al,1111b + mov [postbyte_register],al + shr ah,4 + cmp ah,3 + jne invalid_operand + dec [postbyte_register] + cmp [operand_size],8 + je mov_reg_sreg64 + cmp [operand_size],4 + je mov_reg_sreg32 + cmp [operand_size],2 + jne invalid_operand_size + call operand_16bit + jmp mov_reg_sreg_store + mov_reg_sreg64: + call operand_64bit + jmp mov_reg_sreg_store + mov_reg_sreg32: + call operand_32bit + mov_reg_sreg_store: + mov [base_code],8Ch + jmp nomem_instruction_ready + mov_reg_creg: + lods byte [esi] + mov bl,al + shr al,4 + cmp al,4 + ja invalid_operand + add al,20h + mov [extended_code],al + and bl,1111b + xchg bl,[postbyte_register] + mov [base_code],0Fh + cmp [code_type],64 + je mov_reg_creg_64bit + cmp [operand_size],4 + jne invalid_operand_size + cmp [postbyte_register],8 + jne mov_reg_creg_store + cmp [extended_code],20h + jne mov_reg_creg_store + mov al,0F0h + stos byte [edi] + mov [postbyte_register],0 + mov_reg_creg_store: + jmp nomem_instruction_ready + mov_reg_creg_64bit: + cmp [operand_size],8 + jne invalid_operand_size + jmp nomem_instruction_ready + mov_reg_mem: + add [base_code],2 + call get_address + mov al,[operand_size] + cmp al,1 + je mov_reg_mem_8bit + inc [base_code] + call operand_autodetect + mov al,[postbyte_register] + or al,bl + or al,bh + jz mov_ax_mem + jmp instruction_ready + mov_reg_mem_8bit: + mov al,[postbyte_register] + or al,bl + or al,bh + jz mov_al_mem + jmp instruction_ready + mov_al_mem: + test ch,22h + jnz mov_al_mem_address16 + test ch,44h + jnz mov_al_mem_address32 + test ch,not 88h + jnz invalid_address_size + call check_mov_address64 + cmp al,0 + jg mov_al_mem_address64 + jl instruction_ready + cmp [code_type],16 + jne mov_al_mem_address32 + cmp edx,10000h + jb mov_al_mem_address16 + mov_al_mem_address32: + call store_segment_prefix_if_necessary + call address_32bit_prefix + mov [base_code],0A0h + jmp store_mov_address32 + mov_al_mem_address16: + call store_segment_prefix_if_necessary + call address_16bit_prefix + mov [base_code],0A0h + jmp store_mov_address16 + mov_al_mem_address64: + call store_segment_prefix_if_necessary + mov [base_code],0A0h + jmp store_mov_address64 + mov_ax_mem: + test ch,22h + jnz mov_ax_mem_address16 + test ch,44h + jnz mov_ax_mem_address32 + test ch,not 88h + jnz invalid_address_size + call check_mov_address64 + cmp al,0 + jg mov_ax_mem_address64 + jl instruction_ready + cmp [code_type],16 + jne mov_ax_mem_address32 + cmp edx,10000h + jb mov_ax_mem_address16 + mov_ax_mem_address32: + call store_segment_prefix_if_necessary + call address_32bit_prefix + mov [base_code],0A1h + jmp store_mov_address32 + mov_ax_mem_address16: + call store_segment_prefix_if_necessary + call address_16bit_prefix + mov [base_code],0A1h + jmp store_mov_address16 + mov_ax_mem_address64: + call store_segment_prefix_if_necessary + mov [base_code],0A1h + jmp store_mov_address64 + mov_reg_imm: + mov al,[operand_size] + cmp al,1 + je mov_reg_imm_8bit + cmp al,2 + je mov_reg_imm_16bit + cmp al,4 + je mov_reg_imm_32bit + cmp al,8 + jne invalid_operand_size + mov_reg_imm_64bit: + call operand_64bit + call get_qword_value + mov ecx,edx + cmp [size_declared],0 + jne mov_reg_imm_64bit_store + cmp [value_type],4 + jae mov_reg_imm_64bit_store + cdq + cmp ecx,edx + je mov_reg_64bit_imm_32bit + mov_reg_imm_64bit_store: + push eax ecx + mov al,0B8h + call store_mov_reg_imm_code + pop edx eax + call mark_relocation + stos dword [edi] + mov eax,edx + stos dword [edi] + jmp instruction_assembled + mov_reg_imm_8bit: + call get_byte_value + mov dl,al + mov al,0B0h + call store_mov_reg_imm_code + mov al,dl + stos byte [edi] + jmp instruction_assembled + mov_reg_imm_16bit: + call get_word_value + mov dx,ax + call operand_16bit + mov al,0B8h + call store_mov_reg_imm_code + mov ax,dx + call mark_relocation + stos word [edi] + jmp instruction_assembled + mov_reg_imm_32bit: + call operand_32bit + call get_dword_value + mov edx,eax + mov al,0B8h + call store_mov_reg_imm_code + mov_store_imm_32bit: + mov eax,edx + call mark_relocation + stos dword [edi] + jmp instruction_assembled + store_mov_reg_imm_code: + mov ah,[postbyte_register] + test ah,1000b + jz mov_reg_imm_prefix_ok + or [rex_prefix],41h + mov_reg_imm_prefix_ok: + and ah,111b + add al,ah + mov [base_code],al + call store_classic_instruction_code + ret + mov_reg_64bit_imm_32bit: + mov edx,eax + mov bl,[postbyte_register] + mov [postbyte_register],0 + mov [base_code],0C7h + call store_nomem_instruction + jmp mov_store_imm_32bit + mov_sreg: + mov ah,al + and al,1111b + mov [postbyte_register],al + shr ah,4 + cmp ah,3 + jne invalid_operand + cmp al,2 + je illegal_instruction + dec [postbyte_register] + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + je mov_sreg_mem + cmp al,10h + jne invalid_operand + mov_sreg_reg: + lods byte [esi] + call convert_register + or ah,ah + jz mov_sreg_reg_size_ok + cmp ah,2 + jne invalid_operand_size + mov bl,al + mov_sreg_reg_size_ok: + mov [base_code],8Eh + jmp nomem_instruction_ready + mov_sreg_mem: + call get_address + mov al,[operand_size] + or al,al + jz mov_sreg_mem_size_ok + cmp al,2 + jne invalid_operand_size + mov_sreg_mem_size_ok: + mov [base_code],8Eh + jmp instruction_ready + mov_creg: + lods byte [esi] + mov ah,al + shr ah,4 + cmp ah,4 + ja invalid_operand + add ah,22h + mov [extended_code],ah + and al,1111b + mov [postbyte_register],al + mov [base_code],0Fh + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + mov bl,al + cmp [code_type],64 + je mov_creg_64bit + cmp ah,4 + jne invalid_operand_size + cmp [postbyte_register],8 + jne mov_creg_store + cmp [extended_code],22h + jne mov_creg_store + mov al,0F0h + stos byte [edi] + mov [postbyte_register],0 + mov_creg_store: + jmp nomem_instruction_ready + mov_creg_64bit: + cmp ah,8 + je mov_creg_store + jmp invalid_operand_size +test_instruction: + mov [base_code],84h + lods byte [esi] + call get_size_operator + cmp al,10h + je test_reg + cmp al,'[' + jne invalid_operand + test_mem: + call get_address + push edx ebx ecx + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'(' + je test_mem_imm + cmp al,10h + jne invalid_operand + test_mem_reg: + lods byte [esi] + call convert_register + mov [postbyte_register],al + pop ecx ebx edx + mov al,ah + cmp al,1 + je test_mem_reg_8bit + call operand_autodetect + inc [base_code] + test_mem_reg_8bit: + jmp instruction_ready + test_mem_imm: + mov al,[operand_size] + cmp al,1 + jb test_mem_imm_nosize + je test_mem_imm_8bit + cmp al,2 + je test_mem_imm_16bit + cmp al,4 + je test_mem_imm_32bit + cmp al,8 + jne invalid_operand_size + test_mem_imm_64bit: + cmp [size_declared],0 + jne long_immediate_not_encodable + call operand_64bit + call get_simm32 + cmp [value_type],4 + jae long_immediate_not_encodable + jmp test_mem_imm_32bit_store + test_mem_imm_nosize: + call recoverable_unknown_size + test_mem_imm_8bit: + call get_byte_value + mov byte [value],al + mov [postbyte_register],0 + mov [base_code],0F6h + pop ecx ebx edx + call store_instruction_with_imm8 + jmp instruction_assembled + test_mem_imm_16bit: + call operand_16bit + call get_word_value + mov word [value],ax + mov [postbyte_register],0 + mov [base_code],0F7h + pop ecx ebx edx + call store_instruction_with_imm16 + jmp instruction_assembled + test_mem_imm_32bit: + call operand_32bit + call get_dword_value + test_mem_imm_32bit_store: + mov dword [value],eax + mov [postbyte_register],0 + mov [base_code],0F7h + pop ecx ebx edx + call store_instruction_with_imm32 + jmp instruction_assembled + test_reg: + lods byte [esi] + call convert_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + je test_reg_mem + cmp al,'(' + je test_reg_imm + cmp al,10h + jne invalid_operand + test_reg_reg: + lods byte [esi] + call convert_register + mov bl,[postbyte_register] + mov [postbyte_register],al + mov al,ah + cmp al,1 + je test_reg_reg_8bit + call operand_autodetect + inc [base_code] + test_reg_reg_8bit: + jmp nomem_instruction_ready + test_reg_imm: + mov al,[operand_size] + cmp al,1 + je test_reg_imm_8bit + cmp al,2 + je test_reg_imm_16bit + cmp al,4 + je test_reg_imm_32bit + cmp al,8 + jne invalid_operand_size + test_reg_imm_64bit: + cmp [size_declared],0 + jne long_immediate_not_encodable + call operand_64bit + call get_simm32 + cmp [value_type],4 + jae long_immediate_not_encodable + jmp test_reg_imm_32bit_store + test_reg_imm_8bit: + call get_byte_value + mov dl,al + mov bl,[postbyte_register] + mov [postbyte_register],0 + mov [base_code],0F6h + or bl,bl + jz test_al_imm + call store_nomem_instruction + mov al,dl + stos byte [edi] + jmp instruction_assembled + test_al_imm: + mov [base_code],0A8h + call store_classic_instruction_code + mov al,dl + stos byte [edi] + jmp instruction_assembled + test_reg_imm_16bit: + call operand_16bit + call get_word_value + mov dx,ax + mov bl,[postbyte_register] + mov [postbyte_register],0 + mov [base_code],0F7h + or bl,bl + jz test_ax_imm + call store_nomem_instruction + mov ax,dx + call mark_relocation + stos word [edi] + jmp instruction_assembled + test_ax_imm: + mov [base_code],0A9h + call store_classic_instruction_code + mov ax,dx + stos word [edi] + jmp instruction_assembled + test_reg_imm_32bit: + call operand_32bit + call get_dword_value + test_reg_imm_32bit_store: + mov edx,eax + mov bl,[postbyte_register] + mov [postbyte_register],0 + mov [base_code],0F7h + or bl,bl + jz test_eax_imm + call store_nomem_instruction + mov eax,edx + call mark_relocation + stos dword [edi] + jmp instruction_assembled + test_eax_imm: + mov [base_code],0A9h + call store_classic_instruction_code + mov eax,edx + stos dword [edi] + jmp instruction_assembled + test_reg_mem: + call get_address + mov al,[operand_size] + cmp al,1 + je test_reg_mem_8bit + call operand_autodetect + inc [base_code] + test_reg_mem_8bit: + jmp instruction_ready +xchg_instruction: + mov [base_code],86h + lods byte [esi] + call get_size_operator + cmp al,10h + je xchg_reg + cmp al,'[' + jne invalid_operand + xchg_mem: + call get_address + push edx ebx ecx + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je test_mem_reg + jmp invalid_operand + xchg_reg: + lods byte [esi] + call convert_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + je test_reg_mem + cmp al,10h + jne invalid_operand + xchg_reg_reg: + lods byte [esi] + call convert_register + mov bl,al + mov al,ah + cmp al,1 + je xchg_reg_reg_8bit + call operand_autodetect + cmp [postbyte_register],0 + je xchg_ax_reg + or bl,bl + jnz xchg_reg_reg_store + mov bl,[postbyte_register] + xchg_ax_reg: + cmp [code_type],64 + jne xchg_ax_reg_ok + cmp ah,4 + jne xchg_ax_reg_ok + or bl,bl + jz xchg_reg_reg_store + xchg_ax_reg_ok: + test bl,1000b + jz xchg_ax_reg_store + or [rex_prefix],41h + and bl,111b + xchg_ax_reg_store: + add bl,90h + mov [base_code],bl + call store_classic_instruction_code + jmp instruction_assembled + xchg_reg_reg_store: + inc [base_code] + xchg_reg_reg_8bit: + jmp nomem_instruction_ready +push_instruction: + mov [push_size],al + push_next: + lods byte [esi] + call get_size_operator + cmp al,10h + je push_reg + cmp al,'(' + je push_imm + cmp al,'[' + jne invalid_operand + push_mem: + call get_address + mov al,[operand_size] + mov ah,[push_size] + cmp al,2 + je push_mem_16bit + cmp al,4 + je push_mem_32bit + cmp al,8 + je push_mem_64bit + or al,al + jnz invalid_operand_size + cmp ah,2 + je push_mem_16bit + cmp ah,4 + je push_mem_32bit + cmp ah,8 + je push_mem_64bit + call recoverable_unknown_size + jmp push_mem_store + push_mem_16bit: + test ah,not 2 + jnz invalid_operand_size + call operand_16bit + jmp push_mem_store + push_mem_32bit: + test ah,not 4 + jnz invalid_operand_size + cmp [code_type],64 + je illegal_instruction + call operand_32bit + jmp push_mem_store + push_mem_64bit: + test ah,not 8 + jnz invalid_operand_size + cmp [code_type],64 + jne illegal_instruction + push_mem_store: + mov [base_code],0FFh + mov [postbyte_register],110b + call store_instruction + jmp push_done + push_reg: + lods byte [esi] + mov ah,al + sub ah,10h + and ah,al + test ah,0F0h + jnz push_sreg + call convert_register + test al,1000b + jz push_reg_ok + or [rex_prefix],41h + and al,111b + push_reg_ok: + add al,50h + mov [base_code],al + mov al,ah + mov ah,[push_size] + cmp al,2 + je push_reg_16bit + cmp al,4 + je push_reg_32bit + cmp al,8 + jne invalid_operand_size + push_reg_64bit: + test ah,not 8 + jnz invalid_operand_size + cmp [code_type],64 + jne illegal_instruction + jmp push_reg_store + push_reg_32bit: + test ah,not 4 + jnz invalid_operand_size + cmp [code_type],64 + je illegal_instruction + call operand_32bit + jmp push_reg_store + push_reg_16bit: + test ah,not 2 + jnz invalid_operand_size + call operand_16bit + push_reg_store: + call store_classic_instruction_code + jmp push_done + push_sreg: + mov bl,al + mov dl,[operand_size] + mov dh,[push_size] + cmp dl,2 + je push_sreg16 + cmp dl,4 + je push_sreg32 + cmp dl,8 + je push_sreg64 + or dl,dl + jnz invalid_operand_size + cmp dh,2 + je push_sreg16 + cmp dh,4 + je push_sreg32 + cmp dh,8 + je push_sreg64 + jmp push_sreg_store + push_sreg16: + test dh,not 2 + jnz invalid_operand_size + call operand_16bit + jmp push_sreg_store + push_sreg32: + test dh,not 4 + jnz invalid_operand_size + cmp [code_type],64 + je illegal_instruction + call operand_32bit + jmp push_sreg_store + push_sreg64: + test dh,not 8 + jnz invalid_operand_size + cmp [code_type],64 + jne illegal_instruction + push_sreg_store: + mov al,bl + cmp al,40h + jae invalid_operand + sub al,31h + jc invalid_operand + cmp al,4 + jae push_sreg_386 + shl al,3 + add al,6 + mov [base_code],al + cmp [code_type],64 + je illegal_instruction + jmp push_reg_store + push_sreg_386: + sub al,4 + shl al,3 + add al,0A0h + mov [extended_code],al + mov [base_code],0Fh + jmp push_reg_store + push_imm: + mov al,[operand_size] + mov ah,[push_size] + or al,al + je push_imm_size_ok + or ah,ah + je push_imm_size_ok + cmp al,ah + jne invalid_operand_size + push_imm_size_ok: + cmp al,2 + je push_imm_16bit + cmp al,4 + je push_imm_32bit + cmp al,8 + je push_imm_64bit + cmp ah,2 + je push_imm_optimized_16bit + cmp ah,4 + je push_imm_optimized_32bit + cmp ah,8 + je push_imm_optimized_64bit + or al,al + jnz invalid_operand_size + cmp [code_type],16 + je push_imm_optimized_16bit + cmp [code_type],32 + je push_imm_optimized_32bit + push_imm_optimized_64bit: + cmp [code_type],64 + jne illegal_instruction + call get_simm32 + mov edx,eax + cmp [value_type],0 + jne push_imm_32bit_store + cmp eax,-80h + jl push_imm_32bit_store + cmp eax,80h + jge push_imm_32bit_store + jmp push_imm_8bit + push_imm_optimized_32bit: + cmp [code_type],64 + je illegal_instruction + call get_dword_value + mov edx,eax + call operand_32bit + cmp [value_type],0 + jne push_imm_32bit_store + cmp eax,-80h + jl push_imm_32bit_store + cmp eax,80h + jge push_imm_32bit_store + jmp push_imm_8bit + push_imm_optimized_16bit: + call get_word_value + mov dx,ax + call operand_16bit + cmp [value_type],0 + jne push_imm_16bit_store + cmp ax,-80h + jl push_imm_16bit_store + cmp ax,80h + jge push_imm_16bit_store + push_imm_8bit: + mov ah,al + mov [base_code],6Ah + call store_classic_instruction_code + mov al,ah + stos byte [edi] + jmp push_done + push_imm_16bit: + call get_word_value + mov dx,ax + call operand_16bit + push_imm_16bit_store: + mov [base_code],68h + call store_classic_instruction_code + mov ax,dx + call mark_relocation + stos word [edi] + jmp push_done + push_imm_64bit: + cmp [code_type],64 + jne illegal_instruction + call get_simm32 + mov edx,eax + jmp push_imm_32bit_store + push_imm_32bit: + cmp [code_type],64 + je illegal_instruction + call get_dword_value + mov edx,eax + call operand_32bit + push_imm_32bit_store: + mov [base_code],68h + call store_classic_instruction_code + mov eax,edx + call mark_relocation + stos dword [edi] + push_done: + lods byte [esi] + dec esi + cmp al,0Fh + je instruction_assembled + or al,al + jz instruction_assembled +; mov [operand_size],0 +; mov [operand_flags],0 +; mov [operand_prefix],0 +; mov [rex_prefix],0 + and dword [operand_size],0 + jmp push_next +pop_instruction: + mov [push_size],al + pop_next: + lods byte [esi] + call get_size_operator + cmp al,10h + je pop_reg + cmp al,'[' + jne invalid_operand + pop_mem: + call get_address + mov al,[operand_size] + mov ah,[push_size] + cmp al,2 + je pop_mem_16bit + cmp al,4 + je pop_mem_32bit + cmp al,8 + je pop_mem_64bit + or al,al + jnz invalid_operand_size + cmp ah,2 + je pop_mem_16bit + cmp ah,4 + je pop_mem_32bit + cmp ah,8 + je pop_mem_64bit + call recoverable_unknown_size + jmp pop_mem_store + pop_mem_16bit: + test ah,not 2 + jnz invalid_operand_size + call operand_16bit + jmp pop_mem_store + pop_mem_32bit: + test ah,not 4 + jnz invalid_operand_size + cmp [code_type],64 + je illegal_instruction + call operand_32bit + jmp pop_mem_store + pop_mem_64bit: + test ah,not 8 + jnz invalid_operand_size + cmp [code_type],64 + jne illegal_instruction + pop_mem_store: + mov [base_code],08Fh + mov [postbyte_register],0 + call store_instruction + jmp pop_done + pop_reg: + lods byte [esi] + mov ah,al + sub ah,10h + and ah,al + test ah,0F0h + jnz pop_sreg + call convert_register + test al,1000b + jz pop_reg_ok + or [rex_prefix],41h + and al,111b + pop_reg_ok: + add al,58h + mov [base_code],al + mov al,ah + mov ah,[push_size] + cmp al,2 + je pop_reg_16bit + cmp al,4 + je pop_reg_32bit + cmp al,8 + je pop_reg_64bit + jmp invalid_operand_size + pop_reg_64bit: + test ah,not 8 + jnz invalid_operand_size + cmp [code_type],64 + jne illegal_instruction + jmp pop_reg_store + pop_reg_32bit: + test ah,not 4 + jnz invalid_operand_size + cmp [code_type],64 + je illegal_instruction + call operand_32bit + jmp pop_reg_store + pop_reg_16bit: + test ah,not 2 + jnz invalid_operand_size + call operand_16bit + pop_reg_store: + call store_classic_instruction_code + pop_done: + lods byte [esi] + dec esi + cmp al,0Fh + je instruction_assembled + or al,al + jz instruction_assembled +; mov [operand_size],0 +; mov [operand_flags],0 +; mov [operand_prefix],0 +; mov [rex_prefix],0 + and dword [operand_size],0 + jmp pop_next + pop_sreg: + mov dl,[operand_size] + mov dh,[push_size] + cmp al,32h + je pop_cs + mov bl,al + cmp dl,2 + je pop_sreg16 + cmp dl,4 + je pop_sreg32 + cmp dl,8 + je pop_sreg64 + or dl,dl + jnz invalid_operand_size + cmp dh,2 + je pop_sreg16 + cmp dh,4 + je pop_sreg32 + cmp dh,8 + je pop_sreg64 + jmp pop_sreg_store + pop_sreg16: + test dh,not 2 + jnz invalid_operand_size + call operand_16bit + jmp pop_sreg_store + pop_sreg32: + test dh,not 4 + jnz invalid_operand_size + cmp [code_type],64 + je illegal_instruction + call operand_32bit + jmp pop_sreg_store + pop_sreg64: + test dh,not 8 + jnz invalid_operand_size + cmp [code_type],64 + jne illegal_instruction + pop_sreg_store: + mov al,bl + cmp al,40h + jae invalid_operand + sub al,31h + jc invalid_operand + cmp al,4 + jae pop_sreg_386 + shl al,3 + add al,7 + mov [base_code],al + cmp [code_type],64 + je illegal_instruction + jmp pop_reg_store + pop_cs: + cmp [code_type],16 + jne illegal_instruction + cmp dl,2 + je pop_cs_store + or dl,dl + jnz invalid_operand_size + cmp dh,2 + je pop_cs_store + or dh,dh + jnz illegal_instruction + pop_cs_store: + test dh,not 2 + jnz invalid_operand_size + mov al,0Fh + stos byte [edi] + jmp pop_done + pop_sreg_386: + sub al,4 + shl al,3 + add al,0A1h + mov [extended_code],al + mov [base_code],0Fh + jmp pop_reg_store +inc_instruction: + mov [base_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + je inc_reg + cmp al,'[' + je inc_mem + jne invalid_operand + inc_mem: + call get_address + mov al,[operand_size] + cmp al,1 + je inc_mem_8bit + jb inc_mem_nosize + call operand_autodetect + mov al,0FFh + xchg al,[base_code] + mov [postbyte_register],al + jmp instruction_ready + inc_mem_nosize: + call recoverable_unknown_size + inc_mem_8bit: + mov al,0FEh + xchg al,[base_code] + mov [postbyte_register],al + jmp instruction_ready + inc_reg: + lods byte [esi] + call convert_register + mov bl,al + mov al,0FEh + xchg al,[base_code] + mov [postbyte_register],al + mov al,ah + cmp al,1 + je inc_reg_8bit + call operand_autodetect + cmp [code_type],64 + je inc_reg_long_form + mov al,[postbyte_register] + shl al,3 + add al,bl + add al,40h + mov [base_code],al + call store_classic_instruction_code + jmp instruction_assembled + inc_reg_long_form: + inc [base_code] + inc_reg_8bit: + jmp nomem_instruction_ready +set_instruction: + mov [base_code],0Fh + mov [extended_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + je set_reg + cmp al,'[' + jne invalid_operand + set_mem: + call get_address + cmp [operand_size],1 + ja invalid_operand_size + mov [postbyte_register],0 + jmp instruction_ready + set_reg: + lods byte [esi] + call convert_register + cmp ah,1 + jne invalid_operand_size + mov bl,al + mov [postbyte_register],0 + jmp nomem_instruction_ready +arpl_instruction: + cmp [code_type],64 + je illegal_instruction + mov [base_code],63h + lods byte [esi] + call get_size_operator + cmp al,10h + je arpl_reg + cmp al,'[' + jne invalid_operand + call get_address + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + mov [postbyte_register],al + cmp ah,2 + jne invalid_operand_size + jmp instruction_ready + arpl_reg: + lods byte [esi] + call convert_register + cmp ah,2 + jne invalid_operand_size + mov bl,al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + mov [postbyte_register],al + jmp nomem_instruction_ready +bound_instruction: + cmp [code_type],64 + je illegal_instruction + call take_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + cmp al,2 + je bound_store + cmp al,4 + jne invalid_operand_size + bound_store: + call operand_autodetect + mov [base_code],62h + jmp instruction_ready +enter_instruction: + lods byte [esi] + call get_size_operator + cmp ah,2 + je enter_imm16_size_ok + or ah,ah + jnz invalid_operand_size + enter_imm16_size_ok: + cmp al,'(' + jne invalid_operand + call get_word_value + cmp [next_pass_needed],0 + jne enter_imm16_ok + cmp [value_type],0 + jne invalid_use_of_symbol + test eax,eax + js value_out_of_range + enter_imm16_ok: + push eax + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp ah,1 + je enter_imm8_size_ok + or ah,ah + jnz invalid_operand_size + enter_imm8_size_ok: + cmp al,'(' + jne invalid_operand + call get_byte_value + cmp [next_pass_needed],0 + jne enter_imm8_ok + test eax,eax + js value_out_of_range + enter_imm8_ok: + mov dl,al + pop ebx + mov al,0C8h + stos byte [edi] + mov ax,bx + stos word [edi] + mov al,dl + stos byte [edi] + jmp instruction_assembled +ret_instruction_only64: + cmp [code_type],64 + jne illegal_instruction + jmp ret_instruction +ret_instruction_32bit_except64: + cmp [code_type],64 + je illegal_instruction +ret_instruction_32bit: + call operand_32bit + jmp ret_instruction +ret_instruction_16bit: + call operand_16bit + jmp ret_instruction +ret_instruction_64bit: + call operand_64bit +ret_instruction: + and [prefix_flags],not 10h + ret_common: + mov [base_code],al + lods byte [esi] + dec esi + or al,al + jz simple_ret + cmp al,0Fh + je simple_ret + lods byte [esi] + call get_size_operator + or ah,ah + jz ret_imm + cmp ah,2 + je ret_imm + jmp invalid_operand_size + ret_imm: + cmp al,'(' + jne invalid_operand + call get_word_value + cmp [next_pass_needed],0 + jne ret_imm_ok + cmp [value_type],0 + jne invalid_use_of_symbol + test eax,eax + js value_out_of_range + ret_imm_ok: + cmp [size_declared],0 + jne ret_imm_store + or ax,ax + jz simple_ret + ret_imm_store: + mov dx,ax + call store_classic_instruction_code + mov ax,dx + stos word [edi] + jmp instruction_assembled + simple_ret: + inc [base_code] + call store_classic_instruction_code + jmp instruction_assembled +retf_instruction: + cmp [code_type],64 + jne ret_common +retf_instruction_64bit: + call operand_64bit + jmp ret_common +retf_instruction_32bit: + call operand_32bit + jmp ret_common +retf_instruction_16bit: + call operand_16bit + jmp ret_common +lea_instruction: + mov [base_code],8Dh + call take_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + xor al,al + xchg al,[operand_size] + push eax + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + or [operand_flags],1 + call get_address + pop eax + mov [operand_size],al + call operand_autodetect + jmp instruction_ready +ls_instruction: + or al,al + jz les_instruction + cmp al,3 + jz lds_instruction + add al,0B0h + mov [extended_code],al + mov [base_code],0Fh + jmp ls_code_ok + les_instruction: + mov [base_code],0C4h + jmp ls_short_code + lds_instruction: + mov [base_code],0C5h + ls_short_code: + cmp [code_type],64 + je illegal_instruction + ls_code_ok: + call take_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + add [operand_size],2 + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + cmp al,4 + je ls_16bit + cmp al,6 + je ls_32bit + cmp al,10 + je ls_64bit + jmp invalid_operand_size + ls_16bit: + call operand_16bit + jmp instruction_ready + ls_32bit: + call operand_32bit + jmp instruction_ready + ls_64bit: + call operand_64bit + jmp instruction_ready +sh_instruction: + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,10h + je sh_reg + cmp al,'[' + jne invalid_operand + sh_mem: + call get_address + push edx ebx ecx + mov al,[operand_size] + push eax + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'(' + je sh_mem_imm + cmp al,10h + jne invalid_operand + sh_mem_reg: + lods byte [esi] + cmp al,11h + jne invalid_operand + pop eax ecx ebx edx + cmp al,1 + je sh_mem_cl_8bit + jb sh_mem_cl_nosize + call operand_autodetect + mov [base_code],0D3h + jmp instruction_ready + sh_mem_cl_nosize: + call recoverable_unknown_size + sh_mem_cl_8bit: + mov [base_code],0D2h + jmp instruction_ready + sh_mem_imm: + mov al,[operand_size] + or al,al + jz sh_mem_imm_size_ok + cmp al,1 + jne invalid_operand_size + sh_mem_imm_size_ok: + call get_byte_value + mov byte [value],al + pop eax ecx ebx edx + cmp al,1 + je sh_mem_imm_8bit + jb sh_mem_imm_nosize + call operand_autodetect + cmp byte [value],1 + je sh_mem_1 + mov [base_code],0C1h + call store_instruction_with_imm8 + jmp instruction_assembled + sh_mem_1: + mov [base_code],0D1h + jmp instruction_ready + sh_mem_imm_nosize: + call recoverable_unknown_size + sh_mem_imm_8bit: + cmp byte [value],1 + je sh_mem_1_8bit + mov [base_code],0C0h + call store_instruction_with_imm8 + jmp instruction_assembled + sh_mem_1_8bit: + mov [base_code],0D0h + jmp instruction_ready + sh_reg: + lods byte [esi] + call convert_register + mov bx,ax + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'(' + je sh_reg_imm + cmp al,10h + jne invalid_operand + sh_reg_reg: + lods byte [esi] + cmp al,11h + jne invalid_operand + mov al,bh + cmp al,1 + je sh_reg_cl_8bit + call operand_autodetect + mov [base_code],0D3h + jmp nomem_instruction_ready + sh_reg_cl_8bit: + mov [base_code],0D2h + jmp nomem_instruction_ready + sh_reg_imm: + mov al,[operand_size] + or al,al + jz sh_reg_imm_size_ok + cmp al,1 + jne invalid_operand_size + sh_reg_imm_size_ok: + push ebx + call get_byte_value + mov dl,al + pop ebx + mov al,bh + cmp al,1 + je sh_reg_imm_8bit + call operand_autodetect + cmp dl,1 + je sh_reg_1 + mov [base_code],0C1h + call store_nomem_instruction + mov al,dl + stos byte [edi] + jmp instruction_assembled + sh_reg_1: + mov [base_code],0D1h + jmp nomem_instruction_ready + sh_reg_imm_8bit: + cmp dl,1 + je sh_reg_1_8bit + mov [base_code],0C0h + call store_nomem_instruction + mov al,dl + stos byte [edi] + jmp instruction_assembled + sh_reg_1_8bit: + mov [base_code],0D0h + jmp nomem_instruction_ready +shd_instruction: + mov [base_code],0Fh + mov [extended_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + je shd_reg + cmp al,'[' + jne invalid_operand + shd_mem: + call get_address + push edx ebx ecx + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + mov al,ah + mov [operand_size],0 + push eax + lods byte [esi] + call get_size_operator + cmp al,'(' + je shd_mem_reg_imm + cmp al,10h + jne invalid_operand + lods byte [esi] + cmp al,11h + jne invalid_operand + pop eax ecx ebx edx + call operand_autodetect + inc [extended_code] + jmp instruction_ready + shd_mem_reg_imm: + mov al,[operand_size] + or al,al + jz shd_mem_reg_imm_size_ok + cmp al,1 + jne invalid_operand_size + shd_mem_reg_imm_size_ok: + call get_byte_value + mov byte [value],al + pop eax ecx ebx edx + call operand_autodetect + call store_instruction_with_imm8 + jmp instruction_assembled + shd_reg: + lods byte [esi] + call convert_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + mov bl,[postbyte_register] + mov [postbyte_register],al + mov al,ah + push eax ebx + lods byte [esi] + cmp al,',' + jne invalid_operand + mov [operand_size],0 + lods byte [esi] + call get_size_operator + cmp al,'(' + je shd_reg_reg_imm + cmp al,10h + jne invalid_operand + lods byte [esi] + cmp al,11h + jne invalid_operand + pop ebx eax + call operand_autodetect + inc [extended_code] + jmp nomem_instruction_ready + shd_reg_reg_imm: + mov al,[operand_size] + or al,al + jz shd_reg_reg_imm_size_ok + cmp al,1 + jne invalid_operand_size + shd_reg_reg_imm_size_ok: + call get_byte_value + mov dl,al + pop ebx eax + call operand_autodetect + call store_nomem_instruction + mov al,dl + stos byte [edi] + jmp instruction_assembled +movx_instruction: + mov [base_code],0Fh + mov [extended_code],al + call take_register + mov [postbyte_register],al + mov al,ah + push eax + lods byte [esi] + cmp al,',' + jne invalid_operand + mov [operand_size],0 + lods byte [esi] + call get_size_operator + cmp al,10h + je movx_reg + cmp al,'[' + jne invalid_operand + call get_address + pop eax + mov ah,[operand_size] + or ah,ah + jz movx_unknown_size + cmp ah,al + jae invalid_operand_size + cmp ah,1 + je movx_mem_store + cmp ah,2 + jne invalid_operand_size + inc [extended_code] + movx_mem_store: + call operand_autodetect + jmp instruction_ready + movx_unknown_size: + cmp al,2 + je movx_mem_store + call recoverable_unknown_size + jmp movx_mem_store + movx_reg: + lods byte [esi] + call convert_register + pop ebx + xchg bl,al + cmp ah,al + jae invalid_operand_size + cmp ah,1 + je movx_reg_8bit + cmp ah,2 + je movx_reg_16bit + jmp invalid_operand_size + movx_reg_8bit: + call operand_autodetect + jmp nomem_instruction_ready + movx_reg_16bit: + call operand_autodetect + inc [extended_code] + jmp nomem_instruction_ready +movsxd_instruction: + mov [base_code],al + call take_register + mov [postbyte_register],al + cmp ah,8 + jne invalid_operand_size + lods byte [esi] + cmp al,',' + jne invalid_operand + mov [operand_size],0 + lods byte [esi] + call get_size_operator + cmp al,10h + je movsxd_reg + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],4 + je movsxd_mem_store + cmp [operand_size],0 + jne invalid_operand_size + movsxd_mem_store: + call operand_64bit + jmp instruction_ready + movsxd_reg: + lods byte [esi] + call convert_register + cmp ah,4 + jne invalid_operand_size + mov bl,al + call operand_64bit + jmp nomem_instruction_ready +bt_instruction: + mov [postbyte_register],al + shl al,3 + add al,83h + mov [extended_code],al + mov [base_code],0Fh + lods byte [esi] + call get_size_operator + cmp al,10h + je bt_reg + cmp al,'[' + jne invalid_operand + call get_address + push eax ebx ecx + lods byte [esi] + cmp al,',' + jne invalid_operand + cmp byte [esi],'(' + je bt_mem_imm + cmp byte [esi],11h + jne bt_mem_reg + cmp byte [esi+2],'(' + je bt_mem_imm + bt_mem_reg: + call take_register + mov [postbyte_register],al + pop ecx ebx edx + mov al,ah + call operand_autodetect + jmp instruction_ready + bt_mem_imm: + xor al,al + xchg al,[operand_size] + push eax + lods byte [esi] + call get_size_operator + cmp al,'(' + jne invalid_operand + mov al,[operand_size] + or al,al + jz bt_mem_imm_size_ok + cmp al,1 + jne invalid_operand_size + bt_mem_imm_size_ok: + call get_byte_value + mov byte [value],al + pop eax + or al,al + jz bt_mem_imm_nosize + call operand_autodetect + bt_mem_imm_store: + pop ecx ebx edx + mov [extended_code],0BAh + call store_instruction_with_imm8 + jmp instruction_assembled + bt_mem_imm_nosize: + call recoverable_unknown_size + jmp bt_mem_imm_store + bt_reg: + lods byte [esi] + call convert_register + mov bl,al + lods byte [esi] + cmp al,',' + jne invalid_operand + cmp byte [esi],'(' + je bt_reg_imm + cmp byte [esi],11h + jne bt_reg_reg + cmp byte [esi+2],'(' + je bt_reg_imm + bt_reg_reg: + call take_register + mov [postbyte_register],al + mov al,ah + call operand_autodetect + jmp nomem_instruction_ready + bt_reg_imm: + xor al,al + xchg al,[operand_size] + push eax ebx + lods byte [esi] + call get_size_operator + cmp al,'(' + jne invalid_operand + mov al,[operand_size] + or al,al + jz bt_reg_imm_size_ok + cmp al,1 + jne invalid_operand_size + bt_reg_imm_size_ok: + call get_byte_value + mov byte [value],al + pop ebx eax + call operand_autodetect + bt_reg_imm_store: + mov [extended_code],0BAh + call store_nomem_instruction + mov al,byte [value] + stos byte [edi] + jmp instruction_assembled +bs_instruction: + mov [extended_code],al + mov [base_code],0Fh + call get_reg_mem + jc bs_reg_reg + mov al,[operand_size] + call operand_autodetect + jmp instruction_ready + bs_reg_reg: + mov al,ah + call operand_autodetect + jmp nomem_instruction_ready + get_reg_mem: + call take_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je get_reg_reg + cmp al,'[' + jne invalid_argument + call get_address + clc + ret + get_reg_reg: + lods byte [esi] + call convert_register + mov bl,al + stc + ret +ud_instruction: + mov [extended_code],al + mov [base_code],0Fh + call get_reg_mem + jc ud_reg_reg + cmp [operand_size],4 + jne invalid_operand_size + jmp instruction_ready + ud_reg_reg: + cmp ah,4 + jne invalid_operand_size + jmp nomem_instruction_ready + +imul_instruction: + mov [base_code],0F6h + mov [postbyte_register],5 + lods byte [esi] + call get_size_operator + cmp al,10h + je imul_reg + cmp al,'[' + jne invalid_operand + imul_mem: + call get_address + mov al,[operand_size] + cmp al,1 + je imul_mem_8bit + jb imul_mem_nosize + call operand_autodetect + inc [base_code] + jmp instruction_ready + imul_mem_nosize: + call recoverable_unknown_size + imul_mem_8bit: + jmp instruction_ready + imul_reg: + lods byte [esi] + call convert_register + cmp byte [esi],',' + je imul_reg_ + mov bl,al + mov al,ah + cmp al,1 + je imul_reg_8bit + call operand_autodetect + inc [base_code] + imul_reg_8bit: + jmp nomem_instruction_ready + imul_reg_: + mov [postbyte_register],al + inc esi + cmp byte [esi],'(' + je imul_reg_imm + cmp byte [esi],11h + jne imul_reg_noimm + cmp byte [esi+2],'(' + je imul_reg_imm + imul_reg_noimm: + lods byte [esi] + call get_size_operator + cmp al,10h + je imul_reg_reg + cmp al,'[' + jne invalid_operand + imul_reg_mem: + call get_address + push edx ebx ecx + cmp byte [esi],',' + je imul_reg_mem_imm + mov al,[operand_size] + call operand_autodetect + pop ecx ebx edx + mov [base_code],0Fh + mov [extended_code],0AFh + jmp instruction_ready + imul_reg_mem_imm: + inc esi + lods byte [esi] + call get_size_operator + cmp al,'(' + jne invalid_operand + mov al,[operand_size] + cmp al,2 + je imul_reg_mem_imm_16bit + cmp al,4 + je imul_reg_mem_imm_32bit + cmp al,8 + jne invalid_operand_size + imul_reg_mem_imm_64bit: + cmp [size_declared],0 + jne long_immediate_not_encodable + call operand_64bit + call get_simm32 + cmp [value_type],4 + jae long_immediate_not_encodable + jmp imul_reg_mem_imm_32bit_ok + imul_reg_mem_imm_16bit: + call operand_16bit + call get_word_value + mov word [value],ax + cmp [value_type],0 + jne imul_reg_mem_imm_16bit_store + cmp [size_declared],0 + jne imul_reg_mem_imm_16bit_store + cmp ax,-80h + jl imul_reg_mem_imm_16bit_store + cmp ax,80h + jl imul_reg_mem_imm_8bit_store + imul_reg_mem_imm_16bit_store: + pop ecx ebx edx + mov [base_code],69h + call store_instruction_with_imm16 + jmp instruction_assembled + imul_reg_mem_imm_32bit: + call operand_32bit + call get_dword_value + imul_reg_mem_imm_32bit_ok: + mov dword [value],eax + cmp [value_type],0 + jne imul_reg_mem_imm_32bit_store + cmp [size_declared],0 + jne imul_reg_mem_imm_32bit_store + cmp eax,-80h + jl imul_reg_mem_imm_32bit_store + cmp eax,80h + jl imul_reg_mem_imm_8bit_store + imul_reg_mem_imm_32bit_store: + pop ecx ebx edx + mov [base_code],69h + call store_instruction_with_imm32 + jmp instruction_assembled + imul_reg_mem_imm_8bit_store: + pop ecx ebx edx + mov [base_code],6Bh + call store_instruction_with_imm8 + jmp instruction_assembled + imul_reg_imm: + mov bl,[postbyte_register] + dec esi + jmp imul_reg_reg_imm + imul_reg_reg: + lods byte [esi] + call convert_register + mov bl,al + cmp byte [esi],',' + je imul_reg_reg_imm + mov al,ah + call operand_autodetect + mov [base_code],0Fh + mov [extended_code],0AFh + jmp nomem_instruction_ready + imul_reg_reg_imm: + inc esi + lods byte [esi] + call get_size_operator + cmp al,'(' + jne invalid_operand + mov al,[operand_size] + cmp al,2 + je imul_reg_reg_imm_16bit + cmp al,4 + je imul_reg_reg_imm_32bit + cmp al,8 + jne invalid_operand_size + imul_reg_reg_imm_64bit: + cmp [size_declared],0 + jne long_immediate_not_encodable + call operand_64bit + push ebx + call get_simm32 + cmp [value_type],4 + jae long_immediate_not_encodable + jmp imul_reg_reg_imm_32bit_ok + imul_reg_reg_imm_16bit: + call operand_16bit + push ebx + call get_word_value + pop ebx + mov dx,ax + cmp [value_type],0 + jne imul_reg_reg_imm_16bit_store + cmp [size_declared],0 + jne imul_reg_reg_imm_16bit_store + cmp ax,-80h + jl imul_reg_reg_imm_16bit_store + cmp ax,80h + jl imul_reg_reg_imm_8bit_store + imul_reg_reg_imm_16bit_store: + mov [base_code],69h + call store_nomem_instruction + mov ax,dx + call mark_relocation + stos word [edi] + jmp instruction_assembled + imul_reg_reg_imm_32bit: + call operand_32bit + push ebx + call get_dword_value + imul_reg_reg_imm_32bit_ok: + pop ebx + mov edx,eax + cmp [value_type],0 + jne imul_reg_reg_imm_32bit_store + cmp [size_declared],0 + jne imul_reg_reg_imm_32bit_store + cmp eax,-80h + jl imul_reg_reg_imm_32bit_store + cmp eax,80h + jl imul_reg_reg_imm_8bit_store + imul_reg_reg_imm_32bit_store: + mov [base_code],69h + call store_nomem_instruction + mov eax,edx + call mark_relocation + stos dword [edi] + jmp instruction_assembled + imul_reg_reg_imm_8bit_store: + mov [base_code],6Bh + call store_nomem_instruction + mov al,dl + stos byte [edi] + jmp instruction_assembled +in_instruction: + call take_register + or al,al + jnz invalid_operand + lods byte [esi] + cmp al,',' + jne invalid_operand + mov al,ah + push eax + mov [operand_size],0 + lods byte [esi] + call get_size_operator + cmp al,'(' + je in_imm + cmp al,10h + je in_reg + jmp invalid_operand + in_reg: + lods byte [esi] + cmp al,22h + jne invalid_operand + pop eax + cmp al,1 + je in_al_dx + cmp al,2 + je in_ax_dx + cmp al,4 + jne invalid_operand_size + in_ax_dx: + call operand_autodetect + mov [base_code],0EDh + call store_classic_instruction_code + jmp instruction_assembled + in_al_dx: + mov al,0ECh + stos byte [edi] + jmp instruction_assembled + in_imm: + mov al,[operand_size] + or al,al + jz in_imm_size_ok + cmp al,1 + jne invalid_operand_size + in_imm_size_ok: + call get_byte_value + mov dl,al + pop eax + cmp al,1 + je in_al_imm + cmp al,2 + je in_ax_imm + cmp al,4 + jne invalid_operand_size + in_ax_imm: + call operand_autodetect + mov [base_code],0E5h + call store_classic_instruction_code + mov al,dl + stos byte [edi] + jmp instruction_assembled + in_al_imm: + mov al,0E4h + stos byte [edi] + mov al,dl + stos byte [edi] + jmp instruction_assembled +out_instruction: + lods byte [esi] + call get_size_operator + cmp al,'(' + je out_imm + cmp al,10h + jne invalid_operand + lods byte [esi] + cmp al,22h + jne invalid_operand + lods byte [esi] + cmp al,',' + jne invalid_operand + mov [operand_size],0 + call take_register + or al,al + jnz invalid_operand + mov al,ah + cmp al,1 + je out_dx_al + cmp al,2 + je out_dx_ax + cmp al,4 + jne invalid_operand_size + out_dx_ax: + call operand_autodetect + mov [base_code],0EFh + call store_classic_instruction_code + jmp instruction_assembled + out_dx_al: + mov al,0EEh + stos byte [edi] + jmp instruction_assembled + out_imm: + mov al,[operand_size] + or al,al + jz out_imm_size_ok + cmp al,1 + jne invalid_operand_size + out_imm_size_ok: + call get_byte_value + mov dl,al + lods byte [esi] + cmp al,',' + jne invalid_operand + mov [operand_size],0 + call take_register + or al,al + jnz invalid_operand + mov al,ah + cmp al,1 + je out_imm_al + cmp al,2 + je out_imm_ax + cmp al,4 + jne invalid_operand_size + out_imm_ax: + call operand_autodetect + mov [base_code],0E7h + call store_classic_instruction_code + mov al,dl + stos byte [edi] + jmp instruction_assembled + out_imm_al: + mov al,0E6h + stos byte [edi] + mov al,dl + stos byte [edi] + jmp instruction_assembled + +call_instruction: + mov [postbyte_register],10b + mov [base_code],0E8h + mov [extended_code],9Ah + jmp process_jmp +jmp_instruction: + mov [postbyte_register],100b + mov [base_code],0E9h + mov [extended_code],0EAh + process_jmp: + lods byte [esi] + call get_jump_operator + test [prefix_flags],10h + jz jmp_type_ok + test [jump_type],not 2 + jnz illegal_instruction + mov [jump_type],2 + and [prefix_flags],not 10h + jmp_type_ok: + call get_size_operator + cmp al,'(' + je jmp_imm + mov [base_code],0FFh + cmp al,10h + je jmp_reg + cmp al,'[' + jne invalid_operand + jmp_mem: + cmp [jump_type],1 + je illegal_instruction + call get_address + mov edx,eax + mov al,[operand_size] + or al,al + jz jmp_mem_size_not_specified + cmp al,2 + je jmp_mem_16bit + cmp al,4 + je jmp_mem_32bit + cmp al,6 + je jmp_mem_48bit + cmp al,8 + je jmp_mem_64bit + cmp al,10 + je jmp_mem_80bit + jmp invalid_operand_size + jmp_mem_size_not_specified: + cmp [jump_type],3 + je jmp_mem_far + cmp [jump_type],2 + je jmp_mem_near + call recoverable_unknown_size + jmp_mem_near: + cmp [code_type],16 + je jmp_mem_16bit + cmp [code_type],32 + je jmp_mem_near_32bit + jmp_mem_64bit: + cmp [jump_type],3 + je invalid_operand_size + cmp [code_type],64 + jne illegal_instruction + jmp instruction_ready + jmp_mem_far: + cmp [code_type],16 + je jmp_mem_far_32bit + jmp_mem_48bit: + call operand_32bit + jmp_mem_far_store: + cmp [jump_type],2 + je invalid_operand_size + inc [postbyte_register] + jmp instruction_ready + jmp_mem_80bit: + call operand_64bit + jmp jmp_mem_far_store + jmp_mem_far_32bit: + call operand_16bit + jmp jmp_mem_far_store + jmp_mem_32bit: + cmp [jump_type],3 + je jmp_mem_far_32bit + cmp [jump_type],2 + je jmp_mem_near_32bit + cmp [code_type],16 + je jmp_mem_far_32bit + jmp_mem_near_32bit: + cmp [code_type],64 + je illegal_instruction + call operand_32bit + jmp instruction_ready + jmp_mem_16bit: + cmp [jump_type],3 + je invalid_operand_size + call operand_16bit + jmp instruction_ready + jmp_reg: + test [jump_type],1 + jnz invalid_operand + lods byte [esi] + call convert_register + mov bl,al + mov al,ah + cmp al,2 + je jmp_reg_16bit + cmp al,4 + je jmp_reg_32bit + cmp al,8 + jne invalid_operand_size + jmp_reg_64bit: + cmp [code_type],64 + jne illegal_instruction + jmp nomem_instruction_ready + jmp_reg_32bit: + cmp [code_type],64 + je illegal_instruction + call operand_32bit + jmp nomem_instruction_ready + jmp_reg_16bit: + call operand_16bit + jmp nomem_instruction_ready + jmp_imm: + cmp byte [esi],'.' + je invalid_value + mov ebx,esi + dec esi + call skip_symbol + xchg esi,ebx + cmp byte [ebx],':' + je jmp_far + cmp [jump_type],3 + je invalid_operand + jmp_near: + mov al,[operand_size] + cmp al,2 + je jmp_imm_16bit + cmp al,4 + je jmp_imm_32bit + cmp al,8 + je jmp_imm_64bit + or al,al + jnz invalid_operand_size + cmp [code_type],16 + je jmp_imm_16bit + cmp [code_type],64 + je jmp_imm_64bit + jmp_imm_32bit: + cmp [code_type],64 + je invalid_operand_size + call get_address_dword_value + cmp [code_type],16 + jne jmp_imm_32bit_prefix_ok + mov byte [edi],66h + inc edi + jmp_imm_32bit_prefix_ok: + call calculate_jump_offset + cdq + call check_for_short_jump + jc jmp_short + jmp_imm_32bit_store: + mov edx,eax + sub edx,3 + jno jmp_imm_32bit_ok + cmp [code_type],64 + je jump_out_of_range + jmp_imm_32bit_ok: + mov al,[base_code] + stos byte [edi] + mov eax,edx + call mark_relocation + stos dword [edi] + jmp instruction_assembled + jmp_imm_64bit: + cmp [code_type],64 + jne invalid_operand_size + call get_address_qword_value + call calculate_jump_offset + mov ecx,edx + cdq + cmp edx,ecx + jne jump_out_of_range + call check_for_short_jump + jnc jmp_imm_32bit_store + jmp_short: + mov ah,al + mov al,0EBh + stos word [edi] + jmp instruction_assembled + jmp_imm_16bit: + call get_address_word_value + cmp [code_type],16 + je jmp_imm_16bit_prefix_ok + mov byte [edi],66h + inc edi + jmp_imm_16bit_prefix_ok: + call calculate_jump_offset + cwde + cdq + call check_for_short_jump + jc jmp_short + cmp [value_type],0 + jne invalid_use_of_symbol + mov edx,eax + dec edx + mov al,[base_code] + stos byte [edi] + mov eax,edx + stos word [edi] + jmp instruction_assembled + calculate_jump_offset: + add edi,2 + mov ebp,[addressing_space] + call calculate_relative_offset + sub edi,2 + ret + check_for_short_jump: + cmp [jump_type],1 + je forced_short + ja no_short_jump + cmp [base_code],0E8h + je no_short_jump + cmp [value_type],0 + jne no_short_jump + cmp eax,80h + jb short_jump + cmp eax,-80h + jae short_jump + no_short_jump: + clc + ret + forced_short: + cmp [base_code],0E8h + je illegal_instruction + cmp [next_pass_needed],0 + jne jmp_short_value_type_ok + cmp [value_type],0 + jne invalid_use_of_symbol + jmp_short_value_type_ok: + cmp eax,-80h + jae short_jump + cmp eax,80h + jae jump_out_of_range + short_jump: + stc + ret + jump_out_of_range: + cmp [error_line],0 + jne instruction_assembled + mov eax,[current_line] + mov [error_line],eax + mov [error],relative_jump_out_of_range + jmp instruction_assembled + jmp_far: + cmp [jump_type],2 + je invalid_operand + cmp [code_type],64 + je illegal_instruction + mov al,[extended_code] + mov [base_code],al + call get_word_value + push eax + inc esi + lods byte [esi] + cmp al,'(' + jne invalid_operand + mov al,[value_type] + push eax + push [symbol_identifier] + cmp byte [esi],'.' + je invalid_value + mov al,[operand_size] + cmp al,4 + je jmp_far_16bit + cmp al,6 + je jmp_far_32bit + or al,al + jnz invalid_operand_size + cmp [code_type],16 + jne jmp_far_32bit + jmp_far_16bit: + call get_word_value + mov ebx,eax + call operand_16bit + call store_classic_instruction_code + mov ax,bx + call mark_relocation + stos word [edi] + jmp_far_segment: + pop [symbol_identifier] + pop eax + mov [value_type],al + pop eax + call mark_relocation + stos word [edi] + jmp instruction_assembled + jmp_far_32bit: + call get_dword_value + mov ebx,eax + call operand_32bit + call store_classic_instruction_code + mov eax,ebx + call mark_relocation + stos dword [edi] + jmp jmp_far_segment +conditional_jump: + mov [base_code],al + and [prefix_flags],not 10h + lods byte [esi] + call get_jump_operator + cmp [jump_type],3 + je invalid_operand + call get_size_operator + cmp al,'(' + jne invalid_operand + cmp byte [esi],'.' + je invalid_value + mov al,[operand_size] + cmp al,2 + je conditional_jump_16bit + cmp al,4 + je conditional_jump_32bit + cmp al,8 + je conditional_jump_64bit + or al,al + jnz invalid_operand_size + cmp [code_type],16 + je conditional_jump_16bit + cmp [code_type],64 + je conditional_jump_64bit + conditional_jump_32bit: + cmp [code_type],64 + je invalid_operand_size + call get_address_dword_value + cmp [code_type],16 + jne conditional_jump_32bit_prefix_ok + mov byte [edi],66h + inc edi + conditional_jump_32bit_prefix_ok: + call calculate_jump_offset + cdq + call check_for_short_jump + jc conditional_jump_short + conditional_jump_32bit_store: + mov edx,eax + sub edx,4 + jno conditional_jump_32bit_range_ok + cmp [code_type],64 + je jump_out_of_range + conditional_jump_32bit_range_ok: + mov ah,[base_code] + add ah,10h + mov al,0Fh + stos word [edi] + mov eax,edx + call mark_relocation + stos dword [edi] + jmp instruction_assembled + conditional_jump_64bit: + cmp [code_type],64 + jne invalid_operand_size + call get_address_qword_value + call calculate_jump_offset + mov ecx,edx + cdq + cmp edx,ecx + jne jump_out_of_range + call check_for_short_jump + jnc conditional_jump_32bit_store + conditional_jump_short: + mov ah,al + mov al,[base_code] + stos word [edi] + jmp instruction_assembled + conditional_jump_16bit: + call get_address_word_value + cmp [code_type],16 + je conditional_jump_16bit_prefix_ok + mov byte [edi],66h + inc edi + conditional_jump_16bit_prefix_ok: + call calculate_jump_offset + cwde + cdq + call check_for_short_jump + jc conditional_jump_short + cmp [value_type],0 + jne invalid_use_of_symbol + mov edx,eax + sub dx,2 + mov ah,[base_code] + add ah,10h + mov al,0Fh + stos word [edi] + mov eax,edx + stos word [edi] + jmp instruction_assembled +loop_instruction_16bit: + cmp [code_type],64 + je illegal_instruction + cmp [code_type],16 + je loop_instruction + mov [operand_prefix],67h + jmp loop_instruction +loop_instruction_32bit: + cmp [code_type],32 + je loop_instruction + mov [operand_prefix],67h + jmp loop_instruction +loop_instruction_64bit: + cmp [code_type],64 + jne illegal_instruction +loop_instruction: + mov [base_code],al + lods byte [esi] + call get_jump_operator + cmp [jump_type],1 + ja invalid_operand + call get_size_operator + cmp al,'(' + jne invalid_operand + cmp byte [esi],'.' + je invalid_value + mov al,[operand_size] + cmp al,2 + je loop_jump_16bit + cmp al,4 + je loop_jump_32bit + cmp al,8 + je loop_jump_64bit + or al,al + jnz invalid_operand_size + cmp [code_type],16 + je loop_jump_16bit + cmp [code_type],64 + je loop_jump_64bit + loop_jump_32bit: + cmp [code_type],64 + je invalid_operand_size + call get_address_dword_value + cmp [code_type],16 + jne loop_jump_32bit_prefix_ok + mov byte [edi],66h + inc edi + loop_jump_32bit_prefix_ok: + call loop_counter_size + call calculate_jump_offset + cdq + make_loop_jump: + call check_for_short_jump + jc conditional_jump_short + scas word [edi] + jmp jump_out_of_range + loop_counter_size: + cmp [operand_prefix],0 + je loop_counter_size_ok + push eax + mov al,[operand_prefix] + stos byte [edi] + pop eax + loop_counter_size_ok: + ret + loop_jump_64bit: + cmp [code_type],64 + jne invalid_operand_size + call get_address_qword_value + call loop_counter_size + call calculate_jump_offset + mov ecx,edx + cdq + cmp edx,ecx + jne jump_out_of_range + jmp make_loop_jump + loop_jump_16bit: + call get_address_word_value + cmp [code_type],16 + je loop_jump_16bit_prefix_ok + mov byte [edi],66h + inc edi + loop_jump_16bit_prefix_ok: + call loop_counter_size + call calculate_jump_offset + cwde + cdq + jmp make_loop_jump + +movs_instruction: + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + or eax,eax + jnz invalid_address + or bl,ch + jnz invalid_address + cmp [segment_register],1 + ja invalid_address + push ebx + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + pop edx + or eax,eax + jnz invalid_address + or bl,ch + jnz invalid_address + mov al,dh + mov ah,bh + shr al,4 + shr ah,4 + cmp al,ah + jne address_sizes_do_not_agree + and bh,111b + and dh,111b + cmp bh,6 + jne invalid_address + cmp dh,7 + jne invalid_address + cmp al,2 + je movs_address_16bit + cmp al,4 + je movs_address_32bit + cmp [code_type],64 + jne invalid_address_size + jmp movs_store + movs_address_32bit: + call address_32bit_prefix + jmp movs_store + movs_address_16bit: + cmp [code_type],64 + je invalid_address_size + call address_16bit_prefix + movs_store: + xor ebx,ebx + call store_segment_prefix_if_necessary + mov al,0A4h + movs_check_size: + mov bl,[operand_size] + cmp bl,1 + je simple_instruction + inc al + cmp bl,2 + je simple_instruction_16bit + cmp bl,4 + je simple_instruction_32bit + cmp bl,8 + je simple_instruction_64bit + or bl,bl + jnz invalid_operand_size + call recoverable_unknown_size + jmp simple_instruction +lods_instruction: + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + or eax,eax + jnz invalid_address + or bl,ch + jnz invalid_address + cmp bh,26h + je lods_address_16bit + cmp bh,46h + je lods_address_32bit + cmp bh,86h + jne invalid_address + cmp [code_type],64 + jne invalid_address_size + jmp lods_store + lods_address_32bit: + call address_32bit_prefix + jmp lods_store + lods_address_16bit: + cmp [code_type],64 + je invalid_address_size + call address_16bit_prefix + lods_store: + xor ebx,ebx + call store_segment_prefix_if_necessary + mov al,0ACh + jmp movs_check_size +stos_instruction: + mov [base_code],al + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + or eax,eax + jnz invalid_address + or bl,ch + jnz invalid_address + cmp bh,27h + je stos_address_16bit + cmp bh,47h + je stos_address_32bit + cmp bh,87h + jne invalid_address + cmp [code_type],64 + jne invalid_address_size + jmp stos_store + stos_address_32bit: + call address_32bit_prefix + jmp stos_store + stos_address_16bit: + cmp [code_type],64 + je invalid_address_size + call address_16bit_prefix + stos_store: + cmp [segment_register],1 + ja invalid_address + mov al,[base_code] + jmp movs_check_size +cmps_instruction: + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + or eax,eax + jnz invalid_address + or bl,ch + jnz invalid_address + mov al,[segment_register] + push eax ebx + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + or eax,eax + jnz invalid_address + or bl,ch + jnz invalid_address + pop edx eax + cmp [segment_register],1 + ja invalid_address + mov [segment_register],al + mov al,dh + mov ah,bh + shr al,4 + shr ah,4 + cmp al,ah + jne address_sizes_do_not_agree + and bh,111b + and dh,111b + cmp bh,7 + jne invalid_address + cmp dh,6 + jne invalid_address + cmp al,2 + je cmps_address_16bit + cmp al,4 + je cmps_address_32bit + cmp [code_type],64 + jne invalid_address_size + jmp cmps_store + cmps_address_32bit: + call address_32bit_prefix + jmp cmps_store + cmps_address_16bit: + cmp [code_type],64 + je invalid_address_size + call address_16bit_prefix + cmps_store: + xor ebx,ebx + call store_segment_prefix_if_necessary + mov al,0A6h + jmp movs_check_size +ins_instruction: + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + or eax,eax + jnz invalid_address + or bl,ch + jnz invalid_address + cmp bh,27h + je ins_address_16bit + cmp bh,47h + je ins_address_32bit + cmp bh,87h + jne invalid_address + cmp [code_type],64 + jne invalid_address_size + jmp ins_store + ins_address_32bit: + call address_32bit_prefix + jmp ins_store + ins_address_16bit: + cmp [code_type],64 + je invalid_address_size + call address_16bit_prefix + ins_store: + cmp [segment_register],1 + ja invalid_address + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + cmp al,10h + jne invalid_operand + lods byte [esi] + cmp al,22h + jne invalid_operand + mov al,6Ch + ins_check_size: + cmp [operand_size],8 + jne movs_check_size + jmp invalid_operand_size +outs_instruction: + lods byte [esi] + cmp al,10h + jne invalid_operand + lods byte [esi] + cmp al,22h + jne invalid_operand + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + or eax,eax + jnz invalid_address + or bl,ch + jnz invalid_address + cmp bh,26h + je outs_address_16bit + cmp bh,46h + je outs_address_32bit + cmp bh,86h + jne invalid_address + cmp [code_type],64 + jne invalid_address_size + jmp outs_store + outs_address_32bit: + call address_32bit_prefix + jmp outs_store + outs_address_16bit: + cmp [code_type],64 + je invalid_address_size + call address_16bit_prefix + outs_store: + xor ebx,ebx + call store_segment_prefix_if_necessary + mov al,6Eh + jmp ins_check_size +xlat_instruction: + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + or eax,eax + jnz invalid_address + or bl,ch + jnz invalid_address + cmp bh,23h + je xlat_address_16bit + cmp bh,43h + je xlat_address_32bit + cmp bh,83h + jne invalid_address + cmp [code_type],64 + jne invalid_address_size + jmp xlat_store + xlat_address_32bit: + call address_32bit_prefix + jmp xlat_store + xlat_address_16bit: + cmp [code_type],64 + je invalid_address_size + call address_16bit_prefix + xlat_store: + call store_segment_prefix_if_necessary + mov al,0D7h + cmp [operand_size],1 + jbe simple_instruction + jmp invalid_operand_size + +pm_word_instruction: + mov ah,al + shr ah,4 + and al,111b + mov [base_code],0Fh + mov [extended_code],ah + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,10h + je pm_reg + pm_mem: + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + cmp al,2 + je pm_mem_store + or al,al + jnz invalid_operand_size + pm_mem_store: + jmp instruction_ready + pm_reg: + lods byte [esi] + call convert_register + mov bl,al + cmp ah,2 + jne invalid_operand_size + jmp nomem_instruction_ready +pm_store_word_instruction: + mov ah,al + shr ah,4 + and al,111b + mov [base_code],0Fh + mov [extended_code],ah + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne pm_mem + lods byte [esi] + call convert_register + mov bl,al + mov al,ah + call operand_autodetect + jmp nomem_instruction_ready +lgdt_instruction: + mov [base_code],0Fh + mov [extended_code],1 + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + cmp al,6 + je lgdt_mem_48bit + cmp al,10 + je lgdt_mem_80bit + or al,al + jnz invalid_operand_size + jmp lgdt_mem_store + lgdt_mem_80bit: + cmp [code_type],64 + jne illegal_instruction + jmp lgdt_mem_store + lgdt_mem_48bit: + cmp [code_type],64 + je illegal_instruction + cmp [postbyte_register],2 + jb lgdt_mem_store + call operand_32bit + lgdt_mem_store: + jmp instruction_ready +lar_instruction: + mov [extended_code],al + mov [base_code],0Fh + call take_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + xor al,al + xchg al,[operand_size] + call operand_autodetect + lods byte [esi] + call get_size_operator + cmp al,10h + je lar_reg_reg + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + or al,al + jz lar_reg_mem + cmp al,2 + jne invalid_operand_size + lar_reg_mem: + jmp instruction_ready + lar_reg_reg: + lods byte [esi] + call convert_register + cmp ah,2 + jne invalid_operand_size + mov bl,al + jmp nomem_instruction_ready +invlpg_instruction: + mov [base_code],0Fh + mov [extended_code],1 + mov [postbyte_register],7 + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + jmp instruction_ready +simple_instruction_f2_0f_01: + mov byte [edi],0F2h + inc edi + jmp simple_instruction_0f_01 +simple_instruction_f3_0f_01: + mov byte [edi],0F3h + inc edi + jmp simple_instruction_0f_01 +swapgs_instruction: + cmp [code_type],64 + jne illegal_instruction +simple_instruction_0f_01: + mov ah,al + mov al,0Fh + stos byte [edi] + mov al,1 + stos word [edi] + jmp instruction_assembled + +basic_486_instruction: + mov [base_code],0Fh + mov [extended_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + je basic_486_reg + cmp al,'[' + jne invalid_operand + call get_address + push edx ebx ecx + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + mov [postbyte_register],al + pop ecx ebx edx + mov al,ah + cmp al,1 + je basic_486_mem_reg_8bit + call operand_autodetect + inc [extended_code] + basic_486_mem_reg_8bit: + jmp instruction_ready + basic_486_reg: + lods byte [esi] + call convert_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + mov bl,al + xchg bl,[postbyte_register] + mov al,ah + cmp al,1 + je basic_486_reg_reg_8bit + call operand_autodetect + inc [extended_code] + basic_486_reg_reg_8bit: + jmp nomem_instruction_ready +bswap_instruction: + call take_register + test al,1000b + jz bswap_reg_code_ok + or [rex_prefix],41h + and al,111b + bswap_reg_code_ok: + add al,0C8h + mov [extended_code],al + mov [base_code],0Fh + cmp ah,8 + je bswap_reg64 + cmp ah,4 + jne invalid_operand_size + call operand_32bit + call store_classic_instruction_code + jmp instruction_assembled + bswap_reg64: + call operand_64bit + call store_classic_instruction_code + jmp instruction_assembled +cmpxchgx_instruction: + mov [base_code],0Fh + mov [extended_code],0C7h + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov ah,1 + xchg [postbyte_register],ah + mov al,[operand_size] + or al,al + jz cmpxchgx_size_ok + cmp al,ah + jne invalid_operand_size + cmpxchgx_size_ok: + cmp ah,16 + jne cmpxchgx_store + call operand_64bit + cmpxchgx_store: + jmp instruction_ready +nop_instruction: + mov ah,[esi] + cmp ah,10h + je extended_nop + cmp ah,11h + je extended_nop + cmp ah,'[' + je extended_nop + stos byte [edi] + jmp instruction_assembled + extended_nop: + mov [base_code],0Fh + mov [extended_code],1Fh + mov [postbyte_register],0 + lods byte [esi] + call get_size_operator + cmp al,10h + je extended_nop_reg + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + or al,al + jz extended_nop_store + call operand_autodetect + extended_nop_store: + jmp instruction_ready + extended_nop_reg: + lods byte [esi] + call convert_register + mov bl,al + mov al,ah + call operand_autodetect + jmp nomem_instruction_ready + +basic_fpu_instruction: + mov [postbyte_register],al + mov [base_code],0D8h + lods byte [esi] + call get_size_operator + cmp al,10h + je basic_fpu_streg + cmp al,'[' + je basic_fpu_mem + dec esi + mov ah,[postbyte_register] + cmp ah,2 + jb invalid_operand + cmp ah,3 + ja invalid_operand + mov bl,1 + jmp nomem_instruction_ready + basic_fpu_mem: + call get_address + mov al,[operand_size] + cmp al,4 + je basic_fpu_mem_32bit + cmp al,8 + je basic_fpu_mem_64bit + or al,al + jnz invalid_operand_size + call recoverable_unknown_size + basic_fpu_mem_32bit: + jmp instruction_ready + basic_fpu_mem_64bit: + mov [base_code],0DCh + jmp instruction_ready + basic_fpu_streg: + lods byte [esi] + call convert_fpu_register + mov bl,al + mov ah,[postbyte_register] + cmp ah,2 + je basic_fpu_single_streg + cmp ah,3 + je basic_fpu_single_streg + or al,al + jz basic_fpu_st0 + test ah,110b + jz basic_fpu_streg_st0 + xor [postbyte_register],1 + basic_fpu_streg_st0: + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_fpu_register + or al,al + jnz invalid_operand + mov [base_code],0DCh + jmp nomem_instruction_ready + basic_fpu_st0: + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_fpu_register + mov bl,al + basic_fpu_single_streg: + mov [base_code],0D8h + jmp nomem_instruction_ready +simple_fpu_instruction: + mov ah,al + or ah,11000000b + mov al,0D9h + stos word [edi] + jmp instruction_assembled +fi_instruction: + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + cmp al,2 + je fi_mem_16bit + cmp al,4 + je fi_mem_32bit + or al,al + jnz invalid_operand_size + call recoverable_unknown_size + fi_mem_32bit: + mov [base_code],0DAh + jmp instruction_ready + fi_mem_16bit: + mov [base_code],0DEh + jmp instruction_ready +fld_instruction: + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,10h + je fld_streg + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + cmp al,4 + je fld_mem_32bit + cmp al,8 + je fld_mem_64bit + cmp al,10 + je fld_mem_80bit + or al,al + jnz invalid_operand_size + call recoverable_unknown_size + fld_mem_32bit: + mov [base_code],0D9h + jmp instruction_ready + fld_mem_64bit: + mov [base_code],0DDh + jmp instruction_ready + fld_mem_80bit: + mov al,[postbyte_register] + cmp al,0 + je fld_mem_80bit_store + dec [postbyte_register] + cmp al,3 + je fld_mem_80bit_store + jmp invalid_operand_size + fld_mem_80bit_store: + add [postbyte_register],5 + mov [base_code],0DBh + jmp instruction_ready + fld_streg: + lods byte [esi] + call convert_fpu_register + mov bl,al + cmp [postbyte_register],2 + jae fst_streg + mov [base_code],0D9h + jmp nomem_instruction_ready + fst_streg: + mov [base_code],0DDh + jmp nomem_instruction_ready +fild_instruction: + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + cmp al,2 + je fild_mem_16bit + cmp al,4 + je fild_mem_32bit + cmp al,8 + je fild_mem_64bit + or al,al + jnz invalid_operand_size + call recoverable_unknown_size + fild_mem_32bit: + mov [base_code],0DBh + jmp instruction_ready + fild_mem_16bit: + mov [base_code],0DFh + jmp instruction_ready + fild_mem_64bit: + mov al,[postbyte_register] + cmp al,1 + je fisttp_64bit_store + jb fild_mem_64bit_store + dec [postbyte_register] + cmp al,3 + je fild_mem_64bit_store + jmp invalid_operand_size + fild_mem_64bit_store: + add [postbyte_register],5 + mov [base_code],0DFh + jmp instruction_ready + fisttp_64bit_store: + mov [base_code],0DDh + jmp instruction_ready +fbld_instruction: + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + or al,al + jz fbld_mem_80bit + cmp al,10 + je fbld_mem_80bit + jmp invalid_operand_size + fbld_mem_80bit: + mov [base_code],0DFh + jmp instruction_ready +faddp_instruction: + mov [postbyte_register],al + mov [base_code],0DEh + mov edx,esi + lods byte [esi] + call get_size_operator + cmp al,10h + je faddp_streg + mov esi,edx + mov bl,1 + jmp nomem_instruction_ready + faddp_streg: + lods byte [esi] + call convert_fpu_register + mov bl,al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_fpu_register + or al,al + jnz invalid_operand + jmp nomem_instruction_ready +fcompp_instruction: + mov ax,0D9DEh + stos word [edi] + jmp instruction_assembled +fucompp_instruction: + mov ax,0E9DAh + stos word [edi] + jmp instruction_assembled +fxch_instruction: + mov dx,01D9h + jmp fpu_single_operand +ffreep_instruction: + mov dx,00DFh + jmp fpu_single_operand +ffree_instruction: + mov dl,0DDh + mov dh,al + fpu_single_operand: + mov ebx,esi + lods byte [esi] + call get_size_operator + cmp al,10h + je fpu_streg + or dh,dh + jz invalid_operand + mov esi,ebx + shl dh,3 + or dh,11000001b + mov ax,dx + stos word [edi] + jmp instruction_assembled + fpu_streg: + lods byte [esi] + call convert_fpu_register + shl dh,3 + or dh,al + or dh,11000000b + mov ax,dx + stos word [edi] + jmp instruction_assembled + +fstenv_instruction: + mov byte [edi],9Bh + inc edi +fldenv_instruction: + mov [base_code],0D9h + jmp fpu_mem +fstenv_instruction_16bit: + mov byte [edi],9Bh + inc edi +fldenv_instruction_16bit: + call operand_16bit + jmp fldenv_instruction +fstenv_instruction_32bit: + mov byte [edi],9Bh + inc edi +fldenv_instruction_32bit: + call operand_32bit + jmp fldenv_instruction +fsave_instruction_32bit: + mov byte [edi],9Bh + inc edi +fnsave_instruction_32bit: + call operand_32bit + jmp fnsave_instruction +fsave_instruction_16bit: + mov byte [edi],9Bh + inc edi +fnsave_instruction_16bit: + call operand_16bit + jmp fnsave_instruction +fsave_instruction: + mov byte [edi],9Bh + inc edi +fnsave_instruction: + mov [base_code],0DDh + fpu_mem: + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],0 + jne invalid_operand_size + jmp instruction_ready +fstcw_instruction: + mov byte [edi],9Bh + inc edi +fldcw_instruction: + mov [postbyte_register],al + mov [base_code],0D9h + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + or al,al + jz fldcw_mem_16bit + cmp al,2 + je fldcw_mem_16bit + jmp invalid_operand_size + fldcw_mem_16bit: + jmp instruction_ready +fstsw_instruction: + mov al,9Bh + stos byte [edi] +fnstsw_instruction: + mov [base_code],0DDh + mov [postbyte_register],7 + lods byte [esi] + call get_size_operator + cmp al,10h + je fstsw_reg + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + or al,al + jz fstsw_mem_16bit + cmp al,2 + je fstsw_mem_16bit + jmp invalid_operand_size + fstsw_mem_16bit: + jmp instruction_ready + fstsw_reg: + lods byte [esi] + call convert_register + cmp ax,0200h + jne invalid_operand + mov ax,0E0DFh + stos word [edi] + jmp instruction_assembled +finit_instruction: + mov byte [edi],9Bh + inc edi +fninit_instruction: + mov ah,al + mov al,0DBh + stos word [edi] + jmp instruction_assembled +fcmov_instruction: + mov dh,0DAh + jmp fcomi_streg +fcomi_instruction: + mov dh,0DBh + jmp fcomi_streg +fcomip_instruction: + mov dh,0DFh + fcomi_streg: + mov dl,al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_fpu_register + mov ah,al + cmp byte [esi],',' + je fcomi_st0_streg + add ah,dl + mov al,dh + stos word [edi] + jmp instruction_assembled + fcomi_st0_streg: + or ah,ah + jnz invalid_operand + inc esi + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_fpu_register + mov ah,al + add ah,dl + mov al,dh + stos word [edi] + jmp instruction_assembled + +basic_mmx_instruction: + mov [base_code],0Fh + mov [extended_code],al + mmx_instruction: + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + call make_mmx_prefix + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je mmx_mmreg_mmreg + cmp al,'[' + jne invalid_operand + mmx_mmreg_mem: + call get_address + jmp instruction_ready + mmx_mmreg_mmreg: + lods byte [esi] + call convert_mmx_register + mov bl,al + jmp nomem_instruction_ready +mmx_bit_shift_instruction: + mov [base_code],0Fh + mov [extended_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + call make_mmx_prefix + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + mov [operand_size],0 + lods byte [esi] + call get_size_operator + cmp al,10h + je mmx_mmreg_mmreg + cmp al,'(' + je mmx_ps_mmreg_imm8 + cmp al,'[' + je mmx_mmreg_mem + jmp invalid_operand + mmx_ps_mmreg_imm8: + call get_byte_value + mov byte [value],al + test [operand_size],not 1 + jnz invalid_value + mov bl,[extended_code] + mov al,bl + shr bl,4 + and al,1111b + add al,70h + mov [extended_code],al + sub bl,0Ch + shl bl,1 + xchg bl,[postbyte_register] + call store_nomem_instruction + mov al,byte [value] + stos byte [edi] + jmp instruction_assembled +pmovmskb_instruction: + mov [base_code],0Fh + mov [extended_code],al + call take_register + cmp ah,4 + je pmovmskb_reg_size_ok + cmp [code_type],64 + jne invalid_operand_size + cmp ah,8 + jnz invalid_operand_size + pmovmskb_reg_size_ok: + mov [postbyte_register],al + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + mov bl,al + call make_mmx_prefix + cmp [extended_code],0C5h + je mmx_nomem_imm8 + jmp nomem_instruction_ready + mmx_imm8: + push ebx ecx edx + xor cl,cl + xchg cl,[operand_size] + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + test ah,not 1 + jnz invalid_operand_size + mov [operand_size],cl + cmp al,'(' + jne invalid_operand + call get_byte_value + mov byte [value],al + pop edx ecx ebx + call store_instruction_with_imm8 + jmp instruction_assembled + mmx_nomem_imm8: + call store_nomem_instruction + call append_imm8 + jmp instruction_assembled + append_imm8: + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + test ah,not 1 + jnz invalid_operand_size + cmp al,'(' + jne invalid_operand + call get_byte_value + stosb + ret +pinsrw_instruction: + mov [extended_code],al + mov [base_code],0Fh + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + call make_mmx_prefix + mov [postbyte_register],al + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je pinsrw_mmreg_reg + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],0 + je mmx_imm8 + cmp [operand_size],2 + jne invalid_operand_size + jmp mmx_imm8 + pinsrw_mmreg_reg: + lods byte [esi] + call convert_register + cmp ah,4 + jne invalid_operand_size + mov bl,al + jmp mmx_nomem_imm8 +pshufw_instruction: + mov [mmx_size],8 + mov [opcode_prefix],al + jmp pshuf_instruction +pshufd_instruction: + mov [mmx_size],16 + mov [opcode_prefix],al + pshuf_instruction: + mov [base_code],0Fh + mov [extended_code],70h + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + cmp ah,[mmx_size] + jne invalid_operand_size + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je pshuf_mmreg_mmreg + cmp al,'[' + jne invalid_operand + call get_address + jmp mmx_imm8 + pshuf_mmreg_mmreg: + lods byte [esi] + call convert_mmx_register + mov bl,al + jmp mmx_nomem_imm8 +movd_instruction: + mov [base_code],0Fh + mov [extended_code],7Eh + lods byte [esi] + call get_size_operator + cmp al,10h + je movd_reg + cmp al,'[' + jne invalid_operand + call get_address + test [operand_size],not 4 + jnz invalid_operand_size + call get_mmx_source_register + jmp instruction_ready + movd_reg: + lods byte [esi] + cmp al,0B0h + jae movd_mmreg + call convert_register + cmp ah,4 + jne invalid_operand_size + mov bl,al + call get_mmx_source_register + jmp nomem_instruction_ready + movd_mmreg: + mov [extended_code],6Eh + call convert_mmx_register + mov [postbyte_register],al + call make_mmx_prefix + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je movd_mmreg_reg + cmp al,'[' + jne invalid_operand + call get_address + test [operand_size],not 4 + jnz invalid_operand_size + jmp instruction_ready + movd_mmreg_reg: + lods byte [esi] + call convert_register + cmp ah,4 + jne invalid_operand_size + mov bl,al + jmp nomem_instruction_ready + get_mmx_source_register: + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + mov [postbyte_register],al + make_mmx_prefix: + cmp [operand_size],16 + jne no_mmx_prefix + mov [operand_prefix],66h + no_mmx_prefix: + ret +movq_instruction: + mov [base_code],0Fh + lods byte [esi] + call get_size_operator + cmp al,10h + je movq_reg + cmp al,'[' + jne invalid_operand + call get_address + test [operand_size],not 8 + jnz invalid_operand_size + call get_mmx_source_register + mov al,7Fh + cmp ah,8 + je movq_mem_ready + mov al,0D6h + movq_mem_ready: + mov [extended_code],al + jmp instruction_ready + movq_reg: + lods byte [esi] + cmp al,0B0h + jae movq_mmreg + call convert_register + cmp ah,8 + jne invalid_operand_size + mov bl,al + mov [extended_code],7Eh + call operand_64bit + call get_mmx_source_register + jmp nomem_instruction_ready + movq_mmreg: + call convert_mmx_register + mov [postbyte_register],al + mov [extended_code],6Fh + mov [mmx_size],ah + cmp ah,16 + jne movq_mmreg_ + mov [extended_code],7Eh + mov [opcode_prefix],0F3h + movq_mmreg_: + lods byte [esi] + cmp al,',' + jne invalid_operand + mov [operand_size],0 + lods byte [esi] + call get_size_operator + cmp al,10h + je movq_mmreg_reg + cmp al,'[' + jne invalid_operand + call get_address + test [operand_size],not 8 + jnz invalid_operand_size + jmp instruction_ready + movq_mmreg_reg: + lods byte [esi] + cmp al,0B0h + jae movq_mmreg_mmreg + mov [operand_size],0 + call convert_register + cmp ah,8 + jne invalid_operand_size + mov [extended_code],6Eh + mov [opcode_prefix],0 + mov bl,al + cmp [mmx_size],16 + jne movq_mmreg_reg_store + mov [opcode_prefix],66h + movq_mmreg_reg_store: + call operand_64bit + jmp nomem_instruction_ready + movq_mmreg_mmreg: + call convert_mmx_register + cmp ah,[mmx_size] + jne invalid_operand_size + mov bl,al + jmp nomem_instruction_ready +movdq_instruction: + mov [opcode_prefix],al + mov [base_code],0Fh + mov [extended_code],6Fh + lods byte [esi] + call get_size_operator + cmp al,10h + je movdq_mmreg + cmp al,'[' + jne invalid_operand + call get_address + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + mov [extended_code],7Fh + jmp instruction_ready + movdq_mmreg: + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je movdq_mmreg_mmreg + cmp al,'[' + jne invalid_operand + call get_address + jmp instruction_ready + movdq_mmreg_mmreg: + lods byte [esi] + call convert_xmm_register + mov bl,al + jmp nomem_instruction_ready +lddqu_instruction: + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + push eax + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + pop eax + mov [postbyte_register],al + mov [opcode_prefix],0F2h + mov [base_code],0Fh + mov [extended_code],0F0h + jmp instruction_ready + +movdq2q_instruction: + mov [opcode_prefix],0F2h + mov [mmx_size],8 + jmp movq2dq_ +movq2dq_instruction: + mov [opcode_prefix],0F3h + mov [mmx_size],16 + movq2dq_: + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + cmp ah,[mmx_size] + jne invalid_operand_size + mov [postbyte_register],al + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + xor [mmx_size],8+16 + cmp ah,[mmx_size] + jne invalid_operand_size + mov bl,al + mov [base_code],0Fh + mov [extended_code],0D6h + jmp nomem_instruction_ready + +sse_ps_instruction_imm8: + mov [immediate_size],1 +sse_ps_instruction: + mov [mmx_size],16 + jmp sse_instruction +sse_pd_instruction_imm8: + mov [immediate_size],1 +sse_pd_instruction: + mov [mmx_size],16 + mov [opcode_prefix],66h + jmp sse_instruction +sse_ss_instruction: + mov [mmx_size],4 + mov [opcode_prefix],0F3h + jmp sse_instruction +sse_sd_instruction: + mov [mmx_size],8 + mov [opcode_prefix],0F2h + jmp sse_instruction +cmp_pd_instruction: + mov [opcode_prefix],66h +cmp_ps_instruction: + mov [mmx_size],16 + mov byte [value],al + mov al,0C2h + jmp sse_instruction +cmp_ss_instruction: + mov [mmx_size],4 + mov [opcode_prefix],0F3h + jmp cmp_sx_instruction +cmpsd_instruction: + mov al,0A7h + mov ah,[esi] + or ah,ah + jz simple_instruction_32bit + cmp ah,0Fh + je simple_instruction_32bit + mov al,-1 +cmp_sd_instruction: + mov [mmx_size],8 + mov [opcode_prefix],0F2h + cmp_sx_instruction: + mov byte [value],al + mov al,0C2h + jmp sse_instruction +comiss_instruction: + mov [mmx_size],4 + jmp sse_instruction +comisd_instruction: + mov [mmx_size],8 + mov [opcode_prefix],66h + jmp sse_instruction +cvtdq2pd_instruction: + mov [opcode_prefix],0F3h +cvtps2pd_instruction: + mov [mmx_size],8 + jmp sse_instruction +cvtpd2dq_instruction: + mov [mmx_size],16 + mov [opcode_prefix],0F2h + jmp sse_instruction +movshdup_instruction: + mov [mmx_size],16 + mov [opcode_prefix],0F3h +sse_instruction: + mov [base_code],0Fh + mov [extended_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + sse_xmmreg: + lods byte [esi] + call convert_xmm_register + sse_reg: + mov [postbyte_register],al + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je sse_xmmreg_xmmreg + sse_reg_mem: + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],0 + je sse_mem_size_ok + mov al,[mmx_size] + cmp [operand_size],al + jne invalid_operand_size + sse_mem_size_ok: + mov al,[extended_code] + mov ah,[supplemental_code] + cmp al,0C2h + je sse_cmp_mem_ok + cmp ax,443Ah + je sse_cmp_mem_ok + cmp [immediate_size],1 + je mmx_imm8 + cmp [immediate_size],-1 + jne sse_ok + call take_additional_xmm0 + mov [immediate_size],0 + sse_ok: + jmp instruction_ready + sse_cmp_mem_ok: + cmp byte [value],-1 + je mmx_imm8 + call store_instruction_with_imm8 + jmp instruction_assembled + sse_xmmreg_xmmreg: + cmp [operand_prefix],66h + jne sse_xmmreg_xmmreg_ok + cmp [extended_code],12h + je invalid_operand + cmp [extended_code],16h + je invalid_operand + sse_xmmreg_xmmreg_ok: + lods byte [esi] + call convert_xmm_register + mov bl,al + mov al,[extended_code] + mov ah,[supplemental_code] + cmp al,0C2h + je sse_cmp_nomem_ok + cmp ax,443Ah + je sse_cmp_nomem_ok + cmp [immediate_size],1 + je mmx_nomem_imm8 + cmp [immediate_size],-1 + jne sse_nomem_ok + call take_additional_xmm0 + mov [immediate_size],0 + sse_nomem_ok: + jmp nomem_instruction_ready + sse_cmp_nomem_ok: + cmp byte [value],-1 + je mmx_nomem_imm8 + call store_nomem_instruction + mov al,byte [value] + stosb + jmp instruction_assembled + take_additional_xmm0: + cmp byte [esi],',' + jne additional_xmm0_ok + inc esi + lods byte [esi] + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + test al,al + jnz invalid_operand + additional_xmm0_ok: + ret + +pslldq_instruction: + mov [postbyte_register],al + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],73h + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov bl,al + jmp mmx_nomem_imm8 +movpd_instruction: + mov [opcode_prefix],66h +movps_instruction: + mov [base_code],0Fh + mov [extended_code],al + mov [mmx_size],16 + jmp sse_mov_instruction +movss_instruction: + mov [mmx_size],4 + mov [opcode_prefix],0F3h + jmp sse_movs +movsd_instruction: + mov al,0A5h + mov ah,[esi] + or ah,ah + jz simple_instruction_32bit + cmp ah,0Fh + je simple_instruction_32bit + mov [mmx_size],8 + mov [opcode_prefix],0F2h + sse_movs: + mov [base_code],0Fh + mov [extended_code],10h + jmp sse_mov_instruction +sse_mov_instruction: + lods byte [esi] + call get_size_operator + cmp al,10h + je sse_xmmreg + sse_mem: + cmp al,'[' + jne invalid_operand + inc [extended_code] + call get_address + cmp [operand_size],0 + je sse_mem_xmmreg + mov al,[mmx_size] + cmp [operand_size],al + jne invalid_operand_size + mov [operand_size],0 + sse_mem_xmmreg: + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + jmp instruction_ready +movlpd_instruction: + mov [opcode_prefix],66h +movlps_instruction: + mov [base_code],0Fh + mov [extended_code],al + mov [mmx_size],8 + lods byte [esi] + call get_size_operator + cmp al,10h + jne sse_mem + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + jmp sse_reg_mem +movhlps_instruction: + mov [base_code],0Fh + mov [extended_code],al + mov [mmx_size],0 + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je sse_xmmreg_xmmreg_ok + jmp invalid_operand +maskmovq_instruction: + mov cl,8 + jmp maskmov_instruction +maskmovdqu_instruction: + mov cl,16 + mov [opcode_prefix],66h + maskmov_instruction: + mov [base_code],0Fh + mov [extended_code],0F7h + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + cmp ah,cl + jne invalid_operand_size + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + mov bl,al + jmp nomem_instruction_ready +movmskpd_instruction: + mov [opcode_prefix],66h +movmskps_instruction: + mov [base_code],0Fh + mov [extended_code],50h + call take_register + mov [postbyte_register],al + cmp ah,4 + je movmskps_reg_ok + cmp ah,8 + jne invalid_operand_size + cmp [code_type],64 + jne invalid_operand + movmskps_reg_ok: + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je sse_xmmreg_xmmreg_ok + jmp invalid_operand + +cvtpi2pd_instruction: + mov [opcode_prefix],66h +cvtpi2ps_instruction: + mov [base_code],0Fh + mov [extended_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je cvtpi_xmmreg_xmmreg + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],0 + je cvtpi_size_ok + cmp [operand_size],8 + jne invalid_operand_size + cvtpi_size_ok: + jmp instruction_ready + cvtpi_xmmreg_xmmreg: + lods byte [esi] + call convert_mmx_register + cmp ah,8 + jne invalid_operand_size + mov bl,al + jmp nomem_instruction_ready +cvtsi2ss_instruction: + mov [opcode_prefix],0F3h + jmp cvtsi_instruction +cvtsi2sd_instruction: + mov [opcode_prefix],0F2h + cvtsi_instruction: + mov [base_code],0Fh + mov [extended_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + cvtsi_xmmreg: + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je cvtsi_xmmreg_reg + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],0 + je cvtsi_size_ok + cmp [operand_size],4 + je cvtsi_size_ok + cmp [operand_size],8 + jne invalid_operand_size + call operand_64bit + cvtsi_size_ok: + jmp instruction_ready + cvtsi_xmmreg_reg: + lods byte [esi] + call convert_register + cmp ah,4 + je cvtsi_xmmreg_reg_store + cmp ah,8 + jne invalid_operand_size + call operand_64bit + cvtsi_xmmreg_reg_store: + mov bl,al + jmp nomem_instruction_ready +cvtps2pi_instruction: + mov [mmx_size],8 + jmp cvtpd_instruction +cvtpd2pi_instruction: + mov [opcode_prefix],66h + mov [mmx_size],16 + cvtpd_instruction: + mov [base_code],0Fh + mov [extended_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + cmp ah,8 + jne invalid_operand_size + mov [operand_size],0 + jmp sse_reg +cvtss2si_instruction: + mov [opcode_prefix],0F3h + mov [mmx_size],4 + jmp cvt2si_instruction +cvtsd2si_instruction: + mov [opcode_prefix],0F2h + mov [mmx_size],8 + cvt2si_instruction: + mov [extended_code],al + mov [base_code],0Fh + call take_register + mov [operand_size],0 + cmp ah,4 + je sse_reg + cmp ah,8 + jne invalid_operand_size + call operand_64bit + jmp sse_reg + +ssse3_instruction: + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],al + jmp mmx_instruction +palignr_instruction: + mov [base_code],0Fh + mov [extended_code],3Ah + mov [supplemental_code],0Fh + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + call make_mmx_prefix + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je palignr_mmreg_mmreg + cmp al,'[' + jne invalid_operand + call get_address + jmp mmx_imm8 + palignr_mmreg_mmreg: + lods byte [esi] + call convert_mmx_register + mov bl,al + jmp mmx_nomem_imm8 +amd3dnow_instruction: + mov [base_code],0Fh + mov [extended_code],0Fh + mov byte [value],al + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + cmp ah,8 + jne invalid_operand_size + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je amd3dnow_mmreg_mmreg + cmp al,'[' + jne invalid_operand + call get_address + call store_instruction_with_imm8 + jmp instruction_assembled + amd3dnow_mmreg_mmreg: + lods byte [esi] + call convert_mmx_register + cmp ah,8 + jne invalid_operand_size + mov bl,al + call store_nomem_instruction + mov al,byte [value] + stos byte [edi] + jmp instruction_assembled + +sse4_instruction_38_xmm0: + mov [immediate_size],-1 + jmp sse4_instruction_38 +sse4_instruction_66_38_xmm0: + mov [immediate_size],-1 +sse4_instruction_66_38: + mov [opcode_prefix],66h +sse4_instruction_38: + mov [mmx_size],16 + mov [supplemental_code],al + mov al,38h + jmp sse_instruction +sse4_ss_instruction_66_3a_imm8: + mov [immediate_size],1 + mov cl,4 + jmp sse4_instruction_66_3a_setup +sse4_sd_instruction_66_3a_imm8: + mov [immediate_size],1 + mov cl,8 + jmp sse4_instruction_66_3a_setup +sse4_instruction_66_3a_imm8: + mov [immediate_size],1 + mov cl,16 + sse4_instruction_66_3a_setup: + mov [opcode_prefix],66h + sse4_instruction_3a_setup: + mov [supplemental_code],al + mov al,3Ah + mov [mmx_size],cl + jmp sse_instruction +sse4_instruction_3a_imm8: + mov [immediate_size],1 + mov cl,16 + jmp sse4_instruction_3a_setup +pclmulqdq_instruction: + mov byte [value],al + mov al,44h + mov cl,16 + jmp sse4_instruction_66_3a_setup +extractps_instruction: + call setup_66_0f_3a + lods byte [esi] + call get_size_operator + cmp al,10h + je extractps_reg + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],4 + je extractps_size_ok + cmp [operand_size],0 + jne invalid_operand_size + extractps_size_ok: + push edx ebx ecx + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + pop ecx ebx edx + jmp mmx_imm8 + extractps_reg: + lods byte [esi] + call convert_register + push eax + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + pop ebx + mov al,bh + cmp al,4 + je mmx_nomem_imm8 + cmp al,8 + jne invalid_operand_size + cmp [code_type],64 + jne illegal_instruction + jmp mmx_nomem_imm8 + setup_66_0f_3a: + mov [extended_code],3Ah + mov [supplemental_code],al + mov [base_code],0Fh + mov [opcode_prefix],66h + ret +insertps_instruction: + call setup_66_0f_3a + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je insertps_xmmreg_reg + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],4 + je insertps_size_ok + cmp [operand_size],0 + jne invalid_operand_size + insertps_size_ok: + jmp mmx_imm8 + insertps_xmmreg_reg: + lods byte [esi] + call convert_mmx_register + mov bl,al + jmp mmx_nomem_imm8 +pextrq_instruction: + mov [mmx_size],8 + jmp pextr_instruction +pextrd_instruction: + mov [mmx_size],4 + jmp pextr_instruction +pextrw_instruction: + mov [mmx_size],2 + jmp pextr_instruction +pextrb_instruction: + mov [mmx_size],1 + pextr_instruction: + call setup_66_0f_3a + lods byte [esi] + call get_size_operator + cmp al,10h + je pextr_reg + cmp al,'[' + jne invalid_operand + call get_address + mov al,[mmx_size] + cmp al,[operand_size] + je pextr_size_ok + cmp [operand_size],0 + jne invalid_operand_size + pextr_size_ok: + cmp al,8 + jne pextr_prefix_ok + call operand_64bit + pextr_prefix_ok: + push edx ebx ecx + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + pop ecx ebx edx + jmp mmx_imm8 + pextr_reg: + lods byte [esi] + call convert_register + cmp [mmx_size],4 + ja pextrq_reg + cmp ah,4 + je pextr_reg_size_ok + cmp [code_type],64 + jne pextr_invalid_size + cmp ah,8 + je pextr_reg_size_ok + pextr_invalid_size: + jmp invalid_operand_size + pextrq_reg: + cmp ah,8 + jne pextr_invalid_size + call operand_64bit + pextr_reg_size_ok: + mov [operand_size],0 + push eax + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + mov ebx,eax + pop eax + mov [postbyte_register],al + mov al,ah + cmp [mmx_size],2 + jne pextr_reg_store + mov [opcode_prefix],0 + mov [extended_code],0C5h + call make_mmx_prefix + jmp mmx_nomem_imm8 + pextr_reg_store: + cmp bh,16 + jne invalid_operand_size + xchg bl,[postbyte_register] + jmp mmx_nomem_imm8 +pinsrb_instruction: + mov [mmx_size],1 + jmp pinsr_instruction +pinsrd_instruction: + mov [mmx_size],4 + jmp pinsr_instruction +pinsrq_instruction: + mov [mmx_size],8 + call operand_64bit + pinsr_instruction: + call setup_66_0f_3a + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + pinsr_xmmreg: + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je pinsr_xmmreg_reg + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],0 + je mmx_imm8 + mov al,[mmx_size] + cmp al,[operand_size] + je mmx_imm8 + jmp invalid_operand_size + pinsr_xmmreg_reg: + lods byte [esi] + call convert_register + mov bl,al + cmp [mmx_size],8 + je pinsrq_xmmreg_reg + cmp ah,4 + je mmx_nomem_imm8 + jmp invalid_operand_size + pinsrq_xmmreg_reg: + cmp ah,8 + je mmx_nomem_imm8 + jmp invalid_operand_size +pmovsxbw_instruction: + mov [mmx_size],8 + jmp pmovsx_instruction +pmovsxbd_instruction: + mov [mmx_size],4 + jmp pmovsx_instruction +pmovsxbq_instruction: + mov [mmx_size],2 + jmp pmovsx_instruction +pmovsxwd_instruction: + mov [mmx_size],8 + jmp pmovsx_instruction +pmovsxwq_instruction: + mov [mmx_size],4 + jmp pmovsx_instruction +pmovsxdq_instruction: + mov [mmx_size],8 + pmovsx_instruction: + call setup_66_0f_38 + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + mov [operand_size],0 + lods byte [esi] + call get_size_operator + cmp al,10h + je pmovsx_xmmreg_reg + cmp al,'[' + jne invalid_operand + call get_address + cmp [operand_size],0 + je instruction_ready + mov al,[mmx_size] + cmp al,[operand_size] + jne invalid_operand_size + jmp instruction_ready + pmovsx_xmmreg_reg: + lods byte [esi] + call convert_xmm_register + mov bl,al + jmp nomem_instruction_ready + setup_66_0f_38: + mov [extended_code],38h + mov [supplemental_code],al + mov [base_code],0Fh + mov [opcode_prefix],66h + ret + +xsaves_instruction_64bit: + call operand_64bit +xsaves_instruction: + mov ah,0C7h + jmp xsave_common +fxsave_instruction_64bit: + call operand_64bit +fxsave_instruction: + mov ah,0AEh + xor cl,cl + xsave_common: + mov [base_code],0Fh + mov [extended_code],ah + mov [postbyte_register],al + mov [mmx_size],cl + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov ah,[operand_size] + or ah,ah + jz xsave_size_ok + cmp ah,[mmx_size] + jne invalid_operand_size + xsave_size_ok: + jmp instruction_ready +clflush_instruction: + mov ah,0AEh + mov cl,1 + jmp xsave_common +cldemote_instruction: + mov ah,1Ch + mov cl,1 + jmp xsave_common +stmxcsr_instruction: + mov ah,0AEh + mov cl,4 + jmp xsave_common +prefetch_instruction: + mov [extended_code],18h + prefetch_mem_8bit: + mov [base_code],0Fh + mov [postbyte_register],al + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + or ah,ah + jz prefetch_size_ok + cmp ah,1 + jne invalid_operand_size + prefetch_size_ok: + call get_address + jmp instruction_ready +amd_prefetch_instruction: + mov [extended_code],0Dh + jmp prefetch_mem_8bit +clflushopt_instruction: + mov [extended_code],0AEh + mov [opcode_prefix],66h + jmp prefetch_mem_8bit +pcommit_instruction: + mov byte [edi],66h + inc edi +fence_instruction: + mov bl,al + mov ax,0AE0Fh + stos word [edi] + mov al,bl + stos byte [edi] + jmp instruction_assembled +pause_instruction: + mov ax,90F3h + stos word [edi] + jmp instruction_assembled +movntq_instruction: + mov [mmx_size],8 + jmp movnt_instruction +movntpd_instruction: + mov [opcode_prefix],66h +movntps_instruction: + mov [mmx_size],16 + movnt_instruction: + mov [extended_code],al + mov [base_code],0Fh + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_mmx_register + cmp ah,[mmx_size] + jne invalid_operand_size + mov [postbyte_register],al + jmp instruction_ready + +movntsd_instruction: + mov [opcode_prefix],0F2h + mov [mmx_size],8 + jmp movnts_instruction +movntss_instruction: + mov [opcode_prefix],0F3h + mov [mmx_size],4 + movnts_instruction: + mov [extended_code],al + mov [base_code],0Fh + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + cmp al,[mmx_size] + je movnts_size_ok + test al,al + jnz invalid_operand_size + movnts_size_ok: + lods byte [esi] + cmp al,',' + jne invalid_operand + mov [operand_size],0 + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + jmp instruction_ready + +movdiri_instruction: + mov [supplemental_code],al + mov al,38h +movnti_instruction: + mov [base_code],0Fh + mov [extended_code],al + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + cmp ah,4 + je movnti_store + cmp ah,8 + jne invalid_operand_size + call operand_64bit + movnti_store: + mov [postbyte_register],al + jmp instruction_ready +monitor_instruction: + mov [postbyte_register],al + cmp byte [esi],0 + je monitor_instruction_store + cmp byte [esi],0Fh + je monitor_instruction_store + call take_register + cmp ax,0400h + jne invalid_operand + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + cmp ax,0401h + jne invalid_operand + cmp [postbyte_register],0C8h + jne monitor_instruction_store + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + cmp ax,0402h + jne invalid_operand + monitor_instruction_store: + mov ax,010Fh + stos word [edi] + mov al,[postbyte_register] + stos byte [edi] + jmp instruction_assembled +pconfig_instruction: + mov [postbyte_register],al + jmp monitor_instruction_store +movntdqa_instruction: + call setup_66_0f_38 + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + jmp instruction_ready + +extrq_instruction: + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],78h + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je extrq_xmmreg_xmmreg + test ah,not 1 + jnz invalid_operand_size + cmp al,'(' + jne invalid_operand + xor bl,bl + xchg bl,[postbyte_register] + call store_nomem_instruction + call get_byte_value + stosb + call append_imm8 + jmp instruction_assembled + extrq_xmmreg_xmmreg: + inc [extended_code] + lods byte [esi] + call convert_xmm_register + mov bl,al + jmp nomem_instruction_ready +insertq_instruction: + mov [opcode_prefix],0F2h + mov [base_code],0Fh + mov [extended_code],78h + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov [postbyte_register],al + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_xmm_register + mov bl,al + cmp byte [esi],',' + je insertq_with_imm + inc [extended_code] + jmp nomem_instruction_ready + insertq_with_imm: + call store_nomem_instruction + call append_imm8 + call append_imm8 + jmp instruction_assembled + +crc32_instruction: + mov [opcode_prefix],0F2h + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],0F0h + call take_register + mov [postbyte_register],al + cmp ah,4 + je crc32_reg_size_ok + cmp ah,8 + jne invalid_operand + cmp [code_type],64 + jne illegal_instruction + crc32_reg_size_ok: + lods byte [esi] + cmp al,',' + jne invalid_operand + mov [operand_size],0 + lods byte [esi] + call get_size_operator + cmp al,10h + je crc32_reg_reg + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + test al,al + jz crc32_unknown_size + cmp al,1 + je crc32_reg_mem_store + inc [supplemental_code] + call operand_autodetect + crc32_reg_mem_store: + jmp instruction_ready + crc32_unknown_size: + call recoverable_unknown_size + jmp crc32_reg_mem_store + crc32_reg_reg: + lods byte [esi] + call convert_register + mov bl,al + mov al,ah + cmp al,1 + je crc32_reg_reg_store + inc [supplemental_code] + call operand_autodetect + crc32_reg_reg_store: + jmp nomem_instruction_ready +popcnt_instruction: + mov [opcode_prefix],0F3h + jmp bs_instruction +movbe_instruction: + mov [supplemental_code],al + mov [extended_code],38h + mov [base_code],0Fh + lods byte [esi] + call get_size_operator + cmp al,'[' + je movbe_mem + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_argument + call get_address + mov al,[operand_size] + call operand_autodetect + jmp instruction_ready + movbe_mem: + inc [supplemental_code] + call get_address + push edx ebx ecx + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + mov [postbyte_register],al + pop ecx ebx edx + mov al,[operand_size] + call operand_autodetect + jmp instruction_ready +adx_instruction: + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],0F6h + mov [operand_prefix],al + call get_reg_mem + jc adx_reg_reg + mov al,[operand_size] + cmp al,4 + je instruction_ready + cmp al,8 + jne invalid_operand_size + call operand_64bit + jmp instruction_ready + adx_reg_reg: + cmp ah,4 + je nomem_instruction_ready + cmp ah,8 + jne invalid_operand_size + call operand_64bit + jmp nomem_instruction_ready +rdpid_instruction: + mov [postbyte_register],al + mov [extended_code],0C7h + mov [base_code],0Fh + mov [opcode_prefix],0F3h + call take_register + mov bl,al + cmp [code_type],64 + je rdpid_64bit + cmp ah,4 + jne invalid_operand_size + jmp nomem_instruction_ready + rdpid_64bit: + cmp ah,8 + jne invalid_operand_size + jmp nomem_instruction_ready +ptwrite_instruction: + mov [base_code],0Fh + mov [extended_code],0AEh + mov [postbyte_register],al + mov [opcode_prefix],0F3h + lods byte [esi] + call get_size_operator + cmp al,10h + je ptwrite_reg + ptwrite_mem: + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + cmp al,4 + je ptwrite_mem_store + cmp al,8 + je ptwrite_mem_64bit + or al,al + jnz invalid_operand_size + call recoverable_unknown_size + jmp ptwrite_mem_store + ptwrite_mem_64bit: + call operand_64bit + ptwrite_mem_store: + mov al,[operand_size] + call operand_autodetect + jmp instruction_ready + ptwrite_reg: + lods byte [esi] + call convert_register + mov bl,al + mov al,ah + cmp al,4 + je nomem_instruction_ready + cmp al,8 + jne invalid_operand_size + call operand_64bit + jmp nomem_instruction_ready + +vmclear_instruction: + mov [opcode_prefix],66h + jmp vmx_instruction +vmxon_instruction: + mov [opcode_prefix],0F3h +vmx_instruction: + mov [postbyte_register],al + mov [extended_code],0C7h + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + or al,al + jz vmx_size_ok + cmp al,8 + jne invalid_operand_size + vmx_size_ok: + mov [base_code],0Fh + jmp instruction_ready +vmread_instruction: + mov [extended_code],78h + lods byte [esi] + call get_size_operator + cmp al,10h + je vmread_nomem + cmp al,'[' + jne invalid_operand + call get_address + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + mov [postbyte_register],al + call vmread_check_size + jmp vmx_size_ok + vmread_nomem: + lods byte [esi] + call convert_register + push eax + call vmread_check_size + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + mov [postbyte_register],al + call vmread_check_size + pop ebx + mov [base_code],0Fh + jmp nomem_instruction_ready + vmread_check_size: + cmp [code_type],64 + je vmread_long + cmp [operand_size],4 + jne invalid_operand_size + ret + vmread_long: + cmp [operand_size],8 + jne invalid_operand_size + ret +vmwrite_instruction: + mov [extended_code],79h + call take_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,10h + je vmwrite_nomem + cmp al,'[' + jne invalid_operand + call get_address + call vmread_check_size + jmp vmx_size_ok + vmwrite_nomem: + lods byte [esi] + call convert_register + mov bl,al + mov [base_code],0Fh + jmp nomem_instruction_ready +vmx_inv_instruction: + call setup_66_0f_38 + call take_register + mov [postbyte_register],al + call vmread_check_size + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + or al,al + jz vmx_size_ok + cmp al,16 + jne invalid_operand_size + jmp vmx_size_ok +simple_svm_instruction: + push eax + mov [base_code],0Fh + mov [extended_code],1 + call take_register + or al,al + jnz invalid_operand + simple_svm_detect_size: + cmp ah,2 + je simple_svm_16bit + cmp ah,4 + je simple_svm_32bit + cmp [code_type],64 + jne invalid_operand_size + jmp simple_svm_store + simple_svm_16bit: + cmp [code_type],16 + je simple_svm_store + cmp [code_type],64 + je invalid_operand_size + jmp prefixed_svm_store + simple_svm_32bit: + cmp [code_type],32 + je simple_svm_store + prefixed_svm_store: + mov al,67h + stos byte [edi] + simple_svm_store: + call store_classic_instruction_code + pop eax + stos byte [edi] + jmp instruction_assembled +skinit_instruction: + call take_register + cmp ax,0400h + jne invalid_operand + mov al,0DEh + jmp simple_instruction_0f_01 +clzero_instruction: + call take_register + or al,al + jnz invalid_operand + mov al,0FCh + cmp [code_type],64 + je clzero_64bit + cmp ah,4 + jne invalid_operand + jmp simple_instruction_0f_01 + clzero_64bit: + cmp ah,8 + jne invalid_operand + jmp simple_instruction_0f_01 +invlpga_instruction: + push eax + mov [base_code],0Fh + mov [extended_code],1 + call take_register + or al,al + jnz invalid_operand + mov bl,ah + mov [operand_size],0 + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + cmp ax,0401h + jne invalid_operand + mov ah,bl + jmp simple_svm_detect_size + +rdrand_instruction: + mov [base_code],0Fh + mov [extended_code],0C7h + mov [postbyte_register],al + call take_register + mov bl,al + mov al,ah + call operand_autodetect + jmp nomem_instruction_ready +rdfsbase_instruction: + cmp [code_type],64 + jne illegal_instruction + mov [opcode_prefix],0F3h + mov [base_code],0Fh + mov [extended_code],0AEh + mov [postbyte_register],al + call take_register + mov bl,al + mov al,ah + cmp ah,2 + je invalid_operand_size + call operand_autodetect + jmp nomem_instruction_ready + +xabort_instruction: + lods byte [esi] + call get_size_operator + cmp ah,1 + ja invalid_operand_size + cmp al,'(' + jne invalid_operand + call get_byte_value + mov dl,al + mov ax,0F8C6h + stos word [edi] + mov al,dl + stos byte [edi] + jmp instruction_assembled +xbegin_instruction: + lods byte [esi] + cmp al,'(' + jne invalid_operand + mov al,[code_type] + cmp al,64 + je xbegin_64bit + cmp al,32 + je xbegin_32bit + xbegin_16bit: + call get_address_word_value + add edi,4 + mov ebp,[addressing_space] + call calculate_relative_offset + sub edi,4 + shl eax,16 + mov ax,0F8C7h + stos dword [edi] + jmp instruction_assembled + xbegin_32bit: + call get_address_dword_value + jmp xbegin_address_ok + xbegin_64bit: + call get_address_qword_value + xbegin_address_ok: + add edi,5 + mov ebp,[addressing_space] + call calculate_relative_offset + sub edi,5 + mov edx,eax + cwde + cmp eax,edx + jne xbegin_rel32 + mov al,66h + stos byte [edi] + mov eax,edx + shl eax,16 + mov ax,0F8C7h + stos dword [edi] + jmp instruction_assembled + xbegin_rel32: + sub edx,1 + jno xbegin_rel32_ok + cmp [code_type],64 + je jump_out_of_range + xbegin_rel32_ok: + mov ax,0F8C7h + stos word [edi] + mov eax,edx + stos dword [edi] + jmp instruction_assembled + +bndcl_instruction: + mov ah,0F3h + jmp bndc_instruction +bndcu_instruction: + mov ah,0F2h + bndc_instruction: + mov [opcode_prefix],ah + mov [base_code],0Fh + mov [extended_code],al + call take_bnd_register + mov [postbyte_register],al + call get_bnd_size + mov [operand_size],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + je bndc_mem + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + mov bl,al + jmp nomem_instruction_ready + bndc_mem: + call get_address_of_required_size + jmp instruction_ready +bndmov_instruction: + mov [opcode_prefix],66h + mov [base_code],0Fh + mov [extended_code],al + call get_bnd_size + shl al,1 + mov [operand_size],al + lods byte [esi] + cmp al,14h + je bndmov_reg + call get_size_operator + cmp al,'[' + jne invalid_operand + inc [extended_code] + call get_address_of_required_size + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_bnd_register + mov [postbyte_register],al + jmp instruction_ready + bndmov_reg: + lods byte [esi] + call convert_bnd_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + cmp al,14h + je bndmov_reg_reg + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address_of_required_size + jmp instruction_ready + bndmov_reg_reg: + lods byte [esi] + call convert_bnd_register + mov bl,al + jmp nomem_instruction_ready + take_bnd_register: + lods byte [esi] + cmp al,14h + jne invalid_operand + lods byte [esi] + convert_bnd_register: + mov ah,al + shr ah,4 + cmp ah,6 + jne invalid_operand + and al,1111b + ret +bndmk_instruction: + mov [opcode_prefix],0F3h + mov [base_code],0Fh + mov [extended_code],al + call take_bnd_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_bnd_size + call get_address_prefixes + call get_address_component + cmp byte [esi-1],']' + je bndmk_ready + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + cmp al,'(' + jne invalid_operand + or dl,bl + or dl,[address_sign] + or edx,[address_high] + jnz invalid_address + mov [address_register],bh + call get_address_component + lods byte [esi] + cmp al,']' + jne invalid_operand + or bh,bh + jz bndmk_selected_base + cmp bl,bh + je bndmk_to_index + or bl,bl + jnz invalid_address + mov bl,bh + bndmk_to_index: + inc cl + bndmk_selected_base: + mov bh,[address_register] + bndmk_ready: + or bx,bx + jz instruction_ready + cmp [address_size_declared],0 + jne instruction_ready + and ch,not 0Fh + jmp instruction_ready + get_bnd_size: + mov al,4 + cmp [code_type],64 + jne bnd_size_ok + add al,4 + bnd_size_ok: + mov [address_size],al + ret + get_address_component: + mov [free_address_range],0 + call calculate_address + mov [address_high],edx + mov edx,eax + or bx,bx + jz address_component_ok + mov al,bl + or al,bh + shr al,4 + cmp al,[address_size] + jne invalid_address + address_component_ok: + ret +bndldx_instruction: + mov [base_code],0Fh + mov [extended_code],al + call take_bnd_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_bnd_mib + jmp bndmk_ready +bndstx_instruction: + mov [base_code],0Fh + mov [extended_code],al + call take_bnd_mib + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_bnd_register + mov [postbyte_register],al + jmp bndmk_ready + take_bnd_mib: + lods byte [esi] + cmp al,'[' + jne invalid_operand + call get_bnd_size + call get_address_prefixes + call get_address_component + cmp byte [esi-1],']' + je bnd_mib_ok + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + cmp al,'(' + jne invalid_operand + mov al,[address_sign] + push eax ebx ecx edx + push [address_symbol] + call get_address_component + lods byte [esi] + cmp al,']' + jne invalid_operand + or dl,bl + or dl,[address_sign] + or edx,[address_high] + jnz invalid_address + mov [address_register],bh + pop [address_symbol] + pop edx ecx ebx eax + mov [address_sign],al + or bl,bl + jz mib_place_index + or bh,bh + jnz invalid_address + cmp cl,1 + jne invalid_address + mov bh,bl + mib_place_index: + mov bl,[address_register] + xor cl,cl + or bl,bl + jz bnd_mib_ok + inc cl + bnd_mib_ok: + ret + +tpause_instruction: + mov [postbyte_register],6 + mov [extended_code],0AEh + mov [base_code],0Fh + mov [opcode_prefix],al + call take_register + cmp ah,4 + jne invalid_operand_size + mov bl,al + cmp byte [esi],',' + jne nomem_instruction_ready + inc esi + call take_register + cmp ax,0402h + jne invalid_operand + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + cmp ax,0400h + jne invalid_operand + jmp nomem_instruction_ready +umonitor_instruction: + mov [postbyte_register],6 + mov [extended_code],0AEh + mov [base_code],0Fh + mov [opcode_prefix],0F3h + call take_register + mov bl,al + mov al,ah + call operand_autodetect + jmp nomem_instruction_ready +movdir64b_instruction: + call setup_66_0f_38 + call take_register + mov [postbyte_register],al + xor al,al + xchg al,[operand_size] + push eax + lods byte [esi] + cmp al,',' + jne invalid_operand + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + mov al,[operand_size] + or al,al + jz movdir64b_ready + cmp al,64 + jne invalid_operand_size + movdir64b_ready: + push edi + call store_instruction + pop ebx eax + mov cl,[code_type] + cmp byte [ebx],67h + jne movdir64b_size_check + shr cl,1 + cmp cl,16 + jae movdir64b_size_check + mov cl,32 + movdir64b_size_check: + shl al,3 + cmp al,cl + jne invalid_operand_size + jmp instruction_assembled + +setssbsy_instruction: + shl eax,24 + or eax,010FF3h + stos dword [edi] + jmp instruction_assembled +rstorssp_instruction: + mov ah,1 + jmp setup_clrssbsy +clrssbsy_instruction: + mov ah,0AEh + setup_clrssbsy: + mov [base_code],0Fh + mov [extended_code],ah + mov [postbyte_register],al + mov [opcode_prefix],0F3h + lods byte [esi] + call get_size_operator + cmp al,'[' + jne invalid_operand + call get_address + test [operand_size],not 8 + jnz invalid_operand_size + jmp instruction_ready +rdsspq_instruction: + mov [rex_prefix],48h +rdsspd_instruction: + mov ah,1Eh + jmp setup_incssp +incsspq_instruction: + mov [rex_prefix],48h +incsspd_instruction: + mov ah,0AEh + setup_incssp: + mov [base_code],0Fh + mov [extended_code],ah + mov [postbyte_register],al + mov [opcode_prefix],0F3h + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] + call convert_register + mov bl,al + call cet_size_check + jmp nomem_instruction_ready + cet_size_check: + cmp [rex_prefix],0 + je cet_dword + cmp [code_type],64 + jne illegal_instruction + shr ah,1 + cet_dword: + cmp ah,4 + jne invalid_operand_size + ret +wrussq_instruction: + mov [opcode_prefix],66h +wrssq_instruction: + mov [rex_prefix],48h + jmp wrssd_instruction +wrussd_instruction: + mov [opcode_prefix],66h +wrssd_instruction: + mov [base_code],0Fh + mov [extended_code],38h + mov [supplemental_code],al + lods byte [esi] + call get_size_operator + cmp al,10h + je wrss_reg + cmp al,'[' + jne invalid_operand + call get_address + push edx ebx ecx + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + mov [postbyte_register],al + pop ecx ebx edx + call cet_size_check + jmp instruction_ready + wrss_reg: + lods byte [esi] + call convert_register + mov [postbyte_register],al + lods byte [esi] + cmp al,',' + jne invalid_operand + call take_register + mov bl,al + xchg bl,[postbyte_register] + call cet_size_check + jmp nomem_instruction_ready +endbr_instruction: + shl eax,24 + or eax,1E0FF3h + stos dword [edi] + jmp instruction_assembled + +take_register: + lods byte [esi] + call get_size_operator + cmp al,10h + jne invalid_operand + lods byte [esi] +convert_register: + mov ah,al + shr ah,4 + and al,0Fh + cmp ah,8 + je match_register_size + cmp ah,4 + ja invalid_operand + cmp ah,1 + ja match_register_size + cmp al,4 + jb match_register_size + or ah,ah + jz high_byte_register + or [rex_prefix],40h + match_register_size: + cmp ah,[operand_size] + je register_size_ok + cmp [operand_size],0 + jne operand_sizes_do_not_match + mov [operand_size],ah + register_size_ok: + ret + high_byte_register: + mov ah,1 + or [rex_prefix],10h + jmp match_register_size +convert_fpu_register: + mov ah,al + shr ah,4 + and al,111b + cmp ah,10 + jne invalid_operand + jmp match_register_size +convert_mmx_register: + mov ah,al + shr ah,4 + cmp ah,0Ch + je xmm_register + ja invalid_operand + and al,111b + cmp ah,0Bh + jne invalid_operand + mov ah,8 + jmp match_register_size + xmm_register: + and al,0Fh + mov ah,16 + cmp al,8 + jb match_register_size + cmp [code_type],64 + jne invalid_operand + jmp match_register_size +convert_xmm_register: + mov ah,al + shr ah,4 + cmp ah,0Ch + je xmm_register + jmp invalid_operand +get_size_operator: + xor ah,ah + cmp al,11h + jne no_size_operator + mov [size_declared],1 + lods word [esi] + xchg al,ah + or [operand_flags],1 + cmp ah,[operand_size] + je size_operator_ok + cmp [operand_size],0 + jne operand_sizes_do_not_match + mov [operand_size],ah + size_operator_ok: + ret + no_size_operator: + mov [size_declared],0 + cmp al,'[' + jne size_operator_ok + and [operand_flags],not 1 + ret +get_jump_operator: + mov [jump_type],0 + cmp al,12h + jne jump_operator_ok + lods word [esi] + mov [jump_type],al + mov al,ah + jump_operator_ok: + ret +get_address: + and [address_size],0 + get_address_of_required_size: + call get_address_prefixes + and [free_address_range],0 + call calculate_address + cmp byte [esi-1],']' + jne invalid_address + mov [address_high],edx + mov edx,eax + cmp [address_size_declared],0 + jne address_ok + cmp [segment_register],4 + ja address_ok + or bx,bx + jnz clear_address_size + cmp [code_type],64 + jne address_ok + calculate_relative_address: + mov edx,[address_symbol] + mov [symbol_identifier],edx + mov edx,[address_high] + mov ebp,[addressing_space] + call calculate_relative_offset + mov [address_high],edx + cdq + cmp edx,[address_high] + je address_high_ok + call recoverable_overflow + address_high_ok: + mov edx,eax + ror ecx,16 + mov cl,[value_type] + rol ecx,16 + mov bx,9900h + clear_address_size: + and ch,not 0Fh + address_ok: + ret +get_address_prefixes: + and [segment_register],0 + and [address_size_declared],0 + mov al,[code_type] + shr al,3 + mov [value_size],al + mov al,[esi] + and al,11110000b + cmp al,60h + jne get_address_size_prefix + lods byte [esi] + sub al,60h + mov [segment_register],al + mov al,[esi] + and al,11110000b + get_address_size_prefix: + cmp al,70h + jne address_size_prefix_ok + lods byte [esi] + sub al,70h + cmp al,2 + jb invalid_address_size + cmp al,8 + ja invalid_address_size + mov [value_size],al + or [address_size_declared],1 + or [address_size],al + cmp al,[address_size] + jne invalid_address_size + address_size_prefix_ok: + ret +operand_16bit: + cmp [code_type],16 + je size_prefix_ok + mov [operand_prefix],66h + ret +operand_32bit: + cmp [code_type],16 + jne size_prefix_ok + mov [operand_prefix],66h + size_prefix_ok: + ret +operand_64bit: + cmp [code_type],64 + jne illegal_instruction + or [rex_prefix],48h + ret +operand_autodetect: + cmp al,2 + je operand_16bit + cmp al,4 + je operand_32bit + cmp al,8 + je operand_64bit + jmp invalid_operand_size +store_segment_prefix_if_necessary: + mov al,[segment_register] + or al,al + jz segment_prefix_ok + cmp al,4 + ja segment_prefix_386 + cmp [code_type],64 + je segment_prefix_ok + cmp al,3 + je ss_prefix + jb segment_prefix_86 + cmp bl,25h + je segment_prefix_86 + cmp bh,25h + je segment_prefix_86 + cmp bh,45h + je segment_prefix_86 + cmp bh,44h + je segment_prefix_86 + ret + ss_prefix: + cmp bl,25h + je segment_prefix_ok + cmp bh,25h + je segment_prefix_ok + cmp bh,45h + je segment_prefix_ok + cmp bh,44h + je segment_prefix_ok + jmp segment_prefix_86 +store_segment_prefix: + mov al,[segment_register] + or al,al + jz segment_prefix_ok + cmp al,5 + jae segment_prefix_386 + segment_prefix_86: + dec al + shl al,3 + add al,26h + stos byte [edi] + jmp segment_prefix_ok + segment_prefix_386: + add al,64h-5 + stos byte [edi] + segment_prefix_ok: + ret +store_instruction_code: + cmp [vex_required],0 + jne store_vex_instruction_code +store_classic_instruction_code: + mov al,[operand_prefix] + or al,al + jz operand_prefix_ok + stos byte [edi] + operand_prefix_ok: + mov al,[opcode_prefix] + or al,al + jz opcode_prefix_ok + stos byte [edi] + opcode_prefix_ok: + mov al,[rex_prefix] + test al,40h + jz rex_prefix_ok + cmp [code_type],64 + jne invalid_operand + test al,0B0h + jnz disallowed_combination_of_registers + stos byte [edi] + rex_prefix_ok: + mov al,[base_code] + stos byte [edi] + cmp al,0Fh + jne instruction_code_ok + store_extended_code: + mov al,[extended_code] + stos byte [edi] + cmp al,38h + je store_supplemental_code + cmp al,3Ah + je store_supplemental_code + instruction_code_ok: + ret + store_supplemental_code: + mov al,[supplemental_code] + stos byte [edi] + ret +store_nomem_instruction: + test [postbyte_register],10000b + jz nomem_reg_high_code_ok + or [vex_required],10h + and [postbyte_register],1111b + nomem_reg_high_code_ok: + test [postbyte_register],1000b + jz nomem_reg_code_ok + or [rex_prefix],44h + and [postbyte_register],111b + nomem_reg_code_ok: + test bl,10000b + jz nomem_rm_high_code_ok + or [rex_prefix],42h + or [vex_required],8 + and bl,1111b + nomem_rm_high_code_ok: + test bl,1000b + jz nomem_rm_code_ok + or [rex_prefix],41h + and bl,111b + nomem_rm_code_ok: + and [displacement_compression],0 + call store_instruction_code + mov al,[postbyte_register] + shl al,3 + or al,bl + or al,11000000b + stos byte [edi] + ret +store_instruction: + mov [current_offset],edi + and [displacement_compression],0 + test [postbyte_register],10000b + jz reg_high_code_ok + or [vex_required],10h + and [postbyte_register],1111b + reg_high_code_ok: + test [postbyte_register],1000b + jz reg_code_ok + or [rex_prefix],44h + and [postbyte_register],111b + reg_code_ok: + cmp [code_type],64 + jne address_value_ok + xor eax,eax + bt edx,31 + sbb eax,[address_high] + jz address_value_ok + cmp [address_high],0 + jne address_value_out_of_range + test ch,44h + jnz address_value_ok + test bx,8080h + jz address_value_ok + address_value_out_of_range: + call recoverable_overflow + address_value_ok: + call store_segment_prefix_if_necessary + test [vex_required],4 + jnz address_vsib + or bx,bx + jz address_immediate + cmp bx,9800h + je address_rip_based + cmp bx,9400h + je address_eip_based + cmp bx,9900h + je address_relative + mov al,bl + or al,bh + and al,11110000b + cmp al,80h + je postbyte_64bit + cmp al,40h + je postbyte_32bit + cmp al,20h + jne invalid_address + cmp [code_type],64 + je invalid_address_size + call address_16bit_prefix + test ch,22h + setz [displacement_compression] + call store_instruction_code + cmp bl,bh + jbe determine_16bit_address + xchg bl,bh + determine_16bit_address: + cmp bx,2600h + je address_si + cmp bx,2700h + je address_di + cmp bx,2300h + je address_bx + cmp bx,2500h + je address_bp + cmp bx,2625h + je address_bp_si + cmp bx,2725h + je address_bp_di + cmp bx,2723h + je address_bx_di + cmp bx,2623h + jne invalid_address + address_bx_si: + xor al,al + jmp postbyte_16bit + address_bx_di: + mov al,1 + jmp postbyte_16bit + address_bp_si: + mov al,10b + jmp postbyte_16bit + address_bp_di: + mov al,11b + jmp postbyte_16bit + address_si: + mov al,100b + jmp postbyte_16bit + address_di: + mov al,101b + jmp postbyte_16bit + address_bx: + mov al,111b + jmp postbyte_16bit + address_bp: + mov al,110b + postbyte_16bit: + test ch,22h + jnz address_16bit_value + or ch,ch + jnz address_sizes_do_not_agree + cmp edx,10000h + jge value_out_of_range + cmp edx,-8000h + jl value_out_of_range + or dx,dx + jz address + cmp [displacement_compression],2 + ja address_8bit_value + je address_16bit_value + cmp dx,80h + jb address_8bit_value + cmp dx,-80h + jae address_8bit_value + address_16bit_value: + or al,10000000b + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos byte [edi] + mov eax,edx + stos word [edi] + ret + address_8bit_value: + or al,01000000b + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos byte [edi] + mov al,dl + stos byte [edi] + ret + address: + cmp al,110b + je address_8bit_value + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos byte [edi] + ret + address_vsib: + mov al,bl + shr al,4 + test al,1 + jz vsib_high_code_ok + or [vex_register],10000b + or [vex_required],8 + xor al,1 + vsib_high_code_ok: + cmp al,6 + je vsib_index_ok + cmp al,0Ch + jb invalid_address + vsib_index_ok: + mov al,bh + shr al,4 + cmp al,4 + je postbyte_32bit + cmp [code_type],64 + je address_prefix_ok + test al,al + jnz invalid_address + postbyte_32bit: + call address_32bit_prefix + jmp address_prefix_ok + postbyte_64bit: + cmp [code_type],64 + jne invalid_address_size + address_prefix_ok: + cmp bl,44h + je invalid_address + cmp bl,84h + je invalid_address + test bh,1000b + jz base_code_ok + or [rex_prefix],41h + base_code_ok: + test bl,1000b + jz index_code_ok + or [rex_prefix],42h + index_code_ok: + test ch,44h or 88h + setz [displacement_compression] + call store_instruction_code + or cl,cl + jz only_base_register + base_and_index: + mov al,100b + xor ah,ah + cmp cl,1 + je scale_ok + cmp cl,2 + je scale_1 + cmp cl,4 + je scale_2 + or ah,11000000b + jmp scale_ok + scale_2: + or ah,10000000b + jmp scale_ok + scale_1: + or ah,01000000b + scale_ok: + or bh,bh + jz only_index_register + and bl,111b + shl bl,3 + or ah,bl + and bh,111b + or ah,bh + sib_ready: + test ch,44h or 88h + jnz sib_address_32bit_value + or ch,ch + jnz address_sizes_do_not_agree + cmp bh,5 + je address_value + or edx,edx + jz sib_address + address_value: + cmp [displacement_compression],2 + ja sib_address_8bit_value + je sib_address_32bit_value + cmp edx,80h + jb sib_address_8bit_value + cmp edx,-80h + jnb sib_address_8bit_value + sib_address_32bit_value: + or al,10000000b + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos word [edi] + jmp store_address_32bit_value + sib_address_8bit_value: + or al,01000000b + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos word [edi] + mov al,dl + stos byte [edi] + ret + sib_address: + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos word [edi] + ret + only_index_register: + or ah,101b + and bl,111b + shl bl,3 + or ah,bl + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos word [edi] + test ch,44h or 88h + jnz store_address_32bit_value + or ch,ch + jnz invalid_address_size + cmp [displacement_compression],2 + jbe store_address_32bit_value + mov edx,[uncompressed_displacement] + jmp store_address_32bit_value + zero_index_register: + mov bl,4 + mov cl,1 + jmp base_and_index + only_base_register: + mov al,bh + and al,111b + cmp al,4 + je zero_index_register + test ch,44h or 88h + jnz simple_address_32bit_value + or ch,ch + jnz address_sizes_do_not_agree + or edx,edx + jz simple_address + cmp [displacement_compression],2 + ja simple_address_8bit_value + je simple_address_32bit_value + cmp edx,80h + jb simple_address_8bit_value + cmp edx,-80h + jnb simple_address_8bit_value + simple_address_32bit_value: + or al,10000000b + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos byte [edi] + jmp store_address_32bit_value + simple_address_8bit_value: + or al,01000000b + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos byte [edi] + mov al,dl + stos byte [edi] + ret + simple_address: + cmp al,5 + je simple_address_8bit_value + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos byte [edi] + ret + address_immediate: + cmp [code_type],64 + je address_immediate_sib + test ch,44h or 88h + jnz address_immediate_32bit + test ch,22h + jnz address_immediate_16bit + or ch,ch + jnz invalid_address_size + cmp [code_type],16 + je addressing_16bit + address_immediate_32bit: + call address_32bit_prefix + call store_instruction_code + store_immediate_address: + mov al,101b + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos byte [edi] + store_address_32bit_value: + test ch,0F0h + jz address_32bit_relocation_ok + mov eax,ecx + shr eax,16 + cmp al,4 + jne address_32bit_relocation + mov al,2 + address_32bit_relocation: + xchg [value_type],al + mov ebx,[address_symbol] + xchg ebx,[symbol_identifier] + call mark_relocation + mov [value_type],al + mov [symbol_identifier],ebx + address_32bit_relocation_ok: + mov eax,edx + stos dword [edi] + ret + store_address_64bit_value: + test ch,0F0h + jz address_64bit_relocation_ok + mov eax,ecx + shr eax,16 + xchg [value_type],al + mov ebx,[address_symbol] + xchg ebx,[symbol_identifier] + call mark_relocation + mov [value_type],al + mov [symbol_identifier],ebx + address_64bit_relocation_ok: + mov eax,edx + stos dword [edi] + mov eax,[address_high] + stos dword [edi] + ret + address_immediate_sib: + test ch,44h + jnz address_immediate_sib_32bit + test ch,not 88h + jnz invalid_address_size + test edx,80000000h + jz address_immediate_sib_store + cmp [address_high],0 + je address_immediate_sib_nosignextend + address_immediate_sib_store: + call store_instruction_code + mov al,100b + mov ah,100101b + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos word [edi] + jmp store_address_32bit_value + address_immediate_sib_32bit: + test ecx,0FF0000h + jnz address_immediate_sib_nosignextend + test edx,80000000h + jz address_immediate_sib_store + address_immediate_sib_nosignextend: + call address_32bit_prefix + jmp address_immediate_sib_store + address_eip_based: + mov al,67h + stos byte [edi] + address_rip_based: + cmp [code_type],64 + jne invalid_address + call store_instruction_code + jmp store_immediate_address + address_relative: + call store_instruction_code + movzx eax,[immediate_size] + add eax,edi + sub eax,[current_offset] + add eax,5 + sub edx,eax + jno address_relative_ok + call recoverable_overflow + address_relative_ok: + mov al,101b + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos byte [edi] + shr ecx,16 + xchg [value_type],cl + mov ebx,[address_symbol] + xchg ebx,[symbol_identifier] + mov eax,edx + call mark_relocation + mov [value_type],cl + mov [symbol_identifier],ebx + stos dword [edi] + ret + addressing_16bit: + cmp edx,10000h + jge address_immediate_32bit + cmp edx,-8000h + jl address_immediate_32bit + movzx edx,dx + address_immediate_16bit: + call address_16bit_prefix + call store_instruction_code + mov al,110b + mov cl,[postbyte_register] + shl cl,3 + or al,cl + stos byte [edi] + mov eax,edx + stos word [edi] + cmp edx,10000h + jge value_out_of_range + cmp edx,-8000h + jl value_out_of_range + ret + address_16bit_prefix: + cmp [code_type],16 + je instruction_prefix_ok + mov al,67h + stos byte [edi] + ret + address_32bit_prefix: + cmp [code_type],32 + je instruction_prefix_ok + mov al,67h + stos byte [edi] + instruction_prefix_ok: + ret +store_instruction_with_imm8: + mov [immediate_size],1 + call store_instruction + mov al,byte [value] + stos byte [edi] + ret +store_instruction_with_imm16: + mov [immediate_size],2 + call store_instruction + mov ax,word [value] + call mark_relocation + stos word [edi] + ret +store_instruction_with_imm32: + mov [immediate_size],4 + call store_instruction + mov eax,dword [value] + call mark_relocation + stos dword [edi] + ret diff --git a/toolchain/fasmw17332/TOOLS/DOS/LISTING.ASM b/toolchain/fasmw17332/TOOLS/DOS/LISTING.ASM new file mode 100644 index 0000000..b160732 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/DOS/LISTING.ASM @@ -0,0 +1,229 @@ + + format MZ + heap 0 + stack 8000h + entry loader:init + +include 'loader.inc' + +segment main use32 + + start: + + call get_params + jnc make_listing + + mov esi,_usage + call display_string + mov ax,4C02h + int 21h + + make_listing: + call listing + mov ax,4C00h + int 21h + + error: + mov esi,_error_prefix + call display_string + pop esi + call display_string + mov esi,_error_suffix + call display_string + mov ax,4C00h + int 21h + + get_params: + push ds + mov ds,[psp_selector] + mov esi,81h + mov edi,params + find_param: + lodsb + cmp al,20h + je find_param + cmp al,'-' + je option_param + cmp al,0Dh + je all_params + or al,al + jz all_params + cmp [es:input_file],0 + jne get_output_file + mov [es:input_file],edi + jmp process_param + get_output_file: + cmp [es:output_file],0 + jne bad_params + mov [es:output_file],edi + process_param: + cmp al,22h + je string_param + copy_param: + stosb + lodsb + cmp al,20h + je param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + jmp copy_param + string_param: + lodsb + cmp al,22h + je string_param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + stosb + jmp string_param + option_param: + lodsb + cmp al,'a' + je addresses_option + cmp al,'A' + je addresses_option + cmp al,'b' + je bytes_per_line_option + cmp al,'B' + je bytes_per_line_option + invalid_option: + pop ds + stc + ret + get_option_value: + xor eax,eax + mov edx,eax + get_option_digit: + lodsb + cmp al,20h + je option_value_ok + cmp al,0Dh + je option_value_ok + or al,al + jz option_value_ok + sub al,30h + jc bad_params_value + cmp al,9 + ja bad_params_value + imul edx,10 + jo bad_params_value + add edx,eax + jc bad_params_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + bad_params_value: + stc + ret + bytes_per_line_option: + lodsb + cmp al,20h + je bytes_per_line_option + cmp al,0Dh + je invalid_option + or al,al + jz invalid_option + dec esi + call get_option_value + jc bad_params + or edx,edx + jz invalid_option + cmp edx,1000 + ja invalid_option + mov [es:code_bytes_per_line],edx + jmp find_param + addresses_option: + lodsb + cmp al,20h + je set_addresses_option + cmp al,0Dh + je set_addresses_option + or al,al + jnz bad_params + set_addresses_option: + dec esi + mov [es:show_addresses],1 + jmp find_param + param_end: + dec esi + string_param_end: + xor al,al + stosb + jmp find_param + all_params: + xor al,al + stosb + pop ds + cmp [input_file],0 + je bad_params + cmp [output_file],0 + je bad_params + clc + ret + bad_params: + stc + ret + + include 'system.inc' + + include '..\listing.inc' + + _usage db 'listing generator for flat assembler',0Dh,0Ah + db 'usage: listing ',0Dh,0Ah + db 'optional settings:',0Dh,0Ah + db ' -a show target addresses for assembled code',0Dh,0Ah + db ' -b set the amount of bytes listed per line',0Dh,0Ah + db 0 + _error_prefix db 'error: ',0 + _error_suffix db '.',0Dh,0Ah,0 + + input_file dd 0 + output_file dd 0 + code_bytes_per_line dd 16 + show_addresses db 0 + + line_break db 0Dh,0Ah + + input dd ? + assembled_code dd ? + assembled_code_length dd ? + code_end dd ? + code_offset dd ? + code_length dd ? + output_handle dd ? + output_buffer dd ? + current_source_file dd ? + current_source_line dd ? + source dd ? + source_length dd ? + maximum_address_length dd ? + address_start dd ? + last_listed_address dd ? + + psp_selector dw ? + environment_selector dw ? + + memory_handles_count dd ? + memory_handles rd 400h + + params rb 1000h + characters rb 100h + +segment buffer_segment + + buffer = (buffer_segment-main) shl 4 + + db 1000h dup ? + +segment stack_segment + + stack_bottom = (stack_segment-main) shl 4 + + db 4000h dup ? + + stack_top = stack_bottom + $ diff --git a/toolchain/fasmw17332/TOOLS/DOS/LOADER.INC b/toolchain/fasmw17332/TOOLS/DOS/LOADER.INC new file mode 100644 index 0000000..933c918 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/DOS/LOADER.INC @@ -0,0 +1,102 @@ + +segment loader use16 + +init: + + mov ax,1687h + int 2Fh + or ax,ax ; DPMI installed? + jnz short no_dpmi + test bl,1 ; 32-bit programs supported? + jz short no_dpmi + mov word [cs:mode_switch],di + mov word [cs:mode_switch+2],es + mov bx,si ; allocate memory for DPMI data + mov ah,48h + int 21h + jnc init_protected_mode + init_failed: + call init_error + db 'error: DPMI initialization failed.',0Dh,0Ah,0 + no_dpmi: + call init_error + db 'error: 32-bit DPMI services are not available.',0Dh,0Ah,0 + init_error: + pop si + push cs + pop ds + display_error: + lodsb + test al,al + jz short error_finish + mov dl,al + mov ah,2 + int 21h + jmp short display_error + error_finish: + mov ax,4CFFh + int 21h + init_protected_mode: + mov es,ax + mov ds,[ds:2Ch] + mov ax,1 + call far [cs:mode_switch] ; switch to protected mode + jc init_failed + mov cx,1 + xor ax,ax + int 31h ; allocate descriptor for code + jc init_failed + mov si,ax + xor ax,ax + int 31h ; allocate descriptor for data + jc init_failed + mov di,ax + mov dx,cs + lar cx,dx + shr cx,8 + or cx,0C000h + mov bx,si + mov ax,9 + int 31h ; set code descriptor access rights + jc init_failed + mov dx,ds + lar cx,dx + shr cx,8 + or cx,0C000h + mov bx,di + int 31h ; set data descriptor access rights + jc init_failed + mov ecx,main + shl ecx,4 + mov dx,cx + shr ecx,16 + mov ax,7 + int 31h ; set data descriptor base address + jc init_failed + mov bx,si + int 31h ; set code descriptor base address + jc init_failed + mov cx,0FFFFh + mov dx,0FFFFh + mov ax,8 ; set segment limit to 4 GB + int 31h + jc init_failed + mov bx,di + int 31h + jc init_failed + mov ax,ds + mov ds,di + mov [psp_selector],es + mov [environment_selector],ax + cli + mov ss,di + mov esp,stack_top + sti + mov es,di + xor eax,eax + mov [memory_handles_count],eax + push si + push start + retf + + mode_switch dd ? diff --git a/toolchain/fasmw17332/TOOLS/DOS/PREPSRC.ASM b/toolchain/fasmw17332/TOOLS/DOS/PREPSRC.ASM new file mode 100644 index 0000000..aa0d654 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/DOS/PREPSRC.ASM @@ -0,0 +1,136 @@ + + format MZ + heap 0 + stack 8000h + entry loader:init + +include 'loader.inc' + +segment main use32 + + start: + + call get_params + jnc make_dump + + mov esi,_usage + call display_string + mov ax,4C02h + int 21h + + make_dump: + call preprocessed_source + mov ax,4C00h + int 21h + + error: + mov esi,_error_prefix + call display_string + pop esi + call display_string + mov esi,_error_suffix + call display_string + mov ax,4C00h + int 21h + + get_params: + push ds + mov ds,[psp_selector] + mov esi,81h + mov edi,params + find_param: + lodsb + cmp al,20h + je find_param + cmp al,0Dh + je all_params + or al,al + jz all_params + cmp [es:input_file],0 + jne get_output_file + mov [es:input_file],edi + jmp process_param + get_output_file: + cmp [es:output_file],0 + jne bad_params + mov [es:output_file],edi + process_param: + cmp al,22h + je string_param + copy_param: + stosb + lodsb + cmp al,20h + je param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + jmp copy_param + string_param: + lodsb + cmp al,22h + je string_param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + stosb + jmp string_param + bad_params_value: + stc + ret + param_end: + dec esi + string_param_end: + xor al,al + stosb + jmp find_param + all_params: + xor al,al + stosb + pop ds + cmp [input_file],0 + je bad_params + cmp [output_file],0 + je bad_params + clc + ret + bad_params: + stc + ret + + include 'system.inc' + + include '..\prepsrc.inc' + + _usage db 'preprocessed source dumper for flat assembler',0Dh,0Ah + db 'usage: prepsrc ',0Dh,0Ah + db 0 + _error_prefix db 'error: ',0 + _error_suffix db '.',0Dh,0Ah,0 + + input_file dd 0 + output_file dd 0 + + psp_selector dw ? + environment_selector dw ? + + memory_handles_count dd ? + memory_handles rd 400h + + params rb 1000h + +segment buffer_segment + + buffer = (buffer_segment-main) shl 4 + + db 1000h dup ? + +segment stack_segment + + stack_bottom = (stack_segment-main) shl 4 + + db 4000h dup ? + + stack_top = stack_bottom + $ diff --git a/toolchain/fasmw17332/TOOLS/DOS/SYMBOLS.ASM b/toolchain/fasmw17332/TOOLS/DOS/SYMBOLS.ASM new file mode 100644 index 0000000..0b96961 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/DOS/SYMBOLS.ASM @@ -0,0 +1,140 @@ + + format MZ + heap 0 + stack 8000h + entry loader:init + +include 'loader.inc' + +segment main use32 + + start: + + call get_params + jnc make_dump + + mov esi,_usage + call display_string + mov ax,4C02h + int 21h + + make_dump: + call symbols + mov ax,4C00h + int 21h + + error: + mov esi,_error_prefix + call display_string + pop esi + call display_string + mov esi,_error_suffix + call display_string + mov ax,4C00h + int 21h + + get_params: + push ds + mov ds,[psp_selector] + mov esi,81h + mov edi,params + find_param: + lodsb + cmp al,20h + je find_param + cmp al,0Dh + je all_params + or al,al + jz all_params + cmp [es:input_file],0 + jne get_output_file + mov [es:input_file],edi + jmp process_param + get_output_file: + cmp [es:output_file],0 + jne bad_params + mov [es:output_file],edi + process_param: + cmp al,22h + je string_param + copy_param: + stosb + lodsb + cmp al,20h + je param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + jmp copy_param + string_param: + lodsb + cmp al,22h + je string_param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + stosb + jmp string_param + bad_params_value: + stc + ret + param_end: + dec esi + string_param_end: + xor al,al + stosb + jmp find_param + all_params: + xor al,al + stosb + pop ds + cmp [input_file],0 + je bad_params + cmp [output_file],0 + je bad_params + clc + ret + bad_params: + stc + ret + + include 'system.inc' + + include '..\symbols.inc' + + _usage db 'symbols dumper for flat assembler',0Dh,0Ah + db 'usage: symbols ',0Dh,0Ah + db 0 + _error_prefix db 'error: ',0 + _error_suffix db '.',0Dh,0Ah,0 + + input_file dd 0 + output_file dd 0 + + input dd ? + output_buffer dd ? + output_handle dd ? + + psp_selector dw ? + environment_selector dw ? + + memory_handles_count dd ? + memory_handles rd 400h + + params rb 1000h + +segment buffer_segment + + buffer = (buffer_segment-main) shl 4 + + db 1000h dup ? + +segment stack_segment + + stack_bottom = (stack_segment-main) shl 4 + + db 4000h dup ? + + stack_top = stack_bottom + $ diff --git a/toolchain/fasmw17332/TOOLS/DOS/SYSTEM.INC b/toolchain/fasmw17332/TOOLS/DOS/SYSTEM.INC new file mode 100644 index 0000000..67eb63f --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/DOS/SYSTEM.INC @@ -0,0 +1,239 @@ + +display_string: + lods byte [esi] + or al,al + jz string_end + mov dl,al + mov ah,2 + int 21h + jmp display_string + string_end: + ret +alloc: + push ebx esi edi + mov cx,ax + shr eax,16 + mov bx,ax + mov ax,501h + int 31h + jc dpmi_allocation_failed + mov ax,bx + shl eax,16 + mov ax,cx + mov edx,main + shl edx,4 + sub eax,edx + mov bx,si + shl ebx,16 + mov bx,di + mov ecx,[memory_handles_count] + inc [memory_handles_count] + shl ecx,3 + add ecx,memory_handles + mov [ecx],eax + mov [ecx+4],ebx + pop edi esi ebx + clc + ret + dpmi_allocation_failed: + pop edi esi ebx + stc + ret +free: + push ebx esi edi + mov esi,memory_handles + mov ecx,[memory_handles_count] + find_memory_handle: + cmp eax,[esi] + je memory_handle_found + add esi,8 + loop find_memory_handle + pop edi esi + ret + memory_handle_found: + mov ebx,[esi+4] + dec [memory_handles_count] + dec ecx + jz free_memory + remove_memory_handle: + mov edx,[esi+8] + mov edi,[esi+8+4] + mov [esi],edx + mov [esi+4],edi + add esi,8 + loop remove_memory_handle + free_memory: + mov esi,ebx + shr esi,16 + mov di,bx + mov ax,502h + int 31h + pop edi esi ebx + ret +open: + push esi edi ebp + call adapt_path + mov ax,716Ch + mov bx,100000b + mov dx,1 + xor cx,cx + xor si,si + call dos_int + jnc open_done + cmp ax,7100h + je old_open + stc + jmp open_done + old_open: + mov ax,3D00h + xor dx,dx + call dos_int + open_done: + mov bx,ax + pop ebp edi esi + ret + adapt_path: + mov esi,edx + mov edi,buffer + copy_path: + lodsb + cmp al,'/' + jne path_char_ok + mov al,'\' + path_char_ok: + stosb + or al,al + jnz copy_path + ret + dos_int: + push 0 0 0 + pushw buffer_segment buffer_segment + stc + pushfw + push eax + push ecx + push edx + push ebx + push 0 + push ebp + push esi + push edi + mov ax,300h + mov bx,21h + xor cx,cx + mov edi,esp + push es ss + pop es + int 31h + pop es + mov edi,[esp] + mov esi,[esp+4] + mov ebp,[esp+8] + mov ebx,[esp+10h] + mov edx,[esp+14h] + mov ecx,[esp+18h] + mov ah,[esp+20h] + add esp,32h + sahf + mov eax,[esp-32h+1Ch] + ret +create: + push esi edi ebp + call adapt_path + mov ax,716Ch + mov bx,100001b + mov dx,10010b + xor cx,cx + xor si,si + xor di,di + call dos_int + jnc create_done + cmp ax,7100h + je old_create + stc + jmp create_done + old_create: + mov ah,3Ch + xor cx,cx + xor dx,dx + call dos_int + create_done: + mov bx,ax + pop ebp edi esi + ret +write: + push edx esi edi ebp + mov ebp,ecx + mov esi,edx + write_loop: + mov ecx,1000h + sub ebp,1000h + jnc do_write + add ebp,1000h + mov ecx,ebp + xor ebp,ebp + do_write: + push ecx + mov edi,buffer + shr ecx,2 + rep movsd + mov ecx,[esp] + and ecx,11b + rep movsb + pop ecx + mov ah,40h + xor dx,dx + call dos_int + or ebp,ebp + jnz write_loop + pop ebp edi esi edx + ret +read: + push edx esi edi ebp + mov ebp,ecx + mov edi,edx + read_loop: + mov ecx,1000h + sub ebp,1000h + jnc do_read + add ebp,1000h + mov ecx,ebp + xor ebp,ebp + do_read: + push ecx + mov ah,3Fh + xor dx,dx + call dos_int + cmp ax,cx + jne eof + mov esi,buffer + mov ecx,[esp] + shr ecx,2 + rep movsd + pop ecx + and ecx,11b + rep movsb + or ebp,ebp + jnz read_loop + read_done: + pop ebp edi esi edx + ret + eof: + pop ecx + stc + jmp read_done +close: + mov ah,3Eh + int 21h + ret +lseek: + mov ah,42h + mov ecx,edx + shr ecx,16 + int 21h + pushf + shl edx,16 + popf + mov dx,ax + mov eax,edx + ret diff --git a/toolchain/fasmw17332/TOOLS/FAS.TXT b/toolchain/fasmw17332/TOOLS/FAS.TXT new file mode 100644 index 0000000..ed8786b --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/FAS.TXT @@ -0,0 +1,429 @@ + + flat assembler + Symbolic information file format + + + Table 1 Header + /-------------------------------------------------------------------------\ + | Offset | Size | Description | + |========|=========|======================================================| + | +0 | dword | Signature 1A736166h (little-endian). | + |--------|---------|------------------------------------------------------| + | +4 | byte | Major version of flat assembler. | + |--------|---------|------------------------------------------------------| + | +5 | byte | Minor version of flat assembler. | + |--------|---------|------------------------------------------------------| + | +6 | word | Length of header. | + |--------|---------|------------------------------------------------------| + | +8 | dword | Offset of input file name in the strings table. | + |--------|---------|------------------------------------------------------| + | +12 | dword | Offset of output file name in the strings table. | + |--------|---------|------------------------------------------------------| + | +16 | dword | Offset of strings table. | + |--------|---------|------------------------------------------------------| + | +20 | dword | Length of strings table. | + |--------|---------|------------------------------------------------------| + | +24 | dword | Offset of symbols table. | + |--------|---------|------------------------------------------------------| + | +28 | dword | Length of symbols table. | + |--------|---------|------------------------------------------------------| + | +32 | dword | Offset of preprocessed source. | + |--------|---------|------------------------------------------------------| + | +36 | dword | Length of preprocessed source. | + |--------|---------|------------------------------------------------------| + | +40 | dword | Offset of assembly dump. | + |--------|---------|------------------------------------------------------| + | +44 | dword | Length of assembly dump. | + |--------|---------|------------------------------------------------------| + | +48 | dword | Offset of section names table. | + |--------|---------|------------------------------------------------------| + | +52 | dword | Length of section names table. | + |--------|---------|------------------------------------------------------| + | +56 | dword | Offset of symbol references dump. | + |--------|---------|------------------------------------------------------| + | +60 | dword | Length of symbol references dump. | + \-------------------------------------------------------------------------/ + + Notes: + + If header is shorter than 64 bytes, it comes from a version that does not + support dumping some of the structures. It should then be interpreted + that the data for missing structures could not be provided, not that the + size of that data is zero. + + Offsets given in header generally mean positions in the file, however + input and output file names are specified by offsets in the strings table, + so you have to add their offset to the offset of strings table to obtain + the positions of those strings in the file. + + The strings table contains just a sequence of ASCIIZ strings, which may + be referred to by other parts of the file. It contains the names of + main input file, the output file, and the names of the sections and + external symbols if there were any. + + The symbols table is an array of 32-byte structures, each one in format + specified by table 2. + + The preprocessed source is a sequence of preprocessed lines, each one + in format as defined in table 3. + + The assembly dump contains an array of 28-byte structures, each one in + format specified by table 4, and at the end of this array an additional + double word containing the offset in output file at which the assembly + was ended. + + It is possible that file does not contain assembly dump at all - this + happens when some error occured and only the preprocessed source was + dumped. If error occured during the preprocessing, only the source up to + the point of error is provided. In such case (and only then) the field + at offset 44 contains zero. + + The section names table exists only when the output format was an object + file (ELF or COFF), and it is an array of 4-byte entries, each being an + offset of the name of the section in the strings table. + The index of section in this table is the same, as the index of section + in the generated object file. + + The symbol references dump contains an array of 8-byte structures, each + one describes an event of some symbol being used. The first double word + of such structure contains an offset of symbol in the symbols table, + and the second double word is an offset of structure in assembly dump, + which specifies at what moment the symbol was referenced. + + + Table 2 Symbol structure + /-------------------------------------------------------------------------\ + | Offset | Size | Description | + |========|=======|========================================================| + | +0 | qword | Value of symbol. | + |--------|-------|--------------------------------------------------------| + | +8 | word | Flags (table 2.1). | + |--------|-------|--------------------------------------------------------| + | +10 | byte | Size of data labelled by this symbol (zero means plain | + | | | label without size attached). | + |--------|-------|--------------------------------------------------------| + | +11 | byte | Type of value (table 2.2). Any value other than zero | + | | | means some kind of relocatable symbol. | + |--------|-------|--------------------------------------------------------| + | +12 | dword | Extended SIB, the first two bytes are register codes | + | | | and the second two bytes are corresponding scales. | + |--------|-------|--------------------------------------------------------| + | +16 | word | Number of pass in which symbol was defined last time. | + |--------|-------|--------------------------------------------------------| + | +18 | word | Number of pass in which symbol was used last time. | + |--------|-------|--------------------------------------------------------| + | +20 | dword | If the symbol is relocatable, this field contains | + | | | information about section or external symbol, to which | + | | | it is relative - otherwise this field has no meaning. | + | | | When the highest bit is cleared, the symbol is | + | | | relative to a section, and the bits 0-30 contain | + | | | the index (starting from 1) in the table of sections. | + | | | When the highest bit is set, the symbol is relative to | + | | | an external symbol, and the bits 0-30 contain the | + | | | the offset of the name of this symbol in the strings | + | | | table. | + |--------|-------|--------------------------------------------------------| + | +24 | dword | If the highest bit is cleared, the bits 0-30 contain | + | | | the offset of symbol name in the preprocessed source. | + | | | This name is a pascal-style string (byte length | + | | | followed by string data). | + | | | Zero in this field means an anonymous symbol. | + | | | If the highest bit is set, the bits 0-30 contain the | + | | | offset of the symbol name in the strings table, and | + | | | this name is a zero-ended string in this case (as are | + | | | all the strings there). | + |--------|-------|--------------------------------------------------------| + | +28 | dword | Offset in the preprocessed source of line that defined | + | | | this symbol (see table 3). | + \-------------------------------------------------------------------------/ + + + Table 2.1 Symbol flags + /-----------------------------------------------------------------\ + | Bit | Value | Description | + |=====|=======|===================================================| + | 0 | 1 | Symbol was defined. | + |-----|-------|---------------------------------------------------| + | 1 | 2 | Symbol is an assembly-time variable. | + |-----|-------|---------------------------------------------------| + | 2 | 4 | Symbol cannot be forward-referenced. | + |-----|-------|---------------------------------------------------| + | 3 | 8 | Symbol was used. | + |-----|-------|---------------------------------------------------| + | 4 | 10h | The prediction was needed when checking | + | | | whether the symbol was used. | + |-----|-------|---------------------------------------------------| + | 5 | 20h | Result of last predicted check for being used. | + |-----|-------|---------------------------------------------------| + | 6 | 40h | The prediction was needed when checking | + | | | whether the symbol was defined. | + |-----|-------|---------------------------------------------------| + | 7 | 80h | Result of last predicted check for being defined. | + |-----|-------|---------------------------------------------------| + | 8 | 100h | The optimization adjustment is applied to | + | | | the value of this symbol. | + |-----|-------|---------------------------------------------------| + | 9 | 200h | The value of symbol is negative number encoded | + | | | as two's complement. | + |-----|-------|---------------------------------------------------| + | 10 | 400h | Symbol is a special marker and has no value. | + \-----------------------------------------------------------------/ + + Notes: + + Some of those flags are listed here just for completness, as they + have little use outside of the flat assembler. However the bit 0 + is important, because the symbols table contains all the labels + that occured in source, even if some of them were in the + conditional blocks that did not get assembled. + + + Table 2.2 Symbol value types + /-------------------------------------------------------------------\ + | Value | Description | + |=======|===========================================================| + | 0 | Absolute value. | + |-------|-----------------------------------------------------------| + | 1 | Relocatable segment address (only with MZ output). | + |-------|-----------------------------------------------------------| + | 2 | Relocatable 32-bit address. | + |-------|-----------------------------------------------------------| + | 3 | Relocatable relative 32-bit address (value valid only for | + | | symbol used in the same place where it was calculated, | + | | it should not occur in the symbol structure). | + |-------|-----------------------------------------------------------| + | 4 | Relocatable 64-bit address. | + |-------|-----------------------------------------------------------| + | 5 | [ELF only] GOT-relative 32-bit address. | + |-------|-----------------------------------------------------------| + | 6 | [ELF only] 32-bit address of PLT entry. | + |-------|-----------------------------------------------------------| + | 7 | [ELF only] Relative 32-bit address of PLT entry (value | + | | valid only for symbol used in the same place where it | + | | was calculated, it should not occur in the symbol | + | | structure). | + \-------------------------------------------------------------------/ + + Notes: + + The types 3 and 7 should never be encountered in the symbols dump, + they are only used internally by the flat assembler. + + If type value is a negative number, it is an opposite of a value + from this table and it means that the symbol of a given type has + been negated. + + + Table 2.3 Register codes for extended SIB + /------------------\ + | Value | Register | + |=======|==========| + | 23h | BX | + |-------|----------| + | 25h | BP | + |-------|----------| + | 26h | SI | + |-------|----------| + | 27h | DI | + |-------|----------| + | 40h | EAX | + |-------|----------| + | 41h | ECX | + |-------|----------| + | 42h | EDX | + |-------|----------| + | 43h | EBX | + |-------|----------| + | 44h | ESP | + |-------|----------| + | 45h | EBP | + |-------|----------| + | 46h | ESI | + |-------|----------| + | 47h | EDI | + |-------|----------| + | 48h | R8D | + |-------|----------| + | 49h | R9D | + |-------|----------| + | 4Ah | R10D | + |-------|----------| + | 4Bh | R11D | + |-------|----------| + | 4Ch | R12D | + |-------|----------| + | 4Dh | R13D | + |-------|----------| + | 4Eh | R14D | + |-------|----------| + | 4Fh | R15D | + |-------|----------| + | 80h | RAX | + |-------|----------| + | 81h | RCX | + |-------|----------| + | 82h | RDX | + |-------|----------| + | 83h | RBX | + |-------|----------| + | 84h | RSP | + |-------|----------| + | 85h | RBP | + |-------|----------| + | 86h | RSI | + |-------|----------| + | 87h | RDI | + |-------|----------| + | 88h | R8 | + |-------|----------| + | 89h | R9 | + |-------|----------| + | 8Ah | R10 | + |-------|----------| + | 8Bh | R11 | + |-------|----------| + | 8Ch | R12 | + |-------|----------| + | 8Dh | R13 | + |-------|----------| + | 8Eh | R14 | + |-------|----------| + | 8Fh | R15 | + |-------|----------| + | 94h | EIP | + |-------|----------| + | 98h | RIP | + \------------------/ + + + Table 3 Preprocessed line + /--------------------------------------------------------------------------\ + | Offset | Size | Value | + |========|=================================================================| + | +0 | dword | When the line was loaded from source, this field | + | | | contains either zero (if it is the line from the main | + | | | input file), or an offset inside the preprocessed | + | | | source to the name of file, from which this line was | + | | | loaded (the name of file is zero-ended string). | + | | | When the line was generated by macroinstruction, this | + | | | field contains offset inside the preprocessed source to | + | | | the pascal-style string specifying the name of | + | | | macroinstruction, which generated this line. | + |--------|-------|---------------------------------------------------------| + | +4 | dword | Bits 0-30 contain the number of this line. | + | | | If the highest bit is zeroed, this line was loaded from | + | | | source. | + | | | If the highest bit is set, this line was generated by | + | | | macroinstruction. | + |--------|-------|---------------------------------------------------------| + | +8 | dword | If the line was loaded from source, this field contains | + | | | the position of the line inside the source file, from | + | | | which it was loaded. | + | | | If line was generated by macroinstruction, this field | + | | | contains the offset of preprocessed line, which invoked | + | | | the macroinstruction. | + | | | If line was generated by instantaneous macro, this | + | | | field is equal to the next one. | + |--------|-------|---------------------------------------------------------| + | +12 | dword | If the line was generated by macroinstruction, this | + | | | field contains offset of the preprocessed line inside | + | | | the definition of macro, from which this one was | + | | | generated. | + |--------|-------|---------------------------------------------------------| + | +16 | ? | The tokenized contents of line. | + \--------------------------------------------------------------------------/ + + Notes: + + To determine, whether this is the line loaded from source, or generated by + macroinstruction, you need to check the highest bit of the second double + word. + + The contents of line is no longer a text, which it was in source file, + but a sequence of tokens, ended with a zero byte. + Any chain of characters that aren't special ones, separated from other + similar chains with spaces or some other special characters, is converted + into symbol token. The first byte of this element has the value of 1Ah, + the second byte is the count of characters, followed by this amount of + bytes, which build the symbol. + Some characters have a special meaning, and cannot occur inside the + symbol, they split the symbols and are converted into separate tokens. + For example, if source contains this line of text: + + mov ax,4 + + preprocessor converts it into the chain of bytes, shown here with their + hexadecimal values (characters corresponding to some of those values are + placed below the hexadecimal codes): + + 1A 03 6D 6F 76 1A 02 61 78 2C 1A 01 34 00 + m o v a x , 4 + + The third type of token that can be found in preprocessed line is the + quoted text. This element is created from chain of any bytes other than + line breaks that are placed between the single or double quotes in the + original text. First byte of such element is always 22h, it is followed + by double word which specifies the number of bytes that follow, and the + value of quoted text comes next. For example, this line from source: + + mov eax,'ABCD' + + is converted into (the notation used is the same as in previous sample): + + 1A 03 6D 6F 76 1A 03 65 61 78 2C 22 04 00 00 00 41 42 43 44 00 + m o v e a x , A B C D + + This data defines two symbols followed by symbol character, quoted text + and zero byte that marks end of line. + There is also a special case of symbol token with first byte having the + value 3Bh instead of 1Ah, such symbol means that all the line elements + that follow, including this one, have already been interpreted by + preprocessor and are ignored by assembler. + + + Table 4 Row of the assembly dump + /-------------------------------------------------------------------------\ + | Offset | Size | Description | + |========|=======|========================================================| + | +0 | dword | Offset in output file. | + |--------|-------|--------------------------------------------------------| + | +4 | dword | Offset of line in preprocessed source. | + |--------|-------|--------------------------------------------------------| + | +8 | qword | Value of $ address. | + |--------|-------|--------------------------------------------------------| + | +16 | dword | Extended SIB for the $ address, the first two bytes | + | | | are register codes and the second two bytes are | + | | | corresponding scales. | + |--------|-------|--------------------------------------------------------| + | +20 | dword | If the $ address is relocatable, this field contains | + | | | information about section or external symbol, to which | + | | | it is relative - otherwise this field is zero. | + | | | When the highest bit is cleared, the address is | + | | | relative to a section, and the bits 0-30 contain | + | | | the index (starting from 1) in the table of sections. | + | | | When the highest bit is set, the address is relative | + | | | to an external symbol, and the bits 0-30 contain the | + | | | the offset of the name of this symbol in the strings | + | | | table. | + |--------|-------|--------------------------------------------------------| + | +24 | byte | Type of $ address value (as in table 2.2). | + |--------|-------|--------------------------------------------------------| + | +25 | byte | Type of code - possible values are 16, 32, and 64. | + |--------|-------|--------------------------------------------------------| + | +26 | byte | If the bit 0 is set, then at this point the assembly | + | | | was taking place inside the virtual block, and the | + | | | offset in output file has no meaning here. | + | | | If the bit 1 is set, the line was assembled at the | + | | | point, which was not included in the output file for | + | | | some other reasons (like inside the reserved data at | + | | | the end of section). | + |--------|-------|--------------------------------------------------------| + | +27 | byte | The higher bits of value of $ address. | + \-------------------------------------------------------------------------/ + + + Notes: + + Each row of the assembly dump informs, that the given line of preprocessed + source was assembled at the specified address (defined by its type, value + and the extended SIB) and at the specified position in output file. diff --git a/toolchain/fasmw17332/TOOLS/LIBC/CCALL.INC b/toolchain/fasmw17332/TOOLS/LIBC/CCALL.INC new file mode 100644 index 0000000..cf9f826 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/LIBC/CCALL.INC @@ -0,0 +1,23 @@ + +macro ccall proc,[arg] + { common + push ebp + mov ebp,esp + local size + size = 0 + if ~ arg eq + forward + size = size + 4 + common + sub esp,size + end if + and esp,-16 + if ~ arg eq + add esp,size + reverse + pushd arg + common + end if + call proc + leave } + diff --git a/toolchain/fasmw17332/TOOLS/LIBC/LISTING.ASM b/toolchain/fasmw17332/TOOLS/LIBC/LISTING.ASM new file mode 100644 index 0000000..2075153 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/LIBC/LISTING.ASM @@ -0,0 +1,177 @@ + + format ELF + public main + +include 'ccall.inc' + +section '.text' executable align 16 + + main: + mov ecx,[esp+4] + mov [argc],ecx + mov ebx,[esp+8] + mov [argv],ebx + + mov [display_handle],1 + + call get_params + jnc make_listing + + mov esi,_usage + call display_string + ccall exit,2 + + make_listing: + call listing + ccall exit,0 + + error: + mov [display_handle],2 + mov esi,_error_prefix + call display_string + pop esi + call display_string + mov esi,_error_suffix + call display_string + ccall exit,0 + + get_params: + mov ecx,[argc] + mov ebx,[argv] + add ebx,4 + dec ecx + jz bad_params + get_param: + mov esi,[ebx] + mov al,[esi] + cmp al,'-' + je option_param + cmp [input_file],0 + jne get_output_file + mov [input_file],esi + jmp next_param + get_output_file: + cmp [output_file],0 + jne bad_params + mov [output_file],esi + jmp next_param + option_param: + inc esi + lodsb + cmp al,'a' + je addresses_option + cmp al,'A' + je addresses_option + cmp al,'b' + je bytes_per_line_option + cmp al,'B' + je bytes_per_line_option + bad_params: + stc + ret + addresses_option: + cmp byte [esi],0 + jne bad_params + mov [show_addresses],1 + jmp next_param + bytes_per_line_option: + cmp byte [esi],0 + jne get_bytes_per_line_setting + dec ecx + jz bad_params + add ebx,4 + mov esi,[ebx] + get_bytes_per_line_setting: + call get_option_value + or edx,edx + jz bad_params + cmp edx,1000 + ja bad_params + mov [code_bytes_per_line],edx + next_param: + add ebx,4 + dec ecx + jnz get_param + cmp [input_file],0 + je bad_params + cmp [output_file],0 + je bad_params + clc + ret + get_option_value: + xor eax,eax + mov edx,eax + get_option_digit: + lodsb + cmp al,20h + je option_value_ok + cmp al,0Dh + je option_value_ok + or al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + invalid_option_value: + stc + ret + + include 'system.inc' + + include '..\listing.inc' + +section '.data' writeable align 4 + + input_file dd 0 + output_file dd 0 + code_bytes_per_line dd 16 + show_addresses db 0 + + line_break db 0Dh,0Ah + + _usage db 'listing generator for flat assembler',0Dh,0Ah + db 'usage: listing ',0Dh,0Ah + db 'optional settings:',0Dh,0Ah + db ' -a show target addresses for assembled code',0Dh,0Ah + db ' -b set the amount of bytes listed per line',0Dh,0Ah + db 0 + _error_prefix db 'error: ',0 + _error_suffix db '.',0Dh,0Ah,0 + +section '.bss' writeable align 4 + + argc dd ? + argv dd ? + + input dd ? + assembled_code dd ? + assembled_code_length dd ? + code_end dd ? + code_offset dd ? + code_length dd ? + output_handle dd ? + output_buffer dd ? + current_source_file dd ? + current_source_line dd ? + source dd ? + source_length dd ? + maximum_address_length dd ? + address_start dd ? + last_listed_address dd ? + + display_handle dd ? + character db ? + + params rb 1000h + characters rb 100h + buffer rb 1000h diff --git a/toolchain/fasmw17332/TOOLS/LIBC/PREPSRC.ASM b/toolchain/fasmw17332/TOOLS/LIBC/PREPSRC.ASM new file mode 100644 index 0000000..2ccaca5 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/LIBC/PREPSRC.ASM @@ -0,0 +1,94 @@ + + format ELF + public main + +include 'ccall.inc' + +section '.text' executable align 16 + + main: + mov ecx,[esp+4] + mov [argc],ecx + mov ebx,[esp+8] + mov [argv],ebx + + mov [display_handle],1 + + call get_params + jnc make_dump + + mov esi,_usage + call display_string + ccall exit,2 + + make_dump: + call preprocessed_source + ccall exit,0 + + error: + mov [display_handle],2 + mov esi,_error_prefix + call display_string + pop esi + call display_string + mov esi,_error_suffix + call display_string + ccall exit,0 + + get_params: + mov ecx,[argc] + mov ebx,[argv] + add ebx,4 + dec ecx + jz bad_params + get_param: + mov esi,[ebx] + mov al,[esi] + cmp [input_file],0 + jne get_output_file + mov [input_file],esi + jmp next_param + get_output_file: + cmp [output_file],0 + jne bad_params + mov [output_file],esi + jmp next_param + bad_params: + stc + ret + next_param: + add ebx,4 + dec ecx + jnz get_param + cmp [input_file],0 + je bad_params + cmp [output_file],0 + je bad_params + clc + ret + + include 'system.inc' + + include '..\prepsrc.inc' + +section '.data' writeable align 4 + + input_file dd 0 + output_file dd 0 + + _usage db 'preprocessed source dumper for flat assembler',0Dh,0Ah + db 'usage: prepsrc ',0Dh,0Ah + db 0 + _error_prefix db 'error: ',0 + _error_suffix db '.',0Dh,0Ah,0 + +section '.bss' writeable align 4 + + argc dd ? + argv dd ? + + display_handle dd ? + character db ? + + params rb 1000h + buffer rb 1000h diff --git a/toolchain/fasmw17332/TOOLS/LIBC/SYMBOLS.ASM b/toolchain/fasmw17332/TOOLS/LIBC/SYMBOLS.ASM new file mode 100644 index 0000000..1d33265 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/LIBC/SYMBOLS.ASM @@ -0,0 +1,98 @@ + + format ELF + public main + +include 'ccall.inc' + +section '.text' executable align 16 + + main: + mov ecx,[esp+4] + mov [argc],ecx + mov ebx,[esp+8] + mov [argv],ebx + + mov [display_handle],1 + + call get_params + jnc make_dump + + mov esi,_usage + call display_string + ccall exit,2 + + make_dump: + call symbols + ccall exit,0 + + error: + mov [display_handle],2 + mov esi,_error_prefix + call display_string + pop esi + call display_string + mov esi,_error_suffix + call display_string + ccall exit,0 + + get_params: + mov ecx,[argc] + mov ebx,[argv] + add ebx,4 + dec ecx + jz bad_params + get_param: + mov esi,[ebx] + mov al,[esi] + cmp [input_file],0 + jne get_output_file + mov [input_file],esi + jmp next_param + get_output_file: + cmp [output_file],0 + jne bad_params + mov [output_file],esi + jmp next_param + bad_params: + stc + ret + next_param: + add ebx,4 + dec ecx + jnz get_param + cmp [input_file],0 + je bad_params + cmp [output_file],0 + je bad_params + clc + ret + + include 'system.inc' + + include '..\symbols.inc' + +section '.data' writeable align 4 + + input_file dd 0 + output_file dd 0 + + _usage db 'symbols dumper for flat assembler',0Dh,0Ah + db 'usage: symbols ',0Dh,0Ah + db 0 + _error_prefix db 'error: ',0 + _error_suffix db '.',0Dh,0Ah,0 + +section '.bss' writeable align 4 + + input dd ? + output_buffer dd ? + output_handle dd ? + + argc dd ? + argv dd ? + + display_handle dd ? + character db ? + + params rb 1000h + buffer rb 1000h diff --git a/toolchain/fasmw17332/TOOLS/LIBC/SYSTEM.INC b/toolchain/fasmw17332/TOOLS/LIBC/SYSTEM.INC new file mode 100644 index 0000000..8252fbd --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/LIBC/SYSTEM.INC @@ -0,0 +1,107 @@ + +extrn malloc +extrn getenv +extrn fopen +extrn fclose +extrn fread +extrn fwrite +extrn fseek +extrn ftell +extrn time +extrn exit +extrn 'free' as libc_free +extrn 'write' as libc_write + +alloc: + ccall malloc,eax + test eax,eax + jz allocation_failed + clc + ret + allocation_failed: + stc + ret +free: + ccall libc_free,eax + ret +display_string: + lodsb + or al,al + jz string_displayed + mov dl,al + call display_character + jmp display_string + string_displayed: + ret + display_character: + mov [character],dl + ccall libc_write,[display_handle],character,1 + ret +open: + push esi edi ebp + call adapt_path + ccall fopen,buffer,open_mode + pop ebp edi esi + or eax,eax + jz file_error + mov ebx,eax + clc + ret + adapt_path: + mov esi,edx + mov edi,buffer + copy_path: + lods byte [esi] + cmp al,'\' + jne path_char_ok + mov al,'/' + path_char_ok: + stos byte [edi] + or al,al + jnz copy_path + cmp edi,buffer+1000h + ja not_enough_memory + ret +create: + push esi edi ebp + call adapt_path + ccall fopen,buffer,create_mode + pop ebp edi esi + or eax,eax + jz file_error + mov ebx,eax + clc + ret +close: + ccall fclose,ebx + ret +read: + push ebx ecx edx esi edi + ccall fread,edx,1,ecx,ebx + pop edi esi edx ecx ebx + cmp eax,ecx + jne file_error + clc + ret + file_error: + stc + ret +write: + push ebx ecx edx esi edi + ccall fwrite,edx,1,ecx,ebx + pop edi esi edx ecx ebx + cmp eax,ecx + jne file_error + clc + ret +lseek: + push ebx + movzx eax,al + ccall fseek,ebx,edx,eax + mov ebx,[esp] + ccall ftell,ebx + pop ebx + ret + +open_mode db 'r',0 +create_mode db 'w',0 diff --git a/toolchain/fasmw17332/TOOLS/LISTING.INC b/toolchain/fasmw17332/TOOLS/LISTING.INC new file mode 100644 index 0000000..d301639 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/LISTING.INC @@ -0,0 +1,690 @@ + +listing: + mov edx,[input_file] + call open + jc input_not_found + call load_file + mov [input],eax + cmp ecx,38h + jb invalid_input + cmp dword [eax],1A736166h + jne invalid_input + cmp dword [eax+44],0 + je incomplete_input + add [eax+16],eax + add [eax+24],eax + add [eax+32],eax + add [eax+40],eax + add [eax+48],eax + mov edx,[eax+16] + add [eax+8],edx + add [eax+12],edx + mov edx,[eax+12] + call open + jc code_not_found + call load_file + mov [assembled_code],eax + mov [assembled_code_length],ecx + call close + mov [maximum_address_length],0 + mov ebx,[input] + mov esi,[ebx+40] + lea ebp,[esi-4] + add ebp,[ebx+44] + get_offsets_for_lines: + cmp esi,ebp + je offsets_prepared + mov edx,[esi+4] + add edx,[ebx+32] + find_line_loaded_from_source: + test byte [edx+7],1 shl 7 + jz store_offset_in_line + mov edx,[edx+8] + add edx,[ebx+32] + jmp find_line_loaded_from_source + store_offset_in_line: + cmp dword [edx+12],0 + jne get_next_offset + mov [edx+12],esi + movzx ecx,byte [esi+27] + and cl,1 + mov edi,[esi+20] + test edi,edi + jz base_name_length_ok + xor ecx,ecx + btr edi,31 + jc count_base_name_characters + dec edi + shl edi,2 + add edi,[ebx+48] + mov edi,[edi] + count_base_name_characters: + mov ecx,[ebx+20] + sub ecx,edi + add edi,[ebx+16] + mov edx,edi + xor al,al + repne scasb + mov ecx,edi + sub ecx,edx + base_name_length_ok: + cmp byte [esi+18],1 + jb first_register_length_ok + ja first_register_with_scale + add ecx,5 + jmp first_register_length_ok + first_register_with_scale: + add ecx,5+3 + first_register_length_ok: + cmp byte [esi+19],1 + jb second_register_length_ok + ja second_register_with_scale + add ecx,5 + jmp second_register_length_ok + second_register_with_scale: + add ecx,5+3 + second_register_length_ok: + cmp ecx,[maximum_address_length] + jb get_next_offset + mov [maximum_address_length],ecx + get_next_offset: + add esi,28 + jmp get_offsets_for_lines + offsets_prepared: + mov eax,[esi] + mov [code_end],eax + add [maximum_address_length],19 + mov edi,characters + xor al,al + make_characters_table: + stosb + inc al + jnz make_characters_table + mov edi,characters + mov esi,symbol_characters+1 + movzx ecx,byte [esi-1] + xor eax,eax + mark_symbol_characters: + lodsb + mov byte [edi+eax],0 + loop mark_symbol_characters + mov eax,[code_bytes_per_line] + imul eax,3 + add eax,[maximum_address_length] + add eax,18 + call alloc + jc not_enough_memory + mov [output_buffer],eax + mov esi,[ebx+32] + mov ebp,esi + add ebp,[ebx+36] + mov edx,[output_file] + call create + jc writing_error + mov [output_handle],ebx + xor eax,eax + mov [current_source_file],eax + mov [last_listed_address],eax + mov [code_length],eax + generate_listing: + cmp esi,ebp + jae listing_done + mov edi,[output_buffer] + test byte [esi+7],1 shl 7 + jnz next_line + mov ebx,[esi+12] + test ebx,ebx + jz no_code_listing + test byte [ebx+26],11b + jnz no_code_listing + push esi + mov edx,[esi] + mov ecx,[esi+4] + find_next_code_point: + add esi,16 + call skip_preprocessed_line + cmp esi,ebp + je last_code_point + cmp edx,[esi] + jne next_line_ok + cmp ecx,[esi+4] + je find_next_code_point + next_line_ok: + test byte [esi+7],1 shl 7 + jnz find_next_code_point + mov eax,[esi+12] + test eax,eax + jz find_next_code_point + test byte [eax+26],11b + jnz find_next_code_point + mov eax,[eax] + jmp calculate_code_length + last_code_point: + mov eax,[code_end] + calculate_code_length: + pop esi + mov edx,[ebx] + sub eax,edx + jz no_code_listing + mov [code_length],eax + mov [code_offset],edx + add eax,edx + cmp eax,[assembled_code_length] + jbe write_file_offset + mov [code_length],0 + write_file_offset: + call write_hex_dword + mov ax,': ' + stosw + call list_address + call list_code + jmp code_listing_ok + no_code_listing: + mov al,20h + mov ecx,8+2 + rep stosb + call list_address + mov ecx,[code_bytes_per_line] + imul ecx,3 + mov al,20h + rep stosb + code_listing_ok: + call write_listing_data + mov eax,[input] + mov edx,[esi] + test edx,edx + jz main_source_file + add edx,[eax+32] + jmp source_name_ok + main_source_file: + mov edx,[eax+8] + source_name_ok: + cmp edx,[current_source_file] + je source_loaded + push ebx + push edx + call open + jc source_not_found + pop eax + xchg eax,[current_source_file] + test eax,eax + jz load_source + mov eax,[source] + call free + load_source: + call load_file + mov [source],eax + mov [source_length],ecx + call close + pop ebx + source_loaded: + mov eax,[source] + add eax,[esi+8] + mov [current_source_line],eax + push esi ebp + call write_source_line + pop ebp esi + write_supplemental_rows: + mov eax,[code_length] + or eax,[current_source_line] + jz next_line + mov edi,[output_buffer] + mov ecx,8+2 + movzx eax,[show_addresses] + imul eax,[maximum_address_length] + add ecx,eax + mov al,20h + rep stosb + call list_code + call write_listing_data + push esi ebp + call write_source_line + pop ebp esi + jmp write_supplemental_rows + next_line: + mov edx,[esi] + mov ecx,[esi+4] + find_next_line: + add esi,16 + call skip_preprocessed_line + cmp edx,[esi] + jne generate_listing + cmp ecx,[esi+4] + jne generate_listing + jmp find_next_line + list_address: + cmp [show_addresses],0 + je address_ok + mov [address_start],edi + mov eax,[esi+12] + test eax,eax + jz address_finished + cmp [last_listed_address],0 + je make_address + push esi edi + lea esi,[eax+8] + mov edi,[last_listed_address] + mov ecx,17 + repe cmpsb + pop edi esi + je address_finished + make_address: + mov ebx,[esi+12] + lea eax,[ebx+8] + mov [last_listed_address],eax + mov al,'[' + stosb + mov edx,[ebx+20] + test edx,edx + jz write_main_address + push esi + mov esi,edx + mov eax,[input] + btr esi,31 + jc base_name_ready + dec esi + shl esi,2 + add esi,[eax+48] + mov esi,[esi] + base_name_ready: + add esi,[eax+16] + copy_section_name: + lodsb + test al,al + jz section_name_ok + stosb + jmp copy_section_name + section_name_ok: + pop esi + mov al,':' + test edx,80000000h + jz address_separator_ok + cmp byte [ebx+27],0 + jne address_separator_ok + mov al,'+' + address_separator_ok: + stosb + write_main_address: + cmp byte [ebx+27],0 + jne write_negative_address + mov edx,[ebx+8+4] + call write_hex_dword + mov edx,[ebx+8] + call write_hex_dword + jmp write_address_registers + write_negative_address: + mov al,'-' + stosb + mov eax,[ebx+8] + mov edx,[ebx+8+4] + not eax + not edx + add eax,1 + adc edx,0 + push eax + call write_hex_dword + pop edx + call write_hex_dword + write_address_registers: + mov dl,[ebx+16] + mov dh,[ebx+18] + call address_register + mov dl,[ebx+17] + mov dh,[ebx+19] + call address_register + mov ax,']' + stosb + address_finished: + mov ecx,[maximum_address_length] + sub ecx,edi + add ecx,[address_start] + mov al,20h + rep stosb + address_ok: + ret + address_register: + cmp dh,0 + je register_ok + jl negative_register + mov al,'+' + jmp register_sign_ok + negative_register: + mov al,'-' + register_sign_ok: + stosb + push esi + mov esi,address_registers + find_register: + lodsb + test al,al + jz register_found + cmp al,dl + je register_found + cmp dl,[esi] + je register_found + lodsb + movzx eax,al + add esi,eax + jmp find_register + register_found: + lodsb + movzx ecx,al + rep movsb + pop esi + cmp dh,1 + je register_ok + mov al,'*' + stosb + test dh,0F0h + jz first_scale_digit_ok + mov al,dh + shr al,4 + cmp al,10 + sbb al,69h + das + stosb + first_scale_digit_ok: + mov al,dh + and al,1111b + cmp al,10 + sbb al,69h + das + stosb + register_ok: + ret + list_code: + mov ecx,[code_length] + cmp ecx,[code_bytes_per_line] + jb code_bytes_count_ready + mov ecx,[code_bytes_per_line] + code_bytes_count_ready: + sub [code_length],ecx + mov edx,[code_offset] + add [code_offset],ecx + jecxz code_bytes_ok + push ecx + add edx,[assembled_code] + list_code_bytes: + mov al,[edx] + and al,1111b + cmp al,10 + sbb al,69h + das + mov ah,al + mov al,[edx] + shr al,4 + cmp al,10 + sbb al,69h + das + stosw + mov al,20h + stosb + inc edx + loop list_code_bytes + pop ecx + code_bytes_ok: + neg ecx + add ecx,[code_bytes_per_line] + imul ecx,3 + mov al,20h + rep stosb + ret + write_listing_data: + mov ecx,[output_buffer] + sub ecx,edi + and ecx,111b + mov al,20h + rep stosb + mov edx,[output_buffer] + mov ecx,edi + sub ecx,edx + mov ebx,[output_handle] + call write + jc writing_error + ret + write_source_line: + mov esi,[current_source_line] + test esi,esi + je write_line_break + mov ebp,[source_length] + add ebp,[source] + mov ebx,characters + xor cl,cl + start_cutting: + xor dl,dl + cut_source_line: + cmp esi,ebp + je end_of_file + lodsb + cmp al,0Dh + je cr_character + cmp al,0Ah + je lf_character + cmp al,1Ah + je end_of_line + or al,al + jz end_of_line + cmp dl,3Bh + je cut_source_line + cmp al,3Bh + je start_special_block + cmp dl,22h + je inside_string + cmp dl,27h + je inside_string + cmp al,'\' + je check_for_line_continuation + xlatb + test al,al + jz start_cutting + cmp dl,0FFh + je cut_source_line + cmp al,22h + je start_special_block + cmp al,27h + je start_special_block + mov dl,0FFh + jmp cut_source_line + start_special_block: + mov dl,al + jmp cut_source_line + inside_string: + cmp al,dl + jne cut_source_line + jmp start_cutting + check_for_line_continuation: + or cl,0FFh + cmp esi,ebp + je end_of_file + mov al,[esi] + cmp al,20h + je start_cutting + cmp al,0Dh + je start_cutting + cmp al,0Ah + je start_cutting + cmp al,3Bh + je start_cutting + xor cl,cl + jmp start_cutting + cr_character: + mov edx,esi + mov word [line_break],0Dh + cmp esi,ebp + je line_with_break + mov al,[esi] + cmp al,0Ah + jne line_with_break + inc edx + mov [line_break+1],al + jmp line_with_break + lf_character: + mov edx,esi + mov word [line_break],0Ah + cmp esi,ebp + je line_with_break + mov al,[esi] + cmp al,0Dh + jne line_with_break + inc edx + mov [line_break+1],al + line_with_break: + dec esi + jmp write_line + end_of_line: + dec esi + end_of_file: + mov edx,esi + write_line: + cmp cl,0FFh + je continued_line + xor edx,edx + continued_line: + xchg edx,[current_source_line] + mov ecx,esi + sub ecx,edx + mov ebx,[output_handle] + call write + jc writing_error + write_line_break: + mov edx,line_break + mov ecx,2 + cmp [line_break+1],0 + jne line_break_size_ok + dec ecx + line_break_size_ok: + call write + jc writing_error + ret + listing_done: + mov ebx,[output_handle] + call close + ret + +load_file: + push ebx + mov al,2 + xor edx,edx + call lseek + test eax,eax + jz empty_file + push eax + call alloc + jc not_enough_memory + push eax + xor al,al + xor edx,edx + call lseek + mov ecx,[esp+4] + mov edx,[esp] + call read + jc reading_error + pop eax ecx + pop ebx + ret + empty_file: + pop ebx + mov ecx,eax + ret + +write_hex_dword: + mov ecx,8 + write_hex_digits: + xor al,al + shld eax,edx,4 + cmp al,10 + sbb al,69h + das + stosb + shl edx,4 + loop write_hex_digits + ret + +skip_preprocessed_line: + lods byte [esi] + cmp al,1Ah + je skip_preprocessed_symbol + cmp al,3Bh + je skip_preprocessed_symbol + cmp al,22h + je skip_preprocessed_string + or al,al + jnz skip_preprocessed_line + ret + skip_preprocessed_symbol: + lods byte [esi] + movzx eax,al + add esi,eax + jmp skip_preprocessed_line + skip_preprocessed_string: + lods dword [esi] + add esi,eax + jmp skip_preprocessed_line + + +not_enough_memory: + call error + db 'not enough memory to load the required data',0 +input_not_found: + call error + db 'the input file was not found',0 +code_not_found: + call error + db 'the assembled file was not found',0 +source_not_found: + call error + db 'could not find some of the source files',0 +reading_error: + call error + db 'some error occured while trying to read file',0 +writing_error: + call error + db 'some error occured while trying to write file',0 +invalid_input: + call error + db 'input file is not a recognized assembly information format',0 +incomplete_input: + call error + db 'input file does not contain an assembly dump',0 + +symbol_characters db 27, 9,0Ah,0Dh,1Ah,20h,'+-/*=<>()[]{}:,|&~#`;\' + +address_registers db 23h,2,'bx' + db 25h,2,'bp' + db 26h,2,'si' + db 27h,2,'di' + db 40h,3,'eax' + db 41h,3,'ecx' + db 42h,3,'edx' + db 43h,3,'ebx' + db 44h,3,'esp' + db 45h,3,'ebp' + db 46h,3,'esi' + db 47h,3,'edi' + db 48h,3,'r8d' + db 49h,3,'r9d' + db 4Ah,4,'r10d' + db 4Bh,4,'r11d' + db 4Ch,4,'r12d' + db 4Dh,4,'r13d' + db 4Eh,4,'r14d' + db 4Fh,4,'r15d' + db 80h,3,'rax' + db 81h,3,'rcx' + db 82h,3,'rdx' + db 83h,3,'rbx' + db 84h,3,'rsp' + db 85h,3,'rbp' + db 86h,3,'rsi' + db 87h,3,'rdi' + db 88h,2,'r8' + db 89h,2,'r9' + db 8Ah,3,'r10' + db 8Bh,3,'r11' + db 8Ch,3,'r12' + db 8Dh,3,'r13' + db 8Eh,3,'r14' + db 8Fh,3,'r15' + db 0F4h,3,'eip' + db 0F8h,3,'rip' + db 0,1,'?' diff --git a/toolchain/fasmw17332/TOOLS/PREPSRC.INC b/toolchain/fasmw17332/TOOLS/PREPSRC.INC new file mode 100644 index 0000000..fb9e1c7 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/PREPSRC.INC @@ -0,0 +1,115 @@ + +preprocessed_source: + mov edx,[input_file] + call open + jc input_not_found + mov al,2 + xor edx,edx + call lseek + cmp eax,30h + jb invalid_input + push eax + call alloc + jc not_enough_memory + push eax + xor al,al + xor edx,edx + call lseek + mov ecx,[esp+4] + mov edx,[esp] + call read + jc reading_error + pop eax ecx + cmp dword [eax],1A736166h + jne invalid_input + mov esi,[eax+32] + add esi,eax + mov ebp,[eax+36] + add ebp,esi + mov edi,eax + push eax + preprocessed_to_text: + cmp esi,ebp + jae conversion_done + add esi,16 + xor dl,dl + convert_preprocessed_line: + lodsb + cmp al,1Ah + je copy_symbol + cmp al,22h + je copy_symbol + cmp al,3Bh + je preprocessor_symbols + or al,al + jz line_converted + stosb + xor dl,dl + jmp convert_preprocessed_line + copy_symbol: + or dl,dl + jz space_ok + mov byte [edi],20h + inc edi + space_ok: + cmp al,22h + je quoted + lodsb + movzx ecx,al + rep movsb + or dl,-1 + jmp convert_preprocessed_line + quoted: + mov al,27h + stosb + lodsd + mov ecx,eax + jecxz quoted_copied + copy_quoted: + lodsb + stosb + cmp al,27h + jne quote_ok + stosb + quote_ok: + loop copy_quoted + quoted_copied: + mov al,27h + stosb + or dl,-1 + jmp convert_preprocessed_line + preprocessor_symbols: + mov al,3Bh + stosb + jmp copy_symbol + line_converted: + mov ax,0A0Dh + stosw + jmp preprocessed_to_text + conversion_done: + mov edx,[output_file] + call create + jc writing_error + pop edx + mov ecx,edi + sub ecx,edx + call write + jc writing_error + call close + ret + +not_enough_memory: + call error + db 'not enough memory to load the required data',0 +input_not_found: + call error + db 'the input file was not found',0 +reading_error: + call error + db 'some error occured while trying to read file',0 +writing_error: + call error + db 'some error occured while trying to write file',0 +invalid_input: + call error + db 'input file is not a recognized assembly information format',0 diff --git a/toolchain/fasmw17332/TOOLS/README.TXT b/toolchain/fasmw17332/TOOLS/README.TXT new file mode 100644 index 0000000..5932121 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/README.TXT @@ -0,0 +1,26 @@ + +This directory contains some tools, which extract various types of information +from the symbolic information file generated by flat assembler, and present +them in a human-readable form. + +The listing tool creates a listing of assembled code - this tool needs to be +executed in the exact configuration, in which the assembly was taking place. +All the source files and the output file aswell must not have been moved or +modified - if any of them was altered before generating the listing, it is +going to contain garbage instead of useful information. For example, if you +assembled the file with the command like: + + fasm example.asm example.exe -s example.fas + +you should generate listing by immediately running this command from the same +directory: + + listing example.fas example.lst + +In addition, the "-a" switch is recommended to use in the case of executable +formats, as it allows to get the run-time addresses for all the assembled code +and data. + +The preprocessed source and symbols dump tools are simpler ones - they only +need the symbolic information file as input and generate proper output text +regardless of the availability of other files. diff --git a/toolchain/fasmw17332/TOOLS/SYMBOLS.INC b/toolchain/fasmw17332/TOOLS/SYMBOLS.INC new file mode 100644 index 0000000..fc53917 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/SYMBOLS.INC @@ -0,0 +1,444 @@ + +symbols: + mov edx,[input_file] + call open + jc input_not_found + mov al,2 + xor edx,edx + call lseek + cmp eax,30h + jb invalid_input + push eax + call alloc + jc not_enough_memory + push eax + xor al,al + xor edx,edx + call lseek + mov ecx,[esp+4] + mov edx,[esp] + call read + jc reading_error + pop eax ecx + cmp dword [eax],1A736166h + jne invalid_input + mov [input],eax + add [eax+16],eax + add [eax+24],eax + add [eax+32],eax + add [eax+48],eax + mov edx,[eax+16] + add [eax+8],edx + + mov ebx,eax + mov eax,[ebx+20] + add eax,[ebx+36] + cmp eax,1000h + ja allocate_output_buffer + mov eax,1000h + allocate_output_buffer: + call alloc + jc not_enough_memory + mov [output_buffer],eax + + mov edx,[output_file] + call create + jc writing_error + mov [output_handle],ebx + + mov ebx,[input] + mov edx,[ebx+24] + mov ebp,[ebx+28] + add ebp,edx + dump_symbols: + cmp edx,ebp + je dump_done + test byte [edx+8],1 + jz next_symbol + test byte [edx+9],4 + jnz next_symbol + mov edi,[output_buffer] + mov esi,[edx+24] + test esi,esi + jz anonymous_symbol + mov ebx,[input] + btr esi,31 + jc symbol_name_in_strings_table + add esi,[ebx+32] + lodsb + movzx ecx,al + rep movsb + jmp symbol_name_ok + symbol_name_in_strings_table: + add esi,[ebx+16] + call write_string + jmp symbol_name_ok + anonymous_symbol: + mov al,'@' + stosb + stosb + symbol_name_ok: + test byte [edx+9],2 + jnz negative_value + mov eax,': 0x' + stosd + mov eax,[edx+4] + call write_hex_dword + mov eax,[edx] + call write_hex_dword + jmp write_address_registers + negative_value: + mov eax,': -0' + stosd + mov al,'x' + stosb + mov ecx,[edx] + mov eax,[edx+4] + not ecx + not eax + add ecx,1 + adc eax,0 + push ecx + or ecx,eax + jnz negative_value_ok + mov byte [edi],'1' + inc edi + negative_value_ok: + call write_hex_dword + pop eax + call write_hex_dword + write_address_registers: + mov bl,[edx+12] + mov bh,[edx+14] + call write_address_register + mov bl,[edx+13] + mov bh,[edx+15] + call write_address_register + mov bl,[edx+11] + cmp bl,0 + je symbol_type_ok + jl negated_symbol + mov ax,', ' + stosw + jmp write_symbol_type + negated_symbol: + mov ax,', ' + stosw + mov esi,_negated + call write_string + neg bl + write_symbol_type: + cmp bl,1 + je segment_type + cmp bl,5 + je rva_type + cmp bl,6 + je plt_type + test byte [edx+20+3],80h + jnz external + mov esi,_relocatable + call write_string + cmp dword [edx+20],0 + je symbol_type_ok + mov esi,_in_section + call write_string + jmp write_symbol_base + simple_relocatable: + mov esi,_relocatable + call write_string + jmp symbol_type_ok + external: + mov esi,_relative_to_external + call write_string + jmp write_symbol_base + segment_type: + mov esi,_relocatable_segment + call write_string + jmp symbol_type_ok + rva_type: + mov esi,_rva + call write_string + jmp write_symbol_base + plt_type: + mov esi,_plt + call write_string + write_symbol_base: + mov esi,[edx+20] + btr esi,31 + jc write_external_name + dec esi + shl esi,2 + mov ebx,[input] + add esi,[ebx+48] + mov esi,[esi] + add esi,[ebx+16] + call write_string + mov al,'(' + stosb + mov eax,[edx+20] + call write_dec_number + mov al,')' + stosb + jmp symbol_type_ok + write_external_name: + mov ebx,[input] + add esi,[ebx+16] + call write_string + jmp symbol_type_ok + symbol_type_ok: + mov esi,_defined + call write_string + mov ebx,[edx+28] + mov eax,[input] + add ebx,[eax+32] + call write_line_identifier + mov ax,0A0Dh + stosw + push edx + mov ebx,[output_handle] + mov ecx,edi + mov edx,[output_buffer] + sub ecx,edx + call write + pop edx + next_symbol: + add edx,32 + jmp dump_symbols + dump_done: + mov ebx,[output_handle] + call close + ret + +write_string: + lodsb + test al,al + jz string_ok + stosb + jmp write_string + string_ok: + ret +write_hex_dword: + mov ebx,eax + mov ecx,8 + write_hex_digits: + xor al,al + shld eax,ebx,4 + cmp al,10 + sbb al,69h + das + stosb + shl ebx,4 + loop write_hex_digits + ret +write_dec_number: + push ebx edx + mov ecx,1000000000 + xor edx,edx + xor bl,bl + dec_number_loop: + div ecx + push edx + cmp ecx,1 + je write_dec_digit + or bl,bl + jnz write_dec_digit + or al,al + jz dec_digit_ok + not bl + write_dec_digit: + add al,30h + stosb + dec_digit_ok: + mov eax,ecx + xor edx,edx + mov ecx,10 + div ecx + mov ecx,eax + pop eax + or ecx,ecx + jnz dec_number_loop + pop edx ebx + ret +write_address_register: + cmp bh,0 + je register_ok + jl negative_register + mov al,'+' + jmp register_sign_ok + negative_register: + mov al,'-' + register_sign_ok: + stosb + push esi + mov esi,address_registers + find_register: + lodsb + test al,al + jz register_not_found + cmp al,bl + je register_found + cmp bl,[esi] + je register_found + lodsb + movzx eax,al + add esi,eax + jmp find_register + register_not_found: + mov al,bl + shr al,5 + cmp al,0Ch shr 1 + je xmm_register + cmp al,0Eh shr 1 + je ymm_register + cmp al,6 shr 1 + je zmm_register + register_found: + lodsb + movzx ecx,al + rep movsb + write_register_scale: + pop esi + cmp bh,1 + je register_ok + mov al,'*' + stosb + movzx eax,bh + call write_dec_number + register_ok: + ret + zmm_register: + mov al,'z' + jmp vector_address_register + ymm_register: + mov al,'y' + jmp vector_address_register + xmm_register: + mov al,'x' + vector_address_register: + stosb + mov ax,'mm' + stosw + mov al,bl + and eax,11111b + call write_dec_number + jmp write_register_scale + +write_line_identifier: + test dword [ebx+4],80000000h + jnz identify_macro_generated_line + mov esi,[ebx] + mov eax,[input] + test esi,esi + jz main_file + add esi,[eax+32] + jmp file_name_ok + main_file: + mov esi,[eax+8] + file_name_ok: + call write_string + mov al,'[' + stosb + mov eax,[ebx+4] + call write_dec_number + mov al,']' + stosb + ret + identify_macro_generated_line: + mov al,'{' + stosb + mov esi,_generated_by + call write_string + push ebx + mov ebx,[ebx+8] + mov eax,[input] + add ebx,[eax+32] + call write_line_identifier + pop ebx + mov eax,[ebx+8] + cmp eax,[ebx+12] + je macro_generated_line_identifier_ok + mov esi,_from + call write_string + push ebx + mov ebx,[ebx+12] + mov eax,[input] + add ebx,[eax+32] + call write_line_identifier + pop ebx + macro_generated_line_identifier_ok: + mov al,'}' + stosb + ret + +not_enough_memory: + call error + db 'not enough memory to load the required data',0 +input_not_found: + call error + db 'the input file was not found',0 +code_not_found: + call error + db 'the assembled file was not found',0 +source_not_found: + call error + db 'could not find some of the source files',0 +reading_error: + call error + db 'some error occured while trying to read file',0 +writing_error: + call error + db 'some error occured while trying to write file',0 +invalid_input: + call error + db 'input file is not a recognized assembly information format',0 + +address_registers db 23h,2,'bx' + db 25h,2,'bp' + db 26h,2,'si' + db 27h,2,'di' + db 40h,3,'eax' + db 41h,3,'ecx' + db 42h,3,'edx' + db 43h,3,'ebx' + db 44h,3,'esp' + db 45h,3,'ebp' + db 46h,3,'esi' + db 47h,3,'edi' + db 48h,3,'r8d' + db 49h,3,'r9d' + db 4Ah,4,'r10d' + db 4Bh,4,'r11d' + db 4Ch,4,'r12d' + db 4Dh,4,'r13d' + db 4Eh,4,'r14d' + db 4Fh,4,'r15d' + db 80h,3,'rax' + db 81h,3,'rcx' + db 82h,3,'rdx' + db 83h,3,'rbx' + db 84h,3,'rsp' + db 85h,3,'rbp' + db 86h,3,'rsi' + db 87h,3,'rdi' + db 88h,2,'r8' + db 89h,2,'r9' + db 8Ah,3,'r10' + db 8Bh,3,'r11' + db 8Ch,3,'r12' + db 8Dh,3,'r13' + db 8Eh,3,'r14' + db 8Fh,3,'r15' + db 94h,3,'eip' + db 98h,3,'rip' + db 0,1,'?' + +_negated db 'negated ',0 +_relocatable_segment db 'relocatable segment',0 +_relocatable db 'relocatable',0 +_in_section db ' in section ',0 +_relative_to_external db 'relative to external ',0 +_rva db 'relative to RVA or GOT-based offset of ',0 +_plt db 'relative to address of PLT entry for ',0 +_defined db ', defined in ',0 +_generated_by db 'line generated by ',0 +_from db ' from ',0 diff --git a/toolchain/fasmw17332/TOOLS/WIN32/LISTING.ASM b/toolchain/fasmw17332/TOOLS/WIN32/LISTING.ASM new file mode 100644 index 0000000..7f3ad1a --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/WIN32/LISTING.ASM @@ -0,0 +1,229 @@ + +format PE console 4.0 +entry start + +include 'win32a.inc' + +section '.data' data readable writeable + + _usage db 'listing generator for flat assembler',0Dh,0Ah + db 'usage: listing ',0Dh,0Ah + db 'optional settings:',0Dh,0Ah + db ' -a show target addresses for assembled code',0Dh,0Ah + db ' -b set the amount of bytes listed per line',0Dh,0Ah + db 0 + _error_prefix db 'error: ',0 + _error_suffix db '.',0Dh,0Ah,0 + + line_break db 0Dh,0Ah + + input_file dd 0 + output_file dd 0 + code_bytes_per_line dd 16 + show_addresses db 0 + + input dd ? + assembled_code dd ? + assembled_code_length dd ? + code_end dd ? + code_offset dd ? + code_length dd ? + output_handle dd ? + output_buffer dd ? + current_source_file dd ? + current_source_line dd ? + source dd ? + source_length dd ? + maximum_address_length dd ? + address_start dd ? + last_listed_address dd ? + + display_handle dd ? + bytes_count dd ? + + params rb 1000h + characters rb 100h + +section '.text' code readable executable + + start: + + mov [display_handle],STD_OUTPUT_HANDLE + + call get_params + jnc make_listing + + mov esi,_usage + call display_string + invoke ExitProcess,2 + + make_listing: + call listing + invoke ExitProcess,0 + + error: + mov [display_handle],STD_ERROR_HANDLE + mov esi,_error_prefix + call display_string + pop esi + call display_string + mov esi,_error_suffix + call display_string + invoke ExitProcess,1 + + get_params: + invoke GetCommandLine + mov esi,eax + mov edi,params + find_command_start: + lodsb + cmp al,20h + je find_command_start + cmp al,22h + je skip_quoted_name + skip_name: + lodsb + cmp al,20h + je find_param + or al,al + jz all_params + jmp skip_name + skip_quoted_name: + lodsb + cmp al,22h + je find_param + or al,al + jz all_params + jmp skip_quoted_name + find_param: + lodsb + cmp al,20h + je find_param + cmp al,'-' + je option_param + cmp al,0Dh + je all_params + or al,al + jz all_params + cmp [input_file],0 + jne get_output_file + mov [input_file],edi + jmp process_param + get_output_file: + cmp [output_file],0 + jne bad_params + mov [output_file],edi + process_param: + cmp al,22h + je string_param + copy_param: + stosb + lodsb + cmp al,20h + je param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + jmp copy_param + string_param: + lodsb + cmp al,22h + je string_param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + stosb + jmp string_param + option_param: + lodsb + cmp al,'a' + je addresses_option + cmp al,'A' + je addresses_option + cmp al,'b' + je bytes_per_line_option + cmp al,'B' + je bytes_per_line_option + bad_params: + stc + ret + get_option_value: + xor eax,eax + mov edx,eax + get_option_digit: + lodsb + cmp al,20h + je option_value_ok + cmp al,0Dh + je option_value_ok + or al,al + jz option_value_ok + sub al,30h + jc invalid_option_value + cmp al,9 + ja invalid_option_value + imul edx,10 + jo invalid_option_value + add edx,eax + jc invalid_option_value + jmp get_option_digit + option_value_ok: + dec esi + clc + ret + invalid_option_value: + stc + ret + bytes_per_line_option: + lodsb + cmp al,20h + je bytes_per_line_option + cmp al,0Dh + je bad_params + or al,al + jz bad_params + dec esi + call get_option_value + or edx,edx + jz bad_params + cmp edx,1000 + ja bad_params + mov [code_bytes_per_line],edx + jmp find_param + addresses_option: + lodsb + cmp al,20h + je set_addresses_option + cmp al,0Dh + je set_addresses_option + or al,al + jnz bad_params + set_addresses_option: + dec esi + mov [show_addresses],1 + jmp find_param + param_end: + dec esi + string_param_end: + xor al,al + stosb + jmp find_param + all_params: + cmp [input_file],0 + je bad_params + cmp [output_file],0 + je bad_params + clc + ret + + include 'system.inc' + + include '..\listing.inc' + +section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL' + + include 'api\kernel32.inc' diff --git a/toolchain/fasmw17332/TOOLS/WIN32/PREPSRC.ASM b/toolchain/fasmw17332/TOOLS/WIN32/PREPSRC.ASM new file mode 100644 index 0000000..7ab4c95 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/WIN32/PREPSRC.ASM @@ -0,0 +1,138 @@ + +format PE console 4.0 +entry start + +include 'win32a.inc' + +section '.data' data readable writeable + + _usage db 'preprocessed source dumper for flat assembler',0Dh,0Ah + db 'usage: prepsrc ',0Dh,0Ah + db 0 + _error_prefix db 'error: ',0 + _error_suffix db '.',0Dh,0Ah,0 + + input_file dd 0 + output_file dd 0 + + display_handle dd ? + bytes_count dd ? + + params rb 1000h + +section '.text' code readable executable + + start: + + mov [display_handle],STD_OUTPUT_HANDLE + + call get_params + jnc make_dump + + mov esi,_usage + call display_string + invoke ExitProcess,2 + + make_dump: + call preprocessed_source + invoke ExitProcess,0 + + error: + mov [display_handle],STD_ERROR_HANDLE + mov esi,_error_prefix + call display_string + pop esi + call display_string + mov esi,_error_suffix + call display_string + invoke ExitProcess,1 + + get_params: + invoke GetCommandLine + mov esi,eax + mov edi,params + find_command_start: + lodsb + cmp al,20h + je find_command_start + cmp al,22h + je skip_quoted_name + skip_name: + lodsb + cmp al,20h + je find_param + or al,al + jz all_params + jmp skip_name + skip_quoted_name: + lodsb + cmp al,22h + je find_param + or al,al + jz all_params + jmp skip_quoted_name + find_param: + lodsb + cmp al,20h + je find_param + cmp al,0Dh + je all_params + or al,al + jz all_params + cmp [input_file],0 + jne get_output_file + mov [input_file],edi + jmp process_param + get_output_file: + cmp [output_file],0 + jne bad_params + mov [output_file],edi + process_param: + cmp al,22h + je string_param + copy_param: + stosb + lodsb + cmp al,20h + je param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + jmp copy_param + string_param: + lodsb + cmp al,22h + je string_param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + stosb + jmp string_param + bad_params: + stc + ret + param_end: + dec esi + string_param_end: + xor al,al + stosb + jmp find_param + all_params: + cmp [input_file],0 + je bad_params + cmp [output_file],0 + je bad_params + clc + ret + + include 'system.inc' + + include '..\prepsrc.inc' + +section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL' + + include 'api\kernel32.inc' diff --git a/toolchain/fasmw17332/TOOLS/WIN32/SYMBOLS.ASM b/toolchain/fasmw17332/TOOLS/WIN32/SYMBOLS.ASM new file mode 100644 index 0000000..e4f1e71 --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/WIN32/SYMBOLS.ASM @@ -0,0 +1,142 @@ + +format PE console 4.0 +entry start + +include 'win32a.inc' + +section '.data' data readable writeable + + _usage db 'symbols dumper for flat assembler',0Dh,0Ah + db 'usage: symbols ',0Dh,0Ah + db 0 + _error_prefix db 'error: ',0 + _error_suffix db '.',0Dh,0Ah,0 + + input_file dd 0 + output_file dd 0 + + input dd ? + output_buffer dd ? + output_handle dd ? + + display_handle dd ? + bytes_count dd ? + + params rb 1000h + +section '.text' code readable executable + + start: + + mov [display_handle],STD_OUTPUT_HANDLE + + call get_params + jnc make_dump + + mov esi,_usage + call display_string + invoke ExitProcess,2 + + make_dump: + call symbols + invoke ExitProcess,0 + + error: + mov [display_handle],STD_ERROR_HANDLE + mov esi,_error_prefix + call display_string + pop esi + call display_string + mov esi,_error_suffix + call display_string + invoke ExitProcess,1 + + get_params: + invoke GetCommandLine + mov esi,eax + mov edi,params + find_command_start: + lodsb + cmp al,20h + je find_command_start + cmp al,22h + je skip_quoted_name + skip_name: + lodsb + cmp al,20h + je find_param + or al,al + jz all_params + jmp skip_name + skip_quoted_name: + lodsb + cmp al,22h + je find_param + or al,al + jz all_params + jmp skip_quoted_name + find_param: + lodsb + cmp al,20h + je find_param + cmp al,0Dh + je all_params + or al,al + jz all_params + cmp [input_file],0 + jne get_output_file + mov [input_file],edi + jmp process_param + get_output_file: + cmp [output_file],0 + jne bad_params + mov [output_file],edi + process_param: + cmp al,22h + je string_param + copy_param: + stosb + lodsb + cmp al,20h + je param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + jmp copy_param + string_param: + lodsb + cmp al,22h + je string_param_end + cmp al,0Dh + je param_end + or al,al + jz param_end + stosb + jmp string_param + bad_params: + stc + ret + param_end: + dec esi + string_param_end: + xor al,al + stosb + jmp find_param + all_params: + cmp [input_file],0 + je bad_params + cmp [output_file],0 + je bad_params + clc + ret + + include 'system.inc' + + include '..\symbols.inc' + +section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL' + + include 'api\kernel32.inc' diff --git a/toolchain/fasmw17332/TOOLS/WIN32/SYSTEM.INC b/toolchain/fasmw17332/TOOLS/WIN32/SYSTEM.INC new file mode 100644 index 0000000..999bdfb --- /dev/null +++ b/toolchain/fasmw17332/TOOLS/WIN32/SYSTEM.INC @@ -0,0 +1,66 @@ + +display_string: + invoke GetStdHandle,[display_handle] + mov edx,eax + mov edi,esi + or ecx,-1 + xor al,al + repne scasb + neg ecx + sub ecx,2 + invoke WriteFile,edx,esi,ecx,bytes_count,0 + retn +alloc: + invoke VirtualAlloc,0,eax,MEM_COMMIT,PAGE_READWRITE + or eax,eax + jz allocation_error + clc + retn + allocation_error: + stc + retn +free: + invoke VirtualFree,eax,0,MEM_RELEASE + retn +open: + invoke CreateFile,edx,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,0,0 + cmp eax,-1 + je file_error + mov ebx,eax + clc + retn + file_error: + stc + retn +create: + invoke CreateFile,edx,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0 + cmp eax,-1 + je file_error + mov ebx,eax + clc + retn +write: + invoke WriteFile,ebx,edx,ecx,bytes_count,0 + or eax,eax + jz file_error + clc + retn +read: + push ecx + invoke ReadFile,ebx,edx,ecx,bytes_count,0 + pop edx + or eax,eax + jz file_error + cmp edx,[bytes_count] + jne file_error + clc + retn +close: + invoke CloseHandle,ebx + retn +lseek: + movzx eax,al + invoke SetFilePointer,ebx,edx,0,eax + cmp eax,-1 + je file_error + retn diff --git a/toolchain/fasmw17332/WHATSNEW.TXT b/toolchain/fasmw17332/WHATSNEW.TXT new file mode 100644 index 0000000..c1fa9bd --- /dev/null +++ b/toolchain/fasmw17332/WHATSNEW.TXT @@ -0,0 +1,506 @@ + +Visit http://flatassembler.net/ for more information. + + +version 1.73.32 (Dec 04, 2023) + +[-] Corrected encoding of "rdpid" instruction operand. + + +version 1.73.31 (Jul 12, 2023) + +[+] Handling multiple sign characters before a floating-point value. + +[-] Corrected an issue with negative offsets for some relocatable addresses. + +[-] Fixed a potential crash in external stub processor for PE. + + +version 1.73.30 (Feb 21, 2022) + +[-] No longer signal an error when there is no line to concatenate with "\". + + +version 1.73.29 (Dec 18, 2021) + +[-] Corrected an issue in external use of expression calculator. + + +version 1.73.28 (Sep 16, 2021) + +[+] Added special preprocessing of symbols "__file__" and "__line__" + (backported from flat assembler g). + + +version 1.73.27 (Jan 27, 2021) + +[-] The assembler should no longer prematurely abort when sign-extended 32-bit + value in 64-bit instruction overflows during intermediate passes. + + +version 1.73.26 (Jan 26, 2021) + +[-] Corrected assembly of some "mov" variants when "use32" setting is used + with 64-bit relocatable formats. + + +version 1.73.25 (Aug 20, 2020) + +[-] Corrected operand size handling for "vldmxcsr"/"vstmxcsr" instructions. + + +version 1.73.24 (Apr 29, 2020) + +[+] Added "invlpgb" and "tlbsync" instructions. + +[-] Upper bits of default entry point of ELF64 executable were not correctly + stored in the header. + + +version 1.73.23 (Apr 09, 2020) + +[+] Added "psmash", "pvalidate", "rmpadjust" and "rmpupdate" instructions. + +[-] No longer allowing "mov" to/from CR9-CR15 outside of long mode. + + +version 1.73.22 (Feb 09, 2020) + +[-] Removed a trick from preprocessor's implementation that caused + the x64 version to crash when replacing symbolic constant in a label. + + +version 1.73.21 (Dec 05, 2019) + +[+] Added "$%" and "$%%" symbols, and output offset addressing with "load" + and "store" directives (backported from flat assembler g). + It can be used only with binary output format. + +[+] Added VAES and VPCMULQDQ instruction set extensions. + +[+] Added "pconfig" instruction. + + +version 1.73.20 (Nov 29, 2019) + +[-] Fixed a bug in "cmpxchg" and "xadd" introduced by previous version. + + +version 1.73.19 (Nov 27, 2019) + +[+] Added AVX512_BITALG, AVX512_VPOPCNTDQ, AVX512_VBMI2, AVX512_VNNI + and AVX512_4VNNIW instruction sets. + +[+] Added CET_SS and CET_IBT instruction sets. + +[+] Added "ptwrite" instruction. + + +version 1.73.18 (Nov 13, 2019) + +[-] Addresses prefixed with "fs:" or "gs:" are no longer RIP-relative by default. + + +version 1.73.17 (Nov 10, 2019) + +[+] Added "mcommit" instruction. + + +version 1.73.16 (Aug 04, 2019) + +[-] Corrected a mistake in AVX-512 mask parsing that led to "{k0}" mask being + erroneously accepted. + + +version 1.73.15 (Aug 01, 2019) + +[+] Added "movdiri", "movdir64b" instructions and GFNI instruction set. + + +version 1.73.14 (Jul 30, 2019) + +[+] Added "rdpru" and "wbnoinvd" instructions. + + +version 1.73.13 (Jul 14, 2019) + +[-] Corrections in 64-bit Linux interface. + + +version 1.73.12 (May 19, 2019) + +[-] Implied memory size allowed for 16-bit "movzx"/"movsx". + + +version 1.73.11 (Apr 19, 2019) + +[+] Added "definite" operator. + + +version 1.73.10 (Apr 05, 2019) + +[+] Added "cldemote", "tpause", "umonitor" and "umwait" instructions. + + +version 1.73.09 (Feb 17, 2019) + +[-] Fixed a bug in AVX-512 instruction encoding with "{sae}" modifier. + + +version 1.73.08 (Jan 31, 2019) + +[-] Fixed a bug in "align" directive for "dynamic" variant of ELF executable. + + +version 1.73.07 (Jan 30, 2019) + +[+] Added "dynamic" variant of ELF executable. + +[+] Added "gnurelro" segment type for ELF executable. + + +version 1.73.06 (Jan 04, 2019) + +[+] Added "ud0" and "ud1" instruction. + +[-] Fixed a minor bug in ELF formatter. + + +version 1.73.05 (Jan 03, 2019) + +[-] Segments in ELF executable format automatically expanded to cover headers + and dynamic linking information. + + +version 1.73.04 (Apr 30, 2018) + +[-] Fixed a bug in "bndstx"/"bndldx" special address syntax processing. + + +version 1.73.03 (Apr 15, 2018) + +[+] Added "rdpid", "xsavec", "xsaves", "xrstors", "clzero", "monitorx" and "mwaitx" + instructions. + + +version 1.73.02 (Dec 16, 2017) + +[-] Fixed a bug in the storage of "virtual as" blocks. + + +version 1.73.01 (Nov 25, 2017) + +[+] Added virtual block continuation syntax (backported from flat assembler g). + +[+] Documentation update. + +[-] Fixed a bug in addressing data of the "virtual as" block. + + +version 1.73.00 (Nov 24, 2017) + +[+] Added "virtual as" syntax (backported from flat assembler g). + + +version 1.72 (Oct 10, 2017) + +[+] Support for Intel AVX-512, SHA, CLFLUSHOPT, CLWB, PCOMMIT, ADX, RDSEED, SMAP + and MPX instruction sets. + +[+] Added "irpv" and "postpone" directives. + +[+] Added ability to define a special kind of label identifying the + addressing space. This label can the be used with "load" or "store" + directives to allow operations on bytes in any addressing space, + not just the current one. This special label is defined by following + its name with double colon, and can only be used with "load" and + "store" directive, where address can now be specified in two parts, + first the adressing space label, then the colon and then the + address inside that addressing space. + +[+] In the definition of macroinstruction the last argument can now be followed by + "&" character to indicate that this argument can be filled with all the remaining + contents of line that called the macro. This feature cannot be combined with a + multi-value arguments. + +[+] Default value for macroinstruction parameter can now be defined with ":" + character as an alternative to "=". + +[+] Added a 64-bit ELF executable version of flat assembler for Linux. It has + no extended capabilities compared to regular versions, it just simulates + the 32-bit environment to allow running the assembler on systems that + support only 64-bit executables. + +[+] Added "gnustack" and "gnuehframe" segment types to ELF executable formatter. + +[+] Console versions now display preprocessed instruction that caused an error + (previously only displayed by Windows GUI interface). + +[+] Brought back the "-d" switch for command line. + +[-] Removed dependence on size context for expression operators like NOT and XOR. + +[+] Added "bsf" and "bsr" operators to numerical expressions. + +[+] Allowed underscore character to be put inside a number value. + +[+] Allowed octal numbers ending with "q". + +[-] Removed the restriction that disallowed numerical constant to + forward-reference its own value. + + +version 1.70 (Apr 17, 2012) + +[+] Added support for AVX, AVX2, AES, CLMUL, FMA, RDRAND, FSGSBASE, F16C, + FMA4, XOP, MOVBE, BMI, TBM, INVPCID, HLE and RTM instruction sets. + +[+] Added half-precision floating point values support. + +[+] Extended the syntax of "rept" directive to allow numerical expressions + to be calculated by preprocessor in its arguments. + +[+] Added "large" and "NX" settings for PE format. + +[+] Allowed PE fixups to be resolved anywhere in the generated executable. + +[+] Allowed to specify branding value (use 3 for Linux) after the + "format ELF executable" setting. + +[+] Added "intepreter", "dynamic" and "note" keywords for creation of + special segments in ELF executables. + +[-] Fixed long mode opcode generator to allow absolute addresses to be + generated with "qword" keyword inside square brackets. + +[-] Disallowed negative immediates with "int", "enter", "ret" instructions. + +[+] Allowed symbolic information dump file to be created even in case of error. + In such case it contains only the preprocessed source that can be extracted + with PREPSRC tool. If error occured during preprocessing, only the source up + to the point of error is provided. + +[+] Added symbol references table to symbolic dump file. + +[-] Corrected the "defined" and "used" flags in the symbols dump to reflect the + state from the final assembly pass. + +[+] Added "assert" directive. + +[-] Formatter symbols like "PE" or "readable" are now recognized only in the + context of formatter directives, and thus are no longer disallowed as + labels. + +[+] Macroinstruction argument now can have default value, defined with "=" + symbol followed by value after the argument name in definition. + +[+] Added "relativeto" operator, which can be used in logical expressions + to test whether two values differ only by a constant and not relocatable + amount. + +[-] Revised the expression calculator, it now is able to correctly perform + calculations in signed and unsigned ranges in full 64-bit. This fixes + a number of issues - the overflow will now be correctly detected for + 64-bit values in cases, where previous versions could not distinguish + whether it was an overflow or not. The effect of these corrections is + that "dq" directive will now behave consistently with behavior of the + data directives for smaller sizes, and the same applies to all the + places where "qword" size for value is used. + + +version 1.68 (Jun 13, 2009) + +[+] Added SSSE3 (Supplemental SSE3), SSE4.1, SSE4.2 and SSE4a instructions. + +[+] Added the AMD SVM and Intel SMX instructions. + +[+] Added "rdmsrq", "wrmsrq", "sysexitq" and "sysretq" mnemonics for the + 64-bit variants of respective instructions. + +[+] Added "fstenvw", "fstenvd", "fsavew", "fsaved", "frstorw" and "frstord" + mnemonics to allow choosing between 16-bit and 32-bit variants of + structures used by the "fstenv", "fsave" and "frstor" instructions. + +[+] Added "plt" operator for the ELF output format. + +[+] Allowed "rva" operator to be used in MS COFF object format, and also + added "static" keyword for the "public" directive. + +[+] Added Intel-style aliases for the additional long mode 8-bit registers. + +[-] The PE formatter now automatically detects whether relocatable labels + should be used, depending on whether the fixups directory is placed + somewhere into executable by programer, or not. This makes possible the + more flexible use of the addressing symbols in case of PE executable fixed + at some position. + +[-] Added support for outputting the 32-bit address relocations in case of + 64-bit object formats and PE executable. This makes some specific + instructions compilable, but it also forces linker to put such + generated code into the low 2 gigabytes of addressing space. + +[+] Added "EFI", "EFIboot" and "EFIruntime" subsystem keywords for PE format. + +[-] Corrected the precedence of operators of macroinstruction line maker. + The symbol escaping now has always the higher priority than symbol conversion, + and both have higher precedence than concatenation. + +[+] Allowed to check "@b" and "@f" symbols with "defined" operator. + +[+] Allowed "as" operator to specify the output file extension when + placed at the end of the "format" directive line. + +[-] Definition of macro with the same name as one of the preprocessor's directives + is no longer allowed. + +[+] Allowed single quote character to be put inside the number value, + to help improve long numbers readability. + +[+] Added optional symbolic information output, and a set of tools that extract + various kinds of information from it. + +[+] Added "err" directive that allows to signalize error from the source. + + +version 1.66 (May 7, 2006) + +[+] Added "define" directive to preprocessor, which defines symbolic constants, + the same kind as "equ" directive, however there's an important difference + that "define" doesn't process symbolic constants in the value before + assigning it. For example: + + a equ 1 + a equ a+a + + define b 1 + define b b+b + + defines the "a" constant with value "1+1", but the "b" is defined with + value "b+b". This directive may be useful in some advanced + macroinstructions. + +[-] Moved part of the conditional expression processing into parser, + for slightly better performance and lesser memory usage by assembler. + The logical values defined with "eq", "eqtype" and "in" operators are now + evaluated by the parser and if they are enough to determine the condition, + the whole block is processed accordingly. Thus this block: + + if eax eq EAX | 0/0 + nop + end if + + is parsed into just "nop" instruction, since parser is able to determine + that the condition is true, even though one of the logical values makes no + sense - but since this is none of the "eq", "eqtype" and "in" expressions, + the parser doesn't investigate. + +[-] Also the assembler is now calculating only as many logical values as it + needs to determine the condition. So this block: + + if defined alpha & alpha + + end if + + will not cause error when "alpha" is not defined, as it would with previous + versions. This is because after checking that "defined alpha" is false + condition it doesn't need to know the second logical value to determine the + value of conjunction. + +[+] Added "short" keyword for specifying jump type, the "jmp byte" form is now + obsolete and no longer correct - use "jmp short" instead. + +[-] The size operator applied to jump no longer applies to the size of relative + displacement - now it applies to the size of target address. + +[-] The "ret" instruction with 0 parameter is now assembled into short form, + unless you force using the 16-bit immediate with "word" operator. + +[+] Added missing extended registers for the 32-bit addressing in long mode. + +[+] Added "linkremove" and "linkinfo" section flags for MS COFF output. + +[+] Added support for GOT offsets in ELF object formatter, which can be useful + when making position-independent code for shared libraries. For any label + you can get its offset relative to GOT by preceding it with "rva" operator + (the same keyword as for PE format is used, to avoid adding a new one, + while this one has very similar meaning). + +[-] Changed ELF executable to use "segment" directive in place of "section", + to make the distinction between the run-time segments and linkable + sections. If you had a "section" directive in your ELF executables and they + no longer assemble, replace it with "segment". + +[-] The PE formatter now always creates the fixups directory when told to - + even when there are no fixups to be put there (in such case it creates the + directory with one empty block). + +[-] Some of the internal structures have been extended to provide the + possibility of making extensive symbol dumps. + +[-] Corrected "fix" directive to keep the value intact before assigning it to the + prioritized constant. + +[+] The ` operator now works with any kind of symbol; when used with quoted + string it simply does nothing. Thus the sequence of ` operators applied to + one symbol work the same as if there was just one. In similar manner, the + sequence of # operators now works as if it was a single one - using such a + sequence instead of escaping, which was kept for some backward + compatibility, is now deprecated. + +[-] Corrected order of identifying assembler directives ("if db eq db" was + incorrectly interpreted as data definition). + +[-] Many other small bugs fixed. + + +version 1.64 (Aug 8, 2005) + +[+] Output of PE executables for Win64 architecture (with "format PE64" + setting). + +[+] Added "while" and "break" directives. + +[+] Added "irp" and "irps" directives. + +[+] The macro arguments can be marked as required with the "*" character. + +[-] Fixed checking for overflow when multiplying 64-bit values - the result + must always fit in the range of signed 64 integer now. + +[-] Segment prefixes were generated incorrectly in 16-bit mode when BP was used + as a second addressing register - fixed. + +[-] The "local" directive was not creating unique labels in some cases - fixed. + +[-] The "not encodable with long immediate" error in 64-bit mode was sometimes + wrongly signaled - fixed. + +[-] Other minor fixes and corrections. + + +version 1.62 (Jun 14, 2005) + +[+] Escaping of symbols inside macroinstructions with backslash. + +[+] Ability of outputting the COFF object files for Win64 architecture + (with "format MS64 COFF" setting). + +[+] New preprocessor directives: "restruc", "rept" and "match" + +[+] VMX instructions support (not documented). + +[+] Extended data directives to allow use of the "dup" operator. + +[+] Extended "struc" features to allow custom definitions of main structure's + label. + +[-] When building resources from the the .RES file that contained more + than one resource of the same string name, the separate resource + directories were created with the same names - fixed. + +[-] Several bugs in the ELF64 object output has been fixed. + +[-] Corrected behavior of "fix" directive to more straightforward. + +[-] Fixed bug in "include" directive, which caused files included from within + macros to be processed the wrong way.