From 411ee0a981219ab37fd308b1895c69853f1ee0e5 Mon Sep 17 00:00:00 2001 From: Artem Gavrilov Date: Sun, 11 Feb 2018 23:55:18 +0300 Subject: [PATCH] Ver 1.0 --- .gitignore | 71 ++++ FasmDll/DEMO/ASMDEMO.ASM | 156 ++++++++ FasmDll/DEMO/FASM.ASH | 104 +++++ FasmDll/DEMO/FEDIT.ASH | 69 ++++ FasmDll/FASM.ASH | 104 +++++ FasmDll/FASMDLL.TXT | 49 +++ FasmDll/LICENSE.TXT | 37 ++ FasmDll/SOURCE/DLL/ERRORS.INC | 147 +++++++ FasmDll/SOURCE/DLL/FASM.ASH | 104 +++++ FasmDll/SOURCE/DLL/FASM.ASM | 458 ++++++++++++++++++++++ FasmDll/SOURCE/IDE/FASMW/FEDIT.ASM | 195 ++++++++++ README.md | 3 - Source/Fasm4Delphi.pas | 192 +++++++++ Tests/Test1.asm | 2 + Tests/Tester.dpr | 60 +++ Tests/Tester.dproj | 562 +++++++++++++++++++++++++++ Tests/Tester.res | Bin 0 -> 57140 bytes Tests/TesterMain.pas | 73 ++++ Tests/Win32/Debug/dunitx-results.xml | 20 + 19 files changed, 2403 insertions(+), 3 deletions(-) create mode 100644 .gitignore create mode 100644 FasmDll/DEMO/ASMDEMO.ASM create mode 100644 FasmDll/DEMO/FASM.ASH create mode 100644 FasmDll/DEMO/FEDIT.ASH create mode 100644 FasmDll/FASM.ASH create mode 100644 FasmDll/FASMDLL.TXT create mode 100644 FasmDll/LICENSE.TXT create mode 100644 FasmDll/SOURCE/DLL/ERRORS.INC create mode 100644 FasmDll/SOURCE/DLL/FASM.ASH create mode 100644 FasmDll/SOURCE/DLL/FASM.ASM create mode 100644 FasmDll/SOURCE/IDE/FASMW/FEDIT.ASM create mode 100644 Source/Fasm4Delphi.pas create mode 100644 Tests/Test1.asm create mode 100644 Tests/Tester.dpr create mode 100644 Tests/Tester.dproj create mode 100644 Tests/Tester.res create mode 100644 Tests/TesterMain.pas create mode 100644 Tests/Win32/Debug/dunitx-results.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d41c37b --- /dev/null +++ b/.gitignore @@ -0,0 +1,71 @@ +# Uncomment these types if you want even more clean repository. But be careful. +# Uncomment these types if you want even more clean repository. But be careful. +# It can make harm to an existing project source. Read explanations below. +# +# Resource files are binaries containing manifest, project icon and version info. +# They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files. +#*.res +# +# Type library file (binary). In old Delphi versions it should be stored. +# Since Delphi 2009 it is produced from .ridl file and can safely be ignored. +#*.tlb +# +# Diagram Portfolio file. Used by the diagram editor up to Delphi 7. +# Uncomment this if you are not using diagrams or use newer Delphi version. +#*.ddp +# +# Visual LiveBindings file. Added in Delphi XE2. +# Uncomment this if you are not using LiveBindings Designer. +#*.vlb +# +# Deployment Manager configuration file for your project. Added in Delphi XE2. +# Uncomment this if it is not mobile development and you do not use remote debug feature. +#*.deployproj +# +# C++ object files produced when C/C++ Output file generation is configured. +# Uncomment this if you are not using external objects (zlib library for example). +#*.obj +# + +# Delphi compiler-generated binaries (safe to delete) +*.exe +*.dll +*.bpl +*.bpi +*.dcp +*.so +*.apk +*.drc +*.map +*.dres +*.rsm +*.tds +*.dcu +*.lib +*.a +*.o +*.ocx +Temp/ +*.tmp + +# Delphi autogenerated files (duplicated info) +*.cfg +*.hpp +*Resource.rc + +# Delphi local files (user-specific info) +*.local +*.identcache +*.projdata +*.tvsconfig +*.dsk + +# Delphi history and backups +__history/ +__recovery/ +*.~* + +# Castalia statistics file (since XE7 Castalia is distributed with Delphi) +*.stat + +!FasmDll/ \ No newline at end of file diff --git a/FasmDll/DEMO/ASMDEMO.ASM b/FasmDll/DEMO/ASMDEMO.ASM new file mode 100644 index 0000000..4afd607 --- /dev/null +++ b/FasmDll/DEMO/ASMDEMO.ASM @@ -0,0 +1,156 @@ + +format PE GUI 4.0 +entry start + +include 'win32a.inc' +include 'fasm.ash' +include 'fedit.ash' + +section '.data' data readable writeable + + _fedit db 'FEDIT.DLL',0 + _caption db 'flat assembler %d.%d',0 + _error db 'ERROR',0 + + _source 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 + + buffer rb 10000h + + fasm_memory: + fasm_state FASM_STATE + rb 800000h-($-fasm_memory) ; reserve total 8 MB for assembler + +section '.code' code readable executable + + start: + + invoke LoadLibrary,_fedit + or eax,eax + jz exit + invoke GetModuleHandle,0 + invoke DialogBoxParam,eax,37,HWND_DESKTOP,DialogProc,0 + + 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 fasm_GetVersion + mov edx,eax + and eax,0FFFFh + shr edx,16 + cinvoke wsprintf,buffer,_caption,eax,edx + invoke SendMessage,[hwnddlg],WM_SETTEXT,0,buffer + invoke SetDlgItemText,[hwnddlg],ID_SOURCE,_source + 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_SOURCE,buffer,10000h + + invoke fasm_Assemble,buffer,fasm_memory,800000h,100,NULL + cmp eax,FASM_OK + je show_output + + invoke SetDlgItemText,[hwnddlg],ID_OUTPUT,_error + + jmp processed + + show_output: + + mov esi,[fasm_state.output_data] + mov ecx,[fasm_state.output_length] + mov edi,buffer + xor edx,edx + jecxz output_ok + output_to_hex: + test dl,7 + jz @f + mov al,20h + stosb + @@: + mov al,[esi+edx] + shr al,4 + cmp al,10 + sbb al,69h + das + stosb + mov al,[esi+edx] + and al,0Fh + cmp al,10 + sbb al,69h + das + stosb + inc edx + test dl,7 + jnz @f + mov ax,0D0Ah + stosw + @@: + loop output_to_hex + output_ok: + xor al,al + stosb + + invoke SetDlgItemText,[hwnddlg],ID_OUTPUT,buffer + + jmp processed + wmclose: + invoke EndDialog,[hwnddlg],0 + processed: + mov eax,1 + finish: + pop edi esi ebx + ret +endp + +section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL',\ + user32,'USER32.DLL',\ + fasm,'FASM.DLL' + + include 'api\kernel32.inc' + include 'api\user32.inc' + + import fasm,\ + fasm_GetVersion,'fasm_GetVersion',\ + fasm_Assemble,'fasm_Assemble',\ + fasm_AssembleFile,'fasm_AssembleFile' + +section '.rsrc' resource data readable + + ID_SOURCE = 100 + ID_OUTPUT = 101 + + directory RT_DIALOG,dialogs + + resource dialogs,\ + 37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration + + dialog demonstration,'Memory-to-memory assembly',40,40,180,220,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME + dialogitem 'FEDIT','',ID_SOURCE,10,10,160,120,WS_VISIBLE+WS_BORDER+WS_TABSTOP + dialogitem 'FEDIT','',ID_OUTPUT,10,150,160,60,WS_VISIBLE+WS_BORDER+WS_TABSTOP + dialogitem 'BUTTON','Assemble',IDOK,10,132,160,15,WS_VISIBLE+WS_TABSTOP + enddialog diff --git a/FasmDll/DEMO/FASM.ASH b/FasmDll/DEMO/FASM.ASH new file mode 100644 index 0000000..2ed1ad0 --- /dev/null +++ b/FasmDll/DEMO/FASM.ASH @@ -0,0 +1,104 @@ + +; The following structure resides at the beginning of memory block provided +; to the fasm_Assemble function. The condition field contains the same value +; as the one returned by function. +; When function returns FASM_OK condition, the output_length and +; output_data fields are filled - with pointer to generated output +; (somewhere within the provided memory block) and the count of bytes stored +; there. +; When function returns FASM_ERROR, the error_code is filled with the +; code of specific error that happened and error_line is a pointer to the +; LINE_HEADER structure, providing information about the line that caused +; the error. + +struct FASM_STATE + condition dd ? + union + output_length dd ? + error_code dd ? + ends + union + output_data dd ? + error_line dd ? + ends +ends + +; The following structure has two variants - it either defines the line +; that was loaded directly from source, or the line that was generated by +; macroinstruction. First case has the highest bit of line_number set to 0, +; while the second case has this bit set. +; In the first case, the file_path field contains pointer to the path of +; source file (empty string if it's the source that was provided directly to +; fasm_Assemble function), the line_number is the number of line within +; that file (starting from 1) and the file_offset field contains the offset +; within the file where the line starts. +; In the second case the macro_calling_line field contains the pointer to +; LINE_HEADER structure for the line which called the macroinstruction, and +; the macro_line field contains the pointer to LINE_HEADER structure for the +; line within the definition of macroinstruction, which generated this one. + +struct LINE_HEADER + file_path dd ? + line_number dd ? + union + file_offset dd ? + macro_calling_line dd ? + ends + macro_line dd ? +ends + +; General errors and conditions + +FASM_OK = 0 ; FASM_STATE points to output +FASM_WORKING = 1 +FASM_ERROR = 2 ; FASM_STATE contains error code +FASM_INVALID_PARAMETER = -1 +FASM_OUT_OF_MEMORY = -2 +FASM_STACK_OVERFLOW = -3 +FASM_SOURCE_NOT_FOUND = -4 +FASM_UNEXPECTED_END_OF_SOURCE = -5 +FASM_CANNOT_GENERATE_CODE = -6 +FASM_FORMAT_LIMITATIONS_EXCEDDED = -7 +FASM_WRITE_FAILED = -8 +FASM_INVALID_DEFINITION = -9 + +; Error codes for FASM_ERROR condition + +FASMERR_FILE_NOT_FOUND = -101 +FASMERR_ERROR_READING_FILE = -102 +FASMERR_INVALID_FILE_FORMAT = -103 +FASMERR_INVALID_MACRO_ARGUMENTS = -104 +FASMERR_INCOMPLETE_MACRO = -105 +FASMERR_UNEXPECTED_CHARACTERS = -106 +FASMERR_INVALID_ARGUMENT = -107 +FASMERR_ILLEGAL_INSTRUCTION = -108 +FASMERR_INVALID_OPERAND = -109 +FASMERR_INVALID_OPERAND_SIZE = -110 +FASMERR_OPERAND_SIZE_NOT_SPECIFIED = -111 +FASMERR_OPERAND_SIZES_DO_NOT_MATCH = -112 +FASMERR_INVALID_ADDRESS_SIZE = -113 +FASMERR_ADDRESS_SIZES_DO_NOT_AGREE = -114 +FASMERR_DISALLOWED_COMBINATION_OF_REGISTERS = -115 +FASMERR_LONG_IMMEDIATE_NOT_ENCODABLE = -116 +FASMERR_RELATIVE_JUMP_OUT_OF_RANGE = -117 +FASMERR_INVALID_EXPRESSION = -118 +FASMERR_INVALID_ADDRESS = -119 +FASMERR_INVALID_VALUE = -120 +FASMERR_VALUE_OUT_OF_RANGE = -121 +FASMERR_UNDEFINED_SYMBOL = -122 +FASMERR_INVALID_USE_OF_SYMBOL = -123 +FASMERR_NAME_TOO_LONG = -124 +FASMERR_INVALID_NAME = -125 +FASMERR_RESERVED_WORD_USED_AS_SYMBOL = -126 +FASMERR_SYMBOL_ALREADY_DEFINED = -127 +FASMERR_MISSING_END_QUOTE = -128 +FASMERR_MISSING_END_DIRECTIVE = -129 +FASMERR_UNEXPECTED_INSTRUCTION = -130 +FASMERR_EXTRA_CHARACTERS_ON_LINE = -131 +FASMERR_SECTION_NOT_ALIGNED_ENOUGH = -132 +FASMERR_SETTING_ALREADY_SPECIFIED = -133 +FASMERR_DATA_ALREADY_DEFINED = -134 +FASMERR_TOO_MANY_REPEATS = -135 +FASMERR_SYMBOL_OUT_OF_SCOPE = -136 +FASMERR_USER_ERROR = -140 +FASMERR_ASSERTION_FAILED = -141 diff --git a/FasmDll/DEMO/FEDIT.ASH b/FasmDll/DEMO/FEDIT.ASH new file mode 100644 index 0000000..9d4e330 --- /dev/null +++ b/FasmDll/DEMO/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/FasmDll/FASM.ASH b/FasmDll/FASM.ASH new file mode 100644 index 0000000..2ed1ad0 --- /dev/null +++ b/FasmDll/FASM.ASH @@ -0,0 +1,104 @@ + +; The following structure resides at the beginning of memory block provided +; to the fasm_Assemble function. The condition field contains the same value +; as the one returned by function. +; When function returns FASM_OK condition, the output_length and +; output_data fields are filled - with pointer to generated output +; (somewhere within the provided memory block) and the count of bytes stored +; there. +; When function returns FASM_ERROR, the error_code is filled with the +; code of specific error that happened and error_line is a pointer to the +; LINE_HEADER structure, providing information about the line that caused +; the error. + +struct FASM_STATE + condition dd ? + union + output_length dd ? + error_code dd ? + ends + union + output_data dd ? + error_line dd ? + ends +ends + +; The following structure has two variants - it either defines the line +; that was loaded directly from source, or the line that was generated by +; macroinstruction. First case has the highest bit of line_number set to 0, +; while the second case has this bit set. +; In the first case, the file_path field contains pointer to the path of +; source file (empty string if it's the source that was provided directly to +; fasm_Assemble function), the line_number is the number of line within +; that file (starting from 1) and the file_offset field contains the offset +; within the file where the line starts. +; In the second case the macro_calling_line field contains the pointer to +; LINE_HEADER structure for the line which called the macroinstruction, and +; the macro_line field contains the pointer to LINE_HEADER structure for the +; line within the definition of macroinstruction, which generated this one. + +struct LINE_HEADER + file_path dd ? + line_number dd ? + union + file_offset dd ? + macro_calling_line dd ? + ends + macro_line dd ? +ends + +; General errors and conditions + +FASM_OK = 0 ; FASM_STATE points to output +FASM_WORKING = 1 +FASM_ERROR = 2 ; FASM_STATE contains error code +FASM_INVALID_PARAMETER = -1 +FASM_OUT_OF_MEMORY = -2 +FASM_STACK_OVERFLOW = -3 +FASM_SOURCE_NOT_FOUND = -4 +FASM_UNEXPECTED_END_OF_SOURCE = -5 +FASM_CANNOT_GENERATE_CODE = -6 +FASM_FORMAT_LIMITATIONS_EXCEDDED = -7 +FASM_WRITE_FAILED = -8 +FASM_INVALID_DEFINITION = -9 + +; Error codes for FASM_ERROR condition + +FASMERR_FILE_NOT_FOUND = -101 +FASMERR_ERROR_READING_FILE = -102 +FASMERR_INVALID_FILE_FORMAT = -103 +FASMERR_INVALID_MACRO_ARGUMENTS = -104 +FASMERR_INCOMPLETE_MACRO = -105 +FASMERR_UNEXPECTED_CHARACTERS = -106 +FASMERR_INVALID_ARGUMENT = -107 +FASMERR_ILLEGAL_INSTRUCTION = -108 +FASMERR_INVALID_OPERAND = -109 +FASMERR_INVALID_OPERAND_SIZE = -110 +FASMERR_OPERAND_SIZE_NOT_SPECIFIED = -111 +FASMERR_OPERAND_SIZES_DO_NOT_MATCH = -112 +FASMERR_INVALID_ADDRESS_SIZE = -113 +FASMERR_ADDRESS_SIZES_DO_NOT_AGREE = -114 +FASMERR_DISALLOWED_COMBINATION_OF_REGISTERS = -115 +FASMERR_LONG_IMMEDIATE_NOT_ENCODABLE = -116 +FASMERR_RELATIVE_JUMP_OUT_OF_RANGE = -117 +FASMERR_INVALID_EXPRESSION = -118 +FASMERR_INVALID_ADDRESS = -119 +FASMERR_INVALID_VALUE = -120 +FASMERR_VALUE_OUT_OF_RANGE = -121 +FASMERR_UNDEFINED_SYMBOL = -122 +FASMERR_INVALID_USE_OF_SYMBOL = -123 +FASMERR_NAME_TOO_LONG = -124 +FASMERR_INVALID_NAME = -125 +FASMERR_RESERVED_WORD_USED_AS_SYMBOL = -126 +FASMERR_SYMBOL_ALREADY_DEFINED = -127 +FASMERR_MISSING_END_QUOTE = -128 +FASMERR_MISSING_END_DIRECTIVE = -129 +FASMERR_UNEXPECTED_INSTRUCTION = -130 +FASMERR_EXTRA_CHARACTERS_ON_LINE = -131 +FASMERR_SECTION_NOT_ALIGNED_ENOUGH = -132 +FASMERR_SETTING_ALREADY_SPECIFIED = -133 +FASMERR_DATA_ALREADY_DEFINED = -134 +FASMERR_TOO_MANY_REPEATS = -135 +FASMERR_SYMBOL_OUT_OF_SCOPE = -136 +FASMERR_USER_ERROR = -140 +FASMERR_ASSERTION_FAILED = -141 diff --git a/FasmDll/FASMDLL.TXT b/FasmDll/FASMDLL.TXT new file mode 100644 index 0000000..a1e83d1 --- /dev/null +++ b/FasmDll/FASMDLL.TXT @@ -0,0 +1,49 @@ + +Short description of functions inside FASM.DLL + + +fasm_GetVersion() + + Returns double word containg major version in lower 16 bits, + and minor version in the higher 16 bits. + +fasm_Assemble(lpSource,lpMemory,cbMemorySize,nPassesLimit,hDisplayPipe) + + Assembles the given source, using the provided memory block as a free + storage space (which is also to contain generated output). + + The lpSource should contain a pointer to zero-ended source text. + + The lpMemory should be a pointer to the memory block and cbMemorySize + should contain its size. In the beginning of this memory block the + FASM_STATE structure will reside (as defined in FASM.ASH). The assembler + doesn't allocate any memory beside this block, if it is not enough for + its purposes, the function returns with FASM_OUT_OF_MEMORY state. + + The nPassesLimit should be a value in range from 1 to 65536, defining + the maximum number of passes the assembler can perform in order to + generate the code (the recommended value is 100). If the limit is reached, + the function returns with state FASM_CANNOT_GENERATE_CODE. + + The hDisplayPipe should contain handle of the pipe, to which the output + of DISPLAY directives will be written. If this parameter is NULL, all + the display will get discarded. + + If the assembly is successful, function returns FASM_OK value and fills + the output_data and output_length fields of the FASM_STATE structure + (which resides at the beginning of provided memory block) with pointer + to the generated output and count of bytes stored there. + + If the assembly failed, function returns one of the other general + conditions as defined in FASM.ASH. If the condition returned is FASM_ERROR, + it means that an error caused by a specific place in source occured, + then the error_code and error_line fields of FASM_STATE are filled, + first one with detailed error code as defined in FASM.ASH, and the second + one with pointer to a structure containing data about line that caused + the error. + +fasm_AssembleFile(lpSourceFile,lpMemory,cbMemorySize,nPassesLimit,hDisplayPipe) + + This function performs identically to fasm_Assemble, except that it takes + the lpSourceFile parameter in place of lpSource, and it shall contain the + pointer to zero-ended path to file containing the source to assemble. diff --git a/FasmDll/LICENSE.TXT b/FasmDll/LICENSE.TXT new file mode 100644 index 0000000..2061103 --- /dev/null +++ b/FasmDll/LICENSE.TXT @@ -0,0 +1,37 @@ + +flat assembler version 1.71 +Copyright (c) 1999-2014, 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/FasmDll/SOURCE/DLL/ERRORS.INC b/FasmDll/SOURCE/DLL/ERRORS.INC new file mode 100644 index 0000000..b356d27 --- /dev/null +++ b/FasmDll/SOURCE/DLL/ERRORS.INC @@ -0,0 +1,147 @@ + +; flat assembler core +; Copyright (c) 1999-2017, Tomasz Grysztar. +; All rights reserved. + +invalid_parameter: + mov eax,FASM_INVALID_PARAMETER + jmp general_error +out_of_memory: + mov eax,FASM_OUT_OF_MEMORY + jmp general_error +stack_overflow: + mov eax,FASM_STACK_OVERFLOW + jmp general_error +main_file_not_found: + mov eax,FASM_SOURCE_NOT_FOUND + jmp general_error +unexpected_end_of_file: + mov eax,FASM_UNEXPECTED_END_OF_SOURCE + jmp general_error +code_cannot_be_generated: + mov eax,FASM_CANNOT_GENERATE_CODE + jmp general_error +format_limitations_exceeded: + mov eax,FASM_FORMAT_LIMITATIONS_EXCEDDED + jmp general_error +invalid_definition: + mov eax,FASM_INVALID_DEFINITION + jmp general_error +write_failed: + mov eax,FASM_WRITE_FAILED + jmp general_error + +file_not_found: + mov eax,FASMERR_FILE_NOT_FOUND + jmp assembler_error +error_reading_file: + mov eax,FASMERR_ERROR_READING_FILE + jmp assembler_error +invalid_file_format: + mov eax,FASMERR_INVALID_FILE_FORMAT + jmp assembler_error +invalid_macro_arguments: + mov eax,FASMERR_INVALID_MACRO_ARGUMENTS + jmp assembler_error +incomplete_macro: + mov eax,FASMERR_INCOMPLETE_MACRO + jmp assembler_error +unexpected_characters: + mov eax,FASMERR_UNEXPECTED_CHARACTERS + jmp assembler_error +invalid_argument: + mov eax,FASMERR_INVALID_ARGUMENT + jmp assembler_error +illegal_instruction: + mov eax,FASMERR_ILLEGAL_INSTRUCTION + jmp assembler_error +invalid_operand: + mov eax,FASMERR_INVALID_OPERAND + jmp assembler_error +invalid_operand_size: + mov eax,FASMERR_INVALID_OPERAND_SIZE + jmp assembler_error +operand_size_not_specified: + mov eax,FASMERR_OPERAND_SIZE_NOT_SPECIFIED + jmp assembler_error +operand_sizes_do_not_match: + mov eax,FASMERR_OPERAND_SIZES_DO_NOT_MATCH + jmp assembler_error +invalid_address_size: + mov eax,FASMERR_INVALID_ADDRESS_SIZE + jmp assembler_error +address_sizes_do_not_agree: + mov eax,FASMERR_ADDRESS_SIZES_DO_NOT_AGREE + jmp assembler_error +disallowed_combination_of_registers: + mov eax,FASMERR_DISALLOWED_COMBINATION_OF_REGISTERS + jmp assembler_error +long_immediate_not_encodable: + mov eax,FASMERR_LONG_IMMEDIATE_NOT_ENCODABLE + jmp assembler_error +relative_jump_out_of_range: + mov eax,FASMERR_RELATIVE_JUMP_OUT_OF_RANGE + jmp assembler_error +invalid_expression: + mov eax,FASMERR_INVALID_EXPRESSION + jmp assembler_error +invalid_address: + mov eax,FASMERR_INVALID_ADDRESS + jmp assembler_error +invalid_value: + mov eax,FASMERR_INVALID_VALUE + jmp assembler_error +value_out_of_range: + mov eax,FASMERR_VALUE_OUT_OF_RANGE + jmp assembler_error +undefined_symbol: + mov eax,FASMERR_UNDEFINED_SYMBOL + jmp assembler_error +invalid_use_of_symbol: + mov eax,FASMERR_INVALID_USE_OF_SYMBOL + jmp assembler_error +name_too_long: + mov eax,FASMERR_NAME_TOO_LONG + jmp assembler_error +invalid_name: + mov eax,FASMERR_INVALID_NAME + jmp assembler_error +reserved_word_used_as_symbol: + mov eax,FASMERR_RESERVED_WORD_USED_AS_SYMBOL + jmp assembler_error +symbol_already_defined: + mov eax,FASMERR_SYMBOL_ALREADY_DEFINED + jmp assembler_error +symbol_out_of_scope: + mov eax,FASMERR_SYMBOL_OUT_OF_SCOPE + jmp assembler_error +missing_end_quote: + mov eax,FASMERR_MISSING_END_QUOTE + jmp assembler_error +missing_end_directive: + mov eax,FASMERR_MISSING_END_DIRECTIVE + jmp assembler_error +unexpected_instruction: + mov eax,FASMERR_UNEXPECTED_INSTRUCTION + jmp assembler_error +extra_characters_on_line: + mov eax,FASMERR_EXTRA_CHARACTERS_ON_LINE + jmp assembler_error +section_not_aligned_enough: + mov eax,FASMERR_SECTION_NOT_ALIGNED_ENOUGH + jmp assembler_error +setting_already_specified: + mov eax,FASMERR_SETTING_ALREADY_SPECIFIED + jmp assembler_error +data_already_defined: + mov eax,FASMERR_DATA_ALREADY_DEFINED + jmp assembler_error +too_many_repeats: + mov eax,FASMERR_TOO_MANY_REPEATS + jmp assembler_error +invoked_error: + mov eax,FASMERR_USER_ERROR + jmp assembler_error +assertion_failed: + mov eax,FASMERR_ASSERTION_FAILED + jmp assembler_error \ No newline at end of file diff --git a/FasmDll/SOURCE/DLL/FASM.ASH b/FasmDll/SOURCE/DLL/FASM.ASH new file mode 100644 index 0000000..2ed1ad0 --- /dev/null +++ b/FasmDll/SOURCE/DLL/FASM.ASH @@ -0,0 +1,104 @@ + +; The following structure resides at the beginning of memory block provided +; to the fasm_Assemble function. The condition field contains the same value +; as the one returned by function. +; When function returns FASM_OK condition, the output_length and +; output_data fields are filled - with pointer to generated output +; (somewhere within the provided memory block) and the count of bytes stored +; there. +; When function returns FASM_ERROR, the error_code is filled with the +; code of specific error that happened and error_line is a pointer to the +; LINE_HEADER structure, providing information about the line that caused +; the error. + +struct FASM_STATE + condition dd ? + union + output_length dd ? + error_code dd ? + ends + union + output_data dd ? + error_line dd ? + ends +ends + +; The following structure has two variants - it either defines the line +; that was loaded directly from source, or the line that was generated by +; macroinstruction. First case has the highest bit of line_number set to 0, +; while the second case has this bit set. +; In the first case, the file_path field contains pointer to the path of +; source file (empty string if it's the source that was provided directly to +; fasm_Assemble function), the line_number is the number of line within +; that file (starting from 1) and the file_offset field contains the offset +; within the file where the line starts. +; In the second case the macro_calling_line field contains the pointer to +; LINE_HEADER structure for the line which called the macroinstruction, and +; the macro_line field contains the pointer to LINE_HEADER structure for the +; line within the definition of macroinstruction, which generated this one. + +struct LINE_HEADER + file_path dd ? + line_number dd ? + union + file_offset dd ? + macro_calling_line dd ? + ends + macro_line dd ? +ends + +; General errors and conditions + +FASM_OK = 0 ; FASM_STATE points to output +FASM_WORKING = 1 +FASM_ERROR = 2 ; FASM_STATE contains error code +FASM_INVALID_PARAMETER = -1 +FASM_OUT_OF_MEMORY = -2 +FASM_STACK_OVERFLOW = -3 +FASM_SOURCE_NOT_FOUND = -4 +FASM_UNEXPECTED_END_OF_SOURCE = -5 +FASM_CANNOT_GENERATE_CODE = -6 +FASM_FORMAT_LIMITATIONS_EXCEDDED = -7 +FASM_WRITE_FAILED = -8 +FASM_INVALID_DEFINITION = -9 + +; Error codes for FASM_ERROR condition + +FASMERR_FILE_NOT_FOUND = -101 +FASMERR_ERROR_READING_FILE = -102 +FASMERR_INVALID_FILE_FORMAT = -103 +FASMERR_INVALID_MACRO_ARGUMENTS = -104 +FASMERR_INCOMPLETE_MACRO = -105 +FASMERR_UNEXPECTED_CHARACTERS = -106 +FASMERR_INVALID_ARGUMENT = -107 +FASMERR_ILLEGAL_INSTRUCTION = -108 +FASMERR_INVALID_OPERAND = -109 +FASMERR_INVALID_OPERAND_SIZE = -110 +FASMERR_OPERAND_SIZE_NOT_SPECIFIED = -111 +FASMERR_OPERAND_SIZES_DO_NOT_MATCH = -112 +FASMERR_INVALID_ADDRESS_SIZE = -113 +FASMERR_ADDRESS_SIZES_DO_NOT_AGREE = -114 +FASMERR_DISALLOWED_COMBINATION_OF_REGISTERS = -115 +FASMERR_LONG_IMMEDIATE_NOT_ENCODABLE = -116 +FASMERR_RELATIVE_JUMP_OUT_OF_RANGE = -117 +FASMERR_INVALID_EXPRESSION = -118 +FASMERR_INVALID_ADDRESS = -119 +FASMERR_INVALID_VALUE = -120 +FASMERR_VALUE_OUT_OF_RANGE = -121 +FASMERR_UNDEFINED_SYMBOL = -122 +FASMERR_INVALID_USE_OF_SYMBOL = -123 +FASMERR_NAME_TOO_LONG = -124 +FASMERR_INVALID_NAME = -125 +FASMERR_RESERVED_WORD_USED_AS_SYMBOL = -126 +FASMERR_SYMBOL_ALREADY_DEFINED = -127 +FASMERR_MISSING_END_QUOTE = -128 +FASMERR_MISSING_END_DIRECTIVE = -129 +FASMERR_UNEXPECTED_INSTRUCTION = -130 +FASMERR_EXTRA_CHARACTERS_ON_LINE = -131 +FASMERR_SECTION_NOT_ALIGNED_ENOUGH = -132 +FASMERR_SETTING_ALREADY_SPECIFIED = -133 +FASMERR_DATA_ALREADY_DEFINED = -134 +FASMERR_TOO_MANY_REPEATS = -135 +FASMERR_SYMBOL_OUT_OF_SCOPE = -136 +FASMERR_USER_ERROR = -140 +FASMERR_ASSERTION_FAILED = -141 diff --git a/FasmDll/SOURCE/DLL/FASM.ASM b/FasmDll/SOURCE/DLL/FASM.ASM new file mode 100644 index 0000000..2167126 --- /dev/null +++ b/FasmDll/SOURCE/DLL/FASM.ASM @@ -0,0 +1,458 @@ + +; flat assembler DLL interface for Win32 +; Copyright (c) 1999-2017, Tomasz Grysztar. +; All rights reserved. + +format PE DLL GUI 4.0 +entry DLLEntryPoint + +include 'win32a.inc' +include 'fasm.ash' + +section '.data' data readable writeable + +include '..\variable.inc' + +state dd ? +esp_save dd ? +source dd ? +source_position dd ? +first_write dd ? +first_write_length dd ? +second_write dd ? +second_write_length dd ? +display_pipe dd ? + +systime SYSTEMTIME + +tmp dd ? +buffer rb 1000h + +section '.text' code readable executable + +DLLEntryPoint: + mov eax,TRUE + ret 12 + +fasm_GetVersion: + mov eax,VERSION_MAJOR + VERSION_MINOR shl 16 + ret + +fasm_AssembleFile: + + mov eax,[lpSource] + mov [input_file],eax + mov [output_file],null_byte + + jmp setup_assembler + +fasm_Assemble: + + virtual at esp+4 + lpSource dd ? + lpMemory dd ? + cbMemorySize dd ? + nPassesLimit dd ? + hDisplayPipe dd ? + end virtual + + mov eax,[lpSource] + mov [source],eax + mov [source_position],0 + + mov [input_file],null_byte + mov [output_file],null_byte + + setup_assembler: + + mov eax,[nPassesLimit] + cmp eax,10000h + ja invalid_parameter + or eax,eax + jz invalid_parameter + mov [passes_limit],ax + + mov eax,[lpMemory] + mov ecx,[cbMemorySize] + mov [state],eax + mov [eax+FASM_STATE.condition],FASM_WORKING + sub ecx,sizeof.FASM_STATE + jbe out_of_memory + add eax,sizeof.FASM_STATE + mov [memory_start],eax + mov edx,ecx + shr edx,2 + sub ecx,edx + add eax,ecx + mov [memory_end],eax + mov [additional_memory],eax + add eax,edx + mov [additional_memory_end],eax + + xor eax,eax + mov [initial_definitions],eax + + mov [first_write],eax + mov [second_write],eax + + mov eax,[hDisplayPipe] + mov [display_pipe],eax + + push ebp ebx esi edi + mov eax,esp + mov [esp_save],eax + and eax,not 0FFFh + add eax,1000h-10000h + mov [stack_limit],eax + + call preprocessor + call parser + call assembler + call formatter + + mov ebx,[state] + mov [ebx+FASM_STATE.condition],FASM_OK + + done: + mov eax,[ebx+FASM_STATE.condition] + pop edi esi ebx ebp + ret 20 + + general_error: + mov esp,[esp_save] + mov ebx,[state] + mov [ebx+FASM_STATE.condition],eax + jmp done + + assembler_error: + mov esp,[esp_save] + mov ebx,[state] + mov [ebx+FASM_STATE.error_code],eax + mov eax,[current_line] + mov [ebx+FASM_STATE.error_line],eax + mov eax,FASM_ERROR + jmp general_error + + get_environment_variable: + invoke GetEnvironmentVariable,esi,buffer,1000h + retn + + open: + cmp byte [edx],0 + je open_memory + 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 + open_memory: + xor ebx,ebx + retn + read: + or ebx,ebx + jz read_memory + mov ebp,ecx + invoke ReadFile,ebx,edx,ecx,tmp,0 + or eax,eax + jz file_error + cmp ebp,[tmp] + jne file_error + clc + retn + read_memory: + push esi edi + mov esi,[source] + add esi,[source_position] + mov edi,edx + call move_block + pop edi esi + clc + retn + move_block: + mov al,cl + shr ecx,2 + rep movsd + mov cl,al + and cl,11b + rep movsb + retn + lseek: + or ebx,ebx + jz seek_memory + movzx eax,al + invoke SetFilePointer,ebx,edx,0,eax + cmp eax,-1 + je file_error + retn + seek_memory: + push esi + mov esi,[source] + mov ecx,edx + or al,al + jz seek_forward + add esi,[source_position] + cmp al,2 + je seek_source_end + seek_forward: + sub ecx,1 + jc seek_complete + seek_in_source: + lodsb + or al,al + loopnz seek_in_source + jnz seek_complete + dec esi + seek_complete: + mov eax,esi + sub eax,[source] + mov [source_position],eax + pop esi + retn + seek_source_end: + lodsb + or al,al + jnz seek_source_end + dec esi + sub esi,edx + cmp esi,[source] + jae seek_complete + mov esi,[source] + jmp seek_complete + create: + or ebx,-1 + clc + retn + write: + cmp [first_write],0 + jne make_second_write + mov [first_write],edx + mov [first_write_length],ecx + clc + retn + make_second_write: + cmp [second_write],0 + jne cannot_write + mov [second_write],edx + mov [second_write_length],ecx + clc + retn + cannot_write: + stc + retn + close: + or ebx,ebx + jz file_closed + cmp ebx,-1 + je output_ready + invoke CloseHandle,ebx + file_closed: + retn + output_ready: + mov ebx,[state] + cmp [second_write],0 + jne two_part_output + mov eax,[first_write] + mov [ebx+FASM_STATE.output_data],eax + mov eax,[first_write_length] + mov [ebx+FASM_STATE.output_length],eax + retn + two_part_output: + mov eax,[second_write] + mov [ebx+FASM_STATE.output_data],eax + shuffle_output: + mov ecx,[first_write_length] + cmp ecx,[second_write_length] + ja small_second_part + sub [second_write_length],ecx + mov esi,[first_write] + mov edi,[second_write] + call xchg_block + mov [second_write],edi + jmp shuffle_output + xchg_block: + shr ecx,1 + jnc xchgb_ok + mov al,[edi] + xchg al,[esi] + stosb + inc esi + xchgb_ok: + shr ecx,1 + jnc xchgw_ok + mov ax,[edi] + xchg ax,[esi] + stosw + add esi,2 + xchgw_ok: + jz xchgd_ok + xchgd: + mov eax,[edi] + xchg eax,[esi] + stosd + add esi,4 + loop xchgd + xchgd_ok: + retn + small_second_part: + mov edi,[second_write] + mov esi,edi + add edi,[first_write_length] + cmp edi,[first_write] + jbe move_second_part + mov edi,[first_write] + add edi,[first_write_length] + move_second_part: + push edi + mov ecx,[second_write_length] + lea eax,[edi+ecx] + cmp eax,[tagged_blocks] + ja out_of_memory + call move_block + mov edi,[second_write] + mov esi,[first_write] + mov ecx,[first_write_length] + call move_block + pop esi + mov ecx,[second_write_length] + call move_block + mov ecx,edi + sub ecx,[ebx+FASM_STATE.output_data] + mov [ebx+FASM_STATE.output_length],ecx + retn + + display_block: + mov eax,[display_pipe] + or eax,eax + jz display_ok + invoke WriteFile,eax,esi,ecx,tmp,NULL + display_ok: + retn + + 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 + retn + +dump_symbols: + retn + +include 'errors.inc' + +include '..\preproce.inc' +include '..\parser.inc' +include '..\exprpars.inc' +include '..\exprcalc.inc' +include '..\assemble.inc' +include '..\formats.inc' +include '..\x86_64.inc' +include '..\avx.inc' +include '..\tables.inc' + +include '..\version.inc' + +null_byte db 0 + +section '.idata' import data readable writeable + + library kernel32,'KERNEL32.DLL' + + include 'api\kernel32.inc' + +section '.edata' export data readable + + export 'FASM.DLL',\ + fasm_GetVersion,'fasm_GetVersion',\ + fasm_Assemble,'fasm_Assemble',\ + fasm_AssembleFile,'fasm_AssembleFile' + +section '.reloc' fixups data readable discardable + +section '.rsrc' resource data readable + + directory RT_VERSION,versions + + resource versions,\ + 1,LANG_NEUTRAL,version + + versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,\ + 'FileDescription','flat assembler',\ + 'LegalCopyright',<'Copyright ',0A9h,' 2001-2017 Tomasz Grysztar.'>,\ + 'FileVersion',VERSION_STRING,\ + 'ProductVersion',VERSION_STRING,\ + 'OriginalFilename','FASM.DLL' diff --git a/FasmDll/SOURCE/IDE/FASMW/FEDIT.ASM b/FasmDll/SOURCE/IDE/FASMW/FEDIT.ASM new file mode 100644 index 0000000..fa57415 --- /dev/null +++ b/FasmDll/SOURCE/IDE/FASMW/FEDIT.ASM @@ -0,0 +1,195 @@ + +; flat editor DLL interface for Win32 +; Copyright (c) 2001-2014, Tomasz Grysztar. +; All rights reserved. + +format PE DLL GUI 4.0 +entry DLLEntryPoint + +include 'win32a.inc' + +include 'fedit.ash' + +section '.data' data readable writeable + + _fedit_class db 'FEDIT',0 + + _user_library db 'USER32.DLL',0 + _setgestureconfig_api db 'SetGestureConfig',0 + _getgestureinfo_api db 'GetGestureInfo',0 + _closegestureinfohandle_api db 'CloseGestureInfoHandle',0 + + align 4 + + SetGestureConfig dd 0 + GetGestureInfo dd 0 + CloseGestureInfoHandle dd 0 + + wheel_scroll_lines dd 3 + + fedit_font dd ? + + char rb 4 + kbstate rb 100h + line_colors rb 100h + line_buffer rb 100h + text_buffer rb 100h + upper_case_table rb 100h + + wc WNDCLASS + ps PAINTSTRUCT + tm TEXTMETRIC + sc SCROLLINFO + rect RECT + +section '.text' code readable executable + +proc DLLEntryPoint uses ebx esi edi,hinstDLL,fdwReason,lpvReserved + cmp [fdwReason],DLL_PROCESS_ATTACH + jne .done + 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 LoadCursor,0,IDC_IBEAM + mov [wc.hCursor],eax + mov [wc.style],CS_GLOBALCLASS+CS_DBLCLKS + mov [wc.lpfnWndProc],FlatEditor + mov eax,[hinstDLL] + 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 .failed + 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 .failed + mov [fedit_font],eax + push ebx esi edi + mov edi,upper_case_table + xor ebx,ebx + mov esi,100h + .make_upper_case_table: + invoke CharUpper,ebx + stosb + inc bl + dec esi + jnz .make_upper_case_table + pop edi esi ebx + .done: + mov eax,TRUE + ret + .failed: + mov eax,FALSE + ret +endp + +include 'fedit.inc' + +section '.idata' import data readable writeable + + library kernel,'KERNEL32.DLL',\ + user,'USER32.DLL',\ + gdi,'GDI32.DLL' + + import kernel,\ + GetModuleHandle,'GetModuleHandleA',\ + GetProcAddress,'GetProcAddress',\ + GlobalAlloc,'GlobalAlloc',\ + GlobalReAlloc,'GlobalReAlloc',\ + GlobalLock,'GlobalLock',\ + GlobalUnlock,'GlobalUnlock',\ + GlobalFree,'GlobalFree',\ + VirtualAlloc,'VirtualAlloc',\ + VirtualFree,'VirtualFree',\ + ExitProcess,'ExitProcess' + + import user,\ + RegisterClass,'RegisterClassA',\ + CreateCaret,'CreateCaret',\ + ShowCaret,'ShowCaret',\ + HideCaret,'HideCaret',\ + SetCaretPos,'SetCaretPos',\ + DestroyCaret,'DestroyCaret',\ + BeginPaint,'BeginPaint',\ + EndPaint,'EndPaint',\ + GetDC,'GetDC',\ + GetUpdateRect,'GetUpdateRect',\ + ReleaseDC,'ReleaseDC',\ + GetCursorPos,'GetCursorPos',\ + ClientToScreen,'ClientToScreen',\ + TrackPopupMenu,'TrackPopupMenu',\ + DrawText,'DrawTextA',\ + FillRect,'FillRect',\ + InvalidateRect,'InvalidateRect',\ + GetKeyboardState,'GetKeyboardState',\ + ToAscii,'ToAscii',\ + GetScrollInfo,'GetScrollInfo',\ + SetScrollInfo,'SetScrollInfo',\ + SetCapture,'SetCapture',\ + ReleaseCapture,'ReleaseCapture',\ + OpenClipboard,'OpenClipboard',\ + CloseClipboard,'CloseClipboard',\ + EmptyClipboard,'EmptyClipboard',\ + GetClipboardData,'GetClipboardData',\ + SetClipboardData,'SetClipboardData',\ + LoadCursor,'LoadCursorA',\ + IsClipboardFormatAvailable,'IsClipboardFormatAvailable',\ + CharUpper,'CharUpperA',\ + GetWindowLong,'GetWindowLongA',\ + SetWindowLong,'SetWindowLongA',\ + DefWindowProc,'DefWindowProcA',\ + GetClientRect,'GetClientRect',\ + UpdateWindow,'UpdateWindow',\ + SetFocus,'SetFocus',\ + GetSysColor,'GetSysColor',\ + MessageBox,'MessageBoxA',\ + SendMessage,'SendMessageA',\ + PostMessage,'PostMessageA' + + import gdi,\ + SetBkColor,'SetBkColor',\ + SetTextColor,'SetTextColor',\ + CreateSolidBrush,'CreateSolidBrush',\ + CreateFont,'CreateFontA',\ + GetTextMetrics,'GetTextMetricsA',\ + GetTextExtentPoint32,'GetTextExtentPoint32A',\ + DeleteDC,'DeleteDC',\ + SelectObject,'SelectObject',\ + DeleteObject,'DeleteObject' + +section '.reloc' fixups data readable discardable + +section '.rsrc' resource data readable + + directory RT_VERSION,versions + + resource versions,\ + 1,LANG_NEUTRAL,version + + versioninfo version,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,LANG_ENGLISH+SUBLANG_DEFAULT,0,\ + 'FileDescription','flat editor',\ + 'LegalCopyright',<'Copyright ',0A9h,' 1999-2014 Tomasz Grysztar.'>,\ + 'FileVersion',FEDIT_VERSION_STRING,\ + 'ProductVersion',FEDIT_VERSION_STRING,\ + 'OriginalFilename','FEDIT.DLL' diff --git a/README.md b/README.md index 8406790..e69de29 100644 --- a/README.md +++ b/README.md @@ -1,3 +0,0 @@ -# FASM4Delphi - -Заголовки FASMDll для Delphi/Free Pascal. \ No newline at end of file diff --git a/Source/Fasm4Delphi.pas b/Source/Fasm4Delphi.pas new file mode 100644 index 0000000..b9bef81 --- /dev/null +++ b/Source/Fasm4Delphi.pas @@ -0,0 +1,192 @@ +unit Fasm4Delphi platform; + +{Delphi Translation&Tests:Artyom Gavrilov,Vlad Untkin. + +From FASMDLL.TXT: + +Short description of functions inside FASM.DLL + + +fasm_GetVersion() + + Returns double word containg major version in lower 16 bits, + and minor version in the higher 16 bits. + +fasm_Assemble(lpSource,lpMemory,cbMemorySize,nPassesLimit,hDisplayPipe) + + Assembles the given source, using the provided memory block as a free + storage space (which is also to contain generated output). + + The lpSource should contain a pointer to zero-ended source text. + + The lpMemory should be a pointer to the memory block and cbMemorySize + should contain its size. In the beginning of this memory block the + FASM_STATE structure will reside (as defined in FASM.ASH). The assembler + doesn't allocate any memory beside this block, if it is not enough for + its purposes, the function returns with FASM_OUT_OF_MEMORY state. + + The nPassesLimit should be a value in range from 1 to 65536, defining + the maximum number of passes the assembler can perform in order to + generate the code (the recommended value is 100). If the limit is reached, + the function returns with state FASM_CANNOT_GENERATE_CODE. + + The hDisplayPipe should contain handle of the pipe, to which the output + of DISPLAY directives will be written. If this parameter is NULL, all + the display will get discarded. + + If the assembly is successful, function returns FASM_OK value and fills + the output_data and output_length fields of the FASM_STATE structure + (which resides at the beginning of provided memory block) with pointer + to the generated output and count of bytes stored there. + + If the assembly failed, function returns one of the other general + conditions as defined in FASM.ASH. If the condition returned is FASM_ERROR, + it means that an error caused by a specific place in source occured, + then the error_code and error_line fields of FASM_STATE are filled, + first one with detailed error code as defined in FASM.ASH, and the second + one with pointer to a structure containing data about line that caused + the error. + +fasm_AssembleFile(lpSourceFile,lpMemory,cbMemorySize,nPassesLimit,hDisplayPipe) + + This function performs identically to fasm_Assemble, except that it takes + the lpSourceFile parameter in place of lpSource, and it shall contain the + pointer to zero-ended path to file containing the source to assemble. +} + +interface + +uses + Windows; + +//{$Define FasmStaticLink} + +type + TFasmVersion=packed record + V1,V2:word; + end; + + TLINE_HEADER=record + file_path:PAnsiChar; + line_number:cardinal; + file_offset:cardinal; + macro_calling_line:^TLINE_HEADER; + //macro_line:^TLINE_HEADER; + end; + PLINE_HEADER=^TLINE_HEADER; + + TFASM_STATE=record + condition:Int32; + error_code:Int32; + error_line:PLINE_HEADER; + //output_data:pointer; + //output_length:cardinal; + end; + PFASM_STATE=^TFASM_STATE; +//{$EXTERNALSYM TFASM_STATE} + +const + FASMDLLName='FASM.DLL'; + + // General errors and conditions + + FASM_OK =0; //FASM_STATE points to output + FASM_WORKING =1; + FASM_ERROR =2; //FASM_STATE contains error code + FASM_INVALID_PARAMETER =-1; + FASM_OUT_OF_MEMORY =-2; + FASM_STACK_OVERFLOW =-3; + FASM_SOURCE_NOT_FOUND =-4; + FASM_UNEXPECTED_END_OF_SOURCE =-5; + FASM_CANNOT_GENERATE_CODE =-6; + FASM_FORMAT_LIMITATIONS_EXCEDDED =-7; + FASM_WRITE_FAILED =-8; + FASM_INVALID_DEFINITION =-9; + + //Error codes for FASM_ERROR condition + + FASMERR_FILE_NOT_FOUND =-101; + FASMERR_ERROR_READING_FILE =-102; + FASMERR_INVALID_FILE_FORMAT =-103; + FASMERR_INVALID_MACRO_ARGUMENTS =-104; + FASMERR_INCOMPLETE_MACRO =-105; + FASMERR_UNEXPECTED_CHARACTERS =-106; + FASMERR_INVALID_ARGUMENT =-107; + FASMERR_ILLEGAL_INSTRUCTION =-108; + FASMERR_INVALID_OPERAND =-109; + FASMERR_INVALID_OPERAND_SIZE =-110; + FASMERR_OPERAND_SIZE_NOT_SPECIFIED =-111; + FASMERR_OPERAND_SIZES_DO_NOT_MATCH =-112; + FASMERR_INVALID_ADDRESS_SIZE =-113; + FASMERR_ADDRESS_SIZES_DO_NOT_AGREE =-114; + FASMERR_DISALLOWED_COMBINATION_OF_REGISTERS =-115; + FASMERR_LONG_IMMEDIATE_NOT_ENCODABLE =-116; + FASMERR_RELATIVE_JUMP_OUT_OF_RANGE =-117; + FASMERR_INVALID_EXPRESSION =-118; + FASMERR_INVALID_ADDRESS =-119; + FASMERR_INVALID_VALUE =-120; + FASMERR_VALUE_OUT_OF_RANGE =-121; + FASMERR_UNDEFINED_SYMBOL =-122; + FASMERR_INVALID_USE_OF_SYMBOL =-123; + FASMERR_NAME_TOO_LONG =-124; + FASMERR_INVALID_NAME =-125; + FASMERR_RESERVED_WORD_USED_AS_SYMBOL =-126; + FASMERR_SYMBOL_ALREADY_DEFINED =-127; + FASMERR_MISSING_END_QUOTE =-128; + FASMERR_MISSING_END_DIRECTIVE =-129; + FASMERR_UNEXPECTED_INSTRUCTION =-130; + FASMERR_EXTRA_CHARACTERS_ON_LINE =-131; + FASMERR_SECTION_NOT_ALIGNED_ENOUGH =-132; + FASMERR_SETTING_ALREADY_SPECIFIED =-133; + FASMERR_DATA_ALREADY_DEFINED =-134; + FASMERR_TOO_MANY_REPEATS =-135; + FASMERR_SYMBOL_OUT_OF_SCOPE =-136; + FASMERR_USER_ERROR =-140; + FASMERR_ASSERTION_FAILED =-141; + +{$IFDEF FasmStaticLink} +function fasm_GetVersion:TFasmVersion;stdcall;external FASMDLLName; +function fasm_Assemble(lpSource:PAnsiChar;lpMemory:pointer;cbMemorySize:cardinal; + nPassesLimit:word=100;hDisplayPipe:DWord=0):Int32;stdcall;external FASMDLLName; +function fasm_AssembleFile(lpSourceFile:PAnsiChar;lpMemory:pointer;cbMemorySize:cardinal; + nPassesLimit:word=100;hDisplayPipe:DWord=0):Int32;stdcall;external FASMDLLName; +{$ELSE} +var + fasm_GetVersion:function:TFasmVersion;stdcall; + fasm_Assemble:function(lpSource:PAnsiChar;lpMemory:pointer;cbMemorySize:cardinal;nPassesLimit:word=100;hDisplayPipe:DWord=0):Int32;stdcall; + fasm_AssembleFile:function(lpSourceFile:PAnsiChar;lpMemory:pointer;cbMemorySize:cardinal;nPassesLimit:word=100;hDisplayPipe:DWord=0):Int32;stdcall; +{$ENDIF} + +{$IFNDEF FasmStaticLink} +procedure LoadFASM(Name:string); +procedure FreeFASM; +{$ENDIF} + +implementation + +{$IFNDEF FasmStaticLink} +var + &Library:THandle=0; + +procedure LoadFASM(Name:string); +begin +if &Library<>0 then + FreeFasm; +&Library:=LoadLibrary(PWideChar(Name)); +fasm_GetVersion:=GetProcAddress(&Library,'fasm_GetVersion'); +fasm_Assemble:=GetProcAddress(&Library,'fasm_Assemble'); +fasm_AssembleFile:=GetProcAddress(&Library,'fasm_AssembleFile'); +end; + +procedure FreeFASM; +begin +if &Library=0 then + exit; +fasm_GetVersion:=nil; +fasm_Assemble:=nil; +fasm_AssembleFile:=nil; +&Library:=0; +end; +{$ENDIF} + +end. diff --git a/Tests/Test1.asm b/Tests/Test1.asm new file mode 100644 index 0000000..da321fc --- /dev/null +++ b/Tests/Test1.asm @@ -0,0 +1,2 @@ +a db 0 +cmp [a],0 \ No newline at end of file diff --git a/Tests/Tester.dpr b/Tests/Tester.dpr new file mode 100644 index 0000000..fac2b67 --- /dev/null +++ b/Tests/Tester.dpr @@ -0,0 +1,60 @@ +program Tester; + +{$IFNDEF TESTINSIGHT} +{$APPTYPE CONSOLE} +{$ENDIF}{$STRONGLINKTYPES ON} +uses + System.SysUtils, + {$IFDEF TESTINSIGHT} + TestInsight.DUnitX, + {$ENDIF } + DUnitX.Loggers.Console, + DUnitX.Loggers.Xml.NUnit, + DUnitX.TestFramework, + TesterMain in 'TesterMain.pas', + Fasm4Delphi in '..\Source\Fasm4Delphi.pas'; + +var + runner : ITestRunner; + results : IRunResults; + logger : ITestLogger; + nunitLogger : ITestLogger; +begin +{$IFDEF TESTINSIGHT} + TestInsight.DUnitX.RunRegisteredTests; + exit; +{$ENDIF} + try + //Check command line options, will exit if invalid + TDUnitX.CheckCommandLine; + //Create the test runner + runner := TDUnitX.CreateRunner; + //Tell the runner to use RTTI to find Fixtures + runner.UseRTTI := True; + //tell the runner how we will log things + //Log to the console window + logger := TDUnitXConsoleLogger.Create(true); + runner.AddLogger(logger); + //Generate an NUnit compatible XML File + nunitLogger := TDUnitXXMLNUnitFileLogger.Create(TDUnitX.Options.XMLOutputFile); + runner.AddLogger(nunitLogger); + runner.FailsOnNoAsserts := False; //When true, Assertions must be made during tests; + + //Run tests + results := runner.Execute; + if not results.AllPassed then + System.ExitCode := EXIT_ERRORS; + + {$IFNDEF CI} + //We don't want this happening when running under CI. + if TDUnitX.Options.ExitBehavior = TDUnitXExitBehavior.Pause then + begin + System.Write('Done.. press key to quit.'); + System.Readln; + end; + {$ENDIF} + except + on E: Exception do + System.Writeln(E.ClassName, ': ', E.Message); + end; +end. diff --git a/Tests/Tester.dproj b/Tests/Tester.dproj new file mode 100644 index 0000000..31127ce --- /dev/null +++ b/Tests/Tester.dproj @@ -0,0 +1,562 @@ + + + {4DB29771-5426-49E7-B0D8-B77F95D4EDCE} + 18.2 + None + Tester.dpr + True + Debug + Win32 + 1 + Console + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + .\$(Platform)\$(Config) + .\$(Platform)\$(Config) + false + false + false + false + false + RESTComponents;emsclientfiredac;FireDACIBDriver;emsclient;FireDACCommon;RESTBackendComponents;soapserver;CloudService;FireDACCommonDriver;inet;FireDAC;FireDACSqliteDriver;soaprtl;soapmidas;$(DCC_UsePackage) + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + true + $(BDS)\bin\delphi_PROJECTICON.ico + $(BDS)\bin\delphi_PROJECTICNS.icns + $(DUnitX);$(DCC_UnitSearchPath) + Tester + + + DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage) + android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar + + + DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage) + + + DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage) + + + DBXSqliteDriver;DBXInterBaseDriver;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;ibmonitor;FMXTee;DbxCommonDriver;ibxpress;xmlrtl;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage) + + + DataSnapServerMidas;FireDACADSDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;inetdb;emsedge;IndyCore;dsnap;DataSnapCommon;DataSnapConnectors;bindengine;FireDACOracleDriver;FireDACMySQLDriver;FireDACCommonODBC;DataSnapClient;IndySystem;FireDACDb2Driver;FireDACInfxDriver;emshosting;FireDACPgDriver;FireDACASADriver;FireDACTDataDriver;DbxCommonDriver;DataSnapServer;xmlrtl;DataSnapNativeClient;rtl;DbxClientDriver;CustomIPTransport;bindcomp;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;dbrtl;FireDACMongoDBDriver;IndyProtocols;$(DCC_UsePackage) + + + DBXSqliteDriver;DataSnapServerMidas;DBXInterBaseDriver;DataSnapFireDAC;tethering;FireDACMSSQLDriver;bindcompfmx;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;fmx;fmxdae;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;bindcomp;DBXInformixDriver;IndyIPClient;dbxcds;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage) + + + DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;DataSnapFireDAC;svnui;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;Intraweb;DBXOracleDriver;inetdb;RaizeComponentsVcl;FmxTeeUI;emsedge;RaizeComponentsVclDb;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;CodeSiteExpressPkg;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage) + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + Debug + CompanyName=;FileDescription=$(MSBuildProjectName);FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProgramID=com.embarcadero.$(MSBuildProjectName);ProductName=$(MSBuildProjectName);ProductVersion=1.0.0.0;Comments= + 1033 + + + DBXSqliteDriver;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;DataSnapFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;Intraweb;DBXOracleDriver;inetdb;RaizeComponentsVcl;FmxTeeUI;emsedge;RaizeComponentsVclDb;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;DataSnapConnectors;VCLRESTComponents;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;DataSnapClient;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;emshosting;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage) + + + DEBUG;$(DCC_Define) + true + false + true + true + true + + + false + + + false + RELEASE;$(DCC_Define) + 0 + 0 + + + + MainSource + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + + + + Delphi.Personality.12 + Console + + + + Tester.dpr + + + + + + true + + + + + true + + + + + true + + + + + true + + + + + Tester.exe + true + + + + + 1 + + + Contents\MacOS + 0 + + + + + classes + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + library\lib\armeabi + 1 + + + + + library\lib\mips + 1 + + + + + library\lib\armeabi-v7a + 1 + + + + + res\drawable + 1 + + + + + res\values + 1 + + + + + res\drawable + 1 + + + + + res\drawable-xxhdpi + 1 + + + + + res\drawable-ldpi + 1 + + + + + res\drawable-mdpi + 1 + + + + + res\drawable-hdpi + 1 + + + + + res\drawable-xhdpi + 1 + + + + + res\drawable-small + 1 + + + + + res\drawable-normal + 1 + + + + + res\drawable-large + 1 + + + + + res\drawable-xlarge + 1 + + + + + 1 + + + 1 + + + 0 + + + + + 1 + .framework + + + 0 + + + + + 1 + .dylib + + + 0 + .dll;.bpl + + + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 1 + .dylib + + + 0 + .bpl + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + 1 + + + 1 + + + + + 1 + + + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + ..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF + 1 + + + + + + + + 1 + + + 1 + + + 1 + + + + + + + Contents\Resources + 1 + + + + + library\lib\armeabi-v7a + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + 0 + + + + + 1 + + + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + Assets + 1 + + + Assets + 1 + + + + + + + + + + + + + False + False + False + False + False + False + True + False + + + 12 + + + + + diff --git a/Tests/Tester.res b/Tests/Tester.res new file mode 100644 index 0000000000000000000000000000000000000000..6876088a6648ed90b09c480197508e4404c57dbc GIT binary patch literal 57140 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 I2>8kW0h0=QvH$=8 literal 0 HcmV?d00001 diff --git a/Tests/TesterMain.pas b/Tests/TesterMain.pas new file mode 100644 index 0000000..30283a8 --- /dev/null +++ b/Tests/TesterMain.pas @@ -0,0 +1,73 @@ +unit TesterMain; + +interface + +uses + DUnitX.TestFramework,Fasm4Delphi,SysUtils; + +type + [TestFixture] + TMyTestObject = class(TObject) + public + [Setup] + procedure Setup; + [TearDown] + procedure TearDown; + [Test] + procedure Test1; + [Test] + procedure Test2; + [Test] + procedure Test3; + [Test] + procedure Test4; + end; + +const + CompliterMemSize=$10000; + +var + CompliterMem:PFASM_STATE; + +implementation + +procedure TMyTestObject.Setup; +begin +end; + +procedure TMyTestObject.TearDown; +begin +end; + +procedure TMyTestObject.Test1; +begin +if fasm_AssembleFile('..\..\Test1.ASM',CompliterMem,CompliterMemSize)<>FASM_OK then + raise Exception.Create('Condition: '+CompliterMem^.condition.ToString+sLineBreak+ + 'Error Code: '+CompliterMem^.error_code.ToString+sLineBreak); +end; + +procedure TMyTestObject.Test2; +begin +if fasm_Assemble('add eax,0',CompliterMem,CompliterMemSize)<>FASM_OK then + raise Exception.Create('Condition: '+CompliterMem^.condition.ToString+sLineBreak+ + 'Error Code: '+CompliterMem^.error_code.ToString+sLineBreak); +end; + +procedure TMyTestObject.Test3; +begin +if fasm_AssembleFile('..\..\..\FasmDll\FASM.ASH',CompliterMem,CompliterMemSize)=FASM_OK then + raise Exception.Create('FASM is compiling something that it is can not compile at all.'); +end; + +procedure TMyTestObject.Test4; +begin +if fasm_Assemble('call -100',CompliterMem,CompliterMemSize)<>FASM_OK then + raise Exception.Create('Condition: '+CompliterMem^.condition.ToString+sLineBreak+ + 'Error Code: '+CompliterMem^.error_code.ToString+sLineBreak); +end; + +initialization + TDUnitX.RegisterTestFixture(TMyTestObject); + LoadFASM('..\..\..\FasmDll\FASM.DLL'); + GetMem(CompliterMem,CompliterMemSize); +end. diff --git a/Tests/Win32/Debug/dunitx-results.xml b/Tests/Win32/Debug/dunitx-results.xml new file mode 100644 index 0000000..97e9d13 --- /dev/null +++ b/Tests/Win32/Debug/dunitx-results.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + +