From dbfd94ea40f73b43d58dc4477e076d28f6cc6bfc Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sun, 24 Nov 2024 23:13:28 -0500 Subject: [PATCH] add flat assembler toolchain --- toolchain/fasmg.kl0e/docs/fasmg.txt | 1101 +++ toolchain/fasmg.kl0e/docs/manual.txt | 2474 ++++++ toolchain/fasmg.kl0e/examples/8051/8051.inc | 861 ++ toolchain/fasmg.kl0e/examples/8051/hex.inc | 75 + toolchain/fasmg.kl0e/examples/8051/invert.asm | 46 + toolchain/fasmg.kl0e/examples/8051/make.cmd | 1 + toolchain/fasmg.kl0e/examples/avr/avr.inc | 903 ++ toolchain/fasmg.kl0e/examples/avr/counter.asm | 54 + toolchain/fasmg.kl0e/examples/avr/m16def.inc | 738 ++ toolchain/fasmg.kl0e/examples/avr/make.cmd | 1 + toolchain/fasmg.kl0e/examples/jvm/Test.asm | 134 + .../fasmg.kl0e/examples/jvm/bytecode.inc | 797 ++ toolchain/fasmg.kl0e/examples/jvm/jclass.inc | 254 + toolchain/fasmg.kl0e/examples/jvm/make.cmd | 1 + toolchain/fasmg.kl0e/examples/x86/hello.asm | 14 + .../fasmg.kl0e/examples/x86/include/80186.inc | 383 + .../fasmg.kl0e/examples/x86/include/80286.inc | 86 + .../fasmg.kl0e/examples/x86/include/80287.inc | 16 + .../fasmg.kl0e/examples/x86/include/80386.inc | 2712 ++++++ .../fasmg.kl0e/examples/x86/include/80387.inc | 158 + .../fasmg.kl0e/examples/x86/include/80486.inc | 62 + .../fasmg.kl0e/examples/x86/include/8086.inc | 1605 ++++ .../fasmg.kl0e/examples/x86/include/8087.inc | 555 ++ .../examples/x86/include/ext/adx.inc | 21 + .../examples/x86/include/ext/aes.inc | 43 + .../examples/x86/include/ext/avx.inc | 1266 +++ .../examples/x86/include/ext/avx2.inc | 502 ++ .../examples/x86/include/ext/avx512.inc | 10 + .../x86/include/ext/avx512_4vnniw.inc | 31 + .../x86/include/ext/avx512_bitalg.inc | 29 + .../examples/x86/include/ext/avx512_ifma.inc | 15 + .../examples/x86/include/ext/avx512_vbmi.inc | 22 + .../examples/x86/include/ext/avx512_vbmi2.inc | 65 + .../examples/x86/include/ext/avx512_vnni.inc | 14 + .../x86/include/ext/avx512_vpopcntdq.inc | 16 + .../examples/x86/include/ext/avx512bw.inc | 494 ++ .../examples/x86/include/ext/avx512cd.inc | 29 + .../examples/x86/include/ext/avx512dq.inc | 463 ++ .../examples/x86/include/ext/avx512er.inc | 39 + .../examples/x86/include/ext/avx512f.inc | 2660 ++++++ .../examples/x86/include/ext/avx512pf.inc | 62 + .../examples/x86/include/ext/avx512vl.inc | 8 + .../examples/x86/include/ext/bmi1.inc | 97 + .../examples/x86/include/ext/bmi2.inc | 106 + .../examples/x86/include/ext/cet_ibt.inc | 8 + .../examples/x86/include/ext/cet_ss.inc | 106 + .../examples/x86/include/ext/f16c.inc | 29 + .../examples/x86/include/ext/fma.inc | 30 + .../examples/x86/include/ext/fsgsbase.inc | 24 + .../examples/x86/include/ext/gfni.inc | 53 + .../examples/x86/include/ext/hle.inc | 16 + .../examples/x86/include/ext/invpcid.inc | 15 + .../examples/x86/include/ext/mmx.inc | 149 + .../examples/x86/include/ext/movdir64b.inc | 23 + .../examples/x86/include/ext/movdiri.inc | 19 + .../examples/x86/include/ext/mpx.inc | 196 + .../examples/x86/include/ext/pclmulqdq.inc | 14 + .../examples/x86/include/ext/ptwrite.inc | 18 + .../examples/x86/include/ext/rdrand.inc | 10 + .../examples/x86/include/ext/rdseed.inc | 10 + .../examples/x86/include/ext/rdtscp.inc | 4 + .../examples/x86/include/ext/rtm.inc | 39 + .../examples/x86/include/ext/smx.inc | 4 + .../examples/x86/include/ext/sse.inc | 433 + .../examples/x86/include/ext/sse2.inc | 603 ++ .../examples/x86/include/ext/sse3.inc | 72 + .../examples/x86/include/ext/sse4.1.inc | 204 + .../examples/x86/include/ext/sse4.2.inc | 54 + .../examples/x86/include/ext/ssse3.inc | 26 + .../examples/x86/include/ext/vaes.inc | 37 + .../examples/x86/include/ext/vmx.inc | 65 + .../examples/x86/include/ext/vpclmulqdq.inc | 32 + .../examples/x86/include/ext/xsave.inc | 35 + .../examples/x86/include/format/coff.inc | 470 ++ .../examples/x86/include/format/coffms.inc | 754 ++ .../examples/x86/include/format/elf32.inc | 640 ++ .../examples/x86/include/format/elf64.inc | 652 ++ .../examples/x86/include/format/elfexe.inc | 326 + .../examples/x86/include/format/format.inc | 328 + .../examples/x86/include/format/macho.inc | 1186 +++ .../examples/x86/include/format/mz.inc | 209 + .../examples/x86/include/format/pe.inc | 1064 +++ .../fasmg.kl0e/examples/x86/include/p5.inc | 37 + .../fasmg.kl0e/examples/x86/include/p6.inc | 62 + .../fasmg.kl0e/examples/x86/include/x64.inc | 3476 ++++++++ toolchain/fasmg.kl0e/examples/x86/life.asm | 209 + toolchain/fasmg.kl0e/examples/x86/make.cmd | 9 + toolchain/fasmg.kl0e/examples/x86/mandel.asm | 94 + .../fasmg.kl0e/examples/x86/multiseg.asm | 29 + toolchain/fasmg.kl0e/examples/x86/usedpmi.asm | 99 + toolchain/fasmg.kl0e/examples/x86/win32.asm | 46 + toolchain/fasmg.kl0e/examples/x86/win64.asm | 45 + .../fasmg.kl0e/examples/x86/win64avx.asm | 114 + toolchain/fasmg.kl0e/fasmg | Bin 0 -> 66250 bytes toolchain/fasmg.kl0e/fasmg.exe | Bin 0 -> 67072 bytes toolchain/fasmg.kl0e/fasmg.x64 | Bin 0 -> 70646 bytes toolchain/fasmg.kl0e/license.txt | 24 + toolchain/fasmg.kl0e/readme.txt | 20 + toolchain/fasmg.kl0e/source/assembler.inc | 3383 ++++++++ toolchain/fasmg.kl0e/source/calm.inc | 3293 ++++++++ toolchain/fasmg.kl0e/source/conditions.inc | 669 ++ toolchain/fasmg.kl0e/source/console.inc | 560 ++ toolchain/fasmg.kl0e/source/directives.inc | 4852 +++++++++++ toolchain/fasmg.kl0e/source/dos/fasmg.asm | 651 ++ toolchain/fasmg.kl0e/source/dos/selfhost.inc | 22 + toolchain/fasmg.kl0e/source/dos/system.inc | 415 + toolchain/fasmg.kl0e/source/errors.inc | 177 + toolchain/fasmg.kl0e/source/expressions.inc | 4252 ++++++++++ toolchain/fasmg.kl0e/source/floats.inc | 1182 +++ toolchain/fasmg.kl0e/source/libc/ccall.inc | 23 + toolchain/fasmg.kl0e/source/libc/fasmg.asm | 499 ++ toolchain/fasmg.kl0e/source/libc/selfhost.inc | 60 + toolchain/fasmg.kl0e/source/libc/struct.inc | 17 + toolchain/fasmg.kl0e/source/libc/system.inc | 225 + toolchain/fasmg.kl0e/source/linux/fasmg.asm | 513 ++ .../fasmg.kl0e/source/linux/selfhost.inc | 59 + toolchain/fasmg.kl0e/source/linux/system.inc | 298 + .../fasmg.kl0e/source/linux/x64/32on64.inc | 124 + .../fasmg.kl0e/source/linux/x64/fasmg.asm | 545 ++ .../fasmg.kl0e/source/linux/x64/selfhost.inc | 120 + .../fasmg.kl0e/source/linux/x64/system.inc | 334 + toolchain/fasmg.kl0e/source/macos/fasmg | Bin 0 -> 74062 bytes toolchain/fasmg.kl0e/source/macos/fasmg.asm | 504 ++ toolchain/fasmg.kl0e/source/macos/fasmg.o.asm | 498 ++ .../fasmg.kl0e/source/macos/selfhost.inc | 50 + toolchain/fasmg.kl0e/source/macos/system.inc | 225 + toolchain/fasmg.kl0e/source/macos/x64/fasmg | Bin 0 -> 78185 bytes .../fasmg.kl0e/source/macos/x64/fasmg.asm | 546 ++ .../fasmg.kl0e/source/macos/x64/selfhost.inc | 41 + .../fasmg.kl0e/source/macos/x64/system.inc | 287 + toolchain/fasmg.kl0e/source/malloc.inc | 343 + toolchain/fasmg.kl0e/source/map.inc | 237 + toolchain/fasmg.kl0e/source/messages.inc | 52 + toolchain/fasmg.kl0e/source/output.inc | 883 ++ toolchain/fasmg.kl0e/source/reader.inc | 451 + toolchain/fasmg.kl0e/source/symbols.inc | 1547 ++++ toolchain/fasmg.kl0e/source/tables.inc | 649 ++ toolchain/fasmg.kl0e/source/variables.inc | 314 + toolchain/fasmg.kl0e/source/version.inc | 1 + .../fasmg.kl0e/source/windows/dll/fasmg.asm | 254 + .../source/windows/dll/localptr.inc | 28 + .../source/windows/dll/selfhost.inc | 266 + .../fasmg.kl0e/source/windows/dll/system.inc | 214 + toolchain/fasmg.kl0e/source/windows/fasmg.asm | 529 ++ .../fasmg.kl0e/source/windows/kernel32.inc | 96 + .../fasmg.kl0e/source/windows/selfhost.inc | 171 + .../fasmg.kl0e/source/windows/system.inc | 218 + toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.ASM | 326 + toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.GIF | Bin 0 -> 58677 bytes toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.INC | 424 + .../fasmw17332/EXAMPLES/DDRAW/GIF87A.INC | 196 + .../fasmw17332/EXAMPLES/DIALOG/DIALOG.ASM | 130 + .../fasmw17332/EXAMPLES/DLL/ERRORMSG.ASM | 59 + toolchain/fasmw17332/EXAMPLES/DLL/LASTERR.ASM | 24 + toolchain/fasmw17332/EXAMPLES/HELLO/HELLO.ASM | 18 + .../fasmw17332/EXAMPLES/MINIPAD/MINIPAD.ASM | 206 + .../fasmw17332/EXAMPLES/MINIPAD/MINIPAD.ICO | Bin 0 -> 766 bytes .../fasmw17332/EXAMPLES/MSCOFF/MSCOFF.ASM | 23 + .../fasmw17332/EXAMPLES/OPENGL/OPENGL.ASM | 614 ++ .../fasmw17332/EXAMPLES/OPENGL/OPENGL.INC | 2337 ++++++ .../fasmw17332/EXAMPLES/PEDEMO/PEDEMO.ASM | 46 + .../fasmw17332/EXAMPLES/TEMPLATE/TEMPLATE.ASM | 71 + .../fasmw17332/EXAMPLES/USECOM/USECOM.ASM | 142 + .../fasmw17332/EXAMPLES/WIN64/DLL/MSGDEMO.ASM | 27 + .../EXAMPLES/WIN64/DLL/WRITEMSG.ASM | 47 + .../EXAMPLES/WIN64/MANDEL/DDRAW64.INC | 425 + .../EXAMPLES/WIN64/MANDEL/MANDEL.ASM | 319 + .../EXAMPLES/WIN64/OPENGL/OPENGL.ASM | 615 ++ .../EXAMPLES/WIN64/PE64DEMO/PE64DEMO.ASM | 45 + .../EXAMPLES/WIN64/TEMPLATE/TEMPLATE.ASM | 82 + .../EXAMPLES/WIN64/USECOM/USECOM.ASM | 142 + .../EXAMPLES/WIN64/WIN64AVX/WIN64AVX.ASM | 98 + toolchain/fasmw17332/FASM.EXE | Bin 0 -> 117248 bytes toolchain/fasmw17332/FASM.pdf | Bin 0 -> 529038 bytes toolchain/fasmw17332/FASMW.EXE | Bin 0 -> 160256 bytes toolchain/fasmw17332/INCLUDE/API/ADVAPI32.INC | 535 ++ toolchain/fasmw17332/INCLUDE/API/COMCTL32.INC | 81 + toolchain/fasmw17332/INCLUDE/API/COMDLG32.INC | 38 + toolchain/fasmw17332/INCLUDE/API/GDI32.INC | 419 + toolchain/fasmw17332/INCLUDE/API/KERNEL32.INC | 881 ++ toolchain/fasmw17332/INCLUDE/API/SHELL32.INC | 167 + toolchain/fasmw17332/INCLUDE/API/USER32.INC | 756 ++ toolchain/fasmw17332/INCLUDE/API/WSOCK32.INC | 85 + .../fasmw17332/INCLUDE/ENCODING/UTF8.INC | 77 + .../fasmw17332/INCLUDE/ENCODING/WIN1250.INC | 36 + .../fasmw17332/INCLUDE/ENCODING/WIN1251.INC | 33 + .../fasmw17332/INCLUDE/ENCODING/WIN1252.INC | 31 + .../fasmw17332/INCLUDE/ENCODING/WIN1253.INC | 33 + .../fasmw17332/INCLUDE/ENCODING/WIN1254.INC | 34 + .../fasmw17332/INCLUDE/ENCODING/WIN1255.INC | 36 + .../fasmw17332/INCLUDE/ENCODING/WIN1256.INC | 36 + .../fasmw17332/INCLUDE/ENCODING/WIN1257.INC | 36 + .../fasmw17332/INCLUDE/ENCODING/WIN1258.INC | 36 + .../fasmw17332/INCLUDE/ENCODING/WIN874.INC | 31 + .../fasmw17332/INCLUDE/EQUATES/COMCTL32.INC | 1869 +++++ .../fasmw17332/INCLUDE/EQUATES/COMCTL64.INC | 1871 +++++ .../fasmw17332/INCLUDE/EQUATES/COMDLG32.INC | 333 + .../fasmw17332/INCLUDE/EQUATES/COMDLG64.INC | 334 + .../fasmw17332/INCLUDE/EQUATES/GDI32.INC | 480 ++ .../fasmw17332/INCLUDE/EQUATES/GDI64.INC | 480 ++ .../fasmw17332/INCLUDE/EQUATES/KERNEL32.INC | 812 ++ .../fasmw17332/INCLUDE/EQUATES/KERNEL64.INC | 806 ++ .../fasmw17332/INCLUDE/EQUATES/SHELL32.INC | 128 + .../fasmw17332/INCLUDE/EQUATES/SHELL64.INC | 127 + .../fasmw17332/INCLUDE/EQUATES/USER32.INC | 1934 +++++ .../fasmw17332/INCLUDE/EQUATES/USER64.INC | 1935 +++++ .../fasmw17332/INCLUDE/EQUATES/WSOCK32.INC | 124 + toolchain/fasmw17332/INCLUDE/MACRO/COM32.INC | 53 + toolchain/fasmw17332/INCLUDE/MACRO/COM64.INC | 39 + toolchain/fasmw17332/INCLUDE/MACRO/EXPORT.INC | 66 + toolchain/fasmw17332/INCLUDE/MACRO/IF.INC | 507 ++ .../fasmw17332/INCLUDE/MACRO/IMPORT32.INC | 68 + .../fasmw17332/INCLUDE/MACRO/IMPORT64.INC | 68 + toolchain/fasmw17332/INCLUDE/MACRO/MASM.INC | 66 + toolchain/fasmw17332/INCLUDE/MACRO/PROC32.INC | 301 + toolchain/fasmw17332/INCLUDE/MACRO/PROC64.INC | 618 ++ .../fasmw17332/INCLUDE/MACRO/RESOURCE.INC | 334 + toolchain/fasmw17332/INCLUDE/MACRO/STRUCT.INC | 221 + toolchain/fasmw17332/INCLUDE/MACRO/proc64.bin | 0 .../fasmw17332/INCLUDE/PCOUNT/ADVAPI32.INC | 340 + .../fasmw17332/INCLUDE/PCOUNT/COMCTL32.INC | 69 + .../fasmw17332/INCLUDE/PCOUNT/COMDLG32.INC | 18 + toolchain/fasmw17332/INCLUDE/PCOUNT/GDI32.INC | 319 + .../fasmw17332/INCLUDE/PCOUNT/KERNEL32.INC | 557 ++ .../fasmw17332/INCLUDE/PCOUNT/SHELL32.INC | 73 + .../fasmw17332/INCLUDE/PCOUNT/USER32.INC | 477 ++ .../fasmw17332/INCLUDE/PCOUNT/WSOCK32.INC | 70 + toolchain/fasmw17332/INCLUDE/WIN32A.INC | 25 + toolchain/fasmw17332/INCLUDE/WIN32AX.INC | 172 + toolchain/fasmw17332/INCLUDE/WIN32AXP.INC | 199 + toolchain/fasmw17332/INCLUDE/WIN32W.INC | 25 + toolchain/fasmw17332/INCLUDE/WIN32WX.INC | 188 + toolchain/fasmw17332/INCLUDE/WIN32WXP.INC | 201 + toolchain/fasmw17332/INCLUDE/WIN64A.INC | 25 + toolchain/fasmw17332/INCLUDE/WIN64AX.INC | 205 + toolchain/fasmw17332/INCLUDE/WIN64AXP.INC | 221 + toolchain/fasmw17332/INCLUDE/WIN64W.INC | 24 + toolchain/fasmw17332/INCLUDE/WIN64WX.INC | 204 + toolchain/fasmw17332/INCLUDE/WIN64WXP.INC | 221 + toolchain/fasmw17332/LICENSE.TXT | 37 + toolchain/fasmw17332/SOURCE/ASSEMBLE.INC | 2235 +++++ toolchain/fasmw17332/SOURCE/AVX.INC | 3425 ++++++++ toolchain/fasmw17332/SOURCE/DOS/DPMI.INC | 108 + toolchain/fasmw17332/SOURCE/DOS/FASM.ASM | 435 + toolchain/fasmw17332/SOURCE/DOS/MODES.INC | 539 ++ toolchain/fasmw17332/SOURCE/DOS/SYSTEM.INC | 600 ++ toolchain/fasmw17332/SOURCE/ERRORS.INC | 191 + toolchain/fasmw17332/SOURCE/EXPRCALC.INC | 2272 +++++ toolchain/fasmw17332/SOURCE/EXPRPARS.INC | 1289 +++ toolchain/fasmw17332/SOURCE/FORMATS.INC | 4195 ++++++++++ toolchain/fasmw17332/SOURCE/IDE/BLOCKS.INC | 536 ++ toolchain/fasmw17332/SOURCE/IDE/EDIT.INC | 1027 +++ .../fasmw17332/SOURCE/IDE/FASMD/FASMD.ASM | 6756 +++++++++++++++ .../fasmw17332/SOURCE/IDE/FASMW/FASM.INC | 467 ++ .../fasmw17332/SOURCE/IDE/FASMW/FASMW.ASM | 3812 +++++++++ .../fasmw17332/SOURCE/IDE/FASMW/FEDIT.ASH | 69 + .../fasmw17332/SOURCE/IDE/FASMW/FEDIT.INC | 2279 +++++ .../SOURCE/IDE/FASMW/RESOURCE/ASSIGN.BMP | Bin 0 -> 206 bytes .../SOURCE/IDE/FASMW/RESOURCE/FASMW.ICO | Bin 0 -> 766 bytes toolchain/fasmw17332/SOURCE/IDE/MEMORY.INC | 199 + toolchain/fasmw17332/SOURCE/IDE/NAVIGATE.INC | 511 ++ toolchain/fasmw17332/SOURCE/IDE/SEARCH.INC | 529 ++ toolchain/fasmw17332/SOURCE/IDE/UNDO.INC | 339 + toolchain/fasmw17332/SOURCE/IDE/VARIABLE.INC | 40 + toolchain/fasmw17332/SOURCE/IDE/VERSION.INC | 39 + toolchain/fasmw17332/SOURCE/LIBC/FASM.ASM | 362 + toolchain/fasmw17332/SOURCE/LIBC/SYSTEM.INC | 410 + toolchain/fasmw17332/SOURCE/LINUX/FASM.ASM | 341 + toolchain/fasmw17332/SOURCE/LINUX/SYSTEM.INC | 470 ++ .../fasmw17332/SOURCE/LINUX/X64/FASM.ASM | 360 + .../fasmw17332/SOURCE/LINUX/X64/MODES.INC | 186 + .../fasmw17332/SOURCE/LINUX/X64/SYSTEM.INC | 548 ++ toolchain/fasmw17332/SOURCE/MESSAGES.INC | 51 + toolchain/fasmw17332/SOURCE/PARSER.INC | 1470 ++++ toolchain/fasmw17332/SOURCE/PREPROCE.INC | 2983 +++++++ toolchain/fasmw17332/SOURCE/SYMBDUMP.INC | 450 + toolchain/fasmw17332/SOURCE/TABLES.INC | 4393 ++++++++++ toolchain/fasmw17332/SOURCE/VARIABLE.INC | 155 + toolchain/fasmw17332/SOURCE/VERSION.INC | 39 + toolchain/fasmw17332/SOURCE/WIN32/FASM.ASM | 436 + toolchain/fasmw17332/SOURCE/WIN32/SYSTEM.INC | 570 ++ toolchain/fasmw17332/SOURCE/X86_64.INC | 7391 +++++++++++++++++ toolchain/fasmw17332/TOOLS/DOS/LISTING.ASM | 229 + toolchain/fasmw17332/TOOLS/DOS/LOADER.INC | 102 + toolchain/fasmw17332/TOOLS/DOS/PREPSRC.ASM | 136 + toolchain/fasmw17332/TOOLS/DOS/SYMBOLS.ASM | 140 + toolchain/fasmw17332/TOOLS/DOS/SYSTEM.INC | 239 + toolchain/fasmw17332/TOOLS/FAS.TXT | 429 + toolchain/fasmw17332/TOOLS/LIBC/CCALL.INC | 23 + toolchain/fasmw17332/TOOLS/LIBC/LISTING.ASM | 177 + toolchain/fasmw17332/TOOLS/LIBC/PREPSRC.ASM | 94 + toolchain/fasmw17332/TOOLS/LIBC/SYMBOLS.ASM | 98 + toolchain/fasmw17332/TOOLS/LIBC/SYSTEM.INC | 107 + toolchain/fasmw17332/TOOLS/LISTING.INC | 690 ++ toolchain/fasmw17332/TOOLS/PREPSRC.INC | 115 + toolchain/fasmw17332/TOOLS/README.TXT | 26 + toolchain/fasmw17332/TOOLS/SYMBOLS.INC | 444 + toolchain/fasmw17332/TOOLS/WIN32/LISTING.ASM | 229 + toolchain/fasmw17332/TOOLS/WIN32/PREPSRC.ASM | 138 + toolchain/fasmw17332/TOOLS/WIN32/SYMBOLS.ASM | 142 + toolchain/fasmw17332/TOOLS/WIN32/SYSTEM.INC | 66 + toolchain/fasmw17332/WHATSNEW.TXT | 506 ++ 302 files changed, 145599 insertions(+) create mode 100644 toolchain/fasmg.kl0e/docs/fasmg.txt create mode 100644 toolchain/fasmg.kl0e/docs/manual.txt create mode 100644 toolchain/fasmg.kl0e/examples/8051/8051.inc create mode 100644 toolchain/fasmg.kl0e/examples/8051/hex.inc create mode 100644 toolchain/fasmg.kl0e/examples/8051/invert.asm create mode 100644 toolchain/fasmg.kl0e/examples/8051/make.cmd create mode 100644 toolchain/fasmg.kl0e/examples/avr/avr.inc create mode 100644 toolchain/fasmg.kl0e/examples/avr/counter.asm create mode 100644 toolchain/fasmg.kl0e/examples/avr/m16def.inc create mode 100644 toolchain/fasmg.kl0e/examples/avr/make.cmd create mode 100644 toolchain/fasmg.kl0e/examples/jvm/Test.asm create mode 100644 toolchain/fasmg.kl0e/examples/jvm/bytecode.inc create mode 100644 toolchain/fasmg.kl0e/examples/jvm/jclass.inc create mode 100644 toolchain/fasmg.kl0e/examples/jvm/make.cmd create mode 100644 toolchain/fasmg.kl0e/examples/x86/hello.asm create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/80186.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/80286.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/80287.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/80386.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/80387.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/80486.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/8086.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/8087.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/adx.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/aes.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx2.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_4vnniw.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_bitalg.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_ifma.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vbmi.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vbmi2.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vnni.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512_vpopcntdq.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512bw.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512cd.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512dq.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512er.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512f.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512pf.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/avx512vl.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/bmi1.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/bmi2.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/cet_ibt.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/cet_ss.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/f16c.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/fma.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/fsgsbase.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/gfni.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/hle.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/invpcid.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/mmx.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/movdir64b.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/movdiri.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/mpx.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/pclmulqdq.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/ptwrite.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/rdrand.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/rdseed.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/rdtscp.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/rtm.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/smx.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/sse.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/sse2.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/sse3.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.1.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/sse4.2.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/ssse3.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/vaes.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/vmx.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/vpclmulqdq.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/ext/xsave.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/format/coff.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/format/coffms.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/format/elf32.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/format/elf64.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/format/elfexe.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/format/format.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/format/macho.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/format/mz.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/format/pe.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/p5.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/p6.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/include/x64.inc create mode 100644 toolchain/fasmg.kl0e/examples/x86/life.asm create mode 100644 toolchain/fasmg.kl0e/examples/x86/make.cmd create mode 100644 toolchain/fasmg.kl0e/examples/x86/mandel.asm create mode 100644 toolchain/fasmg.kl0e/examples/x86/multiseg.asm create mode 100644 toolchain/fasmg.kl0e/examples/x86/usedpmi.asm create mode 100644 toolchain/fasmg.kl0e/examples/x86/win32.asm create mode 100644 toolchain/fasmg.kl0e/examples/x86/win64.asm create mode 100644 toolchain/fasmg.kl0e/examples/x86/win64avx.asm create mode 100644 toolchain/fasmg.kl0e/fasmg create mode 100644 toolchain/fasmg.kl0e/fasmg.exe create mode 100644 toolchain/fasmg.kl0e/fasmg.x64 create mode 100644 toolchain/fasmg.kl0e/license.txt create mode 100644 toolchain/fasmg.kl0e/readme.txt create mode 100644 toolchain/fasmg.kl0e/source/assembler.inc create mode 100644 toolchain/fasmg.kl0e/source/calm.inc create mode 100644 toolchain/fasmg.kl0e/source/conditions.inc create mode 100644 toolchain/fasmg.kl0e/source/console.inc create mode 100644 toolchain/fasmg.kl0e/source/directives.inc create mode 100644 toolchain/fasmg.kl0e/source/dos/fasmg.asm create mode 100644 toolchain/fasmg.kl0e/source/dos/selfhost.inc create mode 100644 toolchain/fasmg.kl0e/source/dos/system.inc create mode 100644 toolchain/fasmg.kl0e/source/errors.inc create mode 100644 toolchain/fasmg.kl0e/source/expressions.inc create mode 100644 toolchain/fasmg.kl0e/source/floats.inc create mode 100644 toolchain/fasmg.kl0e/source/libc/ccall.inc create mode 100644 toolchain/fasmg.kl0e/source/libc/fasmg.asm create mode 100644 toolchain/fasmg.kl0e/source/libc/selfhost.inc create mode 100644 toolchain/fasmg.kl0e/source/libc/struct.inc create mode 100644 toolchain/fasmg.kl0e/source/libc/system.inc create mode 100644 toolchain/fasmg.kl0e/source/linux/fasmg.asm create mode 100644 toolchain/fasmg.kl0e/source/linux/selfhost.inc create mode 100644 toolchain/fasmg.kl0e/source/linux/system.inc create mode 100644 toolchain/fasmg.kl0e/source/linux/x64/32on64.inc create mode 100644 toolchain/fasmg.kl0e/source/linux/x64/fasmg.asm create mode 100644 toolchain/fasmg.kl0e/source/linux/x64/selfhost.inc create mode 100644 toolchain/fasmg.kl0e/source/linux/x64/system.inc create mode 100644 toolchain/fasmg.kl0e/source/macos/fasmg create mode 100644 toolchain/fasmg.kl0e/source/macos/fasmg.asm create mode 100644 toolchain/fasmg.kl0e/source/macos/fasmg.o.asm create mode 100644 toolchain/fasmg.kl0e/source/macos/selfhost.inc create mode 100644 toolchain/fasmg.kl0e/source/macos/system.inc create mode 100644 toolchain/fasmg.kl0e/source/macos/x64/fasmg create mode 100644 toolchain/fasmg.kl0e/source/macos/x64/fasmg.asm create mode 100644 toolchain/fasmg.kl0e/source/macos/x64/selfhost.inc create mode 100644 toolchain/fasmg.kl0e/source/macos/x64/system.inc create mode 100644 toolchain/fasmg.kl0e/source/malloc.inc create mode 100644 toolchain/fasmg.kl0e/source/map.inc create mode 100644 toolchain/fasmg.kl0e/source/messages.inc create mode 100644 toolchain/fasmg.kl0e/source/output.inc create mode 100644 toolchain/fasmg.kl0e/source/reader.inc create mode 100644 toolchain/fasmg.kl0e/source/symbols.inc create mode 100644 toolchain/fasmg.kl0e/source/tables.inc create mode 100644 toolchain/fasmg.kl0e/source/variables.inc create mode 100644 toolchain/fasmg.kl0e/source/version.inc create mode 100644 toolchain/fasmg.kl0e/source/windows/dll/fasmg.asm create mode 100644 toolchain/fasmg.kl0e/source/windows/dll/localptr.inc create mode 100644 toolchain/fasmg.kl0e/source/windows/dll/selfhost.inc create mode 100644 toolchain/fasmg.kl0e/source/windows/dll/system.inc create mode 100644 toolchain/fasmg.kl0e/source/windows/fasmg.asm create mode 100644 toolchain/fasmg.kl0e/source/windows/kernel32.inc create mode 100644 toolchain/fasmg.kl0e/source/windows/selfhost.inc create mode 100644 toolchain/fasmg.kl0e/source/windows/system.inc create mode 100644 toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.GIF create mode 100644 toolchain/fasmw17332/EXAMPLES/DDRAW/DDRAW.INC create mode 100644 toolchain/fasmw17332/EXAMPLES/DDRAW/GIF87A.INC create mode 100644 toolchain/fasmw17332/EXAMPLES/DIALOG/DIALOG.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/DLL/ERRORMSG.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/DLL/LASTERR.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/HELLO/HELLO.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/MINIPAD/MINIPAD.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/MINIPAD/MINIPAD.ICO create mode 100644 toolchain/fasmw17332/EXAMPLES/MSCOFF/MSCOFF.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/OPENGL/OPENGL.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/OPENGL/OPENGL.INC create mode 100644 toolchain/fasmw17332/EXAMPLES/PEDEMO/PEDEMO.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/TEMPLATE/TEMPLATE.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/USECOM/USECOM.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/WIN64/DLL/MSGDEMO.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/WIN64/DLL/WRITEMSG.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/WIN64/MANDEL/DDRAW64.INC create mode 100644 toolchain/fasmw17332/EXAMPLES/WIN64/MANDEL/MANDEL.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/WIN64/OPENGL/OPENGL.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/WIN64/PE64DEMO/PE64DEMO.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/WIN64/TEMPLATE/TEMPLATE.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/WIN64/USECOM/USECOM.ASM create mode 100644 toolchain/fasmw17332/EXAMPLES/WIN64/WIN64AVX/WIN64AVX.ASM create mode 100644 toolchain/fasmw17332/FASM.EXE create mode 100644 toolchain/fasmw17332/FASM.pdf create mode 100644 toolchain/fasmw17332/FASMW.EXE create mode 100644 toolchain/fasmw17332/INCLUDE/API/ADVAPI32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/API/COMCTL32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/API/COMDLG32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/API/GDI32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/API/KERNEL32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/API/SHELL32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/API/USER32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/API/WSOCK32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/ENCODING/UTF8.INC create mode 100644 toolchain/fasmw17332/INCLUDE/ENCODING/WIN1250.INC create mode 100644 toolchain/fasmw17332/INCLUDE/ENCODING/WIN1251.INC create mode 100644 toolchain/fasmw17332/INCLUDE/ENCODING/WIN1252.INC create mode 100644 toolchain/fasmw17332/INCLUDE/ENCODING/WIN1253.INC create mode 100644 toolchain/fasmw17332/INCLUDE/ENCODING/WIN1254.INC create mode 100644 toolchain/fasmw17332/INCLUDE/ENCODING/WIN1255.INC create mode 100644 toolchain/fasmw17332/INCLUDE/ENCODING/WIN1256.INC create mode 100644 toolchain/fasmw17332/INCLUDE/ENCODING/WIN1257.INC create mode 100644 toolchain/fasmw17332/INCLUDE/ENCODING/WIN1258.INC create mode 100644 toolchain/fasmw17332/INCLUDE/ENCODING/WIN874.INC create mode 100644 toolchain/fasmw17332/INCLUDE/EQUATES/COMCTL32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/EQUATES/COMCTL64.INC create mode 100644 toolchain/fasmw17332/INCLUDE/EQUATES/COMDLG32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/EQUATES/COMDLG64.INC create mode 100644 toolchain/fasmw17332/INCLUDE/EQUATES/GDI32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/EQUATES/GDI64.INC create mode 100644 toolchain/fasmw17332/INCLUDE/EQUATES/KERNEL32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/EQUATES/KERNEL64.INC create mode 100644 toolchain/fasmw17332/INCLUDE/EQUATES/SHELL32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/EQUATES/SHELL64.INC create mode 100644 toolchain/fasmw17332/INCLUDE/EQUATES/USER32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/EQUATES/USER64.INC create mode 100644 toolchain/fasmw17332/INCLUDE/EQUATES/WSOCK32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/MACRO/COM32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/MACRO/COM64.INC create mode 100644 toolchain/fasmw17332/INCLUDE/MACRO/EXPORT.INC create mode 100644 toolchain/fasmw17332/INCLUDE/MACRO/IF.INC create mode 100644 toolchain/fasmw17332/INCLUDE/MACRO/IMPORT32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/MACRO/IMPORT64.INC create mode 100644 toolchain/fasmw17332/INCLUDE/MACRO/MASM.INC create mode 100644 toolchain/fasmw17332/INCLUDE/MACRO/PROC32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/MACRO/PROC64.INC create mode 100644 toolchain/fasmw17332/INCLUDE/MACRO/RESOURCE.INC create mode 100644 toolchain/fasmw17332/INCLUDE/MACRO/STRUCT.INC create mode 100644 toolchain/fasmw17332/INCLUDE/MACRO/proc64.bin create mode 100644 toolchain/fasmw17332/INCLUDE/PCOUNT/ADVAPI32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/PCOUNT/COMCTL32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/PCOUNT/COMDLG32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/PCOUNT/GDI32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/PCOUNT/KERNEL32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/PCOUNT/SHELL32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/PCOUNT/USER32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/PCOUNT/WSOCK32.INC create mode 100644 toolchain/fasmw17332/INCLUDE/WIN32A.INC create mode 100644 toolchain/fasmw17332/INCLUDE/WIN32AX.INC create mode 100644 toolchain/fasmw17332/INCLUDE/WIN32AXP.INC create mode 100644 toolchain/fasmw17332/INCLUDE/WIN32W.INC create mode 100644 toolchain/fasmw17332/INCLUDE/WIN32WX.INC create mode 100644 toolchain/fasmw17332/INCLUDE/WIN32WXP.INC create mode 100644 toolchain/fasmw17332/INCLUDE/WIN64A.INC create mode 100644 toolchain/fasmw17332/INCLUDE/WIN64AX.INC create mode 100644 toolchain/fasmw17332/INCLUDE/WIN64AXP.INC create mode 100644 toolchain/fasmw17332/INCLUDE/WIN64W.INC create mode 100644 toolchain/fasmw17332/INCLUDE/WIN64WX.INC create mode 100644 toolchain/fasmw17332/INCLUDE/WIN64WXP.INC create mode 100644 toolchain/fasmw17332/LICENSE.TXT create mode 100644 toolchain/fasmw17332/SOURCE/ASSEMBLE.INC create mode 100644 toolchain/fasmw17332/SOURCE/AVX.INC create mode 100644 toolchain/fasmw17332/SOURCE/DOS/DPMI.INC create mode 100644 toolchain/fasmw17332/SOURCE/DOS/FASM.ASM create mode 100644 toolchain/fasmw17332/SOURCE/DOS/MODES.INC create mode 100644 toolchain/fasmw17332/SOURCE/DOS/SYSTEM.INC create mode 100644 toolchain/fasmw17332/SOURCE/ERRORS.INC create mode 100644 toolchain/fasmw17332/SOURCE/EXPRCALC.INC create mode 100644 toolchain/fasmw17332/SOURCE/EXPRPARS.INC create mode 100644 toolchain/fasmw17332/SOURCE/FORMATS.INC create mode 100644 toolchain/fasmw17332/SOURCE/IDE/BLOCKS.INC create mode 100644 toolchain/fasmw17332/SOURCE/IDE/EDIT.INC create mode 100644 toolchain/fasmw17332/SOURCE/IDE/FASMD/FASMD.ASM create mode 100644 toolchain/fasmw17332/SOURCE/IDE/FASMW/FASM.INC create mode 100644 toolchain/fasmw17332/SOURCE/IDE/FASMW/FASMW.ASM create mode 100644 toolchain/fasmw17332/SOURCE/IDE/FASMW/FEDIT.ASH create mode 100644 toolchain/fasmw17332/SOURCE/IDE/FASMW/FEDIT.INC create mode 100644 toolchain/fasmw17332/SOURCE/IDE/FASMW/RESOURCE/ASSIGN.BMP create mode 100644 toolchain/fasmw17332/SOURCE/IDE/FASMW/RESOURCE/FASMW.ICO create mode 100644 toolchain/fasmw17332/SOURCE/IDE/MEMORY.INC create mode 100644 toolchain/fasmw17332/SOURCE/IDE/NAVIGATE.INC create mode 100644 toolchain/fasmw17332/SOURCE/IDE/SEARCH.INC create mode 100644 toolchain/fasmw17332/SOURCE/IDE/UNDO.INC create mode 100644 toolchain/fasmw17332/SOURCE/IDE/VARIABLE.INC create mode 100644 toolchain/fasmw17332/SOURCE/IDE/VERSION.INC create mode 100644 toolchain/fasmw17332/SOURCE/LIBC/FASM.ASM create mode 100644 toolchain/fasmw17332/SOURCE/LIBC/SYSTEM.INC create mode 100644 toolchain/fasmw17332/SOURCE/LINUX/FASM.ASM create mode 100644 toolchain/fasmw17332/SOURCE/LINUX/SYSTEM.INC create mode 100644 toolchain/fasmw17332/SOURCE/LINUX/X64/FASM.ASM create mode 100644 toolchain/fasmw17332/SOURCE/LINUX/X64/MODES.INC create mode 100644 toolchain/fasmw17332/SOURCE/LINUX/X64/SYSTEM.INC create mode 100644 toolchain/fasmw17332/SOURCE/MESSAGES.INC create mode 100644 toolchain/fasmw17332/SOURCE/PARSER.INC create mode 100644 toolchain/fasmw17332/SOURCE/PREPROCE.INC create mode 100644 toolchain/fasmw17332/SOURCE/SYMBDUMP.INC create mode 100644 toolchain/fasmw17332/SOURCE/TABLES.INC create mode 100644 toolchain/fasmw17332/SOURCE/VARIABLE.INC create mode 100644 toolchain/fasmw17332/SOURCE/VERSION.INC create mode 100644 toolchain/fasmw17332/SOURCE/WIN32/FASM.ASM create mode 100644 toolchain/fasmw17332/SOURCE/WIN32/SYSTEM.INC create mode 100644 toolchain/fasmw17332/SOURCE/X86_64.INC create mode 100644 toolchain/fasmw17332/TOOLS/DOS/LISTING.ASM create mode 100644 toolchain/fasmw17332/TOOLS/DOS/LOADER.INC create mode 100644 toolchain/fasmw17332/TOOLS/DOS/PREPSRC.ASM create mode 100644 toolchain/fasmw17332/TOOLS/DOS/SYMBOLS.ASM create mode 100644 toolchain/fasmw17332/TOOLS/DOS/SYSTEM.INC create mode 100644 toolchain/fasmw17332/TOOLS/FAS.TXT create mode 100644 toolchain/fasmw17332/TOOLS/LIBC/CCALL.INC create mode 100644 toolchain/fasmw17332/TOOLS/LIBC/LISTING.ASM create mode 100644 toolchain/fasmw17332/TOOLS/LIBC/PREPSRC.ASM create mode 100644 toolchain/fasmw17332/TOOLS/LIBC/SYMBOLS.ASM create mode 100644 toolchain/fasmw17332/TOOLS/LIBC/SYSTEM.INC create mode 100644 toolchain/fasmw17332/TOOLS/LISTING.INC create mode 100644 toolchain/fasmw17332/TOOLS/PREPSRC.INC create mode 100644 toolchain/fasmw17332/TOOLS/README.TXT create mode 100644 toolchain/fasmw17332/TOOLS/SYMBOLS.INC create mode 100644 toolchain/fasmw17332/TOOLS/WIN32/LISTING.ASM create mode 100644 toolchain/fasmw17332/TOOLS/WIN32/PREPSRC.ASM create mode 100644 toolchain/fasmw17332/TOOLS/WIN32/SYMBOLS.ASM create mode 100644 toolchain/fasmw17332/TOOLS/WIN32/SYSTEM.INC create mode 100644 toolchain/fasmw17332/WHATSNEW.TXT 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 0000000000000000000000000000000000000000..ff039c57e9306ece5aaf3aed1049dca00ea1cc8c GIT binary patch literal 66250 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 N9LMrFnk1v({{exe@WucD literal 0 HcmV?d00001 diff --git a/toolchain/fasmg.kl0e/fasmg.exe b/toolchain/fasmg.kl0e/fasmg.exe new file mode 100644 index 0000000000000000000000000000000000000000..d012aa5d43efd5ea804219e6c549842e9867faff GIT binary patch literal 67072 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 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 0000000000000000000000000000000000000000..9a63a26a1dd36a00bc454c09f1d5b5794ef18939 GIT binary patch literal 74062 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 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 0000000000000000000000000000000000000000..96dea3a326655e142e4d39597a2517133876e7af GIT binary patch literal 58677 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ef8e482db843c70c29d6a4aab772cd313766f164 GIT binary patch literal 766 zcmcgoF%p6>5L_H*pu@^mN`IkGvXhSMNXM6W3Z~`_fQ+N6 z4lq1+z>({jtjH^wVb2H%z0VMubVR0wkz4eA&(#baCsb`ma@diDEsDDX&4O7o;*WIV zE0U|u_Y2T*E*eD>kUPy>lrEopuWu~c>nPnyYn0aeyeW8{Hs3$3UGBXEmgaOsSF_xu zUQL3QO`HGcyZ*5Y#Jm4pv=gW6wcncU{9w{)nRJ*j>H*0A#FFov$P3w!Iv~>*0ux|G literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ebcfecb7d2d550e441af161cb7540ad112ba2c7e GIT binary patch literal 117248 zcmeFadw3K@_CMS`mt-cHp#vlkB1pg>MlL1_N|;FuL?>W01hOVTBvDsKR@c={x{2!r zo6HPJXUwARy1I7}blD_m)(ax;Lc%}-cv%RFTvmvHYd0;|XfA-v`#IG!A-enheSd$v zf4$F}=V9u0>eQ)IRi{p!I@R2Q4+n))(}N!L9o*aFzG}^pPKP zMxW3(E)|Fx{{wFJAoTx#^#8*g=&*LQ&*Hufhr^pEwa(&Hi+ zxvC8%Conr#w;(pj+KgYbbt8+vjo&skPEA9_&DBV#Z2$}>{U~=fx8|R~El)U#Urr5R z70OPEht+4MB4gKF{QPb?eyFbSuC)`jbJatrzWEtK^w!0r%!qbs2(%>L2jC`8QNO3$fK-Q>>2iR#R*OVi~PkHub82`kRQ17G9f- zj1KEIfY4uub;m&L!-3cb)D8T3JFL5rc^^8Ni%xb}_oCp~zh`ku`<7#fHoH^B3-0lv zK#@_lR>A*QtS|j+GxFjn`MXGxz@`X(893ce!S6#h6+eN{m(6IAYzm9$!+qI|Bq87f zw89cVm$o8&Y~L)d>gSDUOYl!dO~RBG!8977{x7sE_=iP`?2#fKVWjf3MuK@*EOp-@ z7P}u6f8j0?CHH-T|0N>q7Qz24g;j$8?-Ujb{8R29F(|`40L)!djGU7y@y!vaBaQlDB7(5(1-3qL zbxku`Qo1H^XTo7Cmkdkh>i5cGPIH!0mq!djQXWU?_B9uR9Vv`61 zM%)VVPQn9Ps)tt2c=-#&>#z2%A%uFoH+ajCOGaY;U`&e!m=MKc>?GfS_RUjA<#OsK ztfg}GZTxP&kQ z)+kIrt3FQc-bC&CQK`&+NC=Shk+a#>DgI*fEGk<{O-?6X`PvhL*@QTwvl$qNVk>aE zU1C-vP*2O~)KAztMN4~ZYCa0$n}rQKy4T9P!usBpiH+-(wqy3@M)yRCZ#>$I3@X?J z*<%o+n$d_sO8-T~*ifEEtX$P7&4%&_Vl5`E_d+-vkwyzKkA!!fG~<*VQ{If_xc46h zBYKZv?d+KHH>61{QT$;lyAMO$+ntVdX6KYyG01tApu73)K=LI+GUxp(3FsKV-Pdnh zHbmLsQ)Bn2{Py>3$X0ex)YorXcAf8}DbjFn8#ZxH8k5PAEZgX@;iK;T_9jm7zk_mh zFIb{A5#+C_&Q4kuYbdsbVjC#-4#jp+tchYrDMn|BrQH;Jkz)2Y5MxU!gkcOfS@of5%i$@U(>|4(GJ=Z8~O z2O?SI8kR?EAnG!S_cjO{Fh=zmoT1a5|}j>S@T0Xz9}=9g_Y|yqmHgg}w>fh^caRc4!u7 z5w9>JRw3{qxF~Fz@HUkSHJg#jIwANsAgnj}Tg3#oEINE!9q!i3uY6lA`cdUl`r+D2 z3yQ8iy|GP2Pd`A8H8?vN8cLpv9a$<9UDkgAsM=v1Vdf~all6&8JMq*>{X&{1 zRl_X;A8jQat#q#?@i==lFxico%IwiSv+Wkq4kg&6%(m!>!P$u@cDk%=0CFu=CKSz1 z^sc5ujn_3hLA1#C+AbkBjKzAv3#|my8w2`@uQgZ6+iz%1lbqBErQl!u4kfQE=p>pa zIhk5maGdhg)x_JjE|Ze?jmn#7valN8xuz2<49z|0xfm?$^PRG#f9&hy#du$zNjl=o zyJ*u76bH*~*!m_}X||cIXYkvT7srdBxhWW9bg>Bl&{B3zGG9?_Nhz>3DZ873c?tOU zpB-(g&$BnydlDM!^WxI@#=0GiWl{cVnAJ+3PaU1EDlyt!)Zz219|e(v8*ftj(+^B4 z_(UoA+FYP21!v3!-zWurz7wOfPE?NUnVrH*-7Zt5C1}!h-*`^GEybiC4JMH`uYQ5E zt5EYYEuJLmPVlxwUt6xKv22B9v+2R~QG>JUhph0YtdQ7husD5>`W7oFCYn!xrakH_ zEMqo`Y%r}X4jDU13I6^;SoSh4 zG*tp8rP$yUQWI{?I#qQwQ`3Vk!{khoARSh{0=F;pV&U1VNAlnXS$3mRRm+ z|CUrtS?@+Z!`oyGw37V^h~8WbKs5mk0H4BUz-m&<)(}PP+_Z)kCJuEpFl%TcuF0jJ zyYchNEHt}@#wj?x6~6)Ocf~wp@`fRSoq~T3qMioJkfL`?>P#p-<&lOTw?)rR4ZS!r z)7jSnP@F-(s@wKH_3blgfm!m!iQ;_u;&}1)_Sh8f8!NXpva-yb&5bDU>hC?Uq968N zPN;nnXp{@-AJi3Gnpf`)uiQo`-$M~l{@U#l{AB=e-z8q#s0UicH@=} zj4tV1^NcR>WZ^tx$S!K-7%XfHjIeQ3GZjZ^3V~@T!j_aqr5~)k%iC1gj1w`Pl=U8h z>h1v)Y!y0%69xY<3Q_A2!a-ddS=U8f5d4K`=@Kva-$!|~t|R*ruN}dbXpF?9$8E~v z4sAU$jM=7~Q=dOevt}tO7~E7JM?d9k8VODmR^LTqLnER!0b~;m)qAOc2oAG%cAXce z2TeFyUbjHm%OWw#US+HPjbc^_W^okF!9i&50~#fp20zqL9iCs(VRZl}{b>t^z)Uus zHmwqNzK}o~4i-3RJcQVyU=kJG)^18k-zC(L98&gWoflTVL@`#TUI94uM*J+!+^KZW zQnHD1NEKyAlX50~e-os6@dEVw4)(kZ6lv^3Oh7yOT4gdvDN)mEaQnM_+xAyTMSvt*p${~1dz#cy(vO8A@|*7wD&!wo(WR#sC$~EmB|IXy7pAqg@t) z;P;XK;S5g1yc7J}z%czxd)@`;_=pm+qX-GvK}rKzCxt+^i$XNMl|nSWi9#^*O$x!? zMhejwjrt(g4@~?Gn9|hbe3TDN{5)hD1~j|ai=LN&0}H^7vEas4z!vxsK_g=bGKQfr z(VZfl)~^FwMSGzhLq&XH*pjC8Lz6^G@Ye$+(fb@iRIs4JR}gfIAVRmz;+Q;X{;cun zg;1$-PWedvH~3nynTmuBbjVFrw0z|PAF984=ETb3)p0Z0q?qp4D(#|EIpXUu>7OY3 z6sTv33TIzFuFBOEUY~O~%wc zBh8X?Ql#m^h7!KvMcA&gix7IY6~{QAs&ovU>hit`^}Y!rCX|L6X*wz zDk@{zXJ2xKyE0CyZ=$?%czfO@*Pu0Dj;<=xNd)j8H@jyFe$|+Efn|VhcAKS%5vpSt zwI1FGs0#_%_y1f1(KmqT7V|rNU7JdGJwlBOzYD+|!m3P9z^`u#{hI0v!`M2mB{~)b zIt70wwyEH44quzOVYHz1PjV6zq*B8Z;qSWFUJPbaI#_7~4DTdtJ|?Wp>M@)~TV^&I z@*{&B<4 zE`g*M(dnw;4dM`9&Y39$)_`*!jSM$LWe{T>T+E0#koAE$R(7RGDZ++4zTqyj2^mSU zYo=t+qu;JP{c}|Sar&)j_H6KR2Y!6Fo8T@r^?;&h@r&`7x9Nx|sgZI0lRX_oYV zqL1BcE6P1uI@%1fVO3>}aQULpouwtpM{Qq@s8iF-!iJr0lXRopZ&{Y<-B?lKb;U^6 zcwMlEN#ij2e46FXE%7B7dOG+lsfz zm^2^VGG=T($QFFGi7ZmvuyhB=Q9(}I7bEN+u}&BpAa!CP$l7jnVy<+O5p`wT$t!(8 zdz0^R3nwK6XWGN!B;V7BPf*V5XO!K+BvOEUClXvtOA~7LpQ8PX9al`s@bU_!(h`aS z*`h#i4FE+BSd4kfaIkN#v?mHafYUz!-hq7%jE&&+ZM9-h7QAEDhhoB(sJ{oZjfL`# zsoitQg%zTbzEGz0&rLs|EVe1PIkX-o{jkE%pN1H$Yr}+nA27lOPnd6Sm={hzt5h<; zj{x`%ubVPXLU9%X9~j^&-88IbJMnCXQ3>!&qNJU1@J#7r#cN2}$UMpPq#B@dKOy+X zVX;CfN)c1sWkO&Ky5;*QEcg=Qu;&j|SWV)}#b%J}cxYK>L7~@_d znR`ENwx1LNT_=sbXJQ0(JNTk~fK1sr8`3Sz^nQ=NUCwb!cfW^rIS(Uc9Y8>UfHS~w zcMdiQxAfI4{kYMp{x3Qae0KCxfQt8^)g^K^VS`+Hl-1=b0`J}Od8{5PtMLX{-@N%0`Soso7vrgnA~;#6W{RNaHQ3I+wP1Txu4;@L!O zx(}z7yMgmQ+GVo|<|*kb#%p;30i9WA69VOs5ONMk91Q>x6v{a!7M>oeT$o3)O8Jb= z_sp>En$Eua7b!COyH3nDtmAk`SFT_8&|cWqKkej+{-15=0lVb`-dn1U5Km zM~@uWz9Mpu7An(|0o_cKYa1pe_!MZ@K}-TDQ=x%!?bc~PRHLp$T;I*8eiZ;1tgC@> z446FBoh^L@3wDb51#&+3=m#TBbW#%^g)&a+F|-ceG0kU_bSpZGb)&Z6Y**)M01t2_rP}I2_4W43RuU96qE8T4Q(3QvZG(PF_liTgXmX1j8s`Xj4PYM zF#oasY5fpS{S>OC=22s+lD!+frETOjw1xWHC>P92YgvX8Jn*a);Y0PRemJ;f%& zX|@uSOCjtWE~XRAqT%+3)H7!zmG!hN@qoRb4oDKVEcaT@w6#SRJ}ZisV@j>!g*s=-}doniJq8l!;Q$T=5Kq zfxM9p*_?FTcgn19lXJ$4)8(AIrA;36$z(P;*hPPDev}g8C~c@P+7+ayGq9xy@GF?R(tDNhzzTDh};Kahojo zKfnsrhS&z~=^#NphURc_FFf-(9i9FUBX{`- zv4(g^GJhU~SOMuByKSO+#9DMQSD9^tjv$R%pgx6Gl&$6@swv2oXlgMl zoGisNdA$J$^nVokve_&UV}a-*Nd3>gmX$9izW6_Z743T)_Yz1{Q zOPxaCJw(bYLRg_fz>GL_E51RDF*O@J<*PHH5)Fq+Bt%pqA@Hx`=vj8=$*9Vc0P~Za zgUJ~}fk(f}jp#;14Gd;+m@)ekF&H%a9SAd92an4dT2RJfVgs>;4nL9Ff`1h;y4y&a z#Ef7PZN2rTqIMH!ECgdhcvQMirNv^-)Bmj;URW2S(Mpe$(pVbc#(KE|6I)sAz&S`v zlwIS+*o~MvoGt|OcwehkkEOGbuNAitHlC&}R+8%p=`H23HVru00DpQ65#?K^%3i^Y zp{XdMUD6IdE{H7B2Q74-z>V2#3#`@4&MBv8w|cSrwHL+D_2Y|;UN0C#BrOf~DIA}b zy^Cq9oo!R{97=(Wp^0-nXpz1RJJO^N7aExOkC_toC+MSc4s@cML6!C_QcAZPz`&>- z#J=dQc>8 zeWFUh7{x%hUX;5zxcHkWRIu`*ex>h(19mn4SRfx%M4(@yTt)x5%0ob{w-~6zRHh3h zKrmZ;?R+Tc;eG9F94KPq+u^SgfgD+XHM%nyGcpA?|JkBVrE4bfi%_0Q3X!9o1{+J}+2I)@U0tWbBMMD4;cO+P|5W?7j| zcvlnX8p5qO2{*O}YBY<QMA64B?3H~Dp3k@mMke?7$+#c^TL^dRT0@*=f zOlo4doAh+VeXR+(@?&9_I26ArQg@NCfy?DBX$y6gpbf|-qu;5;KQxUt)N+`H(WV46 z)l8I32PL#=P9e%t#8le3MQ>0*s_B`nS&Sdz?dsoBClaRA`(JYsfZAt#MC?ibzQC~mzl(qLj%M=)!QeccO zRdx(^mx8BMJh@DfyOgzOuO$O|@DIGC4wTV7L|tAuR8bB)ZGDWVQO=nvjSb$FmS8_5 zj&$?lnA&cVY}`ED1kfOMucZvQ$Y|sfeCokp~i~nDl1tOeA^tWth78$**D$mCOh<5l_-U-k#jer?-xSoY z+t!le#aW}}=EjoE;{Yyfa8fOtK9s&mP`75=fP5om2^(yeEH>F~n^`$YifOmlX6aWU zRaQBMrS8#_kb0t0KuN~YPcIQXMR6j;B7&bIGnJDWm4yFaz@T~52R}_-Ed!*ek7C*g zH9e3|9jwnta(Z4=Z|Pz-HKAtTKsma}=~qR|Th$C!e*?k z#M^w?#5zu#^<)y8-;ot?y&;+OVJve_Hd>IyF$`(Y5NtG1hBn9qTR+?t=c}oJtGpsO zTanIEA!tA-f;O?*-bZu(s|l+1o`Rk zU7{Vo*NNtN`q!ias<*@Zxmek!n)gBK%?(cZ1SBcF$|-0F;#GH+s!LI>01&`7b!-H9 z-={FMR$Za*Q+i?iELCG8`J0h1)N~%inslcb4VN2sy26W*jf@$C1hoOW-VYaw7K5`s zyOn2GwU@7Nu?1a2V>g+8GUz9ler(tn*EsMKxejNSdkWM4qx%D6zVGw_NQ~tP(3i=L z3Nc6#a-(Vy8kI9mVJqRlrF*;e7DS*6-%0_~ZcTtHg(^W(N_G#KDbB`kws^Pt5sprR z?-`n8?jb4C@RIp3WHB&xC5oyRFDh4`qR3AxV1o8$9#VHf&(IE_LWNokJAk~LpDD(- z$C~n+JXp4RO?#{*zX?rg66R2ax)+t(W6k+ZDD+VMdaD0h)L*o?qNo_gFQQ4c0Tn}1 zUbe8Yw4!cn3*YEf_IsP^b~k!gT$qomqu-zoqI+$y=o``3aM2|j(K!ymPyWdO*a=vA z`hw`3BpibgRg=)DK9RJB@pMO0iIFYruv&;e_+x(lx(%#T|BMrcYx=)1d4!r@Kydi7 zX>>TzvCxp0S~04kE4~iF_thDNIamGgZfU`O^qdVJdeGLDP!zTjl1Mk!8dMVP;&23eZK4CgYj)A9WdlA! zw%~6fFxOpaxOsXR(Xf*!S-9AsB`^#*>%cj(U93wG0w$_@+NPaH&r6v~g|604OH+E) zXR*VUyE9lYLTF_s_Efjwd z`2$p1S!bS1Ghv(qePADr)C08LoI|3NapWqTM1`88NLNIt--mdQCCwsD`yP9k2Un>& zelTI3iJ+b|Dmtb#YAMwCX$#S%KP7CMoW=_^D5_6+E|mACS=pO zl?@bIOwLj@fFo5!RUFJ$Q|J~-|D4e%<|4q@WFf%VT#sOmLo7x>lk{`2gF5;LZ0K>= z&||Qn$LS}HU0(l^OkiCBe;z6Apn8PeA;BbXjRFa=@SC5H{wwM3A3SqRV&;f2ckhUA!H75thJCDHP#5#0^Z zd(w!uT@No3BiaB0t(a}Vu;~WD|9d0)9RNlc(L>jZ2`F5iDcTVn&lOF2tn4Hq9sa(6 zAMyzu03e{I0W)+K|60f`cQ$+?ASB#R3jSYH8Wyr=C|oZ1{S@X1{-spz7W_Y_FkSFJ zh)j8c#I<3J0X0=o1JjC5ZH{=T5ThKE8GFWe;mDUbUy<_AaJ->z(oTkZW+&ph%GgO zpR`!FBKQ|l*oW6pfYW{fAZX^G^Dh|W$XYl_lqIN}D6rEOrjZB2_xBf#M^?)MsQt(le7Dfp0TLE+>2_F28t#g* z7SAs!WqSC+#f!?a4hsPV_>>N1-yl-Hckx0!AlGyn@hP~-!-&HKc#X8=2eLM}n>0~R z%X5ukrYUGekQa@5F3ie8fIQGWE$1{dLMWo}v+JkLEhh(d04mp!^0aho$5?n)?@${c zQniyvX0)zk3R;o+II~!lP@|5=8ZbD!mtOhJ8E3Jg&G@y%EG#lvfUSCrCnF zmwfz;d@)0^;>@d?eW$FYTmC`(Zvt!u$&R5g=vW?Y)a(d}Kcm44eMC!GA9jgpmU`SJ zCrJt2)bf0zFPkY-f`1ZDIAJFxeA{fgI*>mc`EpLWw9hESiS`5rGg2(ZU#{{s24ku? zUZp3EzP^OYc$~3q13qvxjV@WrIsq1`WDU-QI{d% zSR%O#eUPP*n~*3}T9qTP36PV}l8n|+gLth8vHI8$>~G`6lk&}crCM#Bna_)MVS@lK z4|oTA>hnz@xNxY8fmqSx{`l%LS>r29gm*_b><7nIgy>gzH?iR$LY%(b%I-aC!&4^V zjgAJlnRzcMTK8+!Qz|EVgR$=9N~e3QI7H5-f#<{_<@~9>P(>l@C$ttMN8uMTmZ>^)(3fYYDa`0z0(&7J|K*U|%RF zSo$T{7ZHNe2?nL+A5uD^G67W8$9jVmd|xO^(#IglY>*VfBRp_l@QwQ?4QsCWGzLuw zbYom_Aef516ER;ljTtBS|AhqJQEsGD;%QU*KgscmipYMD{!bTk;f2ZRBPbai&;sDd zrCfkDU=g=NsA>I}%qbPc5L7#0gHaBvD=@*z%UlbSC3{2hCF22N2oHCp$Lc-2aXaYF z73aF|6(_kX#ffgORDm_Hn$BDHRw?oFCA*r4b-~VInTJBF=}-nZnE6clX|*4{W9Kye z*r3W*^^0hJhm{c0pWY_tOc3vpbJA$--z+_feNcMHV@y(Czge7Ky@YNtmksk^`lg8~ z_?;l8K#b|PX10cy?LD-SmS~7}K>R|^av|@E<@|&R(s;O;Y{UxWsEgH!9vQ}}51S+1 z6vYmp`5&Bgl%gZluVmVe`My17_wans9lkEJ*jBOPmbs9FOs>&fv!FY(OZSvQPY+bl2Nfp zVu#pk>=^wJEl6!QG!xxOz00<(|DdgTSA;gDoBwz<^))y{nW-eG*!np zXl)tSs9V)Lfuz)+er^Oj)y0sANp&Il*qM5Fn*7z785gQ!%Ie1E>&J@p)sb?`!bbg@ zC83t7jjNwTqfM)2_UotLC837=RKu~?$Lt31#xJYmDjO@|a; zWhG`byVFHWA$l8HO-H5xwvZZhn%$D#3bvP)c-P|=dnWGX*+pJu2KJ%JbzQArTjYxt zc$Oc(Bww_NbLESUs$1lXG2+d**LJxlh&RET=LYvg@w#$jgze`UyQO4ikUW77kswij z0=9y+C#~h2NhkWbMP9+vsHhgR4wfJ|nIp0z_4v{hZ?#fY0z6Fj6cz{0@5Ad($V|}F- zuF~w$|B`jMdU!KNV}!dx9ES2CD38-Mc$Kk-d<%`{3k&;08HZeq6rm;!ga8|AO+&2= zFo>_-m)Ti&pisV$D~`MrlKWGuV)k~~WAzVZEftY`i@p^rYBSL4?-lABNbIe>jBqcy zZy;O(gp1r@S={7Qw;g>F}@Rge37r#zm32tPK1ZW6v^Qs z6>JZ?2Anll`n~PAxUIb1dLt<}bXDObTIA`J=JiuVP-f>Al4Ht9rPQL7I#dgGy>{zO zRG}U|<5R^l_pK2>=KGBYoNf<{_LxI%uiz)=CR3Vi{2+-H6BGrUyfF!#@q8_WmE!^xp*3adD9H$RDn5b&=tNZTx|(g+rrh3=E)f(ly;&r{BWtiYCRxWjaB)MRr$76 z`Ic3&i{?u8`a`mlAP}ts1+}fF$sS^KBJ5BlB^Kr%af&!QL@&yrMfP|Bf% z;>X5USm0KGW_vJPQVIz%$SgnzYh!u76;R=MHog@ zE56^e%Zwt#K{M#jvru31Y)ZZ@2p5KYM`*s%HVK{##g=2kf|G>iha4bkI1g^**^Zu4 ziY<#m@KAZg5`SI%BMxy4>+1-kr;nhgDzC)ud4PJV9}jipGtxsDt*^K+fTb#XS^{Sz z^0=%Y;gQcj303s`)#4=i{PUv4)+s%@xG)66?QJmN-dGBgI`b1ML+W~WrnJ2=qg8K3 zA`2iRSut%vWk?NoXGpJ6@oHRzsIMbee^EJt^mFPsBr21U-IA&M)Zvthqf~}g39(qA zTxto^xq7*TO`{JR<8#s!&q^!NTcpBAgqZ-7-2(gqpA=7Fhd<$dUa~D@9qJ1$?8lcW z5&%noRL&;E&q+2t6lV3*jnhHvcI7)p!CJi! zUNkw+Njc4pch)Bn>;jeUj~Cam#1eN{yi(42Ucxt3B-7fEr=c{Qexi3PCLJf5rt#z< zak>SMCOefRYLQWt2P!7GpBK|X6;n~*IzPmH1~#)^yld&fyU26u^+d%UgCzZIlw37R z?h&k#Vf7|dN<*c^ZkQ2%k0zC~@OL^ZK7&UGR^WCpil#2OvCK&Rz()*?d7toSNenASgyZVN|@3QHp7Q|5xHzm zrZZ2D=m7GnIcgp%=qKPW*PpdVx<)zN{hD$~0%Icp6V>qqaM}ZCDW$wZqYDpuwlZ0K zi?U*obv?2WG+=OWUA6;q)4PTqJg?b^D0=|D<_uy?MQ5)cFJG@2uOpYDG{}th#?yCT z`2$sbnSO4epS$R%h<@ItpH}+0oqiHAw6D17haR}Uax?wp;-}r3gWm-80dQFT3x2Bl zSz9hEH6|wb)MOllj8}d)v_fJ0JPY56qC-T~vxAh9o?M$vyv7@JQg^(rIm4tYkj0Bh z-br&3ytJvt%Xix@$xfmmjG_cw7#PsVKaGr3X~;l5o0z0K7|IyR!-g?XFISv_3R_TU zkzjFP?I9tv+6mECS#3BzpmxGQZC`7uHU}dhXA=>e=ReeQvU%vST=??6dXgt5jZ3c zqo?9RU>!=}0g#uhc^4Cawj-}E4S`ReoOMB1sr?;btXN?PaLRNkkhc)F zc?n8hqVfbGQ1Vhks|m*x4g;3eA=Lg2^_tzV)qA0D2sMAiuiGrt(6yrA-wz-+_L+Z^ zUN68&eK;Pq;YKVGG&O7IAAoM~3QYoSE~>3(%#bJK5sxAtUl8-6JexT{J8%;1iH!Eq zMEjJ>w40SDEUSqDApB)QU6+S@B|-3;(1JD#gRmY(W}#*yC=mP|#G6p_D^mfef<{i? ztMt)h`rs78ku&L5F6W9nEjcN7*dDj46RzgCI_C_)=Jebe$4k@X0y|%8t}V9IKV;v1 zQvQf@ix`ITX z*k11>Vse6aCgubmPI#GGyFSmJX0mO|$g|HZh^s4zV>MawrcuSk!h> zjCU0$D#eK`8C@2&1qs0<_SB_#wESb+cRhJnAz5Bm0j`{OfqBBFDqCD-s&|%m60(RO zF$FL-F)@n4RWMA7E{2d?02jvf9>&N=sJeeSev4%1C{W9*tHGzTjGczVKi)D4{@YOe z-#h;D^#6+vW_G%Y9ZK;)7l#Iu)`GMDOGjBJz0^r*B;qExqP-6?3TzgTazWciGnDoF z#zFlyu8#qZYq7ThL0rH)Ps9dsLI{xB7ZD9w1H}t$X3dX?F}oI{A;JF>{9YCmyf~7C zg5Y0-?4De^Wq_aFV3Ezc;^=pmyeoEDEnWpFWlnU!im+(ed`^}N;!Ik`cQEfxNCwmJ z-H_1~FcBfVdu6@H1fv!|IxW;=r6qJp2&{h(SA8*9cs9D*{%%t^+!w+Lve|u&5U52N zSr`2rvQ-h1px#LjGqDZ?D(LusQid8pVfMz*FJ%Piw`a0quieFe)fN4tu znQk6cY)LMl#nLw(8Z8?pOh)5FBD_#bCU_US-WLM2O&JbNf!h!jHcg?810SwIqS=kB z_2V0(t2GYv;Bh*BJxZwEN-G4X3OJ(|x`#>$Fn|md0viBbH-U=e99fK0Z@37Fcoq`T z!}|Loii_v7(WhR=q5JA_^x75{Uf8};^U`a=gq26U%IAy9utY8xv$tnExbY0J>c21B zq;(+KSh6ZzWN0!PWW-M#ApQw}?^skzy06KYoiM~>^((bZ{vp@`49w8prkU&S2Ll_c60*U)~c z*Q-h@ed^GdXC}e-j}62Rbnj(E7)7Iqq2~YpRpxPD-aoD!2`}52f%mN$-G5m#{Jsr3%aIUQ1sYsPO1x)fA9C0BJXh z8=1YlX--o`3D*#3a#MlK{&2lhevUD zLCc>i9aS#qhcgf92Lt%t9&C+M;Y)pl{~*sb#;9{M>d>RwWy$Fu8(;ikrgBw&gIF0Y zElCa*j#h&#ZxU*#8xSqmNB|k~4|#_C1CP`O@B|M$#GlapAP*}nDYAp!4;X%oJeI@{ z48MPW3nM2xN#OG8uX-aMixCfAyWwWz-i7St+{HX1V1g~;nenh}C!9Gmst7TI>s}IhN*)+%04d|^(UqB!kFXyb3GQ7U! zJm%c(ATC&lcm1(ENtRUFn2Oom2|iikhk<$$0FHKh$`;l$ZK-#6Z)eXQUn>ubhP;R4 z`;1UAL;I;Ku&siA`B37^)DL>Xe?a9EL+;a)U1R9xL#WAn6BC+cLeHf# z*BHA0663utvuO2&lJ!$?wPc?z^>&yyTZ2xvcNRF5Cu~6{(|`&r-{071MGJw)fLMlX z6aqg(%ws4wEB}Iy3=)a7)BlG^d}34l6(lq9m8nPnLnaoEBAEylTf}1d$8i^wgK7n4 zpuz+UY~;zo+eQaxr>3{_ZR}MeEnmU61d9kC2I)(mot$p+Ew*s-VjEYtqfIk)zgpKO ze}T7X<=Tioy6B}-7v$*IPz(MC;i&CKnffu4Gu`N0u{s6aD1-fko!f#>*l^}OFv&^W zL<DggGx29WvobaY3A=q;&oQrHx64j@*kwfmxY@ zuSnU_cd%n*!;`i!;A``eC*`F!h&K9))|u~^<3Qm&_Y%E!00WV9zhqT!HA$&}Woo&_K;G_0?APH94 zv|k}KULySp)nO11{FX4%y`ol)GPMh9+M5mE%D^vBaJfql5g0vW0okwFzejDtAZm-% zF{#WU=vt$dDUnugpz607qnKdOHG}9fqs=nyJ1p6OF7gDr2fGFQvB5rA(AX)<=p`Ji zP>i1FFR1j+&6^GX$-u{eyG&{;QtEFY9_zLmM65#wb@g?Guz_8vl0{djsYR>MHF+tW zu2|>C(We(I`bKq&=6Jdt7(CiRzC&r6KgjD=Pq)G8pim@qqFU8XEQ#q0lJ0tu9 zX%_t}R)C`cmc>ukgZ1k@-t5hA*V_u-uqo`{PUA>3#7|Gd7zh0H)mU%#@m!p(V1v@G zM@>U6Gh3dGxWDpsC@@S)!;K1YZ_vy-eG}_SHtRH#+y@N-7M-H%{b*Ue9poB5!UkUb z?PB#+5K^Ymmj;TpZ}A)bgx%H6Bp%-?c-_V<(LsJ!co(KY*YBdN@M?-nXw>yc9V=h9BO%+7BaPGq3UC)kV;=d5^Btmrbkh?UIPYv z&=5@+$BEYNcM$aNte1ke_0L?_GSoVD?KBeNY7VP4CsJz+)zbeOC4CV20_qYk0)NKr z_F(PewnFf)Kq44J-+*j_oUnPV;hP2dCba6!4nHk4OraQd$)|7kDsA501F&@X`f~+e z63g#TtsWAL36@xty?ajx>-Xa;(mpK}H`*S{UbQO5(AbpxKBe@cH?y^OE83DplQ*}% zJl@-OOz_(AlEByQ#8(fSn(95s>k^C%brx{sKq6p(KL5-}X_ zCjoh}`Yy1SDO=MM(}bF?|npmWq z=l?0x?EK4spsD=_;;IK_Ld_7ss%40>r9GFHw)W&HI?b^iA(+vVi%&ROgSj^Se|u}w zHQIP<^WrP)txXcWwOLStH#GDRCyc^@hc+7`kPicLan+UbOiqfvwfTLdXaS0Z8ZQV{ zddm%q&kIN}<}jLnKMV-llwJIJq2}ak=o|Yut5Ev|;-!&;x@h75sSEIA!WT9gnYPx{ z-Ly~*Krm}Bo@CP;>RA-+yTp}SB53y}2>mYyp|2T?-rC@vr@z7QoA7oGE|*Nt z`x-Ee(EADFIVhDxC}F$>B^0_566R?Lql90B_yFOy2KOp$0Y)RUwYy29VPTk`2Mog; zPncg~nD=}k)O`Ia@I~6_qBwBxM;OKZA>vWog1-RhK)FVrf?#M}QM7L(qRtvX`vR&N zga;8L!hHw{`4b4E$R9!chsalHFGP_aMlqwgl#m~XxbtofC5nyNg+z9Q|Ujqu2U2_8;h!oHQ~gxC9U4QG*8Gm6xzAL3<3b zZ2Hd)gxZG@oinaY@ZXANdJphzvy4f(aP8%;+>Us(E8-OXpISA9=D^{{fr^*)uMR8O zg_gi@rFEac7m1(6-}ff4HWQV}EQ;?np>5Ja9SF70i4VS(}~IjpPuMGBl!PlL;hKO zZ4s|}+`IA60cKiv7nC>(zrbfgDD(;b>j38s7Tdh>r8as2kYGms3c=rwu>Qx6xCb0C zk1atr+|LUBTnobI@aV~kO7>2CF$CRkzYMP_WVl-de{2lGzk!<+zKPyY*oul2wh8_n z2sP?ENR_i0pTs!aFU8_ApYHJS@m4s%H?eKn_ke}-Jz#^kszYnTRLyMlu5ZHT)1-I3 zO1}qReO2Gro^R*8z6Ts!b6vizJwJ{IviyXmCaUxds{{uDU{>-I4SReu_$T-efP}#( z^!ft(ZcYAz?>RvBOS&$=SKR^W#T*sq7AkIpucvd71kK7LEaX~ZHXaW@Q;8r0ARH!#%fa>$&>&TnIp~T|bmkDiZ z0@wAZJ>$4n$v4$Kz~jh?UZ6|(Rx{1fw=ipatn7vb$_)}LnZ=QcUP5XnO9_E5R%0sH zB4afvfP*wd37(`hQ>80blX*uUHK^bM zv4_dpABUMvTX;_J)`X^<`aA4iML--qu)xPr>xGuiZsmfx$@(Vt1eeT_G+zHgky`QR zaG0u7#s|oNn!bv@h5aeMg)M&J>obdOzCNrI66C%m*T7XT?Fix7BS!hEkAF_hUyemWPLnWoVwIKHr&;=LAoBFvhfA{Nzbn zq8zTD7grA-7_yPn&x^0mx2sqeT)B1-#b_jdhQ}r)aD{P#T>Wx5EZx-Zv2mdp9y?{m z3-Y~`IlkRvCx3l>F(iUm;UMa-0`*ClVR0G9BlHhd zSAaG>u4n)EdXP>%7{z*!j2;Y$a7wbOlcHUj`hV_>GmTW-PAQ*z7|V}w8p za-i_`P9)K`1_`At7}NUzT&;w_uaV^2gqmjvCZ=~Hk1zbn1VR+q4v9&FS}=%|O!(hn z%AJd;!^QCWwP9@j^d}+@)LyBQ`&iG<;_8liUz+iW5cnlZ>OA!2G&4q%b>T{N5`&44 z!aT@e;td#kxz+@`=;CtqC5UqE&xqqa!Amdw)>R78ax*|(u|nV`gdyUo`VIs-qvbY6 zz*rT2|7^!g1W3In&ihi&&9>u0;IFKaI7Y!(6&f)EI{iliijM;M8Blz=b`6@vgjP#| zow1^BxwBjwhFr$>`gzWA=5fWA)B>mW9juhmOuN}$Y_TCz9h8}A&MdZMAagG=+w+}V z@5tU#OT=le@_HI>NrHb@(9Ark#|fJYoV5ZDG2-azL?0YnrwFf(6kgrBw~N`6^&8|T zP$P@LvUW(BS-Yeu*d5Gd`};XsfMe$Xe4fR373Uf$IfTu5PVmiN1OWAB+O0hQg_tUH zc%Fsm!54bLpvyGf5F~o4CYK1CtDHpAP+|RUVf{HqP`P#P=Msh>M|5k)yFSaIGo$7|P%{>|{t+u~=iy9>-MQ3KXEZ(o7-URktgi|z zw@tsNBwKD3SZ+;7_Eb1B@kQ*6owc#GrIwZRoawQnN-fFrNDiKY{y=n`gLN{}(Z^8b zW%34cLzeqMI4ME&wOP211j9ybG+C|fXxf%MFK^p5dmz&3%%HQEXDzai& zOlWs5YSxuHs5@5yc}8asJTWCz*CQSKGk_yHun>42iOX1_{t~8`4W`T3MbiejX2yf{ zug<7;NG}KT6XY4P^pgJj%tOALIVqXV`C*acnBXr52CV~JVWKkif0C0o0nF=zh{Qw? z$No>Ea44W4M_CieK>;$5Ig8>-F9u$sG358Dmlqq^)t2CuN{r8I;gmhS6SMYI3zf-P zp(=ZL$fVdSN-b3<(?g^7D7eBc(B#NF2yqd8JLx6dmy)GQNe+3S1K13$@n!m&8L8i&0F-848TOTRy%^pHfrI98 z)VlHt0KD{naFCINdG_yVJK+$TcQ~q&jlD_ObTqNbvEnFJH0RCRb7Iea?}|{^j0ef# zSfSx{5a9J);GVu?#V-2qOmXcNHNs36YM*7L{i&4>GP@AJ_o_NPewi)Ciw~GrjW8M^ z%S!?$+M><09ZR$ylx%cJyB#=Sj%hnK)_#yJS;HP+or};4fE!D zg-u;?RdzfRHhc5DdsMG4B!I@TLIW42cCy#W!4GAC)_9@z_>1UC<{>ZaLPLP#ulSE@ zVj?Koj>W+eB>39^a@jJZ;PZ5({W0@Ugq(*MFFlq$U2UqpDj^q?jI6Rxzz2wkcSOn4 z#5hi9kf=Fg+!Q)X4dz?2P`l8e1*8bMf2CqEHiDz=*hr$}CW8`U%Kkxgkogk-N0m@J z66MNy(g&5#aNGXbpt%9>5}F-+^cMdL%m^rFR74l|jZQN?M@;43-fT>1cX)`(I%;MOqWKf&lqF+z$dN(y_XZK|}g+sz-4qTquz zAf*PR;I0W&AMy5Tciob=Uh#}SVMWp1E{j6t$*xH=E{RN=T!G{ zJ8|eTK6Ol))JWoG%rQ~Sr`URezBnF*muoud|Ai!TRM#a`HvW@H!MB$Z2Dfcd1nYr- z)%#(=i!hHyL~PLu&=U+V7(+X^s&4@m+soouW%~ca2ADhOW#VPa03HY${u*4fTK5vz z0pnrcudyeQ4+p+H^_1HrKJ2#Olf^OkG`~%pMJ9pI0PqS;4yLyoWU7}=4-ob)$|1nl ztcAeAA>b8q)B%OeQXNuW zUl$>K28yGEyE*Zpr%gTk!H7h+RZOV1uj3_aYZtzGr@BFAOK$xHqR__ZY*j5dY|MoF z^NrqYn?;QCW?O7R;2yMMxZOa<_};V=2OTonap=lCl)2OJLxYn-{S?A%47JAdn%6>d{qo%{61AB*UMwbxS18`fH+adTmXu8J;{w)+j$$OU& zF`DJ$@Qfqi?&o39z&?PPz|1huQfL>i!$TdRb{`7mY{p z6fKC`4#Dq=pu;bTqvi0g;YT;9uAly=EMwM0m)!0PkxyoJAQFO@iI>mA$<7wWaiAka z=oV2Ep}IZ#S$KXJUWa)4dYjyD6>pXM?XbM{!%+@<3nyQ=Rl3?g|JT1fteP<$IlT* zSW80S5DK+9D4|zPx5yW6ff4Y6Uz`{vWjqlUZ_r~F6ZGfh@U2oqls^B;Bf5+nyk!ap z#B_Pb|cLpky{UT=&TrG&t*z!yI`1m<{MOK{F- zUNaOG0tWz%+&hM$|A^L)p;eM&h81Ku9E680v8DI<4s!A#u5Jul_+!YQCFrCzr8r3> z^n`dk0KE_+UY}F{lzqkp_GuxL1zXEEI5T^r!hHKi$g;m92c)BQkNpP%(h?u5@|8MNL@(j)cyLWMe4?n zNFtwJg>NP3?E{j5nU|W?YhY0&g?{_KCrUpMZxt|n;Gm6fQ-TtD6k_#E z3+p{aFt5U5_yEp_Zm?WIEABd+udtcA>+$G}LIo3x!VG+vk>D}~|Me6?6h91jbty)@ zKAU)1v>^QdQ1&L^Q59L^cRJ~iP6%{>u*woJK@h>9pezZ71OY)2L=nMVY!?(Ybc?$! zohE4_<2tUR0y-l?t5H#LorFLFiVnDa}z1Lr{L4Nyk!c%^^&gD&h$1WWKrC#dkCEU8fZN$0U zYLrh6kzL(G_;D+bFO)knJ3m-Zw?1cqrT<8mOZk-4Q= zQMPLmD6rqHDOk>Ci#2hsP|DD>lTHuIEroJd;km)Inq!yOn?;z!+v`K{4)c_l*?XGU zZ<>ZQVevDspp74?F9t7f7aqp_@!?^|a$aZHppc3+E*h6<4k7s?AH;Bl;#`V)ia)v> zcQVr!sln^YPr`On=o6jEb3hj`^ZW@_iYIu4^OZHXi}PxxZ|=#f2F<$aD!Xjept(2B zwTo5_x-@WwJ#^Kei?5jDzN|U7@2WwUTywSEYt^7@F22(4!VeOi$3N%te5IWZ*$tOg zW<1aKkmq6tS44gRs&`%Ly*8Pjj%XE33m=;|c3ha51KZBwW&*+DM{&awT z;j_9}cKhi!HO9sCw|S}F9bBK9{Jv#kQ*n%2gS<_0wTP@E_!qoVC97Yv_^#H^qeXts z8>ydIEYH^0JnZ@>5ZkKO=w?=g-oz%hiMz{$ZQT@7GxTLHaj#izcv3OMAE|e+gj!YW z-KZvm2k4^%vEpxuj}-hU69Ls7^#iMsh%{%VXk>V&g}OS=Otx8vg8kp|v=MZ56L!d!pffoF!>h#UG6T zFw*dz>j}h*x(6>U>f(?3&@^7Pnx2e46&Ly1pV?7XOr_t|L7G8M%>hB)RZ!5r2*2@Ee4 z8jt3_2B2Br6@<()Ew!A=;Fx|7t}6!?&(BEFFTCip8aD$mmGBZ#xuS-@V*}M4^^wBZ z%iN8o*>Sm&>qz*zyI4B&&Ft^9 zl0l1QhgDUYHFblVJV*KcuxeKRXF@LdW)ZSWQ@gjXWV?0LAma4RFdXTK&G2f`%Yf;$ zJ;8@b+gdcB)5Kp6(a5z0&iR=vbAIM}k)Y4Bm{T-dD8d5^GMzE_r-pRt?WVk(GrA*ZP_txA$6{Snk8uLBdVMF8)pt5s z-G;2@Mx2!tz_VkYzQ)oA({wzts_!_uAkbKvjink(b5gjaRmKE4)<=v;CQs$8WUb^; z#fS=uiOx8;jtRulSaD^`Qg$F#mKunRYzp}TP4YD$CsOZq4;y?yDUWHwnbX-uLyJ8L zR>q(~EXMRTe=(@b_cfB35~=k^w)wfPok^x$%VQhW8JlH4(nSq)B3;Bf<#i@$s^Az~ zUBfxW4!l5OPDI8wzU*RaRv>;?&{<5jE2av5vMbG`ZHB>!mK#JIh0dnVXu*6qeahR3_r52`4u6 z^<}pfmB|ah5`)e&k{Rb%m%zAL(}(FAC8W01n(mzMXln7H_W$Ujqhm%3R!-&RwQ@8| zSxO*l-V$>4>H_>~KWq7YMHM<(l|A?nbKNIg|CP*Dv`y%cZLMDC2AxvqE$_ZW8l&;# zRtd&wTer>Ye|18RXPs`NOz&ce_!#%UL~6VDZ>-cl*}@A7@qqyv9Q&j07jK|3^|Tp* z*iAl72h&zdbjz|X)=>8|v!NcQG{y$F4JtJ-iP+Qt_dz!+Q9V?UC)NGz9ov5g(OCgc zY4#^oYXX_2*%W~;-JK>%-F*w0J-_e{>0Wi*fQGW5c@N$(O}z58Jid0VSQX|c@LGvS zE7icGGa|8})aPv|&B}2KR%`<2MM{erO1qRSx~b&tM;|Ild96gqIfWn>?X>OndfSwh zneX*ph46ZbkW^0V!rs02g$MZTm0C2dL_J6__GkZ{bw7AP@YQ|o1!uXz z@t)$ZvTko`s@tCFe|1_a)4ATj>nW+8O%T)tdzSZ}a!Q?*HhR-`5oxx*MqUG7M4qFH zVWOrx>}5MCSr~|oO`TBpLuP4!g zk?nf}v2`wwMR$lhFk22oZ){Rg#41@OGrRrQU7vwV0?i6EwmNMFdj-6KRaAnpvDty~ z{N?DoYRj+u?-Xbpo14P;rb~%lE9t+EgWHk4w~0YG@nKRi?e9ykGZ=wBDfYGgb1^_?R=a z-Fz$ZWlz}@n4NKUTCwzMP0Hy?rG&CoCq*wnvW7R7{^@?lI!YE@z>~*Aqygu=Amrpo zs6*WCS=$=U5@8H$G50jCZ8NwA`V40Ld7yXr=hf%N~XlKL=qh<9UoYt^CDJyF8RTY4Xg6t z5-S}>twSBu&2vgKZ`LhJbGJ2?cJg~#dzMIgW2HkHN-u)vrTo9r(@@GR;~r@A+aEX{AfqVtX<(`K56-dhQzd503c8@j0_seA7;f;O(J@&*8?XnNQ>2JqAODZ;X zlvF2St})Wm#cr|EGpi>IJH@kZ&!*n%oaVze@DwvO{y=k1~vkz3W^KG)&yl*aT$ z6Z@r|apr)IVyxktuJ62P#%5=e+}W|M`Z86ii7vnpu4{fn$z3#!Bc@#bovv5zd^Bp# zb`DOhZH;{*XQCsQj#u&W13On^L#0z8cxo14bg0!V79Fw~R~IaR~!rJGq@JtEg*m;v{QsEv1<|redEZiD+AS>gpRB$E+qL z)K%>(?_6C)el=FCmQ6+i<36Zp054-x`esVgjF~pa#W{8JG3$Cot^F16@mp1=4~>1e zEn1e(DQd7Y%ku4tYVBICAqJG?hTIW$db#X0tmjq?XI$;SNICwIr>H4c!o%CV!W{UyZ+54B}R!_{?U6!90^m`_BkKA-j3L|y4 zGL{|#uq1edXF^_5nzJJ}6}kw8+~36hzBZAYbJ)Zdo|qr@OvrC8IcelweLqu1=)OzI z@mJh@1HBk`6cPP|kXX5s^y&UhK#ltv)8v$ATE}A>vA8h=ZzoU8O`Di)43eZzE6D>p z!?C>>{C5b|qP5hwjcMPOa8k{^FT<;*GN!eby-mGYEd5M&sGKD-Zvojqe~A_-=u)T= zI3YKUC$>7uzLX?^Z3ZAPcIxU|th*Qk3@~{fyHn@6bqgTfKi@UaspPLhfT7l9d6XJX z0$)nr2eW0EUSOcZf5vZ3O%ErD8f=8)$W%Sn4ho@qK&X@V!8B9nLS5ZPv>h9a`u_?1e+$1CJjq4q| z4H0q6lBqTVaj7nkO}T31lv%9*1N6`T_)T`pjYb=vXwyijarEV)P2|Q|w3M#^s2=U= zwTw_~^ySuKesvPZxiV|{NHWS;H5&P@Q7%VI&XWm|rfTO>E#yOWPQtuuWa;Jp%3A?j zMWCy%w$G*pypFP6?8JfTaHoN&mH^ zUxYRinmn~RAhqYq3tWnrL3AkwHand>eJm}^P@q`WyafO z`&{}~4P{MPwwJ$Y45nqKYa>-2GpM|yrVC8?;!X#{6V5N8#V|FmyNx$euwN=C#nfR+ zW%>@j2k5`^=sfYX7-3K2lY9B8pEh`XWg8ifRS(to=XzuP8)Evix})%@?vX-TVh6q% zJG@hQKYgJW#hbk~>@nx;Qd(+k;~lHT35Iu?``e1xzEx5H1->xgVZC_aSa0n%uW!x5 zR&vlO{p;6bnrlpR<)NkiisR(-8Lcw0IM!{(x?>D_STghD9<1r->{O-(WF8Z}Qqqd$ z#~IL6&YVk@tfu=cW1|{|`%|6tjLmaqeJY2665FZAaq4yUc`(BUgeS+?(>k9o84e5| z>+?rL1cr~z_D8ScL-(wPk7fDrd_vFYw0C}8I&G0{Y5jR0Mm?Z;Edmm2wP>1|$yMh7 zEWf3CQjVwXqG`Di%NLuJ!z8GyOS~Mv8>$I2U|ZcOZCZBq*qlX^au*Gecku!dUVRC6 z82&5IyMP*q3}=rcaQi16IoyeRw`Cjyv`pa{Ig3_tq|QWt#na%B>0DBvu-77aQBG!{ z{gHk;Vuk8(9ec@TZ_nT@#%Aot;UpvP^yCI2qnd)_xcR)t;PruOFV}u~ThD7(K2(&D zU~6yd(D!y&Vz=$!C>l?RJOy$=?87CZOrWVGd(k+y*&Br( zM3LBLQN_Y0O_VPzqf_y^4B8fuw4a4DR$u9cO*uRE=YWn9;eY*yUW`SP47TT5vE&N%^)-&c zV!yXAnZF{86HFUE#~ZpDJ@xZ&+JYBg!Q+xF*th(&W&?=@M+sVpy2#Fjo8UZv>)K9%yS|QzQ8H$rC`WbXR$-zZaxy3fSCQv zB^>l@Tr{NNY_8#BRS|0@WzU-g|5x@*N1S9&8AU+*bL{uSxzH#Q=?e`ak+B`B0u|Kl z{MobFvx5TdX+V!w_*L8C8*k0h$exE8kGauS>{adLt`K{5%}cMYwuE0fYZ26O5( zkL1JZ$sdz&3Rw;k4>Iqv-?MI!w_!3XxW!YFeXz1qY@e=c7mZ7GOUl&<3RI^u=f#ep z6@jL-$m&#kEA~C->-zJtUHLK@YKa#wD#!NKbzt8YkZq_I>^wf7wi z*Ew>_JKm;HPIdQpq#y3(uP-*{9q+-qFefawL~iPr66)>FRQA^^pZ?c}>SlKC0Qay` zAMOQ`)>OT`m&-;yx{V!~E)8o!gX$i-v)E%DKweV+EcV_eYjEwuf$9#Pje*!|=F~kK zBlW3Y|Ljo)HC8sgeu>Q7Kl!GR)N>i4yKoW06wa0QRkA~$OIm8Y3^-~obcUQMbJN-X znX)a$St#A@;Mz&C7}ux_exBTzn%huznBg5`rEgjH;kcDE?zPqu)>m9Ot2bo{9e$;1 z&^j0aX2dbL7JY7ZZ$A87Eqjjl`96%z$ZaUiOj-j8GMSO-b({I2q=prqq|xdO+$KEg z&ft*nsILBKH7VgfXJ<{f+$VQkd!R`g%jNo`mqL?SmTNbH$n%O)IApXc`q0V6{%PJy>gB!@X!uZ*x{ns)NdVIvNIAmO&do z)zxusjx*Gq>Fd9*|K>=obE(hdn%pF@+2NZrSr*uU)$HsVFCqFpZxb?J5UJ00`>VE; zTHRl*D*H`W37pub65Sgs+q>i`@wl@6(`VKzIr8iF;j)&9Lu=ouPhOZ-Qqh~0f!IEM zU$+1GHsZCs6s#wZFX!7IxdD+f;lY6OR8O@#*va<+?>YWiJGXoI&+y!0*@Ll_viY?y)~RH4AU3II zq#@6KPeT@VigjW(llrS9d{gU`;H%YVK-C7a&vY{ zXnLerl9duXJ@&b|potAr=@OmCbIE$ANbTIV>G@=tCw6uh?owJbw+W&}H#f~* zpC#|qo-=lItS#MLCYfVneHWZ>X9Z%X=Uw(q8t4ObO&seXN=F*|SzqCsW^K4y!#rQc zuJolDq^-RBJ$pSHM%+{Uu|HR|w5e>FVb@;m+!M*LK4c!(!eraq)g{1b(tDDg?1r)& zb{gbG>f77v)C3{`uvv%+oA&mrO0H_h%=&&IjG^;*P;wskUO2wBkB;fvq_^4O*%bLl zYOssd7vI*m`C0R^4Nvm;qa6TMkIxMc4+kfQhf`an0ti%}f-)1c{jZES$9MO9HgY`3 zrBEI3^H+_K457UGs7OZD1~U)VhDX%}Q){l^CRj2LT`eEgUvpMGD+IpQ!ec3)r0I%= zvUVO2kzJix$6%**Lz$P9YvOk?Go>?|YLvMjdIVI7smbNP<;IjBE|j6!Gncw~bB?nS zn3QRFX)Kf0 zs5-)3s+h*q+fP1qY>lU?)LT`WURBzvs+5+jeOg0lKc>zH^>ZeQ8%lFhS#Rsw!(Z_O z)iy!Sv5e};IDLx=dj5}g{MlKFcHFe0x{*#a=@~TNx?QK)zUk@1wxs@wBQb)srkLMn zbs|7=7=|Y&XDnh`CMS^=FUtw-M>UiVDQPGjQR1}vN$Kgp0oJ7ScnMkqlD%O59WYlN z{vexlGq9++hwz_ETJ#VSlal`h-rP~BNtI5@=jzsf9X5e2y9!wdOLP^ahj0`xy?PFMYd-&3l6b@oF+5cXRCpdr0p)tE#X|i zh9-f}1f(Z;KM-|mSxs$>v=q!s`?lXau)KDTF4q@StZQTzC297#6cn&erm=imLW+bQC zHY|+R`-XoQyr3BrI!X>K2eTT=+N7)+RDS7ID`E%xe^Plobo6EV(H`hKPVM#Ko71_E ztD!92L94lFxr^Dw{%Dn~Ch~%1keie2$6_~SI)g99tI~@ZyuN>3vP}Hn!_rQk?&=0g zxLf%GvMW}0oP4)2--UJorAE;DCD3-BuhB*c+JDV=(cs!hUB6w+o7q!fx=0yX9{YLl z`q(~u+@3c(8d1PQ^Eu9^YT zbt8NR2R+j|enHo+GL<(~J;96_b$ffQusO|GS?XQEN`1C{cap;fTX98Kq|sYH{1;RS z-p(;~l~fplp7BY@p^Q~DJSlADl{y9&R4-DJ)wBGGDJRW~2{0?wU#SQ9(uS9}Mn@+l zq_rW(fVSVvPvep`UBsoG9&&U6t~lMeK>y88N)J&_6gM*oroYw?9X#IFI%C+6BI+C| z>hu)3LZWg-mr{>$A=S#&r(}g5f0QJr%+)F9uR7IauBb^9?rTv>zYmh&nU=2Q#EGab zWf_~h?4Q0mR+`>enmK50usl}UCZ^{$8`JexVAA94 z1`eGqovtD0B5&wN821m;FYdp|>3jusd@k`;D)F-AUGD(ln%jP%-sTE1MeG^sr?qY? zMqL*=wnsNcFdZzt@@)RhwXU}LTJvxtJp$v=N zHGp7-GeDHijk8&xA&tE^W!>4(Sk@(@dZ0LDrVNm73yDN0Is^WGmx z|M716p)={%40^XnKMZvG&4v`LaKbRG(Dwhy3WZ_?uVV!kv$QRI*n+!Pa$~dQa`R@3 zuu%e|#3pptFQIB%gm1`6)Ov1cZsz_ZnQGUA(_CSj4)Lq>KKnRD9=>%%+T z=pR{~_qAPhq{#HJlX7x-ZbA7Oa0+Eciob;Bo9OMo&O<{c z6OWvg{g>X*GkCqd&6$4)^%<#MI@BhjIW%d6`bdG+(TFe>pO|cNSM>o*JpSqIifApV zbB`R9<$CmRE63Rz!Q2JWyy)d5J|{fV%foRjsdiu#j_PT2(S7_$7fTeR>|oP^I!W^W z3>A2U%%5|hIrC?48RlkwiIe&6YNyU~ujDzN|Cc;}pSr6#&ub-=l;?Drj>HXomw25# z??~vcd0vv7=YLF>JRj!ddEsI5e0qyaKg#V^$0qvj*sgPZojg`nmcxW>%#@0QBsDol zkEtG=Q#~cO`V?}s84U*9_~vxdJ;KCV3!%l~$tG^j zY~TNp+5Jpr=Or>br<#W=$nV}Q^1HX>cXv0x`=PSkHmyv4b*}SkGCrvuDO6KQlqqhy zjCW9qi0Gg)3cWTc)nOH8rXt1Jpy3;aCUd^~J+?J&VFITYVLj9c+0E2Yb= z{g2`k?)ltj0NJ)1tayZ=3FL%YEw?s-TD7Jo5LjU~BvDn&ZAJ@jU2ZLJjtf2E@`_FZ z3F7e($C?rR(G!3-WQ-q29QT1*R}F*#=p&@qqR4ts|X)ReGjR7C~&T( z6;FXR`K2sr-MesR&fJ{FRmYW22zjPZF>@`4|7ol505-kq3wXQ)kEL=}Bd#t+u-wQe zM%T z&XK1Ng|GUEJHz)5wMh8h0$&4&s4E08TLeW!&~*s;y1N++5#<`!_1r* z7f@Iofj}N1v<^IoOaXbl%O(61Vf7nHQ!8M>8r>m0+$`qQvvxAM82nGNw}5@k;kmsK zaja|hRp`eKca^;XMk}oQ;Ou7fV?>Fx+kqKNrK=Nw+5b^7kv$LD{|}-?GCBT?h<*yu zU0u<|@Ivyv?=k~obxRVm3GViH|Kq$$S~t$C7&g0gUd7e@XX@NPPICU<$(Uy=05_jH zm*=ScKtWd{k?Iy=Y5jW}?W(q^DX6em z{Lr`Ax7RqA_0&GP01}Ko!q@J#eL`pKUOOf>ZP@u2Ed^*@ z1f7Ex>alxmRjB=vIF$+O*M4qN>J{0@-tihwJ&!`}UQ5;26B=G6yG}CoDemcrHCT6A{gCO_=0&`=oysjT6#9r5oFokdHBso# z6?JbWYt;~)1G?(+M@|N8U!eLOAoi+PovOScT{79xxq;S1wUNfde?Lf_gvEPcno7I{ zYNMe3F82ENK2Z0c0qPH+>T39}nBNKJ>tJ$#H2h;u-kRNOcKD-buu)9CIyt!>opG9Y z?u04Yu`9aZq~gIt9EX2Il8Yw~5v*oTp}y)mxcs%^tVS)Tz^%rB2BB&V-2zFq+f(@O zsVo<_5r}E6eLStHn{99K2=l?rpSnin7%FzC%UBe$O1Kaxj z4@gYIp>87OZY9&pX(jH%eo3V_irK9H?!kk!6pC;#-TH*^A%31NX?%(L$oTn6Fb*xh zoz!@Et1Z-ky4c%Cs3)#UFgXI?GDrhJPhCvd4Hb>PFX_Un8V83O#0O91m`8z zyEwI4Ezt2v(2oTg2WsRkvHHW;wab~5mw=R)JDl=zU;^0Fg~!I1rKNWpDK5p+rDbj= zZ9jJ|gFbmm%_?;TA2X(_D;cKCjk4A+cSC>FN@+W5YSctxrInJ~T+}~+(j2PIr>CSq zc`R|#xE%{AjoT}N@;*`OP4GCMxk^9W3_@GsZ9PEz!UD;r-D`Z(cRzy9(cy11Qnu+n zqZ)?N_0r@CPRoL(t|87|`4|6gMPg-N>~E*Iey+PLzYvV8t*1#*Xbt2N*ltN+ak|E^1>E?QoHWi?UZHGQfI#H*cR zXHflGhuOrdf1N6ApIb1F4)3Q>oGXMa3q_w6g+lIq4Da^^cUyxK;w$1RN0LL2THkR^ z)0ia!&IafUWQzUN5MZ z3hJ$bIvdo#R=*lEAebY;jH~fDt4^o3zdcT1TY%AzsF2%Ku*$Jwl}$RP8!>;aR)-+Y zG0bd|=$10+iry%ttQMb_R_Q@_B+SB_Yfb7qtgIf#mGb0=2oubVdK-*t_Ym zwNdvXR0>&ek?U>C)Bp!|Aux5B@a~Cab!YT1T=qz>R-Fok6vxGNx;P${VD^mq3VJzc zxx#8E?D`A4&agXdVH0lc)j@DzHWg+otSxuCian$5)e$SKMqq05gytH$wc3M89pg>i z=~66+t7%{{b~r{lbZ3r*YzY9@Ys&!8|I;Y`ib*u#R-p#ncuI11cGs|ML7N$@lx)n> zkf~rfy~{Jy^(bJ977IjNh%>@uu-k#6@4*dTB(KlzdS5Wht%1JD2-n|TrN;?sB^<0D ztEo+N8)OA`;m!jn;c<00lBE3oQ(Se z=ZSZ}23IYsh7VVf=v@Tt0b0R_lHe8d2&j)SfZbN7=4J`6B&-5xZ5@v)RrL!yN-Mu` zs91;f&ft+OZPHWt(-$1;4j z*Eajhh@2sjopv{1o0O!;=vE@DHZvlK$k#E0{qsNNx5zuUd+oL~Z!4Yp1g95?vS_rM zj^V&Uns>48;W+iVbv*E-+@*EMrWw&!;r&fm(gJ-aUO@$+`*l8l#h-+wnbEiOO0G|n zT<<2%FcT6ZHz#U@KGG*kAIPDT(i%2 z$tr#=g{<^hAyebY>jdo+;Az?i_;6^eg|?4+H?FG`mC=kJI))Ra;amC!z`QlDYK<|$ zmFiJYsF$|t)eqUtEyi_E4!-;tvFer!UtXd zk;LW%*udqhH>q^uljO>>i>ery)$#@~zs@th)^&7$oHDupWK$*|BRx_UcaMf~+1USC z7QX=J(6ab5=61^BTf$;DES$3Vtf0I8cBe%CAd#jl-klT~y@r4>*IiEIrwT}rCB{xF zi~i_C0MsL64lR$<4=sSnC4WD_P*dl0<>bNP<`V7q}WDTABj+gM^PH ztUl(CF|4oB7&e7p*RZmzm|RYaj`LTD_t1m+Yl;0kOb=gTZx(SY$r-1_&K6A9f)gZi znM9frJ1HqLI*@=VvGOG)wt!zs?3q#~Gg_9|6r!x7DVc^hEyB+y5kS+9QltDX0csQ; zs_;iYBA{!Nt$ft@ms@*CswwG9T9ow9fom~wwYW@tD>$C^h7&^nfKXY0+%7@S^3JLi z>8Rmd37I_7Jr8T94cg+L5ppmYJO*%FJzXlcY!RdTW5=qua0bUj!6Wogh6JZ<_LgW} zR8Qns)1rx1Y2%Nsr}?$^akUH9DBD*G!LOsxVHB#GaTv3<77)iJt=E1KRl0*OcYZ|Q zCrWz3(su9&Ba9PS^@OI9v|YmdpAj%f1l%nGz678 zFSb6ggy;(+9VhtKAN{5nU+PEyk6*R%X-TQx0Tt?)s4G8!O|;fu)tBGN?v1yi@?+4% z)gsN#W7ysAu$wRJcK@rHoliJ?3$$wW%$jw}xw9a!Lb`WjGgH*N=#0k0@%IC_%2}6_1oU+1!2}fN%h1Px@p0#-kRhh zYWFZg*0^uq9p^bvq1Bu3kxEYn(dOH+l1-n}R zmZ-f%S@(R;SCf2I%2zAV>Q=tY2t&;mUi1c4is5;S5UvMEzgDwt;XdaR8&{KrreCmF zdatJnM4n+U<6}Bw9#%TKl($naA<-o8L#wR_o=Pz?fDfz#|8@EydVEUh%@L_LJ%v`X zuHdjau6%&H3N~TA*x(5|iw$+E4Na}(zr*FX$$A!kY9}S-5Y$@rH4TOJZP-QKXw3&T zuD;_2rhvRCFP%A4{39bIV(uuNv>}qT>jWZ6yPS`zy(Fxi`hujp$!bsDx+!YKw>FoX zqEXOHRZl;uOOGZ#T0H?V7yY_3_jT$bQYR&rIT6gjB1F9HgEJq>a{tAQ{na z#rZlZl6<@`#pL74;h4ljYTWV3lLGjvDA}Ly22{1pF#-;Kz3}K4ERe(piPMRn&4*-& z+77dW=`u@T6@Pa~Y9|Zx*Ow;cpL!8=b%|8?m)3^~oAsAR6QZPmv;bo^V|bV0vOExbLtv+>Z!crsw^-jTlYHm`bg{rdFG8 zrE?wJsV0$cwjEcOB5>w{%|hAHq11Jt-)bcSBqOYsFtWOeFUROl5;o0f7gt@n;`9kl z6r-SY9Ulp^Ee8js2a3|mh)}-+aOX_9L0Mau@xMgvBt6y@-$*WP7y*{d?%YO1RlWLD zqWX(uX;`KA5=pMa;;K~3@mI+FfXFHmhB1JXo%PWH09bzw=JVWks8#s3)PBLPY8qlR zM;wc#j0GY^echsVwLp=^z&_y+U;7q-nzY#UH40o;butWK)u7$;b@iiE`9I$R-j}Fu ze-~H34VNy9Hq#@}i$cAd73!qc60a3Po4sgn4JFGGb^X-1n&GH(?xE_OCF=b92}d1V z?KQ|fq;k4NWWz9qY^p|L8d0zZ8}fs zaW%)t(5qxuiHz3(m^Q`}lvT1%km*b;90xZw4`W&V_=>CQVK~sJV}e~0OJ&bABX1*% zwUzZ-oE67=1h-v?=Z8|6h{z`xSHHqQDzaXLB$4(I1Pns~Dl%c5XDl`qt~$r1U*|XW ze%^X&o1BmvaLBc!Fqvk2*Tn2U?B7vkf)^F zlAFX}x-b|Bg9L20>MXFXz)Y1n$v!HsdYmY3EoSM4=bVHvr&VwbGKW-Qkbi(D26>zr z0M{VLV~}}bkoy2846>Sl+K&CEs)sRV!XnFo+dRRnV`e@^^-G8Ae;VXMqskTPX4H~F z^?w-DGj%uZMkLH>=5shUNoH{tg0E0RU;~#JT$ulZiQzw69YKUt>j!Rt@&2LmZU>K4 z9_Q4GEBK&VPgIQeoFJwMj;0W$TYuA7ef&{*^kO^W5-4VYHfchD;87V)hi_zG6 z1Q9hqF1POGSKHBT?oSu=*B+JDM%Wa%Y)%yT(+M`;sUu(`%1#ze-|BVxllhFRKTsUK z&X;y>&tOp=wSLwg)a~E#;UqzIb&|LVm>zc}lwJ=+4Npk>MLo;6_1!!~{k+`zlHV3e zKO*Q}t+cLT!bw6_4l#DT$`z7G(k!9+2rC-Pe6PkMM3Qu?$oa2MQaPWdI^hl`DWS?Z zOyxDf$l)<1&rTBVZMO*$k<;RQT0nKdUcbwM@Rc3xZroS4(7U z*Ch2AecVbOTOZ-Cc!W$yD03X~PF>@#cvf4S;^hloC&jZDkxsJw6?Z2rS`wV^Ji`iTgYr`sFl#Dn?Z9VbB0SK_XFplht=`?lz;40eVmsO zGpwHAiiJD`d89GbT#2h5qOOemlFH(lcFJI%d2FfDMIz`9YeU(^VPSd#)!y8}dqLIl zOvVlr9n9dKRLZ(1lc>Lw3c)n(#@y6D+&6Fh(Ld)VKW%B=y*a5{3FBWP9Dm}3mS$^w zwc-u}i=|g@`j+7bnK3Y@&90LekvZ8s!=Q8h9RW&r0vGB?**RHqb4r3?PH2cKh6T4K z--N%ZW3Uzz2kOJ8rS88g{V5sVId8cCTf?lesHUbEnzMywFMl9eO!NwSgI3Ea{BhN7 zaFT~@JO;|TLR}w3>j`KL`z17_q`!(?(Nz5I2GR6s!E#ITBSbpx7UZTx#~>BL_5Ozv zc#hv4eUR(6)Cv48KU@6Ho8))509{xhnHFA?BYPilKY34kg>^-_%Ln&6S~yREv-z(3Y(_^ZV5g9OVpd^pMQlM?E+7OqD$C)zQ57m!tazgT}2f4RR3iv^yyGO$9p zSQ5c4PLmhQ$MWfv9j6X{iz!w0?F0Pzluodk4XI=C_xZG6QjZYlXyg>|=LE5o*oPjr z?~AL;29ZE|pjQZ|R|v>83bh1$wm-UxU-Os^^O7qFn4xPiUvV|ip*)t5x`n_DA&n9e z(p&kh+EKNiohU5A%OgU=frP)$2>&-D+{7I1xe`2>;g3$`gX+2)9_;Q);Vd*jyQ|tK zjRjqM$7_G=kEqXq4c?-2rsk=IJ*1e1_t6e+|B&{kHoT7lv6s*AKH9!cAIS$RJOzBn zlS6k3hi5m_2FMAKxVn6xN&b}rf0clwp^kv0;Wd84O?`v;;ij={g>PEG)5HRDt$!W? zl$_R5$#Fo{P^09Nn58CeO~dAni|ska2>hcTSYsW5lOYj-ZM@7X_h-fTSoB9+D!DNNQ=upTSF*@t*{c^*DT! z%y^fux)oR=U9SPrea2Ju2YuEu{Xw5~1Rph5nK36_j1a}tDs-`WxLCRRgPv_``B3|g zHcB7pi=+vT(q|GSN{fs`oNc&(+`Qib5lUOM8%aukF09r8!$2pHOEq)!^(S$4mm}*Q zLHLS*7)TKiS=;yxHytT{RwjNH@kieikSnW#0J3gvDQgZ;buKWq0o`jpHL3Ub7hJZH z)E`Hz-u0f(!%osl_|0w`Jrrh}a(~jEBhRq-qX!Bk{pjRWq)gGH+^;~bb(_Rc13+fP z$BJxpi$E7qR{sa@CpGWTQ*pJE?u&H)R97^#ra|WDV!GfSN11XVK#`y*Qb)ij(u$X3 zve=7&GP8)Wk4_k5v;^6N=hQ>T5j0yDe z{RDz*5j!76hPjI9@fK;{3es(^P`*V0rf zMWn0igzJazi-g?@0(*o!)0!IPH^d^WEGm`E@$YuPgwIoS-*dmevTo$t z$?w~=_~0Djc8k!6%C3nzVj?N~1;X)iiH#*Ver6q?;P|C=6yJKym$xJRX16ZOUg_5H z5QX(_{<#c87z#1n@Heafcl`6eA?I z|C*5XI23_ZUx_QU4an!`7N2SI`TA!bZV7sQYl`iC@yn_Pp4L+T)Qs4zv)fKL zYX6%Se!tGFk-m4S2s;`apuUFi`?UuCGVq3sN5>hhKeJDifLej#_K*7W1^L{rKmR44 ze*L*nJ{c*ygkL%a%M&HYw>~JKt|5?EeCQ@A`t=0W z+W=dyLRs@Dd$6TR{W4L>*9d7&FkfUoC*=D8v?O05(CdP>baek@)}vtF~^# zo-fTZI?(`ZA@~%*S3b8}y|TqlePwIa>bN>p%iv8IXyWR7cu+){g>9YkQPmD8%At^@ z`a#4q{o2Dp@1@aKX>%%p04%(_72e7JzJ zAZr@C^%C7dZcGNeu!qbcRBf)cz4?CcwK^?fJA30drX^F?OCFk)kh3mnsg@d_CoMQn zA-TPXXbK$l;?|z-PQi1Pl1g(kK2xgRd=L{e~Bt7lEqV}oKd)b zK^qwh=_2;1Mz02a_ZoD6fMAu5m9gw?gw)QclfW70%v4LH#d-2#z$>w@N>3qpKfz>u z#%q?tT$W`7h1p7p1qu1=`pgmtvl2};w@V)`wdNCD zjI8(98UyrI1GQR=sLPQ2s zloVT^Vq~=%I@hiIkm9BP2L4xvyoPETT=W_#8TVNii2I_KR{vc>arK6d=Ori|dYq8X z36tF0tvlBUQl$&lg!gLH`G&Ff-LNoz4}f*9#y^`+lsZ~_#5o#~U9Xy~h>+PTFj0p` zN-Vk+3yXyWraST_(K}ms{toM4y;$6d(M8fGV|0!A$_rC3|U6nftiFU<`HO?8pxz1z70)|E=An`!6T`zzLU z6sVNDPX3BF2(aMWRb2OfOFz1WbVh_!m`3_A95f+4O{BkyFFDQk12c)_4TdhP65yZ{ zwY+1HS3xJWm{5I^>y!Q3%%&jDrT+_}kmYK!-eBLzw=={EJd^1L6r5_0pZl_p(b&p z;savEejjxZMP7E<=o+n7!)gph#U5B#&jNbEXJ@{UV~pq8*W||@=06>N6`J-~Lc=!r zqhUfiNt*BFI&QjyIYWoi36XPc@zcX`=DO=nP6|!WPTGf~p-gn~IuJ;p z%mxaAD0?d~5;!oCrMqOKrmo(SGbXM|v<&Vc)e?^+^p~pRC>_;VBeK$rG97`ai$#{! zA;mq$>J2)(bqME$RA^LqOvBOL*R5iQ5+mg8TZcAP7hlP00 z0}!+3t{F=D2|C8Jy!%|E?{bQr%aUeHilNUbo7y?mowL5oC{#It=eWdr-r&1M}=Gu zs8v1%*7|J+oSQKGxlo$Hy|oRPV-DHiV=UziFn#JiETIPI(O|A4wUd^*C+9Gkwl7;O zU=xMU7K%A7AnF92V%_2OSM)<(l5PDJodHQXh3g%Jq$MU( zQN+~)a1?_+#1w)0jzD4$bGAD`s3gidANebvd%CrqzICcWdT z%wc&lbmmqJ_8XN7|0pq5E}RTq8@s`LJm=JY_A9cfrm8-$%KseaN;WUIiYZBfRlDwH z{_HqD-Q1zpY%!1!Uv!j+tNOMkNo%tZ*&dO)!}2O2jwwkTj{1xaok_?|c5dsJ+}g#}R7c)fB5x@HJ+U}KyL`|mJ>Zi?nsgP9Xy)P9g?Pvi?Sq2wyhca`;ZlO+6l-C6 z{(QN0_vwxtTdDKtti{zZ(HL`&05z_TaFeLH_0_OWPMW$1?@I|-zpZr5-?C$R1Lyyd zE$nQcu-iaLC(E^{=(tfw)oR4xAU&Pe2uSAMUgo!Oi!=B5C+1V#%bAE%C;y0le>BPM z`E%d{YU=v2$$pSDVnLA$9YrqI(#j5}$T%H!qJubGhq`ITdQ#X~^81>sQFBC>f7^V$ z&L8U(R7v<>l3ct&ykdtsrnQrB$?;CQi}G29WR|ndWi@JHfd`E1|1WcOOse61vjoc!1tHX}`(FDj<^;D|iMgQ?SM)u<*!~nXaJcByWtbV_wr|^+&gR z^|PSP=T!5uUfqBH2M}ceQ2(Ugrr!dHt4|$2r)J=UJS+-f=n9S*i~Yxkw38fP{RNa3%EY1U=>YHRsOa!79Xt~mo z6bZr?R)1};q!gRI1?oHy^)8hAu$Hy4CXu_G`b-rQ>k`qzR;H||BOOXv*ss_Iu9_?? z7QrH}-Xv0v0arE>q3eG^=zkTutPZSd*lP~1elZ?giG7gR#bW8AlHj1Cyx@^)(Hz;c z>vi_*etVtl+4agp-K!e+uCShjP~8CvCGQ@MneJe|t}%JJ@1fxvL+xtSyo*lpbAFw6}Ws<7t8`X_vxLu(rW zX=!tSsd26<*2(Z>+Q1EKl!+p~C^y(yo#-$cE<}q6SRFM!{Zdiwo98s5KiX9&^q!^g ze)ha&5zO~ffRnS{==vUBq>Z2@ZBG&Do4lsXeMm^nhqa0$N>%d}zOCuJ;F%itWx#?48jxbQva6#hM3ZxthpB&G!~CW4^o61)F8k z=}UzHH_~+QHF3uP2;n~%2#AcTtqXgIsSDQ=oqDj2)JpfXm8q~94Vbh`=Btxr^;T-7 z6d{yzO=KVj9;*t72^33Dbjv}}n}`qiP;E3^&bHMPv~CCau>2kGQeWczy8h{aNvz4B zE1APkYk_O4yF1a$Sb2^JQ|BW@40@qRe3n3SyI8_aKtRt{X*l7`=?mLPtr8x2SxBBJ z`Xgs<>I-=snjE%{`(H%A8Dn@qaa)%*yEv}0!a9}EN?x&8=~^La%;qQ@SKHA{gnx4Y z;e`lKtj28tV!il`q*$&X8^5xrOcj~W|Hbhx;Yh`C5A<>MIc~(173!y0B`d_kg#$Zy z+%_kA0eBmK)cJBbpH4}oR?(u|zJy!LI9)J3sEMm1wJbCI?G3S-1HkRnsNXVQjYzZv(+-ZKZ{cj zVAzdLMV1}x=&w8pNPb3me{1ePs#Leba#Qg!02j8( z-%)g7C_8@4g?iVt4qqD@96#n-&TY-lKv_Dql}&#hY|{AQHp0W>)3vEvr*0?KIR}sv zWWK_z!JAYhEy^cyfqWUZ}0>9+*_@ih|t@==>ktL^3I#$kOU{PudQ?W zu<*Wu;PK(60`7lmIyu-s+%zVbUoXG`0_-cm-U94yw{h9DD@vc6b#R>=r0%=iPV-){ z98G(OIoRfW95st5i#X5n#Zn`hFDYlsN|Lt6eEP@1re!tkokqds=HyY4Kh#z)_bo3P z7ECW1!Q0x4We~Kyez&e~bLc*|5kWa&y_M5%z%oOoFVY%gz!|&ibGY40gGvp7kNYtX zy=SaoFq~4tn^&;v8WU|Nl?2>t_81*UFW!N2E(*9qbk_$lZc>@7b>1$**yEEvue`qRy7%RYE3J-g|pcA6X)bWbuZFA$9#u519RtTdA+A(+PTG{yUcq%O^ga)WxIJ3_1VC}`^NYy7V3`*M&Eqw zZfw3bQyj~=LbG)D+6}Ia)qZ+oycqZubykhH@LPHl+@{8Jfqvcx45qUi*7k)rgzdEO zh7x*h*M`5zsQo6*_XTGveEZ=O>MzFodN<;m(t}W($Ivh^~bFL__^SbZoy zReSR@u;nkJbiPmxgbIB}xcc@==-W~B&1s?Ua(i|QUFGm?eNp-$xteh2r;#jzdWt(o z=aEv8_`>h5$FuM{4xoBM{>)+_uqHhzdCPaN-4PtfYh@~@$Qw$nNnMaGHG6drX%#Aa zNUNaiYv{cSG^WE0bGXoXNAM_3br}3N{(`UXg%+wYp`rR}=k}<#XEmCKgFHW?D}&$w z)xe@+jdx{1l73{~3@o~*E+wTYCFFBxK31Ecwclr`?Ajr^?>8ydaIn~R#>F#y`Cl>X zZ9F$3HCUuJz5nX#($&%DA8G`izh0nQwB&Si-tSk&g;hGjBz;A_TW+7F!r)t%TY2Wl z|LO;-5S>)2q@h((3UoPj$*x36m+XAL6HQtUNpS*Z3V?QBuNA7>U})AI9Z;&84Je>r z@>Zv#A--#ny=n?ECgKDl@M%-lP0ypPeN>BZE4#BJ#HPWJ-iFWoIJv=)Xw`+LLLXH$jgiqf%>!5@(TI|{t)vns`pwK~{O zlQ@zRxUMXEgE~_kG?!&(2j9&NSMtkVdyvEU@Ptmbr8@ize{xJ$xZXaYrAGD_h3kz} z4)04ZB*3XEt*jH?2~A4jPi9%EYG7|r++mzdZW>%qT=o6kOoH|MRR$V`{oNUjSM(@G z=Xa=s?%uZoL!}6UG&_1}kFHOT#QIc+VcWPUzS7!3O|_rC{Wd-{;d^|j0~odZoW)`; z-u9@-VwS}}|KWcie80cqmCxzw%0O}{sAJWm{n+ll&Fi0kA3`Ge}mc>~axG|c$ zMHp_w71YzTLDn-TP^#-y1sW&#@BC2s=RR)ue*}N6N-31IpThgZ!}HD)-jhYyBh9X_ zgZ{g+fjQ<^SBTg`5qlhBHK(6`A-X`c^c!W>7(wc{+b!r;2B?V*&g!LIXf=}q{ut>6 zXwBBiYGeBeL|KfnbMW8?fj6hlRV?^KL%=sGp)XLLMGg zvA7%Gm1*7|nb70Xtl+mY<@qW&YV%|CCTfEpI?HtLT1$YM95@gfz^sSPzxe?5gvgCT z^V8W)P0Mz00|fzNd8Rp-k+?Z@)9!R}U92{lIE=(Qtz(7O8PoA>`H2McGmu{~kguhA zpqs?y>BMybD4Yrnr#xQ50bTul(=Na8kNF2m!l%qNdOzkuP2zFwp7UCMFZLO zEz#l)=jo3^W`wdOeL9Fw>ZZZK_@5xb@1NcCP!mi@9r4`>kw&?Q`1&w;f5; za?LYihOeivR{PpgaUa%ycjzjn;xRfaX7X~k-mKsWWrX#Iz9{MGAIVX@aX~j-d1?sF zu+H>F5>uJ))J)c_hwy*XS~ykTVJbGGo3jxF9Zo_A`ynS?MoV@fN`XjGrQ2jmqKDBk zdM&+;xH<}P)G0NxYAO?1nW95lLWegVW>&~)A5;H2Gwg77tfAiJTt)MA;oJWob^jeE zMX~(>IFpsowz%*5d)Y76%kR?>8YOGkx4z(v%Rbd0TtuLfH`6W5mCXc z7e!HwsF=M9iaIN144B~eIaSrO%l+Q_d)|NEKi++w?Q>4msp^U+b#>1+%u{~l_ap@H z)pt<&zd>|fdM(T{atBw1R>!vCx0Qtca-XoPqb#MW&fR-1<2g94Ka*85)Ae79h`Td?~RkCQ~@hl^X`@d1Y8P^9FqMuHd)akl3~ z+MpX3s&Vnq9V%2;hUR16c6DVCvJf4IKZ^#56A1YJPbccbQ8q3A=bowy-ysQXw_qZ7 zA1JxZu^LHJZ&y|v4ssLe9y}KTV>Ph5@1F%|2@Tl!s2<-1#ogq@{G~f;RaE9Hu(vu} zcN88c6lSPvZ>p8FUI_Xw17NJEJ$EF&i|*DeR>u(PUw=v>buXnB8lfS%`#}GY2U|6c zxAmL<1<=m*SIc$%KBZILZX9-?l@G2Ea$D&u z@x zc^1T|Oc)FU`fHebic%s(4FwGE*9&>dhTQJi(D^tL)w)$;Qx;btsY>BYTmvRCiZTzy zg;~5Rg9_TaYQ=fSUWx;@>3`U-O7wLe27Vl6+7E{+_g2g(H=NE)QKe`MSz6jQ#65&{ z>SiGROSZaddQ92koxlG~Gviv~pNW%~lKRWDVbvkB5*@$bENauy-~{b*S+^V;(Z_A0 zR2q3V+f?)oIhA;yGKQZem$^zjs{`%`w~KLb+mc3GBwugWLqh@4i|%(i;(zdnJ5Q9E zu4h*$hjzdLpt{^F*(&Ao2p7Q};;+bplMpH zaJT9gp?Y{9<(R?Z2jP3t80=Kj);R;qarc!c?l4x|VYJMFVins{jBYQr`lvhIXHPbE z3|?1RfL*CdtSPvG5jb13J>PCSN%dn*B_6$a*OcNqzAI_;woynLy=|yU@_f6xiPor4 zy&#&q-*M4cp`Gj0KA;6m<6W(~)7{k)!d!{175V4B!UnCvnI6c`wV%62baCgUc&b%+ zmhoUA11}-uij9PyP&&5Z+WbVS5-Q;Yc_MTk$pzq~~idU~GT*CmApB z5B3I!YhJ@Y7y=THyoDjV`>mx~SWKgt#FQ@7FNQWFXeyug{m+Q1W72@Bz`;ZY4sq*(gS>7z&eb zLjDxAfbM++RdyeUZA(_a<*2QA(ev_g zR=@N2L^XKAGPt4G*&Dxid3j;mc0L1KHLqZveY%;HIyLjB&RZy781^MA@}qGFF+-xo z&w(v}IYhv=i`*Jyge8A0rY67CeM?6$FCpd#n4!3j=yp$40*Vv1JF>f~k5Y-*s01a3 ziWZZt_+QTCZbyWT+%W9juGOTTh~!&QLFe?nsgpvZbl!$7q;Lw!h_$`CZrh%_cL5ve zbIDbSE%g5C(3(=u2Jr>i{L6R+WZqxZ{pP>=scSLJ_z`n)<9CHo?Y?zYqtugT5;|%D z!g3U=0=McT(Ro0N*SK25vte~z9?ysIqg-^yMk-p$@l!Oo^|6Ipe*{lQ3~&HRc?SEx z--3?kXqZI|W)xB{o>GK|oh27fDZ%-Sg?CZrNHPPbs3*tbu@#=q_MRt>0akX7Ku=WX z*KRKR_5IQsvFkfaMGu7rkS{$PPTRa2eHcjtqW@MJLJhP#F;e70Eqh=~synEzL%)>6 zQYeO4>O-EU^19S+aVzK+?aCj7cRs{w$-jqQi!tzgg6BN$yXX0#pNT!Ra4iW6`Nlb9 zc5m?DytyXFCgzzKB|Y_kVH6&PgEDVC7%Nz~#@Ut-oZg+AO;dk(^U5`PJ*CT7EEm zo38HmK&|-xDLiHONYig0Q_3!gR5Wh^YIg7ELAyHlL&AfVm14P)6(DCwjQxMRc~%uJ zOrh9g`72SoXhVJj~3<6-iTfr#7`$z^1q?eVxFdJ&QIkdbNB17j2mdeKHBz2y;Ax)uDR2aPuPa z<^F-fw3>#~4PHZ%oSfH*$0yCB>)9=md%u1!ksC-lc?^g(iu zg6}1}HA$@oWm3pF{cl_MLcE}&A`1&I_z({$MU-t)4#zHOSBQ7=NLHLgzxoNKY=FnJ z^@6b^<)`KISUF-j9Eju| zehWVX>@1?1R4eS>4X0-hZJ3uWZCIOa&VP;5bV{otq>10*!a%--Gh?W0!CJuXcaqP> z5ze~@8J$s@%5Od{C}k8^Vf8DKEspnG1O$?|PebLZ5(LnsLMWXp22kyy?)7)-sB-uD z!MqLsj})D3K%wj&)a4xHN4-poz2e_uq>iDHD#M-g$05O8XEM+$J<*@uN9K87t6~0- zs7-od$}V^t31VbB^{1%b7rXM#e-wGs@{>`vdsyIFs^W?+whI=!Rh-;eg*yJD2mep{ zq(UG0gEwH5Yr0iE-mN+EJ;1TjiECnfR<>vbRJz7VdABoW!N~7}?Qt|;z zoe}}#o}_+$ikChX;iWBFhMlvKpA;0e>cc0X3&&va;??>4 z5#+JLDTFFa4)&emPQbvMKpL`m}A(?#YEwB?Ak(>;LpluH$)m zdjCXpZ(9CL*YDZ1iFB`6`=V?49dHKt0PF`DIDHF@otgRAGSd0EcwSeCYZT7=TzE4o z*qE2k6|Vp;y1NJnKCXx-GIyeza&RW?{$w2S3_OC?KBsIkhq6;Lxf3>?>Xs6kG!CV! zLNGEL;ZEeoyx=YY#FRuH?40++P7l#;{2MP0*4>!kyg?9_4BZ)F> zbN3zh-`_&xreicjU$zj{9|PZS!Bgjun8|;OIq$p#GplxuXeUA}qJgUm?dmJr^*gN*#g>2-bI~UDN@*l?#a%q8hG3 zZ}SIHQ#YTBrph3H?%U3{K;=(G9l~E1tC%c-Mc7vK2G9Fv1EP+f-$Wf#QAg)`q$t^* z@5Dk<7Om_rJnlzucZ7tS@%f@2YN3dJ+)FhqrKEz3u>?sg^5;_lthx({VH1eXDBTn( zIZAmBDWZZFq9VIhFrAW)ac?7Cwc^e(C|=msVn0j4Jgv~i0iuog{s+n<<^b8^&n>qv1|;VI|M=iR%i4N#qL0GBAAe-o~X7`**Z z+TE4#uliF{Fv7duK&7XHP+r06QuT1kF4nfn-HmtkLb&sNu{_}wCSkz#+Yr3dz>qI75Q%w4;*t!`B3NJ`oZNhDYn?jaCJ z(g2cGC3q4j2r+#977n8VKX%X{$^orf=MHFZDN(9%{{1aEUT?gP@$z8i@(x@nF|r$x zGX>SS+`7+y+NXd_&1|lS*b>2M}1C#Fo2FOMc@=Ie9gmh`Z z&-Icpxd$Z*yK6BKa_AAW5&<^%G(X;c?zVkpl&jFlV^kxji3VK{?^ukcn3D#ibxwrO zCo9}eZ_w{n^M89!K-HY@c`aVm93^J|XSJAm<)YSQUJ9-FnS?f3d-;}r?C0>mI z6?c3YNh|VCpcRmPeb9eu4+***>wZVK{#Q5hH(!IB_0KJdCDf9yXtpm`m zasAF8gI40bhkR>|`Yj;5?%)pkZjF@Ryl_Wk#}YKAXFf!Y@jZb0_a`g^Y<(FutA{wV zF{WbCSn8*khRz56c9%3BSP3S1g8_1u^8b88uCXg#p@IAGb+KIDMWN0~SU~E|vZU(u z0J#YBC#aGqijudXWY@$Wj5JrwA^ssa?eQe(1|jFzd=4pvkdpk3ongqx?@cSW73vKi zR!4={MfgfNGNjGvF62AWZ86&)zf6r@4l@4_H2F4~Xc^rSZG^2xMhZGkn;ahj+l?-D zAC0Me`I{GNkU9^6ZM+-1zU@;PKg3{*2ZJg~M&Gy)VaDB)#b@kgWtE-3VOgwxb=$Dj zuWuW?`i*S^R=>8b@9J;1^<4ekw(`~ALo|Kc{qc{gSk9tb#cEVhn2rB?zwV94!9p<0 zpURNRKy@mAA08kGL+_3a-A$V%prHR>!%D!f%3q2(AoX~zNIe~?T~cQb(z*pBk3;6E zGIR*jXE3(hzIi%TN$=&*Ty*}`My(d|d_{f?xbtV?(%CZy+Y~S46Oa6TldJnJ=!d%J zi5==uoj#`X>J=z*7>bDL{`RHa?!M{OuDk2Ge)-qXaM9GxMym1=Zb(*o#UYhiU3Je@G!~Qs<8xqdkd6uCXs|f*)UzyL0=Cn4v|_j~P90 z>*jgioZfH#XGp;LcS7F-nk!$8_}J=6km~cBQKlf(pFn2kM5IW20@HdgQl#my1HasW z$@*280LWQEt3w_d!%rlG5HFM92dmFNP_PNRB6q~RMrxpDA1Du{7v)0g2)&1nq>oqc zG~(Tv>iqFIDd`@1zmOg^W_$1KL$4^v!|xZ56*2R_LUwxIUv;)E+t@3YThvm#zTyS3 zoqyek*GVoGr-9aPEt|J>o@XowG%3X^NEyl~j>J0WI*kv2Z{bYY8!Rn!#FFF*p z|MNDI!SWWrK0m43SyP<~Y(gK!ZU5&T^{zV>B6{yYJ;~*cxq3+uG{{Bxst_G_FAQ_P zh4+HQP~(G3Kvw;@s0E*BHoA5A;;}Tz^S0`;@8fVYH49^Q>wQl#Az}=Am*y{o0LCaN zPW)hcrEJ=~Tt8`-LguvftK7V;*TrM$6d^iUxmlU7c6rY-I@c)4Np^8>9Rs!C#jSqf-J zTYFVhX42fwq*La-5z_PjMzbeYO4ftrORvt|! zlj+ny23N$=StpWZb%V1ZTz>>zNrnOSbm8myJZ;tBJw%F+ZHR@Xx-8b7aS;(0~; zEiO9Xijqi*ttv^T*=@z??1Lq|HL(_#?6W29>Fh(`oL@9?L5aa*n{ml*DM_X6jU}0c z{bNbCE%Jj_7D>cgQkND-_yxrgdtQa?J6lvKkhpDLT*7jh^NLODhjP=h=Vr{`N@Lk{ za(;0<^=olDwXh^(XV34MH4_m#-e%hA9i=&LvWv7*W3Fu$l`$usWu;{nfyz?47Hbo< zBJBVi`F>kFQM;h{I4xUxoVKdGQo{&qRTbshw2ERaR#B>5Q&FOIjMgHpdTAt~>ydW7 z+Gy1)jD$YW$mnB@cKsjGR=q5m(ECTZ?u)kTd$Lx&oW=EhSVAAbxE^5b`d%j2y)mu_ zTew~`$5S0QpA)E>J||dp!kn6_8FOl@PE7I<2PQj)R;SvBFUXif zJ=u`HC>z!<%CgaWW>cf9v$@fGWjjXygU9u~c}5?@x$ft-ew&d==!2qJPn8zUdaH_} zSzlFgH0!S_iDm;;rO|A#sw|qVsVa|VYpW`v*-%wwG#jq!!Qu&h2umb}&toX7GnDPm zP<8-A*?|mYs~E}-VkkS9q3jTbvO^il?qOm)CYczB$tFhPU=!Ux&_v%4HPPvVu!M*A zG~*flYBLcVI?Y6br54JIghu9dz$u9~5U zBDngh3|#$HQCi9Ui=t^}?ok#^$6`Y#VUj&nJ#qC`^}^Lx)f-oTRUcdfRef;{R`p{M zJF-VPrqok43|DW}a9n*=BXIRsjl?xjH44{Y)#xOz35+;AWnyNEu|3UEr5Up(Fth!V? y`hi5mFY*}nh?07PrwZgeI%|-KN{DB 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 literal 0 HcmV?d00001 diff --git a/toolchain/fasmw17332/FASM.pdf b/toolchain/fasmw17332/FASM.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c5f900bdb9b564af3ebbaa42eccfa99d6b9d6307 GIT binary patch literal 529038 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

8` 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

u$* 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 F{2v$O$Atg@ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..3680a6eb0013b741dd0ebf6a8955c71fc0b3f2a8 GIT binary patch literal 206 zcmZvUu@!(Y2t?2K>?~NrIqdBn!%9mTjR~A38{h#+XTseFE-%~uqRvIE)Y3I!&frM@ xGX+>sEzsFg3NvHiS#Xbz;*AyUj&lMJ2Tw||F^(CKA{Q}>L+X9&^ufr-e;;+)Jf#2t literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..f90f438ea5ab8128552ca93b2e3d0419f46195da GIT binary patch literal 766 zcmbtQF>Zt~5F8+q-H|HoA*IO=QXWrow{%!(&d=fj_Xv_IaF-HYJRYE?VF**me1Z>1Nxo&W#< literal 0 HcmV?d00001 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.

a%s4Bo;vcN%A$?=j)_{E;itjE{o(t=)F+_FT5H5VnnnJ~H~-^VSRI$JhVj>frdR+u=`){%>9hdUXv=f^HGjqHp<>wX=H<+J&Djnd@wl<06Ngd47E^wwk2-Ck?WfZxfLWVPbfvZ&H`sbbBD3yy&Yi0i zwA-GCcvV~b(^r1%!8+N8t(m3rUvn8g=AEb8aqI}=fwSey{?G)v=pr0A+$M^wGH0)y zmft-!XLC-@C2@3cE&t);*0 z(#N{6`y0GH*Vrx(sN#9>f2P-x)BhCX-AII?DB8#0@bD`H{oO6REp;zwq!$Q1U2&0(T`vfkOl{0K!- zhxmkGNafG;dKyUspX34BGZD&64hEtF{RG7APIdqYIT1_go+OC0y_(ZeBjtXV2w25L zs)pdlLE+hW%8C7vk@$5~wRCZ3LfxbBBFVBk>y`Eh!=)^wSP=2iP3JHaCva=!d-qcg zhW7VjVC4sEDU*e+MX45EWv#|26TB`b0D9)g1O}{vqTG|*3S9PZu-@ujp;Y79^D=y% z6~IFBBgU1Hj4%Kdg_8NGTj0J}ak=p(guQ|jsNH_Y+Tfu5A2jW;rLd|D+mRyc06*2+ zcKl2O3(jFW>zKhzSx~b{v4uNR4!h27OCnNx5HZ zY-^o*fhPZ|w8tPl=`EwOu3Lxy{merrctDTlJ~B8A16YTRz;9-9Yu_@4oyDNvHlfaZ zK$@$<`{Gkhcy;pG}u`}v0)^(K9|D0n>A^R|6$;oZnC z5H~D2GAy$D^;|79iV>neNun9Rf`-1()NI3*gifCi;M;_Xn;GBrZ>#35l{5x7xuoM^ zfXbw?37(9xL9$%E(YUz@KhWSAu#zW0h1p=O4@XE;lpLoYC^kLGNRZDBF5-J9h-tWs z%U{OFbRz(iIj;D0x?h4fBr-J#y*p{?a-KuG7{l%`Hw$!FTZ(am0{bYTapUyT5rS4K z>kj!dP5M+NVJLNv%HpFj!7O7(SMS?(c@tAS0%x@(CC48$I2u6Fn{>l@Lt2r0wlc+OmfOjU?^yGyJfQj8(CxB92K#seGH+kt~H-Jv${`vjjzDp*4u;%}E%y z!nEA``y_-55HY(^)T8)7oZW{Na91AsJWLv7I>cZIJ7QK|C?pOpD8`uD>rI4S>z0q0 zLEkJ;ZZ2&fTym(9wOTwrWd+q4>n zE?Kec5SEZ>NHq**3siD0(-=l#$HW4^;~n((u|CqMTS+iQ%PX%ike$_=3wwpgSFzl* zRtUdIOfMZJ?0th>)@lJA4%*W*Y+1v=yR7JDqm*I|vK2X38f+>(?+k+S?@9S+L11NO zktZTTcb=c}%#aAF4FLI^3t;!dpgUE~Z2IQDg9eDHl`CtLNJWfW8UamU?z5FvX+j&q z!(K!Y5>xfvEU%D}w{aKBET)5t$_hfM5MyTY9^6d%1_;(1vDo9L4zRMr)Bw3FSf|sV zhy6yku^6T-YBD9t2UPg|30YeJ%bd-%%VM9|v`G?IaO6IR@W8N7kliKn1(#jgH?t#4 zhc|O2`Jj_Od3!LOSXhkYHQws1GBu_VNTC7G36dD&A?dvxU18H3c~} zyWQ&1Xh)2~M-c`5GDdoHfR{LIaxZ(KU(^HuknGz(pz>@3%A{&;&ql#CQ!8dtv$8ph zij=kn`4(Xe0qhTdezS#khb!C##+S1gwg-V68BFcguuPImw@1x^hc_<3@S>P1HC3C1 zT-iKLTQyC_s}{tt;+QSIY$~Mhrh%gcL9%D0?8tk?#tu@mIgZWb#>^`+xe#53DwMBM z6udjWx-V_&EYlsVO`HW6QX-S0+?nkg{-eJp!~vps#9P(oDH0(RO*9(Vk>mmTxHowT zn0h)0{O8bbYbo`s;5UrL3!1Y?qDNTKa2F*qA4e-mnb|wKw1Tp=L zj4=I>l`ya4Vm~PcImRJBBX%#PkOY(9l~II)^L(?HX+SbmO(6VOJWhG8LB2{i0PTL+ z{d$A%ppFXp2SA_Wudw-_0R2BX_P-MyIR4ZO{%?T(UkxUI0R2DD@$WX8|Gtxj@r!i- z8+`uH&;AFI|5XRb`87@a7bDG|C;$JE$p7mc^&e25<7@ZRzi6bX#?o=zW4rYB75OEb zE}Vtx%db7`yDt!UJnubS~m|Qh=d;qzt@@_ zyIqeb{Tua`>jDFcTINrctPZB0h`>IX`D;rh?e|NF71vt3J#mgqtF7mo%NNy%)n_#% zLIh4euda}tPW&r&*DJPOpDyC__fR=(=9{z5srMQDZ#tj#&m*o^@5bZQar4QFy6!*3 zBsED2P6{^qq&C%q)LQ3V_u^)hO)h@h9EZxfgfRbn>*4(b^y((D|A=|&E6=FfMs=@g zBD2=IgwH1P(r|?}z|U;qU;ZAa#rHi>e@xhMr zd#>Mkp_TJevUq_ZkgXDWpiefQqYNJh(H&shSVzN5XKgXn1ApB>hd)5Mr0p~kEt};aQ!}S-Fcqz*wih+Yk^c``)aI@4oER}Cefpf zt%2HApO^^9k&hxyAQCtQ!|-l+v`s$9PE!zFBNfrqG@Il1B9{G{(HgFKj)WNWMqjyN zB5z6lS?Gy&di8k3WS0zOk&tHMw2_tzaSDEH-2({!uhxqvHvoIfiO>c`&zxG6v3wvU zXya|`^WoqFAW{5`9z!?i#PC5W=5NqQKyuDPLT+=^Z0TlCOv3sUKZFUL9xA{@QKyJK#o&`UKRuB1R=QcJ?v-e8=74; zGZ6IU@iEf$@U_A$8?kVdyPXsjM9Pi>uVQB_t2k8_NNmpfwkO^OXZk4-lOJfM zdQ{NG#{?H=vyUKaqsh^G_oRVPzTYAn$d6UO*ul>gSVRjOxV$hF^L>+6&0hoiD57%n zZY;D5MU%6OMYwa-M?kr6nmEL0@3}u(7Qgxy4wI<5H%+2@icoSFk|hClODwH)H|?G! zYub+{DoteSp5~r6?39{ixSJG}6@t+0L^&)vNBK0s0g9;ki5o)V_@nOHe0DNbB zECI*iV*LOe4uKXN(Kwlx>EEF`rG>jSO2W%PI&k4q%K^$zo*##$`pgqxgp*)|7sBxN z5N9i{Q7U^s>^*^jxwzkR*i>zVO)cv-S@bfj%OF4moEs=n4GEHt1wiN zO(vkvSO#T+>b=Hk>ox@s(I(r1Cv8SmbCP6n@GE5X!iW-AZ6=pFJiqF%DC?euAz%n~ zO8Agfg*+r&s-Upx18!)=xzb3RN&vSUO_-Ez+|P8x?*hN88T*Bm{*v*jQq> z%^{0p7Z`l5zXMJ^>fNO_UsB#l1Udf(Qv~7R1m7Oz0gylHI(3!^htKzz@u8TTR*7Y!6ZA3HUf$)t=(?w-!r3v z08n@q1X#60E|0!AbWPY3d&|ndpan}E{ph25q00_abF{2uaW3_+IMhQfU3u77?nxxchh=hBVy!iOh z>P4NZo?`iaM`#XFRF#muGQt^|F$qy4z85O}<&$$t-(=(R)?%QRaG__oxaAD++-hup zWPy|Ke8sc21|3vShH9+_5n4!1^k$-1xlB!g*L1X&zeM#_jc~!K)*x)E0}xWpJMJwbyfP!JNE;?HffC@~xe9UGDG{2pi+3%{eLOA?% zNj0rIB3U#Q3O~{^cw`yPw`aj%g=wKI;t8ZQmxbJhxR**exoff?JPa_6iBEsv0;)Sr za@_Q_6Rr(nRya#9*Ci;v>06$Bc@`1n+KF5SP(x!)R1lL?Ita}ZEM(Ib>Ne*d13<;= z_F0nX8T=&zn5S~u)xsX`K4ziMcDNIFPuIIB% z?)im-ssM$@n4WAHTG6>(Cd|ckUc+f1MT#i{s3lnfpHP%|3K4Qng5X=h^ai-lC(6dr zSw$K~aaFWKSUI`CukKoMRM7Wbk?>ka5%jQA0%J<0$nt!2V;DbK6l#Oi#&-Zq;ztRp zQ1+lrFZp-3jxIy<$L{XW@4fAW7y_42Efcy2KTElD8rcFE+5v+4&|dZ|GcDsXDYXT) zq9V;L7FSPq(eV08z{v{isJka#^0}&yY`@V+j+lwepxdUYm;m-f@IpK=)QQbmL7;55 zh+h;+BAeYUY}gxsn=PoYd5HShPMHa*r!M>3dgf88a3k%Two#JnKkb8a8G#v`LbaEL zakNNi&4_dUAZP-Opi!3)s+YJx*JOE9BrEMrlAyBPm*3<^wXATtgx#H7V8WH6sOu)~ zNzk0y5UBgMLG3wU{SMyhKBx-=tA4(OD#G2Cli$u>W;};V;tUYt396hk<&#Y~P|vw6 zHC09%sjd_WKIU|Xf1Q!?GcFc2b#^48A!NeA$hoBIvP56!vBzm+J< zbjk2&Ax%`)ZR4l`jMV`H&Ja{01tdAL^*aT%uY!0vyM^z&-e*5NvJ#r#_)O)cN{0_g z3U9mr$2EQMjjKv`1qMeopRk}xm*2|4J!@2mwuZ^k5%Q_C(#<9bmP6dg1AUdTaVTF& zf+ytgr?T`Ei77K9EG)s}q3zwFZ#a~}`ahav{yG-?lS$@JN#O4%nSalw{;wqq&c9l9 z{+ves6hZ#YlJwt77Jrnb{B4l=AIc8@T6*-W+xu^C_>b{}jq_jby{^WbNZ4Szy{t{! zaG*j1_5*<+EB%?IlUePsY%auPe<4q2i_e)_}g zX7k=63~{4=ikd^>q5BD^`6)ePmt?V~@rV4<5~K9@G8BTQV8~#d){Aqb^uz9R(w$D?5qO*!fj|q>nP=urq5r? zwN*djR?M)3+Qvk3pb+ed9cQc91$d)7F%G3mhrw<`dnyDnw5gDg(K{CySc=Gjyn2@1 z6>(*|Vm&mpM-yK2T_aZgO<#8G@bop>SI%?>oWeDc?n;mbYSqu2&umkd0(Y!;t z2svDh)83;&r=g)n5vY;}p+h}oA#;qkL|(uUw!g!iVH+g&zJwbEA`tM%MF2bJxrBqY zDa6|Z((bW8@9Tj^_Ty|GtR=V}>^VW`l$mXSAne)sfh>SH(bk9KY^718nRp1^^o@i_+3xcB~bi;>3^=FLSSD+~SCI8~`*z;fx zBFqFdvgdTNP$dI!hWbu>9EB+P@R=vx!t>I$XhWpNG2 z94Dern?>i0bCdu?0S~+)56s0P0D8sZSE5-6?%SN2Gso<%c)T)qA@H5KtBPQl3SHZ5 z@AciR3m)P!feztz$JslfA$( z;b0++jSeTL{a)cLknvn8;v^7$LSItxpvXRSx}dl|RAY8<)-@d~D9|Fq z?I~a-uX+w7=-}Q;yn|*pghQUHi~=S_{Gq&XC!R3=aUe%%@Db0-*F3adW9yns468>I ztHo$e2yLi74z#t`!-s1r=q~hf=QcB?V|2fU6txt?_)D#2P=7;huT^x5D%J5Ec8@W` z$kxjGDd!YxJwBsXWVUXa$TCvOg~|2i1U!W5g~+cmvU!-n6CZ~fz&`M!n>Hfkfn5n55DYh~1x3t* zNK`$~&%>#x9)kPr+(&s{c2V^Pe0+6H7y$G7Fq6-s_cpXZm&};X7)N5kcman!NQfY}^I?qRzLm zXEN4P>Qyp&zw}Cq$i|Y5PU`y!SuBXgVhn(32oEeqXafC_;KF{6q=W=A+rB3M!jL^b z+r=jPz$ZLNE`=%K>w$BxVk|eSppal&$2CBV`yk_U$5sfF)vWxeCH+BNan2bmS{cGajx&l_i^WNI}YaXz$+aR#( zhqSkAjy&@p;K#q(GSU-XVYUHV2v@)rZiqyMoDXzaz^v@*-P*GJ@#=w#$osky6kt5XXm94*rE=(hw~>dzMq)7 zADnmfPyf&(WJo4cr>QlxKRGRlsqf^kta350zUG(V_pdfDU)rVLa^XOedAb8c`0n_qJXZ1V#3kmkxX%IDSz?7ugeq6z9E7!sBv z8%p4C_ZehCbhuIX^V;^nO)JC8wTq&nQ(2VYa-o8}KMc@N$WS@lb+w>Jxg_67<{e`L z9P3DDNHx}IZeH(7_a60IdYzl=`tS_5QL0!D4cyNm!iR{&&k*ZcQ#8)1?GJU-w(%~e z;*14RT^5XS#@xmf3O)(O>_N0d?#Gg+4ExXc`0#1&?p(`H*lT*qHH?urCFR=UWQZIP zkJjum!VHTSPnW#U#tw31$b=fg~LN@MOxU_l9+KuInF=;KWarnhxZKGcP)><>_f z(M%}Mr1b7TBi%;v_=4v%g@Tl2r3ILP^jVzdFSo4vd_xK|gYqGA%;pXlWR7So1Co^7 zm&5HeL6NtZN3GZl*w?V$r$O~F*C&qvKd`&U^&>QE59kdp0-M1582sbq_u+)y zY_I<56Cz=IBj&|37*Ia{8#D4q^^CFeW`2f0|3ht9Gw|0E9Jz5F7Ge2LeG+BBN|y(* zS@BZ9+5AQV^9PVnL>_;tUnPDhYFy>a*`NbANzzz`o??!jGDB|&&~6{Dh;lbFZg5l? zS4@d1ir&N}hx7wZTcU{lVFeR*Mklf&V#JU!WjUVD6Z6l$xIdP>LFsOnCtn_Z>_(p6 zth!<(Gng%G3JpoEE1xuq(S9Px2eUht*+rfwNnLzuY#Rr~t${kWoAchlGsFv+j)3!Y z3}DV?18Wu%D>D${)n9MAo|mL+ey#yQ(FH2{glR$sL7gJd-_S0SZG~fSsgzW(%orvf zt-`(I79y*OXrc)+wcwO`P#i`K(poYkqDkt}%1YcMOklgE)tUXKm6bk4@mil#q}H^8 zG}H8=!Xo6FO8$0t#+pMEoOCSbg`&X{&fmirdHr4EIiNxrD%f$TCu*6HQeQ*2`iJ&M zsv-&aXdlveM1dT}%{%bX;;mHwUbBiE-q2@&h1X9ni!b?mIo6@ort1}mJM&q^R)xae zcG!G2Ae2)(>Ov<}0hrj*t+vAv6QBKcq0Y+O@hA7r#uD9559&kzAUkU=fdSDfx;q6V{ zdgU?@@+G&BpU6nSZ?VPj@@@GbFeF6&ixJ&*6tk3z^6z)I9`hP;-zqcoS zr4at_>`9z|6-)lW`hT9|UsElZ{(9v9{OtcxEg0#TzP|WhREs}P{{Mz*K`+Y8M8NVj z0Q?d8__|>Dy7)6wLhvsR6#q!iVEG>e6Ta$bHb(zweVmL3s?vSPjLvew#XiGf>#vCd zSv~hBR$vYyRU{(D%#aTTxc=@D{ zoA}UAH3U_P?-Cli#oW)aVO@>5W;@uJyJg#=xO%P^EHGfq_tD`$!p_&b)$QH*dVQv~ z+w*zQn(ceDGj;jC<@;=NH*#sm*R?mKoRW|rL5c5>K+H;uWZGd~*=D+25n8=Jd78IS z-&^8>l1F`HKj`gQUWs=tAyvsDJcYt6c!M@5Y-bfs_C{Q-0GRr_kra;C{#FJvjUDGjga z=>b~rNB8jj-t-)cwH-n&~t%+S% zFmZWS)NDVKzf@HY4xh9kV>vau?#7@?TOgy8X7__C4gC5YY!s|KnEv>B>X3~;lYrhe zM0#u*ov!7DHNm^Y!c zHGlT8?t;olxZynM;-@ApOJPyq-q0J3vrqAb1TpwwT+Qndb# z+&ZDPp{XD}bY|KS?Xjl%wLxjckjsjMjoDj1H!&P|zvKBA=^N@|u%T2wWyE^bA&Ka@ zP);yA$O|?6dkm!qJwSTgt#}l6}OIs@QT5 zsQeaJd;dF33!1k=`Gp2RisJ-OilZ4yJ;9#1Bt^5_$}6fD)6gB$&61?cP64YQwLvh4 z2s3a&jEsp46Y1Bhp06~Cq5B9fBS0ODJA^0h0J1WQ3*b5;IpkB`8U?Tud>w`*eb_8kX?tf-0obK<45hs zAK4Eb*Q*IHw7l_+{&^p85aSFSULF0+SOhNSHL|p@Dy#|9ZsaUl_?A+F+lyAnsp77_ucdk#$DY*|Jrfogc(dX z+_xvl_-1c)oaB%g)bA~<*N}-D)N1k}2iAWx?$vl3M*sFcm40Sc1iV6N`OF0l?k$?1zaCGQs zD2ueZy5+1+$157zUV**K7M4u|z7Wp@ky$Y9vS-orCX39w_m2=reRX`30hs7=J9Hot zST)2xYjgQDQHozSFDFRNor)gi+uX_{W=D+uS38T>SEOv5Q5m@bqD6%G7QdPIy|t)0;ykcgVm-h?#wyd!g); zbY572bHSB>BfPd`UEFj2Vp_MW8Q0+o?l(YJf4uqc8YhgBcbT6h%H zM6cu#9>WRqaY!<+irqQ7?qRnh>IBhp3wwEfEx9 zRZu)XZB2?f6WYW}$tMR$kFbuI0ep`FNf|RRy7B zQ-3Qt*1&VRm2>0*IAvK#gYe4~eseH)3eRp@j_jK^b)PE;hEQ*C6U&9Ssm)PkTqHzA zy#X@STqtqAe0|w94q6csdCs-mY%8-3usiBcs}0qF|0c6ln6F7Vo*=)ICn8mo+UKDse-<7%Lhtgq$kk`M>7%|b&?(Ok@SXu_~4I{>^=Pxw(WLZYk3cNXZ zpxmITr=>>hY=d18J}_E9Ta7jCJl^86fyi~WrPcB+f!FGs-|4Rja`(`Ljk*_wZ_<}u zJ*f+Y$}w=T@!-XL)W$`)#>hH8=7)UTWcx}z<^g-XpI%%p`2rqbeeIPrvHh}IJD3>Q z{PF1z+{p5G&Eo$AG5=R~{L3u=e}$M?8U8an{^vRV9Wnp+?D(JW{;!z#Uoz$YOJJ6j z;UBQ$%#2?d<$u+jqbZfR&w|u*NByFXD}{Y#LrebU##jTE;z#yWf7q^ZkmD|EfZhOQ z?$6zlE;b&sb+5?SHkL?9R{YlEHTvoHb{=V`?mVJyki6>}JL6hHLsfkhl_X-a^mA|L zvX?vm>htlbmcD0)CVMQILQ>~vGRw)Cug~xIy-xf~e2^7x-Az7>Dc3EZ$GtuH$IWw} zmzSHbkgXWKuh*ma87(DW5GXzfb<}Os>)kuB*A|SkYhTJH?~Vt4Id3=1A_vRfqRa2a z2V6LamzvwHdYv7)Jf(=L2GGVk$efXh1aGO+z|AMTvV%E^d~6|y-rTZN{N45yJCVFpEIAzr|~>9eI>a;0sR}KFX{_ZyUBrGdVTz;oQSV2a<@StvcZh;Cf1|4@+LOv}SL0H?rUdifeIyj-gV|AhFILv|5B~nb%(kd~MsdQ* z99&aTOtm;8OA5H^;t4?ZblmFsNUFc&iA4?)D0=owZtC@VXjLzy+qYe?pQF3<*9@tW zcXZ{)4(yNK(v{wy)a{kA=nN5H=l*9mym`dK9Jeae8USb0w?2J7lP3bo$8TzX_YNVQbHUglA~x;Sw9 zp2y*}qjTezFGow-`t^cn?Du%9xkCU-%7$dzvL?26I2rMLfNKrou)3O50>KIwEvs?<~$0~`fJnCdvM|VB=jhVpslh0>Uq}RIrbsKp8 z&YKdOA?v@uD%}i_=zD$J?eRwr7voT$FPawlb-S<3kIS?jxc=OzX$ircY!fDO!t~cRjc=NA=9u+wtKwkDtZoB0sLYWo9!Ukr9T+KVHn#Do; zw`s=mdpVFx-)Y%d?TP}K`K3iSGV5*1VvCHr0{R9{O)%oD9|e*y7Tu-$qyHb?-Z?lD zcIy|7ZQHil$;7s8+cqY)?POw1oQZ8uY-3_gc(dRA?b_eF_rCYM-#K+|RabR&x}VCb zr~8lfTR$vfJuRjmvAH5pI4|Q&Y^=+@0c)Fp4-q$Si-vE#s+v&9d{iF}Mz{{dA)^`! z?Ma8h!<$o=Wuf!!oVUGwJIJdxLp>quj$TB>Sv$03=yR8W;+B421K%*nUfv|q zIxS@5q{8}6O9>(kQDD?jT4Z`X8n6rXo8zN5Tk7c*Qau+j)Js5UR-?!0Q}0{}_Jc*8 z4fLVJMh0*C{;Qe5E|m#K64b0h=s}3D0$8Ln&7LY}MluzMTZ}j1w_Ea7P^_g)bU&&134VvcpVy^~c_Ji0;I$)prMU1l z>GB0skqyzjy?9xarJ=gE^zlmsHTluXNKE>exMZ)giinbawh{z+dgd%(^k73JZ6wij zokV^o{R~S`yY2(GyO5#t=b3kga*dLdzSzRY&O(c~1WXnOPZFeKqNep#gklZaIO%ONUErS?#sUCblK96=UDtWO$2NR9Zambh$r8^4_(;aUs zb1`q+bL&z9bRmBAilImtamvHZDVF}qib=<{*D8tlnT?WH?U}>^%5BlR8KUmlW(?7c z=Dm5LVHmwq*HPz*2%~B^SrM=ogM9678yzotc$R~NFJ$7ROPZEqqoLq=_8<^F?Tcu| zab_hTw-bL0R%_-;{(7fecP?$K&i$>ka647pKic=jdDLVN7D#?H+J39k`=}`c7Yb5c zu{REB3GWp6%f63!@&u%E{I{%Q>S14B8;&4q)Zi@3R+pE|sWIVr$QU-G!z^UhL)Vfn z0?KeGeKg8e^7?iT6jNmCZkp?vtFNqIvnA?q>zG#r?;3%kK!UOA<>*!&CqrY-WKAQn zT=@JQ$aCQJO*98G4|NbdODl2HW0%xVQ%TP>R`N(ab=+~jjGk(WXdt;tb%=LfBIG4~ zn~P2jZjw%#oG6|`iTA=Ksct1kRXUS_Qp;u~wj{Z4ee={yoRh#ervMIzlay{snX0X(xvvY&N{+mX3 zC9hWfg;zeeLf9$V43v`SgCNKYmRnQT$@h-yl5RZTwJP3{ipp$er&s;vvzK7sxIDdq(|%Nprt6ay(TvQ%XU z0a2%4;h1zSue9B86cfboIB0@l`c&0lWbfgP2H=$|YV0)v*h@GK%WlOKw1zCXqMG4* z&RA8O4BEOgf@a~X!Hw(Gi)iVPhG44XQ&1y!2v%n`Dl2Dyh6)K?ld z{CHX+_0Jx!5^RZdPNHjjY&oluLe-T)&JW>BLPqa=J(1uLFCCQ%uubcgLcA!ePA5Bk zUC+!wVh;%J`N(xa60^o3O>sNQ^3OB+xqVn*WiM_60UVw8>a{4C1#daf0Qt%CVG{7> zjcFhrFc}^+wMLn1ImxD%Y3aQ$?w}CT7*Z&Z0NB~EFZuFKl<0r;m-X_eB9SsEusFr`=0t;_(ymrnA19)$?wZw zUBJ9mWFV5fa|2{1MS*Fnwd?oXlP^hzYo`5in>Ums@+52H6h3Q0q^Ox)6$S6HW2EjM;wASryWLL01+Q@3@;fjcO4Zu9ulW=B91! zdln(sXgfAV7u!A0KL|>R9VCZPa(w>&m}xf94@*-~_bL6698hzrUbd=>D7pFUP|6_D z_`M&WRz83a&#eByYJWy;?0-tC|BtBc?;z$+JO?||{~^!8&h#%l$KUJtOFYNl|M|be zw!fH^^k;U0ors<3?^MNK1a$w2o#0^m%R8z5=C=5hJ8g6e#oft-py-1wXL+|CCR*Ab zdbNpVv`J<{W)>RBnXsUjuV%deUKajQea;ClY_G^{0vk;}aNr&0YX zoy=IVCRRzh?7dNwo=+s$-no}03UYOg=iP1ASqU1&bDpe2yvWDXFC2dTkJs_j$+N|< ztxcr6H2tmG^?|UZO8xiSvzN2!O8>X3)HP;$a`Gf42BSh!czTpkk69(h$!Nu>lKlyb z>G{%$vkoM=@^l%|FqX=n#Mwej>~v18UEtW!8ESm~tu$-sMEX^Q4?p2e?v9$&6q`4^ zJv2k1Zn#W2E|}SE@kk(T27kImU5r1ZI+&p+fUM`wG(RbwTNIW*cC4e;bn7x2HZK=U z+;P^aaoR;gcML> ztbu?Zh{$+p4UrR?e32?AcRewP*!$jL76LTgfTs92`k%QHvfXE1{@=+Jcgx`hg|$_z zbr{)4I%#hjfJ?T^93HA?d+6)l($wWosG1rTCeX|g&di}j z7=<13p?eA-XMsPdzCTnv5I}6*Q>1H|jv3kI$yEzoXW-a_^wZ!=@mj* z1~{k8nI?Z(RTfP6KuB%#wqM&;;d|i?Ba^a1H3%NYNNgN98WjB0KRolHP#Rhu z(pd%Iuv=GJHz*JKr?xz7kI1>oPVeUIAB%F3d#E^n8N1HJH5wwx%ZHM|iLTP)pa!%X zvl?GYOY#~XfT{>K)Q?t0Qscl4in#rBi~t=|Yhee*(#h}fm88ClE+sl%;B??aLtW7-4jXD21Vi35`E$*rq|+a{gP%tx|j z64W%+yI-Fw36lD@b!^zYb}VeEt6fU=g}9pXrXG>_Cbw`)AwQpXhFL6Ha~KQi=QRg> z(AU)GkFuODYB$@7L>1XVO44Yh_0hqwH8)>b;yRQ4!-dHHH^Gihn_tACi~=0m>!w3) zb43%5^F=-f4i0c|@-8DNs3_?<6gCF=B-^FSKOZGdPA5-K<7huOzy$=Gl3-IwO2T^I zk#u)F-*M|z8NzS{IcMswcZ9mb8nWSWG2_}`Ue>!sgU78eU0;N=CgUag@%kN zt@6v*fzSS;Z}W%+gV-6Ls)P*Q!`%NR>UiS9AzV5n9VK)GQB}Tfy5tRBs1tTk4q!-f zv6Q{@1rte>W->Z6f<>Arsgl5j{@Z-4=Te&uI6kQ&<83vViOhXyqLh&46t%hkKufOp zoukrc1eMg?#)+IGGyz#QF1W~}%2mZ?^`~8!-{|>!1SGuqT-qYJ2h~BQKGk=NF&8<= z#e~A$43&P-!I0CcZ{cwoA1HwQdu8slA9i89hFmqa*Fy&pAbUP`Af++^jMpsg@j;Rb zQ>N>J?du{u+|AQ~xZ^+&W0AYPlPL#ijAFT7;zgBsTKoqGl8KP+5e8*}O=8LzcC9x97XE7X%TaqTfchFqfN)7Xt zk!E0DC^D-@%N&dl@373`z&c4i*|7}m?ih$tp?(vs$nMIBznRH`MgWOI#qpM!eD(^M zt4%R7vH<>Z59JT%CYL_L_sG0c7-fRRCVEDu7)&Ni8MmK4CP|Z8;ZGmf^WFs3IgEtm z_MKv;mE5BIgwfVL0Y1Q(UNAP!>TZVAYb5B>M1&``F+kPy;M}AG)}H8?fEdgD{?Z#C zUUnhN(Ddp?FR-jwK0}U$f0GkWtah)yF*p`j%MG6hir-k|_+1yiR@njYL#~&xOgfZN z`=@DcQ)t-cvtZXG&c_!@(%0A=)!C%t-WxO$|bCNfi&n zn~tOuHirV24)cwZZv}qaGjY7@Z}{xLI2MUbo{k|J1njjRc|=?w`UShT;5(VY0$^Mp zhX%c;_YoJ&LV5$$MNJ-0{J*LtS&JztLo^kb+xD(l$D4xuXdSAH+~dZ8%zCIoO6)sg0pD)Ycl%apZFq((?EOycp&v{y&wuF}s@xoz;*IH0 z=uKurHTCUY_bC?;*Ml>LncDD_T?03!Fd0T-uY_$oBf+Bsht0Z}J|%gA9wA;dE*3xsiqxTe{quTTjc6)qPwOii^T z`t-jmA3B|N0N3h^VJ}0S=I7HoACO2zT)6*E#;||tW&SD4|9@%g|BZ}cXZjzJG3?BL zPgnY9(kuHP3kd$4^!oR|{i9v~dny0BNw1$!gn|2$Q(@;|V_;$a?A=*DS808+DeRv- z4>QLnE5#^C1ON~*Dibk^+pE|UF^UjT{Uhm>h5By-q|e8H@m1{qn%4UFJNqld5j*q0 zgh>7AC<_-S1J`FX6bly{1KVeD|0=cm`z`Jt-7hm%nJ~;8CpcgBC}M!FH7Y)Q24_PRIy*1KO!J5T}89<3WC(1?D|zn9(^wR0iz{MJA2^71TimfXE} zkMe#v!?_2ATG~usJeSg+h5eEna-8{Mg*UQ2voO+RpM^RJux*3MY;OI|DO;MIAt8(m z?LKe3aUWJzLMuT4!~Nr%MKdp#h`Wo(#@!CeBNzO4DuVR9NYhOcXwB4C(=rOi_LZVc z)|{n7S3za+&V~$npO0(QTp$!_aEVBJH<_ zh7X-+EFN+xPDsl)Sy5HM{Fy!0glfj!fxWiC3TVR%g+fN2k>A#6pj%t*jBg~ zkMQG@q39C1E*dH;e8xcn2w?e9`(IrOv2QK#j%y)(#kw{M8Aw0i89)7j6VUGgO5O{Q zXv^lU0TP}LHd=UfJ$juC5@P~wDxQznE%{LK0z8r%_uJ?m!X%n?1d>f7wM~hOIGPOY z;KU;7RGzp&yU12W`b?22*ib}S zuwnX`O*?>ln{%(Sc4}yOrz-WG{%DDM58pkOvSHCf#+8X@?#*9BBsTy@TGm>N^`K%s z6b6cAiT{9uWM0N{+#@pCx8c%ad$6!u5umbO<@^Tgx#;FvIo^Ig{;KkBE3}yWk$Dqh zRDeQ?puUI^=15XQkELhYix{gr^$NVo27$9xS|Sl7ts6K);TALSNErAKF;sL!jFGF0 zo7=MNnjD&-zzG~t??JsDh1uteVs?Ucp*^r=#6wC7j-Wq@-&JptV9FuY6M%;c7p*Qf zEQS?BVqLy@YCS^a8a~97E4rr(Lfx*MBPmq)w_I%lIHSwElME`Rxv)*!CAR?W zylDn+Ar$^mZR7oK01M>{qfs*ROj2!xi|;3I@hMk$^IAMP%n$I{r>bf!fr&?pHc4TUeLmm21J}Szf~fCe zAZ3MFEK=oWZOw7AHYg?2%~&CK>5#Yz%;VQ#-@b;5U`jieyp{F`FqvElRKe8|uL8kb z#)Fmg8GFu+*JCFhNB>5mQ&XkWQ-mAH(_B@3HQtx?#NL1NuL*UaR!bP}9vn)f28%+U zF_FCC0h{Lrv)?{sf^@~{1=2mhW7XJmy|ZQlO$w5aTQux>wZk=GN%_LK8o%n$Z zDJ&*R+Zi%;)j?hmq@-PP<7yiYSAp9cudp*)39X7Y0Qkk_cnxGolp-4F&7j;~ik`-&XFi#T z`)aNnv>ljdUGszOOx3gKMj!2{;K(#wif;YF$uYMHfASK$>2&nxYvOD>SwFqmnY}k7 z#h{`c50@33H9SNAfZ3Tv_j4$h9;Wb#n=C1jRHs>kpi=_{l`rIQJBYsTdx<=B@^1+J z*jIQR5bh+vKnYug9a4_hPBW#fzxAxyBlXpw8)nXHm4J zV_>C5S9L~xv-$3rzQ&V?M@cENftOWzIIbUcf|r~l{23^8G`BDQ z)Pi}?;~yB!;K^LPc}QrKMWAeqt_wkat}q#Ri0F3yiu_gZ*&S^|jCF12{v^!y=de-! z*W@$$z~syWq%IQDsRaa!{j+TYEv@j%;q&sJlkM#Qv*lQDg>#ofyme|_kVX@f(ZFlBN)@(KE?JFyEie?-$> zNmD0IP)72!IhVzVBOU-$p|1w6fvT!nRetz)Zy7fOQ|MzbFFR~3R|6I-c7rXWUL@;pw_2kwZ zoblK_jvIdc*%nt&V^N>*;=0dmyg?Hnk^uw2ASTZ7wksGz&45I}rkI~!rAD#H=t66Y zJWW^RV1-fVH~;EQ-$zh$`Dk*_)a$av3(2F18F{U-f&G?O7rHY z>%Chght8*dDzJs!7yZ0~-#f$dm2re>-5<{hUSHl`*TxWD-wp3i((?Sh->vU2FZ~QC z)}>(*ponvoR>k+(A}Sr`lp5$}wfO15rCkm!coy|rn3HuVJ*W7FWPQuW9y~{5G|=u= zelFeDlRbUCTbxYQ>L}$$Ucg@uY3|~{g zx49l~6KUVk&`dNvw;VMgDdAP^1U3oR z2DHPua7Lo=>V*_f+{~#S^5J>UaLp)1lS+WBxnx#2u-L~}tXDx^oK09<7QbLyd%Kej z`UJg6s zbOTkOK<~SWq9fq%^{S*0ASq-Sq~|6Cvv8HbUNb-pH31JrLy% zQrq9yc<_O;+AYUY&4S(3&C@%FiCZ(ldvpci0XOx46mvA~PgXMq$I$r)%!&I_ax1tG zx#aGKi-_=+NczkkP^U#lJGHL4YbpOKf+Kn=AV8`ZJ|1D8copBb1N79Y^=)EPaw5Hf zEkP)@#F4uB(|(Z}$u>KdHTTHu;%U)^JWU@dPR=s<%C;{ChMp#wT7k6mz|7#UqY#Zs zty_B%kna>N2-{S&DP7;I{fy16ZP!^UyjMc2?XBsQS>zb&=p53qHu-bf5d-n*8!G8w zasfeLbH&#Sl4;0k&^k^tTOFwhG74O*HN7Q!w0IE4DPe#kuw;CZ4;hi2DrHZTZ?rWX z5rCUp8VE>m2@Us%t^m|DWNX*S@>E(GJ?AzVFTF~M&#ZyHjS;~=I|jv-98tAGcluam zYMJx51q$&B)VwVQs((1OiBUEgbU~~a6>`FHpk35CN0iLOdWMQ8YVmpwa16P3p~B=Z zcQRVuy4%78=(D19`{Qnoe!l+F=GJ;|FY@}@Zo3-Iz{T%T65jch)eq*G@McZNH8Hp3 z%p3=veV!OnmpuKh3B{mG<_yU!R?(*%QBtpj-vS2h%dDsshlZjz&~~DeAk|6FRLd-M zfV8utj61u3sy8|VAlE#8>3owR2|&8>YX0Hw6dEgj4mrodUiaa`N3hFQ0v&!@j}GFD zM8ewzqWSICm&X8IW8czfK_t-oU@Ru8DNfgwTMd_R^=L?wcJEgPwsoiW`f!!aEYF^s zn=l7PdOnxROK|_@OiSEXVVhrY;7Bh(1-5j%4YOazI=y8m3qYd*2>2{@=Uz;tlrE2o zm_)LLE*$;d>y<<}AV0gfNZe3aE?=9*ggLg+%BT#Ylv=6gq7h?Dag=~l+ZP}M@CRJM zRM8Am;6svsZY*!|p8#=5@Z^L0jS`r7Z@AdT1$~XIxW-+4GG)T0FNYU13>21NA!&7h zg^4pN7C@$cNQS;83St6C{@#9i8E2DBExE7UYM{gU@q62d>by-DG@;j;!7dkJ^>zze zC7&l)7pH>;zz(grJ-FQOI$)!+|EP&GB``=p|J#Ya8Fh0ohMJW^az$6ceKXe_gdj;? z(rt`^jBC+23Wk`K*1Q~KuHaJVVuO4jb<(Qjc4V2ky_Ab(ioszlGqEU#opN~xqY_%X z&?@R2` zhQLoS9EU0@hhpM!d#sFAJ3QEVkc9E$>|V4sHvC;%j?sBrxWT~oSkhUM)qlp zycrB9%a{^fJ#LYo61zrHSim&HqjY!66WADg3Ct^lC?R*QKv;wWUT?eh5Lo*R?{ zuhx$8YZ!8TUH|4}wUw^>;#+^UwX`^y#_ovboJYD*qK$(1LZfespRq|AWnjtobURi* zC7OFK#>2?CdRs!{ERo+C)6u{dmCCMkI9AcNA=N6-k*i%n(^>d6bY&e4hK1pi?{#jwIfHWEatUo}mW5BnI2Z#E`GPi%w$+aNNR|i@2u-$cgkAY=+S<#& zt!|J)p+KZ*ixS&0Lv_1$)=Jmu@JcHprF8qdu5$9NDVub-ZDt8Sc<^)dt^mvqr%xxd z-R1Fl6n*l?&MW!W_f{bMaO>B*{pl>3r5n1a?uS6b$LL~D($N9kwp@S)@C561Z(n_D z(PfAeo<}U@Gz(%dLm|u|5Ptc9mAz$Hb1?6^ z3!78N=UrWJzDdt4cgw7#GfQc%VjQrJy;gBG(-ifAlyRp8Kxs))y$3qeX_H67Kb+D{ zBNPr5V>ILw25-f-l@KyW^CVn08J+lgJKj+GVV88G-ka|vx9aH>t|bgC=u6}QC78HE zsO~_D$*3w^IcPA%CY8cwdua}8mmDVi#nlk4)lbVLajNohs{7+9+*wvs_q>#e zfVWe-XS2sq>^yfGd82vv?W9<+L^*f9W+i@VcFMt^oBLd16Q(z(6BMjNCoY#TjYrbd zZaVW|2vgjgCal&|1-g-NW?)ND1Pf*Igi2&4m{43tpI|TZN4d#~g5tJ?3BqEH^IJ)n zf}|Uml1=u;($6}3w6||`Ji~+fa_Xjua`bLkB2X{x0dIx4Xy34o_|WS`^b?`|2YXUo zm-{|yh$#HkG>Z3lpeA%l3mB7J2g|#j8`0Mo(5X1l&GJjMwYZC0>2B87KEV6*uKTQ_ zW2n6oIP8~LhE&4M0WbMxGgnqacZGsS;(%tl)!8((7*Rcs zH=xoTf{GVXa|C(_5Y~ug0x+s}C+q*g$n>rJ*GyiW9F8>V{vHXksh5e7{+P_9( z{NK)oV*dm`|HNJYU>;aM4Lg6){gR{cY31fZ={i!svo$69Dd7{2^1#M=Y+xSfX|Nis zOOzD6n!47fp;Sv&hI*d2<)v6?O7Nzf7HHX;2xz#Cs+rbtCYrVK};c=A6 zHQm5#E|ZPQxmnJJS6&sHMAt3tF%$Rk^xm@Zxu&#QO|y7+@~0`y z^GRCR#wG4S;TOO4x4SdO_1_NNsNR|u_LV9GS?6|@^UIo=&z@X)`W)I>ncplI)=HVP zs-|mrps^>zR|Ty8s@0hreDZLjNWH-38u5yDr(feE9!pmrbsWrrBI)6Gr?LHK5zMy1zbl^NJsch@av zP<10`JJvnpjb3F^6)~h78Wgkn_5f-9d|FO0R6(fWk3BZ*Jg7TdV_q`B;+Gm@wQSED z{bu^*r!MagaNCPQuYE&!22X4;f)^+R_XLerxW&LY6P;}G@+a24jWGp{*4?ZwIM<@a8Htr=D*DumsBk z$BE7jf~SJ}jQDZ`A$h}n2zb6AOmjWpb3Zw(pb{B$&R*twn{7QFH2#ME<;2@aogy-Q z;8%1L9_VU-zlpj7@$zD&KaM>|^2{n}3#oQZQl5ozY9d|r(h8iPd?d|ouwIto0by1~ z^Kog+2SM9mV2V}Obu;z=tSZaBOMYg7C=RxaxPBV@%IB6wK+cXWYU_Y!^L4o3qH-_a z&JnK&o)FTzbk88z5VQ|3g!YAjj|Fj2;Y*W;od~@sWkuPi?&Pi^qhOag2dw}8prPSD zP&MjMA+}_>csoJ!8fT@Hp}ARO&T!tBE>GRjUZpCrFG*>I;HL}?C^9=Aq`~kP-m`;O>MkH9NV$0WE2g>T4jA%hyz&4n%z2onHz-T8B5s-h?VMzBN+2 z2I;F!o6m|iAQnG`0CnN{Oqwn2JtdjTyoSg#IL$E>Gu3D{f`?)?UR030}eaoB>YbsU|oL5Opp*_Y=wga^41fBtRJ zy|JS)tRamuzPv}&a_E=N?kjFeE#h2(LBN;Dg^DpJ0D5jp!C9{+;^Jz$)%mvG^ z;Kf{pn7^hy5lP)g$?!tX*ph&#Bf~0Ft&a#9Am16M!H-7(j>Bo}I^^$Vi}6K--Uw@9 zn(J&1Mpgg1{xs$k%kG!9TZ&BcYS0m8{N0F;+eg(z-Q6K)GY$dI0S%jUL3^FvZ zC3Pw+VSQ*Tbja^Hb~HjI9QSq15Z4`AyZCK1P{gBnhLOiB&kC*9*4sIU34ca6Khrp_ z%M7w-qF zl(-WRiOHo3&nYDfc>1-e)&sMp`}& zhTVrImNbYBRqGBC^yr>Ex49Oqhfy(*9wI-(ZljS6wZplr#qFu9LXiI1CPsn zHoil{xW*ZCZ@$eUJ#Sggx}3AITl$wVcF6CR_UIqK zDNC<4u}u7)7K{*4jr3vf=i)jiL_T;F$|!p@d(9!yvZgGb z)rwabjrhD`4XEV4%o)YXCf8!kdOEZrbxt6B%lc5{!9`l;o)@H=W>VdvhHJZ^5 z&AahWkxVg_W~8%#K8ceAg85h0efy!`j<-7<-o5r*^03u|lZPi1v`QHpCQ>Dy1@;^r zSz9OxH!e+6(GncAxvwrQTG9#RAEWRbGB^E)sx*cx_Cgh#WcM@oM=D^l5w&njy+@<6xVrtepv-M!N1al4 ztC2{nsmRW^aHq~p-PPBZ=B1t6lVaL+NuB<<#53X5TVFN}PkynUdr|vTwM=5mcBt_;ocT3N#LkIZ@y$4NetEO`b&B5J8rgH~)M)FkRp=lFD zl$x#QDzd3|Zk=JGIMygCXDwMKnm^x9zJ%C(*_W8ru%U((9&e4QUls@b{rLBtIRYvv zm?rqe!w{k?8K|rAGpK^_=W#U-7hb1)b4;#M&j3IV^rqsP{TYP^MPp|K{Ei9`&NGPL z+l=x&0d2<&nV+0`UM^znu(Y=AnVn!DBQ4kIjYAC&fGiddVXLlW*300ec43A6NZf>q z+XJFvx$&oB{u*Ew&03nwqlBk0tyyZNN$N1rZM!`#)T;d&ZpRQO_yn# zc$x`~1-(CeqegpwAj$$qEY*z%mz`%SL)Izbv`*69?=@=xT<#JXv-IA!?H47>OOH6o zNNx4&g0EE;sV+7Nr=_CF9<8yDi6}o^-eT8`rD4#_@U5Yu@8qQG8~ikh-UdspVP+>T zg72G=an)6qTw=GYL$;}9F8GT3eOkAy+xB8-Fs4kUyWFxv!njZ=9$_69+)!DfX|Uab zuLy1ayXM6mq>)3=`6@NckWzWD&aVg4Su_&mC0Sxt?CaCbUh6eH{i#mWb<23lgK_D# ze5=~~`nw|ACbxHODuaX=`lf0}Xg)>AA1zK-h-EqQZZqje?=wj5LFfuacWfM z_e>XZ_za}kVBs1fd77&C(T%46oog*7>aPEL_45)|qmw7wzH3g2!)U~Z#9Z^CR{oSV zYgYBQlb;fR0P4;JE8LJU5xrSgD+x7Twv=0(qt#09mAJR;m7wtrGrlei=W>-l#PCD6zyf*crn$ZmfYP2nYL_ZJ;6jTS#jHNHECI zkJJ;^pG6_@B7{LT(jN0c=~~Y^+(DIVQiN+A95KLxMHqz*QWD7WAR&pa z4J9CNhevxKO{drr6WqwtagthS_OgYwXNA5$IV74X)Od| z`a8EPTh`5YJbAFoq3Ne#3U&c!O5rZ(ORA;cPXk4JN^Q~EcnzCD879V}feG=(Lf(n( z2V)26Ol&5$Gt`zyQ={Y=0QxT$ErA7SsU=u~- zBh2)cR~l}4Z&W3r%U_ETA5L*kL)8_8U07~0=u(VKlmVdBNwqJlR&{0A2{8qjKR|fN zeMg37!cXa>U~jmJ!_ur9h!v}b>957&vTkwDLer_d8Iu8dUc?ARn7c~{2cGAUEzIi; z-0rrwhJHI%br<2DY#G2_!Qb#`F+{53#P>TYp=YmrCd|a5YIsz%x#G>i#vt%Ul@_PHy&wEKhvA!@R~HSS;-NaBmOiG~&ZKF8d*BkJ@~>7L;-v;# z$VB>_l=8o~!PeoLl(0ct$5`#g>3WJ7CjX$i(a3yxzUt)&LA2N>g`(a&jT!T~7hAE0 z_At5^jwpBr235QVee^86};uLMP1YAhbdx@-x@z6I80lg4NwGiS700og;E)c#|y}297;KU7d=)$WkA8Jkk5)*LwHvGEsyk@;pI5!0cy@kfE zsdjL4S1ti4Go?J(GtYAHex*d3hKLe~agSJy>p~1S=kN#smpO)40QR6{|%; zxk_mU{fU`>4aP{_6qF{&8;O2C^t8&*&~gzz-6}vdKyIUb2FD`pd#xQ6ypi}jDm(+q zS>R~exvfYogeyJR?Yg4go7ow7qRrVAuPE(4%NTjhGL>@$TDxc$DfTH3V_AoKM8sfF zCjdPk4x>j;qfuPNO1qf98RDM4vdlwrh+&Sec<^OMc~Tc43O3CzVd3_=!03r#w+AgU zNW?2n9TPj~BSj3ZoK>#>3COX`ai>lWWAoXkgR8!pTq(ck7Vd`tTydM4bz{D40c zxLw{5h8qoAtqV#cdO~49sLzL%+ov;nW*}t9oHZ2hEd+Rj%aeMy@p@8U1GxuUzyz`? zbfk46pv}yM@;n@kyhX_ij4ML(;8uzUcB1!6AIo5z(7G>=#gHv#&idH-GzkUuFrjcc zbn=L0#sH8b4=$b<>^_tE`b9|RgS&0?0b};Pj7XdDrUi=SDkExY&l`-}uHJy#?wMu(Ls|1L zdjCJ(`$yycf2Q|mBPKG(f5v$K4Ls(!v^;bvfCW&5Ai_3t3*uWol>XZgQA!Ds#N z=BAZ=*&jV+o=wIoLCG;4*k{qS zP12u_X7tm3yW2p_hIeoJZv=g66Xgugl_U}n zVMmhfEas6r-1kL&u&ZWlGQ=A%tf2hUe`$a8S+rBH?RW6ZenIcgh9++)1-K~X{TSG{cOP9@!?5{<~ zN<9DaB9AbY)xMhgbTNyvz@o{LfjpR4k}q<^&&;1J4j2Cau=bA8fvxMZaBSO7I!-#a zt&VNmwrzE6cWm3XZ5tim>~+39_S(4PTj!kncaHIn`Of*Ps-CKPqy*u0dC$xvfPoi! zCfD>;ETgSGJ!#js#{`T|++A+x3@$q1AEQcbySA2~t#!Z2H(I~fls;M4?9DG08}AK0 z^t^Z8m_S5=ufKfw!u=UkqnfiV11WQ0Ca~sBvf!%kZm^47To;8E`FsX!3B2o<5&NsI0%Rm7E$s z7z|r^w@|FkU5dR?9UrrZ5D1e=HX~W=eP7_o#)H=-8mYZM^ZvoR?1NGGJA`}NU+VLG z(e8>E57=x+toa&f$P9Oz0D@pim`G+p@9y<3*GV+o4$i9ujiG%E448Xy0*|mv+MJQa za|~*M2W_HKRWx`=IJSC|;K7BpNn{34aP=PUL6e&@M5FxV;<(y6`huOf7>~!vxW<74 z{|Hc$n;K_(+VE_SeiVwFiv4Pi0kNG<;YL%8^BVX-ufc%G}CypV#L z*uWOy`1{;wVBdms0t&&~(8hDiaJL@F3)vIbmVKF0D;Huawom|LkF7vYh<*&#P+P_6 zdu_(|O}M1)oW0dtq|m~n8Jg(kBa;#)FY+iPSBF*9kD$XDW)pWDhUP}=@axFEU%G9Z z=m~fxX=15EgDalwcoN<#SK;7Yf}|I7kxlIqoY~G<$tN@HkW*(6TD8G91ZsWMBsIl( ze#`e<+>z$2cauNgx0M*yYTZ{K*uw>$&?vl3!=+c$yK)jgWyvhA6(05ZQ|evsJrIJ$9$ahp`hcX7w*wOC z;Lv_T@q}7QZfb`!P#(A?<}UC>!ZJ-(T(Du^b5oysyzEEh8v1;PAilJO@6Q2?4<-bd zBL}f{!vXS)&F?5faX*o}aaoZ+;nASnirmQ=OCA*lRVmXs&jb3#uYltr-Gi6K8Z6S! zDpN0!O{zZJ5kOvjbSLM#2QUXIRr&tu5rREXecLD92MTgU)pfzYM}~JrxRbX54nk)0 zgt(6Cjq^mf4c*m)05H*!t%wfVr^Ahk3b7`=7^gBM#sXx4PdxB)W*9jh2*Gj2C3Hx% zKYc66j!BrY@5vz`8yqS2u&2};hl+XR47U`oJehq)e_{NC!6F@}p{dW8n z`FAf!y=+QO&9OciquO~sZJ992fpK3jni^lpnbsT8^Rn6oNXg7iNl%>qqb9NU-LoP#UG2$pABbQ% zhq6`+@Nqesw>)*W_{(0n#3G)R_Ux5{;Oxq^$=%73+lMZ!`Es;``rX`%0j0IaR$wbC3{2#H?zhq?pYu@!Qi2e_~|LR zk-U+Mdw75-Lbx{kVO!k+^6Rjxms4epKvG5vi{w84~5Ki8e*Wjgd;n>J{YB%;PMb8Q`4s4LP`Am$Ws1UC@Rp*|rF|&|TMU z48#owT*ak;(Pw~Mxl3R?Q0;eD7!5xlc)E(Ds4|VgfEv-KOoCYf7V}c z<_tbok4nRSU0zI62}WtV6xp!O*oL!qW4&e zCd<@a!GL-%xV9r#Dh1ZpVn`%A=)TQD-GsxH%xwywUJr|`zLbC;KWBU zX`JA|xoF%6ZhR=yV^e*eXT_fQ;lqWNxJsm}B^)$NCO8OBngVM4V-IdL|<xI?1JL5)fKV~*{ zUUNZfjLg8w@^UJ_5QM15qs5iTNpi^lY~M}a40moVaG+PPFzeXYlA{ppdOm2(GZ$Dd zz+pasa_?B+crnbPXj#$!z1}_`FxhItzV0bO&Tu-)Y2|L4ICO+XN|k@7rD}(Yqm7cj zf=ypXb5sc$0<}oanYc=pgEHc$Px7R4-O8F_GIm5Vo#0b@S_<)X9D9=1uXt+Oih+e* z3W`^R1(>lB2r*3&>?o|!Tz|vjQQ|x9?f9xqp1zjeb2m+$aHj@ju_=-OssTyEG0TE` zecbj{0%{7m?G)6FBZE=UARLczLCQkQIJqo;nI4=k;|(WkMze}~`Z|Q8N?OwNlVhZU z$q&pkcEKIl9{luN+x0^cEZcbC`;XB0&>v{Ok9B{TT(TX4@Qi-H&UB3$ruUmdFiSM^ zJ(2y1041u**{Kl$Y#^aoq0f2B>a2MT(UGUu3FFL^_62P_)@1T#n_R@elicj@V;7;(eHik#D2kO?$@6?Gvh_-gkDI{8+dgS9IV^JgK8AB7KY z8Z2qMrf`E}C0O)UAEnVt{In%8c`RH5?#Tw`(@SaEzV=JZ4l4xhkc8uMBK1eb*>+&g za9d|HZc0 z${&fDv?13TuWJLxJ^}&9gL25W1?fOxH4f012(-aXA9#)z$Zk!8UtDl3;oXe!+mCQt zEm+{!UM>YGpN9-&Hy`T|3?`EiC>W`+I1uT)U0u64w7?YNg+RQ`0eEpZM5vLFs;@?TM|af-u@av8X%?cHM+=}KJr>3t^{J~WCsVp5 zL|g@Op*RIXzDHg}?&7`v8w>vL*P!{?+fk$AT5Jepa$pL*DCvYR4|P#>^fSoyZQ9{K z?X+&V#t&aRs6uKiT#3QBrhQvDdE`>be1SR=W$k>sPsSW4`vZ~WuQ8@?-qkl1XP4a|ve?V99)bSdj=;jTH zi{Fc_fDFx@w?Tl514Z`SXsJ3$m^VsTsbhdx(1HX#Nw}}%Z4$Yb-OXwoNN^fAaR-^x z-DRR2yD<-Ln!L`Txr$rl?zVIOPw7&V{6v7xBBNvT1?t?2ORZ`0^$c!`Y9Wd*(qMdP z(jD9`&&K{Ejc7X5wv`aWrSsW`R!M1P8<9wsE=zu6c1__shuDmAc<$Ql7dQ+eEN!kj zIQZ5ruH^+knLIWFjRag=k2QeY0tj&s9foVE(gTdhm~V3XdBt+rYf{PSSokGVgCz#F zPgvxGETH*P3&*4pJA~qDAd@o|$u1+afZ~5i69KS<12eL1)pl>M*G>~_ZMT6?(hpIo z&#Hp(&Og8oZzu%wAwS7V;oBxlKhyLDm}|qYfQ{_;ziEjaX6&nJu${(!XWCXGc&5GpdWk0kkJCB3Xi*%7i;#>)F@`_&AL}b+AO5yl}_O3)~E2Skj;rUNu8TX`-h*76hoxuowAjCRDfpRlK_eiL4J{%2xQ} z99r|tLTw{r3e0p*awz2wpC|bHc(&5;sV#aiaiJR_rk87QK-`ZA=ZvmH@1+OClRS-G zQqel2(!SOtKWWl7s9kaKY>vCz-4-DvhNaMbzhvl461S||(FD?8n}b{)HbK%`F}T7} zK7<$rH^#4V6%l`bY7uVmBRXvmKq%FOkg%F-mMJ>b`PP|DqGmYC7^OC~+pQPzqB_%I zCS`{s{OkEU7$>Mh&R36A9L5G&dZ1%gMZITTCKG6SaA3y`9M-oTF7VJKf0DY|8&~%E@nkrFV0t`17Tx=H6Y5MNm{kmlM z>V|fL;={~JARn~1B#ar(T#4GnFsT# zsG#R&jIlh`tLY@A%mPprZco*)*;@poFEdU_gk`A}n-mJs*_gYN_6lp@)&GEB#`Cbp zuta+^TRp5gL8Jh$?x?qO`|e{PCnF5umGv>*i)RI-LkU&(`E#99YWUNV+&HNf?^)L+ zb$sHCCQ_!AZ_VSfSMC)bx&G*g^cX|-6ZV9t0Ret;V64(+li6?JGBn@8e^;>YhQf+% zDB@nYQtJUPRevOI{HvYRp^u80J51xsh#J5X|MCg{11!Gk0{=hZ=|78+{}(*{hqC$S z<+#j@e~V^*LF~V_9G98tZ;lfAKexDiA>Dsq&Oh+brFgl>jnEN&lXj%)1ZSwlnj zfo$saymi6r?M@fer7%bt8GlZcCvEfb@zQkB7V{IEG=VSpXF5|{Pl!%c6F!|0*4u~i z>rQsp?CwJw%}sij+a88>BE($EmY2r)_4Cy4;#L%XNG>GQl(8rX^OPo5Y2kvk&eesY zOZBu(tw9d*GzBBm&Z{=!s9<1TJFoX>FfS*C^xRXojy@esoL>e@yhs;@r;owGpzrls zuS>GHHgv4EwUu;O?Z^-Y#EvD**&nh^uGfJ5xrGpozl~D|{7z)vC!-T`h|!dE>Pf5c zS{3^Ce$~&|pLKU&=z&s@-VV*W(l+)Yp-CYd>@u+`q6BT$uV0b-K;O?GK z!ouM{mtmr};u!NV(Lt{*B@3FwO!1w!&c|%sEQ8}Iwbggs+uKG{YpUjJ1)ar@o9@62HLuEUIU^2wn4K|hy%RBXODVc}I}JNbKl7}G zz?iC({#w8}$S6gGc7HdoNxi}t%O>A5wPD*GG|tIzO9^Y`qTY97in*!b{d}-xaq8f# z-z{4oE-s;N8hctP7-yP`#v<^G+(B^cslllqc!CRbTSgv$R;qlZe@P9Un{MOjfnM=q zwN#FiLn3pY5z#j>o{5xoR*vNq*oEfauV8hWF058i&cv^Q(DOI)B%ayZBk;u=ad>`Z z@l9J3zAmLHgD}Lp_8s(bEu#9-L=BO2Wf0($YaydHR#%7iQ_5Fa%{s$~<7ixU)#E}n zC(KOR9tlyT@Fmxgd6XHFahxrui1qGT3-=DGirWc2ep4P`Ieh|yqWwrEZaA}dDMS#~ zl^^E{tx>WA#CU!VAa0oNw~Z|2F@5q-eb_~g4kQLCLmpOc6IFSAF$yp&zbaK!bSH~Y z0Tw1jCdTu+HmrR3GVIbP1nxj?d>)T&1wE7$a3fD8(XOB&I;~p`432p75AONyauYYz zvqqUZ{kX-TX@H{;S$Z6U$d2rY@7D_TLXM>X!3KPeN2AA@7nl2o%bS6~Za~ z2_v`SPg*|xt|`SV=LZBOWmOSH9|`u3ms{cajOT?q2-b55JtAg|_r)9akP4H-14SV? zzzFC25r-6*feo2#@PNn@)JK~@Nm+#&*besAK5I)D>WO2V&6a+EAo~}92B@?Pu0*aI zuH^GZdZs>WZW0d9kq(o0yNAdu2RC{qFG_CTa#I9^=1@~yNVduCsW8aJM~7~XN$9ng z8DxuKI1KZl72#-yEMLp*S+=6vXo z6mlMb8R)iftywvI>U#GUCcdg1|bFjo>TP|!qk}Vg|XrZ(z+g>tB#m&Ed<9vGEI98(y6JS0(UyZRG&LY5y zW)lr>cmq;Y1f)IZ=z5El1_-fUa!;wM$IW>NJMCpS<5zY{`$j8jo>s9z=s^5I{Wpx zrrcS2Mukdl1)7xBx|j;63FeHK%Ea>&2(HX=H}Xdz+WE3U0A`@8Az?uUASqWCZ9%O* zS~uvnQWhlL-I&yOa7grWJOU6bTC}8yb#6Cxw^hBw9?(j<1EP-GG7rzPWqvf$uT>lO zr8`gVP8_#D;{CYSJp~p&#or#F(u^OZlipDwr?a~Duen8B(oyke5FqQhZB30cbxVcB zmlL*<1Ubsn@*FKA2H8lRMZELAJxAp!Nu`mM}53ZiV)i>|{2UM-Pb#GaEXCHYfC1#&dui!!84sY6JK09- z8EnKM!VCkm*$Fi&5R>f7UePh2aGKc&1ba+Ek$@Zu(Puz4gw;ydJ&f!@se~|JPVG(e zxtV-tfyZd8<)L1$qtJxIx6`BnK#ioxY4+Q}Vmj|%qYvLTu0;?fC5Q=(IiwqU|xs?7dhut5PD2Dltmk=_B-#ZB$h$31> zvzoreVTwa&N^*21q-v8noO3-^g0j0|U1~ltk)oy~KJKq&IKh)@BS;(NnT)!#GnOzK z?q=wr%&C1!PJfae3I5pMwYl^;S$ean@bxvopEz=&iZCiUV1Ul?MW%(YwLPa!^p69) zHsl|z%xMi7R($R0KE?9>rGMV(Iv=;QUjRWC?`ZF!dcT2Fq}`V_8pbs~2l~4{N1HxS ziAY}sBz&niBvqxn$I{XD_4pXG9m<7)sdgG51&yhrbTu5S0nbOHT2yyC|{Av%DyAJQx&L|M%8i5dyU=q<+{XUzb{Fm%e#A1}y zM`P5*73a#yd>vjUn`?mrKAxF5^IGu>&=r(0?ql?f>MfJ&1fF4wQqYdx(k*uR#&cB$ zMW9%OXMy31}NVHgzXGh98#%=yxU0&lD^k-F|yop7i3UTjmAxYxiqiFs};^AFpzt7E+bmg zhgF4Y%M+#0sJVd3x8){*&&`%J$bw>DB)$XE{}MoDW;TyqnH(34$wy zma;NXZ}NS4h`(mRim-8kcx1%*amofY0!3Wy)X8*| zxa-nZ%&CCdyN*c#tx?*xv2%%!tzE6}VZ*d_-e`HZ*Y~JxTlYL+Zh1VB?Y$!KbP;pq z0&nBe^>NEL|HR9Cx!zr6<8t+Rd$;$f)5h!b8NK32Mn98 z!ia&TN3(S3WFi=7X{+}jV*1&~S21+~At<^Ue&$Fu_)9Sy`M;l z!dy=B=Q99!k)+wA)@M*nv?5xgKsRPdA!?JU?f<(uO`y2BxTw6>G{QPnH z5t__qK*=ly66#5aF~*wYC_w_cT4vL_b!DGehq!5mCh~EKWMQdN{qGg^+4(Oml_-bV!)*Z3;#5 zw(Lylriz2v{OGgAQb0Q*%w;G=mVu%SqP~69KQ#9?fRmcSJhTv^UQ`uVUqjviVaw2- zjpOxm!)%pTzut|N;Obyw{8ISEf0#2*2wSDUkDwFipp_`iTq(^uIHTKL>Z zg+cYPCz&3({}%fJf2|Ffy!8#jnVaxb83`7H76>27!_jMc*jHYW2v|ZEfd+;=w9akF z5aacXXFM4j3n8_a?PFtB7+MR}=swqVs4x6LtU`gxQ7YzPJJT96q`XXX;yuoF8p0Gb z%9qRxgegzNS3q--Nx+X%NE3)Zgcb#zDxwh<_dZIcHIvi|JX@Pjc@`IVFV~*i0!ig2vmOv);?~UX&eqh!cgs;ip2CT zD;jW13qNj4-dUW`uIPFgS{OE;+)1%b6q{kjAAxwLa4n)Zuk?!-g=$>m;QM~f;cP6? zfiR+c0wh6Vpc|$x?Dae{ezZc7JevJ#KfGMXUR0680TA_>ew-0iky-$2&Jii?3dei{ zcq;eIL%oP6(KnT+= z-&2t)|HSdIUIzak7#L}GgU44_n+OM0SD^?ncX$d2eI`?HkGN_6s{kM+FK#)L%QIKD z8Pi~;&7ds9pt*z$5piI04%OcoO>GkyPZOZ0TEr0mL(KE!s4W!JKy1^`FKUh!5V(af z0=c=wK{Npbm+bo!?FaidbL2Yp)3O`7!ctAVK9r zaM|uDIVvv`nvgb2XP`c=$LX$D)iPr0k|gcG#=T(|H`Vo1cHvr^%#^^YYzJvimr?K< z8&~R$7XV`1{f>z;c=aq;ywV+Yv^Jh~VEjy!8d7?0F?r2x;NQILV`*xDUej;)t3Md0 zi`wgUq8+jmK~XV@dD4+~5obqitxs+I;nJzC{fHkkmQzZwPro1$Imv!V zdk-xo;C}H!%Mh${`)!&);UG5TRTsFHVU^D%F;`OQVZ1C z>pYDXMrFq(AaH%nzzmxChqlRJ?_C=o4t?(ut>*D8D`BuW0nE!7!XWAXSk3$iswv_C zLEWMoODod$gpM92GF7)wQnG4A5hKv)h@5osMSP3`1M;9Ed3f&sqi1{V3TbHM6O zulTX(`tOjn<~vyppTs7kDP~}J2UO?7a!&R`9TrP+&-EY>K*oWJ#lEt;(a({_#WJBo zsu-QLNYck-=~QkBtS8PJ$>+hT)l~h09t}4Va}!1aregzghs)HB%d!bUK?io2NHE3b zV1^Bb;%O9wh`dmPIA?phfBg;dbjNq0lCPUPN;KF|;sf5P9})XT*;e9{0uiO)C&mY5 zf^H3X_Q-0)QR;wdr-LA{A(N&SAA~Y1f-c( zYdz+E**E42$F-MO-<>g_OnUg%I)-d=z(`UZAA|CjEmQ32c+~|jo#R?~ka}u40|@yK z@XC}7rr)X3WwPzNbyJoZUJd;}`@I?^5GGo~Sw0Z*NOekVrx>=$q*4SFH6{p=$rFbR zaJUx`fNk0k*NboX(q>&XHVSTrTVi&pGxn4Q;#zgd6f%JE7q`ois(LZ^&2z)YcNO$G zA4I8rBv`pzM5q-I&gE%G$#VEv7`4jF{J-BptsleuE)T%YOoZ1=S_XqRJTx+P*b8=4 zf1VNN2IFL&Ab1V(R(}?E3G<%xG+0Re78;y+67V2DFeD%K`YC@e?qBIlb1W~MI&b&0 zUTAeq720gixhxk!4+xl(9b0$D#N#V3cGG4nVHe@`a%?~^ve%3D`;1$Lgg1HS7^kg&>)zWYP&^mR8 z& z+^9keyP+b=&;}FAE?*UpE^j@->IvJA_91kQ7I&=I*A1a5zd~N~ z8JO$#J!1SPcsysk*RW{M4y*gJwQP@0e{}Fqd)KCN$NW^l;Nh_nfLks?Sc1T3#t#^f z6bcIro?GSi{tB6Q16~<&OB1za*RpKiT>=yU7$KJHx8b4U3){^**JL&+j+fWpH#$ry zsFX>>ynS0GJ0tuZwi!CX2vr(vp{zRv`MiX<6zDSk_B*b*ns^UlpV}J_7OnZ3(3FJ8 z2Q8J{XVvWJ$X)w-81UqprT)S_2`(WUo!Dj!U6^6QZeks$T^mn7ifzlG^KU#eV8QBx z5VOBkMK>GdeA=<$W6s}X&V(zKIgyS4z*#v?59E-wI{mt77nL4Z0H2b@C}7xYus%2A z6A12^$9*BnFKkqzk?K7*BQCB@I)(DopOFx)4p3;$`0#((b7hgTQ7!`mH`BUQk+)co z*HoqICE7B@idvYu)~0yx;EU?QDylmm{pMSEtP)$g3Xq`NyT*9ehYTG7AV$x-&VwEF zEr(!y+qbC|k=zdr2a&$gbbh6Ff6%FPC(g!VEWhPAOrd zHkxCRt(>xF$k^WH6`TH6s&G2gt=eH^UZ<d(mO>)VNrZa0r%YgSj*aUr&(1fg6Nz2w`7uJZ9w+p$x=3fhUo*6ZquiR}$V&dPM|HxHJ!g# zG~!eFXTs7q8Kc~UcSn5{2{=;(E2~!&3;_^DS-Nd|AcVUgATWUbWI(h)9qpkFP?D^o zh1iqvzEl+3!J24?YV=KnDPssC!)B!Q;48H89{%)f^cBOOS$YrkCpFO=lEc}{ zl}p>1=!Wi*4AgE|R8W3|A0C8DGYe;zCpW~WB?#kuqbx})gaX>v!-1<$;G*}PW<$&k ziMJzSv%94i+=D4@=d*-WE13jEs-x3O#v)`}2uy;`hNwP9w&T7D^RLIp!`~qCrCrYx zOTt|cV^=2DV=N;F4(u_RjC(6c@xbcntfZlxL93fb!)^dQ_Lhw08t>V(8Y-2tg-RXO z)_u|I;Dpg()oG1iJZX)e>_}c7mMBx5b~QX&ip%61oda%1XWP5bXl-fnC3t+MrJ=A* z2Jr~4X3l8ci1UZ(Hjc8>HbC&uj+8nlHPoV@vac{q8d~MuFI+_70MQiNLqG5wS^ zXmMnjI^ zi)>mXFMyu|5-HW7&YrxvXN1gw`_s+BfwYR>RkY15jeLfIGGzx$h%P5=-{!(RA(W4` zkn}6taEoeB0?%kPKm~=)=B^=;JWtzcoY6SnK0o7w{{4IHiNIvX%UCc25@g42{SniPs}WA@F{N5ZhtB z6X4JG2HF0+2Cp^IT%|RUc%Y)ASkPGZm9*bRcz{E;Il%ygL-NRih<8?}pf|tDzs@dz z37GEhyl;;{+|L*%-W(ZIru-Y$wc6L^`RUf;-1HK&GXi{nM<9ycKO znyyYt$JY5Vkk*PMT|VSX&yP{M0vzyx%@!I}m7;sdtWZq2-~ZZf-0Ops-)}TiI3SF) zb29-*y>j>|*k!XpnbSh!@=i7mzv}*AUAJPlAcXI^ZvHaaGQpbmO3T!+=h+cdk)V0q z?0WtR3-7hx7;R8Dq0gA%wfRWw0wNcuZ7MBac#sKpn5#a={0^32(k&$32B%gpQ}!)z z@S~&={asFq8G~2Jb=7#Om5+?Jx-%JusQ^WJoPt&PV7;iI3{~YhB5FK^@Yrq~{zNB4 z3nsgx=M>k-$iFQQ@x+?)F}+)O$;xto3B*>}QN5jE3IunF&;bsCCyORCBVZw&=af z?1-umu|?I)4sQ+b&eF(+s-GC{AKE817h}uU5w`8g>?M8!i!GXJ@^BnGuNd2)Kw~)W zf$uI@aySmDjCK$H5mt5K*`b-k>Q~Uz%g%>XwRCz?VruE?fDc`-gjTZ-G2cA_W+eoi zOQG;dzN2nkR%yQybVIpCY3xagG2}|W>v%FMn@P3r9z1YK+}^j1 zDlA=-Gy^K9mWEVIK)Q7@qf}@R7(YD^BQ_X-evTKDJU=!42@&27p_^o%3pjk(xhIl> zUYNo8fZRkVAV}BX9IA;)%C&)U7MH*4}pobZ-+ZVTDa=5LZKO z6D)~gPZn5vB#$5OX24@lU&W9c9b50WC($|hKAl@?{d89@_@A$L?}srPKAo@p1q#}f zFz@s*HbA@iNUJ1!Cq)%d^1N{~6D%m+NHtO>bG%%Zjd8M@OJz{jK66FC4eC(ixUKij z6JLRZQ{eqry?$viOBI!Kf%S>?X=rZ@!!J2Erb3=)x*3BHnXqZh7wj`V)nz1JrYx3qfgs`^ts+{es;*lhj?v|D+TXOTVvjkEcL{U zdE+nql$A0;iAMpLh)YEBPs*37!PPJR*>av6uJ$NPO73B=<%}rQ39~?;xbXA6HC}0V zjG&E(n_<*Ke`Bf0wVb)GD%MNKd7y>*kv$W_r6-KK)6%w&5fEPbQ}#4y-O(OVoXw7n z_qoQZY(iO>05T1AxP)E_^tfZnr|wl*0;xBO zk*OdrgaSILk=wuwkPhSy4(voNmV-A&)TZewD`L7kjZ_`N`W51OZGX`HcqyAR%#w9* zxUeB~D)huow-ZL)|C2}t{ZrJd6m z6~X2)%z*aue(otTtIx|r6-bEb%HZQ#XBD#(PS0g)KbN38vEZwTRzB?&`91NWgVGl%AjQ6Q7NwO z)9QRyght24w7WKnUtijNIJ~r72H0+dISg0*r3%;Nk5YI#m(Qb~N#!z}bnOL->lkII zM&=6wfCv*_Wj(o!$qLq+o&czogs?@-LWW5(U8Saic615{4I#XaF z;yjAe!@dR***)&`i!^7PLAt;pe~@6D?W2k;dU}Sg)KsJb$tda}(AGny7-0lilJTiA zruy*-n_A?kh}++fhWRx@xt_11;|x;iH94j&uN`UX4~Bx7%Fq*Pi2;|-D$R9HXeZc5V_H@JIIZ0LvZXPi0 zb&3SzOv(8@tG+UqAoMXk|7oTV@WL7rw?^*+>JEFmygC6O7 z0D6kG-3Y4^FBWdFWnn-fu)`Kyv!#*V^$WYUN7@b%H&|(n(R9~#!bsKW_A*USEBHob z0ao`g*6Lnj{wn$j2!dovm7@CY**uH-O`f_US~FQ$ba{HqU+4%;qB<8C7^+O#@E7b; z8`8@L`S9Y)2E8opePRR?^9^)_jVaC~tivO8#vxOV2X!WatireMocDe!V}u?naaj~l zbZcKl4Q`1hq}An?%2UqBHxdYwQ(EN)8qbEj3lhxT5in#RRVDf{GmP|2l2l4)Wo0#b zxKaNWg=FGbd1^>>CW@1Y$}-uNgS?1zFeF1PD3WFr7(Wn|pdc{BGf$2*uW{hOzf&rC@gwmd?L+p2*buc;|YM!jIBpPXtBa zfL|8aU3m8UCWyH-2?x%+78yfDX!q;Otp$g2qhH2Lp9lW}B@(|1#SpJ+(}~r-;grD7 z0XgTeG%GighSfXGph?Q=2r|S`LSw`L`ib6v-|8jE4KPG&kxpB4;+pHf(T) zZ?G)u3U1&&74+~%;rC|iyKGYX*lSSblJkb%*{bJ(OoQU%HU+wY;ABDvoz{9lbHxE` z9j)=bx4X+yrhPWJvk=m&j(;@2vXs5EIwWIL9xcX}vZ2W&Nq@W%RCVu%1dmy(>$)CB zjGNl5${QT>C3*TAee8D8*E)h&6#U<|soM8R#p{dY;!DU@dsxar-#eH=#;2_G0-%c) z!w@$rEWYBd6%+yfgJiC?> zZ*m7=vIzE4ocyQdzCpNf@WY(-TiaknIl=y>#bOD!G2$pt~?NqF>b25>Q9*pHcJtr|qRnNW4Gj$M>qhOAXL6Abb}M|6BbR4_Irm7L@NI=ls+`=dtj1DwKk%W>HaWch4)ZJ^Y8 z^zbG~cipZr(E;u~OP-R4Rgon@;4U|NV>6W~R=*FUyx^!Yw|vqZGH`4VP(?Pp94F#F z%jG&7B?5>|v$3U|6e14f98`!+FI?9+_9HEf z#41!UT_0o5zv60w#yW-xYH8W|p_?-eXKte~BlID}hp}uFop$Y61vr*umLrWGZhOH_ zCZ_%BWA!X|+ev{2es@8Oyr92sL3DND3@!1T7SPYTf4G1FqQ25c9U}WcLqB@aLoKw2Z6--`Uw{nZ8Pd{>|m|$FKhTU-@r}{Qm=&6U(1T)8F|4 z^Ve|WFNP@!)g%-4Sm6Fh7i%pj3rV09?in^JaB3u-E3axWE2ZPiC$BDwBy+h-9o-xO zBM=Ce9*mH%V+M-Fg7EkPyglqpsBDE=eiKTeB6SHl%8c%%mUiI~@1<606Kr|ai8XZL z#rt?zV3q&PSQy?%KH-cg?fx{?^vTZU>C+Trgf)C^U8R88{&{(G{hm4B)w1J&C}_CZ)Ku>D zJ7`Sooz@X?Be%52z zKx?Q{hsq8-%d03u0<%dH?QQEuwSZ8Uc!H`54Yj0WHQpe9fV4l}-1r&aFZ`_yziTKr zYhnn3bWPigV%SKrFVJ8{eLYp$%-5dv+{%Tp&Y2rCvmHVxnyFLqXXR(mAyX!z2h-9k z<0G9-3a@w{n>IKg?p>6h7_zfj&c=n`qZeXufd&B@9)LmHVgw~UkuDt?2f((k7XtZF z02rhhj`0cVpZia zi!<9#b7GQwc3|oZak&WQW;v36N1{95`y0m^SP9-8hl&7;P~ixX3v|L4EwTId>?+ms zwsVMdD>+p&sw&`nqrF&R$QXK${Jo>AQ?`oBdeG->A@MfmlR?+H69E0yC4o<2b7-^# z3bA`6d%#L~NFvjF%h^K#6a0y7-?vLZL!h?Xt^pEM_|e(WJ;{po3T6auGg!&Nx1%KA znAy;c*rk3f?F{aP?CdX|eItl5{c*Sg`m(Ar%_bV)9g8~N}UH2Pl zi7ekQRb_oM15~trlUf1yc)38F!=S;j!O3X9<(PN6+1kwpL2Qj~hx_fTyOvdckuAn1 zMY6~tIgqIY8g7pX49DO*E5lNdj=V})#>TilJt7@Zvig{D&pqXVtx!unnkG<%;A^Vx zyA*$F7N{=U-L@}F{}mIRR!YyfYAT>xC#KZya^>T-)%5@wTR>jpJE%Z)XDSUDq5(Xl zP_hCm!?n6`a5e*RUn|BeUVnmV7{goScYOR4=Z2Mxu06^GPK>q^uE?a#N$eZ5Xm*zr zM(l#;fta8CbK{SQR@%>&S=^CYHs=Tfk0&vNif{^yaK9$VJT!4K+d4lQh<~BM;sYu+ zZ9)056whd?Q4{)l(*D{Wql9%wP4ElQ9VK5qS{>`w?Z#BiqAkmD+nSQ-%4TkHf{d6{ zoz0NjHKk2D-meKz)1k$+Fk9?8AUS~jCT^{)cr8Eo;G43C7(IS- z&Bz%l0?r>y_3rz)MSwvYPJw|9zGG9TfN=tSrg{~+sDw%=Xb3iu((ol}5uM*9wE3<)rXCXre8zxpbVG-H-@nEnBK8eQ@pqbywYT(MkSDcB}bi#e-L@N@2jT} zc5pG<8>j4q>IR?f3@5Vh_+F6uXJMjTD(h<40I+M6DP1?3SvQa9cGK;^T+jb#JjV-N zQC1R1;fz!j)abm$8u=i4dl6WD5ula8z?g*lt)58V5bk6B2=jx1EXsC&3XP8T`8BTJ1cXxN!g2KIUDBRuMp>TJ1 zcXxN!0xn%=zBBzz_ng~j?hRu9;EmYNlY8?Lk!xkHl~$bDRr5j|0Z{ubFBp@a_1Do3 zU3D=wIhR3=co!jWR~NvDR&-Af@OPc?S_8Hrzy~&29bqjo>*_eCq+$R`N7ij_$23dZ*sXm|z#$@Xt(yJl>iG4c9w4?_%%2^=B= zgFQsuyodrIt^U&isaPh9hO`v-%rA3fFLPji(r7;Mh=kpJhmyN`U&apRkK zspLQ#swkyBJj{)3gAs%1C`eo+stE!DP;{)g)O0Pq6wPC*j??xj9I)9=E=2^bdx2RR zmb|FY@HpJ1+1cFR(|a%TetX8;PmUI)w)6u^5L&1ze509>7R@!5l|jC% zH5?Ob0~kz73ioB!uQ``D%s|EQ3p5ZbN}@-TnkfoUo8g+ZFIj!{?zt)kIbZ=U!_j_2 z_A2lC!GsvFIwd2NgEocJfI|SBKBRSDrOJvyjt&#=J-MnaJ-8LH{@ znj{ze?Cj`I+6pvp1g-~2P5t!`!IVZp@%Wjw=ft4=pu!v%xFZ^>kXfLMI z79Rt^J1VV!A8a~zrHrpd*zXbUJ@_V5ph7_%)J18gw=zaAqb}BBCUcc`Z_=2R`ZBIH z&2MQzy=j|(ql)S?e}g4h|LjEn_gLb0dih@n_x~8!^gk9Sf7-|Ydt&}Oj(j z!b%e|&qLkI!T6&G~82g)h{xBT1D~S&~P%E^5L&R{9|BL9;K1;l-d**xWGj zn8N!Ex6!qfoH=Co$vrFwkTxaF*CUhdxi4pGKxXvRFf2hiXKpxM?b=Cq@RvJwg`1vV zE)wz`x^>sd0jE#k=R8E6a{phPwv8Oq-YIx4jIgwGr=<=$XmegYh{(Sp`635)@#lMW zkEo^jnau+&SH@?pqo}o%{R_e)Dr{D2@>tXNL}~PaZojij zF~KS1k+*h~-gbO-&1&FQ)6r}2sS-ZgvZc^VOzS~YeGdke6So}&j81%itUl30CKvI; z$&Cx2lD8*JT)a_@b;O~u5E!ZH9iPeOewZgyws!MeE+B+x45yXG0QQkjl!jz|qoE7k zhKr9S51&~|`3OvdU+i#iQB`$F$qY~Kcf=-)D%`dxYG|G&o*}DnGzHq}k*0sqzEA4+ zGn#GK&%Dx?PBuTctS2Is(NVs~OiU)n_!F2TX z);*VdUqwo~ywgHiXEs4tbJ&2a%lf()_(%nM zT?3;EyMWFiLD1|elbdv1Tf~p>798hFNBL}_$q}{u@Y^C_+$0ILEi^| zC7mPgNRoAxz!qkJVHMJ0KMEhxGKv4-s%ROtU6DTHgi>K%fLib0IoXV%cO_4uj1?~A zbnVMY+L&g@BS;xcpreR<66cqMqvr;ahD>vIs@<|5ZQTqBumyDVD1}NgH$pB9xr-1{ z><%Ty5(qo*Kj2^9%}V~XFwar3i+%_i_!Tc9T=Wad(w2r@O>Df)89M9+KC^QzZ*tXP zdDg>uu>!08tM7o)tb26R?jilBq1(=|9&7DnRu^o3@wp#8BojfWIwEP#SYapv$G4;a z4fDdUm%0+ zzF^Ybs#-*2MwmIWiQM8W_kq(H{veLI_j5KK zJRtjOU2d%@t5U z;R4L4bsj|GTPt*EA(qr`#)%W-emZFkjO2RJ;|@;7jG%PcF7sw#J>qdCZdHW}#a=7F zg8LC>iduS%w#_UtQqo5*Jhpj|WdhDebE7FT*`52`%>OuVCHyh}83^+Xqi!6uVJM_VFp9g|F(as^=* zxST28DJ4(&_qecF%T{5D>S}XS)}!dlp@18$?|``)iCFVh@tIk4#j5VFcLy6oMax=F zSGR{)8B(1r&<~WUovpKJ*o>Hz(Ry8xU3d#|^+RVuoUqihxBRe9k5MIk5PwA5UA?{H z(I*c0zHAHC`X}H1YFy`y%xyMaPb33UDiH*nFi*iPrwG93jfRenQbiQ34X~_qqQnS< z)*ht!)jRT*@^ZQPAsJz3=5b%_)*u4+?mz=K-qXQ`y?PR3ZzcdkwK0sVLvf^&K>7AHFnH%HtCJwKNCd!q>+*2W@VI;rZ`t)t_G zusLiR*#xDuEQ^W*DTTHcD57s&Yp3m1g%lv@)lRpkqt>_lu6!wb`7Q~ETq45dyFb4O ziB;1VbzU<}XS)M}{d%$goGhHIJ{B8sEA}jIFB%TrHUy&Xyu_Zm#iZT!BNqTwjb}r0c(|&E5~FmH3vxC_R{aFTD8myaZ_*(wk;WiQ zV{Bq0JmRQzHQLR{+ppz8>lB8kGAZ0N!z2$d-~?gToA~nmU!WPxVdD-vA&_G#-w0 zTuNV`am}6pi=I$An8WBapVue?d_{(@f9yCc5w^)iW0<;SD^IBH*~o;;=@c}>n$%OL zdD(73FPx#Ky-N%Ve+KAne?OU=AGNwXyn=6OA=P?3FQc^ZY7axB)s+1POH~-g{Dy{ zqdU*bJFSG_*Jh{~8XlPu=z242o~w-1-65gp@U;!>;oOMXTDINPXGz-@Ur?Ws1hPnC zt@&8KV=3s38#DTI#isz>L57xcrHn~up{VMW8aFg#ho*ym%XmLI-~QAIuPzLX{au>= z2YLT5M)|)<(|_~R|3>+<{$}j|G3Ec+BmUcRNWj|K#?b*^3!mlFQvNTL|L@QKJ(S-Y zpy-sG3?1EUP4MZYEvzk}=mc%-jZN&e{s0*CI&|W65_CdZe=ybbpEmG{pR_%`7Bedw zE$gSA_|vkUmhID_lbM6#lluQ`&i@>J#l-RVHunFooImTIyJh|$?pgnrvVcxqLld9v z(=MM4pN)l$mi@1jwHSV@p#OEWzij=@`7`}tBKq0H{};~x_g(*M?|-6_f7ICjKj8e? z{@k(jFNnhasr3Gb5ap+)UfgOEtoLNmlGx>#2ARSyA|Bn!@3W4i7G%q^-yP2VRSzmy z>Pf_6Cx`b((ee3XV)w0ZU+NGb{I=ln0cKu{2HE)DV^Li+65}O9S_cog;z)lixQLGA zlh3d3UR*RrNM3&2J}u&TBWh4nC}-xkG)YMu9d`b@dmIdce_Yi*iV(kO6b&0+eZ<4# zTZ68B9-NG_`FO|#MNSkRQYvrABl+hUMl_b82s}t%zkFZC9^fg{|9ZYOEW}>1Cno`?-Q+_c%V9ss16$ zG_SIoS^}CU~3NF zr{*sw-X+(93??ha;Ys>pi^}kc-xLgQh`rTEP6~*@@vy_x9a1reFnUJcM)B^Rhr94SPlav&lfPVE$362i>4dn3q8L)1XzG z&3-_;5Y1e{iuM6tpr>}xt${x#c9rApnJ^))zAbtjF`#}bp?&eCV?r7FFG&iA(sJW? zGZ?B_@zSkrBe88Unq370(h(8ut6_-HFU?0%@Cn!_ehj@?_o0kLejy+~66Oe5^lN06 zNJJ-am1E0O6NpbsIO^YDV#QoOhz2A3Ughfq+7N9AuuHad-lHrYgCa`fAr-?ss@JCu zR+S8-9-x8kO&eRo?n9J<(B%j0n$sl@5a#2#U1PPKr)GOslTaprC8+rvJpo&!n{VE) zEk?D&4*7!OTdu+0`&gq&KquS4zM6uL#z2s1XPasDBQ%yKayLH#_Q#8H6Yn!N2+V|e z*G)13TZMFblh3PW8x;BFz#f5a)coN*EkHQ3QpJ9*Q-L(GWU;u~Y)3`eMP$+KP#VS~ z!nU+O$v7gL6R#r7A<)DEVL-`*pnXt1sm0(`$@k3rdC3LudL<+ZP40~OS=$oX)-+U# z+fNScZR6R?)=8tRn7o^{nfACUXbM9=<*oxX=}NBTL{{`_$1KO<+_#J+S0mhyH~xdHh*axPlFQhGzuE>ksmo z=m4J2JdglPKVEdnx;>?OH})j~nDf+~5~Uq;tl6auCr4%Z-K(5}_Jt{vq)kq@dH@f( zj9VRcv`mb(GmufB4*Te)5kF_#xWz}L?Hf90v`knIX*OU2%;F zd+8~)Yo6ZJ_-K;(o1N|sduiTNcQi@+onFMt-^wUZuS0U`okiHk1fp#_6R9K{nr@Fi zwXj+hV6(biltCjDm5NHghmp*g6nadf>{F?2dt8&oy|RMx=!;EqVh6i^<%WI>_Wr2S z;=RROB3F|_uNMI=1N56e^81|f%?6<0!gB^wf%&*PmL^q{!o@YzHm{EO!w>v>UCtmC zxk*2kSrTsJ!P(3%3@{H%Irf5&alNwyX~uR-+-Z0t{u0$Vzl{)Sggs?sZpe2jS}gMe z6B_{|IUpvsE_@CQFly`o;Ig~Hca{jMhDn29ytt?RAgLZHo17oV&#)mMoL`zy97l@^ ziwA8lrI*rKeTrN2y3Fb8@P&NQ8?5){jYfNJmgIAW<)6O5pnBxkdL{>R@*|2oy7O5f z6-ZL6M*}{gJUlE%-oLAcsvgt}(Zq4XPHL84)D+4UNyNz3A5N*z=DqF(+f>MmqKIO? z7i=X#Y3WHXh`q3{5Iy+4p}$~1&Wqn5&{Y&wq&jC;ll^*UT$wTfHg)I&=Ou9RXRvyX z*G`>YH*IRllUo8TqQ>f$m-^9X_E3#Yn?()_UtJ<4wqP zyvwcLVX$ujh~8m!o!Z=35p!kjgKszm$|78wW5LyD7L>Ec5A;wA?vQUSY)6*wuQJ5_ z!Ymg3;WHtbv)4`0%nV#PFbT0(AWI^meA0o~qea(xRAO|cp99HFPvHX&452G%@?dL8y=d0oI1B;(HkamCu4$lMG?sc1nw;EI9!zyZu=w~OtIgRywXO*+a zD6bmu7bQHa`P+(2i>vik@9RR*A-1;1Mk3e?s)adcDe5iuhSuX8f==MJ?G7RzxB~%vj_+2M6p7vJBRqSvt=5INse!zmin?F6g-b)0U>I>BVuGn+1I8vVvfX zlOe+eoWcXyHs#|OlpWaj2g*uBK$t}I@wpUmhS#LSuv6 zD~1#S!GPmW50;n|;@}vFl$Dz-8naR#$1^;sagR;S@kY3Lm;0|7#hxNQp#vU$mljB~ch zn9B5B`&Z7YXs!oy@d@4CKEq`iUl+R~%&m?j7_RAjDU5lTCf(t+-L9tluF9f63_u`O zs91;YJUJiNWZ|h1K@q>2gBdD8=>N2T;lvVg*jz!Djd)VFQ@(`lPsrNN=jT`mJvg_HkT>B$owjL}6rSloa^4QB;-eM6~-MwXLcWj{s z=F!$oK<*v2b~Um&Xh1JcRM+o#aonI`$lhB>~c5A=;EdTrc5@#W_Lihi~f1Zz@lC|0|^bF#`LXjle?z6^i+@rHP&8^Y>3=_KE)fj|02@(rxuS)_*~u|BrF8e$F@J;J|12lx?$r zB1C334qCQP*);>pXOkE^9zms-v4mB zVq|BbW#IT5O!)g-@UIvDCno$ym8$;m)9MqObEiemn%u!MJrpec=O_A5?WyWgt4MV0JwYuSbOz#@47@& z+k6whf-zFImo*K0)leYR9D^E&rhc}nPVt<8=s9xNg@~o8uzQ$2zfX@Pd{u!`L0E>* zs@T4Hlfy%6yhQKxXkn?xbak~Qo&Kt`puIbRc`g7`%V{EnVw8ZXERL=TERHz zWO$Bwe(~F?icFX?wOV6XnT;9-(3ly$lwhu6YzjFCq2SoUYuTjU%`zC4cjkU@qWwdD z>xG%HEipsTjkUAO{UZfJ3K5_Z9)Rx!3-L!RoM6=LwL2W$ z{HQ>58-G56&DNz+JUt-eI0gh=4loYf4&8jt*TmMOZ6&Z5X%QKbNQf_to9pYcRf!<` zv4sXEZjq9TFc#iT18ymAyNgL{;f%`hj99?y9*&Q5Wt`rV02{r#`Os)Wc!9mVD$Mz`az0_0mhK*605)w81V~?d$2Ja zyTh3C#jM1^gS|v^bzKVcc zwB0#F*n~FJS5l?2v@$WxyJq=PYkW#cuJ?&&bbkK37{Lv@aAk z*)9e|*^U%}AYmc~E6%INB4zPTa92j~Cfqhly8fAN&s#NHS#%%~kPDI*SAg2pDnXkM zC?MoDJE)j}I;37W;!G7naMA;gcq^<0JEqqXL0bH&bjgVQyn$FHm`$o?zF(%uiuTe+vcrfN zy1&U1qW0w<+EXUbgYGMXj_#Og&H6USFg#B~!1LMzc!aZ{XXa27%p(gLU29LBIsjF2S`CRwQ38erNf zev7R&liySK?kmD={asAp&KYlTTu}m@_WLp7D)xfuQKRSdhOzp$xQ$1N+pvjJlIUE8 zI;4B32%u5-Ky8MSDO}%n_k-E=$BFCGiAF^0^v5L(566l7NQiS|%4KKUHqsC?Z8wZf zBJHsr32d+fuMhSy0BveweF@hN(=ou?QUVv<9mc*~nPTaljx*SFrAfGEuno3VerJOH zd4J%e>W18TG0xmKkOsUl%UpSD8cx>61|8|T7DS?eu#l1@7!a-zf5p7b+tyEPJcd#? zkwml-O{X-)sTFB1)F91&s>6}{d0@~oCX+0clvohy&jY*H$bC;OywCJ##cU%1P*>6oN3<{43P!!CHJARpte#UVjvd%#M##$B&jap_qO@%!6K(h~eBP$ngGB<9 zMOTVM@K2W4wjv8%n{fy^R~trOVa&(V3U-*&@y{>E21w=J+#4ZOZ8Tfl6{k(4tI)>h zGuu9&>Ba`%o4B9{c zdxp}K@oCp5d+6cam_Eb#+`2bT+%}O$v=Pmwbmji}Y~T%P!PBJ zJY{)}rC*oJ=W*ayD>PjO3tN1@27eqIK;JWduWEO0)pYu<=v^Ao-L>;L-@t@(GSH@& zdn!E#x^uN)WSt}kuCuCCFn$9-E*xCG{@(c2M)~I)Q_jhlba8AJq{H#9`MQ%d-3}Z7!1tv5OZVO%!-z$_gyj;Rm@OPiOVPE zfDP+eXEZ@AX;@(z(OB%^#v(CJ^=?06mP5g{s}o!D~q~hIkr+n9foVZ!Kez_{L3r$+YdMdN*G% z>4+z4)>3AM6UcY{6FxiY0a5`UW_S~qe{-=@21kjkiYbHZ-sAZVg|rx+6>un2o*#Rb z=`P*hIgLd6@K%P%K#;>|IZMU~{KfjROjL(q>Rvlcy#5I$2P=K3$aF@D-zP4@RXkAH3?r4Q7YKTEg8*I z&7;JWD^@(bz%u18uKK!p!dwD0U9UQb)kmRC(&NWZsqz+8XxCmx|1)9D{kwOKblky8 znuiBSoFE^N#OyCFK-bc0Oz6@H{jU+qvqkXUOfp^_(u1?QIVopKm)6p$GpdW@VsRs| zqI?d;stFv9?GhEM{Z}OwjVwXtuE(^EFP|#0>U!rQLRxMm zXzOa8;MHjUlg&s{9wE1R>U*VbZ)V*hHl>Mp2_5)aKEzHw0RZqYb)L#HvHiX;x32m` zpGLNN?>v~qgy+<~N>6SN-FK%F-f0U%Z)Y-u^KQ8}>*CdqMz)$1B~`NXRg*6c zGv2Z_&bN5M4wX}*XkV!A^LDP}k+4lx*ITfvrqHJV?iwe9NGGtu8Dkq^%T8ppU(QFE zZ8|X4g*A)t#VOJTu_IH7WBNbRdx3U>mMexFy=4yrhrKYVU=3 z*ie8qef9ObjXcqBQzE|q;P3+gck8Y;3x%-~*86mfhdbPc7o^x|BJdC8yIyJi;1F z=A_0}R{HtV@%63gb^DEuvRQFNu2){~{Gwu~OD^|_vSC4P=IU#b-rKY-` zmdz5OU2p|^)T_d*_m}O(^})39g`=U_chfIoE3NN$CN8zp)sInG&Wl-m*E>m3T-)g5 z&)@20J-+CCi@4d97sfjs9A{O|d0cIbxXC;rJ+!#G*NNk?X`q}cc|KWRJJ9|3O-uQa{7d`><*C+pQc^zTyqwEGgO|l`yOP;Fp-qjU<~|bFS7x{OI$H5*Kj8!!;_f3g=FRq3LDEGB zSs#GY{K}B{0`-tya;z+E%OTs!MZk-6U2LVvBgK-?HOOXP0GUI07L8SCwJuKr7YSeS zYIg1Q)aDY-%FAxJ=%UV6cRBLZyR%I$HEU*7`@Jv;M&03p&oj1S4zn_EZ%i9o)YLjX*8YLxooCS7e9i#h?=p-7dSZ!(P?H4Fv7^6 zYISX_)ZHB0C^dQyj<&L)sY{UxA*XpJc8p63PpCKFBn+G<vFihSFyAU8~yGd@PPtbSk z#~k2(_xg1;83S+{FR1_UbMmHslD>92`~0gdY!u0`K6az$G7ab&3{c@-y&=*UfE)Te zk&gK?Fu=LEr5^%EN2r8UZR-AN?#9-@qmB@SEgws$0b||_oKHn+^}gm!dg4Bx>C25FIM5G&nAkzTA422_A$?GI?lQbM^iXsIoe}1PlQlCBK zM3&sD$qF~&3qVXF^8*k<^to0C(Vx`kH&~&+KZ zCXu@07&Aky-wkZY^2M%MwC6n8Cs+Ssw@>|2X?(AIWaOpeLhIdF!P~Aq`o~B!HWkne z#1=sew+~7=jHP5;C;hSk5**=`u?PSme;rXL&BuWg2^FyEh8an>5dOO1*syE)0Xs(} zsd)L53rG~bZanZ5aa_B~db5X&Q|bDEevT{k5HIs+>RHDyE}XvT7xhcv4H@kw05}zp zW3fq~_o%~qS2okkM$r9?b=-jH;hmed2}>_u1}LG30ti4jaQ0GNIkD_+01FTcu&M5h zy{D8&dB`LX0>ZV9Ejy;gm5HfP3*f#7)Iz`m@#W$2%1dnkV7&1lAiaQdBDU>_ zFDBzInWnJGyGQs0 zDZ6dANkY`^0d{C+*n5FJT;J~=o)u4R zk&4hb-J3vP&w}`7IhGP$f-b{aIbH8daxw2iPio*qikw8kL*5$^d_!N2CGxH*f)G-< z(|le#j}752N7`!a0WfO8%=Au4mGLwX2@w08c#4Z|<@oD%N}nSss~5`Bt)?Glz%G`< z*cntiMs=VyD6c+h#Hx#QvG&5%(dOH=01~<`Jy0lp*N6mjf9@caNunB5kx}^;?F}x% zpfYToQc(_mG{;bGRnrr$P>$iG5U2!*QhY*rPCmf4elX^DTqg0I!f%olO^gJ{$?2)EcFP2(t}#M^ zujg}Iu*8HLaBaCcETB6MNFjTsQPD>L5;mLned3PV!%-=12PC>kFq0O;KC%{VuKI*f z-HcB>i{o3s0vP;d>zjCc4sL@|ZBgD)XOTfa9mEV~LY{V>Jdb7lU=2<$RX3R_?>$ z0R|wA$Ak_AO@lHspXrN#-I2wevT`hewA6vT=p~~LmFc*SCcD|L0VawR!H26Z2CqMo z2{%Hti0~L&)_^ajNNJA5U2?S(7nxpFQb>1SyyP2Y!kf4Dm`|)}RwY*fq2AHh)|9A} zd?m%ux>Vt<&RSteTJ&rjA-(>F(VhW&)R}t5GG}zJxlZ39aR^n9j;k?uw>7$v(wVkn z#IzK(k#=mr%HavK^JyBkbu|RP6?{0k9-K@G>W@$0D`AFAkSsrN_Q5Sg@|3G>5`bKciZj0mg* zCof-xBXG%1+@-H8bI$jibkr*yvJ?1lq^qKSd7DZ^u~=TzQ^!{mu)tn3dv$PGb<+Kb zfR9pr^ykc?(d01W5Q@?4o+jLE^B5jK8&;rRf;`#uD%@;ylsA5PjBD7v+gI#Tv`QM4 z<(2Ro_23H3l{>_DuDkX;>JH`=-hK27&L-7drZx)l_rx7uu6!`ik$SOjgx_?uU-5p; zd%8c87~nB^1rsHM&6Xs|>ef%})gKUN$gsx<2PgO6-4=l#1hT}4S?Piw-*;gK>FI?A zjT{J;L~@Jl-OyRF%^uHu)_=qX-A-3Phy(%MmX}9>D?yY30R`NJgqR-C-MHBR3owl~ zprPOo`$}rImlT=-8Mm00&yM9FcueaMnp7XDFZ~@34;=&KHF!SqC@88G?;X1SF(9xrVkI=$TF)}pekAFX#5)7}Or zv#cvWT0aKi@dTOlq$G}|C@O(8#iUSLR!Zbw?aC{h8Sjk7)0VQ%SjL2PUw@ukNjU1( z>&)V{v{h*CpgdnT6&LIaGwadL^(+c7Qmd_*tuIsv?^x!6l?*C*@kfx&Y%T@y+E|I^ zSue#idT;FGOc&6c9(4MDu)5Z7XB4(nIu^!He{ zsW>5kz>IsIaByn?NHlgWsriAIQBF!XWBP}6l3_0$m9L2dvzo45mkgCNd2Ug1-(KcL zzalF)F>K=pA1=>;T??E_Xw5o1IS6E2=b6_jguYYn43$x5UyCzyh{Y9c;S8K=?pU{q z8UA8d9Cff7Na;cs_?2o@JkP*dFVZnL9GF*cGyEeT(vxVX0J`9a-Io2lz%3@XRlrAH zR|l0=**qLNQiuScgaM>!2$4o8Mo^5DkOUOdC;0;{V1{*fzQ^LODBhxLdU$7f=5_mZ zpimh0I{-L1yc4l287`%ICRnH0rqyYz5ekP%#_Udmftg6b)AzG5KMjtrqCpW%%jfgayyBL<-Adgo!x69V`i?tfWmh+HtI7>e#}BmM&M9Bey&F6h;mx(2)I|`< z-n6p)^{hK>%ZF+P8nCte(g5Cj_yJbP5TNy{kj``BHzfRbz5W+jC!s)eH#X> zO|?*8C_@ib{ZD&i;Da4f*@Ouuo=(q#`xu{R)s7A?Y70e`Jja<@6{t_h@#w+gk`77M=E0Pj_QI-oN%66Q+?}Phax@x*EKrJ*{G;VfD=sK5X+a1;=P&}y zqfod4GzQ>eAZ+bUb7^q<3V5O^W-5AzR;Qw~MIn>=eB<_MntX(2_IaQa`eZ|{6m^$> zRNwjAMi6G~7$BoW%jqJfe9j)!Io<{$55bC1P>s$g`?Xc!2bScMw?GROrv?y(T%KxT z4lA%yu#osBSq!}_#-D<9tcGRTP}#{@;QHKirmX)2q#7@`0-$m$`QKX%qozd&OH zDWE!L=Rvxu-NZKsUqDey5%hAlip#! z4;*XE7hN$EJHPWz5NWROwWpY~1$u5>yEJr3b=H(0c)ks;9Dv+=4&(udMoF+BAzp9o z8@;6L@1Jf2mFPOwiag$mu@oKb={J|TUjaOeO{M?_T`Uk7_UY+1qg1MGk4S7+T-0467`(7lI{L;%~u8Hwo(4l`|MftKiYDR zz=XoPKua)Cp(C+GPCm!^A*woyUeW6~13NyECgjovVu)RK85qI;4DNJPMOGnIm=PtW zps>P%PD=gSt6Bs;t>Iu|jL6t~Hp1@)28xgdCim?S@pr-*xrBFrl;DRuZW%BAa z6Bsx+#hZ^ATUu*o*2(z}Ch5bNJU4%>QX=cBVHZV^5`dkoj>|I_>D;!F7p5IEpQq1>m3oyS z!y;Tm9Pd}h@XB!AT=sPwbz^zjz!#*IiNwGr4uU{3EPWq$cHqetdvvqvvT9+v^wkn| zJ|7;bEs4D_SLs^_j|PpBp}wfX7Y9&o+61`OoHb*5HUfWSbRH=2bF%Hyuive|pd&y1 z3c)lK0?MfaglOtLApQYF6gZ638=xQw2II@%bJ-wA?Y^|~l*}4k4!k(fzXfASN;W05 zTxjMTw*+&WhaNq#94;1BU+$x~d}qkSo=&!&a$&;l5T<~=#N5a{A~)vfEg5|8g3dWZ z?^dGFtG^voR&$|UD2MJOYV;HOhv%j~HFRJ;9DlE~y?s!uDg8)u$el$h{{V)PCK@-A zcS|P-#l*NFAY2Le5w*q*rl91LX{6l8(~icwo-1u>yyDO6m}?(+gzzW=3?BinASP%Z zAAw3M5QNAQdDu+AfVK|8tN;&qkj0cPJRaLGCE_pcUl*`d(-^b_578s-Z5ng@W(Q57 z%Pv(gpY5s~@1!6_juzX*L2Bdtg7j1i7fDgBM{0i%OgbYw^b#0dEX!Vr|Ek}PUQ`p( z>Y^;s?itjGv3i6jL{e%4Nfl&SS}H1%Er!s_)I{w>T&Sry8Cd!Ht5c-!ZG4~ZC6bT@ zW)kBK?Qn^_1zlaD!fDNat7rIF1=VHxic8MB>epmoHK-3>akMTicM})4kopm=WAF4` z6zauC;UMz)+bb|n9Dif+?Dx#_@!oeZMkE+P_YVYyEJEyU|ZC(|Yl+Y|`R_$Zv~ zl0$*eD}j^1PE36}C=Dq6?S9ClenVhd*{h}mha_@ej2z(`E=);@rEj4RcrgFe=xva-p7EuLmCRPCF!qqXS!}A413~wuprf}_Ty7{FWFgU6B#rlAXSe45r+jw+W+VP?PCz#m!$Q1u$g^cNh`1kI z;zM0*+p5#?;*M}CC^WE57}06-xHmMS+1H)$LpghNYOJz*D+5oTTp2^@@Ut)AKBdcr zuw6Gn25N&;`&iA4ffPn|>HG&}krvK%Mg-F|B;gC&)NN-%ND=0`+uy8`8R{xzij=jieYB|Y}5K2g7Fts%RFS{&y*XiSeJJgo4l67rPCA%)Y>@@2VgS%_q;1`(`Up$v;DQ2n3qSJJisI zCflIxc}6;(b?KpyTW5a}+M&J|jSYABeZYIg^Y;9a(p#RAwp<3!xd=R|&n=OM-Dsz+ z3chu>mygI2_oM!Gv~jbDaxFy@hfL!=`l|5q{nudUIq$E#r}9~9$=yM-q=M-|Jic=; zcWIrw$4h6tj~603ua_!h4~^hUj(OIGPd>j~<*a<*_(7$J;};7DfU8?A9n%Y(B=o^UZ$0IwJDC$%YcQb9w%lc>HLS-_ouEA z+k@L)4Y<4WB^+aIU7mqbyc0`~Iew(6x2tqiJA;}aGZRCjJ(KeYc~u;o*_6l=s#x|q z?mQ}Hdb>9FuXbqi!L0)w9UWJadT>T!NxXnvCFX)_@ZZ$#+oYyWic9q-9P#7~dY533 z8NFervmo{{mEK>>Wt3ToazK0+`do9lP#3oF_kaMfwXcB;OI~wMc4%PbX&V~UH=MZi zPELQG56Zv}S!t8+vTPj+r%*9{N+t-szTyIgzW6amqJuPnN;!B~%GwlQwoS~Ox@zh@ zhxviUg9BC;Bz?DTJz9td*N27VU97fqf6m8Zx7Nn3f;H=7#b&0775W7Z#%L7_Hok)F zjSf=?ijQzSl0qvFT*fa_=DXk0R9Hq!Qq|u(nC6Wz`N)zQwbqaWOto!F=!O0kWL5cA zyEMiHq2i5~@J>kC%J0NwojYQfAnlSn#}-{cuN~`z zwqmxWG0%QN94VNqdpX|*(yLCcTfTC+0gwIlm>&nM3KwQND~#DbL~%L zEU&cchDCtDUd7;gnuNRLVePg@@_8j{X%iMvARjIEBE8L|w*zFLfvqL^B_XxMVqX1F z1UV4hnbLQo`?1{JQSOpR1rJun-dijyL(w^&R9qZDqSG}f+Ud!H(UuGas|_zjZf9%x zF+nvP;W8Z2vn=|*Xe9gb)qY6q8f=ju!Bmt3;q^rC6T>gD4f`jdQTmKpqSE_9-H{8; zOerRQwR6j!)l7S&l_Rt0lf~#6`&n{K5EA83}eKW$INMfkfU>^hbU?THGR-|9-;?OMwfJ=?my+$U&c^Qty^UP77Gij0}Ym0$m!0t zm=9}~309|+36fnSWEO{2`Spp^o&sQJ4vZC+q&1bQcls3hiQ3FpCL6N^GU|yX+zQSR zQy>Ku!c-NX8vn)ORKcN7`u;{_MOZ~ihjJp@Juo^dAOiY&7f2}|T>`#mxDbKY0bJ<4 ztE@hor>-&e3FwQrtQFxBjA;-CFXBaro%q;*RPZ9{bbKu{Y;NzeRs>|BM4u6PUuA<3 zg}zdBG+7+{G7P;1VjA=24S_38J36=&p5LQVq%Rc}o}VSJ!9iRce9WOMp5O$(z*fC! z#%#L-wZxXXp)?m`HLg0M)U=2(Mi(nI@FWxy7cfbB<<}Sq`r&v9SOhx|1N# zEo`3x+qaO0DC*hzQ*`kzD6SLMTWA?uo3Prt~K@N~_=X&;fo%!r}6#5XM%4AOFFnX&^bWLkIgTrMN($LA( zAbtw7m_F>(x;|1B!R`=U2osCrM-PuClx7TQC0wHo1G-zyb@_#T6>V5SN}_H5AKKn2 z%n~h2*ACmZZQIJQZ95{vHZn47+jeBwwr$&XoUC0{fA8+DKL74M=iIETwVpXI*2O#C z`HeAx6OqU8qIlGgZlKB>m!Nx5kB;kpZ1}r%ff7m?Iapm1zWPwK88Fj9Z*d$7B%v0F zxUm+Q=gc325blsV_v!GeR#BR1+>`QLUl#3Sz!F%fZvVW!j3W0J?T!fhDNg}&_$YR; z0@8QtL5?ppY8_K?kWe9EVHih4QDwhpEZ8o7nx!61k=}sdZ!It~&(#ehA|%xq2XU&1 zl~E!&d&4|cwLqV~PR?d|T~V+h+9>OcAabYx5zKKsCN&^cAV7+a;f_TJD?fNXBq*DZ z&1sP-XU2Cxjh4|}x?d5jQ&rzg=tdXrTL^4UOCv?4xa0^Pqwd?l&1pM42x zhbN%Sf$6&+{6nD-v;y2QVfZkV>KcN~^mcD)KUDHhS8<`S;jqN&INZ#2{+2f4@11*n zB{O22;%JEpqRXzRTvedBh`ra}o506PhymCK{uB=|XQ6kiVMoxx`KM9j9W5 zf3U`Zs8Z{69Er``$mU&~9cGOkYON&F>$r2@^_JQcS^FqhgxBgfeYf@sybi*J#0f%C z0u3cPV=upM|A}0j{E_l03tyOm&EC_-t`uuldAr=Kf($jg@|6!+7{^hov?$c9dqohq zE^P8eUB~TB(Vd8{cPhNXF)|U>Amg+M#H~Cn%^w#?kq$OKQUsaAYpBhZXo=dBd%Fvi z%5SFG_*3Ul6>azJAZNO~#-c68t^CpaXmVYu7h*MzGbPL@;pdBT|2V8Kb2IieLJ0U% zZ4hInhwVdsth}sI6*IF>Tb^*4WyXuRC*gp3c%i&{;M*Um`KMrKioYAcH8G>$6pU~aOsx4-a z?izHasnMZ^lRD8Blv0S70|lgOd{0!44L9E^2YQ|__lSFD$K_G$y1h(YNXXe{y#-HI zq?4^*;5Y76vq;FxV)H591diz21eQkckm%dM-D1GA{M1801$AIY-LUuoLT&lLlCzbm zxKG~CH9G2?eEG55db(w_F@mi@(ocL5re3Z>Z=%u+>f1l=khWJJ{&~{}4;knMzFnTa zjm+(Zu5E9xx~NBLUpb=)BDi)IylSz1Q>O8avasEx&njJyc;;!m8@%<~=)A ztUC0U;xevaPC?nE+mYE}-tx-BmPI?E_++o+_RPL-5{!^-ZJgpU6Cu9t5S5K{e@pZC zkhS@zjtZxaov|C>B?=KvNQDNrj|&4c=0*=(iksV-D^Tv~S5M9*5A6!h>x}Pw=bbO~ zP_mI||EjY1b42K0R~CQp@qc(X_(xdjf1FJEz2^JhnEQ|N;P0&~fArh4{jLjsPt*D@ z8tz#+{@k(f-)xZhYwre}fA0PGXGOru^w%o_4UOo%-|q(5dNa{X)2bABTs3klf`40{ z0m=l2Krj-xYA6R?OB-$c#CUhq1gA)3g2_9=7pg*oUR_oV_vLwa*@kcI5^rK*64AcG zvyP%t7M3n_)=)7%QPlFn8*7nNwJ1s#KS3qs)2>ySNE5d;iUaO``$11lu=Vw9;P~Wo zcSi3z{&9Ub1S|9Y>T|c##qX>A(eg6o%5QAaoTN&nBDn#fJA{GKs^R&lX<}ipPBvQo zbYbypF;8;!W0TFsyH3EA$XydNe!i_<#vL{_#LAdSj#}Y`HR_4m(>&`kxzWfe&16=} zwoQ00YxPq8%B8yfx{)$kMDOUre$QKf@$#gFoPRkplCA7E^r&;9L}-CN$g?+1mS z2&sI_KO~ktQ-23TT!sQ0UGEyAksbl3V6|EfznT#3K;a=#3GWrIPSuDZ)uy{d97EnGG5XB*DVh#qb5Isle5Q zDPxEA9d1?Huey>GII0aQ=4POb^~bic zn90bK41k$FkGZz{P8E(16Bi~Dyj||ygIj7?lK%#~?aj3!nk*25WaG4Jn^pqK$Q=mL zEDH0n2%MfKUsnSVPR|C0!qkQBP(Gx&AI5no_&bg0?Z6{0kPI23xjHMB5Wkxs9|sl= zv*EcqhjNg_by|dkn1^&g><~#xCAcXgTTgc=Fw`nAO`Xx@P_*mhJSN$6&T9LgZZU3>Xf)}W#!Z%6!I`r zWlSK{=ZGAjJp^UH2m#RIqa2`i#$)Ca!2t`qp8?3xvP3SjVsS(h6X$pW{)+<;6dY02 zDW>!Qpe>tH_B@*4NSmFK4fJs&*+d)gvO#)Ioj5%0bO<4U)E}$mtjpL8t(#n=3FsCA z;sMIZbTz7N_sg+*lm>_9xdz4ilpIIFD@dtLl^gmE^dy#_6eFovQBN*g57j(ydN51p zFWjvFNJEZSvA*_4cmUVB4hKxsCPhbzFYhh-F43+IV&A`=W@Uy$-g4rMvqX0}OGTU@ z-X2o#=TEtRxRLKX?%^cewo-aP-^sQYq;W}9Z1oL zDKf2vK`5pA*3g_KN2wt?%GXs1!{ma0NbQdnhM(O^T%jsD>vZHPLX@#fA+QaFvcu}d zpM7R(k!1k(4Q4_`ED55DspzFeRz-I}m8b7q5?q5%@z|gubu)T%2#LGeBZ>(pCSi4M1pPoCS_C^~K9mPdY3TQ58GMX0Iw_34G(zd8j1K;8zF2!$dq`|4(y>-JJhYl1 zRc?=f4%MAf34=ois_aHUFxZYiSP%1Kp68l9sK8;b-vWdR9L}-dlKZml zybt;==f6?vEQ`vbxCCYmD^668DWh!xxTt6*N^MAO6>zrjMO%FzZ{t|Up$tUJIvbd; z!dAZW&|Q~p0 za*o^J{X%AgC)piMfuJvSJm>%I9w#syC<63(Kz6gPJJ6_4r^^ccwNBktR6GgL{2^CRytGJ}q@BdhsE$ z9j=!h(M2zbst)+;3v318tA#A!F>Tn(v*yUN@5E(0^-e$i;78F+Y3c2>c@JnBwJ#Ku z!KMQsOMVNyS77ThxZT(}u-nh>etV#5jFo-hjNeTd`a2c=n4CZCq7e7h*O!M%r#VH8 z<4KNYnHfKvMtkT^y(Z_qpn(sMWc}J}r+{WB37@}%7=xVA|0+H~l0GN&SZwKE%)H0t z-bo8sei2}jYrHojlat}?&M_!$F_5TSP%G{{qHlr(7S?H?Qb}z{@Gwh6ET=f7mv{~|vBxu*F4@R@<-uL|{F8d875=Ra0Uz(%0P=21X$ns{=UdxY5m08h~wE{emiQyBYCLdNd;v?52r!XpjjO9nD$-kc)9!*YZC-< zM-rR9VG%E8Q1n2iLN$JCT+eOm1B>MS^mduO^+7R^phRYmabk_kIQPNt^ZazV^RdB} z#1*r%!M4EU_H-Ar@y4AB*0p}M`Eh23_kLZo_iz~3WZPpy)5}s@7k+3Se3oj5X-SxI zUflX|f8hMp-e^tKhlApf;i|P9c_M40)@K_8^?F;olhlITbEcoxX-!*r@%%R6MBBLA zO@kr(jypNXc4>^(o-;^`{J8wdgOT-lLZ=|8pd&q%Ukqp5_|ObNQL|Dcky3DCO08Uy zz#G!p;RLQtDjBe7;U6NLP$$?TJl0XX>!-$w)U;t{yBE9n z)E5G7>vULq4n7xb#ekq043JI<_qvq42a98#$}zcC6L*56vQ@W=qta|8hT2H>GdA_{ z6|rD=l?lAL_~zY>tR4l2c~@GL6Q3PP)^2^hP9GUi69rN!Vkbi>1VCw0ec5g>uh2}t z7ZRc;N>z-dlr(J~s26~g6uFHXBY(qRXnp~Z4Vv3# z3S&P?6^76nIOv*;FwFcVsw;@d+6z_GJ}W3y85*V1BffGkv(z10#y&+(pw~{*RS{s% z8dpY=3%_uG{A(NF1agbsP5U^%rhcFEMww4ff{*H#sZsASV$Am+_@x;9=gD>QVk7JH zwZPLa#{fAUcJdx!l;=8}6ge8;ptMbyn{tI$>%_DLIozXp4;wYy0Y8MNpyZ8Sl3Vik z?!M-5y~iwlOS$912uTw=>cs70@@hgrjtFDM+#xPyfZ-ljcxQ;rxO*_8MJ95B@{KC` zHfMPWBXfi5zfo-1$)-e)`v)VVbpzpnp|SAP`1$*Til85r?5!g?a8M9t#z9K^B1m!^ z=YY7nqRJ=+bB!|4LovtFGiBNUVfI<+eEY6pfY()D<7<*J1^!t2_-#s>hNljL4m_8%LocI zi2H<{7oF{))25!PjeWyQLZHq$sKFxZh+EKu*_o8fB;*QQ z$TVRKQK*;L85Fi`gXNH?fi|EffI1eeJWS;q0OH*RYqFG4AYd4_tNz$FO5TU6TZ^jF zM!GeKa<`gXrbt8a?>@~tleNBMNm=GQ@YcRPULZgU3JsguXt0n^5jFmfA#CRG;5W360txjn6A7zmpnu}69 z8Yb*KvuQh7a1Y2d(~0HitnfQN&Ea8KXt*j^_AJqu;@ubxtjany!J^k%2_mHH7>LRT z{?nlSqdBQ~Af9n*b)0ExwvWPVm}4@Xpq=nF-5*0&YV}H}f*L%Ft&ih z%NAz=&dgL$f{BnEL6))Lw$-OEeg^$gUU9rZU+MeV?qZ&oMG5LSFZud30&P3P-q@Ss>t#KOY>+&TR{j?NMs;x&am6x-MemCh)Vwq zk@vD?sEh=#NfGYI{^uH+UTGhClwu(;F+9JQac`)@o%(V+HpLwgg)V@_f#oU$3bWhJ z+qG-LYb-bU6Bl4Q5jj(|@r?==@qP0yN+FSHLL7k@B})e;gT;VH zM?l^9-M!%t6%Jgr%0alKWrv!EUow-g+ruLG=VSG>8X!Yx4uT zhFx%>N=*cJqDTaH2jwtz8LMTMn5pweAn59X#B7)@tx}>b3=Al|@xu+``oE|y?O@}` z>;0}5bpe|0?daO}vWFZb>uqR~E#rE2{UZ0p>CaYiq$Gu4l)OGCH;6?ls_3x8gyYiy ztUhxo%ClCq2N-_UOD%bW3<_mWI-0y`!O3NErbZz{1ChpT+WWC4P8`~F+Lyw@Klkgd zQ3Lnaan8g`@J_s9C!ZP>G$aC+Uh@z14jKFsQsR=H-Cy<0HDK(dr7|R0V9? z^!Ofgznls*M(crqHThmtFyuK$VCU%2gp+d+r9FHs6(Hg&1m}Utr zLIool8V$VJz2vd5ZfD>CB4&G95Adl5#`!}S+4aRitoMM};kL*t(Mcgo!71aDh~5a{ zWIOyvTv&N3Os@;jT9U)%%uy}Rq|%$|)P?9{vQCG#5TVswcLH^yKOPb1*H{G;r|R2B zAy$g`jaMg!q2xgiJuE@q(afx5g{GD^U5!G0F*lNs(o=Wwu4tb9!_NSk$)~-Nr;lYy zxAl$?LdZY_E~zq#9R6~OpG=gDDpWSgs(buc;gOzghia%cm!G`DA!6Zdf3UZhQK9i<#P``p!d-sx>`!tVSlSpKuQ{V!no4-fqB z2Gags@AiKL%WMpP4tV@cHgo==um9c#`~M@G|2X_V)AIklkUAT~pDT!e(lXQUEB?ih zdZD^h^qLq_=bPHGI3V$l4}x?NSzV(5H+T&K)c}At&S?}g5kI0Kl7rORFR#-DWu?45 z0MFR6@Q;$Rs@JlzuV21*eR7&M31Q(Z3+W$ygQ&Ik*k(2v=qIMW%kS*7wP8)%$tUJr zDl=10Ynd~2uf$U^!+A|zwg%6aM^A5Wu5VjD9cGtrdVJ?6ec!Jhe-CgS3%SUC^ZmMx zAMLBJV60^{jlbqB-IL&gCcmhVG&(vrHB&xUj6Es!Eo-%Ko+DXI<}I(QoV4Lw*mEh? z!IK%nf<$+wSbGWT!jDB>0G>L=ck3N8jbk<9Wt?$ROON<)FR|2kB3Vn=*nu17iO!0a z`L*Egw2!Gmd3GRxS8`5`;~Y|E?NS=9lgrL+Vq_(%lJDL-xlD2@C~0&{Q9o?_T6?)Y zp9C&vCwc^E0vJ1pl}d+oI%Jw*sd4tiu~6*ec7SOkM_q=LBqy^qV^0O7<95mM0KAHD zBs*kkY`c&>5=8{D4E{@8#&A}A*?{P7L>;bYQCgMd6!<+U&W=naWm*|WYT)zt0G%OB2#UKj+l(KM18{?8 zxe#;RlinO^tj+b#pw9>xFNsEz-9D@PV`E|mhBC4ic}Q2Ns-aq>o0TyOZe=_;VxOfJYxG;wBL%f|>tV7)6GS3$$GP7L-3;DwaO9BOkHFpaR(QwIdoU}Jn-%Kk zQv-QN&~hx|lwJDa1>5^#dSN@8oZZcb1N~nL#T_ap^p8$KCZtaIJF3NkBCyMUf;}dpVs1FE& zV2jtAsPQu}r%p4{>0p4yCw4{q@o=ghp%OdB3j~%=Q zoSYk%T#`0kM}m_bR8QUogB*`$qFe{83W^*0LJ4^iWJOLoac?O|=VFI|}wm<}wvc577>s&15{WfA*wKS!K zK)12uz0sbM1yySFzCMtApfHm8qa?v|qe57#=lwT%jQ|nY;$E9db9;#vc@R1}B#zN= z=q)l;xWYZTmIBG=#SGbpTtMX=LbJ(7X#(Iq#m}MEQwiODX9pndDT4O1ydFwAbN!?o zE*W88?HQ8aa87R4x-IRBJJv0z9S4{@B+uLxyPz}mRUc!O9z(pXa0FGzb6Y|+gvIEG zVh?RT)H3wBj<+}uV2?S?Tcq9Aubt-SpWN&$SodDeBn@fZ60Ubl6T}y7va1M~^s=Fy z;3dnHksiK1pkZ*2@5KW4UWT>D%d33#2yenU*Nlsa3!DV1FH-7mVD& zQQcY^2lpU6mz#|ImY7-(jrcPdRgtmy+#^Lbc9n~QHR0RoQSJ_o74PXP5s2m3286@F zWH(|?Bi@?7a}NqP@Gl(z=bE{8OIiJH?PuzfM2%w++Zq^exDH%|XaLR@S?1&-&S7(E66584vJl2uc9ShXki60#OC>(R*Ys{j$6 z-&?c>gLg3*3+&YtZ|G3s7eM@M>V*KXi*&X6^}i2u02L$~!MPnyri9n`C>449>WD*| zD8`7_30VF~8wqcSybl@=d7F;;;(mCrevfswQ?JjP)zs~w?^Y3_@$(@i7xdD<&j#Td zg<9jx8#Ru%p5NQ{C1g>b=>;4uOZ}@{c6M)q-u}4CxeXP4#@2++L;rM0yq3u zG7@tO9jkd{4nG{ohXjY5ICqGdBIYET#th9mwoDEQT@7xVG3fbnKt&GP6hyPB3)1OD zFHerGk(^054+0LQE;vqc7uS%q3mGa3L>N+!rp&Z>lcxmqB^j-JeFo|m2cz5Zy?W&( zM9oE}>G?-&*ENgjiq$k7=wM%ejF?9UmlijibPCs=Qr|(v7e8~x>(mBI)YdQzRcgAh z{|WpajaK3>3P{9*l@TN7Yt znCUZ_-DuOR!l|zADhp6?C9@XyF5z8WUp*(Z$1iH$q&;AKjiHeEMFOWy;GN-7o18Is zZ)|EMI6ABmS9%2D5e@Va6TANXGr*xo;7HS>C*suv*O7kk8af~2AlY2}0V7bh65}$Y zS(`l85x1+yj#7kL`CUwOi^W{houDjsiNic^MdA?nW7nb}8$u8x|SB{+>l=rlcNOA|=7Vu)7nvS;=f{9tiMWV2c>rh&JTFu8F{ddnVFlHNk z7Lo6Q#i{#x7=HYMW3Zq1?6e4)8(3e8-$sUjR_kkHTxQ&*Nb%y7b+(^66Qd=idcV<$ zGC0_~s-rf1m4r*x9ovwfU>@cBadNg7W}xt`mquJUh&~oGlhaDC?ju1l8u2tCI|d@5 zc3!6kQT1kR9vg3xKEaDv($$zmYd=yD6yQfo|L&ViRmo6ziNpH2a_&V{hHo77{mCx5 zF)Vj);^T8d4?$-v{Xg?18^fQ6g8WOq{5x&^yD$SA!+&q==6{m0Y`@Lszmu_lzsFyZ zvA-v1{_lSJM@*WDiItA&cc0~dj7k6f-v1d*|B}f4@5iLs82%gv|0kz1{9cy)7dbUi z{h#~IuJd7*%P3;w+TZ4Bk*uNa1Nz%2rXK|xkBxF$MH8a-F0!{;Vp^XmCMfmQg&jDA z;ksI4zPLJH4l~8sg`U9+dnaz{B!KuM_hg6)v+?E+Q@;B=D7SumJb$oX2{9hQsO*E= zw?d|zwE6nJ-Q8S-T<}2|(cd?{k-&94@%!-jEdL07%D#%a@_mg3=kMgLYcD+X#-P*# z4VmCW^2w{X+*A4fWPs(lWh-iT{rLvnl%-H|DLpg4oZEib3yja-X_8kWvjuzPv)^p` z#-6PG_Q0vF8b&~<+F_Te*3N+oo#X!My=dkP%BC~LPRx0gk*6oqqM!z-=&3sfu=4{+>Lj zxj?y#7~)zizma1{=GjMzm`0+7GVxF%3A`q(x61B=);Bg-#4e=s&(B_9Yx;d08Lqqw z1Nz_{fn5xG88yVToM-}AJz#O_Uk77hlTp27^wMkYwLE^^zbJjSE=3XW)XDt}Dc>@=tQs(2W?NZ3Dhm}yCc)5 zH703{5ucgNkLsoYPP+m1i@0}9kgC(IH{4B5;70%$Z87E-^?#n4awJZI3P^o8vuMSb zxNmAQY?Vu%Z_8a=`a&}4@aTAk+>FW&deiLCVp^_8#_lcT(2ztB1^VQf1C1vzU8?>-{nW|{$UD4YJ0qBbH(BHy$VdCA zL7R?qe)}~?4Xx-J6T|FCW}QGTAXI;mR(A3Ww_PB-6yN7L7!t}9ToR&&$3Jp7lh?`Y zNKSaB<)vMmz|z~uFe$op0yD*(yRr+66UZLPZOL@J<~8+PvJmOeUdB1DMiy8^DcKco ze6&vRa1DdZPRwW}>F67Bs&G*0gYB`GeTx0_?YTVf%eM$r;3&95=#w^E>p{$MBbR0! z?Bp|36$HBox(~}C%lf0@HH?n@jTEXR4I0=7K{-N2^9HS*Xz3PdIo0jhxmq8#6@mM#=6VkZaU9R{9b$6~2Cpx}rVHuYm}V2J z*gU3ksl-a4z!ySDjCwd1s)p5^=r9)=zpFA6(CP|N|?vLti&7kla+v>ErRUITXK=;lW1xVp2 z+}94Rz_CT`s$$!w=<#Xt=K0h`Ms{KB{T?&tq(B#d1L&d!>d1*$??hUsdOl@^r*^}# z+;2_Cg_jH7dp#~rikynWj}Za*tK15~0Z6?NL*VHcK~d@^%Q(-&Wk=oFrIC@~FQ5(4 zLSJ_Fb_oM^-Xz@hnx1>q6r--l4waUw)3tUz7lxa)kkQ^GUI|9M6qN7TMVyZwq2qw~ z(>9%I(A1&rbMa;JJ`FX%`B5x2(Nb+a)^i=>1y6@+HQjMzLcL0CjPptwdtz@617JH_ z2!hoDaKRXQ0Qx91FYAHiC30c8Ilf57q(g07q!gupp(}=y#~!3nlvk`5R2pS5Yhevk zwdQ+_>g2vOqDJL{u-Xj_t(f>^e+`{gFGMsAsF36sQaa6a;jVY=%?acTO;%ZWFr!I6 z4z6{#a$n+PBP=or?SkK4-wsm0bjS(~Qu;qK{m=gR>``s-hD+n?t&{1@Ez4+;2hkLYX+e>9{0&mYm* z82+pye|tf;-!sksHaGn*gi!x}_$)l) zR>%rf35}yD<+X90J?RwQl3wzzX10M38xTqRMJk%GcYc{nFCgGcJP^8so(?jCFNgpF zD9`_W^W!?)u3CF3Do{Y%=CZ1H`LVZr`ssoKu8QqsK`*IB$MY9lVGSGg((8liuSXH{ z4@?Of@w1OB>Jp#lhrPqYzQgFP?>}E}n&hzOu7^S#rj&jrs{d8 z+8oTY2#REd;J7Qj$?Jp>wJUj-;D8TLYU$ubHBT0}?7Yv$e6FUkjwl|sE2}nsEwc<++g}DOE$E3Yvy07OmvjCSeAedyHAK(bL`5!RAv|J z=hR&!E=YR!IqOtzOv3@Ghn}r<(p!+m#~PTQ(Dw`9iaZ!4U7?_UFa55&uGCRB#!J_x zz|%;1^7S$5Omyb!Ybc``Z3_7d4AE~>M8Vvf#;qz4QBdrcO`bcEx~bMUVAr&a_j1() z70zMyQ%7PsvbyVmty-MCv<@%nn&}fLbzBoj3D=5aDc^ZQ(IPi7T@LI(Pfh40g2Uy* z$s80MCs0jFaYvMY7b22h!YrLw;#=orHh4x53|qme0M z&FBW9isR9|>jgmTjfPJ}CG|O8{7!9(bRo%ZkIf{rn?sV87^N!$zHx~v zo|7bqqJA}F>TXWoEpA+VP6tXJy7r^kQ#oM)vK)UhC4aa%vuT$)7H>2x+kn&!f0jB>G|5 zoc8|w1Quv5ekYv+xZ$3(;W*NKY`mivgGcX_$+bH8tOZy}FR)1Ul_#C27QB*NmGJx` z)q}`p>A@q=PkxAb!5ECH14j)W-G4PXx}L`!uDS6>g1{Hz{u)<+I4X?HTYPf<3sOCg ze-8;C&TLZ`xd(Vr*SC{5zUdb{*M&&W{U?y}hm$7{GHW9)Jw`2r{)wyK2<38LYLX4y zxtqjfRPsJe2hQ@+ovY)>5aGOIFuKt3v5baSGr{srTn4Q*wVVEin0^CCAXyMD+$DN| zlwPfTx)h+FnG{3NEEDYYcL8yS1g z7bd)ms0bpiDj6a!;><&S+zkWqEyDy&X+hpSZw#+Y{<1sXJU0dlK*Jjlwc3cjcWNt=Zsr`GT+aW@b&o{%(N z*ci>(&|(w;ybrQl(VfJ_ZYLJ)?Ze8MM!T~88RIDS%X*OFpy^YTkaB)Y_%e?_FM+z4 z@Ay*PDM0Mv4Rrlx!PMo(FK&XV$OuzO2Rde##6#Dt(CKL7!Hbc$LetJz8s)!bHB`7O zb{6E!7gE$Rbz+$*Mc&8AUm%TF?8XPS2>Z=%Mf8$=B@TQ-G9iOeB%#AWa*F}%QPuNYgXliRM6;GB+o8r#GP-G&3`mqC=n3_>< zUBAebvAMOpNQ*_CU(ivIfH)gDO5m@!=#UT*vH^qRk~dD0GJ14#-wpVYicWCT8*~90 zZ>^SX<+45k(rI@M>hA=>4S_&Dtf*urJJyCaYyxg&wFQiU_CC&sA$)v|U^+JGp%`LeS_#mu^ks(+9COcmgzd z+ZV`VpOpK%>o*+Qk*PWT#z^#uL$rUh0Ydo&0CwJ>hi<&(+)dSWC7=-9Wxbd-iMGS( zTN2+|2bk@9jFI7wUJ&vrV1T)SUlgK|P=}3BU=wAojWbJf6z-L4F?p(vh$E~+4169i zJInZm!qPwe1w5lcr&jY#Zz^r=%-UWd=pzrdIdDpHg_8Ti4 z>WNYet}!G*GSQ#75A(|w*p6~Q(>$DWxVA$4mj;RS8-p8mUa`(Z@b5t{T6z?HZEH+r zso$+Y2`T3^4~875p~^5fV4oul2*<7>{W5PrcJ3ethfMsucwL(#bRiI(gpl)`iT#!< zVM^h1luT_a?j4QzGq6j2xvTW{l89?{aFgB^4A_0f=}K)3*s`e9Q%-{xtjIG|XylE^ z?{(e5OtQJIj8Q;K)D?==#m!NrL_XzfYb;9Cm&dD_71~?~WSWwTZ z&lk*1=fIGmS2*o66>}M{RLRB4u_+Um${66bL%Abw#YWerkomgIbmwzt4j3RNT(=NG zpv@ARrgZ&oWrZRy4u!PQmv>GIeprDUFqm3n(q?tlfJm-utE=Zhhqp@tO7e+MS)BH` zP+E6Yb?@ z^6(LBY;Cz5iTX|igJQ(Dt;dVwFp7AooK7Ut+7fTyPryGE5rdF3g}B6A|3lR&3mN?07O|QeG?5*yHHD8ZPNYR&RNLL8Z zt$4I_{pB--rr7+o7OqIf%lZh0&i+zjW%wnWG`T83Dv!fsa}RYv3^ulkEIHtqHx58z zT&VH4+WuI7?uLBz^2E^YHMSpc;9gJb6V`%982$$rm0sq2X@*vGo-*k{fcFx!rOTVx zYpPKfto@I2Z{9zbkVSHJtf%}tqHkcsz)De8K{80cN&41pZCG!9K$G$(s{9M?XZ-WS z{J-Y@KPdP=_}YI&1pcStSvJN$YvR9g{~!1GE54SE;m^_5{}D);X`uqn~J?hHk@WiQf%`+V9y_4)b~MC0?HSMVOJ ztuYlD<*I6B4W>3I@n@`t9L`oZF`>@Pog`RqldruiUS#`deV+?DnBl+4k4SrrZMbZG z6v=2YZbYJ`uBu_7w?{gJq&=WMBcvV5O4osXSTZwyMF zt|i{Zc!0o&?dyWeTkb_!+>ZsbxI~1chZYRWdXV?&xi7mQn~KS*`eul&&V-rVj`_h( zC&8#ny?A9Oj5lo|l3z=g`V07HJK~i^1BrZT7vwT_6&O&KDl*P>H(~)*ttGLQeI^U`yGEk?f}r3D6jlO|u|+FENHyir zgmCIPe(*u4vwdOwWpLk=4|X3zkg=>KZ$boXNM?oN8Q4eEJ#*@z6rdhx#a41)1fe23 zK`3l=ICx;Zr;-drM^nnjdqzzy@b5S@{u*&8~f%Q+S-+y>5LHRZ|&FID3Zidc`!IlDnw zAe*gu^Tud;&UQ^?wHex}hjL4pPs1`-BI=YxSA>xh_!*Ig4dROS{g9iX z;TO(JD4Hp3d7PsW87_!YA~@-p;8Z(~7`7RAb!NQfNm#83Tzqqe^6`4be-MMR_864n z6x4y;OtT`RozF$$#ElBRs{9qp^f8b@;6ign4E&*Z+)M(01&Z0hk1pf6rRz!H0)3QN z1k>vW3a(mrd$%R6&Nb<9f$h1Grf5I7aFLK`>~XkJ=qqKp2_*_a-W(QIR{^;R(lm}& z08+EpqDWx}VNi9aFJ~^?!i;^fD#A^H!q<}d&e#jd z^vzQ@VSD?N^h)O^6ck&xFui8#tqq~7OHiV889hP?iqkZHAe_^J3%foXS<&Bz5;un848hsSN_Tq^R z&SGj>#RVY9*np@c9`htn-O$b8v>w9c`k`hkxd4(VozQT5U3BhwGYL#IcJI-wEc>&(%CW<@9rmYeShpk=-)m$TZfq#S$Q^pLPfFflJ7>2 z??qOVu}W_f??@pA%Bq^;FHPSr8_FR?(}CsF_H?SMR(oKz?lN$Qj+rS*?M!%G4l9QE zrXOsl##Qx5#v^$JaAj7SYyc`;_;tkrjf;UInYQq=1=M?-DQz0gMaZaLtL_nIlVp$$ z)OB29zxnuBU&v?}M}g_%eX_Ndt4kB?N6^lR{r*?Le$J{-&0HDyu4VZ1lPLx9zcZsC zVDr87^MN8Z((DUbNfs_c16<=j^1_5NhPVgn-_Xtc_yK2B2|g3)h;7O14AIZQ%qR4v zeBYJsZw;c3V@QmO`V9i~C6_~sS>}7?notI+RzBN~(VE_fVf#cjonB-xPf}{L&Vfvk z@QVir$YU=^j{$w`2tuU)#|hflRWbn+D7ZC&^JplS;1qr2u7K9P zENHj}RUdEax*rKvl5LAOiJjwNOn=%B4-yr;5Aw-VM-i)S#4Ujbb)DdzZ|okOcvaeU z6^sX)@mvPbYCU<)4&iAFDDB{(dOvkxqIe=x$2VQj@6^pXGfm`>8_a<71KgM(0#3}Z zk(3OMkYA0)P;yvQd4mc_s18-&4dRl$VaV*smfKrxpegD-Mil}3sgvCj5iV7Pp2g2v z#te!+0l^JtF`Trq<`M>(7>gM1e)vsr__6Inr4ul$G)j#O?*fxW@!H19NbGUZWV(VH z(M!mHh<3C%yaNGCrdUr!juvs~*NX?8E@ zn3-0;i{9UTxFnC#yl!AwryLLIH3@Wnycqa?xqPivKlOV*AAD@OzCXHrU03UEe&@gZ zdgO5Qb;t(a&_{u+E%59N@ZwtOHf}@2IhLx z5@>V4b~+V>rDG3Sne0KGTl_5K)FV8Wg?+WPrL>1h+R{j!o))tB%~m-F6N4@f3{%4i zP7&%=+~)I1{ZVhErH|O!g)6$SAw5&RR?(|}%EVVpXZ6^=EpUr0W&+h51z>ECiYYp3 z;-c2!+bO-3q050Uu6BkZ(Q3BN*-tHb;HP!g{?m>h@{r>t8%G3XXKQP@A(<|&R!#8% z9S~N5t=TuKRU4-rDI8M=cJw(d3u8%O`?W;l%E$H_0lWPr1ov?FhH=MtEj-(y0y>JN z6y|614d}Zl&I+t@6P3hB1Fk$zH;c&irRC_hnQjWgv)vLDKvt=60O=MhVbxRPuYF#W&o3q1!Kb>ZAMEn!{V9Gf5JO|2uQ=UTF`jL)Z^ zr?`YrA(E^)0-h3bi%_n8oE-SSUAq;>O z=@)b0C>T!$Z}nZ?pIqVTl5noG4i2d$KKX1L6JUghL|^;$M`2?$ zW7ABrez6eX26Ig;{zS|y5cCZvBh}*8_g6a+uTmzvXi17YHcxD_VSUwacdE^JtNIRw z&yBStxy$%Wp!`$kKqo%B@kdoc!M3EBsR2=MGZtS0As@shVd==M)%en;b#W})jsPP95=)`5l)4H$-cVtT!#E8P`qFfam{d22|*)a7Gdb$bgm zqwXaqU<5#(N}egh&l*GIxoq|E$Yp6{GxI;B7nLLzEs{A!pPhPrN)7kCoF$e;A$+Sx zq%z}T;c$G>;bYeU0!8(-I@nhJm{t5i>ojQE|W+WNpfnqIk2tpaXl4XN$09 zJ)BUrcLJLX6ZL8AB4rE8iw!#+l93P^EjbzEK=95(F^7b zLt@=ijZ?e_Q9$kyzLgx(P;=Y_QuTu~lCWBU0q*J|2H~;Qh!cNLI5CE>VW7y5YjHV2 zo26e4@3ZudwqaMzj{=;`N?;d2|9!Yn; z`b=#(r+3{Ln1-f^)#?yY)6$QQ5y`+QfVvm5HShva&HuU;NN+G1fJy-FGf*C$vIrb? z_b%Cu$6{1Cfvf$RXYP%LRU5>%%(QKnf?8nEbG&4IDv-EzU9=R<=0I?8Hx~Vw zW1+y$^mi^rfQZI;unU@V@RW!pY*uU*%%+o+x`@cHIcBrpF$tTFOJN!km(L$H&XnzP zsYf0k3IoPt5JA?>Qgs8LffX)e4>&B`G3h3M=_*+~#tF=eZ)#08| zIXrU4WNdBf%GmPN{_0To$!>%~h*25cV1Oz!4K6l;UXVZ$V zMPH^sJfQn9lPAvr@n=GnWbbvnLKU#!gTq5)W3+Z_B-L`+y?wUE%#9G4vGA{2 zvD(nq66EheSnU5Sr-Qw6z)%J5WEnIUukPmbqSm3V5z-_tWj!zAJMHd)!_4nbg~JDE z=HCu!A>j2h72JAB$}gK8v*+Pl8^4d|H~0Y(Xa8C5e1moA1?>w6>%$Gk zlQ_73wl~F+-u(+{3InXVPPjjk%wL_UyQDuQS6#Cq9&7%(xm?tshRe4p z{E3c+Ts1{Qj=hH6?}W!3c_HaimC;EWB3_fHY4Q#!dWVw~ZB@iCU;Pytbf_U(>v*D( zr2n^}d(zlQ2PCEzTRE^tlPj-YL4@gJtWo`%^#D9!ZwbyI%_l+Kc7@K6&`Dj*#tNpOifiU&55L(DFKYn0gJH+6>3 zYt8fXtI#M$;cxNcc1DS$l&!O;e0BNVO~KP_FrXbt^s~P$kj3;%kIP_<7^IMAemLCm z#e2UQeBH70+c)!!AtQ=1Z3sJ`bl~@V*nB-cUC7#FUfXv_k;41F9&UX;(aHsVdAEF> zuIQZ{cC>g!$qz;JShmjoS&ZSWZl{I5Y~juUt)O2o>~0XFSBW6{Uf8r$fkQ*8f3}d1 zW$skQ{mcbBc^ZfHvUSdccf_-Cu8uQYmt4+m4}#N)&|W2(JDE4xBG_qy~RR0 zu@$U38D^zg@eu+lWCr-=;NWe8HtKdaj(;z2_s6g4WIScNXqv$y9&h#pe;19$M*Fm> z;kYQ*Y>#?>^7(c!0PH2_59aD9UDOoIJ#o!q&sE)uw0<$Y_BysR=RQ=i5X4$bEYKS7 zs>mORzYQ||@fQoBd;&%erlK}_G!yTMmN z4v2pa3|ucwhsW9xP)VZ0SYQmjpyv0e?4Y__MA=F+@Z=PDp$^ahXQne4d-(5QBZ%+` zprHkB8QXYO5HtLIv=SbbFX>lcJ)$bLPFCDPF=%EuZr>ZH(ImCpP>gVIAz><}C;aeEORzH-RjL zFm+5#;ttbbc{PO%s#?sHX41WV`SH{6PLh9lT=UMj9-AGr>kn^pkx`c=RO0F0!>Zx~ z&3XeDmr@k0JW?IYc>puyYMX6P7|m~-dFTVkKbXE>&&ZEJk@Mp{JU>Or+8EO5L`K() z>14GYSjtqDh{gzsSK{gN-GMXX)&nfLBo%)Ca^&;>g@e02W0@BiTZ$9#Rv--j5{@E0 zHr^IR=ThPh3;|M2-YjY}#ej~|D`*o?2SVi2JXmh#(1dISsBl`&%o$tUP;`kE^~Bt# zW$t-rj`7RN5na#xQfGn{d{||N^}#g6CbhkM1?#+}hLib^B>JEIq8evabb+d9AS`Ay z6xXe$hXx-R05JMvGMQDyRW8LnR}5NVK40DR-SmGAM^F*osjM3QSIDr zg-xZD@H{%NjU%6q7DTiB(9`!CWK)E8i;IFvn6i{PIpR8%SOCymdA-VV&j6Mh0PUtkkRC6L`fpeSb))n7(c8Q z2!r=w1=elzgrvm4T3@ZIw0}7kAumTUXF?#dbTC`@W*=~75&03k&}IoKWLVw! ztZfd!=KboVMT16W)499!KFJ%bLm$mp5mfCWGh3>30CTD0cc$x9?4AG zpD|n?V$}XM#f+>)w_@R%sm-u$y6{kX)cAKq4`?Xh8`9yjie29s zG_P;9O)_oeLPL2bn8`v+jVTt4f7RVRjcSSq0>M^@?9s#+$T`Qk z#yLp7&Mq%{P+$fGm)Wd(x{)x1dq^)IiIUl@ib?Ku-1 z?5OXTS`>AC_L2+&e&KCXKH=112AUIM8QttEKtlqS|;Ts+3F{w9M!|L#?SE?X3Zn zP`f_NTkj=(+FduT=lC-0ayGVXz(cy1(7B@og7ot_8tE4|m5}|x@>(;<0vAE&TH#jM z257L+jsz*4+>hLacrc3CSg1F^lXZ5ey(+AxC}8{N51^>gjHb=&p=T`6CUE^YLIU8L z((*X)ib=ntWaIP1^qy4?fhY^vBRI7KitbW(ig9nytv}47B2Ya)gL(>#4U%RKs201) zm;y70mt;ZQ(@M`vS}`6Gk}!xr3kHP}4y{~mRY?1OvvLz91Vr0_0dTD(nfR+cY7M53 z{=i%d^z@U$WG~k;+028RBG?S2GxktaCmEpWX_x5FuB6K6;IZ3_JpK+p2o3+@=qfIC z{wy`xXNd!btm07VdyHJuPTSnK)vL`;XF9fH1(FUWGLf2&%;b_bIXZx;(V+E97pKkEIj5I`RSKs;JsC`tbPEz>@ zgilR_p6#i^nekN!tI`yp0o=#zZgC36BU>+|t>nO7pXw5VWe7Ll$wAD1W#b2sjgE#G z0vTzrg_QrTu0_Do&Nzu_>SwT2)}{*5k0lI}e68FxTc4pURnQOY1BstXVTh1-=o=9! zt_UcI(5?H;9C#ONIXR0{!j)ed0M@2TbNf3PqaV3IQA7H`uDqIihb@L5^eDBTM;D({ zUjS`ZnNa_NKbig>JO9`G`4^7;SN{C&K>gq3&%a-9{~Le)b&h}Jxn=y$8vWOt)!(0G zXZWi$mX(>Aj)9Hkzo(`CI{AO6*MDT#{r`}bV*2}8{{v-N*_r>TtegGaf%Uz5?mN{# zsQ}xG%JaWBgI6!GsR1JHDBr@t8`x2dC&7E*@abKlF2d`{689isoIvwaPfgz2&GAg;SzP9Ks-Nu7v0k_Jd#@cnd+yiUMCy`W=GXhZgy}+8^m5(utK=+S zM2Q4dx~wL4!ccj=nicKA;%)k++{n@ATg%0krA=`JUYyuXx3~E^(i_|BfXk9zWmDs@ z@K*ul#>ln{%R0MoJ2yHHzM89)n09F$!^@K9+V>jB*MWSi6u63cj^sVMC;QHJ`m0FN zl8A5{Ht8L5+z&k4Eh1Z6t!VHbO)34un4=mQt7*Y5_-qTB*QQ|&g_klL zIOQ(RBPBjXY`4Q#VaX^S_dPr1EA2i@4>dkX(Rw5~_B4c^C2c*?wEX{0B)QQfu)dg=*P&DYtslys2fwz(E+Kr&t)U482 z7~5Un%e~keHAOyX*)5+0Vk$0Qzw3D_OD@9&MFXlY6JYY5hn=Lvf-Ti>()J3LYD_YQ zmbJ@1a^Sr+K|~Dm(}R)OFAB8#0x)>{172vOl!sN14Cpe%OFE5LxRNQt#VoUXf$B$_ z*k!yxyKS@bD#VfImF8Tn!U*;U9{^3x1{n~A@$t>7J z-D<#bGN*dUI2{PND0@z{iu)5nZB=eoV#jnnlQ*Gd>vc9Fs`5)h2y2p5F0n1NWYj;t zf3!D6OjLBV_Y;&UzA+jmJwm-GD81p)R(C$fQ(@hrs;YBwd+NJaaoTQn+X=@BQ7WOk zpsPti!rS7rXwb|qM45$czCF%Dr2Uikar z1gnG$B;v8?^blG<=h$}&$~gkmrQ>Mx5~oRQ$)ii?PR?Lxz@|w^ejBO0f-@0E32f28 zi7#ogn2#q^|I%*YZ9a?%e3yC$Zx5W&&JV#`BWpAw75kZ&XJY0Zp~r-Jlz@BX7iJ2W zT{eAfrx&o)Rb+BL4G8w{uzbdw0kRY_pFVgk#Do&1Ulu2DW_dNom#0~U`H8jh=Z5Ht zj+ZG@9$vfY2H~E33|eF9?;LQ$vP#CIilrTO0d&8k(T^;h?Ge&~utEq3>$zKrM-pNw zc1_-sbQa+FYRfA<;M$;~L7ay$UZfk_4wHEtc)2;zg*&;B zoxukoM*V9N#>~~OPtrtymwqJO6HG%~H+C2IL1Hy{0Oe+y>r1zc4u-#uA?o{a3`L1S z_=H$lzIPqD?{NQZfOT6xRZx+Rt4*K zZBJq*J%kcA4SRAU-bhq43bB@*S{zg=_`{R!2bNG1C|^SQALzJ9u6go9f9f6^p&l4L z<~Rj_tZrL`aT6!&8xOU2{Eh0JTH=e&Ve{s8nx{W_!(t@rEsP7Kbqs;@Loz%;jO{Pe zim6L}Ye?3((Clq91E-%rqNJYqJDGn_7Fl#f-4ruqlEOT5BT)NrbF_luM18uu-lU8{vx=X9S7wOir{9tSROAogao-@}O> z@1xYGbLo`{vl4+@2UDfx-*L3%o8I#DnVKdBxWwx*~)jj->@YbHt$J8unHJ zK8xdQLBoM|x;+O5X6C_2 z2mv~6pl}?PuoqE`dS?0)hJmeJ9g=nF?rfrRAA7P;N{oSP84NWwS~%#4XE9f;#VN2e2UQaaIoHIB{isS z^KRRm4M6vL;eK3btGOLBtiyQ6nP0_QH*{s1YdKFqKEiV0v36e@hJCc;fI);T;renQ zUtg3Id+g!DS$L@hRlzTEW^Vu}95Fq-t)u5sV-iKi!imfnMMgeOaHi6>mR9&ctQ~Y7dMnGu25+dVn z2@g)8Y06ZADksidVLSK1>oQ0*BxL-FFk8|tV2=bB9Kjv1-KZKMlIum}-*c=nYQPel!&VG(wV}wVUtdo zBqFO->csz=!Y0vrFW<3<5rsyRn_{mW3aS$ox!)^^?-$w5RlZwVXygT_m7Dk?K8H zF(Y|gs&$_3hsIx!y2fo=rh;dk-quagsQK@2ax>?v<9sWuv3kUeleraW9I zSK*vx=ct5|%EzXb7ahhlkp5r$p(|wGBlUw%rWQlSShh0Ng!Bf%e4AW!^{id$GINtk zR9{sLpFkvocv!C=VZbxR^nIt)UxIi!RJH7WVY^&_CwH&@DKA%p`aEf<(2Na*EyHlS zYs^?A4Wn#Xz;<;Qe>6IRI@Qnm0I5J2mt(6;9;=Ljpw*Pn*M9&V76&~bX0~y@Y{Z>@ znnxz0qi}q5oK1E30hk%Ex&146|9ckye**7+>AHU}(qd!!E8g}`19SgMJpQ{^;V*dq zOOF1(ofQ9T@%XQI|9AZUKPVo5FKqkI>EPdqn~{_4AB)F_8d6RhYzW=Q-#uESXanHA zBlo{evn)K#nd|0V$;JZ645E-DlOX4tfAa760H9DV*v=pArt4M>0Sy9m?6g4l^8d>1 z^1dL4-f>f+3>tcMMD(&n5{XiWV3#;F)S=eZ>)r?B6CckT9VfiXP(sC>xW@jIBlYhayWZ|bZ^t`XdcDX!aMy;eZt z^iVzYNp^|M#OKvp)EJ7XqF67!qNr~3(Q?I3sTs#^tg*D!HD345T>^y`DR)yzsicjD zL@Esm5$m@9++4M5k9jGof_51(tgMmTDo1MpeA9dBNA0KKu(M=YGck#oh#)H64+$u$ z=!>0m&a7(wX_znHPJLEIjlD2n1!|CaIzzJtdV*{|QW(d6xCFNR;NNuQSic{x#>0qF z6p`2z8A4wH`cw!EeI4b$nytIvT%KrMVBe55KUT5LA{En9UiiinmaX@=l*3&?My(7O z&@bY(&+ucrv3j1nesNJmL$7Yz7NC=}|26FUK3c*yeNr3HbzVTOS_pt2W?Dl&`T?l|aDC-g%&uuQ1|kYTxq?fYW{LGS z0If9!zAUB{_#KKR3m2Q(CbhxMtEZf{V)GC4gen9GG~xuSs5L8hSvr-DnheDFEVWc? z0@4@=m~(ov*ZvyrlQhd0Nl6kgVIpD;!_4ijBI#o7Gw(e?&s|pTj zi5*$vur{N(fLV2X6&f(0g0Vf~&w>E{$k@XR3CQkk+O%wsfhTWu0gQb)1NjLtT#gOC zK#GZn@$b&1%IwrXA^|L)w*B_DHkd)9yVUhZ;YZJveKa0;3UrT0&e&ac0~IHl;^Mj5M7d0mvAgWjq2= zzf@8+nMO!on&_R|kC@LV9YK-_2oN8N8FY-m6bi=zHIYE*bNl-wHW{LjTqfg;(qh+6 zAClOc-;^N=F|BxEi!GG%=>>_GjnkgQ9Wf#xo(XQmxUVqHWIs4@mT?5*D?D?E#weH? z*KhMwj081jmUxG z^)Ob;Xm@;0LvT{wSer$^Ha{HaAW*oVyJ!9M`?%&BnfOFj?uohw&fl!mt47;BwOSsXQ0+&L_~mCtJ_CX8+hL<`=-}V za`wq!xs%_IIy`AvpBHVGX8NxPzWa+U&p*zb?gJr02MD1L-nT&S`i=#M2>NhJS#t@=I~h+8tPF@@OyY z<}492bH;lvGv~ld!-B88FUUxN?ChRlD5gEdh%Lw`EH@JUF-PsTM%&CQ#eK#- z_A$pwo9$E<*f3>%%UC&9_5>yNkW#oXu$sX2It@O&7%AYG12>lUh_we@#(o z-wQx^o1ZisSKTc;>t?xUgco0jo90S+PKOHa9B-t%dpYh*=m5ddQ_j9SBkqRihw|YO z3T0HY#$w>PG=xr_LbAaLITck9VrA&V3MWmACF>8HH$Q4sWOY{A#o*&#K!lq1g~jA(-UiC z`T3gvz!a_lqF2vHN*?fKH>EwVGb!!BjY9BvY2)cA%GYe#-ex32Di9@FK_m8l)jkS? z5Q27HoueOTdiXqKuSqdP0qI%fdNrm<9wE_2W202Q<4wUb-6#L|8A#~yc~(e3=;me< zN>t`gTT6(vq|rDZAtLGqC^*rOIih@pJS~KGJU}>>--HIhQl_uV?h2KAR&;30mD3v^ zHC8q2)-8bR{&s^LV;0LOk)Qa2c!*(!s8HhRp!_o{Z5Ox2seP0m&=Rg0yrlG&!;J-?l%>Q;1{*Qg7|AK~? z|E{3^8x8$+j(;X)vi%)a{>NwkUCLx)Wu{~KUX=CUil6>E`G04r|G%V6=D+)A|3k{; zVE)H-{#}}ScAKq;e>qfPR=E@kD5&h(di&a1wF8WmaK4M5bm!`@F2>0%vN2w6*}sIp zH=|`2gmt@*?b(aNnfWpcy&O+f=581NkuGoju6nk1@={H5P|ZTs9BH1MVS8BPFJw`@ zc`-4VH+QNj(5soIZ)gnnZ2`k3^Ss-`X}9xh+t%*d@_w}+T0Gm~vo+sc*qD0Q@q2Us zyqena^(;Miq|G*QNHH;k{AJ{5%+--KnwlONrOh^X9#+S1JyNm(f1IkBI;SH7iyhNC zsrJ5bGdkd5NxT9-`u6%hze<92g%j7ssV0H>ao~38;zg+TrWq^~?R#RyyzOvyFj9Gy z7ts6?7&Uf%-8!F`E-js>zf^~qee zMuF{P-%@kDSC^=_iN;pr!Mft;rl#;E-$eA@d=_WAXj_Ga*R0?+F?gAS=He5Ag}Ppy z%h|ewIJv+b{vxQ<&?&Dn=%L$R#Iu~9)d6JiW^?_jVhzo`#kVaWV4N|;HpPn!3H%X5 z7%)7zo)O{3MQCmeu2y(k){l=2n|Hd*SbhcPd^bCIaB!Vj87J+Z{5s;b49_@frxQbT z+I;0|-5{Cjkbj}6_a&KhX;7J}0p~i8`%0@TVLMb5ugUnMIUtGNxHE1uAJn~lqyLqv zB6XfF&j^Z57lk=m=PE7VZ6F^vee*nBwZp*r(fL5%!lR^MO6R%&J-Tc#TCF#fUs2QC zk7WO(7*Mu9X4}U$6mb*5HC>Z;f?%TP#hr|h&cudV<1zGCd|NIA+yzcGKdVHM;@d|_ zpHF|Ao9)U&+%a2>VP{Kptc*1?mi|@1W`;d53oirW6p-HK z%(H()GNtYRI3YSZItr9Y7^=c$);iQmMKKhWnGYF;q3b%$k5?kQRP8%5nHM49U zC(Ru+WBfMm+N}IVRy3@1UsF&?!2u8TG9sOGd3uCYFWcc^*E6^ zd75UiW_>BJ8kOUzj@FMULv?q*8iZ#knNQCEjC<3+k1I z5!0nb>8nMbK#)ETXVE?u8db;|Bs>A@!uZ)qsHs@k*vU0Et}(8m2jp14QTXZ8F8ijq zOTvc96Q^*zF^#-RUhSiBAzKD#9UVK8tzI0;-uLnNJ9x>)4Z^AKI3~K5v0;`y0w{h8 z_B$P~OE^jE30of#5cDFd2mjRPp?F-|K1zbIKt_^*6vontn{0He!7GWtAjAY#fvT~L zWlB8M={8-}KGtZ~F6Rw#&UV7nqPwD@J+2hYdB}3iFhW-gG3H{BKb{;_GzCc!9!rP} z>`Sf=st7D8E!itn=ZZ8gdK@*(S) z8=iQ5ElMyn^QaE!k{V+jaNILkqjAJ#nrOncM62C1lozw}^Z7bevu(F4+_)>L-Kb5{ zjcgrQhUK}=1qS1>mLM%p-GD8Lv2S2BZpVvjxwxGDRQN)y|H3)hHn);9h2;*1z z>)N#F=p_;!Af)VyAE`rttk003sXEXa0w6J9&HcjQfnzc;xC^Lu;#I6LvM0w{k(o`i zq91kT0U`ij(iJdX0Uxh;q&hCdnA0Fy^#7JM^>XLnUFFp#IL>II9Ar`i?R z{}i~X*xgU|#vFax6-+Z^X{s!)N=6)aEN>c|)n^z}gnn4mrs6#l1dC)jZ1Ar$Ov87- z(VG3qAya-(M3MXB4qB9$E)b}ro{P@q(a2V3m`yF87xhJ%^oJGINIb?mWa-i%g|!ou zY+x`~>t_HWHkT78NqT2&lp^>%<2Z1;DnYXTi^Y<0po&smRYqW)-uyF*=hG)F+w~No z+;+YVV9tuPryl`?$NOhVje+`2G$;$P(truTj|NinBN(KSigsK3Qk4lML~`0Nypw7? zYz@o>*;JQfora;aA1c&7%BF-NH@2{@;$}kvMjYp^Qm+KY~wP(yfe|sFrO!f24pI#tiZ}ZhU33(PdVs>Ov{s@u@I3kQZmI#LHk+kt2W+<6> zko?4je%jUOJlUwRfkf-xrxO%gTd+uU`4jBZyjYY4JzSK9sIkjMQFR&hk zT457hY?+1Yuy!@g9~9T-s2V{Px3l7116m1E`M1}JPexU+v>ju@vC~5n>GVIADT@vw zC-+B~Chzx==FU(O&TtYn01?8{GP}HwE;pZyu2u1!_pWJA$!K#-Jt+S$L75|^#PbM` zs)2!LdPF6+T0LILPE3Tvt1825lda@qCZqF~R@1;@;ln=DsO(eTq~TOd27RbW`DIN` z#}G8i20gAUj=-ln*tTR9b61)hqNLsh#p&wnKk`^WQAs+zrj1u}zOF?PDNBC~ScfB@ z*XNRwW1Bwgi8iSQ0c|tJE~^@gAcN>lFspc3aQK3MdcS$&&fj%I9N~@a{%n#!fi&q6 zmD1dbQZH(dwfn%pH6GUJF|B(|S$41Q!Vhvm8q*-mZ$&QxV^NT*_yw=XV+}I^xjQNO zMr7%Zj^V3M?{GrgcYhmE3|l0sd`F^~sUnypR~W&gjF7ttUh@84&X&LFyW(I0#!FSU z>sBE{zs!7WF|ip|!B})5LQ*OKv)v~TZJO$~AiZm7kd1OKeK*Q(-;*&9d->XeL~Ez> zoOxtQHvJ32J(A}TiJ|zamV3pkd^7%du`rC+;E&Ep10#PYW*5~d(>t3hhKIjS09KhZ zkP9^o%g2oI-TE1D$ZTHfPotYr zB>~KU^a7k{N*L^kd6P)xiT)6HmEQ~b-Y@&YPz&!m24)YK3}LxvpsoytXh)|{UYxzn z8(a8gp(>JiZndOi>?+5ce4OD!gr}?f@oZ*Hk-G3AsmU7t>s0jYm1oL-S#Q$W1`FHX5Z^^iC1pnWh zVE!&6|22jD6~Fr@dhTEE{_iu$|3N*M&Se<7IKFQ~FouXw<6CmX3;!ThnK^$J3Tr z@-_vk>GWyl)F)X)KTE6~lGOl<6MN>?)Gt&(pLH2q&L*zncIJ?jD@mnsN z8~?9m(UAZ+wKJ0CzEb>4cK%<^Nbhe0M+Ne?~>+hTgC@Eqwd7DAjnhbpbr zG{GKFgxKL|CNsRqp^B3(Ig5gts4WAXSiS=-garbcEV)jZL~(2CuCsw6?A+WANS5|B zWF0b7nbV1Jc2Td}DDn9Z{`8M4BN(y3T6Djqt|<4{N}t?&5uHAa$y+}zy;VoM5DsP3 zE7&fyyvP!{2rRAVzFse*O0;Mh@3689bxaLx*jxP1gm0VD$6qLWxR z$#0I>(WEZ`{&cYvI{{dsj&!19afrK2(b!%YF^UoN61+imMu=vQ(ikzi;n`(Vmbn#s za#A<}^8@nIHWUenYjxK*0h9y6+hndx)(|XoNjp8S@SiW*0p@eZMf3pJM!Hnj>9DgD zLgw_l-=x!Jhf5@RVfM~(Te*41Y75r^!Kj)!N0y=M2Cqe?I-hstnTV6)n30I09T-di z5g8g^LEwcIo{6}fLGaW+^HbZt*@wxRB3zgHu}XA}{plK}NU+gK>n{TuusGyU%ZW16 z=}$K9W#w10`vdr<(43IxCdnJA+Z!E9^RT(cD7e4qSFjjolii<%pJA!3c%*<}<@?eG zg=MbiJqkDoit3m8>CXX-6HT^0(!dBeARBLQca2FVNGe=Ns7RBDX48o~ADWuZh?sPKeA^0*jDHYAXVvArLc*foch5mAN$zHp>n@In3{r2(4&^Lhn$(EiMk8u0rAx>IK^a zBn6L|+663?x&azcP28vVDSY+-)31S~Y#=?j>@XyM0QuYBrVzrX#)79V0 zFEuN4@WfCd%L_38fCx2OO81WXkbu$ZA?5wD=J(UHr>k62M+WP`s_x8X#2G3VWy zhhibCNLnpU0k|Zbo^PMChgQ~ID3noFOw&}vdvjmY*b3t3%13JscH}_0Tm z*g8lbF}Yt`juv?*NU=%Zd}!yJ(2@GZ-!G*uryKf!UOhPrQ9^~AN^-2T zb1d4jc;JaA!zQwz+#ZTCq$l}LHuA8~aHz@<6_W0^WyEs0LVO4Upl!Dok_*21e4 z`-1%){Bg?6vmxIArhpi|Yg?M;=_$&q)-H{B@03t7iJgiuz8M#xW&xtDd`hSzgZ)*% zp`UZHPDoUfB0}1%vJxzSEb`y+`GF8PvKwQK7#$^i#$1ld!OH`}^C8ca9fa>sU3Zf5 zyh2b!t>j}CK~z$_q}|AcE>C0uv2X}{KSOs9_(Ci4Jdjt9qWsv$acZ$!ZHYSwf6;6%qafX|B5_2aLACCkm#*fVOv~nEbB1S8m?!u13JjUgl2Z?m^E z$qp_X9$%TPya0%Vg!oII`Kaf>Bu{H75>*LBK|u~z7WuEEmGA2O%d4#WOpiLxxaR<7 zD-)F<5%5jD-D{uC=b&g`1GRpuw#5cW<&YJRF3Lx81)9Fqjq+5&kCHxthkj-A9_eB4 zw8SBkhn}Ckw!djf`^9>)iXf-x+me5ui?YOMm6b<^;`kdyzrw=1Jsbw~CEfz2w#xVM zWjh5fWeuWqhbJQAhtPoL^9e%qEC_H$NSQ7l7?2~0?K9Rs?;kEr>Uqt5mx=Ss?&k1C z^`{YootK09m!vt0Gr8i3A;?Y4O4!uhgN@)FI-$b6AH)~0X2Q9F0PuG8KgCB8yVWx^ zN;4#ETJT7fVWWuu3G~88u8teN8#wT`B0-354ay1g65oTbNVd$VT*Ajr%8#WVHfDg{tPfbB14Cnf5mDPU!U|ib@Wn(gw~+Xb2@9pQ2wh~I zzndj*4{Zt(MgPfSZ+mYGmPn}ukX8%ow2TgerL2;>R4W;E0ZpeXuT2$HrdxW1$#3IB z(}6P-&3u)&zGBc+(&Ls;A2owES+-=Hc&(OoscVd+S312;ucC8rpXRWszK-jU% zVY+0`=OnY-q~tpp@wM@&emvhF8-!bvbyq_C=Hu4l@x+grLwo$MSp4rMhkwoDf1&CB zaGUV&c8h;jO7<^q6IlL!iSZYU|CRpxM=cf1e>WTdXDiu1x)Ath$vl?74=Dc+jDP#D z|6xl-HI~k|x#D)KM=)+tIv7b0#N#Qc(J6+;VKq`KUQ$kssD)#Er+pUg3 zWS-%p7(8>=ux@8n2k6zo<7QwcaE8Myec7;ib5eS^C>^s{J>zuEk@pP;a(K<#011)y znCJD-u{*wBICmZdT;l$507rM{*8Qu=KaR@<@0HWZ@P!(>tSGq z=i*LLk%{tz4j!#~yJ&puIIK+dcm+^d zb%Hb0?{F5`1WOK}w#^3OR=|90b=QN4zWC)0DzPDi<6r6{TY>Ag7ZpD`p>|JR7LDiL zro!oJ&p8S->(nR+LwHadi3Vi?Lgh#VGT9lJvQBnUEJeQk+N8qY@u5C$Xi;)-!t&d2 zA}+sPY6pbh*G2#O~)@J06cY4mun=peR3rB#U3^L{U*V0ECX4%MyP6)FnQo z4FaZb6U?kR!T_-PS_eal&fb;u=<8djVx2R=PH9}GPYMdr-;n5l&K9opmJ6be6!m7D zo4y?X6HC@yoT0b(CB@cn~yH0|f(dY@PLJ{u}JRoSm>&vImH`+cckq7)5H| zx!IpwZirxrhDB}eX^YMm_>1Ec*^Y0c@=EUr8ZV0GmE7Npt^qznQXS!f=e_&KGEjSU<3C0lpa@nnEr78C~gmJQU`&9h$w4ln8@zrl&o zjX2DK!8oXBJ7So%?L^NO-p)>|?`Le;3FuaF*d14k>2k*>-E|Che_p}HNaeaRT6s+7 z(}gRaySnQ9j?sf(5>R5bU$u%7U7M+U*G4WgTFN88guCE#!(qSY;Y6C3Du{*-@qh2& z6<+LC2aKU9jDerY+2GA9Ij*Rupg`gF>~Tbz<=~G-0_i0{40F{rREJsOy=(?0nG%qe z0<9Jdb1loF>_#@x8v}O!`5kT|a3|JIyE#mXUNH93(QbR<=o7 z_NS7=Kruak2tH|%;9zCwVcVuNiAb)*!g-UMLIVSEyI-D{*19r2FG61;rCD(k3^XP^ zAd8{8*0gRhyWfBdazYl)L50o6=)$3x=ic?wb)Bm!Hk?x_+in@&av(QPX5Iq1s6k$l z0azXQD^GQ|HBt2$Xb&Fy8f$ZRQNC^lmBB?3ZfE)M#_|lEw}67BdfnO58`g4M5NHoFK;$n}cKadmI!fQV>o!vvt9vTCb&S0`^sJPB2nHS=#lZ8q~f= z4_K4Bp$AyeAIOSkv!VV6U?DZO#6W!djxB4~DhwC=IxMMkT4r3@9!6GijDJi3921GR zlo$kqtke5)xZJA~*VzT``iqR^&L*l3|yZe@KC};t;Qxxo!`$p+AjtOtvvi z56vQ6+dffSZm%pW{fL0#Kcj3fyZ3^V*;aAPT3;|j&~ItN9?{3vV#VO`;eExgSXF{A z3K-%}h4=aL_xD~1wqgn^sEYCJ+!wN3`Mxu4zJRvnNV*zyYp)kWCk!tZ6`NQF_u($w6Qi4 z^%WdG8f{UwfGiA{2d)?mDAG>diy;_-ucN?0`J~6<7`FV=?kY~0z+lbdBkhJG`h9@ z;O8Go%-t8kU~e*Yte$!g1hSA{A}(YjrD=(Z^`Tkz?-OZ!yU%-v=BN%q{=mLWDk+SE<18^tYaL zSzntm#d$>bGwC5mN!vMLe$iASa|D}3?)Jr8sQbmqBIiBo%zt|BbV4OEj70Gv)NFFs zNc(9G*^h@z=25&s3h9j3A|=V?+{C~4n97KYpJ(~JiN(0}d&86JAXi9>;!2uiUm}{@ zk3Z94RYkJfHS;bh{a!lPWi<9pcSO4N&4g#C8&owr$(CtxDUrjY>PK(x|j;8(*%vXScKV-s`k)ozu>}(dLhs z(c+Ey#{3g~JkduVh3UpkkwBAxh3OAVjRJx8pVKaWzxEGG{eQOd zdjS-!qO*aMyPYust(3WqB^0fIt%H%VgXSN|nNFKlj8>dhQ1cH#PN)6HCJmhkG#Tia zY1ls%H4_sP4gKfLUIqq+&xXU#b7nRgI%fLM_wf^OaS_le63~j;D%ldy3K5Vy=^I!X z(=gC5QxJU0?9ap4#^{gTurU4EQuBw{|9#K?Rsu28zcTwjFJ)k3prK=BB4D7Sqxqx8 z_&4j&@4Nhu8}gr(!v7++XZ~{?^N&h_<-e0>H}0_eM}D#5Be`lD>XmGwg=_;w35(~5 zjj=~dGvz4%TKw9wlVo->Q?#WH4*;M#n=|bCMWXKCZl#9aE;3%$C};zjNTc zv|Dq;);Qv>p^GN^Kb6^I9>$8zXyd{g2c5P=RDl(5Jf0O#%xl3Ri%5@!u7Ne ze`Z5^yrSN&OF5p=(GBBiu~8oeVuk-Pr63|;q6_bg50xCpRAyRUTIp6GtXTpZ8EIm>Y zshd`m=Nu=-1Vm92e)`x}V}@AEX48IKWHScz=6jday?X5`@}1fW9)M`3cj#Wlf@MRU zb}xOT3X(;Eg1|1yEQh|J1mrw$^h6KCh>LS?94V-7RT?0IXwp7=jrKSRc^)f2IT`YI zSThqx$`B_j{I0L`{Nqn1)dVf?|4Too|a5SZ@@!fXtd06G_ql7dw!KApbDr9T)=D|1q81c7|y zgP9)Es!x=}$X#vg@SbCX76yF)&@nzeC`vJDvR{=s_!Hw2JkR^4sDa~W#=dY~;h1dc zii=QA0Ss=fy1Jh5AtF4ZYp{FiDAz|6dCLwnOa$v3yJ>6T3DRX9VW6Klow}g26%g(2 ze3YV=uoca)4JJ?xs4DYjXNLOTnGKYM+$H68G0ddsd#91l>*(%FdqZaQ(p&FydeOAp zf`UJEK=mv7R@cJ1vp<$W_2E=4h_VxCCkB2TXu29Cu6f1yK`vmKN%B+Yn15@woy%Am zW~R;`yFpU}c)qa4n~6T1-*1^RaNrh=)Q?d@2 z2H&-cG+Jw?f!r4UE!MHBvxqur*qvy9g^Je}M^B?OCUJm9+fq;qtk*XhC2b#%LX1ek z2U0}!NoNtlF;7`t*0N*qsu8#=K`Zx(3G12}Z8P^^Ohhd~c6ShCzLV_fWUvuf;E z1?H?m)8c~!+L@MkI^CX{a7Pnh$mny1y*#mn!`}4qBkD)f=4GIYnR5t*IRf&sDoqqJ z`AU`mVUrxy;{|NYttIGbP{65pSsNiF>{z`_5^50GE?e7zGBkoU7Z#4CKNah8Q8?X) z!mH1ZQMBt}B@{ERZv9ARXdlL(;2;A|5`(%zIuT2%B zs|rG+rf?Eb^aHyxjF{^Eu-x=3M~IMfU*0`m2s-5m>hY$Y&Azo1MRlbKpY*A$&M%2b z*1~!jFu*&AOeTzCpv3Wl4Q2&PJ^FCj*TOdi?6jqdsHjOf9=vkCwH_x22Prd#AXKeY zt0v>KQE-AwJD*3BY*aj7M@tTeKo8Z)+|J*yif_%tpN!SXsn%VCqf>^P37eNZhkJ;_zr!kRu0&+fPTDTuR-B!qjxeL$@s+JQ>_hE3MhX znlg8XSf?&AuEHR1vYRn-1h!sYkr@=jA2Pl`;tSeZqkwlKD)Oa+gm+bUV}mU~#XnqJ z6-XG_78Wl-6soIQw!RF~F84lidQ@zsxpf{$fRz|uTPN*(l4#7lpX zKDocZ;X##Fs13x#2+9A_B7%`w4iDdW7Kp=QZrq?4TCamSvfF+oPdW1>IO|7MBoN_x zjYQ=%G-smb1Be4`;M zkcQXKR4T)%1`E7f>S0)!RRyu&nW|OLY3_3Lp8IkmxzQlI=6nfKJ4!l1y0>u)2qmjT zHNEQ_cVJnKlS5SDe;0ZfpeZ(A!*U za2t%o3POP=aKJV~QcHt8>Bh zrGyUm67{pSi81G0axtKoYt*5jX(t1wxDtTjy--R|^=O)Hv|FrG1Q`qbELDWV!(;V? z9B#LB{7WFP9}wY8XBv)6MdOujvzQwJ7QQZh03Rcv2`RSK92}^vEwqij%tbAVO9wi_ zYdcpJDWlzTllCI}KicM!99_GWLV0}z8M3-j(S~>IdYSxlpaGj87Fj9Ty|lG%TwqC- zQDTm+(BX+M3yzA$n4i4HfK%q=G^UmkWNE^GA`aU11^OVe>jj`^U)?%Ycg_WnDXBf( zYQ=2@u3X=Dg5Nk{sJyvn#LsT|#`f_2(55Jy(5FdFI^dy_4g4W=PF8Ls0*C0>Jpw@M zxgk6%U7m?n&X_U@?bRyD(F^~Q`dyJx2+RIbKZ-8=j)S*z_6FU>k+>@Qt{?ha-hss- z6wo)iSFyEc>eeA_4+%nHj_RQc%2Q9CwhHz*kzU2vNfA9${PPF=cMz4A+33HhUYP%= z0sf(o|GIklEph)D|1f{?~?p-~0Gm%>*pJFaD1$|EH+`U&Q~+ ze}(^<*#5Q`r%GMZaitl_XR_w<3%6k%2rU8o!KnCJ*`(A=n%bFD@i;I^FPbO$45^rI zI&ZzD z&uXTx#>Ybkz7k6oRWuQAM1F(c!8AJ@hbH?yrGiiT2vPR^9@_lbq^f>3*UIhL0-d(T zyUXC`ppCLN^*K(`?0ey1B}aH&jA=COr8&i;DXQ~}ikUF6Ut%Q?Hfrb1=HuV{#aH0k zGcVU0!Kl$f;~u70)03M~Gpm$NhwDy5O~Mp$qJ;LfyFRknL-U8MZ-tH102}bWt)*3y zQ>DW%8pD2pvyto}cWaa0xU!3F2f8`=En@4Py^{Wrscx=_%}CO%X5j9v;`S(<~2N} z3g~@Q>KtVmwT(ljtPliYi{S*YxZt-cSk=4&||7!5OGPfXSxdb}bI= z;!Bw*Xj6hQH5)`ENX4^v0k#}X1eY)Q0xNH-R?Wu5E$lrUF#h$XxBIK&F7*`SDNWy5 z;X3qe(NDIYstSHT>LK`RS5V-D;$Z7s=orofqSPF90Tj05d*1@}c?vNj{A%~KrTGSc zN4i$qYa*&n2m!JqtTSBb-~a^FH^LDdttiaED(iXT&+d(>JSZl5%Fo!hI=dTTSsbup z+!9FXcrQB0`Rj|1;<)R=j6ZWWpmJ(Z7GV)`e!?3{V%l%8pe*f0|AgfZzJ<{Pzpb4C zA`42YMpFAo3LLV(?SnhKZFIpFb%3H95eJ!W%CxFZci678b=}Rp< zsD*F&)H}Cc!2#1B?1_Em&zz;MQ`n&% z+!!>3Es|vm?%HM|sOT;=$BYB!#bVA9*qwqWJd;Y|&QxNN(rDb=2cKo9hHC&Ejy2NK zSA#1d@aSzy3f!ZUtfe*dGiHNR;GJI*XeEvd+%uYkkP);$y*a9Cqv=D`x|16){g|1&--DrDEdU|@RM{Bh^wCn%N}KWgB?B@agMZwFCYt?!XA$p`l&ucj~*#_ z9jwCjc_j2d201c3z+{XmXd*m&56OeCwMcHJFzIrxs~%Gwy1+Y5U>(_h5iuv) za-?nymm!}=X$|HzN2gUX^NpO1wQqI;lYwh<2^`}x!-n;oeB~tQ2HtG3sI@{isnaT& zMh4jVS^V9wZ!XnQA{{hc&`f=dZ>;0I)zG78h*S`q1kk|CzDlP4O5+=lXPSGx@=&XY z2+V?@$HwjaIjYvkVK!{D!ZYJ3V1!s-;A*6Rs=SFpnn`xF=(?J*iIOoC*RGDT8kx!u z6o#Bk92X@bb_1LPaf56B?am2E9ITmIMlVL)vEtX&%V%!w%K+<}y}|E#>$p8p0{#{{ zUJ+d@1#KWm^7c<;{Zrd(-e*VyD-XYUVo>DFRn!(s~#Mni|q z!|>&Hw1hy4XDr3C^q!nlQ9GvQ#~#s6D#vwFbGYTc(B-%Ub*Sb;Em~O?>;`bZc6B(KUBA!zu#h_C`}hT|wW(0phDxkKQu?}( z=E^9Q)A0!%w*ww{zJJF)5Pz#}nn^#Hn_{!~JiRm-*ajra?1>$zEb>kDm$N{T7Pf51 z`q+ZdLB4K{8*k8|)4{mVDEQ`rv^ZW*zN~U*jyrm$W-g%_K{SsIt;9H5dH!IZR?jZF z!G?~i3gT#ObuhAaj$1Wur#)^`B%|cJ0vwKH6M|7I7i6Q+0GYLIR)oj1e6nF5H27c0 zILcOK&ryPv8hWVUHnm^U|lt>f1mg}!7up3o`N&y|tMuSoU03ZAD_=O%0Wza2GWD#QM3xS58jplma z%w<06NSofpbi=L^VOltIM?*i_IgoPhaJ{8nhh0KW>*(C3n3`!(YcTozIV78Ls=&l! zB^y24_3+p4bfJ?FA>phD3G;>h9!C^2ox&xGx$HBOggG)NL}n~X^ z&sHj{uMNB^Xeqa6vLP_QaDuxUX3YpLln{=gd_%a*YcM}#)}bYLbgNt{oi8opXD+0{|N5?Sswo@FlYYleg8X7_21Y2cXj-~iM;>p82ShD z{tP1gyXKhBtiOcSA=s`H)zdh|Cdr3{m|deK2jQ~#gm^OL>Uzh`2|HJ{{aEDq0_{;> z9ye!r_8(12IE8@IX1BmS;7s>t_v5U*hub12jkoKoR`@m!NoeXW37jctMcqs1wm#wx zO-~Q^7aOm7w^}o98ReC&^3=C$8(nV)_iMxBS#OQn`#K9)=Y?kcOq6JD zgoujEZo5Q`aV_5I{q?pFC;Q`uYM*;Sn_KCtFU*}Gqs*P3C}pP=p3ze-bwfovsx?0> z9{=b*9`kt!(-Mjp5C_ko3q?Iuva;x>-D6EOwj8c^h<=((KE(jY$QzY zNCx6`HA;_M&fF&_DkM@DqojHvRiqW48*ANLfme^0 z&7yc;W6dIW_=MnvOePIHQ|s*9Hs>cho{0gY(nr>W5VLdxHO)3{flifLvG+&co=T-Z0)~* zRtj!-xvfe#qgb%DI49yQX zH^81v(PpipXrviW>SP;i>;FN-*9a9I#bTTeHW8!;#0(673s1zQM6lL)+S=38VFD!x z|ILIRhLWie(QumRE}aWHOO|L(7gBc+A3Q-^+9a9mAaxFt3?AGs@I_eUQh(Qb*$rIZ zu9_Z`61dC1L$GXr8=V>pti0OdW%&K4eE`nl4wg-_F%%i3>S~t-WX?WmI@)S*3Nmd_ zL5MP3y{UsBM@w+qm~I-^BdOb}Am39k>-zQP;tlPdN?;p<9o#%Q_4~roMW(<1yHGEC zl-<|-gVm;STWoQDk$dq-iE_~O75EF|I`zgXkGcuPiywR8=iN9efqj&0osg`e_g8qo z7{tD!1$MRronHfClVjB)1V4HBQyc-25Aou>Dx0$+ECX{s!%rpR@#!UBfo^JNn`qEp z!Qy5W2x$W9j`#v~(YWzO#XSIvB4Dt|hkad&kp|Grh#CpBTV!sP72w?zxfKle_~q)U z(z62Y>xz(cL58O0wqm7tzioZ&>(syt#9gIao)ldg+O$Q5HqpQ))r0 z0eUfJ*vA#)2DAg^UQh3BXp;N~$GWg#Gqngl5Bbgxm4F34c1T*cQ4BiMZ%4RJhUh^w2wGEINdWB+R-Ab zkn~=5T)qwr%#zwGr+28>8T(Gr7PuD$IU zP`)Iv#I>$=f!kjD&^GLJ8s2I1_8B~DQa2(~J+9d#10l&Y7hT%a%)rw^yKISf8!eRm^zGB}OPD{B;Pr;eRGx~^IxDb@nR|IbcKNH`*KQ&ixZopv-9VB~x#S^AG<`tzk*#IAs!H^Ec_{!i5 zs9e*mJ=9N?+Uz&7(!{uHo=0n))?Zs)62yEUo89!Iwv6J7PxSmRGps}JYET{PuAeL| zt6x0RAK>PI^wNMQIr*lNmE$aXZJFgPckL=a`_E}Y=F9GUFmreE+;eC6#H#==#vUhj zC#Tfw8ZMO@I0VPXTu}osQ|IIGjzRB~6SW1Uvo$W~)c5e`cfOLBF@{Hq4S%K@-sC%y zKW;k=p+9Pa!O~?DvGoii;b`%h6VPmKjtTStE@Eg6lCN+2-j|G?{4B!NY);_3?D}e5=Slp~c1U=roXo>*Y}fp~ zB)8uPSg*Zgzg1+OXYlOF^hf3Lm7tNoSv@o`oE(347ZY8qsKsqJmACJ|EL8qwjiy6X z0zSm1tgVL2wq1GkQq<6{b-buG_&u{?Nd$o_yo`iDKRq_h(OI3lcs*^XEwb88*hy`Z z8W#<-(tWGe{b)(w-b?)*$S`ftj%elIx9;_2Ux8rZ*MekCc#n*W0;|EcGb`FG;p-_G#+chJo8XTJT1_2hS|_TK}|zc2ppQu==pG_(9UQ|BL2 znw9bIgJ!HB4l8We=QUIE<@IbJ5PqBI=444_qd4_V;U<*IOE_lX&FXnVwBmz=+BX*~ z-@wG=@+%j|20^g+3O3+Jx~r>wp1w6;8uAm7g;@eCCRkbyNXfA z5DL%cPOn-~Ppst=LK+%8-I@0-j;*EJjOPvoX^!NBFt&e<0K!5ZR|7Hx91$XDLY*G| z{)03uC64fU@8OxvD7WdIz0nc2J<&tzCG?c0CZn=E1`|OXrp~lZd5S5?zU}#(Mk{2 zHyf&BU07$s9OAkivZ|AcAAo5CkCw@p7rwSzj&hDI-A!U>@@Rtyo&OPO&sBmB>rcPi zsndE1LfKhYLVJD`>G`}ZUXwDSs5+26{e$HC@)n6VW(QnLIo!|w%27-Ch)>M&M5~;! z`guEpOlsSCE{6^>=XJqx{?CVt-5;m-Q58Bw@Fmi5Ae3EG%Cvp@ch?3ulSjf41V-O~ zNnVs!9sK8Uw)w~NGfdS^A-rrIA+NFu5xHDp-cjWOV!g5DcB9v*imu0f$OJdsJ2I(0 zvhEwLravFpzfU=L%2P)A%@g_oV}A%&dmzG9q@eG($GX&vS% zSdrx>0;38;u4$vi2`Ym3Z*Gf6N;`M_pN9<~!}c#4L@kcWyX5I+Q93$op(*ywby@>0 zvM&xb6FWEsn!ch-K3biI41aHH$=V4B_IUqQLh|V57m)E)8N;m1q!y?3J*b-eUY(D7 zSFKI&RBo^x?Yg-1=1!>sawT7_)tbE?0jT3Ke4n$Q@aK*8n$nANLJB7k*E%pq?pt;- zd`Mhn``3yp;ptV=phB4zOn-@%uebMX-GdPj%?vk;T6%WEYLmOxzha4+>EwqMaTW2#}6Q{j+ zDaL4%XV5KB3WSRUerrS3S)00i_)uvF!mqOFfJ`aW*NAKT!t_u32;lK2afASa6p(Uu zpeAIM0H|m53%yOZRlrU?$XglUHfA$5A|Xv#`HihAX1z0NbkepJ4w9V54!Tv0k(Coz zpVJ>_#$_V;HP#3ZLxeOF-DYO25a&5+-lE$b7 zg6`0O40jeU*8q;aQZ(p=sIwnRBiak&m@)B_m@$Pcq(j&f{H;St`(@Ii^yn8KWot3y zn*GRAal(q!K4PI|2$cA@!SnCJ`A`HjZ;80>KyTdwG;B|565tTQED*>w`ax(WfXfm? zPYXRMM##At>Pw~`GSdl;XughhIM|j*vmebdz#v_1U%KfO-&s00pag)@6JG%rlvSuA zfkCn%;pvwo4glfhC@UD%Kf@35O?S5kL~3pTzsbRoYgB?xwHcb?30r*Q90nr8u_3+<+sY4RU(?0Z*H?Ik?r07^k ztq@?*MYONoYo>nQ47>S44GBWPCQA=tf)a@1Knn&)UL`6Pza9_x8F1t$!r&8?B-8i- zn+DP*Q$jr=bWQNev<3;>!yqbA!pKJzCUOok8B@SZV{pqFh+Wu$Md?a7M5y=RF(-B@khEF(I%i*PP4fg6T$8)`uc z5E#Le%7*f21u#QhIeow=q5-!Tf7;-hv?9h{AwZDew9f214y(2^W#yjdur)@hwKq}w zSP<^X_za&ixRSp(_3$=%{hS@N*4)z?&2YhqQz)KsFYcvyK?V+ai`>{uHI1=Vp^;x; zeAOh8Nr~xD%~K}+eQI5v4N43Zn6B?&V7Bsdre3}vQ9VfgCg zTjO8N=`IKORWhRFnKEw)UxEdWQ!wZ)JoPfO5gcqYuy^go8mcBK(3SLZDl7oR5chgq zEtXld=jqb?vR>7SBjJCfLv##@k&nqq2_nbxY4s)#b4zW>x)rY(_pmo=Up~~x%1*h+ zN8v;2ZR>2}Q34ceRfMfV)9G7n#^WIikY5&%<=F?++1y*AL;}3a9d_K~}ig~Qf_Av;Uay%N$0uTF^>TKpBm$dDU8E^%(o;(x{ znT|P&gfNGT!7*C|S9BEe6HIY;8;+=ylujN*4%r?tfFG(m5%g;b-NUlks;oRZ`ehab zp;-f4%;Oyj`W&w#Zd*J4a>_WV=w1=%xTpeKJ#*=FNP6IUNiicFviA_Xe6DcsROj6! zzUdgH9UZdVbwt>mMq1cy8Y>gw1qIb44ZONOKgvByBl=Arm(uJ{YS6=g6MMGYLK2T= zyF*k$9A7NrW;=)MuRm$zWiK8~7iWmr`_W?49!q`rL@@~S02&dI#P4BY4&D_Jr0D6> z_}i#7u$FH5Frx*rP^S5-5~>LqFk)~l;@!e3&)>vgFGO!en3P#N`)BPJXT=#4LN+BY zIO#5T==qPo7aTydTAx+WFH8e|a;tVjKL`TE`jRA$x7*&9@5 zL058$j~8K;fq33%@lp=0u&8~uo49Nd9mK1o)0lm+FzCaWY@6Z-ad{a1swW_l3-V2zyg~kuu$+v zX}3xR_{F{3?e!R6ep__9t94S{9})&M;ezE0gxnq{5Zs2QVXBFsjEX9g8Yl}Seqhdw zP>=#OaI3&bM1b@MtE0lkf;WQDZ{Ue8%|ISv4`$m$1t2#=eqoYJTNz(CdzK8rZtU1{ z(UqUKATJ0NtuR8mT0zs?;D5!tl(+Eeb!H zNIe}1$kZ?GwV2B+j1Wmjl^ep)PY)HN%p+=)n`)$2XgKRyMSmkDBTbd---ZOO7a)IB zBge3f=}F_h#UxLtgWXcR=a1WN`bCqaaie+j^Kx_aL{z8? zpd=l`roNgp*&(jPbegzzlKk%7^klK1R=pQukmQcakBzDiVB_hsvcD({{wW*suM30U zGWnko`)APgeQk4kqmwyHWd<#RdQkWV_lgN5}1&6 zhnN;jLg7rgoYJ?G{pFgo7(ME#F43#5O-snXCP_m`;E^LaQo8+dSJ=zF>uEA&!=7bz z)c6owf);4`cD%d$+5BcJWshTbZ0Fqpm*U*}qknjuRua#>+o$2_eHh>DY9|zS3tLg= zM(&v*4E-ebDXy{6cf)wkVf@P$$v&os`%0u{5HkM?4c+M?;*J!O6L4u+P< zc@plb##)g8fYO7!6m;1Dr(9StqfLZfnu=vH47DYcQIP{@CM7O*Ru!-sWTRzbL%7s)ZzsCEQFEI6G8{%O zu|i*o0r4?_0(~#0vg%RSaSNN0*JSlfb9`&23r;k3;3jp^JoQ%7EnZMcYCIn)^>o0z zw9j1{@+?%eda99er1erA0k*Ep-MUH`06z}Pvp*Y2JpF@JkEkL8wP>A`s{Sjx`G~a_ z0T(;Y@v+!q@X<~#*Z(L#nFhL9ega1tL-s-o;JI1$S! zgr22cNl?pWw4U(ynD=I`$D4|Ukg?~@vkG)5pU2tzcu)Y-)zTj)~_>{!jkb{$Qs#&~K zoKfnbz(lcVP<6$M9t)I*Kp4hR^GaRBso+T3*u$a}zXL>3GzoXKjS$uLU^SGXmj23# zLt;Ss1WlYFeS7>>&%<}3#&@{df~ZI4SVZ2I8-`m*v;w{S(77S8qx`*OEh`K|XO|>a zYn7EM!5@nw)PP~1^efR@Ob&by!RqkMrK|?G zca|m{*@(`EW54hQf;1;gKo0+srBWi5a{?V9%Au+Vzz_9*PzqtYPg1xL%ozq6n}vL{ zZ7|V10N>e^9f2Ns23v3vUT>X!F!21C!N^ zX9t|jk+;Mf5?13?1Q}}Ikz#!`2xytLDhqNpMe31b85!BZW~?6Z%pX#*o$yE8S$^Ev zTzE5Q+L?P3xI)*oi`sOpD}%P!Q%`!e=crQ+5qFc8l@lEicP);VFp8Sv)xrujQHFlS zUBHrzvAfPzX6Lk7E@0U%r}{T}s9F_Iw^56l0&aRu0&f!1#$onZ=PYq+eRy^4PD6lf z>Y?wL0?soe9I9aharifOh$2{e0Z#h+;G@F&Cqk{2AK`CJw_O_b1ou8Kz))Xpp!*CF zp*UZN8n3Lu0dT@FB)J>$zue+ia2u#J<15ZAqyS*dEy8{+LamZJ0Rphl28f^PcL3OO z6!z06fyqJ7;$CcQtBYe8amj@_Lv1z&W&v8J zb@kFmaFnrxhBlZVU%otXexGdg03gW;N(sU0={29=fO+yAwFa_q&O26_4@g8t-OgRt%^7iG#_F@%;R(y-W=x zJ0TrJ`S1w>#H!%rOE3>>SN_`OVHjQ?dG~S?h)e|>!)^E$G0;iI<;*bZIHpM>uxsGL z+iUd_sr8GLnJ^FZ5@R0dVb&4t=b$PCMo}cT90MI*4vuJ*P?v-+rT=jH+M z9a}n9H#2XY2ut1QMA9FNhdbTmapNc^v)}SsKtGC;zDqT5es_?@tBZ;mI0Xj15pd-0 z$~eoaOK%Kdfhh2~b%CL4w`kiE;*_~u*-J$>Dc$`X*o!MTCWH~P%+{Pa+lixPA<-w2 z0!@jm4hRC~fB%I#{EyzqKVjqF8tYRq{*V31EPwVm z{FZpXLG<5>Ct>|p)iGa3I~)3GwM{9R3# zq%Q8bGKBQU+!zQIA&>?=PL61;s|qqQRC-F)y*&U#K`3KtF97mUmA&qg6ih3?tX+Yh zw^rPpUTfU1J`dxr7lo}zeX{*>I%jaI_Qw^ElncwUGnW=Ax^Mg9x{n#wIO4V~i0d(| z8CCIh5A@-+i0-yNOMDM!F&D0^wyxdp4*hcv_~$N6mnSQ0FQ2|m&tLz#L?%OsA%KqT3xcUF)RFohgPoPo|72n4$-hF98D`ACFj2qbS}VTm7C^l#|~9 zLOaVk^2^c`=0=1zSf;*pzJ6!Lt)V=www-*zGtn4xoaVjGue5m_%DRAI<_ z`RQpw`?DtOjZSK-!n^8ghirzNr@E#Q9rKk(Y)-U6SCB&8LpR@H^GO}DySAgvgG(+u zVove+@u~tGH3z1&Fj+i?5eoY>cb1cn$9cP#^iRT4rg@VUqN2R@e3!oT|Keq~r=fUI}bQBoe~^IRX}1;-@d*H6%me%;Xtt(WC$pq1kW z7Hpk9u!sIGO4r?^WL|othV$4YT$5kLOJ$UP|E7(BHYFnr5bIxHm+TMWj7~j(Q z_z#daDU*Tmn#lPHxn`KW7~ko%lpZaW*RKJx!fvj=>xnPjF~a%z;m8>dG2Uu6*hV{F z1^)zlhBqTMV-X-K4BA9gpIoavkqYjICpmVqXhO@!&<6=HQOS}JG&QU7mxf!-1i+Qv zg(kNYrpxndW5ggK62v345eT!K#Ei;pHsjcd&e1{YX=&=n(SugI3i8R$@EX67gWR;& z$8x)12^X>h#w9I;dfWv=$Su6dQ=JPfu3{)T8gSI@f=2=qb$I~HFW53@nYTmL(axJK z4B&@mK?e4ku0HVLGTlQ`9wJRh!X2IvTv1|)s0Wf7rAK$3b+{QngWok(6}*Lf<0DDX zD|0$sL$`*1=~{;iGXS?K7Wjn`+qe0C|HTW$vmKd7EZfvb%5-I}Zt$BMqNx3te zioo$9;cAe^rE(PC4~7F`jKHWPan}7fPaw*`^9{#V1FFAj^o0|N@2lF3e@qHXE{Rdg zw?7^MTub(!iFNZ3oEvm7D9`%r-!m<16~vTLWHdq(xTZOJhH)e)%ETCT;R@x>!0ocv z8o2W>$--&Zea18re-WEEVUWmTUgEf~gG zYR3o|YoIQ~ue}jw`G~&Z=EQ`(Vq$tIfuPIjD=IYI`jv{YOZ7uc1tdX`I4iuouW>_F zGUDQ)*0?Mx#$X#mMVsfbB>ky`xhe-T3!_V^y#f{{O zq5!xzp%5E`B_p?5rGTa3At27gRK3t`9PsWJ#}zCYkW{;ixyY;)`A#Xfl~#uFiPkSE zoGmzXE#kWsdT}-mBOacnhAN4zt&qVg)2>nuJ>h5Ub~@zc`D|&UWt!4p&Zj44Vc59j z(~H3BlW~&RSQ)VLa2V=lfi(&6;NKzQ&d##-vPQps!==0p)(DX#bI>zrvO-L#7p`R@ zFvTnM9}vcvHg}sI?D3Si@s1? zGmW%s4!VhxKUm8wJ^ellA8YgW6z(;ao`Fl)AN*aW zHA7Q;h;A7WG=~?$zOc{zQtt(SxV=AgU4um?9sKn zk%O1FM$!IBka!ztuH|MExvtg2N!@rRl)iAKj$Fh?+hETqa};baZVx<8Iw-JUc@Hwz zo04bET$Pf(AZadrz+)|NJKb<5GnSTwEK)H=HPJdnw1Om%qS?f!SX{df5uUY9w1Dj; zLKQI47ePd?Om%ME9fqmW0ECP&BJ+K#b={sBb!OwcvOcr`G1T_z-D<`hG~_Sns~$Lx zgxZOq+v-OHGKWz*(fa7nQmg@b&1=c>&+)Z2t@CpAKh?r;t*TddpQh(vs)WbcG*})N zLKDY$9?~t(8&du93kCH@YUoltXgF>z=+O-v(xZ%b64>w1=~(ASHwxDkp2V?aSv)yV zpMno51H|jbgu&C?;~Y_v(7c)Fs=3MYsH$2Bdb=uFat^KA3&!w{;7u>NgoVGl(AO-# zJ-kHUP_D+8Kdh=;=ec5B7^7IvrgBF#-R_rr_dYXDUSVV*G)9zdG8uo>7(QJ)& zO~F0nMKoJ)?{DSwW*Ojl?#uFInfqZXc=m4JGX!|;<8ucF)+>8h6ts@YZ}{q}E}tLT z;r#XOjSqEq(6#>^h)1v*8=n0N5el)P+i$XNj%w1k^j>Vm*WQWX;HVo8#c!Hy_nQr% zwnw-B1vP*UV{Sb66jnUw>Aum{$fKET$)anh*t0#>c#Vb5&vz+bj8V3t51h*k>?u3t zx#;t2JFA8g{{A;?lj)x{d#PC-thPK3h5?{coDHQFn@vp0l-@5sq8T4n$$A5=Gv;LnHm_OOPKN0VLYVkj+jNkkCI}Dos z--?WXTKbzJv(Pcouzxm7{u@R9z3=~b6q)s}C^FmU^r+ttC|VJ7D<@+I0$LF(eJ5if zV?$db<3GY<9Gx7D^{t`Ymb26~Z9glH-`$k31Jn-^*VFcyEa3JUiyZuZ&G3yvl0xJP z1QcZEAFpXYuFI8iGRe*-;68uHY)wLKRcd_P$>O02`{pp*>pa@S3h3(Yi557d6ddc8 zwO%m?p06+FeLvqan5c+_D#FqhmU^_`a>A?9@{pn`vCJ2eqFR^K`w|0R@gj){{?V!4 z`SJFJmS?rvt@|mZrjQ{od?u2Lq;Ij+w#MaYFRAfTrHhBf=C#bM-B9Ivm!<=y7mK%^ zigNf;)hIty*7XuWid@6TM^H;i#^Hq6h^Gjp`0bz=-ry;R78D*kwNfs8ITnUR*|Q7vu;HBp;yEVQKHDL zm+)t#x&7L7xZOiCin7mvdcqEiunOA8?$-nkB?>sW+}7fdS+ZUZ+m&{G2bE;zvDc>3 z=1A6M8sIgY%vi)l3VIodAH#$sq~ZXk7Mu#OQp?X}1-SCU>IvOo4imm_Tap1$p0JVT|_&!AfHsUW|S{Te%{!4=D#nnC;lYC%)v0ZfE#D zwIv!T8}Pv7pog6ue3;i_d5C|yE$am8i@yjmc0KU0cpaWw|9=NbX~W7W81cE+g8P@*tRORQL$~?wox%gY*$c8Dmhtm zpMBR{YtMG~Jh=DoIX94@t&t^OqancsE9$2Gi4KM=_*ZAlyaW1_Vve2sfOc;<6#Shd5K1aGcPTRAjyf6 z0pK}R!5(8UKOv%GYx&q8aw5`ocoVS8%aY=EG^cxH`;TY16bTlQ$PcVy$+6+@B_@kX z*YmZH-4TK3OqzYMGh8gHFV-3c15_xkbnYQL^|p>;gO6S#d(M|Bq?SYVqo9$PAULxF zPVapYZ`HhPQ$kfLce%a??Pd}+Av5F7Ky4HfEpSzih^o70u?wzfV)U1m)Q%b?b;e6( z5jnDnn(mEUq#3vsS*kS-SHUMq<+P@KMPAG*cvafO5I`RzllzVjk|Kf%6kmy07-*{{ zNOC|lAM!OeB9EH@kG3s$yydDnV+RFGTRjVwK4AbDvb%ONmwR2X9Tw?Mo==|Bg57@0 zvXo&@;h+LRy)?RCxGHVbMXho0_g63aisQSw>8@?lyrLFk0=G5rNI=7?kOAqG>^=a$ zrx&DI#8GJfTWH8$fU^Xl|5)~|u^c!Px5-A9WNDuN5&;zDS5^y-tvsE{kdv8P)w1Ap zT9~BKCNR*4DV%?#cEdF?OXrEPrO#7m{bHr&}p%npHE;2pgOA0+~mnk^-ZpE8FW~FY9Af%fgF3 z${Nc?K0{JE&!Mbx<)KZn!-lOTnmp&yAIfUg#STOt>84Uen=Wut7pH$?BROd#6~G9QFsR#((>{Z22Na$ph4%HrOs4r5WOi6s;t9( zO;el)&1skF3&49CiagSb{N= z306pnV$sM=H|%5qvUT*JBkLK&Xl}ypQ4VFASy^rKIOlx~)c{j7Zl_erg2xv=CFl@9 z#A&#TwUAUh)x#)mV{{?*di0Grssv5uqZE3K)Zq#hP*nKTNz(Cm=suDqAfd0Bft7h} zkPgp9lG$}~XD*|1N26j^epA8}HIHa}TLoT66Bt=0H`3XUy2bNW*NL)US38*}(hA^; z;%lGGkoW6-anICn*%>RVFW=<|HP7p;JMo@4WIjG!CG1qHvf`a->2RsKvg4Ju0iC__<(Cp8GXLwRs<0Qy0Sz!=S3H40-Z z*8HL)PwPr=o8yiC^yeJXQQjY1u-qYq-MM|5_ zgH{8^TVK0Akn`C#bsCoG4jgxm1!myS;*LBdV40qV&9h}3`uXF~FWuL-BS8?J^N3OY~ z=<9CKJA!8m1;ONc#3%_5bxRF5D;F#2XKzVJBfr+d;0DKhy@K$I=_9(c)PerZdcxkj zH9~4&*#9HzNIp>03UQpe=bb4ifF$UNQ1G|o{X4xP1vOl0FnSNk-~^L2 zQhtCcC5Mm*YS1es?I!4=eDjHrhqbM47GX2MQCC-W42*`>UK!Y<zqCDK8s8V(sMq53 zcUkRC!@S2j1*mQaub#jTfdc&kat0H?p4|HZHV4)d2~DO>HbcB(Cr?s zqf5kTI{H~}uBH%IF638F>P8AEemfU(FT5B^JV^bZVzXEw7884 ze>J@P_ZGx%w%Riikzi*NJ#qjd)776E{Yz_|Y&$dVoB2IQr1}^r$m_YtNw>h}} zJkkAUbcOx1$ntLv9m!gb9d(qs>PBw-gO5NSkfdNw%YAdSv>rXAJM zbli!2mosm_mZH4cen{=XMu}HwR?+yX75VwRUA-bozafnp8p_?>c=(J(Dw!gtFB|Ho zg^dmlmJ&fHIW$f#ka@I51m*g9y}2ft^w0XOU7$7jy*!`4y2lZIyuaIL&c^w@zl&zg z4qFzB6fcPm6|e*)5xC`ae{oF1)*2OPZ?sl=1Uk1Y4jN4|&X?|(n-5k_@JQ#>c|X^7 zwX^js9N@w+Uq7m&V2~b=%T(4qwlaVH5XY;6reG4@&q;4{xq6~n=3H_1<5~+SU*M3t z;N)G+^YOUc3MfCe;$r^MYL0CiXH!MCU|6&trdK6eJ*)|uW|oS^Qy`ge$+v+Iu_q+deoj_HlOty{3OO<|(PFZ$~3H?b2i ztyg021mL|){MsQ^h|BviMO_K$?|=uki0wNsi$*v^^D-jJOfotC@_xrf>i}Wt&sCZYIP=ODfVWA$I@?ps z{TK4Z{6Fps(s^upDEe(?6k zW#L8wYJ1;8!3c``*##odpxpSss143RdxIL~)WGy}7L~X{j)HWPP1H$AseZ*x$y!Xf zfLw`SnuJCOKO^GMn#Y??H5s1bjt8$iifGTe_s4Q3n9Jr3%*EmI)XW5G@>xA#K32mz zEQ&!J$%7ImQ@FD*bZY=%0XBiZ|{NwtMw!ut0Wc&J#YUCYdD3s#`mO>MRXhj zOXa;UfaM+}Q92_>@zgHdRcZq2vUc}$Qmk&W!1)!Ljfe4vn#ha~#atRL+>HVlN{<0A zg}~d%33}SKeEf)x9w^T=DKa;7HZtDn*052Q2S?@B9YCmaXbxi}BuOAq*K(IL1>4kH zK!=WB1^*2cQe&ovB|a_@x#DSh_s#U-B6H5ftNJ-lQ`Hl>M7#q+5=rhPELI7g2eV>J zHK(rLfAK4~Zae21YFG+;nuBEj-ot!QU&c&AxG_n(z#0BfV024NC#q++$81%|F&RFh zEHbMql`VzZC--I+)2ydXc<3(toLTpyMQfE33Hu1@g>l`w>TOJ1Bm! z{tK5DFs1QJN|>LqtK<+vB;B95nAEia-hC{O>x%to`#K?F#v;?2Up2L(z>0_U3p>0^ zmpG7gP_Q50oQqXSyNPfZsmX?VYE{%*8??M0try07aj$ zy^q~)iyg9rRdl$_QG69eTH5=w^bWV>K)&~UzV;RFR4a8z^2cWtXlll6tZ%z*$uhi=UFLgCC zz{{X)7te*>v0-+tMcGM(PWFkr~Bd2nZTjQ&FQvA9L9o6DFdNQghG~ zTj+c+b9NH58;#aHDDDEBja2iNT&@KIYEvlwa^Ss+4hRg-D06^Oq5*;X6ySx+(3t$Y zXhr=P*n4)pA;iwUfkldse|J}-bukz~`7tfkf`GNyA-9wZka(=o;@AS>J|T9(KvBjO zl7ft09soe2o>4TjqrAA~h~_$c@Q~)*FTro?JdTQ_bA}w`GhCRAR3Gbbx@}28DlV}k z_XK{4SY~2>zfRMjL%;zZF0JXZ?d*B!0%bf#51=ZFDb3@g3 z(HkbnxrXWD{r+@_EcP(vS_++HyU&(kUI;oL-(V6CU6Anz+Fjw3^B6aIH}d&*m2+)_ zS8DFkwPVc%dc*yjFbz5G#$6bcp(iO(r9O-zDrR!g57o!Z zlD7C&6%NG(7#SOeO)Vaf&;0vpZ&)ORrmo?rQv)@-n+8RcW&+dLrKnX_cF}}*RCyk* zLN_{ZnN+v<1fs)->`PX!2T;U?*lgC=S$bId|Rq8^AKD)Bpfd(FR)5 z2FfboBgb9xJQEc6@M|F?W;nb*1F*WsocjY(Dth7|jV@tuMKB{SfxCBZtdGFFcN3Zf zc~K(a&a0p)RIOwN>s*^XY$zIaCO*Y)J-OxM+c|v7~18$ zub%nVVDt{4ZDe?xJ!Rd-2%SnJTeegSis-jLZ_V1hX4E@!45U?i^?QkvaJ=DJt}W6RT`sr}C*qXm-Z`G+6<59conw3u8r z17V3Z1eOD?;pyA-eP8Qj)L2rtHq|U}Jb&j=yUzzzy=G_LPIxpd(nes)>U-}JcskJ( z__KP;jpk%`fo!~9eQu`z05%_zqy7t6=K6DA_g^dhf1u;P!ZO!CB0c{nu*~)6)XhJX z{y)y~_muvBHwpgb(f`PcGqEyoeU_~MyVB46FVg#edF>z1vM@6-uyOs@XF2}(%>Vzn z1YCdR60k9G{%v5#lCRxwx$WuQ+oB=07DuC&p_voyST$&+S|B+m2`hrs+VjRBkwr}G z@|}7AHG^q7t~g_-NERlFaO@rGx6}RWT{4-U3jIhLMeu@vaDi&7>YG#ybR(bVsv2T1 zMETa6`%~PtU-S<=Rs|QVwF_dSB6mXH=clXRvzgVgwn$;0wXgeteZ^ciLHj+n=h@D! zQNQ0qnYr87&pqUa)x8dtYH1WAoffoQ$tL~awWkVQR8c9ESFC~ARRo>y(dPxVJwLDJ zA8P3F?PDO_57z9JQP53KLk-uooG$tb8Yl9H-_n?ylS@xnbOw>)aKN7J(#tLIak-4aG9UP( zIj>Ke^^XP7@+QVV)LvW1!yClHT@ZMZt)8B|bbMBe^p6{&nJC`-lugQKfkTRo@6t!F zgQl0ZybnT`^AmI+ac*Gqj%d!WGx@gxoA0y{gp>s!qT?wkx21iLh^p@$D;i|ZF`<|X zk}G*K8^aTc=f>OEJMj|9iSpRpiz=_{?%X> zZ2V2E!ZDa5F+K)JEi^u8zQ~fN>wxd3#DoFo7G;yKrGFBYx` z{a~b8Cm0hAJkwN5n_qua=la@I0_Gb_{uE-|buxw|xMHBQWodu~8eNNH=LU%keaarm~~(JxuZ3Nv6S zm}7$JJw&;J+{WJoHQE0GZzcG4pwn-#AMEU$ig9PyTFT=$h%G&k>4}5I)SdEW1A7oI7n@#`uCL0Wf8Q^v3v%hQ&wt0OsI_wxJ~vZJ_V>Rw2=!O z@cUG+U*yZFqVJ{CC!50KkOhb!BVAlzw1{O=_R>Yj41((G`3wT*eEWF&P?W9HqKSez z9Ne*4!1}ku7<7H9eK7z3e<*v>aaE z%w8J)hUald$BP2yve~7A*!O3tQ&ndQ7iNH$e&?4j5vseoDXYb*lY4B3Xg~3#HfpXr z_3!2o5Af?eQ!Z!|^cr|;yq`= zsXb{Oh4WrEJ7?J?e=bqdyGW&o6p5NP6r%|VTXWd7}xxLi#hJGhDy*Hi_0GN8jGUUS;b&>tAfig;jr`!kt7XnUk9{bW@ZLcOdj+= z;$sDEcvN$;#}@7Kjy_*b$2L9$SwR^DQFPSe&+s%vt+qcT=tNL$k!#F41i}<@3KEV^ zmcB}sKW-1QJ(vB060AeKqPyfX; zbZ(;qW{~VrBu%zTVNK}1v!S~j#V#@-*&t;)5WAuDM?p_DpGAyjiAZ+k#%j3+egJGj zI)^;L1&0=%iyZKzR}MZmH?bP^Lmkj?vwfvSzl;!FZepnlPNmakI#xkqI)eOCXw5DV zMRk0CSsFue7{y}>@7D?eb^u~*LAQO%{#;E{sGAi$C)PcNFGfUe|Cl&6--i`zLQf0| z6tQf?Q3?unbQ5`oq__-7A3=LB(-9DUE|T{M6nsQ67O$0Xq09DH`YZQKhqJBUNAa*U z7wK9rOzDjflg?Xge4>~|3LJY?e1c1umq~Kv#BFvUk2h1gDeU^fQ~ew)!L?6nqyx`e z4n;t6@R11+z1TcCdhihTC$Vghk=eU0oyEum1M?CFfLB zT>8oF8sR%=tjG9ozwEDVCljb|cVo|!pcvJKGO(l$qw#CGqw+(?-^#~)wuR>CqV^Iq zR96`*U~I#(ROtnT4em8>X5q8j+3tmb>|epwMD=N$pjIajdtAyHxc)9{ zeBPOF$>yp9?Ys!)s~NshR$Hw7F0#ywHfxj`Gt?V_<|kba__fr?>Jl`l|3UvDx219n ztv*IO!q=YXjjcCHj8u3ZBA6bDslQWBzfUDsxN2Tlvf61j4V<^!up;BB{K(>%Sp1P7 zB6JwqP%F-x9ET?mGQ|=WIF-+T?=J?ADt4-NyhDRO-+MOj``6mR#3*bA!Yhk}1s*f| zMQ$(a&czz5H!IAd%$m>*j>iuv28qbF5{Sw@Pv#n!HJTHT5}Mg9?`LP-Um;+tj za)K&IzOjkIHRx!M1n;O|?nk*qcs@dQFTeyqdTq4;A+q(<6HOzbE)^PuKzF1at0rPE z%?v2~GV{mjLj`sy{O}p^!H0dTe0co2=BKJnlg$zYKEgD~AXALrzaUIlds(A#!)>-P zCb{jPHNU3!dOW_4H+u>EI7|OPD1mJAr5lTZ`~A&c{M*}&X}|1U{{_s7Z_&%RldDHw z?nucVjD@i=GS{sZm)4XFRO)Mv(ju0P`X zk3vL_Pj&f|%>Q)_(jPzjPjdYa#{b`4gT(w9*XRDMjA3JDV_@QDBVy)aVqjusC1PXY zVBlnC`^z;*&aOtzpF5N+?d?8yA+a!U{QEYfKaTu==Xh)^tPD&Xp9_#aFN`vMcB-?n zaWgP8a}%*}a{PBkWBxoE>wh`gziawje_PXM{ujmlk6GhS&vG*T;Ri5tF*9)g*E_Ks zpYz8*gHZpA*B<^i?zM9Nl{vu1{I~BwWNS&sZH%G!ylVWk9Dtz9Xm-dX6EN8WHZw5s zkBBE4JLpT1L0LpwBQDoZH1PG_9@$&?e)&wIjviIJeb-(6Gwd?ceaG6hP&I9|zGscV zZh?>ORNl%q?eKQm&F}t6D2%6Tt0)4Yr&Fz8(Qp0Tr*aWc8rO;oIxF~ob02oyBKUSV zm}~!0|ND09i6%3#aU^&oEi+uYnA)ym4Q>**aDXkv`O1z{Xckz@I`FE;#{&?;pJmrb zwwiOGcR!aZuczvhr%(b(V=S7zx+|pNdZS#mmj||uSV>osFO#?%^lhy}@2kLeY!zNc zg_Xm*OC_s8m`3izdoU@k>U8}kx=_zvySJ}}-U@ION#s~PEh3}oHxu|WxeyGrJR6H@ zs=U=}*#tN=RLIVfBk-I^-&oVFTMG%`$b;#@s z^6b3y1v=m9<08FgK`{_ClxT&_mEcexBY{~=kIRWvZ77riG;#wYe;}s`&E_=(#!c7R zQyhU%sxw{~yAF^542(X5;(?v>G|zT+=stt${q8pC1x%XYoOD$pst9*h&waTu9U_;v zz_bvVX<#jl(gs8mYykJ0U*px5OtXV>-Ybq49cjc3N9M|D)ZWvx0I}zuedG;-ZB=o~ z3p%xMYcQL%SQ;>ea|SfTMT%$^@c|0z+?Uo3Iml`70~J7O>5MyAlhC&%p+Xr;)1RfFeT*T^d(0~DGL=#t^*rRXA3a@)qU}J)5igj!GmXHJ8Quvij z5bU%46JhN&@9-6@4Z^pwMQ}`%jW~nDu!?>4rJL;ZjI+U~b2^1|WfQOc{&gYKq2B!n z2nwIyPTw@io%pVw=NA9XL*&8|4t5BmL{Z(W?&-XlWJaOAj~w9YTa}s=;dxdJ zzt4yZpzq<7u}g^{B+Q&JRxG2xV){dBUEcp|F&A%92QG zxc%nSb!@2gxV`0oAXWQJH^ucsGg5T+$&-IHi|;hyr=X0$=|<~dcawJN|NM0f1sC70 z$F3GhOhH(6bDojUWHdY&3mU|W|7%$KG8TN`?9vJ=+{U88ChuliBL_G`n;h{_Bhjns z_Y-Y7Cw-`0wk$!`*bu82swh3E<(^HAgWEnGtis{#0TqyW_;Q0K@q|*|m?{t@nKn4# z@AjL3QBXy9@#&pdcJL~UF7-lZ-5D(E^#BopexkOR5G19?w`4RbCKN=#czzxTVwh?g z5OhTFd{;{W4)EsO?{g9J{yO`cbP*s6+-P%X)f6nXTp1E*-V=va;;_*qJ~^=UC{Xqx z|2=xs`Op<{HbxD;C;F^Lt0ORCIJRR*m$BvQk#5*ws4B_85{f6~z0~>m>mN$h1tT7f zUWdX>y}Rzmd)ui@s5Iy$D%XQB^tef;y?Ub6%+graxlg{mIK*mYD%Y94Vvb@Z{sGz# zU?)O}tCCAQ->}DFTzrxXB7n~Y0(!sJKFDF1t&u#F9Fl^qZ8vK~j3PCEF>d%T3O|Ey@Jkw9J7om`32N1`5e$qK{J z?lz^-o@|rGDi1g*Ha6EJu+5{2`-YbzjJGlDv)od=)S?9=&g8l4*dHg(4-&=QL@|ub z>P~kFer0^@-=DT+z!Krv6*0kurCjXgq+2J`B~PDkqVJcBC-GS%Y~KIW<`utvjUKlY zDUB;hQ&8J+bdjT=J2eQ)CPj^}fBqsn8AG_NZ9Dmcu=|uDIeP0r_1wGLy0mtLY7gAl zGUl*ST8I}?;%lH9Ei-&!x)&B@<|@SsQ@+aQUxISIdsu@$B*f2qjt&Soo^&I|8}^ay zp{hP`4ahb?TN!1NWr2}TC0(?9&k_U|a3wL~yJx;`h6!o~n23*oMQv8}*EUW3AMjC7 zV><&#bZkmsh;lNSM0H&dy0rHzJ zOE$sQYaiNq^^0I4X*91tWc^oz*H^9c0x8y7HTlFVGtjCc!41W4PK~FqOH%a@U zzfz5gW=iU@AwS(J80#k3Y0q|Q>r>B6hsX;((W*zf z#c2^j${V%ASURhiOezcjpL(XmJYudVg-@OFUG zaRWw%;uK%>)ueVA5!NlL6EIil@SRQDw*S-dz=o}58FNDaezM;))*z?#vEmL~nnfh; z8L@+<60ZJa+i~E_cS8j3-hDld8YNW(SL?I-22jWo4Qrl@>P5%QHUvr9T$6D8_Rhh5 z$jrKl(a}$kPS_HV~)oxD&4R z&lScq(}fq`e0goYe#ZC+JP3W}wxFMAe~!SeSbx~sP~eH4vud{EGF-g%;>75-P1g`O zn%7vyX!&^{Zq~?=xt|%FCD-7I+6AWb| zmd_0-r_m1r3ssoCN}|Q?6XTT*_R`!`(1N{j3DlcQ?YP-#uf#x^BV$AmJj@CZc6_EB%h+`rY_@)?F_RC2O6 z{$l#Mn3af8Nlb!>QPtGL!!MCaj-r_x) z$)8)hE*fNx>BsKk86&32Tlg8BeiGvCuTQ&-pTG0Nsboej>)=ptAj$XTKF*J~%eQj_ zH(Qct`!Y&b(%$#i!;M>M)XB9V{`T7gCc)dogYe^I>g%Pe(H_dWci|pMQlsQ++lDz! z48x%03V?^pp>}~w-V_4vCVKz)b>HEV^1@WeE-kAD<1oOM&|*Zt)G_D#xo3-WiiBv; ztm3<$0t&Ou4%7Z+L~~=yWS2yc(?sA3-VBDCw%CV^Do;lQFXC3+#yJbm72ux0(v&UB zqv~>tO+W4n@6TB3>kG2#b#Cvqd59Lnh0?~$cJ^%BF^i5V<0Q0gXft}7HO{_o`M;ag z6)qsxesl67Oj&GA&da~nyVBPU(6I7ER2FETKLWRZTfh90ELOV9vn{$vwM3Lq!b%Wa zy+6lE4>PStLCfW5G%&2tfN@Bc*w_}nv2|0!zl`sGaXdQD1DQFVsCfJs9-YNcijM`9 ze9VU{{DT}=@ih>%2+Ov7g@_=VO5H?D>~WuAvY?}L88sb2s%ngd(v~Pc+xIvPguuWQ z6a`bVyNzoGK~;?Ghc^MC8_gYV^*1OCf5h?p3lZ}6Ier}ltgqa!K*zDU+TT};${m1X zYA7f}mstt?B^2O3$U&c^Xi_=)uxW9t6fL|h1G>geRa?Jp^d_OcTv3};vW**oPf?y% z)ioy!olHxN;jD%~&mMNL4f#^TQV! zue;Px3M#7hZ|ysHR*fzj(#`Fme)I>a{3N2q<-5r#!dWj#H7JyqTFK*X-5%nvXKHdg z!IN$B6D~3kVRo!AM_)%IX0N21fpMMWrb4RM!mci)a4fC9%9{--FfGc(Mhm$Ao=oH$ZWphIO;x)FV3|`d6%xT zyy8Uf6?rTDj@`w4txYxpLb7z0v=W4U?UFVQ(V zX&agSQiDf0Z*!ID*SFjASE;;cfTCNGNwVm#{7Be0`zfL&%n)}BJUtdZ7s2L5t-Z>s zye>N+@S)-2P^e9Fq_k+XyJO@?)#;o#c&W%5+dfiNu~DFi7;yNXe%oROz=#6Om%95s zgzf`Zw)q*DR!D6rCa?#nTt0n|x&iaE810TG3x2=CXv={EygV-g>&sYH8`Hi#?w1t!WvgQ6=T9s!97~iza(Z16IDILlF&$`P z91Ym1p-ppBBT&j$8tKaXf-5LXHaUP12-*0X(0cG^8Po3}c7HJ@+gU3r*Q%cs;_@rV z0c8yAo!ty<4eg}5JWgLHYWJoM!1o+3HfHqc0uslW#m`#JxKzr9wT&XA4$2DZ#o0@R zBM1n2T=-~?r6@^_hfO$lrqMkC3&dhz<5WcU} z!v{J+1!>Y0fJ4}OtSKqNjT)fHGBs8CKkQB>k{th#55fz6{>l{Q-yB%jAa>&vQh35r z2^~cO*WGg5`|5D$19k~X<>B*M^g?$&#=DDnjBmTYA{ZYUR9@)6I&*yS#uXzxSG}(r z76eSD{3M_#WRZNh>~b#-!cQE<(A^F9&D+JLnO6A99e`3Lanbq6Imyc3fXz(Dq&yM* zp-b#$Akp*4ra#n<0cgnpRE~ zSv>)h_Rq9&ABY5NKRnheUoB+0bOb7Stz*!n%owPI%Jkt63k9oI#FWzRW=dlNE?RN*<*Y?agS7cUI*NRC z;sL{K%Qwd1TppUQ#*)nUHDX>7(Lk_hEjXX5 zuN@as49b0&PykaTTeN*}EYR!p-9N?EMT$?Yb$m+lWT~(NO6JSG4zX6LA76*Pf~rd zJB5uB$O!JTh45ruD`9-PJnSAeuQnsRe9jg~o9Iv&vyW!qta${slbw^OOv}5^tOfN$ zT1foj_*Uk16u`P2qx#QA+b4{KJB#zh@8_X=Kf zWA24MeijbPs~uz3J_GFV#1Wtmi}YAm8zQvtGX<^BSJr*?!^v_9w}lvoU!Rc}KuJPS z-ZW;dcArF)GA0f$-K`jxyKj~%?8O@`^H&wBA+0)C-biA$GW@@gLnGm0O-^QnH)U?@ z(XtLBD1mB5J3Sbbm?b;+G%D5+A~r?eq8Z6-aS*aNh}ksnZGde+yI zWa4h4sAv*8%;Q!1on{79l?S$YUP)WZO^Uxr4CWw6e7iFrYAAZJ(N^RE#Bo_@yyEJl zeq2?TxmZhfzl2(9MZ>QGjC0|JFY9CnvJLY)3MAKJy49&;`1d(YX@cKD3{OovJch)k zzrAkYXV-T^bkVM~CZ!flKV3f^`fecy9Vhb!lVk?CzBe+`CgAgZ(EU>tRh5GFx)z7b z9PiwAIys8ekdIrQZ4^=z42bCVE1)w2kD$S?9^Y0A!>x-%Z)H5G_Lr9U95~Ag3Zf0C ztfhf~&@x7h&`=D@Pt@aQ+?lWrPtu+}6`YfcBF@8j@u|H&YDwt*NIz8HvBxqq(HgL* zhMVtSfoxn|omL%ScAgp!fBYV11E<0q@CF^@T$=z2EmDmp`kvF-{)7JN9zF#kN!$*q z_f1%$hGR4S5uVo1Fy*?ZpH2qTvEX5Zp>Jt`0jhmtc2g4vtiuSY(bs#Vr?>Q^D{@z% zLp>_-uJpQ{q~_Jrq)e>a>zl`eV5egH(qAF?pGy$`I!N;ek^UQk{~_D|?P8w)nmXtH zv)%9qg8zpBz^JLEP4xesI%obDmHFSF{htao3oADR6Wd=z)<4Dnf3p8S0se25!T+yI z)SOIzE)n{lG|$ZS=|ucZnlIM0wcp@Cdf)!K%Lr~lXC@ZGxKIbL*@-d6)Fgxn2fFU7 zWW$3|AQeD1I_~@X%7aqNsfcW_XBEv;@@_lFyU0D&enwEjiMUv*ITj;zBSc=@22-6n zp~%azUCRfa1UcexB7@4K_j~`bV(QnF1bBgudfnlhkB#9}#A`;z_m`XFyVt|(V?tAw zO@-n5@O=;D1$7Sc{4ux?br~zeYV9f`>Z&7SYxm;@H>WSu-(x!XIXy3zZGGcXog7NV z3eKED;i5!^hV^-p z%`nEfKs5{LF%GN-;wMaY;Zp+biAWMgJ!gr=noSS$zMJ?~UKD>nE=L;NB7~5H7Fb3L zMh)#mewH+8=)#adu^bubp5c~?Up$CwmwLOtSyN)^B6h=3YG{!bSz!*4=w#b3QqZUr z#+aMxPh?IHt2`YyE0tl_=Jut(o6UA1WunXRAwz?&XbDnau(~ zOpP@@WSn#kW3W@)m4PMIRyjq{w)pg$jO;}s_3rT1cIRg)>J^FTJ}CXcleO+;8w*Xd zFllz3=bIfH6~0A|5G(68Ow*-bA}2>AFSd5Rvo?1^RCihG(Ral*iJZGsJ)cU;3uUWl zg(>G>WF#g<`OXh=hbN{gEgKQL^v@X7omw zIOG-a5BKLxi}{0nepoUU4`M2F|lSQ8WPD+j39 zi=ZU?QiLRlB98QPn>x=KvoFCYgv5Rp;vWJc+adMQViuRHVWozHXX~JRE2;+auICna zt4?Lq*l>FkqhNyPNbe)9?b3MJK*gaxzgdBI20hu-9z?5>4Y{IP0Q|ihpkP-%ZLDmQ zg$oh4-}sp<)*bsDd8iPkPk)R&ePEo`{o38_3J5UKc}I-YL9X}-9j@rffx>b6YsoMb z)2?ACz>VA)jXLoZ8bv~R)zw6h!pbB8N2^GpEC4I=!?;THv?@QjU?6KidHH&L^kGdj zZuIAX(GfyjLw#LB#wn--D+m@iq#mmdi`P^N;Fr`O)v)1&2K>n(yuIo*zG?%+RK7m6 zb16k(mpyKoV5s{bJ!11qjiE%ebw~Nb60-s|vk|)681NV8G33v?#0Ste!Z*Z5i?@&^ z_WwxHgRi!U~whp^LCj+>gtW+oA5a-J>ek(s@re zp7NPLzyf>~XDuCicIvHJ2C1A(ohF4*2I)u7+E=xxqZLX;H1K|1OP@4_%d=Q;;iL`J zitkIO7^;Ur9!-s<#Z7$`0jVl->^pkXAw)1ZW;NLZ=aheKMnc@ZWnktBgbVgl!6lh zIsJr#Zzef3cs*R?7szC+7~Z3_2S>yP3135%IqN7v07T~+n<*=Yul&q;AyzWJS0N*> z2bJEU8^f3u5iM_IFj+MO%Qdzal*cq-p^_ei>N7heg1$At^<*3u!%Y$QQ4DD);-&s0^Y1SaMUrasP>LqB$dGa&ei?(`WiT#va&@5fvaVZoQlq$%rzcST0nVaCr6;W#iGaKy35>^*Iq&gk@G#R4 zIE%Fo|F4MW&*u1F63>5pYyTVZ{Lgm6zgI=b$@C9vTIC=87p8V5|IiCLnf|PG{y{DO zILF@;9siuE{U@{h-xD1*m_{;BscQH}KHt@3#1EJTi~H-Xo!*bKA6Y7+6w!&FsojDn!QVHtTVY>0bPAJ% zK2y6HCxFG--Yeg=6Sn8e-&c!*zDMI<1uskl??0_<8+~U1$!ULsDfr3`F8c0!%?kNZyw!E4r*u2s))B^q3g|8?_XXk>^ zmMHnebvJbY-%@M7q83(gWC=)F+ToB}@II>CXO)f=D+0Gc!$q%Kp2OH=vk3CnBfK( zXRS8nkj=M0c$RPp2~u2T@Bq3JZ(IEu7Gh&GC$3lcU^ei%{Lq#7Zkd1f`_+@wTIfvh z)gr_%zWMpNYKV6X`SEkpLO8A%VWR54UM%RWu6eGwGLO)`=0h zmI3~>Vwi(GkX3f0!KLf;`m?r!wCHLiV#b1;Y6Y~mZhdW_mo(;xF^CvR=G4&6VGC`J z`hG?FE4dXwT9t8w)w8ux&}KFB`0*!WkPRi&9{rldu-G1)pN|2XI_)* zn?>=>hSNoewqX*p$PRFn5b%-^o!0lqO4<0G%`$^rGnR2v+S|tNPUoCB5_5?g6&nS* z@NS-1I}xrN6Z3TBME;EZ@sUzSS$9Wc-JmD72KR&>2hh=9ICf`ytRk<{Hw=>0ZBRPL z@I!Dd2sbri(zp&t z3nKQYN%n^LNFqB?BUU92u5oeX9o_ikk63bXl0mP2+fBpyC+@YutWN?Zpe?;ef5ZRz z!!J8Gz&l*F5QLn9&@AnrKj!zC2TtYe6{_toO)bH|r02qZ0dK1REIrHjN-nY%_W! z)h^Up`+cVH7UvFcFp)VvJStXqzy$W1v)vrH0yW-+cm@pI%f*nETNK0fDqKQlD+!3@ z49TlYfoJMi8L3kd-OwlltNDB5e5#X*YgdxOsni%48ZbaMfjX{x;?AVJ!9Cp8CnBEG zxuMVp7yCw+;RzB9zFsILU-PI_>T(!(d*CgNud|M$uSoZ3`jHiiuEgy(G z%xgGT&IGdrUPI&lWPl`}QDY37v0>54k$Pf!F58LKg+{AuYI?qF0+%yu(C{QSMCSs)TO`3f zS2T`2F0vwbf*^SnWemO8<%A_tYJA~-f7JJR*5;4pdl(S8{7OpXHlFs17^Fu;N;qzg zo;q{KH2ag~%LVo!4Zk>WCDms*j06Vi2gJO8c&zC5t*k8{t`^0N`G27`1%k1N9Ac<4TR_q?d{<;Fy4)?{B%6QG+% zD+4Li-}C{*(j(ni=%?aVDeiIAk!(a?o1-1Bb$YI4?oxU(?HBpvY~J7#*Z4jl<|%&l z(yWU;k{q3ScG7e9si-pjH%WnUE_h@Bl|wV!zH+ ztn<$mw#m{F$X*4I9%1_;Dgog|-WR)d#pf3Ph$a@?o%Q5tZth%jdr)aBZ< zebnu`mD!z5zfI>mK3g!hw?mV^ zDN|hLf*EE=q|V{ddDzE~GBZp>O4a}(s052tHiV&3*fh9t{obHvt!*$!T40%f@e`a8 z)*OL_uWQw|(?A-e%UVW%j(CicTb<6E7Zo>gG0h)*5i$v54-FowZ-M;~S_H}c>&Vrbkm7Gh|hs)x& zo*%PACxGmQhJ}n-f*Iax#)hZ8kM(-s`(d#6YrWt`N4ra4)i#e2YZ=F6#KIR&Tx?J8 zwC(W`b_23zb3H1xT(;x6WjWKMtmSC@G1bY$8DS1wj~5w0;fM`8ftTwC?L^roInvl| zl?E(@>O3{2-bD*0AskWYy!e%x;~c8+VzunWO=wq=a?5Ut&0T`&BShB!9Gv>U@CB% z)%V;W!eRYO+slK=6hH2-eKAB>kx2ffKMOP($g1Up6CzPRFro#W6CdO#x_oZf^hL2q z9y8!u**}0KdL@khy%Jz&_@fs1A1Z<0vLqD!KZlaDe-5Ac8`}THq2zy73H-6c|5*wA z{T}~S3H-lkpa0@N`0r=`OZ)uf_D_@ZzefT8e)E4fFZ^$`Pi6vUrr(9n=U6``w$BfL zuUY<*lYyP#kA>Dhv`_ZWy*PhS`)t>cj``F+KSz{fG>d@EM^Y#zCQAG5EB>IsB4Aw> z#saD9(?w1yC?~n_nBm{R9G6ILbF2!f3+ZzVCU)GW`(>Pgf5r`w~C}!7ZWkxBDIHkTOArlWrfT@XKTt{^alt1X7ip_KEKH zO@pgFLa%x%aQ0l7V()ufJtF7rsIt~kAo75fd2i7#`QiJj8)y=(lgehvdg#sy!2KjHHI^j1BiyoBbe6egpV)69`zC_R=$ChIofmfpj0X}_vDVw3{ zd#GITquc^jxn<;9!f*trV1{P zPvQWXqIM=QkUaVUaqk*XqAG+P_5XZQ1Bi&STuV+4l$cRM0nT5mrY^vO1+j-h*Prcy zmuE%|*(RMwX7;_+C6j{`3!6bu$`BS``38%kmW)5n*@qjR1sgjU;ITIl!NDJqGgJTO z3mnlxg>NAWCrT^lnuWtL%i~(#gNX=VS2B%5y^w4cQR|J^lo~BA~Ub^*H@R5 z6wY?SZ5te?!ToOh7;}&xbSOy@Mp<$%9)d0tMcD8?6S2X!o0nJ!raGcA(HP{h!osCd z^z2!c=*0D!_`QS=STZ~C3Y})^o&hSwSWI-gUc7X|Ws~uDutVhFRcyagh>o5QWLQ ziAULz)Uhe*YF^dm?~YEE-)RRFydRuTt%G}{74L%(*Q!0Qq=H+ipUxsz&SiwbKU_5n z^^7687kYI$?{%J#aKQlcl zy=cd$zzCG(=Yk~zayGnn>-PMze6YzL1d9#t_1&DB4awx$45f55hD|{DERU=tSTp%( z^kXyN+vs!n0czib*4~CgD&QfIKB8}*-(lamYr__4UrYBEI**yu!yK9u=TeH3bpHHf z%T}!O^2=O)jz^o~B}AhQBe5$Xr%F8ESilq|w-(o9A)d-*@%F{>0DC3q`)DthD>5;Q zDk58qRMa>D=u9oqxaxD&ntvZd^9?=dZE|-=7jUv}j?~0@Ma~;E#jWhvpMl381-<_O z9>0HS{}nub2XX!{z=QFR&B)*I@L#{}e`~t3bNp>(-G7+$#r_%K|FgE~|A!JJ;~!z{ zAGE;v**X4;w2-8+X1B@)<8z_!;EAyf>{vlNqVHwhiZaGfC+z9D94uI!#7)mfUF9Wt z{tKT{>Ai_VqRn9Sq@R$JJzJsHY5yU&Yo(<<0{+WLlZGp&DHwpNmMpsG>ia&>?Bt!1P`|d&+|)_>@heKIAR=qerR%s zox%ZfvGtc~*>=1ir+4xD4*LTFhQcl_htxAPXQasd@8Ifsc$bya7j5mKBv6gN^ZT{^BPO~;jWekhsbTcU+A(%;`&wO_E8 zMH+!bB()6ef<>#rsvdP|paE$xsT){hFH5@HtZn5A=8BGKlj2uj?L`vzP1^?pt63rr z?vJA?yf2HLTyf-jx#|74i;er1p~E$n_NS9yV{^AHt($iQ8&z{PqP>BnH?*nMg)_li5<- z>hLQ1j{)+}MII`$EnxQbL%SGY-vG8#j7!-{bixJvzHFzeDAR=@<>r7IK^&~tc}S|D zJRJ?P!J9Q{V4ASS7h+|L#>XBRBn7l+=S#yC9P+>La_IAMD*BSX`?Tb z1-it7sP>iz4tGEOE?6dvNrbZBiDq+&khb7@K_Kt9;crxPhJdyG4aJvGj0C$zKyfxx z5QSkhZw61Ox(+xWG3V4&buiG9uTw5DWWAgd8fL^HAcS8r#|9cVID=xW4JhrQL^Vhh zF;i5(-YLA_95IUdc_@gvIuUDZy3H9dFdzN|qqDAJ7_-a~$fBiW7A|bgY1g!^@d+fB z=Ai;RLQ@uoVA&VXjHLWn~glC`gIAu+#nyjmW&t`Bv%G?@!;qrp2k3EK$#Mnmg{ z5PJ-&2eoPfWIbbfNkBu400e;w(2qESoi;~{LAqSvJd>vtMk>5!X?mNP?^T(X%D=C; zIyu=@r6E%L=J6$mDjyCcUK^;uhb^9!qbqX`g*Z8F<3=oEGcvuXnB zz{%kl*p9;}6=umUw=+$XTmtL_er^U!@_d`d2LIDkdVdcCh$E0{}%ioN6VetR0zM9-wA38!uad74<`C zF8WNOHJak>y$01{9p^q&M zXlN~Vt7lufmv`{pV50(TLyd=7(c)W?ve*u*MsidxEr;1pKqIZe>?o(>=7*lv(GXa@ zo%hFfhF4)4khNO+3vd6@j*C zoZZ(~SCq;}u&QlZMX;yaqze0z7@DEjP3dFc@9tq72{o@p{&i;fk+ZjYL#&!=uZ4s%DBi;;3q-sWbO< zoU8lBF15qbv63i?)&2{43VwtC)j1`33jU*IMdI;&XGR`>o&VeOM2OGE+r?JS1z)(; zI9&o$vQh<-k*Xw#mMv4Tn;dNW$B#Fj)``JR2cLO9pw>BTqM(*4b^<$AiIiSIC|ZDC#pu z>!-z9;;AzqhyA&SHu8jsLbuA7`+ITx;CB{N+$U}WpHr0`%`Pq6;P<#mUzD#?KMO?BTNsVI8guwnH`61WxmMU_63sWSwEbt6!qwP zg3wy3UQ8Q(nFU7M9+aOmCO+~(Fo`jftyED2&`ugY%ZT^TmLeH?F9M^S2sa29>TQ%> zBF>aJobkKjeeEYRvh zZ-_p2KqidSvZ*8yZdL0k{Ek(?vZHXx=V;Xmndqje5Ipkz%3?f7)&`9L91zsXo}xQW zbwBm<1XH4Is@8C;+wcczEro8wK9G4{Kdh>kB1>6xqBYgaAEK9aUt3nzkc*g6+I%!w zgwW6>LGxxEbUSK#F?kabM>~c@(ZY-c;G%r&TScZi;ejne;Wiv)oOvQ}ym z%oLv1X`#4`i_cdb*5>^&x>JUrpF$qSqiMbZs}}`k>XDb>EqC2(DZ7AM?#l-|MdN7I@gv~u6&HOBQ@B`G zf_t)&(nDl?drupaI=&dvP6u}9&F{*-)j?2$XmPr5m@E&QI!G|Enhzr&DX_#*EcRm- zvLA<`7F8fHQIRf_K-W&t2nMEJDr#98Z2-djoSf8}t|SCj?Kn20>jBcMYc zLlDh2dGoGOfEVLpKXs9d31l3lernU(Ho8-!ChLpXFs&TnXsvHYu=;d?d>llSoZTni zr#27T-~6;=8daq0QmL+`cxvK+-Yg1smbqhJEcYFK~yS^AKrx5=KiXL^2@fkcm4pUfOd?~9+;%pj5FyK zxZg?EK5!mf3zO<6@L8LYr^G!N7TSywAE{Axxq=YGp5Nn3S4tE~dDPc#C|}3wkh=&pcEODZ=NUTv&nn#qqp5_3^dG{HeJbA?>k9B_H~& z4kRfGpMhi)O!%Tz3@~`9B{xGXSU<6!2xk8vERapdA>y*LXAYW+p^ZP#$H$~wUJK7_ z2WuIxNlkyXZZp}Cn`$P6@M$*Lo@+mn0Q{*7b4}LTJ~I8QZf3?%mio=rwG2eQhf)aK zyNmG6NhvzZ9=kH5zWp+iIAc!XX)V;9%agdM;wav}pyoh&(D+^tNXPC?>Hr^uu9xcU z7ugO0r5rMS+q1lAOP%?na!s(1jUK^9uwkS=v|D3a_`(A&R5Cpg9awr_uH~+W+u&d& z7z&SPfO`21{{#Nc&P*N|ofvzA;u>n&t@Q$ew6zjiOiRnm);GK2L~?xsdTzStZ<3j+ z+reqmSS9r?`T4(az7v0B7L{Hq7eu#gO|fXyA(rstd+lL*2wm$#b!LKd?3-a2y74bd z8dH!hJ<%$JH3fp*mPqD%eNVnFGw#NLNvQtN+@{0J*0?@1=<%gd@09IM0G~=ke9~s}y`HCT zvpBI64Oula}on;-Km#K3R)jELw-SPwvK>%O(B{BL65?{RfErt$qEA!1g&g=Krp<_eo6u#FgJ@^;@$0`?}%( zt-!{}`A5?Ex1+yDd@{1J(=oDe{0Wr(v7z`+DEmv|-2VW|nEq_+4*OqM>Y^}*DpuL9 z&nw*;6@k6ODZ;cIrD4FYaN-45190LwCuv>S2edru9-jyWI=rm%lN+)V5(bT`HOktH zE@CP>o&-_hrGg6PuX?UtW5o^QOyS+rgFhE;M$h%w3C7{QJG~yT^Y>asVV;mg)@*+c z_+;nzeyH48(T9tX%mj6Ca~rMYaC?|}*`W{NfPa76e>^|Pal3k3A)Z;uem#WbBcmFv z&*YWq8OzdH=+?^u-I_iLJg8J|Jg+*VtedYq+3=mpN*n-@_mcOm3~} z>IR~BW*@Tb+#dPG48sID(#9z?VpI5R8Cnm5?zK{n{_D!lcY#I41J6?Vqpu<%{v z01XRawG$)X8YK7F*Bw>I?cNU)OMHcSdw)I@ps~m;OfZa}4VDkL4o-%5%FBT7Mj1O- zdt|r(n;m`d5s0LpBO$5^Q0`;5#nONQiui{Y6?{FNyHob{KJgbRXap9hBdcZT@Gt`F ze*5*TtJ0uK|0ki&p*o=+nE=zpNmil7`kqC35|}Q0ZoOu#x@LK|s?Fv5-r;iJh&>IH zcZad|UmknjF)Bu$D@3GqF(A8UD1wtWgyM)6FoJOnNd9D0HoOnij2iGib% z9Rh&6apU1Y9K!+QD~FJ1qkT{H%gT$o_;(6j`_e*{RD{B)=_E~K+^(*5NM z9WSK?@-sT^tTi1l>BR5Hi!;H7=$$WzcoSxtt=9N^N?vUZW-JvS(n@oy4|M8+DlfJRf5q?g=6gq#Gg@qq`20 zyEu*4<;5T7;pkEmey9;opKEFofYIHAg}!eK(<-{^+M$p z7Zhay(Bt$jCMvrSY(UDFYmf^+E5x~hf&iI9`6Iqw!twqhi4bo_D|ob`S42q0lBOG< zuEaQ6y=yxx5NM%mt1vX&Li&;JV zqE><0j41vTLcgcfoT-%pxpb3}87csj9KGQP~b-OH7g4_UaeFtf6}FILo5&?oZD?UOlSu;)O9wEc}aUrA_w zKt%*ZE8)T5h9Ir58_1fW9G>=C#=npVEE4-*hZj!pH0Q0vks4a4cf@v+Uj9rLkJmC3 z!Awg<=%f-oTf$yv9jkA2m4aWn27R2R67vt(toed*HI$1_T<6#`T5{9{8$kr+jbbfE z5b~7$(9C?%5)slgt0DbFlj3+RIIgac*+5xq3JVQq4M{XeC275ATLr4yc>r&C zrlV#g>b7K6u>hu2$=N;O~AbD>blq+aMiM^Dr;4%**| z$GVGX(0f%CyU10L$>`v~tnaO?=cR)m|Zc|r~gPp=qnRZO#2!+Mp%{bXFQ$RTnt zqzH!?b51)YYPthKhMsjt78lzuL)XwBBpkyQ)(Lh=vU)R|ft2e+4O@&PSRoNd7n=z_UX>{aqK+sD7yX0IRY^&@kwdF}Hjwb1` zuZutkbdpM^l?4Z$n23CXWHds!$rLfDqz`ltq2`c#Sqg zU%yCe3D$wWvYb85Q85u+RRlq{#~#3%V-`@k3!LnQWLMS)_hmaqaTF%M1|;vU}~|Q#v)cr!A4s-lb!lad5o=o#fln5 z^Ub^GM0joz`gyJ1u?gH*_nsciM32w`UiHn@Vx&d9CCHku9kTnd9EM-tLxSm~65O;( zN&cW~=~T;Preg{a>bX$j9qnrM1tCc@$qTgkUUoU3o$RUsrbRE`0?W+S*_oV)DysK1LwdB5eU`?}pOjWiK!0^`q}jNM z9%mtJ^{0_r_Zu!NvicK43P7v(#g}57+m^0HK;v_yT&PlT(d=AbV7Q{0N#6TA1Uw(+ zJ@RIxZ?NU7z<}n~vnCNJ(CeWkt~k(5@b?<6u*P4z6>N8vZ0F~T6>g?uOUAqij0lkF z3u&MQnL89Qx1$bbmLR(725pb>&*zH%P%wCx>K;J#_NP4DgUUqEhj~F9UtIcaUl0LRtvXS96n{@G+jmT1`W4GMraHVcf7@2#PO8 z7n=?zUbTtva=FM*77N^wGx!znD71!nnnQtITm6h5go*#>ILOe~Jd0*pxn6aK*DTO8 zs>hL$^J5s|uhlw7bd3UXm6H$=Mq}POiHqp-(Hm({UxtoMgUav;H26EcP}vnc%bYsqRKJRgXf$Au4v-?`#X7$|FXm8nSL?Sf)vxK|8e?I9KV4J(E{ z=~LL}LbE~S=lO-7TtLBEyKrS6`I^L~@FHf{R``Y9FQJWgq}8FBKWf4C+d*>1bjJz@ z%iL;vAQSByJc@UgSm<9x0Gx4t5pLO^D`{C%pNqfB2Yj7-=pzLr3kUD?`Du77nhz5k z^X1FZ`}PGi>SV2bglH20evv{iqqFU~KnfcsW z({b7c&-FMFwn%@4Uo%9%n-$7AUnv##t5@t*iFC0ocoF243b-1k9#KO4&M;QV+tWFhyVkki#hjOQ`k zoCrRXN8WsyTiGf70IpNRhW?WxW_Mp-Xcy1cr2X7?Ufq*9P!YpHtuMkdeqc6UAyMU^1$vt$GP_|`Lk z&;QNm;mQu*d-?U`Tz=y%R$bbmg%( zl`09o`1d*Ynv?Od?2w1vJ@@T3g!F^KnFnw7=P-HIFq*88NxnF zr=h8O*N%NHsZX`zd0x+#w?P8CkFpMqrmQ%#&mt#pxZ!(c9=RKj%C%1O;c1D}>|N#f zc1c_bcG&^r$?rUdew(oI@nx=zt6uYKt*U5xhCe(8Tt@kj>^1)DRKmT8)7Z`wDa@9Z6X|hGXw5(4Z(jPOi75E$J+!`K9aS z;lMt{M%Uae;s;RC?}22_j|Z9-o1{1>Lz{92c4;hf{vC1j;DykQQd$?CLpM zvpbHnYI#HL>d1N;Ot>m;E*QiiZ7C=nZ)Ib=a=Gn2LGt(yJa)CPC0#R-Adf|}~- zc7$!_DI#?8$&{$)^$0`agjinwoH>Zkfm#t1y+Ssyu8TcHpYUkS3ptp0SGT2bXsu8w zR#n?pY=a3YGO1be#iu>tP`JJ`Z>2+)zuyi;RoKVVDVB)61S$x40g@D9 z;xH$t0+^*q6T*#Oi{KB1LPt*xX@83VKfH z9ygxyiU6hWmyo=mqE)|8XGvr%44zIqQ7Ej*wrQVge$c0#EwGB(OPe->PZ>Cnm};`c z<9q&s=T^e(GX9eAK<5GdRQ0Mm=m*~cLZ!^HQ|K9SU&INd##8|iTOxh4f?FzK?KxF# z4;>DIGm0B=T|qIT(t~PJfWyxZ*~^Lrb?AFQT_#Z2jS-sdg8yR=UQhL#rMJwhx9WrvcVBQN3oKVV%>j za+#8v*ONCiKHXh+Lnq6GHdoY#bwmT8ZN_!|R64R*`fUUW`CQBGp_fb3;;gBrqcT z++IaHa$3VDzc!cv)2J=@N>H6{_XgWC7w98%; zA&ed?5_15|F02gz%=#?j_ zUvMDKJ43M`Ux%O4tceZCdnm4B90t5F`kj1!Av7S3jLe4^+AZZ=LQBGzyVZie0tf6v zch#3Gay=c1MpZdwJGuf5cV7xbQvj-e3zal8{;)BKIB2@~rksL&SM7V14}qxLS_rqa z$JRk`+Dy+Y8w28mUGId=+w8WK?qSu}2?{gVCx$6(&@_gntbcqx@I^|0;$bBFhN&Z?bF$BG7Lo!2yfHrlqC(0oTih^R7l;{e zz!=%hbth>t>q49YVlj?-j9t*INdiSK78Mmk`6OLQBSYr?)}(qu#@~vnksDVS4-8(Z zQ9HY%ZKEeeFp%CZmLaJXuq;MqlO5X7MHXJY#C$(gU+A{aZuyCTdePA}*gh#^UTu!d z9Yoro&6Fxv8(rxPXp{k65aQ9cedESB2e3}0Ob|piq<6?!;<+dRT&VSWR{-9Y?8%E- z3GS!vSXhI3z08Iow87Y2%*uK_8qM>?N_&k2p;D?TF>=q><&w%%D1p(Hb4X|4 z9U0wR*~hB`#84`(dA$YVUx;tVrbkmxpe+gNR2NV}AE^hNZQ0N}kZ)RINAe~8PIrUl?5XXspxk*$=&jbCw^juGy>FWg* zHk8*sYGv**`=>#Pe@g{|>cOGlSWEMzihA;Wr0EVq4clUf(DgK;B!n4d-;y<^*KcJe z{fN{!#eESeM9b}Q6+kFVYEfweEP6Qep->KF=xrSVN&_tm=DdGkCiF& z6pdV=^oS(k1u8k4ZQfD(kS>%xy|r)!k5WC^Wcjn zR`h7%_U+2VdQo%{`-PW%_b{9hH%1~5jN}VW#||k{6cRhW)%GX)JpX{nKV$4a8X^7z zWB-?`|Az<<)88x*e?7wU_Xx}%!~9Ht>@WOg?B6+|zaaFp|9;D>JGyk#f z_y=M$e>OM%qG=)sVE4cJ?rH57K!livLR@pKfOqGhGMyTE-_vY zpelf>IM-qwqki2beN8164(PK(Z0gbj0k%R=;51(@r}HQOb+%{26`W}cYsa&At^r@4 z6tsNR$lBwn;{3VNS79I{ORAeBE+LQMyEM_*Gy;Mpr?jxlTEo7EdVpmEmD?H`m2dv% zK=F3>if3cv%*!hBcYlx0ieHA`n(nn%X9#cn98!ia%J*KZf5cZ<1?FBBwc=(GBHb~o z`7pFwfVt*a;eHb&F4Q#W$ZH-HyCk2NQf8$5zTZ#ujg`Thzk&GMlZDVtQ7CGd}!T)OR?=c(f#t^ zg_{mbnH&0cOnoWc=&%a!j({kd&;pPE@O}bo8|;qAVyB{g>BBTHL&KoNWl)U2r>Y-m z+V{ygbSkCOJJ6&u2oZd!u-4%o7FtP>ZWdbL>s*2PBh;AX+GyCHlp7uaI1xM?>K4_CciqSsj^>Y`yf!^2;-S7Wrd>Xhx~EAC@JR^%@|9XD zr3~SAwk^`CSR&SiL8saz*)3@6DTQ3I9+>?f;fZxH`LCXq$k)%QTBLf=&L|AN{9{ws zjkUnqOma62(|gnWlq^&^#*=RpN?V>}8`xuE(NFy;jD%91u{Zv+*7~j!-A6Ro*8BX0 z`2CKLfkpusUfQKBT{nUVe)`8cwV!)|2{jVs0&+Z@juZt^aXL#EKg=M(FZ;_iVK|Oy zM(c52h@UZ4YBz~s1oHsIABDSr_Pr?o_A?i@|co{WN$a+UP z1@Zhm#w4K^sz?}q)z|qOZPVnfkbd`<0qP@Q%Opg+>m3R(klZ6JbZm)SXKSm0a1TiW zOng7Y^>1+03qjIuBtr9F@Q`@Kp_%2CJCsXqi~n+XG93~d8@OYy%s#C`_&@pJ1Z>jbamrRM@-BI|0mB zB-9U+c7m=)qJjTxBkTgJTR$D*>drunJSC=W$THMtr}A+N(l#|lxI@&o$agi*BqAW1TmRF zor=tlMGdzrMHCH&o-n~#nD<98`viD%t@0-3RZ1G4Vy$O)W3Q#+)x(a;gb+Am%Dle$ zy5x*Le!H^oa7pmwqWDL$KT&mT1|Apj*dr`&K9FFJRqvq9@aHpnT6bwKQBxA#f} zIq_UF5VeDIll+P|j<+Hf5WPM9E#@RS70uI0T|R5g&lX}#VtJ61&&C_wjO1S@yo@o} zx2E6Xyj2})TrQbtMr=;UTXsC)(f1XP!}z|Xj7@(lGbLrk%tPkl@lsCPFqtDVOrasz zy9x1vAT+1z^sM4VTc;T&q3jw?^@Ngq0#%P$hxN9et979vO;*wBowgpH^alWE;^KK* zH;GPq@0ONlaU*^_ZZ=blOsg>g3hC_*)WB;5=z^t0gcI6+%xOUt$vjOemOgi~50xrF z*?xBBFx(tYMW;&;PWp71M9G>6z_4NHW2}(GQAS|i2T;Gz zd{HV59GjwwV*KV+ zAjxWrUm8}=ug~73iz802{|*4`-QeW_7OA(1*^gOd5J6@0)Ig<_{GQUe3j9HAv89i& z*#!L}a4|P`*WfqJ)G6rkzsXM*mm0pY7w~URaDBQc2`iDi4al42C)W}17o3}0E6Ku$ z@71mX%637}`~&EblB0gy~5yHPij0eY|J~FHG%m`wX)q zqxy=!sI9>31}ZEpw8kV|0qm3DTG6aHKuNY{l7Z4Dbf+w!nRkpc@o?W1pp3;|yz8XSCSC4i3_rlPPcfEFSh`IP8C15@F2v?>P0y|< zKRN;CJ8CzK&{U#~JNF!8O2e28Y<|8Us7xr)h|G-aVyBP-dlcp(Wmg?8SBFn zl<+I2zkjrQEO}P{>>fF7Cl{r@>Nv<#x9;AVZ?~gqWDZy`n_sikci810K>4e>z<9~0qLHxOUbqB zx4&fCs7ZzYa(#((WVx6!MlINsf%}D}{OQf(z>tq}r!_!84GjL3V>(7H2Aco9@8)Rw ziS*dW;K(IA+6%I~Z%?<+8z$U*z5ka9#Ueu^yzW+O$Xn|NFik_@+n)d@^B*%*e-50# z`Rl)ly8o5t`is+}{v9}(|LD2+8*u)<$6pe4nSRfr`Ui3T_p|?H_+{l}pkroX{5Nk2 z6T=_%+W&Bvg_HgF`l|o#7XI8x`vB{-bbN8b(q@DhrRzH*&(|`a(0$J3K=VCrLNtZjlpS~A}i0w-zLXEH4d4E1P z>iXH$iw>#LcHh2n{kE3Th!479KdwaCw|`!xNEtCJ*2g$gyt=xV!4KR;)UZ}80`kji z>3S2(I|z!;r>Ud;?bWn3!r+>D(yrmtY1jM?(9@d1Z|~^U`u1|3(um)j-GLyE7?Edz zJbk9MRXA2benB*z=q$g1v-vIpwl+1n=|H_hKu!NetM%^wDUfH)&h=6|r7wH%rNyeX zth?aL_eD)LmGV}g^DlZ{(w?9!sKmk(b?L0hDI^x7%^*v)?L*}vTV?~sXajPIKl8Zr zYLIxeS$?o1h-*1$rO(XlE38Nx+RZog39G8WzfI-oW;#Q&#z`s)6pbRo7On) zH>QJs6+YS5cHv6dCud5MC@e%`loo1V>iV@AzB|~+J!ERop=XZ({-nI-2Ks*YAfL0U zrvPo6@^)qKLUg5Xdu_)DzWlW4;d)qxDeT8(AW@}gNy0NzJPyJ58=2)=vGKxkr3sg?ufjdHqVPUsLeFObwKG`DP6Kb+Wy zB03p{$G~m+L2j7f`~}y$zpDTR*xkHepAi?FaPN|+DIbNasl1XR5pJHm;MnVW_(7*c zgX9H!Jmp?OON%*JMic4C`$JhV`8F_uCDS632{^Yh;AMK3cj$ow99$yF`{~ty{-`l! znnq@)xc%EXDkI+2-rlrbS}Jozewsm|xM;U8A9R_b#-lcrwWRfV?o3Ke#Uh(r*V$fg zL#oxf>Ur2U1IaHdjHzkB?rORbEaBau0xr}<&{*omJxghw<$wd}gE2L3yh0jTcLk#kCH~+uQ=KKC?29nbiIP@AE&R#u z=}eqvAXQW8nGU_(B-x9S0df~MhFuF1bB{MN7o5SqeP%{PI+PI&PCr8_C$r*dWT)Mk zG-g%J`@Pi0!toS!)7dz0q>57$k5-$pXIwPsz4C;N(n*@~7+)&fR$CVGQ0k6X;oQT8 zsq!!F%KfmZL&>n2B z0gwZA4aH@O0?cBtklD`%k6`14JS1%XXuFMHmj{NZCUUUk37Utt zs+fSg@p0*;NYY3sI@)VS2E`?o>w0DFF)Z37K5>zEG}%Afvi#HCod~$t$oBi*ui{b` z>saNC{j0?&p?WOW&#=U9rc{#&H=g4i|_<*Gp@zWf@<5j+Wp1 z%qVg@ocUSuY_D=^t=6cCfE%rRR_&uVzk+R^=Wy?MURhROi0Y@eHTZqSo`{G#sF!=F zT6EKBy*e@4S*VX%Gcs;$xLQ$4oukf4vGdWD9_Q{8D#KJJZe#ZnvF86iMK1(L@e@yc zn}m8LU2I?!)f~48+t$MB%P*A7@wMGq1zQ`-2nwe|zVxj@j4_W;v$MRVj^%*-ISp*x zIngFqyNoP=g-0x6h0#Tixe(y~bb4u_t3BZ~!p@D|+HVU!M~Z-iUFPgVPJ7?*>#+gj4MBkO)B+kJ~cDv>Vp*Dw% z=O14RK(tKwDk&dt4Gc0lbWu2E%STv?(%Sb%k!-E<=4$UqtTc>xw}}WzX2P;x1YwE9 zlI0`7+HBESX>=L%(e}Du0`#E5JtL6!xY9C0v>L69A3bo z(*r1`!ta1$NhqSgLx7G(=tTeJO3mvr>dbL}xUZmMwkI4e^Qe_jRR6Op+?k6-qbYz1 z0s&ELYEVu0F~`MSgi!J8vJceMk(+m3i7t**>8*FbTvoIO7235q>0-w)nM}x0Ta@_V zlyMSYJgwX&UE0aTHu(!Jd7Vdt>w@YL-57KvW)((f5@yq}m=~s9cW50*y?7-9e4X0P zg380*>Db*`#s}amh-liMQQjXjQvZSSek*?e;vZ)IKbs8nCzSVZu=QK0{428J?`Quz zE&YEfEB?{k{0~`?>95O*NuPkU(}dVDQF&>5Lts(VwjkSA*;wIVDu;xqHv*#2kxQ8V}|}g-0TecuzHkP+o$} z(`t0-!(Oh{aO^CL8r{`SOWsB4fEki5)78^_p`v1rsm9ImbrobUz*{$ypYFy=La;qL*45jzaRfigU%s?AW-XRdKipl#&XK$`7nKYT^Wq z<_M1zjHR(2cvM-v>gnApuu#Hgjk ztCq`foai|?Rulh00dsi>n1X4Y=#)SYH#Z`MVRF8`SVHY8eE0v*_Kod|=rNF+Ds z+FS=G3#^bp*$-9fzGH3ua=;Sq)wdEiMw-W2Wlf-^H(%|*YnzX~fc{&xv0%RKG!ZPC z#<%SN;-IY%n0WUjewfrBMyN3FlsF!^DLD-EVJgOqmt|Jr?NkKa>0+j^ z-*?z)$my*7;NrJS2F*e5O=Xj1B21?T%2u3d1|Da!3}DbNqh%4Nr+d0wNi8#;QObz> zymejnk$eU+DUZynqUKWan{ktI6`7EeI~-WzMWSpFTz;V9~ zzyhrCEHLsx`K=2RrYOd-CVY!iM`;h{i)gdG?l+@=)u9;G45#o5B?uifOnd5So3bwF zOd4?)%^NIK%pEJN>~SIaP}-*@@tmBB{oblu|212}U~EH$BcQjH%-f&SUb$5&-3Xih zQzv{`hbwU$<280M(Sd$t$!sz?P$PiguETg0qL2AutYV3}bja?S2xa3+RxE`486+LG zCF0@?$m|K_!OECR4LevKdSZUVR*pDeX?U9p^JQRuK=kpbN42NWO8_Y=`{V{r0DhTQ zH5>?@Eo}@S4H9X zCrR^m?luVl4%S@&6(XR8wR;Ah)sK^KK#tmX>=~ESMBF>tY7d7VenQ2mot@PFnLp7s zvQvOLk&Wprf$G4W)K9=U3*)f8%Ew&F$JT3&zsmbNIG{_W5z_Zq>Nr)h3xO9ODV#w$ z={PtV$8Ymb$QNCTJ#f1wxe>R1nT%&9(hAHDH^L!MQwGE|H!A3+ttH))`Gwl6|C)V8 zu{TYuKs&BVnO5teTH^3J<}>I|aA%!{eQVrQzKZ~5?zUY$NbIwn#$hbDV{lw)b%LZ{ z)pHUy*n(4;+(ueHjo^Zus8!muN4R_D%oHM2J|)iWV#0urjFobOih`DQay3RpJ|5dr zojQ>h5@v?mzT*_I@!kHI`K9aXBXt2E?h8LLk}2PRh%R{0e7DW^GD5r^qZMJHN@IeSL;M&>?VMKmEn? zzT}scZc-2*Uo2|jJveodbfw-V7Jd1#B7lA0o?|Llfm=+7MpH`c>tzn#e=gFnvDad>gPy=ZKuWF>uvR#1 zZNoAT_NK%t0OZsipG38V%1@Lo$f&=(WEi$kBkR-xP2Yd}a+I^+mZ_mK9B|lOg(;3v2=QifDnQmAstT2s7bPHmvA^E-460Tg}C@DQzzoF!%~0f ztID#p3=B@y>B~)!#z&7xiu!i3EY<19hp=EV^ zE%H)S-vt3J*3XQw#*8)lJXRbWI9<~C6(on1B<%!~esQ*W4LNp#1iPFYDZQn{BmZ)Q z0r^(#^Xuo;n7d!!KpBOcjna8fphmjz zs}ZZGMRlwkwGZo@)3~eGcxasPjepHA(U@rs&ezPMlxfTn${{ddtH>TIgpfp}zaV>6e!5Yb&xj1p zpZ|z4Fzx7|^N0plXNmz&MJL*kJpeQPnk8`J=pen5=KQwj%I7f=dNuTmK?jXYT{9+o zol$~;s;#H{$ngHYVoMrLbAT@3c}G6ZQJUxXIVvY7iclaKsYVD()kUOr~&mhP61iD&n%|vBS5MB*nzU>a}Ud^@) z(mNDRhw>BAP4$U;AXpB|?Lyrfk_=lPTM)je*%`8fpYu;9_HQrmW(by#syQOkfNKHV z7haQUS$2F4-qH_axk9X8jl8!@$IDEzCOfv?Bi~(T0DuWf&++!&={{IVa%)jre{+(Ac{4H?mFOI8={^s##zIyW!!GkZ%pZrmK z8w`(#?P-WGm)8ymhYj~*XhXEYAw1!2Cj4V6a#(i0QjPNhw+Ul9k_RuF?h-BojZTlu ztJht-*rIOb4AmVY!YfV+1I?suWg&vEfEe}KG0RNi?sSbLrh1EQw1BOqdb88>)}$_YwAGt5AFHpgH!O6;h=uUA@P@rdclpA_gR2G00mJSm!gddk zz~8AkRo7(Ms*c+Y*4WyL0u!t~=nol98Lz=Ibg@ts`A5_PW~0x$IIzWsCLLjl)&1QU z%I3dNmo=4>4tURBhS&V0+FdxAMSA>I0HJ_U5Z%(%yAjjioZswVO>@ItJ?caop>7K3 zuP$l!{HE(nPBNNb{4o}r16FXdV!Pv>SzNRhKbx$V-kmZPz?~sADKP6@FA~DT&>*=O zZFr}E0Q?PQmY+11kCX5y>m?hz&C;qKP+K8iEX=L4=j4ZsMqiUsXIufa@l zGY$2fp~XCxFvcOkSqXh&+*w%Sk&V0U^tHB}Aa$2s#=Xw{lR)xyv-HB*^blntjKry`9DqnBH4Gd^i z(JqT2$+EE|;|cYufxAI7&s+{0sHvcv#fc^D8U@1_XQIxgxkJKK=T%J}l(_r-V#-TH zqr?LBP1u!zK=Y%&_au)q8}_7?xkpe%At`+f$e}wP6$(f?MXKTh%e!8q=0!m?AJn>ywjmULr@=9>W8Fp{Uk7a>Le-02;KuNb5H z8IwC5*zIQ~0-zWVF5B(%fs>{H6*_hior^v5fg($|q3( zvck123;bebK?+8#!Y8TeV8codP*2=0Qlspw3EU)Cx^xwHNW@%7w!upip;3O*p!w1yus#A8G_=KEJ zxMUFa$QJ;Y;^Yry&nLICkTd?MOE>1{jA9w)Ya<;66Zr1{CKU(z+J=3J#UpE1LcXnT-P><*W^zWz5 zP)_d>B6vNskF7VzoI|YVFm$zTbYH<5;3$Frgjz8FKGyqlYVij={`+a-=bY|;NiBYt zxBf;C{`ii+PZR%3pE}zgcmIFYnV5g4AOET|v3@#J{vsa;){wH>`|P5*teK%WKqpGK zcDY3${<1VgTgPDy?HPcLjaN#*B19dUxi6&IJK`(XnND{vj3(2qzM-RYzo=G(2Y2c7 z3%%IY;K*#K^s~8L2l1B$_D>Sc7Yox1*uf1uUDPulzSrH*7)tGGWzw5K_D(3bSvg%c`Ci@;f9VPhU)z zN6xX1j%qFByY+F6o&9FgtE9OH@|1_sM*nZG#PTi*i+4h7xS{1XZlQUDKNq+TTc(lT zDNGL5lSt&6mNz;jJL|?XbdFHoa6@(nJkj@4lU{MZ#;wAs==?;MW?S{|Nd^=565N4m zJKFF@e8SLv;9cli%1>-6({m}i(SHPYJ&cKdS_#}5G2XmwwQg}9-Oe1Y*7*}Km!{G~whJLjLfqq@{vlT{hOWme6I~vnfZHRG7;-^KpB}u*! zXi@Zklx|a`Tt9+592-wsxbK6?b`cF!i2UySBe3xp|LR?)c}T;Z!Ma*SQpla`Yl$V= z7%2?4o&|`WYTZe^-NHc&5FY#7>>cQN(VqX}+D?zE?sR`HwyvBT)fjU&?D(WZWd36%=P3xf&^d_i~B&u`1da-^j8U!^Y`BF zy)QfqCcUy*TyKn1UN(m9z0POTUZwf2IAR4KVlMZaB=pxpOixcJKbL|)FOHDG6T@B=iFzp(6qkj*MCPpbc z_Y}!TUHu`0E}zRBAUa-4@YNiGV*e9pL!ucYg3ksyzmePronyfZlnXxm!W|FKO2kBU z4xHGL*VRkUb|M$@H$+&GnR5)Oyv5l3ByXDr!xPz>je4|@a69QH-m@1>?4nVyI35sL zB-47PBj(sx7#L;^WL*>zxY#oN0&=|DTHF>RqSy(Z{G?-M;`5#iEs#-FIK#pQ|6m}h zbps^KD`G{Y%#X#aI)=&K757D533#YPpV1Cqe^76( z#AEVbm9`kGa{yJsudv`AJnUxor@Sg)cBi5QLh?HkLVY{8;qaR87?05(9|40|IV=(5 z^&vsiwMf{8NlX=<)eKKbmS=>d`2o_{9K~f`66;#pe1R3R>ORFYZi+S3Oj6Pxb(~40 zM4eZ|-K+ep0uTAgfv3*i9=+*vO3i-i}?FVA`1sdu?q_Vjb|9-PEmXV(b`Kxvx2DF=6vdh7z^1_ z>ro28KPH?(?a-;@lJ#PlZ{lmU(25sjgZ8VUpZCGGp`8v7)3VVY;eozKMCR~6)!jmh zq-1B+U3O5lM+~fhcX=UqUQG0a3LM5vWI|0qA42+R@f9|;BYLCEsSJNEc2)}onIAWX z6}JFKWc&>G854Y7#4k}6@rPM-v02CxBg>A66Itpp$sw0&O8|{#cb{RTA!#opP-lRG z53)6G?{m21E(T%kE_hvoFd;?*0z=E}HC;bs(?}RaLGhDV+RuZ~)HqZ7v>V6+#uXlR z7k#U1_BC;dk(6R=Kt;$eGoCn+00JD8yUcM8*a*T~--VU(Eg{=6Gi?cFTeSO575mDt z-H7d|b);s6+na!@hI>Lu4P}w|C$hLRRyYqj`V%9(bK(x}%1(_6oLVvRHT#oce1;gB&TC|M(` z2_qerLC4 zrcnUJ!IYVatFTMT`9W(;tARB%|H__gl~D_lRE=r7Y8`k*w4pRjUfMa(r+8kg6pm{W z6*jAmV2HwO>rGBa${$)()3XgG3Wj|Y)DO9a$+(?)-WR8KVHg*clD>B`36Jv>{Fglt z!XdG77dlmiusO{b(n_#!QZ3kOA8HD62rV-z{ z(AoHxxX-6&;=`s~k5y0Cw}5BTb2NA)JMsTg(|!v*%q77X_0iBEUW;_5>t)9GHM z)Z9!p(!5N9j$6NgRLlk8ECds0H?;4YA)(wmCkd@}V#KYxO}m(?@mKVf6COm@=m|$b zyp(?+B5NM2?G3ypr^d``72_^1hP+Qty`q47#|p9{KSPGSHB~Od+4u$#`}H5#t-NMc zW4sW6tLxmufm)B0NB%e{Q^cM)eY=*f-m6w=dJFW+6&mx+N-841N^tXj2l5PNtj-6G zJQy}|$1xsVSy(J0ocp#xkt0*J=E5xyT^hNYBSV0C%-llS&RdyQ71<^169ppx%mT8d zRaB7lWEmJ!*)o7_A;~Z*+3@52bjVH1(2P`ZYF~JQxQ?G6__VWQWVI+lxU6T{a)(SR za7MR9&C@K74a%#i{`|vg;`C#AK%&i`>d@DEscajXTIs#H<5xyVb+c*snI+zi*(ERb z<{O-O$iw`f5%k|Dvi}J|{~KTZ4+Q=1v*G{oy5DEY(?2A*KM49CCYHaV{jq(vUjO6l ze^b8uYX%dRKQWkmwsQYvhMx6r#V)_dKZCf5@6Q;HL1h&1MGWua4|AB%u{se4w{{Vx%;H&Dk_VIp` zH9jO0mIRS3QxTv0Dj?0sVRlnM52c7v<3$p{Y%24dca9f}!}>x9nIDD*d%n9GBXV|( z8Qq-#mA$ugFwm;e+46M5>Vp}i&~;M;2|R^=Yih??|3E~+!-MGUiC(t53YL(TA8>mn zt>IjZUOwD7!99N~+Hk$g8O^P;_?*|25xmTL&%~fCqnAYOxWc56&L@PxvMApO17+EK z$8(f#RWa1ud@F)E;Nasve4)IOE{j@KUXkPz^(&d7(Z%$7^ zNOk6+K;^*AnDN%LaS{a5^wDt#{e8%Ze)GKkG%yxo6-dRBeuMn|9nXDnP>{sjfG1z< zy3fz-llWw_4TJACR`dYB-bOXe4gJ&1@~e2l&L$OJs*ld@{IpasZ|_ww-9d;_Q$O71cvP@Je>^}^X)`&wPkafRtg>T!c8KU{6HeiSm6 ztA)g0If)x6YeIpA0_fOeB}x$9F83y}9EQzq9!X)-0?;WkPC%Bb71<8y=O@619t0FY z)>PDqt%mX7(erJK@yk^9K5sJ2Mj|sD#XOP?5C_*Rz$z&?zwF2-VF^)mJ(7er5FH2}P|JX6V31K+vl&a( zX2UANJzOPr{4`}Z2oR#qbk6ba^eC91-W>iuy-CP(FgJy}NCYJWesUdxN2m(iv#z;* z_a=#;t!?DqW^4j2{Jhg>-iA&-hBehZn_%uPR_e=+*(ATc zOO~XvhhObquifqUtFd%x_{K6g_Ju)zqMYZRS>ZZ`v&#oAes<6YTk?!Q$D*-PUuRY! zZ4xwdzh!4ksjbn63nx?^~Y+ZJYK7{)(fm>O)z?XZn{aXF0aV`a90&E`!FYT4_|E zq__2oikb(10U}!leEtd5zya;cfSP*=epNSejlb^xd@=w7X+o~8ybCPbDv08@{gB+)-#+;{M1_QPtb4~s$ z*x9W~`>b~$8)p`!cs9qMW$@kC3`f3>-y!2)^W|zU9#O6g__tCDfWPn?ABs*^D#RtE zGkFH1O_Ilx$Cka)E}+DpimdpgtS(R=Z%VD7KQTldtn^+wo@jtV z`Oc|(UB6(hidV#8@A`n01ccHaoskZfTP+oanS=CwY#M?^geu;tzzt%AdojUJ!-wT6 ze55$d=0xm5n?p*5m%B$@a!Sz=Hs-Y>FYh>{3)?MuA2Kc0PTzqiO3Z55Y-ws&0$YPC z<_E63lZjqxTN9l$;VXx&DyC073(5I#cA^&T^C_W_Q_r@!okVWTPbtr@ACc?hmWVS( zeX}KReIHDdS00OcOjn?|%VLJFSeD79<8?wfPfpJXTL;}z z`ovvF*1xXp;7AUKSy^h7IrKwZ-$#t#nqc8r-r7Sgd>+$+yxpJP4%Jfyt`^@87C$7B zQojEQQ(^giT=?fq9py3VQxS^rtZSv4&e8-lh_5Tf11-;0hmXWl zjkaq5zg=df5RZ@BtVZx)!-n4OuodJq)9LD#dF3g$NFa8uY|_?|Ps}^TVIUo37}wIE z;sr+O`fR>G+(=e@mB<<}NIZxL3)cO3K8ZQccpP`GoaYZ6cTPUpdfo^BxsmU+<^(QnH6Hf3riLRKNxYfh_#?4@FoLWyp?#B1}j)8;0(#h^&%XWO$aO86W% zvjnH>wq5iLH`^&YBoq9CLux7vlx}O&X^It6Mo*J#iI9d-OYqmj3kMKx&4;MhOP%3` z-iy_tMg3`u<#y3MTx}JCBw&5I?4K;??!1)1ZiAjEH3X1eh0Sb9Bh1Z)>a`CcEi~=b zXR7ij?wAYvYTr4h;zwh+kGM>oUk;Q}#4~zHH}O4V#|h4JFXFi|^96TQguq>aA_{Uf&35C}yrJsyTGQcG zPdOfO&MydVwcGB)<1eme!RQs(Xw5Pp>H2T{uBd_F)VOrj1NesLOm%MSsX7=^>Kx*C z)D0!P{)Z{T9d_yBCdgt5fNqkS70jvg?`vI;T8FB_j z%;(R5lwF46!6hA9-oQt{q^nEv`eYq1el;JmuHJN6x5p>p%57w`1kmaQe?i5icOvKR z&NlM#>HPq?r76K*LRe{GzJ;WGBP>53~0R=i5SKJ4m!*jDm__L{g!3gsbAb8bkRXY1C%mf z1@)Qrq-50{<%5ZW$V|trF?vAD*EuZAc_3fZ)o}xf9EX<;$yzIcgxOLr*&CW^$--PM3q=v_onxVv*fERyAtLRrI)BUQZO>|8P*CKDYUkPIj3yP|%dQkgvVy2D{8wV!NyV;{UavG{wih7>@8jCRC$3gd?; zQz#8jZ?*i9Z9{SxH2nmKW|JZ?pZ#y&I#dCV#aq*@vb)S02&r*~L^*5GNEi{hricZp z9NW7r!1iS?coRd5z4wNB)flj7K-Yk~XzO`lFqo6zghW}rT=bL5x1J1MH94g-&AM(t ztE)Jn#bD`u5^L1ORG>Vg?6;ntuH}bUu7^CHdw)LnQ^$xw*EwD$W@P%qi6JDx)o&!M zN!XeR)ENoSSs(_i492p^e*B6{x+TLUggPp?tiH`~_`n<>$ zvwxCbsj{V0W|t6cQb1fY*=xScU5ilhILuoNj+R=k?bX3x#(9J3k|>-{y|;ZtGwhqCc+ zaQ<2S@)zN}=pS%C`U&R@h!Q-RN^{16#VN?)v$(5(v#WQXd6G^f9PPHV?+;VqwYYhI$5~3^+SX;jdIgS1L_l}hP6wC9uP&MdWZ&PU=A(RCA&7&hPj&n=&CVyGPF=k!71c$D@)*hdXgpb9`Ixs?~ zrdGUrR8EYf2|Fv&`c)#fRXpE$ng#Yaf}<=?(kQP`H%Ji*WspcO#Q^biYw5xv4)_AS zM*esVXTO}fTIRSQ@f$j^4B>qWU)a~YghV+-R!kkSGIHoW>75Dg=IIWr?9cYbOr*z0 zZ2&=(aB33Yu=8`q6#qa-c}kcGZv~w3AK)cvVLf258(VG;aKYV_6O_@gRA24dIjR^| zl8y;3v{7>}SC^~uWM-R+HOIJHXltdznaw1zO}^tg$`}YKsWPA=;T%YdBgK*P7Hk=g7Q3hi1O^Jr7vb`iEKX*Qs*qp+sL~E4kqo-xF*=Wv{3Knm)6>^>mdAV zcaO8JXolx#AsN;>suHKZbrm3;SOc>|(3w{lVt_+&z6&6j{B?Y84Gl~tLfz6p#2iqh zZTMrQ082qMU0-eHS|2TTgf@RI`JI8&eQR||FsmvoW(!^puRlfo8#`9~n*}YDRc)8@ zJ~2dRa^Ob3C)jH815>))g|!tqEkBAwI-eiNL{{{z)P+-~!%!@Asgvh zojFd&X_y`2*-$sx?i#WIAqvhctsFpMp~<3-onQ{wI?C4`7Gn{TluB|K`y+|vl4w+x z?*=W(HCW-UU`j~sCg0>pUt=l-)m#RgqcWHrkne_bqe_fcF8B2i10~hj!Cto$hH;~C z7xDt^Svv9?_T^oJt2*b!E42Gdwv1$`j*ztZ>9Qbz%cP~iK}&;nZ`Sp;+q*?-ZC9gh z4ZdDkENTUjM^tp#n`ZthKgE}z67IyVWm|9uM)c=hLq1hDK3U`WGS0mmgP$<9^fd`w z`2n>-N!@R+Kfac(nwT(!?CM83BNvqUK3(5z5uKEEC?x48F5z=x1EFga3`pSz`>MOR}zP2yV`J0FcF^Uwy|s;%dDy>=g^OZdt2 zip)=0!GYYh1_9yUQ4jA3(kX^7F`2=*wOj6tGJX%9QuKzV@O+P^aMJBk$~#2*RnF~; z<~^aqpj$)Z`#1!7SLn2~=uz;t=_Ne+wYI0YUzQliI+|0J??#7wdhn}BxWUCJQ zN*C1%k*`ig#XMu`<*PXp|ks~H`B zImV+=hNF9;6yurpg@ir9xc)1UmYLq|(WcN@W>UPgA>;3M+AJz(__dSTQ8BmF?@Wn~ zMptBlUvF)wvpCSZoG`CGLb}1pnSxy9==94<)T9piMrWa~ydOMa`E+-HDUbJkF4{3` zW}hz7f&HN>jwTIIIyox~vq6GW==3Jys2+<_oV!oXAr8-2O{{R8EeS(_p7$(o_w-0W zJ(B+nv44Nf{yAd*fnWdr{rwqy`rldQ`Deubbk6?+6aPT$KVJ0zg4qA{D$gHx|1)6! zAHKg?f8R6uSHR|A`|C+m>QV`7tk9ng@V`{uO{>BRah2_C(xvBx(ns6oh30|O@?BZt zNW|jnH%9lm(eU{-9_B`SQAGmqv+?-f+PtrCqGqTFb{NO^EZenEBr0#cR0=IB$E_Qy z)INkw+TLAXhR4|ysVPi~cZioOg2Hs)-p60gPvK6Z;@ydN?~6xF?jAPIANn;>XZ32D z>^{82BARQOC+PHU*2Lq63CGp2NOlN!>uuC(*wRMwO=#pDu{J#gfUAf63$=f zPNPQVm>J>Niio6A3CX?{XQT>#0~7m>z$ts(LGptQ@qC>eD`@}(evF!ydDaH+%p<{+ zlhO4QhJ2+US??<5@Ua-v1Cy1A$BK*fF{|p>W*LrqBQkWUvM4$`{UY0S&4KwbnT-{P z$M@wn88kGn8*jn~n8_+h*q2YeIF-NB@5Z!+@4_E+0EnuzF!C9Prvxk!R*ae+_HAM1 zk|v51`Laa}w6F%pR$rv_({#GBBr^iO*hizcgyCjnKA~gf4pBrjG{2=hcx`+1sEgV^ zm)3^c11P|kZ(WpLr7A2pb;6Pv_l>xXOIG;mC^CSE6BQKA)DL5Na*HU67w-k)El`P= z=xdgSav%$n#3I+Cm9D4tYVxlI_)4fJK+Esdv9R?teoo8HHZjFM#93iG(Jkzdh`^*& zOnx?(Pd4A@9gfVc+tSU~ig)+38l9y_l?F6aIW-_9@;gKX7#}#fWw;En_avNhXK;r> zy~HDwKYo_iH(;`h=C3q~`B)7wtv6wxM|>xU_5! zf&`L`M^lgkAuhnG;s5Lb^i21( zE(XJl8ivdowDS@Ttjh|e4OBLXE*O7Tp5z^@y`_M4DNd)~f|R&M;Fri#rcMIez}M`B zmo@$dIqeQGt&Eh8F88It@140Apt_u>#=Sc;-1%4#bvClY%+O3=($B*lmb)s#cnSz1 zPebI(l_@9N1V^sHRxBac}0~vr$xp9MzRX8J89nuag%9kXgWqPBBv_RZWcGJoU ze?(h{rC$v_Oc=BvhC{rx z_GnvT`^1AFkanpeUe1Jffj@VHdZTiNmLlPn@MeM+06KV30Gs#&O1Bk2$v6lS%#!m) zV%7I7pwIc`at$hm=&v=v`((GN^9nw_@zB_Q01usfGpli8Vyh>Ie0Vl$!KYZ3 z+VX7&^13~i;Ogwo1RpS-!~5LSTDwZ7f~4Fti!eQ#ToFLo zV+{P}CxbQ-Ozuq2jbKdAeNBDMZNOudt9ONwaqV~^lR`cNHom5L)D2baj8kMAlAp6m zRloO0CI@u5&H}>T=fL0r^mrS(>BHd9} z*d*c7uCL@9F^UV52s*W+%^(rX_WNmUk}zm|y%U{CFsu#E;_GR~+|{*5!M1W=OSQFg z5)USz2Gz0$G#L9Kagp?Cwjn785tU<0>>eyVs-6wLqlmLL%7I&gqZNfhxgACTqE3Y8 zOn{HGD#?B4%e+<;pvtNs0q}t_^@e3Tol7uCz%@oKVSHgo&A#4<3}u)a@_EPOZ?G z$&H;c@&9mkP|&Rbr}Edk)+wdh71a6CHrx2c-DyoJM#grFmwV+|5CVbh38>fI-6Or7 zv#ye3VPcxZ{}n0)pgiKcrh~?w72&1B{617&?i(C;!nk%!-))9VW=TW<5%$Z* z`rcHtRgQQS6|i)m9Pms4F1dAJ{eV|E+I1P=4{4B0*NT5UNE9QMAA z<@%$>ZtK7RI$b-xS2%t4F`7RiN36eleEt)1^mpyzx0p`Wzs(jt`O;rpqxchY^t+1k zH*)mHcl@Q)B(^^;|7Ujee<^4DzU1+*?C8H?eEKxh$NWp;(65<5=t`7MJP;4_1ejPr ziElauDa_>NX}a}PQq|&Su3CHDuDFHNqpQT7m7@e4LO!>XLNDXbgX3%pE#N}k((~rE zn>06bF}EVw#6Ake5%(_Fvk|W=det}7H$LqeA)73(QI41W6{l-!aBSl$&rcZ}!Hd7-wZ|qcqy%II6 z;ZODga+}s1{qm`kyTz_naVuFZHL{spykR;nW#OS#uk0I;Lww112@NyRC2CZd#OWWN z20j*0)~Ud>X;U&$UiPew{H%e2xxN;04NN_ak?FPcpB<{az( zakTnUv%M+lid!{`O#s0^Byc<<*D0_q+jIgy*SLEBXF`+5m4$EsIaVA#`5V3@4us2z zLo{Ut@z`sF_z=9U3fZ=7BqJvz_Z9sWqI4Qroh6)NJuqzp*P?B`wOgS9P|QIr9YFN6 zMd3AU)Ayd|N_2O#y=&{UYh1cJ_AReLLt+O{M((l`RV`Hj378-qM6=Bd69jjgVZ|qM z*q%nbL-{B~KB#Yll#*|`C4`ut)hh&%Mp)JAFQ$aV~#+3Ep_8tH(YO zka%TuMK;V~;Fw`KLs7u`!P1v2TZ}e-uM}utJ3ut;I)yRyIAx-QYH_$nz(XLSp9s)? zQT3*|km7%KUIm-adEZDPNMqnBGz;uat)$?5blj{o_i|vZSS55GjOOR)8 zD|&>1RB!+_Or5=(UPomQ&%E=lgnnqVMTiS$`HvBrX)yyaMA^Yr%^&as@y?vSYxT