Fresh IDE . Check-in Differences
Not logged in

This repository is a mirror!

The original is located on: https://fresh.flatassembler.net/fossil/repo/fresh
If you want to follow the project, please update your remote-url

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Difference From 3a1bbdebe7454bed To 7b6a54baaed72911

2012-10-28
04:39
Fixed small bug in project manager which caused some alias values to disappear from the quick change menu. Updated FASM compiler to the version 1.71.05 Some preparation for v2.1.0 release. check-in: 15624c3901 user: johnfound tags: trunk
2012-09-27
18:28
Updated version of FASM v1.71.3 added. check-in: 3a1bbdebe7 user: johnfound tags: trunk
2012-09-25
16:47
Fixed the problem with compiled executable permissions in Linux. Also, when there is no terminal application configured, Fresh runs the compiled file directly. check-in: cb3298e164 user: johnfound tags: trunk
2011-02-19
22:21
First commit for FreshIDE project. check-in: df8e975d33 user: JohnFound tags: trunk
17:38
initial empty check-in check-in: 7b6a54baae user: JohnFound tags: trunk

Deleted IDE/components/Button.ico.

cannot compute difference between binary files

Deleted IDE/components/Button.vcl.

cannot compute difference between binary files

Deleted IDE/components/ButtonEdit.vcl.

cannot compute difference between binary files

Deleted IDE/components/COMCTL32.vcl.

cannot compute difference between binary files

Deleted IDE/components/Checkbox.ico.

cannot compute difference between binary files

Deleted IDE/components/Combobox.ico.

cannot compute difference between binary files

Deleted IDE/components/EDIT.VCL.

cannot compute difference between binary files

Deleted IDE/components/Edit.ico.

cannot compute difference between binary files

Deleted IDE/components/FORM.ICO.

cannot compute difference between binary files

Deleted IDE/components/Form.vcl.

cannot compute difference between binary files

Deleted IDE/components/Groupbox.ico.

cannot compute difference between binary files

Deleted IDE/components/IMAGE.ICO.

cannot compute difference between binary files

Deleted IDE/components/LABEL.ICO.

cannot compute difference between binary files

Deleted IDE/components/LISTBOX.ICO.

cannot compute difference between binary files

Deleted IDE/components/LISTBOX.VCL.

cannot compute difference between binary files

Deleted IDE/components/LISTVIEW.ICO.

cannot compute difference between binary files

Deleted IDE/components/RADIOBTN.ICO.

cannot compute difference between binary files

Deleted IDE/components/SHAPE.ICO.

cannot compute difference between binary files

Deleted IDE/components/SIZEBOX.ICO.

cannot compute difference between binary files

Deleted IDE/components/SLIDER.ICO.

cannot compute difference between binary files

Deleted IDE/components/SOURCE/ADD.BAT.

1
2
copy *.bin ..\*.vcl
del *.bin
<
<




Deleted IDE/components/SOURCE/BUTTON.ASM.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
; This file contains design-time information for Button controls.
;
; One file may contains description of more than one control.
; Look at 'DesignTimeInfo' macro definition.
;
; This file must be compiled with FASM compiler to get binary
; file. It will be compiled as .COM file. This is not executable
; file. Don't start it.

include '..\..\..\source\designtime.inc'
include 'winconst.inc'


DesignTimeInfo                                     \
                                                   \       ; 1. BUTTON CONTROL
        'BUTTON',                                  \
        'Button control',                          \
        'Standard',                                \
        'Button',                                  \
        WS_VISIBLE or BS_PUSHBUTTON or WS_CHILD,   \       ; default style
        0,                                         \       ; default ex style
        64, 25,                                    \
        <                                          \       ; style names
           BS_ICON,      "Specifies that the button displays an icon",   \
           BS_BITMAP,    "Specifies that the button displays a bitmap",   \
           BS_LEFT,      "Places text on the left of the button",   \
           BS_RIGHT,     "Places text on the right of the button",   \
           BS_CENTER,    "Places text in the center (horizontally) of the button",   \
           BS_TOP,       "Places text on the top of the button",   \
           BS_BOTTOM,    "Places text on the bottom of the button",   \
           BS_VCENTER,   "Places text in the center (vertically) of the button",   \
           BS_MULTILINE, "Allows wrapping of the button's text if necesary",   \
           BS_NOTIFY,    "Enables button to send addictional notification messages",   \
           BS_FLAT,      "Creates flat button"    \
        >,                                         \
        NONE,                                      \            ; style Ex names
\
        $00000000,                                 \            ; This is StyleMaskAnd
        WS_CHILD,                                  \            ; This is StyleMaskOr
        $00000000,                                 \            ; This is StyleExMaskAnd
        $00000000,                                 \            ; This is StyleExMaskOr
        $0000000f,                                 \            ; This is SubtypeMask
        <                                          \
          BS_PUSHBUTTON, 'Normal push button',     \
          BS_DEFPUSHBUTTON, 'Default push button'  \
        >,                                         \            ; This is SubtipeRange
        NONE,                                      \            ; Library file NULL, because it's standard component.
        'Button.ico',                              \            ; Image for icon
\
\ ; Checkbox control.
\
        'BUTTON',                                  \
        'Checkbox control',                        \
        'Standard',                                \
        'Checkbox',                                \
        WS_VISIBLE or BS_CHECKBOX or WS_CHILD,     \       ; default style
        $0,                                        \       ; default ex style
        80, 21,                                    \
        <                                          \       ; style names
           BS_LEFTTEXT,  "Places text on the left of the checkbox",   \
           BS_PUSHLIKE,  "Makes checkbox act like the push button",   \
           BS_MULTILINE, "Allows wrapping of the checkbox's text if necesary",   \
           BS_NOTIFY,    "Enables checkbox to send addictional notification messages",   \
           BS_FLAT,      "Creates flat checkbox"    \
        >,                                         \
        NONE,                                      \            ; style Ex names
\
        $00000000,                                 \            ; This is StyleMaskAnd
        WS_CHILD,                                  \            ; This is StyleMaskOr
        $00000000,                                 \            ; This is StyleExMaskAnd
        $00000000,                                 \            ; This is StyleExMaskOr
        $0000000f,                                 \            ; This is SubtypeMask
        <                                          \
          BS_CHECKBOX,     'User controled checkbox',    \
          BS_AUTOCHECKBOX, 'Auto checked checkbox',      \
          BS_3STATE, '3-state checked checkbox',   \
          BS_AUTO3STATE, 'Auto 3-state checkbox'       \
        >,                                         \            ; This is SubtypeRange
        NONE,                                      \            ; Library file NULL, because it's standard component.
        'CheckBox.ico',                            \            ; Image for the icon.
\
\ ; Radiobutton control.
\
        'BUTTON',                                  \
        'Radiobutton control',                     \
        'Standard',                                \
        'Radiobutton',                             \
        WS_VISIBLE or BS_RADIOBUTTON or WS_CHILD,  \       ; default style
        $0,                                        \       ; default ex style
        80, 21,                                    \
        <                                          \       ; style names
           BS_LEFTTEXT, "Places text on the left of the radiobutton",               \
           BS_PUSHLIKE,  "Makes radiobutton act like the push button",   \
           BS_MULTILINE, "Allows wrapping of the radiobutton's text if necesary",   \
           BS_NOTIFY,    "Enables radiobutton to send addictional notification messages",   \
           BS_FLAT, "Crates flat radiobutton"    \
        >,                                         \
        NONE,                                      \            ; style Ex names
\
        $00000000,                                 \            ; This is StyleMaskAnd
        WS_CHILD,                                  \            ; This is StyleMaskOr
        $00000000,                                 \            ; This is StyleExMaskAnd
        $00000000,                                 \            ; This is StyleExMaskOr
        $0000000f,                                 \            ; This is SubtypeMask
        <                                          \
           BS_RADIOBUTTON, 'Standard Radiobutton', \
           BS_AUTORADIOBUTTON, 'Auto Radiobutton'  \
        >,                                         \            ; This is SubtypeRange
        NONE,                                      \            ; Library file NULL, because it's standard component.
        'radiobtn.ico',                            \            ; Image for the icon.
\
\ ; Groupbox control.
\
        'BUTTON',                                  \
        'Group box control',                       \
        'Standard',                                \
        'Group box',                               \
        BS_MULTILINE or WS_VISIBLE or BS_GROUPBOX or WS_CLIPSIBLINGS or WS_CHILD,    \       ; default style
        $00010020,                                 \       ; default ex style
        128, 128,                                  \
        <                                          \       ; style names
           BS_LEFT,      "Places text on the left of the box'es frame",   \
           BS_RIGHT,     "Places text on the right of the box'es frame",   \
           BS_CENTER,    "Places text in the center (horizontally) of the button",   \
           BS_FLAT,      "Creates flat groupbox"    \
        >,                                         \
        NONE,                                      \            ; style Ex names
\
        $00000000,                                 \            ; This is StyleMaskAnd
        WS_CHILD,                                  \            ; This is StyleMaskOr
        $00000000,                                 \            ; This is StyleExMaskAnd
        $00010000,                                 \            ; This is StyleExMaskOr
        $0000000f,                                 \            ; This is SubtypeMask
        <BS_GROUPBOX, 'Regular group box'>,        \  ; This is SubtypeRange
        NONE,                                      \            ; Library file NONE, because it's standard component.
        'GroupBox.ico'                                          ; Image for the icon.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































Deleted IDE/components/SOURCE/ButtonEdit.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
include '%finc%/win32/win32a.inc'
include '..\..\..\source\designtime.inc'
;include 'winconst.inc'
;include '..\..\..\source\AsmEdit\AsmEdit.inc'

DesignTimeInfo                                     \
                                                   \       ; 1. TButtonEdit control
        'TButtonEdit',                             \
        'Edit control with button inside',         \
        'Fresh',                                   \
        'Edit',                                    \
        WS_VISIBLE or WS_CHILD or ES_LEFT or ES_AUTOHSCROLL, \      ; default style
        WS_EX_CLIENTEDGE,                                          \       ; default ex style
        121, 21,                                   \
        <                                          \       ; style names
            ES_LEFT        , "Align left",         \
            ES_CENTER      , "Align center",       \
            ES_RIGHT       , "Align right",        \
            ES_UPPERCASE   , "Converts the text into uppercase characters", \
            ES_LOWERCASE   , "Converts the text into lowercase characters", \
            ES_PASSWORD    , "Displays all characters in the edit control as asterisks", \
            ES_NOHIDESEL   , "Specifies that the selected text is not hidden when the edit control loses the keyboard focus", \
            ES_AUTOHSCROLL , "Automatically scrolls text horizontally", \
            ES_OEMCONVERT  , "Ensures the proper conversion of characters", \
            ES_READONLY    , "Makes the edit control read-only", \
            ES_WANTRETURN  , "Inserts a carriage return when the user presses the ENTER key", \
            ES_NUMBER      , "Restricts input to the edit control to digits only"             \
        >,                                         \
        NONE,                                      \            ; style Ex names
\
        ES_MULTILINE,                              \            ; This is StyleMaskAnd
        WS_CHILD,                                  \            ; This is StyleMaskOr
        $00000000,                                 \            ; This is StyleExMaskAnd
        $00000000,                                 \            ; This is StyleExMaskOr
        $00000000,                                 \            ; This is SubtypeMask
        NONE,                                      \
        NONE,                                      \         ; Library file NULL, because it's standard component.
        'btnedit.ico'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































Deleted IDE/components/SOURCE/COMCTL32.ASM.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
include '%finc%\win32\win32a.inc'
include '..\..\..\source\designtime.inc'


DesignTimeInfo                                                \
                                                              \         ; 1. Control starts here
        'SysTreeView32',                                      \
        'TreeView Control',                                   \
        'Common',                                             \
        'TreeView',                                           \
        WS_VISIBLE or WS_CHILD or WS_BORDER or TVS_HASLINES,  \         ; default style
        WS_EX_CLIENTEDGE,                                     \         ; default ex style
        128, 128,                                             \
        <                                                     \         ; style names
            TVS_HASBUTTONS      ,"Shows a button to the left side of each parent item.", \
            TVS_HASLINES        ,"Enhances the graphic representation of a tree view control's hierarchy by drawing lines that link child items to their parent item.",\
            TVS_LINESATROOT     ,"Draws lines between root and child nodes",             \
            TVS_EDITLABELS      ,"Allows the user to edit the labels of tree view items.",\
            TVS_DISABLEDRAGDROP ,"Disable drag and drop operation.",                     \
            TVS_SHOWSELALWAYS   ,"Causes a selected item to remain selected when the tree view control loses focus.",    \
            TVS_SINGLEEXPAND    ,"Causes a tree view item to be expanded when it becomes selected and to be closed when it becomes unselected.",\
            TVS_CHECKBOXES      ,"Enables check boxes for items in a tree view control.",\
            TVS_DISABLEDRAGDROP ,"Prevents the tree view control from sending TVN_BEGINDRAG notification messages.",\
            TVS_FULLROWSELECT   ,"The entire row of the selected item is highlighted, and clicking anywhere on an item's row will cause it to be selected.",\
            TVS_INFOTIP         ,"The tree view control will send the TVN_GETINFOTIP notification to obtain tooltip information.",\
            TVS_NOHSCROLL       ,"Disables horizontal scrolling in the control.",\
            TVS_NONEVENHEIGHT   ,"The height of the items can be set to an odd height with the TVM_SETITEMHEIGHT message.",\
            TVS_NOSCROLL        ,"Disables both horizontal and vertical scrolling in the control.",\
            TVS_NOTOOLTIPS      ,"The tree view control does not support tooltips.",\
            TVS_RTLREADING      ,"Normal windows display text left-to-right (LTR).",\
            TVS_TRACKSELECT     ,"Enables hot tracking in a tree view control." \
        >,                                                    \
        NONE,                                                 \         ; style Ex names
                                                              \
        $00000000,                                            \         ; This is StyleMaskAnd
        WS_CHILD ,                                            \         ; This is StyleMaskOr
        $00000000,                                            \         ; This is StyleExMaskAnd
        $00000000,                                            \         ; This is StyleExMaskOr
        $0       ,                                            \         ; This is SubtypeMask
        NONE,                                                 \
        NONE,                                                 \         ; Library file NULL, because it's standard component.
        'treeview.ico',                                       \
                                                              \         ; 1. Control starts here
        'SysListView32',                                      \
        'ListView Control',                                   \
        'Common',                                             \
        'ListView',                                           \
        WS_CHILD or LVS_REPORT or LVS_EDITLABELS,             \         ; default style
        WS_EX_CLIENTEDGE,                                     \         ; default ex style
        128, 128,                                             \
        <                                                     \         ; style names
            LVS_SINGLESEL        ,".",\
            LVS_SHOWSELALWAYS    ,".",\
            LVS_SORTASCENDING    ,".",\
            LVS_SORTDESCENDING   ,".",\
            LVS_SHAREIMAGELISTS  ,".",\
            LVS_NOLABELWRAP      ,".",\
            LVS_AUTOARRANGE      ,".",\
            LVS_EDITLABELS       ,".",\
            LVS_OWNERDATA        ,".",\
            LVS_NOSCROLL         ,".",\
            LVS_ALIGNTOP         ,"Align icons on top.",\
            LVS_ALIGNLEFT        ,"Align icons on left.",\
            LVS_OWNERDRAWFIXED   ,".",\
            LVS_NOCOLUMNHEADER   ,".",\
            LVS_NOSORTHEADER     ,"." \
       >,                                                    \
       <    LVS_EX_GRIDLINES        , "." ,\ ; style Ex names
            LVS_EX_SUBITEMIMAGES    , "." ,\
            LVS_EX_CHECKBOXES       , "." ,\
            LVS_EX_TRACKSELECT      , "." ,\
            LVS_EX_HEADERDRAGDROP   , "." ,\
            LVS_EX_FULLROWSELECT    , "." ,\
            LVS_EX_ONECLICKACTIVATE , "." ,\
            LVS_EX_TWOCLICKACTIVATE , "." ,\
            LVS_EX_FLATSB           , "." ,\
            LVS_EX_REGIONAL         , "." ,\
            LVS_EX_INFOTIP          , "." ,\
            LVS_EX_UNDERLINEHOT     , "." ,\
            LVS_EX_UNDERLINECOLD    , "." ,\
            LVS_EX_MULTIWORKAREAS   , "." ,\
            LVS_EX_LABELTIP         , "." ,\
            LVS_EX_BORDERSELECT     , "." \
        >,                                                    \
                                                              \
        $00000000,                                            \         ; This is StyleMaskAnd
        WS_CHILD or WS_VISIBLE,                               \         ; This is StyleMaskOr
        $00000000,                                            \         ; This is StyleExMaskAnd
        $00000000,                                            \         ; This is StyleExMaskOr
        $3       ,                                            \         ; This is SubtypeMask
        <                                                     \
          LVS_ICON             ,"Each item appears as a full-sized icon with a label below it.",\
          LVS_REPORT           ,"Each item appears on its own line with information arranged in columns. The leftmost column is always left justified, and contains the small icon and label.",\
          LVS_SMALLICON        ,"Each item appears as a small icon with the label to the right of it.",\
          LVS_LIST             ,"Each item appears as a small icon with a label to the right of it. Items are arranged in columns and cannot be dragged to any arbitrary location by the user." \
        >,                                                    \         ; This is SubtipeRange
        NONE,                                                 \         ; Library file NULL, because it's standard component.
        'listview.ico',\
                                                              \         ; 1. Control starts here
        'SysMonthCal32',                                      \
        'MonthView Control',                                  \
        'Common',                                             \
        'MonthView',                                          \
        WS_VISIBLE or WS_CHILD or WS_BORDER,                  \         ; default style
        0,                                                    \         ; default ex style
        128, 128,                                             \
        <                                                     \         ; style names
          MCS_MULTISELECT     ,"Allow the user to select a range of days.",\
          MCS_WEEKNUMBERS     ,"Displays week numbers at the left side of each month.",\
          MCS_NOTODAY         ,"The control no longer circles the current day.",\
          MCS_DAYSTATE        ,"The control highlights specific dates by displaying them in bold."\
        >,                                                    \
        NONE,                                                 \         ; style Ex names
                                                              \
        $00000000,                                            \         ; This is StyleMaskAnd
        WS_CHILD or WS_VISIBLE,                                            \         ; This is StyleMaskOr
        $00000000,                                            \         ; This is StyleExMaskAnd
        $00000000,                                            \         ; This is StyleExMaskOr
        $0       ,                                            \         ; This is SubtypeMask
        NONE,                                                 \
        NONE,                                                 \         ; Library file NULL, because it's standard component.
        'monthview.ico',\
                                                              \         ; 1. Control starts here
        'ToolbarWindow32',                                    \
        'Toolbar Control',                                    \
        'Common',                                             \
        'Toolbar',                                            \
        WS_CHILD or TBSTYLE_TOOLTIPS or CCS_ADJUSTABLE,       \         ; default style
        0,                                                    \         ; default ex style
        128, 128,                                             \
        <                                                     \         ; style names
          TBSTYLE_TOOLTIPS,   "The toolbar creates and manages a tooltip control.", \
          TBSTYLE_ALTDRAG,    'Allows the user to change the position of a toolbar button by dragging it while holding down the ALT key.',     \
          TBSTYLE_WRAPABLE,   'Creates a toolbar that can have multiple lines of buttons.'  \
        >,                                                    \
        NONE,                                                 \         ; style Ex names
                                                              \
        $00000000,                                            \         ; This is StyleMaskAnd
        WS_CHILD ,                                            \         ; This is StyleMaskOr
        $00000000,                                            \         ; This is StyleExMaskAnd
        $00000000,                                            \         ; This is StyleExMaskOr
        $0       ,                                            \         ; This is SubtypeMask
        NONE,                                                 \
        NONE,                                                 \         ; Library file NULL, because it's standard component.
        'toolbar.ico',\
                                                              \         ; 1. Control starts here
        'msctls_statusbar32',                                 \
        'Status Bar Control',                                 \
        'Common',                                             \
        'Status',                                             \
        WS_CHILD,                                             \         ; default style
        0,                                                    \         ; default ex style
        128, 128,                                             \
        NONE,                                                 \         ; style names
        NONE,                                                 \         ; style Ex names
                                                              \
        $00000000,                                            \         ; This is StyleMaskAnd
        WS_CHILD ,                                            \         ; This is StyleMaskOr
        $00000000,                                            \         ; This is StyleExMaskAnd
        $00000000,                                            \         ; This is StyleExMaskOr
        $0       ,                                            \         ; This is SubtypeMask
        NONE,                                                 \
        NONE,                                                 \         ; Library file NULL, because it's standard component.
        'statusbar.ico',                                      \
                                                              \         ; 1. Control starts here
        'SysTabControl32',                                    \
        'Tab Control',                                        \
        'Common',                                             \
        'Tab',                                                \
        WS_CHILD,                                             \         ; default style
        0,                                                    \         ; default ex style
        128, 128,                                             \
        <                                                     \         ; style names
           TCS_SCROLLOPPOSITE, ".",                           \
           TCS_RIGHT,          ".",                           \
           TCS_FORCEICONLEFT,  ".",                           \
           TCS_FORCELABELLEFT, ".",                           \
           TCS_HOTTRACK,       ".",                           \
           TCS_VERTICAL,       '.',                           \
           TCS_BUTTONS,        '.',                           \
           TCS_MULTILINE,      '.',                           \
           TCS_FIXEDWIDTH,     '.',                           \
           TCS_RAGGEDRIGHT,    '.',                           \
           TCS_FOCUSONBUTTONDOWN, '.',                        \
           TCS_OWNERDRAWFIXED, '.',                           \
           TCS_TOOLTIPS,       '.',                           \
           TCS_FOCUSNEVER,     '.'                            \
        >,                                                    \
        NONE,                                                 \         ; style Ex names
                                                              \
        $00000000,                                            \         ; This is StyleMaskAnd
        WS_CHILD ,                                            \         ; This is StyleMaskOr
        $00000000,                                            \         ; This is StyleExMaskAnd
        $00000000,                                            \         ; This is StyleExMaskOr
        $0       ,                                            \         ; This is SubtypeMask
        NONE,                                                 \
        NONE,                                                 \         ; Library file NULL, because it's standard component.
        'tabctl.ico',                                         \
                                                              \         ; 1. Control starts here
        'msctls_trackbar32',                                  \
        'Slider Control',                                     \
        'Common',                                             \
        'Slider',                                             \
        WS_CHILD,                                             \         ; default style
        0,                                                    \         ; default ex style
        128, 128,                                             \
        <                                                     \         ; style names
           0    ,"." \
        >,                                                    \
        NONE,                                                 \         ; style Ex names
                                                              \
        $00000000,                                            \         ; This is StyleMaskAnd
        WS_CHILD ,                                            \         ; This is StyleMaskOr
        $00000000,                                            \         ; This is StyleExMaskAnd
        $00000000,                                            \         ; This is StyleExMaskOr
        $1f      ,                                            \         ; This is SubtypeMask
        NONE,                                                 \
        NONE,                                                 \         ; Library file NULL, because it's standard component.
        'slider.ico',                                         \
\
\
        'msctls_progress32',                                  \
        'Progressbar Control',                                \
        'Common',                                             \
        'Progressbar',                                        \
        WS_CHILD,                                             \         ; default style
        0,                                                    \         ; default ex style
        192, 19,                                              \
        <                                                     \         ; style names
           PBS_SMOOTH    ,"PBS_SMOOTH",                       \
           PBS_VERTICAL,  "PBS_VERTICAL"                      \
        >,                                                    \
        NONE,                                                 \         ; style Ex names
                                                              \
        $00000000,                                            \         ; This is StyleMaskAnd
        WS_CHILD ,                                            \         ; This is StyleMaskOr
        $00000000,                                            \         ; This is StyleExMaskAnd
        $00000000,                                            \         ; This is StyleExMaskOr
        $0       ,                                            \         ; This is SubtypeMask
        NONE,                                                 \
        NONE,                                                 \         ; Library file NULL, because it's standard component.
        'progress.ico'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































Deleted IDE/components/SOURCE/EDIT.ASM.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
include '..\..\..\source\designtime.inc'
include 'winconst.inc'


DesignTimeInfo                                     \
                                                   \       ; 1. Edit control
        'EDIT',                                    \
        'Edit control',                            \
        'Standard',                                \
        'Edit',                                    \
        WS_VISIBLE or WS_CHILD or ES_LEFT or ES_AUTOHSCROLL, \      ; default style
        WS_EX_CLIENTEDGE,                                          \       ; default ex style
        121, 21,                                   \
        <                                          \       ; style names
            ES_LEFT        , "Align left", \
            ES_CENTER      , "Align center", \
            ES_RIGHT       , "Align right", \
            ES_UPPERCASE   , "Converts the text into uppercase characters", \
            ES_LOWERCASE   , "Converts the text into lowercase characters", \
            ES_PASSWORD    , "Displays all characters in the edit control as asterisks", \
            ES_NOHIDESEL   , "Specifies that the selected text is not hidden when the edit control loses the keyboard focus", \
            ES_AUTOHSCROLL , "Automatically scrolls text horizontally", \
            ES_OEMCONVERT  , "Ensures the proper conversion of characters", \
            ES_READONLY    , "Makes the edit control read-only", \
            ES_WANTRETURN  , "Inserts a carriage return when the user presses the ENTER key", \
            ES_NUMBER      , "Restricts input to the edit control to digits only" \
        >,                                         \
        NONE,                                      \            ; style Ex names
\
        ES_MULTILINE,                              \            ; This is StyleMaskAnd
        WS_CHILD,                                  \            ; This is StyleMaskOr
        $00000000,                                 \            ; This is StyleExMaskAnd
        $00000000,                                 \            ; This is StyleExMaskOr
        $00000000,                                 \            ; This is SubtypeMask
        NONE,                                      \
        NONE,                                      \         ; Library file NULL, because it's standard component.
        'Edit.ico',                                \         ; Image for icon
        \ ; 2.Textbox control (edit with style es_multiline)
        'EDIT',                                    \
        'Textbox control',                            \
        'Standard',                                \
        'Textbox',                                    \
        WS_VISIBLE or WS_CHILD or ES_LEFT or ES_MULTILINE or ES_AUTOHSCROLL or ES_AUTOVSCROLL, \       ; default style
        WS_EX_CLIENTEDGE,                                          \       ; default ex style
        128, 128,                                  \
        <                                          \       ; style names
            ES_LEFT        , "Align left", \
            ES_CENTER      , "Align center", \
            ES_RIGHT       , "Align right", \
            ES_UPPERCASE   , "Converts the text into uppercase characters", \
            ES_LOWERCASE   , "Converts the text into lowercase characters", \
            ES_PASSWORD    , "Displays all characters in the textbox control as asterisks", \
            ES_NOHIDESEL   , "Specifies that the selected text is not hidden when the textbox control loses the keyboard focus", \
            ES_AUTOHSCROLL , "Automatically scrolls text horizontally", \
            ES_AUTOVSCROLL , "Automatically scroll text vertically", \
            ES_OEMCONVERT  , "Ensures the proper conversion of characters", \
            ES_READONLY    , "Makes the textbox control read-only", \
            ES_WANTRETURN  , "Inserts a carriage return when the user presses the ENTER key", \
            ES_NUMBER      , "Restricts input to the textbox control to digits only" \
        >,                                         \
        NONE,                                      \            ; style Ex names
\
        $00000000,                                 \            ; This is StyleMaskAnd
        WS_CHILD or ES_MULTILINE,                  \            ; This is StyleMaskOr
        $00000000,                                 \            ; This is StyleExMaskAnd
        $00000000,                                 \            ; This is StyleExMaskOr
        $00000000,                                 \            ; This is SubtypeMask
        NONE,                                      \
        NONE,                                      \         ; Library file NULL, because it's standard component.
        'Textbox.ico'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































Deleted IDE/components/SOURCE/FORM.ASM.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
; This file contains design-time information for TForm control.
;
; This file must be compiled with FASM compiler to get binary
; file. It will be compiled as .COM file. This is not executable
; file. Don't start it.

include '..\..\..\source\designtime.inc'
include '..\win32\win32a.inc'


DesignTimeInfo					   \
						   \	   ; 1. TForm control
	'TForm',				   \
	'Form control', 			   \
	'Standard',				   \
	'Form', 				   \
	WS_VISIBLE or WS_BORDER or WS_CHILD,	   \	   ; default style
	$00010000,				   \	   ; default ex style
	128, 64,				   \
	NONE,					   \	   ; style names
	NONE,					   \	   ; style Ex names
\
	$00000000,				   \		; This is StyleMaskAnd
	$00000000,				   \		; This is StyleMaskOr
	$00000000,				   \		; This is StyleExMaskAnd
	$00010000,				   \		; This is StyleExMaskOr
	$00000000,				   \		; This is SubtypeMask
	NONE,					   \		; This is SubtipeRange
	NONE,					   \		; Library file NULL, because it's standard component.
	'form.ico'						; Image for icon
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































Deleted IDE/components/SOURCE/LISTBOX.ASM.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
include '..\..\..\source\designtime.inc'
include 'winconst.inc'


DesignTimeInfo                                     \
                                                   \
        'LISTBOX',                                 \
        'Listbox control',                         \
        'Standard',                                \
        'Listbox',                                 \
        WS_CHILD+WS_VISIBLE+WS_BORDER,             \       ; default style
        WS_EX_CLIENTEDGE,                          \       ; default ex style
        128, 128,                                  \
        <                                          \       ; style names
            LBS_DISABLENOSCROLL,   'Shows a disabled scrollbar if the listbox doesn''t contain enough items to scroll', \
            LBS_EXTENDEDSEL,       'Allows multiple items to be selected using the SHIFT key', \
            LBS_HASSTRINGS,        'Specifies that the listbox contains string items',\
            LBS_MULTICOLUMN,       'Specifies a multicolumn listbox',\
            LBS_MULTIPLESEL,       'Turns selection on and off when user clicks an item of the listbox',\
            LBS_NOINTEGRALHEIGHT,  'Specifies that height of the listbox isn''t automatically fixed',\
            LBS_NOREDRAW,          'Makes listbox''s appearance not update when changes are made',\
            LBS_NOSEL,             'Prevents user from selecting any items of the listbox',\
            LBS_NOTIFY,            'Makes the listbox send a notification when user double clicks any item',\
            LBS_OWNERDRAWFIXED,    'Specifies that the listbox''s owner is responsible for drawing items, and that they are the same height',\
            LBS_OWNERDRAWVARIABLE, 'Specifies that the listbox''s owner is responsible for drawing items, and that they are different in height', \
            LBS_SORT,              'Makes listbox sort items alphabetically',\
            LBS_USETABSTOPS,       'Makes listbox expand tabs in strings',\
            LBS_WANTKEYBOARDINPUT, 'Makes listbox send WM_VKEYTOITEM message when the key is pressed and the listbox has an input focus'\
        >,                                         \
        NONE,                                      \            ; style Ex names
\
        $00000000,                                 \            ; This is StyleMaskAnd
        WS_CHILD,                                  \            ; This is StyleMaskOr
        $00000000,                                 \            ; This is StyleExMaskAnd
        $00000000,                                 \            ; This is StyleExMaskOr
        $00000000,                                 \            ; This is SubtypeMask
        NONE,                                      \
        NONE,                                      \            ; Library file NULL, because it's standard component.
        'listbox.ico',                             \            ; Image for icon
\
\  ; ComboBox class
\
        'COMBOBOX',                                \
        'Combobox control',                        \
        'Standard',                                \
        'Combobox',                                \
        WS_CHILD+WS_VISIBLE+CBS_DROPDOWN,          \       ; default style
        0,                                         \       ; default ex style
        128, 25,                                   \
        <                                          \       ; style names
            CBS_AUTOHSCROLL,       'Automatically scrolls text in edit when user types something at the end of the line', \
            CBS_DISABLENOSCROLL,   'Displays disabled scrollbar when list doesn''t contain enough items to scroll', \
            CBS_HASSTRINGS,        'Specifies that owner-drawn combobox contains string items', \
            CBS_LOWERCASE,         'Converts to lowercase all texts in combobx', \
            CBS_UPPERCASE,         'Converts to uppercase all texts in combobx', \
            CBS_NOINTEGRALHEIGHT,  'Specifies that height of the combobox isn''t automatically fixed', \
            CBS_OEMCONVERT,        'Converts text in edit control to the OEM character set', \
            CBS_OWNERDRAWFIXED,    'Specifies that the combobox''s owner is responsible for drawing items, and that they are the same height', \
            CBS_OWNERDRAWVARIABLE, 'Specifies that the combobox''s owner is responsible for drawing items, and that they are different in height', \
            CBS_SORT,              'Makes combobox sort items alphabetically' \
        >,                                         \
        NONE,                                      \            ; style Ex names
\
        $00000000,                                 \            ; This is StyleMaskAnd
        WS_CHILD,                                  \            ; This is StyleMaskOr
        $00000000,                                 \            ; This is StyleExMaskAnd
        $00000000,                                 \            ; This is StyleExMaskOr
        $00000003,                                 \            ; This is SubtypeMask
        <                                          \
          CBS_DROPDOWN,     'Dropdown combobox',  \
          CBS_DROPDOWNLIST, 'Dropdown listbox',   \
          CBS_SIMPLE,       'Simple combobox'     \
        >,                                         \            ; This is SubtipeRange
        NONE,                                      \            ; Library file NULL, because it's standard component.
        'combobox.ico'                                          ; Image for icon
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































Deleted IDE/components/SOURCE/STATIC.ASM.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
include '..\..\..\source\designtime.inc'
include 'winconst.inc'


DesignTimeInfo                                                \
        'STATIC',                                             \
        'Label control',                                      \
        'Standard',                                           \
        'Label',                                              \
        WS_VISIBLE or WS_CHILD,                               \         ; default style
        0,                                                    \         ; default ex style
        32, 13,                                               \
        <                                                     \         ; style names
            SS_SUNKEN            , "Draws a half-sunken border around a static control",                                        \
            SS_CENTERIMAGE       , "Centers the image",                                                                                                                            \
            SS_REALSIZEIMAGE     , "Prevents a static icon or bitmap control from being resized as it is loaded or drawn",                                                         \
            SS_RIGHTJUST         , "Specifies that the lower right corner of a static control with the SS_BITMAP or SS_ICON style is to remain fixed when the control is resized", \
            SS_NOPREFIX          , "Prevents interpretation of any ampersand (&) characters in the control's text as accelerator prefix characters",\
            SS_NOTIFY            , "Sends the parent window notification messages when the user clicks or double-clicks the control"          \
        >,                                                    \
        NONE,                                                 \         ; style Ex names
                                                              \
        $00000000,                                            \         ; This is StyleMaskAnd
        WS_CHILD ,                                            \         ; This is StyleMaskOr
        $00000000,                                            \         ; This is StyleExMaskAnd
        $00000000,                                            \         ; This is StyleExMaskOr
        $1f      ,                                            \         ; This is SubtypeMask
        <                                                     \
            SS_LEFT              , "Left aligned with wordwrap",      \
            SS_CENTER            , "Centered",                        \
            SS_RIGHT             , "Right-aligned",                   \
            SS_SIMPLE            , "Simple one line text",            \
            SS_LEFTNOWORDWRAP    , "Left-aligned without wordwrap"   \
        >,                                                    \         ; This is SubtipeRange
        NONE,                                                 \         ; Library file NULL, because it's standard component.
        'label.ico',                                          \         ; Image for icon
                                                              \         ; 2.Shape control starts here
        'STATIC',                                             \
        'Shape control',                                      \
        'Standard',                                           \
        'Shape',                                              \
        WS_VISIBLE or WS_CHILD or SS_ETCHEDFRAME,             \         ; default style
        0,                                                    \         ; default ex style
        128, 128,                                             \
        <                                                     \         ; style names
            SS_SUNKEN            , "Draws a half-sunken border around a static control",                                        \
            SS_CENTERIMAGE       , "Centers the image",                                                                                                                            \
            SS_REALSIZEIMAGE     , "Prevents a static icon or bitmap control from being resized as it is loaded or drawn",                                                         \
            SS_RIGHTJUST         , "Specifies that the lower right corner of a static control with the SS_BITMAP or SS_ICON style is to remain fixed when the control is resized", \
            SS_NOPREFIX          , "Prevents interpretation of any ampersand (&) characters in the control's text as accelerator prefix characters",\
            SS_NOTIFY            , "Sends the parent window notification messages when the user clicks or double-clicks the control"          \
        >,                                                    \
        NONE,                                                 \         ; style Ex names
                                                              \
        $00000000,                                            \         ; This is StyleMaskAnd
        WS_CHILD ,                                            \         ; This is StyleMaskOr
        $00000000,                                            \         ; This is StyleExMaskAnd
        $00000000,                                            \         ; This is StyleExMaskOr
        $1f      ,                                            \         ; This is SubtypeMask
        <                                                     \
            SS_BLACKFRAME        , "Specifies a box with a frame drawn in the same color as the window frames",                 \
            SS_GRAYFRAME         , "Specifies a box with a frame drawn with the same color as the screen background (desktop)", \
            SS_WHITEFRAME        , "Specifies a box with a frame drawn with the same color as the window background",           \
            SS_ETCHEDHORZ        , "Draws the top and bottom edges of the static control using the EDGE_ETCHED edge style",     \
            SS_ETCHEDVERT        , "Draws the left and right edges of the static control using the EDGE_ETCHED edge style",     \
            SS_ETCHEDFRAME       , "Draws the frame of the static control using the EDGE_ETCHED edge style",                    \
            SS_BLACKRECT         , "Specifies a rectangle filled with the current window frame color",                          \
            SS_GRAYRECT          , "Specifies a rectangle filled with the current screen background color",                     \
            SS_WHITERECT         , "Specifies a rectangle filled with the current window background color"                      \
        >,                                                    \         ; This is SubtipeRange
        NONE,                                                 \         ; Library file NULL, because it's standard component.
        'shape.ico',                                          \         ; Image for icon
                                                              \         ; 3.Image control starts here
        'STATIC',                                             \
        'Image control',                                      \
        'Standard',                                           \
        'Image',                                              \
        WS_VISIBLE or WS_CHILD or SS_BITMAP or SS_CENTERIMAGE,\         ; default style
        0,                                                    \         ; default ex style
        128, 128,                                             \
        <                                                     \         ; style names
            SS_SUNKEN            , "Draws a half-sunken border around a static control",                                        \
            SS_CENTERIMAGE       , "Centers the image",                                                                                                                            \
            SS_REALSIZEIMAGE     , "Prevents a static icon or bitmap control from being resized as it is loaded or drawn",                                                         \
            SS_RIGHTJUST         , "Specifies that the lower right corner of a static control with the SS_BITMAP or SS_ICON style is to remain fixed when the control is resized", \
            SS_NOPREFIX          , "Prevents interpretation of any ampersand (&) characters in the control's text as accelerator prefix characters",\
            SS_NOTIFY            , "Sends the parent window notification messages when the user clicks or double-clicks the control"          \
        >,                                                    \
        NONE,                                                 \         ; style Ex names
                                                              \
        $00000000,                                            \         ; This is StyleMaskAnd
        WS_CHILD ,                                            \         ; This is StyleMaskOr
        $00000000,                                            \         ; This is StyleExMaskAnd
        $00000000,                                            \         ; This is StyleExMaskOr
        $1f      ,                                            \         ; This is SubtypeMask
        <                                          \
            SS_BITMAP            , 'Bitmap image'  ,                       \
            SS_ICON              , 'Icon image'    ,                       \
            SS_ENHMETAFILE       , 'Metafile image',                       \
            SS_OWNERDRAW         , 'Owner is responsible for drawing image.',   \
            SS_USERITEM          , 'User defined item'        \
        >,                                                    \         ; This is SubtipeRange
        NONE,                                                 \         ; Library file NULL, because it's standard component.
        'image.ico'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































Deleted IDE/components/SOURCE/SizerClassDTL.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
;**********************************************************************
; Fresh project draft file.
; 20.09.2003 John Found
;
; Method for dynamic loading of source-level libraries in design-time
;
; This is example, how Fresh controls executable code will be loaded
; dynamicaly in run time instead of embeding in the source file.
; For every control will be created wrapper DLL, where the main
; functions have standard names:
;
;    RegisterXXXXXClass - registers the window class for the control.
;    XXXXXWinProc       - Window message handler.
;
;  Note that this wrapper includes exactly the same source file
;  as source-level library. The only problem is with global variables
;  used in source-level libs. For this example I define these in
;  .data section, but this is only to allow compilation. The data
;  for these variables is not the same as in the project.
;  This problem requre some solution, before implementation this idea
;  in Fresh.
;**********************************************************************

format PE GUI 4.0 DLL
entry DllEntryPoint

include '%finc%/win32/win32a.inc'
include 'sourcelevel/SizerClass.inc'

;------------------------------------------------------------
; This section is illegal here. But I have no idea how to
; remove it in common case. These variables are globals from
; Fresh project, used in source-level libraries.

section '.data' code readable writeable

hInstance dd ?
hMainWin  dd ?
xGrid     dd ?
yGrid     dd ?
fSnapToGrid dd ?
;------------------------------------------------------------


section '.code' code readable executable

proc DllEntryPoint, hinstDLL,fdwReason,lpvReserved
        enter
        mov     eax,TRUE
        return

; The files from source-level library must be included without
; any change.
include 'sourcelevel\geometry.asm'
include 'sourcelevel\SizerClass.asm'



section '.idata' import data readable writeable

  library kernel32,'KERNEL32.DLL',      \
          user32,'USER32.DLL',          \
          gdi32, 'GDI32.DLL'

  include '%include%\apia\kernel32.inc'
  include '%include%\apia\user32.inc'
  include '%include%\apia\gdi32.inc'

section '.edata' export data readable

  ; functions have to be sorted alphabetically
  export 'SizerClassDTL.DLL',\
         RegisterSizerClass,'RegisterSizerClass',\
         SizerWinProc,'SizerWinProc'

section '.reloc' fixups data discardable
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































Deleted IDE/components/SOURCE/WINCONST.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323

; USER32.DLL constants


; 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

; 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 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

; 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

; 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

; 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 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 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

; 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

; 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

; 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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































Deleted IDE/components/SOURCE/asmedit.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
include '%finc%/win32/win32a.inc'
include '..\..\..\source\designtime.inc'
include 'winconst.inc'
include '..\..\..\source\AsmEdit\AsmEdit.inc'

DesignTimeInfo                                     \
\ ; AsmEdit control.
        'ASMEDIT',                                    \
        'AsmEdit control',                            \
        'Fresh',                                     \
        'AsmEdit',                                    \
        WS_VISIBLE or WS_CHILD or WS_HSCROLL or WS_VSCROLL or ES_NOHIDESEL or  AES_AUTOINDENT or AES_SMARTTABS or AES_CONSOLECARET, \       ; default style
        WS_EX_CLIENTEDGE,                                          \       ; default ex style
        128, 128,                                  \
        <                                          \       ; style names
            ES_NOHIDESEL,   "Specifies that the selected text is not hidden when the textbox control loses the keyboard focus", \
            AES_AUTOINDENT, 'Auto indent',         \
            AES_SMARTTABS,  'Smart tabs',          \
            AES_OPTIMALFILL, 'Optimal fill',       \
            AES_SECURESEL,   'Security selection', \
            AES_AUTOBRACKETS,'Auto brackets',      \
            AES_CONSOLECARET, 'Console caret',     \
            AES_INDENTSEL,    'Tab indents selection' \
        >,                                         \
        NONE,                                      \            ; style Ex names
\
        $00000000,                                 \            ; This is StyleMaskAnd
        WS_CHILD or ES_MULTILINE,                  \            ; This is StyleMaskOr
        $00000000,                                 \            ; This is StyleExMaskAnd
        $00000000,                                 \            ; This is StyleExMaskOr
        $00000000,                                 \            ; This is SubtypeMask
        NONE,                                      \
        NONE,                                      \         ; Library file NULL, because it's standard component.
        'asmedit.ico'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































Deleted IDE/components/SOURCE/scrollbar.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
; One file may contains description of more than one control.
; Look at 'DesignTimeInfo' macro definition.
;
; This file must be compiled with FASM compiler to get binary
; file. It will be compiled as .BIN file. This is not executable
; file. Don't start it.

include '..\..\..\source\designtime.inc'
include 'winconst.inc'


DesignTimeInfo                                     \
                                                   \       ; 1. SCROLLBAR CONTROL
        'SCROLLBAR',                               \
        'Horizontal scrollbar control',            \
        'Standard',                                \
        '',                                        \
        WS_VISIBLE+WS_CHILD,                       \       ; default style
        0,                                         \       ; default ex style
        128, 16,                                   \
        <                                          \       ; style names
           SBS_BOTTOMALIGN,  "Aligns scrollbar to the bottom of the client area",   \
           SBS_TOPALIGN,     "Aligns scrollbar to the top of the client area",   \
           SBS_BOTTOMALIGN,  "Aligns scrollbar to the left side of the client area",   \
           SBS_TOPALIGN,     "Aligns scrollbar to the right side of the client area"   \
        >,                                         \
        NONE,                                      \            ; style Ex names
\
        $00000000,                                 \            ; This is StyleMaskAnd
        WS_CHILD,                                  \            ; This is StyleMaskOr
        $00000000,                                 \            ; This is StyleExMaskAnd
        $00000000,                                 \            ; This is StyleExMaskOr
        $00000001,                                 \            ; This is SubtypeMask
        <                                          \
          SBS_HORZ, 'Horizontal scrollbar',\
          SBS_VERT, 'Vertical scrollbar'\
        >,                                         \            ; This is SubtipeRange
        NONE,                                      \            ; Library file NULL, because it's standard component.
        'hscrollbar.ico',                          \            ; Image for icon
\
\ ; Vertical scrollbar control.
\
        'SCROLLBAR',                               \
        'Sizebox control',                         \
        'Standard',                                \
        ''      ,                                  \
        WS_VISIBLE+WS_CHILD+SBS_SIZEBOX,           \       ; default style
        0,                                         \       ; default ex style
        16, 16,                                    \
        <                                          \       ; style names
           SBS_SIZEBOXBOTTOMRIGHTALIGN,  "Aligns sizebox to the the lower right of the client area",   \
           SBS_SIZEBOXTOPLEFTALIGN,  "Aligns sizebox to the the upper left of the client area"   \
        >,                                         \
        NONE,                                      \            ; style Ex names
\
        $00000000,                                 \            ; This is StyleMaskAnd
        WS_CHILD+SBS_SIZEBOX,                      \            ; This is StyleMaskOr
        $00000000,                                 \            ; This is StyleExMaskAnd
        $00000000,                                 \            ; This is StyleExMaskOr
        $00000001,                                 \            ; This is SubtypeMask
        <                                          \
          SBS_SIZEBOX, 'Standard sizebox',         \
          SBS_SIZEGRIP, 'SizeGrip'                 \
        >,                                         \            ; This is SubtipeRange
        NONE,                                      \            ; Library file NULL, because it's standard component.
        'sizebox.ico'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































Deleted IDE/components/STATIC.vcl.

cannot compute difference between binary files

Deleted IDE/components/TABCTL.ICO.

cannot compute difference between binary files

Deleted IDE/components/TOOLBAR.ICO.

cannot compute difference between binary files

Deleted IDE/components/TREEVIEW.ICO.

cannot compute difference between binary files

Deleted IDE/components/Textbox.ico.

cannot compute difference between binary files

Deleted IDE/components/asmedit.ico.

cannot compute difference between binary files

Deleted IDE/components/asmedit.vcl.

cannot compute difference between binary files

Deleted IDE/components/btnedit.ico.

cannot compute difference between binary files

Deleted IDE/components/hscrollbar.ico.

cannot compute difference between binary files

Deleted IDE/components/monthview.ico.

cannot compute difference between binary files

Deleted IDE/components/progress.ico.

cannot compute difference between binary files

Deleted IDE/components/scrollbar.vcl.

cannot compute difference between binary files

Deleted IDE/components/statusbar.ico.

cannot compute difference between binary files

Deleted IDE/components/vscrollbar.ico.

cannot compute difference between binary files

Deleted IDE/templates/DOS command/DosCom.fpr.

cannot compute difference between binary files

Deleted IDE/templates/DOS command/MainFile.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
;--------------------------------------------------------------------
; This is template for creating simple .com DOS application.
;--------------------------------------------------------------------
        org     $100
; Put your source here.





exit:
        mov     ax, $4c00
        int     $21
<
<
<
<
<
<
<
<
<
<
<
<
<


























Deleted IDE/templates/DOS command/README.TXT.

1
Simple DOS .com application.
<


Deleted IDE/templates/FreshLib portable GUI application/FreshLibGUI.fpr.

cannot compute difference between binary files

Deleted IDE/templates/FreshLib portable GUI application/MainForm.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
; _______________________________________________________________________________________
;|                                                                                       |
;| ..:: Fresh IDE ::..  template project.                                                |
;|_______________________________________________________________________________________|
;
;  Description: FreshLib portable GUI application; Main form source file;
;
;  Target OS: Any, supported by FreshLib
;
;  Dependencies: FreshLib
;
;  Notes:
;_________________________________________________________________________________________

iglobal
  frmMainForm:
        ObjTemplate  tfEnd, Form, frmMain, \
                     x, 100,        \
                     y, 50,         \
                     width, 320,    \
                     height, 240,   \
                     Visible, TRUE, \
                     Caption, 'FreshLib portable application.'
endg
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































Deleted IDE/templates/FreshLib portable GUI application/main.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
; _______________________________________________________________________________________
;|                                                                                       |
;| ..:: Fresh IDE ::..  template project.                                                |
;|_______________________________________________________________________________________|
;
;  Description: FreshLib portable GUI application.
;
;  Target OS: Any, supported by FreshLib
;
;  Dependencies: FreshLib
;
;  Notes:
;_________________________________________________________________________________________

include "%lib%/freshlib.inc"

@BinaryType GUI

include "%lib%/freshlib.asm"

; include your includes here.
include "MainForm.asm"

start:
        InitializeAll

        stdcall Create, CApplication
        mov     [pApplication], ebx

        stdcall CreateFromTemplate, frmMainForm, 0
        mov     ecx, [pApplication]
        mov     [ecx+TApplication.MainWindow], frmMain

        stdcall Run

        FinalizeAll
        stdcall Terminate, 0


@AllImportEmbeded       ; or @AllImportSection
@AllDataEmbeded         ; or @AllDataSection
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































Deleted IDE/templates/FreshLib portable GUI application/readme.txt.

1
2
3
4
Portable GUI application, based on FreshLib. 
Can be compiled as PE executable or as ELF executable, without source changes.

In order to keep it portable, use only FreshLib functions and avoid use of OS specific API.
<
<
<
<








Deleted IDE/templates/FreshLib portable console application/FreshLibConsole.fpr.

cannot compute difference between binary files

Deleted IDE/templates/FreshLib portable console application/console.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
; _______________________________________________________________________________________
;|                                                                                       |
;| ..:: Fresh IDE ::..  template project.                                                |
;|_______________________________________________________________________________________|
;
;  Description: FreshLib portable console application.
;
;  Target OS: Any, supported by FreshLib
;
;  Dependencies: FreshLib
;
;  Notes:
;_________________________________________________________________________________________

include "%lib%/freshlib.inc"

@BinaryType console

include "%lib%/freshlib.asm"

; include your includes here.

start:
        InitializeAll

; place your code here.

        FinalizeAll
        stdcall Terminate, 0


@AllImportEmbeded       ; or @AllImportSection
@AllDataEmbeded         ; or @AllDataSection
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































Deleted IDE/templates/FreshLib portable console application/readme.txt.

1
2
3
4
Portable console application, based on FreshLib. 
Can be compiled as PE executable or as ELF executable, without source changes.

In order to keep it portable, use only FreshLib functions and avoid use of OS specific API.
<
<
<
<








Deleted IDE/templates/Win32 DLL library/README.TXT.

1
DLL (dynamic link library).
<


Deleted IDE/templates/Win32 DLL library/dlltpl.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
; DLL library template
format PE GUI 4.0 DLL
entry DllEntryPoint

include '%finc%/win32/win32a.inc'


section '.code' code readable executable

;--------------- DLL entry function --------------------
proc DllEntryPoint, .hinstDLL, .fdwReason, .lpvReserved
begin
        mov     eax,TRUE
        return
endp



;--------------- export functions ----------------------
proc DLLExportFunc, .hWnd, .dwError
begin

        ; insert your code here

        return
endp



section '.idata' import data readable

  ; Place imports here.


section '.edata' export data readable

  ; Place exporting functions here.
  ;
  ; NOTE: functions need to be expoted in
  ; aplhabetical order.

  export 'DLLTPL.DLL',\
         DLLExportFunc,'DLLExportFunc'



section '.reloc' fixups data discardable
  ; Fixup section. You don't have to
  ; put anything here manually.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































Deleted IDE/templates/Win32 DLL library/dlltpl.fpr.

cannot compute difference between binary files

Deleted IDE/templates/Win32 SDI tiny application/MainForm.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
;<ff
Window frmMain, 2, 0, 'TForm', 'Tiny GUI application using TForm', $16080000, $0, 0, 222, 200, 320, 240, MainFormWinProc;
;ff>

;-----------------------------------------------------------------------
; Window procedure for the form.
; Arguments:
;   .hwnd - handle of the window
;   .wmsg - code of the message
;   .wparam \ Parameters of the message
;   .lparam /
;-----------------------------------------------------------------------
winproc MainFormWinProc
begin
;-----------------------------------------------------------------------
; Write here the code that have to be executed before
; message dispathing.
;-----------------------------------------------------------------------


ondefault
;-----------------------------------------------------------------------
; Write here the code that have to be executed if message
; was not processed by this procedure.
;-----------------------------------------------------------------------
        stc
        return
endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































Deleted IDE/templates/Win32 SDI tiny application/README.TXT.

1
2
Windows GUI applications of type SDI (Single document interface)that
contains only one main window and possibly other dialog or toolbox windows, owned by the main window.
<
<




Deleted IDE/templates/Win32 SDI tiny application/TinyGUI.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
format PE GUI 4.0
entry Start

include '%finc%/win32/win32a.inc'

include "%finc%/libs/msgutils.inc"
include "%finc%/libs/tform.inc"
include "%finc%/libs/parents.inc"
include "%finc%/libs/templates.inc"

include "%finc%/libs/msgutils.asm"
include "%finc%/libs/tform.asm"
include "%finc%/libs/parents.asm"
include "%finc%/libs/templates.asm"

include "MainForm.frm"

uglobal
  hInstance dd ?
  hHeap     dd ?
  hMainForm dd ?
endg

Start:
        invoke  GetModuleHandleA,0
        mov     [hInstance],eax
        invoke  GetProcessHeap
        mov     [hHeap], eax

        InitializeAll

        stdcall CreateForm, frmMain, NULL
        xor     eax, eax
        test    ebx, ebx
        jz      .terminate

        mov     [hMainForm], ebx

.run:
        call    ProcessMessages
        jc      .terminate

        invoke  WaitMessage
        jmp     .run

.terminate:
        push    eax
        FinalizeAll
        invoke  ExitProcess ; exit code from the stack.

data import
  include '%finc%/win32/allimports.asm'
end data

IncludeAllGlobals
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































Deleted IDE/templates/Win32 SDI tiny application/TinyGUI.fpr.

cannot compute difference between binary files

Deleted IDE/templates/Win32 SysTray application/README.TXT.

1
2
3
Win32 System Tray application template. Includes main window
that creates a tray icon and a popup menu that appears when
user selects the icon.
<
<
<






Deleted IDE/templates/Win32 SysTray application/mainwindow.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
;<ff
Window frmMainWindow, 2, 0, 'TForm', 'Pluggy', $16080000, $0, 0, 231, 202, 320, 240, MainWindowProc;
;ff>
PM_SHELLNOTIFY = WM_USER + 1

IDI_TRAY     = 0
IDM_EXIT     = 100
IDM_SHOWHIDE = 101


iglobal
  szShowHide db "&Show/Hide", 0
  szExit     db "&Exit", 0
endg

uglobal
  nid          NOTIFYICONDATA
  uVisibleFlag dd ?
  hTrayMenu    dd ?
endg


winproc MainWindowProc
begin

ondefault
        stc
        return

onmessage FM_AFTERCREATE

        mov     [nid.cbSize],sizeof.NOTIFYICONDATA              ; prepare tray icon
        push    [.hwnd]
        pop     [nid.hWnd]
        mov     [nid.uID],IDI_TRAY
        mov     [nid.uFlags],NIF_ICON+NIF_MESSAGE+NIF_TIP
        mov     [nid.uCallbackMessage],PM_SHELLNOTIFY
        invoke  LoadIconA, NULL,IDI_WINLOGO
        mov     [nid.hIcon],eax
        mov     dword[nid.szTip],"Tray"
        mov     dword[nid.szTip+4], "Demo"
        invoke  Shell_NotifyIconA, NIM_ADD,nid

        invoke  CreatePopupMenu                 ; create tray popup menu - here you
        mov     [hTrayMenu],eax                 ; can add your own menu items
        invoke  AppendMenuA, eax,MF_STRING,IDM_SHOWHIDE,szShowHide
        invoke  AppendMenuA, [hTrayMenu],MF_STRING,IDM_EXIT,szExit
        clc
        return

onmessage WM_DESTROY
        invoke  Shell_NotifyIconA, NIM_DELETE,nid
        invoke  DestroyMenu, [hTrayMenu]
        invoke  PostQuitMessage, 0
        clc
        return

onmessage WM_COMMAND
        cmp     [.lparam],0
        jne     .ondefault

        mov     eax,[.wparam]           ; handle tray popup menu actions
        cmp     eax,IDM_SHOWHIDE        ;
        je      .showhide
        cmp     eax,IDM_EXIT
        je      .idm_exit
        stc
        return

  .idm_exit:
        invoke  DestroyWindow, [.hwnd]
        clc
        return


onmessage WM_CLOSE
        jmp     .hide

onmessage PM_SHELLNOTIFY                ; handle tray icons actions:
locals                                  ;  left mouse button - show/hide window
  .pt POINT                             ;  right mouse button - show tray popup menu
endl
        cmp     [.lparam],WM_LBUTTONDOWN
        je      .showhide
        cmp     [.lparam],WM_RBUTTONDOWN
        je      .show_tray_popup
        jmp     .finish
  .showhide:
        cmp     [uVisibleFlag],0
        je      .show
      .hide:
        invoke  ShowWindow, [.hwnd],SW_HIDE
        mov     [uVisibleFlag], 0
        jmp     .finish
      .show:
        invoke  ShowWindow, [.hwnd],SW_SHOW
        mov     [uVisibleFlag], 1
        invoke  SetActiveWindow, [.hwnd]
        jmp     .finish
  .show_tray_popup:
        lea     eax,[.pt]
        invoke  GetCursorPos, eax
        invoke  SetForegroundWindow, [.hwnd]
        invoke  TrackPopupMenu, [hTrayMenu],TPM_RIGHTALIGN,[.pt.x],[.pt.y],\
                                NULL,[.hwnd],NULL
        invoke  PostMessageA, [.hwnd],WM_NULL,0,0
  .finish:
        clc
        return
endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































Deleted IDE/templates/Win32 SysTray application/tray.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
format PE GUI 4.0
entry Start

include '%finc%/win32/win32a.inc'
include '%finc%/libs/msgutils.inc'
include '%finc%/libs/templates.inc'
include '%finc%/libs/TForm.inc'
include '%finc%/libs/parents.inc'


section '.code' code readable executable
..ShowSizes = 1
..ShowSkipped = 0

include '%finc%/libs/msgutils.asm'
include '%finc%/libs/templates.asm'
include '%finc%/libs/TForm.asm'
include '%finc%/libs/parents.asm'

include 'mainwindow.frm'

uglobal
  hMainForm dd ?
  hInstance dd ?
endg

Start:
        invoke  GetModuleHandleA, 0
        mov     [hInstance], eax
        InitializeAll

        stdcall CreateForm, frmMainWindow, NULL
        mov     [hMainForm],ebx

        include '%finc%/libs/mainloop.asm'
        push    eax
        FinalizeAll
        invoke  ExitProcess


section '.idata' data import readable writeable
ImportTable:
include '%finc%/win32/allimports.asm'
DispSize 'ImportTable', $ - ImportTable

section '.data' data readable writeable
IncludeAllGlobals
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































Deleted IDE/templates/Win32 SysTray application/tray.fpr.

cannot compute difference between binary files

Deleted IDE/templates/Win32 console/Console.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

; Console Modes, and color atributes

ENABLE_PROCESSED_INPUT          = 1h
ENABLE_LINE_INPUT               = 2h
ENABLE_ECHO_INPUT               = 4h
ENABLE_WINDOW_INPUT             = 8h
ENABLE_MOUSE_INPUT              = 10h
ENABLE_PROCESSED_OUTPUT         = 1h
ENABLE_WRAP_AT_EOL_OUTPUT       = 2h
CONSOLE_TEXTMODE_BUFFER         = 1
FOREGROUND_BLUE                 = 1h
FOREGROUND_GREEN                = 2h
FOREGROUND_RED                  = 4h
FOREGROUND_INTENSITY            = 8h
BACKGROUND_BLUE                 = 10h
BACKGROUND_GREEN                = 20h
BACKGROUND_RED                  = 40h
BACKGROUND_INTENSITY            = 80h

struct COORD
  .x                            dw ?
  .y                            dw ?
ends

struct SMALL_RECT
  .Left                         dw ?
  .Top                          dw ?
  .Right                        dw ?
  .Bottom                       dw ?
ends

struct CONSOLE_SCREEN_BUFFER_INFO
  .dwSize                       COORD
  .dwCursorPosition             COORD
  .wAttributes                  dw ?
  .srWindow                     SMALL_RECT
  .dwMaximumWindowSize          COORD
ends

; Console Colors

macro ConsoleColor Name,[Part] {
 common
   local Color
   Color = 0
 forward
   if ~ Part eq
     Color = Color or FOREGROUND_#Part
   end if
 common
   FGColor.#Name = Color
   BGColor.#Name = (Color shl 4)
}

ConsoleColor Black
ConsoleColor Gray,INTENSITY
ConsoleColor Silver,RED,GREEN,BLUE
ConsoleColor White,RED,GREEN,BLUE,INTENSITY
ConsoleColor Maroon,RED
ConsoleColor Red,RED,INTENSITY
ConsoleColor Navy,BLUE
ConsoleColor Blue,BLUE,INTENSITY
ConsoleColor Green,GREEN
ConsoleColor Lime,GREEN,INTENSITY
ConsoleColor Purple,RED,BLUE
ConsoleColor Pink,RED,BLUE,INTENSITY
ConsoleColor Olive,RED,GREEN
ConsoleColor Yellow,RED,GREEN,INTENSITY
ConsoleColor Teal,BLUE,GREEN
ConsoleColor Cyan,BLUE,GREEN,INTENSITY

; Console Procedures

iglobal
  CSBI          CONSOLE_SCREEN_BUFFER_INFO
  coords        COORD
endg

uglobal
  hStdIn        dd ?
  hStdOut       dd ?
  ConsoleBuffer rb 1024
endg

; FUNCTION SetColor (Color)
; Changes the Console color.
Console.SetColor fix [SetConsoleTextAttribute],[hStdOut]

initialize PrepareConsole
begin
    xor         eax,eax
    mov         dword [coords],eax

    invoke      GetStdHandle,STD_INPUT_HANDLE
    cmp         eax,INVALID_HANDLE_VALUE ;If theres an error, dont open the console
    je          .end
    mov         [hStdIn],eax ;else, save the input handle
    invoke      GetStdHandle,STD_OUTPUT_HANDLE
    cmp         eax,INVALID_HANDLE_VALUE ;If theres an error, dont open the console
    je          .end
    mov         [hStdOut],eax ;else save the output handle
    invoke      SetConsoleMode,[hStdIn],ENABLE_PROCESSED_INPUT or ENABLE_LINE_INPUT or ENABLE_ECHO_INPUT or \
                                                ENABLE_MOUSE_INPUT or ENABLE_WINDOW_INPUT or ENABLE_PROCESSED_OUTPUT or \
                                                ENABLE_WRAP_AT_EOL_OUTPUT
    stdcall     Console.SetColor,FGColor.Silver or BGColor.Black
  .end:
    return
endp

; FUNCTION Print (Text)
; Print a text to the console.
proc Console.Print,.strText
  .WB dd ?
begin
     push       edx
     invoke     lstrlen,[.strText]
     lea        edx,[.WB]
     invoke     WriteConsoleA, [hStdOut], [.strText], eax, edx, 0
     pop        edx
.end:
     return
endp


; FUNCTION Input
; Read one text from the console.
; Returns pointer to buffer.
proc Console.Input
  .RB dd ?
begin
     invoke     FlushConsoleInputBuffer,[hStdIn]
     lea        eax,[.RB]
     invoke     ReadConsoleA,[hStdIn],ConsoleBuffer,1024,eax,0
     mov        esi,ConsoleBuffer ; starting the routine to remove the crlf chars
.loadstrloop:
     lodsb
     cmp        al,13
     jne        .loadstrloop
     mov        byte [esi-1],0
     mov        eax,ConsoleBuffer
     return
endp

; FUNCTION Locate (X,Y)
; Changes the cursor position.
proc Console.Locate,.curX,.curY
begin
     mov        eax,[.curX]
     mov        dword [coords.x],eax
     mov        eax,[.curY]
     mov        dword [coords.y],eax
     invoke     SetConsoleCursorPosition,[hStdOut],[coords]
     return
endp

; FUNCTION Clear (Color)
; Clears the console.
proc Console.Clear,.paramColor
  .WB dd ?
begin
     mov        [coords.x],0
     mov        [coords.y],0
     stdcall    Console.SetColor,[.paramColor]
.next:
     invoke     GetConsoleScreenBufferInfo,[hStdOut],CSBI
     mov        eax,dword [CSBI.dwSize.x]
     mul        [CSBI.dwSize.y]
     ; conSize = edx
     lea        eax,[.WB]
     invoke     FillConsoleOutputCharacterA,[hStdOut],20h,edx,[coords],eax
     invoke     GetConsoleScreenBufferInfo,[hStdOut],CSBI
     lea        eax,[.WB]
     invoke     FillConsoleOutputAttribute,[hStdOut],dword [CSBI.wAttributes],edx,[coords],eax
     invoke     SetConsoleCursorPosition,[hStdOut],[coords]
     return
endp

; FUNCTION SetTitle (Title)
; Changes the console title.
Console.SetTitle equ [SetConsoleTitleA]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































Deleted IDE/templates/Win32 console/MainFile.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

; Win32 Console Application

format PE Console 4.0
entry Start

include '%finc%\win32\win32a.inc'
include 'Console.inc'

uglobal
  hInstance dd ?
  hHeap     dd ?
endg

Start:
        invoke  GetModuleHandleA,0
        mov     [hInstance],eax
        invoke  GetProcessHeap
        mov     [hHeap], eax
        InitializeAll

        ; TODO: Insert code here

        ; Start of example
        iglobal
          strTest       db ' Hello world! ',0
          strEnding     db 'Ending application, press any key...',13,10,0
          strTitle      db 'Testing Console Library',0
        endg
        stdcall Console.Locate,5,5
        stdcall Console.SetColor,FGColor.Maroon or BGColor.Pink
        stdcall Console.SetTitle, strTitle
        stdcall Console.Print, strTest
        stdcall Console.Input
        stdcall Console.Clear, FGColor.Red or BGColor.White
        stdcall Console.Print, strEnding
        stdcall Console.Input
        ; End of example

Exit:
        push    eax
        FinalizeAll
        invoke  ExitProcess ; exit code from the stack.

data import
  include "%finc%\win32\allimports.asm"
end data

IncludeAllGlobals
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































Deleted IDE/templates/Win32 console/README.txt.

1
Windows 32-bit console type applications.
<


Deleted IDE/templates/Win32 console/Win32Console.fpr.

cannot compute difference between binary files

Deleted IDE/templates/complex.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
;<ff
Window FormLabel, 2, 0, 'TForm', 'TForm window', $16080000, $0, 0, 201, 191, 320, 240, CustomWinProc;
;ff>

;-----------------------------------------------------------------------
; Window procedure for the form.
; Arguments:
;   .hwnd - handle of the window
;   .wmsg - code of the message
;   .wparam \ Parameters of the message
;   .lparam /
;-----------------------------------------------------------------------
winproc CustomWinProc
begin
;-----------------------------------------------------------------------
; Write here the code that have to be executed before
; message dispathing.
;-----------------------------------------------------------------------


ondefault
;-----------------------------------------------------------------------
; Write here the code that have to be executed if message
; was not processed by this procedure.
;-----------------------------------------------------------------------
        stc
        return
endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































Deleted IDE/themes/Black&White.theme.

cannot compute difference between binary files

Deleted IDE/themes/Classic.theme.

cannot compute difference between binary files

Deleted IDE/themes/Hackerz.theme.

cannot compute difference between binary files

Deleted IDE/themes/Windows.theme.

cannot compute difference between binary files

Deleted License.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
The Fresh Artistic License

Preamble

The intent  of  this document is to  state the conditions under which a
Package may be  copied,  such that the  Copyright Holder maintains some
semblance of  artistic control  over the  development  of  the package,
while giving  the users  of the package the right to use and distribute
the Package in a more-or-less customary fashion, plus the right to make
reasonable modifications.

Definitions:

    * "Package" refers  to  the  collection of files distributed by the
      Copyright Holder,  and derivatives  of that  collection  of files
      created through textual modification.
    * "Standard Version"  refers  to  such a Package if it has not been
      modified,  or has  been modified in accordance with the wishes of
      the Copyright Holder.
    * "Copyright Holder"  is  whoever  is  named  in  the  copyright or
      copyrights for the package.
    * "You"  is  you,  if you're thinking about copying or distributing
      this Package.
    * "Reasonable copying fee" is whatever you can justify on the basis
      of media cost,  duplication charges, time of people involved, and
      so on. (You  will  not be required to justify it to the Copyright
      Holder, but  only to the computing community at large as a market
      that must bear the fee.)
    * "Freely Available"  means  that  no  fee  is charged for the item
      itself,  though  there may be fees involved in handling the item.
      It  also  means  that recipients of the  item may redistribute it
      under the same conditions they received it.

IMPORTANT NOTE: 
    FASM compiler itself,  which  is  integral  part of this package is 
    distributed under  different  license.  All  source  files  of FASM 
    compiler are separated in "source\fasm\" directory. Please read and 
    apply "source\fasm\license.txt" for FASM license.

1. You may make and give away verbatim copies of the source form of the
   Standard Version  of this Package without restriction, provided that
   you duplicate all  of the  original copyright notices and associated
   disclaimers.

2. You may apply bug fixes, portability fixes  and other  modifications 
   from the Copyright Holder  or those  derived  from the Public Domain 
   and approved by the  Copyright Holder.  A Package modified in such a 
   way shall still be considered the Standard Version.

3. You  may  otherwise  modify  your  copy  of this Package in any way,
   provided  that you  insert  a prominent notice  in each changed file
   stating how and when you changed that file, and provided that you do
   at least ONE of the following:

    a) place your modifications in the Public Domain or  otherwise make
       them Freely Available, such as by posting said  modifications to
       Usenet or an equivalent medium, or placing the  modifications on
       a major  archive site  such as  ftp.uu.net,  or by  allowing the
       Copyright Holder  to include  your modifications in the Standard
       Version of the Package.

    b) use   the  modified  Package  only  within  your  corporation or
       organization.

    c) rename any non-standard executables so the names do not conflict
       with  standard  executables,  which  must  also be provided, and
       provide a separate manual page for each  non-standard executable
       that clearly documents how it differs from the Standard Version.

    d) make other distribution arrangements with the Copyright Holder.

4. You may  distribute  the programs  of this Package in object code or
   executable form, provided that you do at least ONE of the following:

    a) distribute  a  Standard  Version  of the executables and library
       files,  together  with  instructions  ( in  the  manual  page or
       equivalent) on where to get the Standard Version.

    b) accompany  the  distribution with the machine-readable source of
       the Package with your modifications.

    c) accompany any non-standard executables with their  corresponding
       Standard    Version   executables,   giving   the   non-standard
       executables  non-standard  names,  and  clearly  documenting the
       differences  in  manual  pages  (or equivalent),  together  with
       instructions on where to get the Standard Version.

    d) make other distribution arrangements with the Copyright Holder.

5. You may charge a reasonable copying fee for any distribution of this
   Package.  You  may  charge  any  fee  you choose for support of this
   Package. You may not charge a fee for this  Package itself. However,
   you may  distribute  this  Package in aggregate with other (possibly
   commercial)  programs  as  part  of  a  larger (possibly commercial)
   software  distribution  provided  that  you  do  not  advertise this
   Package as a product of your own.

6. The executable and library files supplied as input to or produced as
   output from the  programs  of this Package do not automatically fall
   under  the  copyright  of  this  Package,  but  belong  to  whomever
   generated  them, and may be sold commercially, and may be aggregated
   with this Package.

7. You may not use this package,  nor files created as output from this
   package,  nor  products  derived  from  this  package for producing,
   distrubuting  or  in  any   way   contribute   to  the  creation  or
   distribution of "unwanted advertisement" (known as SPAM).

8. The name  of  the  Copyright  Holder  may  not be used to endorse or
   promote  products  derived from this software without specific prior
   written permission.

9. THIS PACKAGE IS PROVIDED "AS IS"  AND WITHOUT ANY EXPRESS OR IMPLIED
   WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
   MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

The End
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































Deleted ReadMe.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
"Fresh" project
(c)2003...2011, 2012 Fresh developement team

This file is in the root directory of the Fresh RAD IDE.
Fresh is FASM based self compilable RAD IDE.

To browse and compile Fresh sources, use recent version of the
FASMW compiler or Fresh IDE itself.

For more detailed information how to write applications with Fresh,
read "doc/FreshGuide.chm" file.

For the sources look at: "source\" directory.

Also the repository with the project history and latest dev versions is on:
[http://chiselapp.com/user/johnfound/repository/FreshIDE/index]

To get latest version of Fresh, visit Fresh home page: http://fresh.flatassembler.net

For FASM/FASMW information and downloads: http://flatassembler.net

To contact authors of Fresh and/or FASM: http://board.flatassembler.net

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































Deleted WhatsNew.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
This file describes the changes in every new version of Fresh IDE
The date format: DD.MM.YYYY

version 2.0.10 (??????????)

    [-] Fixed bug concerning working in Linux (Wine). When Fresh compiles some ELF executable
        it could not set the executable permissions. Now it is fixed.

    [+] New feature: When no Linux terminal is configured, Fresh runs the Linux ELF binaries
        directly, without terminal.

version 2.0.9 (22.09.2012)

    [!] This release introduces some incompatibility with the earlier sources. Read below.

    [+] New FASM 1.71 compiler with address space labels.

    [+] Removed GlobalAPI symbol. Now, when Win32 API is used, the user must provide the
        full function name. This approach makes the syntax more simple, clear and portable.

    [+] Merged with FreshLibDev - new "uses" macro, more flexible dll import macros.
        New "text" macro that avoids text constants duplication. Stdcall macros now
        allows using string constants directly.

    [+] Examples and project templates adapted to the new style of importing functions.

    [-] Fixed missing syntax highlighting of the data definition directives.

    [-] Fixed rare bug - crash when some file is 1.in the project, 2.does not exists on disk
        and 3.the user choose to keep it in the project. Then on compilation, when the compiled
        file uses this missing file, Fresh crashes.

    [-] Fixed long waiting bug with editor "indent" and "comment" features, that made one more line
        to be commented/indented.

version 2.0.8 (26.08.2012)

    [+] Merged with the latest FreshLibDev with sockets library.
    [-] Fixed buggy behaviour of the background .fas file processing.
    [-] Fixed wrong working directory of andLinux running applications.


version 2.0.7 (22.07.2012)

    [+] Added new application templates - FreshLib based portable console and
        GUI applications.
    [-] Empty templates removed.
    [-] "New application" template dialog behavior fixed.
    [+] Latest version of FreshLibDev merged.
    [+] FASM 1.70.03 compiler.
    [+] New help file with FASM 1.70 manual and FreshLib reference.
    [+] New feature: "Help file Ctrl+F1" - the user can open the configured
        help files individually.
    [+] New feature: Embeded help. Fresh extracts the comment blocks from the
        source files and displays them as a hint in the editor.
    [+] Time consuming processing of the .fas file was moved to the
        background thread and does not slow the IDE.
    [+] The cross-reference window can be closed by ESCAPE key from the editor.
    [+] Autoinstalation now set FreshGuide.chm as a help file.
    [-] More FreshLib and less Win API used.
    [-] Increased default memory, allocated for the compiler.
    [-] Some obscure bugs fixed, including all tickets from the repository.

version 2.0.6 alpha (27.04.2012)

    [+] More informative error messages when missing debug information.
    [+] Symbols cross reference functions (in the label explorer and in the source editor)
    [+] Latest version of FreshLib
    [+] Updated FASM compiler to version 1.70
    [-] Some bugs fixed

version 2.0.5 alpha (13.01.2012)

    [+] Native support for running and debuging Linux executables. Now Fresh can run in
        Linux|Wine and to run ELF executables directly.
    [-] Fixed bug in the editor themes load/save dialog. There is still some inconsistent
        behavior, that have to be fixed later.

version 2.0.4 alpha (25.12.2011)

    [+] Updated FASM compiler to 1.69.35
    [+] The project is managed by Fossil VCS now.
        The repository is hosted on [http://chiselapp.com/user/johnfound/repository/FreshIDE]
        Of course the full source code is still available with the release packages,
        but it is often outdated, especially in FreshLib part that is in heavy development now.
    [+] Merged with the latest development version of FreshLib.
    [-] Fixed old bug. Now in form editor ESC key works - selects the parent window in properties editor.
    [-] Fixed bug in form editor that was unable to create new forms.

version 2.0.3 alpha (15.01.2011)

    [+] The next in a row, big restructure of the source code:

        FreshLib is implemented for following libraries:
           - macros (macro/allmacros.asm)
           - equates (equates/allequates.asm)
           - imports (imports/allimports.asm)
           - the structure of the program ( compiler/executable.inc )
           - memory allocations ( data/memory.asm )
           - data handling (data/arrays.asm; data/memstream.asm)
           - file operations (data/files.asm)
           - String operations (data/strlib.asm) StrLib is now portable as well.
             For details, read the header of StrLib.asm file.
             Some functions are not backward compatible with the old version.

    [+] Updated compiler to FASM v1.69.29
    [+] New 'text' macro introduced. The final goal is to provide automatic handling
        of the string constants in order to avoid duplications in definitions and
        waste of label names. Unfortunately, the speed of the macros is too low for
        practical use, so now only a stub is provided for future development.
    [-] Auto set for "lib" directory alias in Fresh.ini
    [-] Fixed bug in AsmEdit
    [-] Fixed bug in AddCompilationStatistics (fasm.asm)
    [-] Fixed very old bug in LabelsList.asm.

version 2.0.2 alpha (23.11.2010) - silent release :)

    [-] Fixed bug in editorhost.asm that crashed Fresh in some cases.
    [-] Fixed bug in PAHint.asm
    [-] Fixed some include files, not properly updated after changes for this version.
    [-] Fixed example projects that refused to compile, because of the updates.
        It was because of biger memory needed and because of some not fixed include files.
    [-] some Cleanup in the XLib example to make it smaller and cleaner.
    [-] Fixed macro/exceptions.inc library to use the new FASM macro syntax.

version 2.0.2 alpha (22.11.2010)
    API include files replaced with new, builded with ImportDB tool. Several bugs fixed.

    [+] Replaced all import files. There is no apia and apiw directories but only one "api".
        All API files are build with ImportDB utility and contains almost all API functions
        from WinXP dlls. Also, the api files now contain the argument description for almost
        all API functions.
        The type of api is set with GlobalAPI symbolic constant. It accepts following values:

            GlobalAPI equ               ; empty value means, all functions will be imported
                                        ; exactly as they are exported from the libraries.

            GlobalAPI equ ascii         ; ASCII functions will be imported without suffix.
                                        ; Unicode functions will be imported with suffix W.

            GlobalAPI equ unicode       ; ASCII functions will be imported with suffix A
                                        ; Unicode functions will be imported without suffix.

    [-] Changed font of the procedure arguments hint window to "Trebuchet MS" that is
        more readable for programming needs.
    [-] buttonedit.asm and buttonedit.inc moved to '%finc%\libs\' where is the
        right place for these files.
    [-] Minor changes in some of component libraries (TForm and Action lists.)
        in order to cleanup dependencies with other libraries.
    [-] Fixed bug on counting arguments in PAHint, when there are quoted commas
        in the arguments.
    [-] Fixed bug on fake compilation that caused crash in some circumstances.
    [-] Fixed very old bug in ButtonEdit.asm, that manifested itself only in Wine.
    [-] Fixed bug in TDataGrid, that sometimes caused crash on closing Fresh.

version 2.0.1 alpha (14.11.2010)

    One new feature and several bug fixes.

    [+] Procedure arguments hint - when the user type call statements, it shows arguments
        of the procedure. It can be used with imported functions too, but the argument
        descriptions for these is limited for now.
    [-] Changes in CCList.asm in order to make things more clear and to collect the code
        in one place.
    [-] Partially edited user32.inc file to insert procedure arguments.
    [-] Fixed wrong size on save of editor theme.
    [-] Bug fix in TForm window class. It concerns the proper WM_COMMAND processing when
        the form is open as modal dialog and have some parent.
    [-] Fixed missing file from the template directory.
    [-] Several other bug fixes here and there.


version 2.0.0 alpha (09.11.2010)

    First version officially published after the project revival. :)

    [+] New project format with converter from the old projects.
    [+] New Linux execution engine, based on andLinux.
    [+] New icon set.
    [+] New help system, that allows multiply help files to be searched.
    [+] New interface to FASM compiler.
    [-] Many bugfixes here and there.
    [-] Little bug fixed in "Create new application" function.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































Deleted doc/FASM.PDF.

cannot compute difference between binary files

Deleted doc/FreshGuide.chm.

cannot compute difference between binary files

Deleted doc/ManualRu/doc/FASM.doc.

cannot compute difference between binary files

Deleted doc/ManualRu/doc/IA.doc.

cannot compute difference between binary files

Deleted doc/ManualRu/hlp/FASM MANUAL.HLP.

cannot compute difference between binary files

Deleted doc/source/0_advanced_setup.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
Setup manual
# Chapter 4 Fresh IDE setup

    The upcoming version 3.0 of Fresh IDE will be fully portable, but until then,
we have to use the Windows version of Fresh.

    Nevertheless, development of Windows and Linux applications in the same time is possible 
    and easy with the current version of Fresh.

    The good news are that Fresh IDE runs like a charm in [Wine].

    So, now (since v2.0.5) we have a choice - whatever OS we choose we can develop applications
for Linux and Windows, including editing, compiling, running and debugging. Of course we are
talking about GUI applications.

    The installation of Fresh is easy, but if we want to use the full potential of the IDE
some setup and adjustments are necessary. Let see how to setup Fresh IDE for work in Windows 
and Linux:

[wine] http://www.winehq.org/


## Windows setup

    In order to run Linux native applications inside Windows, Fresh uses special Linux
distribution - [andlinux].

    *andLinux* is complete Ubuntu distribution, that uses coLinux kernel in order to allow
running of Linux inside Windows OS.

[andLinux] http://andlinux.org
[andLinux download page] http://andlinux.org/downloads.php

    How to setup andLinux to work with Fresh?

### Download andLinux

    Download andLinux package from [andLinux download page]

    There are two packages: "KDE version" and "minimal/XFCE version" available. For use with
Fresh IDE, it is not important what version you will choose.

    KDE package is very big and very slow distribution that contains many bundled programs
and tools, but in general you will not need them. The size of KDE package is 500MB download
and 5GB installed.

    The XFCE package is relatively smaller and faster. Relatively means 200MB downloaded file
and 2GB installed on the disk.

    It is obvious that the right choice is to use XFCE package.

### Install andLinux

    Run the downloaded setup file and answer to the different questions of the
setup wizard:

    * coLinux version - choose the stable version (0.7.4 in my case) instead of latest (0.8.0) - 
we shall work with andLinux, not to play.

    * Memory size - 256MB RAM (or maybe more - if you can afford it).

    * Install XMing server on your primary screen.

    * Sound - you can enable or disable sound in Linux option - it is harmless although
it is one more running server.

    * Startup type + Panel - select *"run andLinux automatically as a NT service" + "use Windows shortcuts"*;
It is not very important, but can save you a little manual work and troubles later.

    * andLinux login - just select your user name and password for Linux root.

    * Windows File Access - it is important! - select *"using CoFS"*, no matter it is not recommended.

    * File Access Using CoFS - important! - create one new directory somewhere and select it to
be mount via CoFS. This will be the shared directory, visible from Windows and from Linux in the
same time.

    All other features you can choose freely or simply leave them to default state.

    When you start installation, the installer will try to install network driver.
It is possible Windows will protest and will atempt to mislead you by asking to not install
not certified driver. You must ignore these attempts and firmly click "install".

    After the installation of andLinux, you have to restart Windows and probably andLinux will
not run. :)

    It is because of the Windows firewall. All new network adapters are firewalled
by default. As long as installed adapter (named TAP-Colinux) is virtual and local, you will
not need any firewall, so, go to "Control panel/Windows firewall/Advanced" and uncheck
"TAP-Colinux" adapter from the list of adapters.

    Then you can run some Linux program - in the Windows tray, there is a andLinux menu icon
that have shortcuts to several Linux programs.


### Additional tools

    Install several additional Linux tools. You will need additionally debugger and
some decent terminal emulator. I choose xterm for terminal, because it is small and white by
default. ;)

    You can choose to use the built-in terminal named in the simple Linux manner:
"xfce4-terminal" and console debugger "gdb". In this case you can skip this step because these tools
are already installed.

    Start "Synaptic" - package manager for Ubuntu from the tray menu. You have to enter root
password you choose on install.

    When Synaptic is started, click "Reload" to refresh the package list from the network and
then use search to locate needed programs. I personally recommend "xterm" as terminal and "ddd"
as a GUI front end to "gdb".

    Well, I recommend "ddd" only because it is only Linux debugger that I was able to run under
andLinux and able to show disassembled code of the program.

    Mark selected programs for install, click on Apply button and wait until downloading and
installation.

    Here you can encounter only one problem - your computer is behind a proxy server.

    If the proxy is a normal proxy, you simply have to set its address and port in the
Synaptic preferences and it should work.

    Completely another story is when the proxy is MS ISA server configured with NTLM user
authorization.

    Most Linux programs can't work with such authorization and Synaptic is not an exception.

    Fortunately, there is a workaround of this situation. You need [ntlmaps] authorization 
proxy server.

    Setting up of this server is out of the scope of this article. On the ntlmaps home page you
can read complete documentation and explanations.

    OK, we are ready with andLinux. Now you have working copy of Ubuntu inside your Windows box.

    It's time to configure Fresh to run Linux applications inside andLinux. Continue with:

[ntlmaps] http://ntlmaps.sourceforge.net/

### Fresh IDE configuration.

    Run Fresh and open "Options|IDE options" dialog. Select "Debuggers and Emulators" page.
    Then select following directories and commands:

    * "andLinux directory" - the directory where you installed andLinux.

    * "andLinux shared directory" - shared directory you selected during andLinux installation.

    * "Linux debugger" - Enter "ddd" (or whatever debugger you choose).

    * "Linux terminal" - Enter: `xterm -hold +mesg -e` - the options are important.

    *And voila! You finished the configuration!*

    Now you can load the source of some Linux program (for example "Fresh/examples/XLib/XLib.fpr") and run it with
shift+F9 or load it in the debugger with shift+F8.

    Now Fresh IDE will detect when you compiled ELF executable and will run it in andLinux instead of
Windows. Of course, the Windows applications will be treated as usually.


## Linux setup

    Working in Linux needs Wine installation. Fresh is tested with v1.2 and 1.3 and works great.
You can skip some steps if they are already set.

### Install Wine

    Install Wine - use whatever package manager is good for you. Synaptic is the usual choice.
In the "Wine configuration|Graphics" panel, uncheck the option "Allow the window manager to decorate the windows".

### Install Fresh IDE

    Install Fresh IDE v2.0.5 or newer - you can use the installation package or ZIP
archive. It is better (at least for v2.0.5) to install Fresh IDE in "c:\" but you can put it at
whatever place you like.

### Debuggers

    Install whatever debugger you will use for Linux applications and OllyDbg for
Windows applications. (OllyDbg works in Wine).

    For Linux, personally I prefer [EDB] but any other is OK
including mentioned in the previous chapter "ddd" and "gdb".

[edb] http://www.codef00.com/projects#Debugger

### Configure Fresh IDE

Run Fresh IDE and if some paths are not set properly, set them manually in
"Options|IDE options" menu.

    You will need at least following directory aliases: "Fresh", "finc" and "lib" - set
them respectively to the Fresh main directory, Fresh "include" directory and "freshlib"
directory, both located in Fresh main directory. (As a rule, there is an auto setup of these
paths, so you don't to have to make it manually. But sometimes the algorithm fails)

    In order to work with FASM examples and programs, you can set manually "include" or any
other alias (environment variable) you prefer.

### External tools

    Set the paths to the external tools needed: (of course you have to install these
tools in advance).

    In "Options|IDE options|Debuggers and emulators" leave "andLinux directory" and
"andLinux shared directory" fields empty. (they are not needed when Fresh runs in Linux)

    Set "Linux debugger" field to binary file of the debugger you prefer. Add the needed
options to the line as well.

    For example, in my settings "Linux debugger" is set to `z:/usr/bin/edb --run`

    Set "Linux terminal" to preferred terminal. For example `z:/usr/bin/xterm -hold +mesg`.

    Set "Win32 external debugger" to OllyDbg.
In my case: `c:\Program files\OllyDebugger\Ollydbg.exe`.

    *All paths must be "dos style" (Note: Wine maps Linux file system to device Z: ).*

### Test it

    Try to compile and run some test applications both for Windows and Linux.
Ctrl+F9 should compile, Shift+F9 should run the application and Shift+F8 should load it
in the respective debugger. The type of the application should be automatically determined.

    *IMPORTANT NOTE:* The only known problem (for Fresh v2.0.5) is that the first time compiled
ELF is not set to be executable. So, you will get "access denied" message on run. The workaround
is to set the permissions manually from the file manager, or console "chmod" command. It is one
time procedure - the following compilations, runs and debugs should work properly.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































Deleted doc/source/1_tips.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
Tips and tricks
# Chapter 5 Fresh tips and tricks.

    There is still no full user guide for Fresh.

    I will write in this page some tips and tricks. Later, they will be used in the full user guide.


## Linux support

* How to develop Linux application from Windows?

* How to develop Windows application from Linux?

* What about Fresh IDE version for Linux?

    For now, Fresh is Windows application. The versions 2.x.x will be Windows applications.
The upcoming v3.0.0 is planed to be portable - for Windows and Linux. Of course every port
will be able to create applications for every OS.

    Despite of this situation, even the current versions can work in Linux through Wine.

    There is a separate [setup][setup manual] describing the setup of Fresh IDE for Linux development.

[setup] 0_advanced_setup.htm

## Goto address

    How to find the place in the source where application crashes?

    Press Ctrl+G in order to open "Goto address" dialog:

        [!goto][Goto address]

    Then enter the address where application crashes and press OK. Fresh will show you the
line of the source that is compiled on the given address. The format of the number is standard
FASM number format.


## Code exploration and cross reference.

There are several functions, aimed to provide easy exploration the source of the big project.

### Labels explorer

After compilation, you can browse all labels tree from the labels explorer. Open it from the 
main menu: `Project|Label explorer`.
In the label explorer you can view the lables values, type and where in the source these labels 
was defined and used.

### Editor cross reference

If you position the text caret on some label and press Ctrl+R, or choose from context menu 
"Cross reference", a window with the cross reference information for this label will be open.

          [!cross][Cross reference]

The first row of the table display the line of the source, label was defined. 
Following rows - the lines where the label is used. Besides the pointed label, all its 
children labels will be displayed.s

If you double click on some of the rows, the editor will bring you to this line of source.

The cross reference window can be closed by pressing *Esc* key.

## Goto definition

If you position the text caret on some symbol and press *Ctrl+D* or choose from the context menu 
"Goto definition", the editor will bring you to the line of the source where this symbol were 
defined.
The project must be compiled for this function to work.

## Embeded help

Similar to "Goto definition" is the next function "Embeded help". 

If the definition of some symbol is preceded by comments block, describing this symbol, Fresh can
show this description everywhere in the source, when you position the text caret on the symbol and
press *Ctrl+W* shortcut. 

The hint window looks like on the screenshot:

                    [!_images/EmbededHelp.png][Embeded help system]

The hint window can be closed by pressing *Esc* key.

## Arguments hint

    How to use "Procedure arguments hint"?

        [!procarg][Procedure argument hints]

    This function works with call macros: *stdcall, ccall, invoke and cinvoke*;

    When you type such line and the function is known (the source have to be compiled prior to
that moment) Fresh shows a hint window that helps you to enter the arguments. This happens
automatically when you type "," somewhere in the line.

    When you want to open the hint window without typing (just for check up) you can press
Ctrl+Q when the caret is at the line. You can close the hint window, pressing *Esc* key.

    "Procedure argumens hint" works for the procedures defined in the compiled source and if
the program uses import definitions from FreshLib, for imported functions as well.

## Code completion

    How to type less and to code more?

        [!code][Code completion]

    Code completion is very powerful function, that can save you thousands of keystrokes.
In order to use it, the source have to be compiled (at least partially - some errors are
acceptable) because Fresh have to build the tree of labels, defined in you program.

    Fresh does not use fixed pre-defined lists. It uses the labels you defined in the source.

    This is the only possible solution, because Fresh is not committed to any particular OS or
platform. If you write Win32 program, you need Windows API and constants in the auto completion box.
If you write Linux program, you need all Linux constants and API functions.

    To open code completion, press *Ctrl+Space* shortcut. Then when you type, the content of the box
will be refreshed in order to correspond with the word you type.

    You can select suitable element from the list with *Up, Down, PgUp and PgDn* keys
and press *Enter* to insert it in the line.

    Auto competion list will open automatically when you type some existing in the list label
and then press *"."* in order to select local label.

    You can close the auto completion window with *ESC* key.

## Project categories

    How to move a file from one category to another in the project?

    Open the file in the editor. Select the category where you want it to be moved.
Click the right mouse button on the tab of the file in order to display the context menu.
Select "Add to project" function. It will remove the file from the old category and will
move it to the current selected category.

## Fast open files

    How to open the file specified in "include" or "file" directive?

    Place the caret on the line that contains file name and press Ctrl+Enter.
    Opening files this way, Fresh replace the directory aliases and/or environment 
variables in the filename.

    Files like `%lib%/%TargetOS%/MyFile.asm` will be opened correctly.

## Directory aliases

    How to set promptly the values of the environment variables?

    Fresh have very flexible system of environment variables handling. Actually I prefer to call them
"Aliase", because they are aliases of the directories or other text.

    You can define such aliases in three ways:

* As OS environment variable.

* As IDE-wide aliases in the Fresh IDE options dialog ("Options|IDE options|Aliases" menu).

* As Project-wide aliases in the project options (Project|Project options" menu or Ctrl+F12 shortcut)

    When exists alias defined several times, then the project aliases have higher priority, then
the IDE aliases and with lowest priority are the OS environment variables.

    Now on the topic: The project aliases allows rapid value change. In order to use this
feature, you have to define the alias with several values, delimited with "|" symbol.
The count of different values is not limited.

    One typical example is the alias %TargetOS% used in the FreshLib test project.
This alias may have as values the names of the OS, the project will be compiled for.
So, in order to switch quick from Win32 to Linux we can define TargetOS as "Win32|Linux".

    In this case, at the top of the project window appears popup menu, where you can select what of these
values to be used. Additionally, the panel "Settings:" will display currently selected values.

       [!alias][Alias fast change]

## Portable applications

    How to write portable assembly applications with Fresh IDE?

    Most people think that assembly language can't be portable. It is not the case. There are many
examples that assembly can be portable. It is only matter of the project design, not the language.

    In order to allow creating of portable applications, FreshLib was created. It is work-in-progress,
but even now it allows creating of small applications that can be compiled for Win32 and Linux platforms
without change of the source.

    Read the unfinished [FreshLibRef][FreshLib reference manual]
and check the sources of FreshLib in "Fresh/freshlib" directory of your Fresh IDE installation.
There is a working test project called TestFreshLib.fpr that I use to test different FreshLib features.

Also, you can create FreshLib projects from template engine. Choose "File|New Application" from the 
main menu or press *Shift+Ctrl+N* shortcut. 

In the dialog window, select the target directory and application template - 
"FreshLib portble console application" or "FreshLib portable GUI application", 
then click *"OK"* and new project will be created.

Press *Shift+Ctrl+S* to save all new created files (you can change the filenames to whatever you like).

Then you can compile your application to Linux or Windows executable file.

The latest development version of FreshLib can be downloaded from the [rep][repository] - *FreshLibDev* branch.

[FreshLibRef] 2_FreshLibDoc.htm

[rep] http://chiselapp.com/user/johnfound/repository/FreshIDE/
        
[!goto] _images/goto.png

[!procarg] _images/ProcArgumentsHint.png

[!code] _images/CodeCompletion.png

[!alias] _images/AliasFastChange.png

[!cross] _images/CrossReference.png
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































Deleted doc/source/2_FreshLibDoc.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
FreshLib reference
# Chapter 6 FreshLib reference

## Overview 

FreshLib is an assembly library aimed to ease the development of assembly
language applications, freely portable between different platforms,
such as Win32 or Linux.

The library is coded in [FASM][flat assembler] syntax
and is intended to be easily used within [Fresh IDE],
although it could be used for plain FASM development.

The library consists of two layers: one, that is OS dependent and
a second one that is OS independent. The OS dependent layer is very
small, in order to help porting it for different OSes. This layer
only makes interface to the core OS functions, such as memory allocations,
file access, drawing functions, simple window management etc.

The OS independent layer is responsible for the main application functionality
allowing creation of different kind of windows and controls, processing of the
system messages, work with dynamic strings, arrays and other data processing.

FreshLib is mainly intended for developing GUI applications, as they
are the most challenging to be ported across different platforms.
FreshLib is also created with visual programming in mind, so it contains
a flexible, event driven and OS independent template engine allowing
visual creation of application user interfaces.

FreshLib is in early development stage and probably will be changed
many times in order to reach their objectives: to be small, fast and
easy to use.

The main intention is to keep the bloat off the library, but containing
all necessary accessories for comfortable programming of a very wide
range of applications.

The architecture of FreshLib is open and it can be freely expanded
with other libraries without increasing the size of applications.
In other words, only those parts of the library that are effectively
used will be compiled on the final executable.

------------------------------------------------------------------------

## About this manual 

This manual is a "work in progress". Any
part of it can be changed at any time.

Of course, some of the libraries described in this document are more
stable and finished like the macro, system and data libraries. Therefore,
the chapters about these libraries are less likely to be changed.
Other libraries (like graphics and GUI), will be heavily modified
so the manual will be changed accordingly.


------------------------------------------------------------------------

## Structure of the library. 

FreshLib contains many code and macros libraries, structured hierarchically
and depending on each other. Here is shown a part of the library directory tree:
;begin
    freshlib/
        compiler/
            Linux/
            Win32/
        data/
            Linux/
            Win32/
        dialogs/
            Linux/
            Win32/
        ...
;end
The library is structured to support different platforms transparently.
You can see, that the tree consists of main sub-directories, that
contains OS independent libraries, separated by topics.
For example *system* subdirectory contains libraries for accessing system
resources such as memory, files, etc. *data* contains libraries for data
handling and so on.
Every topic directory have also several sub-directories, that contains OS
dependent code these directories are named after the platform they serve. 
(In this moment only Linux and Win32 OSes are supported).

------------------------------------------------------------------------

## Compiler setup for FreshLib use.

You can use any FASM compiler to compile applications that uses FreshLib.
In order to be compiled properly, FreshLib needs environment variables
named `lib` and `TargetOS` to be defined.

The variable `lib` contains the path to the main directory of FreshLib
and the variable `TargetOS` contains the target platform, the application
will be compiled for. The value of `TargerOS` is identical to the name of
OS dependent directories in FreshLib.

There are several ways these variables to be defined, depending on
the compiler you use [FASM], [FASMW] or [Fresh IDE].

1. These variable can be defined in the OS environment - see your OS documentation for details.
this approach is more universal - it works for all kind of FASM compilers. The main drawback is
that you have to use OS specific commands and probably will have to edit some system files.

1. Definition in the section `[environment]` of *"fasm.ini"* or *"Fresh.ini"* file, depending on the
IDE you are using. This approach works for both FASMW and Fresh IDE, but in Fresh, the same
effect can be done from inside the IDE. Besides, defined this way, the environment variables
becomes "global" - active for all projects compiled with FASMW or Fresh.

1. From inside Fresh IDE.

In Fresh IDE, the environment variables are named *alias*,
because they serve to provide short alias for the file paths. Two types of alias (environment variables)
lists are supported by Fresh: *global aliases* and *project aliases*. Global aliases are
defined in the IDE options dialog: *Options|IDE options|Aliases*. Here is the screenshot
of this dialog:

  [!_images/AliasesDlg.png][IDE options dialog, section "Aliases"]

The global aliases are active for every project compiled with Fresh and are stored in the Fresh.ini file,
inside the Fresh program directory.

Project aliases are defined in the Project options dialog: *Project|Project
options* or from the project manager, click on the button *Settings* at the top
and select *Project options*. The project options dialog is shown on the following screenshot:

  [!_images/ProjectOptions.png][Project based aliases can be edited in the project options dialog.]

The project aliases are stored inside the project file (.fpr) and they are project specific.

For FreshLib it is not important what list will be used, but it is
more convenient for `lib` variable to be defined in the global list
and for `TargetOS` variable to be defined in the project aliases. In such way
the common parameter (the place of the library) will be set once for all projects, and
the particular parameter (the target OS) will be set separately for every project.

Also, there is very convenient way of changing the value of project
aliases — if several values are specified in the project alias, separated
with `|` char (for example: `Win32|Linux`), Fresh will provide fast switching
between these values from the project manager options menu, as shown on the picture:

   [!_images/fastswitch.png][The aliases with more than one value will appear in the popup menu for fast changing.]

When Fresh searches for needed alias names, during the compilation, it searches first in the project
aliase list, then the global aliases and at the end, the OS environment variables. Of course, if
the alias is not found on these places, the compilation fails with error.


[FASM] http://flatassembler.net

[FASMW] http://flatassembler.net

[Fresh] http://fresh.flatassembler.net

[Fresh IDE] http://fresh.flatassembler.net

------------------------------------------------------------------------

## FreshLib compiling options 

FreshLib uses some options in order to set the behavior of the compiler and the 
different macro libraries.
These options are defined as a local constants of the label *"options."*
Here is a list:

[#options.FastEnter] `options.FastEnter` controls the behavior of the [#proc] macro.

When *options.FastEnter = 1* the procedure entry/leave code will be created with
faster, but bigger push ebp/pop ebp instructions.

When *options.FastEnter = 0* — enter/leave instructions are used.

[#options.ShowSkipped] `options.ShowSkipped` controls the information displayed during compilation.

When *options.ShowSkipped = 1* the compiler will display in the output window the procedures
that are not compiled because they are not used in the program.

[#options.ShowSizes] `options.ShowSizes` controls the behaviour of the DispSize macro.

When *options.ShowSizes = 0* the macro [#DispSize] will be disabled.

[#options.DebugMode] `options.DebugMode` controls the behaviour of the debug macros.

When *options.DebugMode = 1* the macros from [#simpledebug] library will generate debug code and
debug console will be created on running the application.

When *options.DebugMode = 0* these macros will not generate code and the debug console will not be
created.

------------------------------------------------------------------------

## FreshLib code conventions 

### Naming conventions 

1. The names prefixed with one or more underscores ("_") are not recomended for use by the user.
These are internaly used labels that can be changed later. More underscores in the prefix - 
more "internal" is the given identifier.

For example one underscore ( like this: `_AlmostPrivate`) means - "use it carefully". 

Three underscores (for example `___SomeVeryPrivateLabel`) means - don't use it at all. 
It is for internal use only and will be changed later!

2. The names are considered to be used with code completion editor - i.e. there is no long equal 
prefixes of the names, but there are short "class" prefixes.
For example most of the procedures in StrLib begin with "Str" prefix. 

3. In general, FreshLib uses [CamelCase] naming convention, with constants in lowerCamelCase and 
procedures in HigherCamelCase.

4. All local labels and procedure arguments are prefixed with dot — ".";

5. Almost all of the [#struct] and all of [#object] definitions are prefixed with "T" prefix — for 
example [#TTimer] or [#TButton]

6. The file names convention. All file names with extension `.inc` doesn't contain any code or
data definition. Only macro and constants definitions are permitted.

The files with '.asm' extension can define code and data. Although, the code and data in FreshLib
can exists in the compiled binary, only if they are used. Not used data or code, included in
the binary should be considered a bug.

[CamelCase]  http://en.wikipedia.org/wiki/CamelCase


### Register preserving convention

1. The rule is - preserve all you are using. All procedures in FreshLib preserves all registers, 
except these used for returning result values.

;quote
Note: There is some small retreat from this rule - in the object handling procedures, some register 
are preserved internaly, so the user may not preserve them in its code. See [#object.asm] library 
for details.
;end

2. CF is widely used for returning error status or boolean result. 
As a rule *CF=0* means no error; *CF=1* means error.

The use of CF is described always in the description of the respective procedures.

3. The procedures can return result in more than one register. As a rule, EAX is the result register 
for the most procedures, but sometimes other registers are used - in order to provide better 
interface for assembly programming.

For example number of procedures return X,Y values in EAX, EDX registers.

* EAX — commonly used for returning 32bit values;

* EDX — second choise - used together with EAX for 64 bit values, or as a second returned value.

* ECX — usually some count. For example if EAX returns pointer to some memory, ECX will contains the 
data size. See [#LoadBinaryFile] for example.

------------------------------------------------------------------------

## Using FreshLib

There are only two files, the user should include in order to use FreshLib. They are both located
in the "freshlib" directory, usually referred by %lib% directory alias.

These files are:

* `%lib%/freshlib.inc` - contains all macro and OS dependent equates definitions.

* `%lib%/freshlib.asm` - contains all code of FreshLib. Only the used code will actually be included
in the result binary.

The minimal application with FreshLib have following code:

;begin
include "%lib%/freshlib.inc"

@BinaryType GUI

include "%lib%/freshlib.asm"

start:
        InitializeAll

        ; Place your code here

        FinalizeAll
        stdcall Terminate, 0

@AllImportEmbeded
@AllDataEmbeded
;end

The macros [#@BinaryType], [#@AllImportEmbeded], [#@AllDataEmbeded] will be explained later in the 
next chapter.

------------------------------------------------------------------------
## Data definitions in FreshLib program

FreshLib uses advanced data definitions macros, that allows data definitions to be mixed with the 
code, but then to be grouped and inserted in the data section of the program.
This kind of definitions greatly improves the readability of the program, because keeps the data
near to the code that uses it. It is especially important on big projects where the code is spreaded
among multiply files.
There are two main types of data - uninitialized and initialized data.

The initialized data definitions are enclosed inside [iglobal], [endg] macros and the uninitialized 
data in [uglobal], [endg] macros. Inside these blocks you can use all FASM data definition directives
or any other valid FASM code. Note only, that in `uglobal` block only the size of the data matters, 
if you use some defined data, the values will be lost.

;begin
iglobal
  MyGlobalVar dd 123, 456, 789
endg

uglobal
  SomeUndefinedVar rd 1
  SomeArray        rb 256
endg

;end

Another useful macro is [text] (actually it is struc). It defines some string constant anywhere in
the source code. The string constant is later defined in the data section of the program.

When used data definition macros, the user should define the data section with the macro [@AllDataEmbeded] or
[@AllDataSection] somewhere at appropriate place in the program, where all data should stay.


------------------------------------------------------------------------


## FreshLib directory "compiler/"

This directory contains only one macro library: *"executable.inc"*

### "executable.inc" library 

This library defines the macros that are going to be used for creating the main structure of
the program. The implementation of these macros is OS dependent, as long as the type of the
executable file is OS dependent: PE for Win32 and ELF for Linux. The use of the library, however
is OS independent and is common for all supported OSes.
Depending on the value of `TargetOS` alias, the library will create PE executable or DLL
`(%TargetOS%='Win32')`, or ELF executable or shared library `(%TargetOS%='Linux')`

*NOTE:* Every of the macros from this library must used only once in the program.

--------------

[#@BinaryType] `macro @BinaryType type`

This macro sets the type of the executable. The argument `type` can accept one of the following
values: `GUI`, `console` or `DLL`.

This macro also begins the main code section of the executable and defines the entry label of the 
program. The entry label is fixed to `start:`.

For example, following code will tell the compiler to compile the program as a GUI application:
;begin
      include '%lib%/freshlib.inc'
      @BinaryType GUI
;end

--------------

[#@AllDataSection] `macro @AllDataSection`
[#@AllDataEmbeded] `macro @AllDataEmbeded`

These macros defines all data definitions in the program, defined in `uglobal` and `iglobal` blocks 
and the text constants defined using `text` macro.

@AllDataSection, defines the data in a separate program "section". The meaning of the "section" 
term is different, depending on TargetOS definition. In Win32 it is `section '.data' data readable writeable`. 
In Linux it is `segment readable writeable`

@AllDataEmbeded defines the data, embeded in the code section of the program (created by @BinaryType macro).

Only one of these macros must be used. Usually @AllDataEmbeded will create smaller executable, although
some negative effects are possible, because embeded data and code is often considered "bad practice"

--------------

[#@AllImportSection] `macro @AllImportSection`
[#@AllImportEmbeded] `macro @AllImportEmbeded`

These macros automatically defines the import section of the program. This section is created
automatically depending on what functions was used in the program. 

Similar to the data section macros, @AllImportSection will create this data as a separate section, 
while @AllImportEmbeded will try to embed this data in the code section. 
(NOTE: In ELF executable format, the import data must be in separate segment, so
on TargetOS=Linux @AllImportSection and @AllImportEmbeded are equal.)

If embeded import section is used together with embeded data section, the import section should be
defined before the data section, because of undefined data definitions, that must reside at the end 
of the section (code section in the case of embeded data).

------------------------------------------------------------------------

## FreshLib directory "equates/"

[#allequates.inc] *"allequates.inc"* library. This library defines all
constants and structures needed for OS dependent parts of FreshLib.

Actually, the user should never use these constants and structures in the portable program.

The constants and structures that the user should use are defined in the respective libraries,
not in *"allequates.inc"*.

This library will be included automatically by "%lib%/freshlib.inc" file, so the user should not care
about this library at all.

------------------------------------------------------------------------

## FreshLib directory "imports/" 

[#allimports.asm]Another directory that contains only OS dependent definitions is *"imports/"* with a library
file to be included in the project: *"allimports.asm"*

This file is automatically included in the [#@AllImportSection] and [#@AllImportEmbeded] macros.
Then it will generate the proper import section, depending on the target platform and functions used 
by the OS dependent parts of FreshLib.

FreshLib contains very big catalog of shared libraries for Windows and decent set of Linux
shared libraries. The import macros used by FreshLib includes in the import section of the
program, only the functions used by the program, so it will never define redundant import items.

The user must never call directly imported functions from inside a portable application, except if
the imported dynamic library is portable as well. (as sqlite3.dll, for example)

------------------------------------------------------------------------

## FreshLib directory "macros/" 

This directory contains several libraries that provides common convenience functions to be
used with big assembly projects. 

All these libraries will be included automatically in "%lib%/freshlib.inc" file.

There is no overhead including all these libraries, because there is no code to be generated, 
just macro definitions. 
There is a little delay in compile time but thanks to fasm's speed, it is barely noticeable.

Lets examine each one of these libraries.

### "_stdcall.inc" library 

In general this library provides ways of definition and invoking of the procedures with
argument passing through the stack. It supports STDCALL and CCALL calling conventions.

-------------------

[#proc] `macro proc name, [arg]`
[#begin] `macro begin`
[#endp] `macro endp`
[#return] `macro return`
[#cret] `macro cret`
[#locals] `macro locals`
[#endl] `macro endl`

These macros define a procedure, create a stack frame for the local variables and define
symbolic names for the arguments. The macro "proc" defines the global label "name" as a name
for the procedure. All arguments and local variables are defined as a local labels with regard
to the name of the procedure. That is why all arguments and local variables must have names
beginning with dot.

Between the line with *proc* and *begin*, any number of local variables can be defined.
The macro *begin* marks the begining of the procedural code.

The macro *endp* marks the end of the procedural code.

The return from procedure instruction is provided by macros *return* or *cret* depending on
the calling convention we want to use: *return* clears the arguments from the stack and *cret*
does not.

Inside the procedure, a secondary stack frame can be allocated with the pair *locals* and *endl*.
All data definitions, enclosed between these macros will define a secondary stack frame that
is a continuation of the stack frame defined between *proc* and *begin*.

Any number of *locals* and *endl* pairs can be used, but all of these secondary stack frames
will overlap between each other. This feature is specially intended to provide savings of stack
space and at the same time, to provide talking variable names for the different parts of more
complex procedures.

For example (in Win32) let we have complex window procedure that have to process
multiple messages. 

One of the message handlers may need one variable `.rect`.

Another message handler may need two variables called `.point1` and `.point2`.

But the procedure as a whole is never going to need all those variables at the
same time, because it process only one message at a time. On the other hand it
may need the variable `.ctrldata` for every message processed. The optimal solution
is to define the variables as shown in the following example:

;begin
    proc CtrlWinProc, .hwnd, .wmsg, .wparam, .lparam
    .ctrldata dd ?
    begin
        invoke GetWindowLong, [.hwnd], GWL_USERDATA
        mov    [.ctrldata], eax

        cmp    [.wmsg], WM_MESSAGE1
        je     .message1
        cmp    [.wmsg], WM_MESSAGE2
        je     .message2
        return

    .message1:
    locals
      .rect RECT
    endl
        ; do something.
        return

    .message2:
    locals
      .point1 POINT
      .point2 POINT
    endl
        ; do something. 
        return
    endp
;end

The assignment of the stack memory for the above example is shown in the table:
;table
(1, 2) Address

(3, 1) Stack frames
;-----------------------
Common

Locals 1

Locals 2
;-----------------------
EBP-20

--

.rect.left

.point1.x
;-----------------------
EBP-16

--

.rect.top

.point1.y
;-----------------------
EBP-12

--

.rect.right

.point2.x
;-----------------------
EBP-8

--

.rect.bottom

.point2.y
;-----------------------
EBP-4

.ctrldata

--

--

;end

;;begin
;;+---------+---------+--------------+-------------+
;;|         |           Stack frames               |
;;+ address +---------+--------------+-------------+
;;|         |  common |   locals 1   |   locals2   |
;;|:-------:|:-------:|:------------:|:-----------:|
;;| EBP-20  |         | .rect.left   |   .point1.x |
;;| EBP-16  |         | .rect.top    |   .point1.y |
;;| EBP-12  |         | .rect.right  |   .point2.x |
;;| EBP-08  |         | .rect.bottom |   .point2.y |
;;| EBP-04  |.ctrldata|              |             |
;;+---------+---------+--------------+-------------+
;;        Procedure local labels memory map.
;;end

As you can see, *.rect* occupies the same memory as *.point1* and *.point2*,
but *.ctrldata* is never overlapped and exists independently.

As a general rule, you have to use the definitions between "proc" and "begin" for local
variables that are used in every call of the procedure and separate locals/endl definitions
for variables needed for the particular branches inside the procedure.
This approach will always provide the optimal size for the locals stack frame.

--------------------

[#initialize] `macro initialize`
[#finalize] `macro finalize`

The macros "initialize" and "finalize" defines one special type of procedures that, during
compilation are registered in a two separate lists - one for "initialize" and one for
"finalize" procedures. Procedures defined with "initialize" and "finalize" must have no any
arguments.

After that, using the macros "InitializeAll" and "FinalizeAll", all these procedures can be
call at once. "initialize" procedures are call in the order of their definition and "finalize"
procedures in reverse order.

These macros provides standard and consistent way for initialization and the
finalization of the libraries and modules of the application.

FreshLib uses this mechanism and the user is free to use it also.


-------------------------


[#stdcall] `macro stdcall proc, [arg]`
[#ccall]   `macro ccall proc, [arg]`
[#invoke]  `macro invoke proc, [arg]`
[#cinvoke] `macro cinvoke proc, [arg]`

These macros call the procedures with STDCALL and CCALL calling convention.

`stdcall` macro pushes the arguments to the stack in reverse order and then call
the procedure with label *proc*. As long as the macro "stdcall" does not provide
any stack cleanup (this duty is assigned to the procedure) the arguments can be
pushed in free manner using, for example, separate push instructions for part of
the arguments and arguments in the stdcall line for the remaining arguments.
This can be very convenient in some cases. For example see the following source:
;begin
    stdcall CreateSomeObject
    push    eax
    stdcall DoSomething
    stdcall DeleteSomeObject
;end
Here, the procedure DoSomething changes the value of eax, so the handle is saved
in the stack. The procedure DeleteSomeObject needs one argument — a handle of
the object. But as long as the proper value is already in the stack, it is
mindless to pop the value and then to push it again. So the source calls
DeleteSomeObject without any arguments. The procedure knows the proper number
of arguments (one in this example) and clean the stack properly.

The standard (and wrong) approach is to pop the argument from the stack and then
to pass it to the procedure explicitly is the stdcall statement:
;begin
    stdcall  CreateSomeObject
    push     eax                ; save the handle.
    stdcall  DoSomething
    pop      eax                ; ??? Why ???
    stdcall  DeleteSomeObject, eax
;end
This source will generate the meaningless instructions sequence:
;begin
    pop      eax
    push     eax
;end
*invoke* macro is the same as "stdcall" with the only difference - it calls the procedure
indirectly ( `call [proc]` instead of `call proc` ).  This mechanism usualy is used to call
the functions imported from external dynamic linked libraries.
Of course, the imported functions can be call with `stdcall [someproc]` but the *invoke*
macro helps to better distinguish what procedures are imported and what are internal for the
program.

*NOTE:* The user should never use *invoke* in the portable programs, because such programs
never use directly OS dependent import functions.


*ccall* macro calls a procedure with CCALL convention. This means that the procedure returns
with simple "retn", without cleaning the parameters from the stack. Then "ccall" macro provides
instructions that remove the arguments from the stack.

Because ccall have to know the exact count of passed arguments, all arguments have to be passed
explicitly as a values in the ccall statement.
Tricks as described above will not work properly and leads to stack not properly cleaned after
the call.

"cinvoke" is the same as ccall, but using indirect call. The reason for existing of "cinvoke"
macro is the same as with "invoke" macro — better legibility of the source.

*About the calling conventions:* While all Win32 dynamic linked libraries uses STDCALL
convention, most (if not all) of Linux libraries uses CCALL convention.

*All code libraries of Fresh use STDCALL calling convention and it is platform independient.*

-------------------------------------------------------------------------------------

### "_globals.inc" library 

This library defines several macros intended to deal with data definitions.

Usually all data definitions have to be placed in special section of the
executable file. ([#_DataSection] in FreshLib). This is not very convenient, because the code
that process this data and the data definitions must reside in separate places of the source
code, and in most cases even in different files.

The idea of *"globals.inc"* macro library is to allow the data definition to be
described anywhere in the source code, but these definitions to be defined at
once, at the place the programmer wants - usually in the data section of the
program.

--------------------

[#uglobal] `macro uglobal`
[#iglobal] `macro iglobal`
[#endg] `macro endg`
[#IncludeAllGlobals] `macro IncludeAllGlobals`

*uglobal* begins block for undefined data definition. The block ends with *endg*
macro. Between "uglobal" and "endg" macro any count of data definitions can be
inserted.

Note that because uglobal block defines undefined data, it is only the labels
and the size of data that have meaning inside this block. Any data, defined with
data definition directive will not increase the size of the executable file, but will
be allocated when the executable is loaded in the memory.

The undefined data will be defined later at the place where "IncludeAllGlobals"
macro resides. In order to not increase the size of the executable file,
the undefined data is always placed at the end of all data definitions.

"iglobal" macro, again combined with "endg" defines initialized data. The data
defined in the block will be created at "IncludeAllGlobals" statement.

This block increases the size of the executable file, because it contains
sensible data, that have to be included in the file.

Actually, neither *uglobal*, nor *iglobal* blocks defines any data immediately.
Instead, the data definitions are stored in a list. The real definition occurs
later, when *IncludeAllGlobals* macro is invoked.
For this reason, *IncludeAllGlobals* must be placed in the source after all used
global data blocks.

The programmer should never use explicitely IncludeAllGlobals. This macro will be invoked
on [#@AllDataSection] or [#@AllDataEmbeded] macros use.

---------------------

[#text] `struc text [val]`

The macro *"text"* is actually a structure. It needs to be preceded by some label name.

This macro accepts string or number arguments. When it is invoked with string arguments,
it defines a zero terminated string constant, and also a local constant *.length*
equal to the length of the string without terminating zero. When invoked with number as argument,
*"text"* defines label at the address *val* and does not defines .length constant.

The *"text"* macro, the same way as *iglobal* and *uglobal*, simply stores string data for
defer definition. This definition, occurs in IncludeAllGlobals invocation.
Note that the real definition will be made only if the string is used in the program.
Not used strings will not be defined.

Look at the following example:
;begin
        myName text 'John',$20,'Smith'
;end
This code will define the data and constant labels following way:
;begin
        if used myName
          myName db 'John Smith'
          .length = $-myName
                 db 0
        end if
;end

Why to define separate macro for the strings and not to use the normal iglobal
block? At first, *text* macro defines a real data only if this data is used
somewhere in the source. This way is prevented bloating of the code with
unneeded data definitions.

;quote
Also, the macro "text" was planned to check the strings
content and to not define any string more than once. In the case of repetitive strings,
this macro should return the pointer to the already defined string constant.

In that case, it would be very convenient and harmless to use unnamed string constants
in the function calling macros - stdcall, ccall etc.

Unfortunately, regardless of the power of fasm macro language, this functionality
cannot be implemented. Or, more precisely, it can be implemented, but the
implementation is too slow for any real project use.

This ineffective implementation is still leaved inside the file *"_globals.inc"* -
commented block that defines macro with name "*InitStringList*". If someone have
ideas about fixing this problem, please send it to me!
;end

------------------

[#var] `macro var expr`

The macro *var* defines dword variable with a given value. The use is following:
;begin
        var MyVar = 1234
;end
The only differens from the usual use of *dd* directive is that the variable will be
defined only if used in the source.

Note that the variable is created at the place where *var* is used, so you need to place it
inside a *iglobal* block if you want it to be defined in the global data place.

---------------------

### "_struct.inc" library 

This library contains only two simple macros:

[#struct] `macro struct name`
[#ends] `ends`

*struct* macro is aimed to provide easy creation of data structures. The "struc"
directive in FASM is known to not create actual labels, but only the template
for the label definitions. So, we need to create an instance of the data
structure in order to have addresses and offsets of its fields.

But very often we don't have static data structure of the given type, but data
structure, pointed by some of the registers. In this case in order to use
offsets to the fields of the data structure, we need to define at least one
virtual instance of the structure at address 0. Then we can use the values of
the fields as an offsets in the instructions - for example:
;begin
    mov eax, [esi+RECT.right].
;end
So, this is exactly what "struct" macro does. Besides it defines the "struc"
structure with the given fields, it creates a single virtual instance of this
structure, in order to be used later for register addressing.
Also, the macro defines local constant of *sizeof.* global label equal to the
byte size of the structure.
In all remaining functionality it behaves exactly as the struc directive.

The syntax of struct macro is the following:
;begin
    struct StructureName
      .field1 dd ?
      .field2 RECT
      .fieldN:
    ends
;end
The definition begins with "struct" followed by the structure name.
The definition ends with "ends" directive. Between both, any local label
definition becomes a member of the structure.
The above definition, results in following code:
;begin
    struc StructureName {
      .field1 dd ?
      .field2 RECT
      .fieldN:
    }
    virtual at 0
      StructureName StructureName
      sizeof.StructureName = $
    end virtual
;end

--------------------------------------------------------------

### "_display.inc" library 

This library contains macros that enhance the functionality of standard FASM
"display" directive.


[#disp] `macro disp [arg]`

The macro "disp" displays the strings given in the arguments, just as "display"
FASM directive does. Additionally it can display numbers in any given radix:
;begin
    disp <number, radix>
;end

---------------

[#DispSize] `macro DispSize Text, Sz`

"DispSize" is very specialized macro, that displays the text and number in
the following form:
;begin
Size of [Text] is: Sz bytes
;end
The size number is automatically scaled to bytes or kbytes, depending on the
value of Sz.

This macro allows easy display and control of the sizes of particular areas of
the program - data structures, subroutines etc.

DispSize macro behavior is controlled by [#options.ShowSizes] option.

-----------------

[#display] How Fresh implements "display" directive

There are some specifics in Fresh, concerning message displaying. The "display"
directive in Fresh works in a slightly different way than the original FASM directive.

It outputs text in Fresh message window. Each message can have one of six icons,
or it can have no icon at all. And because message window is implemented as a
TreeView control, you can organize your messages into groups (directories).

Implementation is a bit "tricky" - when you display a character whose code is
less than 16, it is interpreted in a special way. Characters from 1 to 6 set an
icon of current message. It sounds complicated, but it is quite simple. Try:
;begin
    display 2, "some message"
;end
It will display "some message" with an error icon. Another codes are used for
controlling directory structure. Try to type following lines and see what would
happen:
;begin
    display 3, "message at root", 0x09
    display 3, "child message1", 0x0a
    display 3, "child message2", 0x0d
    display 3, "again at root", 0x0a
;end
Of course you don't have to put each message in separate display directive, you
can, with the same result write:

display 3, "at root",$09,3,"child1",$0a,3,"child2", $0d,3,"again at root",$0a

Here is the complete list of all special characters and their meanings:
;table
char

meaning

note
;-------------
$01

set current icon to "warning"

 [?_images/warning.gif]
;------------------
$02

set current icon to "error"

 [?_images/error.gif]
;-----------------
$03

set current icon to "info"

 [?_images/information.gif]
;----------------
$04

set current icon to "find"

 [?_images/find.gif]
;----------------
$05

set current icon to "none"

--
;----------------
$06

set current icon to "debug" 

 [?_images/debug.gif]
;----------------
$08 

end current row and set one level back.

--
;----------------
$09

end current row and set it as new directory.

--
;----------------
$0a

end current row and keep current level.

--
;----------------
$0d

end current row and set current level to root level.

--
;end


;;begin
;;+------+--------------------------------------------------------+
;;| char |   meaning                                              |
;;|:----:|:-------------------------------------------------------|
;;| $01  |   set current icon to "warning"                        |
;;| $02  |   set current icon to "error"                          |
;;| $03  |   set current icon to "info"                           |
;;| $04  |   set current icon to "find"                           |
;;| $05  |   set current icon to "none"                           |
;;| $06  |   set current icon to "debug"                          |
;;| $08  |   end current row and set one level back.              |
;;| $09  |   end current row and set it as new directory.         |
;;| $0a  |   end current row and keep current level               |
;;| $0d  |   end current row and set current level to root level  |
;;+------+--------------------------------------------------------+
;;          display directive special characters
;;end


-------------------


## FreshLib directory "system/" 


-----------------


### "memory.asm" library 

This library provides OS independent way of allocating, reallocating and freeing
dynamic memory blocks.
All other libraries in FreshLib that needs dynamic memory, use this library.

The user who needs such memory blocks should use it as well.

--------------

[#GetMem] `proc GetMem, .size`

Allocates `[.size]` byte of dynamic memory.

Returns:

 `CF=0`; EAX = pointer to the allocated memory;

 `CF=1`; EAX=0 if the memory can not be allocated.

The memory is filled with NULL.

------------------

[#FreeMem] `proc FreeMem, .ptr`

Frees the specified in `[.ptr]` dynamically allocated memory.
Returns nothing.

-------------------

[#ResizeMem] `proc ResizeMem, .ptr, .newsize`

Reallocates memory on address `[.ptr]` to the new size in `[.newsize]`

Returns:

CF=0; EAX = pointer to the allocated memory;

CF=1; EAX=`[.ptr]` if the memory can not be reallocated.
In this case, the memory block is not changed

The increased part of the memory block is not zeroed.

-----------------


### "files.asm" library 


[#FileOpen] `proc FileOpen, .filename`

The procedure opens the file with filename in `[.filename]` for reading.

Returns:

`CF=0`; EAX = Handle to the file.

`CF=1`; EAX = Error code.

-------------------

[#FileCreate] `proc FileCreate, .filename`

Creates a file or opens the existing one and truncates its size to 0. The file is opened for writing.

Returns:

`CF=0`; EAX = Handle to the file.

`CF=1`; EAX = Error code.


----------------------

[#FileClose] `proc FileClose, .handle`

Closes the previously opened file.

Returns:

`CF=0`; EAX = Handle to the file.
`CF=1`; EAX = Error code.

----------------------

[#FileRead] `proc FileRead, .handle, .buffer, .count`

Reads `[.count]` bytes from the file `[.handle]` in the buffer at `[.buffer]`.

Returns:

`CF=0`; EAX = The count of actually read bytes.
`CF=1`; EAX = Error code.

---------------------

[#FileWrite] `proc FileWrite, .handle, .buffer, .count`

Writes `[.count]` bytes from the buffer `[.buffer]` to the file with handle `[.handle]`.

Returns:

`CF=0`; EAX = The count of actually written bytes.

`CF=1`; EAX = Error code.

------------------------

[#FileSeek] `proc FileSeek, .handle, .dist, .direction`

Moves the file pointer of the file `[.handle]` on `[.dist]` distance (in bytes) relative to `[.direction]`.

Direction is one of the following values:

`fsFromBegin` — relative to the file begin.

`fsFromEnd` — relative to the file end (then `[.dist]` should be negative).

`fsFromCurrent` — relative to the current position.

[#FileDelete] `proc FileDelete, .filename`

Deletes the file with filename in `[.filename]`

Returns:

`CF=0`; The file was deleted.
`CF=1`; EAX = Error code.

--------------------------

[#GetErrorString] `proc GetErrorString, .code`

Returns in EAX, pointer to the human readable error message, corresponding to the error code
passed in `[.code]`

The message string have to be passed to FreeErrorString, when not needed.

---------------------------

[#FreeErrorString] `proc FreeErrorString, .ptrString`

Frees the error string `[.ptrString]`, previously returned by GetErrorString. As long as the
error strings are allocated by the OS, they have to be free by OS as well.
Returns nothing.

--------------------------

[#LoadBinaryFile] `proc LoadBinaryFile, .ptrFileName`

Loads the whole file `[.ptrFileName]` to the dynamically allocated memory block.

Returns:

`CF=0`; EAX = pointer to the allocated memory; ECX = the size of the loaded file.

`CF=1`; EAX = Error code. ECX = 0; The memory is not allocated.

The allocated memory have to be free after use with [#FreeMem].

---------------------------

[#SaveBinaryFile] `proc SaveBinaryFile, .ptrFileName, .aptr, .size`

Creates or overwrites the file `[.ptrFileName]` with the `[.size]` bytes from the buffer `[.aptr]`;

Returns:

`CF=0`; EAX = count of the bytes actually write;
`CF=1`; EAX = error code;

--------------------------

[#FileExists] `proc FileExists, .ptrFileName`

Check the existence of the file with name in `[.ptrFileName]`.

Returnds:

`CF=1` — the file *does not* exists.
`CF=0` — the file exists.

The existence of the file is checked using [#FileOpen] procedure.
If the file can be opened, it is considered existing.

-----------------

### "process.asm" library 


[#Terminate] `proc Terminate, .exit_code`

Terminates the application and all of its threads.
Returns `[.exit_code]` to the OS.

This procedure simply does not returns, because the application stops.

----------------------

[#ThreadCreate] `proc ThreadCreate, .ptr_to_function, .ptr_to_args`

Creates new thread. `[.ptr_to_function]` points to the thread procedure.
The thread procedure should have one argument.
When the thread starts, `[.ptr_to_args]` is passed as a thread argument.

Returns:

`CF=0`; EAX = is a handle to the new thread. In the different OSes this value can have different meaning.
But it identifies the thread anyway.

`CF=1`; EAX = error code;

------------------------

[#MutexCreate] `proc MutexCreate, .ptrName, .ptrMutex`

Creates new mutex with name `[.ptrName]` and save its handle to `[.ptrMutex]` variable.

The calling thread takes the owneship of the mutex.

If `[.ptrName]` = 0, unnamed mutex will be created.

------------------------

[#WaitForMutex] `proc WaitForMutex, .ptrMutex, .timeout`

Waits until the mutex is released and takes the ownership.

Returns:

`CF=0` — the mutex ownership is successfuly obtained.
`CF=1` — the timeout was expired.


[#MutexRelease] `proc MutexRelease, .ptrMutex`

Releases the ownership of the specified mutex.

-----------------------

[#MutexDestroy] proc MutexDestroy, .ptrMutex

Destroys the mutex `[.ptrMutex]`

-----------------

### "clipboard.asm" library 

[#clipboard.asm] clipboard.asm library contains very simple clipboard functions that 
works only on text data.

------------------

[#ClipboardRead] `proc ClipboardRead`

Returns in EAX handle to the string with the current clipboard content.
If the clipboard is empty or contains not textual information, EAX=0;
The user should delete the string when not needed by passing it to [#StrDel].

--------------------

[#ClipboardWrite] `proc ClipboardWrite, .hstring`

Writes the string `[.hstring]` to the clipboard.
Returns nothing.

-----------------

## FreshLib directory "timers/" 


### "timers.asm" library 

[#timers.asm] library deals with user created timers and also contains some 
procedures for work with the system time and date.

------------------------------------

[#TTimer] `TTimer` structure.

The timers in FreshLib are represented with the following memory structure:
;begin
    struct TTimer
      .next dd ?

      .interval dd ?
      .value    dd ?


      .flags    dd ?
      .Callback dd ?
      .Expired  dd ?
      .tag      dd ?
    ends
;end
The fields are:

  * `.next` —  Don't change this. It is a pointer to the next timer in the timers chain. It is for internal use only.

  * `.interval` — the interval of the time in ms

  * `.value` — The current value of the timer in ms. When this value becomes higher than `[.interval]` an event is 
fired and the value becomes 0. This value is incremented by the system dependent time step - probably something like 1..100ms

  * `.flags` — contains a set of tmfXXXX flag values. Determines the behavior of the timer. See below for description of the flags.

  * `.Callback` — pointer to the callback procedure of the timer.
                  The callback procedure should accept one argument with the pointer to the timer that fired the event: `proc OnTimer, .ptrTimer`

  * `.Expired`  —  count of the timer expirations, if the callback procedure was not called.

  * `.tag`  —  user defined value associated with the timer.


The `.flags` field can have one or more of the following values:

 * `tmfDoNothing`  — when the timer expires no action should be performed. .Expired field of the timer will be incremented.

 * `tmfCallProc` —   `[TTimer.Callback]` contains pointer to the procedure that to be executed once per timer expiration.

 * `tmfSyncDestroy` — If this flag is set, the timer will be destroyed on the next timer expiration.
                      In this case, the configured event is fired and then the timer is destroyed.
                      The flag is checked after the event returns, so the event handler can reset this flag and thus to prevent destruction.

 * `tmfRunning` — If this flag is set, the timer runs. If the event handler resets this flag, the timer will fire only once and will be suspended.

-----------------------

[#TimerCreate] `proc TimerCreate`

Creates a new timer.

Returns:

 * CF=0; EAX= pointer to the TTimer structure. The timer is created suspended.
         The user can set or reset tmfRunning in `[.flags]` in order to start or stop the timer.
         Also, the user have to enter proper values in the remaining fields.

 * CF=1; Error allocating memory.

---------------------- 

[#TimerDestroy] `proc TimerDestroy, .ptrTimer`

Destroys the timer `[.ptrTimer]`

------------------


## FreshLib directory "simpledebug/"

### "debug.asm" library 

[#simpledebug] This library includes number or macros and procedures aimed to assist the debugging
process of the application. These macros display different data values on the debugging
console.

The library contains its own output procedures, so it does not depend on the other used libraries.

All the macros from this library generate code only when [#options.DebugMode] = 1, so the
programmer can include as many debug statements as needed and leave them in the source.
They will not be included in the final binary.
The debug macros will always preserve all registers, except the EFLAGS register.

-------------

[#DebugMsg] `macro DebugMsg msg`

Displays the text message `msg` to the debug console.
Example:
;begin
     DebugMsg 'The program executes here!'
;end

----------------

[#OutputRegister] `macro OutputRegister reg, radix`

Outputs the content of some register in the given radix. Example:
;begin
    OutputRegister regEAX, 10
;end
The possible register values are: `regEDI`, `regESI`, `regEBP`, `regESP`, `regEBX`, `regEDX`, `regECX`, `regEAX`

----------------

[#OutputMemory] `macro OutputMemory pointer, size`

OutputMemory will dump `[size]` bytes of memory at address `[pointer]`; Example:
;begin
    OutputMemory esi, 128
;end

---------------

[#OutputNumber] `macro OutputNumber number, radix, digits`

Outputs *digits* digits of the *number* in *radix* radix. Example:
;begin
    OutputNumber 12345, 16, 8
;end

------------------

[#GetTimestamp] `proc GetTimestamp`

Returns in eax timestamp measured in milliseconds (ms).

-----------------


## FreshLib directory "data/" 

This directory contains several libraries that handles different data structures.
The libraries are mostly OS independent.
Actually the only OS dependent part is one small routine in Win32 section, that
converts strings from UTF-8 to UTF-16 because Windows can't handle UTF-8 strings
directly.

------------------

### "arrays.asm" library 

This library handles dynamic arrays, containing elements of arbitrary size.
All elements of the array have the same size.

[#TArray] TArray structure have following definition:
;begin
    struct TArray
      .count     dd ?
      .capacity  dd ?
      .itemsize  dd ?
      .lparam    dd ?
      label .array dword
    ends
;end
The above structure represents the header of the array. The actual array will
have arbitrary size, depending on the element count and size.

The first element of the array begins on offset *TArray.array* from the begining
of the memory block.

The field *TArray.count* contains the current element count of the array.

The field *TArray.capacity* contains the current capacity of the array.
It is because the library usually allocates more memory than is needed for the array
element count.
This approach reduces memory allocations and reallocations and
thus increases the speed of inserting and deleting elements in the array.
How many memory will be allocated depends on the user setting of the variable
ResizeIt (defined in memory.asm). This variable contains a pointer to the
procedure that simply increases the value of ECX to the next suitable value.

The field *TArray.itemsize* contains the size in bytes of one array element.
Changing of this value is not recommended.

The field *TArray.lparam* is for user defined parameter, associated with the array.

-----------------------------

[#CreateArray] `proc CreateArray, .itemSize`

This procedure creates new array with item size `[.ItemSize]`

The procedure returns CF=0 if the array is properly created and pointer to the
array is placed in EAX.

In case the memory cannot be allocated, the procedure returns CF=1.
To free the allocated array, use [#FreeMem] procedure.

------------------------------

[#AddArrayItems] `proc AddArrayItems, .ptrArray, .count`

This procedure adds new array items at the end of the array pointed by `[.ptrArray]`

The procedure returns two values:

EAX contains pointer to the first of the new appended elements.

EDX contains pointer to the array (in the process of appending of the new
element, it is possible the whole array to be moved to the new address in
memory, so the programmer should store the value of EDX for the future
reference to the array.

In case, the new memory can not be allocated, the procedure returns CF=1 and
EDX contains the proper pointer to the original array.

----------------------------------

[#InsertArrayItems] `proc InsertArrayItems, .ptrArray, .iElement, .count`

This procedure inserts `[.count]` new elements at the `[.iElement]` position of the
array pointed by `[.ptrArray]`

If `[.iElement]` is larger or equal to `[TArray.count]` the elements are appended
at the end of the array. (Just like AddArrayItems) Otherwise, all elements are
moved to make room for the new elements.

The procedure returns exactly the same results as AddArrayItems procedure — EDX
points to the array and EAX points to the first of the new inserted elements.

CF is an error flag.

---------------------------------

[#GetArrayItem] `proc GetArrayItem, .array, .item`

CF=0; Returns in EAX pointer to the array item with index `[.item]`.

CF=1; The requested item does not exists ( `[.item]` >= `[.array.count]` ). In this case,
EAX contains pointer to the end of the array the byte next after the last array element.

---------------------------------

[#DeleteArrayItems] `proc DeleteArrayItems, .ptrArray, .iElement, .count`

This procedure deletes `[.count]` items with begin index `[.iElement]` the `[.ptrArray]`
dynamic array. If the capacity of the array is bigger than the recommended for
the new count, then the array is resized. The recommended size is calculated
using ResizeIt procedure from memory library.

Returns EDX - pointer to the TArray. In the most cases this pointer will not be
changed, but this also depends on the current OS memory allocation API, so it
is safer to store the pointer for future use, instead of one passed to the
procedure.

This procedure can not fail, because deleting element is always possible. In
some rare cases it can fail to reallocate smaller memory block, but this is
not a problem for the array consistency.

---------------------------

[#VacuumArray] `proc VacuumArray, .ptrArray`

This procedure removes the reserved memory from the array in order to make it
as small as possible.
Note, that the first insert/append operation after the vacuum operation will be very slow.
The memory economized this way depends on reallocation strategy and can be from 25 to 100% in some cases.

--------------------------

[#ListIndexOf] `proc ListIndexOf, .ptrList, .Item`

The list is a special case of array with item size equal to 4 bytes (dword).
This procedure searches the list `[.ptrList]` for item equal to `[.Item]` and
returns the index of the element in EAX. In case of error CF=1.

---------------------------

[#ListFree] `proc ListFree, .ptrList, .FreeProc`

Frees all elements of the list `[.ptrList]`, calling `[.FreeProc]` for every
element of the list.

FreeProc callback procedure have one argument of type dword that is the value
of the current list element. The definition of the callback procedure is similar
to following:

;begin
    proc FreeMyListItem, .ptrItem
    begin
            ;do something with the item being freed
            return
    endp
;end


-----------------


### "strlib.asm" library 

[#StrLib]

Using strings in assembler was often problematic for programmers - static
strings can't be resized, so they had to reserve as many bytes as they thought
user could need, and it still could be not enough. For that reason we created
Dynamic String Library - a library that operates on dynamic strings, that are
automatically resized when needed. Also, StrLib contains many functions that
perform different string operations — comparison, inserting one string into
another, etc.
In StrLib, the strings are represented by handles, not by pointers. This way,
the string can be freely resized and moved in memory.
StrLib can distinguish the handle values from pointer and will process properly
both of them. When the processing is possible, the procedures will operate
on static strings in memory.

[#StrLib string format]

The strings in the StrLib are stored in specific format. The format is defined
following way:
;begin
    struc string {
      .capacity dd ?
      .len      dd ?
      label .data byte
    }

    virtual at -(sizeof.string)
      string string
      sizeof.string = $-string
    end virtual
;end
The structure string have variable length and is dynamically allocated.

The field *string.capacity* on offset `-8` contains the allocated memory size in bytes.

The field *string.len* on offset `-4` contains the current length of the string in bytes.

The string content begins on offset 0. The content of the string always ends with at least one
zero byte, so the string format is compatible with ASCIIZ format used in the most OS API.

All procedures in StrLib will set `[string.len]` to the proper value and will use it in the
string processing.

If the programmer manipulates the string data directly, he should set `[string.len]` himself, or
call [#StrFixLen] in order to let StrLib to scan the string and to fix the length field.


[#StrLib procedures]

StrLib procedure reference:

[#StrNew]
;begin
        proc StrNew
;end
Creates new dynamic string and returns its handle.

[#StrDel]
;begin
        proc StrDel, .hstring
;end
Frees the memory occupied by given string. If the .hstring is pointer to memory, StrDel
will try to find it in the table of created strings and if found, will free it as well.
If the string passed by pointer is not found in the list - StrDel exits without error.
Note, that passing pointer can degrade the performance of the procedure.

[#StrPtr]
;begin
        proc StrPtr, .hstring
;end
Returns in EAX the pointer of the string with handle `[.hstring]`
If .hstring is pointer EAX will be equal to `[.hstring]`
If the handle is invalid, StrPtr returns CF=1 and EAX=0.


[#StrLen]
;begin
        proc StrLen, .hstring
;end
Returns the length of the string in bytes, excluding the terminating zero.
If `[.hstring]` is handle, the procedure returns directly the stored length of the string.
If `[.hstring]` is pointer, the functions scans the string and computes the length.
Thus, passing handle is much faster, especially for long strings.


[#StrDup]
;begin
        proc StrDup, .hstring
;end
Creates new string and copy the content of `[.hstring]` to it.
Returns in EAX — handle of the new string.
`[.hstring]` can be memory pointer or string handle.



[#StrFixLen]
;begin
        proc StrFixLen, .hstring
;end
StrFixLen scans the string in order to compute its actual length and then writes this length
in the field `[string.len]`.
StrFixLen should be call only with handle of the string as argument. It will process pointer as
well, but will assume there is a field `[string.len]` at offset `-4`.
The user should call StrFixLen only if the `[string.len]` field does not contains the proper value,
because of some reason - for example the user made some string processing that changes the length
of the string or the string data is returned by some OS function that does not care about string
length.


[#StrSetCapacity]
;begin
        proc StrSetCapacity, .hString, .capacity
;end
This function ensures that the allocated for the string memory is enough to hold at least
`[.capacity]` bytes. If needed the string memory is reallocated.
Returns pointer to the string data in EAX.
If the reallocation is impossible, returns CF=1;


[#StrCopy]
;begin
    proc StrCopy, .dest, .source
;end

Copies the content of `[.source]` string to `[.dest]` string.
`[.dest]` must be a handle.
`[.source]` can be handle or pointer.
Returns nothing.



[#StrCompCase]
[#StrCompNoCase]
;begin
    proc StrCompCase, .str1, .str2
    proc StrCompNoCase, .str1, .str2
;end
Compares two strings - case sensitive (StrCompCase) or string not sensitive (StrCompNoCase).

Returns CF = 1 if the strings are equal.

Returns CF = 0 if the strings are different.

The speed of this procedure varies depending on passed strings and its content.
The worst case is when the strings are passed as pointers and have equal lengths.
The best case is when the strings are passed as handles and have different lengths.


[#StrCat]
;begin
    proc StrCat, .dest, .source
;end
Concatenates the string `[.source]` to the end of the string `[.dest]`.

[#StrCharPos]
;begin
    proc StrCharPos, .hString, .char
;end
StrCharPos returns a pointer to the first occurence of a given char in specified string.

[#StrPos]
;begin
    proc StrPos, .hstring, .hpattern
;end
StrPos returns in EAX a pointer to the first occurence of a `[.hpattern]` string in
`[.hstring]` or NULL if the pattern was not found.


[#StrCopyPart]
;begin
    proc StrCopyPart, .dest, .source, .pos, .len
;end
Extracts `[.len]` bytes on position `[.pos]` from the string `[.source]` and copies them
to the string `[.dest]`.
Returns CF=1 if the needed memory can not be allocated.


[#StrExtract]
;begin
    proc StrExtract, .string, .pos, .len
;end
Extracts `[.len]` bytes on position `[.pos]` from the string `[.source]` and copies them
to the new created string.
Returns the created string in EAX or CF=1 if the needed memory can not be allocated.


[#StrSplit]
;begin
    proc StrSplit, .hString, .pos
;end
Splits the string `[.hstring]` into two parts on byte possition `[.pos]`.
The left part remains in `[.hstring]`; The right part is returned as new created string in EAX.
Note that the memory of the `[.hstring]` will not be reallocated, only the length of the string
will be set accordingly.


[#StrInsert]
;begin
    proc StrInsert, .dest, .source, .pos
;end
Inserts the `[.source]` string on possition `[.pos]` into the `[.dest]` string.
Returns nothing.


[#NumToStr]
;begin
    proc NumToStr, .num, .flags
;end
Converts number `[.num]` in any radix to string.
Returns the new created string in EAX.

`[.flags]` controls the way number have to be converted.
.flags is dword value that contains following values:

byte0 - number of digits if ntsFixedWidth is specified.

byte1 - radix for the convertion. Some radixes have predefined constants:
;begin
    ntsBin  = $0200
    ntsQuad = $0400
    ntsOct  = $0800
    ntsDec  = $0a00
    ntsHex  = $1000
;end

byte2, byte3 - flags:
;begin
    ntsSigned       = $00000
    ntsUnsigned     = $10000
    ntsFixedWidth   = $20000
;end

[#StrToNumEx]
;begin
    proc StrToNumEx, .hstring
;end
Converts `[.hstring]` to number.
Returns CF=0 and value in EAX if the conversion was successful, or
CF=1 and EAX = 0 if not.

The procedure supports the FASM numbers format:

`0x1111`, `$1111` or `1111h` will be converted as HEX;

`1111` as decimal;

`1111b` as binary;

`1111o` as octal.


[#StrCharCat]
;begin
    proc StrCharCat, .hString, .char
;end
Appends up to 4 bytes fro `[.char]` at the end of `[.hString]`


[#StrCharInsert]
;begin
    proc StrCharInsert, .hString, .char, .pos
;end
Inserts up to 4 characters from `[.char]` into the `[.pos]` position of the `[.hString]`


[#StrClipSpacesR]
[#StrClipSpacesL]

;begin
    proc StrClipSpacesR, .hString
    proc StrClipSpacesL, .hString
;end

Removes the spaces from the start (StrClipSpacesL) or from the end (StrClipSpacesR)
of the string `[.hString]`.


[#StrCleanDupSpaces]
;begin
    proc StrCleanDupSpaces, .hString
;end
Removes duplicating spaces from the string `[.hStrin]` and leaves only single spaces.
For example the string ("." represents the space char) "123.....456" will be processed to "123.456".

[#StrHash]
;begin
    proc StrHash, .hString
;end
Computes the hash value from the string `[.hString]`.
This procedure implements FNV-1b algorithm.

Returns 32 bit hash value in EAX.


[#DataHash]
;begin
    proc DataHash, .ptrData, .len
;end
Computes the hash value from the memory array at address `[.ptrData]` with byte length `[.len]`.
This procedure also uses FNV-1b algorithm.

Returns 32 bit hash value in EAX.


[#StrLenUtf8]
;begin
    proc StrLenUtf8, .hString, .len
;end
Computes the length in chars of the first `[.len]` bytes of the UTF-8 encoded string `[.hString]`
The scan of the string ends on one of the two conditions — terminating zero byte
is reached or `[.len]` bytes are processed. So, if `[.len] == -1` the scan will always end on the
end of the string.


[#StrOffsUtf8]
;begin
    proc StrOffsUtf8, .hString, .pos
;end
Returns in EAX the address of the `[.pos]` character of the UTF-8 encoded string `[.hString]`
If the length of the string is less than `[.pos]` — returns NULL.


[#DecodeUtf8]
;begin
    proc DecodeUtf8, .chars
;end
Decodes 4 bytes in `[.chars]` to UNICODE dword value.

Returns:
`CF=0` — no error; eax — unicode value; edx — byte count of the char. `[1..4]`

`CF=1` — invalid utf-8 char; if eax = edx = 0;  the character can not be decoded;
if edx <> 0 — eax = the overlong encoded character. edx = byte count of the char.

*Note:* When CF=1 and `[.chars]` is overlong encoded char, eax contains the proper
value and edx contains the proper length. But it is still invalid character, according
to the standards.

[#ExpandTabs]
;begin
    proc ExpandTabs, .hstring, .tabstop
;end

Converts the tab characters in `[.hstring]` into space characters, according to `[.tabstop]` length.
Returns in EAX a value, that indicates by how many chars the length of the string increased.


-----------------


### "uConfig.asm" library 

uCongig library is implementation of small [hierarchical] database engine, intended to keep program settings and
preferences in OS independent manner.
The data in the uConfig database have tree structure similar to the file system directory structure
or to Windows registry structure.
Every record or directory in the database has its own key — dword value.
Usually it is convenient to use as a key 4 char ASCII string in order to be human readable, but
it is not mandatory.
;quote
The uConfig format is not "human readable", "universal", "super-puper", etc.
It was designed with only two aims:

1. Small and simple engine, suitable to be used from assembly.

2. Relatively robust database format.

So, if someone wants some new advanced features - these features should make the engine
smaller or at least to keep its current size.
;end

[hierarchical] http://en.wikipedia.org/wiki/Hierarchical_database_model

The database have two representations — packed "file representation" and
expanded "memory representation".
Database operations can be provided only on expanded form.

The base of the database is TConfigRecord structure. The database itself is an array of
TConfigRecords.

[#TConfigRecord]
;begin
    struct TConfigRecord
      .KeyName  dd ?
      .DataSize dd ?
      .Type     dd ?
      .Data     dd ?
    ends
;end
The fields have following meaning:

* .KeyName — contains the key of the record.

* .DataSize — the size of the data in bytes if .Data field contains pointer to the data.

* .Type is one of the following values:
;quote
*  cdtNULL     = 0
*  cdtInteger  = 1  — .Data contains the number.
*  cdtString   = 2  — .Data contains string handle (see [#StrLib])
*  cdtBlob     = 3  — .Data contains pointer to the blob data. .DataSize — its size
*  cdtConfig   = 4  — .Data contains pointer to the [#TArray] of TConfigRecords — i.e. uConfig database.
;end
* .Data — data value if fits in dword or pointer to the data for the bigger formats.

There are number of procedures intended to provide manipulation of uConfig database:

[#LoadCongigDB]
;begin
    proc LoadConfigDB, .ptrSource, .signature
;end
Loads the "file representation" of database and expands it to "memory representation".
".signature" is DWORD value, that identifies the database. The signature is actually 8 bytes long —
the first dword identify the file as a uConfig database and the second dword are user defined.

The procedure returns:

CF=0; EAX = pointer to the root level of the expanded database

CF=1; Database error:
;quote
EAX = `-1` : Bad signature

EAX = `-2` : Damaged database. Some control sum is wrong.
;end


[#SaveConfigFile]
;begin
    proc SaveConfigFile, .ptrRoot, .signature
;end
Creates "file representation" of the database as a memory TArray of dword. The user have to save
this image to the file if needed.

* .ptrRoot is pointer to TArray ot TConfigRecord.

* .signature if the desired signature for the database file.

The procedure returns pointer to TArray. The user should free it later.


[#FreeConfigDB]
;begin
    proc FreeConfigDB, .ptrRoot
;end
Frees the uConfig database and all its records.

[#GetConfigParam]
;begin
    proc GetConfigParam, .ptrConfig, .pDirectory, .name
;end
Search the database `[.ptrConfig]` for the record with keyname `[.name]`

Returns EAX = poiner to the TConfigRecord or NULL if the record is missing.

`[.pDirectory]` should point to the zero terminated array of dwords with the path to the directory
of the needed record. `[.pDirectory]` can be NULL.

[#GetConfigParam.AsString]
;begin
    proc GetConfigParam.AsString, .ptrConfig, .pDirectory, .name
;end
Returns handle to string with textual representation of the value of the database record.
The user have to free this string later with [#StrDel].
This procedure is intended to be use for screen display of the values of the database.
Depending on the type of the field it returns:

 *  cdtNULL — "NULL"

 *  cdtInteger  — The number converted to decimal string.

 *  cdtString   — A copy of the string.

 *  cdtBlob — "BLOB"

 *  cdtConfig  — "SDIR"


[#DelConfigParam]
;begin
    proc DelConfigParam, .ptrVarConfig, .pDirectory, .name
;end
Deletes the specified config record. Returns nothing.



[#SetConfigParam]
;begin
    proc SetConfigParam, .ptrVarConfig, .pDirectory, .name, .type, .value, .size
;end
Set the value of the given config record. If the record exists, the value will be changed.
If the record with the given name does not exists, it will be created.
Returns error in CF. If CF=1 the specified directory does not exists.



-----------------


### "memstream.asm" library 


-----------------


## FreshLib directory "graphics/"

The graphics library provides procedures that draw graphics images and text on
the screen. The library is OS dependent and is placed in the directory
"graphics" in the root directory of FreshLib.

The main conception of this library is ".raster" - represented by handle
object, where the drawing happens. 

The exact meaning for this object is
different for the different OSes — in Win32 it is named "device context", in
Linux it is "drawable" - window or pixmap.

--------------------

### "context.asm" library 


--------------------

### "draw.asm" library 

--------------------

### "fonts.asm" library 

--------------------

### "text.asm" library 

--------------------

### "images.asm" library 

--------------------

### "giflib.asm" library 

--------------------

### "backbuffer.asm" library 

--------------------

## FreshLib directory "mouse/" 

-------------------

### "mouse.asm" library 

------------------

## FreshLib directory "GUI/" 


This directory contains the libraries providing portable GUI for assembly
programming.

Note that these libraries are in very early stage of development, so the
description in this chapter is preliminary and probably will be changed in
one or another way in the near future.

The main idea behind the GUI library is to make one small OS dependent layer of
functions, that to serve as an interface between the OS and the OS independent
layer of the library.

The first will translate OS events, such as mouse, keyboard, timers etc to one
common standard of OS independent event handlers of the user interface
objects — windows, buttons and other widgets.

The biggest advantage of this approach is that the porting of the library
is very easy — most of the code is OS independent and only little part of it
have to be rewriten in order to port the whole library to a new OS.

The biggest drawback of this approach is the bigger size of the library,
because, with this architecture, all controls in the library have to be created
from scratch. It is impossible to use graphic controls that the OS provides —
particularly Win32 controls - buttons, simple text editors, labels, combo boxes
list and tree view controls etc.

This library is not aimed to use all complex GUI system of the target OS.
At first time, the goal of Fresh GUI library is to provide minimal, but decent
functionality that will do the job — writing portable GUI applications in
assembly language.

The GUI library is actually set of libraries.
These libraries defines many data structures and procedures that together, form
something that conditionally can be called "Object oriented" environment.
It is object oriented, as long as it deals with GUI "objects" - forms,
controls, menus etc.

On the other hand, the library does not limit the programmer in the way HLL OOP
limits him. The user have full access to all data structures of the program.
The "encapsulation" principle is fairly impossible in the assembly programming.

All objects in Fresh GUI library, are in fact structures of data.
For every created object, the library allocates some memory and fills this memory
with object parameters data.

There are two types of data structures that describe GUI objects - classes and
instances.

The *class* is a structure that contains data commonly used by all objects of
given type — for example all buttons use one class structure `CButton`.

*Instance* is a data structure that describes the properties and behavior of
particular GUI object — for example button with icon "open file" that opens
a file when the user click on it.

### Classes 

[#class]

*"Class"* in FreshLib is a data structure, that have the following definition:
;begin
    struct TObjectClass
      .ptrParent           dd 0
      .dataSize            dd 0
      .procCreate          dd 0
      .procDestroy         dd 0
      .procGetParam        dd 0
      .procSetParam        dd 0
      .procExecCmd         dd 0
      .procSysEventHandler dd 0
    ends
;end
`.ptrParent` is a pointer to other TObjectClass structure, that appears as a
parent class for the given class.

`.dataSize` contains the size in bytes of the object instance structure.

The following fields are pointers to procedures that provides the "engine"
of the object. All of these pointers as a rule can be NULL, if there is no need
for such processing.

[#.procCreate]

`.procCreate` is a pointer to procedure that creates instance object of the given class.
This field can be NULL. It has the following definition:
;begin
    proc Create, .obj
;end
This procedure sets needed values in the object instance data structure.

*Note:* This procedure does not allocate any memory. The needed memory block is allocated by
the [#objects] library and the pointer to this allocated block is passed to this procedure in the
argument `.obj`.

[#.procDestroy]

`.procDestroy` is a procedure that destroys an instance of the given class.
;begin
    proc Destroy, .obj
;end
Frees the memory, images, fonts and other resources, allocated for the object `.obj` during
its existence. Must not free the object itself.


[#.procGetParam]

.procGetParam is a pointer to the procedure that retrieves and returns the properties of the object.
;begin
    proc GetParam, .obj, .paramID
;end
Returns the value of the object `[.obj]` parameter with ID=`[.paramID]`

[#.procSetParam]

.procSetParam is a pointer to the procedure that set the properties of the object.
;begin
    proc Set, .obj, .paramID, .value
;end
For object `[.obj]`, set the value of the parameter with ID=`[.paramID]`


[#.procExecCmd]

.procExecCmd is a pointer to the procedure that executes object method.
;begin
    proc ExecCmd, .obj, .method
;end
For the object `[.obj]` this procedure executes the method with ID in `[.method]`.

The methods can have arbitrary number of arguments, that are defined in the
 [#object] definition (see below). When the method is executed, the procedure
`[.procExecCmd]` accepts pointer to the arguments array in the register EBX.

The user is supposed to call methods of the object with the macro "execute"
The macro is defined following way:

[#execute]
;begin
    macro execute obj*, meth*, [arg]
;end

[#.procSysEventHandler]

.procSysEventHandler is a pointer to the procedure that process the system
events that are send to the object, i.e. mouse events, keyboard events etc.
;begin
    proc SysEventHandler, .obj, .pEvent
;end
Process one system event for object `[.obj]`. `[.pEvent]` contains pointer to the
system event.

All of the above callback procedures are called internally and should not be
used by the user of the library. How these procedure are called will be described later.

TObjectClass structure is defined statically in memory, in compile time, only
once for every object class. Its definition is located in the library for the
respective GUI element. For example CButton class structure is defined in the
file TButton.asm that contains the code and data of the object class Button.

In order to make construction of such structures easy, macro with name
ObjectClass is defined in objects.asm

[#ObjectClass]
;begin
    macro ObjectClass name*, parent*,   \
                      procCreate*,      \
                      procDestroy*,     \
                      procGetParam*,    \
                      procSetParam*,    \
                      procExecCmd*,     \
                      procSysEvents*
;end
Every defined ObjectClass have a label that points to the begin of the structure.
The name of this label is the name of the class, prefixed with "C".

One example of ObjectClass definition is the definition of Window object class:
;begin
    ObjectClass Window, Object,     \
                TWindow.Create,     \
                TWindow.Destroy,    \
                TWindow.Get,        \
                TWindow.Set,        \
                TWindow.ExecCmd,    \
                TWindow.SysEventHandler
;end

This definition creates following data structure in the memory:
;begin
    CWindow:    dd  CObject
                dd  sizeof.TWindow
                dd  TWindow.Create
                dd  TWindow.Destroy
                dd  TWindow.Get
                dd  TWindow.Set,
                dd  TWindow.ExecCmd
                dd  TWindow.SysEventHandler
;end

### Object instance structure

[#object]
[#endobj]
[#instance]

Object instance is data structure that contains different fields. By that it is
very similar to the normal FASM structures. As structures, the object is only
description of the data but not the data itself.

Objects can inherit field definitions by its parent objects. The memory instance
of the object is allocated dynamically in runtime, when the object is created
by call to the respective FreshLib procedures.

The definition of the object looks like following:
;begin
    object TObject
      .ptrClass     dd ?

      .mxAccess     dd ?
      .ptrVar       dd ?

      .OnCreate     dd ?
      .OnDestroy    dd ?

      method .AddChild, .objchild
    endobj

    object TWindow, TObject
      .handle       dd ?
      .Fcaption     dd ?
      .Fcursor      dd ?

      param .x
      param .y
      param .width
      param .height
      param .visible
      param .caption
      param .parent
      param .cursor

      method .Refresh
    endobj


    object TButton, TWindow
      .state      dd ?
      .Ficon      dd ?
      .FiconAlign dd ?
      .Ftextalign dd ?

      .OnClick dd ?

      param .TextAlign
      param .Icon
      param .IconPosition
    endobj
;end

By convention the names of the objects are composed by the name of the class,
prefixed with "T".

You can see that the object TWindow contains data fields, parameters and methods.
The parameters defined by "param" macro are compile time constants which values
are assigned automatically. These constants are local labels for the object
structure.
They are also inherited from the parent structure.

The methods are very similar to parameters, in that they are constants, defined
in compile time. But besides the value, the method also have list of
arguments, passed to the method, when executed.

In the above example, TButton.width parameter is inherited from TWindow and
have the same value as TWindow.width parameter.

Also, TWindow have all fields of TObject defined as well.

If we have to translate TWindow definition in plain FASM syntax it will looks
similar to this:
;begin
    struc TWindow {
      .ptrClass     dd ?

      .mxAccess     dd ?
      .ptrVar       dd ?

      .OnCreate     dd ?
      .OnDestroy    dd ?

      .handle       dd ?
      .Fcaption     dd ?
      .Fcursor      dd ?

      .AddChild = $80000000
      .x        = $80000001
      .y        = $80000002
      .width    = $80000003
      .height   = $80000004
      .visible  = $80000005
      .caption  = $80000006
      .parent   = $80000007
      .cursor   = $80000008
      .Refresh  = $80000009
    }
    virtual at 0
      TWindow TWindow
      sizeof.TWindow = $
    end virtual
;end

------------------

### "objects.asm" library. 

[#object]

------------------


### "sysevents.asm" library 

[#sysevents.asm]

This library contains event codes and data structures for FreshGUI OS independent
events. For now only several events are defined:
;begin
    ; mouse events
    seMouseMove
    seMouseEnter
    seMouseLeave
    seMouseBtnPress
    seMouseBtnRelease
    seMouseBtnClick
    seMouseBtnDblClick

    ; keyboard events
    seKbdKeyPress
    seKbdKeyRelease
    seKbdStatusChanged
    seKbdChar

    ; Window handling events
    sePaint
    seScroll
    seFocusIn
    seFocusOut
    seMoveResize
;end
These events cover mouse, keyboard and window appearance and behavior events.

Every event have some arguments that have to be sent to the recipient event handler.
The event code and the event arguments are contained in data structure, defined for
every kind of events.

The first dword of the event structure is the field .event that contains the
event code.

Here are the structures defined in sysevents.asm


[#TSysEvent]
;begin
    struct TSysEvent
      .event  dd  ?
    ends
;end
The base event structure. The field `.event` contains the code of the event, as described above.


[#TMouseMoveEvent]
;begin
    struct TMouseMoveEvent
      . TSysEvent
      .x         dd ?
      .y         dd ?
    ends
;end
The event is generated when the mouse cursor moves over some window.
The fields `.x` and `.y` contains the coordinates of the mouse cursor relative to
the upper-left cornet of the window, this message is sent to.


[#TMouseButtonEvent]
;begin
     struct TMouseButtonEvent
      . TSysEvent
      .Button    dd ?
      .kbdStatus dd ?
    ends
;end
This event is generated when some of the mouse buttons changes its state.
The button that changes its state is specified in the field `.Button`.

This field can accept following values:
;begin
    mbLeft      = 0
    mbMiddle    = 1
    mbRight     = 2
;end
The field `.kbdStatus` contains the status of remaining mouse buttons and
keyboard modifying buttons. These buttons are represented by bits in the field:
;begin
    maskBtnLeft     = $0100
    maskBtnMiddle   = $0200
    maskBtnRight    = $0400
    maskCtrl        = $0800
    maskShift       = $1
    maskCapsLock    = $2
    maskCtrl        = $4
    maskAlt         = $8
    maskScrLk       = $10
;end

[#TMouseEnterEvent]
;begin
    struct TMouseEnterEvent
      . TSysEvent
    ends
;end
This event is generated when the mouse cursor enters or leaves some control.
There is no additional parameters besides the event code.


[#TKeyboardEvent]
;begin
    struct TKeyboardEvent
      . TSysEvent
      .key       dd  ?
      .kbdStatus dd  ?
    ends
;end

This event is generated on keyboard button press/release. The field `.key` contains
the code of the pressed button. `.kbdStatus` have the same meaning and the same
values as in TMouseButtonEvent.


[#TPaintEvent]
;begin
    struct TPaintEvent
      . TSysEvent
      .context dd ?
      .rect    RECT
    ends
;end
TPaintEvent is generated when given control have to be repainted. The field `.context`
contains a pointer to [#TContext] structure where the program have to draw.

The field `.rect` is the rectangle of the control that needs to be repainted.


[#TScrollEvent]
;begin
    struct TScrollEvent
      . TSysEvent
      .ScrollBar  dd ?      ; 0
      .ScrollCmd  dd ?      ;
      .Value      dd ?      ; Distance for scUp and scDown and position for scTrack
    ends
;end
This event is sent to the window when it needs to be scrolled.
The field `.ScrollBar` have value 0 for the horizontal scrolling and 1 for vertival.
There are defined constants for these values:
;begin
    scrollX = 0
    scrollY = 1
;end
The field `.ScrollCmd` can have following values:
;begin
    scTrack   = 1
    scUp      = 2
    scDown    = 3
    scWheelUp = 4
    scWheelDn = 5
;end
The field `.Value` contains the absolute position where to scroll the window, for the
command scTrack, and relative distance of the scroll for all remaining commands.


[#TCloseEvent]
;begin
    struct TCloseEvent
      . TSysEvent
      .reason dd ?          ; how the close was requested?
    ends
;end

This event is sent to the window, when the window have to be closed.
`.reason` field defines the reason for the operation. It can have following values:
;begin
    cerFromUser = 0  ;The user pressed X button on the window header, pressed alt+F4
                     from the keyboard, or choose "Close" from the title menu.

    cerFromProgram = 1 ; Method Close was executed from the program.
;end

[#TFocusEvent]
;begin
    struct TFocusInEvent
      . TSysEvent
    ends
;end
This event is sent when the window receives or lose the focus.


[#TMoveResizeEvent]
;begin
    struct TMoveResizeEvent
      . TSysEvent
      .newX  dd ?
      .newY  dd ?
      .newWidth  dd ?
      .newHeight dd ?
    ends
;end
This event is generated when the user resizes the window or moves it to another place.
The fields specify the new coordinates and sizes.


-------------------

### "main.asm" library. 

[#main.asm]

This library implements the procedures for the main program loop of the GUI application.
The modal dialogs procedure is also here.


[#Run]
;begin
    proc Run
;end
This procedure is the main program loop of the GUI application.
The procedure Run process all pending system events, then calls once the OnIdle
event handler of the [#TApplication] object and then sleeps until new events are
sent by the OS.

When the OS terminates the application — the procedure returns an exit code.

The programmer uses this procedure following way:
;begin
        stdcall Run
        push    eax             ; eax contains the exit code.

        FinalizeAll             ; free all resources.

        stdcall Terminate       ; the exit code is already in the stack.
;end

[#ShowModal]
;begin
    proc ShowModal, .pForm, .pParent
;end
Shows the form `[.pForm]` as a modal dialog window with parent window `[.pParent]` —
i.e. the parent window is disabled until the modal windows is visible.

The procedure returns the modal result in EAX. The modal result is also stored in
`TForm.ModalResult` field of the modal form.


[#ProcessSystemEvents]
;begin
    proc ProcessSystemEvents
;end
This procedure process the events generated by the OS. If there are waiting
events in the queue, the procedure reads them, translates them to FreshGUI
event data structures and calls the event handlers of the respective windows.

If there is no pending events in the queue, ProcessSystemEvents ends with CF=0

The second task this procedure serves is to detect the end of the application.
In this case it ends with CF=1.

This procedure is call from the main event loop of the application. ([#Run] procedure).
Also, the user can periodically call this procedure in order to not allow
hanging of the user interface during long processing of some data.


[#WaitForSystemEvent]
;begin
    proc WaitForSystemEvent
;end
This procedure waits until some system message is posted to the application
event queue. Then it exits. During the wait, very low CPU power is consumed
by the application.


-------------------


### "ObjTemplates.asm" library 

[#templates]

This library contains the template engine of FreshGUI.
The template engine provides creation of complex window structures with tree
layout from memory data structure, called template. The templates makes
creation of dialog windows containing children windows and non visual objects.

Templates can be visually created and edited. The template format used by
FreshLib is flexible and allows all parameters and fields of the objects to
be set to needed values during creation of the window.


The template is consisted from one or more data structures of type TObjTemplate,
defined following way:
;begin
    struct TObjTemplate
      .flags     dd  ?
      .class     dd  ?
      .ptrVar    dd  ?
      .paramsize dd  ?
      .params:
    ends
;end
`.flags` — controls what is the place of the object in the whole tree structure.
Can accept one or more of the following values, combined with OR:

`tfChild`  — means the object is a child of the last object with tfParent set.

`tfParent` — means the given object is parent and there will be at least one next
TObjTemplate structure that will be a child object.

`tfEnd` — means the given object is the last child of its parent.
Note, that one object can be parent and child in the same time.
If the current template element is at the root level — the processing of
template stops, after creating the current element and all its children.

.class - pointer to TObjectClass data structure for the created object.

.ptrVar - pointer to dword variable that to accept the pointer to the created object.

.paramsize — the size of the additional data to the end of the template.
Note, that TObjTemplate is variable length structure, not fixed. sizeof.TObjTemplate
contains the size of the header part of the structure.

.params — after the header fields there can be arbitrary count of dword pairs:
(paramID, Value) that to be set to the object during creation. This sequence
ends with dword $FFFFFF (-1) value for paramID.

Easy creation of templates is provided with macro ObjTemplate:

[#ObjTemplate]
;begin
    macro ObjTemplate  flags, class, name, [id, param]
;end
This macro allows use of string values for params and computes automatically
the values for TObjTemplate.paramsize;
The macro have following arguments:

* flags — set of (tfChild, tfParent, tfEnd) constants.

* class — the base name of the object class (without prefix C) — i.e. Form,
        Window, Button, etc.

* name — label of the variable to receive the pointer to the created object.

* id — parameter ID or offset in the object structure.

* param — value of the parameter. Can be dword number or string constant. In the
case the parameter value is string, it will be automatically created in
the memory and the pointer to this string will be placed as a param value.

One example of template structure:
;begin
    ObjTemplate  tfParent or tfEnd, Form, frmMain,      \
                             visible, TRUE,             \
                             x, 100,                    \
                             y, 50,                     \
                             width, 640,                \
                             height, 480,               \
                             caption, 'Fresh portable Win32/Linux application test.'

      ObjTemplate  tfChild, Button, btnChild1,          \
                             visible, TRUE,             \
                             x, 64,                     \
                             y, 48,                     \
                             width, 64,                 \
                             height, 24,                \
                             caption, 'Button1',        \
                             OnClick, Button1Click

      ObjTemplate  tfChild or tfEnd, Button, btnChild2, \
                             x, 136,                    \
                             y, 48,                     \
                             width, 64,                 \
                             height, 24,                \
                             caption, 'Button2' ,       \
                             visible, TRUE
;end

The template engine provides one single procedure:

[#CreateFromTemplate]
;begin
    proc CreateFromTemplate, .ptrTemplate, .parent
;end
This procedure creates all objects from the template, pointed by `[.ptrTemplate]`
as a parent of `[.parent]` argument.

`.ptrTemplate` points to TObjTemplate structure.

`.parent` points to TObject descendant structure. In most cases it will be
actually descendant of TWindow or NULL if the created object is not a child
of any window.

Returns: *EBX* contains a pointer to the topmost of the created object
(it is first of the created objects)

All pointers of the objects are stored in the specified in the template
variables ( i.e. `[TObjTemplate.ptrVar]`)


------------------

### "TObject.asm" library 

[#TObject]

This library implements TObject object class. This is the root class for all object clases in
FreshLib. It is defined following way:
;begin
    object TObject
      .ptrClass     dd ?

      .mxAccess     dd ?
      .ptrVar       dd ?

      .OnCreate     dd ?
      .OnDestroy    dd ?

      method .AddChild, .objchild
    endobj
;end

------------------

### "TApplication.asm" library 

[#TApplication]
;begin
    object TApplication, TObject
      .MainWindow   dd ?
      .Accelerators dd ?
      .OnIdle       dd ?
    endobj
;end
This object class represents the whole GUI application and handles some properties that are
application-wide. For example it keeps the main windows of the application, the list of
keyboard accelerators, etc.
Only one instance of this object must be created during the initialization of the application,
before the call of [#Run] procedure.

`.MainWindow` field is a pointer to the main window of the application. When this window is
closed, the whole application terminates as well.

`.Accelerators` fields is a pointer to a list with application-wide keyboard accelerators.

`.OnIdle` is an application callback that will be call once everytime the events queue is empty.
The user can process here some tasks that have to be processed with low priority. The usual
use of this callback is to detect what toolbar buttons and menu items have to be enabled or
disabled, depending to the current state of the program.


------------------

### "TWindows.asm" library 

[#TWindow]
;begin
    object TWindow, TObject

      .handle       dd ?

      ._x           dd ?
      ._y           dd ?
      ._width       dd ?
      ._height      dd ?

      ._visible     dd ?

      ._bounds_changed dd ?

      ._border      dd ?

      ._align       dd ?

      ._FreeArea    TBounds

      ._caption     dd ?
      ._cursor      dd ?

      .OnKeyPress   dd ?

    ; parameters

      param .x
      param .y
      param .width
      param .height

      param .Align

      param .FreeArea

      param .borderKind
      param .Zorder

      param .Visible
      param .Caption
      param .Parent
      param .Cursor
      param .Children

      method .Refresh
      method .Focus
      method .AlignChildren
      method .ToBack
      method .ToFront

      method ._ComputeFreeArea
    endobj
;end

------------------


### "TScrollWindow.asm" library 

[#TScrollWindow]

;begin
    object TScrollWindow, TWindow
      ._HScroller TScrollbar
      ._VScroller TScrollbar

      method HScrollSet, .Pos, .Max, .Page
      method VScrollSet, .Pos, .Max, .Page
    endobj
;end


------------------

### "TForm.asm" library 

[#TForm]
;begin
    object TForm, TWindow

      .ModalResult  dd ?

      .OnClose dd ?

      param .type
    endobj
;end

------------------

### "TButton.asm" library 

[#TButton]
;begin
    object TButton, TWindow
      .state      dd ?
      .Ficon      dd ?
      .FiconAlign dd ?
      .Ftextalign dd ?

      .ModalResult dd ?
      .OnClick dd ?

      param .TextAlign
      param .Icon
      param .IconPosition
    endobj
;end


------------------

### "TLabel.asm" library 

[#TLabel]
;begin
    object TLabel, TWindow
      .Ftextalign dd ?

      param .TextAlign        ; text align flags.
      param .Control          ; control that to be activated
    endobj
;end

------------------

### "TImagelabel.asm" library 

[#TImageLabel]
;begin
    object TImageLabel, TWindow
      .FImageAlign dd ?
      .FImage      dd ?
      .FMask       dd ?
      .FBackground dd ?

      param .ImageAlign
      param .Image
      param .Mask
    endobj
;end


------------------

### "TEdit.asm" library 

[#TEdit]
;begin
    object TEdit, TWindow
      ._Text  dd ?
      ._Len   dd ?  ; the length of the string in characters. (UTF-8)
      ._Start dd ?  ; Where the string begins to be displayed in the edit window.
      ._Pos   dd ?  ; Position of the caret in the string.
      ._Sel   dd ?  ; Position of the selction in the string.

      ._MarginLeft dd ?
      ._MarginRight dd ?

      ._Focused dd ? ; flag

      param .Text
    endobj
;end


------------------

### "TProgressbar.asm" library 

[#TProgress]
;begin
    object TProgress, TWindow
      ._Pos   dd ?
      ._Max   dd ?
      ._Color dd ?

      param .Pos
      param .Max
      param .Color

      method .Step
    endobj
;end

------------------

### "TTreeView.asm" library 

[#TTreeView]
;begin
    object TTreeView, TScrollWindow
      ._items dd ?
      ._first dd ?
      ._pShadow dd ?

      .OnItemDelete  dd ?

      param .Focused

      method .AddItem, .iParent
      method .DelItem, .iItem
      method .GetItem, .index
    endobj
;end

------------------

## FreshLib directory "FreshEdit/" 

This directory contains one additional control class — TFreshEdit.
It is complex and powerful text editor control, intended to be used
in the advanced programmer's text editors - such as Fresh IDE.

------------------

### "TFreshEdit.asm" library 


[#TFreshEdit]

;begin
    object TFreshEdit, TScrollWindow
      ._Font            dd  ?   ; font of the editor.

    ; main editor font sizes
      ._fontheight      dd  ?   ; in pixels.
      ._fontwidth       dd  ?   ; in pixels.
      ._fontdescent     dd  ?   ; in pixels.

    ; system font sizes (used for additional texts and line numbers)
      ._fontheight2     dd  ?   ; in pixels.
      ._fontwidth2      dd  ?   ; in pixels.
      ._fontdescent2    dd  ?   ; in pixels.

      .__LeftMargin     dd  ?   ; width of the left margin field. Auto computed.
      .__NumberMargin   dd  ?   ; width of the field for the line number. Auto computed.

      ._cols            dd  ?   ; width of the window in text columns.
      ._rows            dd  ?   ; height of the window in text rows.
                                ; must to be update on resize and on font change.

      ._pLines          dd  ?   ; pointer to TArray of TEditorLine items.
      ._pLengths        dd  ?   ; pointer to TArray with counts of the lines with given length.

      ._pUndoList       dd  ?   ; pointer to TArray of TUndoInfo
      ._pRedoList       dd  ?   ; pointer to TArray of TUndoInfo

      ._pShadow         dd  ?   ; pointer to TBackBuffer object.
      ._fShadowValid    dd  ?   ;

    ; view change fields

      ._TopLine         dd  ?   ; number of the line that is at the topmost line of the window.
      ._TopOffset       dd  ?   ; how many rows the top line is off the screen (for word wrapped lines)
      ._LeftColumn      dd  ?   ; the column of the text at the leftmost side of the window.

      ._CaretChar       dd  ?   ; the number of the char the caret resides.
      ._CaretLine       dd  ?   ; the index of the line the caret resides.

      ._SelChar         dd  ?
      ._SelLine         dd  ?

      ._fReadOnly       dd  ?
      ._SelMode         dd  ?        ; NOTE: on selmBlock, the word wrap should be OFF
      ._InsMode         dd  ?
      ._TabStop         dd  ?

    ; end change fields

      ._prevTopLine     dd  ?
      ._prevTopOffset   dd  ?
      ._prevLeftColumn  dd  ?

      ._prevCaretChar   dd  ?
      ._prevCaretLine   dd  ?

      ._prevxDelta      dd  ?
      ._prevyDelta      dd  ?

      ._prevSelMode     dd  ?
      ._prevInsMode     dd  ?

    ; end backup fields

      ._DragButton      dd  ?

      ._procSyntax      dd  ?   ; syntax highlighter procedure.

    ; icons and masks for the left margin
      ._iconBreakpointA dd  ?       ; active breakpoint icon.
      ._iconBreakpointI dd  ?       ; inactive breakpoint icon.
      ._iconDebugInfo   dd  ?
      ._maskBreakpointA dd  ?
      ._maskBreakpointI dd  ?
      ._maskDebugInfo   dd  ?
      ._iconUnfold      dd  ?
      ._iconFold        dd  ?
      ._maskUnfold      dd  ?

    ; Event handlers

      .OnControlKey     dd  ?

    ; Parameters
      param .Selection      ; selected text read/write

      param .CurrentLine    ; TEditorLine where caret resides. read only
      param .Text           ; whole text; read/write
      param .MaxLineLen

    ; Methods

      method .Clear          ; clears the text in the editor.

    ; navigation methods

      method .Move, .direction, .count, .force      ; moves the caret

      method .LineBegin
      method .LineEnd
      method .ScreenBegin
      method .ScreenEnd
      method .FileBegin
      method .FileEnd

    ; editing methods

      method .DeleteSel
      method .InsertLine, .index    ; index = -1 inserts at current position of the caret.
                                    ; index = -2 appends the line at the end of the text.
      method .DeleteLine, .index    ; index = -1 deletes the line on the current position of the caret.

    ; block processing methods.
      method .DeleteText, .lineFrom, .charFrom, .lineTo, .charTo, .BlockKind
      method .GetText, .lineFrom, .charFrom, .lineTo, .charTo, .BlockKind

    ; Undo/Redo functions.

      method .RegisterForUndo, .operation, .data

      method .Undo
      method .Redo

      method .ClearUndo

    ; these two methods are flexible, but very slow.
    ; .Text parameter seting is fastest way to change whole text of the editor.

      method .InsertChar, .char
      method .InsertString, .hstring    ; inserts a string at the caret position.
                                        ; If the string contains formating chars they are
                                        ; processed properly.
      method .DelChar      ; deletes the char under the caret.

    ; format and appearance methods
      method .FormatLine, .index

    ; themes methods

      method LoadTheme, .configdb, .directory

    endobj
;end

------------------

### "fasm_syntax.asm" library 


[#SyntaxFASM]
;begin
    proc SyntaxFASM, .hString, .pAttr, .SynContext
;end


------------------
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted doc/source/FASM.TEX.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
\documentclass[a4paper,12pt]{book}

\usepackage[pdftex,bookmarks=true,hidelinks,pdfstartview=FitH]{hyperref}

\usepackage{longtable}

\usepackage{anysize}
\makeindex

\begin{document}
\author{Tomasz Grysztar}
\title{flat assembler 1.70\\\small{Programmer's Manual}}
\date{}
\maketitle


\chapter{Introduction}
This chapter contains all the most important information you need to begin
using the flat assembler. If you are experienced assembly language programmer,
you should read at least this chapter before using this compiler.

\section{Compiler overview}
Flat assembler is a fast assembly language compiler for the x86
architecture processors, which does multiple passes to optimize
the size of generated machine code. It is self--compilable and
versions for different operating systems are provided. They are
designed to be used from the system command line and they should
not differ in behavior.

This document describes also the IDE version designed for the
Windows system, which uses the graphical interface instead of
console and has the integrated editor. But from the compilation point of view
it has exactly the same functionality as all the
console versions, and so later parts (beginning from
\ref{sec:syntax}) of this document are common with other releases.
The executable of the IDE version is called \verb"fasmw.exe",
while \verb"fasm.exe" is the command line version.

\subsection{System requirements}
All versions require the x86 architecture 32--bit processor (at
least 80386), although they can produce programs for the x86
architecture 16--bit processors, too. Windows console version
requires any Win32 operating system, while Windows GUI version
requires the Win32 GUI system version 4.0 or higher, so it should
run on all systems compatible with Windows 95.

The example source provided with this version require you have
environment variable \verb"INCLUDE" set to the path of the
\verb"include" directory, which is the part of flat assembler
package. If such variable already exists in your system and
contains paths used by some other program, it's enough to add the
new path to it (the different paths should be separated with
semicolons). If you don't want to define such variable in the
system, or don't know how to do it, you can set it for the flat
assembler IDE only by editing the \verb"fasmw.ini" file in its
directory (this file is created by \verb"fasmw.exe" when it's
executed, but you can also create it by yourself). In this case
you should add the \verb"Include" value into the
\verb"Environment" section. For example, when you have unpacked
the flat assembler files into the \verb"c:\fasmw" directory, you
should put the following two lines into your
\verb"c:\fasmw\fasmw.ini" file:
\begin{verbatim}
[Environment]
Include = c:\fasmw\include
\end{verbatim}
If you don't define the \verb"INCLUDE" environment variable
properly, you will have to manually provide the full path to the
Win32 includes in every program you want to compile.

\subsection{Compiler usage}
To start working with flat assembler, simply double click on the icon of \verb"fasmw.exe" file,
or drag the icon of your source file onto it. You can also later open new source files with
the \emph{Open} command from the \emph{File} menu, or by dragging the files into the editor window.
You can have multiple source files opened at one time, each one is represented by one tab button
at the bottom of the editor window. To select file for editing, click on the corresponding tab
with left mouse button. Compiler by default operates on the file you are currently editing, but you
can force it to always operate on some particular file by clicking the appropriate tab with right mouse
button and selecting the \emph{Assign} command. Only single file can be assigned to compiler at one time.

When your source file is ready, you can execute the compiler with \emph{Compile} command from the
\emph{Run} menu. When the compilation is successful, compiler will display the summary of compilation
process; otherwise it will display the information about error that occurred. Compilation summary
includes the information of how many passes was done, how much time it took, and how many bytes were
written into destination file. It also contains a text field called \emph{Display}, in which will
appear any messages from the \verb"display" directives in source (see \ref{sec:other}). Error
summary consists at least of the error message and a text field \emph{Display}, which has the same
purpose as above. If error is related to some specific line of source code, the summary contains also
a text field \emph{Instruction}, which contains the preprocessed form of instruction that caused an
error if the error occured after the preprocessor stage (otherwise it's empty) and the \emph{Source}
list, which shows location of all the source lines related to this error, when you select a line from
this list, it will be at the same time selected in the editor window (if file which contains that line
is not loaded, it will be automatically added).

The \emph{Run} command also executes the compiler, and in case of successful compilation it runs the
compiled program if only it is one of the formats that can be run in Windows environment, otherwise
you'll get a message that such type of file cannot be executed. If an error occurs, compiler displays
information about it in the same form as if the \emph{Compile} command was used.

If the compiler runs out of memory, you can increase the memory allocation in the \emph{Compiler setup}
dialog, which you can start from the \emph{Options} menu. You can specify there the amount of kilobytes
that the compiler should use, and also the priority of the compiler's thread.

If you want only one instance of program to be running, add
the \verb"OneInstanceOnly=1" setting to the \verb"Options" section
of the \verb"fasmw.ini" file.

\subsection{Keyboard commands in editor}
This section lists the all keyboard commands available when working with
editor. Except for the keys listed as specific ones, they are common with the
DOS IDE for flat assembler.

\subsubsection{Movement:}
\begin{longtable}[l]{p{4cm}l}
    Left arrow       & move one character left \\
    Right arrow      & move one character right \\
    Up arrow         & move one line up \\
    Down arrow       & move one line down \\
    Ctrl+Left arrow  & move one word left \\
    Ctrl+Right arrow & move one word right \\
    Home             & move to the beginning of line \\
    End              & move to the end of line \\
    PageUp           & move one page up \\
    PageDown         & move one page down \\
    Ctrl+Home        & move to the first line of page \\
    Ctrl+End         & move to the last line of page \\
    Ctrl+PageUp      & move to the first line of text \\
    Ctrl+PageDown    & move to the last line of text \\
\\
\multicolumn{2}{l}{Each of the movement keys pressed with Shift selects text.}
\end{longtable}

\subsubsection{Editing:}
\begin{longtable}[l]{p{4cm}l}
    Insert         &  switch insert/overwrite mode \\
    Alt+Insert     &  switch horizontal/vertical blocks \\
    Delete         &  delete current character \\
    Backspace      &  delete previous character \\
    Ctrl+Backspace &  delete previous word \\
    Alt+Backspace  &  undo previous operation (also Ctrl+Z) \\
    Ctrl+Y         &  delete current line \\
    F6             &  duplicate current line \\
\end{longtable}

\subsubsection{Block operations:}
\begin{longtable}[l]{p{4cm}l}
    Ctrl+Insert  & copy block into clipboard (also Ctrl+C) \\
    Shift+Insert & paste block from the clipboard (also Ctrl+V) \\
    Ctrl+Delete  & delete block \\
    Shift+Delete & cut block into clipboard (also Ctrl+X) \\
    Ctrl+A       & select all text \\
\end{longtable}

\subsubsection{Search:}
\begin{longtable}[l]{p{4cm}l}
    F5       & go to specified position (also Ctrl+G) \\
    F7       & find (also Ctrl+F) \\
    Shift+F7 & find next (also F3) \\
    Ctrl+F7  & replace (also Ctrl+H) \\
\end{longtable}

\subsubsection{Compile:}
\begin{longtable}[l]{p{4cm}l}
    F9       & compile and run \\
    Ctrl+F9  & compile only \\
    Shift+F9 & assign current file as main file to compile \\
    Ctrl+F8  & compile and build symbols information \\
\end{longtable}

\subsubsection{Other keys:}
\begin{longtable}[l]{p{4cm}l}
    F2              & save current file \\
    Shift+F2        & save file under a new name \\
    F4              & load file \\
    Ctrl+N          & create new file \\
    Ctrl+Tab        & switch to next file \\
    Ctrl+Shift+Tab  & switch to previous file \\
    Alt+[1-9]       & switch to file of given number \\
    Esc             & close current file \\
    Alt+X           & close all files and exit \\
    Ctrl+F6         & calculator \\
    Alt+Left arrow  & scroll left \\
    Alt+Right arrow & scroll right \\
    Alt+Up arrow    & scroll up \\
    Alt+Down arrow  & scroll down \\
    Alt+Delete      & discard undo information \\
\end{longtable}

\subsubsection{Specific keys:}
\begin{longtable}[l]{p{4cm}l}
    F1     & search for keyword in selected help file \\
    Alt+F1 & contents of selected help file \\
\end{longtable}

\subsection{Editor options}
In the \emph{Options} menu resides also a list of editor options, which may be turned on or off and
affect the behavior of editor. This section describes these options.

\emph{Secure selection} -- when you turn this option on, the selected block never
gets deleted when you start typing. When you do any text--changing operation,
the selection is cancelled, not affecting in any way the text that was
selected, and then the command is performed. When this option is off and you
start typing, the current selection is discarded, also Del key simply deletes
the selected block (when secure selection is on you have to use Ctrl+Del).

\emph{Automatic brackets} -- when you type any of the opening brackets, the closing
one is automatically put just after caret.

\emph{Automatic indents} -- when you press Enter to start a new line, the caret is
moved into the new line at the same position, where in the previous line the
first non-blank character is placed. If you are breaking the line, and there
were some non-blank characters after the caret when you pressed Enter, they
are moved into the new line at the position of indent, any blank characters
that were between the caret and them are ignored.

\emph{Smart tabulation} -- when you press Tab, it moves you to the position just
below the next sequence of non-blank characters in the line above starting
from the position just above where you were. If no such sequence is found in
line above, the standard tabulation size of 8 characters is used.

\emph{Optimal fill on saving} -- with this option enabled, when the file is saved,
all blank areas are filled with the optimal combination of tabs and spaces to
get the smaller file size. If this option is off, the blank areas are saved as
filled with spaces (but the spaces at the ends of lines are not saved).

\emph{Revive dead keys} -- when this option is turned on, it disables inside the
editor the so--called
dead keys (keys that don't immediately generate the character, but wait for a next key
to decide what character to put -- usually you enter the character of a dead key by
pressing a space key after it). It may be useful if key for entering some of the characters that
you need to enter often into assembly source is a dead key and you don't need this
functionality for writing programs.

\subsection{Executing compiler from command line}
To perform compilation from the command line you need to execute
the \verb"fasm.exe" executable, providing two parameters -- first
should be name of source file, second should be name of
destination file. If no second parameter is given, the name for
output file will be guessed automatically. After displaying short
information about the program name and version, compiler will read
the data from source file and compile it. When the compilation is
successful, compiler will write the generated code to the
destination file and display the summary of compilation process;
otherwise it will display the information about error that
occurred.

The source file should be a text file, and can be created in any
text editor. Line breaks are accepted in both DOS and Unix
standards, tabulators are treated as spaces.

In the command line you can also include \verb"-m" option followed
by a number, which specifies how many kilobytes of memory flat
assembler should maximally use. In case of DOS version this
options limits only the usage of extended memory. The \verb"-p"
option followed by a number can be used to specify the limit for
number of passes the assembler performs. If code cannot be
generated within specified amount of passes, the assembly will be
terminated with an error message. The maximum value of this
setting is 65536, while the default limit, used when no such
option is included in command line, is 100. It is also possible to
limit the number of passes the assembler performs, with the
\verb"-p" option followed by a number specifying the maximum
number of passes.

There are no command line options that would affect the output of
compiler, flat assembler requires only the source code to include
the information it really needs. For example, to specify output
format you specify it by using the \verb"format" directive at the
beginning of source.

\subsection{Command line compiler messages}
As it is stated above, after the successful compilation, the
compiler displays the compilation summary. It includes the
information of how many passes was done, how much time it took,
and how many bytes were written into the destination file. The
following is an example of the compilation summary:
\begin{verbatim}
flat assembler  version 1.70 (16384 kilobytes memory)
38 passes, 5.3 seconds, 77824 bytes.
\end{verbatim}
In case of error during the compilation process, the program will
display an error message. For example, when compiler can't find
the input file, it will display the following message:
\begin{verbatim}
flat assembler  version 1.70 (16384 kilobytes memory)
error: source file not found.
\end{verbatim}
If the error is connected with a specific part of source code, the
source line that caused the error will be also displayed. Also
placement of this line in the source is given to help you finding
this error, for example:
\begin{verbatim}
flat assembler  version 1.70 (16384 kilobytes memory)
example.asm [3]:
        mob     ax,1
error: illegal instruction.
\end{verbatim}
It means that in the third line of the \verb"example.asm" file
compiler has encountered an unrecognized instruction. When the
line that caused error contains a macroinstruction, also the line
in macroinstruction definition that generated the erroneous
instruction is displayed:
\begin{verbatim}
flat assembler  version 1.70 (16384 kilobytes memory)
example.asm [6]:
        stoschar 7
example.asm [3] stoschar [1]:
        mob     al,char
error: illegal instruction.
\end{verbatim}
It means that the macroinstruction in the sixth line of the
\verb"example.asm" file generated an unrecognized instruction with
the first line of its definition.

\subsection{Output formats}
By default, when there is no \verb"format" directive in source file, flat
assembler simply puts generated instruction codes into output, creating this
way flat binary file. By default it generates 16--bit code, but you can
always turn it into the 16--bit or 32--bit mode by using \verb"use16" or
\verb"use32" directive. Some of the output formats switch into 32--bit mode,
when selected -- more information about formats which you can choose can be
found in \ref{sec:formatter}.

The extension of destination file is chosen automatically by compiler, depending
on the selected output format.

All output code is always in the order in which it was entered into the
source file.

\section{Assembly syntax}
\label{sec:syntax}
The information provided below is intended mainly for the assembler
programmers that have been using some other assembly compilers before.
If you are beginner, you should look for the assembly programming tutorials.

Flat assembler by default uses the Intel syntax for the assembly
instructions, although you can customize it using the preprocessor
capabilities (macroinstructions and symbolic constants). It also has its own
set of the directives -- the instructions for compiler.

All symbols defined inside the sources are case--sensitive.

\begin{table}[h]
\begin{center}\begin{tabular}{|c|c|c|}
\hline
Operator & Bits & Bytes \\
\hline \hline
\verb"byte" & 8 & 1 \\
\verb"word" & 16 & 2 \\
\verb"dword" & 32 & 4 \\
\verb"fword" & 48 & 6 \\
\verb"pword" & 48 & 6 \\
\verb"qword" & 64 & 8 \\
\verb"tbyte" & 80 & 10 \\
\verb"tword" & 80 & 10 \\
\verb"dqword" & 128 & 16 \\
\verb"xword" & 128 & 16 \\
\verb"qqword" & 256 & 32 \\
\verb"yword" & 256 & 32 \\
\hline
\end{tabular}\end{center}
\caption{Size operators.}\label{tab:size_operators}
\end{table}

\begin{table}[bt]
\begin{center}\begin{tabular}{|c|c||cccccccc|}
\hline
Type & Bits & & & & & & & & \\
\hline\hline
 & 8 & \verb"al" & \verb"cl" & \verb"dl" & \verb"bl" & \verb"ah" & \verb"ch" & \verb"dh" & \verb"bh" \\
General & 16 & \verb"ax" & \verb"cx" & \verb"dx" & \verb"bx" & \verb"sp" & \verb"bp" & \verb"si" & \verb"di" \\
 & 32 & \verb"eax" & \verb"ecx" & \verb"edx" & \verb"ebx" & \verb"esp" & \verb"ebp" & \verb"esi" & \verb"edi" \\
\hline
Segment & 16 & \verb"es" & \verb"cs" & \verb"ss" & \verb"ds" & \verb"fs" & \verb"gs" & & \\
\hline
Control & 32 & \verb"cr0" & & \verb"cr2" & \verb"cr3" & \verb"cr4" & & & \\
\hline
Debug & 32 & \verb"dr0" & \verb"dr1" & \verb"dr2" & \verb"dr3" & & & \verb"dr6" & \verb"dr7" \\
\hline
FPU & 80 & \verb"st0" & \verb"st1" & \verb"st2" & \verb"st3" & \verb"st4" & \verb"st5" & \verb"st6" & \verb"st7" \\
\hline
MMX & 64 & \verb"mm0" & \verb"mm1" & \verb"mm2" & \verb"mm3" & \verb"mm4" & \verb"mm5" & \verb"mm6" & \verb"mm7" \\
\hline
SSE & 128 & \verb"xmm0" & \verb"xmm1" & \verb"xmm2" & \verb"xmm3" & \verb"xmm4" & \verb"xmm5" & \verb"xmm6" & \verb"xmm7" \\
\hline
AVX & 256 & \verb"ymm0" & \verb"ymm1" & \verb"ymm2" & \verb"ymm3" & \verb"ymm4" & \verb"ymm5" & \verb"ymm6" & \verb"ymm7" \\
\hline
\end{tabular}\end{center}
\caption{Registers.}
\label{tab:registers}
\end{table}

\subsection{Instruction syntax}
Instructions in assembly language are separated by line breaks, and one
instruction is expected to fill the one line of text. If a line contains
a semicolon, except for the semicolons inside the quoted strings, the rest of
this line is the comment and compiler ignores it. If a line ends with \verb"\"
character (eventually the semicolon and comment may follow it), the next line
is attached at this point.

Each line in source is the sequence of items, which may be one of the three
types. One type are the symbol characters, which are the special characters
that are individual items even when are not spaced from the other ones.
Any of the \verb"+-*/=<>()[]{}:,|&~#`" is the symbol character. The sequence of
other characters, separated from other items with either blank spaces or
symbol characters, is a symbol. If the first character of symbol is either a
single or double quote, it integrates any sequence of characters following
it, even the special ones, into a quoted string, which should end with the same
character, with which it began (the single or double quote) -- however if there
are two such characters in a row (without any other character between them),
they are integrated into quoted string as just one of them and the quoted
string continues then. The symbols other than symbol characters and quoted
strings can be used as names, so are also called the name symbols.

Every instruction consists of the mnemonic and the various number of
operands, separated with commas. The operand can be register, immediate
value or a data addressed in memory, it can also be preceded by size operator
to define or override its size (table \ref{tab:size_operators}). Names of
available registers you can find in table \ref{tab:registers}, their sizes
cannot be overridden. Immediate value can be specified by any numerical
expression.

When operand is a data in memory, the address of that data (also any
numerical expression, but it may contain registers) should be enclosed in
square brackets or preceded by \verb"ptr" operator. For example instruction
\verb"mov eax,3" will put the immediate value 3 into the \verb"eax" register,
instruction \verb"mov eax,[7]" will put the 32--bit value from the address 7
into \verb"eax" and the instruction \verb"mov byte [7],3" will put the
immediate value 3 into the byte at address 7, it can also be written as
\verb"mov byte ptr 7,3". To specify which segment register should be used for
addressing, segment register name followed with a colon should be put just
before the address value (inside the square brackets or after the \verb"ptr"
operator).

\subsection{Data definitions}
\index{DB}\index{RB}\index{DW}\index{DU}\index{RW}\index{DP}\index{RP}\index{DF}\index{RF}
\index{DD}\index{RD}\index{DQ}\index{RQ}\index{DT}\index{RT}
To define data or reserve a space for it, use one of the directives listed
in table \ref{tab:data_directives}. The data definition directive should be
followed by one or more of numerical expressions, separated with commas.
These expressions define the values for data cells of size depending on which
directive is used. For example \verb"db 1,2,3" will define the three bytes of
values 1, 2 and 3 respectively.

The \verb"db" and \verb"du" directives also accept the quoted string values
of any length, which will be converted into chain of bytes when \verb"db"
is used and into chain of words with zeroed high byte when \verb"du" is used.
For example \verb"db 'abc'" will define the three bytes of values 61, 62 and
63.

The \verb"dp" directive and its synonym \verb"df" accept the values
consisting of two numerical expressions separated with colon, the first value
will become the high word and the second value will become the low double
word of the far pointer value. Also \verb"dd" accepts such pointers consisting
of two word values separated with colon, and \verb"dt" accepts the word and quad word value separated
with colon, the quad word is stored first. The \verb"dt" directive with single
expression as parameter accepts only floating point values and creates data in
FPU double extended precision format.

Any of the above directive allows the usage of special \verb"dup" operator to
make multiple copies of given values. The count of duplicates should precede
this operator and the value to duplicate should follow -- it can even be the
chain of values separated with commas, but such set of values needs to be
enclosed with parenthesis, like \verb"db 5 dup (1,2)", which defines five copies
of the given two byte sequence.

\index{FILE}
The \verb"file" is a special directive and its syntax is different. This
directive includes a chain of bytes from file and it should be followed by
the quoted file name, then optionally numerical expression specifying offset
in file preceded by the colon, then -- also optionally -- comma and numerical
expression specifying count of bytes to include (if no count is specified,
all data up to the end of file is included). For example \verb"file 'data.bin'" will
include the whole file as binary data and \verb"file 'data.bin':10h,4" will include
only four bytes starting at offset 10h.

\begin{table}[hbt]
\begin{center}\begin{tabular}{|c||c|c|}
\hline
Size & Define & Reserve \\
(bytes) & data & data \\
\hline \hline
1 & \verb"db" & \verb"rb" \\
& \verb"file" & \\
\hline
2 & \verb"dw" & \verb"rw" \\
& \verb"du" & \\
\hline
4 & \verb"dd" & \verb"rd" \\
\hline
6 & \verb"dp" & \verb"rp" \\
& \verb"df" & \verb"rf" \\
\hline
8 & \verb"dq" & \verb"rq" \\
\hline
10 & \verb"dt" & \verb"rt" \\
\hline
\end{tabular}\end{center}
\caption{Data directives.}
\label{tab:data_directives}
\end{table}

The data reservation directive should be followed by only one numerical
expression, and this value defines how many cells of the specified size
should be reserved. All data definition directives also accept the \verb"?"
value, which means that this cell should not be initialized to any value and
the effect is the same as by using the data reservation directive. The
uninitialized data may not be included in the output file, so its values
should be always considered unknown.

\subsection{Constants and labels}
\label{sec:labels}
In the numerical expressions you can also use constants or labels instead of
numbers. To define the constant or label you should use the specific
directives. Each label can be defined only once and it is accessible from the
any place of source (even before it was defined). Constant can be redefined
many times, but in this case it is accessible only after it was defined, and
is always equal to the value from last definition before the place where it's
used. When a constant is defined only once in source, it is -- like the label --
accessible from anywhere.

\index{=}
The definition of constant consists of name of the constant followed by the
\verb"=" character and numerical expression, which after calculation will
become the value of constant. This value is always calculated at the time the
constant is defined. For example you can define \verb"count" constant by
using the directive \verb"count = 17", and then use it in the assembly
instructions, like \verb"mov cx,count" -- which will become \verb"mov cx,17"
during the compilation process.

There are different ways to define labels. The simplest is to follow the name
of label by the colon, this directive can even be followed by the other
instruction in the same line. It defines the label whose value is equal to
offset of the point where it's defined. This method is usually used to label
the places in code. The other way is to follow the name of label (without a
colon) by some data directive. It defines the label with value equal to
offset of the beginning of defined data, and remembered as a label for data
with cell size as specified for that data directive in table
\ref{tab:data_directives}.

The label can be treated as constant of value equal to offset of labeled
code or data. For example when you define data using the labeled directive
\verb"char db 224", to put the offset of this data into
\verb"bx" register you should use \verb"mov bx,char" instruction, and to put
the value of byte addressed by \verb"char" label to \verb"dl" register,
you should use \verb"mov dl,[char]" (or \verb"mov dl,ptr char"). But when you
try to assemble \verb"mov ax,[char]", it will cause an error, because fasm
compares the sizes of operands, which should be equal. You can force
assembling that instruction by using size override:
\verb"mov ax,word [char]", but remember that this instruction will read the
two bytes beginning at \verb"char" address, while it was defined as a one
byte.

\index{LABEL}
The last and the most flexible way to define labels is to use \verb"label"
directive. This directive should be followed by the name of label, then
optionally size operator and then -- also optionally \verb"at" operator and
the numerical expression defining the address at which this label should be
defined. For example \verb"label wchar word at char" will define a new label
for the 16--bit data at the address of \verb"char". Now the instruction
\verb"mov ax,[wchar]" will be after compilation the same as
\verb"mov ax,word [char]". If no address is specified, \verb"label" directive
defines the label at current offset. Thus \verb"mov [wchar],57568" will copy
two bytes while \verb"mov [char],224" will copy one byte to the same address.

The label whose name begins with dot is treated as local label, and its name
is attached to the name of last global label (with name beginning with
anything but dot) to make the full name of this label. So you can use the
short name (beginning with dot) of this label anywhere before the next global
label is defined, and in the other places you have to use the full name.
Label beginning with two dots are the exception -- they are like global, but
they don't become the new prefix for local labels.

The \verb"@@" name means anonymous label, you can have defined many of them
in the source. Symbol \verb"@b" (or equivalent \verb"@r") references the
nearest preceding anonymous label, symbol \verb"@f" references the nearest
following anonymous label. These special symbol are case--insensitive.

\subsection{Numerical expressions}
In the above examples all the numerical expressions were the simple numbers,
constants or labels. But they can be more complex, by using the arithmetical
or logical operators for calculations at compile time. All these operators
with their priority values are listed in table \ref{tab:operators_priority}.
The operations with higher priority value will be calculated first, you can
of course change this behavior by putting some parts of expression into
parenthesis. The \verb"+", \verb"-", \verb"*" and \verb"/" are standard
arithmetical operations, \verb"mod" calculates the remainder from division.
The \verb"and", \verb"or", \verb"xor", \verb"shl", \verb"shr" and \verb"not"
perform the same logical operations as assembly instructions of those names.
The \verb"rva" and \verb"plt" are special unary operators that perform
conversions between different kinds of addresses, they can be used only with
few of the output formats and their meaning may vary (see \ref{sec:formatter}).

The arithmetical and logical calculations are usually processed as if they
operated on infinite precision 2-adic numbers, and assembler signalizes an
overflow error if because of its limitations it is not table to perform the
required calculation, or if the result is too large number to fit in either
signed or unsigned range for the destination unit size. However \verb"not", \verb"xor"
and \verb"shr" operators are exceptions from this rule -- if the value specified
by numerical expression has to fit in a unit of specified size, and the
arguments for operation fit into that size, the operation will be performed
with precision limited to that size.

\begin{table}[hbt]
\begin{center}\begin{tabular}{|c|c|}
\hline
Priority & Operators \\
\hline \hline
0 & \verb"+" \\
  & \verb"-" \\
\hline
1 & \verb"*" \\
  & \verb"/" \\
\hline
2 & \verb"mod" \\
\hline
3 & \verb"and" \\
  & \verb"or" \\
  & \verb"xor" \\
\hline
4 & \verb"shl" \\
  & \verb"shr" \\
\hline
5 & \verb"not" \\
\hline
6 & \verb"rva" \\
  & \verb"plt" \\
\hline
\end{tabular}\end{center}
\caption{Arithmetical and logical operators by priority.}
\label{tab:operators_priority}
\end{table}

The numbers in the expression are by default treated as a decimal, binary
numbers should have the \verb"b" letter attached at the end, octal number
should end with \verb"o" letter, hexadecimal numbers should begin with \verb"0x" characters
(like in C language) or with the \verb"$" character (like in Pascal language)
or they should end with \verb"h" letter. Also quoted string, when encountered
in expression, will be converted into number -- the first character will become
the least significant byte of number.

The numerical expression used as an address value can also contain
any of general registers used for addressing, they can be added
and multiplied by appropriate values, as it is allowed for x86
architecture instructions.

There are also some special symbols that can be used inside the numerical
expression. First is \verb"$", which is always equal to the value of current
offset, while \verb"$$" is equal to base address of current addressing space.
The other one is \verb"%", which is the number of current repeat in parts of
code that are repeated using some special directives (see \ref{sec:control}).
There's also \verb"%t" symbol, which is always equal to the current time stamp.

Any numerical expression can also consist of single floating point value
(flat assembler does not allow any floating point operations at compilation
time) in the scientific notation, they can end with the \verb"f" letter
to be recognized, otherwise they should contain at least one of the \verb"."
or \verb"E" characters. So \verb"1.0", \verb"1E0" and \verb"1f" define the
same floating point value, while simple \verb"1" defines an integer value.

\subsection{Jumps and calls}
\label{sec:jumps}
The operand of any jump or call instruction can be preceded not only by the
size operator, but also by one of the operators specifying type of the jump:
\verb"short", \verb"near" of \verb"far". For example, when assembler is in 16--bit mode,
instruction \verb"jmp dword [0]" will become the far jump and when assembler is
in 32--bit mode, it will become the near jump. To force this instruction to be
treated differently, use the \verb"jmp near dword [0]" or \verb"jmp far dword [0]" form.

When operand of near jump is the immediate value, assembler will generate
the shortest variant of this jump instruction if possible (but will not create
32--bit instruction in 16--bit mode nor 16--bit instruction in 32--bit mode,
unless there is a size operator stating it). By specifying the jump type
you can force it to always generate long variant (for example \verb"jmp near 0")
or to always generate short variant and terminate with an error when it's
impossible (for example \verb"jmp short 0").


\subsection{Size settings}
When instruction uses some memory addressing, by default the smallest form of
instruction is generated by using the short displacement if only address
value fits in the range. This can be overridden using the \verb"word" or \verb"dword"
operator before the address inside the square brackets (or after the \verb"ptr"
operator), which forces the long displacement of appropriate size to be made.
In case when address is not relative to any registers, those operators allow
also to choose the appropriate mode of absolute addressing.

Instructions \verb"adc", \verb"add", \verb"and", \verb"cmp",
\verb"or", \verb"sbb", \verb"sub" and \verb"xor" with first
operand being 16--bit or 32--bit are by default generated in
shortened 8--bit form when the second operand is immediate value
fitting in the range for signed 8-bit values. It also can be
overridden by putting the \verb"word" or \verb"dword" operator
before the immediate value. The similar rules applies to the
\verb"imul" instruction with the last operand being immediate
value.

Immediate value as an operand for \verb"push" instruction without a size
operator is by default treated as a word value if assembler is in 16--bit
mode and as a double word value if assembler is in 32--bit mode, shorter
8--bit form of this instruction is used if possible, \verb"word" or
\verb"dword" size operator forces the \verb"push" instruction to be generated
in longer form for specified size. \verb"pushw" and \verb"pushd" mnemonics
force assembler to generate 16-bit or 32--bit code without forcing it to use
the longer form of instruction.

\chapter{Instruction set}
This chapter provides the detailed information about the instructions and
directives supported by flat assembler. Directives for defining labels were
already discussed in \ref{sec:labels}, all other directives will be described later in this chapter.

\section{The x86 architecture instructions}
In this section you can find both the information about the syntax and
purpose the assembly language instructions. If you need more technical
information, look for the Intel Architecture Software Developer's Manual.

Assembly instructions consist of the mnemonic (instruction's name) and from
zero to three operands. If there are two or more operands, usually first is
the destination operand and second is the source operand. Each operand can be
register, memory or immediate value (see \ref{sec:syntax} for details about
syntax of operands). After the description of each instruction there are
examples of different combinations of operands, if the instruction has any.

Some instructions act as prefixes and can be followed by other instruction
in the same line, and there can be more than one prefix in a line. Each name
of the segment register is also a mnemonic of instruction prefix, altough it
is recommended to use segment overrides inside the square brackets instead of
these prefixes.

\subsection{Data movement instructions}
\index{mov}
\verb"mov" transfers a byte, word or double word from the source operand to
the destination operand. It can transfer data between general registers, from
the general register to memory, or from memory to general register, but it
cannot move from memory to memory. It can also transfer an immediate value to
general register or memory, segment register to general register or memory,
general register or memory to segment register, control or debug register to
general register and general register to control or debug register. The
\verb"mov" can be assembled only if the size of source operand and size of
destination operand are the same. Below are the examples for each of the
allowed combinations:
\begin{verbatim}
    mov bx,ax       ; general register to general register
    mov [char],al   ; general register to memory
    mov bl,[char]   ; memory to general register
    mov dl,32       ; immediate value to general register
    mov [char],32   ; immediate value to memory
    mov ax,ds       ; segment register to general register
    mov [bx],ds     ; segment register to memory
    mov ds,ax       ; general register to segment register
    mov ds,[bx]     ; memory to segment register
    mov eax,cr0     ; control register to general register
    mov cr3,ebx     ; general register to control register
\end{verbatim}

\index{xchg}
\verb"xchg" swaps the contents of two operands. It can swap two byte
operands, two word operands or two double word operands. Order of operands is
not important. The operands may be two general registers, or general register
with memory. For example:
\begin{verbatim}
    xchg ax,bx      ; swap two general registers
    xchg al,[char]  ; swap register with memory
\end{verbatim}

\index{push}\index{pushw}\index{pushd}
\verb"push" decrements the stack frame pointer (\verb"esp" register), then
transfers the operand to the top of stack indicated by \verb"esp". The
operand can be memory, general register, segment register or immediate value
of word or double word size. If operand is an immediate value and no size is
specified, it is by default treated as a word value if assembler is in
16--bit mode and as a double word value if assembler is in 32--bit mode.
\verb"pushw" and \verb"pushd" mnemonics are variants of this instruction that
store the values of word or double word size respectively. If more operands
follow in the same line (separated only with spaces, not commas), compiler
will assemble chain of the \verb"push" instructions with these operands.
The examples are with single operands:
\begin{verbatim}
    push ax         ; store general register
    push es         ; store segment register
    pushw [bx]      ; store memory
    push 1000h      ; store immediate value
\end{verbatim}

\index{pusha}\index{pushaw}\index{pushad}
\verb"pusha" saves the contents of the eight general register on the stack.
This instruction has no operands. There are two version of this instruction,
one 16--bit and one 32--bit, assembler automatically generates the right
version for current mode, but it can be overridden by using \verb"pushaw"
or \verb"pushad" mnemonic to always get the 16--bit or 32--bit version.
The 16--bit version of this instruction pushes general registers on the stack
in the following order: \verb"ax", \verb"cx", \verb"dx", \verb"bx", the
initial value of \verb"sp" before \verb"ax" was pushed, \verb"bp", \verb"si"
and \verb"di". The 32--bit version pushes equivalent 32--bit general
registers in the same order.

\index{pop}\index{popw}\index{popd}
\verb"pop" transfers the word or double word at the current top of stack to
the destination operand, and then increments \verb"esp" to point to the new
top of stack. The operand can be memory, general register or segment
register. \verb"popw" and \verb"popd" mnemonics are variants of this
instruction for restoring the values of word or double word size respectively.
If more operands separated with spaces follow in the same line, compiler will
assemble chain of the \verb"pop" instructions with these operands.
\begin{verbatim}
    pop bx          ; restore general register
    pop ds          ; restore segment register
    popw [si]       ; restore memory
\end{verbatim}

\index{popa}\index{popaw}\index{popad}
\verb"popa" restores the registers saved on the stack by \verb"pusha"
instruction, except for the saved value of \verb"sp" (or \verb"esp"),
which is ignored. This instruction has no operands. To force assembling
16--bit or 32--bit version of this instruction use \verb"popaw" or
\verb"popad" mnemonic.

\subsection{Type conversion instructions}
The type conversion instructions convert bytes into words, words into double
words, and double words into quad words. These conversions can be done using
the sign extension or zero extension. The sign extension fills the extra bits
of the larger item with the value of the sign bit of the smaller item,
the zero extension simply fills them with zeros.

\index{cwd}\index{cdq}
\verb"cwd" and \verb"cdq" double the size of value \verb"ax" or \verb"eax"
register respectively and store the extra bits into the \verb"dx" or
\verb"edx" register. The conversion is done using the sign extension.
These instructions have no operands.

\index{cbw}\index{cwde}
\verb"cbw" extends the sign of the byte in \verb"al" throughout \verb"ax",
and \verb"cwde" extends the sign of the word in \verb"ax" throughout
\verb"eax". These instructions also have no operands.

\index{movsx}\index{movzx}
\verb"movsx" converts a byte to word or double word and a word to double word
using the sign extension. \verb"movzx" does the same, but it uses the zero
extension. The source operand can be general register or memory, while the
destination operand must be a general register. For example:
\begin{verbatim}
    movsx ax,al         ; byte register to word register
    movsx edx,dl        ; byte register to double word register
    movsx eax,ax        ; word register to double word register
    movsx ax,byte [bx]  ; byte memory to word register
    movsx edx,byte [bx] ; byte memory to double word register
    movsx eax,word [bx] ; word memory to double word register
\end{verbatim}

\subsection{Binary arithmetic instructions}
\index{add}
\verb"add" replaces the destination operand with the sum of the source and
destination operands and sets CF if overflow has occurred. The operands may
be bytes, words or double words. The destination operand can be general
register or memory, the source operand can be general register or immediate
value, it can also be memory if the destination operand is register.
\begin{verbatim}
    add ax,bx       ; add register to register
    add ax,[si]     ; add memory to register
    add [di],al     ; add register to memory
    add al,48       ; add immediate value to register
    add [char],48   ; add immediate value to memory
\end{verbatim}

\index{adc}
\verb"adc" sums the operands, adds one if CF is set, and replaces the
destination operand with the result. Rules for the operands are the same as
for the \verb"add" instruction. An \verb"add" followed by multiple \verb"adc"
instructions can be used to add numbers longer than 32 bits.

\index{inc}
\verb"inc" adds one to the operand, it does not affect CF. The operand can be
a general register or memory, and the size of the operand can be byte, word or double word.
\begin{verbatim}
    inc ax          ; increment register by one
    inc byte [bx]   ; increment memory by one
\end{verbatim}

\index{sub}
\verb"sub" subtracts the source operand from the destination operand and
replaces the destination operand with the result. If a borrow is required,
the CF is set. Rules for the operands are the same as for the \verb"add"
instruction.

\index{sbb}
\verb"sbb" subtracts the source operand from the destination operand,
subtracts one if CF is set, and stores the result to the destination operand.
Rules for the operands are the same as for the \verb"add" instruction.
A \verb"sub" followed by multiple \verb"sbb" instructions may be used to
subtract numbers longer than 32 bits.

\index{dec}
\verb"dec" subtracts one from the operand, it does not affect CF. Rules for
the operand are the same as for the \verb"inc" instruction.

\index{cmp}
\verb"cmp" subtracts the source operand from the destination operand. It
updates the flags as the \verb"sub" instruction, but does not alter the
source and destination operands. Rules for the operands are the same as for
the \verb"sub" instruction.

\index{neg}
\verb"neg" subtracts a signed integer operand from zero. The effect of this
instructon is to reverse the sign of the operand from positive to negative or
from negative to positive. Rules for the operand are the same as for the
\verb"inc" instruction.

\index{xadd}
\verb"xadd" exchanges the destination operand with the source operand,
then loads the sum of the two values into the destination operand. Rules for
the operands are the same as for the \verb"add" instruction.

All the above binary arithmetic instructions update SF, ZF, PF and OF flags.
SF is always set to the same value as the result's sign bit, ZF is set
when all the bits of result are zero, PF is set when low order eight bits of
result contain an even number of set bits, OF is set if result is too large for a
positive number or too small for a negative number (excluding sign bit) to fit in
destination operand.

\index{mul}
\verb"mul" performs an unsigned multiplication of the operand and the
accumulator. If the operand is a byte, the processor multiplies it by the
contents of \verb"al" and returns the 16--bit result to \verb"ah" and
\verb"al". If the operand is a word, the processor multiplies it by the
contents of \verb"ax" and returns the 32--bit result to \verb"dx" and
\verb"ax". If the operand is a double word, the processor multiplies it by
the contents of \verb"eax" and returns the 64--bit result in \verb"edx" and
\verb"eax". \verb"mul" sets CF and OF when the upper half of the result is
nonzero, otherwise they are cleared. Rules for the operand are the same as
for the \verb"inc" instruction.

\index{imul}
\verb"imul" performs a signed multiplication operation. This
instruction has three variations. First has one operand and
behaves in the same way as the \verb"mul" instruction. Second has
two operands, in this case destination operand is multiplied by
the source operand and the result replaces the destination
operand. Destination operand must be a general register, it can be
word or double word, source operand can be general register,
memory or immediate value. Third form has three operands, the
destination operand must be a general register, word or double
word in size, source operand can be general register or memory,
and third operand must be an immediate value. The source operand
is multiplied by the immediate value and the result is stored in
the destination register. All the three forms calculate the
product to twice the size of operands and set CF and OF when the
upper half of the result is nonzero, but second and third form
truncate the product to the size of operands. So second and third
forms can be also used for unsigned operands because, whether the
operands are signed or unsigned, the lower half of the product is
the same. Below are the examples for all three forms:
\begin{verbatim}
    imul bl         ; accumulator by register
    imul word [si]  ; accumulator by memory
    imul bx,cx      ; register by register
    imul bx,[si]    ; register by memory
    imul bx,10      ; register by immediate value
    imul ax,bx,10   ; register by immediate value to register
    imul ax,[si],10 ; memory by immediate value to register
\end{verbatim}

\index{div}
\verb"div" performs an unsigned division of the accumulator by the operand.
The dividend (the accumulator) is twice the size of the divisor (the
operand), the quotient and remainder have the same size as the divisor.
If divisor is byte, the dividend is taken from \verb"ax" register, the
quotient is stored in \verb"al" and the remainder is stored in \verb"ah".
If divisor is word, the upper half of dividend is taken from \verb"dx",
the lower half of dividend is taken from \verb"ax", the quotient is stored
in \verb"ax" and the remainder is stored in \verb"dx". If divisor is double
word, the upper half of dividend is taken from \verb"edx", the lower half of
dividend is taken from \verb"eax", the quotient is stored in \verb"eax" and
the remainder is stored in \verb"edx". Rules for the operand are the same as
for the \verb"mul" instruction.

\index{idiv}
\verb"idiv" performs a signed division of the accumulator by the operand.
It uses the same registers as the \verb"div" instruction, and the rules for
the operand are the same.

\subsection{Decimal arithmetic instructions}
Decimal arithmetic is performed by combining the binary arithmetic
instructions (already described in the prior section) with the decimal
arithmetic instructions. The decimal arithmetic instructions are used to
adjust the results of a previous binary arithmetic operation to produce a
valid packed or unpacked decimal result, or to adjust the inputs to a
subsequent binary arithmetic operation so the operation will produce a valid
packed or unpacked decimal result.

\index{daa}
\verb"daa" adjusts the result of adding two valid packed decimal operands in
\verb"al". \verb"daa" must always follow the addition of two pairs of packed
decimal numbers (one digit in each half--byte) to obtain a pair of valid
packed decimal digits as results. The carry flag is set if carry was needed.
This instruction has no operands.

\index{das}
\verb"das" adjusts the result of subtracting two valid packed decimal
operands in \verb"al". \verb"das" must always follow the subtraction of one
pair of packed decimal numbers (one digit in each half--byte) from another
to obtain a pair of valid packed decimal digits as results. The carry flag is
set if a borrow was needed. This instruction has no operands.

\index{aaa}
\verb"aaa" changes the contents of register \verb"al" to a valid unpacked
decimal number, and zeroes the top four bits. \verb"aaa" must always follow
the addition of two unpacked decimal operands in \verb"al". The carry flag is
set and \verb"ah" is incremented if a carry is necessary. This instruction
has no operands.

\index{aas}
\verb"aas" changes the contents of register \verb"al" to a valid unpacked
decimal number, and zeroes the top four bits. \verb"aas" must always follow
the subtraction of one unpacked decimal operand from another in \verb"al".
The carry flag is set and \verb"ah" decremented if a borrow is necessary.
This instruction has no operands.

\index{aam}
\verb"aam" corrects the result of a multiplication of two valid unpacked
decimal numbers. \verb"aam" must always follow the multiplication of two
decimal numbers to produce a valid decimal result. The high order digit is
left in \verb"ah", the low order digit in \verb"al". The generalized version
of this instruction allows adjustment of the contents of the \verb"ax" to
create two unpacked digits of any number base. The standard version of this
instruction has no operands, the generalized version has one operand -- an
immediate value specifying the number base for the created digits.

\index{aad}
\verb"aad" modifies the numerator in \verb"ah" and \verb"ah" to prepare for
the division of two valid unpacked decimal operands so that the quotient
produced by the division will be a valid unpacked decimal number. \verb"ah"
should contain the high order digit and \verb"al" the low order digit.
This instruction adjusts the value and places the result in \verb"al", while
\verb"ah" will contain zero. The generalized version of this instruction
allows adjustment of two unpacked digits of any number base. Rules for the
operand are the same as for the \verb"aam" instruction.

\subsection{Logical instructions}
\index{not}
\verb"not" inverts the bits in the specified operand to form a one's
complement of the operand. It has no effect on the flags. Rules for the
operand are the same as for the \verb"inc" instruction.

\index{and}\index{or}\index{xor}
\verb"and", \verb"or" and \verb"xor" instructions perform the standard
logical operations. They update the SF, ZF and PF flags. Rules for the
operands are the same as for the \verb"add" instruction.

\index{bt}\index{bts}\index{btr}\index{btc}
\verb"bt", \verb"bts", \verb"btr" and \verb"btc" instructions operate on a
single bit which can be in memory or in a general register. The location of
the bit is specified as an offset from the low order end of the operand.
The value of the offset is the taken from the second operand, it either may
be an immediate byte or a general register. These instructions first assign
the value of the selected bit to CF. \verb"bt" instruction does nothing more,
\verb"bts" sets the selected bit to 1, \verb"btr" resets the selected bit to
0, \verb"btc" changes the bit to its complement. The first operand can be
word or double word.
\begin{verbatim}
    bt  ax,15        ; test bit in register
    bts word [bx],15 ; test and set bit in memory
    btr ax,cx        ; test and reset bit in register
    btc word [bx],cx ; test and complement bit in memory
\end{verbatim}

\index{bsf}\index{bsr}
\verb"bsf" and \verb"bsr" instructions scan a word or double word for first
set bit and store the index of this bit into destination operand, which must
be general register. The bit string being scanned is specified by source
operand, it may be either general register or memory. The ZF flag is set if
the entire string is zero (no set bits are found); otherwise it is cleared.
If no set bit is found, the value of the destination register is undefined.
\verb"bsf" from low order to high order (starting from bit index zero).
\verb"bsr" scans from high order to low order (starting from bit index 15 of
a word or index 31 of a double word).
\begin{verbatim}
    bsf ax,bx        ; scan register forward
    bsr ax,[si]      ; scan memory reverse
\end{verbatim}

\index{shl}
\verb"shl" shifts the destination operand left by the number of bits
specified in the second operand. The destination operand can be byte, word,
or double word general register or memory. The second operand can be an
immediate value or the \verb"cl" register. The processor shifts zeros in from
the right (low order) side of the operand as bits exit from the left side.
The last bit that exited is stored in CF. \verb"sal" is a synonym for
\verb"shl".
\begin{verbatim}
    shl al,1         ; shift register left by one bit
    shl byte [bx],1  ; shift memory left by one bit
    shl ax,cl        ; shift register left by count from cl
    shl word [bx],cl ; shift memory left by count from cl
\end{verbatim}

\index{shr}\index{sar}
\verb"shr" and \verb"sar" shift the destination operand right by the number
of bits specified in the second operand. Rules for operands are the same as
for the \verb"shl" instruction. \verb"shr" shifts zeros in from the left side
of the operand as bits exit from the right side. The last bit that exited is
stored in CF. \verb"sar" preserves the sign of the operand by shifting in
zeros on the left side if the value is positive or by shifting in ones if the
value is negative.

\index{shld}
\verb"shld" shifts bits of the destination operand to the left by the number
of bits specified in third operand, while shifting high order bits from the
source operand into the destination operand on the right. The source operand
remains unmodified. The destination operand can be a word or double word
general register or memory, the source operand must be a general register,
third operand can be an immediate value or the \verb"cl" register.
\begin{verbatim}
    shld ax,bx,1     ; shift register left by one bit
    shld [di],bx,1   ; shift memory left by one bit
    shld ax,bx,cl    ; shift register left by count from cl
    shld [di],bx,cl  ; shift memory left by count from cl
\end{verbatim}

\index{shrd}
\verb"shrd" shifts bits of the destination operand to the right, while
shifting low order bits from the source operand into the destination operand
on the left. The source operand remains unmodified. Rules for operands are
the same as for the \verb"shld" instruction.

\index{rol}\index{rcl}
\verb"rol" and \verb"rcl" rotate the byte, word or double word destination
operand left by the number of bits specified in the second operand. For each
rotation specified, the high order bit that exits from the left of the
operand returns at the right to become the new low order bit. \verb"rcl"
additionally puts in CF each high order bit that exits from the left side
of the operand before it returns to the operand as the low order bit on the
next rotation cycle. Rules for operands are the same as for the \verb"shl"
instruction.

\index{ror}\index{rcr}
\verb"ror" and \verb"rcr" rotate the byte, word or double word destination
operand right by the number of bits specified in the second operand. For each
rotation specified, the low order bit that exits from the right of the
operand returns at the left to become the new high order bit. \verb"rcr"
additionally puts in CF each low order bit that exits from the right side of
the operand before it returns to the operand as the high order bit on the
next rotation cycle. Rules for operands are the same as for the \verb"shl"
instruction.

\index{test}
\verb"test" performs the same action as the \verb"and" instruction, but it
does not alter the destination operand, only updates flags. Rules for the
operands are the same as for the \verb"and" instruction.

\index{bswap}
\verb"bswap" reverses the byte order of a 32--bit general register:
bits 0 through 7 are swapped with bits 24 through 31, and bits 8 through 15
are swapped with bits 16 through 23. This instruction is provided for
converting little--endian values to big--endian format and vice versa.
\begin{verbatim}
    bswap edx        ; swap bytes in register
\end{verbatim}

\subsection{Control transfer instructions}

\index{jmp}
\verb"jmp" unconditionally transfers control to the target location. The
destination address can be specified directly within the instruction or
indirectly through a register or memory, the acceptable size of this address
depends on whether the jump is near or far (it can be specified by preceding
the operand with \verb"near" or \verb"far" operator) and whether the instruction is
16--bit or 32--bit. Operand for near jump should be \verb"word" size for 16--bit
instruction or the \verb"dword" size for 32--bit instruction. Operand for far jump
should be \verb"dword" size for 16--bit instruction or \verb"pword" size for 32--bit
instruction. A direct \verb"jmp" instruction includes the destination address as
part of the instruction (and can be preceded by \verb"short", \verb"near" or \verb"far"
operator), the operand specifying address should be the numerical expression
for near or short jump, or two numerical expressions separated with colon for
far jump, the first specifies selector of segment, the second is the offset
within segment. The \verb"pword" operator can be used to force the 32--bit far call,
and \verb"dword" to force the 16-bit far call. An indirect \verb"jmp" instruction
obtains the destination address indirectly through a register or a pointer
variable, the operand should be general register or memory. See also \ref{sec:jumps} for
some more details.
\begin{verbatim}
    jmp 100h         ; direct near jump
    jmp 0FFFFh:0     ; direct far jump
    jmp ax           ; indirect near jump
    jmp pword [ebx]  ; indirect far jump
\end{verbatim}

\index{call}
\verb"call" transfers control to the procedure, saving on the stack the
address of the instruction following the \verb"call" for later use by a
\verb"ret" (return) instruction. Rules for the operands are the same as for
the \verb"jmp" instruction, but the \verb"call" has no short variant of
direct instruction and thus it not optimized.

\index{ret}\index{retn}\index{retf}
\index{retw}\index{retnw}\index{retfw}
\index{retd}\index{retnd}\index{retfd}
\verb"ret", \verb"retn" and \verb"retf" instructions terminate the execution
of a procedure and transfers control back to the program that originally
invoked the procedure using the address that was stored on the stack by the
\verb"call" instruction. \verb"ret" is the equivalent for \verb"retn", which
returns from the procedure that was executed using the near call, while
\verb"retf" returns from the procedure that was executed using the far call.
These instructions default to the size of address appropriate for the current
code setting, but the size of address can be forced to 16--bit by using the
\verb"retw", \verb"retnw" and \verb"retfw" mnemonics, and to 32--bit by using
the \verb"retd", \verb"retnd" and \verb"retfd" mnemonics. All these
instructions may optionally specify an immediate operand, by adding this
constant to the stack pointer, they effectively remove any arguments that the
calling program pushed on the stack before the execution of the \verb"call"
instruction.

\index{iret}\index{iretw}\index{iretd}
\verb"iret" returns control to an interrupted procedure. It differs from
\verb"ret" in that it also pops the flags from the stack into the flags
register. The flags are stored on the stack by the interrupt mechanism. It
defaults to the size of return address appropriate for the current code
setting, but it can be forced to use 16--bit or 32--bit address by using the
\verb"iretw" or \verb"iretd" mnemonic.

\index{jo}\index{jno}\index{jc}\index{jb}\index{jnae}\index{jnc}\index{jae}
\index{jnb}\index{je}\index{jz}\index{jne}\index{jnz}\index{jbe}\index{jna}
\index{ja}\index{jnbe}\index{js}\index{jns}\index{jp}\index{jpe}\index{jnp}
\index{jpo}\index{jl}\index{jnge}\index{jge}\index{jnl}\index{jle}\index{jng}
\index{jg}\index{jnle}
The conditional transfer instructions are jumps that may or may not transfer
control, depending on the state of the CPU flags when the instruction
executes. The mnemonics for conditional jumps may be obtained by attaching
the condition mnemonic (see table \ref{tab:conditions}) to the \verb"j"
mnemonic, for example \verb"jc" instruction will transfer the control when
the CF flag is set. The conditional jumps can be short or near, and direct only, and
can be optimized (see \ref{sec:jumps}), the operand should be an immediate
value specifying target address.

\begin{table}[p]
\begin{center}\begin{tabular}{|c|c|c|}
\hline
Mnemonic & Condition tested & Description \\
\hline \hline
\verb"o" & OF = 1 & overflow\\
\hline
\verb"no" & OF = 0 & not overflow\\
\hline
\verb"c" & & carry\\
\verb"b" & CF = 1 & below\\
\verb"nae" & & not above nor equal\\
\hline
\verb"nc" & & not carry\\
\verb"ae" & CF = 0 & above or equal\\
\verb"nb" & & not below\\
\hline
\verb"e" & ZF = 1 & equal\\
\verb"z" & & zero\\
\hline
\verb"ne" & ZF = 0 & not equal\\
\verb"nz" & & not zero\\
\hline
\verb"be" & CF \verb"or" ZF = 1 & below or equal\\
\verb"na" & & not above\\
\hline
\verb"a" & CF \verb"or" ZF = 0 & above\\
\verb"nbe" & & not below nor equal\\
\hline
\verb"s" & SF = 1 & sign\\
\hline
\verb"ns" & SF = 0 & not sign\\
\hline
\verb"p" & PF = 1 & parity\\
\verb"pe" & & parity even\\
\hline
\verb"np" & PF = 0 & not parity\\
\verb"po" & & parity odd\\
\hline
\verb"l" & SF \verb"xor" OF = 1 & less\\
\verb"nge" & & not greater nor equal\\
\hline
\verb"ge" & SF \verb"xor" OF = 0 & greater or equal\\
\verb"nl" & & not less\\
\hline
\verb"le" & (SF \verb"xor" OF) \verb"or" ZF = 1 & less or equal\\
\verb"ng" & & not greater\\
\hline
\verb"g" & (SF \verb"xor" OF) \verb"or" ZF = 0 & greater\\
\verb"nle" & & not less nor equal\\
\hline
\end{tabular}\end{center}
\caption{Conditions.}
\label{tab:conditions}
\end{table}

\index{loop}\index{loopw}\index{loopd}
\index{loope}\index{loopz}\index{loopew}\index{loopzw}\index{looped}\index{loopzd}
\index{loopne}\index{loopnz}\index{loopnew}\index{loopnzw}\index{loopned}\index{loopnzd}
The \verb"loop" instructions are conditional jumps that use a value placed in
\verb"cx" (or \verb"ecx") to specify the number of repetitions of a software
loop. All \verb"loop" instructions automatically decrement \verb"cx" (or
\verb"ecx") and terminate the loop (don't transfer the control) when
\verb"cx" (or \verb"ecx") is zero. It uses \verb"cx" or \verb"ecx" whether
the current code setting is 16--bit or 32--bit, but it can be forced to use
\verb"cx" with the \verb"loopw" mnemonic or to use \verb"ecx" with the
\verb"loopd" mnemonic. \verb"loope" and \verb"loopz" are the synonyms for the
same instruction, which acts as the standard \verb"loop", but also terminates
the loop when ZF flag is set. \verb"loopew" and \verb"loopzw" mnemonics force
them to use \verb"cx" register while \verb"looped" and \verb"loopzd" force
them to use \verb"ecx" register. \verb"loopne" and \verb"loopnz" are the
synonyms for the same instructions, which acts as the standard \verb"loop",
but also terminate the loop when ZF flag is not set. \verb"loopnew" and
\verb"loopnzw" mnemonics force them to use \verb"cx" register while
\verb"loopned" and \verb"loopnzd" force them to use \verb"ecx" register.
Every \verb"loop" instruction needs an operand being an immediate value
specifying target address, it can be only short jump (in the range of 128
bytes back and 127 bytes forward from the address of instruction following
the \verb"loop" instruction).

\index{jcxz}\index{jecxz}
\verb"jcxz" branches to the label specified in the instruction if it finds a
value of zero in \verb"cx", \verb"jecxz" does the same, but checks the value
of \verb"ecx" instead of \verb"cx". Rules for the operands are the same as
for the \verb"loop" instruction.

\index{int}\index{int3}\index{into}
\verb"int" activates the interrupt service routine that corresponds to the
number specified as an operand to the instruction, the number should be in
range from 0 to 255. The interrupt service routine terminates with an
\verb"iret" instruction that returns control to the instruction that follows
\verb"int". \verb"int3" mnemonic codes the short (one byte) trap that invokes
the interrupt 3. \verb"into" instruction invokes the interrupt 4 if the OF
flag is set.

\index{bound}
\verb"bound" verifies that the signed value contained in the specified
register lies within specified limits. An interrupt 5 occurs if the value
contained in the register is less than the lower bound or greater than the
upper bound. It needs two operands, the first operand specifies the register
being tested, the second operand should be memory address for the two signed
limit values. The operands can be \verb"word" or \verb"dword" in size.
\begin{verbatim}
    bound ax,[bx]    ; check word for bounds
    bound eax,[esi]  ; check double word for bounds
\end{verbatim}

\subsection{I/O instructions}

\index{in}
\verb"in" transfers a byte, word, or double word from an input port to
\verb"al", \verb"ax", or \verb"eax". I/O ports can be addressed either
directly, with the immediate byte value coded in instruction, or indirectly
via the \verb"dx" register. The destination operand should be \verb"al",
\verb"ax", or \verb"eax" register. The source operand should be an immediate
value in range from 0 to 255, or \verb"dx" register.
\begin{verbatim}
    in al,20h        ; input byte from port 20h
    in ax,dx         ; input word from port addressed by dx
\end{verbatim}

\index{out}
\verb"out" transfers a byte, word, or double word to an output port from
\verb"al", \verb"ax", or \verb"eax". The program can specify the number of
the port using the same methods as the \verb"in" instruction. The destination
operand should be an immediate value in range from 0 to 255, or \verb"dx"
register. The source operand should be \verb"al", \verb"ax", or \verb"eax"
register.
\begin{verbatim}
    out 20h,ax       ; output word to port 20h
    out dx,al        ; output byte to port addressed by dx
\end{verbatim}

\subsection{Strings operations}

The string operations operate on one element of a string. A string element
may be a byte, a word, or a double word. The string elements are addressed by
\verb"si" and \verb"di" (or \verb"esi" and \verb"edi") registers. After every
string operation \verb"si" and/or \verb"di" (or \verb"esi" and/or \verb"edi")
are automatically updated to point to the next element of the string. If DF
(direction flag) is zero, the index registers are incremented, if DF is one,
they are decremented. The amount of the increment or decrement is 1, 2, or 4
depending on the size of the string element. Every string operation
instruction has short forms which have no operands and use \verb"si" and/or
\verb"di" when the code type is 16--bit, and \verb"esi" and/or \verb"edi"
when the code type is 32--bit. \verb"si" and \verb"esi" by default address
data in the segment selected by \verb"ds", \verb"di" and \verb"edi" always
address data in the segment selected by \verb"es". Short form is obtained
by attaching to the mnemonic of string operation letter specifying the size
of string element, it should be \verb"b" for byte element, \verb"w" for word
element, and \verb"d" for double word element. Full form of string operation
needs operands providing the size operator and the memory addresses, which
can be \verb"si" or \verb"esi" with any segment prefix, \verb"di" or
\verb"edi" always with \verb"es" segment prefix.

\index{movs}\index{movsb}\index{movsw}\index{movsd}
\verb"movs" transfers the string element pointed to by \verb"si" (or
\verb"esi") to the location pointed to by \verb"di" (or \verb"edi"). Size of
operands can be \verb"byte", \verb"word" or \verb"dword". The destination
operand should be memory addressed by \verb"di" or \verb"edi", the source
operand should be memory addressed by \verb"si" or \verb"esi" with any
segment prefix.
\begin{verbatim}
    movs byte [di],[si]        ; transfer byte
    movs word [es:di],[ss:si]  ; transfer word
    movsd                      ; transfer double word
\end{verbatim}

\index{cmps}\index{cmpsb}\index{cmpsw}\index{cmpsd}
\verb"cmps" subtracts the destination string element from the source string
element and updates the flags AF, SF, PF, CF and OF, but it does not change
any of the compared elements. If the string elements are equal, ZF is set,
otherwise it is cleared. The first operand for this instruction should be the
source string element addressed by \verb"si" or \verb"esi" with any segment
prefix, the second operand should be the destination string element addressed
by \verb"di" or \verb"edi".
\begin{verbatim}
    cmpsb                      ; compare bytes
    cmps word [ds:si],[es:di]  ; compare words
    cmps dword [fs:esi],[edi]  ; compare double words
\end{verbatim}

\index{scas}\index{scasb}\index{scasw}\index{scasd}
\verb"scas" subtracts the destination string element from \verb"al",
\verb"ax", or \verb"eax" (depending on the size of string element) and
updates the flags AF, SF, ZF, PF, CF and OF. If the values are equal, ZF is
set, otherwise it is cleared. The operand should be the destination string
element addressed by \verb"di" or \verb"edi".
\begin{verbatim}
    scas byte [es:di]          ; scan byte
    scasw                      ; scan word
    scas dword [es:edi]        ; scan double word
\end{verbatim}

\index{lods}\index{lodsb}\index{lodsw}\index{lodsd}
\verb"lods" places the source string element into \verb"al", \verb"ax", or
\verb"eax". The operand should be the source string element addressed by
\verb"si" or \verb"esi" with any segment prefix.
\begin{verbatim}
    lods byte [ds:si]          ; load byte
    lods word [cs:si]          ; load word
    lodsd                      ; load double word
\end{verbatim}

\index{stos}\index{stosb}\index{stosw}\index{stosd}
\verb"stos" places the value of \verb"al", \verb"ax", or \verb"eax" into the
destination string element. Rules for the operand are the same as for the
\verb"scas" instruction.

\index{ins}\index{insb}\index{insw}\index{insd}
\verb"ins" transfers a byte, word, or double word from an input port
addressed by \verb"dx" register to the destination string element. The
destination operand should be memory addressed by \verb"di" or \verb"edi",
the source operand should be the \verb"dx" register.
\begin{verbatim}
    insb                       ; input byte
    ins word [es:di],dx        ; input word
    ins dword [edi],dx         ; input double word
\end{verbatim}

\index{outs}\index{outsb}\index{outsw}\index{outsd}
\verb"outs" transfers the source string element to an output port addressed
by \verb"dx" register. The destination operand should be the \verb"dx"
register and the source operand should be memory addressed by \verb"si" or
\verb"esi" with any segment prefix.
\begin{verbatim}
    outs dx,byte [si]           ; output byte
    outsw                       ; output word
    outs dx,dword [gs:esi]      ; output double word
\end{verbatim}

\index{rep}\index{repe}\index{repz}\index{repne}\index{repnz}
The repeat prefixes \verb"rep", \verb"repe"/\verb"repz", and
\verb"repne"/\verb"repnz" specify repeated string operation. When a string
operation instruction has a repeat prefix, the operation is executed
repeatedly, each time using a different element of the string. The repetition
terminates when one of the conditions specified by the prefix is satisfied.
All three prefixes automatically decrease \verb"cx" or \verb"ecx" register
(depending whether string operation instruction uses the 16--bit or 32--bit
addressing) after each operation and repeat the associated operation until
\verb"cx" or \verb"ecx" is zero. \verb"repe"/\verb"repz" and
\verb"repne"/\verb"repnz" are used exclusively with the \verb"scas" and
\verb"cmps" instructions (described below). When these prefixes are used,
repetition of the next instruction depends on the zero flag (ZF) also,
\verb"repe" and \verb"repz" terminate the execution when the ZF is zero,
\verb"repne" and \verb"repnz" terminate the execution when the ZF is set.
\begin{verbatim}
    rep  movsd       ; transfer multiple double words
    repe cmpsb       ; compare bytes until not equal
\end{verbatim}

\subsection{Flag control instructions}

The flag control instructions provide a method for directly changing the
state of bits in the flag register. All instructions described in this
section have no operands.

\index{stc}\index{clc}\index{cmc}\index{std}\index{cld}\index{sti}\index{cli}
\verb"stc" sets the CF (carry flag) to 1, \verb"clc" zeroes the CF,
\verb"cmc" changes the CF to its complement. \verb"std" sets the DF
(direction flag) to 1, \verb"cld" zeroes the DF, \verb"sti" sets the IF
(interrupt flag) to 1 and therefore enables the interrupts, \verb"cli" zeroes
the IF and therefore disables the interrupts.

\index{lahf}
\verb"lahf" copies SF, ZF, AF, PF, and CF to bits 7, 6, 4, 2, and 0 of the
\verb"ah" register. The contents of the remaining bits are undefined.
The flags remain unaffected.

\index{sahf}
\verb"sahf" transfers bits 7, 6, 4, 2, and 0 from the \verb"ah" register
into SF, ZF, AF, PF, and CF.

\index{pushf}\index{pushfw}\index{pushfd}
\verb"pushf" decrements \verb"esp" by two or four and stores the low word or
double word of flags register at the top of stack, size of stored data
depends on the current code setting. \verb"pushfw" variant forces storing the
word and \verb"pushfd" forces storing the double word.

\index{popf}\index{popfw}\index{popfd}
\verb"popf" transfers specific bits from the word or double word at the top
of stack, then increments \verb"esp" by two or four, this value depends on
the current code setting. \verb"popfw" variant forces restoring from the word
and \verb"popfd" forces restoring from the double word.

\subsection{Conditional operations}

\index{seto}\index{setno}\index{setc}\index{setb}\index{setnae}\index{setnc}\index{setae}
\index{setnb}\index{sete}\index{setz}\index{setne}\index{setnz}\index{setbe}\index{setna}
\index{seta}\index{setnbe}\index{sets}\index{setns}\index{setp}\index{setpe}\index{setnp}
\index{setpo}\index{setl}\index{setnge}\index{setge}\index{setnl}\index{setle}\index{setng}
\index{setg}\index{setnle}
The instructions obtained by attaching the condition mnemonic (see table
\ref{tab:conditions}) to the \verb"set" mnemonic set a byte to one if the
condition is true and set the byte to zero otherwise. The operand should be
an 8--bit be general register or the byte in memory.
\begin{verbatim}
    setne al         ; set al if zero flag cleared
    seto byte [bx]   ; set byte if overflow
\end{verbatim}

\index{salc}
\verb"salc" instruction sets the all bits of \verb"al" register when the
carry flag is set and zeroes the \verb"al" register otherwise. This
instruction has no arguments.

\index{cmovo}\index{cmovno}\index{cmovc}\index{cmovb}\index{cmovnae}\index{cmovnc}\index{cmovae}
\index{cmovnb}\index{cmove}\index{cmovz}\index{cmovne}\index{cmovnz}\index{cmovbe}\index{cmovna}
\index{cmova}\index{cmovnbe}\index{cmovs}\index{cmovns}\index{cmovp}\index{cmovpe}\index{cmovnp}
\index{cmovpo}\index{cmovl}\index{cmovnge}\index{cmovge}\index{cmovnl}\index{cmovle}\index{cmovng}
\index{cmovg}\index{cmovnle}
The instructions obtained by attaching the condition mnemonic to
\verb"cmov" mnemonic transfer the word or double word from the general
register or memory to the general register only when the condition is true.
The destination operand should be general register, the source operand can be
general register or memory.
\begin{verbatim}
    cmove ax,bx      ; move when zero flag set
    cmovnc eax,[ebx] ; move when carry flag cleared
\end{verbatim}

\index{cmpxchg}
\verb"cmpxchg" compares the value in the \verb"al", \verb"ax", or \verb"eax"
register with the destination operand. If the two values are equal,
the source operand is loaded into the destination operand. Otherwise,
the destination operand is loaded into the \verb"al", \verb"ax", or \verb"eax"
register. The destination operand may be a general register or memory, the
source operand must be a general register.
\begin{verbatim}
    cmpxchg dl,bl    ; compare and exchange with register
    cmpxchg [bx],dx  ; compare and exchange with memory
\end{verbatim}

\index{cmpxchg8b}
\verb"cmpxchg8b" compares the 64--bit value in \verb"edx" and \verb"eax"
registers with the destination operand. If the values are equal, the 64--bit
value in \verb"ecx" and \verb"ebx" registers is stored in the destination
operand. Otherwise, the value in the destination operand is loaded into
\verb"edx" and \verb"eax" registers. The destination operand should be a
quad word in memory.
\begin{verbatim}
    cmpxchg8b [bx]   ; compare and exchange 8 bytes
\end{verbatim}

\subsection{Miscellaneous instructions}

\index{nop}
\verb"nop" instruction occupies one byte but affects nothing but the
instruction pointer. This instruction has no operands and doesn't perform any
operation.

\index{ud2}
\verb"ud2" instruction generates an invalid opcode exception. This
instruction is provided for software testing to explicitly generate an
invalid opcode. This is instruction has no operands.

\index{xlat}
\verb"xlat" replaces a byte in the \verb"al" register with a byte indexed by
its value in a translation table addressed by \verb"bx" or \verb"ebx". The
operand should be a byte memory addressed by \verb"bx" or \verb"ebx" with any
segment prefix. This instruction has also a short form \verb"xlatb" which has
no operands and uses the \verb"bx" or \verb"ebx" address in the segment
selected by \verb"ds" depending on the current code setting.

\index{lds}\index{les}\index{lfs}\index{lgs}\index{lss}
\verb"lds" transfers a pointer variable from the source operand to \verb"ds"
and the destination register. The source operand must be a memory operand,
and the destination operand must be a general register. The \verb"ds"
register receives the segment selector of the pointer while the destination
register receives the offset part of the pointer. \verb"les", \verb"lfs",
\verb"lgs" and \verb"lss" operate identically to \verb"lds" except that
rather than \verb"ds" register the \verb"es", \verb"fs", \verb"gs" and
\verb"ss" is used respectively.
\begin{verbatim}
    lds bx,[si]      ; load pointer to ds:bx
\end{verbatim}

\index{lea}
\verb"lea" transfers the offset of the source operand (rather than its value)
to the destination operand. The source operand must be a memory operand, and
the destination operand must be a general register.
\begin{verbatim}
    lea dx,[bx+si+1] ; load effective address to dx
\end{verbatim}

\index{cpuid}
\verb"cpuid" returns processor identification and feature information in the
\verb"eax", \verb"ebx", \verb"ecx", and \verb"edx" registers. The information
returned is selected by entering a value in the \verb"eax" register before
the instruction is executed. This instruction has no operands.

\index{pause}
\verb"pause" instruction delays the execution of the next instruction an
implementation specific amount of time. It can be used to improve the
performance of spin wait loops. This instruction has no operands.

\index{enter}\index{leave}
\verb"enter" creates a stack frame that may be used to implement the scope
rules of block--structured high--level languages. A \verb"leave" instruction
at the end of a procedure complements an \verb"enter" at the beginning of the
procedure to simplify stack management and to control access to variables for
nested procedures. The \verb"enter" instruction includes two parameters. The
first parameter specifies the number of bytes of dynamic storage to be
allocated on the stack for the routine being entered. The second parameter
corresponds to the lexical nesting level of the routine, it can be in range
from 0 to 31. The specified lexical level determines how many sets of stack
frame pointers the CPU copies into the new stack frame from the preceding
frame. This list of stack frame pointers is sometimes called the display.
The first word (or double word when code is 32--bit) of the display is a
pointer to the last stack frame. This pointer enables a \verb"leave"
instruction to reverse the action of the previous \verb"enter" instruction by
effectively discarding the last stack frame. After \verb"enter" creates the
new display for a procedure, it allocates the dynamic storage space for that
procedure by decrementing \verb"esp" by the number of bytes specified in the
first parameter. To enable a procedure to address its display, \verb"enter"
leaves \verb"bp" (or \verb"ebp") pointing to the beginning of the new stack
frame. If the lexical level is zero, \verb"enter" pushes \verb"bp" (or
\verb"ebp"), copies \verb"sp" to \verb"bp" (or \verb"esp" to \verb"ebp") and
then subtracts the first operand from \verb"esp". For nesting levels greater
than zero, the processor pushes additional frame pointers on the stack before
adjusting the stack pointer.
\begin{verbatim}
    enter 2048,0     ; enter and allocate 2048 bytes on stack
\end{verbatim}

\subsection{System instructions}

\index{lmsw}\index{smsw}
\verb"lmsw" loads the operand into the machine status word (bits 0 through 15
of \verb"cr0" register), while \verb"smsw" stores the machine status word
into the destination operand. The operand for both those instructions can be 16--bit
general register or memory, for \verb"smsw" it can also be 32--bit general
register.
\begin{verbatim}
    lmsw ax          ; load machine status from register
    smsw [bx]        ; store machine status to memory
\end{verbatim}

\index{lgdt}\index{lidt}\index{sgdt}\index{sidt}
\verb"lgdt" and \verb"lidt" instructions load the values in operand into the
global descriptor table register or the interrupt descriptor table register
respectively. \verb"sgdt" and \verb"sidt" store the contents of the global
descriptor table register or the interrupt descriptor table register
in the destination operand. The operand should be a 6 bytes in memory.
\begin{verbatim}
    lgdt [ebx]       ; load global descriptor table
\end{verbatim}

\index{lldt}\index{sldt}\index{ltr}\index{str}
\verb"lldt" loads the operand into the segment selector field of
the local descriptor table register and \verb"sldt" stores the
segment selector from the local descriptor table register in the
operand. \verb"ltr" loads the operand into the segment selector
field of the task register and \verb"str" stores the segment
selector from the task register in the operand. Rules for operand
are the same as for the \verb"lmsw" and \verb"smsw" instructions.

\index{lar}
\verb"lar" loads the access rights from the segment descriptor
specified by the selector in source operand into the destination
operand and sets the ZF flag. The destination operand can be a
16-bit or 32--bit general register. The source operand should be a
16-bit general register or memory.
\begin{verbatim}
    lar ax,[bx]      ; load access rights into word
    lar eax,dx       ; load access rights into double word
\end{verbatim}

\index{lsl}
\verb"lsl" loads the segment limit from the segment descriptor specified by
the selector in source operand into the destination operand and sets the ZF
flag. Rules for operand are the same as for the \verb"lar" instruction.

\index{verr}\index{verw}
\verb"verr" and \verb"verw" verify whether the code or data segment specified
with the operand is readable or writable from the current privilege level.
The operand should be a word, it can be general register or memory.
If the segment is accessible and readable (for \verb"verr") or writable (for
\verb"verw") the ZF flag is set, otherwise it's cleared. Rules for operand
are the same as for the \verb"lldt" instruction.

\index{arpl}
\verb"arpl" compares the RPL (requestor's privilege level) fields of two
segment selectors. The first operand contains one segment selector and the
second operand contains the other. If the RPL field of the destination
operand is less than the RPL field of the source operand, the ZF flag is set
and the RPL field of the destination operand is increased to match that of
the source operand. Otherwise, the ZF flag is cleared and no change is made
to the destination operand. The destination operand can be a word general
register or memory, the source operand must be a general register.
\begin{verbatim}
    arpl bx,ax       ; adjust RPL of selector in register
    arpl [bx],ax     ; adjust RPL of selector in memory
\end{verbatim}

\index{clts}
\verb"clts" clears the TS (task switched) flag in the \verb"cr0" register.
This instruction has no operands.

\index{lock}
\verb"lock" prefix causes the processor's bus--lock signal to be asserted during
execution of the accompanying instruction. In a multiprocessor environment,
the bus--lock signal insures that the processor has exclusive use of any shared
memory while the signal is asserted. The \verb"lock" prefix can be prepended
only to the following instructions and only to those forms of the
instructions where the destination operand is a memory operand: \verb"add",
\verb"adc", \verb"and", \verb"btc", \verb"btr", \verb"bts", \verb"cmpxchg",
\verb"cmpxchg8b", \verb"dec", \verb"inc", \verb"neg", \verb"not", \verb"or",
\verb"sbb", \verb"sub", \verb"xor", \verb"xadd" and \verb"xchg". If the
\verb"lock" prefix is used with one of these instructions and the source
operand is a memory operand, an undefined opcode exception may be generated.
An undefined opcode exception will also be generated if the \verb"lock"
prefix is used with any instruction not in the above list. The \verb"xchg"
instruction always asserts the bus--lock signal regardless of the presence or
absence of the \verb"lock" prefix.

\index{hlt}
\verb"hlt" stops instruction execution and places the processor in a halted
state. An enabled interrupt, a debug exception, the BINIT, INIT or the RESET
signal will resume execution. This instruction has no operands.

\index{invlpg}
\verb"invlpg" invalidates (flushes) the TLB (translation lookaside buffer)
entry specified with the operand, which should be a memory. The processor
determines the page that contains that address and flushes the TLB entry for
that page.

\index{rdmsr}\index{wrmsr}
\verb"rdmsr" loads the contents of a 64--bit MSR (model specific register)
of the address specified in the \verb"ecx" register into registers \verb"edx"
and \verb"eax". \verb"wrmsr" writes the contents of registers \verb"edx" and
\verb"eax" into the 64--bit MSR of the address specified in the \verb"ecx"
register. \verb"rdtsc" loads the current value of the processor's time stamp
counter from the 64--bit MSR into the \verb"edx" and \verb"eax" registers.
The processor increments the time stamp counter MSR every clock cycle and
resets it to 0 whenever the processor is reset.

\index{rdpmc}
\verb"rdpmc" loads the contents of the 40--bit performance monitoring counter
specified in the \verb"ecx" register into registers \verb"edx" and
\verb"eax". These instructions have no operands.

\index{wbinvd}
\verb"wbinvd" writes back all modified cache lines in the processor's
internal cache to main memory and invalidates (flushes) the internal caches.
The instruction then issues a special function bus cycle that directs
external caches to also write back modified data and another bus cycle to
indicate that the external caches should be invalidated. This instruction has
no operands.

\index{rsm}
\verb"rsm" return program control from the system management mode to the
program that was interrupted when the processor received an SMM interrupt.
This instruction has no operands.

\index{sysenter}\index{sysexit}
\verb"sysenter" executes a fast call to a level 0 system procedure, \verb"sysexit"
executes a fast return to level 3 user code. The addresses used by these instructions
are stored in MSRs. These instructions have no operands.

\subsection{FPU instructions}

The FPU (Floating-Point Unit) instructions operate on the floating--point
values in three formats: single precision (32--bit), double precision
(64--bit) and double extended precision (80--bit). The FPU registers form
the stack and each of them holds the double extended precision floating--point
value. When some values are pushed onto the stack or are removed from the top,
the FPU registers are shifted, so \verb"st0" is always the value on
the top of FPU stack, \verb"st1" is the first value below the top, etc.
The \verb"st0" name has also the synonym \verb"st".

\index{fld}
\verb"fld" pushes the floating--point value onto the FPU register stack.
The operand can be 32--bit, 64--bit or 80--bit memory location or the
FPU register, its value is then loaded onto the top of FPU register stack
(the \verb"st0" register) and is automatically converted into the
double extended precision format.
\begin{verbatim}
    fld dword [bx]   ; load single prevision value from memory
    fld st2          ; push value of st2 onto register stack
\end{verbatim}

\index{fld1}\index{lfdz}\index{ldl2t}\index{lfdl2e}\index{fldpi}
\index{fldlg2}\index{fldln2}
\verb"fld1", \verb"fldz", \verb"fldl2t", \verb"fldl2e", \verb"fldpi",
\verb"fldlg2" and \verb"fldln2" load the commonly used contants onto the
FPU register stack. The loaded constants are $+1.0$, $+0.0$, $\log_{2}10$,
$\log_{2}e$, $\pi$, $\log_{10}2$ and $\ln{2}$ respectively. These instructions
have no operands.

\index{fild}
\verb"fild" converts the signed integer source operand into double extended
precision floating-point format and pushes the result onto the FPU register
stack. The source operand can be a 16--bit, 32--bit or 64--bit memory location.
\begin{verbatim}
    fild qword [bx]  ; load 64-bit integer from memory
\end{verbatim}

\index{fst}\index{fstp}
\verb"fst" copies the value of \verb"st0" register to the destination operand,
which can be 32--bit or 64--bit memory location or another FPU register.
\verb"fstp" performs the same operation as \verb"fst" and then pops the register
stack, getting rid of \verb"st0". \verb"fstp" accepts the same operands as
the \verb"fst" instruction and can also store value in the 80--bit memory.
\begin{verbatim}
    fst st3          ; copy value of st0 into st3 register
    fstp tword [bx]  ; store value in memory and pop stack
\end{verbatim}

\index{fist}
\verb"fist" converts the value in \verb"st0" to a signed integer and stores
the result in the destination operand. The operand can be 16--bit or
32--bit memory location. \verb"fistp" performs the same operation and then
pops the register stack, it accepts the same operands as the \verb"fist"
instruction and can also store integer value in the 64--bit memory, so it
has the same rules for operands as \verb"fild" instruction.

\index{fbld}
\verb"fbld" converts the packed BCD integer into double extended precision
floating--point format and pushes this value onto the FPU stack. \verb"fbstp"
converts the value in \verb"st0" to an 18--digit packed BCD integer, stores the
result in the destination operand, and pops the register stack. The operand
should be an 80--bit memory location.

\index{fadd}
\verb"fadd" adds the destination and source operand and stores the sum in the
destination location. The destination operand is always an FPU register, if the
source is a memory location, the destination is \verb"st0" register and only
source operand should be specified. If both operands are FPU registers, at
least one of them should be \verb"st0" register. An operand in memory can be
a 32--bit or 64--bit value.
\begin{verbatim}
    fadd qword [bx]  ; add double precision value to st0
    fadd st2,st0     ; add st0 to st2
\end{verbatim}

\index{faddp}
\verb"faddp" adds the destination and source operand, stores the sum in the
destination location and then pops the register stack. The destination operand
must be an FPU register and the source operand must be the \verb"st0". When
no operands are specified, \verb"st1" is used as a destination operand.
\begin{verbatim}
    faddp            ; add st0 to st1 and pop the stack
    faddp st2,st0    ; add st0 to st2 and pop the stack
\end{verbatim}

\index{fiadd}
\verb"fiadd" instruction converts an integer source operand into double
extended precision floating--point value and adds it to the destination
operand. The operand should be a 16--bit or 32--bit memory location.
\begin{verbatim}
    fiadd word [bx]  ; add word integer to st0
\end{verbatim}

\index{fsub}\index{fsubr}\index{fmul}\index{fdiv}\index{fdivr}
\verb"fsub", \verb"fsubr", \verb"fmul", \verb"fdiv", \verb"fdivr" instruction
are similar to \verb"fadd", have the same rules for operands and differ only in
the perfomed computation. \verb"fsub" substracts the source operand from the
destination operand, \verb"fsubr" substract the destination operand from the
source operand, \verb"fmul" multiplies the destination and source operands,
\verb"fdiv" divides the destination operand by the source operand and \verb"fdivr"
divides the source operand by the destination operand. \verb"fsubp", \verb"fsubrp",
\verb"fmulp", \verb"fdivp", \verb"fdivrp" perform the same operations and pop the
register stack, the rules for operand are the same as for the \verb"faddp"
instruction. \verb"fisub", \verb"fisubr", \verb"fimul", \verb"fidiv", \verb"fidivr"
perform these operations after converting the integer source operand into
floating--point value, they have the same rules for operands as \verb"fiadd"
instruction.

\index{fsqrt}\index{fsin}\index{fcos}\index{fchs}\index{fabs}\index{frndint}
\index{f2xm1}
\verb"fsqrt" computes the square root of the value in \verb"st0" register,
\verb"fsin" computes the sine of that value, \verb"fcos" computes the cosine
of that value, \verb"fchs" complements its sign bit, \verb"fabs" clears its sign to
create the absolute value, \verb"frndint" rounds it to the nearest integral value,
depending on the current rounding mode. \verb"f2xm1" computes the exponential value
of 2 to the power of \verb"st0" and substracts the $1.0$ from it, the value of
\verb"st0" must lie in the range $-1.0$ to $+1.0$.
All these instruction store the result in \verb"st0" and have no operands.

\index{fsincos}\index{fptan}\index{fpatan}\index{fyl2x}\index{fyl2xp1}
\index{fprem}\index{fprem1}\index{fscale}\index{fxtract}\index{fnop}
\verb"fsincos" computes both the sine and the cosine of the value in
\verb"st0" register, stores the sine in \verb"st0" and pushes the cosine on the
top of FPU register stack. \verb"fptan" computes the tangent of the value in
\verb"st0", stores the result in \verb"st0" and pushes a $1.0$ onto the FPU register
stack. \verb"fpatan" computes the arctangent of the value in \verb"st1" divided by
the value in \verb"st0", stores the result in \verb"st1" and pops the FPU register
stack. \verb"fyl2x" computes the binary logarithm of \verb"st0", multiplies it by
\verb"st1", stores the result in \verb"st1" and pops the FPU register stack;
\verb"fyl2xp1" performs the same operation but it adds $1.0$ to \verb"st0" before
computing the logarithm. \verb"fprem" computes the remainder obtained from
dividing the value in \verb"st0" by the value in \verb"st1", and stores the result
in \verb"st0". \verb"fprem1" performs the same operation as \verb"fprem", but it
computes the remainder in the way specified by IEEE Standard 754. \verb"fscale"
truncates the value in \verb"st1" and increases the exponent of \verb"st0" by this value.
\verb"fxtract" separates the value in \verb"st0" into its exponent and significand,
stores the exponent in \verb"st0" and pushes the significand onto the register
stack. \verb"fnop" performs no operation. These instruction have no operands.

\index{fxch}
\verb"fxch" exchanges the contents of \verb"st0" an another FPU register. The
operand should be an FPU register, if no operand is specified, the contents of
\verb"st0" and \verb"st1" are exchanged.

\index{fcom}\index{fcomp}
\verb"fcom" and \verb"fcomp" compare the contents of \verb"st0" and the source
operand and set flags in the FPU status word according to the results.
\verb"fcomp" additionally pops the register stack after performing the comparison.
The operand can be a single or double precision value in memory or the FPU register.
When no operand is specified, \verb"st1" is used as a source operand.
\begin{verbatim}
    fcom             ; compare st0 with st1
    fcomp st2        ; compare st0 with st2 and pop stack
\end{verbatim}

\index{fcompp}
\verb"fcompp" compares the contents of \verb"st0" and \verb"st1", sets flags in the
FPU status word according to the results and pops the register stack twice.
This instruction has no operands.

\index{fucom}\index{fucomp}\index{fucompp}
\verb"fucom", \verb"fucomp" and \verb"fucompp" performs an unordered comparison of
two FPU registers. Rules for operands are the same as for the \verb"fcom",
\verb"fcomp" and \verb"fcompp", but the source operand must be an FPU register.

\index{ficom}\index{ficomp}
\verb"ficom" and \verb"ficomp" compare the value in \verb"st0" with an integer
source operand and set the flags in the FPU status word according to the results.
\verb"ficomp" additionally pops the register stack after performing the comparison.
The integer value is converted to double extended precision floating--point format
before the comparison is made. The operand should be a 16--bit or 32--bit memory
location.
\begin{verbatim}
    ficom word [bx]  ; compare st0 with 16-bit integer
\end{verbatim}

\index{fcomi}\index{fcomip}\index{fucomi}\index{fucomip}
\verb"fcomi", \verb"fcomip", \verb"fucomi", \verb"fucomip" perform the comparison
of \verb"st0" with another FPU register and set the ZF, PF and CF flags according to
the results. \verb"fcomip" and \verb"fucomip" additionaly pop the register stack
after performing the comparison.

\index{fcmovb}\index{fcmove}\index{fcmovbe}\index{fcmovu}
\index{fcmovnb}\index{fcmovne}\index{fcmovnbe}\index{fcmovnu}
The instructions obtained by attaching the FPU
condition mnemonic (see table \ref{tab:FPU_conditions}) to the \verb"fcmov" mnemonic
transfer the specified FPU register into \verb"st0" register if the given test
condition is true. These instruction allow two different syntaxes, one with single
operand specifying the source FPU register, and one with two operands, in that case
destination operand should be \verb"st0" register and the second operand specifies
the source FPU register.
\begin{verbatim}
    fcomi st2        ; compare st0 with st2 and set flags
    fcmovb st0,st2   ; transfer st2 to st0 if below
\end{verbatim}

\label{tab:FPU_conditions}
\begin{table}[hbt]
\caption{FPU conditions.}
\begin{center}\begin{tabular}{|c|c|c|}
\hline
Mnemonic & Condition tested & Description \\
\hline \hline
\verb"b" & CF = 1 & below\\
\hline
\verb"e" & ZF = 1 & equal\\
\hline
\verb"be" & CF \verb"or" ZF = 1 & below or equal\\
\hline
\verb"u" & PF = 1 & unordered\\
\hline
\verb"nb" & CF = 0 & not below\\
\hline
\verb"ne" & ZF = 0 & not equal\\
\hline
\verb"nbe" & CF \verb"and" ZF = 0 & not below nor equal\\
\hline
\verb"nu" & PF = 0 & not unordered\\
\hline
\end{tabular}\end{center}
\end{table}

\index{ftst}\index{fxam}
\verb"ftst" compares the value in \verb"st0" with $0.0$ and sets the flags in the
FPU status word according to the results. \verb"fxam" examines the contents of the
\verb"st0" and sets the flags in FPU status word to indicate the class of value in
the register. These instructions have no operands.

\index{fstsw}\index{fnstsw}
\verb"fstsw" and \verb"fnstsw" store the current value of the FPU status word in the
destination location. The destination operand can be either a 16--bit memory or the
\verb"ax" register. \verb"fstsw" checks for pending umasked FPU exceptions before
storing the status word, \verb"fnstsw" does not.

\index{fstcw}\index{fnstcw}
\verb"fstcw" and \verb"fnstcw" store the current value of the FPU control word
at the specified destination in memory. \verb"fstcw" checks for pending unmasked FPU
exceptions before storing the control word, \verb"fnstcw" does not. \verb"fldcw" loads
the operand into the FPU control word. The operand should be a 16--bit memory
location.

\index{fstenv}\index{fnstenv}\index{fldenv}\index{fsave}\index{fnsave}\index{frstor}
\index{fstenvw}\index{fnstenvw}\index{fldenvw}\index{fsavew}\index{fnsavew}\index{frstorw}
\index{fstenvd}\index{fnstenvd}\index{fldenvd}\index{fsaved}\index{fnsaved}\index{frstord}
\verb"fstenv" and \verb"fnstenv" store the current FPU operating environment at
the memory location specified with the destination operand, and then mask all
FPU exceptions. \verb"fstenv" checks for pending umasked FPU exceptions before
proceeding, \verb"fnstenv" does not. \verb"fldenv" loads the complete operating
environment from memory into the FPU. \verb"fsave" and \verb"fnsave"
store the current FPU state (operating environment and register stack) at the
specified destination in memory and reinitializes the FPU. \verb"fsave" check
for pending unmasked FPU exceptions before proceeding, \verb"fnsave" does not.
\verb"frstor" loads the FPU state from the specified memory location.
All these instructions need an operand being a memory location.
For each of these instruction
exist two additional mnemonics that allow to precisely select the type of the
operation. The \verb"fstenvw", \verb"fnstenvw", \verb"fldenvw", \verb"fsavew", \verb"fnsavew" and
\verb"frstorw" mnemonics force the instruction to perform operation as in the 16--bit
mode, while \verb"fstenvd", \verb"fnstenvd", \verb"fldenvd", \verb"fsaved", \verb"fnsaved" and \verb"frstord"
force the operation as in 32--bit mode.

\index{finit}\index{fninit}\index{fclex}\index{fnclex}\index{wait}\index{fwait}
\verb"finit" and \verb"fninit" set the FPU operating environment into its default
state. \verb"finit" checks for pending unmasked FPU exception before proceeding,
\verb"fninit" does not. \verb"fclex" and \verb"fnclex" clear the FPU exception flags in the FPU
status word. \verb"fclex" checks for pending unmasked FPU exception before proceeding,
\verb"fnclex" does not. \verb"wait" and \verb"fwait" are synonyms for the same
instruction, which causes the processor to check for pending unmasked FPU exceptions
and handle them before proceeding. These instruction have no operands.

\index{ffree}
\verb"ffree" sets the tag associated with specified FPU register to empty. The
operand should be an FPU register.

\index{fincstp}\index{fdecstp}
\verb"fincstp" and \verb"fdecstp" rotate the FPU stack by one by adding or
substracting one to the pointer of the top of stack. These instruction have no
operands.

\subsection{MMX instructions}
\label{sec:MMX_instructions}

The MMX instructions operate on the packed integer types and use the MMX registers,
which are the low 64--bit parts of the 80--bit FPU registers. Because of this MMX
instructions cannot be used at the same time as FPU instructions. They can operate
on packed bytes (eight 8--bit integers), packed words (four 16--bit integers) or
packed double words (two 32--bit integers), use of packed formats allows to perform
operations on multiple data at one time.

\index{movq}
\verb"movq" copies a quad word from the source operand to the destination operand.
At least one of the operands must be a MMX register, the second one can be also
a MMX register or 64--bit memory location.
\begin{verbatim}
    movq mm0,mm1     ; move quad word from register to register
    movq mm2,[ebx]   ; move quad word from memory to register
\end{verbatim}

\index{movd}
\verb"movd" copies a double word from the source operand to the destination operand.
One of the operands must be a MMX register, the second one can be a general register
or 32--bit memory location. Only low double word of MMX register is used.

All general MMX operations have two operands, the destination operand should be
a MMX register, the source operand can be a MMX register or 64--bit memory location.
Operation is performed on the corresponding data elements of the source and destination
operand and stored in the data elements of the destination operand.

\index{paddb}\index{paddw}\index{paddd}
\verb"paddb", \verb"paddw" and \verb"paddd" perform the addition of packed bytes,
packed words, or packed double words.  

\index{psubb}\index{psubw}\index{psubd}
\verb"psubb", \verb"psubw" and \verb"psubd" perform the substraction of appropriate types. 

\index{paddsb}\index{paddsw}\index{psubsb}\index{psubsw}
\verb"paddsb", \verb"paddsw", \verb"psubsb" and \verb"psubsw" perform the addition or 
substraction of packed bytes or packed words with the signed saturation. 

\index{paddusb}\index{paddusw}\index{psubusb}\index{psubusw}
\verb"paddusb", \verb"paddusw", \verb"psubusb", \verb"psubusw" are analoguous, but with 
unsigned saturation.

\index{pmulhw}\index{pmullw}\
\verb"pmulhw" and \verb"pmullw" performs a signed multiplication of the packed words
and store the high or low words of the results in the destination operand.

\index{pmaddwd}
\verb"pmaddwd" performs a multiply of the packed words and adds the four intermediate
double word products in pairs to produce result as a packed double words.

\index{pand}\index{por}\index{pxor}\index{pandn}
\verb"pand", \verb"por" and \verb"pxor" perform the logical operations on the quad words,
\verb"pandn" peforms also a logical negation of the destination operand before the
operation.

\index{pcmpeqb}\index{pcmpeqw}\index{pcmpeqd}
\verb"pcmpeqb", \verb"pcmpeqw" and \verb"pcmpeqd" compare for equality of packed
bytes, packed words or packed double words. If a pair of data elements is equal,
the corresponding data element in the destination operand is filled with bits of
value 1, otherwise it's set to 0. 

\index{pcmpgtb}\index{pcmpgtw}\index{pcmpgtd}
\verb"pcmpgtb", \verb"pcmpgtw" and \verb"pcmpgtd"
perform the similar operation, but they check whether the data elements in
the destination operand are greater than the correspoding data elements in the
source operand.

\index{packsswb}\index{packssdw}\index{packuswb}
\verb"packsswb" converts packed signed words into packed signed bytes, \verb"packssdw"
converts packed signed double words into packed signed words, using saturation to
handle overflow conditions. \verb"packuswb" converts packed signed words into
packed unsigned bytes. Converted data elements from the source operand are stored
in the low part of the destination operand, while converted data elements from
the destination operand are stored in the high part.

\index{punpckhbw}\index{punpckhwd}\index{punpckhdq}
\verb"punpckhbw", \verb"punpckhwd" and \verb"punpckhdq" interleaves the
data elements from the high parts of the source and destination operands and stores
the result into the destination operand. 

\index{punpcklbw}\index{punpcklwd}\index{punpckldq}
\verb"punpcklbw", \verb"punpcklwd" and
\verb"punpckldq" perform the same operation, but the low parts of the source and destination
operand are used.
\begin{verbatim}
    paddsb mm0,[esi] ; add packed bytes with signed saturation
    pcmpeqw mm3,mm7  ; compare packed words for equality
\end{verbatim}

\index{psllw}\index{pslld}\index{psllq}
\verb"psllw", \verb"pslld" and \verb"psllq" perform logical shift left of the packed
words, packed double words or a single quad word in the destination operand by the
amount specified in the source operand. 

\index{psrlw}\index{psrld}\index{psrlq}
\verb"psrlw", \verb"psrld" and \verb"psrlq" perform logical shift right of the packed words, 
packed double words or a single quad word. 

\index{psraw}\index{psrad}
\verb"psraw" and \verb"psrad" perform arithmetic shift of the packed words or
double words. The destination operand should be a MMX register, while source operand
can be a MMX register, 64--bit memory location, or 8--bit immediate value.
\begin{verbatim}
    psllw mm2,mm4    ; shift words left logically
    psrad mm4,[ebx]  ; shift double words right arithmetically
\end{verbatim}

\index{emms}
\verb"emms" makes the FPU registers usable for the FPU instructions, it must be used
before using the FPU instructions if any MMX instructions were used.

\subsection{SSE instructions}
The SSE extension adds more MMX instructions and also introduces the
operations on packed single precision floating point values. The 128--bit
packed single precision format consists of four single precision floating
point values. The 128--bit SSE registers are designed for the purpose of
operations on this data type.

\index{movaps}\index{movups}
\verb"movaps" and \verb"movups" transfer a double quad word operand containing packed
single precision values from source operand to destination operand. At least
one of the operands have to be a SSE register, the second one can be also a
SSE register or 128--bit memory location. Memory operands for \verb"movaps"
instruction must be aligned on boundary of 16 bytes, operands for \verb"movups"
instruction don't have to be aligned.
\begin{verbatim}
    movups xmm0,[ebx]  ; move unaligned double quad word
\end{verbatim}

\index{movlps}\index{movhps}
\verb"movlps" moves packed two single precision values between the memory and the
low quad word of SSE register. \verb"movhps" moved packed two single precision
values between the memory and the high quad word of SSE register. One of the
operands must be a SSE register, and the other operand must be a 64--bit memory
location.
\begin{verbatim}
    movlps xmm0,[ebx]  ; move memory to low quad word of xmm0
    movhps [esi],xmm7  ; move high quad word of xmm7 to memory
\end{verbatim}

\index{movlhps}\index{movhlps}
\verb"movlhps" moves packed two single precision values from the low quad word
of source register to the high quad word of destination register. \verb"movhlps"
moves two packed single precision values from the high quad word of source
register to the low quad word of destination register. Both operands have to
be a SSE registers.

\index{movmskps}
\verb"movmskps" transfers the most significant bit of each of the four single
precision values in the SSE register into low four bits of a general register.
The source operand must be a SSE register, the destination operand must be a
general register.

\index{movss}
\verb"movss" transfers a single precision value between source and destination
operand (only the low double word is trasferred). At least one of the operands
have to be a SSE register, the second one can be also a SSE register or 32--bit
memory location.
\begin{verbatim}
    movss [edi],xmm3   ; move low double word of xmm3 to memory
\end{verbatim}

Each of the SSE arithmetic operations has two variants. When the mnemonic
ends with \verb"ps", the source operand can be a 128--bit memory location or a SSE
register, the destination operand must be a SSE register and the operation is
performed on packed four single precision values, for each pair of the
corresponding data elements separately, the result is stored in the
destination register. When the mnemonic ends with \verb"ss", the source operand
can be a 32--bit memory location or a SSE register, the destination operand
must be a SSE register and the operation is performed on single precision
values, only low double words of SSE registers are used in this case, the
result is stored in the low double word of destination register. 

\index{addps}\index{addss}\index{subps}\index{subss}\index{mulps}\index{mulss}
\index{divps}\index{divss}\index{rcpps}\index{rcpss}\index{sqrtps}\index{sqrtss}
\index{rsqrtps}\index{rsqrtss}\index{maxps}\index{maxss}\index{minps}\index{minss}
\verb"addps" and \verb"addss" add the values, \verb"subps" and \verb"subss" substract the 
source value from destination value, \verb"mulps" and \verb"mulss" multiply the values, 
\verb"divps" and \verb"divss" divide the destination value by the source value, 
\verb"rcpps" and \verb"rcpss" compute the approximate reciprocal of the source value, 
\verb"sqrtps" and \verb"sqrtss" compute the square root of the source value, 
\verb"rsqrtps" and \verb"rsqrtss" compute the approximate reciprocal of square root 
of the source value, \verb"maxps" and \verb"maxss" compare the source and destination 
values and return the greater one, \verb"minps" and \verb"minss" compare the source and 
destination values and return the lesser one.
\begin{verbatim}
    mulss xmm0,[ebx]   ; multiply single precision values
    addps xmm3,xmm7    ; add packed single precision values
\end{verbatim}

\index{andps}\index{andnps}\index{orps}\index{xorps}
\verb"andps", \verb"andnps", \verb"orps" and \verb"xorps" perform the logical operations on
packed single precision values. The source operand can be a 128--bit memory
location or a SSE register, the destination operand must be a SSE register.

\index{cmpps}\index{cmpss}\index{cmpeqps}\index{cmpeqss}\index{cmpltps}\index{cmpltss}
\index{cmpleps}\index{cmpless}\index{cmpunordps}\index{cmpunordss}\index{cmpneqps}\index{cmpneqss}
\index{cmpnltps}\index{cmpnltss}\index{cmpnleps}\index{cmpnless}\index{cmpordps}\index{cmpordss}
\verb"cmpps" compares packed single precision values and returns a mask result
into the destination operand, which must be a SSE register. The source operand
can be a 128--bit memory location or SSE register, the third operand must be an
immediate operand selecting code of one of the eight compare conditions
(table \ref{tab:SSE_conditions}). \verb"cmpss" performs the same operation on single precision values,
only low double word of destination register is affected, in this case source
operand can be a 32--bit memory location or SSE register. These two
instructions have also variants with only two operands and the condition
encoded within mnemonic. Their mnemonics are obtained by attaching the
mnemonic from table \ref{tab:SSE_conditions} to the \verb"cmp" mnemonic and then attaching the \verb"ps" or
\verb"ss" at the end.
\begin{verbatim}
    cmpps xmm2,xmm4,0  ; compare packed single precision values
    cmpltss xmm0,[ebx] ; compare single precision values
\end{verbatim}

\begin{table}[hbt]
\begin{center}\begin{tabular}{|c|c|c|}
\hline
Code & Mnemonic & Description \\
\hline \hline
0 & \verb"eq" & equal \\
\hline
1 & \verb"lt" & less than \\
\hline
2 & \verb"le" & less than or equal \\
\hline
3 & \verb"unord" & unordered \\
\hline
4 & \verb"neq" & not equal \\
\hline
5 & \verb"nlt" & not less than \\
\hline
6 & \verb"nle" & not less than nor equal \\
\hline
7 & \verb"ord" & ordered \\
\hline
\end{tabular}\end{center}
\caption{SSE conditions.}
\label{tab:SSE_conditions}
\end{table}

\index{comiss}\index{ucomiss}
\verb"comiss" and \verb"ucomiss" compare the single precision values and set the ZF,
PF and CF flags to show the result. The destination operand must be a SSE
register, the source operand can be a 32--bit memory location or SSE register.

\index{shufps}
\verb"shufps" moves any two of the four single precision values from the
destination operand into the low quad word of the destination operand, and any
two of the four values from the source operand into the high quad word of the
destination operand. The destination operand must be a SSE register, the
source operand can be a 128--bit memory location or SSE register, the third
operand must be an 8--bit immediate value selecting which values will be moved
into the destination operand. Bits 0 and 1 select the value to be moved from
destination operand to the low double word of the result, bits 2 and 3 select
the value to be moved from the destination operand to the second double word,
bits 4 and 5 select the value to be moved from the source operand to the third
double word, and bits 6 and 7 select the value to be moved from the source
operand to the high double word of the result.
\begin{verbatim}
    shufps xmm0,xmm0,10010011b ; shuffle double words
\end{verbatim}

\index{unpckhps}\index{unpcklps}
\verb"unpckhps" performs an interleaved unpack of the values from the high parts
of the source and destination operands and stores the result in the
destination operand, which must be a SSE register. The source operand can be
a 128--bit memory location or a SSE register. \verb"unpcklps" performs an
interleaved unpack of the values from the low parts of the source and
destination operand and stores the result in the destination operand,
the rules for operands are the same.

\index{cvtpi2ps}
\verb"cvtpi2ps" converts packed two double word integers into the the packed two
single precision floating point values and stores the result in the low quad
word of the destination operand, which should be a SSE register. The source
operand can be a 64--bit memory location or MMX register.
\begin{verbatim}
    cvtpi2ps xmm0,mm0  ; integers to single precision values
\end{verbatim}

\index{cvtsi2ss}
\verb"cvtsi2ss" converts a double word integer into a single precision floating
point value and stores the result in the low double word of the destination
operand, which should be a SSE register. The source operand can be a 32--bit
memory location or 32--bit general register.
\begin{verbatim}
    cvtsi2ss xmm0,eax  ; integer to single precision value
\end{verbatim}

\index{cvtps2pi}\index{cvttps2pi}
\verb"cvtps2pi" converts packed two single precision floating point values into
packed two double word integers and stores the result in the destination
operand, which should be a MMX register. The source operand can be a 64--bit
memory location or SSE register, only low quad word of SSE register is used.
\verb"cvttps2pi" performs the similar operation, except that truncation is used to
round a source values to integers, rules for the operands are the same.
\begin{verbatim}
    cvtps2pi mm0,xmm0  ; single precision values to integers
\end{verbatim}

\index{cvtss2si}\index{cvttss2si}
\verb"cvtss2si" convert a single precision floating point value into a double
word integer and stores the result in the destination operand, which should be
a 32--bit general register. The source operand can be a 32--bit memory location
or SSE register, only low double word of SSE register is used. \verb"cvttss2si"
performs the similar operation, except that truncation is used to round a
source value to integer, rules for the operands are the same.
\begin{verbatim}
    cvtss2si eax,xmm0  ; single precision value to integer
\end{verbatim}

\index{pextrw}
\verb"pextrw" copies the word in the source operand specified by the third
operand to the destination operand. The source operand must be a MMX register,
the destination operand must be a 32--bit general register (the high word of
the destination is cleared), the third operand must an 8--bit immediate value.
\begin{verbatim}
    pextrw eax,mm0,1   ; extract word into eax
\end{verbatim}

\index{pinsrw}
\verb"pinsrw" inserts a word from the source operand in the destination operand
at the location specified with the third operand, which must be an 8--bit
immediate value. The destination operand must be a MMX register, the source
operand can be a 16--bit memory location or 32--bit general register (only low
word of the register is used).
\begin{verbatim}
    pinsrw mm1,ebx,2   ; insert word from ebx
\end{verbatim}

\index{pavgb}\index{pavgw}\index{pmaxub}\index{pminub}\index{pmaxsw}\index{pminsw}
\index{pmulhuw}\index{psadbw}
\verb"pavgb" and \verb"pavgw" compute average of packed bytes or words. \verb"pmaxub"
return the maximum values of packed unsigned bytes, \verb"pminub" returns the
minimum values of packed unsigned bytes, \verb"pmaxsw" returns the maximum values
of packed signed words, \verb"pminsw" returns the minimum values of packed signed
words. \verb"pmulhuw" performs a unsigned multiplication of the packed words and stores
the high words of the results in the destination operand. \verb"psadbw" computes
the absolute differences of packed unsigned bytes, sums the differences, and
stores the sum in the low word of destination operand. All these instructions
follow the same rules for operands as the general MMX operations described in
previous section.

\index{pmovmskb}
\verb"pmovmskb" creates a mask made of the most significant bit of each byte in
the source operand and stores the result in the low byte of destination
operand. The source operand must be a MMX register, the destination operand
must a 32--bit general register.

\index{pshufw}
\verb"pshufw" inserts words from the source operand in the destination operand
from the locations specified with the third operand. The destination operand
must be a MMX register, the source operand can be a 64--bit memory location or
MMX register, third operand must an 8--bit immediate value selecting which
values will be moved into destination operand, in the similar way as the third
operand of the \verb"shufps" instruction.

\index{movntq}\index{movntps}\index{maskmovq}
\verb"movntq" moves the quad word from the source operand to memory using a
non--temporal hint to minimize cache pollution. The source operand should be a
MMX register, the destination operand should be a 64--bit memory location.
\verb"movntps" stores packed single precision values from the SSE register to
memory using a non--temporal hint. The source operand should be a SSE register,
the destination operand should be a 128--bit memory location. \verb"maskmovq" stores
selected bytes from the first operand into a 64--bit memory location using a
non--temporal hint. Both operands should be a MMX registers, the second operand
selects wich bytes from the source operand are written to memory. The
memory location is pointed by DI (or EDI) register in the segment selected
by DS.

\index{prefetch0}\index{prefetch1}\index{prefetch2}\index{prefetchnta}
\verb"prefetcht0", \verb"prefetcht1", \verb"prefetcht2" and \verb"prefetchnta" fetch the line
of data from memory that contains byte specified with the operand to a
specified location in hierarchy.  The operand should be an 8--bit memory
location.

\index{sfence}
\verb"sfence" performs a serializing operation on all instruction storing to
memory that were issued prior to it. This instruction has no operands.

\index{ldmxcsr}\index{stmxcsr}
\verb"ldmxcsr" loads the 32--bit memory operand into the MXCSR register. \verb"stmxcsr"
stores the contents of MXCSR into a 32--bit memory operand.

\index{fxsave}\index{fxrstor}\index{fxsave}
\verb"fxsave" saves the current state of the FPU, MXCSR register, and all the FPU
and SSE registers to a 512--byte memory location specified in the destination
operand. \verb"fxrstor" reloads data previously stored with \verb"fxsave" instruction
from the specified 512--byte memory location. The memory operand for both those
instructions must be aligned on 16 byte boundary, it should declare operand
of no specified size.

\subsection{SSE2 instructions}
The SSE2 extension introduces the operations on packed double precision
floating point values, extends the syntax of MMX instructions, and adds also
some new instructions.

\index{movapd}\index{movupd}
\verb"movapd" and \verb"movupd" transfer a double quad word operand containing packed
double precision values from source operand to destination operand. These
instructions are analogous to \verb"movaps" and \verb"movups" and have the same rules
for operands.

\index{movlpd}\index{movhpd}
\verb"movlpd" moves double precision value between the memory and the low quad
word of SSE register. \verb"movhpd" moved double precision value between the memory
and the high quad word of SSE register. These instructions are analogous to
\verb"movlps" and \verb"movhps" and have the same rules for operands.

\index{movmskpd}
\verb"movmskpd" transfers the most significant bit of each of the two double
precision values in the SSE register into low two bits of a general register.
This instruction is analogous to \verb"movmskps" and has the same rules for
operands.

\index{movsd}
\verb"movsd" transfers a double precision value between source and destination
operand (only the low quad word is trasferred). At least one of the operands
have to be a SSE register, the second one can be also a SSE register or 64--bit
memory location.

\index{addpd}\index{addsd}\index{subpd}\index{subsd}\index{mulpd}\index{mulsd}
\index{divpd}\index{divsd}\index{sqrtpd}\index{sqrtsd}\index{maxpd}\index{maxsd}
\index{minpd}\index{minsd}
Arithmetic operations on double precision values are: \verb"addpd", \verb"addsd",
\verb"subpd", \verb"subsd", \verb"mulpd", \verb"mulsd", \verb"divpd", \verb"divsd", \verb"sqrtpd", \verb"sqrtsd",
\verb"maxpd", \verb"maxsd", \verb"minpd", \verb"minsd", and they are analoguous to arithmetic
operations on single precision values described in previous section. When the
mnemonic ends with \verb"pd" instead of \verb"ps", the operation is performed on packed
two double precision values, but rules for operands are the same. When the
mnemonic ends with \verb"sd" instead of \verb"ss", the source operand can be a 64--bit
memory location or a SSE register, the destination operand must be a SSE
register and the operation is performed on double precision values, only low
quad words of SSE registers are used in this case.

\index{andpd}\index{andnpd}\index{orpd}\index{xorpd}
\verb"andpd", \verb"andnpd", \verb"orpd" and \verb"xorpd" perform the logical operations on
packed double precision values. They are analoguous to SSE logical operations
on single prevision values and have the same rules for operands.

\index{cmppd}\index{cmpsd}\index{cmpeqpd}\index{cmpeqsd}\index{cmpltpd}\index{cmpltsd}
\index{cmplepd}\index{cmplesd}\index{cmpunordpd}\index{cmpunordsd}\index{cmpneqpd}\index{cmpneqsd}
\index{cmpnltpd}\index{cmpnltsd}\index{cmpnlepd}\index{cmpnlesd}\index{cmpordpd}\index{cmpordsd}
\verb"cmppd" compares packed double precision values and returns and returns a
mask result into the destination operand. This instruction is analoguous to
\verb"cmpps" and has the same rules for operands. \verb"cmpsd" performs the same
operation on double precision values, only low quad word of destination
register is affected, in this case source operand can be a 64--bit memory or
SSE register. Variant with only two operands are obtained by attaching the
condition mnemonic from table \ref{tab:SSE_conditions} to the \verb"cmp" mnemonic and then attaching
the \verb"pd" or \verb"sd" at the end.

\index{comisd}\index{ucomisd}
\verb"comisd" and \verb"ucomisd" compare the double precision values and set the ZF,
PF and CF flags to show the result. The destination operand must be a SSE
register, the source operand can be a 128--bit memory location or SSE register.

\index{shufpd}\index{shufps}
\verb"shufpd" moves any of the two double precision values from the destination
operand into the low quad word of the destination operand, and any of the two
values from the source operand into the high quad word of the destination
operand. This instruction is analoguous to \verb"shufps" and has the same rules for
operand. Bit 0 of the third operand selects the value to be moved from the
destination operand, bit 1 selects the value to be moved from the source
operand, the rest of bits are reserved and must be zeroed.

\index{unpckhpd}\index{unpcklpd}
\verb"unpckhpd" performs an unpack of the high quad words from the source and
destination operands, \verb"unpcklpd" performs an unpack of the low quad words from
the source and destination operands. They are analoguous to \verb"unpckhps" and
\verb"unpcklps", and have the same rules for operands.

\index{cvtps2pd}\index{cvtpd2ps}\index{cvtss2sd}\index{cvtsd2ss}
\verb"cvtps2pd" converts the packed two single precision floating point values to
two packed double precision floating point values, the destination operand
must be a SSE register, the source operand can be a 64--bit memory location or
SSE register. \verb"cvtpd2ps" converts the packed two double precision floating
point values to packed two single precision floating point values, the
destination operand must be a SSE register, the source operand can be a
128--bit memory location or SSE register. \verb"cvtss2sd" converts the single
precision floating point value to double precision floating point value, the
destination operand must be a SSE register, the source operand can be a 32--bit
memory location or SSE register. \verb"cvtsd2ss" converts the double precision
floating point value to single precision floating point value, the destination
operand must be a SSE register, the source operand can be 64--bit memory
location or SSE register.

\index{cvtpi2pd}\index{cvtsi2sd}\index{cvtpd2pi}
\index{cvttpd2pi}\index{cvtsd2si}\index{cvttsd2si}
\verb"cvtpi2pd" converts packed two double word integers into the the packed
double precision floating point values, the destination operand must be a SSE
register, the source operand can be a 64--bit memory location or MMX register.
\verb"cvtsi2sd" converts a double word integer into a double precision floating
point value, the destination operand must be a SSE register, the source
operand can be a 32--bit memory location or 32--bit general register. \verb"cvtpd2pi"
converts packed double precision floating point values into packed two double
word integers, the destination operand should be a MMX register, the source
operand can be a 128--bit memory location or SSE register. \verb"cvttpd2pi" performs
the similar operation, except that truncation is used to round a source values
to integers, rules for operands are the same. \verb"cvtsd2si" converts a double
precision floating point value into a double word integer, the destination
operand should be a 32--bit general register, the source operand can be a
64--bit memory location or SSE register. \verb"cvttsd2si" performs the similar
operation, except that truncation is used to round a source value to integer,
rules for operands are the same.

\index{cvtps2dq}\index{cvttps2dq}
\index{cvtpd2dq}\index{cvttpd2dq}\index{cvtdq2ps}
\verb"cvtps2dq" and \verb"cvttps2dq" convert packed single precision floating point
values to packed four double word integers, storing them in the destination
operand. \verb"cvtpd2dq" and \verb"cvttpd2dq" convert packed double precision floating
point values to packed two double word integers, storing the result in the low
quad word of the destination operand. \verb"cvtdq2ps" converts packed four double 
word integers to packed single precision floating point values. 

For all these instruction destination operand must be a SSE register, the
source operand can be a 128--bit memory location or SSE register.

\index{cvtdq2pd}
\verb"cvtdq2pd" converts packed two double word integers from the low quad word
of the source operand to packed double precision floating point values, the source can be a 64-bit
memory location or SSE register, destination has to be SSE register.

\index{movdqa}\index{movdqu}
\verb"movdqa" and \verb"movdqu" transfer a double quad word operand containing packed
integers from source operand to destination operand. At least one of the
operands have to be a SSE register, the second one can be also a SSE register
or 128--bit memory location. Memory operands for \verb"movdqa" instruction must be
aligned on boundary of 16 bytes, operands for \verb"movdqu" instruction don't have
to be aligned.

\index{movq2dq}\index{movdq2q}
\verb"movq2dq" moves the contents of the MMX source register to the low quad word
of destination SSE register. \verb"movdq2q" moves the low quad word from the source
SSE register to the destination MMX register.
\begin{verbatim}
    movq2dq xmm0,mm1   ; move from MMX register to SSE register
    movdq2q mm0,xmm1   ; move from SSE register to MMX register
\end{verbatim}

\index{pshufhw}\index{pshuflw}\index{pshufd}
All MMX instructions operating on the 64--bit packed integers (those with
mnemonics starting with \verb"p") are extended to operate on 128--bit packed
integers located in SSE registers. Additional syntax for these instructions
needs an SSE register where MMX register was needed, and the 128--bit memory
location or SSE register where 64--bit memory location or MMX register were
needed. The exception is \verb"pshufw" instruction, which doesn't allow extended
syntax, but has two new variants: \verb"pshufhw" and \verb"pshuflw", which allow only
the extended syntax, and perform the same operation as \verb"pshufw" on the high
or low quad words of operands respectively. Also the new instruction \verb"pshufd"
is introduced, which performs the same operation as \verb"pshufw", but on the
double words instead of words, it allows only the extended syntax.
\begin{verbatim}
    psubb xmm0,[esi]   ; substract 16 packed bytes
    pextrw eax,xmm0,7  ; extract highest word into eax
\end{verbatim}

\index{paddq}\index{psubq}\index{pmuludq}
\verb"paddq" performs the addition of packed quad words, \verb"psubq" performs the
substraction of packed quad words, \verb"pmuludq" performs an unsigned multiplication
of low double words from each corresponding quad words and returns the results
in packed quad words. These instructions follow the same rules for operands as
the general MMX operations described in \ref{sec:MMX_instructions}.

\index{pslldq}\index{psrldq}
\verb"pslldq" and \verb"psrldq" perform logical shift left or right of the double
quad word in the destination operand by the amount of bytes specified in the source
operand. The destination operand should be a SSE register, source operand
should be an 8--bit immediate value.

\index{punpckhqdq}\index{punpcklqdq}
\verb"punpckhqdq" interleaves the high quad word of the source operand and the
high quad word of the destination operand and writes them to the destination
SSE register. \verb"punpcklqdq" interleaves the low quad word of the source operand
and the low quad word of the destination operand and writes them to the
destination SSE register. The source operand can be a 128--bit memory location
or SSE register.

\index{movntdq}\index{movntpd}\index{movnti}\index{maskmovdqu}
\verb"movntdq" stores packed integer data from the SSE register to memory using
non--temporal hint. The source operand should be a SSE register, the
destination operand should be a 128--bit memory location. \verb"movntpd" stores
packed double precision values from the SSE register to memory using a
non--temporal hint. Rules for operand are the same. \verb"movnti" stores integer
from a general register to memory using a non--temporal hint. The source
operand should be a 32--bit general register, the destination operand should
be a 32--bit memory location. \verb"maskmovdqu" stores selected bytes from the first
operand into a 128--bit memory location using a non--temporal hint. Both
operands should be a SSE registers, the second operand selects wich bytes from
the source operand are written to memory. The memory location is pointed by DI
(or EDI) register in the segment selected by DS and does not need to be
aligned.

\index{clflush}
\verb"clflush" writes and invalidates the cache line associated with the address
of byte specified with the operand, which should be a 8--bit memory location.

\index{lfence}\index{mfence}\index{sfence}\index{lfence}
\verb"lfence" performs a serializing operation on all instruction loading from
memory that were issued prior to it. \verb"mfence" performs a serializing operation
on all instruction accesing memory that were issued prior to it, and so it
combines the functions of \verb"sfence" (described in previous section) and
\verb"lfence" instructions. These instructions have no operands.

\subsection{SSE3 instructions}
Prescott technology introduced some new instructions to improve
the performance of SSE and SSE2 -- this extension is called SSE3.

\index{fisttp}
\verb"fisttp" behaves like the \verb"fistp" instruction and accepts the same operands,
the only difference is that it always used truncation, irrespective of the
rounding mode.

\index{movshdup}
\verb"movshdup" loads into destination operand the 128--bit value obtained from
the source value of the same size by filling the each quad word with the two
duplicates of the value in its high double word.

\index{movsldup}
\verb"movsldup" performs the same action, except it duplicates the values of low double words.
The destination operand should be SSE register, the source operand can be SSE register or
128--bit memory location.

\index{movddup}
\verb"movddup" loads the 64--bit source value and duplicates it into high and low
quad word of the destination operand. The destination operand should be SSE
register, the source operand can be SSE register or 64--bit memory location.

\index{lddqu}
\verb"lddqu" is functionally equivalent to \verb"movdqu" with memory as
source operand, but it may improve performance when the source operand crosses
a cacheline boundary. The destination operand has to be SSE register, the source
operand must be 128--bit memory location.

\index{adddubps}
\verb"addsubps" performs single precision addition of second and fourth pairs and
single precision substracion of the first and third pairs of floating point
values in the operands.

\index{addsubpd}
\verb"addsubpd" performs double precision addition of the
second pair and double precision substraction of the first pair of floating
point values in the operand.

\index{haddps}
\verb"haddps" performs the addition of two single
precision values within the each quad word of source and destination operands,
and stores the results of such horizontal addition of values from destination
operand into low quad word of destination operand, and the results from the
source operand into high quad word of destination operand.

\index{haddpd}
\verb"haddpd" performs
the addition of two double precision values within each operand, and stores
the result from destination operand into low quad word of destination operand,
and the result from source operand into high quad word of destination operand.
All these instruction need the destination operand to be SSE register, source
operand can be SSE register or 128--bit memory location.

\index{monitor}
\verb"monitor" sets up an address range for monitoring of write--back stores. It
need its three operands to be EAX, ECX and EDX register in that order.

\index{mwait}
\verb"mwait" waits for a write--back store to the address range set up by the
\verb"monitor" instruction.
It uses two operands with additional parameters, first being the EAX and second
the ECX register.

The functionality of SSE3 is further extended by the set of Supplemental
SSE3 instructions (SSSE3). They generally follow the same rules for operands
as all the MMX operations extended by SSE.

\index{phaddw}\index{phaddd}\index{phaddsw}
\index{phsubw}\index{phsubd}\index{phsubsw}
\verb"phaddw" and \verb"phaddd" perform the horizontal additional of the pairs of
adjacent values from both the source and destination operand, and stores the
sums into the destination (sums from the source operand go into lower part of
destination register). They operate on 16--bit or 32--bit chunks, respectively.
\verb"phaddsw" performs the same operation on signed 16--bit packed values, but the
result of each addition is saturated. \verb"phsubw" and \verb"phsubd" analogously
perform the horizontal substraction of 16--bit or 32--bit packed value, and
\verb"phsubsw" performs the horizontal substraction of signed 16--bit packed values
with saturation.

\index{pabsb}\index{pabsw}\index{pabsd}
\verb"pabsb", \verb"pabsw" and \verb"pabsd" calculate the absolute value of each signed
packed signed value in source operand and stores them into the destination
register. They operator on 8--bit, 16--bit and 32--bit elements respectively.

\index{pmaddubsw}
\verb"pmaddubsw" multiplies signed 8--bit values from the source operand with the
corresponding unsigned 8--bit values from the destination operand to produce
intermediate 16--bit values, and every adjacent pair of those intermediate
values is then added horizontally and those 16--bit sums are stored into the
destination operand.

\index{pmulhrsw}
\verb"pmulhrsw" multiplies corresponding 16--bit integers from the source and
destination operand to produce intermediate 32--bit values, and the 16 bits
next to the highest bit of each of those values are then rounded and packed
into the destination operand.

\index{pshufb}
\verb"pshufb" shuffles the bytes in the destination operand according to the
mask provided by source operand - each of the bytes in source operand is
an index of the target position for the corresponding byte in the destination.

\index{psignb}\index{psignw}\index{psignd}
\verb"psignb", \verb"psignw" and \verb"psignd" perform the operation on 8--bit, 16--bit or
32--bit integers in destination operand, depending on the signs of the values
in the source. If the value in source is negative, the corresponding value in
the destination register is negated, if the value in source is positive, no
operation is performed on the corresponding value is performed, and if the
value in source is zero, the value in destination is zeroed, too.

\index{palifnr}
\verb"palignr" appends the source operand to the destination operand to form the
intermediate value of twice the size, and then extracts into the destination
register the 64 or 128 bits that are right-aligned to the byte offset
specified by the third operand, which should be an 8--bit immediate value. This
is the only SSSE3 instruction that takes three arguments.


\subsection{AMD 3DNow! instructions}
The 3DNow! extension adds a new MMX instructions to those described in \ref{sec:MMX_instructions},
and introduces operation on the 64--bit packed floating point values, each
consisting of two single precision floating point values.

These instructions follow the same rules as the general MMX operations, the
destination operand should be a MMX register, the source operand can be a MMX
register or 64--bit memory location. 

\index{pavgusb}\index{pmulhrw}\index{pi2fd}\index{pf2id}\index{pi2fw}\index{pf2iw}
\index{pfadd}\index{pfsub}\index{pfsubr}\index{pfmul}
\index{pfacc}\index{pfnacc}\index{pfpnacc}
\index{pfmax}\index{pfmin}\index{pswapd}\index{pfrcp}\index{pfrsqrt}
\index{pfrcpit1}\index{pfrsqit1}\index{pfrcpit2}
\index{pfcmpeq}\index{pfcmpge}\index{pfcmpgt}
\verb"pavgusb" computes the rounded averages
of packed unsigned bytes. \verb"pmulhrw" performs a signed multiplication of the packed
words, round the high word of each double word results and stores them in the
destination operand. \verb"pi2fd" converts packed double word integers into
packed floating point values. \verb"pf2id" converts packed floating point values
into packed double word integers using truncation. \verb"pi2fw" converts packed
word integers into packed floating point values, only low words of each
double word in source operand are used. \verb"pf2iw" converts packed floating
point values to packed word integers, results are extended to double words
using the sign extension. \verb"pfadd" adds packed floating point values. \verb"pfsub"
and \verb"pfsubr" substracts packed floating point values, the first one substracts
source values from destination values, the second one substracts destination
values from the source values. \verb"pfmul" multiplies packed floating point
values. \verb"pfacc" adds the low and high floating point values of the destination
operand, storing the result in the low double word of destination, and adds
the low and high floating point values of the source operand, storing the
result in the high double word of destination. \verb"pfnacc" substracts the high
floating point value of the destination operand from the low, storing the
result in the low double word of destination, and substracts the high floating
point value of the source operand from the low, storing the result in the high
double word of destination. \verb"pfpnacc" substracts the high floating point value
of the destination operand from the low, storing the result in the low double
word of destination, and adds the low and high floating point values of the
source operand, storing the result in the high double word of destination.
\verb"pfmax" and \verb"pfmin" compute the maximum and minimum of floating point values.
\verb"pswapd" reverses the high and low double word of the source operand. \verb"pfrcp"
returns an estimates of the reciprocals of floating point values from the
source operand, \verb"pfrsqrt" returns an estimates of the reciprocal square
roots of floating point values from the source operand, \verb"pfrcpit1" performs
the first step in the Newton--Raphson iteration to refine the reciprocal
approximation produced by \verb"pfrcp" instruction, \verb"pfrsqit1" performs the first
step in the Newton--Raphson iteration to refine the reciprocal square root
approximation produced by \verb"pfrsqrt" instruction, \verb"pfrcpit2" performs the
second final step in the Newton--Raphson iteration to refine the reciprocal
approximation or the reciprocal square root approximation. \verb"pfcmpeq",
\verb"pfcmpge" and \verb"pfcmpgt" compare the packed floating point values and sets
all bits or zeroes all bits of the correspoding data element in the
destination operand according to the result of comparison, first checks
whether values are equal, second checks whether destination value is greater
or equal to source value, third checks whether destination value is greater
than source value.

\index{prefetch}\index{prefetchw}
\verb"prefetch" and \verb"prefetchw" load the line of data from memory that contains
byte specified with the operand into the data cache, \verb"prefetchw" instruction
should be used when the data in the cache line is expected to be modified,
otherwise the \verb"prefetch" instruction should be used. The operand should be an
8--bit memory location.

\index{femms}
\verb"femms" performs a fast clear of MMX state. It has no operands.

\subsection{The x86-64 long mode instructions}

The AMD64 and EM64T architectures (we will use the common name x86--64 for them
both) extend the x86 instruction set for the 64--bit processing. While legacy
and compatibility modes use the same set of registers and instructions, the
new long mode extends the x86 operations to 64 bits and introduces several new
registers. You can turn on generating the code for this mode with the \verb"use64"
directive.

Each of the general purpose registers is extended to 64 bits and the eight
whole new general purpose registers and also eight new SSE registers are added.
See table \ref{tab:x86_64_registers} for the summary of new registers (only the ones that was not
listed in table \ref{tab:registers}). The general purpose registers of smallers sizes are the
low order portions of the larger ones. You can still access the \verb"ah", \verb"bh",
\verb"ch" and \verb"dh" registers in long mode, but you cannot use them in the same
instruction with any of the new registers.

\begin{table}[htb]
\begin{center}\begin{tabular}{|c||c|c|c|c|c|c|}
\hline
Type & \multicolumn{4}{c|}{General} & SSE & AVX \\
\hline
Bits & 8 & 16 & 32 & 64 & 128 & 256 \\
\hline \hline
& & & & \verb"rax" & & \\
& & & & \verb"rcx" & & \\
& & & & \verb"rdx" & & \\
& & & & \verb"rbx" & & \\
& \verb"spl" & & & \verb"rsp" & & \\
& \verb"bpl" & & & \verb"rbp" & & \\
& \verb"sil" & & & \verb"rsi" & & \\
& \verb"dil" & & & \verb"rdi" & & \\
& \verb"r8b" & \verb"r8w" & \verb"r8d" & \verb"r8" & \verb"xmm8" & \verb"ymm8" \\
& \verb"r9b" & \verb"r9w" & \verb"r9d" & \verb"r9" & \verb"xmm9" & \verb"ymm9" \\
& \verb"r10b" & \verb"r10w" & \verb"r10d" & \verb"r10" & \verb"xmm10" & \verb"ymm10" \\
& \verb"r11b" & \verb"r11w" & \verb"r11d" & \verb"r11" & \verb"xmm11" & \verb"ymm11" \\
& \verb"r12b" & \verb"r12w" & \verb"r12d" & \verb"r12" & \verb"xmm12" & \verb"ymm12" \\
& \verb"r13b" & \verb"r13w" & \verb"r13d" & \verb"r13" & \verb"xmm13" & \verb"ymm13" \\
& \verb"r14b" & \verb"r14w" & \verb"r14d" & \verb"r14" & \verb"xmm14" & \verb"ymm14" \\
& \verb"r15b" & \verb"r15w" & \verb"r15d" & \verb"r15" & \verb"xmm15" & \verb"ymm15" \\
\hline
\end{tabular}\end{center}
\caption{New registers in long mode.} \label{tab:x86_64_registers}
\end{table}

In general any instruction from x86 architecture, which allowed 16--bit or
32--bit operand sizes, in long mode allows also the 64--bit operands. The 64--bit
registers should be used for addressing in long mode, the 32--bit addressing
is also allowed, but it's not possible to use the addresses based on 16--bit
registers. Below are the samples of new operations possible in long mode on the
example of \verb"mov" instruction:
\begin{verbatim}
    mov rax,r8   ; transfer 64-bit general register
    mov al,[rbx] ; transfer memory addressed by 64-bit register
\end{verbatim}
The long mode uses also the instruction pointer based addresses, you can
specify it manually with the special RIP register symbol, but such addressing
is also automatically generated by flat assembler, since there is no 64--bit
absolute addressing in long mode. You can still force the assembler to use the
32--bit absolute addressing by putting the \verb"dword" size override for address
inside the square brackets. There is also one exception, where the 64--bit
absolute addressing is possible, it's the \verb"mov" instruction with one of the
operand being accumulator register, and second being the memory operand.
To force the assembler to use the 64--bit absolute addressing there, use the
\verb"qword" size operator for address inside the square brackets. When no size
operator is applied to address, assembler generates the optimal form
automatically.
\begin{verbatim}
    mov [qword 0],rax  ; absolute 64-bit addressing
    mov [dword 0],r15d ; absolute 32-bit addressing
    mov [0],rsi        ; automatic RIP-relative addressing
    mov [rip+3],sil    ; manual RIP-relative addressing
\end{verbatim}

Also as the immediate operands for 64--bit operations only the signed 32--bit
values are possible, with the only exception being the \verb"mov" instruction with
destination operand being 64--bit general purpose register. Trying to force the
64--bit immediate with any other instruction will cause an error.

If any operation is performed on the 32--bit general registers in long mode,
the upper 32 bits of the 64--bit registers containing them are filled with
zeros. This is unlike the operations on 16--bit or 8--bit portions of those
registers, which preserve the upper bits.

\index{cdqe}\index{cqo}\index{movsxd}
Three new type conversion instructions are available. The \verb"cdqe" sign extends
the double word in EAX into quad word and stores the result in RAX register.
\verb"cqo" sign extends the quad word in RAX into double quad word and stores the
extra bits in the RDX register. These instructions have no operands.
\verb"movsxd" sign extends the double word source operand, being either the 32--bit register
or memory, into 64--bit destination operand, which has to be register.
No analogous instruction is needed for the zero extension, since it is done
automatically by any operations on 32--bit registers, as noted in previous
paragraph. And the \verb"movzx" and \verb"movsx" instructions, conforming to the general
rule, can be used with 64--bit destination operand, allowing extension of byte
or word values into quad words.

All the binary arithmetic and logical instruction have been promoted to allow
64--bit operands in long mode. The use of decimal arithmetic instructions in
long mode is prohibited.

The stack operations, like \verb"push" and \verb"pop" in long mode default to 64--bit
operands and it's not possible to use 32--bit operands with them.
The \verb"pusha" and \verb"popa" are disallowed in long mode.

The indirect near jumps and calls in long mode default to 64--bit operands and
it's not possible to use the 32--bit operands with them. On the other hand, the
indirect far jumps and calls allow any operands that were allowed by the x86
architecture and also 80--bit memory operand is allowed (though only EM64T seems
to implement such variant), with the first eight bytes defining the offset and
two last bytes specifying the selector. The direct far jumps and calls are not
allowed in long mode.

\index{movsq}\index{cmpsq}\index{scasq}\index{lodsq}\index{stosq}
The I/O instructions, \verb"in", \verb"out", \verb"ins" and \verb"outs" are the exceptional
instructions that are not extended to accept quad word operands in long mode.
But all other string operations are, and there are new short forms \verb"movsq",
\verb"cmpsq", \verb"scasq", \verb"lodsq" and \verb"stosq" introduced for the variants of string
operations for 64--bit string elements. The RSI and RDI registers are used by
default to address the string elements.

The \verb"lfs", \verb"lgs" and \verb"lss" instructions are extended to accept 80--bit source
memory operand with 64--bit destination register (though only EM64T seems to
implement such variant). The \verb"lds" and \verb"les" are disallowed in long mode.

The system instructions like \verb"lgdt" which required the 48--bit memory operand,
in long mode require the 80--bit memory operand.

\index{cmpxchg16b}
The \verb"cmpxchg16b" is the 64--bit equivalent of \verb"cmpxchg8b" instruction, it uses
the double quad word memory operand and 64--bit registers to perform the analoguous operation.

\index{fxsave64}\index{fxrstor64}
The \verb"fxsave64" and \verb"fxrstor64" are new variants of \verb"fxsave" and \verb"fxrstor"
instructions, available only in long mode, which use a different format of
storage area in order to store some pointers in full 64-bit size.

\index{swapgs}
\verb"swapgs" is the new instruction, which swaps the contents of GS register and
the KernelGSbase model--specific register (MSR address 0C0000102h).

\index{syscall}\index{sysret}\index{sysexitq}\index{sysretq}
\verb"syscall" and \verb"sysret" is the pair of new instructions that provide the
functionality similar to \verb"sysenter" and \verb"sysexit" in long mode, where the
latter pair is disallowed. The \verb"sysexitq" and \verb"sysretq" mnemonics provide the
64--bit versions of \verb"sysexit" and \verb"sysret" instructions.

\index{rdmsrq}\index{wrmsrq}
The \verb"rdmsrq" and \verb"wrmsrq" mnemonics are the 64--bit variants of the \verb"rdmsr"
and \verb"wrmsr" instructions.


\subsection{SSE4 instructions}

There are actually three different sets of instructions under the name SSE4.
Intel designed two of them, SSE4.1 and SSE4.2, with latter extending the
former into the full Intel's SSE4 set. On the other hand, the implementation
by AMD includes only a few instructions from this set, but also contains
some additional instructions, that are called the SSE4a set.

The SSE4.1 instructions mostly follow the same rules for operands, as
the basic SSE operations, so they require destination operand to be SSE
register and source operand to be 128--bit memory location or SSE register,
and some operations require a third operand, the 8--bit immediate value.

\index{pmulld}\index{pmuldq}\index{pminsb}\index{pmaxsb}\index{pminuw}
\index{pmaxuw}\index{pminud}\index{pmaxud}\index{pminsd}\index{pmaxsd}
\verb"pmulld" performs a signed multiplication of the packed double words and
stores the low double words of the results in the destination operand.
\verb"pmuldq" performs a two signed multiplications of the corresponding double
words in the lower quad words of operands, and stores the results as
packed quad words into the destination register. \verb"pminsb" and \verb"pmaxsb"
return the minimum or maximum values of packed signed bytes, \verb"pminuw" and
\verb"pmaxuw" return the minimum and maximum values of packed unsigned words,
\verb"pminud", \verb"pmaxud", \verb"pminsd" and \verb"pmaxsd" return minimum or maximum values
of packed unsigned or signed words. These instruction complement the
instructions computing packed minimum or maximum introduced by SSE.

\index{ptest}\index{pcmpeqq}
\verb"ptest" sets the ZF flag to one when the result of bitwise AND of the
both operands is zero, and zeroes the ZF otherwise. It also sets CF flag
to one, when the result of bitwise AND of the destination operand with
the bitwise NOT of the source operand is zero, and zeroes the CF otherwise.
\verb"pcmpeqq" compares packed quad words for equality, and fills the
corresponding elements of destination operand with either ones or zeros,
depending on the result of comparison.

\index{packusdw}
\verb"packusdw" converts packed signed double words from both the source and
destination operand into the unsigned words using saturation, and stores
the eight resulting word values into the destination register.

\index{phminposuw}
\verb"phminposuw" finds the minimum unsigned word value in source operand
and places it into the lowest word of destination operand, setting the
remaining upper bits of destination to zero.

\index{roundps}\index{roundss}\index{roundpd}\index{roundsd}
\verb"roundps", \verb"roundss", \verb"roundpd" and \verb"roundsd" perform the rounding of
packed or individual floating point value of single or double precision,
using the rounding mode specified by the third operand.
\begin{verbatim}
    roundsd xmm0,xmm1,0011b ; round toward zero
\end{verbatim}

\index{dpps}\index{dppd}\index{mpsadbw}\index{roundps}
\verb"dpps" calculates dot product of packed single precision floating point
values, that is it multiplies the corresponding pairs of values from source and
destination operand and then sums the products up. The high four bits of the
8--bit immediate third operand control which products are calculated and taken
to the sum, and the low four bits control, into which elements of destination
the resulting dot product is copied (the other elements are filled with zero).
\verb"dppd" calculates dot product of packed double precision floating point values.
The bits 4 and 5 of third operand control, which products are calculated and
added, and bits 0 and 1 of this value control, which elements in destination
register should get filled with the result. \verb"mpsadbw" calculates multiple sums
of absolute differences of unsigned bytes. The third operand controls, with
value in bits 0--1, which of the four-byte blocks in source operand is taken to
calculate the absolute differencies, and with value in bit 2, at which of the
two first four-byte block in destination operand start calculating multiple
sums. The sum is calculated from four absolute differencies between the
corresponding unsigned bytes in the source and destination block, and each next
sum is calculated in the same way, but taking the four bytes from destination
at the position one byte after the position of previous block. The four bytes
from the source stay the same each time. This way eight sums of absolute
differencies are calculated and stored as packed word values into the
destination operand. The instructions described in this paragraph follow the
same rules for operands, as \verb"roundps" instruction.

\index{blendps}\index{blendvps}\index{blendpd}\index{blendvpd}
\verb"blendps", \verb"blendvps", \verb"blendpd" and \verb"blendvpd" conditionally copy the
values from source operand into the destination operand, depending on the bits
of the mask provided by third operand. If a mask bit is set, the corresponding
element of source is copied into the same place in destination, otherwise this
position is destination is left unchanged. The rules for the first two operands
are the same, as for general SSE instructions. \verb"blendps" and \verb"blendpd" need
third operand to be 8--bit immediate, and they operate on single or double
precision values, respectively. \verb"blendvps" and \verb"blendvpd" require third operand
to be the XMM0 register.
\begin{verbatim}
    blendvps xmm3,xmm7,xmm0 ; blend according to mask
\end{verbatim}

\index{pblendw}\index{pblendvb}
\verb"pblendw" conditionally copies word elements from the source operand into the
destination, depending on the bits of mask provided by third operand, which
needs to be 8--bit immediate value. \verb"pblendvb" conditionally copies byte
elements from the source operands into destination, depending on mask defined
by the third operand, which has to be XMM0 register. These instructions follow
the same rules for operands as \verb"blendps" and \verb"blendvps" instructions,
respectively.

\index{insertps}
\verb"insertps" inserts a single precision floating point value taken from the
position in source operand specified by bits 6--7 of third operand into location
in destination register selected by bits 4--5 of third operand. Additionally,
the low four bits of third operand control, which elements in destination
register will be set to zero. The first two operands follow the same rules as
for the general SSE operation, the third operand should be 8--bit immediate.

\index{extractps}
\verb"extractps" extracts a single precision floating point value taken from the
location in source operand specified by low two bits of third operand, and
stores it into the destination operand. The destination can be a 32--bit memory
value or general purpose register, the source operand must be SSE register,
and the third operand should be 8--bit immediate value.
\begin{verbatim}
    extractps edx,xmm3,3 ; extract the highest value
\end{verbatim}

\index{pinsrb}\index{pinsrd}\index{pinsrq}
\verb"pinsrb", \verb"pinsrd" and \verb"pinsrq" copy a byte, double word or quad word from
the source operand into the location of destination operand determined by the
third operand. The destination operand has to be SSE register, the source
operand can be a memory location of appropriate size, or the 32--bit general
purpose register (but 64--bit general purpose register for \verb"pinsrq", which is
only available in long mode), and the third operand has to be 8--bit immediate
value. These instructions complement the \verb"pinsrw" instruction operating on SSE
register destination, which was introduced by SSE2.
\begin{verbatim}
    pinsrd xmm4,eax,1 ; insert double word into second position
\end{verbatim}

\index{pextrb}\index{pextrw}\index{pextrd}\index{pextrq}
\verb"pextrb", \verb"pextrw", \verb"pextrd" and \verb"pextrq" copy a byte, word, double word or
quad word from the location in source operand specified by third operand, into
the destination. The source operand should be SSE register, the third operand
should be 8--bit immediate, and the destination operand can be memory location
of appropriate size, or the 32--bit general purpose register (but 64--bit general
purpose register for \verb"pextrq", which is only available in long mode). The
\verb"pextrw" instruction with SSE register as source was already introduced by
SSE2, but SSE4 extends it to allow memory operand as destination.
\begin{verbatim}
    pextrw [ebx],xmm3,7 ; extract highest word into memory
\end{verbatim}

\index{pmovsxbw}\index{pmovzxbw}\index{pmovsxbd}\index{pmovzxbd}
\index{pmovsxbq}\index{pmovzxbq}\index{pmovsxwd}\index{pmovzxwd}
\index{pmovsxwq}\index{pmovzxwq}\index{pmovsxdq}\index{pmovzxdq}
\verb"pmovsxbw" and \verb"pmovzxbw" perform sign extension or zero extension of eight
byte values from the source operand into packed word values in destination
operand, which has to be SSE register. The source can be 64--bit memory or SSE
register - when it is register, only its low portion is used. \verb"pmovsxbd" and
\verb"pmovzxbd" perform sign extension or zero extension of the four byte values
from the source operand into packed double word values in destination operand,
the source can be 32--bit memory or SSE register. \verb"pmovsxbq" and \verb"pmovzxbq"
perform sign extension or zero extension of the two byte values from the
source operand into packed quad word values in destination operand, the source
can be 16--bit memory or SSE register. \verb"pmovsxwd" and \verb"pmovzxwd" perform sign
extension or zero extension of the four word values from the source operand
into packed double words in destination operand, the source can be 64--bit
memory or SSE register. \verb"pmovsxwq" and \verb"pmovzxwq" perform sign extension or
zero extension of the two word values from the source operand into packed quad
words in destination operand, the source can be 32--bit memory or SSE register.
\verb"pmovsxdq" and \verb"pmovzxdq" perform sign extension or zero extension of the two
double word values from the source operand into packed quad words in
destination operand, the source can be 64--bit memory or SSE register.
\begin{verbatim}
    pmovzxbq xmm0,word [si]  ; zero-extend bytes to quad words
    pmovsxwq xmm0,xmm1       ; sign-extend words to quad words
\end{verbatim}

\index{movntdqa}
\verb"movntdqa" loads double quad word from the source operand to the destination
using a non-temporal hint. The destination operand should be SSE register,
and the source operand should be 128--bit memory location.

The SSE4.2, described below, adds not only some new operations on SSE
registers, but also introduces some completely new instructions operating on
general purpose registers only.

\index{pcmpistri}\index{pcmpistrm}\index{pcmpestri}\index{pcmpestrm}
\verb"pcmpistri" compares two zero-ended (implicit length) strings provided in
its source and destination operand and generates an index stored to ECX;
\verb"pcmpistrm" performs the same comparison and generates a mask stored to XMM0.
\verb"pcmpestri" compares two strings of explicit lengths, with length provided
in EAX for the destination operand and in EDX for the source operand, and
generates an index stored to ECX; \verb"pcmpestrm" performs the same comparision
and generates a mask stored to XMM0. The source and destination operand follow
the same rules as for general SSE instructions, the third operand should be
8--bit immediate value determining the details of performed operation - refer to
Intel documentation for information on those details.

\index{pcmpgtq}
\verb"pcmpgtq" compares packed quad words, and fills the corresponding elements of
destination operand with either ones or zeros, depending on whether the value
in destination is greater than the one in source, or not. This instruction
follows the same rules for operands as \verb"pcmpeqq".

\index{crc32}
\verb"crc32" accumulates a CRC32 value for the source operand starting with
initial value provided by destination operand, and stores the result in
destination. Unless in long mode, the destination operand should be a 32--bit
general purpose register, and the source operand can be a byte, word, or double
word register or memory location. In long mode the destination operand can
also be a 64--bit general purpose register, and the source operand in such case
can be a byte or quad word register or memory location.
\begin{verbatim}
    crc32 eax,dl          ; accumulate CRC32 on byte value
    crc32 eax,word [ebx]  ; accumulate CRC32 on word value
    crc32 rax,qword [rbx] ; accumulate CRC32 on quad word value
\end{verbatim}

\index{popcnt}
\verb"popcnt" calculates the number of bits set in the source operand, which can
be 16--bit, 32--bit, or 64--bit general purpose register or memory location,
and stores this count in the destination operand, which has to be register of
the same size as source operand. The 64--bit variant is available only in long
mode.
\begin{verbatim}
    popcnt ecx,eax        ; count bits set to 1
\end{verbatim}

\index{lzcnt}
The SSE4a extension, which also includes the \verb"popcnt" instruction introduced
by SSE4.2, at the same time adds the \verb"lzcnt" instruction, which follows the
same syntax, and calculates the count of leading zero bits in source operand
(if the source operand is all zero bits, the total number of bits in source
operand is stored in destination).

\index{extrq}
\verb"extrq" extract the sequence of bits from the low quad word of SSE register
provided as first operand and stores them at the low end of this register,
filling the remaining bits in the low quad word with zeros. The position of bit
string and its length can either be provided with two 8--bit immediate values
as second and third operand, or by SSE register as second operand (and there
is no third operand in such case), which should contain position value in bits
8--13 and length of bit string in bits 0--5.
\begin{verbatim}
    extrq xmm0,8,7        ; extract 8 bits from position 7
    extrq xmm0,xmm5       ; extract bits defined by register
\end{verbatim}

\index{insertq}
\verb"insertq" writes the sequence of bits from the low quad word of the source
operand into specified position in low quad word of the destination operand,
leaving the other bits in low quad word of destination intact. The position
where bits should be written and the length of bit string can either be
provided with two 8--bit immediate values as third and fourth operand, or by
the bit fields in source operand (and there are only two operands in such
case), which should contain position value in bits 72--77 and length of bit
string in bits 64--69.
\begin{verbatim}
    insertq xmm1,xmm0,4,2 ; insert 4 bits at position 2
    insertq xmm1,xmm0     ; insert bits defined by register
\end{verbatim}

\index{movntss}\index{movntsd}
\verb"movntss" and \verb"movntsd" store single or double precision floating point
value from the source SSE register into 32--bit or 64--bit destination memory
location respectively, using non--temporal hint.

\subsection{AVX instructions}

The Advanced Vector Extensions introduce instructions that are new variants
of SSE instructions, with new scheme of encoding that allows extended syntax
having a destination operand separate from all the source operands. It also
introduces 256--bit AVX registers, which extend up the old 128--bit SSE
registers. Any AVX instruction that puts some result into SSE register, puts
zero bits into high portion of the AVX register containing it.

The AVX version of SSE instruction has the mnemonic obtained by prepending
SSE instruction name with \verb"v". For any SSE arithmetic instruction which had a
destination operand also being used as one of the source values, the AVX
variant has a new syntax with three operands -- the destination and two sources.
The destination and first source can be SSE registers, and second source can be
SSE register or memory. If the operation is performed on single pair of values,
the remaining bits of first source SSE register are copied into the the
destination register.
\begin{verbatim}
    vsubss xmm0,xmm2,xmm3         ; substract two 32-bit floats
    vmulsd xmm0,xmm7,qword [esi]  ; multiply two 64-bit floats
\end{verbatim}
In case of packed operations, each instruction can also operate on the 256--bit
data size when the AVX registers are specified instead of SSE registers, and
the size of memory operand is also doubled then.
\begin{verbatim}
    vaddps ymm1,ymm5,yword [esi]  ; eight sums of 32-bit float pairs
\end{verbatim}
The instructions that operate on packed integer types (in particular the ones
that earlier had been promoted from MMX to SSE) also acquired the new syntax
with three operands, however they are only allowed to operate on 128--bit
packed types and thus cannot use the whole AVX registers.
\begin{verbatim}
    vpavgw xmm3,xmm0,xmm2         ; average of 16-bit integers
    vpslld xmm1,xmm0,1            ; shift double words left
\end{verbatim}
If the SSE version of instruction had a syntax with three operands, the third
one being an immediate value, the AVX version of such instruction takes four
operands, with immediate remaining the last one.
\begin{verbatim}
    vshufpd ymm0,ymm1,ymm2,10010011b ; shuffle 64-bit floats
    vpalignr xmm0,xmm4,xmm2,3        ; extract byte aligned value
\end{verbatim}
The promotion to new syntax according to the rules described above has been
applied to all the instructions from SSE extensions up to SSE4, with the
exceptions described below.

\index{vdppd}
\verb"vdppd" instruction has syntax extended to four operans, but it does not
have a 256--bit version.

\index{vsqrtpd}\index{vsqrtps}\index{vrcpps}\index{vrsqrtps}
The are a few instructions, namely \verb"vsqrtpd", \verb"vsqrtps", \verb"vrcpps" and
\verb"vrsqrtps", which can operate on 256--bit data size, but retained the syntax
with only two operands, because they use data from only one source:
\begin{verbatim}
    vsqrtpd ymm1,ymm0         ; put square roots into other register
\end{verbatim}

\index{vroundpd}\index{vroundps}
In a similar way \verb"vroundpd" and \verb"vroundps" retained the syntax with three
operands, the last one being immediate value.
\begin{verbatim}
    vroundps ymm0,ymm1,0011b  ; round toward zero
\end{verbatim}

\index{vpcmpestri}\index{vpcmpestrm}\index{vpcmpistri}\index{vpcmpistrm}
\index{vphminposuw}\index{vpshufd}\index{vpshufhw}\index{vpshuflw}
\index{vcomiss}\index{vcomisd}\index{vcvtss2si}\index{vcvtsd2si}
\index{vcvttss2si}\index{vcvttsd2si}\index{vextractps}\index{vpextrb}
\index{vpextrw}\index{vpextrd}\index{vpextrq}\index{vmovd}
\index{vmovq}\index{vmovntdqa}\index{vmaskmovdqu}\index{vpmovmskb}
\index{vpmovsxbw}\index{vpmovsxbd}\index{vpmovsxbq}\index{vpmovsxwd}
\index{vpmovsxwq}\index{vpmovsxdq}\index{vpmovzxbw}\index{vpmovzxbd}
\index{vpmovzxbq}\index{vpmovzxwd}\index{vpmovzxwq}\index{vpmovzxdq}
Also some of the operations on packed integers kept their two--operand or
three--operand syntax while being promoted to AVX version. In such case these
instructions follow exactly the same rules for operands as their SSE
counterparts (since operations on packed integers do not have 256--bit variants
in AVX extension). These include \verb"vpcmpestri", \verb"vpcmpestrm", \verb"vpcmpistri",
\verb"vpcmpistrm", \verb"vphminposuw", \verb"vpshufd", \verb"vpshufhw", \verb"vpshuflw". And there are
more instructions that in AVX versions keep exactly the same syntax for
operands as the one from SSE, without any additional options: \verb"vcomiss",
\verb"vcomisd", \verb"vcvtss2si", \verb"vcvtsd2si", \verb"vcvttss2si", \verb"vcvttsd2si", \verb"vextractps",
\verb"vpextrb", \verb"vpextrw", \verb"vpextrd", \verb"vpextrq", \verb"vmovd", \verb"vmovq", \verb"vmovntdqa",
\verb"vmaskmovdqu", \verb"vpmovmskb", \verb"vpmovsxbw", \verb"vpmovsxbd", \verb"vpmovsxbq", \verb"vpmovsxwd",
\verb"vpmovsxwq", \verb"vpmovsxdq", \verb"vpmovzxbw", \verb"vpmovzxbd", \verb"vpmovzxbq", \verb"vpmovzxwd",
\verb"vpmovzxwq" and \verb"vpmovzxdq".

\index{vcvtdq2ps}\index{vcvtps2dq}\index{vcvttps2dq}\index{vmovaps}
\index{vmovapd}\index{vmovups}\index{vmovupd}\index{vmovdqa}
\index{vmovdqu}\index{vlddqu}\index{vmovntps}\index{vmovntpd}
\index{vmovntdq}\index{vmovsldup}\index{vmovshdup}\index{vmovmskps}
\index{vmovmskpd}
The move and conversion instructions have mostly been promoted to allow
256--bit size operands in addition to the 128--bit variant with syntax identical
to that from SSE version of the same instruction. Each of the
\verb"vcvtdq2ps", \verb"vcvtps2dq" and \verb"vcvttps2dq",
\verb"vmovaps", \verb"vmovapd", \verb"vmovups", \verb"vmovupd",
\verb"vmovdqa", \verb"vmovdqu", \verb"vlddqu",
\verb"vmovntps", \verb"vmovntpd", \verb"vmovntdq",
\verb"vmovsldup", \verb"vmovshdup",
\verb"vmovmskps" and \verb"vmovmskpd" inherits the 128--bit
syntax from SSE without any changes, and also allows a new form with 256--bit
operands in place of 128--bit ones.
\begin{verbatim}
    vmovups [edi],ymm6        ; store unaligned 256-bit data
\end{verbatim}

\index{vmovddup}
\verb"vmovddup" has the identical 128--bit syntax as its SSE version, and it also
has a 256--bit version, which stores the duplicates of the lowest quad word
from the source operand in the lower half of destination operand, and in the
upper half of destination the duplicates of the low quad word from the upper
half of source. Both source and destination operands need then to be 256--bit
values.

\index{vmovlhps}\index{vmovhlps}
\verb"vmovlhps" and \verb"vmovhlps" have only 128--bit versions, and each takes three
operands, which all must be SSE registers. \verb"vmovlhps" copies two single
precision values from the low quad word of second source register to the high
quad word of destination register, and copies the low quad word of first
source register into the low quad word of destination register. \verb"vmovhlps"
copies two single  precision values from the high quad word of second source
register to the low quad word of destination register, and copies the high
quad word of first source register into the high quad word of destination
register.

\index{vmovlps}\index{vmovhps}\index{vmovlpd}\index{vmovhpd}
\verb"vmovlps", \verb"vmovhps", \verb"vmovlpd" and \verb"vmovhpd" have only 128--bit versions and
their syntax varies depending on whether memory operand is a destination or
source. When memory is destination, the syntax is identical to the one of
equivalent SSE instruction, and when memory is source, the instruction requires
three operands, first two being SSE registers and the third one 64--bit memory.
The value put into destination is then the value copied from first source with
either low or high quad word replaced with value from second source (the
memory operand).
\begin{verbatim}
    vmovhps [esi],xmm7       ; store upper half to memory
    vmovlps xmm0,xmm7,[ebx]  ; low from memory, rest from register
\end{verbatim}

\index{vmovss}\index{vmovsd}
\verb"vmovss" and \verb"vmovsd" have syntax identical to their SSE equivalents as long
as one of the operands is memory, while the versions that operate purely on
registers require three operands (each being SSE register). The value stored
in destination is then the value copied from first source with lowest data
element replaced with the lowest value from second source.
\begin{verbatim}
    vmovss xmm3,[edi]        ; low from memory, rest zeroed
    vmovss xmm0,xmm1,xmm2    ; one value from xmm2, three from xmm1
\end{verbatim}

\index{vcvtss2sd}\index{vcvtsd2ss}\index{vcvtsi2ss}\index{vcvtsi2d}
\verb"vcvtss2sd", \verb"vcvtsd2ss", \verb"vcvtsi2ss" and \verb"vcvtsi2d" use the three--operand
syntax, where destination and first source are always SSE registers, and the
second source follows the same rules and the source in syntax of equivalent
SSE instruction. The value stored in destination is then the value copied from
first source with lowest data element replaced with the result of conversion.
\begin{verbatim}
    vcvtsi2sd xmm4,xmm4,ecx  ; 32-bit integer to 64-bit float
    vcvtsi2ss xmm0,xmm0,rax  ; 64-bit integer to 32-bit float
\end{verbatim}

\index{vcvtdq2pd}\index{vcvtps2pd}\index{vcvtpd2dq}\index{vcvttpd2dq}\index{vcvtpd2ps}
\verb"vcvtdq2pd" and \verb"vcvtps2pd" allow the same syntax as their SSE equivalents,
plus the new variants with AVX register as destination and SSE register or
128--bit memory as source. Analogously \verb"vcvtpd2dq", \verb"vcvttpd2dq" and
\verb"vcvtpd2ps", in addition to variant with syntax identical to SSE version,
allow a variant with SSE register as destination and AVX register or 256--bit
memory as source.

\index{vinsertps}\index{vpinsrb}\index{vpinsrw}\index{vpinsrd}\index{vpinsrq}\index{vpblendw}
\verb"vinsertps", \verb"vpinsrb", \verb"vpinsrw", \verb"vpinsrd", \verb"vpinsrq" and \verb"vpblendw" use
a syntax with four operands, where destination and first source have to be SSE
registers, and the third and fourth operand follow the same rules as second
and third operand in the syntax of equivalent SSE instruction. Value stored in
destination is the the value copied from first source with some data elements
replaced with values extracted from the second source, analogously to the
operation of corresponding SSE instruction.
\begin{verbatim}
    vpinsrd xmm0,xmm0,eax,3  ; insert double word
\end{verbatim}

\index{vblendvps}\index{vblendvpd}\index{vpblendvb}
\verb"vblendvps", \verb"vblendvpd" and \verb"vpblendvb" use a new syntax with four register
operands: destination, two sources and a mask, where second source can also be
a memory operand. \verb"vblendvps" and \verb"vblendvpd" have 256--bit variant, where
operands are AVX registers or 256--bit memory, as well as 128--bit variant,
which has operands being SSE registers or 128--bit memory. \verb"vpblendvb" has only
a 128--bit variant. Value stored in destination is the value copied from the
first source with some data elements replaced, according to mask, by values
from the second source.
\begin{verbatim}
    vblendvps ymm3,ymm1,ymm2,ymm7  ; blend according to mask
\end{verbatim}

\index{vptest}\index{vtestps}\index{vtestpd}
\verb"vptest" allows the same syntax as its SSE version and also has a 256--bit
version, with both operands doubled in size. There are also two new
instructions, \verb"vtestps" and \verb"vtestpd", which perform analogous tests, but only
of the sign bits of corresponding single precision or double precision values,
and set the ZF and CF accordingly. They follow the same syntax rules as
\verb"vptest".
\begin{verbatim}
    vptest ymm0,yword [ebx]  ; test 256-bit values
    vtestpd xmm0,xmm1        ; test sign bits of 64-bit floats
\end{verbatim}

\index{vbroadcastss}\index{vbroadcastsd}\index{vbroadcastf128}
\verb"vbroadcastss", \verb"vbroadcastsd" and \verb"vbroadcastf128" are new instructions,
which broadcast the data element defined by source operand into all elements
of corresponing size in the destination register. \verb"vbroadcastss" needs
source to be 32--bit memory and destination to be either SSE or AVX register.
\verb"vbroadcastsd" requires 64--bit memory as source, and AVX register as
destination. \verb"vbroadcastf128" requires 128--bit memory as source, and AVX
register as destination.
\begin{verbatim}
    vbroadcastss ymm0,dword [eax]  ; get eight copies of value
\end{verbatim}

\index{vinsertf128}
\verb"vinsertf128" is the new instruction, which takes four operands. The
destination and first source have to be AVX registers, second source can be
SSE register or 128--bit memory location, and fourth operand should be an
immediate value. It stores in destination the value obtained by taking
contents of first source and replacing one of its 128--bit units with value of
the second source. The lowest bit of fourth operand specifies at which
position that replacement is done (either 0 or 1).

\index{vextractf128}
\verb"vextractf128" is the new instruction with three operands. The destination
needs to be SSE register or 128--bit memory location, the source must be AVX
register, and the third operand should be an immediate value. It extracts
into destination one of the 128--bit units from source. The lowest bit of third
operand specifies, which unit is extracted.

\index{vmaskmovps}\index{vmaskmovpd}
\verb"vmaskmovps" and \verb"vmaskmovpd" are the new instructions with three operands
that selectively store in destination the elements from second source
depending on the sign bits of corresponding elements from first source. These
instructions can operate on either 128--bit data (SSE registers) or 256--bit
data (AVX registers). Either destination or second source has to be a memory
location of appropriate size, the two other operands should be registers.
\begin{verbatim}
    vmaskmovps [edi],xmm0,xmm5  ; conditionally store
    vmaskmovpd ymm5,ymm0,[esi]  ; conditionally load
\end{verbatim}

\index{vpermilpd}\index{vpermilps}
\verb"vpermilpd" and \verb"vpermilps" are the new instructions with three operands
that permute the values from first source according to the control fields from
second source and put the result into destination operand. It allows to use
either three SSE registers or three AVX registers as its operands, the second
source can be a memory of size equal to the registers used. In alternative
form the second source can be immediate value and then the first source
can be a memory location of the size equal to destination register.

\index{vperm2f128}
\verb"vperm2f128" is the new instruction with four operands, which selects
128--bit blocks of floating point data from first and second source according
to the bit fields from fourth operand, and stores them in destination.
Destination and first source need to be AVX registers, second source can be
AVX register or 256--bit memory area, and fourth operand should be an immediate
value.
\begin{verbatim}
    vperm2f128 ymm0,ymm6,ymm7,12h  ; permute 128-bit blocks
\end{verbatim}

\index{vzeroall}\index{vzeroupper}
\verb"vzeroall" instruction sets all the AVX registers to zero. \verb"vzeroupper" sets
the upper 128--bit portions of all AVX registers to zero, leaving the SSE
registers intact. These new instructions take no operands.

\index{vldmxcsr}\index{vstmxcsr}
\verb"vldmxcsr" and \verb"vstmxcsr" are the AVX versions of \verb"ldmxcsr" and \verb"stmxcsr"
instructions. The rules for their operands remain unchanged.


\subsection{AVX2 instructions}

The AVX2 extension allows all the AVX instructions operating on packed integers
to use 256--bit data types, and introduces some new instructions as well.

The AVX instructions that operate on packed integers and had only a 128--bit
variants, have been supplemented with 256--bit variants, and thus their syntax
rules became analogous to AVX instructions operating on packed floating point
types.
\begin{verbatim}
    vpsubb ymm0,ymm0,[esi]   ; substract 32 packed bytes
    vpavgw ymm3,ymm0,ymm2    ; average of 16-bit integers
\end{verbatim}
However there are some instructions that have not been equipped with the
256--bit variants. \verb"vpcmpestri", \verb"vpcmpestrm", \verb"vpcmpistri", \verb"vpcmpistrm",
\verb"vpextrb", \verb"vpextrw", \verb"vpextrd", \verb"vpextrq", \verb"vpinsrb", \verb"vpinsrw", \verb"vpinsrd",
\verb"vpinsrq" and \verb"vphminposuw" are not affected by AVX2 and allow only the
128--bit operands.

The packed shift instructions, which allowed the third operand specifying
amount to be SSE register or 128--bit memory location, use the same rules
for the third operand in their 256--bit variant.
\begin{verbatim}
    vpsllw ymm2,ymm2,xmm4        ; shift words left
    vpsrad ymm0,ymm3,xword [ebx] ; shift double words right
\end{verbatim}

\index{vpsllvd}\index{vpsllvq}\index{vpsrlvd}\index{vpsrlvq}\index{vpsravd}
There are also new packed shift instructions with standard three--operand AVX
syntax, which shift each element from first source by the amount specified in
corresponding element of second source, and store the results in destination.
\verb"vpsllvd" shifts 32-bit elements left, \verb"vpsllvq" shifts 64--bit elements left,
\verb"vpsrlvd" shifts 32-bit elements right logically, \verb"vpsrlvq" shifts 64--bit
elements right logically and \verb"vpsravd" shifts 32-bit elements right
arithmetically.

The sign--extend and zero--extend instructions, which in AVX versions allowed
source operand to be SSE register or a memory of specific size, in the new
256--bit variant need memory of that size doubled or SSE register as source and
AVX register as destination.
\begin{verbatim}
    vpmovzxbq ymm0,dword [esi]   ; bytes to quad words
\end{verbatim}

Also \verb"vmovntdqa" has been upgraded with 256--bit variant, so it allows to
transfer 256--bit value from memory to AVX register, it needs memory address
to be aligned to 32 bytes.

\index{vpmaskmovd}\index{vpmaskmovq}
\verb"vpmaskmovd" and \verb"vpmaskmovq" are the new instructions with syntax identical
to \verb"vmaskmovps" or \verb"vmaskmovpd", and they performs analogous operation on
packed 32--bit or 64--bit values.

\index{vinserti128}\index{vextracti128}\index{vbroadcasti128}\index{vperm2i128}
\verb"vinserti128", \verb"vextracti128", \verb"vbroadcasti128" and \verb"vperm2i128" are the new
instructions with syntax identical to \verb"vinsertf128", \verb"vextractf128",
\verb"vbroadcastf128" and \verb"vperm2f128" respectively, and they perform analogous
operations on 128--bit blocks of integer data.

\verb"vbroadcastss" and \verb"vbroadcastsd" instructions have been extended to allow
SSE register as a source operand (which in AVX could only be a memory).

\index{vpbroadcastb}\index{vpbroadcastw}\index{vpbroadcastd}\index{vpbroadcastq}
\verb"vpbroadcastb", \verb"vpbroadcastw", \verb"vpbroadcastd" and \verb"vpbroadcastq" are the
new instructions which broadcast the byte, word, double word or quad word from
the source operand into all elements of corresponing size in the destination
register. The destination operand can be either SSE or AVX register, and the
source operand can be SSE register or memory of size equal to the size of data
element.
\begin{verbatim}
    vpbroadcastb ymm0,byte [ebx]  ; get 32 identical bytes
\end{verbatim}

\index{vpermd}\index{vpermps}
\verb"vpermd" and \verb"vpermps" are new three--operand instructions, which use each
32--bit element from first source as an index of element in second source which
is copied into destination at position corresponding to element containing
index. The destination and first source have to be AVX registers, and the
second source can be AVX register or 256--bit memory.

\index{vpermq}\index{vpermpd}
\verb"vpermq" and \verb"vpermpd" are new three--operand instructions, which use 2--bit
indexes from the immediate value specified as third operand to determine which
element from source store at given position in destination. The destination
has to be AVX register, source can be AVX register or 256--bit memory, and the
third operand must be 8--bit immediate value.

The family of new instructions performing \verb"gather" operation have special
syntax, as in their memory operand they use addressing mode that is unique to
them. The base of address can be a 32--bit or 64--bit general purpose register
(the latter only in long mode), and the index (possibly multiplied by scale
value, as in standard addressing) is specified by SSE or AVX register. It is
possible to use only index without base and any numerical displacement can be
added to the address. Each of those instructions takes three operands. First
operand is the destination register, second operand is memory addressed with
a vector index, and third operand is register containing a mask. The most
significant bit of each element of mask determines whether a value will be
loaded from memory into corresponding element in destination. The address of
each element to load is determined by using the corresponding element from
index register in memory operand to calculate final address with given base
and displacement. When the index register contains less elements than the
destination and mask registers, the higher elements of destination are zeroed.
After the value is successfuly loaded, the corresponding element in mask
register is set to zero. The destination, index and mask should all be
distinct registers, it is not allowed to use the same register in two
different roles.

\index{vgatherdps}
\verb"vgatherdps" loads single precision floating point values addressed by
32--bit indexes. The destination, index and mask should all be registers of the
same type, either SSE or AVX. The data addressed by memory operand is 32--bit
in size.
\begin{verbatim}
    vgatherdps xmm0,[eax+xmm1],xmm3    ; gather four floats
    vgatherdps ymm0,[ebx+ymm7*4],ymm3  ; gather eight floats
\end{verbatim}

\index{vgatherqps}
\verb"vgatherqps" loads single precision floating point values addressed by
64--bit indexes. The destination and mask should always be SSE registers, while
index register can be either SSE or AVX register. The data addressed by memory
operand is 32--bit in size.
\begin{verbatim}
    vgatherqps xmm0,[xmm2],xmm3        ; gather two floats
    vgatherqps xmm0,[ymm2+64],xmm3     ; gather four floats
\end{verbatim}

\index{vgatherdpd}
\verb"vgatherdpd" loads double precision floating point values addressed by
32--bit indexes. The index register should always be SSE register, the
destination and mask should be two registers of the same type, either SSE or
AVX. The data addressed by memory operand is 64--bit in size.
\begin{verbatim}
    vgatherdpd xmm0,[ebp+xmm1],xmm3    ; gather two doubles
    vgatherdpd ymm0,[xmm3*8],ymm5      ; gather four doubles
\end{verbatim}

\index{vgatherqpd}
\verb"vgatherqpd" loads double precision floating point values addressed by
64--bit indexes. The destination, index and mask should all be registers of the
same type, either SSE or AVX. The data addressed by memory operand is 64--bit
in size.

\index{vpgatherdd}\index{vpgatherqd}
\verb"vpgatherdd" and \verb"vpgatherqd" load 32--bit values addressed by either 32--bit
or 64--bit indexes. They follow the same rules as \verb"vgatherdps" and \verb"vgatherqps"
respectively.

\index{vpgatherdq}\index{vpgatherqq}
\verb"vpgatherdq" and \verb"vpgatherqq" load 64--bit values addressed by either 32--bit
or 64--bit indexes. They follow the same rules as \verb"vgatherdpd" and \verb"vgatherqpd"
respectively.


\subsection{Auxiliary sets of computational instructions}

There is a number of additional instruction set extensions related to
AVX. They introduce new vector instructions (and sometimes also their SSE
equivalents that use classic instruction encoding), and even some new
instructions operating on general registers that use the AVX--like encoding
allowing the extended syntax with separate destination and source operands.
The CPU support for each of these instruction sets needs to be determined
separately.

The AES extension provides a specialized set of instructions for the
purpose of cryptographic computations defined by Advanced Encryption Standard.
Each of these instructions has two versions: the AVX one and the one with
SSE--like syntax that uses classic encoding. Refer to the Intel manuals for the
details of operation of these instructions.

\index{aesenc}\index{aesenclast}\index{vaesenc}\index{vaesenclast}
\verb"aesenc" and \verb"aesenclast" perform a single round of AES encryption on data
from first source with a round key from second source, and store result in
destination. The destination and first source are SSE registers, and the
second source can be SSE register or 128--bit memory. The AVX versions of these
instructions, \verb"vaesenc" and \verb"vaesenclast", use the syntax with three operands,
while the SSE--like version has only two operands, with first operand being
both the destination and first source.

\index{aesdec}\index{aesdeclast}
\verb"aesdec" and \verb"aesdeclast" perform a single round of AES decryption on data
from first source with a round key from second source. The syntax rules for
them and their AVX versions are the same as for \verb"aesenc".

\index{aesimc}\index{vaesimc}
\verb"aesimc" performs the InvMixColumns transformation of source operand and
store the result in destination. Both \verb"aesimc" and \verb"vaesimc" use only two
operands, destination being SSE register, and source being SSE register or
128--bit memory location.

\index{aeskeygenassist}
\verb"aeskeygenassist" is a helper instruction for generating the round key.
It needs three operands: destination being SSE register, source being SSE
register or 128--bit memory, and third operand being 8--bit immediate value.
The AVX version of this instruction uses the same syntax.

\index{pclmulqdq}\index{vpclmulqdq}
The CLMUL extension introduces just one instruction, \verb"pclmulqdq", and its
AVX version as well. This instruction performs a carryless multiplication of
two 64--bit values selected from first and second source according to the bit
fields in immediate value. The destination and first source are SSE registers,
second source is SSE register or 128--bit memory, and immediate value is
provided as last operand. \verb"vpclmulqdq" takes four operands, while \verb"pclmulqdq"
takes only three operands, with the first one serving both the role of
destination and first source.

The FMA (Fused Multiply--Add) extension introduces additional AVX
instructions which perform multiplication and summation as single operation.
Each one takes three operands, first one serving both the role of destination
and first source, and the following ones being the second and third source.
The mnemonic of FMA instruction is obtained by appending to \verb"vf" prefix: first
either \verb"m" or \verb"nm" to select whether result of multiplication should be taken
as--is or negated, then either \verb"add" or \verb"sub" to select whether third value
will be added to the product or substracted from the product, then either
\verb"132", \verb"213" or \verb"231" to select which source operands are multiplied and which
one is added or substracted, and finally the type of data on which the
instruction operates, either \verb"ps", \verb"pd", \verb"ss" or \verb"sd". As it was with SSE
instructions promoted to AVX, instructions operating on packed floating point
values allow 128--bit or 256--bit syntax, in former all the operands are SSE
registers, but the third one can also be a 128--bit memory, in latter the
operands are AVX registers and the third one can also be a 256--bit memory.
Instructions that compute just one floating point result need operands to be
SSE registers, and the third operand can also be a memory, either 32--bit for
single precision or 64--bit for double precision.
\begin{verbatim}
    vfmsub231ps ymm1,ymm2,ymm3     ; multiply and substract
    vfnmadd132sd xmm0,xmm5,[ebx]   ; multiply, negate and add
\end{verbatim}
In addition to the instructions created by the rule described above, there are
families of instructions with mnemonics starting with either \verb"vfmaddsub" or
\verb"vfmsubadd", followed by either \verb"132", \verb"213" or \verb"231" and then either \verb"ps" or
\verb"pd" (the operation must always be on packed values in this case). They add
to the result of multiplication or substract from it depending on the position
of value in packed data -- instructions from the \verb"vfmaddsub" group add when the
position is odd and substract when the position is even, instructions from the
\verb"vfmsubadd" group add when the position is even and subtstract when the
position is odd. The rules for operands are the same as for other FMA
instructions.

The FMA4 instructions are similar to FMA, but use syntax with four operands
and thus allow destination to be different than all the sources. Their
mnemonics are identical to FMA instructions with the \verb"132", \verb"213" or \verb"231" cut
out, as having separate destination operand makes such selection of operands
superfluous. The multiplication is always performed on values from the first
and second source, and then the value from third source is added or
substracted. Either second or third source can be a memory operand, and the
rules for the sizes of operands are the same as for FMA instructions.
\begin{verbatim}
    vfmaddpd ymm0,ymm1,[esi],ymm2  ; multiply and add
    vfmsubss xmm0,xmm1,xmm2,[ebx]  ; multiply and substract
\end{verbatim}

\index{vcvtps2ph}\index{vcvtph2ps}
The F16C extension consists of two instructions, \verb"vcvtps2ph" and
\verb"vcvtph2ps", which convert floating point values between single precision and
half precision (the 16--bit floating point format). \verb"vcvtps2ph" takes three
operands: destination, source, and rounding controls. The third operand is
always an immediate, the source is either SSE or AVX register containing
single precision values, and the destination is SSE register or memory, the
size of memory is 64 bits when the source is SSE register and 128 bits when
the source is AVX register. \verb"vcvtph2ps" takes two operands, the destination
that can be SSE or AVX register, and the source that is SSE register or memory
with size of the half of destination operand's size.

\index{vfrczps}\index{vfrczss}\index{vfrczpd}\index{vfrczsd}
The AMD XOP extension introduces a number of new vector instructions with
encoding and syntax analogous to AVX instructions. \verb"vfrczps", \verb"vfrczss",
\verb"vfrczpd" and \verb"vfrczsd" extract fractional portions of single or double
precision values, they all take two operands. The packed operations allow
either SSE or AVX register as destination, for the other two it has to be SSE
register. Source can be register of the same type as destination, or memory
of appropriate size (256--bit for destination being AVX register, 128--bit for
packed operation with destination being SSE register, 64--bit for operation
on a solitary double precision value and 32--bit for operation on a solitary
single precision value).
\begin{verbatim}
    vfrczps ymm0,[esi]           ; load fractional parts
\end{verbatim}

\index{vpcmov}
\verb"vpcmov" copies bits from either first or second source into destination
depending on the values of corresponding bits in the fourth operand (the
selector). If the bit in selector is set, the corresponding bit from first
source is copied into the same position in destination, otherwise the bit from
second source is copied. Either second source or selector can be memory
location, 128--bit or 256--bit depending on whether SSE registers or AVX
registers are specified as the other operands.
\begin{verbatim}
    vpcmov xmm0,xmm1,xmm2,[ebx]  ; selector in memory
    vpcmov ymm0,ymm5,[esi],ymm2  ; source in memory
\end{verbatim}
The family of packed comparison instructions take four operands, the
destination and first source being SSE register, second source being SSE
register or 128--bit memory and the fourth operand being immediate value
defining the type of comparison. The mnemonic or instruction is created
by appending to \verb"vpcom" prefix either \verb"b" or \verb"ub" to compare signed or
unsigned bytes, \verb"w" or \verb"uw" to compare signed or unsigned words, \verb"d" or \verb"ud"
to compare signed or unsigned double words, \verb"q" or \verb"uq" to compare signed or
unsigned quad words. The respective values from the first and second source
are compared and the corresponding data element in destination is set to
either all ones or all zeros depending on the result of comparison. The fourth
operand has to specify one of the eight comparison types (table \ref{tab:XOP_comparisons}). All
these instruction have also variants with only three operands and the type
of comparison encoded within the instruction name by inserting the comparison
mnemonic after \verb"vpcom".
\begin{verbatim}
    vpcomb   xmm0,xmm1,xmm2,4    ; test for equal bytes
    vpcomgew xmm0,xmm1,[ebx]     ; compare signed words
\end{verbatim}

\begin{table}[hbt]
\begin{center}\begin{tabular}{|c|c|c|}
\hline
Code & Mnemonic & Description \\
\hline \hline
0 & \verb"lt" & less than \\
\hline
1 & \verb"le" & less than or equal \\
\hline
2 & \verb"gt" & greater than \\
\hline
3 & \verb"ge" & greater than or equal \\
\hline
4 & \verb"eq" & equal \\
\hline
5 & \verb"neq" & not equal \\
\hline
6 & \verb"false" & false \\
\hline
7 & \verb"true" & true \\
\hline
\end{tabular}\end{center}
\caption{XOP comparisons.}
\label{tab:XOP_comparisons}
\end{table}

\index{vpermil2ps}\index{vpermil2pd}
\verb"vpermil2ps" and \verb"vpermil2pd" set the elements in destination register to
zero or to a value selected from first or second source depending on the
corresponding bit fields from the fourth operand (the selector) and the
immediate value provided in fifth operand. Refer to the AMD manuals for the
detailed explanation of the operation performed by these instructions. Each
of the first four operands can be a register, and either second source or
selector can be memory location, 128--bit or 256--bit depending on whether SSE
registers or AVX registers are used for the other operands.
\begin{verbatim}
    vpermil2ps ymm0,ymm3,ymm7,ymm2,0  ; permute from two sources
\end{verbatim}

\index{vphaddbw}\index{vphaddubw}\index{vphaddbd}\index{vphaddubd}
\index{vphaddbq}\index{vphaddubq}\index{vphaddwd}\index{vphadduwd}
\index{vphaddwq}\index{vphadduwq}\index{vphadddq}\index{vphaddudq}
\index{vphsubbw}\index{vphsubwd}\index{vphsubdq}
\verb"vphaddbw" adds pairs of adjacent signed bytes to form 16--bit values and
stores them at the same positions in destination. \verb"vphaddubw" does the same
but treats the bytes as unsigned. \verb"vphaddbd" and \verb"vphaddubd" sum all bytes
(either signed or unsigned) in each four--byte block to 32--bit results,
\verb"vphaddbq" and \verb"vphaddubq" sum all bytes in each eight--byte block to
64--bit results, \verb"vphaddwd" and \verb"vphadduwd" add pairs of words to 32--bit
results, \verb"vphaddwq" and \verb"vphadduwq" sum all words in each four--word block to
64--bit results, \verb"vphadddq" and \verb"vphaddudq" add pairs of double words to 64--bit
results. \verb"vphsubbw" substracts in each two--byte block the byte at higher
position from the one at lower position, and stores the result as a signed
16--bit value at the corresponding position in destination, \verb"vphsubwd"
substracts in each two--word block the word at higher position from the one at
lower position and makes signed 32--bit results, \verb"vphsubdq" substract in each
block of two double word the one at higher position from the one at lower
position and makes signed 64--bit results. Each of these instructions takes
two operands, the destination being SSE register, and the source being SSE
register or 128--bit memory.
\begin{verbatim}
    vphadduwq xmm0,xmm1          ; sum quadruplets of words
\end{verbatim}

\index{vpmacsww}\index{vpmacssww}\index{vpmacsdd}\index{vpmacssdd}
\index{vpmacswd}\index{vpmacsswd}\index{vpmacsdql}\index{vpmacssdql}
\index{vpmacsdqh}\index{vpmacssdqh}\index{vpmadcswd}\index{vpmadcsswd}
\verb"vpmacsww" and \verb"vpmacssww" multiply the corresponding signed 16--bit values
from the first and second source and then add the products to the parallel
values from the third source, then \verb"vpmacsww" takes the lowest 16 bits of the
result and \verb"vpmacssww" saturates the result down to 16--bit value, and they
store the final 16--bit results in the destination. \verb"vpmacsdd" and \verb"vpmacssdd"
perform the analogous operation on 32--bit values. \verb"vpmacswd" and \verb"vpmacsswd" do
the same calculation only on the low 16--bit values from each 32--bit block and
form the 32--bit results. \verb"vpmacsdql" and \verb"vpmacssdql" perform such operation
on the low 32--bit values from each 64--bit block and form the 64--bit results,
while \verb"vpmacsdqh" and \verb"vpmacssdqh" do the same on the high 32--bit values from
each 64--bit block, also forming the 64--bit results. \verb"vpmadcswd" and
\verb"vpmadcsswd" multiply the corresponding signed 16--bit value from the first
and second source, then sum all the four products and add this sum to each
16--bit element from third source, storing the truncated or saturated result
in destination. All these instructions take four operands, the second source
can be 128--bit memory or SSE register, all the other operands have to be
SSE registers.
\begin{verbatim}
    vpmacsdd xmm6,xmm1,[ebx],xmm6  ; accumulate product
\end{verbatim}

\index{vpperm}
\verb"vpperm" selects bytes from first and second source, optionally applies a
separate transformation to each of them, and stores them in the destination.
The bit fields in fourth operand (the selector) specify for each position in
destination what byte from which source is taken and what operation is applied
to it before it is stored there. Refer to the AMD manuals for the detailed
information about these bit fields. This instruction takes four operands,
either second source or selector can be a 128--bit memory (or they can be SSE
registers both), all the other operands have to be SSE registers.

\index{vpshlb}\index{vpshlw}\index{vpshld}\index{vpshlq}
\verb"vpshlb", \verb"vpshlw", \verb"vpshld" and \verb"vpshlq" shift logically bytes, words, double
words or quad words respectively. The amount of bits to shift by is specified
for each element separately by the signed byte placed at the corresponding
position in the third operand. The source containing elements to shift is
provided as second operand. Either second or third operand can be 128--bit
memory (or they can be SSE registers both) and the other operands have to be
SSE registers.
\begin{verbatim}
    vpshld xmm3,xmm1,[ebx]       ; shift bytes from xmm1
\end{verbatim}

\index{vpshab}\index{vpshaw}\index{vpshad}\index{vpshaq}
\index{vprotb}\index{vprotw}\index{vprotd}\index{vprotq}
\verb"vpshab", \verb"vpshaw", \verb"vpshad" and \verb"vpshaq" arithmetically shift bytes, words,
double words or quad words. These instructions follow the same rules as the
logical shifts described above. \verb"vprotb", \verb"vprotw", \verb"vprotd" and \verb"vprotq"
rotate bytes, word, double words or quad words. They follow the same rules as
shifts, but additionally allow third operand to be immediate value, in which
case the same amount of rotation is specified for all the elements in source.
\begin{verbatim}
    vprotb xmm0,[esi],3          ; rotate bytes to the left
\end{verbatim}

\index{movbe}
The MOVBE extension introduces just one new instruction, \verb"movbe", which
swaps bytes in value from source before storing it in destination, so can
be used to load and store big endian values. It takes two operands, either
the destination or source should be a 16--bit, 32--bit or 64--bit memory (the
last one being only allowed in long mode), and the other operand should be
a general register of the same size.

The BMI extension, consisting of two subsets -- BMI1 and BMI2, introduces
new instructions operating on general registers, which use the same encoding
as AVX instructions and so allow the extended syntax. All these instructions
use 32--bit operands, and in long mode they also allow the forms with 64--bit
operands.

\index{andn}
\verb"andn" calculates the bitwise AND of second source with the inverted bits
of first source and stores the result in destination. The destination and
the first source have to be general registers, the second source can be
general register or memory.
\begin{verbatim}
    andn edx,eax,[ebx]   ; bit-multiply inverted eax with memory
\end{verbatim}

\index{bextr}
\verb"bextr" extracts from the first source the sequence of bits using an index
and length specified by bit fields in the second source operand and stores
it into destination. The lowest 8 bits of second source specify the position
of bit sequence to extract and the next 8 bits of second source specify the
length of sequence. The first source can be a general register or memory,
the other two operands have to be general registers.
\begin{verbatim}
    bextr eax,[esi],ecx  ; extract bit field from memory
\end{verbatim}

\index{blsi}
\verb"blsi" extracts the lowest set bit from the source, setting all the other
bits in destination to zero. The destination must be a general register,
the source can be general register or memory.
\begin{verbatim}
    blsi rax,r11         ; isolate the lowest set bit
\end{verbatim}

\index{blsmsk}\index{blsr}
\verb"blsmsk" sets all the bits in the destination up to the lowest set bit in
the source, including this bit. \verb"blsr" copies all the bits from the source to
destination except for the lowest set bit, which is replaced by zero. These
instructions follow the same rules for operands as \verb"blsi".

\index{tzcnt}\index{lzcnt}
\verb"tzcnt" counts the number of trailing zero bits, that is the zero bits up to
the lowest set bit of source value. This instruction is analogous to \verb"lzcnt"
and follows the same rules for operands, so it also has a 16--bit version,
unlike the other BMI instructions.

\index{bzhi}
\verb"bzhi" is BMI2 instruction, which copies the bits from first source to
destination, zeroing all the bits up from the position specified by second
source. It follows the same rules for operands as \verb"bextr".

\index{pext}\index{pdep}
\verb"pext" uses a mask in second source operand to select bits from first
operands and puts the selected bits as a continuous sequence into destination.
\verb"pdep" performs the reverse operation -- it takes sequence of bits from the
first source and puts them consecutively at the positions where the bits in
second source are set, setting all the other bits in destination to zero.
These BMI2 instructions follow the same rules for operands as \verb"andn".

\index{mulx}
\verb"mulx" is a BMI2 instruction which performs an unsigned multiplication of
value from EDX or RDX register (depending on the size of specified operands)
by the value from third operand, and stores the low half of result in the
second operand, and the high half of result in the first operand, and it does
it without affecting the flags. The third operand can be general register or
memory, and both the destination operands have to be general registers.
\begin{verbatim}
    mulx edx,eax,ecx     ; multiply edx by ecx into edx:eax
\end{verbatim}

\index{shlx}\index{shrx}\index{sarx}
\verb"shlx", \verb"shrx" and \verb"sarx" are BMI2 instructions, which perform logical or
arithmetical shifts of value from first source by the amount specified by
second source, and store the result in destination without affecting the
flags. The have the same rules for operands as \verb"bzhi" instruction.

\index{rorx}
\verb"rorx" is a BMI2 instruction which rotates right the value from source
operand by the constant amount specified in third operand and stores the
result in destination without affecting the flags. The destination operand
has to be general register, the source operand can be general register or
memory, and the third operand has to be an immediate value.
\begin{verbatim}
    rorx eax,edx,7       ; rotate without affecting flags
\end{verbatim}

\index{blsic}\index{blsfill}
The TBM is an extension designed by AMD to supplement the BMI set. The
\verb"bextr" instruction is extended with a new form, in which second source is
a 32--bit immediate value. \verb"blsic" is a new instruction which performs the
same operation as \verb"blsi", but with the bits of result reversed. It uses the
same rules for operands as \verb"blsi". \verb"blsfill" is a new instruction, which takes
the value from source, sets all the bits below the lowest set bit and store
the result in destination, it also uses the same rules for operands as \verb"blsi".

\index{blci}\index{blcic}\index{blcs}\index{blcmsk}\index{blcfill}
\verb"blci", \verb"blcic", \verb"blcs", \verb"blcmsk" and \verb"blcfill" are instructions analogous
to \verb"blsi", \verb"blsic", \verb"blsr", \verb"blsmsk" and \verb"blsfill" respectively, but they
perform the bit--inverted versions of the same operations. They follow the
same rules for operands as the instructions they reflect.

\index{tzmsk}\index{t1mskc}
\verb"tzmsk" finds the lowest set bit in value from source operand, sets all bits
below it to 1 and all the rest of bits to zero, then writes the result to
destination. \verb"t1mskc" finds the least significant zero bit in the value from
source  operand, sets the bits below it to zero and all the other bits to 1,
and writes the result to destination. These instructions have the same rules
for operands as \verb"blsi".


\subsection{Other extensions of instruction set}

There is a number of additional instruction set extensions recognized by flat
assembler, and the general syntax of the instructions introduced by those
extensions is provided here. For a detailed information on the operations
performed by them, check out the manuals from Intel (for the VMX, SMX, XSAVE,
RDRAND, FSGSBASE, INVPCID, HLE and RTM extensions) or AMD (for the SVM extension).

\index{vmxon}\index{vmxoff}\index{vmlaunch}\index{vmresume}\index{vmcall}
The Virtual--Machine Extensions (VMX) provide a set of instructions for the
management of virtual machines. The \verb"vmxon" instruction, which enters the VMX
operation, requires a single 64--bit memory operand, which should be a physical
address of memory region, which the logical processor may use to support VMX
operation. The \verb"vmxoff" instruction, which leaves the VMX operation, has no
operands. The \verb"vmlaunch" and \verb"vmresume", which launch or resume the virtual
machines, and \verb"vmcall", which allows guest software to call the VM monitor,
use no operands either.

\index{vmptrld}\index{vmptrst}\index{vmclear}
The \verb"vmptrld" loads the physical address of current Virtual Machine Control
Structure (VMCS) from its memory operand, \verb"vmptrst" stores the pointer to
current VMCS into address specified by its memory operand, and \verb"vmclear" sets
the launch state of the VMCS referenced by its memory operand to clear. These
three instruction all require single 64--bit memory operand.

\index{vmread}\index{vmwrite}
The \verb"vmread" reads from VCMS a field specified by the source operand and
stores it into the destination operand. The source operand should be a
general purpose register, and the destination operand can be a register of
memory. The \verb"vmwrite" writes into a VMCS field specified by the destination
operand the value provided by source operand. The source operand can be a
general purpose register or memory, and the destination operand must be a
register. The size of operands for those instructions should be 64--bit when
in long mode, and 32--bit otherwise.

\index{invept}\index{invvpid}
The \verb"invept" and \verb"invvpid" invalidate the translation lookaside buffers
(TLBs) and paging--structure caches, either derived from extended page tables
(EPT), or based on the virtual processor identifier (VPID). These instructions
require two operands, the first one being the general purpose register
specifying the type of invalidation, and the second one being a 128--bit
memory operand providing the invalidation descriptor. The first operand
should be a 64--bit register when in long mode, and 32--bit register otherwise.

\index{getsec}
The Safer Mode Extensions (SMX) provide the functionalities available
throught the \verb"getsec" instruction. This instruction takes no operands, and
the function that is executed is determined by the contents of EAX register
upon executing this instruction.

\index{skinit}
The Secure Virtual Machine (SVM) is a variant of virtual machine extension
used by AMD. The \verb"skinit" instruction securely reinitializes the processor
allowing the startup of trusted software, such as the virtual machine monitor
(VMM). This instruction takes a single operand, which must be EAX, and
provides a physical address of the secure loader block (SLB).

\index{vmrun}\index{vmsave}\index{vmload}
The \verb"vmrun" instruction is used to start a guest virtual machine,
its only operand should be an accumulator register (AX, EAX or RAX, the
last one available only in long mode) providing the physical address of the
virtual machine control block (VMCB). The \verb"vmsave" stores a subset of
processor state into VMCB specified by its operand, and \verb"vmload" loads the
same subset of processor state from a specified VMCB. The same operand rules
as for the \verb"vmrun" apply to those two instructions.

\index{vmmcall}
\verb"vmmcall" allows the guest software to call the VMM. This instruction takes
no operands.

\index{stgi}\index{clgi}
\verb"stgi" set the global interrupt flag to 1, and \verb"clgi" zeroes it. These
instructions take no operands.

\index{invlpga}
\verb"invlpga" invalidates the TLB mapping for a virtual page specified by the
first operand (which has to be accumulator register) and address space
identifier specified by the second operand (which must be ECX register).

\index{xsave}\index{xsaveopt}\index{xrstor}\index{xsave64}\index{xsaveopt64}\index{xrstor64}
The XSAVE set of instructions allows to save and restore processor state
components. \verb"xsave" and \verb"xsaveopt" store the components of processor state
defined by bit mask in EDX and EAX registers into area defined by memory
operand. \verb"xrstor" restores from the area specified by memory operand the
components of processor state defined by mask in EDX and EAX. The \verb"xsave64",
\verb"xsaveopt64" and \verb"xrstor64" are 64--bit versions of these instructions, allowed
only in long mode.

\index{xgetbv}\index{xsetbv}
\verb"xgetbv" read the contents of 64--bit XCR (extended control register)
specified in ECX register into EDX and EAX registers. \verb"xsetbv" writes the
contents of EDX and EAX into the 64--bit XCR specified by ECX register. These
instructions have no operands.

\index{rdrand}
The RDRAND extension introduces one new instruction, \verb"rdrand", which loads
the hardware--generated random value into general register. It takes one
operand, which can be 16--bit, 32--bit or 64--bit register (with the last one
being allowed only in long mode).

\index{rdfsbase}\index{rdgsbase}\index{wrfsbase}\index{wrgsbase}
The FSGSBASE extension adds long mode instructions that allow to read and
write the segment base registers for FS and GS segments. \verb"rdfsbase" and
\verb"rdgsbase" read the corresponding segment base registers into operand, while
\verb"wrfsbase" and \verb"wrgsbase" write the value of operand into those register.
All these instructions take one operand, which can be 32--bit or 64--bit general
register.

\index{invpcid}
The INVPCID extension adds \verb"invpcid" instruction, which invalidates mapping
in the TLBs and paging caches based on the invalidation type specified in
first operand and PCID invalidate descriptor specified in second operand.
The first operands should be 32--bit general register when not in long mode,
or 64--bit general register when in long mode. The second operand should be
128--bit memory location.

\index{xacquire}\index{xrelease}\index{xbegin}\index{xend}\index{xabort}\index{xtest}
The HLE and RTM extensions provide set of instructions for the transactional
management. The \verb"xacquire" and \verb"xrelease" are new prefixes that can be used
with some of the instructions to start or end lock elision on the memory
address specified by prefixed instruction. The \verb"xbegin" instruction starts
the transactional execution, its operand is the address a fallback routine
that gets executes in case of transaction abort, specified like the operand
for near jump instruction. \verb"xend" marks the end of transcational execution
region, it takes no operands. \verb"xabort" forces the transaction abort, it takes
an 8--bit immediate value as its only operand, this value is passed in the
highest bits of EAX to the fallback routine. \verb"xtest" checks whether there is
transactional execution in progress, this instruction takes no operands.


\section{Control directives}
\label{sec:control}
This section describes the directives that control the assembly process, they
are processed during the assembly and may cause some blocks of instructions
to be assembled differently or not assembled at all.

\subsection{Numerical constants}
\index{=}
The \verb"=" directive allows to define the numerical constant. It should be preceded by
the name for the constant and followed by the numerical expression providing the value.
The value of such constants can be a number or an address, but -- unlike labels -- the
numerical constants are not allowed to hold the register--based addresses.
Besides this difference, in their basic variant numerical constants behave
very much like labels and you can even forward--reference them (access their
values before they actually get defined).

There is, however, a second variant of numerical constants, which is recognized by assembler when
you try to define the constant of name, under which there already was a numerical constant defined.
In such case assembler treats that constant as an assembly--time variable and allows it to be
assigned with new value, but forbids forward--referencing it (for obvious reasons). Let's see both the
variant of numerical constants in one example:
\begin{verbatim}
    dd sum
    x = 1
    x = x+2
    sum = x
\end{verbatim}
Here the \verb"x" is an assembly--time variable, and every time it is accessed, the value
that was assigned to it the most recently is used. Thus if we tried to access the \verb"x" before
it gets defined the first time, like if we wrote \verb"dd x" in place of the \verb"dd sum" instruction,
it would cause an error. And when it is re--defined with the \verb"x = x+2" directive, the previous value
of \verb"x" is used to calculate the new one. So when the \verb"sum" constant gets defined, the \verb"x" has
value of 3, and this value is assigned to the \verb"sum". Since this one is defined only once in source,
it is the standard numerical constant, and can be forward--referenced. So the \verb"dd sum" is assembled
as \verb"dd 3". To read more about how the assembler is able to resolve this, see section \ref{sec:passes}.

The value of numerical constant can be preceded by size operator, which can ensure that the value
will fit in the range for the specified size, and can affect also how some of the calculations inside
the numerical expression are performed. This example:
\begin{verbatim}
    c8 = byte -1
    c32 = dword -1
\end{verbatim}
defines two different constants, the first one fits in 8 bits, the second one fits in 32 bits.

When you need to define constant with the value of address, which may be register--based
(and thus you cannot employ numerical constant for this purpose), you can use the extended
syntax of \verb"label" directive (already described in section \ref{sec:labels}), like:
\begin{verbatim}
    label myaddr at ebp+4
\end{verbatim}
which declares label placed at \verb"ebp+4" address. However remember that labels,
unlike numerical constants, cannot become assembly--time variables.


\subsection{Conditional assembly}
\index{IF}
\verb"if" directive causes some block of instructions to be assembled only under
certain condition. It should be followed by logical expression specifying the
condition, instructions in next lines will be assembled only when this
condition is met, otherwise they will be skipped. The optional \verb"else if"
directive followed with logical expression specifying additional condition
begins the next block of instructions that will be assembled if previous
conditions were not met, and the additional condition is met. The optional
\verb"else" directive begins the block of instructions that will be assembled if
all the conditions were not met. The \verb"end if" directive ends the last block of
instructions.

You should note that \verb"if" directive is processed at assembly stage and
therefore it doesn't affect any preprocessor directives, like the definitions
of symbolic constants and macroinstructions -- when the assembler recognizes the
\verb"if" directive, all the preprocessing has been already finished.

The logical expression consist of logical values and logical operators. The
logical operators are \verb"~" for logical negation, \verb"&" for logical and, \verb"|" for
logical or. The negation has the highest priority. Logical value can be a
numerical expression, it will be false if it is equal to zero, otherwise it
will be true. Two numerical expression can be compared using one of the
following operators to make the logical value: \verb"=" (equal), \verb"<" (less),
\verb">" (greater), \verb"<=" (less or equal), \verb">=" (greater or equal),
\verb"<>" (not equal).

The \verb"used" operator followed by a symbol name, is the logical value that
checks whether the given symbol is used somewhere (it returns correct result
even if symbol is used only after this check). The \verb"defined" operator can be
followed by any expression, usually just by a single symbol name; it checks
whether the given expression contains only symbols that are defined in the
source and accessible from the current position.

With \verb"relativeto" operator it is possible to check whether values of two
expressions differ only by constant amount. The valid syntax is a numerical
expression followed by \verb"relativeto" and then another expression (possibly
register-based). Labels that have no simple numerical value can be tested
this way to determine what kind of operations may be possible with them.

The following simple example uses the \verb"count" constant that should be
defined somewhere in source:
\begin{verbatim}
    if count>0
        mov cx,count
        rep movsb
    end if
\end{verbatim}
These two assembly instructions will be assembled only if the \verb"count" constant
is greater than 0. The next sample shows more complex conditional structure:
\begin{verbatim}
    if count & ~ count mod 4
        mov cx,count/4
        rep movsd
    else if count>4
        mov cx,count/4
        rep movsd
        mov cx,count mod 4
        rep movsb
    else
        mov cx,count
        rep movsb
    end if
\end{verbatim}
The first block of instructions gets assembled when the \verb"count" is non zero and
divisible by four, if this condition is not met, the second logical expression,
which follows the \verb"else if", is evaluated and if it's true, the second block
of instructions get assembled, otherwise the last block of instructions, which
follows the line containing only \verb"else", is assembled.

There are also operators that allow comparison of values being any chains of
symbols. The \verb"eq" compares whether two such values are exactly the same.
The \verb"in" operator checks whether given value is a member of the list of values
following this operator, the list should be enclosed between \verb"<" and \verb">"
characters, its members should be separated with commas. The symbols are
considered the same when they have the same meaning for the assembler -- for
example \verb"pword" and \verb"fword" for assembler are the same and thus are not
distinguished by the above operators. In the same way \verb"16 eq 10h" is the true
condition, however \verb"16 eq 10+4" is not.

The \verb"eqtype" operator checks whether the two compared values have the same
structure, and whether the structural elements are of the same type. The
distinguished types include numerical expressions, individual quoted strings,
floating point numbers, address expressions (the expressions enclosed in square
brackets or preceded by \verb"ptr" operator), instruction mnemonics, registers, size
operators, jump type and code type operators. And each of the special
characters that act as a separators, like comma or colon, is the separate type
itself. For example, two values, each one consisting of register name followed
by comma and numerical expression, will be regarded as of the same type, no
matter what kind of register and how complicated numerical expression is used;
with exception for the quoted strings and floating point values, which are the
special kinds of numerical expressions and are treated as different types. Thus
\verb"eax,16 eqtype fs,3+7" condition is true, but \verb"eax,16 eqtype eax,1.6" is false.

\subsection{Repeating blocks of instructions}
\label{sec:repeating}
\index{TIMES}
\verb"times" directive repeats one instruction specified number of times. It
should be followed by numerical expression specifying number of repeats and
the instruction to repeat (optionally colon can be used to separate number and
instruction). When special symbol \verb"%" is used inside the instruction, it is
equal to the number of current repeat. For example \verb"times 5 db %" will define
five bytes with values 1, 2, 3, 4, 5. Recursive use of \verb"times" directive is
also allowed, so \verb"times 3 times % db %" will define six bytes with values
1, 1, 2, 1, 2, 3.

\index{REPEAT}
\verb"repeat" directive repeats the whole block of instructions. It should be
followed by numerical expression specifying number of repeats. Instructions
to repeat are expected in next lines, ended with the \verb"end repeat" directive,
for example:
\begin{verbatim}
    repeat 8
        mov byte [bx],%
        inc bx
    end repeat
\end{verbatim}
The generated code will store byte values from one to eight in the memory
addressed by BX register.

Number of repeats can be zero, in that case the instructions are not
assembled at all.

\index{BREAK}
The \verb"break" directive allows to stop repeating earlier and continue assembly
from the first line after the \verb"end repeat". Combined with the \verb"if" directive it
allows to stop repeating under some special condition, like:
\begin{verbatim}
    s = x/2
    repeat 100
        if x/s = s
            break
        end if
        s = (s+x/s)/2
    end repeat
\end{verbatim}

\index{WHILE}
The \verb"while" directive repeats the block of instructions as long as the
condition specified by the logical expression following it is true. The block
of instructions to be repeated should end with the \verb"end while" directive.
Before each repetition the logical expression is evaluated and when its value
is false, the assembly is continued starting from the first line after the
\verb"end while". Also in this case the \verb"%" symbol holds the number of current
repeat. The \verb"break" directive can be used to stop this kind of loop in the same
way as with \verb"repeat" directive. The previous sample can be rewritten to use the
\verb"while" instead of \verb"repeat" this way:
\begin{verbatim}
    s = x/2
    while x/s <> s
        s = (s+x/s)/2
        if % = 100
            break
        end if
    end while
\end{verbatim}

The blocks defined with \verb"if", \verb"repeat" and \verb"while" can be nested in any order,
however they should be closed in the same order in which they were started. The
\verb"break" directive always stops processing the block that was started last with
either the \verb"repeat" or \verb"while" directive.

\subsection{Addressing spaces}
\index{ORG}
\verb"org" directive sets address at which the following code is expected to
appear in memory. It should be followed by numerical expression specifying
the address. This directive begins the new addressing space, the following
code itself is not moved in any way, but all the labels defined within it
and the value of \verb"$" symbol are affected as if it was put at the given
address. However it's the responsibility of programmer to put the code at
correct address at run--time.

\index{LOAD}
The \verb"load" directive allows to define constant with a binary value loaded
from the already assembled code. This directive should be followed by the name
of the constant, then optionally size operator, then \verb"from" operator and a
numerical expression specifying a valid address in current addressing space.
The size operator has unusual meaning in this case -- it states how many bytes
(up to 8) have to be loaded to form the binary value of constant. If no size
operator is specified, one byte is loaded (thus value is in range from 0 to
255). The loaded data cannot exceed current offset.

\index{STORE}
The \verb"store" directive can modify the already generated code by replacing
some of the previously generated data with the value defined by given
numerical expression, which follows. The expression can be preceded by the
optional size operator to specify how large value the expression defines, and
therefore how much bytes will be stored, if there is no size operator, the
size of one byte is assumed. Then the \verb"at" operator and the numerical
expression defining the valid address in current addressing code space, at
which the given value have to be stored should follow. This is a directive for
advanced appliances and should be used carefully.

Both \verb"load" and \verb"store" directives are limited to operate on places in
current addressing space. The \verb"$$" symbol is always equal to the base address
of current addressing space, and the \verb"$" symbol is the address of current
position in that addressing space, therefore these two values define limits
of the area, where \verb"load" and \verb"store" can operate.

Combining the \verb"load" and \verb"store" directives allows to do things like encoding
some of the already generated code. For example to encode the whole code
generated in current addressing space you can use such block of directives:
\begin{verbatim}
    repeat $-$$
        load a byte from $$+%-1
        store byte a xor c at $$+%-1
    end repeat
\end{verbatim}
and each byte of code will be xored with the value defined by \verb"c" constant.

\index{VIRTUAL}
\verb"virtual" defines virtual data at specified address. This data will not be
included in the output file, but labels defined there can be used in other
parts of source. This directive can be followed by \verb"at" operator and the
numerical expression specifying the address for virtual data, otherwise is
uses current address, the same as \verb"virtual at $". Instructions defining data
are expected in next lines, ended with \verb"end virtual" directive. The block of
virtual instructions itself is an independent addressing space, after it's
ended, the context of previous addressing space is restored.

The \verb"virtual" directive can be used to create union of some variables, for
example:
\begin{verbatim}
    GDTR dp ?
    virtual at GDTR
        GDT_limit dw ?
        GDT_address dd ?
    end virtual
\end{verbatim}
It defines two labels for parts of the 48--bit variable at \verb"GDTR" address.

It can be also used to define labels for some structures addressed by a
register, for example:
\begin{verbatim}
    virtual at bx
        LDT_limit dw ?
        LDT_address dd ?
    end virtual
\end{verbatim}
With such definition instruction \verb"mov ax,[LDT_limit]" will be assembled
to the same instruction as \verb"mov ax,[bx]".

Declaring defined data values or instructions inside the virtual block would
also be useful, because the \verb"load" directive can be used to load the values
from the virtually generated code into a constants. This directive should be
used after the code it loads but before the virtual block ends, because it can
only load the values from the same addressing space. For example:
\begin{verbatim}
    virtual at 0
        xor eax,eax
        and edx,eax
        load zeroq dword from 0
    end virtual
\end{verbatim}
The above piece of code will define the \verb"zeroq" constant containing four bytes
of the machine code of the instructions defined inside the virtual block.
This method can be also used to load some binary value from external file.
For example this code:
\begin{verbatim}
    virtual at 0
        file 'a.txt':10h,1
        load char from 0
    end virtual
\end{verbatim}
loads the single byte from offset 10h in file \verb"a.txt" into the \verb"char"
constant.

Any of the \verb"section" directives described in \ref{sec:formatter} also begins a new
addressing space.

\subsection{Other directives}
\label{sec:other}
\index{ALIGN}
\verb"align" directive aligns code or data to the specified boundary. It should
be followed by a numerical expression specifying the number of bytes, to the
multiply of which the current address has to be aligned. The boundary value
has to be the power of two.

The \verb"align" directive fills the bytes that had to be skipped to perform the
alignment with the \verb"nop" instructions and at the same time marks this area as
uninitialized data, so if it is placed among other uninitialized data that
wouldn't take space in the output file, the alignment bytes will act the same
way. If you need to fill the alignment area with some other values, you can
combine \verb"align" with \verb"virtual" to get the size of alignment needed and then
create the alignment yourself, like:
\begin{verbatim}
    virtual
        align 16
        a = $ - $$
    end virtual
    db a dup 0
\end{verbatim}
The \verb"a" constant is defined to be the difference between address after alignment
and address of the \verb"virtual" block (see previous section), so it is equal to
the size of needed alignment space.

\index{DISPLAY}
\verb"display" directive displays the message at the assembly time. It should
be followed by the quoted strings or byte values, separated with commas. It
can be used to display values of some constants, for example:
\begin{verbatim}
    bits = 16
    display 'Current offset is 0x'
    repeat bits/4
        d = '0' + $ shr (bits-%*4) and 0Fh
        if d > '9'
            d = d + 'A'-'9'-1
        end if
        display d
    end repeat
    display 13,10
\end{verbatim}
This block of directives calculates the four hexadecimal digits of 16--bit value
and converts them into characters for displaying. Note that this will not work if
the adresses in current addressing space are relocatable (as it might happen with
PE or object output formats), since only absolute values can be used this way.
The absolute value may be obtained by calculating the relative address, like
\verb"$-$$", or \verb"rva $" in case of PE format.

The \verb"err" directive immediately terminates the assembly process when it is
encountered by assembler.

The \verb"assert" directive tests whether the logical expression that follows it
is true, and if not, it signalizes the error.


\subsection{Multiple passes}
\label{sec:passes}
Because the assembler allows to reference some of the labels or constants
before they get actually defined, it has to predict the values of such labels
and if there is even a suspicion that prediction failed in at least one case,
it does one more pass, assembling the whole source, this time doing better
prediction based on the values the labels got in the previous pass.

The changing values of labels can cause some instructions to have encodings
of different length, and this can cause the change in values of labels again.
And since the labels and constants can also be used inside the expressions that
affect the behavior of control directives, the whole block of source can be
processed completely differently during the new pass. Thus the assembler does
more and more passes, each time trying to do better predictions to approach
the final solution, when all the values get predicted correctly. It uses
various method for predicting the values, which has been chosen to allow
finding in a few passes the solution of possibly smallest length for the most
of the programs.

Some of the errors, like the values not fitting in required boundaries, are
not signaled during those intermediate passes, since it may happen that when
some of the values are predicted better, these errors will disappear. However
if assembler meets some illegal syntax construction or unknown instruction, it
always stops immediately. Also defining some label more than once causes such
error, because it makes the predictions groundless.

Only the messages created
with the \verb"display" directive during the last performed pass get actually
displayed. In case when the assembly has been stopped due to an error, these messages
may reflect the predicted values that are not yet resolved correctly.

The solution may sometimes not exist and in such cases the assembler will
never manage to make correct predictions -- for this reason there is a limit for
a number of passes, and when assembler reaches this limit, it stops and displays
the message that it is not able to generate the correct output. Consider the
following example:
\begin{verbatim}
    if ~ defined alpha
        alpha:
    end if
\end{verbatim}
The \verb"defined" operator gives the true value when the expression following it
could be calculated in this place, what in this case means that the \verb"alpha"
label is defined somewhere. But the above block causes this label to be defined
only when the value given by \verb"defined" operator is false, what leads to an
antynomy and makes it impossible to resolve such code. When processing the \verb"if"
directive assembler has to predict whether the \verb"alpha" label will be defined
somewhere (it wouldn't have to predict only if the label was already defined
earlier in this pass), and whatever the prediction is, the opposite always
happens. Thus the assembly will fail, unless the \verb"alpha" label is defined
somewhere in source preceding the above block of instructions -- in such case,
as it was already noted, the prediction is not needed and the block will just
get skipped.

The above sample might have been written as a try to define the label only
when it was not yet defined. It fails, because the \verb"defined" operator does
check whether the label is defined anywhere, and this includes the definition
inside this conditionally processed block. However adding some additional
condition may make it possible to get it resolved:
\begin{verbatim}
    if ~ defined alpha | defined @f
        alpha:
        @@:
    end if
\end{verbatim}
The \verb"@f" is always the same label as the nearest \verb"@@" symbol in the source
following it, so the above sample would mean the same if any unique name was
used instead of the anonymous label. When \verb"alpha" is not defined in any other
place in source, the only possible solution is when this block gets defined,
and this time this doesn't lead to the antynomy, because of the anonymous
label which makes this block self--establishing. To better understand this,
look at the blocks that has nothing more than this self-establishing:
\begin{verbatim}
    if defined @f
        @@:
    end if
\end{verbatim}
This is an example of source that may have more than one solution, as both
cases when this block gets processed or not are equally correct. Which one of
those two solutions we get depends on the algorithm on the assembler, in case
of flat assembler -- on the algorithm of predictions. Back to the previous
sample, when \verb"alpha" is not defined anywhere else, the condition for \verb"if" block
cannot be false, so we are left with only one possible solution, and we can
hope the assembler will arrive at it. On the other hand, when \verb"alpha" is
defined in some other place, we've got two possible solutions again, but one of
them causes \verb"alpha" to be defined twice, and such an error causes assembler to
abort the assembly immediately, as this is the kind of error that deeply
disturbs the process of resolving. So we can get such source either correctly
resolved or causing an error, and what we get may depend on the internal
choices made by the assembler.

However there are some facts about such choices that are certain. When
assembler has to check whether the given symbol is defined and it was already
defined in the current pass, no prediction is needed -- it was already noted
above. And when the given symbol has been defined never before, including all
the already finished passes, the assembler predicts it to be not defined.
Knowing this, we can expect that the simple self--establishing block shown
above will not be assembled at all and that the previous sample will resolve
correctly when \verb"alpha" is defined somewhere before our conditional block,
while it will itself define \verb"alpha" when it's not already defined earlier, thus
potentially causing the error because of double definition if the \verb"alpha" is
also defined somewhere later.

The \verb"used" operator may be expected to behave in a similar manner in
analogous cases, however any other kinds of predictions my not be so simple and
you should never rely on them this way.

The \verb"err" directive, usually used to stop the assembly when some condition is
met, stops the assembly immediately, regardless of whether the current pass
is final or intermediate. So even when the condition that caused this directive
to be interpreted is mispredicted and temporary, and would eventually disappear in the later
passes, the assembly is stopped anyway.

The \verb"assert" directive signalizes the error only if its expression is false
after all the symbols have been resolved. You can use \verb"assert 0" in place of
\verb"err" when you do not want to have assembly stopped during the intermediate
passes.


\section{Preprocessor directives}
\label{sec:preprocessor}
All preprocessor directives are processed before the main assembly process,
and therefore are not affected by the control directives. At this time also
all comments are stripped out.

\subsection{Including source files}
\index{INCLUDE}
\verb"include" directive includes the specified source file at the position
where it is used. It should be followed by the quoted name of file that
should be included, for example:
\begin{verbatim}
    include 'macros.inc'
\end{verbatim}
The whole included file is preprocessed before preprocessing the lines next
to the line containing the \verb"include" directive. There are no limits to
the number of included files as long as they fit in memory.

The quoted path can contain environment variables enclosed within \verb"%"
characters, they will be replaced with their values inside the
path, both the \verb"\" and \verb"/" characters are allowed as a
path separators. The file is first
searched for in the directory containing file which included it and when it is
not found there, the search is continued in the directories specified in the
environment variable called INCLUDE (the multiple paths separated with
semicolons can be defined there, they will be searched in the same order as
specified). If file was not found in any of these places, preprocessor looks
for it in the directory containing the main source file (the one specified in
command line). These rules concern also paths given with the \verb"file" directive.

\subsection{Symbolic constants}
\label{sec:symbolic_constants}
The symbolic constants are different from the numerical constants, before the
assembly process they are replaced with their values everywhere in source
lines after their definitions, and anything can become their values.

\index{EQU}
The definition of symbolic constant consists of name of the constant followed
by the \verb"equ" directive. Everything that follows this directive will
become the value of constant. If the value of symbolic constant contains
other symbolic constants, they are replaced with their values before
assigning this value to the new constant. For example:
\begin{verbatim}
    d equ dword
    NULL equ d 0
    d equ edx
\end{verbatim}
After these three definitions the value of \verb"NULL" constant is
\verb"dword 0" and the value of \verb"d" is \verb"edx". So, for example,
\verb"push NULL" will be assembled as \verb"push dword 0" and \verb"push d"
will be assembled as \verb"push edx". And if then the following line was put:
\begin{verbatim}
    d equ d,eax
\end{verbatim}
the \verb"d" constant would get the new value of \verb"edx,eax". This way the growing
lists of symbols can be defined.

\index{RESTORE}
\verb"restore" directive allows to get back previous value of redefined symbolic
constant. It should be followed by one more names of symbolic constants,
separated with commas. So \verb"restore d" after the above definitions will give
\verb"d" constant back the value \verb"edx", the second one will restore it to value
\verb"dword", and one more will revert \verb"d" to original meaning as if no such
constant was defined. If there was no constant defined of given name,
\verb"restore" will not cause an error, it will be just ignored.

Symbolic constant can be used to adjust the syntax of assembler to personal
preferences. For example the following set of definitions provides the handy
shortcuts for all the size operators:
\begin{verbatim}
    b equ byte
    w equ word
    d equ dword
    p equ pword
    f equ fword
    q equ qword
    t equ tword
    x equ dqword
    y equ qqword
\end{verbatim}

Because symbolic constant may also have an empty value, it can be used to
allow the syntax with \verb"offset" word before any address value:
\begin{verbatim}
    offset equ
\end{verbatim}
After this definition \verb"mov ax,offset char" will be valid construction
for copying the offset of \verb"char" variable into \verb"ax" register,
because \verb"offset" is replaced with an empty value, and therefore ignored.

\index{DEFINE}
The \verb"define" directive followed by the name of constant and then the value,
is the alternative way of defining symbolic constant. The only difference
between \verb"define" and \verb"equ" is that \verb"define" assigns the value as it is, it does
not replace the symbolic constants with their values inside it.

\index{FIX}
Symbolic constants can also be defined with the \verb"fix" directive, which has
the same syntax as \verb"equ", but defines constants of high priority -- they are
replaced with their symbolic values even before processing the preprocessor
directives and macroinstructions, the only exception is \verb"fix" directive
itself, which has the highest possible priority, so it allows redefinition of
constants defined this way.

The \verb"fix" directive can be used for syntax adjustments related to directives
of preprocessor, what cannot be done with \verb"equ" directive. For example:
\begin{verbatim}
    incl fix include
\end{verbatim}
defines a short name for \verb"include" directive, while the similar definition done
with \verb"equ" directive wouldn't give such result, as standard symbolic constants
are replaced with their values after searching the line for preprocessor
directives.


\subsection{Macroinstructions}
\index{MACRO}
\verb"macro" directive allows you to define your own complex instructions,
called macroinstructions, using which can greatly simplify the process of
programming. In its simplest form it's similar to symbolic constant
definition. For example the following definition defines a shortcut for the
\verb"test al,0xFF" instruction:
\begin{verbatim}
    macro tst {test al,0xFF}
\end{verbatim}
After the \verb"macro" directive there is a name of macroinstruction and then
its contents enclosed between the \verb"{" and \verb"}" characters. You can
use \verb"tst" instruction anywhere after this definition and it will be
assembled as \verb"test al,0xFF". Defining symbolic constant \verb"tst" of
that value would give the similar result, but the difference is that the name
of macroinstruction is recognized only as an instruction mnemonic. Also,
macroinstructions are replaced with corresponding code even before the
symbolic constants are replaced with their values. So if you define
macroinstruction and symbolic constant of the same name, and use this name as
an instruction mnemonic, it will be replaced with the contents of
macroinstruction, but it will be replaced with value if symbolic constant if
used somewhere inside the operands.

The definition of macroinstruction can consist of many lines, because
\verb"{" and \verb"}" characters don't have to be in the same line as
\verb"macro" directive. For example:
\begin{verbatim}
    macro stos0
     {
        xor al,al
        stosb
     }
\end{verbatim}
The macroinstruction \verb"stos0" will be replaced with these two assembly
instructions anywhere it's used.

Like instructions which needs some number of operands, the macroinstruction
can be defined to need some number of arguments separated with commas. The
names of needed argument should follow the name of macroinstruction in the
line of \verb"macro" directive and should be separated with commas if there
is more than one. Anywhere one of these names occurs in the contents of
macroinstruction, it will be replaced with corresponding value, provided when
the macroinstruction is used. Here is an example of a macroinstruction that
will do data alignment for binary output format:
\begin{verbatim}
    macro align value { rb (value-1)-($+value-1) mod value }
\end{verbatim}
When the \verb"align 4" instruction is found after this macroinstruction is
defined, it will be replaced with contents of this macroinstruction, and the
\verb"value" will there become 4, so the result will be
\verb%rb (4-1)-($+4-1) mod 4%.

If a macroinstruction is defined that uses an instruction with the same name
inside its definition, the previous meaning of this name is used. Useful
redefinition of macroinstructions can be done in that way, for example:
\begin{verbatim}
    macro mov op1,op2
     {
      if op1 in <ds,es,fs,gs,ss> & op2 in <cs,ds,es,fs,gs,ss>
        push  op2
        pop   op1
      else
        mov   op1,op2
      end if
     }
\end{verbatim}
This macroinstruction extends the syntax of \verb"mov" instruction, allowing
both operands to be segment registers. For example \verb"mov ds,es" will be
assembled as \verb"push es" and \verb"pop ds". In all other cases the
standard \verb"mov" instruction will be used. The syntax of this \verb"mov"
can be extended further by defining next macroinstruction of that name, which
will use the previous macroinstruction:
\begin{verbatim}
    macro mov op1,op2,op3
     {
      if op3 eq
        mov   op1,op2
      else
        mov   op1,op2
        mov   op2,op3
      end if
     }
\end{verbatim}
It allows \verb"mov" instruction to have three operands, but it can still
have two operands only, because when macroinstruction is given less arguments
than it needs, the rest of arguments will have empty values. When three
operands are given, this macroinstruction will become two macroinstructions
of the previous definition, so \verb"mov es,ds,dx" will be assembled as
\verb"push ds", \verb"pop es" and \verb"mov ds,dx".

By placing the \verb"*" after the name of argument you can mark the argument as
required -- preprocessor will not allow it to have an empty value. For example the
above macroinstruction could be declared as \verb"macro mov op1*,op2*,op3" to make
sure that first two arguments will always have to be given some non empty
values.

Alternatively, you can provide the default value for argument, by placing
the \verb"=" followed by value after the name of argument. Then if the argument
has an empty value provided, the default value will be used instead.

When it's needed to provide macroinstruction with argument that contains
some commas, such argument should be enclosed between \verb"<" and \verb">"
characters. If it contains more than one \verb"<" character, the same number
of \verb">" should be used to tell that the value of argument ends.

\index{PURGE}
\verb"purge" directive allows removing the last definition of specified
macroinstruction. It should be followed by one or more names of
macroinstructions, separated with commas. If such macroinstruction has not
been defined, you will not get any error. For example after having the syntax of
\verb"mov" extended with the macroinstructions defined above, you can disable
syntax with three operands back by using \verb"purge mov" directive. Next
\verb"purge mov" will disable also syntax for two operands being segment
registers, and all the next such directives will do nothing.

If after the \verb"macro" directive you enclose some group of arguments'
names in square brackets, it will allow giving more values for this group of
arguments when using that macroinstruction. Any more argument given after the
last argument of such group will begin the new group and will become the
first argument of it. That's why after closing the square bracket no more
argument names can follow. The contents of macroinstruction will be processed
for each such group of arguments separately. The simplest example is to
enclose one argument name in square brackets:
\begin{verbatim}
    macro stoschar [char]
     {
        mov al,char
        stosb
     }
\end{verbatim}
This macroinstruction accepts unlimited number of arguments, and each one
will be processed into these two instructions separately. For example
\verb"stoschar 1,2,3" will be assembled as the following instructions:
\begin{verbatim}
    mov al,1
    stosb
    mov al,2
    stosb
    mov al,3
    stosb
\end{verbatim}

\index{LOCAL}
There are some special directives available only inside the definitions of
macroinstructions. \verb"local" directive defines local names, which will be
replaced with unique values each time the macroinstruction is used. It should
be followed by names separated with commas. If the name given as parameter to \verb"local" directive begins with a dot or two
dots, the unique labels generated by each evaluation of macroinstruction will
have the same properties. This directive is usually needed
for the constants or labels that macroinstruction defines and uses
internally.
For example:
\begin{verbatim}
    macro movstr
     {
        local move
      move:
        lodsb
        stosb
        test al,al
        jnz move
     }
\end{verbatim}
Each time this macroinstruction is used, \verb"move" will become other
unique name in its instructions, so you will not get an error you normally get
when some label is defined more than once.

\index{FORWARD}\index{REVERSE}\index{COMMON}
\verb"forward", \verb"reverse" and \verb"common" directives divide
macroinstruction into blocks, each one processed after the processing of
previous is finished. They differ in behavior only if macroinstruction allows
multiple groups of arguments. Block of instructions that follows
\verb"forward" directive is processed for each group of arguments, from
first to last -- exactly like the default block (not preceded by any of these
directives). Block that follows \verb"reverse" directive is processed
for each group of argument in reverse order -- from last to first. Block that
follows \verb"common" directive is processed only once, commonly for all
groups of arguments. Local name defined in one of the blocks is available in
all the following blocks when processing the same group of arguments as when
it was defined, and when it is defined in common block it is available in all
the following blocks not depending on which group of arguments is processed.

Here is an example of macroinstruction that will create the table of
addresses to strings followed by these strings:
\begin{verbatim}
    macro strtbl name,[string]
     {
      common
        label name dword
      forward
        local label
        dd label
      forward
        label db string,0
     }
\end{verbatim}
First argument given to this macroinstruction will become the label for table
of addresses, next arguments should be the strings. First block is processed
only once and defines the label, second block for each string declares its
local name and defines the table entry holding the address to that string.
Third block defines the data of each string with the corresponding label.

The directive starting the block in macroinstruction can be followed by the
first instruction of this block in the same line, like in the following
example:
\begin{verbatim}
    macro stdcall proc,[arg]
     {
      reverse push arg
      common call proc
     }
\end{verbatim}
This macroinstruction can be used for calling the procedures using STDCALL
convention, which has all the arguments pushed on stack in the reverse order. For example
\verb"stdcall foo,1,2,3" will be assembled as:
\begin{verbatim}
    push 3
    push 2
    push 1
    call foo
\end{verbatim}

If some name inside macroinstruction has multiple values (it is either one of
the arguments enclosed in square brackets or local name defined in the block
following \verb"forward" or \verb"reverse" directive) and is used in block
following the \verb"common" directive, it will be replaced with all of its
values, separated with commas. For example the following macroinstruction
will pass all of the additional arguments to the previously defined
\verb"stdcall" macroinstruction:
\begin{verbatim}
    macro invoke proc,[arg]
     { common stdcall [proc],arg }
\end{verbatim}
It can be used to call indirectly (by the pointer stored in memory) the
procedure using STDCALL convention.

Inside macroinstruction also special operator \verb"#" can be used. This
operator causes two names to be concatenated into one name. It can be useful,
because it's done after the arguments and local names are replaced with their
values. The following macroinstruction will generate the conditional jump
according to the \verb"cond" argument:
\begin{verbatim}
    macro jif op1,cond,op2,label
     {
        cmp op1,op2
        j#cond label
     }
\end{verbatim}
For example \verb"jif ax,ae,10h,exit" will be assembled as \verb"cmp ax,10h"
and \verb"jae exit" instructions.

The \verb"#" operator can be also used to concatenate two quoted strings into one.
Also conversion of name into a quoted string is possible, with the \verb"`" operator,
which likewise can be used inside the macroinstruction. It converts the name
that follows it into a quoted string -- but note, that when it is followed by
a macro argument which is being replaced with value containing more than one
symbol, only the first of them will be converted, as the \verb"`" operator converts
only one symbol that immediately follows it. Here's an example of utilizing
those two features:
\begin{verbatim}
    macro label name
     {
        label name
        if ~ used name
          display `name # " is defined but not used.",13,10
        end if
     }
\end{verbatim}
When label defined with such macro is not used in the source, macro will warn
you with the message, informing to which label it applies.

To make macroinstruction behaving differently when some of the arguments are
of some special type, for example a quoted strings, you can use \verb"eqtype"
comparison operator. Here's an example of utilizing it to distinguish a
quoted string from an other argument.
\begin{verbatim}
    macro message arg
     {
      if arg eqtype ""
        local str
        jmp   @f
        str   db arg,0Dh,0Ah,24h
        @@:
        mov   dx,str
      else
        mov   dx,arg
      end if
        mov   ah,9
        int   21h
     }
\end{verbatim}
The above macro is designed for displaying messages in DOS programs. When the
argument of this macro is some number, label, or variable, the string from
that address is displayed, but when the argument is a quoted string, the
created code will display that string followed by the carriage return and
line feed.

It is also possible to put a declaration of macroinstruction
inside another macroinstruction, so one macro can define another,
but there is a problem with such definitions caused by the fact,
that \verb"}" character cannot occur inside the macroinstruction,
as it always means the end of definition. To
overcome this problem, the escaping of symbols inside macroinstruction can be
used. This is done by placing one or more
backslashes in front of any other symbol (even the special
character). Preprocessor sees such sequence as a single symbol,
but each time it meets such symbol during the macroinstruction
processing, it cuts the backslash character from the front of it.
For example \verb"\}" is treated as single symbol, but during
processing of the macroinstruction it becomes the \verb"}" symbol.
This allows to put one definition of macroinstruction inside
another:
\begin{verbatim}
    macro ext instr
     {
      macro instr op1,op2,op3
       \{
        if op3 eq
          instr op1,op2
        else
          instr op1,op2
          instr op2,op3
        end if
       \}
     }

    ext add
    ext sub
\end{verbatim}
The macro \verb"ext" is defined correctly, but when it is used,
the \verb"\{" and \verb"\}" become the \verb"{" and \verb"}"
symbols. So when the \verb"ext add" is processed, the contents of
macro becomes valid definition of a macroinstruction and this way
the \verb"add" macro becomes defined. In the same way \verb"ext sub" defines
the \verb"sub" macro. The use of \verb"\{" symbol wasn't
really necessary here, but is done this way to make the definition
more clear.

If some directives specific to macroinstructions, like \verb"local" or \verb"common"
are needed inside some macro embedded this way, they can be
escaped in the same way. Escaping the symbol with more than one
backslash is also allowed, which allows multiple levels of nesting
the macroinstruction definitions.

The another technique for defining one macroinstruction by another is to
use the \verb"fix" directive, which becomes useful when some macroinstruction only
begins the definition of another one, without closing it. For example:
\begin{verbatim}
    macro tmacro [params]
     {
      common macro params {
     }

    MACRO fix tmacro
    ENDM fix }
\end{verbatim}
defines an alternative syntax for defining macroinstructions, which looks like:
\begin{verbatim}
    MACRO stoschar char
        mov al,char
        stosb
    ENDM
\end{verbatim}
Note that symbol that has such customized definition must be defined with \verb"fix"
directive, because only the prioritized symbolic constants are processed before
the preprocessor looks for the \verb"}" character while defining the macro. This
might be a problem if one needed to perform some additional tasks one the end
of such definition, but there is one more feature which helps in such cases.
Namely it is possible to put any directive, instruction or  macroinstruction
just after the \verb"}" character that ends the macroinstruction and it will be
processed in the same way as if it was put in the next line.

\subsection{Structures}
\index{STRUC}
\verb"struc" directive is a special variant of \verb"macro" directive that is
used to define data structures. Macroinstruction defined using the
\verb"struc" directive must be preceded by a label (like the data definition
directive) when it's used. This label will be also attached at the beginning
of every name starting with dot in the contents of macroinstruction. The
macroinstruction defined using the \verb"struc" directive can have the same
name as some other macroinstruction defined using the \verb"macro" directive,
structure macroinstruction will not prevent the standard macroinstruction from being
processed when there is no label before it and vice versa. All the rules and features
concerning standard macroinstructions apply to structure macroinstructions.

Here is the sample of structure macroinstruction:
\begin{verbatim}
    struc point x,y
     {
        .x dw x
        .y dw y
     }
\end{verbatim}
For example \verb"my point 7,11" will define structure labeled \verb"my",
consisting of two variables: \verb"my.x" with value 7 and \verb"my.y" with
value 11.

If somewhere inside the definition of structure the name consisting of a
single dot it found, it is replaced by the name of the label for the given
instance of structure and this label will not be defined automatically in
such case, allowing to completely customize the definition. The following
example utilizes this feature to extend the data definition directive \verb"db"
with ability to calculate the size of defined data:
\begin{verbatim}
    struc db [data]
     {
       common
        . db data
        .size = $ - .
     }
\end{verbatim}
With such definition \verb"msg db 'Hello!',13,10" will define also \verb"msg.size"
constant, equal to the size of defined data in bytes.

Defining data structures addressed by registers or absolute values should be
done using the \verb"virtual" directive with structure macroinstruction
(see \ref{sec:other}).

\index{RESTRUC}
\verb"restruc" directive removes the last definition of the structure, just like
\verb"purge" does with macroinstructions and \verb"restore" with symbolic constants.
It also has the same syntax -- should be followed by one or more names of
structure macroinstructions, separated with commas.

\subsection{Repeating macroinstructions}
\index{REPT}
The \verb"rept" directive is a special kind of macroinstruction, which makes given
amount of duplicates of the block enclosed with braces. The basic syntax is
\verb"rept" directive followed by number and then block of source enclosed between
the \verb"{" and \verb"}" characters. The simplest example:
\begin{verbatim}
    rept 5 { in al,dx }
\end{verbatim}
will make five duplicates of the \verb"in al,dx" line. The block of instructions
is defined in the same way as for the standard macroinstruction and any
special operators and directives which can be used only inside
macroinstructions are also allowed here. When the given count is zero, the
block is simply skipped, as if you defined macroinstruction but never used
it. The number of repetitions can be followed by the name of counter symbol, which will get replaced
symbolically with the number of duplicate currently generated. So this:
\begin{verbatim}
    rept 3 counter
     {
        byte#counter db counter
     }
\end{verbatim}
will generate lines:
\begin{verbatim}
    byte1 db 1
    byte2 db 2
    byte3 db 3
\end{verbatim}
The repetition mechanism applied to \verb"rept" blocks is the same as the one used
to process multiple groups of arguments for macroinstructions, so directives
like \verb"forward", \verb"common" and \verb"reverse" can be used in their usual meaning.
Thus such macroinstruction:
\begin{verbatim}
    rept 7 num { reverse display `num }
\end{verbatim}
will display digits from 7 to 1 as text. The \verb"local" directive behaves in the
same way as inside macroinstruction with multiple groups of arguments, so:
\begin{verbatim}
    rept 21
     {
       local label
       label: loop label
     }
\end{verbatim}
will generate unique label for each duplicate.

The counter symbol by default counts from 1, but you can declare different
base value by placing the number preceded by colon immediately after the name
of counter. For example:
\begin{verbatim}
    rept 8 n:0 { pxor xmm#n,xmm#n }
\end{verbatim}
will generate code which will clear the contents of eight SSE registers.
You can define multiple counters separated with commas, and each one can have
different base.

The number of repetitions and the base values for counters can be specified
using the numerical expressions with operator rules identical as in the case
of assembler. However each value used in such expression must either be a
directly specified number, or a symbolic constant with value also being an
expression that can be calculated by preprocessor (in such case the value
of expression associated with symbolic constant is calculated first, and then
substituted into the outer expression in place of that constant). If you need
repetitions based on values that can only be calculated at assembly time, use
one of the code repeating directives that are processed by assembler, see
section \ref{sec:repeating}.

\index{IRP}
The \verb"irp" directive iterates the single argument through the given list of
parameters. The syntax is \verb"irp" followed by the argument name, then the comma
and then the list of parameters. The parameters are specified in the same
way like in the invocation of standard macroinstruction, so they have to be
separated with commas and each one can be enclosed with the \verb"<" and \verb">"
characters. Also the name of argument may be followed by \verb"*" to mark that it
cannot get an empty value. Such block:
\begin{verbatim}
   irp value, 2,3,5
    { db value }
\end{verbatim}
will generate lines:
\begin{verbatim}
   db 2
   db 3
   db 5
\end{verbatim}
\index{IRPS}
The \verb"irps" directive iterates through the given list of symbols, it should
be followed by the argument name, then the comma and then the sequence of any
symbols. Each symbol in this sequence, no matter whether it is the name
symbol, symbol character or quoted string, becomes an argument value for one
iteration. If there are no symbols following the comma, no iteration is done
at all. This example:
\begin{verbatim}
   irps reg, al bx ecx
    { xor reg,reg }
\end{verbatim}
will generate lines:
\begin{verbatim}
   xor al,al
   xor bx,bx
   xor ecx,ecx
\end{verbatim}
The blocks defined by the \verb"irp" and \verb"irps" directives are also processed in
the same way as any macroinstructions, so operators and directives specific
to macroinstructions may be freely used also in this case.


\subsection{Conditional preprocessing}
\label{sec:conditional_preprocessing}
\index{MATCH}
\verb"match" directive causes some block of source to be preprocessed and passed
to assembler only when the given sequence of symbols matches the specified
pattern. The pattern comes first, ended with comma, then the symbols
that have to be matched with the pattern, and finally the block of
source, enclosed within braces as macroinstruction.

There are the few rules for building the expression for matching, first is
that any of symbol characters and any quoted string should be matched exactly as is. In this example:
\begin{verbatim}
    match +,+ { include 'first.inc' }
    match +,- { include 'second.inc' }
\end{verbatim}
the first file will get included, since \verb"+" after comma matches the \verb"+" in
pattern, and the second file will not be included, since there is no match.

To match any other symbol literally, it has to be preceded by \verb"=" character
in the pattern. Also to match the \verb"=" character itself, or the comma, the
\verb"==" and \verb"=," constructions have to be used. For example the \verb"=a==" pattern
will match the \verb"a=" sequence.

If some name symbol is placed in the pattern, it matches any sequence
consisting of at least one symbol and then this name is replaced with the
matched sequence everywhere inside the following block, analogously to the
parameters of macroinstruction. For instance:
\begin{verbatim}
    match a-b, 0-7
     { dw a,b-a }
\end{verbatim}
will generate the \verb"dw 0,7-0" instruction. Each name is always matched with
as few symbols as possible, leaving the rest for the following ones, so in
this case:
\begin{verbatim}
    match a b, 1+2+3 { db a }
\end{verbatim}
the \verb"a" name will match the \verb"1" symbol, leaving the \verb"+2+3" sequence to be
matched with \verb"b". But in this case:
\begin{verbatim}
    match a b, 1 { db a }
\end{verbatim}
there will be nothing left for \verb"b" to match, so the block will not get processed
at all.

The block of source defined by match is processed in the same way as any
macroinstruction, so any operators specific to macroinstructions can be used
also in this case.

What makes "match" directive more useful is the fact, that it replaces the
symbolic constants with their values in the matched sequence of symbols (that
is everywhere after comma up to the beginning of the source block) before
performing the match. Thanks to this it can be used for example to process
some block of source under the condition that some symbolic constant has the
given value, like:
\begin{verbatim}
    match =TRUE, DEBUG { include 'debug.inc' }
\end{verbatim}
which will include the file only when the symbolic constant \verb"DEBUG" was
defined with value \verb"TRUE".

\subsection{Order of processing}
When combining various features of the preprocessor, it's important to know
the order in which they are processed. As it was already noted, the highest
priority has the \verb"fix" directive and the replacements defined with it. This
is done completely before doing any other preprocessing, therefore this
piece of source:
\begin{verbatim}
    V fix {
      macro empty
       V
    V fix }
       V
\end{verbatim}
becomes a valid definition of an empty macroinstruction. It can be interpreted
that the \verb"fix" directive and prioritized symbolic constants are processed in
a separate stage, and all other preprocessing is done after on the resulting
source.

The standard preprocessing that comes after, on each line begins with
recognition of the first symbol. It starts with checking for the preprocessor
directives, and when none of them is detected, preprocessor checks whether the
first symbol is macroinstruction. If no macroinstruction is found, it moves
to the second symbol of line, and again begins with checking for directives,
which in this case is only the \verb"equ" directive, as this is the only one that
occurs as the second symbol in line. If there is no directive, the second
symbol is checked for the case of structure macroinstruction and when none
of those checks gives the positive result, the symbolic constants are replaced
with their values and such line is passed to the assembler.

To see it on the example, assume that there is defined the macroinstruction
called \verb"foo" and the structure macroinstruction called \verb"bar". Those lines:
\begin{verbatim}
    foo equ
    foo bar
\end{verbatim}
would be then both interpreted as invocations of macroinstruction \verb"foo", since
the meaning of the first symbol overrides the meaning of second one.

When the macroinstruction generates the new lines from its
definition block, in every line it first scans for
macroinstruction directives, and interpretes them accordingly. All
the other content in the definition block is used to brew the new
lines, replacing the parameters with their values and then
processing the symbol escaping and \verb"#" and \verb"`"
operators. The conversion operator has the higher priority than
concatenation and if any of them operates on the escaped symbol,
the escaping is cancelled before finishing the operation. After
this is completed, the newly generated line goes through the
standard preprocessing, as described above.

Though the symbolic constants are usually only replaced in the lines, where
no preprocessor directives nor macroinstructions has been found, there are some
special cases where those replacements are performed in the parts of lines
containing directives. First one is the definition of symbolic constant, where
the replacements are done everywhere after the \verb"equ" keyword and the resulting
value is then assigned to the new constant (see \ref{sec:symbolic_constants}).
The second such case is the \verb"match" directive, where the replacements are done in the symbols
following comma before matching them with pattern. These features can be used
for example to maintain the lists, like this set of definitions:
\begin{verbatim}
    list equ

    macro append item
     {
       match any, list \{ list equ list,item \}
       match , list \{ list equ item \}
     }
\end{verbatim}
The \verb"list" constant is here initialized with empty value, and the \verb"append"
macroinstruction can be used to add the new items into this list, separating
them with commas. The first match in this macroinstruction occurs only when
the value of list is not empty (see \ref{sec:conditional_preprocessing}), in such case the new value for the
list is the previous one with the comma and the new item appended at the end.
The second match happens only when the list is still empty, and in such case
the list is defined to contain just the new item. So starting with the empty
list, the \verb"append 1" would define \verb"list equ 1" and the \verb"append 2" following it
would define \verb"list equ 1,2". One might then need to use this list as the
parameters to some macroinstruction. But it cannot be done directly -- if \verb"foo"
is the macroinstruction, then \verb"foo list" would just pass the \verb"list" symbol
as a parameter to macro, since symbolic constants are not unrolled at this
stage. For this purpose again \verb"match" directive comes in handy:
\begin{verbatim}
    match params, list { foo params }
\end{verbatim}
The value of \verb"list", if it's not empty, matches the \verb"params" keyword, which is
then replaced with matched value when generating the new lines defined by the
block enclosed with braces. So if the \verb"list" had value \verb"1,2", the above line
would generate the line containing \verb"foo 1,2", which would then go through the
standard preprocessing.

The other special case is in the parameters of \verb"rept" directive. The amount
of repetitions and the base value for counter can be specified using
numerical expressions, and if there is a symbolic constant with non--numerical
name used in such an expression, preprocessor tries to evaluate its value as a numerical expression
and if succeeds, it replaces the symbolic constant with the result of that
calculation and continues to evaluate the primary expression. If the
expression inside that symbolic constants also contains some symbolic
constants, preprocessor will try to calculate all the needed values
recursively.

This allows to perform some calculations at the time of preprocessing, as
long as all the values used are the numbers known at the preprocessing stage.
A single repetition with \verb"rept" can be used for the sole purpose of
calculating some value, like in this example:
\begin{verbatim}
    define a b+4
    define b 3
    rept 1 result:a*b+2 { define c result }
\end{verbatim}
To compute the base value for \verb"result" counter, preprocessor replaces the \verb"b"
with its value and recursively calculates the value of \verb"a", obtaining 7 as
the result, then it calculates the main expression with the result being 23.
The \verb"c" then gets defined with the first value of counter (because the block
is processed just one time), which is the result of the computation, so the
value of \verb"c" is simple \verb"23" symbol. Note that if \verb"b" is later redefined with
some other numerical value, the next time and expression containing \verb"a" is
calculated, the value of \verb"a" will reflect the new value of \verb"b", because the
symbolic constant contains just the text of the expression.

There is one more special case -- when preprocessor goes to checking the
second symbol in the line and it happens to be the colon character (what is
then interpreted by assembler as definition of a label), it stops in this
place and finishes the preprocessing of the first symbol (so if it's the
symbolic constant it gets unrolled) and if it still appears to be the label,
it performs the standard preprocessing starting from the place after the
label. This allows to place preprocessor directives and macroinstructions
after the labels, analogously to the instructions and directives processed
by assembler, like:
\begin{verbatim}
    start: include 'start.inc'
\end{verbatim}
However if the label becomes broken during preprocessing (for example when
it is the symbolic constant with empty value), only replacing of the symbolic
constants is continued for the rest of line.

It should be remembered, that the jobs performed by preprocessor are the
preliminary operations on the texts symbols, that are done in a simple
single pass before the main process of assembly. The text that is the
result of preprocessing is passed to assembler, and it then does its
multiple passes on it. Thus the control directives, which are recognized and
processed only by the assembler -- as they are dependent on the numerical
values that may even vary between passes -- are not recognized in any way by
the preprocessor and have no effect on the preprocessing. Consider this
example source:
\begin{verbatim}
    if 0
    a = 1
    b equ 2
    end if
    dd b
\end{verbatim}
When it is preprocessed, they only directive that is recognized by the
preprocessor is the \verb"equ", which defines symbolic constant \verb"b", so later
in the source the \verb"b" symbol is replaced with the value \verb"2". Except for this
replacement, the other lines are passes unchanged to the assembler. So
after preprocessing the above source becomes:
\begin{verbatim}
    if 0
    a = 1
    end if
    dd 2
\end{verbatim}
Now when assembler processes it, the condition for the \verb"if" is false, and
the \verb"a" constant doesn't get defined. However symbolic constant \verb"b" was
processed normally, even though its definition was put just next to the one
of \verb"a". So because of the possible confusion you should be very careful
every time when mixing the features of preprocessor and assembler - in such
cases it is important to realize what the source will become after the
preprocessing, and thus what the assembler will see and do its multiple passes
on.

\section{Formatter directives}
\label{sec:formatter}
\index{FORMAT}
These directives are actually also a kind of control directives, with the
purpose of controlling the format of generated code.

\verb"format" directive followed by the format identifier allows to select
the output format. This directive should be put at the beginning of the
source. Default output format is a flat binary file, it can also be selected
by using \verb"format binary" directive.
This directive can be followed by the \verb"as" keyword
and the quoted string specifying the default file extension for the output
file. Unless the output file name was specified from the command line,
assembler will use this extension when generating the output file.

\index{USE16, USE32, USE64}
\verb"use16" and \verb"use32" directives force the assembler to generate 16--bit or
32--bit code, omitting the default setting for selected output format. \verb"use64"
enables generating the code for the long mode of x86--64 processors.

Below are described different output formats with the directives
specific to these formats.

\subsection{MZ executable}
To select the MZ output format, use \verb"format MZ" directive. The default
code setting for this format is 16--bit.

\index{SEGMENT}
\verb"segment" directive defines a new segment, it should be followed by
label, which value will be the number of defined segment, optionally
\verb"use16" or \verb"use32" word can follow to specify whether code in this
segment should be 16--bit or 32--bit. The origin of segment is aligned to
paragraph (16 bytes). All the labels defined then will have values relative
to the beginning of this segment.

\index{ENTRY}
\verb"entry" directive sets the entry point for MZ executable, it should be
followed by the far address (name of segment, colon and the offset inside
segment) of desired entry point.

\index{STACK}
\verb"stack" directive sets up the stack for MZ executable. It can be
followed by numerical expression specifying the size of stack to be created
automatically or by the far address of initial stack frame when you want to
set up the stack manually. When no stack is defined, the stack of default
size 4096 bytes will be created.

\index{HEAP}
\verb"heap" directive should be followed by a 16--bit value defining maximum
size of additional heap in paragraphs (this is heap in addition to stack and
undefined data). Use \verb"heap 0" to always allocate only memory program
really needs. Default size of heap is 65535.

\subsection{Portable Executable}
To select the Portable Executable output format, use \verb"format PE" directive,
it can be followed by additional format settings: first the target subsystem
setting, which can be \verb"console" or \verb"GUI" for Windows applications, \verb"native"
for Windows drivers, \verb"EFI", \verb"EFIboot" or \verb"EFIruntime" for the UEFI, it may be
followed by the minimum version of system that the executable is targeted to
(specified in form of floating-point value). Optional \verb"DLL" and \verb"WDM" keywords
mark the output file as a dynamic link library and WDM driver respectively,
and the \verb"large" keyword marks the executable as able to handle addresses
larger than 2 GB.

After those settings can follow the \verb"at" operator and the numerical expression
specifying the base of PE image and then optionally \verb"on" operator followed by
the quoted string containing file name selects custom MZ stub for PE program
(when specified file is not a MZ executable, it is treated as a flat binary
executable file and converted into MZ format). The default code setting for
this format is 32--bit. The example of fully featured PE format declaration:
\begin{verbatim}
    format PE GUI 4.0 DLL at 7000000h on 'stub.exe'
\end{verbatim}

To create PE file for the x86--64 architecture, use \verb"PE64" keyword instead of
\verb"PE" in the format declaration, in such case the long mode code is generated
by default.

\index{SECTION}
\verb"section" directive defines a new section, it should be
followed by quoted string defining the name of section, then one
or more section flags can follow. Available flags are:
\verb"code", \verb"data", \verb"readable", \verb"writeable",
\verb"executable", \verb"shareable", \verb"discardable",
\verb"notpageable". The origin of section is aligned to page (4096
bytes). Example declaration of PE section:
\begin{verbatim}
    section '.text' code readable executable
\end{verbatim}
Among with flags also on of special PE data identifiers can be
specified to mark the whole section as a special data, possible
identifiers are \verb"export", \verb"import", \verb"resource" and
\verb"fixups". If the section is marked to contain fixups, they
are generated automatically and no more data needs to be defined
in this section. Also resource data can be generated automatically
from the resource file, it can be achieved by writing the
\verb"from" operator and quoted file name after the
\verb"resource" identifier. Below are the examples of sections
containing some special PE data:
\begin{verbatim}
    section '.reloc' data readable discardable fixups
    section '.rsrc' data readable resource from 'my.res'
\end{verbatim}

\index{ENTRY}
\verb"entry" directive sets the entry point for Portable Executable, the
value of entry point should follow.

\index{STACK}
\verb"stack" directive sets up the size of stack for Portable Executable,
value of stack reserve size should follow, optionally value of stack commit
separated with comma can follow. When stack is not defined, it's set by
default to size of 4096 bytes.

\index{HEAP}
\verb"heap" directive chooses the size of heap for Portable Executable, value
of heap reserve size should follow, optionally value of heap commit separated
with comma can follow. When no heap is defined, it is set by default to size
of 65536 bytes, when size of heap commit is unspecified, it is by default set
to zero.

\index{DATA}\index{END}
\verb"data" directive begins the definition of special PE data, it should be
followed by one of the data identifiers (\verb"export", \verb"import",
\verb"resource" or \verb"fixups") or by the number of data entry in PE
header. The data should be defined in next lines, ended with \verb"end data"
directive. When fixups data definition is chosen, they are generated
automatically and no more data needs to be defined there.
The same applies to the resource data when the \verb"resource"
identifier is followed by \verb"from" operator and quoted file name --
in such case data is  taken from the given resource file.

The \verb"rva" operator can be used inside the numerical expressions to obtain
the RVA of the item addressed by the value it is applied to, that is the
offset relative to the base of PE image.

\subsection{Common Object File Format}
To select Common Object File Format, use \verb"format COFF" or \verb"format MS COFF"
directive, depending whether you want to create classic (DJGPP) or Microsoft's
variant of COFF file. The default code setting for this format is 32-bit. To
create the file in Microsoft's COFF format for the x86-64 architecture, use
\verb"format MS64 COFF" setting, in such case long mode code is generated by
default.

\index{SECTION}
\verb"section" directive defines a new section, it should be followed by
quoted string defining the name of section, then one or more section flags
can follow. Section flags available for both COFF variants are \verb"code" and \verb"data",
while flags \verb"readable", \verb"writeable", \verb"executable", \verb"shareable", \verb"discardable",
\verb"notpageable", \verb"linkremove" and \verb"linkinfo" are available only with
Microsoft's COFF variant.

By default section is aligned
to double word (four bytes), in case of Microsoft COFF variant other alignment
can be specified by providing the \verb"align" operator followed by alignment value
(any power of two up to 8192) among the section flags.

\index{EXTRN}
\verb"extrn" directive defines the external symbol, it should be
followed by the name of symbol and optionally the size operator
specifying the size of data labeled by this symbol. The name of
symbol can be also preceded by quoted string containing name of
the external symbol and the \verb"as" operator. Some example
declarations of external symbols:
\begin{verbatim}
    extrn exit
    extrn '__imp__MessageBoxA@16' as MessageBox:dword
\end{verbatim}

\index{PUBLIC}
\verb"public" directive declares the existing symbol as public, it
should be followed by the name of symbol, optionally it can be
followed by the \verb"as" operator and the quoted string
containing name under which symbol should be available as public.
Some examples of public symbols declarations:
\begin{verbatim}
    public main
    public start as '_start'
\end{verbatim}
Additionally, with COFF format it's possible to specify exported symbol as
static, it's done by preceding the name of symbol with the \verb"static" keyword.

When using the Microsoft's COFF format, the \verb"rva" operator can be used
inside the numerical expressions to obtain the RVA of the item addressed by the
value it is applied to.


\subsection{Executable and Linkable Format}
To select ELF output format, use \verb"format ELF" directive. The default code
setting for this format is 32--bit. To create ELF file for the x86--64
architecture, use \verb"format ELF64" directive, in such case the long mode code is
generated by default.

\index{SECTION}
\verb"section" directive defines a new section, it should be followed by quoted
string defining the name of section, then can follow one or both of the
\verb"executable" and \verb"writeable" flags, optionally also \verb"align" operator
followed by the number specifying the alignment of section (it has to be the power of
two), if no alignment is specified, the default value is used, which is 4 or 8,
depending on which format variant has been chosen.

\index{EXTRN}\index{PUBLIC}
\verb"extrn" and \verb"public" directives have the same meaning and syntax as
when the COFF output format is selected (described in previous section).

The  \verb"rva" operator can be used also in the case of this format (however not
when target architecture is x86--64), it converts the address into the offset
relative to the GOT table, so it may be useful to create position-independent
code. There's also a special \verb"plt" operator, which allows to call the external
functions through the Procedure Linkage Table. You can even create an alias
for external function that will make it always be called through PLT, with
the code like:
\begin{verbatim}
    extrn 'printf' as _printf
    printf = PLT _printf
\end{verbatim}

To create executable file, follow the format choice directive with the \verb"executable" keyword
and optionally the number specifying the brand of the target operating system
(for example value 3 would mark the executable for Linux systems).
With this format selected it is allowed to use \verb"entry" directive followed by the value to set as entry
point of program. On the other hand it makes \verb"extrn" and
\verb"public" directives unavailable, and instead of \verb"section" there should be the
\verb"segment" directive used, followed by one or
more segment permission flags and optionally a marker of special ELF
executable segment, which can be \verb"interpreter", \verb"dynamic" or \verb"note".
The origin of segment is aligned to page (4096 bytes), and available
permission flags are: \verb"readable", \verb"writeable" and \verb"executable".


\chapter{Windows programming}
With the Windows version of flat assembler comes the package of
standard includes designed to help in writing the programs for
Windows environment.

The includes package contains the headers for 32--bit and 64--bit Windows
programming in the root folder and the specialized includes in the
subfolders. In general, the headers include the required
specialized files for you, though sometimes you might prefer to
include some of the macroinstruction packages yourself (since few
of them are not included by some or even all of the headers).

There are six headers for 32--bit Windows that you can choose from, with names
starting with \verb"win32" followed by either a letter \verb"a"
for using the ASCII encoding, or a letter \verb"w" for the
WideChar encoding. The \verb"win32a.inc" and \verb"win32w.inc" are
the basic headers, the \verb"win32ax.inc" and \verb"win32wx.inc"
are the extended headers, they provide more advanced
macroinstructions, those extensions will be discussed separately.
Finally the \verb"win32axp.inc" and \verb"win32wxp.inc" are the
same extended headers with enabled feature of checking the count
of parameters in procedure calls.

There are analogous six packages for the 64--bit Windows, with
names starting with \verb"win64". They provide in general the
same functionality as the ones for 32--bit Windows, with just a few
differences explained later.

You can include the headers any way you prefer, by providing the
full path or using the custom environment variable, but the
simplest method is to define the \verb"INCLUDE" environment
variable properly pointing to the directory containing headers and
then include them just like:
\begin{verbatim}
  include 'win32a.inc'
\end{verbatim}

It's important to note that all macroinstructions, as opposed to
internal directives of flat assembler, are case sensitive and the
lower case is used for the most of them. If you'd prefer to use
the other case than default, you should do the appropriate
adjustments with \verb"fix" directive.

\section{Basic headers}
The basic headers \verb"win32a.inc", \verb"win32w.inc",
\verb"win64a.inc" and \verb"win64w.inc" include
the declarations of Windows equates and structures and provide the
standard set of macroinstructions.

\subsection{Structures}
All headers enable the \verb"struct" macroinstruction, which
allows to define structures in a way more similar to other
assemblers than the \verb"struc" directive. The definition of
structure should be started with \verb"struct" macroinstruction
followed by the name, and ended with \verb"ends" macroinstruction.
In lines between only data definition directives are allowed, with
labels being the pure names for the fields of structure:
\begin{verbatim}
  struct POINT
    x dd ?
    y dd ?
  ends
\end{verbatim}
With such definition this line:
\begin{verbatim}
  point1 POINT
\end{verbatim}
will declare the \verb"point1" structure with the \verb"point1.x"
and \verb"point1.y" fields, giving them the default values -- the
same ones as provided in the definition of structure (in this case
the defaults are both uninitialized values). But declaration of
structure also accepts the parameters, in the same count as the
number of fields in the structure, and those parameters, when
specified, override the default values for fields. For example:
\begin{verbatim}
  point2 POINT 10,20
\end{verbatim}
initializes the \verb"point2.x" field with value 10, and the
\verb"point2.y" with value 20.

The \verb"struct" macro not only enables to declare the structures
of given type, but also defines labels for offsets of fields
inside the structure and constants for sized of every field and
the whole structure. For example the above definition of
\verb"POINT" structure defines the \verb"POINT.x" and
\verb"POINT.y" labels to be the offsets of fields inside the
structure, and \verb"sizeof.POINT.x", \verb"sizeof.POINT.y" and
\verb"sizeof.POINT" as sizes of the corresponding fields and of
the whole structure. The offset labels may be used for accessing
the structures addressed indirectly, like:
\begin{verbatim}
  mov eax,[ebx+POINT.x]
\end{verbatim}
when the \verb"ebx" register contains the pointer to \verb"POINT"
structure. Note that field size checking will be performed with
such accessing as well.

The structures itself are also allowed inside the structure
definitions, so the structures may have some other structures as a
fields:
\begin{verbatim}
  struct LINE
    start POINT
    end   POINT
  ends
\end{verbatim}
When no default values for substructure fields are specified, as
in this example, the defaults from the definition of the type of
substructure apply.

Since value for each field is a single parameter in the
declaration of the structure, to initialize the substructures with
custom values the parameters for each substructure must be grouped
into a single parameter for the structure:
\begin{verbatim}
  line1 LINE <0,0>,<100,100>
\end{verbatim}
This declaration initializes each of the \verb"line1.start.x" and
\verb"line1.start.y" fields with 0, and each of the
\verb"line1.end.x" and \verb"line1.end.y" with 100.

When the size of data defined by some value passed to the
declaration structure is smaller than the size of corresponding
field, it is padded to that size with undefined bytes (and when it
is larger, the error happens). For example:
\begin{verbatim}
  struct FOO
    data db 256 dup (?)
  ends

  some FOO <"ABC",0>
\end{verbatim}
fills the first four bytes of \verb"some.data" with defined values
and reserves the rest.

Inside the structures also unions and unnamed substructures can be
defined. The definition of union should start with \verb"union"
and end with \verb"ends", like in this example:
\begin{verbatim}
  struct BAR
    field_1 dd ?
    union
      field_2  dd ?
      field_2b db ?
    ends
  ends
\end{verbatim}
Each of the fields defined inside union has the same offset and
they share the same memory. Only the first field of union is
initialized with given value, the values for the rest of fields
are ignored (however if one of the other fields requires more
memory than the first one, the union is padded to the required
size with undefined bytes). The whole union is initialized by the
single parameter given in structure declaration, and this
parameter gives value to the first field of union.

The unnamed substructure is defined in a similar way to the union,
only starts with the \verb"struct" line instead of \verb"union",
like:
\begin{verbatim}
  struct WBB
    word dw ?
    struct
      byte1 db ?
      byte2 db ?
    ends
  ends
\end{verbatim}
Such substructure only takes one parameter in the declaration of
whole structure to define its values, and this parameter can
itself be the group of parameters defining each field of the
substructure. So the above type of structure may get declared
like:
\begin{verbatim}
  my WBB 1,<2,3>
\end{verbatim}
The fields inside unions and unnamed substructures are accessed
just as if the were directly the fields of the parent structure.
For example with above declaration \verb"my.byte1" and
\verb"my.byte2" are correct labels for the substructure fields.

The substructures and unions can be nested with no limits for the
nesting depth:
\begin{verbatim}
  struct LINE
    union
      start POINT
      struct
        x1  dd ?
        y1  dd ?
      ends
    ends
    union
      end   POINT
      struct
        x2  dd ?
        y2  dd ?
      ends
    ends
  ends
\end{verbatim}

The definition of structure may also be based on some of the
already defined structure types and it inherits all the fields
from that structure, for example:
\begin{verbatim}
  struct CPOINT POINT
    color dd ?
  ends
\end{verbatim}
defines the same structure as:
\begin{verbatim}
  struct CPOINT
    x     dd ?
    y     dd ?
    color dd ?
  ends
\end{verbatim}

All headers define the \verb"CHAR" data type, which can be used to
define character strings in the data structures.

\subsection{Imports}
The import macroinstructions help to build the import data for PE
file (usually put in the separate section). There are two
macroinstructions for this purpose. The first one is called
\verb"library", must be placed directly in the beginning of the
import data and it defines from what libraries  the functions will
be imported. It should be followed by any amount of the pairs of
parameters, each pair being the label for the table of imports
from the given library, and the quoted string defining the name of
the library. For example:
\begin{verbatim}
  library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL'
\end{verbatim}
declares to import from the two libraries. For each of libraries,
the table of imports must be then declared somewhere inside the
import data. This is done with \verb"import" macroinstruction,
which needs first parameter to define the label for the table (the
same as declared earlier to the \verb"library" macro), and then
the pairs of parameters each containing the label for imported
pointer and the quoted string defining the name of function
exactly as exported by library. For example the above
\verb"library" declaration may be completed with following
\verb"import" declarations:
\begin{verbatim}
  import kernel32,\
         ExitProcess,'ExitProcess'

  import user32,\
         MessageBeep,'MessageBeep',\
         MessageBox,'MessageBoxA'
\end{verbatim}
The labels defined by first parameters in each pair passed to the
\verb"import" macro address the double word pointers, which after
loading the PE are filled with the addresses to exported
procedures.

Instead of quoted string for the name of procedure to import, the
number may be given to define import by ordinal, like:
\begin{verbatim}
  import custom,\
         ByName,'FunctionName',\
         ByOrdinal,17
\end{verbatim}

The import macros optimize the import data, so only imports for
functions that are used somewhere in program are placed in the
import tables, and if some import table would be empty this way,
the whole library is not referenced at all. For this reason it's
handy to have the complete import table for each library -- the
package contains such tables for some of the standard libraries,
they are stored in the \verb"APIA" and \verb"APIW" subdirectories
and import the ASCII and WideChar variants of the API functions.
Each file contains one import table, with lowercase label the same
as the name of the file. So the complete tables for importing from
the \verb"KERNEL32.DLL" and \verb"USER32.DLL" libraries can be
defined this way (assuming your \verb"INCLUDE" environment
variable points to the directory containing the includes package):
\begin{verbatim}
  library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL'

  include 'apia\kernel32.inc'
  include 'apiw\user32.inc'
\end{verbatim}

\subsection{Procedures (32--bit)}
Headers for 32--bit Windows provide four macroinstructions for calling procedures with
parameters passed on stack. The \verb"stdcall" calls directly the
procedure specified by the first argument using the STDCALL
calling convention. The rest of arguments passed to macro define
the parameters to procedure and are stored on the stack in reverse
order. The \verb"invoke" macro does the same, however it calls the
procedure indirectly, through the pointer labelled by the first
argument. Thus \verb"invoke" can be used to call the procedures
through pointers defined in the import tables. This line:
\begin{verbatim}
  invoke MessageBox,0,szText,szCaption,MB_OK
\end{verbatim}
is equivalent to:
\begin{verbatim}
  stdcall [MessageBox],0,szText,szCaption,MB_OK
\end{verbatim}
and they both generate this code:
\begin{verbatim}
  push MB_OK
  push szCaption
  push szText
  push 0
  call [MessageBox]
\end{verbatim}

The \verb"ccall" and \verb"cinvoke" are analogous to the
\verb"stdcall" and \verb"invoke", but they should be used to call
the procedures that use the C calling convention, where the stack
frame has to be restored by the caller.

To define the procedure that uses the stack for parameters and
local variables, you should use the \verb"proc" macroinstruction.
In its simplest form it has to be followed by the name for the
procedure and then names for the all the parameters it takes,
like:
\begin{verbatim}
  proc WindowProc,hwnd,wmsg,wparam,lparam
\end{verbatim}
The comma between the name of procedure and the first parameter is
optional. The procedure instructions should follow in the next
lines, ended with the \verb"endp" macroinstruction. The stack
frame is set up automatically on the entry to procedure, the EBP
register is used as a base to access the parameters, so you should
avoid using this register for other purposes. The names specified
for the parameters are used to define EBP-based labels, which you
can use to access the parameters as regular variables. For example
the \verb"mov eax,[hwnd]" instruction inside the procedure defined
as in above sample, is equivalent to \verb"mov eax,[ebp+8]". The
scope of those labels is limited to the procedure, so you may use
the same names for other purposes outside the given procedure.

Since any parameters are pushed on the stack as double words when
calling such procedures, the labels for parameters are defined to
mark the double word data by default, however you can you specify
the sizes for the parameters if you want, by following the name of
parameter with colon and the size operator. The previous sample
can be rewritten this way, which is again equivalent:
\begin{verbatim}
  proc WindowProc,hwnd:DWORD,wmsg:DWORD,wparam:DWORD,lparam:DWORD
\end{verbatim}
If you specify a size smaller than double word, the given label
applies to the smaller portion of the whole double word stored on
stack. If you you specify a larger size, like far pointer of quad
word, the two double word parameters are defined to hold this
value, but are labelled as one variable.

The name of procedure can be also followed by either the
\verb"stdcall" or \verb"c" keyword to define the calling
convention it uses. When no such type is specified, the default is
used, which is equivalent to STDCALL. Then also the \verb"uses"
keyword may follow, and after it the list of registers (separated
only with spaces) that will be automatically stored on entry to
procedure and restored on exit. In this case the comma after the
list of registers and before the first parameter is required. So
the fully featured procedure statement might look like this:
\begin{verbatim}
  proc WindowProc stdcall uses ebx esi edi,\
       hwnd:DWORD,wmsg:DWORD,wparam:DWORD,lparam:DWORD
\end{verbatim}

To declare the local variable you can use the \verb"local"
macroinstruction, followed by one or more declarations separated
with commas, each one consisting of the name for variable followed
by colon and the type of variable -- either one of the standard
types (must be upper case) or the name of data structure. For
example:
\begin{verbatim}
  local hDC:DWORD,rc:RECT
\end{verbatim}
To declare a local array, you can follow the name of variable by
the size of array enclosed in square brackets, like:
\begin{verbatim}
  local str[256]:BYTE
\end{verbatim}
The other way to define the local variables is to declare them
inside the block started with "locals" macroinstruction and ended
with "endl", in this case they can be defined just like regular
data. This declaration is the equivalent of the earlier sample:
\begin{verbatim}
  locals
    hDC dd ?
    rc RECT
  endl
\end{verbatim}
The local variables can be declared anywhere inside the procedure,
with the only limitation that they have to be declared before they
are used. The scope of labels for the variables defined as local
is limited to inside the procedure, you can use the same names for
other purposes outside the procedure. If you give some initialized
values to the variables declared as local, the macroinstruction
generates the instructions that will initialize these variables
with the given values and puts these instruction at the same
position in procedure, where the declaration is placed.

The \verb"ret" placed anywhere inside the procedure, generates the
complete code needed to correctly exit the procedure, restoring
the stack frame and the registers used by procedure. If you need
to generate the raw return instruction, use the \verb"retn"
mnemonic, or follow the \verb"ret" with the number parameter, what
also causes it to be interpreted as single instruction.

To recapitulate, the complete definition of procedure may look
like this:
\begin{verbatim}
  proc WindowProc uses ebx esi edi,hwnd,wmsg,wparam,lparam
    local hDC:DWORD,rc:RECT
    ; the instructions
    ret
  endp
\end{verbatim}

\subsection{Procedures (64--bit)}

In 64--bit Windows there is only one calling convention, and thus only two macroinstructions for calling procedures are provided.
The \verb"fastcall" calls directly the procedure specified by the first argument using the standard convention of 64--bit Windows system.
The \verb"invoke" macro does the same, but indirectly, through the pointer labelled by the first argument.
Parameters are provided by the arguments that follow, and they can be of any size up to 64 bits.
The macroinstructions use RAX register as a temporary storage when some parameter value cannot be copied directly into the stack using the
\verb"mov" instruction. If the parameter is preceded with \verb"addr" word, it is treated as an address and is
calculated with the \verb"lea" instruction -- so if the address is absolute, it will get calculated as RIP-relative,
thus preventing generating a relocation in case of file with fixups.

Because in 64--bit Windows the floating--point parameters are passed in a different way, they have to be marked by preceding each one of them
with \verb"float" word. They can be either double word or quad word in size.
Here is an example of calling some OpenGL procedures with either double--precision or single--precision parameters:
\begin{verbatim}
  invoke glVertex3d,float 0.6,float -0.6,float 0.0
  invoke glVertex2f,float dword 0.1,float dword 0.2
\end{verbatim}

The stack space for parameters are allocated before each call and freed immediately after it.
However it is possible to allocate this space just once for all the calls inside some given block of code,
for this purpose there are \verb"frame" and \verb"endf" macros provided. They should be used to enclose a block,
inside which the RSP register is not altered between the procedure calls and they prevent each call from allocating
stack space for parameters, as it is reserved just once by the \verb"frame" macro and then freed at the end by the \verb"endf" macro.
\begin{verbatim}
  frame ; allocate stack space just once
    invoke TranslateMessage,msg
    invoke DispatchMessage,msg
  endf
\end{verbatim}
The \verb"proc" macro for 64--bit Windows has the same syntax and features as 32--bit one (though \verb"stdcall" and \verb"c" options are of no use in its case).
It should be noted however that in the calling convention used in 64--bit Windows first four parameters are passed in registers (RCX, RDX, R8 and R9),
and therefore, even though there is a space reserved for them at the stack and it is labelled with name provided in the procedure definition,
those four parameters will not initially reside there. They should be accessed by directly reading the registers. But if those registers are
needed to be used for some other purpose, it is recommended to store the value of such parameter into the memory cell reserved for it.
The beginning of such procedure may look like:
\begin{verbatim}
  proc WindowProc hwnd,wmsg,wparam,lparam
    mov [hwnd],rcx
    mov [wmsg],edx
    mov [wparam],r8
    mov [lparam],r9
    ; now registers can be used for other purpose
    ; and parameters can still be accessed later
\end{verbatim}

\subsection{Customizing procedures}
It is possible to create a custom code for procedure framework when using \verb"proc" macroinstruction.
There are three symbolic variables, \verb"prologue@proc", \verb"epilogue@proc" and \verb"close@proc",
which define the names of macroinstructions that \verb"proc" calls upon entry to the procedure,
return from procedure (created with \verb"ret" macro) and at the end of procedure (made with \verb"endp" macro).
Those variables can be re--defined to point to some other macroinstructions, so that all the code
generated with \verb"proc" macro can be customized.

Each of those three macroinstructions takes five parameters.
The first one provides a label of procedure entry point, which is the name of procedure aswell.
The second one is a bitfield containing some flags, notably the bit 4 is set when the caller is supposed to restore the stack, and cleared otherwise.
The third one is a value that specifies the number of bytes that parameters to the procedure take on the stack.
The fourth one is a value that specified the number of bytes that should be reserved for the local variables.
Finally, the fifth an last parameter is the list of comma--separated registers, which procedure declared to be used
and which should therefore be saved by prologue and restored by epilogue.

The prologue macro apart from generating code that would set up the stack frame and the pointer to local variables
has to define two symbolic variables, \verb"parmbase@proc" and \verb"localbase@proc".
The first one should provide the base address for where the parameters reside, and the second
one should provide the address for where the local variables reside -- usually relative to
EBP/RBP register, but it is possible to use other bases if it can be ensured that those pointers
will be valid at any point inside the procedure where parameters or local variables are accessed.
It is also up to the prologue macro to make any alignments necessary for valid procedure implementation;
the size of local variables provided as fourth parameter may itself be not aligned at all.

The default behavior of \verb"proc" is defined by \verb"prologuedef" and \verb"epiloguedef" macros
(in default case there is no need for closing macro, so the \verb"close@proc" has an empty value).
If it is needed to return to the defaults after some customizations were used, it should be done
with the following three lines:
\begin{verbatim}
  prologue@proc equ prologuedef
  epilogue@proc equ epiloguedef
  close@proc equ
\end{verbatim}

As an example of modified prologue, below is the macroinstruction that implements stack-probing prologue for
32--bit Windows. Such method of allocation should be used every time the area of local variables may
get larger than 4096 bytes.
\begin{verbatim}
  macro sp_prologue procname,flag,parmbytes,localbytes,reglist
  { local loc
    loc = (localbytes+3) and (not 3)
    parmbase@proc equ ebp+8
    localbase@proc equ ebp-loc
    if parmbytes | localbytes
     push ebp
     mov ebp,esp
     if localbytes
      repeat localbytes shr 12
       mov byte [esp-%*4096],0
      end repeat
      sub esp,loc
     end if
    end if
    irps reg, reglist \{ push reg \} }

  prologue@proc equ sp_prologue
\end{verbatim}
It can be easily modified to use any other stack probing method of the programmer's preference.

The 64--bit headers provide an additional set of prologue/epilogue macros, which allow to define
procedure that uses RSP to access parameters and local variables (so RBP register is free to use for any other by procedure)
and also allocates the common space for all the procedure calls made inside, so that \verb"fastcall"
or \verb"invoke" macros called do not need to allocate any stack space themselves. It is an effect
similar to the one obtained by putting the code inside the procedure into \verb"frame" block, but in
this case the allocation of stack space for procedure calls is merged with the allocation of space
for local variables. The code inside such procedure must not alter RSP register in any way.
To switch to this behavior of 64--bit \verb"proc", use the following instructions:
\begin{verbatim}
  prologue@proc equ static_rsp_prologue
  epilogue@proc equ static_rsp_epilogue
  close@proc equ static_rsp_close
\end{verbatim}


\subsection{Exports}
The \verb"export" macroinstruction constructs the export data for
the PE file (it should be either placed in the section marked as
export, or within the \verb"data export" block. The first argument
should be quoted string defining the name of library file, and the
rest should be any number of pairs of arguments, first in each
pair being the name of procedure defined somewhere inside the
source, and the second being the quoted string containing the name
under which this procedure should be exported by the library. This
sample:
\begin{verbatim}
  export 'MYLIB.DLL',\
         MyStart,'Start',\
         MyStop,'Stop'
\end{verbatim}
defines the table exporting two functions, which are defined under
the names \verb"MyStart" and \verb"MyStop" in the sources, but
will be exported by library under the shorter names. The
macroinstruction take care of the alphabetical sorting of the
table, which is required by PE format.

\subsection{Component Object Model}
The \verb"interface" macro allows to declare the interface of the
COM object type, the first parameter is the name of interface, and
then the consecutive names of the methods should follow, like in
this example:
\begin{verbatim}
  interface ITaskBarList,\
             QueryInterface,\
             AddRef,\
             Release,\
             HrInit,\
             AddTab,\
             DeleteTab,\
             ActivateTab,\
             SetActiveAlt
\end{verbatim}

The \verb"comcall" macro may be then used to call the method of
the given object. The first parameter to this macro should be the
handle to object, the second one should be name of COM interface
implemented by this object, and then the name of method and
parameters to this method. For example:
\begin{verbatim}
  comcall ebx,ITaskBarList,ActivateTab,[hwnd]
\end{verbatim}
uses the contents of EBX register as a handle to COM object with
the \verb"ITaskBarList" interface, and calls the
\verb"ActivateTab" method of this object with the \verb"[hwnd]"
parameter.

You can also use the name of COM interface in the same way as the
name of data structure, to define the variable that will hold the
handle to object of given type:
\begin{verbatim}
  ShellTaskBar ITaskBarList
\end{verbatim}
The above line defines the variable, in which the
handle to COM object can be stored. After storing there the handle
to an object, its methods can be called with the \verb"cominvk".
This macro needs only the name of the variable with assigned
interface and the name of method as first two parameters, and then
parameters for the method. So the \verb"ActivateTab" method of
object whose handle is stored in the \verb"ShellTaskBar" variable
as defined above can be called this way:
\begin{verbatim}
  cominvk ShellTaskBar,ActivateTab,[hwnd]
\end{verbatim}
which does the same as:
\begin{verbatim}
  comcall [ShellTaskBar],ITaskBarList,ActivateTab,[hwnd]
\end{verbatim}

\subsection{Resources}
There are two ways to create resources, one is to include the
external resource file created with some other program, and the
other one is to create resource section manually. The latter
method, though doesn't need any additional program to be involved,
is more laborious, but the standard headers provide the assistance
-- the set of elementary macroinstructions that serve as bricks to
compose the resource section.

The \verb"directory" macroinstruction must be placed directly in
the beginning of manually built resource data and it defines what
types of resources it contains. It should be followed by the pairs
of values, the first one in each pair being the identifier of the
type of resource, and the second one the label of subdirectory of
the resources of given type. It may look like this:
\begin{verbatim}
  directory RT_MENU,menus,\
            RT_ICON,icons,\
            RT_GROUP_ICON,group_icons
\end{verbatim}

The subdirectories can be placed anywhere in the resource area
after the main directory, and they have to be defined with the
\verb"resource" macroinstruction, which requires first parameter
to be the label of the subdirectory (corresponding to the entry in
main directory) followed by the trios of parameters -- in each
such entry the first parameter defines the identifier of resource
(this value is freely chosen by the programmer and is then used to
access the given resource from the program), the second specifies
the language and the third one is the label of resource. Standard
equates should be used to create language identifiers. For example
the subdirectory of menus may be defined this way:
\begin{verbatim}
  resource menus,\
           1,LANG_ENGLISH+SUBLANG_DEFAULT,main_menu,\
           2,LANG_ENGLISH+SUBLANG_DEFAULT,other_menu
\end{verbatim}
If the resource is of kind for which the language doesn't matter,
the language identifier \verb"LANG_NEUTRAL" should be used. To define the
resources of various types there are specialized
macroinstructions, which should be placed inside the resource
area.

The bitmaps are the resources with \verb"RT_BITMAP" type
identifier. To define the bitmap resource use the \verb"bitmap"
macroinstruction with the first parameter being the label of
resource (corresponding to the entry in the subdirectory of
bitmaps) and the second being the quoted string containing the
path to the bitmap file, like:
\begin{verbatim}
  bitmap program_logo,'logo.bmp'
\end{verbatim}

The are two resource types related to icons, the
\verb"RT_GROUP_ICON" is the type for the resource, which has to be
linked to one or more resources of \verb"RT_ICON" type, each one
containing single image. This allows to declare images of
different sizes and color depths under the common resource
identifier. This identifier, given to the resource of
\verb"RT_GROUP_ICON" type may be then passed to the
\verb"LoadIcon" function, and it will choose the image of suitable
dimensions from the group. To define the icon, use the \verb"icon"
macroinstruction, with first parameter being the label of
\verb"RT_GROUP_ICON" resource, followed by the pairs of parameters
declaring the images. First parameter in each pair should be the
label of \verb"RT_ICON" resource, and the second one the quoted
string containing the path to the icon file. In the simplest
variant, when group of icon contains just one image, it will look
like:
\begin{verbatim}
  icon main_icon,icon_data,'main.ico'
\end{verbatim}
where the \verb"main_icon" is the label for entry in resource
subdirectory for \verb"RT_GROUP_ICON" type, and the
\verb"icon_data" is the label for entry of \verb"RT_ICON" type.

The cursors are defined in a way similar to icons,
with the \verb"RT_GROUP_CURSOR" and \verb"RT_CURSOR" types and the
\verb"cursor" macro, which takes parameters analogous to those
taken by \verb"icon" macro. So the definition of cursor may look
like this:
\begin{verbatim}
  cursor my_cursor,cursor_data,'my.cur'
\end{verbatim}

The menus have the \verb"RT_MENU" type of resource and are defined
with the \verb"menu" macroinstruction followed by few others
defining the items inside the menu. The \verb"menu" itself takes
only one parameter -- the label of resource. The \verb"menuitem"
defines the item in the menu, it takes up to five parameters, but
only two are required -- the first one is the quoted string
containing the text for the item, and the second one is the
identifier value (which is the value that will be returned when
user selects the given item from the menu). The
\verb"menuseparator" defines a separator in the menu and doesn't
require any parameters.

The optional third parameter of \verb"menuitem" specifies the menu
resource flags. There are two such flags available --
\verb"MFR_END" is the flag for the last item in the given menu,
and the \verb"MFR_POPUP" marks that the given item is the submenu,
and the following items will be items composing that submenu until
the item with \verb"MFR_END" flag is found. The \verb"MFR_END"
flag can be also given as the parameter to the
\verb"menuseparator" and is the only parameter this
macroinstruction can take. For the menu definition to be complete,
every submenu must be closed by the item with \verb"MFR_END" flag,
and the whole menu must also be closed this way. Here is an
example of complete definition of the menu:
\begin{verbatim}
  menu main_menu
       menuitem '&File',100,MFR_POPUP
                menuitem '&New',101
                menuseparator
                menuitem 'E&xit',109,MFR_END
       menuitem '&Help',900,MFR_POPUP + MFR_END
                menuitem '&About...',901,MFR_END
\end{verbatim}

The optional fourth parameter of \verb"menuitem" specifies the
state flags for the given item, these flags are the same as the
ones used by API functions, like \verb"MFS_CHECKED" or
\verb"MFS_DISABLED". Similarly, the fifth parameter can specify
the type flags. For example this will define item checked with a
radio--button mark:
\begin{verbatim}
  menuitem 'Selection',102, ,MFS_CHECKED,MFT_RADIOCHECK
\end{verbatim}

The dialog boxes have the \verb"RT_DIALOG" type of resource and
are defined with the \verb"dialog" macroinstruction followed by
any number of items defined with \verb"dialogitem" ended with the
\verb"enddialog".

The \verb"dialog" can take up to eleven parameters, first seven
being required. First parameter, as usual, specifies the label of
resource, second is the quoted string containing the title of the
dialog box, the next four parameters specify the horizontal and
vertical coordinates, the width and the height of the dialog box
window respectively. The seventh parameter specifies the style
flags for the dialog box window, the optional eighth one specifies
the extended style flags. The ninth parameter can specify the menu
for window -- it should be the identifier of menu resource, the
same as one specified in the subdirectory of resources with
\verb"RT_MENU" type. Finally the tenth and eleventh parameter can
be used to define the font for the dialog box -- first of them
should be the quoted string containing the name of font, and the
latter one the number defining the size of font. When these
optional parameters are not specified, the default MS Sans Serif
of size 8 is used.

This example shows the \verb"dialog" macroinstruction with all the
parameters except for the menu (which is left with blank value),
the optional ones are in the second line:
\begin{verbatim}
  dialog about,'About',50,50,200,100,WS_CAPTION+WS_SYSMENU,\
               WS_EX_TOPMOST, ,'Times New Roman',10
\end{verbatim}

The \verb"dialogitem" has eight required parameters and one
optional. First parameter should be the quoted string containing
the class name for the item. Second parameter can be either the
quoted string containing text for the item, or resource identifier
in case when the contents of item has to be defined by some
additional resource (like the item of \verb"STATIC" class with the
\verb"SS_BITMAP" style). The third parameter is the identifier for
the item, used to identify the item by the API functions. Next
four parameters specify the horizontal, vertical coordinates, the
width and height of the item respectively. The eighth parameter
specifies the style for the item, and the optional ninth specifies
the extended style flags. An example dialog item definition:
\begin{verbatim}
  dialogitem 'BUTTON','OK',IDOK,8,8,45,15,WS_VISIBLE+WS_TABSTOP
\end{verbatim}
And an example of static item containing bitmap, assuming that
there exists a bitmap resource of identifier 7:
\begin{verbatim}
  dialogitem 'STATIC',7,0,10,50,50,20,WS_VISIBLE+SS_BITMAP
\end{verbatim}

The definition of dialog resource can contain any amount of items
or none at all, and it should be always ended with
\verb"enddialog" macroinstruction.

The resources of type \verb"RT_ACCELERATOR" are created with
\verb"accelerator" macroinstruction. After first parameter
traditionally being the label of resource, there should follow the
trios of parameters -- the accelerator flags followed by the
virtual key code or ASCII character and the identifier value
(which is like the identifier of the menu item). A simple
accelerator definition may look like this:
\begin{verbatim}
  accelerator main_keys,\
              FVIRTKEY+FNOINVERT,VK_F1,901,\
              FVIRTKEY+FNOINVERT,VK_F10,109
\end{verbatim}

The version information is the resource of type \verb"RT_VERSION"
and is created with the \verb"versioninfo" macroinstruction. After the
label of the resource, the second parameter specifies the
operating system of PE file (usually it should be
\verb"VOS__WINDOWS32"), third parameter the type of file (the most
common are \verb"VFT_APP" for program and \verb"VFT_DLL" for
library), fourth the subtype (usually \verb"VFT2_UNKNOWN"), fifth
the language identifier, sixth the code page and then the quoted
string parameters, being the pairs of property name and
corresponding value. The simplest version information can be
defined like:
\begin{verbatim}
  versioninfo vinfo,VOS__WINDOWS32,VFT_APP,VFT2_UNKNOWN,\
                    LANG_ENGLISH+SUBLANG_DEFAULT,0,\
              'FileDescription','Description of program',\
              'LegalCopyright','Copyright et cetera',\
              'FileVersion','1.0',\
              'ProductVersion','1.0'
\end{verbatim}

Other kinds of resources may be defined with \verb"resdata"
macroinstruction, which takes only one parameter -- the label of
resource, and can be followed by any instructions defining the
data, ended with \verb"endres" macroinstruction, like:
\begin{verbatim}
  resdata manifest
    file 'manifest.xml'
  endres
\end{verbatim}

\subsection{Text encoding}
The resource macroinstructions use the \verb"du" directive to
define any Unicode strings inside resources -- since this
directive simply zero extends the characters to the 16--bit
values, for the strings containing some non--ASCII characters, the
\verb"du" may need to be redefined. For some of the encodings the
macroinstructions redefining the \verb"du" to generate the Unicode
texts properly are provided in the \verb"ENCODING" subdirectory.
For example if the source text is encoded with Windows 1250 code
page, such line should be put somewhere in the beginning of the
source:
\begin{verbatim}
  include 'encoding\win1250.inc'
\end{verbatim}

\section{Extended headers}
The files \verb"win32ax.inc", \verb"win32wx.inc", \verb"win64ax.inc" and \verb"win64wx.inc"
provide all the functionality of base headers and include a few
more features involving more complex macroinstructions. Also if no
PE format is declared before including the extended headers, the
headers declare it automatically. The files \verb"win32axp.inc",
\verb"win32wxp.inc", \verb"win64axp.inc" and \verb"win64wxp.inc"
are the variants of extended headers which
additionally perform checking the count of parameters to procedure
calls.

\subsection{Procedure parameters}
With the extended headers the macroinstructions for calling
procedures allow more types of parameters than just the double
word values as with basic headers. First of all, when the quoted
string is passes as a parameter to procedure, it is used to define
string data placed among the code, and passes to procedure the
double word pointer to this string. This allows to easily define
the strings that don't have to be re-used, just in the line
calling the procedure that requires pointers to those strings,
like:
\begin{verbatim}
  invoke MessageBox,HWND_DESKTOP,"Message","Caption",MB_OK
\end{verbatim}
If the parameter is the group containing some values separated
with commas, it is treated in the same way as simple quoted string
parameter.

If the parameter is preceded by the \verb"addr" word, it means
that this value is an address and this address should
be passed to procedure, even if it cannot be done directly -- like
in the case of local variables, which have addresses relative to
EBP/RBP register. In 32--bit case the EDX register is used temporarily to
calculate the value of address and pass it to the procedure. For
example:
\begin{verbatim}
  invoke RegisterClass,addr wc
\end{verbatim}
in case when the \verb"wc" is the local variable with address
\verb"ebp-100h", will generate this sequence of instructions:
\begin{verbatim}
  lea edx,[ebp-100h]
  push edx
  call [RegisterClass]
\end{verbatim}
However when the given address is not relative to any register, it
is stored directly.

In 64--bit case the \verb"addr" prefix is allowed even when only standard
headers are used, as it can be useful even in case of the regular addresses,
because it enforces RIP-relative address calculation.

With 32--bit headers, if the parameter is preceded by the word \verb"double", it is
treated as 64--bit value and passed to the procedure as two
32--bit parameters. For example:
\begin{verbatim}
  invoke glColor3d,double 1.0,double 0.1,double 0.1
\end{verbatim}
will pass the three 64--bit parameters as six double words to
procedure. If the parameter following \verb"double" is the memory
operand, it should not have size operator, the \verb"double"
already works as the size override.

Finally, the calls to procedures can be nested, that is call to
one procedure may be used as the parameter to another. In such
case the value returned in EAX/RAX by the nested procedure is passed
as the parameter to the procedure which it is nested in. A sample
of such nesting:
\begin{verbatim}
  invoke MessageBox,<invoke GetTopWindow,[hwnd]>,\
                    "Message","Caption",MB_OK
\end{verbatim}
There are no limits for the depth of nesting the procedure calls.

\subsection{Structuring the source}
The extended headers enable some macroinstructions that help with
easy structuring the program. The \verb".data" and \verb".code"
are just the shortcuts to the declarations of sections for data
and for the code. The \verb".end" macroinstruction should be put
at the end of program, with one parameter specifying the entry
point of program, and it also automatically generates the import
section using all the standard import tables. In 64--bit Windows
the \verb".end" automatically aligns the stack on 16 bytes
boundary.

The \verb".if" macroinstruction generates a piece of code that
checks for some simple condition at the execution time, and
depending on the result continues execution of following block or
skips it. The block should be ended with \verb".endif", but
earlier also \verb".elseif" macroinstruction might be used to
begin the code that will be executed under some additional
condition, when the previous were not met, and the \verb".else" as
the last before \verb".endif" to begin the block that will be
executed when all the conditions were false.

The condition can be specified by using comparison operator -- one of the \verb"=",
\verb"<", \verb">", \verb"<=", \verb">=", and \verb"<>" -- between the two
values, first of which must be either register or memory operand.
The values are compared as unsigned ones, unless the comparison expression is preceded by the word \verb"signed".
If you provide only single value as a condition, it will be tested to be zero,
and the condition will be true only if it's not. For example:
\begin{verbatim}
  .if eax
    ret
  .endif
\end{verbatim}
generates the instructions, which skip over the \verb"ret" when the EAX is zero.

There are also some special symbols recognized as conditions: the \verb"ZERO?" is true when the ZF flag is set,
in the same way the \verb"CARRY?", \verb"SIGN?", \verb"OVERFLOW?" and \verb"PARITY?" correspond to the state of CF, SF, OF and PF flags.

The simple conditions like above can be composed into complex conditional expressions
using the \verb"&", \verb"|" operators for conjunction and alternative, the \verb"~" operator for negation, and parenthesis. For example:
\begin{verbatim}
  .if eax<=100 & ( ecx | edx )
    inc ebx
  .endif
\end{verbatim}
will generate the compare and jump instructions that will cause the given block to get executed only when EAX is below or
equal 100 and at the same time at least one of the ECX and EDX is not zero.

The \verb".while" macroinstruction generates the instructions that
will repeat executing the given block (ended with \verb".endw"
macroinstruction) as long as the condition is true. The condition
should follow the \verb".while" and can be specified in the same
way as for the \verb".if". The pair of \verb".repeat" and
\verb".until" macroinstructions define the block that will be
repeatedly executed until the given condition will be met -- this
time the condition should follow the \verb".until"
macroinstruction, placed at the end of block, like:
\begin{verbatim}
  .repeat
    add ecx,2
  .until ecx>100
\end{verbatim}

\end{document}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted doc/source/_images/AliasFastChange.png.

cannot compute difference between binary files

Deleted doc/source/_images/AliasesDlg.png.

cannot compute difference between binary files

Deleted doc/source/_images/CodeCompletion.png.

cannot compute difference between binary files

Deleted doc/source/_images/CrossReference.png.

cannot compute difference between binary files

Deleted doc/source/_images/EmbededHelp.png.

cannot compute difference between binary files

Deleted doc/source/_images/ProcArgumentsHint.png.

cannot compute difference between binary files

Deleted doc/source/_images/ProjectOptions.png.

cannot compute difference between binary files

Deleted doc/source/_images/debug.gif.

cannot compute difference between binary files

Deleted doc/source/_images/error.gif.

cannot compute difference between binary files

Deleted doc/source/_images/fastswitch.png.

cannot compute difference between binary files

Deleted doc/source/_images/find.gif.

cannot compute difference between binary files

Deleted doc/source/_images/goto.png.

cannot compute difference between binary files

Deleted doc/source/_images/information.gif.

cannot compute difference between binary files

Deleted doc/source/_images/warning.gif.

cannot compute difference between binary files

Deleted doc/source/clean.bat.

1
2
3
4
5
6
7
8
del *.hhc
del *.hhk
del *.hhp
del *.tid
del *.tms
del *.html
del *.chm
del *.htm
<
<
<
<
<
<
<
<
















Deleted doc/source/clean.sh.

1
2
3
4
5
6
7
8
9
#!/usr/bin/env bash
rm *.hhc
rm *.hhk
rm *.hhp
rm *.tid
rm *.tms
rm *.htm
rm *.html
rm *.chm
<
<
<
<
<
<
<
<
<


















Deleted doc/source/compile.bat.

1
2
3
tools\tth -w1 -zhelp.css FASM.TEX 
tools\FreshHelp.exe -x FASM.tid FASM.html 0_advanced_setup.txt 1_tips.txt 2_FreshLibDoc.txt
tools\chmcmd project.hhp
<
<
<






Deleted doc/source/compile.sh.

1
2
3
4
#!/usr/bin/env bash
tools/tth -w1 -zhelp.css FASM.TEX 
tools/FreshHelp -x FASM.tid FASM.html 0_advanced_setup.txt 1_tips.txt 2_FreshLibDoc.txt
tools/chmcmd project.hhp
<
<
<
<








Deleted doc/source/help.css.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/* Common layout styles                                 */
/* They will define the common web site appearance      */

body {
   font-family: Verdana, Helvetica, sans-serif;
   font-size: 10pt;
   background-color: #fffff0;
}

/* Styles for the article formating. */

table {
   border-left-width: 0px;
   border-top-width: 0px;
   border-right-width: 0px;
   border-bottom-width: 0px;

   border-style: solid;
   border-color: #606060;
   background-color: white;
   border-collapse: collapse;
   margin: auto;
}


table td {
   font-size: 10pt;
   border-right-width: 1px;
   border-bottom-width: 1px;
   border-left-width: 1px;
   border-top-width: 1px;

   border-style: solid;
   border-color: #606060;
   padding-left: 4px;
   padding-right: 4px;
   padding-top: 1px;
   padding-bottom: 1px;
   margin: 0px;
}


h1 {
   color: black;
   font-size: 13pt;
   text-align: center;
}


h2 {
  font-size: 11pt;
  margin-top: 20pt;
  margin-bottom: 10pt;
  text-align: left;
}

h3 {
  font-size: 10pt;
  margin-top: 20pt;
  margin-bottom: 10pt;
  text-align: left;
}

h4 {
  font-size: 9pt;
  margin-top: 10pt;
  margin-bottom: 8pt;
  text-align: left;
}


p {
   text-align: justify;
   font-size: 10pt;
   margin-top: 0.75em;
   margin-bottom: 0.75em;
}


p.uli {
  display: list-item;
  list-style: disc inside;
}


code, tt {
  font-family: "Courier New", monospace;
  font-size: 10pt;
  font-weight: bold;

  padding: 0px 3px 0px 3px;
  text-indent: 0px;
  display: inline;
  white-space: nowrap;
}


div.code {
  padding: 1em;
  margin: 0.5em;

  font-family: "Courier New", monospace;
  font-size: 10pt;
  font-weight: bold;

  overflow: auto;
  max-height: 30em;
  max-width: 150%;
  white-space: pre;

  background-color: white;
  border: 2px solid gray;
}


img.txt {
  margin-left:auto;
  margin-right: auto;
  display: block;
  clear: both;
  max-width: 100%;
}


div.bq {
  border: 0px solid #808080;
  padding: 1em;
  padding-left: 2em;
  margin: 0.5em;

  background-color: #f8f8f8;
  opacity: 0.7;
  filter:alpha(opacity=70);

  -webkit-box-shadow: 3px 3px 5px #808080;
  -moz-box-shadow: 3px 3px 5px #808080;
  box-shadow: 3px 3px 5px #808080;

  clear: both;
}

/* Article anchors content */
a.a:before {
 text-decoration: none;
 display: inline-block;
 overflow: hidden;
 content: url(images/anchor.gif);
 vertical-align: middle;
}


hr {
 margin-top: 1em;
 margin-bottom: 1em;
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































Deleted doc/source/tools/FreshHelp.

cannot compute difference between binary files

Deleted doc/source/tools/FreshHelp.exe.

cannot compute difference between binary files

Deleted doc/source/tools/chmcmd.

cannot compute difference between binary files

Deleted doc/source/tools/chmcmd.exe.

cannot compute difference between binary files

Deleted doc/source/tools/tth.

cannot compute difference between binary files

Deleted doc/source/tools/tth.exe.

cannot compute difference between binary files

Deleted examples/Arrays/Arrays.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
include '%lib%/freshlib.inc'

@BinaryType console

include '%lib%/freshlib.asm'

; Topic: Complex data structures in FASM
;   subtopic: Easy way to create initialized arrays of structures in FASM.
;
;       This example was written, because this is one of most common
;    questions on FASM message board. Sometimes it is problem even for
;    expirianced assembly programmers using other assemblers. Actually it is
;    not so hard to create not only arrays but even more complex data structures
;    as linked lists or trees, using so powerfull macro system of FASM.
;
;       I will refrain from using very complex macroses, because it is not
;    very useful for beginers to use them, even using ready for use libraries.
;    IMHO, it is better for every beginer to understand what actually happen and
;    then to begin to use complex macro libaries with full understanding.
;
;       Actually structures in FASM are almost same thing as macroses.
;    Only difference is that structures need label before it, but macro does
;    not need it.
;
;      There are two aspects in the "arrays" problem: "definition" and "using".
;    I will try to explain both aspects on the simple example.
;    Let we need some array with points and then we need some procedure that will
;    draw poliline from the first point to the last point of the array.
;    Indication for end of the array will be the point with negative x coordinate.
;
;    At first we will define base point structure, because we will need it when we
;    want to access defined data:

struct TPoint
  .x dd ?
  .y dd ?
ends

;    Then we will define macro for definition of initialized array.
macro PointArray [x, y] {
  forward  ; This means that following rows will be repeated for every set of arguments
    dd x
    dd y
  common
    dd -1  ; This will define one dword with content -1 at the end of the array.
}


iglobal

; Ok, we have the macro definitions, let's define an array:
MyArray:
        PointArray                      \
          100, 100,                     \
          200, 100,                     \
          200, 200,                     \
          100, 200,                     \
          100, 100,                     \
          150, 130,                     \
          200, 100

cMessage:
         db 'Look at upper left side of the console. There you can see', 13
         db 'black wireframe figure like "envelope".',13, 13, 13
         db 'This is example how to create and use initialized arrays in FASM.',13
         db 'author: John Found', 13, 0
endg


start:
        invoke  GetConsoleWindow
        invoke  GetDC, eax
        mov     edi, eax

        invoke  Rectangle, edi, 0, 0, 300, 300

; And here the program will make some draw on the surface of the application console.
; I make it this way to keep additional code as small as possible.

        mov     esi, MyArray
        invoke  MoveToEx, edi, [esi+TPoint.x], [esi+TPoint.y], NULL   ; first point
        add     esi, sizeof.TPoint

.drawloop:
        cmp    [esi+TPoint.x], -1
        je     .enddraw

        invoke  LineTo, edi, [esi+TPoint.x], [esi+TPoint.y]
        add     esi, sizeof.TPoint
        jmp     .drawloop

.enddraw:
        invoke  ReleaseDC, edi
        invoke  MessageBoxA, NULL, cMessage, NULL, MB_OK or MB_ICONINFORMATION
        invoke  ExitProcess, 0



@AllImportSection
@AllDataSection

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































Deleted examples/Arrays/Arrays.fpr.

cannot compute difference between binary files

Deleted examples/CharCount/CharCount.fpr.

cannot compute difference between binary files

Deleted examples/CharCount/Main.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
include '%lib%/freshlib.inc'

@BinaryType GUI

uses gdi32

LIB_MODE equ old

include '%lib%/freshlib.asm'

include '%finc%/libs/msgutils.inc'
include '%finc%/libs/templates.inc'
include '%finc%/libs/TForm.inc'
include '%finc%/libs/parents.inc'

include '%finc%/libs/msgutils.asm'
include '%finc%/libs/templates.asm'
include '%finc%/libs/TForm.asm'
include '%finc%/libs/parents.asm'


include 'MainForm.frm'

uglobal
  hMainForm dd ?
  hInstance dd ?
endg

start:
        invoke  GetModuleHandleA, 0
        mov     [hInstance], eax

        InitializeAll

        call    RegisterFormClass
        stdcall CreateForm, frmMainForm, NULL
        mov     [hMainForm],ebx

include '%finc%/libs/mainloop.asm'

        push    eax
        FinalizeAll
        invoke  ExitProcess


@AllImportSection
@AllDataSection




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































Deleted examples/CharCount/MainForm.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
;<ff
Window frmMainForm, 3, 5, 'TForm', 'Character count (pure assembly program)', $160F0000, $10001, 0, 229, 191, 320, 238, frmMainWinProc;
Window NONE, 0, 3, 'STATIC', '', $50000200, $200, 2, 0, 0, 312, 21, 0;
Window NONE, 2, 5, 'EDIT', '', $50280104, $200, 100, 0, 21, 312, 190, multiEditProc;
;ff>

;-----------------------------------------------------------------------
; Window procedure for the form.
; Arguments:
;   .hwnd - handle of the window
;   .wmsg - code of the message
;   .wparam \ Parameters of the message
;   .lparam /
;-----------------------------------------------------------------------
winproc frmMainWinProc
begin
;-----------------------------------------------------------------------
; Write here the code that have to be executed before
; message dispathing.
;-----------------------------------------------------------------------
ondefault
;-----------------------------------------------------------------------
; Write here the code that have to be executed if message
; was not processed by this procedure.
;-----------------------------------------------------------------------
        stc
        return

onmessage WM_COMMAND

cLabelPrefix text 'Characters: '

        cmp     word [.wparam+2], EN_CHANGE
        jne     .ondefault
        invoke  SendDlgItemMessageA, [.hwnd], 100, WM_GETTEXTLENGTH, 0, 0
        mov     edx, eax

        stdcall StrDup, cLabelPrefix
        mov     ebx, eax
        stdcall NumToStr, edx, ntsDec or ntsUnsigned
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax

        stdcall StrPtr, ebx
        invoke  SendDlgItemMessageA, [.hwnd], 2, WM_SETTEXT, 0, eax
        stdcall StrDel, ebx
        clc
        return
endwp



winproc multiEditProc
begin

ondefault
        stc
        return

onmessage WM_GETDLGCODE
        mov     eax, DLGC_WANTARROWS or DLGC_WANTTAB or DLGC_WANTALLKEYS or DLGC_HASSETSEL or DLGC_WANTCHARS
        clc
        return
endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































Deleted examples/ELFExe/Linux.fpr.

cannot compute difference between binary files

Deleted examples/ELFExe/hello.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
format ELF executable
entry _start

segment readable executable
_start:

        mov     eax,4
        mov     ebx,1
        mov     ecx,msg
        mov     edx,msg_size
        int     $80

        mov     eax,1
        xor     ebx,ebx
        int     $80


segment readable writeable
msg db 'Hello world!',$0a
    db 'Now Fresh can run Linux ELF executables. :)', $0a
msg_size = $-msg
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































Deleted examples/ELFExe/readame.txt.

1
2
3
4
5
6
This example creates simple Hello world program for Linux.
You can run it from inside Fresh IDE, but you need to install andLinux
and configure Fresh IDE to run Linux applications in andLinux
For detailed explanation how to do it, browse to
[http://chiselapp.com/user/johnfound/repository/FreshIDE/wiki?name=Fresh+and+Linux]
or read the related chapter in "%Fresh%/doc/GreshGuide.chm"
<
<
<
<
<
<












Deleted examples/Fractal/Mandelbrod.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
format binary as "tga"

; DON'T _RUN_ this file, just COMPILE it and view it with any
; image program that supports 8-bit paletted TGA-images (many does).

; usage: "FASM MANDELDB.ASM MANDELDB.TGA"
; better keep the ".TGA"-extension, else this might confuse some lamish
; image programs.

; Some basic image properties. Feel free to modify
Width equ 80
Height equ 80
IterLim equ 256
Prec equ 29; don't set above 29 nor to low, else image may be scrambled

; TGA-header: 8-bit paletted image
dw 256,1
db 0,0,1,24
dw 0,0,Width,Height
db 8,8

; palette: 256*3bytes (RGB)
repeat 256
db (%+54h) and 0FFh
db (%+0A9h) and 0FFh
db % - 1
end repeat

; actual image (Mandelbrot fractal)
PrecScale = 1 shl (Prec-1)

StepR = (5 shl (Prec-1) +Width shr 1) / Width; = 2.5/Width
StepI = (5 shl (Prec-1) +Height shr 1) / Height; = 3/Height

PosI = -5 shl (Prec-2); = -1.25
repeat Height
PosR = -2 shl Prec; = -2
repeat Width
R = PosR
I = PosI
RR = (PosR*PosR) shr Prec
II = (PosI*PosI) shr Prec

Color = IterLim - 1; Color is also the current iteration number
repeat IterLim
if (RR + II) < 4 shl Prec
Tmp = (RR - II) + PosR
I = (R*I) / PrecScale + PosI
R = Tmp
RR = (Tmp*Tmp) shr Prec
II = (I*I) shr Prec
Color = Color - 1; discounting Color
end if
end repeat
if Color < 0
Color = 0
end if
db Color

PosR = PosR + StepR
end repeat
PosI = PosI + StepI
end repeat
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































Deleted examples/Fractal/Mandelbrod.fpr.

cannot compute difference between binary files

Deleted examples/HotButton/HotButton.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
format PE GUI 4.0
entry Start

include '%finc%\win32\win32a.inc'

include "%finc%\libs\msgutils.inc"
include "%finc%\libs\tform.inc"
include "%finc%\libs\parents.inc"
include "%finc%\libs\templates.inc"

include "%finc%\libs\msgutils.asm"
include "%finc%\libs\tform.asm"
include "%finc%\libs\parents.asm"
include "%finc%\libs\templates.asm"

include "MainForm.frm"

uglobal
  hInstance dd ?
  hHeap     dd ?
  hMainForm dd ?

;  baddata ddcdcb 1234
endg


iglobal
  cString db 'test',0
endg


Start:
        invoke  GetModuleHandleA,0
        mov     [hInstance],eax
        invoke  GetProcessHeap
        mov     [hHeap], eax

        InitializeAll

        stdcall CreateForm, frmMain, NULL
        xor     eax, eax
        test    ebx, ebx
        jz      .terminate

        mov     [hMainForm], ebx

.run:
        call    ProcessMessages
        jc      .terminate

        invoke  WaitMessage
        jmp     .run

.terminate:
        push    eax
   ;     FinalizeAll
        invoke  ExitProcess ; exit code from the stack.

data import
  include "%finc%\win32\allimports.asm"
end data

IncludeAllGlobals
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































Deleted examples/HotButton/HotButton.fpr.

cannot compute difference between binary files

Deleted examples/HotButton/MainForm.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
;<ff
Window frmMain, 3, 0, 'TForm', 'Hot button example.', $16080000, $0, 0, 223, 193, 320, 240, 0;
Window NONE, 2, 0, 'BUTTON', 'Button', $50008000, $0, 1, 40, 24, 136, 89, btnWinProc;
;ff>
btnID = 1

winproc btnWinProc
begin

ondefault
        stc
        return

onmessage WM_MOUSEMOVE

        invoke  GetCapture
        cmp     eax, [.hwnd]
        je      .captured

        invoke  SetCapture, [.hwnd]

        invoke  GetWindowLongA, [.hwnd], GWL_STYLE
        and     eax, not BS_FLAT
        invoke  SetWindowLongA, [.hwnd], GWL_STYLE, eax
        invoke  InvalidateRect, [.hwnd], 0, 0
        clc
        return

.captured:
  locals
    .rect RECT
  endl
        lea     esi, [.rect]
        invoke  GetClientRect, [.hwnd], esi

        movsx   eax, word [.lparam]
        movsx   ecx, word [.lparam+2]
        invoke  PtInRect, esi, eax, ecx
        test    eax, eax
        jz      .outside

        clc
        return

.outside:
        invoke  SetCapture, NULL
        invoke  GetWindowLongA, [.hwnd], GWL_STYLE
        or      eax, BS_FLAT
        invoke  SetWindowLongA, [.hwnd], GWL_STYLE, eax
        invoke  InvalidateRect, [.hwnd], 0, 0

        clc
        return

endwp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































Deleted examples/HotButton/README.TXT.

1
2
3
This is very simple example for creating hot buttons.


<
<
<






Deleted examples/Portable/Portable.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
; _______________________________________________________________________________________
;|                                                                                       |
;| Portable GUI application in assembler.                                                |
;|_______________________________________________________________________________________|
;
;  Description: The main file of very simple example demonstrating how to write portable
;               GUI applications using FreshLib.
;
;  Target OS: Any
;
;  Dependencies: FreshLib - see includes in the source.
;_________________________________________________________________________________________

include '%lib%/freshlib.inc'
@BinaryType GUI

include '%lib%/freshlib.asm'

options.FastEnter         = 0           ; enter/leave or push ebp/pop ebp approach to the procedures.
options.ShowSkipped       = 0           ; shows the procedures skiped because of no use.
options.ShowSizes         = 1           ; enable/disable work of DispSize macro.
options.DebugMode         = 0           ; enable/disable macroses of simpledebug library.


iglobal
  frmMainForm:
        ObjTemplate  tfParent or tfEnd, Form, frmMain, \
                     x, 100,        \
                     y, 50,         \
                     width, 320,    \
                     height, 240,   \
                     Visible, TRUE, \
                     Caption, 'FreshLib portable application.'

           ObjTemplate tfEnd, Button, btnTest,  \
                       x, 50, y, 50,            \
                       width, 128, height, 24,   \
                       Visible, TRUE,           \
                       TextAlign, dtfAlignCenter or dtfAlignMiddle, \
                       IconPosition, AlignLeft,                     \
                       OnClick, procOnClick,                        \
                       Caption, 'Do something'
endg


uglobal
  ClickCount dd ?
endg

cCaption text 'Clicked: '

proc procOnClick, .self, .button
begin
; On click handler for the button.

        inc     [ClickCount]

        stdcall NumToStr, [ClickCount], ntsDec or ntsUnsigned
        push    eax
        push    eax
        stdcall StrDup, cCaption
        stdcall StrCat, eax ; second from the stack.
        stdcall StrDel ; from the stack.
        push    eax
        stdcall Set, [btnTest], TButton.Caption, eax
        stdcall StrDel ; from the stack.

        return
endp



; Main Program
start:
        InitializeAll

        stdcall Create, CApplication
        jc      .terminate

        mov     [pApplication], ebx

        stdcall CreateFromTemplate, frmMainForm, 0
        mov     ecx, [pApplication]
        mov     [ecx+TApplication.MainWindow], frmMain

        stdcall Run

.terminate:
        push    eax
        FinalizeAll

        stdcall Terminate    ; from the stack

; end of main program

@AllImportSection
@AllDataSection

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































Deleted examples/Portable/Portable.fpr.

cannot compute difference between binary files

Deleted examples/ReadMe.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
IMPORTANT:
These examples are intended to be open and compile from this directory.
They expect that the include libraries will be located in "../../include"
and "../../freshlib/" directories.
It was made in order to ensure compilation even if Fresh IDE is not set up 
properly.
If you want to copy these projects somewhere and to play with them, you
have to edit the options of the project (Project|Project options) and to
remove "finc" and "lib" aliases from the list.

simple.asm
~~~~~~~~~~
Very simple "Hello world" Win32 GUI application, it doesn't use any
includes, so you can compile and run it with Fresh even if it is not 
configured properly.


Arrays\
~~~~~~~
  Example how to create and use initialized arrays of structures in 
FASM/Fresh.


Char count\
~~~~~~~~~~~
  Windows program that counts characters typed in edit box.


ElfExe\
~~~~~~~
  Simple "Hello world" application for Linux.
In order to run it in Fresh you need to install andLinux distribution - 
see on "www.adnlinux.org" and to set its path in Fresh IDE options.
Of course you can compile this example without using andLinux and
start it on your own Linux instalation.


Fractal\
~~~~~~~~
  Good example how powerfull is FASM compiler. This project creates 
not an executable file, but .tga image file. You can view it using 
any graphic editor/viewer.


HotButton\
~~~~~~~~~~
  Demonstrates how to create simple "Hot" buttons - i.e. the button
changes his look when the mouse pointer hovers over it.


ScrollBox\
~~~~~~~~~~
  Example how to create Windows with scrollable client area using 
standard Fresh libraries.


SEH\
~~~
  Example how to use structured exception handling libary
in assembly programs.

SQLiteExample\
~~~~~~~~~~~~~~

  Demonstrates how to use SQLite library for work with relational
databases.

VisualPad\
~~~~~~~~~~
  Simple project for Notepad like text editor, using Fresh GUI
library. Not finished, but you can use it as a example for project
created with current Fresh visual programming features.

ToolPanel\
~~~~~~~~~~

  Simple tool panel, that hides itself when not needed.
Demonstrates use of timers and how to handle mouse messages.

XLib\
~~~~
  Simple GUI application for Linux. This example is stand alone
and does not depend on Fresh include files.
  Demonstrate the use of XLib in Linux.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































Deleted examples/SEH/Main.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
include '%lib%/freshlib.inc'

@BinaryType GUI

include '%lib%/freshlib.asm'

start:
        InitializeAll

; First level of exception handling
beginTry

  ; Second level of exception handling
  beginTry

        xor     esi, esi
        mov     eax, [esi]        ; exception
        invoke  MessageBoxA, NULL, eax, NULL, MB_ICONINFORMATION or MB_OK

    onException

        ; Get the exception number
        mov     eax, [ptrExceptionRecord]
        mov     eax, [eax+EXCEPTION_RECORD.ExceptionCode]

        ; This is simply creating of the message for message box.
        ; Strictly preserve esi, edi, ebx and ebp registers
        push    ebx
        stdcall NumToStr, eax, ntsUnsigned or ntsHex
        mov     ebx, eax
        stdcall StrInsert, ebx, msgException, 0
        stdcall StrCat, ebx, msgSecond
        stdcall StrPtr, ebx
        invoke  MessageBoxA, NULL, eax, NULL, MB_ICONINFORMATION or MB_YESNO
        stdcall StrDel, ebx
        pop     ebx

        ; How to proceed? Yes means the exception will be passed to the
        ; previous exception handler - i.e. the first one.
        cmp     eax, IDYES
        jne     @f

    Next

@@:

    Ignore

  endTry

  invoke  MessageBoxA, NULL, msgAfterSecond, NULL, MB_ICONINFORMATION or MB_OK

onException

        invoke  MessageBoxA, NULL, msgFirst, NULL, MB_ICONINFORMATION or MB_YESNO
        cmp     eax, IDYES
        je      .patchesi

        Ignore

        ; Change esi register to have valid value after retry.
  .patchesi:
        mov     eax, [ptrExceptionContext]
        mov     [eax+CONTEXT.regEsi], ptrRecovered
        Retry

endTry

        FinalizeAll
        invoke  MessageBoxA, NULL, msgBeforeEnd, NULL, MB_ICONINFORMATION or MB_OK
        invoke  ExitProcess, 0

msgBeforeEnd db 'Just before termination.', 0
msgRecovered db 'Recovered. ESI have proper value now.', 0
msgSecond    db ' Second level exception handler. Do you want to pass exception to the first level handler?', 0
msgFirst     db 'First level exception handler. Do you want to fix the value of the esi register?', 0
msgAfterSecond db 'Code, after second level exception handler.', 0
msgException db 'Exception No. $', 0
ptrRecovered dd msgRecovered

@AllImportEmbeded
@AllDataEmbeded
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































Deleted examples/SEH/seh.fpr.

cannot compute difference between binary files

Deleted examples/SQLiteExample/CreateDB/DBCreate.fpr.

cannot compute difference between binary files

Deleted examples/SQLiteExample/CreateDB/MainFile.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

; Win32 Console Application

format PE Console
entry Start

include '%finc%\win32\win32a.inc'

uglobal
  hInstance dd ?
  hHeap     dd ?
  ptrDBase  dd ?
  hSQL      dd ?
  ptrDummy  dd ?

  findData  FINDDATA
  hFind     dd ?
endg

iglobal
  cDBName  db 'Pictures.sqlite', 0
  files    db '.\pictures\*.bmp', 0

  filePath db '.\pictures\'
  filename rb 100

  sqlCreateDB file 'createdb.sql'
              db 0

  sqlInsert db 'insert into Pictures (Name, Picture) values (?, ?);', 0
endg

Start:
        invoke  GetModuleHandleA,0
        mov     [hInstance],eax
        invoke  GetProcessHeap
        mov     [hHeap], eax
        InitializeAll

        ; TODO: Insert code here
        cinvoke sqliteOpen, cDBName, ptrDBase
        cinvoke sqliteExec, [ptrDBase], sqlCreateDB, NULL, NULL, NULL

        invoke  FindFirstFileA, files, findData
        cmp     eax, INVALID_HANDLE_VALUE
        je      .finish

        mov     [hFind], eax

.readloop:
        lea     esi, [findData.cFileName]
        lea     edi, [filename]
        cld
.copy:
        lodsb
        stosb
        test    al,al
        jnz     .copy

        stdcall LoadBinaryFile, filePath

        mov     esi, eax
        mov     ebx, ecx

        cinvoke sqlitePrepare, [ptrDBase], sqlInsert, -1, hSQL, ptrDummy

        cinvoke sqliteBindText, [hSQL], 1, findData.cFileName, -1, NULL
        cinvoke sqliteBindBlob, [hSQL], 2, esi, ebx, SQLITE_TRANSIENT
        cinvoke sqliteStep, [hSQL]
        cinvoke sqliteFinalize, [hSQL]

        invoke  HeapFree, [hHeap], 0, esi

        invoke  FindNextFileA, [hFind], findData
        test    eax, eax
        jnz     .readloop


.finish:
        cinvoke sqliteClose, [ptrDBase]

Exit:
        push    eax
        FinalizeAll
        invoke  ExitProcess ; exit code from the stack.


;--------------------------------------------------------------------
; Allocates needed memory and loads the entire file in this memory.
; Returns pointer to memory block or NULL if there is error.
; Returns size in ecx
;--------------------------------------------------------------------
proc LoadBinaryFile, .ptrFileName
.bytes dd ?
begin
        push    esi edi ebx

        invoke  CreateFileA, [.ptrFileName], GENERIC_READ,FILE_SHARE_READ, 0, \
                OPEN_EXISTING, 0, 0

        cmp     eax, INVALID_HANDLE_VALUE
        je      .error
        mov     edi, eax

        invoke  GetFileSize, edi, NULL
        mov     ebx, eax

        lea     ecx, [ebx+2]    ; It is for the case that the file is
                                ; text and we want to use it as null terminated
                                ; string.

        invoke  HeapAlloc, [hHeap], HEAP_ZERO_MEMORY, ecx
        mov     esi, eax
        test    esi, esi
        jz      .close

        lea     ecx, [.bytes]
        invoke  ReadFile, edi, esi, ebx, ecx, NULL

.close:
        invoke  CloseHandle, edi

        test    esi, esi
        jz      .error

        cmp     [.bytes], ebx
        je      .ok

        invoke  HeapFree, [hHeap], 0, esi

.error:
        xor     eax, eax
        xor     ecx, ecx
        pop     ebx edi esi
        return

.ok:
        mov     eax, esi
        mov     ecx, ebx
        pop     ebx edi esi
        return
endp







data import
  include '%finc%/win32/allimports.asm'
end data

IncludeAllGlobals
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































Deleted examples/SQLiteExample/CreateDB/PICTURES/Earth.bmp.

cannot compute difference between binary files

Deleted examples/SQLiteExample/CreateDB/PICTURES/Jupiter.bmp.

cannot compute difference between binary files

Deleted examples/SQLiteExample/CreateDB/PICTURES/Mars.bmp.

cannot compute difference between binary files

Deleted examples/SQLiteExample/CreateDB/PICTURES/Mercury.bmp.

cannot compute difference between binary files

Deleted examples/SQLiteExample/CreateDB/PICTURES/Neptune.bmp.

cannot compute difference between binary files

Deleted examples/SQLiteExample/CreateDB/PICTURES/Saturn.bmp.

cannot compute difference between binary files

Deleted examples/SQLiteExample/CreateDB/PICTURES/Uranus.bmp.

cannot compute difference between binary files

Deleted examples/SQLiteExample/CreateDB/PICTURES/Venus.bmp.

cannot compute difference between binary files

Deleted examples/SQLiteExample/CreateDB/PICTURES/pluto_sri.bmp.

cannot compute difference between binary files

Deleted examples/SQLiteExample/CreateDB/createdb.sql.

1
2
3
4
5
6
7
create table Pictures (
  ID integer primary key autoincrement,
  FromSun integer,
  Name    text,
  Description text,
  Picture blob
);
<
<
<
<
<
<
<














Deleted examples/SQLiteExample/CreateDB/readme.txt.

1
2
3
4
This example creates database with the images from the directory "PICTURES".
In order to run it you need the file "sqlite3.dll" that is placed one 
directory up in the tree. Simply copy it here or in some of the system 
directories, as Windows/system32 ; Windows/system ; etc.
<
<
<
<








Deleted examples/SQLiteExample/MainForm.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
;<ff
Window frmMain, 3, 0, 'TForm', 'SQLite simple example', $16080000, $10000, 0, 257, 216, 434, 312, MainFormWinProc;
Window NONE, 0, 1, 'LISTBOX', 'Listbox', $50800141, $200, 100, 0, 0, 136, 285, 0;
Window NONE, 2, 5, 'STATIC', 'Image', $5000120E, $0, 101, 136, 0, 290, 285, 0;
;ff>
idListBox = 100
idImage   = 101

idMainIcon = 2
idDefaultImage = 1

uglobal
  ptrDatabase dd ?
  hSQL        dd ?
  ptrDummy    dd ?
endg


winproc MainFormWinProc
begin

ondefault
        stc
        return

onmessage FM_AFTERCREATE
; Set main window icons
        invoke  LoadImageA, [hInstance], idMainIcon, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR
        invoke  SendMessageA, [.hwnd], WM_SETICON, ICON_SMALL, eax
        invoke  LoadImageA, [hInstance], idMainIcon, IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR
        invoke  SendMessageA, [.hwnd], WM_SETICON, ICON_BIG, eax

; set default image.
        invoke  LoadImageA, [hInstance], idDefaultImage, IMAGE_BITMAP, 0, 0, 0
        invoke  SendDlgItemMessageA, [.hwnd], idImage, STM_SETIMAGE, IMAGE_BITMAP, eax

; Open the images database
iglobal
  cDBName db 'pictures.sqlite', 0
endg
        cinvoke sqliteOpen, cDBName, ptrDatabase

; Read the list of the images in the database and fill the listbox with names and ID's of the images.
iglobal
  sqlSelectNames db 'select ID, Name from Pictures order by FromSun',0
endg
        cinvoke sqlitePrepare, [ptrDatabase], sqlSelectNames, -1, hSQL, ptrDummy
.loop:
        cinvoke sqliteStep, [hSQL]
        cmp     eax, SQLITE_ROW
        jne     .endloop

        cinvoke sqliteColumnInt, [hSQL], 0      ; ID
        mov     ebx, eax
        cinvoke sqliteColumnText, [hSQL], 1     ; Name

        invoke  SendDlgItemMessageA, [.hwnd], idListBox, LB_ADDSTRING, 0, eax
        cmp     eax, LB_ERR
        je      .loop
        invoke  SendDlgItemMessageA, [.hwnd], idListBox, LB_SETITEMDATA, eax, ebx
        jmp     .loop

.endloop:
        cinvoke sqliteFinalize, [hSQL]
        clc
        return

onmessage WM_DESTROY
        cinvoke sqliteClose, [ptrDatabase]
        xor     eax, eax
        clc
        return



onmessage WM_COMMAND
locals
  .ptrBits dd ?
endl
        cmp     word [.wparam], idListBox          ; ID of the control that sends the message.
        jne     .ondefault

        cmp     word [.wparam+2], LBN_SELCHANGE
        jne     .ondefault

; The selection in the listbox were changed, so read the image from database and assign it to
; the static control at the right (idImage)
iglobal
  sqlGetPicture  db 'select Picture from Pictures where ID = ?', 0
endg
        cinvoke sqlitePrepare, [ptrDatabase], sqlGetPicture, -1, hSQL, ptrDummy

        invoke  SendDlgItemMessageA, [.hwnd], idListBox, LB_GETCURSEL, 0, 0
        cmp     eax, LB_ERR
        je      .finalize
        invoke  SendDlgItemMessageA, [.hwnd], idListBox, LB_GETITEMDATA, eax, 0

        cinvoke sqliteBindInt, [hSQL], 1, eax
        cinvoke sqliteStep, [hSQL]

        cinvoke sqliteColumnBytes, [hSQL], 0
        mov     ebx, eax

        cinvoke sqliteColumnBlob, [hSQL], 0
        mov     esi, eax

; Here you can see how to read bitmap directly from the memory, not from resource or file...
        lea     eax, [esi+14]   ; start of the BITMAPINFOHEADER
        lea     ecx, [.ptrBits]
        invoke  CreateDIBSection, 0, eax, 0, ecx, 0, 0

        push    eax     ; store the handle in the stack for future processing...

        xor     eax, eax
        movzx   ecx, [esi+sizeof.BITMAPFILEHEADER+BITMAPINFOHEADER.biBitCount]
        cmp     ecx, 8
        ja      .paletteok

        mov     eax, 1
        add     ecx, 2  ; every palette item is 4 bytes
        shl     eax, cl

.paletteok:
        lea     esi, [esi + sizeof.BITMAPFILEHEADER + sizeof.BITMAPINFOHEADER + eax]
        lea     ecx, [ebx - sizeof.BITMAPFILEHEADER - sizeof.BITMAPINFOHEADER]
        sub     ecx, eax

        shr     ecx, 2

        mov     edi, [.ptrBits]
        rep movsd

        invoke  SendDlgItemMessageA, [.hwnd], idImage, STM_SETIMAGE, IMAGE_BITMAP ; handle from the stack
        test    eax, eax
        jz      .finalize

        invoke  DeleteObject, eax ; delete the previous selected image

.finalize:
        cinvoke sqliteFinalize, [hSQL]    ; don't forget to finalize SQL statements.
        xor     eax, eax
        clc
        return

endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































Deleted examples/SQLiteExample/Pictures.sqlite.

cannot compute difference between binary files

Deleted examples/SQLiteExample/Planets.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
format PE GUI 4.0
entry Start

include '%finc%\win32\win32a.inc'

include "%finc%\libs\msgutils.inc"
include "%finc%\libs\tform.inc"
include "%finc%\libs\parents.inc"
include "%finc%\libs\templates.inc"

include "%finc%\libs\msgutils.asm"
include "%finc%\libs\tform.asm"
include "%finc%\libs\parents.asm"
include "%finc%\libs\templates.asm"

include "MainForm.frm"

uglobal
  hInstance dd ?
  hHeap     dd ?
  hMainForm dd ?
endg

Start:
        invoke  GetModuleHandleA,0
        mov     [hInstance],eax
        invoke  GetProcessHeap
        mov     [hHeap], eax

        InitializeAll

        stdcall CreateForm, frmMain, NULL
        xor     eax, eax
        test    ebx, ebx
        jz      .terminate

        mov     [hMainForm], ebx

.run:
        call    ProcessMessages
        jc      .terminate

        invoke  WaitMessage
        jmp     .run

.terminate:
        push    eax
        FinalizeAll
        invoke  ExitProcess ; exit code from the stack.

data import
  include '%finc%/win32/allimports.asm'
end data


data resource from 'resources/planets.res'
end data

IncludeAllGlobals
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































Deleted examples/SQLiteExample/Planets.fpr.

cannot compute difference between binary files

Deleted examples/SQLiteExample/README.TXT.

1
2
3
4
5
6
7
8
9
10
11
12
13
This example demonstrates how SQLite database engine can be used in
assembly written applications.

Actually there are 2 examples - first one "DBCreate.fpr" is console
application, that creates database with images inside as a blob fields.
(I wrote it only because standard SQLite management utilities can't
handle blob fields properly)

The second one "Planets.fpr" is simple catalog of all planets from the
Solar system with pictures. There is already prepared database with the
information: "Pictures.sqlite".

Enjoy.
<
<
<
<
<
<
<
<
<
<
<
<
<


























Deleted examples/SQLiteExample/Resources/Neptune.ico.

cannot compute difference between binary files

Deleted examples/SQLiteExample/Resources/planets.res.

cannot compute difference between binary files

Deleted examples/SQLiteExample/Resources/sqlite.bmp.

cannot compute difference between binary files

Deleted examples/SQLiteExample/sqlite3.dll.

cannot compute difference between binary files

Deleted examples/ScrollBox/Main.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
format PE GUI 4.0
entry Start

include '%finc%\win32\win32a.inc'
include '%finc%\libs\msgutils.inc'
include '%finc%\libs\templates.inc'
include '%finc%\libs\TForm.inc'
include '%finc%\libs\parents.inc'

section '.code' code readable executable

include '%finc%\libs\msgutils.asm'
include '%finc%\libs\templates.asm'
include '%finc%\libs\TForm.asm'
include '%finc%\libs\parents.asm'

include 'MainForm.frm'
include '%finc%\libs\scrollbars.asm'

uglobal
  hMainForm dd ?
  hInstance dd ?
  hHeap     dd ?
endg

Start:
        invoke  GetModuleHandleA, 0
        mov     [hInstance], eax
        invoke  GetProcessHeap
        mov     [hHeap], eax

        invoke  InitCommonControls
        InitializeAll

        call    RegisterFormClass
        stdcall CreateForm, frmMainForm, NULL
        mov     [hMainForm],ebx

include '%finc%\libs\mainloop.asm'
        push    eax
        FinalizeAll
        invoke  ExitProcess


section '.idata' data import readable writeable
ImportTable:
include '%finc%\win32\allimports.asm'
DispSize 'ImportTable', $ - ImportTable

section '.data' data readable writeable
IncludeAllGlobals


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































Deleted examples/ScrollBox/MainForm.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
;<ff
Window frmMainForm, 3, 0, 'TForm', 'Scrollable client area example.', $163F0000, $0, 0, 215, 131, 372, 315, MainFormProc;
Window NONE, 0, 0, 'BUTTON', 'Launch "Far star" to Y=200000', $50002000, $0, 1001, 192, 64, 96, 41, 0;
Window NONE, 0, 0, 'BUTTON', 'Checkbox', $50000003, $0, 0, 48, 136, 80, 21, 0;
Window NONE, 0, 0, 'STATIC', 'This is little example, how to create windows with client area biger than the window size.', $50800000, $0, 0, 72, 24, 216, 32, 0;
Window NONE, 0, 0, 'EDIT', 'Textbox', $500000C4, $200, 0, 280, 128, 200, 1000, 0;
Window NONE, 0, 0, 'STATIC', 'Unfortunately, for now it is impossible to create these kind of windows in the visual editor. But this will be changed. ;)', $50000000, $0, 0, 24, 1500, 216, 48, 0;
Window NONE, 0, 0, 'EDIT', 'Go down...', $50000080, $200, 0, 40, 500, 121, 21, 0;
Window NONE, 0, 0, 'EDIT', 'Go down...', $50000080, $200, 0, 48, 700, 121, 21, 0;
Window NONE, 0, 0, 'EDIT', 'Go down...', $50000080, $200, 0, 40, 1000, 121, 21, 0;
Window NONE, 0, 0, 'STATIC', 'Left, Top', $50800001, $0, 0, 0, 0, 32, 32, 0;
Window NONE, 0, 0, 'STATIC', 'You can scroll the window client area in order to reach controls that are outside the normal client rectangle of the window.', $50800001, $0, 0, 16, 168, 216, 56, 0;
Window NONE, 2, 0, 'BUTTON', '"Far star" spaceship.', $50000000, $0, 1002, 40, 68, 144, 25, 0;
;ff>

;-----------------------------------------------------------------------
; Window procedure for the form.
; Arguments:
;   .hwnd - handle of the window
;   .wmsg - code of the message
;   .wparam \ Parameters of the message
;   .lparam /
;-----------------------------------------------------------------------
winproc MainFormProc
begin

ondefault
        stc
        return

onmessage FM_AFTERCREATE
        stdcall AutoSizeScrollers, [.hwnd]
        stdcall UpdateThumbs, [.hwnd]
        clc
        return

onmessage WM_VSCROLL
onmessage WM_HSCROLL
        stdcall ScrollBarMessage, [.hwnd], [.wmsg], [.wparam], DoCorrectChildren
        clc
        return

onmessage WM_SIZE
        stdcall UpdateThumbs, [.hwnd]
        clc
        return

onmessage WM_COMMAND
       cmp      word [.wparam], 1001
       jne      .ondefault

       invoke   GetDlgItem, [.hwnd], 1002
       invoke   SetWindowPos, eax, 0, 100, 200000, 0, 0, SWP_NOSIZE or SWP_NOZORDER
       stdcall AutoSizeScrollers, [.hwnd]
       stdcall UpdateThumbs, [.hwnd]

       clc
       return

endwp


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































Deleted examples/ScrollBox/ScrollBox.fpr.

cannot compute difference between binary files

Deleted examples/ScrollBox/Scrollbars.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
ScrollbarsLib:
;---------------------------------------------------------
; Scrollbar lib is small library that provides
; windows with client area bigger than its actual size.
;---------------------------------------------------------

;----------------------------------------------------------------------
; This procedure is handler for WM_HSCROLL and WM_VSCROLL
; messages. Call it from window message procedure passing
; the message parameters.
;----------------------------------------------------------------------
proc ScrollBarMessage, .hwnd, .wmsg, .wparam, .updateproc
.sbi SCROLLINFO
.kind dd ?
begin
        mov    eax, [.wmsg]
        sub    eax, WM_HSCROLL
        mov    [.kind], eax

        lea    edi, [.sbi]

        mov     [.sbi.cbSize], sizeof.SCROLLINFO
        mov     [.sbi.fMask], SIF_RANGE or SIF_PAGE or SIF_POS
        invoke  GetScrollInfo, [.hwnd], [.kind], edi

        movzx   ebx, word [.wparam]
        cmp     ebx, SB_THUMBTRACK
        je      .track
        cmp     ebx, SB_THUMBPOSITION
        je      .track

        cmp     ebx, SB_TOP
        je      .top
        cmp     ebx, SB_BOTTOM
        je      .bottom

        mov     edx, 1  ; multiplier down

        cmp     ebx, SB_PAGEDOWN
        je      .pageupdn
        cmp     ebx, SB_LINEDOWN
        je      .lineupdn

        mov     edx, -1  ; multiplier UP

        cmp     ebx, SB_PAGEUP
        je      .pageupdn
        cmp     ebx, SB_LINEUP
        je      .lineupdn
; Undefined command...
        return

;-----------------------------------------------------
; Handling of different actions...
;-----------------------------------------------------
.track:
        movsx   eax, word [.wparam+2]
        jmp     .setpos

.top:
        mov     eax, [.sbi.nMin]
        jmp     .setpos

.bottom:
        mov     eax, [.sbi.nMax]
        sub     eax, [.sbi.nPage]
        jmp     .setpos

.pageupdn:
        mov     eax, [.sbi.nPos]
        mov     ecx, [.sbi.nPage]
        imul    ecx, edx
        add     eax, ecx
        jmp     .setpos

.lineupdn:
        mov     eax, [.sbi.nPos]
        mov     ecx, [.sbi.nPage]
        sar     ecx, 4
        jnz     @f
        inc     ecx
@@:
        imul    ecx, edx
        add     eax, ecx

.setpos:
        mov     esi, [.sbi.nPos] ; Old scroll position.

        mov     [.sbi.nPos], eax ; New scroll position.
        mov     [.sbi.fMask], SIF_POS
        invoke  SetScrollInfo, [.hwnd], [.kind], edi, TRUE

; Update children windows positions
        mov     [.sbi.fMask], SIF_POS
        invoke  GetScrollInfo, [.hwnd], [.kind], edi ; get the position corrected by Windows

        sub     esi, [.sbi.nPos] ; correction value
        stdcall [.updateproc], [.hwnd], [.kind], esi
        return
endp



;--------------------------------------------------------------------
; Call this procedure when the window size have been changed, to
; adjust scrollbars thumbs size acordingly.
;--------------------------------------------------------------------
proc UpdateThumbs, .hwnd
.rect RECT
begin
        lea     eax, [.rect]
        invoke  GetClientRect, [.hwnd], eax
        stdcall _DoUpdateOneThumb, [.hwnd], SB_HORZ, [.rect.right]
        stdcall _DoUpdateOneThumb, [.hwnd], SB_VERT, [.rect.bottom]
        return
endp



proc _DoUpdateOneThumb, .hwnd, .kind, .size
.sbi SCROLLINFO
begin
; Get the current possition of the scrollbar.
        mov     [.sbi.cbSize], sizeof.SCROLLINFO
        mov     [.sbi.fMask], SIF_POS
        lea     eax, [.sbi]
        invoke  GetScrollInfo, [.hwnd], [.kind], eax
        mov     esi, [.sbi.nPos] ; Old position of the scrollbar

; Set the new page size of the scrollbar.
        mov     eax, [.size]
        mov     [.sbi.nPage], eax
        mov     [.sbi.fMask], SIF_PAGE
        lea     eax, [.sbi]
        invoke  SetScrollInfo, [.hwnd], [.kind], eax, TRUE

; Get again the new position, because possibly Windows changed it.
        mov     [.sbi.fMask], SIF_POS
        lea     eax, [.sbi]
        invoke  GetScrollInfo, [.hwnd], [.kind], eax

; Move the first level children acording to the new scroll position.
        sub     esi, [.sbi.nPos]  ; correction value
        jz      .finish
        stdcall DoCorrectChildren, [.hwnd], [.kind], esi
.finish:
        return
endp


proc DoCorrectChildren, .hwnd, .kind, .correct
.defer dd ?
.rect  RECT
begin
        mov     edi, [.kind]
        shl     edi, 2          ; eax = 0 if .kind = SB_HORZ (0) and eax = 4 if .kind = SB_VERT (1)
        mov     esi, [.correct]

        invoke  BeginDeferWindowPos, 10
        mov     [.defer], eax

        invoke  GetWindow, [.hwnd], GW_CHILD
.loop:
        test    eax, eax
        je      .enddefer

        mov     ebx, eax

        lea     eax, [.rect]
        invoke  GetWindowRect, ebx, eax

        lea     eax, [.rect]
        invoke  ScreenToClient, [.hwnd], eax

        add     [.rect+edi], esi
        invoke  DeferWindowPos, [.defer], ebx, 0, [.rect.left], [.rect.top], 0, 0, SWP_NOSIZE or SWP_NOZORDER
        mov     [.defer], eax

        invoke  GetWindow, ebx, GW_HWNDNEXT
        jmp     .loop

.enddefer:
        invoke  EndDeferWindowPos, [.defer]
        return
endp




proc AutoSizeScrollers, .hwnd
.sbi SCROLLINFO
.rect RECT
.maxrect RECT
begin
        mov     eax, $7fffffff
        mov     [.maxrect.left], eax
        mov     [.maxrect.top], eax
        inc     eax
        mov     [.maxrect.right], eax
        mov     [.maxrect.bottom], eax

        invoke  GetWindow, [.hwnd], GW_CHILD

.loop:
        test    eax, eax
        jz      .endloop
        mov     ebx, eax

        lea     esi, [.rect]
        invoke  GetWindowRect, ebx, esi
        invoke  ScreenToClient, [.hwnd], esi
        lea     eax, [esi+8]
        invoke  ScreenToClient, [.hwnd], eax

        mov     eax, [.rect.left]
        cmp     eax, [.maxrect.left]
        jge     @f
        mov     [.maxrect.left], eax
@@:
        mov     eax, [.rect.top]
        cmp     eax, [.maxrect.top]
        jge     @f
        mov     [.maxrect.top], eax
@@:
        mov     eax, [.rect.right]
        cmp     eax, [.maxrect.right]
        jle     @f
        mov     [.maxrect.right], eax
@@:
        mov     eax, [.rect.bottom]
        cmp     eax, [.maxrect.bottom]
        jle     @f
        mov     [.maxrect.bottom], eax
@@:
        invoke  GetWindow, ebx, GW_HWNDNEXT
        jmp     .loop

.endloop:
        mov     eax, [.maxrect.left]
        mov     ecx, [.maxrect.right]

        mov     [.sbi.nMin], 0
        mov     [.sbi.nMax], ecx
        mov     [.sbi.fMask], SIF_RANGE
        mov     [.sbi.cbSize], sizeof.SCROLLINFO
        lea     eax, [.sbi]
        invoke  SetScrollInfo, [.hwnd], SB_HORZ, eax, TRUE

        mov     eax, [.maxrect.top]
        mov     ecx, [.maxrect.bottom]

        mov     [.sbi.nMin], 0
        mov     [.sbi.nMax], ecx
        lea     eax, [.sbi]
        invoke  SetScrollInfo, [.hwnd], SB_VERT, eax, TRUE

        return
endp


DispSize 'Scrollbars library:', $-ScrollbarsLib
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































Deleted examples/Simple.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

   ; fasm example of writing 32-bit PE program using Win32 API

format PE GUI
entry start

; MessageBox type flags

MB_OK                = 0000h
MB_OKCANCEL          = 0001h
MB_ABORTRETRYIGNORE  = 0002h
MB_YESNOCANCEL       = 0003h
MB_YESNO             = 0004h
MB_RETRYCANCEL       = 0005h
MB_ICONHAND          = 0010h
MB_ICONQUESTION      = 0020h
MB_ICONEXCLAMATION   = 0030h
MB_ICONASTERISK      = 0040h
MB_DEFBUTTON1        = 0000h
MB_DEFBUTTON2        = 0100h
MB_DEFBUTTON3        = 0200h
MB_APPLMODAL         = 0000h
MB_SYSTEMMODAL       = 1000h
MB_TASKMODAL         = 2000h
MB_NOFOCUS           = 8000h

; Conventional dialog box and message box command IDs

IDOK      = 1
IDCANCEL  = 2
IDABORT   = 3
IDRETRY   = 4
IDIGNORE  = 5
IDYES     = 6
IDNO      = 7

section '.code' code readable executable

CodeSectionOrigin:

  start:
        push    MB_OK + MB_ICONEXCLAMATION
        push    _caption

        push    _message
        push    0
        call    [MessageBox]
  .local1:
        push    0
  .local2:
        call    [ExitProcess]

        jmp     .local1

section '.data' data readable writeable

DataSectionOrigin:

  _caption db 'Win32 assembly program',0
  _message db 'Hello World!',0

section '.idata' import data readable writeable

ImportSectionOrigin:

  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:
    MessageBox 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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































Deleted examples/VisualPad/Form1.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
;<ff
Window Form1, 3, 0, 'TForm', 'Simply a test', $16CF0000, $0, 0, 208, 200, 359, 240, Form1WinProc;
Window NONE, 0, 5, 'EDIT', 'You can type here.', $503010C4, $200, 1, 0, 0, 351, 197, 0;
Window NONE, 2, 4, 'STATIC', 'This form is visually created using Fresh IDE.', $50001001, $0, 2, 0, 197, 351, 16, 0;
;ff>
uglobal
  hMainForm dd ?
  hMainMenu dd ?
  hMainToolbar dd ?
endg


winproc Form1WinProc
begin

ondefault
        stc
        return

onmessage WM_COMMAND
        movzx   esi,word [.wparam]
        cmp     esi, FirstID
        jl      .ondefault

        sub     esi,FirstID
        cmp     esi,[MainActionList.Number]
        jge     .ondefault

        imul    esi,sizeof.TAction
        add     esi,MainActionList

        stdcall [esi+TAction.OnExecute], [.wparam], [.lparam]
        xor     eax, eax
        clc
        return

onmessage AM_INITWINDOW

        stdcall ImageList_LoadGif, [hInstance], resMainToolbar, 16, FALSE
        mov     [hIml], eax

        stdcall ImageList_LoadGif, [hInstance], resMainToolbar, 16, TRUE
        mov     [hImlGray],eax

        stdcall CreateCoolMenu, MainMenu, FALSE
        mov     [hMainMenu], eax
        invoke  SetMenu, [.hwnd], eax

        stdcall CreateCoolToolbar, MainActionList, MainToolbar, [.hwnd], 11, [hIml], [hImlGray]
        mov     [hMainToolbar],eax
        stdcall SetAlign, eax, waTop
;        stdcall SetAutoSize, [hMainToolbar], TRUE
        invoke  SetPropA, [hApplication], [propMainForm], [.hwnd]
        clc
        return

onmessage WM_CLOSE
        invoke  GetWindow, [.hwnd], GW_OWNER
        invoke  SendMessageA, eax, [.wmsg], [.wparam], [.lparam]
        clc
        return

onmessage WM_INITDIALOG
        clc
        return

endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































Deleted examples/VisualPad/ReadMe.txt.

1
2
3
4
    This is small Notepad like program,
created using Fresh visual design and 
Fresh graphic libraries for menues
and toolbars.
<
<
<
<








Deleted examples/VisualPad/VisualPad.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
format PE GUI 4.0
entry start

include "%finc%/win32/win32a.inc"

include '%finc%/libs/gui.inc'
include '%finc%/libs/parents.inc'
include '%finc%/libs/msgutils.inc'
include '%finc%/libs/templates.inc'
include '%finc%/libs/tform.inc'
include '%finc%/libs/application.inc'


section '.code' code readable executable

include '%finc%/libs/gui.asm'
include '%finc%/libs/parents.asm'
include '%finc%/libs/msgutils.asm'
include '%finc%/libs/templates.asm'
include '%finc%/libs/tform.asm'
include '%lib%/system/memory.asm'
include '%finc%/libs/giflib.asm'
include '%finc%/libs/application.asm'

include 'actions.asm'

include 'Form1.frm'

uglobal
  hInstance       dd 0  ; Instance handle for common use.
  hHeap           dd 0

  hIml            dd 0
  hImlGray        dd 0
endg

iglobal
  cMainTitle db 'Visual test',0
endg

resAppIcon = 1
resMainToolbar = 2

start:
        invoke  GetModuleHandleA, 0
        mov     [hInstance],eax
        invoke  GetProcessHeap
        mov     [hHeap], eax

; Init common controls
        invoke  InitCommonControls      ;Ex,ComCtrlsFlags

        InitializeAll
        stdcall InitApplication, resAppIcon, cMainTitle

        stdcall CreateForm, Form1, [hApplication]
        mov     [hMainForm], ebx

;----------------------------------------------
; Main message loop
;----------------------------------------------
Run:
        call    ProcessMessages
        jc      .terminate

        invoke  SendMessageA, [hApplication], AM_ONIDLE, 0, 0
        invoke  WaitMessage
        jmp     Run

.terminate:
        push    eax
        FinalizeAll
        invoke  ExitProcess


section '.data' data readable writeable
  data resource from 'resources/resources.res'
  end data

  IncludeAllGlobals


section '.idata' import data readable writeable
 include '%finc%/win32/allimports.asm'

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































Deleted examples/VisualPad/VisualPad.fpr.

cannot compute difference between binary files

Deleted examples/VisualPad/actions.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
ImageChecked = 8

iglobal

ActionList MainActionList, MainAccels,                                                                             \
  actNew,         0, '&New...',         <Ctrl, 'N'>,         'Creates new file.',          OnNew,               \
  actOpen,        1, '&Open',           <Ctrl, 'O'>,         'Open file',                  OnOpen,              \
  actSave,        2, '&Save',           <Ctrl, 'S'>,         'Save file',                  OnSave,              \
  actSaveAs,     -1, 'Save &As',        <NONE>,              'Save file with new name',    OnSaveAs,            \
  actExit,       -1, '&Exit',           <Alt,  'X'>,         'Exit program',               OnExit,              \
\
  actUndo,        3, '&Undo',           <Ctrl, 'Z'>,         'Undo last change',           OnUndo,              \
  actCut ,        4, 'Cu&t',            <Ctrl, 'X'>,         'Cut to clipboard',           OnCut,               \
  actCopy,        5, '&Copy',           <Ctrl, 'C'>,         'Copy to clipboard',          OnCopy,              \
  actPaste,       6, '&Paste',          <Ctrl, 'V'>,         'Paste from clipboard',       OnPaste


CoolMenu MainMenu,                      \
  mfSubmenu, '&File',                   \
    mfNormal, actNew,                   \
    mfNormal, actOpen,                  \
    mfNormal, actSave,                  \
    mfNormal, actSaveAs,                \
    mfSeparator, NONE,                  \
    mfNormal, actExit,                  \
  mfEnd, NONE,                          \
  mfSubmenu, '&Edit',                   \
    mfNormal, actUndo,                  \
    mfSeparator, NONE,                  \
    mfNormal, actCut,                   \
    mfNormal, actCopy,                  \
    mfNormal, actPaste,                 \
  mfEnd, NONE

CoolToolbar MainToolbar,                \
  bfButton, actNew,                     \
  bfButton, actOpen,                    \
  bfButton, actSave,                    \
  bfSeparator, NONE,                    \
  bfButton, actUndo,                    \
  bfSeparator, NONE,                    \
  bfButton, actCut,                     \
  bfButton, actCopy,                    \
  bfButton, actPaste

endg


proc OnNew, .wparam, .lparam
begin
        invoke  SendDlgItemMessageA, [hMainForm], 1, WM_SETTEXT, 0, 0
        return
endp

proc OnOpen, .wparam, .lparam
begin
        invoke  MessageBoxA, [hMainForm],               \
                'So, this is simply example. You have to write this action handler yourself. Check "actions.asm" to see where you should code it.', \
                'Just an example.', MB_ICONINFORMATION or MB_OK
        return
endp


proc OnSave, .wparam, .lparam
begin
        invoke  MessageBoxA, [hMainForm],               \
                'So, this is simply example. You have to write this action handler yourself. Check "actions.asm" to see where you should code it.', \
                'Just an example.', MB_ICONINFORMATION or MB_OK
        return
endp

proc OnSaveAs, .wparam, .lparam
begin
        invoke  MessageBoxA, [hMainForm],               \
                'So, this is simply example. You have to write this action handler yourself. Check "actions.asm" to see where you should code it.', \
                'Just an example.', MB_ICONINFORMATION or MB_OK
        return
endp

proc OnExit, .wparam, .lparam
begin
        invoke  MessageBoxA, [hMainForm],               \
                'So, this is simply example. You have to write this action handler yourself. Check "actions.asm" to see where you should code it.', \
                'Just an example.', MB_ICONINFORMATION or MB_OK
        return
endp

proc OnUndo, .wparam, .lparam
begin
        invoke  MessageBoxA, [hMainForm],               \
                'So, this is simply example. You have to write this action handler yourself. Check "actions.asm" to see where you should code it.', \
                'Just an example.', MB_ICONINFORMATION or MB_OK
        return
endp

proc OnCut, .wparam, .lparam
begin
        invoke  MessageBoxA, [hMainForm],               \
                'So, this is simply example. You have to write this action handler yourself. Check "actions.asm" to see where you should code it.', \
                'Just an example.', MB_ICONINFORMATION or MB_OK
        return
endp

proc OnCopy, .wparam, .lparam
begin
        invoke  MessageBoxA, [hMainForm],               \
                'So, this is simply example. You have to write this action handler yourself. Check "actions.asm" to see where you should code it.', \
                'Just an example.', MB_ICONINFORMATION or MB_OK
        return
endp

proc OnPaste, .wparam, .lparam
begin
        invoke  MessageBoxA, [hMainForm],               \
                'So, this is simply example. You have to write this action handler yourself. Check "actions.asm" to see where you should code it.', \
                'Just an example.', MB_ICONINFORMATION or MB_OK
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































Deleted examples/VisualPad/resources/minimalistic.gif.

cannot compute difference between binary files

Deleted examples/VisualPad/resources/resources.res.

cannot compute difference between binary files

Deleted examples/VisualPad/resources/turtlemini.ico.

cannot compute difference between binary files

Deleted examples/XLib/XLib.fpr.

cannot compute difference between binary files

Deleted examples/XLib/Xlib.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
format ELF executable 3
entry start

include 'linux_inc/elf_import.inc'

include 'linux_inc/_display.inc'
include 'linux_inc/_globals.inc'
include 'linux_inc/_stdcall.inc'
include 'linux_inc/_struct.inc'
include 'linux_inc/x.inc'
include 'linux_inc/geometry.inc'

segment readable executable
include 'test.asm'

segment readable writeable
IncludeAllGlobals

segment interpreter readable

include 'linux_inc/allimports.asm'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































Deleted examples/XLib/linux_inc/_display.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
iconWarning = 1
iconError = 2
iconInfo = 3
iconFind = 4
iconNone = 5
iconDebug = 6


macro __digit num
{
   if num < 10
    display '0'+num
   else
    display 'A'+num-10
   end if
}


macro __disp arg1,arg2
{
   if arg2 eq
    display arg1
   else
    local ..tmp
    ..tmp = arg1
    virtual at 0
     repeat 32
      if ..tmp > 0
       db ..tmp mod arg2
       ..tmp = ..tmp / arg2
      end if
     end repeat
     repeat $
      load ..tmp byte from $-%
      __digit ..tmp
     end repeat
     if $ = 0
      display '0'
     end if
    end virtual
   end if
}

macro disp [arg] { __disp arg }


macro DispSize Text, Sz {
  if defined options.ShowSizes & options.ShowSizes
    disp 3,"Sizeof [", Text, "] is: "
    if Sz>10000
      disp <Sz/1024,10>, 'K',$0d,$0a
    else
      disp <Sz,10>, ' bytes.',$0d,$0a
    end if
  end if
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































Deleted examples/XLib/linux_inc/_globals.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
;**********************************************
; Macroses for global variables handling.
; This macro library is part of Fresh project.
;
; (C)2003, 2004
;
; Authors:
;   John Found
;   Tomasz Grisztar
;
; usage:
;   1. Include this library in the begining
;      of your source file.
;   2. Use it as blocks anywhere in the source.
;        iglobal
;           somelabel dd 1234h
;           otherlabel RECT
;           lbl3       db 12h
;        endg
;
;   3. Data section must be at the end of the
;      source file. Use 'IncludeAllGlobals' to
;      really define variables.
;
;**********************************************


;------------------------------------------------------------------
; use "iglobal" for inserting initialized global data definitions.
;------------------------------------------------------------------
macro iglobal {
  IGlobals equ IGlobals,
  macro __IGlobalBlock \{
}


;-------------------------------------------------------------
; use 'uglobal' for inserting uninitialized global definitions.
; even when you define some data values, these variables
; will be stored as uninitialized data.
;-------------------------------------------------------------
macro uglobal {
  UGlobals equ UGlobals,
  macro __UGlobalBlock \{
}

; Use endg for ending iglobal and uglobal blocks.
endg fix }


macro IncludeIGlobals {
  macro IGlobals dummy, [n] \{
    __IGlobalBlock
    purge __IGlobalBlock
  \}
  match I, IGlobals \{
    I
  \}
}


macro IncludeUGlobals {
  macro UGlobals dummy, [n] \{
    \common
      \local begin, size
      begin = $
      virtual at $
    \forward
        __UGlobalBlock
        purge __UGlobalBlock
    \common
        size = $ - begin
      end virtual
      rb size
  \}
  match U, UGlobals \{
    U
  \}
}


macro CmpStr newtext, [lbl, text] {

  forward
    if newtext eq text


}



;--------------------------------------------
; Use this macro to define non duplicated
; string constants.
;
; constStr Str1, 'This is string constant'
;--------------------------------------------
macro  constStr  lbl, text {
  __StringsArray equ __StringsArray, lbl, text     ;;  add to the list
}


macro IncludeStringConstants {
  macro __StringsArray dummy, [lbls, text] \{
    forward
      if text eqtype 'A'
        align 4

        lbls db text
        sizeof.#lbls = $ - lbls
        dw 0
      else
        if text eqtype 0
          lbls = text
        end if
      end if
  \}

  match S, __StringsArray \{
    S
  \}
}




macro IncludeAllGlobals {
  local begin

  begin = $
  IncludeIGlobals
  DispSize 'Initialized data', ($ - begin)

  begin = $
  IncludeStringConstants
  DispSize 'String constants data', ($ - begin)

  begin = $
  IncludeUGlobals
  DispSize 'Uninitialized data', ($ - begin)
}




iglobal
endg

uglobal
endg
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































Deleted examples/XLib/linux_inc/_stdcall.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
;-----------------------------------------
; This file is part of Fresh standard
; macro library.
;-----------------------------------------

 INIT@CHAIN = 0


macro locals {
  local ..locsize
  locsize equ ..locsize
  virtual at ebp - ..locsize - .__info.commonframe.size
  @@:
}


macro endl {
  rb (4 - ($- @b) and 11b) and 11b
  locsize = $ - @b
  if $-@b > maxsize
    maxsize = $-@b
  end if
  end virtual
  restore locsize
}


macro err@endp { }


macro proc name, [arg] {
  common
    \err@endp

    macro err@endp \{
      end if
      Missing 'endp' or 'endwp' before the procedure.
    \}

    if ~ used name
      if defined options.ShowSkipped & options.ShowSkipped
        display 1,'Procedure skiped: ',`name, $0d, $0a
      end if
    else

  name:
    .__info.id = 1

    virtual at ebp+8
      if ~ arg eq
        forward
          arg dd ?
          if ~ defined name#arg
            ERROR! the argument `arg MUST begins with dot
          end if
        common
      end if
        .__info.argsize = $-ebp-8
    end virtual

    virtual at ebp - .__info.commonframe.size
    .__info.commonframe.begin:
}


macro begin {
      rb (4 - ($ - .__info.commonframe.begin) and 11b) and 11b
      .__info.commonframe.size = $ - .__info.commonframe.begin
    end virtual

    local ..maxsize
    maxsize equ ..maxsize
    ..maxsize = 0

    if .__info.framesize
      if defined options.FastEnter & options.FastEnter
        push ebp
        mov  ebp, esp
        sub  esp, .__info.framesize
      else
        enter .__info.framesize, 0
      end if
    else
      if .__info.argsize
        push ebp
        mov  ebp, esp
      end if
    end if
}


macro cret {
  if .__info.argsize | .__info.framesize
    if ..FastEnter
      mov   esp, ebp
      pop   ebp
    else
      leave
    end if
  end if
  retn
}


macro return {
  if .__info.argsize | .__info.framesize
    if defined options.FastEnter & options.FastEnter
      mov   esp, ebp
      pop   ebp
    else
      leave
    end if
  end if

  if .__info.argsize
    retn .__info.argsize
  else
    retn
  end if
}



macro endp {
    .__info.framesize = maxsize + .__info.commonframe.size
  end if
  restore maxsize
  purge err@endp
}



macro winproc name, [arg] {
common

  \err@endp

  macro err@endp \{
    end if
    Missing 'endp' or 'endwp' before the procedure.
  \}


  if ~ used name
    if defined options.ShowSkipped & options.ShowSkipped
      display 1,'Message procedure skiped: ',`name, $0d, $0a
    end if
  else

 name:
    .__info.id = 2

  if arg eq
    virtual at ebp+8
      .hwnd dd ?
      .wmsg dd ?
      .wparam dd ?
      .lparam dd ?
      .__info.argsize = 16
    end virtual
  else
    virtual at ebp+8
      forward
        arg dd ?
        if ~ defined name#arg
          ERROR! the argument `arg MUST begin with dot
        end if
      common
        .__info.argsize = $ - ebp - 8
    end virtual
  end if

  if .__info.argsize <> 16
    Error! The count of `name arguments MUST be 4 dwords.
  end if

  virtual at ebp - .__info.commonframe.size
  .__info.commonframe.begin:
}



macro ondefault {  ; begins procedure instructions
  common
    local ..msgcounter, ..msglist
    msgcounter equ ..msgcounter
    msglist equ ..msglist

    ..msgcounter = 0

    call JumpTo
    ..msglist:
    rd   .__info.msgcount
    dd   0

    .ondefault:
}


macro onmessage message {
  .#message:
  .#message#.__info.id = 3
  .#message#.__info.number = msgcounter / 4
     store word message at (msglist + msgcounter)
     store word ($ - msglist - msgcounter - 4 ) at (msglist + msgcounter + 2)
  msgcounter = msgcounter + 4
}


macro endwp {
    .__info.msgcount = msgcounter / 4
    .__info.framesize = maxsize + .__info.commonframe.size
  end if
  restore maxsize, msgcounter, msglist
  purge err@endp
}


macro initialize procname {
  INIT@CHAIN equ INIT@CHAIN, procname
  proc procname
}

macro finalize procname {
  FINISH@CHAIN equ FINISH@CHAIN,procname
  proc procname
}

;macro callchain dummy, [arg] {
;common
;   call dummy
;forward
;   call arg
;}

macro InitializeAll {
  macro INIT@CHAIN dummy, [n] \{
  \forward
    call n
  \}

  match I, INIT@CHAIN \{
    I
  \}
}

macro FinalizeAll {
  macro FINISH@CHAIN dummy, [n] \{
  \forward
    if n eqtype 1234
    call n
    end if
  \}

  match F, FINISH@CHAIN \{
    F
  \}
}


;*****************************************
; Call macroses
;*****************************************

macro stdcall proc, [arg] {    ; call procedure
common
  local ..argsize
  ..argsize = 0
  if ~ arg eq
reverse
    pushd arg
    ..argsize = ..argsize + 4
common
  end if
  if defined options.CheckArguments & options.CheckArguments
    if (defined proc#.__info.argsize) & (proc#.__info.argsize <> ..argsize)
      ERROR! wrong argument count for procedure call.
    end if
  end if

  call proc
}


macro invoke proc,[arg] {   ; invoke procedure (indirect)
common
  if ~ arg eq
reverse
    pushd arg
common
  end if
  call [proc]
}


macro ccall proc,[arg]                  ; call procedure in C calling convention
 { common local ..size
   ..size = 0
   reverse
   pushd arg
   ..size = ..size+4
   common
   call proc
   add esp,..size }

macro cinvoke proc,[arg]                ; invoke procedure (indirect)
 { common
    if ~ arg eq
     ccall [proc],arg
    else
     call [proc]
    end if }


;****************************************
; INT3 break point, when first = second.
;****************************************

macro BreakEq first, second {
  local .lbl
  push  eax
  mov   eax, first
  cmp   eax, second
  pop   eax
  jne   .lbl

  int3

.lbl:
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































































































Deleted examples/XLib/linux_inc/_struct.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
; structure definition helper

macro struct name {
  macro name@struct \{ name name \}
  macro size@struct \{ sizeof.#name = $ \}
  struc name \{
}


ends fix } struct_helper


macro struct_helper {
  virtual at 0
    name@struct
    size@struct
  end virtual
  purge name@struc
  purge size@struct
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted examples/XLib/linux_inc/allimports.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
_importdata:
interpreter '/lib/ld-linux.so.2'
needed 'libc.so.6', 'libX11.so.6'
import                                           \
        XActivateScreenSaver                    ,\
        XAddConnectionWatch                     ,\
        XAddExtension                           ,\
        XAddHost                                ,\
        XAddHosts                               ,\
        XAddPixel                               ,\
        XAddToExtensionList                     ,\
        XAddToSaveSet                           ,\
        XAllPlanes                              ,\
        XAllocClassHint                         ,\
        XAllocColor                             ,\
        XAllocColorCells                        ,\
        XAllocColorPlanes                       ,\
        XAllocIconSize                          ,\
        XAllocNamedColor                        ,\
        XAllocSizeHints                         ,\
        XAllocStandardColormap                  ,\
        XAllocWMHints                           ,\
        XAllowEvents                            ,\
        XAutoRepeatOff                          ,\
        XAutoRepeatOn                           ,\
        XBaseFontNameListOfFontSet              ,\
        XBell                                   ,\
        XBitmapBitOrder                         ,\
        XBitmapPad                              ,\
        XBitmapUnit                             ,\
        XBlackPixel                             ,\
        XBlackPixelOfScreen                     ,\
        XCellsOfScreen                          ,\
        XChangeActivePointerGrab                ,\
        XChangeGC                               ,\
        XChangeKeyboardControl                  ,\
        XChangeKeyboardMapping                  ,\
        XChangePointerControl                   ,\
        XChangeProperty                         ,\
        XChangeSaveSet                          ,\
        XChangeWindowAttributes                 ,\
        XCheckIfEvent                           ,\
        XCheckMaskEvent                         ,\
        XCheckTypedEvent                        ,\
        XCheckTypedWindowEvent                  ,\
        XCheckWindowEvent                       ,\
        XCirculateSubwindows                    ,\
        XCirculateSubwindowsDown                ,\
        XCirculateSubwindowsUp                  ,\
        XClearArea                              ,\
        XClearWindow                            ,\
        XClipBox                                ,\
        XCloseDisplay                           ,\
        XCloseIM                                ,\
        XCloseOM                                ,\
        XConfigureWindow                        ,\
        XConnectionNumber                       ,\
        XContextDependentDrawing                ,\
        XContextualDrawing                      ,\
        XConvertCase                            ,\
        XConvertSelection                       ,\
        XCopyArea                               ,\
        XCopyColormapAndFree                    ,\
        XCopyGC                                 ,\
        XCopyPlane                              ,\
        XCreateBitmapFromData                   ,\
        XCreateColormap                         ,\
        XCreateFontCursor                       ,\
        XCreateFontSet                          ,\
        XCreateGC                               ,\
        XCreateGlyphCursor                      ,\
        XCreateIC                               ,\
        XCreateImage                            ,\
        XCreateOC                               ,\
        XCreatePixmap                           ,\
        XCreatePixmapCursor                     ,\
        XCreatePixmapFromBitmapData             ,\
        XCreateRegion                           ,\
        XCreateSimpleWindow                     ,\
        XCreateWindow                           ,\
        XDefaultColormap                        ,\
        XDefaultColormapOfScreen                ,\
        XDefaultDepth                           ,\
        XDefaultDepthOfScreen                   ,\
        XDefaultGC                              ,\
        XDefaultGCOfScreen                      ,\
        XDefaultRootWindow                      ,\
        XDefaultScreen                          ,\
        XDefaultScreenOfDisplay                 ,\
        XDefaultString                          ,\
        XDefaultVisual                          ,\
        XDefaultVisualOfScreen                  ,\
        XDefineCursor                           ,\
        XDeleteContext                          ,\
        XDeleteModifiermapEntry                 ,\
        XDeleteProperty                         ,\
        XDestroyIC                              ,\
        XDestroyImage                           ,\
        XDestroyOC                              ,\
        XDestroyRegion                          ,\
        XDestroySubwindows                      ,\
        XDestroyWindow                          ,\
        XDirectionalDependentDrawing            ,\
        XDisableAccessControl                   ,\
        XDisplayCells                           ,\
        XDisplayHeight                          ,\
        XDisplayHeightMM                        ,\
        XDisplayKeycodes                        ,\
        XDisplayMotionBufferSize                ,\
        XDisplayName                            ,\
        XDisplayOfIM                            ,\
        XDisplayOfOM                            ,\
        XDisplayOfScreen                        ,\
        XDisplayPlanes                          ,\
        XDisplayString                          ,\
        XDisplayWidth                           ,\
        XDisplayWidthMM                         ,\
        XDoesBackingStore                       ,\
        XDoesSaveUnders                         ,\
        XDrawArc                                ,\
        XDrawArcs                               ,\
        XDrawImageString                        ,\
        XDrawImageString16                      ,\
        XDrawLine                               ,\
        XDrawLines                              ,\
        XDrawPoint                              ,\
        XDrawPoints                             ,\
        XDrawRectangle                          ,\
        XDrawRectangles                         ,\
        XDrawSegments                           ,\
        XDrawString                             ,\
        XDrawString16                           ,\
        XDrawText                               ,\
        XDrawText16                             ,\
        XEHeadOfExtensionList                   ,\
        XESetBeforeFlush                        ,\
        XESetCloseDisplay                       ,\
        XESetCopyGC                             ,\
        XESetCreateFont                         ,\
        XESetCreateGC                           ,\
        XESetError                              ,\
        XESetErrorString                        ,\
        XESetEventToWire                        ,\
        XESetFlushGC                            ,\
        XESetFreeFont                           ,\
        XESetFreeGC                             ,\
        XESetPrintErrorValues                   ,\
        XESetWireToError                        ,\
        XESetWireToEvent                        ,\
        XEmptyRegion                            ,\
        XEnableAccessControl                    ,\
        XEqualRegion                            ,\
        XEventMaskOfScreen                      ,\
        XEventsQueued                           ,\
        XExtendedMaxRequestSize                 ,\
        XExtentsOfFontSet                       ,\
        XFetchBuffer                            ,\
        XFetchBytes                             ,\
        XFetchName                              ,\
        XFillArc                                ,\
        XFillArcs                               ,\
        XFillPolygon                            ,\
        XFillRectangle                          ,\
        XFillRectangles                         ,\
        XFilterEvent                            ,\
        XFindContext                            ,\
        XFindOnExtensionList                    ,\
        XFlush                                  ,\
        XFlushGC                                ,\
        XFontsOfFontSet                         ,\
        XForceScreenSaver                       ,\
        XFree                                   ,\
        XFreeColormap                           ,\
        XFreeColors                             ,\
        XFreeCursor                             ,\
        XFreeExtensionList                      ,\
        XFreeFont                               ,\
        XFreeFontInfo                           ,\
        XFreeFontNames                          ,\
        XFreeFontPath                           ,\
        XFreeFontSet                            ,\
        XFreeGC                                 ,\
        XFreeModifiermap                        ,\
        XFreePixmap                             ,\
        XFreeStringList                         ,\
        XGContextFromGC                         ,\
        XGeometry                               ,\
        XGetAtomName                            ,\
        XGetAtomNames                           ,\
        XGetClassHint                           ,\
        XGetCommand                             ,\
        XGetDefault                             ,\
        XGetErrorDatabaseText                   ,\
        XGetErrorText                           ,\
        XGetFontPath                            ,\
        XGetFontProperty                        ,\
        XGetGCValues                            ,\
        XGetGeometry                            ,\
        XGetICValues                            ,\
        XGetIMValues                            ,\
        XGetIconName                            ,\
        XGetIconSizes                           ,\
        XGetImage                               ,\
        XGetInputFocus                          ,\
        XGetKeyboardControl                     ,\
        XGetKeyboardMapping                     ,\
        XGetModifierMapping                     ,\
        XGetMotionEvents                        ,\
        XGetNormalHints                         ,\
        XGetOCValues                            ,\
        XGetOMValues                            ,\
        XGetPixel                               ,\
        XGetPointerControl                      ,\
        XGetPointerMapping                      ,\
        XGetRGBColormaps                        ,\
        XGetScreenSaver                         ,\
        XGetSelectionOwner                      ,\
        XGetSizeHints                           ,\
        XGetStandardColormap                    ,\
        XGetSubImage                            ,\
        XGetTextProperty                        ,\
        XGetTransientForHint                    ,\
        XGetVisualInfo                          ,\
        XGetWMClientMachine                     ,\
        XGetWMColormapWindows                   ,\
        XGetWMHints                             ,\
        XGetWMIconName                          ,\
        XGetWMName                              ,\
        XGetWMNormalHints                       ,\
        XGetWMProtocols                         ,\
        XGetWMSizeHints                         ,\
        XGetWindowAttributes                    ,\
        XGetWindowProperty                      ,\
        XGetZoomHints                           ,\
        XGrabButton                             ,\
        XGrabKey                                ,\
        XGrabKeyboard                           ,\
        XGrabPointer                            ,\
        XGrabServer                             ,\
        XHeightMMOfScreen                       ,\
        XHeightOfScreen                         ,\
        XIMOfIC                                 ,\
        XIconifyWindow                          ,\
        XIfEvent                                ,\
        XImageByteOrder                         ,\
        XInitExtension                          ,\
        XInitImage                              ,\
        XInitThreads                            ,\
        XInsertModifiermapEntry                 ,\
        XInstallColormap                        ,\
        XInternAtom                             ,\
        XInternAtoms                            ,\
        XInternalConnectionNumbers              ,\
        XIntersectRegion                        ,\
        XKeycodeToKeysym                        ,\
        XKeysymToKeycode                        ,\
        XKeysymToString                         ,\
        XKillClient                             ,\
        XLastKnownRequestProcessed              ,\
        XListDepths                             ,\
        XListExtensions                         ,\
        XListFonts                              ,\
        XListFontsWithInfo                      ,\
        XListHosts                              ,\
        XListInstalledColormaps                 ,\
        XListPixmapFormats                      ,\
        XListProperties                         ,\
        XLoadFont                               ,\
        XLoadQueryFont                          ,\
        XLocaleOfFontSet                        ,\
        XLocaleOfIM                             ,\
        XLocaleOfOM                             ,\
        XLockDisplay                            ,\
        XLookupColor                            ,\
        XLookupKeysym                           ,\
        XLookupString                           ,\
        XLowerWindow                            ,\
        XMapRaised                              ,\
        XMapSubwindows                          ,\
        XMapWindow                              ,\
        XMaskEvent                              ,\
        XMatchVisualInfo                        ,\
        XMaxCmapsOfScreen                       ,\
        XMaxRequestSize                         ,\
        XMinCmapsOfScreen                       ,\
        XMoveResizeWindow                       ,\
        XMoveWindow                             ,\
        XNewModifiermap                         ,\
        XNextEvent                              ,\
        XNextRequest                            ,\
        XNoOp                                   ,\
        XOMOfOC                                 ,\
        XOffsetRegion                           ,\
        XOpenDisplay                            ,\
        XOpenIM                                 ,\
        XOpenOM                                 ,\
        XParseColor                             ,\
        XParseGeometry                          ,\
        XPeekEvent                              ,\
        XPeekIfEvent                            ,\
        XPending                                ,\
        XPlanesOfScreen                         ,\
        XPointInRegion                          ,\
        XPolygonRegion                          ,\
        XProcessInternalConnection              ,\
        XProtocolRevision                       ,\
        XProtocolVersion                        ,\
        XPutBackEvent                           ,\
        XPutImage                               ,\
        XPutPixel                               ,\
        XQLength                                ,\
        XQueryBestCursor                        ,\
        XQueryBestSize                          ,\
        XQueryBestStipple                       ,\
        XQueryBestTile                          ,\
        XQueryColor                             ,\
        XQueryColors                            ,\
        XQueryExtension                         ,\
        XQueryFont                              ,\
        XQueryKeymap                            ,\
        XQueryPointer                           ,\
        XQueryTextExtents                       ,\
        XQueryTextExtents16                     ,\
        XQueryTree                              ,\
        XRaiseWindow                            ,\
        XReadBitmapFile                         ,\
        XReadBitmapFileData                     ,\
        XRebindKeysym                           ,\
        XRecolorCursor                          ,\
        XReconfigureWMWindow                    ,\
        XRectInRegion                           ,\
        XRefreshKeyboardMapping                 ,\
        XRegisterIMInstantiateCallback          ,\
        XRemoveConnectionWatch                  ,\
        XRemoveFromSaveSet                      ,\
        XRemoveHost                             ,\
        XRemoveHosts                            ,\
        XReparentWindow                         ,\
        XResetScreenSaver                       ,\
        XResizeWindow                           ,\
        XResourceManagerString                  ,\
        XRestackWindows                         ,\
        XRootWindow                             ,\
        XRootWindowOfScreen                     ,\
        XRotateBuffers                          ,\
        XRotateWindowProperties                 ,\
        XSaveContext                            ,\
        XScreenCount                            ,\
        XScreenNumberOfScreen                   ,\
        XScreenOfDisplay                        ,\
        XScreenResourceString                   ,\
        XSelectInput                            ,\
        XSendEvent                              ,\
        XServerVendor                           ,\
        XSetAccessControl                       ,\
        XSetAfterFunction                       ,\
        XSetArcMode                             ,\
        XSetAuthorization                       ,\
        XSetBackground                          ,\
        XSetClassHint                           ,\
        XSetClipMask                            ,\
        XSetClipOrigin                          ,\
        XSetClipRectangles                      ,\
        XSetCloseDownMode                       ,\
        XSetCommand                             ,\
        XSetDashes                              ,\
        XSetErrorHandler                        ,\
        XSetFillRule                            ,\
        XSetFillStyle                           ,\
        XSetFont                                ,\
        XSetFontPath                            ,\
        XSetForeground                          ,\
        XSetFunction                            ,\
        XSetGraphicsExposures                   ,\
        XSetICFocus                             ,\
        XSetICValues                            ,\
        XSetIMValues                            ,\
        XSetIOErrorHandler                      ,\
        XSetIconName                            ,\
        XSetIconSizes                           ,\
        XSetInputFocus                          ,\
        XSetLineAttributes                      ,\
        XSetLocaleModifiers                     ,\
        XSetModifierMapping                     ,\
        XSetNormalHints                         ,\
        XSetOCValues                            ,\
        XSetOMValues                            ,\
        XSetPlaneMask                           ,\
        XSetPointerMapping                      ,\
        XSetRGBColormaps                        ,\
        XSetRegion                              ,\
        XSetScreenSaver                         ,\
        XSetSelectionOwner                      ,\
        XSetSizeHints                           ,\
        XSetStandardColormap                    ,\
        XSetStandardProperties                  ,\
        XSetState                               ,\
        XSetStipple                             ,\
        XSetSubwindowMode                       ,\
        XSetTSOrigin                            ,\
        XSetTextProperty                        ,\
        XSetTile                                ,\
        XSetTransientForHint                    ,\
        XSetWMClientMachine                     ,\
        XSetWMColormapWindows                   ,\
        XSetWMHints                             ,\
        XSetWMIconName                          ,\
        XSetWMName                              ,\
        XSetWMNormalHints                       ,\
        XSetWMProperties                        ,\
        XSetWMProtocols                         ,\
        XSetWMSizeHints                         ,\
        XSetWindowBackground                    ,\
        XSetWindowBackgroundPixmap              ,\
        XSetWindowBorder                        ,\
        XSetWindowBorderPixmap                  ,\
        XSetWindowBorderWidth                   ,\
        XSetWindowColormap                      ,\
        XSetZoomHints                           ,\
        XShrinkRegion                           ,\
        XStoreBuffer                            ,\
        XStoreBytes                             ,\
        XStoreColor                             ,\
        XStoreColors                            ,\
        XStoreName                              ,\
        XStoreNamedColor                        ,\
        XStringListToTextProperty               ,\
        XStringToKeysym                         ,\
        XSubImage                               ,\
        XSubtractRegion                         ,\
        XSupportsLocale                         ,\
        XSync                                   ,\
        XSynchronize                            ,\
        XTextExtents                            ,\
        XTextExtents16                          ,\
        XTextPropertyToStringList               ,\
        XTextWidth                              ,\
        XTextWidth16                            ,\
        XTranslateCoordinates                   ,\
        XUndefineCursor                         ,\
        XUngrabButton                           ,\
        XUngrabKey                              ,\
        XUngrabKeyboard                         ,\
        XUngrabPointer                          ,\
        XUngrabServer                           ,\
        XUninstallColormap                      ,\
        XUnionRectWithRegion                    ,\
        XUnionRegion                            ,\
        XUnloadFont                             ,\
        XUnlockDisplay                          ,\
        XUnmapSubwindows                        ,\
        XUnmapWindow                            ,\
        XUnregisterIMInstantiateCallback        ,\
        XUnsetICFocus                           ,\
        XVaCreateNestedList                     ,\
        XVendorRelease                          ,\
        XVisualIDFromVisual                     ,\
        XWMGeometry                             ,\
        XWarpPointer                            ,\
        XWhitePixel                             ,\
        XWhitePixelOfScreen                     ,\
        XWidthMMOfScreen                        ,\
        XWidthOfScreen                          ,\
        XWindowEvent                            ,\
        XWithdrawWindow                         ,\
        XWriteBitmapFile                        ,\
        XXorRegion                              ,\
        XcmsAddColorSpace                       ,\
        XcmsAddFunctionSet                      ,\
        XcmsAllocColor                          ,\
        XcmsAllocNamedColor                     ,\
        XcmsCCCOfColormap                       ,\
        XcmsCIELabClipL                         ,\
        XcmsCIELabClipLab                       ,\
        XcmsCIELabClipab                        ,\
        XcmsCIELabColorSpace                    ,\
        XcmsCIELabQueryMaxC                     ,\
        XcmsCIELabQueryMaxL                     ,\
        XcmsCIELabQueryMaxLC                    ,\
        XcmsCIELabQueryMinL                     ,\
        XcmsCIELabToCIEXYZ                      ,\
        XcmsCIELabWhiteShiftColors              ,\
        XcmsCIELuvClipL                         ,\
        XcmsCIELuvClipLuv                       ,\
        XcmsCIELuvClipuv                        ,\
        XcmsCIELuvColorSpace                    ,\
        XcmsCIELuvQueryMaxC                     ,\
        XcmsCIELuvQueryMaxL                     ,\
        XcmsCIELuvQueryMaxLC                    ,\
        XcmsCIELuvQueryMinL                     ,\
        XcmsCIELuvToCIEuvY                      ,\
        XcmsCIELuvWhiteShiftColors              ,\
        XcmsCIEXYZColorSpace                    ,\
        XcmsCIEXYZToCIELab                      ,\
        XcmsCIEXYZToCIEuvY                      ,\
        XcmsCIEXYZToCIExyY                      ,\
        XcmsCIEXYZToRGBi                        ,\
        XcmsCIEuvYColorSpace                    ,\
        XcmsCIEuvYToCIELuv                      ,\
        XcmsCIEuvYToCIEXYZ                      ,\
        XcmsCIEuvYToTekHVC                      ,\
        XcmsCIExyYColorSpace                    ,\
        XcmsCIExyYToCIEXYZ                      ,\
        XcmsClientWhitePointOfCCC               ,\
        XcmsConvertColors                       ,\
        XcmsCreateCCC                           ,\
        XcmsDefaultCCC                          ,\
        XcmsDisplayOfCCC                        ,\
        XcmsFormatOfPrefix                      ,\
        XcmsFreeCCC                             ,\
        XcmsLinearRGBFunctionSet                ,\
        XcmsLookupColor                         ,\
        XcmsPrefixOfFormat                      ,\
        XcmsQueryBlack                          ,\
        XcmsQueryBlue                           ,\
        XcmsQueryColor                          ,\
        XcmsQueryColors                         ,\
        XcmsQueryGreen                          ,\
        XcmsQueryRed                            ,\
        XcmsQueryWhite                          ,\
        XcmsRGBColorSpace                       ,\
        XcmsRGBToRGBi                           ,\
        XcmsRGBiColorSpace                      ,\
        XcmsRGBiToCIEXYZ                        ,\
        XcmsRGBiToRGB                           ,\
        XcmsScreenNumberOfCCC                   ,\
        XcmsScreenWhitePointOfCCC               ,\
        XcmsSetCCCOfColormap                    ,\
        XcmsSetCompressionProc                  ,\
        XcmsSetWhiteAdjustProc                  ,\
        XcmsSetWhitePoint                       ,\
        XcmsStoreColor                          ,\
        XcmsStoreColors                         ,\
        XcmsTekHVCClipC                         ,\
        XcmsTekHVCClipV                         ,\
        XcmsTekHVCClipVC                        ,\
        XcmsTekHVCColorSpace                    ,\
        XcmsTekHVCQueryMaxC                     ,\
        XcmsTekHVCQueryMaxV                     ,\
        XcmsTekHVCQueryMaxVC                    ,\
        XcmsTekHVCQueryMaxVSamples              ,\
        XcmsTekHVCQueryMinV                     ,\
        XcmsTekHVCToCIEuvY                      ,\
        XcmsTekHVCWhiteShiftColors              ,\
        XcmsUNDEFINEDColorSpace                 ,\
        XcmsVisualOfCCC                         ,\
        XkbAddDeviceLedInfo                     ,\
        XkbAddGeomColor                         ,\
        XkbAddGeomDoodad                        ,\
        XkbAddGeomKey                           ,\
        XkbAddGeomKeyAlias                      ,\
        XkbAddGeomOutline                       ,\
        XkbAddGeomOverlay                       ,\
        XkbAddGeomOverlayKey                    ,\
        XkbAddGeomOverlayRow                    ,\
        XkbAddGeomProperty                      ,\
        XkbAddGeomRow                           ,\
        XkbAddGeomSection                       ,\
        XkbAddGeomShape                         ,\
        XkbAddKeyType                           ,\
        XkbAllocClientMap                       ,\
        XkbAllocCompatMap                       ,\
        XkbAllocControls                        ,\
        XkbAllocDeviceInfo                      ,\
        XkbAllocGeomColors                      ,\
        XkbAllocGeomDoodads                     ,\
        XkbAllocGeomKeyAliases                  ,\
        XkbAllocGeomKeys                        ,\
        XkbAllocGeomOutlines                    ,\
        XkbAllocGeomOverlayKeys                 ,\
        XkbAllocGeomOverlayRows                 ,\
        XkbAllocGeomOverlays                    ,\
        XkbAllocGeomPoints                      ,\
        XkbAllocGeomProps                       ,\
        XkbAllocGeomRows                        ,\
        XkbAllocGeomSectionDoodads              ,\
        XkbAllocGeomSections                    ,\
        XkbAllocGeomShapes                      ,\
        XkbAllocGeometry                        ,\
        XkbAllocIndicatorMaps                   ,\
        XkbAllocKeyboard                        ,\
        XkbAllocNames                           ,\
        XkbAllocServerMap                       ,\
        XkbApplyCompatMapToKey                  ,\
        XkbApplyVirtualModChanges               ,\
        XkbBell                                 ,\
        XkbBellEvent                            ,\
        XkbChangeDeviceInfo                     ,\
        XkbChangeEnabledControls                ,\
        XkbChangeKeycodeRange                   ,\
        XkbChangeMap                            ,\
        XkbChangeNames                          ,\
        XkbChangeTypesOfKey                     ,\
        XkbComputeEffectiveMap                  ,\
        XkbComputeRowBounds                     ,\
        XkbComputeSectionBounds                 ,\
        XkbComputeShapeBounds                   ,\
        XkbComputeShapeTop                      ,\
        XkbCopyKeyType                          ,\
        XkbCopyKeyTypes                         ,\
        XkbDeviceBell                           ,\
        XkbDeviceBellEvent                      ,\
        XkbFindOverlayForKey                    ,\
        XkbForceBell                            ,\
        XkbForceDeviceBell                      ,\
        XkbFreeClientMap                        ,\
        XkbFreeCompatMap                        ,\
        XkbFreeComponentList                    ,\
        XkbFreeControls                         ,\
        XkbFreeDeviceInfo                       ,\
        XkbFreeGeomColors                       ,\
        XkbFreeGeomDoodads                      ,\
        XkbFreeGeomKeyAliases                   ,\
        XkbFreeGeomKeys                         ,\
        XkbFreeGeomOutlines                     ,\
        XkbFreeGeomOverlayKeys                  ,\
        XkbFreeGeomOverlayRows                  ,\
        XkbFreeGeomOverlays                     ,\
        XkbFreeGeomPoints                       ,\
        XkbFreeGeomProperties                   ,\
        XkbFreeGeomRows                         ,\
        XkbFreeGeomSections                     ,\
        XkbFreeGeomShapes                       ,\
        XkbFreeGeometry                         ,\
        XkbFreeIndicatorMaps                    ,\
        XkbFreeKeyboard                         ,\
        XkbFreeNames                            ,\
        XkbFreeServerMap                        ,\
        XkbGetAutoRepeatRate                    ,\
        XkbGetAutoResetControls                 ,\
        XkbGetCompatMap                         ,\
        XkbGetControls                          ,\
        XkbGetDetectableAutoRepeat              ,\
        XkbGetDeviceButtonActions               ,\
        XkbGetDeviceInfo                        ,\
        XkbGetDeviceInfoChanges                 ,\
        XkbGetDeviceLedInfo                     ,\
        XkbGetGeometry                          ,\
        XkbGetIndicatorMap                      ,\
        XkbGetIndicatorState                    ,\
        XkbGetKeyActions                        ,\
        XkbGetKeyBehaviors                      ,\
        XkbGetKeyExplicitComponents             ,\
        XkbGetKeyModifierMap                    ,\
        XkbGetKeySyms                           ,\
        XkbGetKeyTypes                          ,\
        XkbGetKeyVirtualModMap                  ,\
        XkbGetKeyboard                          ,\
        XkbGetKeyboardByName                    ,\
        XkbGetMap                               ,\
        XkbGetMapChanges                        ,\
        XkbGetNamedDeviceIndicator              ,\
        XkbGetNamedGeometry                     ,\
        XkbGetNamedIndicator                    ,\
        XkbGetNames                             ,\
        XkbGetPerClientControls                 ,\
        XkbGetState                             ,\
        XkbGetUpdatedMap                        ,\
        XkbGetVirtualMods                       ,\
        XkbGetXlibControls                      ,\
        XkbIgnoreExtension                      ,\
        XkbInitCanonicalKeyTypes                ,\
        XkbKeyTypesForCoreSymbols               ,\
        XkbKeycodeToKeysym                      ,\
        XkbKeysymToModifiers                    ,\
        XkbLatchGroup                           ,\
        XkbLatchModifiers                       ,\
        XkbLibraryVersion                       ,\
        XkbListComponents                       ,\
        XkbLockGroup                            ,\
        XkbLockModifiers                        ,\
        XkbLookupKeyBinding                     ,\
        XkbLookupKeySym                         ,\
        XkbNoteControlsChanges                  ,\
        XkbNoteDeviceChanges                    ,\
        XkbNoteMapChanges                       ,\
        XkbNoteNameChanges                      ,\
        XkbOpenDisplay                          ,\
        XkbQueryExtension                       ,\
        XkbRefreshKeyboardMapping               ,\
        XkbResizeDeviceButtonActions            ,\
        XkbResizeKeyActions                     ,\
        XkbResizeKeySyms                        ,\
        XkbResizeKeyType                        ,\
        XkbSelectEventDetails                   ,\
        XkbSelectEvents                         ,\
        XkbSetAtomFuncs                         ,\
        XkbSetAutoRepeatRate                    ,\
        XkbSetAutoResetControls                 ,\
        XkbSetCompatMap                         ,\
        XkbSetControls                          ,\
        XkbSetDebuggingFlags                    ,\
        XkbSetDetectableAutoRepeat              ,\
        XkbSetDeviceButtonActions               ,\
        XkbSetDeviceInfo                        ,\
        XkbSetDeviceLedInfo                     ,\
        XkbSetGeometry                          ,\
        XkbSetIgnoreLockMods                    ,\
        XkbSetIndicatorMap                      ,\
        XkbSetMap                               ,\
        XkbSetNamedDeviceIndicator              ,\
        XkbSetNamedIndicator                    ,\
        XkbSetNames                             ,\
        XkbSetPerClientControls                 ,\
        XkbSetServerInternalMods                ,\
        XkbSetXlibControls                      ,\
        XkbToControl                            ,\
        XkbTranslateKey                         ,\
        XkbTranslateKeyCode                     ,\
        XkbTranslateKeySym                      ,\
        XkbUpdateActionVirtualMods              ,\
        XkbUpdateKeyTypeVirtualMods             ,\
        XkbUpdateMapFromCore                    ,\
        XkbUseExtension                         ,\
        XkbVirtualModsToReal                    ,\
        XkbXlibControlsImplemented              ,\
        XmbDrawImageString                      ,\
        XmbDrawString                           ,\
        XmbDrawText                             ,\
        XmbLookupString                         ,\
        XmbResetIC                              ,\
        XmbSetWMProperties                      ,\
        XmbTextEscapement                       ,\
        XmbTextExtents                          ,\
        XmbTextListToTextProperty               ,\
        XmbTextPerCharExtents                   ,\
        XmbTextPropertyToTextList               ,\
        Xpermalloc                              ,\
        XrmCombineDatabase                      ,\
        XrmCombineFileDatabase                  ,\
        XrmDestroyDatabase                      ,\
        XrmEnumerateDatabase                    ,\
        XrmGetDatabase                          ,\
        XrmGetFileDatabase                      ,\
        XrmGetResource                          ,\
        XrmGetStringDatabase                    ,\
        XrmInitialize                           ,\
        XrmLocaleOfDatabase                     ,\
        XrmMergeDatabases                       ,\
        XrmParseCommand                         ,\
        XrmPermStringToQuark                    ,\
        XrmPutFileDatabase                      ,\
        XrmPutLineResource                      ,\
        XrmPutResource                          ,\
        XrmPutStringResource                    ,\
        XrmQGetResource                         ,\
        XrmQGetSearchList                       ,\
        XrmQGetSearchResource                   ,\
        XrmQPutResource                         ,\
        XrmQPutStringResource                   ,\
        XrmQuarkToString                        ,\
        XrmSetDatabase                          ,\
        XrmStringToBindingQuarkList             ,\
        XrmStringToQuark                        ,\
        XrmStringToQuarkList                    ,\
        XrmUniqueQuark                          ,\
        Xutf8DrawImageString                    ,\
        Xutf8DrawString                         ,\
        Xutf8DrawText                           ,\
        Xutf8LookupString                       ,\
        Xutf8ResetIC                            ,\
        Xutf8SetWMProperties                    ,\
        Xutf8TextEscapement                     ,\
        Xutf8TextExtents                        ,\
        Xutf8TextListToTextProperty             ,\
        Xutf8TextPerCharExtents                 ,\
        Xutf8TextPropertyToTextList             ,\
        XwcDrawImageString                      ,\
        XwcDrawString                           ,\
        XwcDrawText                             ,\
        XwcFreeStringList                       ,\
        XwcLookupString                         ,\
        XwcResetIC                              ,\
        XwcTextEscapement                       ,\
        XwcTextExtents                          ,\
        XwcTextListToTextProperty               ,\
        XwcTextPerCharExtents                   ,\
        XwcTextPropertyToTextList               ,\
        XUniqueContext                          ,\
        puts                                    ,\
        exit                                    ,\
        malloc                                  ,\
        free                                    ,\
        realloc                                 ,\
        stime




DispSize 'ELF Import data:', $-_importdata
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted examples/XLib/linux_inc/elf_import.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
; macroinstruction for importing functions in Linux

macro Elf32_Sym name,value,size,bind,type,other,shndx
{
 dd name+0
 dd value+0
 dd size+0
 db (bind+0) shl 4 + (type+0)
 db other+0
 dw shndx+0
}

virtual at 0
 Elf32_Sym
 sizeof.Elf32_Sym = $
end virtual

macro Elf32_Rel offset,symbol,type
{
  dd offset+0
  dd (symbol+0) shl 8 + (type+0)
}

virtual at 0
 Elf32_Rel
 sizeof.Elf32_Rel = $
end virtual

macro Elf32_Rela offset,symbol,type,addend
{
  dd offset+0
  dd (symbol+0) shl 8 + (type+0)
  dd addend+0
}

virtual at 0
 Elf32_Rela
 sizeof.Elf32_Rela = $
end virtual

macro Elf64_Sym name,value,size,bind,type,other,shndx
{
 dd name+0
 db (bind+0) shl 4 + (type+0)
 db other+0
 dw shndx+0
 dq value+0
 dq size+0
}

virtual at 0
 Elf64_Sym
 sizeof.Elf64_Sym = $
end virtual

macro Elf64_Rel offset,symbol,type
{
  dq offset+0
  dq (symbol+0) shl 32 + (type+0)
}

virtual at 0
 Elf64_Rel
 sizeof.Elf64_Rel = $
end virtual

macro Elf64_Rela offset,symbol,type,addend
{
  dq offset+0
  dq (symbol+0) shl 32 + (type+0)
  dq addend+0
}

virtual at 0
 Elf64_Rela
 sizeof.Elf64_Rela = $
end virtual

DT_NULL    = 0
DT_NEEDED  = 1
DT_HASH    = 4
DT_STRTAB  = 5
DT_SYMTAB  = 6
DT_RELA    = 7
DT_RELASZ  = 8
DT_RELAENT = 9
DT_STRSZ   = 10
DT_SYMENT  = 11
DT_REL     = 17
DT_RELSZ   = 18
DT_RELENT  = 19

STB_LOCAL  = 0
STB_GLOBAL = 1
STB_WEAK   = 2

STT_NOTYPE  = 0
STT_OBJECT  = 1
STT_FUNC    = 2
STT_SECTION = 3
STT_FILE    = 4

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



macro interpreter [library]
{
 db library,0
}

macro needed [library]
{
 local str
 match needed,needed@dynamic \{ define needed@dynamic needed,str:library \}
 match ,needed@dynamic \{ define needed@dynamic str:library \}
}
define needed@dynamic

macro import [name]
{
 common
  local strtab,strsz,symtab,rel,relsz,hash
  segment dynamic readable
  match needed,needed@dynamic
  \{ irp item,needed \\{ match str:library,item \\\{ dd DT_NEEDED,str-strtab \\\} \\} \}
  dd DT_STRTAB,strtab
  dd DT_STRSZ,strsz
  dd DT_SYMTAB,symtab
  dd DT_SYMENT,sizeof.Elf32_Sym
  dd DT_REL,rel
  dd DT_RELSZ,relsz
  dd DT_RELENT,sizeof.Elf32_Rel
  dd DT_HASH,hash
  dd DT_NULL,0
  segment readable writeable
  symtab: Elf32_Sym
 forward
  if used name
    local fstr
    Elf32_Sym fstr-strtab,0,0,STB_GLOBAL,STT_FUNC,0,0
  end if
 common
  rel:
  local counter
  counter = 1
 forward
   if used name
     Elf32_Rel name,counter,R_386_32
     counter = counter+1
   end if
 common
  relsz = $-rel
  hash:
  dd 1,counter
  dd 0
  repeat counter
   if %=counter
    dd 0
   else
    dd %
   end if
  end repeat
  strtab db 0
 forward
  if used name
    fstr db `name,0
  end if
 common
  match needed,needed@dynamic
  \{ irp item,needed \\{ match str:library,item \\\{ str db library,0 \\\} \\} \}
  strsz = $-strtab
 forward
  if used name
    name dd 0
  end if
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































Deleted examples/XLib/linux_inc/geometry.inc.

1
2
3
4
5
6
7
8
9
10
11
struct RECT
  .left   dd ?
  .top    dd ?
  .right  dd ?
  .bottom dd ?
ends

struct POINT
  .x  dd ?
  .y  dd ?
ends
<
<
<
<
<
<
<
<
<
<
<






















Deleted examples/XLib/linux_inc/x.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188

; X Protocol
 X_PROTOCOL              =       11
 X_PROTOCOL_REVISION     =       0

;X Constants

None            =       0
ParentRelative  =       1
CopyFromParent  =       0
PointerWindow   =       0
InputFocus      =       1
PointerRoot     =       1
AnyPropertyType =       0
AnyKey          =       0
AnyButton       =       0
AllTemporary    =       0
CurrentTime     =       0
NoSymbol        =       0

;Event Masks

NoEventMask              =       0h
KeyPressMask             =       1h
KeyReleaseMask           =       2h
ButtonPressMask          =       4h
ButtonReleaseMask        =       8h
EnterWindowMask          =      10h
LeaveWindowMask          =      20h
PointerMotionMask        =      40h
PointerMotionHintMask    =      80h
Button1MotionMask        =     100h
Button2MotionMask        =     200h
Button3MotionMask        =     400h
Button4MotionMask        =     800h
Button5MotionMask        =    1000h
ButtonMotionMask         =    2000h
KeymapStateMask          =    4000h
ExposureMask             =    8000h
VisibilityChangeMask     =   10000h
StructureNotifyMask      =   20000h
ResizeRedirectMask       =   40000h
SubstructureNotifyMask   =   80000h
SubstructureRedirectMask =  100000h
FocusChangeMask          =  200000h
PropertyChangeMask       =  400000h
ColormapChangeMask       =  800000h
OwnerGrabButtonMask      = 1000000h

AllEventsMask            = 1fbff7fh   ;1ffffffh




;Event           Names

KeyPress                =       2
KeyRelease              =       3
ButtonPress             =       4
ButtonRelease           =       5
MotionNotify            =       6
EnterNotify             =       7
LeaveNotify             =       8
FocusIn                 =       9
FocusOut                =       10
KeymapNotify            =       11
Expose                  =       12
GraphicsExpose          =       13
NoExpose                =       14
VisibilityNotify        =       15
CreateNotify            =       16
DestroyNotify           =       17
UnmapNotify             =       18
MapNotify               =       19
MapRequest              =       20
ReparentNotify          =       21
ConfigureNotify         =       22
ConfigureRequest        =       23
GravityNotify           =       24
ResizeRequest           =       25
CirculateNotify         =       26
CirculateRequest        =       27
PropertyNotify          =       28
SelectionClear          =       29
SelectionRequest        =       30
SelectionNotify         =       31
ColormapNotify          =       32
ClientMessage           =       33
MappingNotify           =       34
LASTEvent               =       35

;Key             Masks

ShiftMask       =       1h
LockMask        =       2h
ControlMask     =       4h
Mod1Mask        =       8h
Mod2Mask        =       10h
Mod3Mask        =       20h
Mod4Mask        =       40h
Mod5Mask        =       80h

;Modifier                Names

ShiftMapIndex   =       0
LockMapIndex    =       1
ControlMapIndex =       2
Mod1MapIndex    =       3
Mod2MapIndex    =       4
Mod3MapIndex    =       5
Mod4MapIndex    =       6
Mod5MapIndex    =       7

;Button          Masks

Button1Mask     =       100h
Button2Mask     =       200h
Button3Mask     =       400h
Button4Mask     =       800h
Button5Mask     =       1000h
AnyModifier     =       10000h

;Button          Names

Button1         =       1
Button2         =       2
Button3         =       3
Button4         =       4
Button5         =       5

;Notify          Modes
NotifyNormal    =       0
NotifyGrab      =       1
NotifyUngrab    =       2
NotifyWhileGrabbed      =       3
NotifyHint      =       1

;Notify          Detail

NotifyAncestor  =       0
NotifyVirtual   =       1
NotifyInferior  =       2
NotifyNonlinear =       3
NotifyNonlinearVirtual  =       4
NotifyPointer   =       5
NotifyPointerRoot       =       6
NotifyDetailNone        =       7

;Visibility              Notify

VisibilityUnobscured    =       0
VisibilityPartiallyObscured     =       1
VisibilityFullyObscured =       2

;Circulation             request

PlaceOnTop      =       0
PlaceOnBottom   =       1

;Protocol                Families

FamilyInternet  =       0
FamilyDECnet    =       1
FamilyChaos     =       2
FamilyInternet6 =       6

;Unspecific              authentication  families

FamilyServerInterpreted =       5

;Property       Notification

PropertyNewValue        =       0
PropertyDelete  =       1

;Color           Map     notification

ColormapUninstalled     =       0
ColormapInstalled       =       1

;Grab            Modes
GrabModeSync    =       0
GrabModeAsync   =       1

;Grab            reply   status
GrabSuccess     =       0
AlreadyGrabbed  =       1
GrabInvalidTime =       2
GrabNotViewable =       3
GrabFrozen      =       4

;AllowEvents             modes
AsyncPointer    =       0
SyncPointer     =       1
ReplayPointer   =       2
AsyncKeyboard   =       3
SyncKeyboard    =       4
ReplayKeyboard  =       5
AsyncBoth       =       6
SyncBoth        =       7

;InputFocus              specific

RevertToNone    =       None
RevertToPointerRoot     =       PointerRoot
RevertToParent  =       2

;Error           Codes
Success =       0
BadRequest      =       1
BadValue        =       2
BadWindow       =       3
BadPixmap       =       4
BadAtom =       5
BadCursor       =       6
BadFont =       7
BadMatch        =       8
BadDrawable     =       9
BadAccess       =       10
BadAlloc        =       11
BadColor        =       12
BadGC   =       13
BadIDChoice     =       14
BadName =       15
BadLength       =       16
BadImplementation       =       17
FirstExtensionError     =       128
LastExtensionError      =       255

;Window          Classes

InputOutput     =       1
InputOnly       =       2

;Window          Attributes
CWBackPixmap    =       1h
CWBackPixel     =       2h
CWBorderPixmap  =       4h
CWBorderPixel   =       8h
CWBitGravity    =       10h
CWWinGravity    =       20h
CWBackingStore  =       40h
CWBackingPlanes =       80h
CWBackingPixel  =       100h
CWOverrideRedirect      =       200h
CWSaveUnder     =       400h
CWEventMask     =       800h
CWDontPropagate =       1000h
CWColormap      =       2000h
CWCursor        =       4000h

;ConfigureWindow         Structure
CWX             =       1h
CWY             =       2h
CWWidth         =       4h
CWHeight        =       8h
CWBorderWidth   =       10h
CWSibling       =       20h
CWStackMode     =       40h

;Bit             Gravity
ForgetGravity           =       0
NorthWestGravity        =       1
NorthGravity            =       2
NorthEastGravity        =       3
WestGravity             =       4
CenterGravity           =       5
EastGravity             =       6
SouthWestGravity        =       7
SouthGravity            =       8
SouthEastGravity        =       9
StaticGravity           =       10

;Window          Gravity
UnmapGravity    =       0

;CreateWindow            backing-store   hint
NotUseful       =       0
WhenMapped      =       1
Always  =       2

;GetWindowAttributes             reply
IsUnmapped      =       0
IsUnviewable    =       1
IsViewable      =       2

;Used            in      ChangeSaveSet
SetModeInsert   =       0
SetModeDelete   =       1

;Used            in      ChangeCloseDownMode
DestroyAll      =       0
RetainPermanent =       1
RetainTemporary =       2

;Window          stacking        method  (in     configureWindow)
Above   =       0
Below   =       1
TopIf   =       2
BottomIf        =       3
Opposite        =       4

;Circulation             direction
RaiseLowest     =       0
LowerHighest    =       1

;Property                modes
PropModeReplace =       0
PropModePrepend =       1
PropModeAppend  =       2

;Graphics                Functions
GXclear =       0h
GXand   =       1h
GXandReverse    =       2h
GXcopy  =       3h
GXandInverted   =       4h
GXnoop  =       5h
GXxor   =       6h
GXor    =       7h
GXnor   =       8h
GXequiv =       9h
GXinvert        =       10h
GXorReverse     =       11h
GXcopyInverted  =       12h
GXorInverted    =       13h
GXnand  =       14h
GXset   =       15h

;LineStyle
LineSolid       =       0
LineOnOffDash   =       1
LineDoubleDash  =       2

;capStyle
CapNotLast      =       0
CapButt =       1
CapRound        =       2
CapProjecting   =       3

;joinStyle
JoinMiter       =       0
JoinRound       =       1
JoinBevel       =       2

;fillStyle
FillSolid       =       0
FillTiled       =       1
FillStippled    =       2
FillOpaqueStippled      =       3

;fillRule

EvenOddRule     =       0
WindingRule     =       1

;subwindow               mode

ClipByChildren  =       0
IncludeInferiors        =       1

;SetClipRectangles               ordering

Unsorted        =       0
YSorted =       1
YXSorted        =       2
YXBanded        =       3

;CoordinateMode          for     drawing routines

CoordModeOrigin =       0
CoordModePrevious       =       1

;Polygon         shapes

Complex =       0
Nonconvex       =       1
Convex  =       2

;Arc             modes   for     PolyFillArc

ArcChord        =       0
ArcPieSlice     =       1

;GC              components

GCFunction      =       1h
GCPlaneMask     =       2h
GCForeground    =       4h
GCBackground    =       8h
GCLineWidth     =       10h
GCLineStyle     =       20h
GCCapStyle      =       40h
GCJoinStyle     =       80h
GCFillStyle     =       100h
GCFillRule      =       200h
GCTile  =       400h
GCStipple       =       800h
GCTileStipXOrigin       =       1000h
GCTileStipYOrigin       =       2000h
GCFont  =       4000h
GCSubwindowMode =       8000h
GCGraphicsExposures     =       10000h
GCClipXOrigin   =       20000h
GCClipYOrigin   =       40000h
GCClipMask      =       80000h
GCDashOffset    =       100000h
GCDashList      =       200000h
GCArcMode       =       400000h

GCLastBit       =       22

;used            in      QueryFont       --      draw    direction

FontLeftToRight =       0
FontRightToLeft =       1

FontChange      =       255

;ImageFormat             --      PutImage,       GetImage

XYBitmap        =       0
XYPixmap        =       1
ZPixmap =       2

;For             CreateColormap

AllocNone       =       0
AllocAll        =       1


;Flags           used    in      StoreNamedColor,        StoreColors

DoRed   =       1h
DoGreen =       2h
DoBlue  =       4h

;QueryBestSize           Class

CursorShape     =       0
TileShape       =       1
StippleShape    =       2

;Keyboard                pointer stuff

AutoRepeatModeOff       =       0
AutoRepeatModeOn        =       1
AutoRepeatModeDefault   =       2

LedModeOff      =       0
LedModeOn       =       1

;masks           for     ChangeKeyboardControl

KBKeyClickPercent       =       1h
KBBellPercent   =       2h
KBBellPitch     =       4h
KBBellDuration  =       8h
KBLed   =       10h
KBLedMode       =       20h
KBKey   =       40h
KBAutoRepeatMode        =       80h

MappingSuccess  =       0
MappingBusy     =       1
MappingFailed   =       2

MappingModifier =       0
MappingKeyboard =       1
MappingPointer  =       2

;Screensaver             stuff

DontPreferBlanking      =       0
PreferBlanking  =       1
DefaultBlanking =       2

DisableScreenSaver      =       0
DisableScreenInterval   =       0

DontAllowExposures      =       0
AllowExposures  =       1
DefaultExposures        =       2

;for             ForceScreenSaver

ScreenSaverReset        =       0
ScreenSaverActive       =       1

;for             ChangeHosts

HostInsert      =       0
HostDelete      =       1

;for             ChangeAccessControl

EnableAccess    =       1
DisableAccess   =       0

;display         classes

StaticGray      =       0
GrayScale       =       1
StaticColor     =       2
PseudoColor     =       3
TrueColor       =       4
DirectColor     =       5


;Byte            order           used    in      imageByteOrder  and     bitmapBitOrder

LSBFirst        =       0
MSBFirst        =       1

;Keyboard and Pointer Event Structures

struct   XButtonEvent
  .type         rd    1
  .serial       rd    1
  .send_event   rd    1
  .display      rd    1
  .window       rd    1
  .root         rd    1
  .subwindow    rd    1
  .time         rd    1
  .x            rd    1
  .y            rd    1
  .x_root       rd    1
  .y_root       rd    1
  .state        rd    1
  .button       rd    1
  .same_screen  rd    1
ends


virtual at 0
XButtonPressedEvent  XButtonEvent
end virtual

virtual at 0
XButtonReleasedEvent XButtonEvent
end virtual

struct   XKeyEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .root                           rd    1
        .subwindow                      rd    1
        .time                           rd    1
        .x                              rd    1
        .y                              rd    1
        .x_root                         rd    1
        .y_root                         rd    1
        .state                          rd    1
        .keycode                        rd    1
        .same_screen                    rd    1
ends


virtual at 0
XKeyPressedEvent   XKeyEvent
end virtual

virtual at 0
XKeyReleasedEvent  XKeyEvent
end virtual


struct   XMotionEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .root                           rd    1
        .subwindow                      rd    1
        .time                           rd    1
        .x                              rd    1
        .y                              rd    1
        .x_root                         rd    1
        .y_root                         rd    1
        .state                          rd    1
        .is_hint                        rb    1
        .same_screen                    rd    1
ends


virtual at 0
XPointerMovedEvent  XMotionEvent
end virtual

;Window Entry/Exit Events

struct   XCrossingEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .root                           rd    1
        .subwindow                      rd    1
        .time                           rd    1
        .x                              rd    1
        .y                              rd    1
        .x_root                         rd    1
        .y_root                         rd    1
        .mode                           rd    1
        .detail                         rd    1
        .same_screen                    rd    1
        .focus                          rd    1
        .state                          rd    1
ends

virtual at 0
XEnterWindowEvent  XCrossingEvent
end virtual

virtual at 0
XLeaveWindowEvent  XCrossingEvent
end virtual

;       Input           Focus   Events

struct   XFocusChangeEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .mode                           rd    1
        .detail                         rd    1
ends



virtual at 0
XFocusInEvent  XFocusChangeEvent
end virtual

virtual at 0
XFocusOutEvent  XFocusChangeEvent
end virtual

;       Keymap          Notification    Events

struct   XKeymapEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .key_vector                     rb    32
ends

;       Exposure/Update         Events

struct   XExposeEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .x                              rd    1
        .y                              rd    1
        .width                          rd    1
        .height                         rd    1
        .count                          rd    1
ends


struct   XGraphicsExposeEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .drawable                       rd    1
        .x                              rd    1
        .y                              rd    1
        .width                          rd    1
        .height                         rd    1
        .count                          rd    1
        .major_code                     rd    1
        .minor_code                     rd    1
ends


struct   XNoExposeEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .drawable                       rd    1
        .major_code                     rd    1
        .minor_code                     rd    1
ends


;       CirculateNotify         Events

struct   XCirculateEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
        .place                          rd    1
ends


struct   XCirculateRequestEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .parent                         rd    1
        .window                         rd    1
        .place                          rd    1
ends

;       Configuration           Change  Events

struct   XConfigureEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
        .x                              rd    1
        .y                              rd    1
        .width                          rd    1
        .height                         rd    1
        .border_width                   rd    1
        .above                          rd    1
        .override_redirect              rd    1
ends

struct   XConfigureRequestEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .parent                         rd    1
        .window                         rd    1
        .x                              rd    1
        .y                              rd    1
        .width                          rd    1
        .height                         rd    1
        .border_width                   rd    1
        .above                          rd    1
        .detail                         rd    1
        .value_mask                     rd    1
ends

struct   XPropertyEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .atom                           rd    1
        .time                           rd    1
        .state                          rd    1
ends

struct   XResizeEvent
        .type                           rd    1
        .serial                         rd    1
        .display                        rd    1
        .window                         rd    1
        .width                          rd    1
        .height                         rd    1
ends

struct   XColormapEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .colormap                       rd    1
        .new                            rd    1
        .state                          rd    1
ends

;       Creation/Destruction            Notifications

struct   XCreateWindowEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .parent                         rd    1
        .window                         rd    1
        .x                              rd    1
        .y                              rd    1
        .width                          rd    1
        .heigth                         rd    1
        .border_width                   rd    1
        .override_redirect              rd    1
ends


struct   XDestroyWindowEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
ends

;       Parent          Movement        Events

struct   XGravityEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
        .x                              rd    1
        .y                              rd    1
ends

;       Mapping         Events

struct   XMapEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
        .override_redirect              rd    1
ends

struct   XMappingEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .request                        rd    1
        .first_keycode                  rd    1
        .count                          rd    1
ends


struct   XMapRequestEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .parent                         rd    1
        .window                         rd    1
ends

;       Parent          Change  Events

struct   XReparentEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
        .parent                         rd    1
        .x                              rd    1
        .y                              rd    1
        .override_redirect              rd    1
ends

struct   XSelectionClearEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .selection                      rd    1
        .time                           rd    1
ends

struct   XSelectionRequestEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .owner                          rd    1
        .requestor                      rd    1
        .selection                      rd    1
        .target                         rd    1
        .property                       rd    1
        .time                           rd    1
ends

struct   XSelectionEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .requestor                      rd    1
        .selection                      rd    1
        .target                         rd    1
        .property                       rd    1
        .time                           rd    1
ends

;       Hidden          Window  Events

struct   XUnmapEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
        .from_configure                 rd    1
ends

struct   XVisibilityEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .state                          rd    1
ends

;       Client          Messages        (XSendEvent)

struct   XClientMessageEvent
  .type                           rd    1
  .serial                         rd    1
  .send_event                     rd    1
  .display                        rd    1
  .window                         rd    1
  .message_type                   rd    1
  .format                         rd    1
  .data                           rb    20
ends


struct   XErrorEvent
        .type                           rd    1
        .serial                         rd    1
        .error_code                     rd    1
        .request_code                   rd    1
        .minor_code                     rd    1
        .resourceid                     rd    1
ends



struct XAnyEvent
  .type         rd    1
  .serial       rd    1
  .send_event   rd    1
  .display      rd    1
  .window       rd    1
ends


struct XEvent
  .xany XAnyEvent
  .pad  rb 24*4 - sizeof.XAnyEvent

  virtual at .xany
  . XAnyEvent
  end virtual


  virtual at .xany
  .xkey XKeyEvent
  end virtual

  virtual at .xany
  .xbutton XButtonEvent
  end virtual

  virtual at .xany
  .xmotion XMotionEvent
  end virtual

  virtual at .xany
  .xcrossing XCrossingEvent
  end virtual

  virtual at .xany
  .xfocus XFocusChangeEvent
  end virtual

  virtual at .xany
  .xexpose XExposeEvent
  end virtual

  virtual at .xany
  .xgraphicsexpose XGraphicsExposeEvent
  end virtual

  virtual at .xany
  .xnoexpose XNoExposeEvent
  end virtual

  virtual at .xany
  .xvisibility XVisibilityEvent
  end virtual

  virtual at .xany
  .xcreatewindow XCreateWindowEvent
  end virtual

  virtual at .xany
  .xdestroywindow XDestroyWindowEvent
  end virtual

  virtual at .xany
  .xunmap XUnmapEvent
  end virtual

  virtual at .xany
  .xmap XMapEvent
  end virtual

  virtual at .xany
  .xmaprequest XMapRequestEvent
  end virtual

  virtual at .xany
  .xreparent XReparentEvent
  end virtual

  virtual at .xany
  .xconfigure XConfigureEvent
  end virtual

  virtual at .xany
  .xgravity XGravityEvent
  end virtual

  virtual at .xany
  .xresizerequest XResizeEvent
  end virtual

  virtual at .xany
  .xconfigurerequest XConfigureRequestEvent
  end virtual

  virtual at .xany
  .xcirculate XCirculateEvent
  end virtual

  virtual at .xany
  .xcirculaterequest XCirculateRequestEvent
  end virtual

  virtual at .xany
  .xproperty XPropertyEvent
  end virtual

  virtual at .xany
  .xselectionclear XSelectionClearEvent
  end virtual

  virtual at .xany
  .xselectionrequest XSelectionRequestEvent
  end virtual

  virtual at .xany
  .xselection XSelectionEvent
  end virtual

  virtual at .xany
  .xcolormap XColormapEvent
  end virtual

  virtual at .xany
  .xclient XClientMessageEvent
  end virtual

  virtual at .xany
  .xmapping XMappingEvent
  end virtual

  virtual at .xany
  .xerror XErrorEvent
  end virtual

  virtual at .xany
  .xkeymap XKeymapEvent
  end virtual
ends


;       Misc.           Structures

struct   XKeyboardControl
        .key_click_percent              rd    1
        .bell_percent                   rd    1
        .bell_pitch                     rd    1
        .bell_duration                  rd    1
        .led                            rd    1
        .led_mode                       rd    1
        .key                            rd    1
        .auto_repeat_mode               rd    1
ends



struct   XModifierKeymap
        .max_keypermod                  rd    1
        .modifiermap                    rd    1
ends




struct XWindowAttributes
  .x                     dd  ?     ; location of window
  .y                     dd  ?     ;
  .width                 dd  ?     ; width and height of window
  .height                dd  ?     ;
  .border_width          dd  ?     ; border width of window
  .depth                 dd  ?     ; depth of window
  .pVisual               dd  ?     ; the associated visual structure
  .root                  dd  ?     ; root of screen containing window
  .class                 dd  ?     ; InputOutput, InputOnly
  .bit_gravity           dd  ?     ; one of the bit gravity values
  .win_gravity           dd  ?     ; one of the window gravity values
  .backing_store         dd  ?     ; NotUseful, WhenMapped, Always
  .backing_planes        dd  ?     ; planes to be preserved if possible
  .backing_pixel         dd  ?     ; value to be used when restoring planes
  .save_under            dd  ?     ; boolean, should bits under be saved?
  .colormap              dd  ?     ; color map to be associated with window
  .map_installed         dd  ?     ; boolean, is color map currently installed
  .map_state             dd  ?     ; IsUnmapped, IsUnviewable, IsViewable
  .all_event_masks       dd  ?    ; set of events all people have interest in
  .your_event_mask       dd  ?          ; my event mask
  .do_not_propagate_mask dd  ?    ; set of events that should not propagate
  .override_redirect     dd  ?    ; boolean value for override-redirect
  .pScreen               dd  ?  ; back pointer to correct screen
ends



struct XCharStruct
  .lbearing   dw ?       ; origin to left edge of raster
  .rbearing   dw ?       ; origin to right edge of raster
  .width      dw ?       ; advance to next char's origin
  .ascent     dw ?       ; baseline to top edge of raster
  .descent    dw ?       ; baseline to bottom edge of raster
  .attributes dw ?       ; per char flags (not predefined)
ends


struct XFontStruct
  .ext_data          dd   ?       ; hook for extension to hang data
  .fid               dd   ?       ; Font id for this font
  .direction         dd   ?       ; hint about the direction font is painted
  .min_char_or_byte2 dd   ?       ; first character
  .max_char_or_byte2 dd   ?       ; last character
  .min_byte1         dd   ?       ; first row that exists
  .max_byte1         dd   ?       ; last row that exists
  .all_chars_exist   dd   ?       ; flag if all characters have nonzero size
  .default_char      dd   ?       ; char to print for undefined character
  .n_properties      dd   ?       ; how many properties there are
  .properties        dd   ?       ; pointer to array of additional properties
  .min_bounds        XCharStruct  ; minimum bounds over all existing char
  .max_bounds        XCharStruct  ; maximum bounds over all existing char
  .per_char          dd   ?       ; first_char to last_char information
  .ascent            dd   ?       ; logical extent above baseline for spacing
  .descent           dd   ?       ; logical decent below baseline for spacing
ends


struct XWindowChanges
  .x            dd ?
  .y            dd ?
  .width        dd ?
  .height       dd ?
  .border_width dd ?
  .sibling      dd ?
  .stack_mode   dd ?
ends
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted examples/XLib/test.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
proc start, .argc, .argv, .argp
.fontlist  dd ?
.fontcount dd ?
begin
        stdcall Xinitialize, strCaption, 10, 20, 400, 200

        ;;; Main Event Loop

.msg_pump:
        cinvoke XNextEvent, [hdisplay], event
        stdcall Xeventhandler
        jmp     .msg_pump

        stdcall Xshutdown

.do_exit:        ; Non-Local for XSetErrorHandler
        xor     eax, eax
        cinvoke exit, eax
        return
endp




proc Xshutdown
begin
        cinvoke XFreeGC, [hdisplay], [hGC]
        cinvoke XDestroyWindow, [hwin], [hdisplay]
        cinvoke XSetErrorHandler, [oError]

        xor     eax, eax
        return
endp


proc Xinitialize, .txt, .x, .y, .w, .h
  .hscreen rd 1
  .hroot   rd 1
begin
        cinvoke XOpenDisplay, 0
        or      eax, eax
        jnz     .display_ok

        cinvoke puts, strErrorDisplay
        jmp     start.do_exit

.display_ok:
        mov     [hdisplay], eax
        cinvoke XDefaultScreen, eax
        mov     [.hscreen], eax

        cinvoke XDefaultRootWindow, [hdisplay]
        mov     [.hroot], eax

        cinvoke XCreateSimpleWindow, [hdisplay], eax, [.x], [.y], [.w], [.h], 0, $000000, $d4d0c8
        or      eax, eax
        jnz     .create_ok

        cinvoke puts, strErrorCreation
        jmp     start.do_exit

.create_ok:
        mov     [hwin], eax
        cinvoke XCreateSimpleWindow, [hdisplay], eax, 10, 10, 64, 24, 0, $606060, $d4d0c8
        mov     [hwin2], eax

        cinvoke XSelectInput, [hdisplay], [hwin], KeyPressMask + KeyReleaseMask + ExposureMask
        cinvoke XSelectInput, [hdisplay], [hwin2], KeyPressMask + KeyReleaseMask + ExposureMask + EnterWindowMask + LeaveWindowMask
        cinvoke XStoreName, [hdisplay], [hwin], [.txt]
        cinvoke XStoreName, [hdisplay], [hwin2], cBtnCaption
        cinvoke XMapRaised, [hdisplay], [hwin]
        cinvoke XMapRaised, [hdisplay], [hwin2]
        or      eax, eax
        jnz     .show_ok

        cinvoke puts, strErrorShow
        jmp     start.do_exit

.show_ok:
        cinvoke XCreateGC, [hdisplay], [hwin], 0, 0
        mov     [hGC], eax

        cinvoke XSetForeground, [hdisplay], [hGC], $000000
        cinvoke XSetBackground, [hdisplay], [hGC], $ffffff

        xor     eax, eax
        return
endp



proc Xdrawscreen
begin
        cinvoke XDrawLine, [hdisplay], [hwin], [hGC], 0, 110, 400, 110
        cinvoke XDrawLine, [hdisplay], [hwin], [hGC], 0, 80, 400, 80
        cinvoke XDrawString, [hdisplay], [hwin], [hGC], 10, 100, strMessage, lenMessage
        return
endp


proc StrLength, .ptrString
begin
        push    esi

        xor     eax, eax

        mov     esi, [.ptrString]
        test    esi, esi
        jz      .exit

        cld
.loop:
        mov     cl, [esi]
        inc     esi
        test    cl, cl
        jz      .exit

        inc     eax
        jmp     .loop

.exit:
        pop     esi
        return
endp

proc DrawBtn, .hwin, .inside
.attr XWindowAttributes
.name dd ?
.font dd ?
.direction dd ?
.ascent    dd ?
.descent   dd ?
.overall   XCharStruct
begin
        push    ebx ecx esi edi

        lea     ecx, [.attr]
        cinvoke XGetWindowAttributes, [hdisplay], [.hwin], ecx
        dec     [.attr.width]
        dec     [.attr.height]

        cinvoke XCreateGC, [hdisplay], [.hwin], 0, 0
        mov     ebx, eax

        cmp     [.inside], 0
        jne     .border_beveled

        cinvoke XSetForeground, [hdisplay], ebx, $606060
        cinvoke XDrawRectangle, [hdisplay], [.hwin], ebx, 0, 0, [.attr.width], [.attr.height]

        sub     [.attr.width], 2
        sub     [.attr.height], 2

        cinvoke XSetForeground, [hdisplay], ebx, $d4d0c8
        cinvoke XDrawRectangle, [hdisplay], [.hwin], ebx, 1, 1, [.attr.width], [.attr.height]
        inc     [.attr.width]
        inc     [.attr.height]
        jmp     .border_ok

.border_beveled:
        cinvoke XSetForeground, [hdisplay], ebx, $ffffff
        cinvoke XDrawLine, [hdisplay], [.hwin], ebx, 0, 0, [.attr.width], 0
        cinvoke XDrawLine, [hdisplay], [.hwin], ebx, 0, 0, 0, [.attr.height]

        cinvoke XSetForeground, [hdisplay], ebx, $404040
        cinvoke XDrawLine, [hdisplay], [.hwin], ebx, 0, [.attr.height], [.attr.width], [.attr.height]
        cinvoke XDrawLine, [hdisplay], [.hwin], ebx, [.attr.width], 0, [.attr.width], [.attr.height]

        dec     [.attr.width]
        dec     [.attr.height]

        cinvoke XSetForeground, [hdisplay], ebx, $808080
        cinvoke XDrawLine, [hdisplay], [.hwin], ebx, 1, [.attr.height], [.attr.width], [.attr.height]
        cinvoke XDrawLine, [hdisplay], [.hwin], ebx, [.attr.width], 1, [.attr.width], [.attr.height]

.border_ok:
        cinvoke XSetForeground, [hdisplay], ebx, $000000

        cinvoke XLoadQueryFont, [hdisplay], cGUIfont
        mov     [.font], eax
        cinvoke XSetFont, [hdisplay], ebx, [eax+XFontStruct.fid]

        lea     ecx, [.name]
        cinvoke XFetchName, [hdisplay], [.hwin], ecx

        stdcall StrLength, [.name]
        mov     edi, eax
        lea     ecx, [.direction]
        lea     edx, [.ascent]
        lea     eax, [.descent]
        lea     esi, [.overall]
        cinvoke XTextExtents, [.font], [.name], edi, ecx, edx, eax, esi

        xor     eax, eax
        mov     ax, [.overall.ascent]
        add     ax, [.overall.descent]
        movsx   eax, ax
        sub     eax, [.attr.height]
        add     eax, 1
        neg     eax
        sar     eax, 1
        movsx   ecx, [.overall.ascent]
        lea     eax, [eax+ecx+1]  ; this is the baseline.
        mov     [.attr.y], eax

        mov     ax, [.overall.width]
        movsx   eax, ax
        sub     eax, [.attr.width]
        add     eax, 1
        neg     eax
        sar     eax, 1
        add     eax, 1
        cmp     eax, 1
        jge     @f
        mov     eax, 1
@@:
        mov     [.attr.x], eax

        stdcall StrLength, [.name]
        cinvoke XDrawString, [hdisplay], [.hwin], ebx, [.attr.x], [.attr.y], [.name], eax

        cinvoke XFree, [.name]
        cinvoke XFreeFont, [hdisplay], [.font]
        cinvoke XFreeGC, [hdisplay], ebx

        pop   edi esi ecx  ebx
        return
endp



proc Xeventhandler
begin
        mov     eax, [event]

        cmp     eax, Expose
        je      .on_expose

        cmp     eax, KeyPress
        je      .on_keypress

        cmp     eax, EnterNotify
        je      .on_enter

        cmp     eax, LeaveNotify
        je      .on_leave

        return

.on_leave:
        mov     eax, [event+XEnterWindowEvent.window]
        cmp     eax, [hwin2]
        je      .button_leave

        return

.button_leave:
        stdcall DrawBtn, [event+XEnterWindowEvent.window], 0
        return


.on_enter:
        mov     eax, [event+XEnterWindowEvent.window]
        cmp     eax, [hwin2]
        je      .button_enter
        return

.button_enter:
        stdcall DrawBtn, [event+XEnterWindowEvent.window], 1
        return

.on_expose:
        mov     eax, [event+XExposeEvent.window]

        cmp     eax, [hwin]
        je      .mainwin

        cmp     eax, [hwin2]
        je      .button

        return

.button:
        stdcall DrawBtn, [hwin2], 0
        return


.mainwin:
        stdcall Xdrawscreen
        return


.on_keypress:
        cinvoke XLookupKeysym, event, 0
        cmp     eax, 'q'
        je      .terminate

        return

.terminate:
; keypress exits the application
        jmp     start.do_exit
endp






iglobal
  strCaption db 'Xlib Fresh!', 0
  strMessage db "This is native assembly language Linux program."
  lenMessage = ($-strMessage)

  cBtnCaption db 'Button',0

  oError           dd 0
  strErrorDisplay  db 'XOpenDisplay: could not open connection to X server.', 0
  strErrorCreation db 'XCreateSimpleWindow: could not create window.', 0
  strErrorShow     db 'XMapRaised: could not display window.', 0

  strAll       db '*helvetica-medium-r*--12*', 0
  cGUIfont     db '*helvetica-medium-r*--12*', 0        ;'*lucida-medium-r*-sans-12*',0

  cNewLine      db $0a, 0

  hGC             dd 0
  hwin            dd 0
  hwin2           dd 0
  hdisplay        dd 0
  event           rd 132
endg
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































Deleted examples/toolpanel/Main.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
format PE GUI 4.0
entry Start

include '%finc%/win32/win32a.inc'

include "%finc%/libs/msgutils.inc"
include "%finc%/libs/tform.inc"
include "%finc%/libs/parents.inc"
include "%finc%/libs/templates.inc"

include "%finc%/libs/msgutils.asm"
include "%finc%/libs/tform.asm"
include "%finc%/libs/parents.asm"
include "%finc%/libs/templates.asm"

include "MainForm.frm"

options.ShowSizes = 1


uglobal
  hInstance dd ?
  hHeap     dd ?
  hMainForm dd ?
endg



Start:
        invoke  GetModuleHandleA,0
        mov     [hInstance],eax
        invoke  GetProcessHeap
        mov     [hHeap], eax

        InitializeAll

        invoke  InitCommonControls

        stdcall CreateForm, frmMain, NULL
        xor     eax, eax
        test    ebx, ebx
        jz      .terminate

        mov     [hMainForm], ebx

.run:
        call    ProcessMessages
        jc      .terminate

        invoke  WaitMessage
        jmp     .run

.terminate:
        push    eax
        FinalizeAll
        invoke  ExitProcess ; exit code from the stack.

data import
  include "%finc%/win32/allimports.asm"
end data

IncludeAllGlobals
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































Deleted examples/toolpanel/MainForm.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
;<ff
Window frmMain, 3, 0, 'TForm', 'TForm window', $16C00000, $80, 0, 637, 203, 276, 359, MainFormProc;
Window NONE, 2, 0, 'BUTTON', 'Autohide', $50008003, $0, 100, 4, 0, 64, 16, 0;
;ff>
uglobal
  timerID dd ?
  outsideCNT dd ?
endg



winproc MainFormProc
  .rect RECT
  .rect2 RECT
begin

ondefault
        stc
        return


onmessage WM_TIMER

        cmp     [.wparam], 1234
        je      .mousetimer

        clc
        return

.mousetimer:
        invoke  SendDlgItemMessageA, [.hwnd], 100, BM_GETCHECK, 0, 0
        test    eax, eax
        jnz     .autohide

        invoke  KillTimer, [.hwnd], 1234
        mov     [timerID], 0
        clc
        return

.autohide:
        lea     esi, [.rect]
        invoke  GetWindowRect, [.hwnd], esi

        lea     eax, [.rect2]
        invoke  GetCursorPos, eax

        invoke  PtInRect, esi, [.rect2.left], [.rect2.top]
        test    eax, eax
        jz      .outside

        mov     [outsideCNT], 6

        clc
        return

.outside:
        dec     [outsideCNT]
        jz      .mouseleave

        clc
        return

.mouseleave:
        invoke  KillTimer, [.hwnd], 1234
        mov     [timerID], 0

.hidewindow:
        lea     eax, [.rect2]
        invoke  GetWindowRect, [.hwnd], eax

        mov     eax, [.rect2.right]
        sub     eax, [.rect2.left]
        neg     eax
        add     eax, 4

        invoke  SetWindowPos, [.hwnd], 0, eax, [.rect2.top], 0, 0, SWP_NOSIZE or SWP_NOZORDER or SWP_SHOWWINDOW

        clc
        return


onmessage WM_NCMOUSEMOVE
onmessage WM_MOUSEMOVE
        cmp     [timerID], 0
        jne     .endmove

; mouse enter
        lea     eax, [.rect2]
        invoke  GetWindowRect, [.hwnd], eax
        invoke  SetWindowPos, [.hwnd], HWND_TOPMOST, 0,[.rect2.top], 0, 0, SWP_NOSIZE or SWP_SHOWWINDOW
        invoke  SetTimer, [.hwnd], 1234, 50, 0
        mov     [timerID], 1
        mov     [outsideCNT], 10

.endmove:
        clc
        return


onmessage FM_AFTERCREATE
;        invoke  SetProp, [.hwnd], [propColor], $0000ff

        jmp     .hidewindow
endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































Deleted examples/toolpanel/ToolPanel.fpr.

cannot compute difference between binary files

Deleted examples/toolpanel/readme.txt.

1
2
3
This example creates some simple tool window that auto hides itself to the left edge of the screen.
When the user points to the panel it pops out.
Something like autohide Windows task bar.
<
<
<






Deleted freshlib/FreshEdit/FreshEdit.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TFreshEdit object class; Advanced visual programming editor.
;
;  Target OS: Any
;
;  Dependencies:  strlib, memory, arrays, GUI
;
;  Notes:
;    FreshEdit features:
;    - Unicode (UTF-8)
;    - Word wrap
;    - Code folding
;    - Associated debug information
;    - save with format information (bookmarks and breakpoints)
;    - Read-only lines
;    - Undo and Redo functions.
;    - Adjustable colors, keyboard and behavior.
;    - Char, Block and Line selections.
;    - Syntax highlighters interface for different languages.
;    - Interface to visual programming tools and auto source generators.
;_________________________________________________________________________________________
include "FreshEditThemes.asm"

module "TFreshEdit library"

ObjectClass FreshEdit,                   \
            ScrollWindow,                \
            TFreshEdit.Create,           \
            TFreshEdit.Destroy,          \
            TFreshEdit.Get,              \
            TFreshEdit.Set,              \
            TFreshEdit.ExecCmd,          \
            TFreshEdit.SysEventHandler

; Line flags

lfBookmark   = 1        ; the line have bookmark set.
lfFocused    = 2        ; the line is focused until the user press some key.
lfProtected  = 4        ; the line can not be edited.
lfWordWrap   = 8        ; the line must be word wrapped. After changes, the format have to be updated.
lfBreakpoint = 16       ; set breakpoint in debug mode.
lfFoldHeader = 32       ; this is the first line of foldable part of the text.


struct TEditorLine
  .Data         dd  ?   ; pointer to line data.
  .flags        dd  ?   ; line flags

  .syn_context  dd  ?   ; flags about current syntax highlighter context.
  .debugdata    dd  ?   ; pointer to debug data, associated to this line
  .fold_level   dd  ?   ; the level of folding.

  .width        dd  ?   ; width of the line text in chars. It is the length of the string for non wrapped lines and maximal subline for wrapped.
  align 32
  .shift = 5
ends


undoInsertText     = 0
undoDeleteText     = 1


struct TUndoInfo
  .operation   db ?       ; what was changed???
  .selMode     db ?
  align 4
  .caretX      dd ?
  .caretY      dd ?
  .selectionX  dd ?
  .selectionY  dd ?
  .data        dd ?
  align 32
  .shift = 5
ends

; About TEditorLine.syn_context:
;
; This context flags depend on the current syntax highlighter active.
; The purpose of the context is to follow syntax constructions that
; spreads on several lines. Such as multiline comments, markup tags, etc.
; Also, some of the flags could be used for other purposes - code folding
; is one of the options.



; Flags that indicates what is changed in the editor window after some operation
; Indicate what update should be processed

chgfNoClearSelection = 1
chgfNeedRefresh      = 2
chgfFinished         = 4

; insert modes

modeInsert = 0
modeOverwrite = 1

; selection modes

selmChar = 0
selmBlock = 1

; flag ReadOnly values
froReadWrite          = 0
froReadOnlyWithCaret  = 1
froReadOnlyNoCaret    = 2


object TFreshEdit, TScrollWindow
  ._Font            dd  ?   ; font of the editor.

; main editor font sizes
  ._fontheight      dd  ?   ; in pixels.
  ._fontwidth       dd  ?   ; in pixels.
  ._fontdescent     dd  ?   ; in pixels.

; system font sizes (used for additional texts and line numbers)
  ._fontheight2     dd  ?   ; in pixels.
  ._fontwidth2      dd  ?   ; in pixels.
  ._fontdescent2    dd  ?   ; in pixels.

  .__LeftMargin     dd  ?   ; width of the left margin field. Auto computed.
  .__NumberMargin   dd  ?   ; width of the field for the line number. Auto computed.
  ._ExtraFont       dd  ?   ;

  ._cols            dd  ?   ; width of the window in text columns.
  ._rows            dd  ?   ; height of the window in text rows.
                            ; must to be update on resize and on font change.

  ._pLines          dd  ?   ; pointer to TArray of TEditorLine items.
  ._pIndex          dd  ?   ; pointer to TArray of dword that contains numbers of TEditorLine for the screen.
  ._pLengths        dd  ?   ; pointer to TArray with counts of the lines with given length.

  ._pUndoList       dd  ?   ; pointer to TArray of TUndoInfo
  ._pRedoList       dd  ?   ; pointer to TArray of TUndoInfo

  ._pShadow         dd  ?   ; double buffer pointer to TBackBuffer object.
  ._fShadowValid    dd  ?   ;

; view change fields

  ._TopLine         dd  ?   ; number of the line that is at the topmost line of the window.
  ._LeftColumn      dd  ?   ; the column of the text at the leftmost side of the window.

  ._xCaret          dd  ?   ; horizontal position of the caret inside the current line.
  ._yCaret          dd  ?   ; vertical position of the caret inside the text.

  ._xSelection      dd  ?
  ._ySelection      dd  ?

  ._fReadOnly       dd  ?
  ._SelMode         dd  ?
  ._InsMode         dd  ?
  ._TabStop         dd  ?

; end change fields

  ._prevTopLine     dd  ?
  ._prevLeftColumn  dd  ?

  ._prevxCaret      dd  ?
  ._prevyCaret      dd  ?

  ._prevxDelta      dd  ?
  ._prevyDelta      dd  ?

  ._prevSelMode     dd  ?
  ._prevInsMode     dd  ?

; end backup fields

  ._DragButton      dd  ?

;  ._Theme           TFETheme

  ._procSyntax      dd  ?   ; syntax highlighter procedure.

  ._iconBreakpointA dd  ?       ; active breakpoint icon.
  ._iconBreakpointI dd  ?       ; inactive breakpoint icon.
  ._iconDebugInfo   dd  ?
  ._maskBreakpointA dd  ?
  ._maskBreakpointI dd  ?
  ._maskDebugInfo   dd  ?


  ._iconUnfold      dd  ?
  ._iconFold        dd  ?

  ._maskUnfold      dd  ?

; Event handlers

  .OnControlKey     dd  ?

; Parameters
  param .Selection      ; selected text read/write

  param .CurrentLine    ; TEditorLine where caret resides.
  param .Text
  param .MaxLineLen

; Methods

  method .Clear          ; clears the text in the editor.

; navigation methods

  method .Move, .direction, .count, .force      ; moves the caret

  method .LineBegin
  method .LineEnd
  method .ScreenBegin
  method .ScreenEnd
  method .FileBegin
  method .FileEnd

; editing methods

  method .DeleteSel
  method .InsertLine, .index    ; index = -1 inserts at current position of the caret.
                                ; index = -2 appends the line at the end of the text.
  method .DeleteLine, .index    ; index = -1 deletes the line on the current position of the caret.

; block processing methods.
  method .DeleteText, .indexFrom, .charFrom, .indexTo, .charTo
  method .GetText, .indexFrom, .charFrom, .indexTo, .charTo

; Undo/Redo functions.

  method .RegisterForUndo, .operation, .data

  method .Undo
  method .Redo

  method .ClearUndo

; these two methods are flexible, but very slow. .Text parameter seting is fastest way to change whole text of the editor.
  method .InsertChar, .char
  method .InsertString, .hstring    ; inserts a string at the caret position.
                                    ; If the string contains formating chars they are processed properly.
  method .DelChar      ; deletes the char under the caret.

; appearance methods
  method .FormatLine, .index

; themes methods

  method LoadTheme, .configdb, .directory

endobj


; about .pIndex field:
;
;  This array contains the number of text lines that have to be displayed on the
;  respective screen lines.
;  Not every text line have screen line representation - it means the count of items of [pIntex]
;  can be smaller than count of items of [pLines]. This case is when some lines are folded and not visible.
;  On the other hand, another variant is also possible - several items of [pIndex] to point to
;  one line in [pLines] - when the text line is wraped and displayed on several lines of the screen.
;
;_________________________________________________________________________________________

cDefaultEditorFont text 'Fixedsys Excelsior 3.01'
;cDefaultEditorFont text 'Droid sans mono'

; left margin icons.
;iglobal
    getfile iconBreakpointA, 'images/breakpoint.gif'
    getfile iconBreakpointI, 'images/breakpoint_inactive.gif'
    getfile maskBreakpointA, 'images/breakpoint_mask.gif'
    getfile maskBreakpointI, 'images/breakpoint_mask_inactive.gif'
    getfile iconDebugInfo,   'images/debug_icon.gif'
    getfile maskDebugInfo,   'images/debug_mask.gif'
    getfile iconUnfold,      'images/unfold.gif'
    getfile iconFold,        'images/fold.gif'
    getfile maskUnfold,      'images/unfold_mask.gif'
;endg


proc TFreshEdit.Create, .pobj
begin
        push    eax edx

        mov     ebx, [.pobj]

; Main Font settings.
        stdcall FontCreate, cDefaultEditorFont, 0, 0, ffMonospaced
        mov     [ebx+TFreshEdit._Font], eax
        mov     [ebx+TFreshEdit._cursor], mcText

        stdcall FontGetCharSize, [ebx+TFreshEdit.handle], [ebx+TFreshEdit._Font], __HeightProbeString
        test    edx, edx
        jnz     @f
        inc     edx
@@:
        mov     [ebx+TFreshEdit._fontheight], edx
        mov     [ebx+TFreshEdit._fontwidth], eax
        mov     [ebx+TFreshEdit._fontdescent], ecx

; System font settings.
        stdcall FontGetCharSize, [ebx+TFreshEdit.handle], 0, __NumberProbeString
        mov     [ebx+TFreshEdit._fontheight2], edx
        mov     [ebx+TFreshEdit._fontwidth2], eax
        mov     [ebx+TFreshEdit._fontdescent2], ecx

; Icons for internal use

        stdcall CreateImageGIF, iconBreakpointA, iconBreakpointA.size
        mov     [ebx+TFreshEdit._iconBreakpointA], eax

        stdcall CreateImageGIF, iconBreakpointI, iconBreakpointI.size
        mov     [ebx+TFreshEdit._iconBreakpointI], eax

        stdcall CreateImageGIF, iconDebugInfo, iconDebugInfo.size
        mov     [ebx+TFreshEdit._iconDebugInfo], eax

        stdcall CreateImageGIF, maskBreakpointA, maskBreakpointA.size
        mov     [ebx+TFreshEdit._maskBreakpointA], eax

        stdcall CreateImageGIF, maskBreakpointI, maskBreakpointI.size
        mov     [ebx+TFreshEdit._maskBreakpointI], eax

        stdcall CreateImageGIF, maskDebugInfo, maskDebugInfo.size
        mov     [ebx+TFreshEdit._maskDebugInfo], eax

        stdcall CreateImageGIF, iconUnfold, iconUnfold.size
        mov     [ebx+TFreshEdit._iconUnfold], eax

        stdcall CreateImageGIF, iconFold, iconFold.size
        mov     [ebx+TFreshEdit._iconFold], eax

        stdcall CreateImageGIF, maskUnfold, maskUnfold.size
        mov     [ebx+TFreshEdit._maskUnfold], eax

; Init some values.
        mov     [ebx+TFreshEdit._TabStop], 8

        mov     [eax+TFETheme.WrapPos], 80
        mov     [eax+TFETheme.UndoLevels], 20

        mov     [ebx+TFreshEdit._DragButton], -1

        stdcall CreateArray, sizeof.TEditorLine
        mov     [ebx+TFreshEdit._pLines], eax

        stdcall CreateArray, 4
        mov     [ebx+TFreshEdit._pIndex], eax

        stdcall CreateArray, 4
        mov     [ebx+TFreshEdit._pLengths], eax

        stdcall CreateArray, sizeof.TUndoInfo
        mov     [ebx+TFreshEdit._pUndoList], eax

        stdcall CreateArray, sizeof.TUndoInfo
        mov     [ebx+TFreshEdit._pRedoList], eax

        stdcall CreateBackBuffer, [ebx+TFreshEdit.handle], 1, 1
        mov     [ebx+TFreshEdit._pShadow], eax

        pop     edx eax
        clc
        return
endp



;_________________________________________________________________________________________


proc TFreshEdit.Destroy, .pobj
begin
        mov     ebx, [.pobj]
        execute ebx, TFreshEdit.Clear
        stdcall FreeMem, [ebx+TFreshEdit._pLines]
        stdcall FreeMem, [ebx+TFreshEdit._pIndex]
        stdcall FreeMem, [ebx+TFreshEdit._pLengths]
        stdcall FreeMem, [ebx+TFreshEdit._pUndoList]
        stdcall FreeMem, [ebx+TFreshEdit._pRedoList]

        stdcall DestroyBackBuffer, [ebx+TFreshEdit._pShadow]

        stdcall DestroyImage, [ebx+TFreshEdit._iconBreakpointA]
        stdcall DestroyImage, [ebx+TFreshEdit._iconBreakpointI]
        stdcall DestroyImage, [ebx+TFreshEdit._iconDebugInfo]
        stdcall DestroyImage, [ebx+TFreshEdit._maskBreakpointA]
        stdcall DestroyImage, [ebx+TFreshEdit._maskBreakpointI]
        stdcall DestroyImage, [ebx+TFreshEdit._maskDebugInfo]
        stdcall DestroyImage, [ebx+TFreshEdit._iconUnfold]
        stdcall DestroyImage, [ebx+TFreshEdit._iconFold]

        stdcall DestroyImage, [ebx+TFreshEdit._maskUnfold]
        clc
        return
endp


;_________________________________________________________________________________________


proc TFreshEdit.Get, .pobj, .paramID
begin
        stdcall IsObject, [.pobj], CFreshEdit
        jc      .exit

        cmp     [.paramID], TFreshEdit.MaxLineLen
        je      .maxlinelen

        cmp     [.paramID], TFreshEdit.CurrentLine
        je      .currentline

        cmp     [.paramID], TFreshEdit.Text
        je      .gettext

        cmp     [.paramID], TFreshEdit.Selection
        je      .get_selection

        stc
.exit:
        return

;................................................................
.get_selection:
        push    esi

        mov     esi, [.pobj]
        mov     eax, [esi+TFreshEdit._SelMode]
        cmp     eax, selmChar
        je      .get_sel_char
        cmp     eax, selmBlock
        je      .get_sel_block

        stc
        return

.get_sel_char:
        execute esi, TFreshEdit.GetText, [esi+TFreshEdit._yCaret], [esi+TFreshEdit._xCaret],      \
                                         [esi+TFreshEdit._ySelection], [esi+TFreshEdit._xSelection]

        clc
        pop     esi
        return


.get_sel_block:
        xor     eax, eax
        clc
        pop     esi
        return


;................................................................
.gettext:
        push    ebx ecx edx esi edi


        stdcall StrNew
        mov     ebx, eax
        mov     edi, [.pobj]

        mov     esi, [edi+TFreshEdit._pLines]
        mov     ecx, [esi+TArray.count]

        jecxz   .text_ready
        lea     esi, [esi+TArray.array]

.line_loop:
        stdcall TFreshEdit.__AddFormatLine, ebx, [esi+TEditorLine.flags]

        stdcall StrDup, [esi+TEditorLine.Data]
        push    eax
        push    eax
        push    eax
        stdcall StrLen, eax
        mov     edx, eax
        stdcall StrPtr ; from the stack

        test    edx, edx
        jz      .line_ready

.loop_char:
        cmp     byte [eax], 1
        jne     .next
        mov     byte [eax], $20
.next:
        inc     eax
        dec     edx
        jnz     .loop_char

.line_ready:
        stdcall StrCat, ebx ; from the stack.
        stdcall StrDel      ; from the stack
        stdcall StrCharCat, ebx, $0a0d

.next_line:
        add     esi, sizeof.TEditorLine
        loop    .line_loop

.text_ready:
        mov     eax, ebx
        pop     edi esi edx ecx ebx
        clc
        return

;................................................................

.currentline:
        push    ebx edx edi

        mov     edi, [.pobj]
        mov     eax, [edi+TFreshEdit._yCaret]
        mov     ebx, [edi+TFreshEdit._pIndex]
        cmp     eax, [ebx+TArray.count]
        jae     .errorcl

.lineloop:
        mov     edx, [ebx+TArray.array+4*eax]
        cmp     edx, -1
        jne     .found

        dec     eax
        jns     .lineloop

.errorcl:
        stc
        pop     edi edx ebx
        return

; edx is the number of string in the lines array.
.found:
        mov     ebx, [edi+TFreshEdit._pLines]
        cmp     edx, [ebx+TArray.count]
        jae     .errorcl

        shl     edx, TEditorLine.shift
        lea     eax, [ebx+TArray.array+edx]

        clc
        pop     edi edx ebx
        return

;................................................................

.maxlinelen:
        mov     eax, [.pobj]
        mov     eax, [eax+TFreshEdit._pLengths]
        mov     eax, [eax+TArray.count]
        dec     eax
        jns     @f
        xor     eax, eax
@@:
        clc
        return

endp


;_________________________________________________________________________________________


proc TFreshEdit.Set, .pobj, .paramID, .value
begin
        push    eax ebx edx esi edi
        mov     edi, [.pobj]

        mov     eax, [.paramID]
        cmp     eax, TFreshEdit.Text
        je      .settext

        cmp     eax, TFreshEdit.Selection
        je      .set_selection

        stc

.finish:
        pop     edi esi edx ebx eax
        return

;.........................................................................................
.set_selection:
; delete the old selection
        push    esi eax edx
        mov     esi, [.pobj]

        execute esi, TFreshEdit.DeleteSel
        mov     [esi+TFreshEdit._yCaret], eax
        mov     [esi+TFreshEdit._xCaret], edx

; Insert the specified string on the current caret position.
        execute [.pobj], TFreshEdit.InsertString, [.value]
        pop     edx eax esi
        clc
        return

;.........................................................................................

.settext:
locals
.pLine    dd ?
.flags    dd ?
endl
        execute edi, TFreshEdit.Clear

        stdcall StrPtr, [.value]
        mov     esi, eax

.lineloop:
        mov     [.flags], 0

        stdcall TFreshEdit.__DecodeFormatLine, esi
        jc      .line_begin

        mov     [.flags], eax
        add     esi, ecx

.line_begin:
        push    esi

.char:
        lodsb
        test    al, al
        jz      .end_of_line

        cmp     al, $0a
        je      .end_of_line
        cmp     al, $0d
        jne     .char

.end_of_line:
        mov     ebx, esi
        sub     ebx, [esp]
        dec     ebx

        test    al, al
        jnz     @f
        dec     esi
        jmp     .lineok

@@:
        xor     al, $0a xor $0d
        cmp     [esi], al
        jne     .lineok
        inc     esi

.lineok:
        pop     eax
        push    ecx esi edi

        mov     ecx, ebx
        mov     esi, eax

        stdcall StrNew
        mov     ebx, eax
        stdcall StrSetCapacity, ebx, ecx
        mov     edi, eax

        mov     [edi+string.len], ecx

        rep movsb
        xor eax, eax    ; terminating zero - important for linux sometimes,
                        ; because the memory reallocation returns not zero filled memory.
        stosb

        pop     edi esi ecx

; insert text line.
        stdcall AddArrayItems, [edi+TFreshEdit._pLines], 1
        mov     [edi+TFreshEdit._pLines], edx
        mov     ecx, [edx+TArray.count]
        mov     [.pLine], eax

        mov     [eax+TEditorLine.Data], ebx
        push    [.flags]
        pop     [eax+TEditorLine.flags]
        mov     [eax+TEditorLine.syn_context], 0
        mov     [eax+TEditorLine.debugdata], 0
        mov     [eax+TEditorLine.width], -1

; insert index line.
        stdcall AddArrayItems, [edi+TFreshEdit._pIndex], 1
        mov     [edi+TFreshEdit._pIndex], edx

        dec     ecx
        mov     [eax], ecx

; format the line
        mov     ecx, [edx+TArray.count]
        dec     ecx
        execute edi, TFreshEdit.FormatLine, ecx

; goto next line.
        cmp     byte [esi], 0
        jne     .lineloop

        mov     [edi+TFreshEdit._TopLine], 0
        mov     [edi+TFreshEdit._yCaret], 0

        mov     eax, [edi+TFreshEdit._pLengths]

        stdcall TFreshEdit.__UpdateScrollBars, edi
        mov     [edi+TFreshEdit._fShadowValid], 0

        clc
        jmp     .finish
endp



;_________________________________________________________________________________________

; move commands
mvcMoveX   = 1
mvcMoveY   = 2
mvcScrollX = 4
mvcScrollY = 8


proc TFreshEdit.ExecCmd, .self, .method
begin
        cmp     [.method], TFreshEdit.Refresh
        je      .refresh

        cmp     [.method], TFreshEdit.Clear
        je      .clear

        cmp     [.method], TFreshEdit.Move
        je      .movecaret

        cmp     [.method], TFreshEdit.LineBegin
        je      .linebegin

        cmp     [.method], TFreshEdit.LineEnd
        je      .lineend

        cmp     [.method], TFreshEdit.DeleteSel
        je      .delete_selection

        cmp     [.method], TFreshEdit.DeleteText
        je      .delete_text

        cmp     [.method], TFreshEdit.GetText
        je      .get_text

        cmp     [.method], TFreshEdit.DeleteLine
        je      .delete_line

        cmp     [.method], TFreshEdit.InsertChar
        je      .insert_char

        cmp     [.method], TFreshEdit.InsertString
        je      .insert_string

        cmp     [.method], TFreshEdit.InsertLine
        je      .insert_line

        cmp     [.method], TFreshEdit.FormatLine
        je      .format_line

        cmp     [.method], TFreshEdit.DelChar
        je      .del_char

        stc
        return

;.........................................................................................
.refresh:
        mov     eax, [.self]
        mov     [eax+TFreshEdit._fShadowValid], 0
        stc
        return

;.........................................................................................
; formats some line of the text, depending on the flags. Also, fix the index items for
; this line.
.format_line:
virtual at ebx
  .index dd ?
end virtual

; first get the line pointer
locals
  .imin  dd  ?
  .imax  dd  ?
  .start_count dd ?
  .rows        dd ?

  .caret_ofs dd ?
  .wrap_here dd ?

  .retval dd ?   ; correction count on tab-expansion
endl
        push    ecx esi edi

        mov     esi, [.self]
        mov     edi, [esi+TFreshEdit._pIndex]

        mov     ecx, [.index]
        cmp     ecx, [edi+TArray.count]
        jae     .error_format

.loop_end:
        inc     ecx
        cmp     ecx, [edi+TArray.count]
        jae     .end_found
        cmp     [edi+TArray.array+4*ecx], -1
        je      .loop_end

.end_found:
        dec     ecx
        mov     [.imax], ecx

        mov     ecx, [.index]
        inc     ecx

.loop_start:
        dec     ecx
        js      .error_format

        cmp     [edi+TArray.array+4*ecx], -1
        je      .loop_start

        mov     [.imin], ecx
        mov     [.rows], 1    ; how many lines are withit the line

        mov     ecx, [edi+TArray.array+4*ecx]   ; index in _pLines array.
        shl     ecx, TEditorLine.shift
        add     ecx, [esi+TFreshEdit._pLines]
        lea     edi, [ecx+TArray.array]         ; edi points to TEditorLine structure.

; begin of formating
        stdcall StrClipSpacesR, [edi+TEditorLine.Data]
        stdcall ExpandTabs, [edi+TEditorLine.Data], [esi+TFreshEdit._TabStop]
        mov     [.retval], eax
        stdcall StrLen, [edi+TEditorLine.Data]
        mov     ecx, eax
        mov     [.start_count], eax
        jecxz   .wrap_ok

        stdcall StrPtr, [edi+TEditorLine.Data]
        mov     edx, eax

; first replace $01 with $20 (wrap char to space)
        push    edx ecx
.spc_loop:
        cmp     byte [edx], $01
        jne     @f
        mov     byte [edx], $20
@@:
        inc     edx
        loop    .spc_loop
        pop     ecx edx

; word wrap?
        test    [edi+TEditorLine.flags], lfWordWrap
        jz      .wrap_ok

        push    edi

        mov     edi, edx
.wrap_outer:
        mov     ecx, [FreshEditTheme.WrapPos]
        inc     ecx
        mov     [.wrap_here], -1
        xor     edx, edx

.wrap_loop:
        add     edi, edx
        stdcall DecodeUtf8, [edi]
        test    eax, eax
        jz      .wrap_ready

        cmp     eax, ' '
        jne     @f
        mov     [.wrap_here], edi
@@:
        loop    .wrap_loop

        cmp     [.wrap_here], -1
        jne     .do_wrap

.forward:
        add     edi, edx
        stdcall DecodeUtf8, [edi]
        test    eax, eax
        jz      .wrap_ready

        cmp     eax, ' '
        jne     .forward

        mov     [.wrap_here], edi

.do_wrap:
        mov     edi, [.wrap_here]
        mov     byte [edi], $01         ; wrap the line.
        inc     edi
        inc     [.rows]
        jmp     .wrap_outer


.wrap_ready:
; ready, so fix the index.
        pop     edi

.wrap_ok:
        mov     eax, [.imin]
        inc     eax

        mov     ecx, [.imax]
        sub     ecx, [.imin]
        inc     ecx
        sub     ecx, [.rows]    ; ecx>0 means some rows from the index must be deleted
                                ; ecx<0 means some rows must be added.
                                ; ecx=0 means the index is ok
        jz      .index_ok
        js      .add_more_index

        stdcall DeleteArrayItems, [esi+TFreshEdit._pIndex], eax, ecx
        mov     [esi+TFreshEdit._pIndex], edx
        jmp     .index_ok

.add_more_index:
        neg     ecx
        stdcall InsertArrayItems, [esi+TFreshEdit._pIndex], eax, ecx
        mov     [esi+TFreshEdit._pIndex], edx

.fill_new_items:
        mov     dword [eax], -1
        lea     eax, [eax+4]
        loop    .fill_new_items

.index_ok:
        stdcall TFreshEdit.__LineWidth, [edi+TEditorLine.Data]
        xchg    eax, [edi+TEditorLine.width]
        stdcall TFreshEdit.__FixLength, esi, [edi+TEditorLine.width], eax

        clc
        mov     eax, [.retval]
        mov     edx, [.imin]
        pop     edi esi ecx
        return

.error_format:
        int3
        mov     eax, -1
        clc
        pop     edi esi ecx
        return

;.........................................................................................
.delete_line:
virtual at ebx
  .del_index dd ?
end virtual

        push    edx esi edi
        mov     esi, [.self]

        mov     eax, [.del_index]
        cmp     eax, -1
        jne     @f
        mov     eax, [esi+TFreshEdit._yCaret]
@@:
        mov     edi, [esi+TFreshEdit._pIndex]
        cmp     eax, [edi+TArray.count]
        jae     .end_del_line

.beg_search:
        cmp     [edi+TArray.array+4*eax], -1    ; word wrap
        jne     .do_del
        dec     eax
        jnz     .beg_search

.do_del:
        mov     ecx, [edi+TArray.array+4*eax]
        shl     ecx, TEditorLine.shift
        add     ecx, TArray.array
        add     ecx, [esi+TFreshEdit._pLines]
        stdcall StrDel, [ecx+TEditorLine.Data]
        stdcall TFreshEdit.__FixLength, esi, -1, [ecx+TEditorLine.width]

        stdcall DeleteArrayItems, [esi+TFreshEdit._pLines], [edi+TArray.array+4*eax], 1
        mov     [esi+TFreshEdit._pLines], edx

.del_index2:
        stdcall DeleteArrayItems, edi, eax, 1
        mov     edi, edx
        cmp     eax, [edi+TArray.count]
        jae     .end_del_index2

        cmp     [edi+TArray.array+4*eax], -1
        je      .del_index2

.end_del_index2:
        mov     [esi+TFreshEdit._pIndex], edi
        push    eax

; fix the index to the end:
.fix_index_del:
        cmp     eax, [edi+TArray.count]
        jae     .end_fix_index

        cmp     [edi+TArray.array+4*eax], -1
        je      @f
        dec     [edi+TArray.array+4*eax]
@@:
        inc     eax
        jmp     .fix_index_del

.end_fix_index:
        pop     eax
.end_del_line:
        clc
        pop     edi esi edx
        return

;.........................................................................................
.get_text:
; have the same arguments and local variables as .delete_text
        pushad
        mov     [.ret_str], 0

; sort the "from" and "To" in order to have "From" < "To"
        mov     eax, [.indexFrom]
        mov     ecx, [.charFrom]
        cmp     eax, [.indexTo]
        jne     @f
        cmp     ecx, [.charTo]
@@:
        je      .finish_get    ; from == to so nothing to return
        jb      @f
        xchg    eax, [.indexTo]
        xchg    ecx, [.charTo]
        mov     [.indexFrom], eax
        mov     [.charFrom], ecx
@@:

; last line processing
        stdcall TFreshEdit.__PosToPointer, [.self], [.charTo], [.indexTo]
        mov     [.toline], edx

        stdcall StrExtract, [edx+TEditorLine.Data], 0, eax
        mov     [.final_str], eax

; first line processing
        stdcall TFreshEdit.__PosToPointer, [.self], [.charFrom], [.indexFrom]
        mov     [.fromline], edx

        mov     edi, [edx+TEditorLine.Data]
        cmp     edx, [.toline]
        jne     .dup_first
        mov     edi, [.final_str]
.dup_first:
        push    eax
        stdcall StrDup, edi
        mov     edi, eax
        pop     eax

        jecxz   .get_splitit
        add     eax, ecx

.get_addspc:
        stdcall StrCharCat, edi, ' '
        dec     ecx
        jnz     .get_addspc

.get_splitit:
        stdcall StrSplit, edi, eax
        stdcall StrDel, edi
        mov     [.ret_str], eax

; now concatenate all lines to the first.

        mov     edi, [.toline]
        mov     esi, [.fromline]
        cmp     esi, edi
        je      .end_get2

.get_loop:
        add     esi, sizeof.TEditorLine
        cmp     esi, edi
        je      .end_get
        stdcall StrCharCat, [.ret_str], $0a0d
        stdcall StrCat, [.ret_str], [esi+TEditorLine.Data]
        jmp     .get_loop

.end_get:
        stdcall StrCharCat, [.ret_str], $0a0d
        stdcall StrCat, [.ret_str], [.final_str]

.end_get2:
        stdcall StrDel, [.final_str]

; here, format the string - remove word wrap characters if any...
        stdcall  StrPtr, [.ret_str]

.get_format:
        cmp     byte [eax], 0
        je      .finish_get

        cmp     byte [eax], $01      ; word wrap char
        jne     @f
        mov     byte [eax], $20
@@:
        inc     eax
        jmp     .get_format

.finish_get:
        clc
        popad
        mov     eax, [.ret_str]
        return

;.........................................................................................
.delete_text:
virtual at ebx  ; arguments
  .indexFrom dd ?
  .charFrom  dd ?
  .indexTo   dd ?
  .charTo    dd ?
end virtual
locals
  .final_str   dd ?
  .final_flags dd ?
  .final_level dd ?
  .fromline    dd ?
  .toline      dd ?
  .ret_str     dd ?
endl
        pushad

; sort the "from" and "To" in order to have "From" < "To"
        mov     eax, [.indexFrom]
        mov     ecx, [.charFrom]
        cmp     eax, [.indexTo]
        jne     @f
        cmp     ecx, [.charTo]
@@:
        je      .nothing_to_delete    ; from == to so nothing to delete.
        jb      @f
        xchg    eax, [.indexTo]
        xchg    ecx, [.charTo]
        mov     [.indexFrom], eax
        mov     [.charFrom], ecx
@@:

; last line processing
        stdcall TFreshEdit.__PosToPointer, [.self], [.charTo], [.indexTo]

        stdcall StrSplit, [edx+TEditorLine.Data], eax
        mov     [.final_str], eax

        mov     eax, [edx+TEditorLine.flags]
        mov     ecx, [edx+TEditorLine.fold_level]
        mov     [.final_flags], eax
        mov     [.final_level], ecx

; first line processing
        stdcall TFreshEdit.__PosToPointer, [.self], [.charFrom], [.indexFrom]
        mov     [.fromline], edx

        jecxz   .splitit
        add     eax, ecx
.addspc:
        stdcall StrCharCat, [edx+TEditorLine.Data], ' '
        dec     ecx
        jnz     .addspc

.splitit:
        stdcall StrSplit, [edx+TEditorLine.Data], eax
        stdcall StrDel, eax
        stdcall StrCat, [edx+TEditorLine.Data], [.final_str]
        stdcall StrDel, [.final_str]
        mov     eax, [.final_level]
        mov     ecx, [.final_flags]
        mov     [edx+TEditorLine.fold_level], eax
        or      [edx+TEditorLine.flags], ecx

; now delete all lines except the first.

        mov     edi, [.indexTo]

.del_loop:
        stdcall TFreshEdit.__PosToPointer, [.self], -1, edi
        cmp     edx, [.fromline]
        je      .delete_ok

        execute [.self], TFreshEdit.DeleteLine, edi
        mov     edi, eax
        dec     edi
        jmp     .del_loop


.delete_ok:
        execute [.self], TFreshEdit.FormatLine, [.indexFrom]

        clc
        popad
        mov     eax, [.indexFrom]
        mov     edx, [.charFrom]
        return

.nothing_to_delete:
        clc
        popad
        xor     eax, eax
        dec     eax
        return

;.........................................................................................
; delete the selection
.delete_selection:
        mov     esi, [.self]
        mov     eax, [esi+TFreshEdit._SelMode]
        cmp     eax, selmChar
        je      .del_sel_char
        cmp     eax, selmBlock
        je      .del_sel_block

        stc
        return

.del_sel_char:
        execute esi, TFreshEdit.DeleteText, [esi+TFreshEdit._yCaret], [esi+TFreshEdit._xCaret],      \
                                            [esi+TFreshEdit._ySelection], [esi+TFreshEdit._xSelection]
        clc
        return


.del_sel_block:
        clc
        return

;.........................................................................................
.insert_line:
virtual at ebx
  .ins_index dd ?
end virtual
        push    esi edi
        mov     esi, [.self]

; first where to search. The next line is OK, but if the line is wrapped...
        cmp     [.ins_index], -1
        jne     @f
        mov     eax, [esi+TFreshEdit._yCaret]
        mov     [.ins_index], eax
@@:

        mov     edi, [esi+TFreshEdit._pIndex]
        mov     edx, [.ins_index]

        cmp     edx, [edi+TArray.count]
        jb      .search_begin

; insert as a last line
        mov     edx, [edi+TArray.count]
        mov     ecx, -1
        jmp     .ins_here

; if the line is wrapped, search for the begin.
.search_begin:
        mov     ecx, [edi+TArray.array+4*edx]
        cmp     ecx, -1                         ; wrapped line?
        jne     .ins_here
        dec     edx
        jns     .search_begin
        jmp     .err_ins_line

; ...insert index item.
; edx contains the index in _pIndex where the new line have to be inserted.
; ecx contains the index in _pLines where the new line have to be inserted.
.ins_here:
        push    edx
        stdcall InsertArrayItems, [esi+TFreshEdit._pIndex], edx, 1
        mov     [esi+TFreshEdit._pIndex], edx
        mov     edi, edx
        pop     edx
        jc      .err_ins_line

        cmp     ecx, -1
        jne     .storeline

        mov     ecx, [esi+TFreshEdit._pLines]
        mov     ecx, [ecx+TArray.count]

.storeline:
        mov     [eax], ecx

; ...then fix the index to the end.

        sub     edx, [edi+TArray.count]
        neg     edx
        dec     edx
        jle     .index_fixed

.inc_index:
        lea     eax, [eax+4]
        cmp     dword [eax], -1
        je      @f
        inc     dword [eax]
@@:
        dec     edx
        jnz     .inc_index


.index_fixed:
; then insert new line
        stdcall InsertArrayItems, [esi+TFreshEdit._pLines], ecx, 1
        mov     [esi+TFreshEdit._pLines], edx
        jc      .err_ins_line

        mov     edx, eax
        stdcall StrNew

        mov     [edx+TEditorLine.Data], eax
        xor     eax, eax
        mov     [edx+TEditorLine.flags], eax
        mov     [edx+TEditorLine.syn_context], eax
        mov     [edx+TEditorLine.debugdata], eax
        mov     [edx+TEditorLine.width], eax
        mov     eax, edx

        stdcall TFreshEdit.__FixLength, esi, 0, -1

        pop     edi esi
        clc
        return

.err_ins_line:
        pop     edi esi
        stc
        return

;.........................................................................................
.del_char:
locals
  .del_char_line dd ?
  .del_line_index dd ?
  .byte_offs dd ?
endl
        push    ecx edx esi edi

        mov     esi, [.self]
        stdcall TFreshEdit.__PosToPointer, esi, [esi+TFreshEdit._xCaret], [esi+TFreshEdit._yCaret]
        jc      .end_del_char

        test    [edx+TEditorLine.flags], lfProtected
        jnz     .end_del_char

        jecxz   .do_del_char

.del_pad_spc:
        stdcall StrCharInsert, [edx+TEditorLine.Data], ' ', eax
        inc     eax
        loop    .del_pad_spc

.do_del_char:
        mov     [.byte_offs], eax
        mov     [.del_char_line], edx
        mov     ebx, eax
        stdcall StrLen, [edx+TEditorLine.Data]
        cmp     ebx, eax
        je      .join_next_line

        mov     ecx, eax
        sub     ecx, ebx

        stdcall StrPtr, [edx+TEditorLine.Data]
        mov     edi, eax
        stdcall DecodeUtf8, [edi+ebx]
        lea     esi, [edi+edx]
        sub     [edi+string.len], edx
        add     esi, ebx
        add     edi, ebx
        cld
        rep movsb

.end_del_char:
        mov     eax, [.byte_offs]
        pop     edi esi edx ecx
        clc
        return

.join_next_line:
        mov     eax, [.del_char_line]
        mov     edx, [esi+TFreshEdit._pLines]
        sub     eax, edx
        sub     eax, TArray.array
        shr     eax, TEditorLine.shift
        inc     eax
        cmp     eax, [edx+TArray.count]
        jae     .end_del_char

        mov     [.del_line_index], eax

        mov     edx, [.del_char_line]
        mov     ebx, edx
        add     edx, sizeof.TEditorLine
        test    [edx+TEditorLine.flags], lfProtected
        jz      .do_join

        stdcall StrLen, [ebx+TEditorLine.Data]
        test    eax, eax
        jnz     .end_del_char

.do_join:
        stdcall StrCat, [ebx+TEditorLine.Data], [edx+TEditorLine.Data]
        mov     eax, [edx+TEditorLine.flags]
        or      [ebx+TEditorLine.flags], eax

; now delete the line
        stdcall TFreshEdit.__FixLength, esi, -1, [edx+TEditorLine.width]
        stdcall StrDel, [edx+TEditorLine.Data]
        stdcall DeleteArrayItems, [esi+TFreshEdit._pLines], [.del_line_index], 1
        mov     [esi+TFreshEdit._pLines], edx

; then fix the index.
        mov     edi, [esi+TFreshEdit._pIndex]
        mov     eax, [esi+TFreshEdit._yCaret]
        mov     edx, [.del_line_index]
        inc     eax

.char_fix_index:
        cmp     eax, [edi+TArray.count]
        jae     .end_del_char

        cmp     [edi+TArray.array+4*eax], -1
        je      .next_line_fix
        cmp     [edi+TArray.array+4*eax], edx
        je      .del_index_elements

        dec     [edi+TArray.array+4*eax]

.next_line_fix:
        inc     eax
        jmp     .char_fix_index

.del_index_elements:
        mov     ecx, eax

.char_scan_loop:
        inc     ecx
        cmp     ecx, [edi+TArray.count]
        jae     .end_char_scan
        cmp     [edi+TArray.array+4*ecx], -1
        je      .char_scan_loop

.end_char_scan:
        sub     ecx, eax
        stdcall DeleteArrayItems, edi, eax, ecx
        mov     [esi+TFreshEdit._pIndex], edx
        mov     edi, edx
        mov     edx, [.del_line_index]
        jmp     .char_fix_index

;.........................................................................................
.insert_char:
; arguments
virtual at ebx
  .ins_char dd ?
end virtual

        push    ecx edx esi edi

        mov     esi, [.self]
.ins_loop:
        stdcall TFreshEdit.__PosToPointer, esi, [esi+TFreshEdit._xCaret], [esi+TFreshEdit._yCaret]
        jnc     .line_found

        execute [.self], TFreshEdit.InsertLine, -2
        jnc     .ins_loop                               ; possible hang!

        xor     edx, edx
        jmp     .end_ins_char

.line_found:
        test    [edx+TEditorLine.flags], lfProtected
        jz      .not_protected

        lea     edx, [eax+ecx]
        jmp     .end_ins_char

.not_protected:
        cmp     [.ins_char], $0d
        je      .split_here
        cmp     [.ins_char], $0a
        je      .split_here

        jecxz   .spaces_ok

.addspc2:
        stdcall StrCharInsert, [edx+TEditorLine.Data], ' ', eax
        inc     eax
        loop    .addspc2

.spaces_ok:
.do_ins_char:
        stdcall StrCharInsert, [edx+TEditorLine.Data], [.ins_char], eax
        mov     esi, eax
        stdcall DecodeUtf8, [.ins_char]
        add     edx, esi
        jmp     .end_ins_char

.split_here:
        push    eax edx

        mov     eax, [esi+TFreshEdit._yCaret]
        inc     eax
        execute [.self], TFreshEdit.InsertLine, eax
        mov     edi, eax

        pop     edx eax
        stdcall StrSplit, [edx+TEditorLine.Data], eax

        stdcall StrDel, [edi+TEditorLine.Data]
        mov     [edi+TEditorLine.Data], eax

        mov     eax, [esi+TFreshEdit._yCaret]
        inc     eax
        execute esi, TFreshEdit.FormatLine, eax
        execute esi, TFreshEdit.FormatLine, [esi+TFreshEdit._yCaret]

.split_ok:
        execute esi, TFreshEdit.LineBegin
        execute esi, TFreshEdit.Move, mvcMoveY, 1, TRUE
        xor     edx, edx

.end_ins_char:
        push    edx
        mov     esi, [.self]
        stdcall TFreshEdit.__PointerToPos, [.self], [esi+TFreshEdit._yCaret], edx
        mov     [esi+TFreshEdit._xCaret], edx
        mov     [esi+TFreshEdit._yCaret], eax
        pop     eax
        clc
        pop     edi esi edx ecx
        return
;.........................................................................................

.insert_string:
; arguments
virtual at ebx
  .hstring dd ?
end virtual

        push    ecx edx esi

        stdcall StrPtr, [.hstring]
        mov     esi, eax

.char_loop:
        stdcall DecodeUtf8, [esi]
        jc      .end_ins_str

        mov     eax, [esi]
        add     esi, edx

        lea     ecx, [8*edx]
        mov     edx, 1
        shl     edx, cl
        dec     edx
        and     eax, edx

        cmp     eax, 0
        je      .end_ins_str

        cmp     eax, $0d
        je      .ins_cr
        cmp     eax, $0a
        jne     .ins_it

.ins_cr:
        xor     al, $0d xor $0a
        cmp     al, [esi]
        je      .char_loop

.ins_it:
        execute [.self], TFreshEdit.InsertChar, eax
        jmp     .char_loop

.end_ins_str:
        clc
        pop     esi edx ecx
        return

;.........................................................................................
.linebegin:
        stdcall TFreshEdit.__FitCaretInWindow, [.self]
        jnz     .endlb

        mov     eax, [.self]
        mov     [eax+TFreshEdit._xCaret], 0
        mov     [eax+TFreshEdit._LeftColumn], 0

.endlb:
        clc
        return

;.........................................................................................
.lineend:
        push    ecx edx esi edi
        mov     esi, [.self]

        stdcall TFreshEdit.__FitCaretInWindow, esi
        jnz     .endle

        mov     esi, [.self]
        mov     ecx, [esi+TFreshEdit._yCaret]
        mov     ebx, [esi+TFreshEdit._pIndex]

        stdcall TFreshEdit.__PosToPointer, esi, [esi+TFreshEdit._xCaret], [esi+TFreshEdit._yCaret]
        mov     ebx, eax

        stdcall StrPtr, [edx+TEditorLine.Data]
        mov     edi, eax

; search the end of the current line
.el_loop:
        stdcall DecodeUtf8, [edi+ebx]
        test    eax, eax
        jz      .el_found
        cmp     eax, $01
        je      .el_found

        add     ebx, edx
        jmp     .el_loop

.el_found:
        stdcall TFreshEdit.__PointerToPos, esi, [esi+TFreshEdit._yCaret], ebx
        mov     [esi+TFreshEdit._yCaret], eax
        mov     [esi+TFreshEdit._xCaret], edx

.endle:
        stdcall TFreshEdit.__FitCaretInWindow, esi
        pop     edi esi edx ecx
        clc
        return

;.........................................................................................
; The method TFreshEdit.Move moves the caret towards given direction and on
; the given count of steps.
;
.movecaret:
virtual at ebx
  .direction dd ?
  .count     dd ?
  .force     dd ?
end virtual

        push    edx esi edi


        mov     esi, [.self]

        test    [.direction], mvcMoveX or mvcMoveY
        jz      .fitok

        cmp     [.force], 0
        jne     .fitok

        stdcall TFreshEdit.__FitCaretInWindow, esi

        test    eax, eax
        jnz     .endmove

.fitok:
        test    [.direction], mvcMoveX or mvcScrollX
        jnz     .move_horizontal

        test    [.direction], mvcMoveY or mvcScrollY
        jnz     .move_vertical

.endmove:
        clc
        pop     edi esi edx
        return


.move_horizontal:
        test    [.direction], mvcMoveX
        jz      .xcaretok

        mov     ecx, [esi+TFreshEdit._xCaret]
        add     ecx, [.count]
        jns     @f
        xor     ecx, ecx
@@:
        mov     [esi+TFreshEdit._xCaret], ecx

.xcaretok:
        test    [.direction], mvcScrollX
        jz      .leftcolok

        mov     ecx, [esi+TFreshEdit._LeftColumn]
        add     ecx, [.count]
        jns     @f
        xor     ecx, ecx
@@:
        mov     [esi+TFreshEdit._LeftColumn], ecx

.leftcolok:

        mov     ecx, [esi+TFreshEdit._xCaret]
        mov     edx, [esi+TFreshEdit._LeftColumn]
        cmp     ecx, edx
        jb      .hscroll
        add     edx, [esi+TFreshEdit._cols]
        cmp     ecx, edx
        jb      .endmove

.hscroll:
        mov     ecx, [esi+TFreshEdit._cols]
        mov     eax, [.count]
        shr     ecx, 2
        cdq

        mov     eax, [esi+TFreshEdit._xCaret]
        sub     eax, ecx
        sub     eax, ecx
        sub     eax, ecx
        imul    edx, ecx
        sub     eax, edx
        sub     eax, edx
        jns     @f
        xor     eax, eax
@@:
        mov     [esi+TFreshEdit._LeftColumn], eax
        jmp     .endmove

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.move_vertical:
        test    [.direction], mvcMoveY
        jz      .ycaretok

        mov     ecx, [esi+TFreshEdit._yCaret]
        add     ecx, [.count]
        jns     @f
        xor     ecx, ecx
@@:
        mov     [esi+TFreshEdit._yCaret], ecx

.ycaretok:
        test    [.direction], mvcScrollY
        jz      .toplineok

        mov     ecx, [esi+TFreshEdit._TopLine]
        add     ecx, [.count]
        jns     @f
        xor     ecx, ecx
@@:
        mov     edx, [esi+TFreshEdit._pIndex]
        mov     edx, [edx+TArray.count]
        sub     edx, [esi+TFreshEdit._rows]
        jns     @f
        xor     edx, edx
@@:
        cmp     ecx, edx
        jl      @f
        mov     ecx, edx
@@:
        mov     [esi+TFreshEdit._TopLine], ecx

.toplineok:

        mov     ecx, [esi+TFreshEdit._yCaret]
        mov     eax, [esi+TFreshEdit._pIndex]
        mov     eax, [eax+TArray.count]
        cmp     ecx, eax
        jb      @f
        lea     ecx, [eax-1]
@@:
        mov     [esi+TFreshEdit._yCaret], ecx

        mov     edx, [esi+TFreshEdit._TopLine]
        cmp     ecx, edx
        jb      .vscroll
        add     edx, [esi+TFreshEdit._rows]
        cmp     ecx, edx
        jb      .endmove

.vscroll:
        test    [.direction], mvcMoveX or mvcMoveY
        jz      .endmove                             ; it is only scroll, so don't care about caret.

; scrolls the view, in order to fit caret in window.
        mov     ecx, [esi+TFreshEdit._rows]
        mov     eax, [.count]
        neg     eax
        cdq
        mov     eax, [esi+TFreshEdit._rows]
        dec     eax
        imul    edx, eax

        mov     eax, [esi+TFreshEdit._yCaret]
        add     eax, edx
        jns     @f
        xor     eax, eax
@@:
        mov     [esi+TFreshEdit._TopLine], eax
        jmp     .endmove

;.........................................................................................
; method TFreshEdit.Clear clears the text loaded in the editor.
;
.clear:
        mov     ebx, [.self]
        mov     ebx, [ebx+TFreshEdit._pLines]
        mov     ecx, [ebx+TArray.count]
        lea     ebx, [ebx+TArray.array]

.clrloop:
        jecxz   .endclr
        stdcall StrDel, [ebx+TEditorLine.Data]
        mov     [ebx+TEditorLine.Data], 0
        add     ebx, sizeof.TEditorLine
        dec     ecx
        jmp     .clrloop

.endclr:
        mov     ebx, [.self]
        stdcall FreeMem, [ebx+TFreshEdit._pIndex]
        stdcall FreeMem, [ebx+TFreshEdit._pLines]
        stdcall FreeMem, [ebx+TFreshEdit._pLengths]

        stdcall CreateArray, 4
        mov     [ebx+TFreshEdit._pIndex], eax

        stdcall CreateArray, sizeof.TEditorLine
        mov     [ebx+TFreshEdit._pLines], eax

        stdcall CreateArray, 4
        mov     [ebx+TFreshEdit._pLengths], eax

        xor     eax, eax

        mov     [ebx+TFreshEdit._fShadowValid], eax
        mov     [ebx+TFreshEdit._xCaret], eax
        mov     [ebx+TFreshEdit._yCaret], eax
        mov     [ebx+TFreshEdit._xSelection], eax
        mov     [ebx+TFreshEdit._ySelection], eax

        execute ebx, TFreshEdit.Refresh
        stdcall TFreshEdit.__UpdateScrollBars, ebx

        clc
        return
endp



;_________________________________________________________________________________________



proc TFreshEdit.SysEventHandler, .pobj, .pEvent
.changes dd ?
begin
        push    eax ebx ecx edx esi edi

        mov     [.changes], 0
        mov     ebx, [.pEvent]
        mov     esi, [.pobj]

        mov     eax, [ebx+TSysEvent.event]

        cmp     [ebx+TSysEvent.event], seMoveResize
        je      .moveresize

        cmp     [ebx+TSysEvent.event], sePaint
        je      .paint

        cmp     [ebx+TSysEvent.event], seKbdKeyPress
        je      .keypress

        cmp     [ebx+TSysEvent.event], seFocusIn
        je      .focusin

        cmp     [ebx+TSysEvent.event], seFocusOut
        je      .focusout

        cmp     [ebx+TSysEvent.event], seScroll
        je      .scroll

        cmp     [ebx+TSysEvent.event], seMouseBtnPress
        je      .mousebtnpress

        cmp     [ebx+TSysEvent.event], seMouseBtnRelease
        je      .mousebtnrelease

        cmp     [ebx+TSysEvent.event], seMouseMove
        je      .mousemove


.continue:
        stc
.finish:
        pop     edi esi edx ecx ebx eax
        return

;.........................................................................................
.mousemove:
        mov     ecx, mcText
        mov     eax, [ebx+TMouseMoveEvent.x]
        cmp     eax, [esi+TFreshEdit.__LeftMargin]
        ja      @f
        mov     ecx, mcArrow
@@:
        mov     [esi+TFreshEdit._cursor], ecx

        cmp     [esi+TFreshEdit._DragButton], mbLeft
        jne     .continue

        stdcall TFreshEdit.__MoveCaretToPixel, esi, [ebx+TMouseMoveEvent.x], [ebx+TMouseMoveEvent.y]
        jc      .continue
        jmp     .refresh

;.........................................................................................
.mousebtnrelease:
        mov     eax, [ebx+TMouseButtonEvent.Button]
        cmp     eax, [esi+TFreshEdit._DragButton]
        jne     .continue

        stdcall MouseCapture, 0
        mov     [esi+TFreshEdit._DragButton], -1
        jmp     .continue

;.........................................................................................
.mousebtnpress:
        mov     ecx, [ebx+TMouseButtonEvent.x]
        mov     edx, [esi+TFreshEdit._FreeArea.x]
        cmp     ecx, edx
        jl      .continue

        add     edx, [esi+TFreshEdit._FreeArea.width]
        cmp     ecx, edx
        jge     .continue

        mov     eax, [ebx+TMouseButtonEvent.y]
        mov     edx, [esi+TFreshEdit._FreeArea.y]
        cmp     eax, edx
        jl      .continue

        add     edx, [esi+TFreshEdit._FreeArea.height]
        cmp     eax, edx
        jge     .continue

        mov     edx, [esi+TFreshEdit.__LeftMargin]
        cmp     ecx, edx
        jl      .left_margin_process

        stdcall MouseCapture, [esi+TWindow.handle]
        mov     eax, [ebx+TMouseButtonEvent.Button]
        mov     [esi+TFreshEdit._DragButton], eax

        cmp     [ebx+TMouseButtonEvent.Button], mbLeft
        jne     .continue

        stdcall TFreshEdit.__MoveCaretToPixel, esi, [ebx+TMouseButtonEvent.x], [ebx+TMouseButtonEvent.y]
        jc      .continue
        jmp     .refresh

.left_margin_process:
        sub     edx, 16
        cmp     ecx, edx
        jl      .continue       ; number or breakpoint click

; Fold/unfold click
; check for the fold/unfold icon under the cursor
        xor     edx, edx
        div     [esi+TFreshEdit._fontheight]
        add     eax, [esi+TFreshEdit._TopLine]

        mov     edx, [esi+TFreshEdit._pIndex]
        cmp     eax, [edx+TArray.count]
        jae     .continue

        mov     ecx, [edx+TArray.array+4*eax]
        cmp     ecx, -1
        je      .continue       ; it is not fold icon row.

        shl     ecx, TEditorLine.shift
        add     ecx, [esi+TFreshEdit._pLines]
        add     ecx, TArray.array                       ; pointer to TEditorLine

        test    [ecx+TEditorLine.flags], lfFoldHeader
        jz      .continue

; determine what is the current state folded or expanded
locals
  .current dd ?
  .next    dd ?
endl
        mov     [.current], eax        ; current line index
        mov     ecx, [edx+TArray.array+4*eax]
        inc     ecx

.next_loop:
        inc     eax
        cmp     eax, [edx+TArray.count]
        jae     .folded

        cmp     [edx+TArray.array+4*eax], -1
        je      .next_loop

        mov     [.next], eax
        cmp     ecx, [edx+TArray.array+4*eax]         ; the next index == current+1 -> expanded
        jne     .folded

; so, fold it...
        stdcall TFreshEdit.__FoldZoneLen, esi, [.current]

        mov     ecx, [.next]
        sub     ecx, [.current]
        inc     ecx

        cmp     eax, ecx
        jbe     .continue       ; nothing to fold

        sub     eax, ecx
        stdcall DeleteArrayItems, [esi+TFreshEdit._pIndex], [.next], eax
        mov     [esi+TFreshEdit._pIndex], edx

        stdcall TFreshEdit.__UpdateScrollBars, esi
        or      [.changes], chgfNeedRefresh
        jmp     .refresh

.folded:
; the zone is folded, so restore the index items.
        stdcall TFreshEdit.__RestoreIndex, esi, [.current], [.next]
        stdcall TFreshEdit.__UpdateScrollBars, esi
        or      [.changes], chgfNeedRefresh
        jmp     .refresh

;.........................................................................................
.scroll:
        cmp     [ebx+TScrollEvent.ScrollBar], scrollX
        je      .xscroll

; yscroll
        xor     edx, edx
        mov     ecx, [ebx+TScrollEvent.Value]
        cmp     [ebx+TScrollEvent.ScrollCmd], scTrack
        je      .track

        cmp     [ebx+TScrollEvent.ScrollCmd], scWheelUp
        je      .scrollwheelup
        cmp     [ebx+TScrollEvent.ScrollCmd], scWheelDn
        je      .scrollwheeldn

        cmp     [ebx+TScrollEvent.ScrollCmd], scUp
        je      .scrollup
        cmp     [ebx+TScrollEvent.ScrollCmd], scDown
        je      .scrolldn

        jmp     .continue

; scroll down
.scrollwheeldn:
        imul    ecx, [FreshEditTheme.MouseWheel]

.scrolldn:
        execute esi, TFreshEdit.Move, mvcScrollY, ecx, FALSE
        jmp     .refresh

.scrollwheelup:
        imul    ecx, [FreshEditTheme.MouseWheel]
        neg     ecx
.scrollup:
        execute esi, TFreshEdit.Move, mvcScrollY, ecx, FALSE
        jmp     .refresh

.track:
        mov     [esi+TFreshEdit._TopLine], ecx
        jmp     .refresh

.xscroll:
        mov     eax, [ebx+TScrollEvent.Value]
        mov     [esi+TFreshEdit._LeftColumn], eax
        jmp     .refresh


;.........................................................................................

.focusin:
        cmp     [esi+TFreshEdit._fReadOnly], froReadOnlyNoCaret
        je      .continue

        stdcall CaretAttach, esi
        stdcall CaretShow, TRUE
        stdcall TFreshEdit.__UpdateCaretPosition, esi
        jmp     .continue

.focusout:
        stdcall CaretShow, FALSE
        jmp     .endmove

;.........................................................................................
.keypress:
        cmp     [ebx+TKeyboardEvent.key], $0d
        je      .insert_it

        cmp     [ebx+TKeyboardEvent.key], $09
        je      .insert_it

        cmp     [ebx+TKeyboardEvent.key], $20
        jb      .control

        cmp     [ebx+TKeyboardEvent.scancode], $ff
        ja      .control

        test    [ebx+TKeyboardEvent.kbdStatus], maskCtrl or maskAlt
        jnz     .control

.insert_it:
; insert typed character
locals
  .byte_offs dd ?
endl
        cmp     [esi+TFreshEdit._fReadOnly], froReadWrite
        jne     .refresh

        execute esi, TFreshEdit.DeleteSel
        test    eax, eax
        js      @f
        mov     [esi+TFreshEdit._yCaret], eax
        mov     [esi+TFreshEdit._xCaret], edx
@@:
        execute esi, TFreshEdit.InsertChar, [ebx+TKeyboardEvent.key]
        mov     [.byte_offs], eax

        execute esi, TFreshEdit.FormatLine, [esi+TFreshEdit._yCaret]
        add     [.byte_offs], eax

        stdcall TFreshEdit.__PointerToPos, esi, [esi+TFreshEdit._yCaret], [.byte_offs]

        mov     [esi+TFreshEdit._yCaret], eax
        mov     [esi+TFreshEdit._xCaret], edx

        stdcall TFreshEdit.__UpdateScrollBars, esi
        stdcall TFreshEdit.__FitCaretInWindow, esi

        or     [.changes], chgfNeedRefresh
        jmp    .refresh

.control:
        test    [ebx+TKeyboardEvent.kbdStatus], maskShift
        jz      @f
        or      [.changes], chgfNoClearSelection
@@:

; check the keyboard shortcuts
        lea     edi, [FreshEditTheme.shortcuts]
        xor     ecx, ecx

.shortcut_loop:
        mov     eax, [edi+TShortcut.key]
        test    eax, eax
        jz      .compare_scancode

        cmp     eax, [ebx+TKeyboardEvent.key]
        je      .found_shortcut

.next_shortcut:
        add     edi, sizeof.TShortcut
        inc     ecx
        cmp     ecx, TFETheme.shortcuts.count
        je      .external_shortcut
        jmp     .shortcut_loop

.compare_scancode:
        mov     eax, [edi+TShortcut.scancode]
        mov     edx, [edi+TShortcut.maskStatus]
        and     edx, [ebx+TKeyboardEvent.kbdStatus]
        cmp     edx, [edi+TShortcut.kbdStatus]
        jne     .next_shortcut

        cmp     eax, [ebx+TKeyboardEvent.scancode]
        jne     .next_shortcut

.found_shortcut:
        cmp     ecx, .shortcut_handlers.count
        jae     .external_shortcut

        movzx   ecx, word [.shortcut_handlers+2*ecx]
        add     ecx, .shortcut_handlers
        jmp     ecx

.shortcut_handlers:
        dw      .handler_up         - .shortcut_handlers
        dw      .handler_down       - .shortcut_handlers
        dw      .handler_left       - .shortcut_handlers
        dw      .handler_right      - .shortcut_handlers
        dw      .handler_pgup       - .shortcut_handlers
        dw      .handler_pgdn       - .shortcut_handlers
        dw      .handler_home       - .shortcut_handlers
        dw      .handler_end        - .shortcut_handlers
        dw      .handler_pgbeg      - .shortcut_handlers
        dw      .handler_pgend      - .shortcut_handlers
        dw      .handler_txtbeg     - .shortcut_handlers
        dw      .handler_txtend     - .shortcut_handlers
        dw      .handler_wordleft   - .shortcut_handlers
        dw      .handler_wordright  - .shortcut_handlers
        dw      .handler_delete     - .shortcut_handlers
        dw      .handler_linedel    - .shortcut_handlers
        dw      .handler_backspc    - .shortcut_handlers
        dw      .handler_wordwrap   - .shortcut_handlers
        dw      .handler_bookmark   - .shortcut_handlers
        dw      .handler_insmode    - .shortcut_handlers
        dw      .handler_selmode    - .shortcut_handlers
        .shortcut_handlers.count = ($ - .shortcut_handlers)/2

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_up:
        mov     eax, -1
        mov     ecx, mvcMoveY
        jmp     .moveit

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_down:
        mov     eax, 1
        mov     ecx, mvcMoveY
        jmp     .moveit

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_left:
        mov     eax, -1
        mov     ecx, mvcMoveX
        jmp     .moveit

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_right:
        mov     eax, 1
        mov     ecx, mvcMoveX
        jmp     .moveit

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_pgup:
        mov     eax, [esi+TFreshEdit._rows]
        dec     eax
        neg     eax
        mov     ecx, mvcMoveY or mvcScrollY
        jmp     .moveit

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_pgdn:
        mov     eax, [esi+TFreshEdit._rows]
        dec     eax
        mov     ecx, mvcMoveY or mvcScrollY
        jmp     .moveit


.moveit:
        test    [ebx+TKeyboardEvent.kbdStatus], maskScrLk
        jnz     .scroll_override

        cmp     [esi+TFreshEdit._fReadOnly], froReadOnlyNoCaret
        jne     .scroll_override_ok

.scroll_override:
        test    ecx, mvcMoveX
        jz      @f
        or     ecx, mvcScrollX
@@:
        test    ecx, mvcMoveY
        jz      @f
        or      ecx, mvcScrollY
@@:

.scroll_override_ok:
        execute esi, TFreshEdit.Move, ecx, eax, FALSE
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_home:
        execute esi, TFreshEdit.LineBegin
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_end:
        execute esi, TFreshEdit.LineEnd
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_pgbeg:
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_pgend:
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_txtbeg:
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_txtend:
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_wordleft:
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_wordright:
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.handler_delete:
locals
  .byte_offs2 dd ?
endl
        cmp     [esi+TFreshEdit._fReadOnly], froReadWrite
        jne     .refresh

        execute esi, TFreshEdit.DeleteSel
        test    eax, eax
        jns     .deleted

        execute esi, TFreshEdit.DelChar
        mov     [.byte_offs2], eax
        execute esi, TFreshEdit.FormatLine, [esi+TFreshEdit._yCaret]
        stdcall TFreshEdit.__PointerToPos, esi, edx, [.byte_offs2]

.deleted:
        mov     [esi+TFreshEdit._yCaret], eax
        mov     [esi+TFreshEdit._xCaret], edx

        stdcall TFreshEdit.__FitCaretInWindow, esi
        stdcall TFreshEdit.__UpdateScrollBars, esi
        or      [.changes], chgfNeedRefresh
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
; BUG:  it does not works as expected, but I don't have anough patience to fix it just now.....
.handler_backspc:
        cmp     [esi+TFreshEdit._fReadOnly], froReadWrite
        jne     .refresh

        push    [esi+TFreshEdit._xCaret] [esi+TFreshEdit._yCaret]
        execute esi, TFreshEdit.Move, mvcMoveX, -1, FALSE
        pop     edx eax

        cmp     eax, [esi+TFreshEdit._xCaret]
        jne     .do_del
        cmp     edx, [esi+TFreshEdit._yCaret]
        je      .refresh

.do_del:
        stdcall TFreshEdit.__PosToPointer, esi, [esi+TFreshEdit._xCaret], [esi+TFreshEdit._yCaret]
        test    ecx, ecx
        jnz     .refresh

        stdcall StrLen, [edx+TEditorLine.Data]
        cmp     ecx, eax
        jae     .refresh

        jmp     .handler_delete

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.handler_linedel:
        cmp     [esi+TFreshEdit._fReadOnly], froReadWrite
        jne     .refresh

        execute esi, TFreshEdit.DeleteLine, [esi+TFreshEdit._yCaret]
        mov     [esi+TFreshEdit._yCaret], eax
        mov     [esi+TFreshEdit._xCaret], 0
        stdcall TFreshEdit.__UpdateCaretPosition, esi
        stdcall TFreshEdit.__UpdateScrollBars, esi
        or      [.changes], chgfNeedRefresh
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_wordwrap:
        cmp     [esi+TFreshEdit._fReadOnly], froReadWrite
        jne     .refresh

        stdcall Get, esi, TFreshEdit.CurrentLine
        jc      .refresh

        xor     [eax+TEditorLine.flags], lfWordWrap
        execute esi, TFreshEdit.FormatLine, [esi+TFreshEdit._yCaret]
        stdcall TFreshEdit.__UpdateScrollBars, esi
        or      [.changes], chgfNeedRefresh
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_bookmark:
        cmp     [esi+TFreshEdit._fReadOnly], froReadWrite
        jne     .refresh

        stdcall Get, esi, TFreshEdit.CurrentLine
        jc      .refresh

        xor     [eax+TEditorLine.flags], lfBookmark
        or      [.changes], chgfNeedRefresh or chgfNoClearSelection
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_insmode:
        xor     [esi+TFreshEdit._InsMode], $1
        or      [.changes], chgfNoClearSelection or chgfNeedRefresh
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.handler_selmode:
        mov     eax, [esi+TFreshEdit._SelMode]
        inc     eax
        cmp     eax, selmBlock
        jbe     @f
        xor     eax, eax
@@:
        mov     [esi+TFreshEdit._SelMode], eax
        or      [.changes], chgfNoClearSelection
        jmp     .refresh

;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

.external_shortcut:
        cmp     [esi+TFreshEdit.OnControlKey], 0
        je      .refresh

        push    ebx ecx edx esi edi
        stdcall [esi+TFreshEdit.OnControlKey], esi, ebx
        pop     edi esi edx ecx ebx

        or      [.changes], eax

.refresh:
        test    [.changes], chgfNoClearSelection
        jnz     .selectionchanged

        cmp     [ebx+TSysEvent.event], seScroll
        je      .selectionchanged

        cmp     [ebx+TSysEvent.event], seMouseMove
        je      .selectionchanged

        cmp     [ebx+TSysEvent.event], seMouseBtnPress
        jne     .clearsel


.clearsel:
        push    [esi+TFreshEdit._xCaret] [esi+TFreshEdit._yCaret]
        pop     [esi+TFreshEdit._ySelection] [esi+TFreshEdit._xSelection]
        jmp     .endmove

.selectionchanged:

.endmove:
; compare fields with backup fields
        mov     eax, [esi+TFreshEdit._TopLine]
        mov     ecx, [esi+TFreshEdit._LeftColumn]
        cmp     eax, [esi+TFreshEdit._prevTopLine]
        jne     .scrolled
        cmp     ecx, [esi+TFreshEdit._prevLeftColumn]
        je      .scrollerok

.scrolled:
        stdcall TFreshEdit.__UpdateScrollBars, esi
        or      [.changes], chgfNeedRefresh
        jmp     .caretmoved

.scrollerok:
        mov     eax, [esi+TFreshEdit._xCaret]
        mov     ecx, [esi+TFreshEdit._yCaret]
        mov     edx, [esi+TFreshEdit._InsMode]
        cmp     eax, [esi+TFreshEdit._prevxCaret]
        jne     .caretmoved
        cmp     ecx, [esi+TFreshEdit._prevyCaret]
        jne     .caretmoved
        cmp     edx, [esi+TFreshEdit._prevInsMode]
        je      .caretposok

.caretmoved:
        stdcall TFreshEdit.__UpdateCaretPosition, esi

.caretposok:
        mov     eax, [esi+TFreshEdit._xSelection]
        mov     ecx, [esi+TFreshEdit._ySelection]
        sub     eax, [esi+TFreshEdit._xCaret]
        sub     ecx, [esi+TFreshEdit._yCaret]
        mov     edx, [esi+TFreshEdit._prevSelMode]

        cmp     eax, [esi+TFreshEdit._prevxDelta]
        jne     .selchanged
        cmp     ecx, [esi+TFreshEdit._prevyDelta]
        jne     .selchanged
        cmp     edx, [esi+TFreshEdit._SelMode]
        je      .selok

.selchanged:
        or      [.changes], chgfNeedRefresh
.selok:
; now save the status fields for the next pass

        mov     eax, [esi+TFreshEdit._TopLine]
        mov     ecx, [esi+TFreshEdit._LeftColumn]
        mov     [esi+TFreshEdit._prevTopLine], eax
        mov     [esi+TFreshEdit._prevLeftColumn], ecx

        mov     eax, [esi+TFreshEdit._xCaret]
        mov     ecx, [esi+TFreshEdit._yCaret]
        mov     edx, [esi+TFreshEdit._InsMode]
        mov     [esi+TFreshEdit._prevxCaret], eax
        mov     [esi+TFreshEdit._prevyCaret], ecx
        mov     [esi+TFreshEdit._prevInsMode], edx

        mov     eax, [esi+TFreshEdit._xSelection]
        mov     ecx, [esi+TFreshEdit._ySelection]
        sub     eax, [esi+TFreshEdit._xCaret]
        sub     ecx, [esi+TFreshEdit._yCaret]
        mov     edx, [esi+TFreshEdit._SelMode]
        mov     [esi+TFreshEdit._prevxDelta], eax
        mov     [esi+TFreshEdit._prevyDelta], ecx
        mov     [esi+TFreshEdit._prevSelMode], edx


        test    [.changes], chgfNeedRefresh
        jz      .finish_event

        mov     [esi+TFreshEdit._fShadowValid], 0
        execute esi, TWindow.Refresh

.finish_event:
        test    [.changes], chgfFinished
        jz      .continue
        clc
        jmp     .finish

;.........................................................................................

.paint:
        cmp     [esi+TFreshEdit._fShadowValid], 0
        jne     @f
        stdcall TFreshEdit.__DrawShadow, esi
@@:
        stdcall SetClipRectangle, [ebx+TPaintEvent.context], 0
        stdcall TScrollWindow.SysEventHandler, [.pobj], [.pEvent]
        stdcall DrawBackBuffer, [ebx+TPaintEvent.context], [esi+TFreshEdit._pShadow], 0, 0

        clc
        jmp     .finish

;.........................................................................................

.moveresize:
        stdcall Get, esi, TFreshEdit.FreeArea

        cmp     [esi+TFreshEdit._fontwidth], 0
        je      .continue
        cmp     [esi+TFreshEdit._fontheight], 0
        je      .continue

        stdcall TFreshEdit.__ComputeLeftMargin, esi

        mov     eax, [esi+TFreshEdit._FreeArea.width]
        sub     eax, [esi+TFreshEdit.__LeftMargin]
        xor     edx, edx
        div     [esi+TFreshEdit._fontwidth]
        mov     [esi+TFreshEdit._cols], eax

        mov     eax, [esi+TFreshEdit._FreeArea.height]
        xor     edx, edx
        div     [esi+TFreshEdit._fontheight]
        mov     [esi+TFreshEdit._rows], eax

        stdcall TFreshEdit.__UpdateScrollBars, esi

        stdcall DestroyBackBuffer, [esi+TFreshEdit._pShadow]
        stdcall CreateBackBuffer, [esi+TFreshEdit.handle], [esi+TFreshEdit._FreeArea.width], [esi+TFreshEdit._FreeArea.height]
        mov     [esi+TFreshEdit._pShadow], eax

        mov     [esi+TFreshEdit._fShadowValid], 0
        jmp     .continue
endp



;_________________________________________________________________________________________



proc TFreshEdit.__MoveCaretToPixel, .editor, .x, .y
begin
        push    ecx edx esi

        xor     ecx, ecx
        mov     esi, [.editor]

; x
        mov     eax, [.y]
        mov     edx, [esi+TFreshEdit._FreeArea.y]
        cmp     eax, edx
        jl      .nomove

        add     edx, [esi+TFreshEdit._FreeArea.height]
        cmp     eax, edx
        jge     .nomove

        mov     eax, [.x]
        mov     edx, [esi+TFreshEdit._FreeArea.x]
        cmp     eax, edx
        jl      .nomove

        add     edx, [esi+TFreshEdit._FreeArea.width]
        cmp     eax, edx
        jge     .nomove

        sub     eax, [esi+TFreshEdit.__LeftMargin]
        jge     @f
        xor     eax, eax
@@:
        cdq
        idiv    [esi+TFreshEdit._fontwidth]
        add     eax, [esi+TFreshEdit._LeftColumn]

        cmp     [esi+TFreshEdit._xCaret], eax
        je      @f

        test    eax, eax
        js      @f

        mov     [esi+TFreshEdit._xCaret], eax
@@:
; y
        mov     eax, [.y]
        cdq
        idiv    [esi+TFreshEdit._fontheight]
        add     eax, [esi+TFreshEdit._TopLine]

        cmp     [esi+TFreshEdit._yCaret], eax
        je      @f

        test    eax, eax
        js      @f
        mov     [esi+TFreshEdit._yCaret], eax
@@:
        mov     eax, ecx
        clc

.finish:
        pop     esi edx ecx
        return

.nomove:
        stc
        jmp     .finish
endp




proc TFreshEdit.__DrawShadow, .editor
  .context  dd  ?
  .latest   dd  ?
  .color     dd ?
  .colormask dd ?
begin
        pushad

        mov     esi, [.editor]
        mov     edi, [esi+TFreshEdit._pShadow]

        cmp     [edi+TBackBuffer.width], 1
        jle     .finish
        cmp     [edi+TBackBuffer.height], 1
        jle     .finish

        cmp     [esi+TFreshEdit._fShadowValid], 0
        jne     .finish

        stdcall AllocateContext, [edi+TBackBuffer.raster]
        mov     [.context], eax

        stdcall TFreshEdit.__ComputeLeftMargin, esi

; draw left margin field
        mov     eax, [esi+TFreshEdit.__LeftMargin]
        sub     eax, 4

        stdcall DrawFillRect, [.context], 0, 0, eax, [edi+TBackBuffer.height], [FreshEditTheme.clLeftMargin]

; clean the image. How good is to paint in double buffer - no flicker at all. :)
        inc     eax
        mov     ecx, [edi+TBackBuffer.width]
        sub     ecx, eax
        test    [FreshEditTheme.Options], eoStripedBackground
        jnz     .do_zebra

        stdcall DrawFillRect, [.context], eax, 0, ecx, [edi+TBackBuffer.height], [FreshEditTheme.clBackground]
        jmp     .leftmargin_ok

.do_zebra:
        xor     edx, edx
        mov     ebx, [FreshEditTheme.clBackground]
        mov     [.color], ebx
        xor     ebx, [FreshEditTheme.clAltBack]

        test    [esi+TFreshEdit._TopLine], 1
        jz      .zebra
        xor     [.color], ebx
.zebra:
        stdcall DrawFillRect, [.context], eax, edx, ecx, [esi+TFreshEdit._fontheight], [.color]
        add     edx, [esi+TFreshEdit._fontheight]
        xor     [.color], ebx
        cmp     edx, [edi+TBackBuffer.height]
        jb      .zebra

.leftmargin_ok:

; draw the wrap position if visible
.wrap_position:
        mov     eax, [FreshEditTheme.WrapPos]
        sub     eax, [esi+TFreshEdit._LeftColumn]
        imul    eax, [esi+TFreshEdit._fontwidth]
        add     eax, [esi+TFreshEdit.__LeftMargin]

        cmp     eax, [esi+TFreshEdit.__LeftMargin]
        jl      .wrapok
        cmp     eax, [edi+TBackBuffer.width]
        jge     .wrapok

        stdcall SetSimpleLine, [.context], [FreshEditTheme.clWrapColumn]
        stdcall DrawLine, [.context], eax, 0, eax, [edi+TBackBuffer.height]

.wrapok:
; ebx is pointer to the index array.
        mov     ebx, [esi+TFreshEdit._pIndex]

; edx is the number of the line in [pIndex]
        mov     edx, [esi+TFreshEdit._TopLine]

; ecx is the y coordinate of the line.
        mov     ecx, [esi+TFreshEdit._fontheight]
        sub     ecx, [esi+TFreshEdit._fontdescent]
;        sub     ecx, 3                                  ; this is not good.

; check the first line
.searchbegin:
        cmp     [ebx+TArray.array+4*edx], -1
        jne     .lineloop

        sub     ecx, [esi+TFreshEdit._fontheight]
        dec     edx
        jnz     .searchbegin

; so draw the lines.
.lineloop:
        mov     eax, ecx
        sub     eax, [esi+TFreshEdit._fontheight]
        add     eax, [esi+TFreshEdit._fontdescent]
        cmp     eax, [edi+TBackBuffer.height]
        jge     .endlines

        cmp     edx, [ebx+TArray.count]
        jae     .endlines

; call the TFreshEditLineType.procDraw for the current line type.
        stdcall TFreshEdit.__DrawLine, esi, [.context], edx, ecx
        add     ecx, [esi+TFreshEdit._fontheight]

        inc     edx
        jmp     .lineloop

.endlines:
; fix the left line border to the end of the windows.
        add     ecx, [esi+TFreshEdit._fontdescent]
        mov     eax, [esi+TFreshEdit.__LeftMargin]
        sub     ecx, [esi+TFreshEdit._fontheight]
        sub     eax, 2
        stdcall SetSimpleLine, [.context], [FreshEditTheme.clLeftMarginBorder]
        stdcall DrawLine, [.context], eax, ecx, eax, [edi+TBackBuffer.height]
        stdcall SetSimpleLine, [.context], [FreshEditTheme.clLeftMargin]
        dec     eax
        stdcall DrawLine, [.context], eax, ecx, eax, [edi+TBackBuffer.height]
        dec     eax
        stdcall DrawLine, [.context], eax, ecx, eax, [edi+TBackBuffer.height]

        stdcall ReleaseContext, [.context]

.finish:
        mov     [esi+TFreshEdit._fShadowValid], 1

        popad
        return
endp



proc TFreshEdit.__DrawLine, .editor, .context, .indexLine, .y
  .line   dd  ?
  .last_line dd ?

  .attr   dd  ?
  .ysel0  dd  ?
  .xsel0  dd  ?
  .ysel1  dd  ?
  .xsel1  dd  ?

  .unfold dd  ?

  .next   dd  ?
  .markh  dd  ?

  .linenumber dd ?

  .fold_icon dd ?
  .fold_line dd ?

begin
        pushad

        mov     edi, [.editor]

        mov     [.line], -1
        mov     [.unfold], 0

        mov     eax, [.indexLine]
        lea     ecx, [eax+1]
        mov     edx, [edi+TFreshEdit._pIndex]

.nextloop:
        cmp     ecx, [edx+TArray.count]
        jae     .unfoldok
        cmp     [edx+TArray.array+4*ecx], -1
        jne     @f
        inc     ecx
        jmp     .nextloop
@@:
        push    ecx
        mov     ecx, [edx+TArray.array+4*ecx]
        dec     ecx
        cmp     ecx, [edx+TArray.array+4*eax]
        pop     ecx
        je      .unfoldok

        mov     [.unfold], 1

.unfoldok:
        mov     [.next], ecx

; if the line is part of the word-wrapped line, don't draw the text, because it is already OK.
        mov     edx, [edx+TArray.array+4*eax]     ; index in pLines
        mov     [.linenumber], edx
        inc     [.linenumber]           ; count it from 1
        cmp     edx, -1
        je      .end_draw_text       ; wrapped line.

        mov     eax, [edi+TFreshEdit._pLines]
        mov     [.last_line], 0
        mov     eax, [eax+TArray.count]
        dec     eax
        cmp     eax, edx
        jne     @f
        inc     [.last_line]    ; flag that this line is the last line.
@@:
        shl     edx, TEditorLine.shift
        add     edx, [edi+TFreshEdit._pLines]
        add     edx, TArray.array
        mov     [.line], edx                      ; pointer to TEditorLines

; draw the text of the line
;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
        stdcall StrLen, [edx+TEditorLine.Data]
        test    eax, eax
        jz      .empty_string

        mov     ecx, eax
        shl     eax, 4          ; sizeof.TCharAttr =  16

        stdcall GetMem, eax     ; attr array.
        mov     [.attr], eax
        mov     esi, eax

        mov     ebx, [FreshEditTheme.clSimpleText]
        test    [edx+TEditorLine.flags], lfProtected
        jz      @f
        mov     ebx, [FreshEditTheme.clProtectedText]
@@:
        mov     edx, [edi+TFreshEdit._Font]

; fill the attribute array with the default values.
.attrloop:
        mov     [esi+TCharAttr.color], ebx
        mov     [esi+TCharAttr.font], edx
        lea     esi, [esi+sizeof.TCharAttr]
        loop    .attrloop

        mov     edx, [.line]
        test    [edx+TEditorLine.flags], lfProtected
        jnz     .syntaxok

; Call the syntax highlighter if any:
        xor     ecx, ecx
        cmp     [.indexLine], ecx
        je      @f
        mov     ecx, [edx-sizeof.TEditorLine+TEditorLine.syn_context]
@@:
        cmp     [edi+TFreshEdit._procSyntax], 0
        je      .syntaxok

        push    edi edx
        stdcall [edi+TFreshEdit._procSyntax], [edx+TEditorLine.Data], [.attr], ecx
        pop     edx edi
        mov     [edx+TEditorLine.syn_context], eax

.syntaxok:
        stdcall StrPtr, [edx+TEditorLine.Data]
        cmp     byte [eax], 0
        je      .end_draw_text

        stdcall DrawColoredString, [.context], eax, [.attr], [eax+string.len], [edi+TFreshEdit.__LeftMargin],     \
                                   [.y], [edi+TFreshEdit._LeftColumn], [edi+TFreshEdit._fontwidth], [edi+TFreshEdit._fontheight]

        stdcall FreeMem, [.attr]

.end_draw_text:

; draw left margin graphics:
        stdcall TFreshEdit.__DrawLeftMargin, edi, [.context], [.indexLine]

; now draw transparent selection

; selection bounds.
        mov     eax, [edi+TFreshEdit._xSelection]
        mov     ecx, [edi+TFreshEdit._ySelection]
        mov     ebx, [edi+TFreshEdit._xCaret]
        mov     edx, [edi+TFreshEdit._yCaret]

        cmp     ecx, edx
        jl      @f
        je      .sortx
        xchg    ecx, edx
        cmp     [edi+TFreshEdit._SelMode], selmChar
        jne     @f
        xchg    eax, ebx
@@:
        cmp     [edi+TFreshEdit._SelMode], selmChar
        je      .endsort

.sortx:
        cmp     eax, ebx
        jle     @f
        xchg    eax, ebx
@@:

.endsort:
        mov     [.xsel0], eax
        mov     [.ysel0], ecx
        mov     [.xsel1], ebx
        mov     [.ysel1], edx

        mov     eax, [.indexLine]
        cmp     eax, [.ysel0]
        jl      .end_sel
        cmp     eax, [.ysel1]
        jg      .end_sel

        mov     eax, [edi+TFreshEdit._SelMode]

        cmp     eax, selmChar
        je      .selchar

; sel block
        mov     eax, [.xsel0]
        cmp     eax, [.xsel1]
        je      .end_sel

        sub     eax, [edi+TFreshEdit._LeftColumn]
        jge     @f
        xor     eax, eax
@@:
        imul    eax, [edi+TFreshEdit._fontwidth]
        add     eax, [edi+TFreshEdit.__LeftMargin]

        mov     ecx, [.xsel1]
        sub     ecx, [edi+TFreshEdit._LeftColumn]
        jge     @f
        xor     ecx, ecx
@@:
        imul    ecx, [edi+TFreshEdit._fontwidth]
        add     ecx, [edi+TFreshEdit.__LeftMargin]
        sub     ecx, eax
        jmp     .drawsel

.selchar:
        xor     eax, eax
        mov     edx, [.indexLine]
        cmp     edx, [.ysel0]
        jne     .firstok

        mov     eax, [.xsel0]
        sub     eax, [edi+TFreshEdit._LeftColumn]
        jge     .firstok
        xor     eax, eax

.firstok:
        imul    eax, [edi+TFreshEdit._fontwidth]
        add     eax, [edi+TFreshEdit.__LeftMargin]

        mov     ecx, [edi+TFreshEdit._cols]    ; selection is to the end of the line, for the intermediate lines.
        inc     ecx

        cmp     edx, [.ysel1]
        jne     .lastok

        mov     ecx, [.xsel1]
        sub     ecx, [edi+TFreshEdit._LeftColumn]
        test    ecx, ecx
        jns     .lastok
        xor     ecx, ecx

.lastok:
        imul    ecx, [edi+TFreshEdit._fontwidth]
        add     ecx, [edi+TFreshEdit.__LeftMargin]
        sub     ecx, eax

.drawsel:
        mov     edx, [.y]
        sub     edx, [edi+TFreshEdit._fontheight]
        add     edx, 3

        stdcall SetDrawMode, [.context], [FreshEditTheme.clSelMode]
        stdcall DrawFillRect, [.context], eax, edx, ecx, [edi+TFreshEdit._fontheight], [FreshEditTheme.clSelBack]
        stdcall SetDrawMode, [.context], cmCopy

.end_sel:
        popad
        return

.empty_string:
        mov     eax, [.indexLine]
        mov     ecx, [FreshEditTheme.clBackground]
        cmp     eax, [.ysel0]
        jb      .setback
        cmp     eax, [.ysel1]
        jae     .setback

        mov     ecx, [FreshEditTheme.clSelBack]

.setback:
        jmp     .end_draw_text

endp





proc TFreshEdit.__DrawLeftMargin, .editor, .context, .indexLine

.x         dd ?
.y         dd ?
.width     dd ?
.height    dd ?

.ytext     dd ?
.yicons    dd ?

.unfold    dd ?  ; is the line folded?
.indexNext dd ?  ; the index of the next line in TFreshEdit._pIndex

.ipLines   dd ?  ; the index of the current line in pLines array.
.ptrLine   dd ?  ; pointer of the current TEditorLine.

.fold_icon dd ?
.fold_line dd ?

begin
        pushad

        mov     esi, [.editor]

        test    [FreshEditTheme.Options], eoLeftMargin
        jz      .finish

        stdcall SetDrawMode, [.context], cmCopy

; search for the next line index;
        mov     ecx, [.indexLine]
        mov     edx, [esi+TFreshEdit._pIndex]
        cmp     [edx+TArray.array+4*ecx], -1
        je      .finish

        mov     [.unfold], 0

        xor     eax, eax
        dec     eax

.nextloop:
        inc     ecx
        cmp     ecx, [edx+TArray.count]
        jae     .found_next

        cmp     [edx+TArray.array+4*ecx], eax
        je      .nextloop

.found_next:
        mov     [.indexNext], ecx

        mov     eax, [.indexLine]
        mov     eax, [edx+TArray.array+4*eax]   ; current line - index in pLines
        mov     [.ipLines], eax

        cmp     ecx, [edx+TArray.count]
        jae     .unfoldok

        mov     ecx, [edx+TArray.array+4*ecx]   ; next line index in pLines
        dec     ecx
        cmp     ecx, eax
        setne   byte [.unfold]

.unfoldok:
        mov     edx, eax
        shl     edx, TEditorLine.shift
        add     edx, TArray.array
        add     edx, [esi+TFreshEdit._pLines]
        mov     [.ptrLine], edx

; determine the bounds of the drawing
        mov     ecx, [.indexNext]
        sub     ecx, [.indexLine]
        mov     eax, [esi+TFreshEdit.__LeftMargin]
        imul    ecx, [esi+TFreshEdit._fontheight]
        mov     [.width], eax
        mov     [.height], ecx

        xor     eax, eax
        mov     [.x], eax

        mov     eax, [.indexLine]
        sub     eax, [esi+TFreshEdit._TopLine]
        imul    eax, [esi+TFreshEdit._fontheight]
        mov     [.y], eax                               ; it can be negative for the word wrapped lines, partially displayed.

        add     eax, [esi+TFreshEdit._fontheight]
        sub     eax, [esi+TFreshEdit._fontdescent]
        mov     [.ytext], eax

        mov     ecx, [esi+TFreshEdit._iconBreakpointA]
        mov     eax, [esi+TFreshEdit._fontheight]
        sub     eax, [ecx+TImage.height]
        sar     eax, 1
        adc     eax, [.y]
        mov     [.yicons], eax

; draw the bookmark background.
        test    [edx+TEditorLine.flags], lfBookmark
        jz      .bookmarkok
        mov     eax, [.width]
        sub     eax, 4
        stdcall DrawFillRect, [.context], [.x], [.y], eax, [.height], [FreshEditTheme.clBookmarkBack]
.bookmarkok:

; draw the cutted right border:
        mov     eax, [.width]
        mov     ecx, [.y]
        sub     eax, 2
        add     ecx, [.height]

        stdcall SetSimpleLine, [.context], [FreshEditTheme.clLeftMarginBorder]

        test    [edx+TEditorLine.flags], lfWordWrap
        jnz     .wrap_border

        stdcall DrawLine, [.context], eax, [.y], eax, ecx

        mov     ebx, [FreshEditTheme.clLeftMargin]
        test    [edx+TEditorLine.flags], lfBookmark
        jz      @f
        mov     ebx, [FreshEditTheme.clBookmarkBack]
@@:
        stdcall SetSimpleLine, [.context], ebx
        dec     eax
        stdcall DrawLine, [.context], eax, [.y], eax, ecx
        dec     eax
        stdcall DrawLine, [.context], eax, [.y], eax, ecx
        jmp     .borderok

.wrap_border:
        dec     ecx

        push    ecx  eax [.y] eax [.context]       ; vertical
        push    [.y] eax [.y] eax [.context]       ; upper edge
        push    ecx  eax ecx  eax [.context]       ; down edge

        sub     dword [esp+12], 2
        sub     dword [esp+16], 2
        stdcall DrawLine

        sub     dword [esp+12], 2
        add     dword [esp+16], 2
        stdcall DrawLine

        sub     dword [esp+4], 2
        add     dword [esp+8], 2
        sub     dword [esp+12], 2
        sub     dword [esp+16], 1
        stdcall DrawLine

        mov     ebx, [FreshEditTheme.clLeftMargin]
        test    [edx+TEditorLine.flags], lfBookmark
        jz      @f
        mov     ebx, [FreshEditTheme.clBookmarkBack]
@@:
        stdcall SetSimpleLine, [.context], ebx

        push    [.y] eax [.y] eax [.context]       ; upper edge
        push    [.y] eax [.y] eax [.context]       ; upper edge
        push    ecx  eax ecx  eax [.context]       ; down corner pixels
        push    ecx  eax ecx  eax [.context]       ; down corner pixels

        sub     dword [esp+4], 2
        stdcall DrawLine

        sub     dword [esp+4], 2
        sub     dword [esp+8], 1
        sub     dword [esp+12], 2
        stdcall DrawLine

        sub     dword [esp+4], 2
        stdcall DrawLine

        sub     dword [esp+4], 2
        add     dword [esp+8], 1
        sub     dword [esp+12], 2
        stdcall DrawLine

.borderok:
; Line number draw
        test    [FreshEditTheme.Options], eoLineNumbers
        jz      .line_numbers_ok

        mov     ecx, [.ipLines]
        test    ecx, ecx
        jl      .line_numbers_ok

        inc     ecx
        stdcall NumToStr, ecx, ntsDec or ntsUnsigned
        push    eax eax
        stdcall StrLen, eax
        mov     ecx, eax
        stdcall StrPtr ; from the stack
        mov     ebx, eax

        stdcall GetTextBounds, [.context], eax, ecx, 0 ; [edi+TFreshEdit._Font]
        sub     eax, [esi+TFreshEdit.__NumberMargin]
        neg     eax
        stdcall DrawString, [.context], ebx, ecx, eax, [.ytext], 0, [FreshEditTheme.clLeftMarginText]
        stdcall StrDel ; from the stack

.line_numbers_ok:
; draw icons in the middle

; icon breakpoint
        mov     edx, [.ptrLine]
        test    [edx+TEditorLine.flags], lfBreakpoint
        jnz     .draw_breakpoint

        cmp     [edx+TEditorLine.debugdata], 0
        je      .breakpoint_ok

.draw_breakpoint:
        mov     eax, [esi+TFreshEdit.__NumberMargin]
        add     eax, 3
        push    [.yicons] eax ; coordinates

        mov     eax, [esi+TFreshEdit._maskDebugInfo]
        mov     ecx, [esi+TFreshEdit._iconDebugInfo]
        test    [edx+TEditorLine.flags], lfBreakpoint
        jz      @f
        mov     eax, [esi+TFreshEdit._maskBreakpointA]
        mov     ecx, [esi+TFreshEdit._iconBreakpointA]
        cmp     [edx+TEditorLine.debugdata], 0
        jne     @f
        mov     eax, [esi+TFreshEdit._maskBreakpointI]
        mov     ecx, [esi+TFreshEdit._iconBreakpointI]
@@:
        stdcall DrawMaskedImage, [.context], eax, ecx

.breakpoint_ok:

; draw fold tree.

        mov     edx, [.ptrLine]

; first, determine, what icon should be set for fold/unfold icon:
        xor     ecx, ecx
        mov     ebx, [esi+TFreshEdit._pIndex]
        mov     eax, [.indexNext]
        cmp     eax, [ebx+TArray.count]
        jae     @f
        mov     eax, [ebx+TArray.array+4*eax]   ; index in pLines of the next visible line.
        shl     eax, TEditorLine.shift
        mov     ecx, [esi+TFreshEdit._pLines]
        lea     ecx, [ecx+TArray.array+eax]
@@:
        test    [edx+TEditorLine.flags], lfFoldHeader
        jnz     .fold_fold

        jecxz   .fold_end

        mov     eax, [ecx+TEditorLine.fold_level]
        cmp     eax, [edx+TEditorLine.fold_level]
        ja      .fold_continue
        jb      .fold_end

        test    [ecx+TEditorLine.flags], lfFoldHeader
        jz      .fold_continue

.fold_end:
        xor     eax, eax
        mov     ecx, 2          ; 2 means corner up/right
        jmp     .fold_ok

.fold_fold:
        mov     ecx, 1          ; 1 means half vertical down
        mov     eax, [esi+TFreshEdit._iconUnfold]
        cmp     [.unfold], 0
        jne     .fold_ok
        mov     eax, [esi+TFreshEdit._iconFold]
        jmp     .fold_ok

.fold_continue:
        xor     eax, eax
        xor     ecx, ecx        ; 0 means full vertical line

.fold_ok:
        mov     [.fold_icon],  eax
        mov     [.fold_line], ecx

; compute the coordinates.
.coordinates:
        mov     ecx, [.yicons]
        mov     eax, [esi+TFreshEdit.__LeftMargin]
        sub     eax, 15

; icon unfold
        cmp     [edx+TEditorLine.fold_level], 0
        je      .tree_ok

        push    eax ebx ecx
        lea     ebx, [ecx+5] ; ebx == Y middle of the icon.
        add     eax, 5       ; eax == X middle of the icon.
        mov     ecx, [.height]

        stdcall SetDrawMode, [.context], cmCopy
        stdcall SetSimpleLine, [.context], [FreshEditTheme.clLeftMarginTree]

        push    [.y] eax [.y] eax
        add     [esp+4], ecx

        cmp     [.fold_line], 0  ; full vertical.
        je      .draw_line

        push    ebx eax ebx eax
        add     dword [esp+8], 9
        stdcall DrawLine, [.context] ; coordinates from the stack

        xchg    [esp+12], ebx

        cmp     [.fold_line], 1      ; short vertical
        je      .draw_line

        xchg    [esp+4], ebx

.draw_line:
        stdcall DrawLine, [.context] ; coordinates from the stack.
        pop     ecx ebx eax

        cmp     [.fold_icon], 0
        je      .tree_ok

        stdcall DrawMaskedImage, [.context], [esi+TFreshEdit._maskUnfold], [.fold_icon], eax, ecx

.tree_ok:

.finish:
        popad
        return
endp





;_________________________________________________________________________________________
; Moves the caret to the proper pixel position, depending on caret position inside the text.
proc TFreshEdit.__UpdateCaretPosition, .editor
.width dd ?
.height dd ?
.offset dd ?
begin
        push    eax ebx edx

        mov     ebx, [.editor]


        mov     eax, [ebx+TFreshEdit._fontheight]
        mov     edx, [ebx+TFreshEdit._fontwidth]

        mov     [.offset], 0

        cmp     [ebx+TFreshEdit._InsMode], modeInsert
        jne     .sizeok

        test    [FreshEditTheme.Options], eoVerticalCaret
        jz      .hcaret
        mov     edx, 1
        jmp     .sizeok

.hcaret:
        sub     eax, 2
        mov     [.offset], eax
        mov     eax, 2

.sizeok:
        mov     [.width], edx
        mov     [.height], eax

        mov     eax, [ebx+TFreshEdit._yCaret]
        sub     eax, [ebx+TFreshEdit._TopLine]
        jl      .hideit

        cmp     eax, [ebx+TFreshEdit._rows]
        jg      .hideit

        imul    eax, [ebx+TFreshEdit._fontheight]
        add     eax, [.offset]

        mov     edx, [ebx+TFreshEdit._xCaret]
        sub     edx, [ebx+TFreshEdit._LeftColumn]
        imul    edx, [ebx+TFreshEdit._fontwidth]
        add     edx, [ebx+TFreshEdit.__LeftMargin]

        stdcall CaretChange, edx, eax, [.width], [.height]

.finish:
        pop     edx ebx eax
        return

.hideit:
        stdcall CaretChange, -1, -1, 1, 1
        jmp     .finish

endp



;_________________________________________________________________________________________

proc TFreshEdit.__UpdateScrollBars, .editor
begin
        push    eax ebx ecx edx

        mov     ebx, [.editor]

; V scroller
        mov     eax, [ebx+TFreshEdit._pIndex]
        mov     eax, [eax+TArray.count]
        sub     eax, [ebx+TFreshEdit._rows]
        mov     [ebx+TFreshEdit._VScroller.Max], eax

        mov     eax, [ebx+TFreshEdit._TopLine]
        mov     [ebx+TFreshEdit._VScroller.Pos], eax

        mov     eax, [ebx+TFreshEdit._rows]
        mov     [ebx+TFreshEdit._VScroller.Page], eax

; H scroller
        stdcall Get, ebx, TFreshEdit.MaxLineLen

        mov     ecx, [ebx+TFreshEdit._cols]
        sub     eax, ecx
        mov     [ebx+TFreshEdit._HScroller.Max], eax

        mov     [ebx+TFreshEdit._HScroller.Page], ecx
        mov     eax, [ebx+TFreshEdit._LeftColumn]
        mov     [ebx+TFreshEdit._HScroller.Pos], eax

        pop     edx ecx ebx eax
        return
endp



; if the caret is inside the window - does nothing.
; if the caret is outside the window - scrolls the text to get the caret in the window.

proc TFreshEdit.__FitCaretInWindow, .editor
begin
        push    ebx ecx edx esi
        xor     eax, eax
        mov     esi, [.editor]

; vertical
        mov     ecx, [esi+TFreshEdit._TopLine]
        mov     edx, ecx
        add     edx, [esi+TFreshEdit._rows]
        dec     edx
        mov     ebx, [esi+TFreshEdit._yCaret]

        cmp     ebx, ecx
        jb      .updown
        cmp     ebx, edx
        jbe     .checkx

.updown:
        mov     ecx, [esi+TFreshEdit._rows]
        shr     ecx, 1
        sub     ebx, ecx
        jg      @f
        xor     ebx, ebx
@@:
        mov     [esi+TFreshEdit._TopLine], ebx
        or      eax, $1

.checkx:
        mov     ecx, [esi+TFreshEdit._LeftColumn]
        mov     edx, ecx
        add     edx, [esi+TFreshEdit._cols]
        dec     edx
        mov     ebx, [esi+TFreshEdit._xCaret]

        cmp     ebx, ecx
        jb      .leftright
        cmp     ebx, edx
        jbe     .endset

.leftright:
        mov     ecx, [esi+TFreshEdit._cols]
        shr     ecx, 1
        sub     ebx, ecx
        jg      @f
        xor     ebx, ebx
@@:
        mov     [esi+TFreshEdit._LeftColumn], ebx
        or      eax, $2

.endset:
        test    eax, eax
        pop     esi edx ecx ebx
        return
endp

; Converts x,y position in the text to memory parameters
; arguments:
;   .x, .y - x and y coordinates of the position.
; returns:
; edx - pointer to the TEditorLine
; eax - byte offset inside the string that corresponds with the given position.
; ecx - count of the spaces that have to be inserted on offset eax in the string
;       in order to reach the .x coordinate (when the position is beyond the end of the line)
proc TFreshEdit.__PosToPointer, .editor, .x, .y
.pline dd ?
.start dd ?
begin
        push    ebx esi edi

        mov     edi, [.editor]
        mov     eax, [.y]
        mov     ebx, [edi+TFreshEdit._pIndex]
        cmp     eax, [ebx+TArray.count]
        jae     .error

        xor     ecx, ecx

.lineloop:
        mov     edx, [ebx+TArray.array+4*eax]
        cmp     edx, -1
        jne     .found

        inc     ecx
        dec     eax
        jns     .lineloop

.error:
        stc
        jmp     .finish

.crash_error:
        int3
        jmp     .error

; ecx is the wrapped line count.
; edx is the number of string in the lines array.
.found:
        mov     ebx, [edi+TFreshEdit._pLines]
        cmp     edx, [ebx+TArray.count]
        jae     .crash_error

        shl     edx, TEditorLine.shift
        lea     eax, [ebx+TArray.array+edx]

        mov     [.pline], eax        ; handle of the string.

        cmp     [.x], -1
        je      .only_line

        stdcall StrPtr, [eax+TEditorLine.Data]
        mov     esi, eax
        mov     [.start], eax
        jecxz   .wrapok

.wraploop:
        stdcall DecodeUtf8, dword [esi]
        add     esi, edx

        test    eax, eax
        jz      .crash_error

        cmp     eax, $01        ; line wrap char
        jne     .wraploop

        dec     ecx
        jnz     .wraploop

.wrapok:
        mov     ecx, [.x]
        jecxz   .endofstring

.charloop:
        stdcall DecodeUtf8, dword [esi]
        test    eax, eax
        jz      .endofstring
        cmp     eax, $01
        je      .endofstring

        add     esi, edx
        dec     ecx
        jnz     .charloop

.endofstring:
        sub     esi, [.start]
        mov     eax, esi

.only_line:
        mov     edx, [.pline]

        clc

.finish:
        pop     edi esi ebx
        return
endp


; Converts the pointer parameters to caret coordinate.
; arguments:
;   .index - index of the line
;   .offset - byte offset inside the string.
; returns:
;   eax - y coordinate of the caret
;   edx - x coordinate of the caret
;   ecx - pointer to the current TEditorLine

proc TFreshEdit.__PointerToPos, .editor, .index, .offset
.base dd ?
.x    dd ?
begin
        push    esi edi

        mov     esi, [.editor]
        mov     edi, [esi+TFreshEdit._pIndex]
        mov     ecx, [.index]

.line_loop:
        cmp     [edi+TArray.array+4*ecx], -1
        jne     .found
        dec     ecx
        jns     .line_loop

.error:
        stc
        jmp     .finish

.found:
        mov     [.base], ecx                ; base index
        mov     [.x], 0

        mov     ecx, [edi+TArray.array+4*ecx] ; index in pLines
        shl     ecx, TEditorLine.shift
        add     ecx, [esi+TFreshEdit._pLines]
        add     ecx, TArray.array

        cmp     [.offset], 0
        je      .ready

        stdcall StrPtr, [ecx+TEditorLine.Data]
        mov     esi, eax

.char_loop:
        stdcall DecodeUtf8, [esi]
        jc      .error
        add     esi, edx

        cmp     eax, 1  ; wrap char
        jne     .no_wrap

        inc     [.base]
        mov     [.x], -1

.no_wrap:
        inc     [.x]
        sub     [.offset], edx
        ja      .char_loop

.ready:
        mov     eax, [.base]
        mov     edx, [.x]
        clc

.finish:
        pop     edi esi
        return
endp



; .hString - the string containing the line.
;
; returns:
;   eax - the width of the line in chars.
;         if the line contains wrapped sublines,
;         the maximal length will be returned.

proc TFreshEdit.__LineWidth, .hString
.maxlen dd ?
begin
        push    esi ecx edx

        mov     [.maxlen], 0
        stdcall StrPtr, [.hString]
        mov     esi, eax

.outer:
        xor     ecx, ecx

.loop:
        stdcall DecodeUtf8, [esi]
        jc      .error

        add     esi, edx

        test    eax, eax
        jz      .endofline

        cmp     eax, $01        ; wrap char
        je      .endofline

        inc     ecx
        jmp     .loop

.endofline:
        cmp     ecx, [.maxlen]
        jbe     .maxok
        mov     [.maxlen], ecx
.maxok:
        test    eax, eax
        jnz     .outer

        mov     eax, [.maxlen]
        clc

.error:
        pop     edx ecx esi
        return
endp




proc TFreshEdit.__FixLength, .editor, .newlen, .oldlen
begin
        push    eax ecx edx esi edi

        mov     esi, [.editor]
        mov     edx, [esi+TFreshEdit._pLengths]

        mov     eax, [.oldlen]

        cmp     eax, -1
        je      .oldok

        cmp     eax, [edx+TArray.count]
        jae     .oldok  ; wrong arguments???

        cmp     [edx+TArray.array+4*eax], 0
        je      .oldok  ; wrong count.

        dec     dword [edx+TArray.array+4*eax]

.oldok:
        mov     ecx, [.newlen]

        cmp     ecx, -1
        je      .newok

        cmp     ecx, [edx+TArray.count]
        jb      .incr

        sub     ecx, [edx+TArray.count]
        inc     ecx

        stdcall AddArrayItems, edx, ecx
        mov     [esi+TFreshEdit._pLengths], edx
        mov     edi, eax
        xor     eax, eax
        rep stosd
        mov     ecx, [.newlen]

.incr:
        inc     dword [edx+TArray.array+4*ecx]

; then, shrink the array.
.newok:
        mov     ecx, [edx+TArray.count]

.searchloop:
        dec     ecx
        jz      .endsearch

        cmp     [edx+TArray.array+4*ecx], 0
        je      .searchloop

.endsearch:
        lea     eax, [ecx+1]
        sub     ecx, [edx+TArray.count]
        neg     ecx
        stdcall DeleteArrayItems, edx, eax, ecx
        mov     [esi+TFreshEdit._pLengths], edx

        pop     edi esi edx ecx eax
        return
endp



proc TFreshEdit.__ComputeLeftMargin, .editor
begin
        pushad
        mov     esi, [.editor]
        xor     ebx, ebx
        mov     [esi+TFreshEdit.__NumberMargin], ebx

        test    [FreshEditTheme.Options], eoLeftMargin
        jz      .marginok

        test    [FreshEditTheme.Options], eoLineNumbers
        jz      .marginok1

        mov     eax, [esi+TFreshEdit._pLines]
        mov     eax, [eax+TArray.count]
        test    eax, eax
        jz      .marginok1
        mov     ecx, 10

.digits:
        add     ebx, [esi+TFreshEdit._fontwidth2]
        cdq
        div     ecx
        test    eax, eax
        jnz     .digits

        mov     [esi+TFreshEdit.__NumberMargin], ebx

.marginok1:
        add     ebx, 17+11+3+1 ; 17px breakpoints and other icons; 11px fold tree; 3px word-wrap cut; 1px whitespace at the begining of the line.

.marginok:
        xchg    [esi+TFreshEdit.__LeftMargin], ebx
        cmp     ebx, [esi+TFreshEdit.__LeftMargin]
        je      .finish

        stdcall TFreshEdit.__UpdateCaretPosition, esi

.finish:
        popad
        return
endp



proc TFreshEdit.__FoldZoneLen, .editor, .index
.result dd ?
begin
        pushad

        mov     [.result], 0

        mov     esi, [.editor]
        mov     edi, [esi+TFreshEdit._pLines]
        mov     edx, [esi+TFreshEdit._pIndex]

        mov     eax, [.index]
        cmp     eax, [edx+TArray.count]
        jae     .finish

        mov     ecx, [edx+TArray.array+4*eax]   ; index of the first element.
        shl     ecx, TEditorLine.shift
        mov     ebx, [edi+TArray.array+ecx+TEditorLine.fold_level]

.loop:
        inc     [.result]
        inc     eax
        cmp     eax, [edx+TArray.count]
        je      .finish

        mov     ecx, [edx+TArray.array+4*eax]
        cmp     ecx, -1
        je      .loop

        shl     ecx, TEditorLine.shift

        cmp     [edi+TArray.array+ecx+TEditorLine.fold_level], ebx
        jb      .finish
        ja      .loop

        test    [edi+TArray.array+ecx+TEditorLine.flags], lfFoldHeader
        jz      .loop

.finish:
        popad
        mov     eax, [.result]
        return
endp


proc TFreshEdit.__RestoreIndex, .editor, .start_index, .end_index
begin
        pushad

        mov     esi, [.editor]
        mov     edi, [esi+TFreshEdit._pIndex]

        mov     eax, [.start_index]
        mov     edx, [.end_index]

        mov     ebx, [edi+TArray.array+4*edx]
        mov     ecx, [edi+TArray.array+4*eax]   ; index of the first element
        sub     ebx, ecx
        dec     ebx
        jz      .finish

        stdcall InsertArrayItems, [esi+TFreshEdit._pIndex], edx, ebx
        mov     [esi+TFreshEdit._pIndex], edx

        add     [.end_index], ebx

.fill_loop:
        inc     ecx
        mov     [eax], ecx
        add     eax, 4
        dec     ebx
        jnz     .fill_loop

        mov     ecx, [.end_index]

.format_loop:
        execute esi, TFreshEdit.FormatLine, ecx
        dec     ecx
        cmp     ecx, [.start_index]
        jne     .format_loop

.finish:
        popad
        return
endp


proc TFreshEdit.__AddFormatLine, .hstring, .format
begin
        test    [.format], lfBookmark or lfWordWrap or lfProtected
        jz      .format_ok

        stdcall StrCharCat, [.hstring], ';#F:'

        test    [.format], lfBookmark
        jz      @f
        stdcall StrCharCat, [.hstring], 'b'    ; ctrl-B == Bookmark
@@:
        test    [.format], lfWordWrap
        jz      @f
        stdcall StrCharCat, [.hstring], 'w'   ; ctrl-A == Word wrap
@@:
        test    [.format], lfProtected
        jz      @f
        stdcall StrCharCat, [.hstring], 'p'   ; ctrl-D == Protected
@@:
        stdcall StrCharCat, [.hstring], $0a0d

.format_ok:
        return
endp


; decodes format line (begining with ';#F:')
; returns:
;       CF=0 if the line contains format information.
;            eax - format flags
;            ecx - format line length;
;

proc TFreshEdit.__DecodeFormatLine, .pString
begin
        push    ebx esi

        mov     esi, [.pString]

        lodsb
        cmp     al, ';'
        jne     .not_format
        lodsb
        cmp     al, '#'
        jne     .not_format
        lodsb
        cmp     al, 'F'
        jne     .not_format
        lodsb
        cmp     al, ':'
        jne     .not_format

        xor     ebx, ebx

.format_loop:
        lodsb
        test    al, al
        jz      .not_format

        cmp     al, $0d
        je      .eol
        cmp     al, $0a
        je      .eol

        cmp     al, 'b'
        jne     @f
        or      ebx, lfBookmark
        jmp     .format_loop
@@:
        cmp     al, 'w'
        jne     @f
        or      ebx, lfWordWrap
        jmp     .format_loop
@@:
        cmp     al, 'p'
        jne     @f
        or      ebx, lfProtected
        jmp     .format_loop
@@:

.not_format:
        xor     eax, eax
        pop     esi ebx
        stc
        return

.eol:
        mov     ah, al
        xor     ah, $0a xor $0d
        lodsb
        cmp     al, ah
        je      .format_ok
        dec     esi

.format_ok:
        sub     esi, [.pString]
        mov     ecx, esi
        mov     eax, ebx
        pop     esi ebx
        clc
        return
endp


endmodule

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/FreshEdit/FreshEditThemes.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TFreshEdit themes library.
;
;  Target OS: Any
;
;  Dependencies: None
;
;  Notes:
;_________________________________________________________________________________________

module "TFreshEdit default theme"


struct TShortcut
  .key        dd  ?     ; if .key is <> 0 the scancode and .kbdStatus are not used.
  .scancode   dd  ?
  .kbdStatus  dd  ?
  .maskStatus dd  ?     ; what bits from the kbdStatus to be compared
ends


macro Shortcut .key, .scancode, .kbdstatus, .maskstatus {
        dd  .key
        dd  .scancode
        dd  .kbdstatus
        dd  .maskstatus
}


eoAutoIndents       = 1
eoSaveWithTabs      = 2
eoVerticalCaret     = 4
eoStripedBackground = 8
eoLeftMargin        = 16
eoLineNumbers       = 32


struct TFETheme
; colors
  .clBackground      dd ?       ; background color of the editor field.
  .clAltBack         dd ?       ; althernative background (when eoStripedBackground is true)
  .clSimpleText      dd ?       ; The default color of the text, when no syntax highlighter is attached.
  .clProtectedText   dd ?       ; the color of the protected line text.

  .clSelBack         dd ?       ;
  .clSelMode         dd ?       ;

  .clLeftMargin      dd ?       ; the color of the left margin field.
  .clLeftMarginBorder dd ?       ; left margin border color.
  .clLeftMarginText  dd ?
  .clLeftMarginTree  dd ?

  .clBookmarkBack    dd ?       ; background of the left margin when the bookmark is set.
  .clWrapColumn      dd ?       ; color of the line that marks word wrap column.

; options and behavior
  .Options           dd ?       ; flags eoLineSeparator, eoAutoIndents, eoSaveWithTabs, eoVerticalCaret
  .MouseWheel        dd ?       ; the count of the lines, one mouse wheel event scrolls.
  .WrapPos           dd ?       ; word wrap position for the lines that have lfWordWrap flag set.
  .UndoLevels        dd ?       ; how many levels of undo/redo to be remembered.

; keyboard shortcuts:

; navigation
  .shortcuts:
  .keyUp             TShortcut
  .keyDown           TShortcut
  .keyLeft           TShortcut
  .keyRight          TShortcut
  .keyPgUp           TShortcut
  .keyPgDn           TShortcut
  .keyHome           TShortcut
  .keyEnd            TShortcut
  .keyPageBegin      TShortcut
  .keyPageEnd        TShortcut
  .keyTextBegin      TShortcut
  .keyTextEnd        TShortcut
  .keyWordLeft       TShortcut
  .keyWordRight      TShortcut

; Edit
  .Delete            TShortcut
  .DelLine           TShortcut
  .Backspace         TShortcut

; Formating
  .ToggleWordWrap    TShortcut
  .ToggleBookmark    TShortcut

; Control
  .ToggleInsMode     TShortcut
  .ToggleSelMode     TShortcut
  .shortcuts.count = ($ - .shortcuts)/sizeof.TShortcut
ends


iglobal
  if used FreshEditThemeKeys
    FreshEditThemeKeys:
        ; colors
          dd    TFETheme.clBackground,          'cBKG'
          dd    TFETheme.clAltBack,             'cABK'
          dd    TFETheme.clSimpleText,          'cTXT'
          dd    TFETheme.clProtectedText,       'cPRT'
          dd    TFETheme.clSelBack,             'cSBK'
          dd    TFETheme.clSelMode,             'cSMD'
          dd    TFETheme.clLeftMargin,          'cMrg'
          dd    TFETheme.clLeftMarginBorder,    'cMBr'
          dd    TFETheme.clLeftMarginText,      'cMTx'
          dd    TFETheme.clLeftMarginTree,      'cMTr'
          dd    TFETheme.clBookmarkBack,        'cBMB'
          dd    TFETheme.clWrapColumn,          'cWrC'

          dd    TFETheme.Options,               'Opts'
          dd    TFETheme.MouseWheel             'nWhl'
          dd    TFETheme.WrapPos,               'WrPs'
          dd    TFETheme.UndoLevels,            'UdLv'

        ; keyboard shortcuts:
        ; navigation
          dd    TFETheme.keyUp,                 'kkUp'
          dd    TFETheme.keyDown,               'kkDn'
          dd    TFETheme.keyLeft,               'kLft'
          dd    TFETheme.keyRight,              'kRgt'
          dd    TFETheme.keyPgUp,               'kPUp'
          dd    TFETheme.keyPgDn,               'kPDn'
          dd    TFETheme.keyHome,               'kHom'
          dd    TFETheme.keyEnd,                'kEnd'
          dd    TFETheme.keyPageBegin,          'kPgB'
          dd    TFETheme.keyPageEnd,            'kPgE'
          dd    TFETheme.keyTextBegin,          'kTxB'
          dd    TFETheme.keyTextEnd,            'kTxE'
          dd    TFETheme.keyWordLeft,           'kWdL'
          dd    TFETheme.keyWordRight,          'kWdR'

        ; Edit
          dd    TFETheme.Delete,                'kDel'
          dd    TFETheme.DelLine,               'kDLn'
          dd    TFETheme.Backspace,             'kBkS'

        ; Formating
          dd    TFETheme.ToggleWordWrap,        'kWWr'
          dd    TFETheme.ToggleBookmark,        'kBkm'
          dd    TFETheme.ToggleInsMode,         'kIMd'
          dd    TFETheme.ToggleSelMode,         'kSMd'
          dd    0
  end if
endg



iglobal
  if used TFETheme.DefaultShortcuts
    TFETheme.DefaultShortcuts:
          Shortcut 0,   keyUp,     0,        maskCtrl or maskAlt    ; up
          Shortcut 0,   keyDown,   0,        maskCtrl or maskAlt    ; down
          Shortcut 0,   keyLeft,   0,        maskCtrl or maskAlt    ; left
          Shortcut 0,   keyRight,  0,        maskCtrl or maskAlt    ; right
          Shortcut 0,   keyPgUp,   0,        maskCtrl or maskAlt    ; pg up
          Shortcut 0,   keyPgDown, 0,        maskCtrl or maskAlt    ; pg dn
          Shortcut 0,   keyHome,   0,        maskCtrl or maskAlt    ; home
          Shortcut 0,   keyEnd,    0,        maskCtrl or maskAlt    ; end
          Shortcut 0,   keyHome,   maskCtrl, maskCtrl or maskAlt    ; page begin
          Shortcut 0,   keyEnd,    maskCtrl, maskCtrl or maskAlt    ; page end
          Shortcut 0,   keyPgUp,   maskCtrl, maskCtrl or maskAlt    ; text begin
          Shortcut 0,   keyPgDown, maskCtrl, maskCtrl or maskAlt    ; text end
          Shortcut 0,   keyLeft,   maskCtrl, maskCtrl or maskAlt    ; word left
          Shortcut 0,   keyRight,  maskCtrl, maskCtrl or maskAlt    ; word right
          Shortcut 0,   keyDelete, 0,        maskCtrl or maskAlt    ; delete
          Shortcut $19, 0,         0,        0                      ; del line = ctrl+Y
          Shortcut $08, 0,         0,        0                      ; back space = ctrl+H = backspace
          Shortcut $17, 0,         0,        0                      ; Toggle word wrap = ctrl+W
          Shortcut $02, 0,         0,        0                      ; Toggle bookmark = ctrl+B
          Shortcut 0,   keyInsert, 0,        maskAlt                ; Toggle insert mode
          Shortcut 0,   keyInsert, maskAlt,  maskAlt                ; Toggle selection mode
    TFETheme.DefaultShortcuts.size = ($ - TFETheme.DefaultShortcuts)/4
  end if
endg

uglobal
  FreshEditTheme TFETheme
endg

if used CFreshEdit
initialize InitFreshEditTheme
begin
        stdcall TFETheme.SetDefaultThemeWindows, FreshEditTheme
        return
endp
end if


proc TFETheme.SetDefaultThemeWindows, .ptrTheme
begin
        push    ebx ecx esi edi
        mov     ebx, [.ptrTheme]

; colors
        mov     [ebx+TFETheme.clBackground], $ffffff
        mov     [ebx+TFETheme.clAltBack],    $e8e8e8

        mov     [ebx+TFETheme.clSimpleText], $000000
        mov     [ebx+TFETheme.clProtectedText], $a0a000

        mov     [ebx+TFETheme.clSelBack], $ffff7f
        mov     [ebx+TFETheme.clSelMode], cmXor

        mov     [ebx+TFETheme.clLeftMargin],       $d0d0d8
        mov     [ebx+TFETheme.clLeftMarginBorder], $606060
        mov     [ebx+TFETheme.clLeftMarginText],   $000000
        mov     [ebx+TFETheme.clLeftMarginTree],   $9000ff
        mov     [ebx+TFETheme.clBookmarkBack],     $ffd000

        mov     [ebx+TFETheme.clWrapColumn], $c0c0ff
        mov     [ebx+TFETheme.Options], eoLeftMargin or eoLineNumbers

        mov     [ebx+TFETheme.WrapPos], 70
        mov     [ebx+TFETheme.MouseWheel], 3

        mov     esi, TFETheme.DefaultShortcuts
        lea     edi, [ebx+TFETheme.shortcuts]
        mov     ecx, TFETheme.DefaultShortcuts.size
        rep movsd

        pop     edi esi ecx ebx
        return
endp




proc TFETheme.SetDefaultThemeClassic, .ptrTheme
begin
        push    ebx ecx esi edi
        mov     ebx, [.ptrTheme]

; colors
        mov     [ebx+TFETheme.clBackground], $000080
        mov     [ebx+TFETheme.clAltBack],    $000090

        mov     [ebx+TFETheme.clSimpleText], $ffffff
        mov     [ebx+TFETheme.clProtectedText], $a0a000

        mov     [ebx+TFETheme.clSelBack], $0000ff
        mov     [ebx+TFETheme.clSelMode], cmOr

        mov     [ebx+TFETheme.clLeftMargin],      $c0c0c0
        mov     [ebx+TFETheme.clLeftMarginBorder], $ffffff
        mov     [ebx+TFETheme.clLeftMarginText],  $000000
        mov     [ebx+TFETheme.clLeftMarginTree],  $ff0000
        mov     [ebx+TFETheme.clBookmarkBack],    $ffd000

        mov     [ebx+TFETheme.clWrapColumn], $0000ff
        mov     [ebx+TFETheme.Options], eoLeftMargin or eoLineNumbers

        mov     [ebx+TFETheme.WrapPos], 70
        mov     [ebx+TFETheme.MouseWheel], 3

        mov     esi, TFETheme.DefaultShortcuts
        lea     edi, [ebx+TFETheme.shortcuts]
        mov     ecx, TFETheme.DefaultShortcuts.size
        rep movsd

        pop     edi esi ecx ebx
        return
endp





endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































Deleted freshlib/FreshEdit/fasm_syntax.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Syntax highlighter procedure for FASM syntax.
;
;  Target OS:
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________
module "FASM syntax highlighter"

ttText = 0
ttRem  = 1
ttStr  = 2
ttNum  = 3
ttChar = 4



iglobal

  var SynTheme = fasm_colors_windows

; Windows theme.

  if used fasm_colors_windows
    label fasm_colors_windows dword
      .comment      dd $808080
      .string       dd $ff0080
      .number       dd $0080ff
      .symbol       dd $000000
      .register     dd $008080
      .instruction  dd $0080ff
      .directive    dd $000080
      .preprocessor dd $008000
      .macro        dd $ff00ff
  end if

; Classic theme.

  if used fasm_colors_classic
    label fasm_colors_classic dword
      .comment      dd $a0a0a0
      .string       dd $00ffff
      .number       dd $00ffff
      .symbol       dd $d0d0d0
      .register     dd $00ff00
      .instruction  dd $ffff00
      .directive    dd $ff00ff
      .preprocessor dd $ff00ff
      .macro        dd $ff00ff
  end if
endg


;_________________________________________________________________________________________
;
; Arguments:
;   .hString - handle to the line string.
;   .pAttr   - pointer to the array of TCharAttributes for the characters of the string.
;   .SynContext - input context of the highligher.
;
; Returns:
;       eax - output context of the highligher.
;
proc SyntaxFASM, .hString, .pAttr, .SynContext
.Quo rb 4
.start dd ?
begin

        mov     edi, [.pAttr]
        mov     ebx, [SynTheme]

        stdcall StrPtr, [.hString]
        mov     esi, eax
        mov     [.start], eax

.loop:
        mov     al, [esi]
        test    al,al
        jz      .end_of_line

        cmp     [.SynContext], ttRem
        je      .endif

        cmp     [.SynContext], ttStr
        jne     .ifnotstr

        cmp     al,[.Quo]
        jne     .endif

        mov     [.SynContext], ttText
        mov     eax, ttStr
        jmp     .setcolor

.ifnotstr:
        cmp     al, ';'
        jne     .notrem

        mov     [.SynContext], ttRem
        jmp     .endif

.notrem:
        cmp     al, '"'
        je      .str
        cmp     al, "'"
        jne     .notstr

.str:
        mov     [.SynContext], ttStr
        mov     [.Quo], al
        jmp     .endif

.notstr:
        call    .CharInSymbols
        jnc     .notsym

        mov     [.SynContext], ttChar
        jmp     .endif

.notsym:
        cmp     [.SynContext], ttNum
        je      .endif

        cmp     esi, [.start]
        je      .maybenum

        cmp     [.SynContext], ttChar
        jne     .endif

; The number begins only after ttChar or at the begining of the line.
.maybenum:
        call    .CharInNum
        jnc     .notnum

        mov      [.SynContext], ttNum
        jmp      .endif

.notnum:
        mov     [.SynContext], ttText

.endif:
        mov     eax, [.SynContext]
        cmp     eax, ttText
        je      .next

.setcolor:
        cmp     [edi+TCharAttr.flags], 0
        jne     .next                           ; the char have protected attributes.

        mov     ecx, [ebx+4*eax-4]
        mov     [edi+TCharAttr.color], ecx

.next:
        add     edi, sizeof.TCharAttr
        inc     esi
        stdcall ScanForwardUtf8
        jmp     .loop

.end_of_line:
        mov     eax, ttText
        return
endp


.CharInSymbols:
        push    edi ecx

        mov     edi, symbol_characters+1
        movzx   ecx, byte [edi-1]

        repne scasb
        jne   @f
        stc
        pop     ecx edi
        ret
@@:
        clc
        pop     ecx edi
        retn


.CharInNum:
        cmp     al, '$'
        jne     @f
        stc
        retn

@@:
        cmp     al, '0'
        jb      @f
        cmp     al, '9'
        ja      @f
        stc
        retn
@@:
        clc
        retn


symbol_characters db 27
                  db 9,0Ah,0Dh,1Ah,20h,'+-/*=<>()[]{}:,|&~#`;\'

endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































Deleted freshlib/FreshEdit/images/breakpoint.gif.

cannot compute difference between binary files

Deleted freshlib/FreshEdit/images/breakpoint_inactive.gif.

cannot compute difference between binary files

Deleted freshlib/FreshEdit/images/breakpoint_mask.gif.

cannot compute difference between binary files

Deleted freshlib/FreshEdit/images/breakpoint_mask_inactive.gif.

cannot compute difference between binary files

Deleted freshlib/FreshEdit/images/debug_icon.gif.

cannot compute difference between binary files

Deleted freshlib/FreshEdit/images/debug_mask.gif.

cannot compute difference between binary files

Deleted freshlib/FreshEdit/images/fold.gif.

cannot compute difference between binary files

Deleted freshlib/FreshEdit/images/unfold.gif.

cannot compute difference between binary files

Deleted freshlib/FreshEdit/images/unfold_mask.gif.

cannot compute difference between binary files

Deleted freshlib/License.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
The Fresh Artistic License

Preamble

The intent  of  this document is to  state the conditions under which a
Package may be  copied,  such that the  Copyright Holder maintains some
semblance of  artistic control  over the  development  of  the package,
while giving  the users  of the package the right to use and distribute
the Package in a more-or-less customary fashion, plus the right to make
reasonable modifications.

Definitions:

    * "Package" refers  to  the  collection of files distributed by the
      Copyright Holder,  and derivatives  of that  collection  of files
      created through textual modification.
    * "Standard Version"  refers  to  such a Package if it has not been
      modified,  or has  been modified in accordance with the wishes of
      the Copyright Holder.
    * "Copyright Holder"  is  whoever  is  named  in  the  copyright or
      copyrights for the package.
    * "You"  is  you,  if you're thinking about copying or distributing
      this Package.
    * "Reasonable copying fee" is whatever you can justify on the basis
      of media cost,  duplication charges, time of people involved, and
      so on. (You  will  not be required to justify it to the Copyright
      Holder, but  only to the computing community at large as a market
      that must bear the fee.)
    * "Freely Available"  means  that  no  fee  is charged for the item
      itself,  though  there may be fees involved in handling the item.
      It  also  means  that recipients of the  item may redistribute it
      under the same conditions they received it.

IMPORTANT NOTE: 
    FASM compiler itself,  which  is  integral  part of this package is 
    distributed under  different  license.  All  source  files  of FASM 
    compiler are separated in "source\fasm\" directory. Please read and 
    apply "source\fasm\license.txt" for FASM license.

1. You may make and give away verbatim copies of the source form of the
   Standard Version  of this Package without restriction, provided that
   you duplicate all  of the  original copyright notices and associated
   disclaimers.

2. You may apply bug fixes, portability fixes  and other  modifications 
   from the Copyright Holder  or those  derived  from the Public Domain 
   and approved by the  Copyright Holder.  A Package modified in such a 
   way shall still be considered the Standard Version.

3. You  may  otherwise  modify  your  copy  of this Package in any way,
   provided  that you  insert  a prominent notice  in each changed file
   stating how and when you changed that file, and provided that you do
   at least ONE of the following:

    a) place your modifications in the Public Domain or  otherwise make
       them Freely Available, such as by posting said  modifications to
       Usenet or an equivalent medium, or placing the  modifications on
       a major  archive site  such as  ftp.uu.net,  or by  allowing the
       Copyright Holder  to include  your modifications in the Standard
       Version of the Package.

    b) use   the  modified  Package  only  within  your  corporation or
       organization.

    c) rename any non-standard executables so the names do not conflict
       with  standard  executables,  which  must  also be provided, and
       provide a separate manual page for each  non-standard executable
       that clearly documents how it differs from the Standard Version.

    d) make other distribution arrangements with the Copyright Holder.

4. You may  distribute  the programs  of this Package in object code or
   executable form, provided that you do at least ONE of the following:

    a) distribute  a  Standard  Version  of the executables and library
       files,  together  with  instructions  ( in  the  manual  page or
       equivalent) on where to get the Standard Version.

    b) accompany  the  distribution with the machine-readable source of
       the Package with your modifications.

    c) accompany any non-standard executables with their  corresponding
       Standard    Version   executables,   giving   the   non-standard
       executables  non-standard  names,  and  clearly  documenting the
       differences  in  manual  pages  (or equivalent),  together  with
       instructions on where to get the Standard Version.

    d) make other distribution arrangements with the Copyright Holder.

5. You may charge a reasonable copying fee for any distribution of this
   Package.  You  may  charge  any  fee  you choose for support of this
   Package. You may not charge a fee for this  Package itself. However,
   you may  distribute  this  Package in aggregate with other (possibly
   commercial)  programs  as  part  of  a  larger (possibly commercial)
   software  distribution  provided  that  you  do  not  advertise this
   Package as a product of your own.

6. The executable and library files supplied as input to or produced as
   output from the  programs  of this Package do not automatically fall
   under  the  copyright  of  this  Package,  but  belong  to  whomever
   generated  them, and may be sold commercially, and may be aggregated
   with this Package.

7. You may not use this package,  nor files created as output from this
   package,  nor  products  derived  from  this  package for producing,
   distrubuting  or  in  any   way   contribute   to  the  creation  or
   distribution of "unwanted advertisement" (known as SPAM).

8. The name  of  the  Copyright  Holder  may  not be used to endorse or
   promote  products  derived from this software without specific prior
   written permission.

9. THIS PACKAGE IS PROVIDED "AS IS"  AND WITHOUT ANY EXPRESS OR IMPLIED
   WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
   MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.

The End
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































Deleted freshlib/TestFreshLib.fpr.

cannot compute difference between binary files

Deleted freshlib/_doc/FreshLibRefMan.odt.

cannot compute difference between binary files

Deleted freshlib/_doc/Fresh_IDE.wiki.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<table class="index" align="right">
<tr><td class="index">
<b>Index</b><br>
[http://fresh.flatassembler.net | Fresh home]<br>
[FreshLib reference | FreshLib reference]<br>
[Fresh user guide | Fresh tips&tricks]<br>
</td></tr>
</table>

Fresh is a visual assembly language IDE with built-in FASM assembler.

The main goal of Fresh is to make programming in assembly as fast and
efficient as in other visual languages, without sacrificing the small
application size and the raw power of assembly language.

Because Fresh is the logical continuation of the FASM project in the
area of visual programming, it is perfectly compatible with FASM and you
can use all your knowledge about FASM to program in Fresh.

Of course, you can use Fresh not only for Windows programming, but also
to create programs for any OS that FASM supports - DOS, Linux, FreeBSD,
BeOS, MenuetOS - the same way as you do this in FASM.

Now, the main direction of Fresh development is towards creating FreshLib - freely portable library, that to
provide portability for Fresh and programs created with Fresh to number of different OSes. 
Initially for Win32 and Linux.

This site is [http://www.fossil-scm.org|fossil] repository of Fresh sources.
You can clone the repository with following fossil command:
<pre><b>fossil clone http://chiselapp.com/user/johnfound/repository/FreshIDE/ Fresh.fossil</b></pre>

In order to use more functionality in this site, please [/login|login] as "anonimous" user.
Particularly you will be able to follow the links in the source tree, to download code and to fill bug reports and feature requests.

If you want to contribute to the project, please contact me (johnfound) on [http://board.flatassembler.net|FASM message board]

In order to download compiled FreshIDE, visit [http://fresh.flatassembler.net|Fresh IDE home page.]

You can report bugs, or make some feature requests here, in the [/reportlist|Tickets system]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































Deleted freshlib/_doc/Fresh_and_Linux.wiki.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<h4>Running and debugging Linux applications in Windows with Fresh IDE</h4>

Fresh can compile applications for Linux. But how to run and debug these applications? 

There are different approaches, including virtual machines, second computer, running Linux, or rebooting every time you want to test compiled project.

Fresh provides one very simple way of testing Linux applications. This method is to use [http://andlinux.org|andLinux]. andLinux is complete Ubuntu distribution, that uses coLinux kernel in order to allow running of Linux inside Windows OS.

How to setup andLinux to work with Fresh?

  <b>Step 1.</b> Download andLinux package from [http://andlinux.org/downloads.php|andLinux download page].

  There are two packages: "KDE version" and "minimal/XFCE version" available. For using with Fresh IDE, it is not important what version you will choose.

  KDE package is very big and very slow distribution that contains many bundled programs and tools, but in general you will not need them. The size of KDE package is 500MB download and 5GB installed.

  The XFCE package is relatively smaller and faster. Relatively means 200MB downloaded file and 2GB installed on the disk.

  It is obvious that the right choice is to use XFCE package.

  <b>Step 2.</b> Run the downloaded setup file and answer to the different questions of the setup wizard.

  The important features that we need are:

  *  coLinux version - choose the stable version (0.7.4 in my case) instead of latest (0.8.0) - we shall work with andLinux, not to play.

  *  Memory size - 256MB RAM (or maybe more - if you can afford it).

  *  Install XMing server on your primary screen.

  *  Sound - you can enable or disable sound in Linux option - it is harmless although it is one more running server.

  *  Startup type + Panel - select "run andLinux automatically as a NT service + use Windows shortcuts"; It is not very important, but can save you a little manual work and troubles later.

  *  andLinux login - just select your user name and password for Linux root.

  *  Windows File Access - it is important! - select "using CoFS", no matter it is not recommended.

  * File Access Using CoFS - important! - create one new directory somewhere and select it to be mount via CoFS. This will be the shared directory, visible from Windows and from Linux in the same time.

  All other features you can choose freely or simply leave them to default state.

  When you start installation, the installer will try to install network driver. It is possible Windows will protest and will atempt to mislead you by asking to not install not certified driver. You must ignore these attempts and firmly click "install".

  After installation of andLinux you have to restart Windows and probably andLinux will not run. :D It is because of the Windows firewall. All new network adapters are firewalled by default. As long as installed adapter (named TAP-Colinux) is virtual and local, you will not need any firewall so, go to control panel/Windows firewall/Advanced and uncheck "TAP-Colinux" adapter from the list of adapters.

  Then you can run some Linux program - in the Windows tray, there is a andLinux menu icon that have shortcuts to several Linux programs.

  <b>Step 3.</b> Install several additional Linux tools. You will need additionally debugger and come decent terminal emulator. I choose xterm for terminal, because it is small and white by default. ;) You can choose to use the built-in terminal named in the simple Linux manner: "xfce4-terminal" and console debugger "gdb". In this case you have skip this step.

  Start "Synaptic" - package manager for Ubuntu from the tray menu. You have to enter root password you choose on install.

  When Synaptic is started, click "Reload" to refresh the package list from the network and then use search to locate needed programs. I personally recommend "xterm" as terminal and "ddd" as a GUI front end to "gdb". 

  Well, I recommend "ddd" only because it is only Linux debugger that I was able to run under andLinux and able to show disassembled code of the program.
  
  Mark selected programs for install, click on Apply button and wait until downloading and installation. 

  Here you can encounter only one problem - your computer is behind a proxy server. 
  
  If the proxy is normal proxy, you simply have to set its address and port in the Synaptic preferences and it should work. 

  Completely another story is when the proxy is MS ISA server configured with NTLM user authorization. 

  Most Linux programs can't work with such authorization and Synaptic is not an exception.

  Fortunately, there is a workaround of this situation. You need [http://ntlmaps.sourceforge.net/|ntlmaps] authorization proxy server. 
  
  Setting up of this server is out of the scope of this article. On the ntlmaps home page you can read complete documentation and explanations.

  OK, we are ready with andLinux. Now you have working copy of Ubuntu inside your Windows box.

  It's time to configure Fresh to run Linux applications inside andLinux. Continue with:

  <b>Step 4.</b> Fresh IDE configuration.

  Run Fresh and open "Options|IDE options" dialog. Select "Debuggers and Emulators" page.

  Then select following directories and commands: 
  
  *  "andLinux directory" - the directory where you installed andLinux.

  *  "andLinux shared directory" - shared directory you selected during andLinux installation.

  *  "Linux debugger" - Enter "ddd" (or whatever debugger you choose).

  *  "Linux terminal" - Enter "xterm -hold +mesg -e" - note the options. 

  <h4>And voila! You finished the configuration!</h4>

  Now you can load the source of some Linux program (look at Fresh examples) and run it with shift+F9 or load it in the debugger with shift+F8. 
  
  Fresh will detect when you compiled ELF executable and will run it in andLinux instead of Windows.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































Deleted freshlib/_doc/GUI.wiki.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
<nowiki>

<a name="GUI"><h1>FreshLib directory: GUI</h1></a>

<p>GUI library defines many data structures and procedures that together form
something that conditionally can be called "OOP". It is object oriented, as
long as it deals with GUI "objects" - forms, controls, menus etc.
All these objects are in fact structures of data. For every created object,
the library allocates some memory and fills this memory with object parameters
data.</p>

<p>There are two types of data structures that describe GUI objects - classes
and instances.</p>

<p>The class is a structure that contains data commonly used by all objects of given type - for example all buttons use one class structure CButton.</p>

<p>The instance is data structure that describes the properties and behavior of particular GUI object - for example button with icon "open file" that opens a file when the user click on it.</p>

<a name="Classes"><h2>Classes</h2></a>

<p>"Class" in FreshLib is a data structure, that have the following definition:</p>

<pre class="fasm-code">
struct TObjectClass
  .ptrParent           dd 0   
  .dataSize            dd 0   
  .procCreate          dd 0
  .procDestroy         dd 0
  .procGetParam        dd 0
  .procSetParam        dd 0
  .procExecCmd         dd 0
  .procSysEventHandler dd 0
ends
</pre>

<p><span class="variable">.ptrParent</span> is a pointer to other TObjectClass structure, that appears as a parent class for the given class.</p>
<p><span class="variable">.dataSize</span> contains the size of the object instance structure.</p>

<p>The following fields are the pointers to procedures that provides the "work" of the object. All of these pointers as a rule can be <span class="constant">NULL</span>, if there is no need for such processing.</p>

<a name="Create"><h4>Create</h4></a>
<p><span class="variable">.procCreate</span> is a procedure that creates instance object of the given class. This 
field can be <span class="constant">NULL</span>. It has the following definition:</p>
<pre class="fasm-code">
proc Create, .obj
</pre>
<p>This procedure sets needed values in the object instance data structure.</p>

<a name="Destroy"><h4>Destroy</h4></a>
<p><span class="variable">.procDestroy</span> is a procedure that destroys an instance of the given class.</p>
<pre class="fasm-code">
proc Destroy, .obj
</pre>
<p>Destroys the object passed in <span class="variable">[.obj]</span> and frees all memory allocated for this object.</p>

<a name="GetParam"><h4>GetParam</h4></a>
<p><span class="variable">.procGetParam</span> is a pointer to the procedure that retrieves and returns the properties of the object.</p>
<pre class="fasm-code">
proc GetParam, .obj, .paramID
</pre>
<p>Returns the value of the object <span class="variable">[.obj]</span> parameter with ID=<span class="variable">[.paramID]</span></p>

<a name="Set"><h4>Set</h4></a>
<p><span class="variable">.procSetParam</span> is a pointer to the procedure that set the properties of the object.</p>
<pre class="fasm-code">
proc Set, .obj, .paramID, .value
</pre>
<p>For object <span class="variable">[.obj]</span>, set the value of the parameter with ID=<span class="variable">[.paramID]</span></p>

<h4>ExecCmd</h4>
<p><span class="variable">.procExecCmd</span> is a pointer to the procedure that executes object method.</p>
<pre class="fasm-code">
proc ExecCmd, .obj, .method
</pre>
<p>For the object [.obj] this procedure executes the method with method ID in [.method].</p>
<p>The methods can have arbitrary number of arguments, that are defined in the "object" definition (see below). 
When the method is executed, the procedure <span class="procedure">[.procExecCmd]</span> accepts pointer to the arguments array in <span class="register">[ebx]</span></p>
<p>The user is supposed to call methods of the object with the macro "execute"
The macro is defined following way:</p>
<pre class="fasm-code">
macro execute obj*, meth*, [arg]
</pre>


<a name="SysEventHandler"><h4>SysEventHandler</h4></a>
<p><span class="variable">.procSysEventHandler</span> is a pointer to the procedure that process the system events that are send to the object, i.e. mouse events, keyboard events etc.</p>
<pre class="fasm-code">
proc SysEventHandler, .obj, .pEvent
</pre>
<p>Process one system event for object <span class="variable">[.obj]</span>. <span class="variable">[.pEvent]</span> contains pointer to the system event.</p>

<p>All of these procedures are called internally and should not be used by the user of the library. 
How these procedure are called will be described later.</p>

<p>TObjectClass structure is defined statically in memory in compile time, only once for every object class. Its definition is located in the library for the respective GUI element. For example CButton class structure is defined in the file TButton.asm that contains the code and data of the object class Button.</p>

<p>In order to make construction of such structures easy, macro with name ObjectClass is defined in objects.asm</p>

<a name="ObjectClass"><h3>ObjectClass Macro</h3></a>
<pre class="fasm-code">
macro ObjectClass name*, parent*, procCreate*, procDestroy*, procGetParam*, procSetParam*, procExecCmd*, procSysEvents*
</pre>

<p>Every defined ObjectClass have a label that points to the begin of the structure. The name of this label is the name of the class, prefixed with "C".</p>

<p>One example of ObjectClass definition is the definition of Window object class:</p>
<pre class="fasm-code">
ObjectClass Window,             \
            Object,             \
            TWindow.Create,     \
            TWindow.Destroy,    \
            TWindow.Get,        \
            TWindow.Set,        \
            TWindow.ExecCmd,    \
            TWindow.SysEventHandler
</pre>

<p>This definition creates following data structure:</p>
<pre class="fasm-code">
CWindow:
            dd  CObject         
            dd  sizeof.TWindow             
            dd  TWindow.Create
            dd  TWindow.Destroy    
            dd  TWindow.Get      
            dd  TWindow.Set,        
            dd  TWindow.ExecCmd
            dd  TWindow.SysEventHandler
</pre>



<a name="Object structure"><h3>Object structure</h3></a>
<p>Object instance is data structure that contains different fields. By that it is very similar to the normal FASM structures. As structures, the object is only description of the data but not the data itself. </p>
<p>Objects can inherit field definitions by its parent objects.
The memory instance of the object is allocated dynamically in runtime, when the object is created by call to the respective FreshLib functions.</p>
<p>The definition of the object looks like following:</p>

<pre class="fasm-code">
object TObject
  .ptrClass     dd ? 

  .OnCreate     dd ? 
  .OnDestroy    dd ?

  method .AddChild, .objchild
endobj


object TWindow, TObject
  .handle       dd ?   
  .Fcaption     dd ?    
  .Fcursor      dd ?    

  param .x
  param .y
  param .width
  param .height
  param .visible
  param .caption
  param .parent
  param .cursor

  method .Refresh
endobj


object TButton, TWindow
  .state      dd ?
  .Ficon      dd ?
  .FiconAlign dd ?
  .Ftextalign dd ?

  .OnClick dd ?

  param .TextAlign
  param .Icon
  param .IconPosition
endobj
</pre>

<p>By convention the names of the objects begin with "T".</p>
<p>You can see that the object TWindow contains data fields, parameters and methods. 
The parameters defined by "param" macro are compile time constants which values are assigned automatically. 
There constants are local labels for the object structure. They are also inherited from the parent structure.</p>
<p>The methods are very similar to parameters, in that they are constants, defined in compile time. 
But besides the constant, the method also have list of arguments, passed to the method, when executed.</p>


<p>In the above example, <span class="variable">TButton.width</span> parameter is inherited from <span class="variable">TWindow</span> and have the same value as <span class="variable">TWindow.width</span> parameter.</p>
<p>Also, <span class="variable">TWindow</span> have all fields of TObject defined as well.</p>
<p>If we have to translate TWindow definition in plain FASM syntax it will looks like this:</p>

<pre class="fasm-code">
struc TWindow {
  .ptrClass     dd ? 

  .OnCreate     dd ? 
  .OnDestroy    dd ?

  .handle       dd ?   
  .Fcaption     dd ?    
  .Fcursor      dd ?    

  .x       = $80000000
  .y       = $80000001
  .width   = $80000002
  .height  = $80000003
  .visible = $80000004
  .caption = $80000005
  .parent  = $80000006
  .cursor  = $80000007
}
virtual at 0
  TWindow TWindow
  sizeof.TWindow = $
end virtual
</pre>

<p>This directory contains the libraries providing portable GUI for assembly programming.</p>
<p class="note">Note that this libraries are in very early stage of development, so the description in this chapter is preliminary and probably will be changed in one or another way in the near future.</p>
<p>Later in this text, the whole GUI subsystem of FreshLib will be called FreshGUI</p>

<h2>FreshGUI structure</h2>
<p>The main idea behind the FreshGUI is to make one small OS dependent layer of functions, that to serve as an interface between the OS and the OS independent layer of the library.</p> 
<p>The first will translate OS events, such as mouse, keyboard, timers etc to one common standard of OS independent event handlers of the user interface objects – windows, buttons and other widgets.</p>
<p>The biggest advantage of this approach is that the portability of the library is very easy – most of the code is OS independent and only little  part of it have to be write in order to port the whole library to a new OS.</p>
<p>The biggest drawback of this approach is the bigger size of the library, because, with this architecture, all controls in the library have to be created  from scratch. It is impossible to use graphic controls that the OS provides – particularly Win32 controls - buttons, simple text editors, labels, combo boxes list and tree view controls etc.</p>
<p>FreshGUI is not aimed to use all complex GUI system of the target OS. At first time, the goal of FreshGUI is to provide minimal but decent functionality that will do the job – writing portable applications in assembly language.</p>
<h3>Graphics library</h3>
<p>The graphics library provides procedures that draw graphics images and text on the screen. The library is OS dependent and is placed in the directory "graphics" in the root directory of FreshLib. The main conception of this library is ".raster" - represented by handle, object where the drawing happens. The exact meaning for this object is different for the different OS – in Win32 it is named "device context", in Linux it is "drawable" - window or pixmap.</p>

<h3>Event translation layer</h3>

<h4>Library "sysevents.asm"</h4>
<p>This library contains event codes and data structures for FreshGUI OS independent events. For now only several events are defined:</p>
<pre class="fasm-code">
seMouseMove        
seMouseEnter       
seMouseLeave       
seMouseBtnPress    
seMouseBtnRelease  
seMouseBtnClick    
seMouseBtnDblClick 

seTimer            

seKbdKeyPress      
seKbdKeyRelease    
seKbdStatusChanged 
seKbdChar          

sePaint 
</pre>           
<p>These events cover mouse, keyboard, timers and paint events.</p>
<p>Every event have some arguments that have to be sent to the recipient event handler. The event code and the event arguments are contained in data structure, defined for every kind of events.</p>
<p>The first dword of the event structure is the field <span class="variable">.event</span> that contains the event code.</p>
<p>Here are the structures defined in sysevents.asm</p>
<pre class="fasm-code">
struct TSysEvent
  .event  dd  ?
ends
</pre>
<p>The base event structure.</p>

<pre class="fasm-code">
struct TMouseMoveEvent
  . TSysEvent
  .x         dd ?
  .y         dd ?
ends
</pre>
<p>The event is generated when the mouse cursor moves over some window or control. <span class="variable">.x</span> and <span class="variable">.y</span> contains the coordinates of the mouse cursor relative to the control this message is sent to.</p>

<pre class="fasm-code">
 struct TMouseButtonEvent
  . TSysEvent
  .Button    dd ?
  .kbdStatus dd ?
ends
</pre>
<p>This event is generated when some of the mouse buttons changes its state. The button that changes its state is specified in the field <span class="variable">.Button</span></p>
<p>This field can accept following values:</p>
<table style="margin-left: 40px;">
	<tr><td><span class="constant">mbLeft</span>  </td> <td align="right">= 0</td></tr>
	<tr><td><span class="constant">mbMiddle</span></td> <td align="right">= 1</td></tr>
	<tr><td><span class="constant">mbRight</span> </td> <td align="right">= 2</td></tr>
</table>
<p>The field <span class="variable">.kbdStatus</span> contains the status of remaining mouse buttons and keyboard modifying buttons. These buttons are represented by bits in the field:</p> 
<table style="margin-left: 40px;">
	<tr><td><span class="constant">maskBtnLeft</span>   </td> <td align="right">= $01</td></tr>
	<tr><td><span class="constant">maskBtnMiddle</span> </td> <td align="right">= $02</td></tr>
	<tr><td><span class="constant">maskBtnRight</span>  </td> <td align="right">= $04</td></tr>
	<tr><td><span class="constant">maskCtrl</span>      </td> <td align="right">= $08</td></tr>
	<tr><td><span class="constant">maskShift</span>     </td> <td align="right">= $10</td></tr>
</table>
<pre class="fasm-code">
struct TMouseEnterEvent
  . TSysEvent
ends
</pre>
<p>This event is generated when the mouse cursor enters or leaves some control. There is no additional parameters besides the event code.</p>

<pre class="fasm-code">
struct TKeyboardEvent
  . TSysEvent
  .key       dd  ?
  .kbdStatus dd  ?
ends
</pre>
<p>This event is generated on keyboard button press/release. The field <span class="variable">.key</span> contains the code of the pressed button. <span class="variable">.kbdStatus</span> have the same meaning and the same values as in TMouseButtonEvent.</p>

<pre class="fasm-code">
struct TTimerEvent
  . TSysEvent
ends
</pre>
<p>TTimerEvent is generated on timer events. :)</p>

<pre class="fasm-code">
struct TPaintEvent
  . TSysEvent
  .raster dd ?  ; ID of the raster where you should paint.
  .rect   RECT
ends  
</pre>
<p>TPaintEvent is generated when given control have to be repainted. The field <span class="variable">.raster</span> contains the handle to the graphic surface where the program have to draw. This handle have different meanings in the different target OS, but it simply need to be understandable by the graphics procedures from the OS dependent library graphics.asm.</p>
<p>The field <span class="variable">.rect</span> is the rectangle of the control that needs to be repainted.</p>

<h3>Library "main.asm"</h3>

<a name="Run"><h4>proc Run</h4></a>
<p>This procedure is the main program loop of the GUI application.</p>
<p>The procedure Run process all pending system events, then calls once the OnIdle event handler of the application object and then sleeps until new events are sent by the OS.</p>
<p>When the OS terminates the application – the procedure returns an exit code.</p>
<p>The user uses this procedure following way:</p>
<pre class="fasm-code">
        stdcall Run
        jmp     ExitApplication
</pre>

<a name="ProcessSystemEvents"><h4>proc ProcessSystemEvents</h4></a>
<p>This procedure process the events generated by the OS. If there are waiting events in the queue, the procedure reads them, translates them to FreshGUI  event data structures and calls the event handlers of the respective controls.</p>
<p>If there is no pending events in the queue, ProcessSystemEvents ends with <span class="flag">CF=0</span></p>
<p>The second task this procedure serves is to detect the end of the application. In this case it ends with <span class="flag">CF=1</span>.</p>
<p>This procedure is call from the main event loop of the application. Also, the user can periodically call this procedure in order to not allow hanging of the user interface during long processing of some data.</p>

<a name="WaitForSystemEvent"><h4>proc WaitForSystemEvent</h4></a>
<p>This procedure waits until some system message is posted to the application event queue. Then it exits. During the wait, very low CPU power is consumed by the application.</p>

<a name="Terminate"><h4>proc Terminate</h4></a>
<p>It provides all finalization tasks and ends the application. The exit code is provided in <span class="register">EAX</span>.</p>

<a name="Template engine"><h3>Template engine</h3></a>
<p>The template engine provides creation of complex window structures with tree layout from memory data structure, called template. The templates makes creation of dialog windows  containing children windows and non visual objects.</p>
<p>Templates can be visually created and edited. The template format used by FreshLib is flexible and allows all parameters and fields of the objects to be set to needed values during creation of the window.</p>
<p>The template engine is located in the file ObjTemplates.asm</p>

<a name="Template data structure"><h4>Template data structure</h4></a>
<p>The template is consisted from one or more data structures of type TObjTemplate, defined following way:</p>
<pre class="fasm-code">
struct TObjTemplate
  .flags     dd  ?     
  .class     dd  ?
  .ptrVar    dd  ?     
  .paramsize dd  ?
  .params:
ends
</pre>
<p><span class="variable">.flags</span> – controls what is the place of the object in the whole tree structure.</p>
<p>Can accept one or both of the following values, combined with OR:</p>
<table style="margin-left: 40px;">
	<tr><td><span class="constant">tfChild</span> </td><td>=0</td> <td>means the object is child of the last object with tfParent set.</td></tr>
	<tr><td><span class="constant">tfParent</span>  </td><td>=1</td> <td>means the given object is parent and there will be next TObjTemplate structure that will be a child object.</td></tr>
	<tr style="vertical-align: top;"><td><span class="constant">tfEnd</span>   </td><td> =2</td> <td>means the given object is the last child of its parent. Note, that one object can be parent and child in the same time. If the current template is at root level – the processing of template stops, after creating the current element and all its children.</td></tr>
</table>

<p><span class="variable">.class</span> – pointer to TObjectClass data structure for the created object.</p>
<p><span class="variable">.ptrVar</span> – pointer to dword variable that to accept the pointer to the created object.</p>
<p><span class="variable">.paramsize</span> – the size of the additional data to the end of the template. Note, that TObjTemplate is variable length structure, not fixed. sizeof.TObjTemplate contains the size of the header part of the structure.</p>
<p><span class="variable">.params</span>: after the header fields there can be arbitrary count of dword pairs: (<span class="variable">paramID</span>, <span class="variable">Value</span>) that to be set the the object during creation. This sequence ends with dword <span class="constant">$FFFFFF</span> (<span class="constant">-1</span>) value for paramID. </p>

<p>Easy creation of templates is provided with macro ObjTemplate:</p>
<pre class="fasm-code">
macro ObjTemplate  flags, class, name, [id, param]
</pre>
<p>This macro allows use of string values for params and computes automatically the values for <span class="variable">TObjTemplate.paramsize</span></p>
<p><span class="variable">flags</span> – set of (<span class="constant">tfParent</span>, <span class="constant">tfEnd</span>) constants.</p>
<p><span class="variable">class</span> – the base name of the object class (without prefix C) – i.e. Form, Window, Button, etc.</p>
<p><span class="variable">name</span> – label of the variable to receive the pointer to the created object.</p>
<p><span class="variable">id</span> – parameter ID or offset in the object structure.</p>
<p><span class="variable">param</span> – value of the parameter. Can be dword number or string constant. In the case the parameter value is string, it will be automatically created in the memory and the pointer to this string will be placed as a param value.</p>
<p>One simple example of template structure:</p>
<pre class="fasm-code">
ObjTemplate  tfParent or tfEnd, Form, frmMain, \
			 visible, TRUE, \
			 x, 100,        \
			 y, 50,         \
			 width, 640,    \
			 height, 480,   \
			 caption, 'Fresh portable Win32/Linux application test.'

  ObjTemplate  tfChild, Button, btnChild1,          \
			 visible, TRUE, \
			 x, 64,         \
			 y, 48,         \
			 width, 64,     \
			 height, 24,    \
			 caption, 'Button1',        \
			 OnClick, Button1Click

  ObjTemplate  tfChild or tfEnd, Button, btnChild2,          \
			 x, 136,         \
			 y, 48,         \
			 width, 64,     \
			 height, 24,        \
			 caption, 'Button2' ,\
			 visible, TRUE
</pre>

<a name="Template engine procedures"><h4>Template engine procedures</h4></a>
<p>Actually the procedure is one:</p>
<pre class="fasm-code">
proc CreateFromTemplate, .ptrTemplate, .parent
</pre>

<p>This procedure creates all objects from the template, pointed by <span class="variable">[.ptrTemplate]</span> as a parent of <span class="variable">[.parent]</span> argument.</p>
<p><span class="variable">.ptrTemplate</span> points to TObjTemplate structure.</p>
<p><span class="variable">.parent</span> points to TObject descendant structure. In most cases it will be actually descendant of TWindow or <span class="constant">NULL</span> if the created object is not a child of any window.</p>
<p>Returns: <span class="register">EBX</span> contains a pointer to the topmost of the created object (it is first of the created objects)</p>
<p>All pointers of the objects are stored in the specified in the template variables ( i.e. <span class="variable">[TObjTemplate.ptrVar]</span>)</p>
</nowiki>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/_doc/compiler.wiki.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<nowiki>
<a name="data"><h1>FreshLib directory: compiler</h1></a>
<p>This directory contains only one macro library: "executable.inc"</p>
<p>This library defines the macros that are going to be used for creating the main structure of the program. These macros are OS dependent as long as the type of the executable file is OS dependent: PE for Win32 and ELF for Linux.</p>
<p>Every one of the macros from this library should be used only once in the program.</p>

<h3>FreshLib Executable macros</h3>
<p>This macro library contains:</p>
<a name="_BinaryType"><h4>_BinaryType</h4></a>
<pre class="fasm-code">macro _BinaryType type</pre>
<p>This macro sets the type of the executable. The argument <span class="variable">type</span> can accept one of the following values: <span class="constant">GUI</span>, <span class="constant">console</span> or <span class="constant">DLL</span>.</p>
<p>This macro defines also the entry label of the program. This label is fixed to <span class="constant">start:</span></p>
<p>For example, following code will tell the compiler to compile the program as a GUI application:</p>
<pre class="fasm-code">
include 'compiler/executable.inc'
_BinaryType GUI
</pre>

<a name="_CodeSection"><h4>_CodeSection</h4></a>
<pre class="fasm-code">macro _CodeSection</pre>
<p>This macro defines the section where the code of the program to be  placed.</p>
<p>Actually this section is the main section of the project. Here should be included all used libraries and other project files.</p>

<a name="_DataSection"><h4>_DataSection</h4></a>
<pre class="fasm-code">macro _DataSection</pre>

<p>This macro defines the section where the data of the program to be  placed. The common way to use this section is to use inside the macro <span class="procedure">IncludeAllGlobals</span> that will allow you to use data defining macros from every place inside the source and leave the compiler to order this data properly for you.</p>
<p>For details on using global data definition macros see: <a href="macros.html#_globals">_globals.inc</a></p>

<a name="_ImportSection"><h4>_ImportSection</h4></a>
<pre class="fasm-code">macro _ImportSection</pre>
<p>This macro defines the section where to be inserted the list with functions dynamically imported from external libraries.</p>
<p>Usually you only have to include here the library "allimports.asm"  and the compiler will import for you only those functions that are used in the project.</p>
</nowiki>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































Deleted freshlib/_doc/data.wiki.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
<nowiki>
<table class="index" align="right">
	<tr><td class="index"><p></p>
		<b><a href="freshlib_reference.wiki">FreshLib</a>:Data:</b><br />
		<a href="#Arrays">Arrays</a><br />
		<a href="#Strings">Strings</a><br />
	</p></td></tr>
</table>
<a name="data"><h1>FreshLib directory: data</h1></a>
<p>This directory contains data handling routines and useful data structures. Actually it contains two abstract data structures: Arrays and Strings.</p>
<p class="note">Current implementation is fully portable: it does not contain any OS dependent code.</p>
<a name="Arrays"><h2>FreshLib Arrays</h2></a>
<p>The FreshLib <b>Arrays</b> data structure handles dynamic arrays that contain elements of arbitrary size.</p>
<h3>Structure</h3>
<p>The following structure represents the header of the array. The actual array will have arbitrary size, depending on the element count and size.</p>
<pre class="fasm-code">
struct TArray
  .count     dd ?
  .capacity  dd ?
  .itemsize  dd ?
  .lparam    dd ?
  label .array dword
ends
</pre>

<p>The first element of the array begins on offset <span class="variable">TArray.array</span> from the begining of the memory block.</p>
<p>The field <span class="variable">TArray.count</span> contains the current element count of the array.</p>
<p>The field <span class="variable">TArray.capacity</span> contains the current capacity of the array. It is because the library usually allocates more memory than is needed for the array element count. This approach reduces memory allocations and reallocations and thus increases the speed of inserting and deleting elements in the array. How many memory will be allocated depends on the user setting of the variable <span class="variable">ResizeIt</span> (defined in <a  href="system.html#memory">memory.asm</a>). This variable contains a pointer to the procedure that simply increases the value of <span class="register">ECX</span> to the next suitable value.</p>
<p>The field <span class="variable">TArray.itemsize</span> contains the size in bytes of one array element. Changing of this value is not recommended.</p>
<p>The field <span class="variable">TArray.lparam</span> is for user defined parameter, associated with the array.</p>

<h3>Procedures</h3>

<a name="CreateArray"><h4>CreateArray</h4></a>
<pre class="fasm-code">
proc CreateArray, .itemSize
</pre>
<p>This procedure creates new array with item size <span class="variable">[.ItemSize]</span></p>
<p>The procedure returns <span class="flag">CF=0</span> if the array is properly created and pointer to the array is placed in <span class="register">EAX</span>.</p>
<p>In case the memory cannot be allocated, the procedure returns <span class="flag">CF=1</span>.</p>
<p>The array must be freed after use. There is no special procedure for array free. Use <span class="procedure">FreeMem</span> procedure to free array memory after use.</p>

<a name="AddArrayItems"><h4>AddArrayItems</h4></a>
<pre class="fasm-code">
proc AddArrayItems, .ptrArray, .count
</pre>
<p>This procedure adds new array items at the end of the array pointed by <span class="variable">[.ptrArray]</span></p>
<p>The procedure returns two values:</p>
<p><span class="register">EAX</span> contains pointer to the first of the new appended elements.</p>
<p><span class="register">EDX</span> contains pointer to the array (in the process of appending of the new element, it is possible the whole array to be moved to the new address in memory, so the programmer should store the value of <span class="register">EDX</span> for the future reference to the array.</p>
<p>In case, the new memory can not be allocated, the procedure returns <span class="flag">CF=1</span> and <span class="register">EDX</span> contains the proper pointer to the original array.</p>

<a name="InsertArrayItems"><h4>InsertArrayItems</h4></a>
<pre class="fasm-code">
proc InsertArrayItems, .ptrArray, .iElement, .count
</pre>
<p>This procedure inserts [.count] new elements at the <span class="variable">[.iElement]</span> position of the array pointed by <span class="variable">[.ptrArray]</span></p>
<p>If <span class="variable">[.iElement]</span> is larger or equal to <span class="variable">[TArray.count]</span> the elements are appended at the end of the array. (Just like AddArrayItems)  Otherwise, all elements are moved  to make room for the new elements.</p>
<p>The procedure returns exactly the same results as <span class="procedure">AddArrayItems</span> procedure  <span class="register">EDX</span>  points to the array and <span class="register">EAX</span>  points to the first of the new inserted elements.</p>
<p><span class="flag">CF</span> is error flag.</p>

<a name="DeleteArrayItems"><h4>DeleteArrayItems</h4></a>
<pre class="fasm-code">
proc DeleteArrayItems, .ptrArray, .iElement, .count
</pre>
<p>This procedure deletes [.count] items with begin index <span class="variable">[.iElement]</span> the <span class="variable">[.ptrArray]</span> dynamic array.  If the capacity of the array is bigger than the recommended for the new count, then the array is resized. The recommended size is calculated using ResizeIt procedure from memory library.</p>
<p>Returns <span class="register">EDX</span> - pointer to the TArray. In the most cases this pointer will not be changed, but this also depends on the current OS memory allocation API, so it is safer to store the pointer for future use, instead of one passed to the procedure.</p>
<p>This procedure can not fail, because deleting element is always possible. In some rare cases it can fail to reallocate smaller memory block, but this is not a problem for the array consistency.</p>

<a name="VacuumArray"><h4>VacuumArray</h4></a>
<pre class="fasm-code">
proc VacuumArray, .ptrArray
</pre>
<p>This procedure removes the reserved memory from the array in order to make it as small as possible. This operation should be executed only if there will be no more inserts in the array. The memory economized this way depends on reallocation strategy and can be from 25 to 100% in some cases.</p>

<a name="ListIndexOf"><h4>ListIndexOf</h4></a>
<pre class="fasm-code">
proc ListIndexOf, .ptrList, .Item
</pre>
<p>The list is a special case of array with item size equal to 4 bytes (dword). This procedure searches the list <span class="variable">[.ptrList]</span> for item equal to <span class="variable">[.Item]</span> and returns the index of the element in <span class="register">EAX</span>. In case of error  <span class="flag">CF=1</span>.</p>

<a name="ListFree"><h4>ListFree</h4></a>
<pre class="fasm-code">
proc ListFree, .ptrList, .FreeProc
</pre>
<p>Frees all elements of the list <span class="variable">[.ptrList]</span>, calling <span class="variable">[.FreeProc]</span> for every element of the list.</p>
<p>FreeProc callback procedure have one argument of type dword that is the value of the current list element. The definition of the callback procedure is similar to following:</p>
<pre class="fasm-code">
proc FreeMyListItem, .ptrItem
begin
	;do something with the item being freed
	return
endp
</pre>

<a name="Strings"><h2>FreshLib Strings</h2></a>
<p>Using strings in assembler was often problematic for programmers - static strings can't be resized, so they had to reserve as many bytes as they thought user could need, and it still could be not enough. Thus we created StrLib - a library that operates on dynamic strings, that are automatically resized when needed. Also, StrLib contains many functions that perform string comparison, inserting one string into another, and more. And most of this functions can operate on static strings too. StrLib uses "memory.asm" library for memory allocations and does not contains any OS dependent code.</p>
<p class="note">FreshLib Strings uses FreshLib Arrays to handle the list with pointers to allocated string memory.</p>

<h3>StrLib string format</h3>
<p>The strings used in StrLib are implemented using a specific structure, compatible but not equal to AsciiZ, used by Windows API. The string structure is defined in the following way:</p>
<pre class="fasm-code">
struc string {
  .capacity dd ?
  .len      dd ?
  label .data byte
}

virtual at -(sizeof.string)
  string string
  sizeof.string = $-string
end virtual
</pre>

<p>The string data is placed on offset 0 to the pointer of the string. Its label is "string.data". The string data always is terminated by at least one zero byte and the length of the memory buffer is always dword aligned. 
It is safe to process the string data by dword instructions.</p>
<p>On offset [string-4] is located a dword field, that contains the length of the string data, not including the terminating zero bytes.</p>
<p>On offset [string-8] is located a dword with the capacity of the memory allocated for the string.</p>
<p>These fields are accessible by its symbolic names: string.len and string.capacity; This fields are for internal use only  it is not safe for the user to change the values of these fields.</p>
<p>Using special field that to keep the length of the string makes some of the string operations extremely fast, because searching for the terminating zero is very slow operation. </p>
<p>All procedures in StrLib compute the proper value for <span class="variable">[.len]</span> field and never search for the terminating zeros, except for the AsciiZ strings that are external towards StrLib  those returned from the OS API functions or by string constants in memory.</p>

<h3>StrLib string handles</h3>
<p>The string in StrLib is identified not with its pointer, but by a handle. While the pointer can be changed when the string memory is reallocated, the handle is always a constant for the whole life cycle of the string.</p>
<p>There is a procedure that extracts the current pointer of the string by its handle.</p>
<p>	Because handle values never collides with memory addresses, almost all StrLib procedures can work with handles and with memory pointers at the same time.</p>
<p>For the strings passed to the procedures with memory pointer, StrLib assumes they are static strings from memory, or returned from the OS. </p>
<p>Because of this assumption, StrLib process these strings safely and slowly  scans the string to determine the length, assumes it is byte aligned etc. In other words it process it as a standard AsciiZ string.</p>

<h3>StrLib procedures</h3>
<a name="StrNew"><h4>StrNew</h4></a>
<pre class="fasm-code">proc StrNew</pre>
<p>Creates new string and returns handle in <span class="register">EAX</span>.</p> 

<a name="StrPtr"><h4>StrPtr</h4></a>
<pre class="fasm-code">proc StrPtr, .hString</pre>
<p>Returns the current pointer to the string with handle <span class="variable">[.hString]</span>.</p>
<p>If <span class="variable">[.hString]</span> looks like a valid handle, but it is not found in the strings table, the procedure returns <span class="flag">CF=1</span>.</p>

<a name="StrDel"><h4>StrDel</h4></a>
<pre class="fasm-code">proc StrDel, .hString</pre>
<p>Deletes the string with handle <span class="variable">[.hString]</span> and frees all allocated memory. If <span class="variable">[.hString]</span> is a pointer, it tries to search the strings table for the given handle and deletes it.</p>
<p>If a string is not found, the procedure does not return an error.</p>

<a name="StrDup"><h4>StrDup</h4></a>
<pre class="fasm-code">proc StrDup, .hSource</pre>
<p>Creates a duplicate of the string <span class="variable">.hSource</span>. Returns a handle to the new created string in <span class="register">EAX</span>.</p>

<a name="StrLen"><h4>StrLen</h4></a>
<pre class="fasm-code">proc StrLen, .hString</pre>
<p>Returns the length of the string <span class="variable">[.hString]</span>. If the handle is valid, it returns the value of the field <span class="variable">[string.len]</span>. If <span class="variable">[.hString]</span> is a pointer, it computes the length by scanning the string up to the zero terminator.</p>

<a name="StrFixLen"><h4>StrFixLen</h4></a>
<pre class="fasm-code">proc StrFixLen, .hString</pre>
<p>This procedure scans the length of zero terminated string and "fixes" <span class="variable">[string.len]</span> field. StrFixLen should be call when the content of the string is created by an external call, for example a Win32 API function.</p>

<a name="StrSetCapacity"><h4>StrSetCapacity</h4></a>
<pre class="fasm-code">proc StrSetCapacity, .hString, .capacity</pre>
<p>If the capacity of <span class="variable">[.hString]</span> is larger than the requested capacity it does nothing.</p>
<p>If the capacity of <span class="variable">[.hString]</span> is smaller than the requested capacity, it sets the capacity of the string to the requested value.</p>
<p>Returns a pointer to the string after reallocation in <span class="register">EAX</span>.</p>
<p><span class="variable">.hString</span> is a handle to the string that have to be resized. Pointers are not acceptable here.</p>
<p><span class="variable">.capacity</span> contains requested capacity for the string.</p>
<p>If returns <span class="flag">CF=1</span> the reallocation failed. <span class="register">EAX</span> still contains the pointer to the string, but the string was not resized.</p>

<a name="StrCopy"><h4>StrCopy</h4></a>
<pre class="fasm-code">proc StrCopy, .dest, .source</pre>
<p>Copies the content of <span class="variable">[.source]</span> string to <span class="variable">[.destination]</span> string.</p>

<a name="StrCompCase"><h4>StrCompCase</h4></a>
<pre class="fasm-code">proc StrCompCase, .str1, .str2</pre>
<p>Compares the content of two strings <span class="variable">[.str1]</span> and <span class="variable">[.str2]</span> case sensitive.</p>
<p>Returns:</p> 
<p><span class="flag">CF=1</span> if the strings are EQUAL.</p>  
<p><span class="flag">CF=0</span> if the strings are NOT equal.</p> 

<a name="StrCompNoCase"><h4>StrCompNoCase</h4></a>
<pre class="fasm-code">proc StrCompNoCase, .str1, .str2</pre>
<p>Compares the content of two strings <span class="variable">[.str1]</span> and <span class="variable">[.str2]</span> case NOT sensitive.</p>
<p>Returns:</p>
<p><span class="flag">CF=1</span> if the strings are EQUAL</p>
<p><span class="flag">CF=0</span> if the strings are NOT equal.</p>

<a name="SetString"><h4>SetString</h4></a>
<pre class="fasm-code">proc SetString, .ptrHString, .ptrSource</pre>
<p>Creates string and assigns it to variable. If the variable already contains string handle, the old string will be  reused. Copies the content of <span class="variable">[.ptrSource]</span> to the string variable.</p>
<p>Arguments:</p>
<p><span class="variable">.ptrHString</span>  pointer to the variable that contains string handle.</p>
<p><span class="variable">.ptrSource</span>  pointer to the source for string.</p>

<a name="StrCat"><h4>StrCat</h4></a>
<pre class="fasm-code">proc StrCat, .dest, .source</pre>
<p>Concatenates two strings. The operation is: destination = destination + source.</p>
<p>The destination string <span class="variable">[.dest]</span> can be only handle. <span class="variable">[.source]</span> can be handle or pointer.</p>

<a name="StrCharPos"><h4>StrCharPos</h4></a>
<pre class="fasm-code">proc StrCharPos, .hString, .char</pre>
<p>StrCharPos returns a pointer to the first occurrence of a given char in specified string.</p>
<p>Arguments:</p>
<p><span class="variable">.hString</span> -  string to search</p>
<p><span class="variable">.char</span> - char to look for</p>
<p>Returns:</p>
<p>A pointer to the char in source, or <span class="constant">NULL</span> if char doesn't occur in the given string.</p>

<a name="StrPos"><h4>StrPos</h4></a>
<pre class="fasm-code">proc StrPos, .hString, .hPattern</pre>
<p>StrPos returns a pointer to the first occurrence of a <span class="variable">.hPattern</span> string in <span class="variable">.hString</span>.
<p>Arguments:</p>
<p>hPattern - 'pattern' string</p>
<p>hString -  string to search</p>
<p>Returns:</p>
<p>Pointer to the pattern string in source, or <span class="constant">NULL</span> if pattern string doesn't occur in the string to search.</p>

<a name="StrCopyPart"><h4>StrCopyPart</h4></a>
<pre class="fasm-code">proc StrCopyPart, .dest, .source, .pos, .len</pre>
<p>Copies part of the source string to the destination string.</p>
<p>Arguments:</p>
<p><span class="variable">.dest</span>  handle to destination string.</p>
<p><span class="variable">.source</span>  handle or pointer to the source string.</p>
<p><span class="variable">.pos</span>  Source part start position.</p>
<p><span class="variable">.len</span>  length of the copied part.</p>
<p>Returns nothing.</p>

<a name="StrExtract"><h4>StrExtract</h4></a>
<pre class="fasm-code">proc StrExtract, .string, .pos, .len</pre>
<p>The same as StrCopyPart, but creates and returns new string with extracted part of the source <span class="variable">[.string]</span></p>
<p>Returns the new created string in <span class="register">EAX</span>.</p>

<a name="StrSplit"><h4>StrSplit</h4></a>
<pre class="fasm-code">proc StrSplit, .hString, .pos</pre>
<p>Splits the string on two strings, at position <span class="variable">[.pos]</span></p>
<p>Arguments:
<p><span class="variable">.hString</span>  handle of the string to be split.</p>
<p><span class="variable">.pos</span>      -  position where to split the string.</p>
<p>Returns:
<p><span class="register">EAX</span> - handle to the new created string with second part of the string. The original string does not reallocate memory and it's capacity and the pointer will remains the same.</p>

<a name="StrInsert"><h4>StrInsert</h4></a>
<pre class="fasm-code">proc StrInsert, .dest, .source, .pos</pre>
<p>Inserts the string <span class="variable">[.source]</span> into the string <span class="variable">[.dest]</span> at position [.pos]</span></p>

<a name="StrLCase"><h4>StrLCase</h4></a>
<pre class="fasm-code">proc StrLCase, .hString</pre>
<p>Converts <span class="variable">[.hString]</span> to lower case.</p>


<a name="StrUCase"><h4>StrUCase</h4></a>
<pre class="fasm-code">proc StrUCase, .hString</pre>
<p>Converts <span class="variable">[.hString]</span> to upper case.</p>

<a name="NumToStr"><h4>NumToStr</h4></a>
<pre class="fasm-code">proc NumToStr, .num, .flags</pre>
<p>Converts the given number to a string representing it.</p>
<p><span class="variable">[.flags]</span> controls how the number to be converted.</p> 
<p>The procedure returns a handle to the string in <span class="register">EAX</span> and direct pointer to the string in <span class="register">EAX</span>.</p>
<p>The <span class="variable">[.flags]</span> is a dword with following format:</p>
<p>The LSB contains the number of digits, the number must have, if ntsFixedWidth flag is specified.</p>
<p>Second byte of <span class="variable">[.flags]</span> contains the radix that to be used for conversion.</p>
<p>The third and the fourth bytes are reserved for bit flags.</p>
<p>Following constants are predefined in StrLib in order to set the value for <span class="variable">[.flags]</span>:</p>
<table style="margin-left: 40px;">
<tr><td><span class="constant">ntsSigned</span></td><td>converts number in signed format.</td><td align="right">$00000</td></tr>
<tr><td><span class="constant">ntsUnsigned</span></td><td>converts number in unsigned format.</td><td align="right">$10000</td></tr>
<tr><td><span class="constant">ntsFixedWidth</span></td><td>the count of the digits is fixed.</td><td align="right">$20000</td></tr>
<tr><td><span class="constant">ntsBin</span></td><td>for binary number</td><td align="right">$0200</td></tr>
<tr><td><span class="constant">ntsQuad</span></td><td>for quad number</td><td align="right">$0400</td></tr>
<tr><td><span class="constant">ntsOct</span></td><td>for octal number</td><td align="right">$0800</td></tr>
<tr><td><span class="constant">ntsDec</span></td><td>for decimal number</td><td align="right">$0a00</td></tr>
<tr><td><span class="constant">ntsHex</span></td><td>for hexadecimal number</td><td align="right">$1000</td></tr>
</table>
<p>Example:</p>
<pre class="fasm-code">stdcall NumToStr,<span class="register">EAX</span>,	ntsDec or ntsFixedWidth or 8</pre>
<p>This example will convert the number in <span class="register">EAX</span> to a signed decimal number with exactly 8 digits. If <span class="register">EAX</span> contains <span class="constant">$00000080</span>, the result string will be <span class="constant">'00000128'</span>.</p>

<a name="StrCharCat"><h4>StrCharCat</h4></a>
<pre class="fasm-code">proc StrCharCat, .hString, .char</pre>
<p>This procedure appends up to 4 characters at the end of the string <span class="variable">[.hString]</span>. The characters are contained in the dword argument <span class="variable">[.char]</span></p>

<a name="StrCharInsert"><h4>StrCharInsert</h4></a>
<pre class="fasm-code">proc StrCharInsert, .hString, .char, .pos</pre>
<p>Inserts up to 4 characters <span class="variable">[.char]</span> at position <span class="variable">[.pos]</span> in the string <span class="variable">[.hString]</span></p>

<a name="StrHash"><h4>StrHash</h4></a>
<pre class="fasm-code">proc StrHash, .hString</pre>
<p>Computes 32 bit hash value from the string <span class="variable">[.hString]</span>. This procedure implements the hash algorithm FNV-1b. Returns the result in <span class="register">EAX</span>.</p>
</nowiki>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































Deleted freshlib/_doc/equates.wiki.

1
2
3
4
5
<nowiki>
<a name="data"><h1>FreshLib directory: equates</h1></a>
<p>This directory contains the equates library "allequates.inc". This library defines all constants and structures needed for OS dependent parts of FreshLib.</p> 
<p>The user should never use these constants and structures in the portable program.</p>
</nowiki>
<
<
<
<
<










Deleted freshlib/_doc/freshlib.css.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
body {
	margin: 0px auto 0px auto;
	padding: 2px;
	text-align: justify;
}

p {
	padding-left: 20px;
}

td {
	padding: 2px 8px 2px 8px;
}

span.register {
	margin: 0px;
	padding: 2px;
}

span.variable {
	margin: 0px;
	padding: 2px;
}

span.flag {
	margin: 0px;
	padding: 2px 2px 2px 2px;
}

span.constant {
	margin: 0px;
	padding: 2px 2px 2px 2px;
}

span.procedure {
	margin: 0px;
	padding: 2px 2px 2px 2px;
	font-weight: bold;
}

p.note {
	margin: 0px;
	padding: 2px 2px 2px 26px;
}

p.todo {
	margin: 0px;
	padding: 2px 2px 2px 26px;
}

pre.fasm-code {
	margin: 4px 4px 4px 20px;
	padding: 2px 6px 2px 6px;
}

@media screen {
	body {
		background-color: #ffffe8;
		max-width: 1024px;
		font: "fresh";
		font-family: FreeSans, Verdana, sans-serif;
		font-size: 10pt;
	}

	/* The project logo in the upper left-hand corner of each page */
	div.logo {
		display: table-cell;
		text-align: center;
		vertical-align: bottom;
		font-weight: bold;
		color: #000000;
		min-width: 100px;
	}

	/* The page title centered at the top of each page */
	div.title {
		display: table-cell;
		font-size: 20px;
		font-weight: bold;
		text-align: left;
		padding: 0 0 0 1em;
		color: black;
		vertical-align: middle;
		width: 100% ;
	}

	/* The main menu bar that appears at the top of the page beneath
	** the header */
	div.mainmenu {
		padding: 5px 10px 5px 10px;
		font-size: 12px;
		font-weight: bold;
		text-align: center;
		letter-spacing: 1px;
		background-color: #ff7000;
		border: 1px solid red;
		color: white;
	}

	/* The submenu bar that *sometimes* appears below the main menu */
	div.submenu {
		padding: 2px 10px 2px 10px;
		margin: 3px 0px 3px 0px;
		font-size: 12px;
		text-align: center;
		background-color: #ffff70;
		color: #000080;
		border: 1px solid red;
	}
	div.mainmenu a, div.mainmenu a:visited {
		padding: 3px 10px 3px 10px;
		color: white;
		text-decoration: none;
	}

	div.submenu a, div.submenu a:visited {
		padding: 1px 10px 1px 10px;
		color: black;
		text-decoration: none;
	}


	div.mainmenu a:hover {
		color: #558195;
		background-color: white;
	}


	div.submenu a:hover {
		color: black;
		background-color: #40ffa0;
	}

	/* All page content from the bottom of the menu or submenu down to
	** the footer */
	div.content {
		padding: 8px 8px 8px 8px;
		font-size: 12px;
		max-width: 800px;
		margin: 4px auto 4px auto;
		background-color: white;
		border: 1px #a0a0a0 solid;
	}

	/* The footer at the very bottom of the page */
	div.footer {
		font-size: 12px;
		margin-top: 2px;
		padding: 5px 10px 5px 10px;
		text-align: right;
		background-color: #ff7000;
		border: 1px solid red;
		color: white;
	}

	td {
		font: "fresh";
		font-family: "helvetica";
		font-size: 10pt;
	}

	span.register {
		background-color: #FFCCFF;
	}

	span.variable {
		background-color: #CCFFFF;
	}

	span.flag {
		background-color: #FFFFCC;
	}

	span.constant {
		background-color: #CCFFCC;
	}

	span.procedure {
		font-weight: bold;
	}

	p.note {
		background-color: #FFFFCC;
		border: 1px solid #FFCCCC;
	}

	p.todo {
		background-color: #FFCCCC;
		border: 1px solid #FF9999;
	}

	pre.fasm-code {
		max-width: 700px;
		background-color: #F3F3F3;
		border: 1px dashed #C0C0C0;
		font-size: 9pt;
	}

}

@media print {
	body {
		background-color: none;
		font-family: FreeSans, Verdana, sans-serif;
	}
	div.mainmenu {
		visibility: hidden;
	}
		
	div.submenu {
		visibility: hidden;
	}

	a {
		text-decoration: none;
	}

}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































Deleted freshlib/_doc/freshlib_reference.wiki.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<nowiki>
<table class="index" align="right">
	<tr><td class="index"><p></p>
		<b><a href="/home">Home</a>:FreshLib:</b><br />
		<a href="compiler.wiki">compiler</a><br />
		<a href="data.wiki">data</a><br />
		<a href="equates.wiki">equates</a><br />
		<a href="graphics.wiki">graphics</a><br />
		<a href="GUI.wiki">GUI</a><br />
		<a href="imports.wiki">imports</a><br />
		<a href="macros.wiki">macros</a><br />
		<a href="simpledebug.wiki">simpledebug</a><br />
		<a href="system.wiki">system</a><br />
	</p></td></tr>
</table>
<h3>Overview</h3>

<p>FreshLib is an assembly library aimed to ease the development of rapid assembly language applications, freely portable between different platforms, such as Win32 or Linux.</p>
<p>The  library is coded in flat assembler syntax <a href="http://www.flatassembler.net">(fasm)</a> and is intended to be easily used within <a href="http://fresh.flatassembler.net">Fresh IDE</a> although it could be used for plain fasm development.</p>

<p>The library consists of two layers: one that is OS dependent and a second one that is OS independent. The OS dependent layer is very small, in order to help porting it for different OS. This layer only makes interface to the core OS functions, such as memory allocations, file access, drawing functions, simple window management etc.</p>

<p>The OS independent layer is responsible for the main application functionality allowing creation of different kind of windows and controls, user interaction with the program and interaction between particular windows and other GUI elements.</p>
<p>FreshLib is mainly intended for developing GUI applications, as they are the most challenging to be ported across different platforms. FreshLib is also created with visual programming in mind, so it contains a flexible, event driven and OS independent template engine allowing visual creation of application user interfaces.</p>
<p>FreshLib is in early development stage and probably will be changed many times in order to reach their objectives: to be small, fast and easy to use.</p>

<p>The main intention is to keep the bloat off the library, but containing all necessary accessories for comfortable programming of a very wide range of applications.</p>

<p>The architecture of FreshLib is open and it can be freely expanded with other libraries without increasing the size of applications. In other words, only those parts of the library that are effectively used will be compiled on the final executable.</p>

<h3>About this manual</h3>

<p class="todo">This manual is a "work in progress". Any part of it can be changed at any time.</p>
<p>Of course, some of the libraries described in this document are more stable and finished like the macro, system and data libraries. Therefore, the chapters about these libraries are less likely to be changed. Other libraries (like graphics and GUI), will be heavily modified  so the manual will be changed accordingly.</p>

<h3>Structure of the library</h3>
<p>FreshLib contains many code and macros libraries, structured hierarchically and depending on each other. Here is the directory tree of the library:</p>
<ul>
<li><a href="compiler.wiki">compiler</a></li>
<li><a href="data.wiki">data</a></li>
<li><a href="equates.wiki">equates</a></li>
<li><a href="graphics.wiki">graphics</a></li>
<li><a href="GUI.wiki">GUI</a></li>

<li><a href="imports.wiki">imports</a></li>
<li><a href="macros.wiki">macros</a></li>
<li><a href="simpledebug.wiki">simpledebug</a></li>
<li><a href="system.wiki">system</a></li>
</ul>
<p>The library is structured to support different platforms transparently. The platform dependient code is contained in a subdirectory of each library component. For example, "system" subdirectory contains libraries for accessing system resources  such as memory, files, etc. Inside "system" there several subdirectories that contain OS dependent code  these directories are named after the platform they serve.</p>
<p class="note">Currently, only Win32 and Linux platforms are supported.</p>
<h3>Getting started</h3>
<p>FreshLib main scope is to provide a fast and easy framework to start programming multiplatform assembly applications. Now, <a href="starting.wiki">what is needed to start writing applications?</a></p>
<h3>Tutorials</h3>
<ul>
	<li><a href="starting.wiki#simplest">Simplest Application</a></li>
	<li><a href="starting.wiki#files">Creating Files</a></li>
	<li><a href="starting.wiki#console">Basic Console</a></li>
	<li><a href="starting.wiki#GUI">Basic GUI</a></li>
</ul>
</nowiki>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































Deleted freshlib/_doc/imports.wiki.

1
2
3
4
5
6
<nowiki>
<a name="data"><h1>FreshLib directory: imports</h1></a>
<p>Another directory that contains only OS dependent definitions is "imports" with a library file to be included in the project: "allimports.asm"</p> 
<p>This file have to be included in the _IncludeSection of the application. Then it will generate the proper import section, depending on the target platform and functions used by the OS dependent parts of FreshLib.</p>
<p>The user should never call directly imported functions from inside the portable application.</p>
</nowiki>
<
<
<
<
<
<












Deleted freshlib/_doc/index.wiki.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<nowiki>
<table class="index" align="right">
<tr><td class="index">
<p><b>Index</b><br />
<a href="http://fresh.flatassembler.net">Fresh home</a><br />
<a href="/doc/FreshLibDev/freshlib/_doc/freshlib_reference.wiki">FreshLib reference</a><br />
<a href="/doc/trunk/doc/fresh_user_guide.html">Fresh tips&amp;tricks</a><br />
</p></td></tr>
</table>

<p>Fresh is a visual assembly language IDE with built-in FASM assembler.
</p>

<p>The main goal of Fresh is to make programming in assembly as fast and
efficient as in other visual languages, without sacrificing the small
application size and the raw power of assembly language.
</p>

<p>Because Fresh is the logical continuation of the FASM project in the
area of visual programming, it is perfectly compatible with FASM and you
can use all your knowledge about FASM to program in Fresh.
</p>

<p>Of course, you can use Fresh not only for Windows programming, but also
to create programs for any OS that FASM supports - DOS, Linux, FreeBSD,
BeOS, MenuetOS - the same way as you do this in FASM.
</p>

<p>This site is <a href="http://www.fossil-scm.org">fossil</a> repository of Fresh sources.
You can clone the repository with following fossil command:
<pre><b>fossil clone http://chiselapp.com/user/johnfound/repository/FreshIDE/ Fresh.fossil</b></pre>
</p>

<p>In order to use more functionality in this site, please <a href="/login">login</a> as "anonimous" user.
Particularly you will be able to follow the links in the source tree, to download code and to fill bug reports and feature requests.
</p>

<p>If you want to contribute to the project, please contact me (johnfound) on <a href="http://board.flatassembler.net">FASM message board</a>
</p>

<p>In order to download compiled FreshIDE, visit <a href="http://fresh.flatassembler.net">Fresh IDE home page.</a>
</p>

<p>You can report bugs, or make some feature requests here, in the <a href="/reportlist">Tickets system</a>
</p>
</nowiki>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































Deleted freshlib/_doc/macros.wiki.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
<nowiki>
<table class="index" align="right">
	<tr><td class="index"><p></p>
		<b><a href="freshlib_reference.wiki">FreshLib</a>:Macros:</b><br />
		<a href="#_stdcall">_stdcall.inc</a><br />
		<a href="#_globals">_globals.inc</a><br />
		<a href="#_struct">_struct.inc</a><br />
		<a href="#_display">_display.inc</a><br />
	</p></td></tr>
</table>
<a name="macros"><h1>FreshLib directory: macros</h1></a>
<p>This directory contains several libraries that provides common convenience functions to be used with big assembly projects. All libraries can be included in the project at once from the file "allmacros.inc".</p>
<p>There is no overhead at including all those libraries because there is no code to be generated, just macros. There is a little delay in compile time but thanks to fasm's speed, it is barely noticeable.</p>
<p>Lets examine each one of these libraries.</p>
<a name="_stdcall"><h2>FreshLib _stdcall.inc</h2>
<p>In general this library provides ways of definition and invoking of the procedures with argument passing through the stack. It supports STDCALL and CCALL calling conventions.</p>
<pre class="fasm-code">
macro proc name, [arg]
macro begin
macro endp
macro return
macro cret
macro locals
macro endl
</pre>
<p>These macros define a procedure, creates a stack frame for the local variables and defines symbolic names for the arguments. The macro "proc" defines the global label "name" as a name for the procedure. All arguments and local variables are defined as a local labels with regard to the name of the procedure. That is why all arguments and local variables must have names beginning with dot.</p>
<p>Between the line with "proc" and "begin", any number of local variables can be defined. The macro "begin" marks the begining of the procedural code.</p>
<p>The macro "endp" marks the end of the procedural code.</p>
<p>The return from procedure instruction is provided by macros "return" or "cret" depending on the calling convention we want to use: "return" clears the arguments from the stack and "cret" do not.</p>
<p>Inside the procedure, a secondary stack frame can be allocated with the pair "locals" and "endl".  All data definitions, enclosed between these macros will define a secondary stack frame that is a continuation of the stack frame defined between "proc" and "begin".</p>

<p>Any number of "locals" and "endl" pairs can be used, but all of these secondary stack frames will overlap between each other. This feature is specially intended to provide savings of stack space and at the same time, to provide talking variable names for the different parts of more complex procedures.</p>
<p>For example (in Win32) if we have complex window procedure that have to process multiple messages: One of the message handlers may need one variable <span class="variable">.rect</span>. Another message handler may need two variables called <span class="variable">.point1</span> and <span class="variable">.point2</span>. But the procedure as a whole is never going to need all those variables at the same time, because it process only one message at a time. On the other hand it may need the variable <span class="variable">.ctrldata</span> for every message processed. The optimal solution is to define the variables in the following way:</p>
<pre class="fasm-code">
proc CtrlWinProc,.hwnd,.wmsg,.wparam,.lparam
.ctrldata dd ?
begin
    invoke GetWindowLong, [.hwnd], GWL_USERDATA
    mov    [.ctrldata], eax

    cmp    [.wmsg], WM_MESSAGE1
    je     .message1
    cmp    [.wmsg], WM_MESSAGE2
    je     .message2
    return

.message1:
locals
  .rect RECT
endl
    return

.message2:
locals
  .point1 POINT
  .point2 POINT
endl
    return
endp
</pre>
<p>In the above example, <span class="variable">.ctrldata</span> is defined on <span class="register">[EBP-4]</span>; <span class="variable">.rect</span> is defined on <span class="register">[EBP-20]</span>; <span class="register">.point1</span> is also defined on <span class="register">[EBP-20]</span>  and <span class="variable">.point2</span> is defined on <span class="register">[EBP-12]</span>.<p>
<table class="stack" style="margin-left: 40px; border: 1px solid black;">
	<tr><td>[EBP-04]</td><td colspan=2>.ctrldata</span></td></tr>
	<tr><td>[EBP-08]</td><td>.rect.bottom</td><td>.point2.y</td></tr>
	<tr><td>[EBP-12]</td><td>.rect.right</td><td>.point2.x</td></tr>
	<tr><td>[EBP-16]</td><td>.rect.top</td><td>.point1.y</td></tr>
	<tr><td>[EBP-20]</td><td>.rect.left</td><td>.point1.x</td></tr>
</table>
<p>As you can see, <span class="variable">.rect</span> occupies the same memory as <span class="variable">.point1</span> and <span class="variable">.point2</span>, but <span class="variable">.ctrldata</span> is never overlapped and exists independently.<p>
<p>As a general rule, you have to use the definitions between "proc" and "begin" for local variables that are used in every call of the procedure and separate locals/endl definitions for variables needed for the particular branches inside the procedure.<p>
<p>This approach will always provide the optimal size for the locals stack frame.</p>

<pre class="fasm-code">
macro initialize
macro finalize
</pre>
<p>The macros "initialize" and "finalize" defines one special type of procedures that during compilation are registered in a two separate lists - one for "initialize" and one for "finalize" procedures.</p>
<p>After that using the macros "InitializeAll" and "FinalizeAll", all these procedures can be call at once. "initialize" procedures are call in the order of their definition and "finalize" procedures in reverse order.</p>
<p>These macros provides standard and consistent way to process the initialization and the finalization of the libraries and modules of the application.</p>
<p>Procedures defined with "initialize" and "finalize" must have no any arguments.</p>
<p>FreshLib uses this mechanism and the user is free to use it also.
<pre class="fasm-code">
macro stdcall proc, [arg]
macro ccall proc, [arg]
macro invoke proc, [arg]
macro cinvoke proc, [arg]
</pre>
<p>This macros call the procedures with STDCALL and CCALL calling convention.</p>
<p>"stdcall" macro pushes the arguments to the stack in reverse order and then call the procedure with label "proc". As long as the macro "stdcall" does not provide any stack cleanup (this duty is assigned to the procedure) the arguments can be pushed in free manner using, for example, separate push instructions for part of the arguments and arguments in the stdcall line for the remaining arguments. This can be very convenient in some cases. For example see the following source:</p>
<pre class="fasm-code">
    stdcall CreateSomeObject   
    push	    eax   			
    stdcall DoSomething
    stdcall DeleteSomeObject
</pre>
<p>Here, the procedure DoSomething  changes the value of eax, so the handle is saved in the stack. The procedure DeleteSomeObject needs one argument - a handle of the object. But as long as the proper value is already in the stack, it is mindless to pop the value and then to push it again. So the source calls DeleteSomeObject without any arguments. The procedure knows the proper number of arguments (one in this example) and clean the stack properly.</p>
<p>The standard (and wrong) approach is to pop the argument from the stack and then to pass it to the procedure explicitly is the stdcall statement:</p>
<pre class="fasm-code">
    stdcall	CreateSomeObject
    push	     eax   ; save the handle.
    stdcall  DoSomething
    pop      eax             ; ??? Why ???
    stdcall  DeleteSomeObject, eax
</pre>
<p>This source will generate the meaningless instructions sequence:</p>
<pre class="fasm-code">
    pop      eax       
    push     eax       	
</pre>
<p>"invoke" macro is the same as "stdcall" with the only difference - it calls the procedure indirectly (call [proc] instead of call proc).</p>
<p>This mechanism is used to call the functions imported from external dynamic linked libraries.</p>
<p>"ccall" macro calls a procedure with CCALL convention. This means that the procedure returns with simple "retn", without cleaning the parameters from the stack. Then "ccall" macro provides instructions that remove the arguments from the stack.</p>
<p>Because ccall have to know the exact count of passed arguments, all arguments have to be passed explicitly as a values in the ccall statement.</p>
<p>Tricks as described above will not work properly and leads to stack not properly cleaned after the call.</p>
<p>"cinvoke" is the same as ccall, but using indirect call. The reason is the same as with "invoke" macro. </p>
<p class="note">About the calling conventions: While  all Win32 dynamic linked libraries uses STDCALL convention, most (if not all) of Linux libraries uses CCALL convention.<br />
All code libraries of Fresh use STDCALL calling convention and it is platform independient.</p>

<a name="_globals"><h2>FreshLib _globals.inc</h2>
<p>This library defines several macros intended to deal with data definitions.</p>
<p>Usually all data definitions have to be placed in special section of the executable file. This is not very convenient, because the code that process this data and the data definitions must reside in separate places of the source code, and in most cases even in different files.</p>
<p>The idea of globals.inc macro library is to allow the data definition to be described anywhere in the source code, but these definitions to be defined at once, at the place the programmer wants - usually in the data section of the program.</p>
<pre class="fasm-code">
macro uglobal
macro iglobal
macro endg
macro IncludeAllGlobals
</pre>
<p>"uglobal" begins block for undefined data definition. The block ends with "endg" macro. Between "uglobal" and "endg" macro any count of data definitions can be inserted.</p>
<p>Note that because uglobal block defines undefined data, it is only the labels and the size of data that have meaning inside this block. Any data defined with data definition directive will not be included in the binary file.</p>
<p>The undefined data will be defined later at the place where "IncludeAllGlobals" macro resides.</p>
<p>The undefined data is always placed at the end of all data definitions, so it will never increase the size of the executable file.</p>

<p>"iglobal" macro, again combined with "endg" defines initialized data. The data defined in the block will be created at "IncludeAllGlobals" statement.</p>
<p>This block increases the size of the executable file, because it contains sensible data, that have to be included in the file.</p>
<p>Actually, neither uglobal, nor iglobal blocks defines any data immediately.</p>
<p>Instead, the data definitions are stored in a list.  The real definition occurs later, when IncludeAllGlobals macro is invoked.</p>
<p>For this reason, IncludeAllGlobals must be placed  in the source  after all used global data blocks.</p>

<pre class="fasm-code">struc text [val]</pre>

<p>The macro "text" is actually a structure. It needs to be preceded by some label name.</p>
<p>This macro defines a zero terminated string constant, and also a local label for this string in the "sizeof" global label.</p>
<p>The "text" macro, similar to iglobal and uglobal simply stores string data for defer definition.</p>
<p>This definition, as for all global data macros, occur in IncludeAllGlobals invocation.</p>
<p>Why to define separate macro for the strings and not to use the normal iglobal block? The thing is that the macro "text" was planned to check the strings and to not define any string more than once. In the case of repetitive strings, this macro should return the pointer to the already defined string constant.</p>
<p>In that case, it would be very convenient and harmless to use string constants in the function calling macros - stdcall, ccall etc.</p>
<p class="todo">Unfortunately, regardless of the power of fasm macro language, this functionality cannot be implemented. Or, more precisely, it can be implemented, but the implementation is too slow for any real project use.<br />
This ineffective implementation is still leaved inside the file _globals.inc - commented block that defines macro with name "InitStringList". If someone have ideas about fixing this problem, please send it to me!</p>

<a name="_struct"><h2>FreshLib _struct.inc</h2>
<p>This library contains only one simple macro:</p>
<a name=""><h4></h4></a>
<pre class="fasm-code">
macro struct name
ends
</pre>
<p>This macro is aimed to provide easy creation of data structures. The "struc" directive in FASM is known to not create actual labels, but only the template for the label definitions. So, we need to create an instance of the data structure in order to have addresses and offsets of its fields.</p>
<p>But very often we don't have static data structure of the given type, but data structure, pointed by some of the registers. In this case in order to use offsets to the fields of the data structure, we need to define at least one virtual  instance of the structure at address 0. Then we can use the values of the fields as an offsets in the instructions - for example: mov eax, [esi+RECT.right].</p>
<p>So, this is exactly what "struct" macro does. Besides it defines the "struc" structure with the given fields, it creates a single virtual instance of this structure, in order to be used later for register addressing. In all remaining functionality it behaves exactly as the struc directive.</p>
<p>The syntax of struct macro is the following:</p>
<pre class="fasm-code">
struct StructureName
  .field1 dd ?
  .field2 RECT
  .fieldN:
ends
</pre>
<p>The definition begins with "struct" followed by the structure name. The definition ends with "ends" directive. Between both, any local label definition becomes a member of the structure.</p>

<a name="_display"><h2>FreshLib _display.inc</h2>
<p>This library contains macros that enhance the functionality of standard FASM "display" directive.</p>
<a name=""><h4></h4></a>
<pre class="fasm-code">macro disp [arg]</pre>
<p>The macro "disp" displays the strings given in the arguments, just as "display" FASM directive does</p>
<pre class="fasm-code">disp &lt;number, radix&gt;</pre>
<p>The macro here is used to display numbers in any radix.</p>

<pre class="fasm-code">macro DispSize Text, Sz</pre>
<p>"DispSize" macro is very specialized macro, that displays the text and number in the following form:</p>

<pre class="fasm-code">Size of [Text] is: Sz bytes</pre>

<p>The size number is automatically scaled to bytes or kbytes, depending on the value of Sz.</p>
<p>This macro allows easy display and control of the sizes of particular areas of the program - data structures, subroutines etc.</p>

<a name="Fresh display"><h4>How Fresh implements "display" directive</h4></a>
<p>There are some specifics in Fresh, concerning message displaying. The "display" directive in Fresh works in a different way than original FASM directive. It outputs text in Fresh message window. Each message can have one of six icons, or it can have no icon at all. And because message window is implemented as a TreeView control, you can organize your messages into groups (directories). Implementation is a bit "tricky" - when you display a character whose code is less than 16, it is interpreted in a special way. Characters from 1 to 6 set an icon of current message. It sounds complicated, but it is quite simple. Try:</p>
<pre class="fasm-code">
    display 2, "some message"
</pre>
<p>It will display "some message" with an error icon. Another codes are used for controlling directory structure. Try to type following lines and see what would happen:</p> 
<pre class="fasm-code">
    display 3, "message at root", 0x09
    display 3, "child message1", 0x0a
    display 3, "child message2", 0x0d
    display 3, "again at root", 0x0a
</pre>
<p>Of course you don't have to put each message in separate display directive, you can, with the same result write:</p>
<pre class="fasm-code">
display 3, "at root",$09,3,"child1",$0a,3,"child2", $0d,3,"again at root",$0a 
</pre>
<p>Here is the complete list of all special characters and their meanings:</p>
<table style="margin-left: 40px;">
	<tr><td><span class="constant">$01</span></td><td>set current icon to "warning"</td></tr>
	<tr><td><span class="constant">$02</span></td><td>set current icon to "error"</td></tr>
	<tr><td><span class="constant">$03</span></td><td>set current icon to "info"</td></tr>
	<tr><td><span class="constant">$04</span></td><td>set current icon to "find"</td></tr>
	<tr><td><span class="constant">$05</span></td><td>set current icon to "none"</td></tr>
	<tr><td><span class="constant">$06</span></td><td>set current icon to "debug"</td></tr>
	<tr><td><span class="constant">$08</span></td><td>end current row and set one level back.</td></tr>
	<tr><td><span class="constant">$09</span></td><td>end current row and set it as new directory.</td></tr>
	<tr><td><span class="constant">$0a</span></td><td>end current row and keep current level</td></tr>
	<tr><td><span class="constant">$0d</span></td><td>end current row and set current level to root level</td></tr>
</table>
</nowiki>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































Deleted freshlib/_doc/porting.wiki.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<h3>Porting FreshLib to other platforms.</h3>

<h4>Minimal system requirements</h4>

  *  Some kind of heap management. Currently FreshLib uses heap functions in Win32 and libc functions
in Linux.

Although, if it is impossible for the OS to provide dynamic memory allocation, it can be implemented
using some other heap manager - for example vid's one from FASMLIB. In this case, the OS should provide only
one big memory block.

However, this solution can greatly complicate the porting process.

  *  Some kind of process management. Threads.

  *  Timer - FreshLib needs one timer that to be able to interrupt the main program loop.

  *  Graphics - FreshLib needs basic graphics functions in order to work. Lines, Rectangles and text drawing
should be enough.

  *  Graphics Text rendering - FreshLib needs UTF-8 support at least on level of conversion of UTF-8 to
the OS internal format (as is with Win32). As long as ASCII (0..$7f) is valid UTF-8 code, if the OS uses
only plain ASCII it is possible for text rendering to provide only ASCII text drawing.

In Win32 FreshLib uses Windows unicode support with conversion. In Linux it uses XFT library, that supports
direct use of UTF-8 strings.

  *  Console text output - FreshLib needs output to the console window - (native or emulated) for debuging
purposes.

  *  Windows - FreshLib uses only one base type of window, able to accept the system events and to be displayed
on the screen. This window should be able to appear on the screen and to be able to have children of the same type.

In Win32 FreshLib uses its own window class "FreshWin". In Linux (XLib) uses usual XLib window.



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































Deleted freshlib/_doc/simpledebug.wiki.

1
2
3
4
5
6
<nowiki>

<a name="data"><h1>FreshLib directory: simpledebug</h1></a>
<p>This directory contains debugging utilities.</p>
</nowiki>

<
<
<
<
<
<












Deleted freshlib/_doc/starting.wiki.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<nowiki>
<a name="setup"><h2>Setting Up</h2></a>

<p>The first thing to do is to download <a href="http://www.flatassembler.net">fasm</a> in your platform of choice.
 Fasm does not require installation nor do you need special administrative privileges or a root account in order to start using it.</p>
<p>The second thing is to get a copy of <a href="http://chiselapp.com/user/johnfound/repository/FreshIDE/zip/FreshLib.zip?uuid=FreshLib">FreshLib</a>. FreshLib is just fasm source code, simply save it in a directory of choice.</p>
<p>FreshLib needs an environment variable called <span class="variable">TargetOS</span> 
in order to know the target platform of the generated application.
 Currently, the allowed values are: <span class="constant">Win32</span> and <span class="constant">Linux</span>.</p>
<p>A second environment variable is suggested called <span class="variable">lib</span> having the full path to FreshLib. The library does not need this, but it will make your own sources more portable.</p> 
<p>From Linux:</p>
<pre class="fasm-code">
export TargetOS=Linux
export lib=/home/test/freshlib
</pre>
<p>From Windows:</p>
<pre class="fasm-code">
set TargetOS=Win32
set lib=c:\projects\freshlib
</pre>

<p>That's all. Now it is time to produce the first FreshLib application using just Fasm.</p>

<a name="simplest"><h3>Hello World</h3></a>

<pre class="fasm-code">
include '%lib%/compiler/executable.inc'
include '%lib%/macros/allmacros.inc'
include '%lib%/equates/allequates.inc'

_BinaryType console

include '%lib%/system/process.asm'
include '%lib%/simpledebug/debug.asm'

_CodeSection

start:

        InitializeAll

        DebugMsg 'Hello world!'

        FinalizeAll
        call    Terminate

_ImportSection

include '%lib%/imports/allimports.asm'

_DataSection

IncludeAllGlobals
</pre>

<p>The most important thing to note is that regardless the platform you have chosen, the code is exactly the same.
In other words, if you change the value of your environment variable <span class="variable">TargetOS</span>,
the same code will produce a different executable file targeting that platform.
This is the main characteristic of the FreshLib and this is the first design criteria that you will
want to follow to have a truly platform independent application.</p>

<p class="note">This is a highly portable development environment, perhaps the most portable
among non interpreted languages. The entire development process could run from removable media
and the same set of source code files could be used from Win32 and Linux to produce binaries for either of them.</p>

<a name="files"><h3>Creating Files</h3></a>

<pre class="fasm-code">
include '%lib%/compiler/executable.inc'
include '%lib%/macros/allmacros.inc'
include '%lib%/equates/allequates.inc'

_BinaryType console

include '%lib%/simpledebug/debug.asm'
include '%lib%/system/files.asm'
include '%lib%/system/process.asm'

_CodeSection

start:

        InitializeAll

        DebugMsg 'FreshLib Tutorials - Module: Files'

iglobal
        filename        db './tut01.txt',0
        sizeof.filename = $-filename
endg

uglobal
        hFile   dd ?
endg

        stdcall FileCreate, filename
        jc      .error
        mov     [hFile], eax
        DebugMsg "A new file was created:"
        stdcall OutputNumber, [hFile], 16, 2
        DebugMsg " is the handle of the file"

        stdcall FileWrite, [hFile], filename, sizeof.filename
        jc      .error
        stdcall OutputNumber, eax, 10, 2
        DebugMsg " bytes were written into the file"

        stdcall FileClose, [hFile]
        jc      .error
        DebugMsg "The file was properly closed"

        stdcall FileDelete, filename
        jc      .error
        DebugMsg "The file was finally deleted"
        jmp     .exit

.error:
        DebugMsg "Sorry, an error occurred"

.exit:
        FinalizeAll
        stdcall Terminate, 0

_ImportSection

include '%lib%/imports/allimports.asm'

_DataSection

IncludeAllGlobals
</pre>

<a name="console"><h3>Simple Console</h3></a>

<pre class="fasm-code">
</pre>

<a name="GUI"><h3>Basic GUI</h3></a>

<pre class="fasm-code">
</pre>

</nowiki>

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































Deleted freshlib/_doc/system.wiki.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<nowiki>
<a name="data"><h1>FreshLib directory: system</h1></a>
<p>This directory contains two libraries: "memory.asm" and "files.asm". They constitute the interface to the overlaying system for the rest of the FreshLib modules.</p>
<a name="memory"><h2>FreshLib Memory</h2></a>
<p>This library contains simple but pretty complete functions for dynamic memory allocation, reallocation and release.</p>
<p>The Win32 implementation of the library uses the process heap, returned by GetProcessHeap to manage the memory allocations. Linux implementation uses libc functions: "malloc", "free" and "realloc".</p>

<a name="GetMem"><h4>GetMem</h4></a>
<pre class="fasm-code">
proc GetMem, .size
</pre>
<p>This procedure allocates dynamic memory block with size in bytes in the argument <span class="variable">[.size]</span></p>
<p>If there is no error the procedure returns <span class="flag">CF=0</span> and pointer to the requested memory in <span class="register">EAX</span>. If the memory cannot be allocated, the procedure returns <span class="flag">CF=1</span></p>

<a name="FreeMem"><h4>FreeMem</h4></a>
<pre class="fasm-code">
proc FreeMem, .ptr
</pre>
<p>This procedure frees the memory block pointed by <span class="variable">[.ptr]</span> argument.</p>

<a name="ResizeMem"><h4>ResizeMem</h4></a>
<pre class="fasm-code">
proc ResizeMem, .ptr, .newsize
</pre>
<p>This procedure tries to resize the memory block pointed by <span class="variable">[.ptr]</span> to the new size, given by <span class="variable">[.newsize]</span> argument.</p>


<a name="files"><h2>FreshLib Files</h2></a>
<p>This library provides simple file access procedures.</p>

<a name="FileOpen"><h4>FileOpen</h4></a>
<pre class="fasm-code">
proc FileOpen, .filename
</pre>
<p>This procedure opens the file with a filename in the string pointed by <span class="variable">[.filename]</span> argument.</p>
<p>On success (<span class="flag">CF=0</span>) <span class="procedure">FileOpen</span> returns a handle of the open file. On error (<span class="flag">CF=1</span>) returns error code.</p>

<a name="FileCreate"><h4>FileCreate</h4></a>
<pre class="fasm-code">
proc FileCreate, .filename
</pre>
<p>This procedure creates new empty file with a filename in the string pointed by <span class="variable">[.filename]</span> argument.</p>
<p>On success (<span class="flag">CF=0</span>) FileCreate returns a handle of the open file. On error (<span class="flag">CF=1</span>) returns error code in <span class="register">EAX</span>.</p>

<a name="FileClose"><h4>FileClose</h4></a>
<pre class="fasm-code">
proc FileClose, .handle
</pre>
<p>This procedure closes the open file with a handle in <span class="variable">[.handle]</span>  argument.</p>
<p>On success (<span class="flag">CF=0</span>) does not return any value and preserves <span class="register">EAX</span>.</p>
<p>On error (<span class="flag">CF=1</span>) returns error code in <span class="register">EAX</span>.</p>

<a name="FileRead"><h4>FileRead</h4></a>
<pre class="fasm-code">
proc FileRead, .handle, .buffer, .count
</pre>
<p>This procedure reads <span class="variable">[.count]</span> bytes  from the file <span class="variable">[.handle]</span> in the buffer pointed by <span class="variable">[.buffer]</span> arguments.</p>
<p>On success (<span class="flag">CF=0</span>) returns the count of actually read bytes in <span class="register">EAX</span>.</p>
<p>On error (<span class="flag">CF=1</span>) returns error code in <span class="register">EAX</span>.</p>

<a name="FileWrite"><h4>FileWrite</h4></a>
<pre class="fasm-code">
proc FileWrite, .handle, .buffer, .count
</pre>
<p>This procedure writes <span class="variable">[.count]</span> bytes  from the buffer pointed by <span class="variable">[.buffer]</span> argument to the file [.handle] that have to be open for write.</p>
<p>On success (<span class="flag">CF=0</span>) returns the count of actually read bytes in <span class="register">EAX</span>.</p>
<p>On error (<span class="flag">CF=1</span>) returns error code in <span class="register">EAX</span>.</p>

<a name="FileSeek"><h4>FileSeek</h4></a>
<pre class="fasm-code">
proc FileSeek, .handle, .dist, .direction
</pre>
<p>This procedure moves the file pointer to the some position. The handle of the file is in <span class="variable">[.handle]</span>, the target position is in <span class="variable">[.dist]</span> and the direction of the move is in <span class="variable">[.direction]</span> arguments.</p>
<p><span class="variable">[.direction]</span> accept one of the following values: <span class="constant">fsFromBegin</span>, <span class="constant">fsFromEnd</span> and <span class="constant">fsFromCurrent</span>.</p>
<p>The exact values of these constants may vary between different OSes, so the programmer have to use the symbolic names, predefined in "files.asm" library.</p>
<p>On success (<span class="flag">CF=0</span>) returns the new position of the file in <span class="register">EAX</span>.</p>
<p>On error (<span class="flag">CF=1</span>) returns error code in <span class="register">EAX</span>.</p>

<a name="FileDelete"><h4>FileDelete</h4></a>
<pre class="fasm-code">
proc FileDelete, .filename
</pre>
<p>This procedure deletes a file with name in pointed by <span class="variable">[.filename]</span> argument.</p>
<p>On success (<span class="flag">CF=0</span>) no value.</p>
<p>On error (<span class="flag">CF=1</span>) returns error code in <span class="register">EAX</span>.</p>

<a name="GetErrorString"><h4>GetErrorString</h4></a>
<pre class="fasm-code">
proc GetErrorString, .code
</pre>
<p>This procedure returns in <span class="register">EAX</span> a pointer to a human readable error string for the error code passed in <span class="variable">[.code]</span>. The string is dynamically allocated by the OS and should be released after use with the procedure <span class="procedure">FreeErrorString</span>.</p>

<a name="FreeErrorString"><h4>FreeErrorString</h4></a>
<pre class="fasm-code">
proc FreeErrorString, .ptrString
</pre>
<p>This procedure frees the memory allocated for error string from the procedure <span class="procedure">GetErrorString</span>.</p>

<a name="LoadBinaryFile"><h4>LoadBinaryFile</h4></a>
<pre class="fasm-code">
proc LoadBinaryFile, .ptrFileName
</pre>
<p>This procedure allocates needed memory and loads the whole file with filename pointed by <span class="variable">[.ptrFileName]</span> to the allocated buffer.</p>
<p>The memory is allocated with the library <a href="system.html#memory">memory.asm</a>, so the user have to free the memory after use with the procedure <span class="procedure">FreeMem</span>. 
<p>On success (<span class="flag">CF=0</span>) the procedure returns a pointer to the allocated memory in <span class="register">EAX</span> and the count of bytes read in <span class="register">ECX</span>.</p>
<p>On error (<span class="flag">CF=1</span>) the procedure returns nothing.</p>

<a name="SaveBinaryFile"><h4>SaveBinaryFile</h4></a>
<pre class="fasm-code">
proc SaveBinaryFile, .ptrFileName, .aptr, .size
</pre>
<p>This procedure creates new file with the name pointed by <span class="variable">[.ptrFileName]</span> and saves <span class="variable">[.size]</span> bytes from the buffer pointed by  <span class="variable">[.aptr]</span>.</p>
<p>The procedure returns error flag in <span class="flag">CF</span>.</p>

<a name="FileExists"><h4>FileExists</h4></a>
<pre class="fasm-code">
proc FileExists, .ptrFileName
</pre>
<p>This procedure checks whether the file with name pointed by <span class="variable">[.ptrFileName]</span> exists on disk.</p>
<p>The procedure returns <span class="flag">CF=0</span> if the file exists, otherwise it returns<span class="flag">CF=1</span>.</p>
</nowiki>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































Deleted freshlib/_pending/FBasDx01/FASMBas.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
   Well it's something like qbasic, meaning that it's a lot like most basic's...

   You can only have one basic command per line. The exception is a comment / remark starts with a semi colon and can be at the end of a line 

Print "example"     ;This is an example

   Basic commands can be all caps, all small or start with a cap.

PRINT
print
Print

   FASM Basic does not use line numbers.

   Right now FASM Basic only supports a few variable types.

Short = 8 bit number
Integer = 16 bit number
Long = 32 bit number
String = text

   All variables must be defined. They are case sensitive.

DEF     A, Short    ,32         
DEF     B, Integer  ,12312      
DEF     C, Long     ,2000000    
DEF     D, String   ,"String variable"

   INPUT, only works with strings right now, but you can also print text with the input command.

Input D			; Waits for the user to type in text and hit enter, The text is stored in D
Input "Enter: ",D	; Prints 'Enter: ' then waits for user input
Input D,E,F		; Would wait for user to enter text 3 times, hitting enter after each
Input "Text"            ; Will just print the word 'Text'
Input "Enter1: ",D," Enter2: ",E," Enter3: ",F
			; Puts up the text and inputs 3 entries

   PRINT, puts text or variables on the screen. /n causes a print command to start a new line.

Print "text"		; Puts the word 'text' on the screen
Print A			; Puts the value stored in A on the screen at the current location
Print A,B		; Puts the value of A then the B on the screen, with no space between them
Print "Numbers 1 & 2 : ",A," ",B
			; puts the text in quotes on the screen, then A, then a space, then B
Print "Line1",/n,"Line2"; puts text on 2 lines

   BEEP, makes the computer beep once

   CLS, clears the screen, 0 the entire screen, 2 a line at bottom is left, 3 three lines at bottom
	4 a line at top is left, 5 three lines at the top are left
	the second and third numbers set the text color

Cls		; clears the screen
cls 0		; clears the screen
Cls 2		; clears everything except a line of text at the bottom
Cls 3   	; clears everything except three lines at the bottom
Cls 4		; clears everything except a line of text at the top
cls 5		; clears everything except three lines at the top
cls 0, 8, 4	; clears everything, sets the text color to gray and background to red

   COLOR, First number sets text color. Second sets the background color
	(new text, what's on the screen stays the same Color )
	Last number sets the color for the border / over scan area
	Add 16 to the text number to make it blink
        |  Text       |  Text
	| Background  | Background  |  Text            |   Text
        |  Border     |  Border     |                  |
        |-------------|-------------|------------------|-------------------
	| 0 = black   | 4 = red     | 8 = grey         | 12 = light red
	| 1 = blue    | 5 = magenta | 9 = light blue   | 13 = light magenta
	| 2 = green   | 6 = brown   | 10 = light green | 14 = yellow
	| 3 = cyan    | 7 = white   | 11 = light cyan  | 15 = bright white

Color 7		; white text, black background, black border
Color 14, 1     ; yellow test on a blue background with a black border
Color 8, 4, 4   ; gray text on a red background with a red border
Color 24, 4, 4  ; blinking gray text on a red background with a red border

   END_PROGRAM, must be the last line of your program

   GOTO, takes the program from where it is and continues execution at a label.

...					; some random program lines 
...
Goto NewStuff				; tells program to go to the label 'NewStuff'
Print "Text that will never get printed"; so this line gets skipped
NewStuff:				; and the program keeps going here
...
...

   GOSUB, goes to a label, but returns 
...
...
Gosub New stuff
Print "This gets printed second",/n
...
...
New stuff:
Print "This line gets printed first",/n
Return
...
...

   RETURN, returns from a gosub command

   LET, well it doesn't do any thing right now....

   LOCATE, the screen location to put text at

Locate 0,0		; text will start printing on the screen in the upper left corner

   PEEK, puts the value of a memory location into register al

Peek 123456

   POKE, puts a value to a memory location

Poke 123456,255

   REBOOT, reboots the computer

   IN_PORT, puts the value of a port into register al

In_port 245

   OUT_PORT, outputs a value to a port

Out_port 245,128

   SLEEP, the computer waits until a key is pressed to do any thing, the key pressed ends up in reg AX
	or if a number is given it waits that many clock ticks.

Sleep		; waits for a key press
Sleep 37	; waits 37 clock ticks, about 2 seconds

   SCREEN, sets the screen mode
	0 = Standard Dos text mode
	1 = 320 x 200 4 color
	2 = 640 x 200 2 color
	7 = 320 x 200 16 color
	8 = 640 x 200 16 color
	9 = 640 x 350 4 color
	11 = 640 x 480 2 color
	12 = 640 x 480 16 color
	13 = 320 x 200 256 color
	14 = DexOS Text mode
	15 = Vesa text mode 132 x 60
	100 = 640 x 400 256 color	; only 0-15 fully working right now
	101 = 640 x 480 256 color
	103 = 800 x 600 256 color
	105 = 1024 x 768 256 color
	107 = 1280 x 1024 256 color
	110 = 320 x 200 16m color
	112 = 640 x 480 16m color
	115 = 800 x 600 16m color
	118 = 1024 x 768 16m color
	119 - 1280 x 1024 16m color

Screen 14	; puts you in DexOS text mode	

   SOUND, makes a tone, the frequency of the tone is the first number and the duration is the second

Sound 45,18	; 45 hrz tone for about one second

   CURSORON, turns the cursor on

   CURSOROFF, turns the cursor off

   CURSOR, turns the cursor off or on

Cursor TRUE	; turns on the cursor
Cursor FALSE	; turns the cursor off

   PAUSE, pauses the computer for a given time, 18.5 is about one second (you can only use integers)

Pause 37	; pauses for about 2 seconds


Reserved words: 
	Other then the asm and basic command words any thing starting with "_grfx" should be avoided, unless you intend to mess with the basic macro functions.

_grfxMode:      read only, is set to what ever graphics mode you are in
		needs to be set by the macro and be right

_grfxScreen:    Should probably only be read, unless you want to do some sort of double buffer
		This is the start of memory for the screen

_grfxCls:       This is the screen size (in dword) for the mode you are in

_grfxLL:        line length (dword) for the mode you are in

_grfxScreen_x   Cursor location
_grfxScreen_y   Cursor location, or if changed, where the macros assume the cursor to be

_grfxColor	The color all new text will be displayed with, 
		byte format = BBBCTTTT,
		B = Background color, C = Blinking or not, T = Text color

Added asm functions: (use instead of the dex functions when using the basic macros)

_grfxPrintString: Prints a 0 terminated string pointed to by ESI

_grfxPrint_char:  Prints the ASCII char in al

_grfxLocate:      moves the cursor to location al, ah


Thanks to rCX for starting this project, TonyMac and Dex for starting it in DexOS. A really big thanks to every one at the FASM board for endless great info on FASM and to Tomasz Grysztar for the great toy, um I mean tool :)

Steve
http://home.comcast.net/~dexos/

DexOS home page:
http://www.dex4u.com/
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































Deleted freshlib/_pending/FBasDx01/fbasic.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
; ====================================
; | Fasm Basic ver 0.10 Beta  oct 09 |
; ====================================

; QBASIC.inc was written by rCX (converted to run on DexOS, by Dex)
; added to by TonyMac & now added to by Steve, who also changed the name

Beep            fix BEEP        ; Done
beep            fix BEEP
cls             fix CLS         ; Done for text mode, oops need to put cursor in right spot
Cls             fix CLS
color           fix COLOR       ; Done in text mode
Color           fix COLOR
end_program     fix END_PROGRAM ; Done
End_program     fix END_PROGRAM
End_Program     fix END_PROGRAM
gosub           fix GOSUB       ; Done
Gosub           fix GOSUB
GoTo            fix GOTO        ; Done
Goto            fix GOTO
goto            fix GOTO
input           fix INPUT       ; Done (just does strings, at this time)
Input           fix INPUT
let             fix LET         ; Needs lots of work, not included at this time
Let             fix LET
locate          fix LOCATE      ; Done
Locate          fix LOCATE
peek            fix PEEK        ; Done
Peek            fix PEEK
poke            fix POKE        ; Done
Poke            fix POKE
print           fix PRINT       ; Done
Print           fix PRINT
return          fix RETURN      ; Done
Return          fix RETURN
reboot          fix REBOOT      ; Done
Reboot          fix REBOOT
In_Port         fix IN_PORT     ; Done (need to redo so it works with 8, 16 & 32)
In_port         fix IN_PORT
in_port         fix IN_PORT
Out_Port        fix OUT_PORT    : Done ( need to redo so it works with 8, 16 & 32)
Out_port        fix OUT_PORT
out_port        fix OUT_PORT
Sleep           fix SLEEP       ; Done
sleep           fix SLEEP
Screen          fix SCREEN      ; Done in text. enters graphics modes
screen          fix SCREEN
Sound           fix SOUND       ; done (crash if below min, need to add a minimum check)
sound           fix SOUND
def             fix DEF         ; need to work on strings, make definable size and pad out
Def             fix DEF
cursoron        fix CURSORON    ; done
Cursoron        fix CURSORON
CursorOn        fix CURSORON
cursoroff       fix CURSOROFF   ; done
Cursoroff       fix CURSOROFF
CursorOff       fix CURSOROFF
pause           fix PAUSE       ; done
Pause           fix PAUSE
cursor          fix CURSOR      ; done
Cursor          fix CURSOR

 ;--------------------;
 ; Set up DexOS stuff ;
 ;--------------------;

use32
        ORG 0x400000           ; where our program gets loaded
        jmp @f                 ; jump over ver tag
        db 'DEX2'              ; Mark it a DexOS ver3 file.
@@:
        mov ax,18h             ; set ax to nonlinear base
        mov ds,ax              ; set ds to nonlinear base
        mov es,ax              ; set es to nonlinear base.
        mov edi,Functions      ; address of jump table (in dex.inc)
        mov ax,0x0a00          ; load table wih DexOS function addresses
        int 40h

        jmp   SkipQBASIC       ; jump over all the macros

 ;---------------------------------;
 ; Dam, a run time lib             ;
 ; not sure how to get around this ;
 ;---------------------------------;
_grfxLocate:
        cmp   [_grfxMode],byte 15
        je    @f
        cmp   al,80             ; did they put in to high a x for mode 0,14
        jb    @f
        ret                     ; out of range do nothing
@@:
        cmp   al,132            ; is the x to high for mode 15
        jb    @f
        ret                     ; out of range do nothing
@@:
        cmp   [_grfxMode],byte 14
        je    @f
        cmp   ah,25             ; y to high for mode 0
        jb    @f
        ret                     ; out of range do nothing
@@:
        cmp   [_grfxMode],byte 15
        je    @f
        cmp   ah,50             ; y to high for mode 14
        jb    @f
        ret                     ; out of range do nothing
@@:
        cmp   ah,60             ; y to high for mode 15
        jb    @f
        ret                     ; out of range do nothing
@@:
        mov   [_grfxScreen_x],al
        mov   [_grfxScreen_y],ah
_grfxLocate2:
        pushad
        xor   ebx,ebx
        mov   bl,[_grfxScreen_x]; figure out where the cursor is now
        mov   ecx,ebx
        mov   bl,[_grfxScreen_y]
        mov   eax,[_grfxLL]     ; line length (dword, half color half char)
        shl   eax,1             ; line length (in bytes of char)
        mul   bx
        add   eax,ecx
        mov   edx,0x3d4         ; video card register index port
        mov   ecx,eax
        mov   al,0x0f           ; set for cursor register (lsb)
        out   dx,al
        mov   eax,ecx           ; cursor location
        add   edx,1             ; video card register port
        out   dx,al
        mov   al,0x0e           ; set for cursor register (msb)
        sub   edx,1             ; video card registr index port
        out   dx,al
        mov   al,ch             ; cursor location
        add   edx,1             ; video card reg port
        out   dx,al
        popad
        ret

_grfxPrintString:
        pop   esi                       ; get address of data off the stack
        push  eax
_grfxPrintString_Loop:
        lodsb                           ; load al, inc esi to next char
        cmp   al,0                      ; 0x00 = end of string
        jne   @f
        call  _grfxLocate2              ; End of string so place cursor and leave
        pop   eax
        jmp   esi                       ; out of data so this address should be next instruction
@@:
        cmp   al,0x0d                   ; 0x0d = CR ( = \n )
        je    @f
        call  _grfxPrintChar            ; not a control, so must need printing
        jmp   _grfxPrintString_Loop
@@:
        call  _grfxCR                   ; do the CR (next line)
        jmp   _grfxPrintString_Loop

_grfxCR:
        push  eax
        mov   [_grfxScreen_x],byte 0
        mov   ah,[_grfxScreen_y]
        cmp   ah,24                     ; no reason to scroll if less then 24th line
        jb    _grfxCR_NoScroll
        cmp   [_grfxMode],byte 0
        je    @f
        cmp   ah,49                     ; less then line 49 and mode 14 or 15, no reason to scroll
        jb    _grfxCR_NoScroll
        cmp   [_grfxMode],byte 14
        je    @f
        cmp   ah,59                     ; mode 15 and less then 59, no reason to scroll
        jb    _grfxCR_NoScroll
@@:
        push  ecx
        push  esi
        push  edi
        mov   edi,[_grfxScreen]         ; Address of the screen
        mov   esi,edi
        movzx eax,byte [_grfxLL]        ; line size (in dword)
        shl   eax,2                     ; make it bytes
        add   esi,eax                   ; address of 2nd line to be new 1st line
        movzx ecx,word [_grfxCls]       ; screen size
        cli                             ; can't have something writing to screen during a scroll
        rep   movsd                     ; move the text
        sti
        pop   edi
        pop   esi
        pop   ecx
        pop   eax
        ret
_grfxCR_NoScroll:                       ; don't need to scroll, so just go down one line
        add   [_grfxScreen_y],byte 1
        pop   eax
        ret

_grfxPrintChar:
        pushad
        push  ax                        ; put char in a safe place
        movzx eax,word [_grfxLL]        ; line size (dword)
        movzx ebx,byte [_grfxScreen_y]
        shl   eax,1                     ; line size (word)
        mul   bx                        ; number of lines times line size
        movzx ebx,byte [_grfxScreen_x]
        add   ebx,eax                   ; screen mem moves (word size)
        shl   ebx,1                     ; screen mem moves (byte size)
        add   ebx,[_grfxScreen]         ; add that to the screen base mem location
        pop   ax                        ; char to print
        mov   ah,[_grfxColor]           ; the color text we want
        mov   [ebx],ax                  ; put the text and color on screen
        mov   al,[_grfxLL]              ; load up the line size
        shl   al,1                      ; convert line size to bytes of text
        add   [_grfxScreen_x],byte 1    ; set new text location
        cmp   [_grfxScreen_x],al        ; is new x location to large
        jb    @f
        call  _grfxCR
@@:
        popad
        ret


 ;-----------------------;
 ; The Fasm Basic macros ;
 ;-----------------------;

;___________CLS______________________
macro CLS clrmode,_opt2,_opt3           ; just for textmode right now
{
        push ecx
        push eax
        push edx
        push edi
        mov  edi,[_grfxScreen]          ; start address of screen fill
        if clrmode eq
        else if clrmode eq 4            ; start cls one line down
                movzx eax,word [_grfxLL]
                shl   eax,2
                add   edi,eax
        else if clrmode eq 5            ; Start cls two lines down
                movzx eax,word [_grfxLL]
                mov   edx,12
                mul   edx
                add   edi,eax
        end if
        if _opt2 eq
                mov  eax,0x0f200f20     ; char to fill screen with (0f=color 20=blank)
        else
                mov  ah,_opt3           ; Background color 0-7
                shl  ah,4
                add  ah,_opt2           ; Text color 0-31
                cmp  ah,0               ; was there no color set
                jne  @f
                        mov  ah,0x0f    ; set a color
                @@:
                mov  al," "             ; a blank space
                mov  cx,ax              ; now fill up eax
                shl  eax,16
                mov  ax,cx
        end if
        movzx ecx,word [_grfxCls]       ; how many dwords to write
        if clrmode in <2,4>
                sub  cx,[_grfxLL]       ; leave 1 line uncleared
        else if clrmode in <3,5>
                sub  cx,[_grfxLL]       ; leave 3 lines uncleared
                sub  cx,[_grfxLL]
                sub  cx,[_grfxLL]
        end if
        cli                             ; can't be changing the screen while clearing it
        rep stosd                       ; put blanks on screen
        sti
        pop edi
        pop edx
        pop eax
        pop ecx
        Locate 0,0
}

;___________CURSOR__________________
macro CURSOR option*            ;Turns on cursor if option = TRUE, off if option = FALSE.
{
        pushf
        pusha
        mov   ch,0x0b           ;Turns on cursor if option = TRUE
        mov   cl,0x0c
        if option = FALSE
                mov   ch,0x1c   ;turns it off if option = FALSE.
                mov   cl,0x1b
        end if
        mov   ah,1              ;Set cursor status
        call  [RealModeInt10h]
        popa
        popf
}


;_____________CURSOROFF________________
macro CURSOROFF
{
   push  cx
   push  ax
   mov   ch,00110000b
   mov   cl,00010000b
   mov   ah,01h
   call  [RealModeInt10h]
   pop   ax
   pop   cx
}

;_______________CURSORON_______________
macro CURSORON
{
   push  cx
   push  ax
   mov   ch,00010000b
   mov   cl,00010000b
   mov   ah,01h
   call  [RealModeInt10h]
   pop   ax
   pop   cx
}

;_______________PAUSE__________________
macro PAUSE time
{
   push  ax
   mov   ax,time
   call  [SetDelay]
   pop   ax
}

;________________COLOR_________________
macro COLOR _opt1,_opt2,_opt3

{
        push  eax
        push  ebx
        if _opt2 eq
                   mov  al,0
        else
                   mov  al,_opt2          ; Background color 0-7
                   shl   al,4
        end if
        add   al,_opt1                    ; Text color 0-31
        mov   [_grfxColor],al             ; Set the text color
        if _opt3 eq
        else
                   mov   ah,0
                   mov   al,_opt3         ; Border color 0-3Fh
                   shl   eax,16           ; top 16 of eax are bx in 16 bit dos mode
                   mov   ax,0B00h         ; Set border color
                   call  [RealModeInt10h]
        end if
        pop   ebx
        pop   eax
}

;_________________END___________________
macro END_PROGRAM
{
        call  [SetDex4uFonts]
        mov   cx,0
        call  [InterruptTimer]; restore timer
        ret
include 'Dex.inc'             ; Dex inc file
}

;_______________LOCATE_________________
macro LOCATE row,col
{
        push eax
        local  .temp
        if col eq ah
                mov  .temp,byte col
                mov  ah,row
                mov  al, .temp
        else
                mov  ah,row
                mov  al,col
        end if
        call _grfxLocate
        pop  eax
}


;_______________PRINT_________________
macro PRINT [String]
{
        if String eqtype ""
                local .a
                        push esi
                        call _grfxPrintString   ; call print & push address of data to stack
                        .a db String,0          ; String to print
                        pop  esi
        else if String eq /n
                local .a
                        push esi
                        call _grfxPrintString
                        .a db 13,0
                        pop  esi
        else if String eq /N
                local .a
                        push esi
                        call _grfxPrintString
                        .a db 13,0
                        pop  esi
        else
                local .NotDone
                local .Done
                local .Start
                local .NotString
                        push esi
                        pushad
                        mov  esi,String
                        cmp  [esi],byte 9       ; is it a string varable
                        jne  .NotString
                        add  esi,3
                @@:
                        mov   al,[esi]
                        add   esi,1
                        cmp   al,0              ; 0x00 = end of string
                        je    .Done
                        call  _grfxPrintChar    ; not a control, so must need printing
                        jmp   @b
                .NotString:
                        mov   ebx,String
                        cmp   [ebx],byte 0      ; is data a byte
                        jne   @f
                        add   ebx,1
                        movzx eax,byte [ebx]    ; store it in eax (make it a dword)
                        jmp   .Start
                @@:
                        cmp   [ebx],byte 1      ; is data a word
                        jne    @f
                        add   ebx,1
                        movzx eax,word [ebx]    ; store it in eax (make it a dword)
                        jmp   .Start
                @@:
                        add   ebx,1             ; data must be a dword
                        mov   eax,[ebx]         ; store it in eax
                .Start:
                        mov  ebx,1000000000           ; 32 bit can only be 10 ascii digits
                @@:
                        cmp  eax,0                    ; need to check if it's 0
                        jnz  @f                       ; if it's not 0 go figure out what it is
                        mov  al,"0"                   ; put ascii 0 in al
                        call _grfxPrintChar           ; and write it to screen
                        jmp  .Done
                @@:
                        mov  ecx,1                    ; a flag to blow off leading 0's
                        mov  esi,10                   ; we are working in base 10
                .NotDone:
                        cmp  ebx,0                    ; are we done counting off digits
                        jnz  @f
                        jmp  .Done
                @@:
                        cmp  eax,ebx                  ; is this digit a non zero one
                        jb   @f
                        xor  ecx,ecx                  ; clear the flag to start printing 0's
                @@:
                        mov  edx,0
                        div  ebx                      ; digit to write ends up in al, rest of number in edx
                        cmp  ecx,1                    ; do we need to write yet
                        je   @f
                        add  al,"0"                   ; make al an ASCII digit
                        call _grfxPrintChar           ; and write it to screen
                @@:
                        push edx                      ; put the rest of number in a safe place
                        xor  edx,edx
                        mov  eax,ebx                  ; put the digit count in eax
                        div  esi                      ; reduce digit count one place
                        mov  ebx,eax                  ; digit count back in ebx
                        pop  eax                      ; get number back in eax
                        jmp  .NotDone                 ; try next digit
                .Done:
                popad
                pop   esi
                call  _grfxLocate2      ; End of string so place cursor and leave
        end if
}

;_______________INPUT_________________
Macro INPUT [String]
{
        if String eqtype ""
                local .a
                        push esi
                        call _grfxPrintString
                        .a db String,0
                        pop  esi
        else if String eq /n
                local .a
                        push esi
                        call _grfxPrintString
                        .a db 13,0
                        pop  esi
        else if String eq /N
                local .a
                        push esi
                        call _grfxPrintString
                        .a db 13,0
                        pop  esi
        else
                local .loop
                local .done
                push edi
                push eax
                mov  edi,String
                cmp  [edi],byte 9       ; is the varable a string
                jne  .done              ; major bug if they don't use a string
                add  edi,3              ; skip over varable type and size
        .loop:
                call [WaitForKeyPress]  ; need to not let them enter to much
                cmp  al,13
                je   .done
                mov  [edi],al           ; <----need to make a string move
                inc  edi
                call _grfxPrintChar
                call _grfxLocate2
                jmp  .loop
        .done:
                mov byte [edi], 0        ;zero-terminate the string
                pop  eax
                pop  edi
        end if
}

;_______________SCREEN_________________
macro SCREEN mode         ;need to add active and working page....
{
        push eax
        mov  ah,0h
        mov  [_grfxMode],byte mode

        if mode = 0
                mov  al,3h                       ; text 80 x 25
                call [RealModeInt10h]
                mov  [_grfxScreen],dword 0xb79e0 ; start address of screen
                mov  [_grfxCls],word 1000        ; size of screen (in dword)
                mov  [_grfxLL],word 40           ; screen width (in dword)
        else if mode = 1
                mov  al,04h
                call [RealModeInt10h]
        else if mode = 2
                mov  al,06h
                call [RealModeInt10h]
        else if mode = 7
                mov  al,0Dh
                call [RealModeInt10h]
        else if mode = 8
                mov  al,0Eh
                call [RealModeInt10h]
        else if mode = 9
                mov  al,10h
                call [RealModeInt10h]
        else if mode = 11
                mov  al,11h
                call [RealModeInt10h]
        else if mode = 12
                mov  al,12h
                call [RealModeInt10h]
        else if mode = 13
                mov  al,13h
                call [RealModeInt10h]
        else if mode = 14                        ; DexOS text 80 x 50
                call [SetDex4uFonts]
                mov  [_grfxScreen],dword 0xb79e0 ; start address of screen
                mov  [_grfxCls],word 2000        ; screen size
                mov  [_grfxLL],word 40           ; screen width
        else if mode = 15                        ; text 132 x 60
                push cx
                mov  cx,0x10c
                call [SetVesaMode]
                mov  [_grfxScreen],dword 0xb79e0 ; Start address of screen
                mov  [_grfxCls],word 3960        ; screen size
                mov  [_grfxLL],word 66           ; screen width
                pop  cx
                mov  [_grfxScreen],dword 0xb79e0 ; start address of screen
        ;---------256 color modes-------------
        else if mode = 100
                push  ecx
                push  edi
                mov   cx,0x4100 ; gfx 640 x 400
        else if mode = 101
                push  ecx
                push  edi
                mov   cx,0x4101 ; gfx 640 x 480
        else if mode = 103
                push  ecx
                push  edi
                mov   cx,0x4103 ; gfx 800 x 600
        else if mode = 105
                push  ecx
                push  edi
                mov   cx,0x4105 ; gfx 1024 x 768
        else if mode = 107
                push  ecx
                push  edi
                mov   cx,0x4101 ; gfx 1280 x 1024 ; oops need to fix
        ;---------32bit color modes-------------
        else if mode = 110
                push  ecx
                push  edi
                mov   cx,0x410f ; gfx 320 x 200
        else if mode = 112
                push  ecx
                push  edi
                mov   cx,0x410f ; gfx 640 x 480
        else if mode = 115
                push  ecx
                push  edi
                mov   cx,0x4115 ; gfx 800 x 600
        else if mode = 118
                push  ecx
                push  edi
                mov   cx,0x4118 ; gfx 1024 x 768
        else if mode = 119
                push  ecx
                push  edi
                mov   cx,0x411B ; gfx 1280 x 1024
        end if
        if mode in <100,101,103,105,107,110,112,115,118,119>
                call  [SetVesaMode]               ; set the mode
                call  [LoadVesaInfo]              ; load vesa into to esi
                mov   edi,VESA_Info               ; where to put vesa info
                mov   ecx,193                     ; size of vesa info
                cld                               ; clear direction flag, string instructions forward
                cli                               ; turn off int
                rep   movsd                       ; copy the vesa info 32 bits at a time
                sti                               ; turn on int
                mov   edi,[ModeInfo_PhysBasePtr]  ; location of vid memory
                sub   edi,0x621                   ; magic number for DexOS offset
                mov   [_grfxScreen],edi           ; start of vid mem.
                pop   edi
                pop   ecx
        end if
        if mode in <0,14,15>                      ; if we are in text mode
                xor   eax,eax                     ; put cursor at 0,0
                call  _grfxLocate
        end if
        pop eax
}

;________________SLEEP_________________
macro SLEEP time
{
;Output:
;       ah = BIOS scancode of key pressed
;       al = ASCII character of key pressed
   push ax
   if time eq
      call  [WaitForKeyPress]
   else
      mov   ax,time
      call  [SetDelay]
   end if
   pop ax
}

;________________GOTO__________________
Macro GOTO _op1
{
        jmp _op1
}

;________________GOSUB_________________
Macro GOSUB _subname
{
        call _subname
}

;________________RETURN________________
Macro RETURN
{
        ret
}

;________________PEEK__________________
Macro PEEK _op1
{
        mov al, [_op1]          ;put value of address in eax
}

;________________POKE__________________
Macro POKE _op1, _op2           ; need to check type, so they can use a varable not just number
{
        push edx
        mov edx, _op1
        mov byte [edx], _op2    ;put _op2 into address _op1
        pop edx
}

;________________OUT___________________
Macro OUT_PORT _op1, _op2            ; need to check type, so they can use a varable not just number
{
        push dx
        push al
        mov dx, _op1
        mov al, _op2
        out word dx,al          ;put _op2 into port _op1
        pop al
        pop dx
}

;________________IN____________________
Macro IN_PORT _op1
{
        mov al, [_op1]          ;put value of address in eax
}

;________________REBOOT________________
Macro REBOOT
{
        call [ExitSystem]
}

;________________SOUND_________________
Macro SOUND _opt1,_opt2
{
        push  ax
        push  bx
        push  dx
        mov   al,0xB6           ; Init channel 2 of timer
        out   0x43,al
        mov   dx,0x12           ; clock frequency /
        mov   ax,0x34DD
        mov   bx,_opt1          ; Frequency
        div   bx                ; = timer clock ticks
        out   0x42,al           ; Load timer
        mov   al,ah
        out   0x42,al
        in    al,0x61           ; get value port 61h
        or    al,00000011b      ; Set bits to turn speaker on
        out   0x61,al
        mov   ax,_opt2          ; sound duration in clock ticks
        call  [SetDelay]
        in    al,0x61           ; turn off speaker
        and   al,11111100b
        out   0x61,al
        pop   dx
        pop   bx
        pop   ax
}

;________________BEEP__________________
Macro BEEP
{
        push  ax
        push  bx
        push  dx
        mov   bx,0x200
        mov   ax,0x34dd
        mov   dx,0x0012
        div   bx                ; **** pre calc this number ***
        mov   bx,ax
        in    al,0x61           ; get value of port 61h
        test  al,3              ; is the speaker turned on
        jnz   @f                ; skip the init and turning on if it's on
        or    al,3
        out   0x61,al           ; speaker on
        mov   al,0xb6
        out   0x43,al           ; Init port
@@:
        mov   al,bl             ; set timer to frequency
        out   0x42,al
        mov   al,bh
        out   0x42,al
        mov   ax,8              ; wait about 1/2 second
        call  [SetDelay]
        in    al,0x61           ; turn off speaker
        and   al,11111100b
        out   0x61,al
        pop   dx
        pop   bx
        pop   ax
}

;________________DEF___________________
Macro DEF  _varname, _vartype, _varval
{
        if _vartype = Short
           _varname     db 0
                        db _varval
        else if _vartype = Integer
           _varname     db 1
                        dw _varval
        else if _vartype = Long
           _varname     db 2
                        dd _varval
        else if _vartype = String
           _varname     db 9
                        dw 128        ;need to let it be defined several ways<----------**
                        db _varval,0
        end if
}

Short       equ 0
Integer     equ 1
Long        equ 2
Float       equ 3
String      equ 9
FALSE       equ 0
False       equ 0
false       equ 0
TRUE        equ 1
True        equ 1
true        equ 1

 ;---------------------------------;
 ; Dam, bunch of run time data     ;
 ; not sure how to get around this ;
 ;---------------------------------;

_grfxMode:      db 14           ; the graphics mode we are in
_grfxScreen:    dd 0xb79e0      ; the base address of the screen
_grfxCls:       dw 2000         ; screen size (dwords)
_grfxLL:        dw 40           ; line size (dword)
_grfxScreen_x   db 0            ; cursor location on screen
_grfxScreen_y   db 0            ; cursor location on screen
_grfxColor      db 0Fh          ; text color

SkipQBASIC:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/_pending/FBasDx01/test.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
include 'FBASIC.INC'
cls
print "print in quits works "

goto humm
print "this shouldn't get printed"
humm:

gosub DoSub

color 1
print "color 1"
color 2
print "color 2"
locate 5,5
color 3
print "color 3 at new location"
sleep

screen 0
print "Dos text mode works, locate is off location"
sleep
screen 15
print "decided to add hi res vesa text mode here"
sleep
screen 14
print "decided to add Dexos text mode here"
sleep

PRINT /n,"Quoted String"," on the same line",/n,"or on the next line",/n,/n ; /n = next line
PRINT "Short ",A,/n
PRINT "Integer ",B,/n
PRINT "Long ",C,/n
PRINT D,/n,/n
BEEP
SLEEP

Print "Sounds:"
Sound 32,4
Sound 64,4
Sound 128,4
Sound 256,4
Sound 512,4
Sound 1024,4
Sound 2048,4
Sound 4096,4
Print /n,"cursor is now off"
CursorOff
Sleep
Print /n,"cursor is now back on"
CursorOn
Sleep

Input /n,"an input with no input",/n,/n
Input "input a new D ",D
Print /n,/n,"the old string over writen: ",D
Sleep

Print /n,/n,"Now lets wait a moment.",/n
Pause 37
Print "We are back.",/n
sleep

screen 14
print "Back to Dexos mode. Fasm Basic doesn't leave the title block at a screen change"
PRINT /n,/n,"but cls does have a few options"
sleep

screen 0
cls 0,7,5
gosub TwentyFive
sleep
cls 2,7,3
sleep
cls 0,7,5
gosub TwentyFive
sleep
cls 3,7,3
sleep
cls 0,7,5
gosub TwentyFive
sleep
cls 4,7,3
sleep
cls 0,7,5
gosub TwentyFive
sleep
cls 5,7,3
sleep
cls 0,7,5
gosub TwentyFive
Sleep

goto stop

DoSub:
        print "gosub and return work"
Return

TwentyFive:
	color 7,5,5
	Print "1",/n,"2",/n,"3",/n,"4",/n,"5",/n,"6",/n,"7",/n,"8",/n,"9",/n
	Print "10",/n,"11",/n,"12",/n,"13",/n,"14",/n,"15",/n,"16",/n,"17",/n,"18",/n,"19",/n
	Print "20",/n,"21",/n,"22",/n,"23",/n,"24",/n,"25"
Return

DEF     A, Short    ,32         ; Examples of "Def" command
DEF     B, Integer  ,12312      ;
DEF     C, Long     ,2000000    ;
DEF     D, String   ,"String Varable"

stop:
end_program
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































Deleted freshlib/_pending/lzss/readme.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
LZSS compression library for Flat Assembler
by Mateusz Tymek

1. Introduction
LZSS is a library that provides you with simple routines for data compression. The 
algorithm is based on oryginal idea of Lempel and Ziv, with the modyfications suggeted by 
Storer and Szymanski (that's why its name is LZSS). You can search the Web for "LZSS 
compression" if you need any further information. This implementation uses binary search
trees to speed up compression. It is based on the code of the Allegro Library 
(http://alleg.sourceforge.net), and it have similar (a bit better actually) compression 
ratio. All source code is included. The library is written in FASM, and it uses Fresh
macro library. 
It is distributed under the terms of Fresh Artistic License 
(see http://www.decard.net/license.php).

2. Using LZSS library
To use LZSS library, first you have to include its files in your source. You have to 
include "lzss.inc" file somewhere in the beginning (it contains some definitions, not
the code), and then "lzss.asm" (anywhere in the code section). See "lzsspack.asm" file.
Now you can use the library functions. They can compress/decompress the data, and save
or load it from file.
In next part those functions are covered with more details.

2.1. LZSS Function Reference

proc lzssFreeData, lzss_data
Frees memory occupied by given lzss data. As lzss_data parameter you should use value
returned by lzssPackData.

proc lzssLoadFile, file_name, ptr_size
Loads packed file of given name, decompresses it and returns pointer to unpacked data.
Usually you will want to obtain size of the data after decompression, in such case you 
have to pass a pointer to dword variable as "ptr_size" parameter. If you pass NULL, 
its also OK but then you won't know unpacked data size.

proc lzssPackData, data_to_pack,data_size
Compresses given data of given size. Returns pointer to LZSSData in eax.


proc lzssSaveFile, file_name, buffer, size
Compresses given data of given size and stores it in specified file. If given file
already exists, it will be overwritten. Function returns zero on fail, and non-zero value
on success.

proc lzssUnpackData, lzss_data
Decompresses packed data. lzss_data should be the value returned by lzssPackData.


3. lzsspack.exe
lzsspack is a simple utility that preforms file compression. It is a command line utility. 
To pack some file just type: 
    >lzsspack source_file output_file
source is your file with data to be packed, and output is a name of file to be generated.
To unpack, type: 
    >lzsspack -u packed_file output_file
and it will decompress given file.

lzsspack's source code is included in the package.

4. Changelog

26.10.2004 - fixed serious bug that was causing data loss.
27.10.2004 - optimizations to bitstream library.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































Deleted freshlib/_pending/lzss/source/bits.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
; creates bits stream and returns pointer
proc BitsCreateNew, .buf_size
        begin
        push    ebx edi
        invoke  GetProcessHeap
        mov     edi,eax
        invoke  HeapAlloc,eax,HEAP_ZERO_MEMORY,sizeof.BitStream
        or      eax,eax
        jz      .finish
        mov     ebx,eax
        invoke  HeapAlloc,edi,HEAP_ZERO_MEMORY,[.buf_size]
        or      eax,eax
        jz      .finish
        mov     [ebx+BitStream.buf],eax
        mov     [ebx+BitStream.ptr],eax
        mov     [ebx+BitStream.bit_ptr],0
        mov     eax,ebx
        pop     edi ebx
     .finish:
        return
endp

; create bitstream over existing buffer
proc BitsCreateFrom, .bitbuf
        begin
        push    ebx edi
        invoke  GetProcessHeap
        mov     edi,eax
        invoke  HeapAlloc,eax,HEAP_ZERO_MEMORY,sizeof.BitStream
        or      eax,eax
        jz      .finish
        mov     ebx,eax
        mov     eax,[.bitbuf]
        mov     [ebx+BitStream.buf],eax
        mov     [ebx+BitStream.ptr],eax
        mov     [ebx+BitStream.bit_ptr],0
        mov     eax,ebx
        pop     edi ebx
     .finish:
        return
endp

; destroys given bitstream, but not the buffer (!)
proc BitsDestroy, .stream
       begin
       push     eax
       invoke   GetProcessHeap
       invoke   HeapFree,eax,0,[.stream]
       pop      eax
       return
endp

; destroys given bitstream with buffer
proc BitsDestroyBuf, .stream
       begin
       push     eax ebx
       invoke   GetProcessHeap
       mov      ebx,eax
       mov      eax,[.stream]
       mov      eax,[eax+BitStream.buf]
       invoke   HeapFree,ebx,0,eax
       invoke   HeapFree,ebx,0,[.stream]
       pop      ebx eax
       return
endp


; sets given stream to position 0
proc BitsReset, .stream
        begin
        push    eax ebx
        mov     ebx,[.stream]
        mov     [ebx+BitStream.bit_ptr],0
        mov     eax,[ebx+BitStream.buf]
        mov     [ebx+BitStream.ptr],eax
        pop     ebx eax
        return
endp

; puts given number of bits into stream
proc BitsPut, .stream,.bits,.bit_count
        begin
        push    eax ebx ecx edx esi edi
        ; generate mask in edi:esi
        xor     eax,eax
        dec     eax
        mov     esi,eax
        mov     edi,eax
        mov     ebx,[.stream]
        mov     ecx,[.bit_count]
        shl     esi,cl
        mov     ecx,[ebx+BitStream.bit_ptr]
        shld    edi,esi,cl
        shld    esi,eax,cl
        ; load new bits into edx:ecx; at this point ecx==[ebx+BitStream.bit_ptr]
        xor     edx,edx
        mov     eax,[.bits]
        shld    edx,eax,cl
        shl     eax,cl
        mov     ecx,eax
        ; finally, store new bits using
        mov     ebx,[ebx+BitStream.ptr]
        and     [ebx],esi
        or      [ebx],ecx
        add     ebx,4
        and     [ebx],edi
        or      [ebx],edx
        ; and fix the pointers
        mov     ebx,[.stream]
        mov     eax,[.bit_count]
        add     [ebx+BitStream.bit_ptr],eax
        cmp     [ebx+BitStream.bit_ptr],32
        jb      .finish
        sub     [ebx+BitStream.bit_ptr],32
        add     [ebx+BitStream.ptr],4
      .finish:
        pop     edi esi edx ecx ebx eax
        return
endp

; reads given number of bits form the stream
proc BitsGet, .stream,.bit_count
        begin
        push    ebx ecx edx esi
        ; generate mask (in esi)
        xor     esi,esi
        dec     esi
        mov     ecx,[.bit_count]
        shl     esi,cl
        not     esi
        mov     ebx,[.stream]
        mov     eax,[ebx+BitStream.ptr]
        mov     edx,[eax+4]
        mov     eax,[eax]
        mov     ecx,[ebx+BitStream.bit_ptr]
        shrd    eax,edx,cl
        and     eax,esi
        ; fix the pointers
        mov     ebx,[.stream]
        mov     edx,[.bit_count]
        add     [ebx+BitStream.bit_ptr],edx
        cmp     [ebx+BitStream.bit_ptr],32
        jb      .finish
        sub     [ebx+BitStream.bit_ptr],32
        add     [ebx+BitStream.ptr],4
     .finish:
        pop     esi edx ecx ebx
        return
endp

; returns size (in bytes) of given stream
proc BitsGetSize, .stream
        begin
        push    ebx edx
        mov     ebx,[.stream]
        xor     edx,edx                         ; get number of bytes in additional bits
        mov     eax,[ebx+BitStream.bit_ptr]
        or      eax,eax
        jz      .no_extra_bits
        shr     eax,3
        inc     eax
        mov     edx,eax
     .no_extra_bits:
        mov     eax,[ebx+BitStream.ptr]
        sub     eax,[ebx+BitStream.buf]
        add     eax,edx
        pop     edx ebx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































Deleted freshlib/_pending/lzss/source/bits.inc.

1
2
3
4
5
struct BitStream
  .buf dd ?
  .ptr dd ?
  .bit_ptr dd ?
ends
<
<
<
<
<










Deleted freshlib/_pending/lzss/source/cmdln.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
; ------------------------------
; Base64 encoding program v1.0
; by Mateusz Tymek (c) 2004
;
; ------------------------------
; cmdln.asm
;   command line parsing
; ------------------------------


iglobal
; command line variables
cmdln:
  .argc   dd ?
  .argv   rd 0x10    ; 16 parameters limit
  .params rb 0x100

  .input_fname  dd ?
  .output_fname dd ?
  .switches     rd 8
  .out_buf      rb 0x50
endg


; strlen - returns length of given string
; from Fresh Standard Library
proc strlen, .str
        begin
        push    ebx
        mov     eax,[.str]
        mov     ebx,eax
  .scan:
        cmp     byte[eax],0
        lea     eax,[eax+1]
        jne     .scan
        sub     eax,ebx
        dec     eax         ; return value in eax
        pop     ebx
        return
endp

; strlen - returns length of given string
; from Fresh Standard Library
proc strcpy, .dest, .source
        begin
        push    esi edi eax ecx
        mov     edi,[.dest]
        mov     esi,[.source]
        stdcall strlen, esi
        mov     ecx,eax
        cld
        rep     movsb               ; copy strings
.finish:
        pop     ecx eax edi esi
        return
endp


; splits command line into single parameters
; (argv table)
proc parse_command_line, .cmdline
        begin
        push    eax ebx esi edi
        mov     [cmdln.argc],0
        mov     ebx,cmdln.argv
        mov     edi,cmdln.params
        mov     esi,[.cmdline]
     .load:
        mov     al,[esi]
        inc     esi
     .scan:
        cmp     al,0x20
        je      .load
        or      al,al
        jz      .finish
        inc     [cmdln.argc]
        mov     [ebx],edi
        add     ebx,4
        cmp     al,'"'
        je      .copy_quoted
     .copy_param:
        mov     [edi],al
        inc     edi
        mov     al,[esi]
        inc     esi
        cmp     al,0x20
        je      .param_copied
        or      al,al
        jz      .param_copied
        jmp     .copy_param
     .param_copied:
        mov     byte[edi],0
        inc     edi
        jmp     .scan
     .copy_quoted:
        mov     al,[esi]
        inc     esi
        cmp     al,'"'
        je      .end_quoted
        or      al,al
        jz      .param_copied
        mov     [edi],al
        inc     edi
        jmp     .copy_quoted
     .end_quoted:
        mov     al,[esi]
        inc     esi
        jmp     .param_copied
     .finish:
        pop     edi esi ebx eax
        return
endp


proc arrange_cmdline, .cmdline,.def_output_ext
        begin
        stdcall parse_command_line, [.cmdline]
        mov     esi,cmdln.switches
        xor     edx,edx
        xor     ecx,ecx

     .scan_param:
        inc     ecx
        cmp     ecx,[cmdln.argc]
        jae     .params_scanned
        mov     eax,[cmdln.argv+ecx*4]
        cmp     byte[eax],'-'
        je      .switch
        or      edx,edx
        jnz     .output_name
        mov     [cmdln.input_fname],eax
        inc     edx
        jmp     .scan_param
     .output_name:
        mov     [cmdln.output_fname],eax
        inc     edx
        jmp     .scan_param
     .switch:
        mov     [esi],eax
        add     esi,4
        jmp     .scan_param

     .params_scanned:
        cmp     [cmdln.argc],1
        je      .got_output_fname
        mov     dword[esi],0

        cmp     edx,2
        jae     .got_output_fname
        stdcall strcpy, cmdln.out_buf,[cmdln.input_fname]
        stdcall replace_ext, cmdln.out_buf,[.def_output_ext]
        mov     [cmdln.output_fname],cmdln.out_buf
     .got_output_fname:
        return
endp


; replaces extension of given filename to specified one.
; if ext is NULL, then the extension is removed
proc replace_ext, .filename,.ext
        begin
        mov     edi,[.filename]
        stdcall strlen, [.filename]
        add     edi,eax
        mov     ebx,edi
        dec     edi
    .scan:
        mov     al,[edi]
        cmp     al,'.'
        je      .got_extension
        cmp     al,'\'
        je      .append
        cmp     al,'/'
        je      .append
        cmp     al,':'
        je      .append
        or      al,al
        jz      .append
        dec     edi
        jmp     .scan

    .append:
        mov     edi,ebx
        mov     byte[edi],'.'
        inc     edi
        jmp     .get_new_ext

    .got_extension:
        inc     edi
    .get_new_ext:
        mov     esi,[.ext]
        or      esi,esi
        jz      .remove_ext
    .copy_ext:
        mov     al,[esi]
        mov     [edi],al
        inc     esi
        inc     edi
        or      al,al
        jnz     .copy_ext
    .finish:
        return
    .remove_ext:
        dec     edi
        xor     al,al
        mov     [edi],al
        jmp     .finish
endp


; replaces filename in given path
; if fname is NULL, then the file name is removed
proc replace_fname, .path,.fname
        begin
        mov     edi,[.path]
        stdcall strlen, [.path]
        or      eax,eax
        jz      .prepare_copy
        add     edi,eax
        mov     ebx,edi
        dec     edi
    .scan:
        mov     al,[edi]
        cmp     al,'\'
        je      .got_fname
        cmp     al,'/'
        je      .got_fname
        cmp     al,':'
        je      .got_fname
        or      al,al
        jz      .got_fname
        dec     edi
        jmp     .scan

    .got_fname:
        inc     edi
    .prepare_copy:
        mov     esi,[.fname]
    .copy_fname:
        mov     al,[esi]
        mov     [edi],al
        inc     esi
        inc     edi
        or      al,al
        jnz     .copy_fname
    .finish:
        return
endp


proc get_switch_w
        begin
        push    ebx edx
        mov     ebx,cmdln.switches
     .check:
        cmp     dword[ebx],0
        je      .false
        mov     edx,[ebx]

        cmp     word[edx],ax
        je      .true
        add     ebx,4
        jmp     .check
     .false:
        xor     eax,eax
        pop     edx ebx
        return
     .true:
        xor     eax,eax
        inc     eax
        pop     edx ebx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































Deleted freshlib/_pending/lzss/source/lzss.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
;  lzss compression library
;  copyright (c) 2004 Mateusz Tymek
;
;  17.03.2004
;  last updated 27.10.2004
;  version 1.01


uglobal

lzss:
  .rnode rd LZSS_DICTIONARY_SIZE + 1 + 0x100
  .lnode rd LZSS_DICTIONARY_SIZE + 1
  .parent rd LZSS_DICTIONARY_SIZE + 1
  sizeof.trees = $-lzss.rnode

  .dictionary rb LZSS_DICTIONARY_SIZE + LZSS_MAX_COUNT
  sizeof.dictionary = $-lzss.dictionary

  .best_match_len dd ?
  .best_match_pos dd ?
endg

iglobal
  lzss.packer_func dd 0
endg

; creates new empty LZSSData structure
proc lzssNewData
        begin
        invoke  GetProcessHeap
        invoke  HeapAlloc, eax,HEAP_ZERO_MEMORY,sizeof.LZSSData         ; alloc mem for LZSSData struc
        return
endp


; destroys givem LZSSData structure
proc lzssFreeData, .lzss_data
        begin
        push    eax ebx
        invoke  GetProcessHeap
        mov     ebx,eax
        mov     eax,[.lzss_data]
        invoke  HeapFree, ebx,0,[eax+LZSSData.data]
        invoke  HeapFree, ebx,0,[.lzss_data]
        pop     ebx eax
        return
endp

;-----------------------------------------------------------------------------------------------


proc lzss_new_tree
        begin
        push    eax ecx esi edi
        mov     eax,LZSS_NO_TREE
        mov     ecx,LZSS_DICTIONARY_SIZE + 1
        mov     esi,lzss.lnode
        mov     edi,lzss.parent
     .clear:
        mov     [esi],eax
        mov     [edi],eax
        add     edi,4
        add     esi,4
        dec     ecx
        jnz     .clear
        mov     edi,lzss.rnode
        mov     ecx,LZSS_DICTIONARY_SIZE + 0x101
     .clear_btrees:
        mov     [edi],eax
        add     edi,4
        dec     ecx
        jnz     .clear_btrees
        pop     edi esi ecx eax
        return
endp


proc lzss_insert_node, .buffer_pos    ; inserts string at text_buf+[buf_pos] into the tree
        begin
        push    eax ebx ecx edx esi edi
        xor     eax,eax
        mov     [lzss.best_match_len],eax
        mov     [lzss.best_match_pos],eax

        mov     eax,[.buffer_pos]
        mov     edx,eax
        add     eax,lzss.dictionary
        movzx   eax,byte[eax]
        lea     ebx,[LZSS_DICTIONARY_SIZE+1+eax]
        mov     edx,1           ; edx will hold comparision result
        mov     eax,LZSS_NO_TREE
        mov     [lzss.rnode+edx*4],eax
        mov     [lzss.lnode+edx*4],eax

  .search_tree:
        or      edx,edx
        js      .left_node
     .right_node:
        cmp     [lzss.rnode+ebx*4],LZSS_NO_TREE
        je      .put_right

        mov     ebx,[lzss.rnode+ebx*4]
        jmp     .node_ok
     .put_right:
        mov     eax,[.buffer_pos]
        mov     [lzss.rnode+ebx*4],eax
        mov     [lzss.parent+eax*4],ebx
        jmp     .finish
     .left_node:
        cmp     [lzss.lnode+ebx*4],LZSS_NO_TREE
        je      .put_left

        mov     ebx,[lzss.lnode+ebx*4]
        jmp     .node_ok
     .put_left:
        mov     eax,[.buffer_pos]
        mov     [lzss.lnode+ebx*4],eax
        mov     [lzss.parent+eax*4],ebx
        jmp     .finish
     .node_ok:
        push    esi edi
        lea     edi,[lzss.dictionary+ebx]
        mov     esi,[.buffer_pos]
        lea     esi,[lzss.dictionary+esi]
        mov     ecx,LZSS_MAX_COUNT-1
        inc     esi     ;  we know that first character
        inc     edi     ;  already matches
        xor     edx,edx
        xor     eax,eax
     .compare:
        mov     dl,[esi]
        mov     al,byte[edi]
        sub     edx,eax
        or      edx,edx
        jnz     .compared
        inc     edi
        inc     esi
        dec     ecx
        jnz     .compare
     .compared:
        pop     esi edi

        mov     eax,LZSS_MAX_COUNT-1
        dec     ecx
        sub     eax,ecx
        cmp     eax,[lzss.best_match_len]
        jbe     .search_tree
        mov     [lzss.best_match_len],eax
        mov     [lzss.best_match_pos],ebx

        cmp     eax,LZSS_MAX_COUNT
        jae     .got_max_count

        jmp     .search_tree

     .got_max_count:
        mov     eax,[.buffer_pos]
        mov     edx,[lzss.parent+ebx*4]
        mov     [lzss.parent+eax*4],edx

        mov     edx,[lzss.lnode+ebx*4]
        mov     [lzss.lnode+eax*4],edx
        mov     [lzss.parent+edx*4],eax

        mov     edx,[lzss.rnode+ebx*4]
        mov     [lzss.rnode+eax*4],edx
        mov     [lzss.parent+edx*4],eax

        mov     edx,[lzss.parent+ebx*4]
        cmp     [lzss.rnode+edx*4],ebx
        je      .right
     .left:
        mov     [lzss.lnode+edx*4],eax
        jmp     .ok
     .right:
        mov     [lzss.rnode+edx*4],eax
     .ok:
        mov     eax,LZSS_NO_TREE
        mov     [lzss.parent+ebx*4],eax
        mov     [lzss.lnode+ebx*4],eax
        mov     [lzss.rnode+ebx*4],eax

     .finish:
        pop     edi esi edx ecx ebx eax
        return
endp


; removes tree node at [buffer_pos]
proc lzss_delete_node, .buffer_pos
        begin
        push    eax ebx ecx edx
        mov     eax,[.buffer_pos]
        cmp     dword[lzss.parent+eax*4],LZSS_NO_TREE   ; empty?
        je      .finish

        cmp     dword[lzss.rnode+eax*4],LZSS_NO_TREE
        je      .empty_right
        cmp     dword[lzss.lnode+eax*4],LZSS_NO_TREE
        je      .empty_left


        ; if we are here then none of children is empty

        mov     ebx,[lzss.lnode+eax*4]
        cmp     [lzss.rnode+ebx*4],LZSS_NO_TREE
        je      .got_free_rnode
      .find_free_rnode:
        mov     ebx,[lzss.rnode+ebx*4]
        cmp     [lzss.rnode+ebx*4],LZSS_NO_TREE
        jne     .find_free_rnode

        mov     edx,[lzss.parent+ebx*4]
        mov     ecx,[lzss.lnode+ebx*4]
        mov     [lzss.rnode+edx*4],ecx
        mov     [lzss.parent+ecx*4],edx

        mov     edx,[lzss.lnode+eax*4]
        mov     [lzss.lnode+ebx*4],edx
        mov     [lzss.parent+edx*4],ebx

  .got_free_rnode:

        mov     edx,[lzss.rnode+eax*4]
        mov     [lzss.rnode+ebx*4],edx
        mov     [lzss.parent+edx*4],ebx

        jmp     .remove

  .empty_left:
        mov     ebx,[lzss.rnode+eax*4]
        jmp     .remove
  .empty_right:
        mov     ebx,[lzss.lnode+eax*4]

  .remove:

        mov     edx,[lzss.parent+eax*4]         ; now edx holds parent of node being removed
        mov     [lzss.parent+ebx*4],edx

        ; now fix the valid child
        cmp     [lzss.rnode+edx*4],eax
        je      .fix_right_child
  .fix_left_child:
        mov     [lzss.lnode+edx*4],ebx
        jmp     .clear
  .fix_right_child:
        mov     [lzss.rnode+edx*4],ebx

  .clear:       ; clear the node that is being removed
        mov     [lzss.parent+eax*4],LZSS_NO_TREE
        mov     [lzss.rnode+eax*4],LZSS_NO_TREE
        mov     [lzss.lnode+eax*4],LZSS_NO_TREE

  .finish:

        pop     edx ecx ebx eax
        return
endp


proc lzssPackData, .buffer,.buffer_size
.lzss_data dd ?
.bitstream dd ?
        begin
        push    ebx ecx edx esi edi
        ; fill the dictionary with zeroes
        mov     edi,lzss.dictionary
        mov     ecx,(LZSS_DICTIONARY_SIZE + LZSS_MAX_COUNT)/2
        xor     eax,eax
      .clear_dictionary:
        mov     [edi],ax
        add     edi,2
        dec     ecx
        jnz     .clear_dictionary

        stdcall lzssNewData
        or      eax,eax
        jz      .finish
        mov     [.lzss_data],eax
        mov     edi,eax
        invoke  GetProcessHeap
        mov     ebx,eax
        mov     eax,[.buffer_size]       ; calculate maximum memory that can be needed by
        shr     eax,3                   ; compressed data. It is data_size + data_size/8 ...
        inc     eax                     ; and one more byte just to be sure :)
        add     eax,[.buffer_size]       ;
        invoke  HeapAlloc, ebx,HEAP_ZERO_MEMORY,eax
        or      eax,eax
        jz      .finish
        mov     [edi+LZSSData.data],eax
        mov     ecx,[.buffer_size]
        mov     [edi+LZSSData.unpacked_size],ecx
        mov     eax,[.buffer]            ; esi will point to input buffer
        add     eax,ecx         ; add eax,[buffer_size]
        stdcall BitsCreateFrom, [edi+LZSSData.data]
        mov     [.bitstream],eax

        ; edi will point to the end of the dictionary...
        mov     edi,LZSS_DICTIONARY_SIZE-LZSS_MAX_COUNT
        ; ... and esi will mark the start
        xor     esi,esi
        stdcall lzss_new_tree


        xor     edx,edx
     .read_first_bytes:
        mov     eax,[.buffer]
        mov     al,[eax]
        inc     [.buffer]
        mov     [lzss.dictionary+edi+edx],al
        inc     edx
        cmp     edx,LZSS_MAX_COUNT
        jae     .got_first_bytes
        dec     [.buffer_size]
        jz      .got_first_bytes
        jmp     .read_first_bytes
     .got_first_bytes:

        or      edx,edx
        jz      .packed

        mov     ecx,LZSS_MAX_COUNT-1
        mov     eax,edi
        dec     eax
     .prepare_tree:
        stdcall lzss_insert_node,eax
        dec     eax
        dec     ecx
        jnz     .prepare_tree
        stdcall lzss_insert_node,edi         ; insert the string just read; best_match_len and best_match_pos are set

     .packer_loop:
        cmp     [lzss.best_match_len],edx    ; best_match_len may be too long near the end
        jbe      .lzss.best_match_len_ok
        mov     [lzss.best_match_len],edx
     .lzss.best_match_len_ok:

        cmp     [lzss.best_match_len],LZSS_THRESHOLD   ; send unpacked byte or ofs-length pair?
        ja      .send_packed
        stdcall BitsPut, [.bitstream],0,1       ; send "unpacked data" flag
        mov     al,[lzss.dictionary+edi]
        stdcall BitsPut, [.bitstream],eax,8     ; send byte directly
        mov     [lzss.best_match_len],1              ; mark that we have processed just one byte

        jmp     .item_packed
     .send_packed:
        stdcall BitsPut, [.bitstream],1,1       ; "packed data" flag
        stdcall BitsPut, [.bitstream],[lzss.best_match_pos],LZSS_OFFSET_BITS
        mov     eax,[lzss.best_match_len]
        sub     eax,LZSS_THRESHOLD+1
        stdcall BitsPut, [.bitstream],eax,LZSS_COUNT_BITS


     .item_packed:
        xor     ecx,ecx
        mov     ebx,[lzss.best_match_len]    ; ebx will hold value of "last match length"
        cmp     [.buffer_size],0
        je      .new_bytes_ok
     .get_new_bytes:
        cmp     ecx,ebx                 ; compare ecx to [last_match_len]
        jae     .new_bytes_ok
        dec     [.buffer_size]
        jz      .new_bytes_ok
        stdcall lzss_delete_node,esi
        mov     eax,[.buffer]
        inc     [.buffer]
        mov     al,[eax]
        mov     [lzss.dictionary+esi],al        ; put new byte in the dictionary
        cmp     esi,LZSS_MAX_COUNT
        jae     .no_extra
        mov     [lzss.dictionary+esi+LZSS_DICTIONARY_SIZE],al
     .no_extra:
        inc     esi
        inc     edi
        mov     eax,LZSS_DICTIONARY_SIZE
        dec     eax
        and     esi,eax
        and     edi,eax

        stdcall lzss_insert_node,edi         ; insert new string

        inc     ecx
        jmp     .get_new_bytes
     .new_bytes_ok:
        cmp     ecx,ebx
        jae     .packed
        inc     ecx
        stdcall lzss_delete_node,esi
        inc     esi
        inc     edi
        mov     eax,LZSS_DICTIONARY_SIZE
        dec     eax
        and     esi,eax
        and     edi,eax
        dec     edx
        jz      .new_bytes_ok

        stdcall lzss_insert_node,edi
        jmp     .new_bytes_ok
     .packed:

        or      edx,edx
        jnz     .packer_loop

        mov     ebx,[.lzss_data]
        stdcall BitsGetSize, [.bitstream]
        mov     [ebx+LZSSData.packed_size],eax
     .finish:

        mov     eax,[.lzss_data]
        pop     edi esi edx ecx ebx
        return
endp


;iglobal
;  szOutFile db "out.dat", 0
;  szOutFile2 db "out2.dat", 0
;endg
;

;-----------------------------------------------------------------------------------------------



; debug lines
;iglobal
;  szDictionary db "ofs: %d, len: %d", 13, 10, 0
;  szDirect     db "direct byte: %d ('%c')", 13, 10, 0
;  szEndMarker  db "eof", 13, 10, 0
;endg


; unpacks given LZSSData structure and returns pointer
; when you have finished with this data, you should
; free this memory using HeapFree()
proc lzssUnpackData, .lzss_data
.uncompressed dd ?
.size         dd ?
        begin
        push    ebx ecx edx esi edi

        ; fill the dictionary with zeroes
        mov     edi,lzss.dictionary
        mov     ecx,(LZSS_DICTIONARY_SIZE + LZSS_MAX_COUNT)/2
        xor     eax,eax
      .clear_dictionary:
        mov     [edi],ax
        add     edi,2
        dec     ecx
        jnz     .clear_dictionary

        mov     ebx,[.lzss_data]
        invoke  GetProcessHeap
        invoke  HeapAlloc, eax,HEAP_ZERO_MEMORY,[ebx+LZSSData.unpacked_size]
        mov     [.uncompressed],eax
        mov     edi,eax
        stdcall BitsCreateFrom, [ebx+LZSSData.data]
        mov     esi,eax
        mov     eax,[ebx+LZSSData.unpacked_size]
        mov     [.size],eax
        mov     edx,LZSS_DICTIONARY_SIZE - LZSS_MAX_COUNT

   .unpack:
        stdcall BitsGet,esi,1
        or      eax,eax
        jnz     .from_dictionary
        stdcall BitsGet,esi,8

     ; debug lines
;     pusha
;     cinvoke printf, szDirect, eax,eax
;     popa
        mov     [edi],al
        inc     edi

        mov     [lzss.dictionary+edx],al
        inc     edx
        mov     eax,LZSS_DICTIONARY_SIZE
        dec     eax
        and     edx,eax
        dec     [.size]
        jz      .finish
        jmp     .unpack


    .from_dictionary:
        stdcall BitsGet, esi,LZSS_OFFSET_BITS         ; load position
;     push    eax  ; debug line
        mov     ebx,eax    ; no, unpack portion
        stdcall BitsGet, esi,LZSS_COUNT_BITS          ; load counter
        mov     ecx,eax
        add     ecx,LZSS_THRESHOLD+1
        sub     [.size],ecx

; debug lines
;     pop     eax
;     pusha
;     cinvoke printf, szDictionary, eax,ecx
;     popa

     .copy:
        mov     al,[lzss.dictionary+ebx]
        mov     [edi],al
        mov     [lzss.dictionary+edx],al
        inc     ebx
        inc     edi
        inc     edx
        mov     eax,LZSS_DICTIONARY_SIZE
        dec     eax
        and     edx,eax
        and     ebx,eax

        dec     ecx
        jnz     .copy
        cmp     [.size],0

        je      .finish
        jmp     .unpack
     .finish:

;  debug lines
;     pusha
;     cinvoke printf, szEndMarker
;     popa

        stdcall BitsDestroy, esi


;        invoke  CreateFile, szOutFile2,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0
;        mov     ebx,eax
;        invoke  WriteFile,eax,lzss.dictionary,sizeof.dictionary,tmp,0
;        invoke  CloseHandle,ebx
;

        mov     eax,[.uncompressed]


        pop     edi esi edx ecx ebx
        return
endp



; file routines

; compress data and store it in given file; returns 0 on fail
proc lzssSaveFile, .file_name,.buffer,.size
.hdr LZSSFileHeader
.tmp dd ?
        begin
        push    ebx ecx edx esi
        mov     eax,[lzss.packer_func]
        or      eax,eax
        jnz     .packer_func_ok
        mov     [lzss.packer_func],lzssPackData
     .packer_func_ok:
        stdcall [lzss.packer_func], [.buffer],[.size]
        mov     esi,eax
        mov     [.hdr.id],"LZSS"
        mov     eax,[.size]
        mov     [.hdr.unpacked_size],eax
        invoke  CreateFile, [.file_name],GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0
        cmp     eax,INVALID_HANDLE_VALUE
        je      .error
        mov     ebx,eax
        lea     eax,[.hdr]
        lea     edx,[.tmp]
        invoke  WriteFile,ebx,eax,sizeof.LZSSFileHeader,edx,0
        mov     ecx,[esi+LZSSData.packed_size]
        mov     eax,[esi+LZSSData.data]
        invoke  WriteFile,ebx,eax,ecx,tmp,0
        invoke  CloseHandle,ebx
        stdcall lzssFreeData,esi
        xor     eax,eax
        dec     eax
     .finish:
        pop     esi edx ecx ebx
        return
     .error:
        xor     eax,eax
        jmp     .finish
endp


; loads packed data from given file, unpacks it and returns pointer
; (0 on fail); ptr_size should be a pointer to dword variable
; that will contain unpacked data size
proc lzssLoadFile, .file_name, .ptr_size
.input_buf  dd ?
.input_size dd ?
        begin
        push    ebx ecx edx esi edi
        invoke  CreateFile, [.file_name],GENERIC_READ,0,0,OPEN_EXISTING,0,0
        cmp     eax,INVALID_HANDLE_VALUE
        je      .error
        mov     ebx,eax
        invoke  SetFilePointer,ebx,0,0,FILE_END
        mov     [.input_size],eax
        mov     esi,eax
        invoke  GetProcessHeap
        invoke  HeapAlloc, eax,HEAP_ZERO_MEMORY,esi
        or      eax,eax
        jz      .finish
        mov     [.input_buf],eax
        invoke  SetFilePointer, ebx,0,0,FILE_BEGIN
        invoke  ReadFile, ebx,[.input_buf],esi,tmp,0
        invoke  CloseHandle,ebx
        stdcall lzssNewData
        or      eax,eax
        jz      .finish
        mov     esi,eax
        mov     eax,[.input_buf]
        add     eax,sizeof.LZSSFileHeader
        mov     [esi+LZSSData.data],eax
        mov     eax,[.input_buf]
        mov     eax,[eax+LZSSFileHeader.unpacked_size]
        mov     [esi+LZSSData.unpacked_size],eax
        stdcall lzssUnpackData, esi
        or      eax,eax
        jz      .finish
        mov     ebx, eax

        mov     eax,[.ptr_size]
        or      eax,eax
        jz      .no_size_ptr
        mov     edx,[esi+LZSSData.unpacked_size]
        mov     [eax],edx
     .no_size_ptr:
        stdcall lzssFreeData,esi
        mov     eax,ebx
     .finish:
        pop     edi esi edx ecx ebx
        return
     .error:
        xor     eax,eax
        jmp     .finish
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/_pending/lzss/source/lzss.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
; packed data structure
struct LZSSData
  .packed_size     dd ?
  .unpacked_size   dd ?
  .data            dd ?
ends


; packed file header
struct LZSSFileHeader
  .id            dd ?
  .unpacked_size dd ?
ends


; lzss settings

LZSS_THRESHOLD       = 2

LZSS_COUNT_BITS      = 4
LZSS_OFFSET_BITS     = 12

LZSS_DICTIONARY_SIZE = (2 shl (LZSS_OFFSET_BITS-1))
LZSS_MAX_COUNT       = (2 shl (LZSS_COUNT_BITS-1)) + LZSS_THRESHOLD

LZSS_NO_TREE = LZSS_DICTIONARY_SIZE
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































Deleted freshlib/_pending/lzss/source/lzsspack.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
format PE console
entry start
include "%finc%/win32/win32a.inc"
include "%finc%/libs/strlib.inc"
include "bits.inc"
include "lzss.inc"
include "lzssstat.inc"

..ShowSkipped = 0

section '.code' code readable executable

include "%finc%/libs/strlib.asm"
include "bits.asm"
include "cmdln.asm"
include "lzss.asm"
include "lzssstat.asm"


  start:
        invoke  GetCommandLine
        stdcall arrange_cmdline, eax,szDefExt

        mov     ax,'-u'
        call    get_switch_w
        or      eax,eax
        jz      pack_file


     unpack_file:
        cmp     [cmdln.input_fname],0
        je      usage
        stdcall replace_ext, [cmdln.output_fname],szDefOutExt
        stdcall lzssLoadFile,[cmdln.input_fname],unp_size
        push    eax
        invoke  CreateFile, [cmdln.output_fname],GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0
        mov     ebx,eax
        pop     eax
        invoke  WriteFile,ebx,eax,[unp_size],tmp,0
        invoke  CloseHandle,ebx
        stdcall lzssFreeData, esi
        jmp     finish

     pack_file:
        cmp     [cmdln.input_fname],0
        je      usage
        invoke  CreateFile, [cmdln.input_fname],GENERIC_READ,0,0,OPEN_EXISTING,0,0
        cmp     eax,INVALID_HANDLE_VALUE
        je      finish
        mov     ebx,eax
        invoke  SetFilePointer, ebx,0,0,FILE_END
        mov     [input_size],eax
        mov     esi,eax
        invoke  GetProcessHeap
        invoke  HeapAlloc, eax,HEAP_ZERO_MEMORY,esi
        or      eax,eax
        jz      finish
        mov     [input_buf],eax
        invoke  SetFilePointer, ebx,0,0,FILE_BEGIN
        invoke  ReadFile, ebx,[input_buf],esi,tmp,0
        invoke  CloseHandle, ebx
        mov     [lzss.packer_func],lzssStatPack
        mov     ebx,[cmdln.argv]
        stdcall lzssSaveFile, [cmdln.output_fname],[input_buf],[input_size]
        cinvoke printf, szStatus, [lzss_stat.time],[lzss_stat.kbytes_per_sec],\
                                  [lzss_stat.size],[lzss_stat.packed_size],[lzss_stat.ratio],\
                                  [lzss_stat.total_items],[lzss_stat.direct_bytes],\
                                  [lzss_stat.dictionary_entries]
        jmp     finish

     usage:
        cinvoke printf, szUsage
     finish:
        invoke  ExitProcess, 0



iglobal
  szDefExt    db "lzss", 0
  szDefOutExt db "out", 0

  szUsage db "usage:", 13, 10, "  to compress: lzsspack input [output]", 13, 10
          db "  to decompress: lzsspack -u input output", 13, 10, 0

  szStatus db "status: ", 13, 10
           db "   total compression time: %d seconds", 13, 10
           db "            average speed: %d kbytes/sec", 13, 10
           db "       unpacked file size: %d bytes", 13, 10
           db "         packed data size: %d bytes", 13, 10
           db "        compression ratio: %d percent", 13, 10
           db 13, 10
           db "              total items: %d", 13, 10
           db "  direct (unpacked) bytes: %d", 13, 10
           db "       dictionary entries: %d", 13, 10, 0

endg


uglobal
  input_buf   dd ?
  input_size  dd ?
  output_name dd ?
  tmp         dd ?
  unp_size    dd ?
  argc        dd ?
  argv        dd ?
  env         dd ?
  hdr         LZSSFileHeader
  name_buf    rb 0x100
endg

;data fixups
;end data

section '.data' data readable writeable
IncludeAllGlobals


section '.idata' import data readable

library kernel32,"KERNEL32.DLL",\
        crtdll,"CRTDLL.DLL"

include "%finc%/win32/apia/kernel32.inc"

import crtdll,\
       __getmainargs,"__GetMainArgs",\
       printf,"printf",\
       flushall,"_flushall"
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































Deleted freshlib/_pending/lzss/source/lzsspack.fpr.

cannot compute difference between binary files

Deleted freshlib/_pending/lzss/source/lzssstat.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
proc lzssStatPack, .buffer, .buffer_size
        begin
        ; pack the data and count the time of the process
        invoke  GetTickCount
        mov     edi,eax
        stdcall lzssPackData, [.buffer],[.buffer_size]
        mov     ebx,eax
        invoke  GetTickCount
        sub     eax,edi
        xor     edx,edx

        mov     esi,1000
        div     esi
        mov     [lzss_stat.time],eax
        mov     esi,eax
        mov     eax,[.buffer_size]
        xor     edx,edx
        or      esi,esi
        jz      @f
        div     esi
    @@:
        shr     eax,10          ; divide eax by 1024
        mov     [lzss_stat.kbytes_per_sec],eax

        xor     eax,eax
        mov     [lzss_stat.total_items],eax
        mov     [lzss_stat.direct_bytes],eax
        mov     [lzss_stat.dictionary_entries],eax

        ; calculate ratio
        mov     edi,[.buffer_size]
        mov     [lzss_stat.size],edi
        mov     eax,[ebx+LZSSData.packed_size]
        mov     [lzss_stat.packed_size],eax
        mov     esi,100
        mul     esi
        div     edi
        mov     [lzss_stat.ratio],eax
        mov     edi,[ebx+LZSSData.unpacked_size]
        ; now scan compressed data
        stdcall BitsCreateFrom, [ebx+LZSSData.data]
        mov     esi,eax
   .unpack:
        inc     [lzss_stat.total_items]
        stdcall BitsGet,esi,1
        or      eax,eax
        jnz     .from_dictionary
        inc     [lzss_stat.direct_bytes]
        stdcall BitsGet,esi,8
        dec     edi
        jz      .finish
        jmp     .unpack
    .from_dictionary:
        stdcall BitsGet, esi,LZSS_OFFSET_BITS         ; load position
        inc     [lzss_stat.dictionary_entries]
        stdcall BitsGet, esi,LZSS_COUNT_BITS          ; load counter
        sub     edi,eax
        sub     edi,LZSS_THRESHOLD+1
        jz      .finish
        js      .finish
        jmp     .unpack
     .finish:
        stdcall BitsDestroy, esi

        mov     eax,ebx
        return
endp

uglobal
  lzss_stat:
    .time               dd ?
    .kbytes_per_sec     dd ?
    .size               dd ?
    .packed_size        dd ?
    .ratio              dd ?

    .total_items        dd ?
    .direct_bytes       dd ?
    .dictionary_entries dd ?
endg
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































Deleted freshlib/_pending/lzss/source/lzssstat.inc.

Deleted freshlib/_pending/profiling/data.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
include '%lib%/compiler/executable.inc'

include '%lib%/macros/allmacros.inc'
include '%lib%/equates/allequates.inc'

_BinaryType console

_CodeSection

include '%lib%/system/process.asm'
include '%lib%/simpledebug/debug.asm'
include '%lib%/system/memory.asm'
include '%lib%/system/files.asm'
include '%lib%/data/arrays.asm'
include '%lib%/data/strlib.asm'

; very simple CPU clock cycles counter:

macro START
{
        align  4
        push   ecx
        push   ebx
        cpuid  ;cpuid has different execution times the first two times
        xor    eax, eax ; Flush the pipeline
        fwait
        cpuid
        rdtsc  ;Get RDTSC counter in edx:eax
        push   edx
        push   eax
        cpuid
}

macro STOP ; CPU cycles in edx:eax
{
        fwait
        cpuid
        rdtsc
        pop    ebx
        pop    ecx
        clc
        sub    eax,ebx
        sub    eax,144h ; Cut measurement overhead
        sbb    edx,ecx
        pop    ebx
        pop    ecx
}

start:

        InitializeAll

iglobal
        msg1    db 0ah,'Profiling FreshLib: data module',0ah,0ah,0
        sizeof.msg1 = $-msg1
        msg2    db 'This string is going to be used and abused:',0ah
                db '[español, français] {áèïôü} (1234567890)',0ah
                db '< @ # ¡ ! $ % & * - + " / | \ ', "' = ¿ ? >",0ah,0
        sizeof.msg2 = $-msg2
        msg3    db 'used ',0
        testfile db '../../UnicodeSample.txt',0
endg

uglobal
        array1  dd ?
        file1   dd ?
        string1 dd ?
        string2 dd ?
        string3 dd ?
        string4 dd ?
        string5 dd ?
        string6 dd ?
        string7 dd ?
endg

        stdcall  Output,msg1
        DebugMsg 'Cycles to create the first string:'
START
        stdcall  SetString, string1, msg1
STOP
        stdcall  OutputRegister, regEAX, 10
        DebugMsg 'Cycles to create the second string:'
START
        stdcall  SetString, string2, msg2
STOP
        stdcall  OutputRegister, regEAX, 10

        DebugMsg 'Cycles to load a file to a new string:'

START
                push     esi
                stdcall  FileOpen, testfile
                mov      [file1], eax
        stdcall  FileSeek, [file1], 0, fsFromEnd
        mov      ecx, eax
        stdcall  FileSeek, [file1], 0, fsFromBegin
                stdcall  StrNew
                mov      [string7], eax
                stdcall  StrSetCapacity, eax, ecx
                mov      esi, eax
                stdcall  FileRead, [file1], esi, ecx
                stdcall  FileClose, [file1]
                stdcall  StrFixLen, string7
STOP
        stdcall  OutputRegister, regEAX, 10
        stdcall  Output, esi
        pop      esi
        DebugMsg ''

        DebugMsg 'Cycles to extract and create a new string:'
START
        stdcall  StrExtract, [string2], 27, 15
        mov      [string4], eax
STOP
        stdcall  OutputRegister, regEAX, 10



        stdcall  StrPtr, [string4]
        stdcall  Output, eax
        DebugMsg ' <- should be: used and abused'

        stdcall  StrNew
        mov      [string6], eax
        stdcall  StrCopy, [string6], [string2]
        stdcall  SetString, string5, msg3
        stdcall  StrPos, [string6], [string5]
        mov      esi, eax
        stdcall  StrSplit, [string6], 42
        stdcall  Output, esi
        DebugMsg ' <- should be: used and abused'

        DebugMsg 'Cycles to measure string lenght:'
START
        stdcall  StrPtr,[string2]
        stdcall  StrLen,eax
        mov      esi, eax
STOP
        stdcall  OutputRegister, regEAX, 10
        DebugMsg 'Lenght of the string:'
        mov      eax,esi
        stdcall  OutputRegister, regEAX, 10

        DebugMsg 'Original string for the following tests:'
                stdcall  Output,msg2

        DebugMsg 'Cycles to ucase the loaded string:'
START
        stdcall  StrUCase2,[string7]
STOP
        stdcall  OutputRegister, regEAX, 10
        stdcall  StrPtr, [string7]
        stdcall  Output, eax

        DebugMsg 'Cycles to lcase the loaded string:'
START
        stdcall  StrLCase2,[string7]
STOP
        stdcall  OutputRegister, regEAX, 10
        stdcall  StrPtr, [string7]
        stdcall  Output, eax

        DebugMsg "**** testing pelaillo's case functions ****"
        stdcall  SetString,string3,msg2

        DebugMsg 'Cycles to ucase the third string:'
START
        stdcall  StrUCase2,[string3]
STOP
        stdcall  OutputRegister, regEAX, 10
        stdcall  StrPtr, [string3]
        stdcall  Output, eax

        DebugMsg 'Cycles to lcase the third string:'
START
        stdcall  StrLCase2,[string3]
STOP
        stdcall  OutputRegister, regEAX, 10
        stdcall  StrPtr, [string3]
        stdcall  Output, eax


        jmp      .exit
        stdcall  CreateArray, 20h
        jc       .error
        mov      [array1],eax
        DebugMsg 'Step2: Array Created'
        stdcall  NumToStr,eax,ntsHex
        stdcall  StrPtr, eax
        stdcall  Output, eax
        stdcall  StrNew
        mov      [string1],eax

        stdcall  AddArrayItem,[array1]
        jmp      .exit

.error:
        DebugMsg 'An error occurred'

.exit:
        FinalizeAll
        stdcall  Terminate,0

_ImportSection

include '%lib%/imports/allimports.asm'

_DataSection

IncludeAllGlobals
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































Deleted freshlib/_pending/tutorial/files.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
include '%lib%/compiler/executable.inc'
include '%lib%/macros/allmacros.inc'
include '%lib%/equates/allequates.inc'

_BinaryType console

include '%lib%/simpledebug/debug.asm'
include '%lib%/system/files.asm'
include '%lib%/system/process.asm'

_CodeSection

start:

        InitializeAll

        DebugMsg 'FreshLib Tutorials - Module: Files'

iglobal
        filename        db './tut01.txt',0
        sizeof.filename = $-filename
endg

uglobal
        hFile   dd ?
endg

        stdcall FileCreate, filename
        jc      .error
        mov     [hFile], eax
        DebugMsg "A new file was created:"
        stdcall OutputNumber, [hFile], 16, 2
        DebugMsg " is the handle of the file"

        stdcall FileWrite, [hFile], filename, sizeof.filename
        jc      .error
        stdcall OutputNumber, eax, 10, 2
        DebugMsg " bytes were written into the file"

        stdcall FileClose, [hFile]
        jc      .error
        DebugMsg "The file was properly closed"

        stdcall FileDelete, filename
        jc      .error
        DebugMsg "The file was finally deleted"
        jmp     .exit

.error:
        DebugMsg "Sorry, an error occurred"

.exit:
        FinalizeAll
        stdcall Terminate, 0

_ImportSection

include '%lib%/imports/allimports.asm'

_DataSection

IncludeAllGlobals
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































Deleted freshlib/_pending/tutorial/gui.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
include '%lib%/compiler/executable.inc'
_BinaryType GUI


include '%lib%/macros/allmacros.inc'
include '%lib%/equates/allequates.inc'
include '%lib%/GUI/SysEvents.asm'


_CodeSection

include '%lib%/simpledebug/debug.asm'
include '%lib%/system/process.asm'

include '%lib%/system/memory.asm'
include '%lib%/system/files.asm'
include '%lib%/data/arrays.asm'
include '%lib%/data/strlib.asm'

include '%lib%/timers/timers.asm'

include '%lib%/graphics/context.asm'
include '%lib%/graphics/text.asm'
include '%lib%/graphics/draw.asm'
include '%lib%/graphics/images.asm'
include '%lib%/graphics/giflib.asm'

include '%lib%/mouse/mouse.asm'
include '%lib%/GUI/GUI.asm'


iglobal
frmMainForm:
        ObjTemplate  tfParent or tfEnd, Form, frmMain, \
                     x, 100,        \
                     y, 50,         \
                     width, 320,    \
                     height, 200,   \
                     visible, TRUE, \
                     caption, 'Very simple window'

          ObjTemplate  tfChild or tfEnd, Button, btnChild1,          \
                     x, 48,         \
                     y, 48,         \
                     width, 80,     \
                     height, 48,    \
                     TextAlign, dtfAlignLeft or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     caption, 'Hello',        \
                     visible, TRUE, \
                     OnClick, Button1Click
endg

start:
        InitializeAll

        stdcall Create, CApplication
        jc      .start_error
        mov     [pApplication], ebx

uglobal
  test_timer1 dd ?
endg

DebugMsg 'After initializing.'

        stdcall CreateFromTemplate, frmMainForm, 0
        mov     ecx, [Application]
        mov     [ecx+TApplication.MainWindow], ebx

        DebugMsg 'After attaching window.'


        stdcall TimerCreate
        mov     [test_timer1], eax
        mov     [eax+TTimer.interval], 10
        mov     [eax+TTimer.Callback], procTestTimer1
        mov     [eax+TTimer.flags], tmfCallProc
        or      [eax+TTimer.flags], tmfRunning


        stdcall Run

        FinalizeAll
        stdcall Terminate, eax

.start_error:
        stdcall Terminate, 1

proc Button1Click, .self, .button
begin
        DebugMsg 'Button1 clicked'
        return
endp

iglobal
  test_counter dd 0
endg


proc procTestTimer1, .ptrTimer
begin
        add [test_counter],1
        cmp [test_counter],100
        jbe .not_yet
        stdcall OutputNumber,[test_counter],10,10
        stdcall Destroy,[frmMainForm]
  .not_yet:
        return
endp



_ImportSection

include '%lib%/imports/allimports.asm'

_DataSection
IncludeAllGlobals
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































Deleted freshlib/_pending/tutorial/hello.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
include '%lib%/compiler/executable.inc'
include '%lib%/macros/allmacros.inc'
include '%lib%/equates/allequates.inc'

GlobalAPI equ ascii
_BinaryType console

include '%lib%/system/process.asm'
include '%lib%/simpledebug/debug.asm'

_DataSection

IncludeAllGlobals

_CodeSection

start:

	InitializeAll

	DebugMsg 'Hello world!'

	FinalizeAll

	stdcall Terminate,0

_ImportSection

include '%lib%/imports/allimports.asm'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































Deleted freshlib/_trash/Common/header.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description:
;
;  Target OS:
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________
<
<
<
<
<
<
<
<
<
<
<
<
<


























Deleted freshlib/_trash/FastSwitch.png.

cannot compute difference between binary files

Deleted freshlib/_trash/IDE options.png.

cannot compute difference between binary files

Deleted freshlib/_trash/Project options.png.

cannot compute difference between binary files

Deleted freshlib/_trash/SurplusSources/ForthScript/ForthLib.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: ForthScript standard word library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

macro ForthBlock blockname {
  forth@block equ blockname
  forth@block@size equ blockname#.size

  label blockname byte

  macro forthword name \{
    \local nnnn

    macro endfw \\{
    \\local ..footer
      endp
      label ..footer byte
      db   name
      db   16-($-..footer) dup 0
      dd   nnnn - blockname
      \\purge endfw
    \\}
    \proc nnnn
  \}
}

macro EndForthBlock {
  forth@block@size = $ - forth@block
  restore forth@block, forth@block@size
  purge forthword
}



ForthBlock ForthStandardLib

; "->" word.
forthword '->'
begin
        or      [ebx+TForthContext.Status], forthAssignMode
        clc
        retn
endfw


forthword '+'
begin
        mov     eax, [ebx+TForthContext.pAStack]
        mov     ecx, [eax+TArray.count]
        cmp     ecx, 2
        jb      .error

        dec     ecx
        imul    ecx, [eax+TArray.itemsize]
        lea     ecx, [eax+TArray.array+ecx]

        mov     edx, [ecx+TFStackCell.value]
        sub     ecx, [eax+TArray.itemsize]
        add     [ecx+TFStackCell.value], edx
        mov     [ecx+TFStackCell.type], ftypeNumber

        mov     ecx, [eax+TArray.count]
        dec     ecx
        stdcall DeleteArrayItem, [ebx+TForthContext.pAStack], ecx
        mov     [ebx+TForthContext.pAStack], edx
        clc
        return

.error:
        stc
        return
endfw


forthword '-'
begin
        mov     eax, [ebx+TForthContext.pAStack]
        mov     ecx, [eax+TArray.count]
        cmp     ecx, 2
        jb      .error

        dec     ecx
        imul    ecx, [eax+TArray.itemsize]
        lea     ecx, [eax+TArray.array+ecx]

        mov     edx, [ecx+TFStackCell.value]
        sub     ecx, [eax+TArray.itemsize]
        sub     [ecx+TFStackCell.value], edx
        mov     [ecx+TFStackCell.type], ftypeNumber

        mov     ecx, [eax+TArray.count]
        dec     ecx
        stdcall DeleteArrayItem, [ebx+TForthContext.pAStack], ecx
        mov     [ebx+TForthContext.pAStack], edx
        clc
        return

.error:
        stc
        return
endfw



forthword '*'
begin
        mov     eax, [ebx+TForthContext.pAStack]
        mov     ecx, [eax+TArray.count]
        cmp     ecx, 2
        jb      .error

        dec     ecx
        imul    ecx, [eax+TArray.itemsize]
        lea     ecx, [eax+TArray.array+ecx]

        mov     edx, [ecx+TFStackCell.value]
        sub     ecx, [eax+TArray.itemsize]
        imul    edx, [ecx+TFStackCell.value]
        mov     [ecx+TFStackCell.value], edx
        mov     [ecx+TFStackCell.type], ftypeNumber

        mov     ecx, [eax+TArray.count]
        dec     ecx
        stdcall DeleteArrayItem, [ebx+TForthContext.pAStack], ecx
        mov     [ebx+TForthContext.pAStack], edx
        clc
        return

.error:
        stc
        return
endfw



forthword '/'
begin
        mov     eax, [ebx+TForthContext.pAStack]
        mov     ecx, [eax+TArray.count]
        cmp     ecx, 2
        jb      .error

        dec     ecx
        imul    ecx, [eax+TArray.itemsize]
        lea     ecx, [eax+TArray.array+ecx]

        mov     edx, [ecx+TFStackCell.value]
        sub     ecx, [eax+TArray.itemsize]

        push    eax
        mov     eax, edx
        cdq
        idiv    [ecx+TFStackCell.value]
        mov     [ecx+TFStackCell.value], eax
        mov     [ecx+TFStackCell.type], ftypeNumber
        pop     eax

        mov     ecx, [eax+TArray.count]
        dec     ecx
        stdcall DeleteArrayItem, [ebx+TForthContext.pAStack], ecx
        mov     [ebx+TForthContext.pAStack], edx
        clc
        return

.error:
        stc
        return
endfw


forthword '%'
begin
        mov     eax, [ebx+TForthContext.pAStack]
        mov     ecx, [eax+TArray.count]
        cmp     ecx, 2
        jb      .error

        dec     ecx
        shl     ecx, 3
        lea     ecx, [eax+TArray.array+ecx]

        mov     edx, [ecx+TFStackCell.value]
        sub     ecx, [eax+TArray.itemsize]

        push    eax
        mov     eax, edx
        cdq
        idiv    [ecx+TFStackCell.value]
        mov     [ecx+TFStackCell.value], eax
        mov     [ecx+TFStackCell.type], ftypeNumber
        pop     eax

        mov     ecx, [eax+TArray.count]
        dec     ecx
        stdcall DeleteArrayItem, [ebx+TForthContext.pAStack], ecx
        mov     [ebx+TForthContext.pAStack], edx
        clc
        return

.error:
        stc
        return
endfw




forthword 'swap'
begin
        mov     eax, [ebx+TForthContext.pAStack]
        mov     ecx, [eax+TArray.count]
        cmp     ecx, 2
        jb      .finish         ; jb == jc

        shl     ecx, 3
        add     ecx, [ebx+TForthContext.pAStack]
;        lea     ecx, [ecx+TArray.array-2*sizeof.TFStackCell] TArray.array = 2*sizeof.TFStackCell

        mov     eax, [ecx+TFStackCell.value]
        mov     edx, dword [ecx+TFStackCell.type]
        xchg    eax, [ecx+sizeof.TFStackCell+TFStackCell.value]
        xchg    edx, dword [ecx+sizeof.TFStackCell+TFStackCell.type]
        mov     [ecx+TFStackCell.value], ecx
        mov     dword [ecx+TFStackCell.type], edx

        clc
.finish:
        return
endfw



forthword 'dup'
begin
        mov     eax, [ebx+TForthContext.pAStack]
        mov     ecx, [eax+TArray.count]
        cmp     ecx, 1
        jb      .finish         ; jb == jc

        shl     ecx, 3
        add     ecx, [ebx+TForthContext.pAStack]
        lea     ecx, [ecx+TArray.array-sizeof.TFStackCell]

        stdcall AddArrayItem, [ebx+TForthContext.pAStack]
        mov     [ebx+TForthContext.pAStack], edx
        jc      .finish

        pushd   [ecx+TFStackCell.value] dword [ecx+TFStackCell.type]
        popd    dword [eax+TFStackCell.type] [eax+TFStackCell.value]

        clc
.finish:
        return
endfw



forthword 'label'
begin


endfw




forthword 'jump'
begin


endfw




forthword '?branch'
begin


endfw



; : if +1 ?branch ;
forthword 'if'
begin


endfw



; : else label not +1 ?branch ;
forthword 'else'
begin


endfw


; : then label ;
forthword 'then'
begin


endfw





; : do label ;
forthword 'do'
begin


endfw


; : loop -1 ?branch ;
forthword 'loop'




forthword '.'
begin
        mov     eax, [ebx+TForthContext.pAStack]
        mov     ecx, [eax+TArray.count]
        jecxz   .exit

        dec     ecx
        mov     edx, ecx

        imul    ecx, [eax+TArray.itemsize]
        lea     ecx, [eax+TArray.array+ecx]

        cmp     [ecx+TFStackCell.type], ftypeNumber
        jne     .printstring

        stdcall NumToStr, [ecx+TFStackCell.value], ntsSigned or ntsDec
        mov     [ecx+TFStackCell.value], eax
        mov     [ecx+TFStackCell.type], ftypeStringFree

.printstring:
        stdcall StrPtr, [ecx+TFStackCell.value]
        stdcall Output, eax

        cmp     [ecx+TFStackCell.type], ftypeStringFree
        jne     .popit

        stdcall StrDel, [ecx+TFStackCell.value]

.popit:
        stdcall DeleteArrayItem, [ebx+TForthContext.pAStack], edx
        mov     [ebx+TForthContext.pAStack], edx

.exit:
        clc
        return

endfw



forthword 'crlf'
begin
        stdcall Output, sCRLF
        clc
        return
endfw



EndForthBlock



sCRLF db 13, 10, 0, 0

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/ForthScript/ForthScript.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: ForthScript engine.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________
module "Forth script compiler"

include 'ForthLib.asm'

; NOTE: E8    is the opcode for relative call
;       B8    is the opcode for mov eax, dword const
;       BA    is the opcode for mov edx, dword const
;       FF D0 is the opcode for call eax
;       C3    is the opcode for retn
;       e9    is the opcode for jmp long offset



ftypeNumber  = 0
ftypeString  = 1
ftypeStringFree = 2      ; this string should be destroyed after use.

struct TFStackCell
  .value dd ?           ; number or handle of the string.
  .type  db ?           ; number/string
  align 4
ends


struct TFLoopStackCell
ends



struct TFWordFooter
  .name    rb 16        ; max 12 bytes name paded with 0
  .entry   dd ?         ; offset to the code of the word  [.entry]-4 points to the footer of the previous word.
ends


; values for the Status flags.

forthCompileMode =  1   ; if set the script is compiled instead of interpreted
forthNextNewName =  2   ; if set the next extracted word should be interpreted as a new name.
forthAssignMode  =  4   ; if set the next variable word must pop value from the stack, instead of push.



struct TForthContext
  .pAStack     dd  ?     ; pointer to the aritmetic stack TArray.
  .pLStack     dd  ?     ; pointer to the loop stack TArray.
  .pWords      dd  ?     ; pointer to the words memory.
  .iWords      dd  ?     ; offset to the first free byte in the words memory.
  .iLastWord   dd  ?     ; offset to the end of the last word defined.
  .sizeWords   dd  ?     ; size of the words memory.

  .Status      dd ?

  .pUserWords  dd  ?     ; pointer to the user words memory.
  .iUserWords  dd  ?     ; offset of the end of the user word memory.
  .pUser       dd  ?     ; pointer to the user provided object for example TFreshEdit or other.
ends


ForthInitWordsMemory = 1024


proc ForthCreateContext
begin
        push    edi

        stdcall GetMem, sizeof.TForthContext
        mov     edi, eax

        stdcall CreateArray, sizeof.TFStackCell
        mov     [edi+TForthContext.pAStack], eax

        stdcall CreateArray, sizeof.TFLoopStackCell
        mov     [edi+TForthContext.pLStack], eax

        mov     [edi+TForthContext.sizeWords], ForthInitWordsMemory
        stdcall GetMem, [edi+TForthContext.sizeWords]
        mov     [edi+TForthContext.pWords], eax

        mov     eax, edi
        pop     edi
        return
endp


proc ForthFreeContext, .forth_context
begin


        return
endp



ferrSyntaxError = 1
ferrUnknownWord = 2
ferrOutOfMemory = 3
ferrInvalidNumber = 4
ferrInvalidString = 5
ferrMissingBracket = 6

ferrMaxError = 6

dmsgEndWithoutBegin db  'Syntax error', 0
dmsgUnknownWord     db  'Unknown word', 0
dmsgOutOfMemory     db  'Out of memory', 0
dmsgInvalidNumber   db  'Invalid number', 0
dmsgInvalidString   db  'Invalid string', 0
dmsgMissingBracket  db  'Missing ")"', 0
dmsgUnknownError    db  'Unknown error. Probably bug.', 0



ForthErrorMessages  dd  0
                    dd dmsgEndWithoutBegin
                    dd dmsgUnknownWord
                    dd dmsgOutOfMemory
                    dd dmsgInvalidNumber
                    dd dmsgInvalidString
                    dd dmsgMissingBracket
; this should be last.
                    dd dmsgUnknownError


proc GetForthErrorMsg, .errcode
begin
        mov     eax, [.errcode]
        cmp     eax, ferrMaxError
        jbe     @f
        mov     eax, ferrMaxError+1
@@:
        mov     eax, [ForthErrorMessages+4*eax]
        return
endp



proc ForthExecScript, .pcontext, .psource
.word     rb 16
.newword  rb 16
.entry    dd ?  ; the entry point of the currently compiled word.
.ofs_error dd ?
.sign      dd ?
begin
        push    ebx ecx esi edi

        mov     ebx, [.pcontext]
        mov     esi, [.psource]

.script_loop:

        xor     eax, eax
        mov     dword [.word], eax
        mov     dword [.word+4], eax
        mov     dword [.word+8], eax
        mov     dword [.word+12], eax
        xor     ecx, ecx

        dec     esi

.start_scan:

        inc     esi
        mov     al, [esi]

; offset for the error message, if any
        mov     edx, esi
        sub     edx, [.psource]
        mov     [.ofs_error], edx

        test    al, al
        jz      .end_of_script

        cmp     al, '+'
        je      .maybe_number
        cmp     al, '-'
        je      .maybe_number

        cmp     al, '0'
        jb      .nan
        cmp     al, '9'
        jbe     .extract_number

.nan:
        cmp     al, '"'
        je      .extract_string
        cmp     al, "'"
        je      .extract_string

        cmp     al, ' '
        jbe     .start_scan

        cmp     al, ':'
        jne     @f

        test    [ebx+TForthContext.Status], forthCompileMode
        jnz     .syntax_error

        or      [ebx+TForthContext.Status], forthCompileMode or forthNextNewName
        mov     eax, [ebx+TForthContext.iWords]
        mov     [.entry], eax
        jmp     .start_scan

@@:
        cmp     al, ';'
        jne     @f

        test    [ebx+TForthContext.Status], forthCompileMode
        jz      .syntax_error

; finalize the compilation of a word.

        mov     eax, sizeof.TFWordFooter+1
        call    .allocate_bytes
        jc      .err_out_of_memory

        sub     eax, sizeof.TFWordFooter
        mov     byte [eax+edx-1], $c3   ; retn

        pushd   dword [.newword] dword [.newword+4] dword [.newword+8] dword [.newword+12]
        popd    [eax+edx+12] [eax+edx+8] [eax+edx+4] [eax+edx]

        push    [.entry]
        pop     [eax+edx+TFWordFooter.entry]

        push    [ebx+TForthContext.iWords]
        pop     [ebx+TForthContext.iLastWord]

        and    [ebx+TForthContext.Status], not forthCompileMode

        jmp     .start_scan

@@:
        cmp     al, '('
        jne     @f

; comment ()
.comment_loop:
        inc     esi
        mov     al, [esi]
        test    al, al
        jz      .err_missing_bracket

        cmp     al, ')'
        jne     .comment_loop
        inc     esi
        jmp     .script_loop

@@:
        cmp     al, '\'
        jne     .extract_word

; one line comment
.comment_loop2:
        inc     esi
        mov     al, [esi]
        cmp     al, ' '
        jae     .comment_loop2
        jmp     .script_loop

.extract_word:
        mov     [.word+ecx], al
        inc     ecx
        and     ecx, $0f
        inc     esi
        mov     al, [esi]
        cmp     al, ' '
        ja      .extract_word

;.word_ok:
        test    [ebx+TForthContext.Status], forthNextNewName
        jz      .process_word

; copy the word as a new word name to be placed at the end of the word definition.
        mov     eax, dword [.word]
        mov     ecx, dword [.word+4]
        mov     dword [.newword], eax
        mov     dword [.newword+4], ecx

        mov     eax, dword [.word+8]
        mov     ecx, dword [.word+12]
        mov     dword [.newword+8], eax
        mov     dword [.newword+12], ecx

        and     [ebx+TForthContext.Status], not forthNextNewName
        jmp     .script_loop


.process_word:
        call    .search_word    ; eax offset relative to [TForthContext.pWords]
        jc      .err_unknown_word

        test    [ebx+TForthContext.Status], forthCompileMode
        jnz     .compile_the_word

        push    esi

        mov     esi, [ebx+TForthContext.pUser]
        add     eax, [ebx+TForthContext.pWords]
        call    eax

        pop     esi
        jmp     .script_loop

.compile_the_word:
        mov     ecx, eax        ; offset of the word entry

        cmp     eax, [ebx+TForthContext.iWords]
        jb      .internal_call

;.external_call:
        add     ecx, [ebx+TForthContext.pWords]         ; absolute address

        mov     eax, 7
        call    .allocate_bytes
        jc      .err_out_of_memory

        mov     byte [edx+eax-7], $b8   ; mov eax, const
        mov     [edx+eax-6], ecx
        mov     word [edx+eax-2], $d0ff

        jmp     .script_loop


.internal_call:
        mov     eax, 5
        call    .allocate_bytes ; return new offset in eax and pointer to the memory block in edx
        jc      .err_out_of_memory

; relative call to the word entry point.
        sub     ecx, eax
        mov     byte [edx+eax-5], $e8    ; call instruction opcode.
        mov     [edx+eax-4], ecx

        jmp     .script_loop


.maybe_number:
        cmp     byte [esi+1], '0'
        jb      .extract_word
        cmp     byte [esi+1], '9'
        ja      .extract_word

.extract_number:
        xor     edx, edx
        movzx   eax, al

        mov     byte [.sign], al
        cmp     al, '-'
        je      .next
        cmp     al, '+'
        je      .next

.num_loop:
        cmp     al, ' '
        jbe     .number_ok

        cmp     al, '0'
        jb      .err_invalid_number
        cmp     al, '9'
        ja      .err_invalid_number

        sub     al, '0'
        imul    edx, 10
        add     edx, eax

.next:
        inc     esi
        mov     al, [esi]
        jmp     .num_loop

.number_ok:
        cmp     byte [.sign], '-'
        jne     @f
        neg     edx
@@:
        test    [ebx+TForthContext.Status], forthCompileMode
        jnz     .compile_number

        call    forth_push_number
        jmp     .script_loop


.compile_number: ; $b8 forth_push_number $ba number $ff $d0
        mov     ecx, edx

        mov     eax, 12
        call    .allocate_bytes
        jc      .err_out_of_memory

        mov     byte  [edx+eax-12], $b8   ; mov eax, const
        mov     dword [edx+eax-11], forth_push_number
        mov     byte  [edx+eax-7], $ba    ; mov edx, const
        mov     dword [edx+eax-6], ecx
        mov     word  [edx+eax-2], $d0ff

        jmp     .script_loop


.extract_string:
        mov     ah, al          ; end character.
        xor     ecx, ecx        ; length of the string
        lea     edi, [esi+1]

.str_loop:
        inc     esi
        mov     al, [esi]
        test    al, al
        jz      .err_invalid_string

        cmp     al, ah
        je      .string_ok

        inc     ecx
        jmp     .str_loop

.string_ok:
        mov     ecx, esi
        sub     ecx, edi

        inc     esi

        test    [ebx+TForthContext.Status], forthCompileMode
        jnz     .compile_string

        stdcall StrNew
        mov     edx, eax

        stdcall StrCopyPart, edx, edi, 0, ecx

        push    edx
        stdcall AddArrayItem, [ebx+TForthContext.pAStack]
        mov     [ebx+TForthContext.pAStack], edx
        mov     [eax+TFStackCell.type], ftypeStringFree
        pop     [eax+TFStackCell.value]

        jmp     .script_loop

.compile_string:
        push    esi
        mov     esi, edi
        mov     edi, [ebx+TForthContext.iWords]

        lea     eax, [ecx+1+17]
        stdcall .allocate_bytes
        jc      .err_out_of_memory

        lea     eax, [edi+17]
        add     edi, [ebx+TForthContext.pWords]

        mov     byte [edi], $ba                ; mov edx, offset of string
        mov     dword [edi+1], eax             ; offset of string
        mov     byte [edi+5], $b8              ; mov eax, forth_push_string
        mov     dword [edi+6], forth_push_string
        mov     word [edi+10], $d0ff           ; call eax
        lea     eax, [ecx+1]
        mov     byte [edi+12], $e9             ; jmp  end
        mov     dword [edi+13], eax            ;

        add     edi, 17

        rep movsb
        mov     al, 0
        stosb

        pop     esi
        jmp     .script_loop


.end_of_script:
        mov     ecx, [ebx+TForthContext.pAStack]
        mov     eax, [ecx+TArray.count]
        test    eax, eax
        jz      @f

        lea     eax, [ecx+TArray.array+8*eax-8]
        mov     eax, [eax+TFStackCell.value]
        dec     [ecx+TArray.count]

@@:
        clc
        jmp     .finish

; error handlers
.err_missing_bracket:
        mov     eax, ferrMissingBracket
        jmp     .error

.err_invalid_string:
        mov     eax, ferrInvalidString
        jmp     .error

.err_invalid_number:
        mov     eax, ferrInvalidNumber
        jmp     .error

.err_out_of_memory:
        mov     eax, ferrOutOfMemory
        jmp     .error

.err_unknown_word:
        mov     eax, ferrUnknownWord
        jmp     .error

.syntax_error:
        mov     eax, ferrSyntaxError

.error:
        mov     edx, [.ofs_error]
        stc

.finish:
        pop     edi esi ecx ebx
        return


; internal subroutines


; returns:
; CF=0 - word found.
; eax - offset of word entry point in pWords memory.
;
; CF=1 - word not found.
.search_word:
        push    edx esi

; search in the compiled words
        mov     edx, [ebx+TForthContext.pWords]
        mov     esi, [ebx+TForthContext.iLastWord]
        call    .search_list
        jnc     .word_found

; if not found, search in the user provided words, if any.
        mov     edx, [ebx+TForthContext.pUserWords]
        test    edx, edx
        jz      .check_std

        mov     esi, [ebx+TForthContext.iUserWords]
        call    .search_list
        jnc     .word_found

.check_std:
        mov     edx, ForthStandardLib
        mov     esi, ForthStandardLib.size
        call    .search_list
        jnc     .word_found

        stc
        pop     esi edx
        retn

.word_found:
        clc
        pop     esi edx
        retn



; arguments:
;   esi - offset of the end of the word area.
;   edx - pointer to the begin of the word area.
; returns:
;   CF=0; eax=offset of the word entry in the word area.
;   CF=1 - not found
.search_list:
        add     esi, edx

.search_loop:
        sub     esi, sizeof.TFWordFooter
        cmp     esi, edx
        jb      .notfound

        mov     eax, dword [esi+TFWordFooter.name]
        cmp     eax, dword [.word]
        jne     .prev_word

        mov     eax, dword [esi+TFWordFooter.name+4]
        cmp     eax, dword [.word+4]
        jne     .prev_word

        mov     eax, dword [esi+TFWordFooter.name+8]
        cmp     eax, dword [.word+8]
        jne     .prev_word

        mov     eax, dword [esi+TFWordFooter.name+12]
        cmp     eax, dword [.word+12]
        je      .found

.prev_word:
        mov     esi, [esi+TFWordFooter.entry]
        add     esi, edx
        jmp     .search_loop

.found:
        mov     eax, [esi+TFWordFooter.entry]
        add     eax, edx
        sub     eax, [ebx+TForthContext.pWords]         ; relatively to TForthContext.pWords
        clc
        retn

.notfound:
        stc
        retn


; argument: eax - count of bytes to allocate.
; returns:
;   eax - offset in pWords of the new end ( iWords )
;   edx - pointer of pWords memory.

.allocate_bytes:
        push    ecx

        mov     edx, [ebx+TForthContext.iWords]
        add     edx, eax
        cmp     edx, [ebx+TForthContext.sizeWords]
        jb      .sizeok

        mov     ecx, [ebx+TForthContext.sizeWords]
        call    [ResizeIt]
        mov     [ebx+TForthContext.sizeWords], ecx

        stdcall ResizeMem, [ebx+TForthContext.pWords], ecx
        jc      .end_alloc
        mov     [ebx+TForthContext.pWords], eax

.sizeok:
        mov     [ebx+TForthContext.iWords], edx
        mov     eax, edx
        mov     edx, [ebx+TForthContext.pWords]
        clc

.end_alloc:
        pop     ecx
        retn

endp

; arguments:
;    ebx - TForthContext
;    edx - number to be pushed
; returns
;
forth_push_number:
        push    edx
        stdcall AddArrayItem, [ebx+TForthContext.pAStack]
        mov     [ebx+TForthContext.pAStack], edx
        mov     [eax+TFStackCell.type], ftypeNumber
        pop     [eax+TFStackCell.value]
        retn


; arguments:
;    ebx - TForthContext
; returns
;    eax - value from the top of the stack
proc forth_pop_number
begin
        mov     edx, [ebx+TForthContext.pAStack]
        mov     eax, [edx+TArray.count]
        dec     eax
        js      .empty_stack

        push    eax

        imul    eax, [edx+TArray.itemsize]
        mov     eax, [edx+TArray.array+edx+TFStackCell.value]

        stdcall DeleteArrayItem, edx ; from the stack
        clc
        return

.empty_stack:
        xor     eax, eax
        stc
        return
endp



; arguments:
;    ebx - TForthContext
;    edx - offset to the string related to pWords memory.
; returns
;
proc forth_push_string
begin
        add     edx, [ebx+TForthContext.pWords]
        push    edx
        stdcall AddArrayItem, [ebx+TForthContext.pAStack]
        mov     [ebx+TForthContext.pAStack], edx
        mov     [eax+TFStackCell.type], ftypeString
        pop     [eax+TFStackCell.value]
        return
endp






endmodule





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/FreshEdit/forth_link.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
iglobal
FreshEditKeyScript file 'keyboard.forth'
                   dd   0
endg



ForthBlock __FreshEditForthWords


forthword 'Left'
begin
        call    TFreshEdit.__FitCaretInWindow
        jz      @f

        stc
        return

@@:
        push    ecx

        mov     ecx, [esi+TFreshEdit._xCaret]
        jecxz   .exit

        dec     ecx
        mov     [esi+TFreshEdit._xCaret], ecx

        mov     ecx, [esi+TFreshEdit._LeftColumn]
        cmp     [esi+TFreshEdit._xCaret], ecx
        ja      .exit

        mov     ecx, [esi+TFreshEdit._cols]
        shr     ecx, 2
        test    ecx, ecx
        jnz     @f
        inc     ecx
@@:
        sub     [esi+TFreshEdit._LeftColumn], ecx
        jns     @f

        mov     [esi+TFreshEdit._LeftColumn], 0
@@:

.exit:
        clc
        pop     ecx
        return
endfw



forthword 'Right'
begin
        call    TFreshEdit.__FitCaretInWindow
        jz      @f

        stc
        return

@@:
        push    ecx edx

        mov     ecx, [esi+TFreshEdit._xCaret]
        inc     ecx
        mov     [esi+TFreshEdit._xCaret], ecx

        mov     edx, [esi+TFreshEdit._cols]
        add     edx, [esi+TFreshEdit._LeftColumn]
        cmp     ecx, edx
        jae     .scroll_left

.finish:
        clc
        pop     edx ecx
        return

.scroll_left:
        mov     ecx, [esi+TFreshEdit._cols]
        shr     ecx, 2
        test    ecx, ecx
        jnz     @f
        inc     ecx
@@:
        add     [esi+TFreshEdit._LeftColumn], ecx
        jmp     .finish
endfw



forthword 'Up'
begin
        call    TFreshEdit.__FitCaretInWindow
        jz      @f

        stc
        return

@@:
        push    ecx

        cmp     [esi+TFreshEdit._yCaret], 0
        je      .exit

        dec     [esi+TFreshEdit._yCaret]

        mov     ecx, [esi+TFreshEdit._TopLine]
        cmp     [esi+TFreshEdit._yCaret], ecx
        jl      .scrollup

.exit:
        clc
        pop     ecx
        return

.scrollup:
        mov     ecx, [esi+TFreshEdit._TopLine]
        jecxz   .exit
        dec     [esi+TFreshEdit._TopLine]
        jmp     .exit
endfw



TFreshEdit.__CommandScrollLockUp:
forthword 'ScrLockUp'
begin
        call    TFreshEdit.__FitCaretInWindow
        jz      @f

        stc
        return

@@:
        push    ecx

        cmp     [esi+TFreshEdit._yCaret], 0
        je      .exit

        dec     [esi+TFreshEdit._yCaret]

        mov     ecx, [esi+TFreshEdit._TopLine]
        jecxz   .exit

        dec     [esi+TFreshEdit._TopLine]

.exit:
        clc
        pop     ecx
        return
endfw



forthword 'ScrollUp'
begin
        push    ecx
        cmp     [esi+TFreshEdit._TopLine], 0
        je      .finish
        dec     [esi+TFreshEdit._TopLine]
.finish:
        clc
        pop     ecx
        return
endfw




TFreshEdit.__CommandDown:
forthword 'Down'
begin
        call    TFreshEdit.__FitCaretInWindow
        jz      @f

        stc
        return

@@:
        push    ecx edx

        mov     edx, [esi+TFreshEdit._pIndex]

        mov     ecx, [esi+TFreshEdit._yCaret]
        inc     ecx
        cmp     ecx, [edx+TArray.count]
        jae     .exit

        mov     [esi+TFreshEdit._yCaret], ecx

        mov     ecx, [esi+TFreshEdit._TopLine]
        add     ecx, [esi+TFreshEdit._rows]
        cmp     [esi+TFreshEdit._yCaret], ecx
        jae     .scrolldn

.exit:
        clc
        pop     edx ecx
        return

.scrolldn:
        mov     ecx, [esi+TFreshEdit._TopLine]
        inc     ecx
        cmp     ecx, [edx+TArray.count]
        jae     .exit

        mov     [esi+TFreshEdit._TopLine], ecx
        jmp     .exit
endfw




TFreshEdit.__CommandScrollLockDown:
forthword 'ScrLockDown'
begin
        call    TFreshEdit.__FitCaretInWindow
        jz      @f

        stc
        return

@@:
        push    ecx edx

        mov     edx, [esi+TFreshEdit._pIndex]

        mov     ecx, [esi+TFreshEdit._yCaret]
        inc     ecx
        cmp     ecx, [edx+TArray.count]
        jae     .exit

        mov     [esi+TFreshEdit._yCaret], ecx

        mov     ecx, [esi+TFreshEdit._TopLine]
        inc     ecx
        add     ecx, [esi+TFreshEdit._rows]
        cmp     ecx, [edx+TArray.count]
        ja      .exit

        inc     [esi+TFreshEdit._TopLine]

.exit:
        clc
        pop     edx ecx
        return

endfw



forthword 'ScrollDown'
begin
        push    ecx edx
        mov     edx, [esi+TFreshEdit._pIndex]

        mov     ecx, [esi+TFreshEdit._TopLine]
        inc     ecx
        add     ecx, [esi+TFreshEdit._rows]
        cmp     ecx, [edx+TArray.count]
        ja      .finish

        inc     [esi+TFreshEdit._TopLine]

.finish:
        clc
        pop     edx ecx
        return

endfw





forthword 'PgDown'
begin
        push    ecx
        mov     ecx, [esi+TFreshEdit._rows]

@@:
        call    TFreshEdit.__CommandScrollLockDown
        jc      .finish
        loop    @b

.finish:
        pop     ecx
        return
endfw



forthword 'PgUp'
begin
        push    ecx
        mov     ecx, [esi+TFreshEdit._rows]
@@:
        call    TFreshEdit.__CommandScrollLockUp
        jc      .finish
        loop    @b

.finish:
        pop     ecx
        return
endfw




forthword 'LineBegin'
begin
        call    TFreshEdit.__FitCaretInWindow
        jz      @f

        stc
        return

@@:
        cmp     [esi+TFreshEdit._xCaret], 0
        je      .end

        mov     [esi+TFreshEdit._xCaret], 0

        cmp     [esi+TFreshEdit._LeftColumn], 0
        je      .end

        mov     [esi+TFreshEdit._LeftColumn], 0

.end:
        clc
        return
endfw





forthword 'LineEnd'
begin
        call    TFreshEdit.__FitCaretInWindow
        jz      @f

        stc
        return

@@:
        push    ebx ecx

        mov     ecx, [esi+TFreshEdit._yCaret]
        mov     ebx, [esi+TFreshEdit._pIndex]

        cmp     ecx, [ebx+TArray.count]
        jae     .end

        mov     ecx, [ebx+TArray.array+4*ecx]

        shl     ecx, TEditorLine.shift
        add     ecx, [esi+TFreshEdit._pLines]
        add     ecx, TArray.array

        stdcall StrLenUtf8, [ecx+TEditorLine.Data], -1

        cmp     [esi+TFreshEdit._xCaret], eax
        je      .end

        mov     [esi+TFreshEdit._xCaret], eax

        mov     ecx, [esi+TFreshEdit._cols]
        lea     ecx, [ecx*3]
        shr     ecx, 2

        cmp     eax, [esi+TFreshEdit._LeftColumn]
        jg      .leftok

        sub     eax, ecx
        jns     @f
        xor     eax, eax
@@:
        mov     [esi+TFreshEdit._LeftColumn], eax
        jmp     .end

.leftok:
        add     ecx, [esi+TFreshEdit._LeftColumn]
        sub     ecx, [esi+TFreshEdit._xCaret]
        jge     .end

        sub     [esi+TFreshEdit._LeftColumn], ecx

.end:
        clc
        pop     ecx ebx
        return
endfw



TFreshEdit.__CommandBeginOfScreen:
forthword 'ScreenBegin'
begin
        call    TFreshEdit.__FitCaretInWindow
        jz      @f

        stc
        return

@@:
        mov     eax, [esi+TFreshEdit._TopLine]
        cmp     eax, [esi+TFreshEdit._yCaret]
        je      .end

        mov     [esi+TFreshEdit._yCaret], eax
.end:
        return
endfw


forthword 'ScreenEnd'
begin
        call    TFreshEdit.__FitCaretInWindow
        jz      @f

        stc
        return

@@:
        call    TFreshEdit.__CommandBeginOfScreen

        mov     ecx, [esi+TFreshEdit._rows]
        jecxz   .end
        dec     ecx
        jecxz   .end

@@:
        call    TFreshEdit.__CommandDown
        jc      .end
        loop    @b

.end:
        return
endfw


forthword 'FileBegin'
begin

        return
endfw


forthword 'FileEnd'
begin

        return
endfw


forthword 'WordPrev'
begin

        return
endfw


forthword 'WordNext'
begin

        return
endfw



forthword 'GetSelMode'
begin

        return
endfw



forthword 'SetSelMode'
begin

        return
endfw



forthword 'GetInsMode'
begin

        return
endfw


forthword 'SetInsMode'
begin

        return
endfw


forthword 'GetRowCount'
begin

        return
endfw



forthword 'ToggleSelMode'
begin
        mov     eax, [esi+TFreshEdit._SelMode]
        inc     eax
        cmp     eax, 2
        jbe     @f
        xor     eax, eax
@@:
        mov     [esi+TFreshEdit._SelMode], eax
        return
endfw



EndForthBlock

;_________________________________________________________________________________________
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/FreshEdit/keyboard.forth.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
( This file contains ForthScript definitions for navigation and control keys in FreshEdit.
  The name of the words is actually the name of the pressed key, as returned by CreateKeyName procedure
  defined in the library SysEvents.asm
  The words can return a value through the stack top value. It is
  1 - means the
)

: keyUp Up 0 ;
: keyShift+Up Up 1 ;

: keyDown Down 0 ;
: keyShift+Down Down 1 ;

: keyLeft Left 0 ;
: keyShift+Left Left 1 ;

: keyRight Right 0 ;
: keyShift+Right Right 1 ;

: keyPgUp PgUp 0 ;
: keyShift+PgUp PgUp 1 ;

: keyPgDn PgDown 0 ;
: keyShift+PgDn PgDown 1 ;

: keyHome LineBegin 0 ;
: keyShift+Home LineBegin 1 ;

: keyEnd LineEnd 0 ;
: keyShift+End LineEnd 1 ;

: keyCtrl+Alt+Ins ToggleSelMode 1 ;
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































Deleted freshlib/_trash/SurplusSources/Linux/TButtonLinux.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270

proc TButton.Create, .obj, .parent
begin
        push    eax ecx edx esi edi

        mov     ebx, [.obj]

        mov     eax, [.parent]
        test    eax, eax
        jz      .root

        mov     eax, [eax+TWindow.handle]
        jmp     .parentok

.root:
        mov     eax, [hRootWindow]

.parentok:
        cinvoke XCreateSimpleWindow, [hApplicationDisplay], eax, 0, 0, 1, 1, 0, 0, $d4d0c8
        mov     [ebx+TButton.handle], eax

        stdcall _SetWindowStruct, eax, ebx

        cinvoke XSelectInput, [hApplicationDisplay], [ebx+TButton.handle], ExposureMask or       \
                                                                           EnterWindowMask or    \
                                                                           LeaveWindowMask or    \
                                                                           ButtonPressMask or    \
                                                                           ButtonReleaseMask


        pop     edi esi edx ecx eax
        return
endp





proc TButton.SysEventHandler, .ptrEvent

begin
        push    esi edi

        mov     esi, [.ptrEvent]

        stdcall _GetWindowStruct, [esi+XEvent.window]
        mov     edi, eax

        mov     eax, [esi+XEvent.type]
        cmp     eax, Expose
        je      .expose
        cmp     eax, LeaveNotify
        je      .leave
        cmp     eax, EnterNotify
        je      .enter
        cmp     eax, ButtonPress
        je      .button_press
        cmp     eax, ButtonRelease
        je      .button_release


.finish:
        pop   edi esi
        stc
        return

.button_release:
        cmp     [esi+XButtonPressedEvent.button], 1
        jne     .finish

        cinvoke XUngrabPointer, [hApplicationDisplay], CurrentTime

        mov     [edi+TButton.state], btnPointed
        jmp     .needrepaint

.button_press:
        cmp     [esi+XButtonPressedEvent.button], 1
        jne     .finish

        cinvoke XGrabPointer, [hApplicationDisplay], [esi+XButtonEvent.window], FALSE,          \
                              ButtonReleaseMask or EnterWindowMask or LeaveWindowMask,          \
                              GrabModeAsync, GrabModeAsync, None, None, CurrentTime

        mov     [edi+TButton.state], btnPressed
        jmp     .needrepaint

.leave:
        cmp     [edi+TButton.state], btnPressed
        je      .end_mouse

        mov     [edi+TButton.state], btnNormal
        jmp     .needrepaint

.enter:
        cmp     [edi+TButton.state], btnPressed
        je      .end_mouse

        mov     [edi+TButton.state], btnPointed

.needrepaint:
locals
  .event XExposeEvent
endl
        lea     eax, [.event]
        mov     ecx, [hApplicationDisplay]
        mov     edx, [esi+XEvent.window]
        mov     [eax+XExposeEvent.type], Expose
        mov     [eax+XExposeEvent.display], ecx
        mov     [eax+XExposeEvent.window], edx

        cinvoke XSendEvent, ecx, edx, FALSE, ExposureMask, eax

.end_mouse:
        pop     edi esi
        clc
        return

.expose:
        stdcall _DrawBtnFace, [esi+XEvent.window], [edi+TButton.state]
        clc
        pop     edi esi
        return
endp







proc _DrawBtnFace, .hwin, .state
.attr XWindowAttributes
.name dd ?
.font dd ?
.direction dd ?
.ascent    dd ?
.descent   dd ?
.overall   XCharStruct

begin
        pushad

        lea     ecx, [.attr]
        cinvoke XGetWindowAttributes, [hApplicationDisplay], [.hwin], ecx
        dec     [.attr.width]
        dec     [.attr.height]

        cinvoke XCreateGC, [hApplicationDisplay], [.hwin], 0, 0
        mov     ebx, eax

; clear the background
        cinvoke XSetForeground, [hApplicationDisplay], ebx, $d4d0c8
        cinvoke XFillRectangle, [hApplicationDisplay], [.hwin], ebx, 1, 1, [.attr.width], [.attr.height]

; draw button frame
        mov     eax, $ffffff
        mov     ecx, $000000

        cmp     [.state], btnPointed
        je      .border_ok

        xchg    eax, ecx

        cmp     [.state], btnPressed
        je      .border_ok

; normal state.
        mov     eax, $e0e0e0
        mov     ecx, $808080

.border_ok:
        stdcall DrawBtnFrame, ebx, [.hwin], eax, ecx, 0, 0, [.attr.width], [.attr.height]

        cinvoke XSetForeground, [hApplicationDisplay], ebx, $000000
        cinvoke XLoadQueryFont, [hApplicationDisplay], cGUIfont
        mov     [.font], eax
        cinvoke XSetFont, [hApplicationDisplay], ebx, [eax+XFontStruct.fid]

        lea     ecx, [.name]
        cinvoke XFetchName, [hApplicationDisplay], [.hwin], ecx

        stdcall StrLength, [.name]
        mov     edi, eax
        lea     ecx, [.direction]
        lea     edx, [.ascent]
        lea     eax, [.descent]
        lea     esi, [.overall]
        cinvoke XTextExtents, [.font], [.name], edi, ecx, edx, eax, esi

        xor     eax, eax
        mov     ax, [.overall.ascent]
        add     ax, [.overall.descent]
        movsx   eax, ax
        sub     eax, [.attr.height]
        add     eax, 1
        neg     eax
        sar     eax, 1
        movsx   ecx, [.overall.ascent]
        lea     eax, [eax+ecx+1]  ; this is the baseline.
        mov     [.attr.y], eax

        mov     ax, [.overall.width]
        movsx   eax, ax
        sub     eax, [.attr.width]
        add     eax, 1
        neg     eax
        sar     eax, 1
        add     eax, 1
        cmp     eax, 1
        jge     @f
        mov     eax, 1
@@:
        mov     [.attr.x], eax

; debug only
;        cinvoke XDrawLine, [hApplicationDisplay], [.hwin], ebx, [.attr.x], 1, [.attr.x], [.attr.height]
;        cinvoke XDrawLine, [hApplicationDisplay], [.hwin], ebx, 1, [.attr.y], [.attr.width], [.attr.y]

        stdcall StrLength, [.name]
        cinvoke XDrawString, [hApplicationDisplay], [.hwin], ebx, [.attr.x], [.attr.y], [.name], eax

        cinvoke XFree, [.name]
        cinvoke XFreeFont, [hApplicationDisplay], [.font]
        cinvoke XFreeGC, [hApplicationDisplay], ebx

        popad
        return
endp


proc DrawBtnFrame, .GC, .hwin, .upcolor, .dncolor, .left, .top, .right, .bottom
begin
        cinvoke XSetForeground, [hApplicationDisplay], [.GC], [.upcolor]
        cinvoke XDrawLine, [hApplicationDisplay], [.hwin], [.GC], [.left], [.top], [.right], [.top]
        cinvoke XDrawLine, [hApplicationDisplay], [.hwin], [.GC], [.left], [.top], [.left],  [.bottom]

        cinvoke XSetForeground, [hApplicationDisplay], [.GC], [.dncolor]
        cinvoke XDrawLine, [hApplicationDisplay], [.hwin], [.GC], [.left], [.bottom], [.right], [.bottom]
        cinvoke XDrawLine, [hApplicationDisplay], [.hwin], [.GC], [.right], [.bottom], [.right],  [.top]

        return
endp






iglobal
  cGUIfont     db '*helvetica-medium-r*--12*', 0        ;'*lucida-medium-r*-sans-12*',0
endg


proc StrLength, .name
begin
        push    ecx
        mov     ecx, [.name]
        xor     eax, eax
        jecxz   .exit

        dec     eax
.loop:
        inc     eax
        cmp     byte [ecx+eax], 0
        jne     .loop
.exit:
        pop     ecx
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/Linux/TFormLinux.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
proc TForm.Create, .obj, .parent
begin
        push    eax ecx edx esi edi

        mov     ebx, [.obj]

        mov     eax, [.parent]
        test    eax, eax
        jz      .root
        mov     eax, [eax+TWindow.handle]
        jmp     .parentok

.root:
        mov     eax, [hRootWindow]

.parentok:
        cinvoke XCreateSimpleWindow, [hApplicationDisplay], eax, 0, 0, 1, 1, 1, 0, $d4d0c8
        mov     [ebx+TForm.handle], eax

        stdcall _SetWindowStruct, eax, ebx

        cinvoke XSetWMProtocols, [hApplicationDisplay], [ebx+TForm.handle], wmdelete_atom, 1
        cinvoke XSelectInput, [hApplicationDisplay], [ebx+TForm.handle], ExposureMask or KeyPressMask or KeyReleaseMask or SubstructureNotifyMask

        pop     edi esi edx ecx eax
        return
endp



proc TForm.Get, .obj, .idparam
begin
        stc
        return
endp


proc TForm.Set, .obj, .idparam, .value
begin
        stc
        return
endp




proc TForm.SysEventHandler, .ptrEvent
begin
        push    esi edi

        stdcall _GetWindowStruct, [esi+XEvent.window]
        mov     edi, eax

        mov     esi, [.ptrEvent]

        mov     eax, [esi+XEvent.type]

        cmp     eax, Expose
        je      .expose

        cmp     eax, DestroyNotify
        je      .destroy_notify

        cmp     eax, ClientMessage
        je      .clientmessage

.finish:
        pop   edi esi
        stc                     ; not processed
        return

.clientmessage:
        mov     eax, dword [esi+XClientMessageEvent.data]
        mov     ecx, [wmdelete_atom]
        cmp     eax, ecx
        je      .do_destroy

        clc
        pop     edi esi
        return

.do_destroy:
        cinvoke XDestroyWindow, [hApplicationDisplay], [esi+XClientMessageEvent.window]
        clc
        pop     edi esi
        return

.destroy_notify:
        stdcall FreeMem, edi

        clc
        pop     edi esi
        return

.expose:
        stc
        pop     edi esi
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































Deleted freshlib/_trash/SurplusSources/Linux/_common.asm.

Deleted freshlib/_trash/SurplusSources/Linux/allutils.asm.

1
include '_common.asm'
<


Deleted freshlib/_trash/SurplusSources/OldLibs/lists.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
;------------------------------------------------------------------
; Creates TList dynamic list
; or init existing one.
; if ptrList = NULL, the memory for the list will be allocated.
; Returns: pointer to TList structure, properly initialized.
;------------------------------------------------------------------
proc ListCreate, .ptrList
begin
        push    ebx esi
        xor     ebx, ebx
        mov     esi, [.ptrList]
        test    esi,esi
        jnz     .listok

        invoke  HeapAlloc, [hHeap], ebx, sizeof.TList
        mov     esi, eax

.listok:
        mov     [esi+TList.Count], ebx

        invoke  HeapAlloc, [hHeap], HEAP_ZERO_MEMORY, 4*cMinListCapacity
        mov     [esi+TList.ptrItems], eax

        mov     eax, esi
        pop     esi ebx
        return
endp


;--------------------------------------------
; Frees all elements of the list calling
; [FreeProc] on every element.
; (proc FreeProc, ptrItem)
; Frees the array of items
;--------------------------------------------
proc ListFree, .ptrList, .FreeProc
begin
        push    esi edi ebx

        mov     edi, [.ptrList]
        xor     ebx, ebx
        xor     esi, esi
        xchg    esi, [edi+TList.ptrItems]
        xchg    ebx, [edi+TList.Count]

        cmp     [.FreeProc], 0
        je      .endwhile

        test    esi, esi
        jz      .finish

.freeloop:
        dec     ebx
        js      .endwhile

        lea     eax, [esi+4*ebx]
        stdcall [.FreeProc], [eax]
        jmp     .freeloop

.endwhile:
        invoke  HeapFree, [hHeap], 0, esi

.finish:
        pop     ebx edi esi
        return
endp



;-----------------------------------------
; Inserts new element in the list and
; returns it's address.
; If [Index] is bigger than List.Count
; the new element will be appended as last
; element.
;-----------------------------------------
proc ListInsert, .ptrList, .Index
begin
        push    esi edi ebx

        mov     esi, [.ptrList]

        invoke  HeapSize, [hHeap], 0, [esi+TList.ptrItems]
        cmp     eax, -1
        je      .exiterror

        shr     eax, 2          ; get capacity
        mov     ebx, eax

        mov     edi, [.Index]
        cmp     edi, [esi+TList.Count]
        jb      .indexok
        mov     edi, [esi+TList.Count]

.indexok:
        cmp     [esi+TList.Count], ebx
        jb      .capacityok

        mov     eax, ebx
        shr     eax, 1
        add     eax, 2

        cmp     eax, 1024
        jbe     .incok
        mov     eax, 1024

.incok:
        add     ebx, eax
        shl     ebx, 2
        invoke  HeapReAlloc, [hHeap], 0, [esi+TList.ptrItems], ebx
        mov     [esi+TList.ptrItems], eax

.capacityok:
        mov     ecx, [esi+TList.Count]
        sub     ecx, edi ; index
        jz      .dontmove

; Move the items.
        std
        mov     eax, [esi+TList.Count]
        mov     esi, [esi+TList.ptrItems]
        lea     edi, [esi+4*eax]
        lea     esi, [edi-4]
        rep movsd
        cld

        mov     eax, edi
        jmp     .exit

.exiterror:
        xor     eax, eax
        jmp     .exit

.dontmove:
        inc     [esi+TList.Count]
        mov     eax, [esi+TList.ptrItems]
        lea     eax, [eax+4*edi]
.exit:
        pop     ebx edi esi
        return
endp



proc ListDelete, .ptrList, .Index
begin
        push    esi edi ebx

        mov     esi, [.ptrList]
        mov     edi, [.Index]

        cmp     edi, [esi+TList.Count]
        jae     .exit

        dec     [esi+TList.Count]
        mov     ecx, [esi+TList.Count]
        sub     ecx, edi
        jz      .exit

        mov     eax, [esi+TList.ptrItems]
        lea     edi, [eax+4*edi]
        lea     esi, [edi+4]

        rep movsd

.exit:
        pop     ebx edi esi
        return
endp


proc ListIndexOf, .ptrList, .Item
begin
        push    esi edi
        mov     esi, [.ptrList]
        mov     ecx, [esi+TList.Count]
        jecxz   .empty
        mov     edi, [esi+TList.ptrItems]
        lea     edi, [edi+4*ecx-4]              ; from the end
        mov     eax, [.Item]
        std
        repnz scasd
        cld
        jz      .found
.empty:
        dec     ecx
.found:
        mov     eax, ecx
        pop     edi esi
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/OldLibs/lists.inc.

1
2
3
4
5
6
7
cMinListCapacity  = 128

struct TList
  .Count    dd ?
  .ptrItems dd ?
ends

<
<
<
<
<
<
<














Deleted freshlib/_trash/SurplusSources/OldLibs/qsort.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
QuickSortLib:

;****************************************************
; Quick sort of the array in the memory.
;
;  ptrArray       - pointer to the memory array.
;  ElementSize    - size of one array element in bytes.
;  iBegin         - index of the first element
;  iEnd           - index of the last element
;  ptrCompareProc - pointer to procedure that compares two elements.
;
; ptrCompareProc have interface:
;  proc CompareSomething, ptrElement1, ptrElement2
;    returns: c=1 if elements are not properly sorted.
;             c=0 if elements are sorted, i.e.
;                 element1 should be before element2
;****************************************************


proc QSort, ptrArray, ElementSize, iBegin, iEnd, ptrCompareProc
begin
        push    esi edi ebx
        mov     esi, [ptrArray]
        mov     edi, [ptrCompareProc]
        mov     ebx, [ElementSize]

        stdcall DoQSort, [iBegin], [iEnd]
        pop     ebx edi esi
        return
endp

;*****************************************************
; Procedure for internal call from QSort procedure.
;*****************************************************
proc DoQSort, Left, Right
begin
        push    ecx

        mov     ecx, [Left]     ; i variable
        mov     eax, ecx
        mov     edx, [Right]    ; j variable
        add     eax, edx
        sar     eax, 1
        imul    eax, ebx
        imul    ecx, ebx
        imul    edx, ebx
        add     eax, esi
        add     ecx, esi
        add     edx, esi

.repeat:
        sub     ecx, ebx
        add     edx, ebx

.whylei:
        add     ecx, ebx
        stdcall edi, ecx, eax
        jnc     .whylei

.whylej:
        sub     edx, ebx
        stdcall edi, eax, edx
        jnc     .whylej

        cmp     edx, ecx
        jl      .next

        call    SwapElements

        push    edx
        cmp     eax, ecx
        je      @f
        mov     [esp], ecx
        cmp     eax, edx
        je      @f

        mov     [esp], eax
@@:
        pop     eax

        add     ecx, ebx
        sub     edx, ebx

.next:
        cmp     ecx, edx
        jle     .repeat

        mov     eax, edx
        sub     eax, esi
        cdq
        idiv    ebx

        cmp     [Left], eax
        jge     .leftok

        stdcall DoQSort, [Left], eax

.leftok:
        mov     eax, ecx
        sub     eax, esi
        cdq
        idiv    ebx

        cmp     eax, [Right]
        jge     .rightok

        stdcall DoQSort, eax, [Right]

.rightok:
        pop     ecx
        return
endp



;********************************************
; Swaps two elements of the array with
; pointers in:
;   Element1 - ecx
;   Element2 - edx
;   ElementSize - ebx
;********************************************
proc SwapElements
begin
        push    esi eax

        xor     esi, esi
.loop:
        mov     al, [ecx+esi]
        xchg    al, [edx+esi]
        mov     [ecx+esi], al

        inc     esi
        cmp     esi, ebx
        jne     .loop

        pop     eax esi
        return
endp




proc CompareIntAscending, ptrElement1, ptrElement2
begin
        push    eax esi edi

        mov     esi, [ptrElement1]
        mov     edi, [ptrElement2]

        mov     eax, [esi]
        cmp     eax, [edi]
        jl      .qfalse

        stc
        pop     edi esi eax
        return


.qfalse:
        clc
        pop     edi esi eax
        return
endp



DispSize 'QSort lib', $ - QuickSortLib
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/OldLibs/strlib.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
;************************************************************
; FASM dynamic string library.
;
; (c)2003 John Found
; (c)2003 Mateusz Tymek (aka decard)
; (c)2003 Victor Loh (aka roticv)
;
; You can use and modify this library, as long as modifyed
; versions are clearly marked (author of the modification
; and what is changed), copyright notice is not
; removed and the library remains free.
; Copyright for the library concept and parts written by
; me, remains to me, John Found
; Copyright for the modifyed/new parts remains to their
; authors.
;
; Versions:
;   dd.mm.yyyy  version   author of modification
;     - description
;--------------------------------------------------------
;   09.07.2003  v1.0    John Found
;     - the first public version.
;   15.07.2003  v1.0.1  John Found
;     - minor bug with string table expand. Look in NewStr
;   17.09.2003  v1.1.0  Mateusz Tymek
;     - made all functions stdcall
;     - added StrCat and StrPos, and modified StrLen
;   25.09.2003  v1.1.2  Mateusz Tymek, Victor Loh
;     - added StrLCase, StrUCase, StrCopyMMX, StrInsert
;     - added new NumToStr, old version renamed to _NumStr
;     - some small optimizations & bugfixes
;   26.09.2003 v1.1.3  JohnFound
;     - some bug fixes and style corections.
;   29.09.2003 v1.1.4  John Found, Mateusz Tymek
;     - library rewtiten to use John Found's stdcall macros
;     - added two new low-level NumToStr routines: NumToStrF and NumToStrUF
;     - NumToStr rewriten
;     - some small bugfixes & modifications
;     - added StrExtract
;   01.11.2003 v1.1.4.1 Mateusz Tymek
;     - preserved ecx in StrDel (it was destroyed by API calls)
;   21.11.2003 v1.1.5 John Found
;     - StrComp splitted to 2 functions: StrCompCase and StrCompNoCase
;       IMPORTANT: inversed return result: CARRY = 1 mean strings equal.
;       This is because the using is more natural this way:
;            stdcall  StrCompCase, str1, str2
;            jc       .equal
;   27.11.2003 v1.2 John Found
;     - Added function StrHash, that produces 32bit hash value of the string.
;       The hash function is based on FASM hash function and have to be compatible.
;   03.12.2003 v1.2.3 Mateusz Tymek
;     - Added StrCharPos and StrToNum
;   13.12.2003 v1.2.4 Materusz Tymek
;     - added StrCharCat and StrInsertChar
;   04.01.2005 v1.2.5 John Found
;     - Fixed bug in StrSetLength
;     - Added function StrURLEncode
;*************************************************************************************


;--< How to use it >-----------------------------------------------------------------
; 1. Include "strutils.inc" somewhere in the begining of main file.
; 2. Define structure "StrTable" of type "TStrTable" somewhere in data section.
; 3. Before using of library functions, call "InitStrings"
; 4. After last use of the library (probably on close of application),
;    call "FreeStrings" to free all used memory.
; 5. Some functions are with register parameter passing, other with "stdcall"
;    parameter passing. Read the header descriptions of the functions.
;------------------------------------------------------------------------------------

; Global variable, storing parameters of dynamic strings list.
uglobal
  StrTable        TStrTable      ; StrLib library variable.
endg


; < Library functions >

;************************************************************************************
; Allocates memory for string table and allocates memory for strings.
; Start it before any work with strings.
; Returns 0 if failed to allocate needed memory.
;************************************************************************************
initialize InitStrings
begin
        StrLib = 1

        push    esi ebx
        mov     esi,StrTable
        invoke  GetProcessHeap
        test    eax,eax
        jz      .finish
        mov     [StrTable.heap],eax
        invoke  HeapAlloc,[StrTable.heap],HEAP_ZERO_MEMORY, STR_MINCOUNT * 4
        test    eax,eax
        jz      .finish
        mov     [StrTable.ptr],eax
        mov     [StrTable.LastHandle], 0
        mov     [StrTable.count], STR_MINCOUNT
        or      dword [eax], -1
.finish:
        pop     ebx esi
        return
endp

;**************************************************************************************
; Frees all memory used for strings library
; Call it before exit of the program.
;**************************************************************************************
finalize FreeStrings
begin
        push    edi esi ebx
        mov     esi,[StrTable.ptr]
        mov     edi,[StrTable.count]
        xor     ebx,ebx
.freeloop:
        mov     ebx, [esi]
        test    ebx,ebx
        jz      .nxt
        js      .nxt
        invoke  HeapFree,[StrTable.heap],0,ebx
.nxt:
        add     esi,4
        dec     edi
        jnz     .freeloop
        invoke  HeapFree,[StrTable.heap],0, [StrTable.ptr]
        xor     ebx,ebx
        mov     [StrTable.heap],ebx
        mov     [StrTable.ptr],ebx
        mov     [StrTable.count],ebx
        pop     ebx esi edi
        return
endp

;**************************************************************************************
;  Returns the pointer in memory of the hString, or NULL on error
;**************************************************************************************
proc StrPtr         ; proc StrPtr [hString]
        begin
        mov     eax,[esp+4]             ; mov eax,[hString]
        test    eax,$ffff0000
        jnz     .finish                 ; It's pointer, go to finish.
        cmp     eax,[StrTable.count]
        jae     .notfound
        push    ebx
        mov     ebx, [StrTable.ptr]
        mov     eax, [4*eax+ebx]
        pop     ebx
.finish:
        ret     4
.notfound:
        xor     eax,eax
        ret     4
endp

;**************************************************************************************
;  Creates new empty string and returns handle
;  Return: handle of the new created string.
;**************************************************************************************
proc StrNew
begin
        push    ebx ecx edx esi edi

; Find first empty place.
        mov     ecx,[StrTable.count]
        mov     ebx,[StrTable.ptr]
        mov     esi,[StrTable.LastHandle]
        xor     edx,edx

.search:
        inc     esi
        cmp     esi, [StrTable.count]
        jne     @f
        xor     esi,esi
        inc     esi
@@:
        cmp     [4*esi+ebx],edx
        je      .found
        dec     ecx
        jnz     .search

.notfound:                              ; expands the table. esi is right.
        mov     esi, [StrTable.count]
        mov     eax, esi
        shl     eax,1
        add     eax, esi
        shr     eax,1                   ; count = count * 1.5
        inc     eax
        mov     [StrTable.count],eax
        shl     eax,2
        invoke  HeapReAlloc,[StrTable.heap],HEAP_ZERO_MEMORY, [StrTable.ptr],eax
        mov     [StrTable.ptr],eax
        mov     ebx, eax                ; 15.07.2003 this added to repair bug with table expanding

.found:                                 ; [4*esi+ebx] points to StrTable entry.
        mov     [StrTable.LastHandle], esi
        invoke  HeapAlloc, [StrTable.heap], HEAP_ZERO_MEMORY, STR_MINSTRLEN
        mov     dword [eax], 0
        mov     [4*esi+ebx],eax
        mov     eax,esi
        pop     edi esi edx ecx ebx
        return
endp

;**************************************************************************
; Deletes the string if it is possible.
;**************************************************************************
proc StrDel, .hString
        begin
        push    eax ebx ecx edx esi
        mov     esi, [StrTable.ptr]
        mov     eax,[.hString]               ; mov eax,[hString]
        test    eax, eax
        jz      .finish
        test    eax,$ffff0000
        jz      .process
; Find the pointer in the table.
        mov     ecx, [StrTable.count]
        xor     ebx,ebx
.search:
        cmp     [esi+4*ebx],eax
        je      .free
        inc     ebx
        dec     ecx
        jnz     .search
        jmp     .finish

.process:
        mov     ebx, eax
        stdcall StrPtr,eax
        test    eax,eax
        jz      .finish
.free:
        invoke  HeapFree, [StrTable.heap], 0, eax
        mov     dword [esi+4*ebx], NULL        ; Set the cell of the table to null.
.finish:
        pop     esi edx ecx ebx eax
        return
endp


;**************************************************************************
; Duplicates given string, and returns a handle to new one
;**************************************************************************
proc StrDup         ; proc StrDup [hBaseStr]
begin
        mov     eax,[esp+4]             ; mov eax,[esp+4]
        or      eax,eax
        jz      .exit
        stdcall StrNew
        stdcall StrCopy, eax,dword[esp+4]    ; stdcall StrCopy, [hBaseStr]
.exit:  ret     4
endp

;**************************************************************************
; Returns the length of the string.
; Arguments:
;  hString - handle or pointer to the string (static or dynamic)
;**************************************************************************
proc StrLen, .hString    ; proc StrLen [hString]
        begin
        push    ebx
        stdcall StrPtr, [.hString]
        mov     ebx,eax
  .scan:
        cmp     byte[eax],0
        lea     eax,[eax+1]
        jne     .scan
        sub     eax,ebx
        dec     eax         ; return value in eax
        pop     ebx
        return
endp

;***************************************************************************
; If the hString is larger than length - do nothing
; If the hString is smaller than length -> set the length of string to length
; returns pointer to the new (old) string
;
; Arguments:
;   hString - string handle. /not pointer!/
;   length - new string length.
; Returns: pointer to the string.
;***************************************************************************
proc StrSetLength, .hString, .length   ; proc StrSetLength [hString], [length]
        begin
        push    ebx ecx edx esi edi     ; esp=esp-20

        mov     ebx, [.length]          ; mov ecx,[length]
        lea     ebx, [ebx+4]            ; the string have to be at least 1 dword bigger than the length specified.

        mov     eax,[.hString]          ; mov eax,[hString]
        test    eax,$ffff0000   ; if eax is pointer then error
        jnz     .error
        cmp     eax,[StrTable.count]    ; invalid handle.
        jge     .error

        mov     edi,[StrTable.ptr]
        lea     edi,[4*eax+edi]         ; points to the address of table pointer of destination string
        mov     esi,[edi]
        test    esi,esi                 ; Error string not defined
        jz      .error                  ;

        invoke  HeapSize, [StrTable.heap], 0, esi
        cmp     eax,-1
        je      .error
        cmp     eax,ebx
        jl      .resize
        mov     eax,esi
        jmp     .finish

.resize:
        invoke  HeapReAlloc, [StrTable.heap], HEAP_GENERATE_EXCEPTIONS or HEAP_ZERO_MEMORY, esi, ebx
        mov     [edi], eax
        jmp     .finish

.error:
        xor     eax,eax

.finish:
        pop     edi esi edx ecx ebx
        return
endp


;***************************************************************************************
;  Copyes source to destination string.
;  Arguments:
;     source - destination string (handle only)
;     dest -  source string (handle or pointer)
;***************************************************************************************
proc StrCopy, .dest, .source
        begin
        push    esi edi eax ecx
        mov     edi,[.dest]
        test    edi,$ffff0000   ; if edi is pointer go to finish.
        jnz     .finish
        mov     esi,[.source]
        test    esi,esi
        jz      .finish
        stdcall StrPtr, esi
        mov     esi,eax
        test    esi, esi
        jz      .finish
        stdcall StrLen, eax
        inc     eax
        mov     ecx,eax
        stdcall StrSetLength, edi,eax
        test    eax,eax
        jz      .finish
        stdcall StrPtr, edi
        mov     edi,eax
        cld
        rep movsb               ; copy strings
.finish:
        pop     ecx eax edi esi
        return
endp

;***************************************************************************************
; Compares two strings - case sensitive.
; Returns CARRY = 1 if the strings are equal.
; Returns CARRY = 0 if the strings are different.
;***************************************************************************************
proc StrCompCase, .str1, .str2
begin
        push    eax esi edi

        cmp     [.str1], 0
        je      .noteq
        cmp     [.str2], 0
        je      .noteq

        stdcall StrPtr, [.str1]
        mov     esi,eax
        stdcall StrPtr, [.str2]
        mov     edi,eax
.loop:
        mov     al, [esi]
        lea     esi, [esi+1]
        cmp     al, [edi]
        lea     edi, [edi+1]
        jne     .noteq

        test    al, al
        jnz     .loop

        stc
        pop     edi esi eax
        return

.noteq:
        clc
        pop     edi esi eax
        return
endp


;***************************************************************************************
; Compares two strings - case NOT sensitive.
; Returns CARRY = 1 if the strings are equal.
; Returns CARRY = 0 if the strings are different.
;***************************************************************************************
proc StrCompNoCase, .str1, .str2
begin
        push    eax esi edi
        stdcall StrPtr, [.str1]
        mov     esi,eax
        stdcall StrPtr, [.str2]
        mov     edi,eax

.cmploop:
        mov     al, [esi]
        lea     esi, [esi+1]
        mov     ah, [edi]
        lea     edi, [edi+1]

        test    al,al
        jz      .eos
        test    ah,ah
        jz      .noteq

        or      eax, $2020
        cmp     al, ah
        je      .cmploop

.noteq:
        clc
        pop     edi esi eax
        return

.eos:
        test    ah,ah
        jnz     .noteq

        stc
        pop     edi esi eax
        return
endp



;*******************************************************************************
; Get the text of the [Control] using WM_GETTEXT and put it to the string with
; handle (only) in [string].
;
; if [string] = NULL creates new string and returns the handle.
; if [string] <> NULL just copyes the text.
;*******************************************************************************
proc GetControlText, .Control, .string
.res dd ?
.len dd ?
begin
        push    ebx edi
        mov     eax,[.string]
        test    eax,eax
        jnz     @f
        stdcall StrNew
@@:
        mov     [.res],eax
        invoke  SendMessage, [.Control], WM_GETTEXTLENGTH, 0, 0
        add     eax, 16
        mov     [.len], eax
        stdcall StrSetLength, [.res], eax
        test    eax,eax
        jz      .error
        invoke  SendMessage, [.Control], WM_GETTEXT, [.len], eax
        mov     eax,[.res]
.error:
        pop     edi ebx
        return
endp

;*******************************************************************************
; Sets the text in control using WM_SETTEXT from string with handle or pointer
; in [string].
;*******************************************************************************
proc SetControlText, .Control, .string
begin
        push    eax ecx edx
        stdcall StrPtr, [.string]
        invoke  SendMessage, [.Control], WM_SETTEXT, 0, eax
        pop     edx ecx eax
        return
endp

;**********************************************************
;  Creates string and assigns it to variable. If variable
;  already contains string handle, the old string will be
;  deleted.
;  Arguments:
;    [ptrHString] - variable containing string handle.
;    ptrSource - pointer to the source for string.
;**********************************************************
; Bug fix 26.09.2003 JohnFound
proc SetString, .ptrHString, .ptrSource
begin
        push    eax esi
        mov     esi, [.ptrHString]

        cmp     dword [esi], 0
        je      @f
        stdcall StrDel, [esi]
@@:
        stdcall StrNew
        mov     [esi], eax
        stdcall StrCopy, eax, [.ptrSource]
        pop     esi eax
        return
endp

;**********************************************************************************
; StrCat appends one string to another
; Arguments:
;   dest - destination string (handle only)
;   source - source string
;**********************************************************************************
proc StrCat, .dest, .source
begin
        push    eax ebx ecx

        stdcall StrLen, [.dest]
        mov     ebx,eax                 ; store dest length in ebx

        stdcall StrLen, [.source]
        add     eax, ebx
        inc     eax                     ; new dest length
        stdcall StrSetLength, [.dest], eax
        add     ebx, eax                ; calculate end of old dest in ebx
        stdcall StrPtr, [.source]
.copy:
        mov     cl,[eax]
        inc     eax
        mov     [ebx],cl
        inc     ebx
        or      cl,cl
        jnz     .copy
        pop     ecx ebx eax
        return
endp


;**********************************************************************************
; StrCharPos returns a pointer to the first occurence of a given char
;   in specified string
; Arguments:
;   Char - char to look for
;   hString -  string to search
; Returns: a pointer to the char in source, or NULL if char doesn't occur
;   in given string
;**********************************************************************************
proc StrCharPos, .hPattern, .char
        begin
        push    esi
        stdcall StrPtr,[.hPattern]
        mov     esi,eax
        mov     eax,[.char]
        xchg    al,ah
     .search:
        mov     al,[esi]
        inc     esi
        or      al,al
        je      .not_found
        cmp     al,ah
        jne     .search
        mov     eax,esi
        dec     eax
        pop     esi
        return
     .not_found:
        xor     eax,eax
        pop     esi
        return
endp


;**********************************************************************************
; StrPos returns a pointer to the first occurence of a pattern string
;   in another string
; Arguments:
;   hPattern - 'pattern' string
;   hString -  string to search
; Returns: a pointer to the pattern string in source , or NULL if pattern string
; doesn't occur in the string to search
;**********************************************************************************
proc StrPos         ; proc StrPos [hString], [hPattern]
begin
        push    ebx ecx edx esi edi     ; esp = esp -20
        mov     esi,[esp+20+8]          ; mov esi,[hPattern]
        mov     edi,[esp+20+4]          ; mov edi,[hString]
        stdcall StrLen, edi
        mov     ebx,eax                 ; now ebx holds lenght of the string to search
        stdcall StrLen, esi
        mov     edx,eax                 ; now edx holds length of the pattern string
        stdcall StrPtr, esi
        mov     esi,eax                 ; put pointer to the pattern str in esi
        stdcall StrPtr,edi
        mov     edi,eax                 ; put pointer to the search str in edi
        lodsb                           ; load first character of the pattern
        mov     ecx,ebx                 ;
        mov     ebx,edx                 ; put str_len(pattern)-1 in ebx
        dec     ebx                     ;
  .search:
        repne   scasb
        jne     .not_found
        cmp     ecx,ebx
        jb      .not_found
        push    edi esi ecx
        or      ebx,ebx                 ; ebx==0 means that we were searching for one
        jz      .got_it                 ; character. We found it, so we stop.
        mov     ecx,ebx
        repe    cmpsb
        jne     .not_match
  .got_it:
        pop     ecx esi edi
        dec     edi
        mov     eax,edi
  .ret:
        pop     edi esi edx ecx ebx
        ret     8
  .not_match:
        pop     ecx esi edi
        jmp     .search
  .not_found:
        xor     eax,eax
        jmp     .ret
endp

;**********************************************************************************
; StrInsert inserts one string into another at specified pos
; Arguments:
;   dest - destination where the source will be inserted (handle only)
;   source -  string to insert
;**********************************************************************************
proc StrInsert      ; proc StrInsert [dest], [source], [pos]
        begin
        push    eax ebx ecx esi edi     ; esp = esp-20
        stdcall StrLen, dword[esp+20+4] ; stdcall StrLen,[dest]
        cmp     eax,dword[esp+20+12]    ; cmp eax,[pos]
        jb      .ret                    ; don't insert a string if pos>StrLen(dest)
        inc     eax
        mov     ecx,eax
        stdcall StrNew                  ; create temporary string...
        mov     ebx,eax                 ; ... and store its handle in ebx
        stdcall StrSetLength, ebx,ecx
        stdcall StrPtr, dword[esp+20+4] ; stdcall StrPtr,[dest]
        mov     esi,eax
        stdcall StrPtr, ebx
        mov     edi,eax
        mov     ecx,dword[esp+20+12]    ; mov ecx,[pos]
        jz      @f
        rep     movsb
  @@:   stdcall StrCat, ebx,dword[esp+20+8]     ; stdcall StrCat, ebx,[source]
        stdcall StrCat, ebx,esi
        mov     eax,dword[esp+24]
        stdcall StrCopy, eax,ebx
        stdcall StrDel, ebx
  .ret:
        pop     edi esi ecx ebx eax
        ret     12
endp

;**********************************************************************************
; Converts strings to Lower Case
; First parameter = String to Convert to lower case
; corrupts eax
;**********************************************************************************
proc StrLCase               ; proc StrLCase [hString]
        begin
        push    edi
        stdcall StrPtr, [esp+4+1*4]
        xchg    edi, eax
._lowercaseloop:
        mov     al, [edi]
        cmp     al, 'A'
        jc      @F
        cmp     al, 'Z'
        ja      @F
        or      byte[edi], 20h
@@:
        cmp     byte[edi],0
        lea     edi, [edi+1]
        jnz     ._lowercaseloop
        pop     edi
        retn    4
endp


;**********************************************************************************
; Converts strings to Upper Case
; First parameter = String to Convert to upper case
; corrupts eax
;**********************************************************************************
proc StrUCase       ; proc StrUCase [hString]
        begin
        push    edi
        stdcall StrPtr, [esp+4+1*4]
        xchg    edi, eax
._uppercaseloop:
        mov     al, [edi]
        cmp     al, 'a'
        jc      @F
        cmp     al, 'z'
        ja      @F
        sub     byte[edi], 20h
@@:
        cmp     byte[edi], 0
        lea     edi, [edi+1]
        jnz     ._uppercaseloop
        pop     edi
        retn    4
endp

;**********************************************************************************
; String copy mmx version for long strings does by copying qword at a time
; First parameter = String destination
; Second parameter = String source
;**********************************************************************************
proc StrCopyMMX     ; proc StrCopyMMX [str1], [str2]
        begin
        push    eax
        push    ebx
        push    ecx
        push    edx
        stdcall StrPtr, [esp+4+4*4]
        xchg    eax, edx
        stdcall StrPtr, [esp+8+4*4]
        mov     ecx,eax
        stdcall StrLen,eax
        stdcall StrSetLength, [esp+4+4*4+4], eax
        mov     eax,ecx
        xor     ecx,ecx
        pxor    MM7, MM7
.MMX_loop:
        movq    MM0, [eax+ecx]
        movq    MM1, MM0
        pcmpeqb MM0, MM7
        packsswb MM0, MM0
        movd    ebx, MM0
        test    ebx, ebx
        jnz     .normal_copy
        movq    [edx+ecx], MM1
        add     ecx, 8
        jmp     .MMX_loop
.normal_copy:
        mov     bl, [eax+ecx]
        mov     [edx+ecx], bl
        inc     ecx
        test    bl, bl
        jnz     .normal_copy
        pop     edx
        pop     ecx
        pop     ebx
        pop     eax
        retn    8
endp

;**********************************************************************************
; StrExtract copies the part of [str] from [index] with lenght in [len]
; Returns handle to new created string.
;**********************************************************************************
proc StrExtract, .string, .index, .len
begin
        push    ebx ecx esi edi
        stdcall StrLen,[.string]
        cmp     eax,[.index]
        jbe     .error
        stdcall StrNew
        mov     ebx,eax
        mov     ecx,[.len]
        stdcall StrSetLength, eax,ecx   ; stdcall StrSetLength, eax,[len]
        stdcall StrPtr, eax
        mov     edi,eax
        stdcall StrPtr, [.string]
        add     eax,[.index]
        mov     esi,eax
    @@: mov     al,[esi]
        mov     [edi],al
        inc     esi
        inc     edi
        or      al,al
        jz      .copied
        dec     ecx
        jnz     @b
        xor     al,al
        mov     [edi],al
  .copied:
        mov     eax,ebx
        pop     edi esi ecx ebx
        return
  .error:
        xor     eax,eax
        pop     edi esi ecx ebx
        return
endp

;**********************************************************************************
; _NumToStr converts the number in eax to the string in any radix approx. [2..26]
; Arguments:
;   [edi] - pointer to the string buffer
;   ecx - radix
;   eax - number to convert.
; There is no parameter check, so be careful.
; returns: edi points to the end of a converted number
;**********************************************************************************
proc _NumToStr
begin
    test  eax,eax
    jns   _NumToStrU
    neg   eax
    mov   byte [edi],"-"
    inc   edi
endp

proc _NumToStrU
begin
    cmp   eax,ecx
    jb    .lessA
    xor   edx,edx
    div   ecx
    push  edx
    call  _NumToStrU
    pop   eax
.lessA:
    cmp   al, 10
    sbb   al, 69h
    das
    stosb
    return
endp

;*****************************************************
; NumToStrF:
;   Converts signed integer value to string.
; NumToStrUF:
;   Converts unsigned integer value to string.
;
; edi - pointer to string buffer
; eax - Number to convert
; ecx - radix from 2 to $ff
; esi - length of the number in chars
;
; returns: edi - pointer to the end of converted num
;
; Note: Don't use 1 as radix.
;*****************************************************
proc NumToStrF
begin
        test    eax,eax
        jns     NumToStrUF
        neg     eax
        mov     byte [edi],'-'
        push    esi
        dec     esi
        add     edi,esi
        push    edi
        jmp     NumToStrUF.loopc
endp

proc NumToStrUF
        begin
        push    esi
        add     edi, esi
        push    edi
        dec     edi
.loopc:
        xor     edx,edx
        div     ecx
        xchg    al,dl
        cmp     al,$0a
        sbb     al,$69
        das
        mov     [edi],al
        dec     edi
        xchg    al,dl
        dec     esi
        jnz     .loopc
        pop     edi
        pop     esi
        return
endp


;***********************************************************
; NumToStr - converts number to any radix.
; num - number to convert
; str - handle of the string. If NULL - creates new string.
; index - Offset in string where to put converted number.
; flags:
;   byte 0 - number of digits if ntsFixedWidth is set.
;   byte 1 - contains radix for the convertion.
;   byte 2,3 - flags.
; Returns:
;   eax - handle of the string (new one or passed in [str])
;   edx - pointer to the string.
;***********************************************************
proc NumToStr, .num, .strng, .index, .flags
.max_len dd ?
.len_tab rb 20      ; table that holds maximum number of digits in given system
        begin
        push    ebx ecx edx esi edi

        mov     [.len_tab+2],32+2       ; binary number - max. 32 digits (+2 bytes for '-' character and NULL terminator)
        mov     [.len_tab+4],16+2       ; quad number - max. 16 digits
        mov     [.len_tab+8],11+2       ; octal number - max. 11 digits
        mov     [.len_tab+10],9+2       ; decimal number - max. 9 digits
        mov     [.len_tab+16],8+2       ; hexadecimal number - max. 8 digits
        movzx   ebx,byte [.flags+1]     ; load radix into ebx
        movzx   eax,byte[.len_tab+ebx]
        mov     [.max_len],eax          ; store max. number of digits
        mov     eax,[.strng]
        or      eax,eax
        jnz     .string_exists
        stdcall StrNew
        mov     [.strng],eax
  .string_exists:
        test    eax,0xffff0000
        jnz     @f                      ; don't resize if [str] isn't a handle
        mov     ebx,eax
        mov     eax,[.max_len]
        add     eax,[.index]
        mov     edx,eax
        stdcall StrLen,ebx
        cmp     eax,edx
        ja      @f                      ; don't resize string if it has enough place for converted number

        stdcall StrSetLength,ebx, edx

  @@:   ; determine which conversion func to use
        mov     eax,[.flags]
        mov     edx,eax
        and     eax,ntsFixedWidth
        jnz     .fixed_width
        mov     eax,edx
        and     eax,ntsUnsigned
        jnz     .unsigned
        mov     ebx,_NumToStr
        jmp     .got_func
  .unsigned:
        mov     ebx,_NumToStrU
        jmp     .got_func

  .fixed_width:
        movzx   esi, byte [.flags]         ; load fixed width into esi
        mov     eax, edx
        and     eax, ntsUnsigned
        jnz     .fixed_unsigned
        mov     ebx,NumToStrF
        jmp     .got_func
  .fixed_unsigned:
        mov     ebx,NumToStrUF
  .got_func:
        stdcall StrPtr, [.strng]
        add     eax,[.index]
        mov     edi,eax
        movzx   ecx,byte [.flags+1]       ; load radix into ecx
        mov     eax, [.num]
        call    ebx                     ; call low-level convertion routine
        mov     eax, [.flags]
        and     eax, ntsZeroTerminated
        jz      .ret
        mov     byte [edi], 0

  .ret:
        pop     edi esi edx ecx ebx
        mov     eax, [.strng]
        return
endp


;-------------------------------------------------
; function StrHash
;   Computes 32 bit hash value from the string.
;   The function is compatible with FASM hash
;   function if OrMask = 0.
;
; Arguments:
;   hString - handle/pointer of the string.
;   OrMask  - every byte from the string will be ORed
;             with this value (byte)
; Return:
;   eax - 32bit hash value.
;-------------------------------------------------
proc StrHashOld, .hString, .OrMask
begin
        push    esi ebx ecx

        stdcall StrPtr, [.hString]
        mov     esi, eax

        xor     ebx, ebx
        xor     eax, eax
.hashloop:
        rol     eax, 12
        mov     ecx, eax
        shr     eax, 8
        and     ecx, 1111b
        or      eax, ecx
        movzx   ecx, byte [esi+ebx]
        jecxz   .endloop
        or      cl, byte [.OrMask]
        add     eax, ecx
        inc     ebx
        jmp     .hashloop

.endloop:
        and     eax,0FFFFFFh
        shl     ebx,24
        or      eax,ebx
        pop     ecx ebx esi
        return
endp


proc StrHash, .hString, .OrMask
begin
        push    esi edi ebx ecx edx

        stdcall StrPtr, [.hString]
        mov     esi, eax

        xor     ebx, ebx
        mov     eax,2166136261          ; FNV offset basis
        xor     ecx, ecx
        mov     edi, 16777619                ; FNV prime
.hashloop:
        mov     cl, [esi+ebx]
        jecxz   .endstring
        inc     bl
        or      cl, byte [.OrMask]
        xor     al,cl                   ; FNV-1a hashing
        mul     edi
        jmp     .hashloop

.endstring:
        mov     edx,eax
        and     eax,0FFFFFFh            ; xor-fold to 24 bits
        shr     edx,24
        xor     eax,edx
        shl     ebx,24                  ; the length of the string
        or      eax,ebx                 ; store length in high 8 bits
        pop     edx ecx ebx edi esi
        return
endp



;-------------------------------------------------------
; function StrToNum
;   Converts specified string into a number
;
; Arguments:
;   hString - handle/pointer of the string containing
;     number to convert. It doesn't have to be ended by
;     NULL, any other character will stop conversion.
;     Number to convert must be decimal.
;
; Return:
;   eax - converted number
;
; Note: in case of failture (first char of given pointer
;   isn't a number) function returns -1.
;-------------------------------------------------------
proc StrToNum, .hString
        begin
        push    ebx edx esi
        xor     ebx,ebx         ; ebx will store our number
        stdcall StrPtr, [.hString]
        mov     esi,eax
        xor     eax,eax
        mov     al,[esi]
        cmp     al,'0'
        jb      .error
        cmp     al,'9'
        jbe     .digit
        jmp     .error
     .digit:
        sub     al,'0'
        add     ebx,eax
        inc     esi
        mov     al,[esi]
        cmp     al,'0'
        jb      .finish
        cmp     al,'9'
        ja      .finish
        mov     edx,ebx         ; multiply ebx by 10
        shl     ebx,3
        add     ebx,edx
        add     ebx,edx
        jmp     .digit
     .finish:
        mov     eax,ebx
        pop     esi edx ebx
        return

     .error:
        xor     eax,eax
        dec     eax
        pop     esi edx ebx
        return
endp

;-------------------------------------------------------
; function StrCharCat
;   Addes specified char to the end of a string
;
; Arguments:
;   hString - string to append
;   char - char to add
;-------------------------------------------------------
proc StrCharCat, .hString, .char
begin
        push    eax ebx ecx
        mov     ebx, [.hString]
        stdcall StrLen, ebx
        mov     ecx, eax
        inc     eax
        stdcall StrSetLength, ebx, eax
;        stdcall StrPtr, ebx                    ; StrSetLength returns a pointer to the string
        add     ecx, eax
        mov     eax, [.char]
        mov     [ecx], al
        inc     ecx
        mov     byte [ecx], 0
        pop     ecx ebx eax
        return
endp

;------------------------------------------------------------
; function StrInsertChar
;   Inserts specified char into given position ot the string
;
; Arguments:
;   hString - string to append
;   char    - char to add
;   pos     - position where to add the char
;-------------------------------------------------------------
proc StrInsertChar, .hString, .char, .pos
        begin
        push    eax ebx ecx
        mov     ebx, [.hString]
        stdcall StrLen, ebx
        cmp     eax, [.pos]
        jb      .finish
        je      .append
        mov     ecx,eax
        inc     eax
        stdcall StrSetLength, ebx, eax
        stdcall StrPtr, ebx
        add     ecx, eax
        mov     ebx, eax
        add     ebx, [.pos]
        mov     byte [ecx+1], 0     ; add NULL-terminator in the end of our string
  .shift:
        mov     al, [ecx-1]
        mov     [ecx], al
        dec     ecx
        cmp     ecx, ebx
        jne     .shift
        mov     eax, [.char]
        mov     [ebx], al
  .finish:
        pop     ecx ebx eax
        return
  .append:
        stdcall StrCharCat, ebx, [.char]
        jmp     .finish
endp





proc StrURLEncode, .hstr
.res dd ?
begin
        push    ebx ecx edx esi edi
        stdcall StrPtr, [.hstr]
        mov     esi, eax

        stdcall StrLen, esi
        mov     ecx, eax
        lea     edx, [2*eax+eax]        ; the encoded string can be max 3x long as original string.

        stdcall StrNew
        mov     [.res], eax
        jecxz   .finish

        stdcall StrSetLength, eax, edx
        mov     edi, eax
        xor     edx, edx
        xor     ebx, ebx

.encode:
        lodsb
        cmp     al, $80
        jae     .store          ; it is a hack, but I hope save enough.

        mov     dl, al
        mov     bl, al
        shr     edx, 5
        and     ebx, $1f
        bt      dword [URLCharTable+4*edx], ebx
        jnc     .store

        mov     ah, al
        mov     al, '%'
        stosb
        mov     al, ah
        shr     al, 4
        cmp     al, $0a
        sbb     al, $69
        das
        stosb
        mov     al, ah
        and     al, $0f
        cmp     al, $0a
        sbb     al, $69
        das

.store:
        stosb
        loop    .encode
.end:
        xor     al, al
        stosb
.finish:
        mov     eax, [.res]
        pop     edi esi edx ecx ebx
        return
endp

; Contains 1 where the character must be % encoded and 0 where it is save to pass it directly
URLCharTable db 11111111b       ;
             db 11111111b       ;
             db 11111111b       ;
             db 11111111b       ; 0..31 -control chars | encoded
             db 11111111b       ; $27 - $20: '&%$#"!   | encoded
             db 11111111b       ; $2f - $28: /.-,+*)(  | encoded
             db 00000000b       ; $37 - $30: 76543210  | not encoded
             db 11111100b       ; $3f - $38: ?>=<;:98  | partially
             db 00000001b       ; $47 - $40: GFEDCBA@  | partially
             db 00000000b       ; $4f - $48: ONMLKJIH  | not encoded
             db 00000000b       ; $57 - $50: WVUTSRQP  | not encoded
             db 11111000b       ; $5f - $58: _^]\[ZYX  | partially
             db 00000001b       ; $67 - $60: gfedcba`  | partially
             db 00000000b       ; $6f - $68: onmlkjih  | not encoded
             db 00000000b       ; $77 - $70: wvutsrqp  | not encoded
             db 11111000b       ; $7f - $78:  ~}|{zyx  | partially
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/OldLibs/strlib.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
STR_MINCOUNT = 10       ; minimum 10 strings in the table
STR_MINSTRLEN = 16      ; 16 bytes minimum string length

struct TStrTable
  .count    dd 0           ; max count of the strings in table.
  .LastHandle dd 0         ; last allocated handle.
  .ptr      dd 0           ; pointer to the table data
  .heap     dd 0           ; handle of strings heap
ends


; NumToStr flags
ntsSigned = $00000
ntsUnsigned = $10000
ntsZeroTerminated = $20000
ntsFixedWidth     = $40000

ntsBin  = $0200
ntsQuad = $0400
ntsOct  = $0800
ntsDec  = $0a00
ntsHex  = $1000


;-------------------------------------
; It is stand-alone macroses
;-------------------------------------
macro IndexedStrings [lparam, string] {
  forward
    local ..lbl
    dd  ..lbl, lparam
  common
    dd  0
  forward
..lbl db string, 0
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































Deleted freshlib/_trash/SurplusSources/Win32/TFormWin32.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
;************************************************************
;*   Form class library                                     *
;*                                                          *
;*   This file is part of Fresh base library                *
;*   This is base window class for "Fresh" created project  *
;*                                                          *
;*   (C)2003, 2004 John Found                               *
;************************************************************






;;*********************************************************************************************
;; Main window procedure for 'TForm' window class.
;;*********************************************************************************************
;winproc FormMessageProc
;begin
;        push    ebx edi esi
;        mov     ebx, [.wmsg]
;
;ondefault
;        invoke  DefWindowProc, [.hwnd],[.wmsg],[.wparam],[.lparam]
;        pop     esi edi ebx
;        return
;
;;------------------------------------------------------------------------
;onmessage WM_SYSCOMMAND
;        mov     eax, [.wparam]
;        and     eax, $fff0
;
;        cmp     eax, SC_KEYMENU
;        jne     .ondefault
;
;        invoke  GetParent, [.hwnd]
;        mov     ebx, eax
;        test    eax, eax
;        jnz     .resendmessage
;
;; Get the main application window.
;        mov     eax, [Application]
;        mov     eax, [eax+TApplication.MainWindow]
;        test    eax, eax
;        jz      .ondefault
;
;        cmp     eax, [.hwnd]
;        je      .ondefault
;
;        mov     ebx, eax
;
;        invoke  GetMenu, [.hwnd]
;        test    eax, eax
;        jnz     .ondefault
;
;        invoke  GetFocus
;        mov     [hLastBeforeMenu], eax
;
;        invoke  SetFocus, ebx
;
;.resendmessage:
;        invoke  SendMessage, ebx, [.wmsg], [.wparam], [.lparam]
;
;        xor     eax, eax
;        pop     esi edi ebx
;        return
;
;;------------------------------------------------------------------------
;onmessage WM_ERASEBKGND
;locals
;  .rect    RECT
;endl
;        lea     eax, [.rect]
;        invoke  GetClientRect, [.hwnd], eax
;
;        invoke  GetSysColor, COLOR_BTNFACE
;
;.colorok:
;        and     eax, $ffffff
;        invoke  CreateSolidBrush, eax
;        push    eax
;        lea     ecx, [.rect]
;        invoke  FillRect, [.wparam], ecx, eax
;        invoke  DeleteObject ; from the stack.
;        xor     eax, eax
;        inc     eax
;        pop     esi edi ebx
;        return
;
;;------------------------------------------------------------------------
;onmessage WM_CLOSE
;
;        mov     eax, [Application]
;        mov     eax, [eax+TApplication.MainWindow]
;        cmp     eax, [.hwnd]
;        jne     .ondefault
;
;        invoke  PostQuitMessage, 0
;        jmp     .ondefault
;
;;------------------------------------------------------------------------
;onmessage WM_EXITMENULOOP
;        cmp     [hLastBeforeMenu], 0
;        je      @f
;
;        invoke  SetFocus, [hLastBeforeMenu]
;@@:
;        xor     eax, eax
;        mov     [hLastBeforeMenu], eax
;        pop     esi edi ebx
;        return
;
;endwp
;
;
;
;proc GetFocusedControl, .hwnd
;begin
;        push    esi ebx
;        invoke  GetFocus
;        mov     esi, eax
;
;.parentloop:
;        mov     ebx, eax
;        invoke  GetParent, eax
;        test    eax, eax
;        jnz     .parentloop
;
;;        xor     eax, eax     ; eax is zero here...
;        cmp     ebx, [.hwnd]
;        jne     .endfocused
;        mov     eax, esi
;.endfocused:
;        pop     ebx esi
;        return
;endp
;
;
;;*********************************************************************************************
;; Shows given form in modal form.
;; Returns modal result
;; This is first version so behaviour is not very proper.
;;*********************************************************************************************
;
;proc ShowModal, .hwnd, .flags
;
;.rect RECT
;
;        begin
;        push    esi edi ebx
;
;        invoke  GetFocus
;        push    eax      ; the parameter for SetFocus at the end of the procedure.
;
;        lea     eax, [.rect]
;        invoke  GetWindowRect, [.hwnd], eax
;
;        mov     esi, [.rect.left]
;        mov     edi, [.rect.top]
;
;        test    [.flags], MSF_HCENTER
;        jz      @f
;
;        invoke  GetSystemMetrics, SM_CXSCREEN
;        sub     eax, [.rect.right]
;        add     eax, [.rect.left]
;        sar     eax,1
;        mov     esi, eax
;@@:
;        test    [.flags], MSF_VCENTER
;        jz      @f
;
;        invoke  GetSystemMetrics, SM_CYSCREEN
;        sub     eax, [.rect.bottom]
;        add     eax, [.rect.top]
;        sar     eax,1
;        mov     edi, eax
;
;@@:
;        invoke  SendMessage, [.hwnd], WM_INITDIALOG, 0, 0
;        invoke  SetWindowPos, [.hwnd], HWND_TOP, esi, edi, 0, 0, SWP_NOSIZE
;        invoke  ShowWindow, [.hwnd], SW_SHOW
;;        invoke  SendMessage, [.hwnd], AM_CHILDRESIZED, 0, 0
;
;        invoke  GetWindow, [.hwnd], GW_OWNER
;        mov     ebx, eax
;
;; Disables window owner and all other windows owned by window owner.
;
;        invoke  EnableWindow, ebx, FALSE
;        stdcall EnableAllOwnedWindows, ebx, FALSE       ; This is useless if all top level windows
;                                                        ; are TForm, but it is important if not...
;
;        invoke  EnableWindow, [.hwnd], TRUE              ; IMPORTANT: re-enable modal window.
;
;        invoke  GetNextDlgTabItem, [.hwnd], NULL, FALSE
;        test    eax, eax
;        jz      @f
;        invoke  SetFocus, eax
;@@:
;        invoke  SetProp, [.hwnd], [propModalResult], MR_NONE
;
;; Special message loop for modal window. It not finish until window becomes invisible.
;.modalloop:
;        call    ProcessMessages
;
;        invoke  IsWindowVisible, [.hwnd]
;        test    eax,eax
;        jz      .endloop
;
;        invoke  GetProp, [.hwnd], [propModalResult]
;        test    eax,eax              ; mrNone = 0
;        jnz     .endloop
;
;        invoke  SendMessage, [.hwnd], AM_ONIDLE, 0, 0
;
;        invoke  WaitMessage
;        jmp     .modalloop
;
;.endloop:
;        stdcall EnableAllOwnedWindows, ebx, TRUE
;        invoke  EnableWindow, ebx, TRUE
;        invoke  ShowWindow, [.hwnd], SW_HIDE
;
;        invoke  SetFocus                       ; the parameter is in stack
;
;        invoke  GetProp, [.hwnd], [propModalResult]
;        pop     ebx edi esi
;        return
;endp
;
;
;;-------------------------------------------------------------
;; Enables or disables all windows owned by specifyed window.
;;
;; fEnable - TRUE = enable
;;           FALSE = disable
;;-------------------------------------------------------------
;proc EnableAllOwnedWindows, .hwnd, .fEnable
;        begin
;
;        mov     eax, _EnableOwnedProc
;        cmp     [.fEnable], FALSE
;        jne     @f
;        mov     eax, _DisableOwnedProc
;@@:
;        invoke  EnumWindows, eax, [.hwnd]
;        return
;endp
;
;
;; callback procedure used in EnableAllOwnedWindows
;proc _EnableOwnedProc, .hwnd, .owner
;begin
;
;        invoke  GetWindow, [.hwnd], GW_OWNER
;        cmp     eax, [.owner]
;        jne     .ready
;        invoke  EnableWindow, [.hwnd], TRUE
;
;.ready:
;        mov     eax, 1
;        return
;endp
;
;
;; callback procedure used in EnableAllOwnedWindows
;proc _DisableOwnedProc, .hwnd, .owner
;begin
;        invoke  GetWindow, [.hwnd], GW_OWNER
;
;        cmp     eax, [.owner]
;        jne     .ready
;        invoke  EnableWindow, [.hwnd], FALSE
;.ready:
;        mov     eax, 1
;        return
;endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/Win32/_chainmsg.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
winmessage WM_SUBCLASSED   ;(ptrProcedure, Tag) the window receives this message immediately after subclassing with AddWinProc.

struct TChainElement
  .WinProc dd ?
  .Tag     dd ?
  .count   dd ?
  .next    dd ?
ends


iglobal
  winproperty propWinProcChain, 'WinProcChain'
endg


;initialize InitChainMessages
;begin
;        stdcall CreateWinProperty, propWinProcChain
;        return
;endp
;
;
;finalize FinalChainMessages
;begin
;        stdcall DestroyWinProperty, propWinProcChain
;        return
;endp
;


proc AddWinProc, .hwnd, .winproc, .tag
begin
        push    esi edi

        stdcall SearchChainElement, [.hwnd], [.winproc], [.tag]
        jc      .addit

; The message handler exists, just inc the count
        inc     [esi+TChainElement.count]
        jmp     .exit

; Add new message handler.
.addit:
        stdcall GetMem, sizeof.TChainElement
        mov     esi, eax

        mov     eax, [.winproc]
        mov     ecx, [.tag]
        mov     [esi+TChainElement.WinProc], eax
        mov     [esi+TChainElement.Tag], ecx
        mov     [esi+TChainElement.count], 1

        invoke  GetProp, [.hwnd], [propWinProcChain]
        test    eax, eax
        jz      .newchain

        mov     [esi+TChainElement.next], eax
.save:
        invoke  SetProp, [.hwnd], [propWinProcChain], esi
.exit:
        invoke  SendMessage, [.hwnd], WM_SUBCLASSED, [.winproc], [.tag]
        pop     edi esi
        return

.newchain:
        stdcall GetMem, sizeof.TChainElement
        mov     edi, eax

        invoke  GetWindowLong, [.hwnd], GWL_WNDPROC
        mov     [edi+TChainElement.WinProc], eax
        mov     [esi+TChainElement.next], edi
        invoke  SetWindowLong, [.hwnd], GWL_WNDPROC, ChainWinProc
        jmp     .save
endp




;----------------------------------------------------
; if [.winproc] <> 0 removes the message handle with
; specified [.winproc], [.tag] from the handler chain
; if [.winproc] = 0 removes the first handler from
; the chain.
;----------------------------------------------------
proc RemoveWinProc, .hwnd, .winproc, .tag
begin
        push    edi esi

        stdcall SearchChainElement, [.hwnd], [.winproc], [.tag]
        jc      .exit

        dec     [esi+TChainElement.count]
        jnz     .exit                           ; don't remove, someone needs it.

        test    edi, edi
        jz      .first

        mov     ecx, [esi+TChainElement.next]
        jecxz   .exit   ; can't be removed the original handler.

        mov     [edi+TChainElement.next], ecx

.free:
        stdcall FreeMem, esi
.exit:
        pop     esi edi
        return

.first:
        mov     edi, [esi+TChainElement.next]
        cmp     [edi+TChainElement.next], 0
        je      .removechain

        invoke  SetProp, [.hwnd], [propWinProcChain], edi
        jmp     .free

.removechain:
        invoke  SetWindowLong, [.hwnd], GWL_WNDPROC, [edi+TChainElement.WinProc]
        invoke  RemoveProp, [.hwnd], [propWinProcChain]
        stdcall FreeMem, edi
        jmp     .free
endp



;-----------------------------------------------
; Arguments:
;   .hwnd - handle of the window
;   .winproc - user winproc (if 0 - returns the first in chain)
;   .tag     - user defined value.
; Returns:
;   CF = 0 -> element found.
;   esi - TChainElement
;   edi - previous in chain
;   CF = 1 -> element not found.
;     esi = 0
;     edi = 0 -> the window is not subclassed
;     edi <> 0 -> TChainElement of original winproc
;-----------------------------------------------
proc SearchChainElement, .hwnd, .winproc, .tag
begin
        xor     edi, edi

        invoke  GetProp, [.hwnd], [propWinProcChain]
        mov     esi, eax
        test    eax, eax
        jz      .exit

        cmp     [.winproc], 0
        je      .found

.loop:
        mov     ecx, [esi+TChainElement.WinProc]
        mov     eax, [esi+TChainElement.Tag]

        cmp     ecx, [.winproc]
        jne     .next
        cmp     ecx, [.tag]
        jne     .next

.found:
        clc
        return

.next:
        mov     edi, esi
        mov     esi, [esi+TChainElement.next]
        test    esi, esi
        jnz     .loop

.exit:
        stc
        return
endp


;--------------------------------------------------------------
; This is universal message handler for subclassed windows.
; Saves registers and provides call to the previous handler.
;--------------------------------------------------------------
proc ChainWinProc, .hwnd, .wmsg, .wparam, .lparam
begin
        push    ebx esi edi

        invoke  GetProp, [.hwnd], [propWinProcChain]
        mov     ecx, eax

.loop:
        jecxz   .finish

        push    [ecx+TChainElement.next]      ; in the case current handler removes itself from the chain.
        mov     edi, [ecx+TChainElement.Tag]
        cmp     [ecx+TChainElement.WinProc], 0
        jg      .procedure

        ; handle
        invoke  CallWindowProc, [ecx+TChainElement.WinProc], [.hwnd], [.wmsg], [.wparam], [.lparam]
        jmp     .next

.procedure:
        stdcall [ecx+TChainElement.WinProc], [.hwnd], [.wmsg], [.wparam], [.lparam]

.next:
        pop     ecx
        jc      .loop

.finish:
        cmp     [.wmsg], WM_DESTROY
        jne     .quit

; clear whole chain and remove the property.
        push    eax
        xor     ebx, ebx

.freeloop:
        stdcall RemoveWinProc, [.hwnd], ebx, ebx
        invoke  GetProp, [.hwnd], [propWinProcChain]
        test    eax, eax
        jnz     .freeloop
        pop     eax

.quit:
        pop     edi esi ebx
        return
endp



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/Win32/_winprops.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
;------------------------------------------------------------------------
; Macro for defining names for window properties (SetProp/GetProp)
; that to be used with and without AddAtom function.
; When the name is not added to the atom table, the first
; dword of the structure contains pointer to the string.
; If the macro is added to the application atom table
; (via CreateProperty procedure), the first dword contains
; atom handle. In both cases GetProp and SetProp uses [propname] as
; pointer to the property name.
;------------------------------------------------------------------------
macro winproperty [name, string] {
  forward
    align 4
    local ..txt
    name  dd ..txt
    TEXT ..txt, string
    dw   0
}


; Various property related string procedures
proc CreateWinProperty, .ptrProp
begin
        push    ebx
        mov     ebx, [.ptrProp]
        invoke  IsBadReadPtr, ebx, 4
        test    eax, eax
        jnz     .exit

        invoke  IsBadStringPtr, [ebx], 256
        test    eax, eax
        jnz     .exit

        invoke  AddAtom, [ebx]
        movzx   eax, ax
        mov     [ebx], eax
.exit:
        pop     ebx
        return
endp


proc DestroyWinProperty, .ptrProp
begin
        push    ebx
        mov     ebx, [.ptrProp]
        invoke  IsBadReadPtr, ebx, 4
        test    eax, eax
        jnz     .exit

        invoke  DeleteAtom, [ebx]
.exit:
        pop     ebx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































Deleted freshlib/_trash/SurplusSources/Win32/allutils.asm.

1
2
Sequence winmessage, WM_USER+$3000
winmessage.display = 1
<
<




Deleted freshlib/_trash/SurplusSources/command_tables.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
; This file is not needed anymore, but it contains very tiny implementation of Forth-like script engine.
; maybe it worths to keep it some time......

__ScriptEngine:

struct TCommandItem
  .name dd ?
  .proc dd ?
ends

macro CommandList lbl, [name, proc] {
common
  label lbl dword
forward
  local len
  dd name, proc
common
  dd 0
}


CommandList  ScriptCommands,                     \
  'l' ,   TFreshEdit.__CommandLeft,              \       ; left
  'r' ,   TFreshEdit.__CommandRight,             \       ; right
  'u' ,   TFreshEdit.__CommandUp,                \       ; up
  'd' ,   TFreshEdit.__CommandDown,              \       ; down
  'ul',   TFreshEdit.__CommandScrollLockUp,      \       ; up scroll lock
  'dl',   TFreshEdit.__CommandScrollLockDown,    \       ; down scroll lock
  'su',   TFreshEdit.__CommandScrollUp,          \       ; scroll up
  'sd',   TFreshEdit.__CommandScrollDown,        \       ; scroll down
  'pu',   TFreshEdit.__CommandPgUp,              \       ; page up
  'pd',   TFreshEdit.__CommandPgDown,            \       ; page down
  'lb',   TFreshEdit.__CommandHome,              \       ; line begin
  'le',   TFreshEdit.__CommandEnd,               \       ; line end
  'sb',   TFreshEdit.__CommandBeginOfScreen,     \       ; begin of screen
  'se',   TFreshEdit.__CommandEndOfScreen,       \       ;
  'fb',   TFreshEdit.__CommandFileBegin,         \       ; file begin
  'fe',   TFreshEdit.__CommandFileEnd,           \       ; file end
  'wp',   TFreshEdit.__CommandWordPrev,          \       ; word previous
  'wn',   TFreshEdit.__CommandWordNext,          \       ; word next
  'gsm',  TFreshEdit.__CommandGetSelectionMode,  \       ; get selection mode (0..2)
  'ssm',  TFreshEdit.__CommandSetSelectionMode,  \       ; set selection mode (0..2)
  'gim',  TFreshEdit.__CommandGetInsertMode,     \       ; get insert mode.
  'sim',  TFreshEdit.__CommandSetInsertMode,     \       ; set insert mode.
  'grc',  TFreshEdit.__CommandGetRowCount,       \       ; get row count.
\
\ ; Aritmerics
\
  '+',    __ScriptPlus,                          \
  '-',    __ScriptMinus,                         \
  '*',    __ScriptMul,                           \
  '/',    __ScriptDiv,                           \
  '%',    __ScriptMod,                           \
  'neg',  __ScriptNeg,                           \
\
\ ; Output
\
  '.',    __ScriptOutNumber,                     \
  '?',    __ScriptOutString,                     \
\
\ ; Stack operations and variables
\
  'swap', __ScriptSwap,                          \
  'pop',  __ScriptPop,                           \
  '->',   ExecScript.__assign,                   \
\
\ ; word logic
\
  'and',  __ScriptAnd,                           \
  'or',   __ScriptOr,                            \
  'xor',  __ScriptXor,                           \
  'not',  __ScriptNot,                           \
\
\ ; Loop
\
  'rep',  __ScriptRepeat,                        \
  'loop', __ScriptLoop,                          \
\
\ ; conditional
\
  'if',   ExecScript.__if,                       \
  'else', ExecScript.__else,                     \
  'then', ExecScript.__then




macro KeyScripts [scancode, modkeys, script] {
forward
local ptrscr
  dd scancode, modkeys
  if script eqtype 'A'
    dd ptrscr
  else
    dd script
  end if
common
  dd 0
forward
  if script eqtype 'A'
    ptrscr db script, 0
    align 4
  end if
}

struc script text {
  db text, 0
  align 4
}


KeyScripts                                     \
  keyUp,         0,        scrUp,      \
  keyUpNumpad,   0,        scrUp,      \
  keyDown,       0,        scrDown,    \
  keyDownNumpad, 0,        scrDown,    \
  keyLeft,       0,        scrLeft,    \
  keyLeftNumpad, 0,        scrLeft,    \
  keyRight,      0,        scrRight,   \
  keyRightNumpad,0,        scrRight,   \
  keyPgUp,       0,        scrPgUp,    \
  keyPgUpNumpad, 0,        scrPgUp,    \
  keyPgDown,     0,        scrPgDn,    \
  keyPgDnNumpad, 0,        scrPgDn,    \
  keyHome,       0,        scrHome,    \
  keyHomeNumpad, 0,        scrHome,    \
  keyEnd,        0,        scrEnd,     \
  keyEndNumpad,  0,        scrEnd,     \
  keyPgDown,     maskCtrl, scrEndOfFile,        \
  keyPgDnNumpad, maskCtrl, scrEndOfFile,        \
  keyPgUp,       maskCtrl, scrBegOfFile,        \
  keyPgUpNumpad, maskCtrl, scrBegOfFile,        \
  keyHome,       maskCtrl, scrBegOfScreen,      \
  keyHomeNumpad, maskCtrl, scrBegOfScreen,      \
  keyEnd,        maskCtrl, scrEndOfScreen,      \
  keyEndNumpad,  maskCtrl, scrEndOfScreen,      \
  keyInsert,     0,        scrToggleInsMode,    \
  keyInsNumpad,  0,        scrToggleInsMode,    \
  keyInsert,     maskAlt,  scrToggleSelectionMode


scrUp                   script 'u'
scrDown                 script 'd'
scrLeft                 script 'l'
scrRight                script 'r'
scrPgUp                 script 'pu'
scrPgDn                 script 'pd'
scrHome                 script 'lb'
scrEnd                  script 'le'
scrEndOfFile            script 'fe'
scrBegOfFile            script 'fb'
scrBegOfScreen          script 'sb'
scrEndOfScreen          script 'se'
scrToggleInsMode        script 'gim 1 xor sim'
scrToggleSelectionMode  script 'gsm 1 + 3 % ssm'




proc ExecScript, .editor, .pScript

.stack     rd 16

.pvar      dd ?
.fassign   dd ?

.changes dd ?

.errInvalidCommand = -1
.errInvalidNumber  = -2
.errStackOverflow  = -3
.errMissingQuote   = -4
.errInvalidVar     = -5
.errIfThenElse     = -6


begin
        push    ebx ecx edx esi edi

        stdcall GetMem, 65536
        mov     [.pvar], eax

        mov     ecx, 16
        lea     edi, [.stack]
        xor     eax, eax
        rep stosd

        mov     [.changes], eax
        mov     [.fassign], eax
        mov     edi, 15          ; intex to the stack bottom
        mov     esi, [.pScript]

.scriptloop:
        xor     ebx, ebx
        xor     ecx, ecx
        xor     eax, eax

.wordloop:
        movzx   eax, byte [esi]

        cmp     al, ' '
        jbe     .endofword

        cmp     al, '@'
        je      .variable

        cmp     al, "'"
        je      .string

        cmp     al, '"'
        je      .string

        cmp     al, '0'
        jb      .word
        cmp     al, '9'
        jbe     .digit

.word:
        inc     esi
        shl     eax, cl
        or      ebx, eax        ; command
        add     cl, 8
        cmp     cl, 32
        jbe     .wordloop
        jmp     .invalid_command


.variable:
        test    ecx, ecx
        jnz     .invalid_command

        mov     eax, $811C9DC5                  ; 2166136261              ; FNV offset basis

.hashloop:
        inc     esi

        movzx   edx, byte [esi]

        cmp     edx, ' '
        jbe     .endofvar

        xor     eax, edx
        imul    eax, $01000193                  ;   16777619              ; FNV prime
        jmp     .hashloop

.endofvar:
        mov     ebx, eax
        and     eax, $ffff
        shr     ebx, 16
        xor     ebx, eax
        and     ebx, $fffc
        add     ebx, [.pvar]

        cmp     [.fassign], 0
        je      .pushvar
; pop var
        mov     [.fassign], 0
        cmp     edi, 15
        jae     .stack_overflow

        inc     edi
        mov     eax, [.stack+4*edi]
        mov     [ebx], eax
        jmp     .nextchar

.pushvar:
        test    edi, edi
        js      .stack_overflow

        mov     eax, [ebx]
        mov     [.stack+4*edi], eax
        dec     edi
        jmp     .nextchar

.string:
        test    ecx, ecx
        jnz     .invalid_command

        inc     esi
        mov     ebx, esi

        xor     ecx, ecx

.lenloop:
        cmp     byte [esi], 0
        je      .missing_quote

        cmp     byte [esi], al
        je      .endofstring

        inc     esi
        inc     ecx
        jmp     .lenloop

.endofstring:
        test    edi, edi
        js      .stack_overflow

        stdcall StrNew
        mov     [.stack+4*edi], eax
        stdcall StrCopyPart, eax, ebx, 0, ecx
        stdcall StrPtr, eax

        dec     edi
        inc     esi
        jmp     .scriptloop

.digit:
        test    ecx, ecx
        jnz     .invalid_command

.numberloop:
        mov     al, [esi]
        cmp     al, ' '
        jbe     .endofnumber
        inc     esi

        cmp     al, '0'
        jb      .invalid_number
        cmp     al, '9'
        ja      .invalid_number

        and     eax, $0f
        imul    ebx, 10
        add     ebx, eax
        jmp     .numberloop

.endofnumber:
        test    edi, edi
        js      .stack_overflow

        mov     [.stack+4*edi], ebx
        dec     edi

        test    eax, eax
        jz      .endofscript

        inc     esi
        jmp     .scriptloop


.endofword:
        jecxz   .nextchar
        mov     eax, ScriptCommands - sizeof.TCommandItem

.search_command:
        add     eax, sizeof.TCommandItem

        cmp     dword [eax], 0
        je      .invalid_command

        cmp     [eax], ebx
        jne     .search_command

;.found:
        push    esi
        lea     ebx, [.stack]
        mov     esi, [.editor]
        call    [eax+TCommandItem.proc]
        pop     esi

        jc      .stack_overflow
        or      [.changes], eax

        cmp     edi, 15
        ja      .stack_overflow

.nextchar:
        inc     esi
        cmp     byte [esi-1], 0
        jne     .scriptloop

.endofscript:
        clc
        mov     eax, [.changes]

.finish:
        stdcall FreeMem, [.pvar]
        pop     edi esi edx ecx ebx
        return

; Context dependent control commands

; "->" (assign) command
.__assign:
        mov     [.fassign], 1
        xor     eax, eax
        clc
        retn

.__if:
        cmp     edi, 15
        jae     .ifok

        inc     edi
        cmp     [.stack+4*edi], 0
        jne     .ifok

; search for else of then
        mov     eax, [esp+4]    ; stored pointer to the script text
        xor     ecx, ecx

.ifloop:
        inc     eax
        mov     edx, [eax]
        cmp     edx, 'else'
        je      .else
        cmp     edx, 'then'
        je      .then
        test    edx, $ff000000
        jz      .iferror

        and     edx, $ffff
        cmp     edx, 'if'
        jne     .ifloop

        inc     ecx
        jmp     .ifloop

.else:
        jecxz   .elsehere
        dec     ecx
        jmp     .ifloop

.elsehere:
        add     eax, 4
        cmp     byte [eax], ' '
        ja      .iferror

        mov     [esp+4], eax
        jmp     .ifok

.then:
        jecxz   .thenhere
        dec     ecx
        jmp     .ifloop

.thenhere:
        add     eax, 4
        cmp     byte [eax], ' '
        ja      .iferror
        mov     [esp+4], eax

.ifok:
        xor     eax, eax
        clc
        retn

.iferror:
        stc
        mov     eax, .errIfThenElse
        retn


.__else:
; search for "then"
        mov     eax, [esp+4]    ; stored pointer to the script text
        xor     ecx, ecx

.elseloop:
        inc     eax
        mov     edx, [eax]
        cmp     edx, 'else'
        je      .else2
        cmp     edx, 'then'
        je      .then2
        test    edx, $ff000000
        jz      .iferror

        and     edx, $ffff
        cmp     edx, 'if'
        jne     .elseloop

        inc     ecx
        jmp     .elseloop

.else2:
        jecxz   .iferror
        dec     ecx
        jmp     .elseloop

.then2:
        jecxz   .thenhere2
        dec     ecx
        jmp     .elseloop

.thenhere2:
        add     eax, 4
        cmp     byte [eax], ' '
        ja      .iferror
        mov     [esp+4], eax
        jmp     .ifok

.__then:
        xor     eax, eax
        clc
        retn


; errors

.invalid_command:
        stc
        mov     eax, .errInvalidCommand
        jmp     .finish

.invalid_number:
        stc
        mov     eax, .errInvalidNumber
        jmp     .finish

.stack_overflow:
        stc
        mov     eax, .errStackOverflow
        jmp     .finish

.missing_quote:
        stc
        mov     eax, .errMissingQuote
        jmp     .finish

endp


call    ExecScript



proc __ScriptPlus
begin
        cmp     edi, 14
        jae     .end

        mov     eax, [ebx+4*edi+4]
        inc     edi
        add     [ebx+4*edi+4], eax

.end:
        xor     eax, eax
        return
endp



proc __ScriptMinus
begin
        cmp     edi, 14
        jae     .end

        mov     eax, [ebx+4*edi+4]
        inc     edi
        sub     [ebx+4*edi+4], eax

.end:
        xor     eax, eax
        clc
        return
endp



proc __ScriptMul
begin
        cmp     edi, 14
        jae     .end

        mov     eax, [ebx+4*edi+4]
        inc     edi
        imul    eax, [ebx+4*edi+4]
        mov     [ebx+4*edi+4], eax
.end:
        xor     eax, eax
        clc
        return
endp



proc __ScriptDiv
begin
        cmp     edi, 14
        jae     .end

        cmp     dword [ebx+4*edi+4], 0
        je      .err

        inc     edi
        mov     eax, [ebx+4*edi+4]
        cdq
        div     dword [ebx+4*edi]
        mov     [ebx+4*edi+4], eax

.end:
        xor     eax, eax
        clc
        return

.err:
        stc
        return
endp




proc __ScriptMod
begin
        cmp     edi, 14
        jae     .end

        cmp     dword [ebx+4*edi+4], 0
        je      .err

        inc     edi
        mov     eax, [ebx+4*edi+4]
        cdq
        div     dword [ebx+4*edi]
        mov     [ebx+4*edi+4], edx

.end:
        xor     eax, eax
        clc
        return

.err:
        stc
        return
endp



proc __ScriptOutNumber
begin
        cmp     edi, 15
        jae     .end

        inc     edi
        mov     eax, [ebx+4*edi]

        stdcall NumToStr, eax, ntsSigned or ntsDec
        push    eax

        stdcall StrPtr, eax
        stdcall Output, eax
        stdcall StrDel ; from the stack.

.end:
        xor     eax, eax
        clc
        return
endp


proc __ScriptOutString
begin
        cmp     edi, 15
        jae     .end

        inc     edi
        cmp     dword [ebx+4*edi], 0
        je      .crlf

        stdcall StrPtr, [ebx+4*edi]
        stdcall Output, eax
        stdcall StrDel, [ebx+4*edi]

.end:
        xor     eax, eax
        clc
        return

.crlf:
        stdcall Output, .scrlf
        jmp     .end

.scrlf db 13, 10, 0

endp



proc __ScriptSwap
begin
        cmp     edi, 14
        jae     .end

        pushd   [ebx+4*edi+4]
        pushd   [ebx+4*edi+8]
        popd    [ebx+4*edi+4]
        popd    [ebx+4*edi+8]

.end:
        xor     eax, eax
        clc
        return
endp


proc __ScriptPop
begin
        cmp     edi, 15
        jae     .end

        inc     edi
.end:
        xor     eax, eax
        clc
        return
endp



proc __ScriptAnd
begin
        cmp     edi, 14
        jae     .end

        mov     eax, [ebx+4*edi+4]
        inc     edi
        and     [ebx+4*edi+4], eax

.end:
        xor     eax, eax
        clc
        return
endp


proc __ScriptOr
begin
        cmp     edi, 14
        jae     .end

        mov     eax, [ebx+4*edi+4]
        inc     edi
        or      [ebx+4*edi+4], eax

.end:
        xor     eax, eax
        clc
        return
endp


proc __ScriptXor
begin
        cmp     edi, 14
        jae     .end

        mov     eax, [ebx+4*edi+4]
        inc     edi
        xor     [ebx+4*edi+4], eax

.end:
        xor     eax, eax
        clc
        return
endp




proc __ScriptNot
begin
        cmp     edi, 15
        jae     .end

        not     dword [ebx+4*edi+4]

.end:
        xor     eax, eax
        clc
        return
endp



proc __ScriptNeg
begin
        cmp     edi, 15
        jae     .end

        neg     dword [ebx+4*edi+4]

.end:
        xor     eax, eax
        clc
        return
endp



proc __ScriptRepeat
begin
        cmp     edi, 14
        jae     .end


.end:
        xor     eax, eax
        clc
        return
endp


proc __ScriptLoop
begin
        cmp     edi, 14
        jae     .end

.end:
        xor     eax, eax
        clc
        return
endp







DispSize 'Script engine', $ - __ScriptEngine

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/drafts/HashList.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
;uses memory.asm

cInitTreeSize = 256

struct THashList
  .ptrHashTree dd ?
  .TreeSize    dd ?
  .StrHeap     TStringPool
ends



proc HashListCreate, .ptrHashList
begin
        push    esi eax

        mov     esi, [.ptrHashList]

        mov     [esi+THashList.TreeSize], cInitTreeSize
        stdcall GetMem, [esi+THashList.TreeSize]
        mov     [esi+THashList.ptrHashTree], eax

        lea     esi, [esi+THashList.StrHeap]
        stdcall StringHeapCreate, esi

        pop     eax esi
        return
endp




proc HashListDestroy, .ptrHashList
begin
        push    esi
        mov     esi, [.ptrHashList]
        stdcall FreeMem, [esi+THashList.ptrHashTree]
        stdcall FreeMem, [esi+THashList.ptrStrList]
        pop     esi
        return
endp


;_______________________________________________________________________
;
; RETURNS:
; if CF=1 the string is already in the list.
; returns eax = pointer to the string in the list.
;         edx = hash of the string.
;
; if CF=0 the string is not in the list.
; in this case if fAdd=TRUE, adds the string to the list.
; returns eax = pointer to the string in the list.
;         edx = hash of the string.
;
; if fAdd = FALSE doesn't add the string to the list and
;_______________________________________________________________________
proc HashListCheck, .ptrHashList, .hString, .fAdd
begin

        return
endp



;_______________________________________________________________________
;
; function StrHash
;   Computes 32 bit hash value from the string.
;   The function is compatible with FASM hash
;   function if OrMask = 0.
;
; Arguments:
;   ptrString - pointer to PASCAL string with dword length at [ptr-4]
;
; Return:
;   eax - 32bit hash value.
;
; Changes:
;   eax
;_______________________________________________________________________
proc Hash_FNV1a, .ptrString
begin
        push    edx ecx esi

        mov     esi, [.ptrString]
        mov     eax, $811C9DC5                  ; 2166136261              ; FNV offset basis
        mov     ecx, [esi-4]                    ; length of the string
        jecxz   .exit

.hashloop:
        movzx   edx, byte [esi]
        xor     eax, edx
        inc     esi
        imul    eax, $01000193                  ;   16777619              ; FNV prime
        dec     ecx
        jnz     .hashloop

.exit:
        pop     esi ecx edx
        return
endp

DispSize "Hash_FNV1a", $-Hash_FNV1a
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































Deleted freshlib/_trash/SurplusSources/drafts/StrLibUltra.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
; ____________________________________________________________________
;|                                                                    |
;| This file is part of the project:                                  |
;|                                                                    |
;| ..::FreshLib::.. - portable, assembler library and GUI toolkit.    |
;|____________________________________________________________________|
;|                                                                    |
;|                          This file                                 |
;|                          _________                                 |
;|   Author:                                                          |
;|                                                                    |
;|   Title: StrLib.asm - OS independent string manipulation library.  |
;|                                                                    |
;|   OS:                                                              |
;|                                                                    |
;|   Notes and changes:                                               |
;|     Uses memory.asm library for memory functions.                  |
;|                                                                    |
;|                                                                    |
;|____________________________________________________________________|

; NumToStr flags
ntsSigned         = $00000000
ntsUnsigned       = $00010000
ntsZeroTerminated = $00020000
ntsFixedWidth     = $00040000

ntsBin            = $00000200
ntsQuad           = $00000400
ntsOct            = $00000800
ntsDec            = $00000a00
ntsHex            = $00001000

cStrShift     = 6
cStrChunkSize = 1 shl cStrShift

cStrChunkCount = 1024

; TChunkIndex is a dword with following format:
;  $00000000 - empty chunk
;  $pxffffff - last chunk in the string. Only $ffffff have special meaning. $fffffe for example is normal chunk number.
;              .next is unsigned 24 bit number.
;  $nxyyyyyy - first chunk in the string.       nx = not (px) - it is not NEG!
struct TChunkIndex
  .next rb 3
  .len  db ?
ends


struct TStrTableNew
  .count      dd 0      ; Count of the chunks in the string pool
  .ptrPool    dd 0      ; One big area of memory to be allocated for strings.
  .ptrIndex   dd 0      ; array of dword for every chunk in the pool: if >0 it is index of the next chunk in the string. If <0 it is occuped space in the last chunk.
  .Hint       dd ?      ; index of the fast found free chunk. From here you must start to search for the next allocation.
ends


uglobal
  _StrList    TStrTableNew
endg


initialize StrLibInit
begin
        stdcall GetMem, cStrChunkCount * cStrChunkSize
        jc      .error_init
        mov     [_StrList.ptrPool], eax

        stdcall GetMem, cStrChunkCount * 4
        jc      .error_init
        mov     [_StrList.ptrIndex], eax

        mov     [_StrList.count], cStrChunkCount
        mov     [_StrList.Hint], -1
        return

.error_init:
        int3
        return

endp




finalize StrLibDestroy
begin
        stdcall FreeMem, [_StrList.ptrPool]
        stdcall FreeMem, [_StrList.ptrIndex]
        return
endp


; ____________________________________________________________________
;| proc StrNew                                                        |
;|   Creates new dynamic string and returns the handle.               |
;| Arguments:                                                         |
;|   None                                                             |
;| Returns:                                                           |
;|   CF = 0; no error: eax contains handle of the string.             |
;|   CF = 1; error. eax = 0                                           |
;|____________________________________________________________________|
proc StrNew
begin
        push    ebx
        mov     ebx, [_StrList.ptrIndex]
        call    _search_empty_chunk
        jc      .error_new
        mov     dword [ebx+4*eax], $ffffffff    ; first chunk; last chunk; zero occupied (empty string).
        clc
        pop     ebx
        return

.error_new:
        stc
        pop     ebx
        return
endp


;__________________________________________
;
; Arguments:
;   ebx - pointer to the index.

; Returns:
;   eax - index of new empty  chunk.
;
; Returns index of a empty chunk.
; If needed, resizes memory arrays for
; chunks and for index.
; Updates _StrList as well.
;__________________________________________

proc _search_empty_chunk
begin
        push    ecx  edx

        mov     edx, [_StrList.Hint]
        mov     ecx, [_StrList.count]

.searchloop:
        inc     edx
        cmp     edx, [_StrList.count]
        jb      @f
        xor     edx, edx
@@:
        cmp     dword [ebx+4*edx], 0
        je      .free_found

        dec     ecx
        jnz     .searchloop

; the empty chunk not found. so, resize the arrays
        mov     edx, [_StrList.count]   ; that is the new string handle.

        lea     eax, [2*edx]            ; new size of the arrays. very aggressive.
        mov     [_StrList.count], eax

        shl     eax, cStrShift
        stdcall ResizeMem, [_StrList.ptrPool], eax
        jc      .finish

        mov     [_StrList.ptrPool], eax

        mov     eax, [_StrList.count]
        lea     eax, [4*eax]
        stdcall ResizeMem, [_StrList.ptrIndex], eax
        mov     [_StrList.ptrIndex], eax
        mov     ebx, eax

.free_found:
        mov     [_StrList.Hint], edx
        mov     eax, edx
.finish:
        pop     edx ecx
        return
endp



; ____________________________________________________________________
;| proc StrDel, .hString                                              |
;|   Destroys dynamic string                                          |
;| Arguments:                                                         |
;|   .hString - only handle to a string.                              |
;| Returns:                                                           |
;|   CF = 0; no error:                                                |
;|   CF = 1; error                                                    |
;|____________________________________________________________________|
proc StrDel, .hString
begin
        push    ebx edx
        mov     ebx, [_StrList.ptrIndex]
        mov     edx, [.hString]
        cmp     byte [ebx+4*edx+TChunkIndex.len], 0     ; first .len should be negative!
        jge     .invalid_handle

        mov     [_StrList.Hint], edx
        dec     [_StrList.Hint]

.del_loop:
        push    dword [ebx+4*edx]
        mov     dword [ebx+4*edx], 0    ; free chunk
        pop     edx
        and     edx, $ffffff
        cmp     edx, $ffffff
        je      .end_string

        cmp     byte [ebx+4*edx+TChunkIndex.len], 0
        jge     .del_loop                               ; every next .len should be positive.

.invalid_handle:
        stc
        pop     edx ebx
        return

.end_string:
        clc
        pop     edx ebx
        return

endp



;____________________________________________________________________
;
; proc StrCatAsciiZ, .hString, .ptrAsciiZ
;
;   Concatenates asciiz string from the memory to the given dynamic
; string.
;
; Arguments:
;   .hString - handle of a dynamic string.
;   .ptrAsciiZ - pointer to asciiz string in memory.
;
; Returns:
;   CF=1 if error.
;____________________________________________________________________

proc StrCatAsciiZ, .hString, .ptrAsciiZ
begin
        push    eax ebx ecx edx esi edi

        mov     ebx, [_StrList.ptrIndex]
        mov     eax, [.hString]

; first search to the end chunk of the string.
.endloop:
        mov     edx, eax
        mov     eax, [ebx+4*edx]
        and     eax, $ffffff
        cmp     eax, $ffffff
        jne     .endloop

        mov     eax, edx
        mov     edi, [_StrList.ptrPool]
        shl     eax, cStrShift
        add     edi, eax                 ; edi - pointer to the begin of the last chunk in string.

        movsx   ecx, byte [ebx+4*edx+TChunkIndex.len]    ; offset in the chunk.
        mov     esi, [.ptrAsciiZ]
        test    ecx, ecx
        jns     .copyloop

        not     ecx

; so, copy to the end of the chunk
.copyloop:
        cmp     ecx, cStrChunkSize
        jb      .sizeok

        call    _search_empty_chunk
        jc      .finish

; set previous chunk index.
        mov     [ebx+4*edx], eax
        mov     cl, cStrChunkSize
        cmp     edx, [.hString]
        jne     @f
        not     cl
@@:
        mov     byte [ebx+4*edx+TChunkIndex.len], cl

        mov     edi, eax
        xor     ecx, ecx  ; zero offset.
        shl     edi, cStrShift
        mov     edx, eax                ; new chunk index.
        add     edi, [_StrList.ptrPool] ; new chunk pointer

.sizeok:
        mov     al, [esi]
        inc     esi
        cmp     al, 0
        je      .endofstring
        mov     [edi+ecx], al
        inc     ecx
        jmp     .copyloop

.endofstring:
        mov     dword [ebx+4*edx+TChunkIndex.next], $00ffffff

        cmp     edx, [.hString]
        jne     @f
        not     cl
@@:
        mov     byte  [ebx+4*edx+TChunkIndex.len],  cl

.finish:
        pop     edi esi edx ecx ebx eax
        return
endp



;____________________________________________________________________
;
; proc StrCatChar, .hString, .char
;
;   Concatenates 1..4 characters to the given dynamic string.
;   Actually uses StrCatAsciiZ to do the work.
;
; Arguments:
;   .hString - handle of a dynamic string.
;   .char - dword with 1 to 4 characters.
;
; Returns:
;   CF=1 if error.
;____________________________________________________________________

proc StrCatChar, .hString, .char
.buff rd 2
begin
        push    eax
        mov     eax, [.char]
        mov     [.buff], eax
        mov     [.buff+4], 0
        lea     eax, [.buff]
        stdcall StrCatAsciiZ, [.hString], eax
        pop     eax
        return
endp




;____________________________________________________________________
;
; proc StrSplit, .hString, .pos
;
; Splits [.hString] at position [.pos].
; The left portion of the string remains in [.hString]
; The right portion forms new string that is returned by function.
; This procedure increases fragmentation of the string pool.
; In most cases it allocates one more chunk to keep the begin of
; the right part of the string.
;
; Arguments:
;   .hString - handle of string to be splitted.
;   .pos     - position for split.
; Returns:
;   CF = 1 - error.
;   CF = 0 - no error. eax contains handle of string with right part of
;            the splitted string.
;____________________________________________________________________

proc StrSplit, .hString, .pos
begin
        push    ebx ecx edx esi edi

        mov     ebx, [_StrList.ptrIndex]
        mov     edx, [.hString]
        cmp     edx, [_StrList.count]
        cmc
        jc      .finish

        movsx   eax, [ebx+4*edx+TChunkIndex.len]
        not     eax

        bt      eax, 31
        jc      .finish

        sub     [.pos], eax
        jle     .found

.lenloop:
        mov     edx, [ebx+4*edx]
        and     edx, $00ffffff
        cmp     edx, $00ffffff
        je      .exit_error

        movsx   eax, [ebx+4*edx+TChunkIndex.len]
        bt      eax, 31
        jc      .finish

        sub     [.pos], eax
        jg      .lenloop

.found:
        jl      .insertchunk

        mov     eax, [ebx+4*edx]
        and     eax, $00ffffff
        cmp     eax, $00ffffff
        je      .exit_error

        or      dword [ebx+4*edx], $00ffffff
        xor     dword [ebx+4*eax], $ff000000
        clc
        jmp     .finish

.insertchunk:
        sar     [ebx+4*edx+TChunkIndex.len], 7
        add     [.pos], eax
        mov     ecx, [.pos]   ; remaining in the left string.
        xor     [ebx+4*edx+TChunkIndex.len], cl    ; proper sign length.

        mov     esi, edx
        shl     esi, cStrShift
        add     esi, ecx        ; the offset in the pool.

        push    dword [ebx+4*edx]
        or      dword [ebx+4*edx], $00ffffff
        pop     edx
        and     edx, $00ffffff

        sub     eax, [.pos]     ; length of the remaining in the right.
        mov     ecx, eax

        call    _search_empty_chunk

        mov     [ebx+4*eax+TChunkIndex.len], cl
        xor     dword [ebx+4*eax], $ff000000    ; it is first chunk in the new string.
        or      dword [ebx+4*eax], edx          ; next chunk.

        mov     edi, eax
        shl     edi, cStrShift
        add     edi, [_StrList.ptrPool]
        add     esi, [_StrList.ptrPool]
        rep movsb
        clc
.finish:
        pop     edi esi edx ecx ebx
        return

.exit_error:
        stc
        jmp     .finish
endp



;____________________________________________________________________
;
; proc StrInsert, .hDest, .hSrc, .position
;
; Insrts [.hSrs] at [.position] inside [.hDest].
; Uses StrSplit and StrCat to do the work.
; .hStr is destroyed.
;
; Arguments:
;   .hDest - handle of destination string.
;   .hStr  - string to be inserted.
;   .position - position of insertion.
;
; Returns:
;   CF = 1 - error.
;   CF = 0 - no error.
;____________________________________________________________________

proc StrInsert, .hDest, .hSrc, .position
begin
        push    eax
        stdcall StrSplit, [.hDest], [.position]
        jc      .finish
        stdcall StrCat, [.hDest], [.hSrc]
        jc      .freeeax
        stdcall StrCat, [.hDest], eax
        jc      .strange

.finish:
        pop     eax
        return

.freeeax:
        stdcall StrCat, [.hDest], eax
        jc      .strange
        stc
        jmp     .finish

.strange:
        stdcall StrDel, eax
        stc
        jmp     .finish

endp



;____________________________________________________________________
;
; proc StrCat, .hDest, .hSrc
;
;   Concatenates two dynamic strings. The result string is [.hDest]
;   After concatenation, [.hSrc] is destroyed. If you need to keep
;   .hSrc, make copy of it with StrDup and then concatenate the
;   copy with the destination string.
;
; Arguments:
;   .hString - handle of a dynamic string.
;   .ptrAsciiZ - pointer to asciiz string in memory.
;
; Returns:
;   CF=1 if error.
;____________________________________________________________________
proc StrCat, .hDest, .hSrc
begin
        push    eax ebx ecx edx

        mov     ebx, [_StrList.ptrIndex]
        mov     eax, [.hDest]
        cmp     eax, [_StrList.count]
        cmc
        jc      .finish

        movsx   ecx, [ebx+4*eax+TChunkIndex.len]
        not     ecx
        bt      ecx, 31
        jc      .finish

.chunkloop:
        mov     edx, eax
        mov     eax, [ebx+4*edx]
        and     eax, $00ffffff
        cmp     eax, $00ffffff
        jne     .chunkloop

        mov     ecx, [.hSrc]
        cmp     ecx, [_StrList.count]
        cmc
        jc      .finish

        xor     dword [ebx+4*ecx], $ff000000
        bt      dword [ebx+4*ecx], 31
        jc      .finish

        and     dword [ebx+4*edx], $ff000000
        or      dword [ebx+4*edx], ecx

.finish:
        pop     edx ecx ebx eax
        return
endp


;____________________________________________________________________
; proc StrCompact, .hStr
;
; Compacts the string. This means, that if some chunks of the string
; are not fully used (as a result of string manipulations -
; inserts, concatenations, deletes, etc.) this function removes
; the empty spaces from the chunks and frees resulted empty chunks
; from the end of the string.
; This operation is slow if the string is fragmented and should be
; avoided without reason. Even when needed, you should call this
; procedure as later as possible, after all operations that may
; fragment the string.
;
;____________________________________________________________________
proc StrCompact, .hStr
begin


        return
endp




;____________________________________________________________________
;
; proc StrDup, .hString
;
;   Creates duplicate of the given string.
;
; Arguments:
;   .hString - handle of a dynamic string.
;
; Returns:
;   CF=1 if error.
;   CF=0 - eax = handle of the new created string.
;____________________________________________________________________
proc StrDup, .hString
.new dd ?
begin
        push    ebx ecx edx esi edi

        mov     edx, [.hString]
        mov     ebx, [_StrList.ptrIndex]
        cmp     edx, [_StrList.count]
        cmc
        jc      .finish

        movsx   ecx, [ebx+4*edx+TChunkIndex.len]
        not     ecx
        bt      ecx, 31
        jc      .finish

        call    _search_empty_chunk
        jc      .finish

        mov     [.new], eax

.chunkloop:
        mov     edi, eax
        mov     esi, edx
        shl     edi, cStrShift
        shl     esi, cStrShift
        add     edi, [_StrList.ptrPool]
        add     esi, [_StrList.ptrPool]

        mov     ecx, cStrChunkSize / 4
        rep movsd

        mov     ecx, [ebx+4*edx]
        and     ecx, $ff000000
        push    ecx

        mov     edx, [ebx+4*edx]
        and     edx, $00ffffff
        cmp     edx, $00ffffff
        je      .endofstring

        mov     ecx, eax
        call    _search_empty_chunk
        jc      .finish

        pop     dword [ebx+4*ecx]
        or      [ebx+4*ecx], eax

        jmp     .chunkloop

.endofstring:
        pop     dword [ebx+4*eax]
        or      [ebx+4*eax], edx
        mov     eax, [.new]
        clc
.finish:
        pop     edi esi edx ecx ebx
        return
endp




proc SubStr, .hString, .index, .length
begin




endp




; ____________________________________________________________________
;|                                                                    |
;| proc StrLen, .hString                                              |
;|   Returns the length of the string in bytes.                       |
;| Arguments:                                                         |
;|   .hString: pointer or handle to a string.                         |
;| Returns:                                                           |
;|    ecx - length of the strin in bytes.                             |
;|____________________________________________________________________|

proc StrLen, .hString
begin
        push    ebx edx eax

        mov     ebx, [_StrList.ptrIndex]
        mov     edx, [.hString]
        cmp     edx, [_StrList.count]
        cmc
        jc      .finish

        movsx   ecx, [ebx+4*edx+TChunkIndex.len]
        not     ecx

        bt      ecx, 31
        jc      .finish

.lenloop:
        mov     edx, [ebx+4*edx]
        and     edx, $00ffffff
        cmp     edx, $00ffffff
        je      .finish

        movsx   eax, [ebx+4*edx+TChunkIndex.len]
        bt      eax, 31
        jc      .finish

        add     ecx, eax
        jmp     .lenloop

.finish:
        pop     eax edx ebx
        return
endp


;_____________________________________________________________________
;
; proc StrFreeBuffer, .ptrBuffer
;
; Frees thestring buffer, allocated by StrPointer.
; Arguments:
;   .ptrBuffer - pointer to the buffer.
; Returns:
;   CF=1 if error. In this case, the memory is not released.
;_____________________________________________________________________

proc StrFreeBuffer, .ptrBuffer
begin
        push    eax
        mov     eax, [.ptrBuffer]
        sub     eax, 4
        stdcall FreeMem, eax
        pop     eax
        return
endp


;____________________________________________________________________________________
; proc StrPointer, .hString
;
; Extracts the string [.hString] to the allocated buffer and returns pointer
; to the allocated memory.
; Allocated memory must be freed with StrFreeBuffer.
; The buffer have dword size. The string is Zero terminated and there is guarantied
; that at least one full dword at the end is zero.
; At the [pointer - 4] is placed the length of the string in bytes.
;
; Arguments:
;   .hString - handle to a string.
; Returns:
;   esi - pointer to allocated buffer in memory.
;   CF = 1 in case of error - invalid handle of string or the memory can not be
;          allocated.
;____________________________________________________________________________________
proc StrPointer, .hString
.ptr dd ?
.len dd ?
begin
        push    eax ebx ecx edx edi

        stdcall StrLen, [.hString]
        jc      .finish

        mov     [.len], ecx
        add     ecx, 11              ; we need 8bytes more memory for length and termination
        and     cl, $fc

        stdcall GetMem, ecx
        jc      .finish

        mov     [.ptr], eax
        lea     edi, [eax+4]

        mov     ebx, [_StrList.ptrIndex]
        mov     edx, [.hString]

        cmp     dword [ebx+4*edx], 0
        je      .invalid_handle

.outerextract:
        mov     esi, edx
        shl     esi, cStrShift
        add     esi, [_StrList.ptrPool]
        movsx   ecx, [ebx+4*edx+TChunkIndex.len]
        test    ecx, ecx
        jns     .innerextract
        not     ecx

.innerextract:
        cmp     ecx, 0
        jle     .endofchunk

        movsd
        sub     ecx, 4
        jmp     .innerextract

.endofchunk:
        add     edi, ecx        ; ecx <= 0

        mov     edx, [ebx+4*edx]
        and     edx, $00ffffff
        cmp     edx, $00ffffff
        jne     .outerextract

        xor     eax, eax
        stosd                   ; terminator
        mov     esi, [.ptr]
        pushd   [.len]
        popd    [esi]
        add     esi, 4
        clc
.finish:
        pop     edi edx ecx ebx eax
        return

.invalid_handle:
        stc
        pop     edi edx ecx ebx eax
        return
endp


;_______________________________________________________________________
;
; function StrHash
;   Computes 32 bit hash value from the string.
;
; Arguments:
;   .hString - handle or pointer to the string.
;
; Return:
;   eax - 32bit hash value; FNV-1a algorithm.
;
; Changes:
;   eax
;_______________________________________________________________________
proc StrHash, .hString, .OrMask
begin
        push    edx ecx esi

        stdcall StrPtr, [.hString]
        mov     esi, eax
        mov     eax, $811C9DC5                  ; 2166136261              ; FNV offset basis
        mov     ecx, [esi-4]                    ; length of the string
        jecxz   .exit

.hashloop:
        movzx   edx, byte [esi]
        inc     esi
        or      edx, [.OrMask]
        xor     eax, edx
        imul    eax, $01000193                  ;   16777619              ; FNV prime
        dec     ecx
        jnz     .hashloop

.exit:
        pop     esi ecx edx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/drafts/StringHeap.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
cInitStringPoolSize = 1024


struct TStringPool
  .ptrPool  dd ?
  .iEnd     dd ?
ends



proc StringHeapCreate, .ptrStringPool
begin
        push    esi
        mov     esi, [.ptrStringPool]
        stdcall GetMem, cInitStringPoolSize
        mov     [esi+TStringPool.ptrPool], eax

        pop     esi
        return
endp



proc StringHeapAdd, .ptrStringPool, .ptrString
.size dd ?
begin
        push    ebx ecx edx esi edi

        mov     esi, [.ptrString]
        mov     edi, [.ptrStringPool]

        stdcall GetMemSize, [edi+TStringPool.ptrPool]
        mov     [.size], eax

        mov     ebx, [edi+TStringPool.iEnd]
        add     ebx, [esi-4]    ; length of the string.
        add     ebx, 8          ; dword len + dword zero terminator.
        cmp     ebx, [.size]    ;
        jb      .sizeok

        mov     ecx, [.size]
        sar     ecx, 2  ; 1/4 of the size.
        cmp     ecx, cInitStringPoolSize
        ja      .reserveok
        mov     ecx, cInitStringPoolSize
.reserveok:

        add     ebx, ecx
        stdcall ResizeMem, [edi+TStringPool.ptrPool], ebx
        mov     [edi+TStringPool.ptrPool], eax

.sizeok:
; size is OK, so go copy:

        mov     ebx, [edi+TStringPool.ptrPool]
        mov     ecx, [esi-4]                    ; len of the string

        mov     eax, [edi+TStringPool.iEnd]
        lea     eax, [eax+4]
        push    eax                             ; result offset.

        lea     ebx, [ebx+eax]
        mov     [ebx-4], ecx                    ; length of the string

; ebx -> pointer to the destination
; esi -> pointer to the source
; ecx -> lenght in bytes.

        mov     edx, ecx
        shr     edx, 2          ; quotient
        and     ecx, 3          ; remainder

        mov     dword [ebx+4*edx], 0        ; zero termination
        mov     dword [ebx+4*edx+4], 0        ; zero termination
        lea     eax, [ebx+4*edx+8]
        sub     eax, [edi+TStringPool.ptrPool]
        mov     [edi+TStringPool.iEnd], eax

        push    ebx esi
        lea     ebx, [ebx+4*edx]
        lea     esi, [esi+4*edx]

.looprem:
        dec     ecx
        js      .endrem
        mov     al, [esi+ecx]
        mov     [ebx+ecx], al
        jmp     .looprem

.endrem:
        pop     esi ebx

.loopdword:
        dec     edx
        js      .endcopy
        mov     eax, [esi+4*edx]
        mov     [ebx+4*edx], eax
        jmp     .loopdword

.endcopy:
        pop     eax
        pop     edi esi edx ecx ebx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































Deleted freshlib/_trash/SurplusSources/drafts/strlib.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
;************************************************************
; FASM dynamic string library.
;
; (c)2003 John Found
; (c)2003 Mateusz Tymek (aka decard)
; (c)2003 Victor Loh (aka roticv)
;
; You can use and modify this library, as long as modifyed
; versions are clearly marked (author of the modification
; and what is changed), copyright notice is not
; removed and the library remains free.
; Copyright for the library concept and parts written by
; me, remains to me, John Found
; Copyright for the modifyed/new parts remains to their
; authors.
;
; Versions:
;   dd.mm.yyyy  version   author of modification
;     - description
;--------------------------------------------------------
;   09.07.2003  v1.0    John Found
;     - the first public version.
;   15.07.2003  v1.0.1  John Found
;     - minor bug with string table expand. Look in NewStr
;   17.09.2003  v1.1.0  Mateusz Tymek
;     - made all functions stdcall
;     - added StrCat and StrPos, and modified StrLen
;   25.09.2003  v1.1.2  Mateusz Tymek, Victor Loh
;     - added StrLCase, StrUCase, StrCopyMMX, StrInsert
;     - added new NumToStr, old version renamed to _NumStr
;     - some small optimizations & bugfixes
;   26.09.2003 v1.1.3  JohnFound
;     - some bug fixes and style corections.
;   29.09.2003 v1.1.4  John Found, Mateusz Tymek
;     - library rewtiten to use John Found's stdcall macros
;     - added two new low-level NumToStr routines: NumToStrF and NumToStrUF
;     - NumToStr rewriten
;     - some small bugfixes & modifications
;     - added StrExtract
;   01.11.2003 v1.1.4.1 Mateusz Tymek
;     - preserved ecx in StrDel (it was destroyed by API calls)
;   21.11.2003 v1.1.5 John Found
;     - StrComp splitted to 2 functions: StrCompCase and StrCompNoCase
;       IMPORTANT: inversed return result: CARRY = 1 mean strings equal.
;       This is because the using is more natural this way:
;            stdcall  StrCompCase, str1, str2
;            jc       .equal
;   27.11.2003 v1.2 John Found
;     - Added function StrHash, that produces 32bit hash value of the string.
;       The hash function is based on FASM hash function and have to be compatible.
;   03.12.2003 v1.2.3 Mateusz Tymek
;     - Added StrCharPos and StrToNum
;   13.12.2003 v1.2.4 Materusz Tymek
;     - added StrCharCat and StrInsertChar
;   04.01.2005 v1.2.5 John Found
;     - Fixed bug in StrSetLength
;     - Added function StrURLEncode
;*************************************************************************************


;--< How to use it >-----------------------------------------------------------------
; 1. Include "strutils.inc" somewhere in the begining of main file.
; 2. Define structure "StrTable" of type "TStrTable" somewhere in data section.
; 3. Before using of library functions, call "InitStrings"
; 4. After last use of the library (probably on close of application),
;    call "FreeStrings" to free all used memory.
; 5. Some functions are with register parameter passing, other with "stdcall"
;    parameter passing. Read the header descriptions of the functions.
;------------------------------------------------------------------------------------


STR_MINCOUNT = 10       ; minimum 10 strings in the table
STR_MINSTRLEN = 16      ; 16 bytes minimum string length



; NumToStr flags
ntsSigned = $00000
ntsUnsigned = $10000
ntsZeroTerminated = $20000
ntsFixedWidth     = $40000


ntsBin  = $0200
ntsQuad = $0400
ntsOct  = $0800
ntsDec  = $0a00
ntsHex  = $1000


; Global variable, storing parameters of dynamic strings list.
uglobal
  StrTable  dd  ?      ; StrLib library variable.
endg


; < Library functions >

;************************************************************************************
; Allocates memory for string table and allocates memory for strings.
; Start it before any work with strings.
; Returns 0 if failed to allocate needed memory.
;************************************************************************************
initialize InitStrings
begin
        StrLib = 1

        stdcall CreateArray, 4
        jc      .finish

        stdcall AddArrayItem, eax
        mov     [StrTable], edx
        mov     [edx+TArray.lparam], 0          ; lParam is the last allocated handle number
        or      dword [eax], -1

.finish:
        return
endp

;**************************************************************************************
; Frees all memory used for strings library
; Call it before exit of the program.
;**************************************************************************************
finalize FreeStrings
begin
        mov     esi, [StrTable]
        mov     edi, [esi+TArray.count]
        xor     ebx,ebx

.freeloop:
        mov     ebx, [esi+TArray.array]
        test    ebx,ebx
        jz      .nxt
        js      .nxt

        stdcall FreeMem, ebx

.nxt:
        add     esi, 4
        dec     edi
        jnz     .freeloop

        stdcall FreeMem, [StrTable]
        mov     [StrTable], 0
        return
endp



;**************************************************************************************
;  Returns the pointer in memory of the hString, or NULL on error
;**************************************************************************************
proc StrPtr, .hString
begin
        mov     eax, [.hString]
        test    eax, $ffff0000
        jnz     .finish                 ; It's pointer, go to finish.

        push    ebx

        mov     ebx, [StrTable]
        cmp     eax, [ebx+TArray.count]
        jae     .notfound

        mov     eax, [ebx+TArray.array+4*eax]
        pop     ebx
.finish:
        return

.notfound:
        pop     ebx
        xor     eax,eax
        return
endp

;**************************************************************************************
;  Creates new empty string and returns handle
;  Return: handle of the new created string.
;**************************************************************************************
proc StrNew
begin
        push    ecx edx esi

; Find first empty place.
        mov     edx, [StrTable]
        mov     ecx,[edx+TArray.count]
        mov     esi,[edx+TArray.lparam]
        xor     eax,eax

.search:
        inc     esi
        cmp     esi, [edx+TArray.count]
        jne     @f
        xor     esi,esi
        inc     esi
@@:
        cmp     [edx+TArray.array+4*esi],eax
        je      .found
        dec     ecx
        jnz     .search

.notfound:
        mov     esi, [edx+TArray.count]
        cmp     esi, $10000
        jb      @f
        int3                    ; 65535 strings max.
@@:
        stdcall AddArrayItem, edx
        mov     [StrTable], edx

.found:
        mov     [edx+TArray.lparam], esi
        stdcall GetMem, STR_MINSTRLEN
        mov     [edx+TArray.array+4*esi], eax
        mov     eax, esi
        pop     esi edx ecx
        return
endp

;**************************************************************************
; Deletes the string if it is possible.
;**************************************************************************
proc StrDel, .hString
begin
        push    eax ebx ecx edx esi

        mov     esi, [StrTable]
        mov     eax, [.hString]
        test    eax, eax
        jz      .finish

        test    eax,$ffff0000
        jz      .process

; search the pointer in the table.
        mov     ecx, [esi+TArray.count]

.search:
        dec     ecx
        js      .finish
        cmp     [esi+TArray.array+4*ecx], eax
        jne     .search

        stdcall FreeMem, eax
        mov     [esi+TArray.array+4*ecx], 0

        jmp     .finish

.process:
        mov     ebx, eax
        stdcall StrPtr,eax
        test    eax,eax
        jz      .finish
.free:
        invoke  HeapFree, [StrTable.heap], 0, eax
        mov     dword [esi+4*ebx], NULL        ; Set the cell of the table to null.
.finish:
        pop     esi edx ecx ebx eax
        return
endp


;**************************************************************************
; Duplicates given string, and returns a handle to new one
;**************************************************************************
proc StrDup         ; proc StrDup [hBaseStr]
begin
        mov     eax,[esp+4]             ; mov eax,[esp+4]
        or      eax,eax
        jz      .exit
        stdcall StrNew
        stdcall StrCopy, eax,dword[esp+4]    ; stdcall StrCopy, [hBaseStr]
.exit:  ret     4
endp

;**************************************************************************
; Returns the length of the string.
; Arguments:
;  hString - handle or pointer to the string (static or dynamic)
;**************************************************************************
proc StrLen, .hString    ; proc StrLen [hString]
        begin
        push    ebx
        stdcall StrPtr, [.hString]
        mov     ebx,eax
  .scan:
        cmp     byte[eax],0
        lea     eax,[eax+1]
        jne     .scan
        sub     eax,ebx
        dec     eax         ; return value in eax
        pop     ebx
        return
endp

;***************************************************************************
; If the hString is larger than length - do nothing
; If the hString is smaller than length -> set the length of string to length
; returns pointer to the new (old) string
;
; Arguments:
;   hString - string handle. /not pointer!/
;   length - new string length.
; Returns: pointer to the string.
;***************************************************************************
proc StrSetLength, .hString, .length   ; proc StrSetLength [hString], [length]
        begin
        push    ebx ecx edx esi edi     ; esp=esp-20

        mov     ebx, [.length]          ; mov ecx,[length]
        lea     ebx, [ebx+4]            ; the string have to be at least 1 dword bigger than the length specified.

        mov     eax,[.hString]          ; mov eax,[hString]
        test    eax,$ffff0000   ; if eax is pointer then error
        jnz     .error
        cmp     eax,[StrTable.count]    ; invalid handle.
        jge     .error

        mov     edi,[StrTable.ptr]
        lea     edi,[4*eax+edi]         ; points to the address of table pointer of destination string
        mov     esi,[edi]
        test    esi,esi                 ; Error string not defined
        jz      .error                  ;

        invoke  HeapSize, [StrTable.heap], 0, esi
        cmp     eax,-1
        je      .error
        cmp     eax,ebx
        jl      .resize
        mov     eax,esi
        jmp     .finish

.resize:
        invoke  HeapReAlloc, [StrTable.heap], HEAP_GENERATE_EXCEPTIONS or HEAP_ZERO_MEMORY, esi, ebx
        mov     [edi], eax
        jmp     .finish

.error:
        xor     eax,eax

.finish:
        pop     edi esi edx ecx ebx
        return
endp


;***************************************************************************************
;  Copyes source to destination string.
;  Arguments:
;     source - destination string (handle only)
;     dest -  source string (handle or pointer)
;***************************************************************************************
proc StrCopy, .dest, .source
        begin
        push    esi edi eax ecx
        mov     edi,[.dest]
        test    edi,$ffff0000   ; if edi is pointer go to finish.
        jnz     .finish
        mov     esi,[.source]
        test    esi,esi
        jz      .finish
        stdcall StrPtr, esi
        mov     esi,eax
        test    esi, esi
        jz      .finish
        stdcall StrLen, eax
        inc     eax
        mov     ecx,eax
        stdcall StrSetLength, edi,eax
        test    eax,eax
        jz      .finish
        stdcall StrPtr, edi
        mov     edi,eax
        cld
        rep movsb               ; copy strings
.finish:
        pop     ecx eax edi esi
        return
endp

;***************************************************************************************
; Compares two strings - case sensitive.
; Returns CARRY = 1 if the strings are equal.
; Returns CARRY = 0 if the strings are different.
;***************************************************************************************
proc StrCompCase, .str1, .str2
begin
        push    eax esi edi

        cmp     [.str1], 0
        je      .noteq
        cmp     [.str2], 0
        je      .noteq

        stdcall StrPtr, [.str1]
        mov     esi,eax
        stdcall StrPtr, [.str2]
        mov     edi,eax
.loop:
        mov     al, [esi]
        lea     esi, [esi+1]
        cmp     al, [edi]
        lea     edi, [edi+1]
        jne     .noteq

        test    al, al
        jnz     .loop

        stc
        pop     edi esi eax
        return

.noteq:
        clc
        pop     edi esi eax
        return
endp


;***************************************************************************************
; Compares two strings - case NOT sensitive.
; Returns CARRY = 1 if the strings are equal.
; Returns CARRY = 0 if the strings are different.
;***************************************************************************************
proc StrCompNoCase, .str1, .str2
begin
        push    eax esi edi
        stdcall StrPtr, [.str1]
        mov     esi,eax
        stdcall StrPtr, [.str2]
        mov     edi,eax

.cmploop:
        mov     al, [esi]
        lea     esi, [esi+1]
        mov     ah, [edi]
        lea     edi, [edi+1]

        test    al,al
        jz      .eos
        test    ah,ah
        jz      .noteq

        or      eax, $2020
        cmp     al, ah
        je      .cmploop

.noteq:
        clc
        pop     edi esi eax
        return

.eos:
        test    ah,ah
        jnz     .noteq

        stc
        pop     edi esi eax
        return
endp



;*******************************************************************************
; Get the text of the [Control] using WM_GETTEXT and put it to the string with
; handle (only) in [string].
;
; if [string] = NULL creates new string and returns the handle.
; if [string] <> NULL just copyes the text.
;*******************************************************************************
proc GetControlText, .Control, .string
.res dd ?
.len dd ?
begin
        push    ebx edi
        mov     eax,[.string]
        test    eax,eax
        jnz     @f
        stdcall StrNew
@@:
        mov     [.res],eax
        invoke  SendMessage, [.Control], WM_GETTEXTLENGTH, 0, 0
        add     eax, 16
        mov     [.len], eax
        stdcall StrSetLength, [.res], eax
        test    eax,eax
        jz      .error
        invoke  SendMessage, [.Control], WM_GETTEXT, [.len], eax
        mov     eax,[.res]
.error:
        pop     edi ebx
        return
endp

;*******************************************************************************
; Sets the text in control using WM_SETTEXT from string with handle or pointer
; in [string].
;*******************************************************************************
proc SetControlText, .Control, .string
begin
        push    eax ecx edx
        stdcall StrPtr, [.string]
        invoke  SendMessage, [.Control], WM_SETTEXT, 0, eax
        pop     edx ecx eax
        return
endp

;**********************************************************
;  Creates string and assigns it to variable. If variable
;  already contains string handle, the old string will be
;  deleted.
;  Arguments:
;    [ptrHString] - variable containing string handle.
;    ptrSource - pointer to the source for string.
;**********************************************************
; Bug fix 26.09.2003 JohnFound
proc SetString, .ptrHString, .ptrSource
begin
        push    eax esi
        mov     esi, [.ptrHString]

        cmp     dword [esi], 0
        je      @f
        stdcall StrDel, [esi]
@@:
        stdcall StrNew
        mov     [esi], eax
        stdcall StrCopy, eax, [.ptrSource]
        pop     esi eax
        return
endp

;**********************************************************************************
; StrCat appends one string to another
; Arguments:
;   dest - destination string (handle only)
;   source - source string
;**********************************************************************************
proc StrCat, .dest, .source
begin
        push    eax ebx ecx

        stdcall StrLen, [.dest]
        mov     ebx,eax                 ; store dest length in ebx

        stdcall StrLen, [.source]
        add     eax, ebx
        inc     eax                     ; new dest length
        stdcall StrSetLength, [.dest], eax
        add     ebx, eax                ; calculate end of old dest in ebx
        stdcall StrPtr, [.source]
.copy:
        mov     cl,[eax]
        inc     eax
        mov     [ebx],cl
        inc     ebx
        or      cl,cl
        jnz     .copy
        pop     ecx ebx eax
        return
endp


;**********************************************************************************
; StrCharPos returns a pointer to the first occurence of a given char
;   in specified string
; Arguments:
;   Char - char to look for
;   hString -  string to search
; Returns: a pointer to the char in source, or NULL if char doesn't occur
;   in given string
;**********************************************************************************
proc StrCharPos, .hPattern, .char
        begin
        push    esi
        stdcall StrPtr,[.hPattern]
        mov     esi,eax
        mov     eax,[.char]
        xchg    al,ah
     .search:
        mov     al,[esi]
        inc     esi
        or      al,al
        je      .not_found
        cmp     al,ah
        jne     .search
        mov     eax,esi
        dec     eax
        pop     esi
        return
     .not_found:
        xor     eax,eax
        pop     esi
        return
endp


;**********************************************************************************
; StrPos returns a pointer to the first occurence of a pattern string
;   in another string
; Arguments:
;   hPattern - 'pattern' string
;   hString -  string to search
; Returns: a pointer to the pattern string in source , or NULL if pattern string
; doesn't occur in the string to search
;**********************************************************************************
proc StrPos         ; proc StrPos [hString], [hPattern]
begin
        push    ebx ecx edx esi edi     ; esp = esp -20
        mov     esi,[esp+20+8]          ; mov esi,[hPattern]
        mov     edi,[esp+20+4]          ; mov edi,[hString]
        stdcall StrLen, edi
        mov     ebx,eax                 ; now ebx holds lenght of the string to search
        stdcall StrLen, esi
        mov     edx,eax                 ; now edx holds length of the pattern string
        stdcall StrPtr, esi
        mov     esi,eax                 ; put pointer to the pattern str in esi
        stdcall StrPtr,edi
        mov     edi,eax                 ; put pointer to the search str in edi
        lodsb                           ; load first character of the pattern
        mov     ecx,ebx                 ;
        mov     ebx,edx                 ; put str_len(pattern)-1 in ebx
        dec     ebx                     ;
  .search:
        repne   scasb
        jne     .not_found
        cmp     ecx,ebx
        jb      .not_found
        push    edi esi ecx
        or      ebx,ebx                 ; ebx==0 means that we were searching for one
        jz      .got_it                 ; character. We found it, so we stop.
        mov     ecx,ebx
        repe    cmpsb
        jne     .not_match
  .got_it:
        pop     ecx esi edi
        dec     edi
        mov     eax,edi
  .ret:
        pop     edi esi edx ecx ebx
        ret     8
  .not_match:
        pop     ecx esi edi
        jmp     .search
  .not_found:
        xor     eax,eax
        jmp     .ret
endp

;**********************************************************************************
; StrInsert inserts one string into another at specified pos
; Arguments:
;   dest - destination where the source will be inserted (handle only)
;   source -  string to insert
;**********************************************************************************
proc StrInsert      ; proc StrInsert [dest], [source], [pos]
        begin
        push    eax ebx ecx esi edi     ; esp = esp-20
        stdcall StrLen, dword[esp+20+4] ; stdcall StrLen,[dest]
        cmp     eax,dword[esp+20+12]    ; cmp eax,[pos]
        jb      .ret                    ; don't insert a string if pos>StrLen(dest)
        inc     eax
        mov     ecx,eax
        stdcall StrNew                  ; create temporary string...
        mov     ebx,eax                 ; ... and store its handle in ebx
        stdcall StrSetLength, ebx,ecx
        stdcall StrPtr, dword[esp+20+4] ; stdcall StrPtr,[dest]
        mov     esi,eax
        stdcall StrPtr, ebx
        mov     edi,eax
        mov     ecx,dword[esp+20+12]    ; mov ecx,[pos]
        jz      @f
        rep     movsb
  @@:   stdcall StrCat, ebx,dword[esp+20+8]     ; stdcall StrCat, ebx,[source]
        stdcall StrCat, ebx,esi
        mov     eax,dword[esp+24]
        stdcall StrCopy, eax,ebx
        stdcall StrDel, ebx
  .ret:
        pop     edi esi ecx ebx eax
        ret     12
endp

;**********************************************************************************
; Converts strings to Lower Case
; First parameter = String to Convert to lower case
; corrupts eax
;**********************************************************************************
proc StrLCase               ; proc StrLCase [hString]
        begin
        push    edi
        stdcall StrPtr, [esp+4+1*4]
        xchg    edi, eax
._lowercaseloop:
        mov     al, [edi]
        cmp     al, 'A'
        jc      @F
        cmp     al, 'Z'
        ja      @F
        or      byte[edi], 20h
@@:
        cmp     byte[edi],0
        lea     edi, [edi+1]
        jnz     ._lowercaseloop
        pop     edi
        retn    4
endp


;**********************************************************************************
; Converts strings to Upper Case
; First parameter = String to Convert to upper case
; corrupts eax
;**********************************************************************************
proc StrUCase       ; proc StrUCase [hString]
        begin
        push    edi
        stdcall StrPtr, [esp+4+1*4]
        xchg    edi, eax
._uppercaseloop:
        mov     al, [edi]
        cmp     al, 'a'
        jc      @F
        cmp     al, 'z'
        ja      @F
        sub     byte[edi], 20h
@@:
        cmp     byte[edi], 0
        lea     edi, [edi+1]
        jnz     ._uppercaseloop
        pop     edi
        retn    4
endp

;**********************************************************************************
; String copy mmx version for long strings does by copying qword at a time
; First parameter = String destination
; Second parameter = String source
;**********************************************************************************
proc StrCopyMMX     ; proc StrCopyMMX [str1], [str2]
        begin
        push    eax
        push    ebx
        push    ecx
        push    edx
        stdcall StrPtr, [esp+4+4*4]
        xchg    eax, edx
        stdcall StrPtr, [esp+8+4*4]
        mov     ecx,eax
        stdcall StrLen,eax
        stdcall StrSetLength, [esp+4+4*4+4], eax
        mov     eax,ecx
        xor     ecx,ecx
        pxor    MM7, MM7
.MMX_loop:
        movq    MM0, [eax+ecx]
        movq    MM1, MM0
        pcmpeqb MM0, MM7
        packsswb MM0, MM0
        movd    ebx, MM0
        test    ebx, ebx
        jnz     .normal_copy
        movq    [edx+ecx], MM1
        add     ecx, 8
        jmp     .MMX_loop
.normal_copy:
        mov     bl, [eax+ecx]
        mov     [edx+ecx], bl
        inc     ecx
        test    bl, bl
        jnz     .normal_copy
        pop     edx
        pop     ecx
        pop     ebx
        pop     eax
        retn    8
endp

;**********************************************************************************
; StrExtract copies the part of [str] from [index] with lenght in [len]
; Returns handle to new created string.
;**********************************************************************************
proc StrExtract, .string, .index, .len
begin
        push    ebx ecx esi edi
        stdcall StrLen,[.string]
        cmp     eax,[.index]
        jbe     .error
        stdcall StrNew
        mov     ebx,eax
        mov     ecx,[.len]
        stdcall StrSetLength, eax,ecx   ; stdcall StrSetLength, eax,[len]
        stdcall StrPtr, eax
        mov     edi,eax
        stdcall StrPtr, [.string]
        add     eax,[.index]
        mov     esi,eax
    @@: mov     al,[esi]
        mov     [edi],al
        inc     esi
        inc     edi
        or      al,al
        jz      .copied
        dec     ecx
        jnz     @b
        xor     al,al
        mov     [edi],al
  .copied:
        mov     eax,ebx
        pop     edi esi ecx ebx
        return
  .error:
        xor     eax,eax
        pop     edi esi ecx ebx
        return
endp

;**********************************************************************************
; _NumToStr converts the number in eax to the string in any radix approx. [2..26]
; Arguments:
;   [edi] - pointer to the string buffer
;   ecx - radix
;   eax - number to convert.
; There is no parameter check, so be careful.
; returns: edi points to the end of a converted number
;**********************************************************************************
proc _NumToStr
begin
    test  eax,eax
    jns   _NumToStrU
    neg   eax
    mov   byte [edi],"-"
    inc   edi
endp

proc _NumToStrU
begin
    cmp   eax,ecx
    jb    .lessA
    xor   edx,edx
    div   ecx
    push  edx
    call  _NumToStrU
    pop   eax
.lessA:
    cmp   al, 10
    sbb   al, 69h
    das
    stosb
    return
endp

;*****************************************************
; NumToStrF:
;   Converts signed integer value to string.
; NumToStrUF:
;   Converts unsigned integer value to string.
;
; edi - pointer to string buffer
; eax - Number to convert
; ecx - radix from 2 to $ff
; esi - length of the number in chars
;
; returns: edi - pointer to the end of converted num
;
; Note: Don't use 1 as radix.
;*****************************************************
proc NumToStrF
begin
        test    eax,eax
        jns     NumToStrUF
        neg     eax
        mov     byte [edi],'-'
        push    esi
        dec     esi
        add     edi,esi
        push    edi
        jmp     NumToStrUF.loopc
endp

proc NumToStrUF
        begin
        push    esi
        add     edi, esi
        push    edi
        dec     edi
.loopc:
        xor     edx,edx
        div     ecx
        xchg    al,dl
        cmp     al,$0a
        sbb     al,$69
        das
        mov     [edi],al
        dec     edi
        xchg    al,dl
        dec     esi
        jnz     .loopc
        pop     edi
        pop     esi
        return
endp


;***********************************************************
; NumToStr - converts number to any radix.
; num - number to convert
; str - handle of the string. If NULL - creates new string.
; index - Offset in string where to put converted number.
; flags:
;   byte 0 - number of digits if ntsFixedWidth is set.
;   byte 1 - contains radix for the convertion.
;   byte 2,3 - flags.
; Returns:
;   eax - handle of the string (new one or passed in [str])
;   edx - pointer to the string.
;***********************************************************
proc NumToStr, .num, .strng, .index, .flags
.max_len dd ?
.len_tab rb 20      ; table that holds maximum number of digits in given system
        begin
        push    ebx ecx edx esi edi

        mov     [.len_tab+2],32+2       ; binary number - max. 32 digits (+2 bytes for '-' character and NULL terminator)
        mov     [.len_tab+4],16+2       ; quad number - max. 16 digits
        mov     [.len_tab+8],11+2       ; octal number - max. 11 digits
        mov     [.len_tab+10],9+2       ; decimal number - max. 9 digits
        mov     [.len_tab+16],8+2       ; hexadecimal number - max. 8 digits
        movzx   ebx,byte [.flags+1]     ; load radix into ebx
        movzx   eax,byte[.len_tab+ebx]
        mov     [.max_len],eax          ; store max. number of digits
        mov     eax,[.strng]
        or      eax,eax
        jnz     .string_exists
        stdcall StrNew
        mov     [.strng],eax
  .string_exists:
        test    eax,0xffff0000
        jnz     @f                      ; don't resize if [str] isn't a handle
        mov     ebx,eax
        mov     eax,[.max_len]
        add     eax,[.index]
        mov     edx,eax
        stdcall StrLen,ebx
        cmp     eax,edx
        ja      @f                      ; don't resize string if it has enough place for converted number

        stdcall StrSetLength,ebx, edx

  @@:   ; determine which conversion func to use
        mov     eax,[.flags]
        mov     edx,eax
        and     eax,ntsFixedWidth
        jnz     .fixed_width
        mov     eax,edx
        and     eax,ntsUnsigned
        jnz     .unsigned
        mov     ebx,_NumToStr
        jmp     .got_func
  .unsigned:
        mov     ebx,_NumToStrU
        jmp     .got_func

  .fixed_width:
        movzx   esi, byte [.flags]         ; load fixed width into esi
        mov     eax, edx
        and     eax, ntsUnsigned
        jnz     .fixed_unsigned
        mov     ebx,NumToStrF
        jmp     .got_func
  .fixed_unsigned:
        mov     ebx,NumToStrUF
  .got_func:
        stdcall StrPtr, [.strng]
        add     eax,[.index]
        mov     edi,eax
        movzx   ecx,byte [.flags+1]       ; load radix into ecx
        mov     eax, [.num]
        call    ebx                     ; call low-level convertion routine
        mov     eax, [.flags]
        and     eax, ntsZeroTerminated
        jz      .ret
        mov     byte [edi], 0

  .ret:
        pop     edi esi edx ecx ebx
        mov     eax, [.strng]
        return
endp


;-------------------------------------------------
; function StrHash
;   Computes 32 bit hash value from the string.
;   The function is compatible with FASM hash
;   function if OrMask = 0.
;
; Arguments:
;   hString - handle/pointer of the string.
;   OrMask  - every byte from the string will be ORed
;             with this value (byte)
; Return:
;   eax - 32bit hash value.
;-------------------------------------------------
proc StrHashOld, .hString, .OrMask
begin
        push    esi ebx ecx

        stdcall StrPtr, [.hString]
        mov     esi, eax

        xor     ebx, ebx
        xor     eax, eax
.hashloop:
        rol     eax, 12
        mov     ecx, eax
        shr     eax, 8
        and     ecx, 1111b
        or      eax, ecx
        movzx   ecx, byte [esi+ebx]
        jecxz   .endloop
        or      cl, byte [.OrMask]
        add     eax, ecx
        inc     ebx
        jmp     .hashloop

.endloop:
        and     eax,0FFFFFFh
        shl     ebx,24
        or      eax,ebx
        pop     ecx ebx esi
        return
endp


proc StrHash, .hString, .OrMask
begin
        push    esi edi ebx ecx edx

        stdcall StrPtr, [.hString]
        mov     esi, eax

        xor     ebx, ebx
        mov     eax,2166136261          ; FNV offset basis
        xor     ecx, ecx
        mov     edi, 16777619                ; FNV prime
.hashloop:
        mov     cl, [esi+ebx]
        jecxz   .endstring
        inc     bl
        or      cl, byte [.OrMask]
        xor     al,cl                   ; FNV-1a hashing
        mul     edi
        jmp     .hashloop

.endstring:
        mov     edx,eax
        and     eax,0FFFFFFh            ; xor-fold to 24 bits
        shr     edx,24
        xor     eax,edx
        shl     ebx,24                  ; the length of the string
        or      eax,ebx                 ; store length in high 8 bits
        pop     edx ecx ebx edi esi
        return
endp



;-------------------------------------------------------
; function StrToNum
;   Converts specified string into a number
;
; Arguments:
;   hString - handle/pointer of the string containing
;     number to convert. It doesn't have to be ended by
;     NULL, any other character will stop conversion.
;     Number to convert must be decimal.
;
; Return:
;   eax - converted number
;
; Note: in case of failture (first char of given pointer
;   isn't a number) function returns -1.
;-------------------------------------------------------
proc StrToNum, .hString
        begin
        push    ebx edx esi
        xor     ebx,ebx         ; ebx will store our number
        stdcall StrPtr, [.hString]
        mov     esi,eax
        xor     eax,eax
        mov     al,[esi]
        cmp     al,'0'
        jb      .error
        cmp     al,'9'
        jbe     .digit
        jmp     .error
     .digit:
        sub     al,'0'
        add     ebx,eax
        inc     esi
        mov     al,[esi]
        cmp     al,'0'
        jb      .finish
        cmp     al,'9'
        ja      .finish
        mov     edx,ebx         ; multiply ebx by 10
        shl     ebx,3
        add     ebx,edx
        add     ebx,edx
        jmp     .digit
     .finish:
        mov     eax,ebx
        pop     esi edx ebx
        return

     .error:
        xor     eax,eax
        dec     eax
        pop     esi edx ebx
        return
endp

;-------------------------------------------------------
; function StrCharCat
;   Addes specified char to the end of a string
;
; Arguments:
;   hString - string to append
;   char - char to add
;-------------------------------------------------------
proc StrCharCat, .hString, .char
begin
        push    eax ebx ecx
        mov     ebx, [.hString]
        stdcall StrLen, ebx
        mov     ecx, eax
        inc     eax
        stdcall StrSetLength, ebx, eax
;        stdcall StrPtr, ebx                    ; StrSetLength returns a pointer to the string
        add     ecx, eax
        mov     eax, [.char]
        mov     [ecx], al
        inc     ecx
        mov     byte [ecx], 0
        pop     ecx ebx eax
        return
endp

;------------------------------------------------------------
; function StrInsertChar
;   Inserts specified char into given position ot the string
;
; Arguments:
;   hString - string to append
;   char    - char to add
;   pos     - position where to add the char
;-------------------------------------------------------------
proc StrInsertChar, .hString, .char, .pos
        begin
        push    eax ebx ecx
        mov     ebx, [.hString]
        stdcall StrLen, ebx
        cmp     eax, [.pos]
        jb      .finish
        je      .append
        mov     ecx,eax
        inc     eax
        stdcall StrSetLength, ebx, eax
        stdcall StrPtr, ebx
        add     ecx, eax
        mov     ebx, eax
        add     ebx, [.pos]
        mov     byte [ecx+1], 0     ; add NULL-terminator in the end of our string
  .shift:
        mov     al, [ecx-1]
        mov     [ecx], al
        dec     ecx
        cmp     ecx, ebx
        jne     .shift
        mov     eax, [.char]
        mov     [ebx], al
  .finish:
        pop     ecx ebx eax
        return
  .append:
        stdcall StrCharCat, ebx, [.char]
        jmp     .finish
endp





proc StrURLEncode, .hstr
.res dd ?
begin
        push    ebx ecx edx esi edi
        stdcall StrPtr, [.hstr]
        mov     esi, eax

        stdcall StrLen, esi
        mov     ecx, eax
        lea     edx, [2*eax+eax]        ; the encoded string can be max 3x long as original string.

        stdcall StrNew
        mov     [.res], eax
        jecxz   .finish

        stdcall StrSetLength, eax, edx
        mov     edi, eax
        xor     edx, edx
        xor     ebx, ebx

.encode:
        lodsb
        cmp     al, $80
        jae     .store          ; it is a hack, but I hope save enough.

        mov     dl, al
        mov     bl, al
        shr     edx, 5
        and     ebx, $1f
        bt      dword [URLCharTable+4*edx], ebx
        jnc     .store

        mov     ah, al
        mov     al, '%'
        stosb
        mov     al, ah
        shr     al, 4
        cmp     al, $0a
        sbb     al, $69
        das
        stosb
        mov     al, ah
        and     al, $0f
        cmp     al, $0a
        sbb     al, $69
        das

.store:
        stosb
        loop    .encode
.end:
        xor     al, al
        stosb
.finish:
        mov     eax, [.res]
        pop     edi esi edx ecx ebx
        return
endp

; Contains 1 where the character must be % encoded and 0 where it is save to pass it directly
URLCharTable db 11111111b       ;
             db 11111111b       ;
             db 11111111b       ;
             db 11111111b       ; 0..31 -control chars | encoded
             db 11111111b       ; $27 - $20: '&%$#"!   | encoded
             db 11111111b       ; $2f - $28: /.-,+*)(  | encoded
             db 00000000b       ; $37 - $30: 76543210  | not encoded
             db 11111100b       ; $3f - $38: ?>=<;:98  | partially
             db 00000001b       ; $47 - $40: GFEDCBA@  | partially
             db 00000000b       ; $4f - $48: ONMLKJIH  | not encoded
             db 00000000b       ; $57 - $50: WVUTSRQP  | not encoded
             db 11111000b       ; $5f - $58: _^]\[ZYX  | partially
             db 00000001b       ; $67 - $60: gfedcba`  | partially
             db 00000000b       ; $6f - $68: onmlkjih  | not encoded
             db 00000000b       ; $77 - $70: wvutsrqp  | not encoded
             db 11111000b       ; $7f - $78:  ~}|{zyx  | partially
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/drafts/strlibnew.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; ____________________________________________________________________
;|                                                                    |
;| This file is part of the project:                                  |
;|                                                                    |
;| ..::FreshLib::.. - portable, assembler library and GUI toolkit.    |
;|____________________________________________________________________|
;|                                                                    |
;|                          This file                                 |
;|                          _________                                 |
;|   Author:                                                          |
;|                                                                    |
;|   Title: StrLib.asm - OS independent string manipulation library.  |
;|                                                                    |
;|   OS:                                                              |
;|                                                                    |
;|   Notes and changes:                                               |
;|     Uses memory.asm library for memory functions.                  |
;|                                                                    |
;|                                                                    |
;|____________________________________________________________________|


STR_MINSTRLEN = 16      ; 16 bytes minimum string length

; NumToStr flags
ntsSigned = $00000
ntsUnsigned = $10000
ntsZeroTerminated = $20000
ntsFixedWidth     = $40000

ntsBin  = $0200
ntsQuad = $0400
ntsOct  = $0800
ntsDec  = $0a00
ntsHex  = $1000

struc TString {
  .capacity dd ?        ; length of allocated buffer.
  .len      dd ?        ; length of the string.
  label .data byte
}
virtual at -(sizeof.TString)
  TString TString
  sizeof.TString = $-TString
end virtual


struc string [value] {
common
local ..len, ..capacity, ..pad1, ..pad2
      virtual
        align 4
        ..pad1 = $ - $$
      end virtual
      db  ..pad1 dup 0

      dd  ..capacity
      dd  ..len
label . byte
forward
        db  value
common
  ..len = $ - .
      virtual
        align 4
        ..pad2 = $ - $$
      end virtual
      db  ..pad2 dup 0
  ..capacity = $ - .
      dd  0
}


; String format:
;   Let esi points to StrLib string. Then:
;   dword [esi-8] contains allocated memory size for the string.
;   dword [esi-4] contains length of the string in bytes.
;   [esi] .. [esi+length] contains the string itself.
;   at the end of the string, always have at least one dword zero, so it is safe to
;   scan the string by dwords.


; < Library functions >


;______________________________________________________________________________________
;
;  Creates new empty string and returns pointer to it.
;  Arguments:
;    NONE
;  RETURNS:
;    CF=0 -> no error; ebx = pointer to the new created string.
;    CF=1 -> memory allocation error. ebx=0
;______________________________________________________________________________________
proc StrNew
begin
        stdcall GetMem, STR_MINSTRLEN+sizeof.TString+4
        jc      .finish

        lea     eax, [eax+sizeof.TString]
        mov     [eax+TString.capacity], STR_MINSTRLEN

.finish:
        return
endp


;__________________________________________________________________________
;
; Delete string.
; Arguments:
;   .pString - string created with StrNew, or other StrLib procedure.
; Returns:
;   Nothing
;__________________________________________________________________________
proc StrDel, .pString
begin
        push    [.pString]
        sub     dword [esp], sizeof.TString
        call    FreeMem
        return
endp



;__________________________________________________________________________
;
; Duplicates given string, and returns a pointer to new one
; Arguments:
;   .pString - pointer to the string, allocated with StrLib
; Returns:
;   CF=0; eax - pointer to the duplicated string.
;   CF=1; eax - NULL
;__________________________________________________________________________
proc StrDup, .pString
begin
        stdcall StrNew
        jc      .exit

        stdcall StrCopy, eax, [.pString]
        jnc     .exit

        stdcall StrDel, eax
        xor     eax, eax
        stc
.exit:
        return
endp



proc StrDupAsciiZ, .pAsciiZ
begin
        stdcall StrNew
        jc      .exit

        stdcall StrCopyAsciiZ, eax, [.pAsciiZ]
        jnc     .exit

        stdcall StrDel, eax
        xor     eax, eax
        stc
.exit:
        return
endp



;__________________________________________________________________________
;
; proc StrSearchLen, .pString
; Searches to the end of ASCIIZ string and returns the length of the string.
;
; Arguments:
;  pString - pointer to the string.
; Returns:
;  ecx - length of the string in bytes.
;__________________________________________________________________________
proc StrSearchLen, .pString
begin
        mov     ecx, [.pString]
.scan:
        cmp     byte [ecx], 0
        lea     ecx, [ecx+1]
        jne     .scan

        stc
        sbb     ecx, [.pString]
        return
endp


;__________________________________________________________________________
; proc StrSearchLenFast, .pString
; The same as StrSearchLen, but works on dwords and is much faster.
; The string must ends with at least one aligned dword of NULL.
; This is the case with every string from StrLib, but not always with
; system provided strings.
;
; Arguments:
;  pString - pointer to the string.
; Returns:
;  ecx - length of the string in bytes.
;__________________________________________________________________________
proc StrSearchLenFast, .pString
begin
        mov     ecx, [.pString]
.scan:
        cmp     dword [ecx], 0
        lea     ecx, [ecx+4]
        jne     .scan

        lea     ecx, [ecx-4]

; so search back
.byteloop:
        lea     ecx, [ecx-1]
        cmp     byte [ecx], 0
        je      .byteloop

        lea     ecx, [ecx+1]
        sub     ecx, [.pString]
        return
endp





;___________________________________________________________________________
;
; Ensures that the string can take [.capacity] bytes.
; If the function resize the string, the new size is multiple of 4.
;
; Arguments:
;   .pString - string pointer.
;   .capacity - desired string capacity.
; Returns:
;   eax - pointer to the string (can be different than passed in .pString)
;   CF=1 if error allocation. In this case eax still contains pointer, but
;   the capacity is not changed.
;___________________________________________________________________________
proc StrSetCapacity, .pString, .capacity
begin
        push    ecx

        mov     ecx, [.capacity]

        add     ecx, 3 + sizeof.TString + 4
        and     cl, $fc
        cmp     ecx, STR_MINSTRLEN + sizeof.TString + 4
        jae     @f
        mov     ecx, STR_MINSTRLEN + sizeof.TString + 4
@@:
        sub     [.pString], sizeof.TString

        stdcall ResizeMem, [.pString], ecx
        jc      .finish

.sizeok:
        lea     ecx, [ecx-(sizeof.TString+4)]
        mov     [eax], ecx

.finish:
        lea     eax, [eax+sizeof.TString]
        pop     ecx
        return
endp




;_______________________________________________________________________________________
;  Copies source to destination string.
;  Arguments:
;     source - source string. for StrCopyAsciiZ - can be any zero terminated string.
;              for StrCopy, must be strlib string.
;     dest -  destination string. Always strlib string.
;  Returns:
;     eax - pointer to destination string.
;     CF=1 -> error with memory allocation. source is not copied and destination is
;             not changed.
;_______________________________________________________________________________________
proc StrCopyAsciiZ, .dest, .source
begin
        push    ecx esi edi

        mov     esi, [.source]
        stdcall StrSearchLen, esi
        jmp     StrCopy.docopy
virtual
  call StrCopy
end virtual
endp



proc StrCopy, .dest, .source
begin
        push    ecx esi edi

        mov     esi, [.source]
        mov     ecx, [esi+TString.len]

.docopy:
        stdcall StrSetCapacity, [.dest], ecx
        jc      .finish

        mov     edi, eax
        mov     [eax+TString.len], ecx
        push    ecx
        shr     ecx, 2
        rep movsd
        pop     ecx
        and     ecx, 3
        rep movsb

        mov     dword [edi], ecx
        add     edi, 3
        and     edi, $fffffffc
        mov     dword [edi], ecx
        clc

.finish:
        pop     edi esi ecx
        return
endp




proc StrCopyPart, .dest, .source, .pos
begin
        push    ecx esi edi

        mov     eax, [.dest]
        mov     esi, [.source]
        mov     ecx, [esi+TString.len]
        cmp     [.pos], ecx
        jae     .finish

        sub     ecx, [.pos]
        add     esi, [.pos]

        stdcall StrSetCapacity, [.dest], ecx
        jc      .finish

        mov     edi, eax
        mov     [eax+TString.len], ecx

        push    ecx
        shr     ecx, 2
        rep movsd
        pop     ecx
        and     ecx, 3
        rep movsb

        mov     dword [edi], ecx
        add     edi, 3
        and     edi, $fffffffc
        mov     dword [edi], ecx
        clc

.finish:
        pop     edi esi ecx
        return
endp


;__________________________________________________________________________________
; Splits the string on two strings, at position [.pos]
; Arguments:
;   .pString - pointer to string to be splitted.
;   .pos     - position where to split the string.
; Returns:
;   eax - pointer to the new created string with second part of the string.
;         the original string does not reallocate memory and it's capacity
;         and the pointer will remains the same.
;__________________________________________________________________________________

proc StrSplit, .pString, .pos
begin
        push    ecx

        stdcall StrNew

        mov     ecx, [.pString]
        mov     ecx, [ecx+TString.len]
        cmp     [.pos], ecx
        jae     .ready

        stdcall StrCopyPart, eax, [.pString], [.pos]

        mov     ecx, [.pString]
        push    [.pos]
        pop     [ecx+TString.len]  ; new length of the string.

        add     ecx, [ecx+TString.len]

        mov     dword [ecx], 0
        add     ecx, 3
        and     cl, $fc
        mov     dword [ecx], 0

.ready:
        pop     ecx
        return
endp








;_______________________________________________________________________________________
; Compares two strings - case sensitive.
; Returns CARRY = 1 if the strings are equal.
; Returns CARRY = 0 if the strings are different.
;_______________________________________________________________________________________
proc StrCompCase, .str1, .str2
begin
        push    eax ecx esi edi

        mov     esi, [.str1]
        mov     edi, [.str2]

        cmp     esi, 0
        je      .noteq

        cmp     edi, 0
        je      .noteq

        mov     ecx, [esi+TString.len]
        cmp     ecx, [edi+TString.len]
        jne     .noteq

        repe cmpsb
        jne     .noteq

        stc
        pop     edi esi ecx eax
        return

.noteq:
        clc
        pop     edi esi ecx eax
        return
endp


;_______________________________________________________________________________________
; Compares two strings - case NOT sensitive.
; Returns CARRY = 1 if the strings are equal.
; Returns CARRY = 0 if the strings are different.
;_______________________________________________________________________________________
proc StrCompNoCase, .str1, .str2
begin
        push    eax esi edi
        stdcall StrPtr, [.str1]
        mov     esi,eax
        stdcall StrPtr, [.str2]
        mov     edi,eax

.cmploop:
        mov     al, [esi]
        lea     esi, [esi+1]
        mov     ah, [edi]
        lea     edi, [edi+1]

        test    al,al
        jz      .eos
        test    ah,ah
        jz      .noteq

        or      eax, $2020
        cmp     al, ah
        je      .cmploop

.noteq:
        clc
        pop     edi esi eax
        return

.eos:
        test    ah,ah
        jnz     .noteq

        stc
        pop     edi esi eax
        return
endp





;__________________________________________________________________________________
; StrCat appends one string to another
; Arguments:
;   dest - destination string (handle only)
;   source - source string
; Returs:
;   eax - pointer to destination string.
;   CF - error flag.
;__________________________________________________________________________________
proc StrCat, .dest, .source
begin
        push    ecx esi edi

        mov     eax, [.dest]
        mov     esi, [.source]
        mov     edi, eax

        mov     ecx, [esi+TString.len]
        add     ecx, [edi+TString.len]
        cmp     ecx, [edi+TString.capacity]
        jbe     .sizeok

        stdcall StrSetCapacity, edi, ecx
        jc      .finish
        mov     edi, eax

.sizeok:
        xchg    [edi+TString.len], ecx
        add     edi, ecx

        mov     ecx, [esi+TString.len]
        push    ecx
        shr     ecx, 2

        rep movsd
        pop     ecx
        and     ecx, 3
        rep movsb

        mov     dword [edi], 0

        clc

.finish:
        pop     edi esi ecx
        return
endp


;__________________________________________________________________________________
; StrCharPos returns a pointer to the first occurence of a given char
;   in specified string
; Arguments:
;   Char - char to look for
;   hString -  string to search
; Returns:
;   ebx - offset of the char in the string.
;   CF=1 if the char is found.
;   CF=0 if the char is not found. EBX is not changed in this case.
;__________________________________________________________________________________
proc StrPosChar, .pString, .char
begin
        push    eax ecx ebx

        mov     ebx, [.pString]
        mov     ecx, [esi+TString.len]

        mov     al, byte [.char]

.search:
        cmp     [ebx], al
        je      .found
        lea     ebx, [ebx+1]
        dec     ecx
        jnz     .search

        clc
        pop     ebx ecx eax
        return

.found:
        sub     ebx, [.pString]
        lea     esp, [esp+4]
        stc
        pop     ecx eax
        return
endp


;__________________________________________________________________________________
; StrPos returns the offset of the first occurence of a pattern string
;   in another string
; Arguments:
;   hPattern - 'pattern' string
;   hString -  string to search
; Returns: a pointer to the pattern string in source , or NULL if pattern string
; doesn't occur in the string to search
;__________________________________________________________________________________
proc StrPos, .pString, .pPatern
begin
        push    esi edi eax ecx ebx

        mov     esi, [.pString]
        mov     edi, [.pPatern]

        mov     ecx, [esi+TString.len]
        mov     ebx, [edi+TString.len]
        test    ebx, ebx
        jz      .found

        cmp     ebx, ecx
        ja      .notfound       ; the parern is longer than string.

        sub     ecx, ebx
        dec     esi
        lea     ecx, [ecx+2]

.outer:
        dec     ecx
        jz      .notfound

        mov     ebx, [edi+TString.len]
        lea     esi, [esi+1]

.inner:
        mov     al, [esi+ebx-1]
        cmp     al, [edi+ebx-1]
        jne     .outer

        dec     ebx
        jnz     .inner

.found:
        sub     esi, [.pString]
        mov     [esp], esi
        stc
        pop     ebx ecx eax edi esi
        return

.notfound:
        clc
        pop     ebx ecx eax edi esi
        return
endp




;__________________________________________________________________________________
; StrInsert inserts one string into another at specified pos
; Arguments:
;   dest - destination where the source will be inserted.
;   source -  string to insert
;   pos    - where to insert.
; Returns:
;   eax - pointer to destination string.
;__________________________________________________________________________________
proc StrInsert, .dest, .source, .pos
begin
        stdcall StrSplit, [.dest], [.pos]
        push    eax eax
        stdcall StrCat, [.dest], [.source]
        stdcall StrCat, eax ; source from the stack.
        stdcall StrDel; from the stack.
        return
endp



;__________________________________________________________________________________
; Converts strings to Lower Case
; First parameter = String to Convert to lower case
; corrupts eax
;__________________________________________________________________________________
proc StrLCase, .ptrString
begin
        push    eax edi
        mov     edi, [.ptrString]
        mov     eax, [edi+TString.len]
        dec     edi
.loop:
        inc     edi
        dec     eax
        js      .endstring

        cmp     byte [edi], 'A'
        jb      .loop
        cmp     byte [edi], 'Z'
        ja      .loop

        or      byte [edi], 20h
        jmp     .loop

.endstring:
        pop     edi eax
        return
endp


;__________________________________________________________________________________
; Converts strings to Upper Case
; First parameter = String to Convert to upper case
; corrupts eax
;__________________________________________________________________________________
proc StrUCase, .ptrString
begin
        push    eax edi
        mov     edi, [.ptrString]
        mov     eax, [edi+TString.len]
        dec     edi
.loop:
        inc     edi
        dec     eax
        js      .endstring

        cmp     byte [edi], 'a'
        jb      .loop
        cmp     byte [edi], 'z'
        ja      .loop

        and     byte [edi], ~20h
        jmp     .loop

.endstring:
        pop     edi eax
        return
endp




;__________________________________________________________________________________
; _NumToStr converts the number in eax to the string in any radix approx. [2..26]
; Arguments:
;   edi - pointer to the string buffer
;   ecx - radix
;   eax - number to convert.
; There is no parameter check, so be careful.
; returns: edi points to the end of a converted number
;__________________________________________________________________________________
proc _NumToStr
begin
    test  eax, eax
    jns   _NumToStrU
    neg   eax
    mov   byte [edi],"-"
    inc   edi
endp


proc _NumToStrU
begin
    cmp   eax,ecx
    jb    .lessA

    xor   edx,edx
    div   ecx
    push  edx
    call  _NumToStrU
    pop   eax

.lessA:
    cmp   al, 10
    sbb   al, 69h
    das
    stosb
    return
endp

;_____________________________________________________
; NumToStrF:
;   Converts signed integer value to string.
; NumToStrUF:
;   Converts unsigned integer value to string.
;
; edi - pointer to string buffer
; eax - Number to convert
; ecx - radix from 2 to 26
; esi - length of the number in chars
;
; returns: edi - pointer to the end of converted num
;
; Note: Don't use 1 as radix.
;_____________________________________________________
proc NumToStrF
begin
        test    eax,eax
        jns     NumToStrUF
        neg     eax
        mov     byte [edi],'-'
        push    esi
        dec     esi
        add     edi,esi
        push    edi
        jmp     NumToStrUF.loopc
endp

proc NumToStrUF
        begin
        push    esi
        add     edi, esi
        push    edi
        dec     edi
.loopc:
        xor     edx,edx
        div     ecx
        xchg    al,dl
        cmp     al,$0a
        sbb     al,$69
        das
        mov     [edi],al
        dec     edi
        xchg    al,dl
        dec     esi
        jnz     .loopc
        pop     edi
        pop     esi
        return
endp


;___________________________________________________________
; NumToStr - converts number to any radix.
; num - number to convert
; str - handle of the string. If NULL - creates new string.
; index - Offset in string where to put converted number.
; flags:
;   byte 0 - number of digits if ntsFixedWidth is set.
;   byte 1 - contains radix for the convertion.
;   byte 2,3 - flags.
; Returns:
;   eax - handle of the string (new one or passed in [str])
;   edx - pointer to the string.
;___________________________________________________________
proc NumToStr, .num, .strng, .index, .flags
.max_len dd ?
.len_tab rb 20      ; table that holds maximum number of digits in given system
begin
        push    ebx ecx edx esi edi

        mov     [.len_tab+2],32+2       ; binary number - max. 32 digits (+2 bytes for '-' character and NULL terminator)
        mov     [.len_tab+4],16+2       ; quad number - max. 16 digits
        mov     [.len_tab+8],11+2       ; octal number - max. 11 digits
        mov     [.len_tab+10],9+2       ; decimal number - max. 9 digits
        mov     [.len_tab+16],8+2       ; hexadecimal number - max. 8 digits
        movzx   ebx,byte [.flags+1]     ; load radix into ebx
        movzx   eax,byte[.len_tab+ebx]
        mov     [.max_len],eax          ; store max. number of digits
        mov     eax,[.strng]
        or      eax,eax
        jnz     .string_exists
        stdcall StrNew
        mov     [.strng],eax

  .string_exists:
        test    eax,0xffff0000
        jnz     @f                      ; don't resize if [str] isn't a handle
        mov     ebx,eax
        mov     eax,[.max_len]
        add     eax,[.index]
        mov     edx,eax
        stdcall StrSearchLen, ebx
        cmp     eax,edx
        ja      @f                      ; don't resize string if it has enough place for converted number

        stdcall StrSetLength,ebx, edx

  @@:   ; determine which conversion func to use
        mov     eax,[.flags]
        mov     edx,eax
        and     eax,ntsFixedWidth
        jnz     .fixed_width
        mov     eax,edx
        and     eax,ntsUnsigned
        jnz     .unsigned
        mov     ebx,_NumToStr
        jmp     .got_func
  .unsigned:
        mov     ebx,_NumToStrU
        jmp     .got_func

  .fixed_width:
        movzx   esi, byte [.flags]         ; load fixed width into esi
        mov     eax, edx
        and     eax, ntsUnsigned
        jnz     .fixed_unsigned
        mov     ebx,NumToStrF
        jmp     .got_func
  .fixed_unsigned:
        mov     ebx,NumToStrUF
  .got_func:
        stdcall StrPtr, [.strng]
        add     eax,[.index]
        mov     edi,eax
        movzx   ecx,byte [.flags+1]       ; load radix into ecx
        mov     eax, [.num]
        call    ebx                     ; call low-level convertion routine
        mov     eax, [.flags]
        and     eax, ntsZeroTerminated
        jz      .ret
        mov     byte [edi], 0

  .ret:
        pop     edi esi edx ecx ebx
        mov     eax, [.strng]
        return
endp



;-------------------------------------------------------
; function StrToNum
;   Converts specified string into a number
;
; Arguments:
;   hString - handle/pointer of the string containing
;     number to convert. It doesn't have to be ended by
;     NULL, any other character will stop conversion.
;     Number to convert must be decimal.
;
; Return:
;   eax - converted number
;
; Note: in case of failture (first char of given pointer
;   isn't a number) function returns -1.
;-------------------------------------------------------
proc StrToNum, .hString
begin
        push    ebx edx esi
        xor     ebx,ebx         ; ebx will store our number
        stdcall StrPtr, [.hString]
        mov     esi,eax
        xor     eax,eax
        mov     al,[esi]
        cmp     al,'0'
        jb      .error
        cmp     al,'9'
        jbe     .digit
        jmp     .error
     .digit:
        sub     al,'0'
        add     ebx,eax
        inc     esi
        mov     al,[esi]
        cmp     al,'0'
        jb      .finish
        cmp     al,'9'
        ja      .finish
        mov     edx,ebx         ; multiply ebx by 10
        shl     ebx,3
        add     ebx,edx
        add     ebx,edx
        jmp     .digit
     .finish:
        mov     eax,ebx
        pop     esi edx ebx
        return

     .error:
        xor     eax,eax
        dec     eax
        pop     esi edx ebx
        return
endp


;-------------------------------------------------------
; function StrCharCat
;   Addes up to 4 chars to the end of a string.
;
; Arguments:
;   ptrString - string to append
;   char - char(s) to add
; Returns
;   eax: pointer to the string.
;-------------------------------------------------------
proc StrCatChar, .ptrString, .char
begin
        push    ebx ecx

        mov     eax, [.ptrString]
        mov     ecx, [eax+TString.len]
        lea     ebx, [ecx+4]
        cmp     ebx, [eax+TString.capacity]
        jbe     .sizeok

        stdcall StrSetCapacity, eax, ebx

        pushd   [.char]
        popd    [eax+ecx]
        xor     ebx, ebx
        mov     [eax+ecx+4], ebx
        dec     ecx
.len:
        inc     ecx
        cmp     [eax+ecx], bl
        jne     .len

        mov     [eax+TString.len], ecx
        pop     ecx ebx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/drafts/tests/MainForm.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
;<ff
Window frmMain, 3, 0, 'TForm', 'Tiny GUI application using TForm', $16080000, $0, 0, 339, 199, 320, 240, MainFormWinProc;
Window NONE, 0, 0, 'BUTTON', 'Button', $50000000, $0, 0, 96, 40, 64, 25, 0;
Window NONE, 0, 0, 'STATIC', 'Label', $50001200, $0, 101, 136, 88, 80, 16, 0;
Window NONE, 0, 0, 'STATIC', 'Result:', $50000000, $0, 0, 136, 72, 88, 16, 0;
Window NONE, 0, 0, 'STATIC', 'Time [ms]', $50000000, $0, 0, 16, 72, 88, 16, 0;
Window NONE, 2, 0, 'STATIC', 'Label', $50001200, $0, 100, 16, 88, 80, 16, 0;
;ff>
uglobal
  pointer dd ?
endg



proc StrProc1, .ptr

begin
        push    edi ecx

        xor     eax, eax
        or      ecx, -1
        mov     edi, [.ptr]

        repnz scasb

        not     ecx
        dec     ecx
        mov     eax, ecx

        pop     ecx edi
        return
endp



proc StrProc2, .ptr
begin
        mov     eax, [.ptr]

.loop:
        cmp     byte [eax], 0
        lea     eax, [eax+1]
        jne     .loop

        stc
        sbb     eax, [.ptr]
        return
endp




proc StrProc3, .ptr
begin
        push    ebx ecx edx esi edi

        mov     edi, $7f7f7f7f
        mov     ecx, $80808080

        mov     esi, [.ptr]

.scan:
        mov     eax, [esi]
        mov     edx, [esi+4]

        and     eax, edi
        and     edx, edi

        add     eax, edi
        add     edx, edi

        or      eax, [esi]
        or      edx, [esi+4]

        and     eax, ecx
        and     edx, ecx

        and     eax, edx
        add     esi, 8

        cmp     eax, ecx
        je      .scan

.found:
        lea     eax, [esi-9]

; so search by bytes
.byteloop:
        lea     eax, [eax+1]
        cmp     byte [eax], 0
        jne     .byteloop

        sub     eax, [.ptr]

        pop     edi esi edx ecx ebx
        return
endp





proc StrProc4, .pString
begin
        mov     eax, [.pString]
.scan:
        cmp     dword [eax], 0
        lea     eax, [eax+4]
        jne     .scan

        lea     eax, [eax-4]

; so search back
.byteloop:
        lea     eax, [eax-1]
        cmp     byte [eax], 0
        je      .byteloop

        lea     eax, [eax+1]
        sub     eax, [.pString]
        return
endp




proc StrProc5, .ptr
begin
        push    edx esi

        mov     esi, [.ptr]
.scan:
        mov     eax, [esi]
        mov     edx, [esi+4]

        and     eax, $7f7f7f7f
        and     edx, $7f7f7f7f

        add     eax, $7f7f7f7f
        add     edx, $7f7f7f7f

        or      eax, [esi]
        or      edx, [esi+4]

        and     eax, $80808080
        and     edx, $80808080

        and     eax, edx
        add     esi, 8

        cmp     eax, $80808080
        je      .scan

        lea     eax, [esi-9]

; so search by bytes
.byteloop:
        lea     eax, [eax+1]
        cmp     byte [eax], 0
        jne     .byteloop

        sub     eax, [.ptr]

        pop     esi edx
        return
endp


proc StrProc6, .ptr
begin
        push    ecx edx esi edi

        mov     eax, [.ptr]
.scan:
        mov     ecx, [eax]
        mov     edx, [eax+4]

        lea     eax, [eax+8]

        lea     esi, [ecx-$01010101]
        lea     edi, [edx-$01010101]

        not     ecx
        not     edx

        and     esi, ecx
        and     edi, edx

        and     esi, $80808080
        and     edi, $80808080

        or      esi, edi
        jz      .scan

        sub     eax, 9

; byte 0 was found: so search by bytes.
.byteloop:
        lea     eax, [eax+1]
        cmp     byte [eax], 0
        jne     .byteloop

        sub     eax, [.ptr]

        pop     edi esi edx ecx
        return
endp



proc StrProc7, .ptr
begin
        push    ebx ecx

        mov     eax, [.ptr]

.scan:
        mov     ebx, [eax]
        lea     eax, [eax+4]

        lea     ecx, [ebx-$01010101]
        not     ebx
        and     ecx, ebx
        and     ecx, $80808080
        jz      .scan

        lea     eax, [eax-5]

; so search by bytes
.byteloop:
        inc     eax
        cmp     byte [eax], 0
        jne     .byteloop

        sub     eax, [.ptr]

        pop     ecx ebx
        return
endp












winproc MainFormWinProc
begin


ondefault
        stc
        return




onmessage WM_COMMAND

        invoke  GetProcessHeap
        invoke  HeapAlloc, eax, HEAP_ZERO_MEMORY, 1000000

        mov     [pointer], eax

        mov     edi, eax
        mov     ecx, 985000 / 4
        or      eax, -1

        rep stosd
        mov     ecx, 29
        rep stosb


        invoke  GetTickCount
        push    eax

        mov     ecx, 1000

.loop1:
        stdcall StrProc7, [pointer]
        loop    .loop1

        pop     ebx
        push    eax

        invoke  GetTickCount
        sub     eax, ebx

        stdcall SetNumber, [.hwnd], 100, eax

        pop     eax
        stdcall SetNumber, [.hwnd], 101, eax

        invoke  GetProcessHeap
        invoke  HeapFree, eax, 0, [pointer]

        clc
        return


endwp





proc SetNumber, .hwnd, .id, .number
begin
        pushad

        stdcall NumToStr, [.number], 0, 0, ntsDec or ntsUnsigned or ntsZeroTerminated
        push    eax
        stdcall StrPtr, eax
        invoke  SendDlgItemMessage, [.hwnd], [.id], WM_SETTEXT, 0, eax
        stdcall StrDel ; from the stack

        popad
        return
endp



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/drafts/tests/README.TXT.

1
2
3
4
5
6
7
8
9
10
11
Atom 270 1.6GHz (eeepc 901HA)

Proc1 - [repnz scasb]           -       2380ms
Proc2 - [cmp byte [eax],0]      -       3000ms
Proc3 - [$7f/$80 qword regs]    -       1078ms
Proc4 - [cmp dword[eax],0]      -        828ms
Proc5 - [$7f/$80 qword const]   -       1080ms
Proc6 - [$01/$80 qword const]   -       1000ms
Proc7 - [$01/$80 dword const]   -       1297ms

Proc2 is interesting.
<
<
<
<
<
<
<
<
<
<
<






















Deleted freshlib/_trash/SurplusSources/drafts/tests/TinyGUI.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
format PE GUI 4.0
entry Start

include '%finc%\win32\win32a.inc'
include '%finc%\libs\strlib.inc'

include "%finc%\libs\msgutils.inc"
include "%finc%\libs\tform.inc"
include "%finc%\libs\parents.inc"
include "%finc%\libs\templates.inc"

include "%finc%\libs\msgutils.asm"
include "%finc%\libs\tform.asm"
include "%finc%\libs\parents.asm"
include "%finc%\libs\templates.asm"

include '%finc%\libs\strlib.asm'


include "MainForm.frm"

uglobal
  hInstance dd ?
  hHeap     dd ?
  hMainForm dd ?
endg

Start:
        invoke  GetModuleHandle,0
        mov     [hInstance],eax
        invoke  GetProcessHeap
        mov     [hHeap], eax

        InitializeAll

        stdcall CreateForm, frmMain, NULL
        xor     eax, eax
        test    ebx, ebx
        jz      .terminate

        mov     [hMainForm], ebx

.run:
        call    ProcessMessages
        jc      .terminate

        invoke  WaitMessage
        jmp     .run

.terminate:
        push    eax
        FinalizeAll
        invoke  ExitProcess ; exit code from the stack.

data import
  ImportLib kernel32, user32, gdi32,         \
            comctl32, comdlg32, shell32,     \
            ole32, advapi32
end data

IncludeAllGlobals
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































Deleted freshlib/_trash/SurplusSources/drafts/tests/TinyGUI.fpr.

cannot compute difference between binary files

Deleted freshlib/_trash/SurplusSources/macroses.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
;*************************************************************
;* macroses.inc
;*
;* This file contains some common data structures and
;* constants. It not contains any data or
;* code.
;*
;* You must include somewhere in the begining of the program.
;*
;* You can use this work for any purpos, only don't forget to
;* write somewhere in docs: "Based on work of John Found" or
;* something similar. :)
;*
;* '2003 John Found
;*************************************************************

macro icon group, [label, icon_file, index] {
  common
    local count

    count = 0
  forward
    local data,size,position

    load size dword from icon_file:$0e + $10 * index  ; size of icon
    load position dword from icon_file:$12 + $10 * index  ; position

    label dd RVA data,size, 0, 0

    data file icon_file:position,size

    count = count + 1

  common
    local header

    align 4
    group dd RVA header,6+count*14,0,0
    header dw 0,1,count

  forward

    file icon_file: 6+index*16, 12
    dw label#.resid

  common
    align 4

}



macro cursor [group,_label,cursor_file] {
  forward
    local _header, _data,_size,_position,_hotX, _hotY, _xsize, _ysize

    load _xsize     byte  from cursor_file:$06
    load _ysize     byte  from cursor_file:$07
    load _hotX	    word  from cursor_file:$0a
    load _hotY	    word  from cursor_file:$0c
    load _size	    dword from cursor_file:$0e
    load _position  dword from cursor_file:$12

    align 4

    group   dd	  RVA _header, $14, 0, 0

    _header dw	  0, 2, 1
	    dw	  _xsize, _ysize
	    dw	  $1			 ; Planes ???
	    dw	  $00			  ; Bit count ???
	    dd	  _size+4		     ; Resource len

    filter_id = RVA _label

	    dw	  _label#.resid

    _label dd RVA _data, _size+4, 0, 0

    _data dw _hotX, _hotY
	    file    cursor_file:_position,_size
}








struc TInitCommonControlsEx Flg {
  .dwSize: dd .size	    ; size of this structure
  .dwICC:  dd Flg	    ; flags indicating which classes to be initialized
  .size = $ - .dwSize
}


struc TMenuItemInfo {
  .cbSize	 dd  .size
  .fMask	 dd  ?
  .fType	 dd  ?
  .fState	 dd  ?
  .wID		 dd  ?
  .hSubMenu	 dd  ?
  .hBmpChecked	 dd  ?
  .hBmpUnchecked dd  ?
  .dwItemData	 dd  ?
  .dwTypeData	 dd  ?
  .cch		 dd  ?
  .size 	 =   $ - .cbSize
}


virtual at 0
  TMenuItemInfo TMenuItemInfo
end virtual



struc  TMeasureItemStruct {
  .CtlType    dd ?
  .CtlID      dd ?
  .itemID     dd ?
  .itemWidth  dd ?
  .itemHeight dd ?
  .itemData   dd ?

  .size = $ - .CtlType
}

virtual at 0
  TMeasureItemStruct TMeasureItemStruct
end virtual


struc	TDrawItemStruct {
  .CtlType     dd ?
  .CtlID       dd ?
  .itemID      dd ?
  .itemAction  dd ?
  .itemState   dd ?
  .hwndItem    dd ?
  .hDC	       dd ?
  .rectItem    RECT
  .itemData    dd ?

  .size = $ - .CtlType
}

virtual at 0
  TDrawItemStruct TDrawItemStruct
end virtual




struc TLogBrush Color {
  .lbStyle    dd    BS_SOLID
  .lbColor    dd    Color
  .lbHatch    dd    ?
}


struc TWindowClass AStyle, AWinProc, ABackground, AClassName
 {
   .style	  dd AStyle
   .lpfnWndProc   dd AWinProc
   .cbClsExtra	  dd 0
   .cbWndExtra	  dd 0
   .hInstance	  dd ?
   .hIcon	  dd ?
   .hCursor	  dd ?
   .hbrBackground dd ABackground
   .lpszMenuName  dd 0

   if AClassName eqtype ''
     .lpszClassName dd .ClassName
     .ClassName   db AClassName,0
   else
     .lpszClassName dd AClassName
     .ClassName = AClassName
   end if
 }


struc TLogBrush Color {
  .lbStyle    dd    BS_SOLID
  .lbColor    dd    Color
  .lbHatch    dd    ?
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































Deleted freshlib/_trash/SurplusSources/qsort.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
QuickSortLib:

;****************************************************
; Quick sort of the array in the memory.
;
;  ptrArray       - pointer to the memory array.
;  ElementSize    - size of one array element in bytes.
;  iBegin         - index of the first element
;  iEnd           - index of the last element
;  ptrCompareProc - pointer to procedure that compares two elements.
;
; ptrCompareProc have interface:
;  proc CompareSomething, ptrElement1, ptrElement2
;    returns: c=1 if elements are not properly sorted.
;             c=0 if elements are sorted, i.e.
;                 element1 should be before element2
;****************************************************


proc QSort, ptrArray, ElementSize, iBegin, iEnd, ptrCompareProc
begin
        push    esi edi ebx
        mov     esi, [ptrArray]
        mov     edi, [ptrCompareProc]
        mov     ebx, [ElementSize]

        stdcall DoQSort, [iBegin], [iEnd]
        pop     ebx edi esi
        return
endp

;*****************************************************
; Procedure for internal call from QSort procedure.
;*****************************************************
proc DoQSort, Left, Right
begin
        push    ecx

        mov     ecx, [Left]     ; i variable
        mov     eax, ecx
        mov     edx, [Right]    ; j variable
        add     eax, edx
        sar     eax, 1
        imul    eax, ebx
        imul    ecx, ebx
        imul    edx, ebx
        add     eax, esi
        add     ecx, esi
        add     edx, esi

.repeat:
        sub     ecx, ebx
        add     edx, ebx

.whylei:
        add     ecx, ebx
        stdcall edi, ecx, eax
        jnc     .whylei

.whylej:
        sub     edx, ebx
        stdcall edi, eax, edx
        jnc     .whylej

        cmp     edx, ecx
        jl      .next

        call    SwapElements

        push    edx
        cmp     eax, ecx
        je      @f
        mov     [esp], ecx
        cmp     eax, edx
        je      @f

        mov     [esp], eax
@@:
        pop     eax

        add     ecx, ebx
        sub     edx, ebx

.next:
        cmp     ecx, edx
        jle     .repeat

        mov     eax, edx
        sub     eax, esi
        cdq
        idiv    ebx

        cmp     [Left], eax
        jge     .leftok

        stdcall DoQSort, [Left], eax

.leftok:
        mov     eax, ecx
        sub     eax, esi
        cdq
        idiv    ebx

        cmp     eax, [Right]
        jge     .rightok

        stdcall DoQSort, eax, [Right]

.rightok:
        pop     ecx
        return
endp



;********************************************
; Swaps two elements of the array with
; pointers in:
;   Element1 - ecx
;   Element2 - edx
;   ElementSize - ebx
;********************************************
proc SwapElements
begin
        push    esi eax

        xor     esi, esi
.loop:
        mov     al, [ecx+esi]
        xchg    al, [edx+esi]
        mov     [ecx+esi], al

        inc     esi
        cmp     esi, ebx
        jne     .loop

        pop     eax esi
        return
endp




proc CompareIntAscending, ptrElement1, ptrElement2
begin
        push    eax esi edi

        mov     esi, [ptrElement1]
        mov     edi, [ptrElement2]

        mov     eax, [esi]
        cmp     eax, [edi]
        jl      .qfalse

        stc
        pop     edi esi eax
        return


.qfalse:
        clc
        pop     edi esi eax
        return
endp



DispSize 'QSort lib', $ - QuickSortLib
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































Deleted freshlib/_trash/readme.txt.

1
2
3
4
5
6
7
8
9
10
So, this is very early version of "FreshLib", that
is highly portable library for Fresh and FASM
development.

Even now, you can create simple applications, portable
between Win32 and Linux simply with one-click change in
project options.

The test project, that uses FreshLib is "TestFreshLib.fpr"
You can compile and run it as Windows or as Linux application.
<
<
<
<
<
<
<
<
<
<




















Deleted freshlib/data/Linux/utf8.asm.

Deleted freshlib/data/ToBeRemoved/StrLibOS.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
;*******************************************************************************
; Get the text of the [Control] using WM_GETTEXT and put it to the string with
; handle (only) in [string].
;
; if [string] = NULL creates new string and returns the handle.
; if [string] <> NULL just copyes the text.
;*******************************************************************************
proc GetControlText, .Control, .string
.len dd ?
begin
        push    ebx ecx edx

        mov     eax, [.string]
        test    eax,eax
        jnz     @f
        stdcall StrNew
@@:
        mov     ebx, eax

        invoke  SendMessageA, [.Control], WM_GETTEXTLENGTH, 0, 0
        mov     [.len], eax
        stdcall StrSetCapacity, ebx, eax
        jc      .error

        push    eax
        add     [.len], 1
        invoke  SendMessageA, [.Control], WM_GETTEXT, [.len], eax
        pop     ecx
        mov     [ecx+string.len], eax
        mov     eax, ebx
        clc

.error:
        pop     edx ecx ebx
        return
endp





;*******************************************************************************
; Sets the text in control using WM_SETTEXT from string with handle or pointer
; in [string].
;*******************************************************************************
proc SetControlText, .Control, .string
begin
        push    eax ecx edx
        stdcall StrPtr, [.string]
        invoke  SendMessageA, [.Control], WM_SETTEXT, 0, eax
        pop     edx ecx eax
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































Deleted freshlib/data/Win32/utf8.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Library for converting UTF8 to and from WideChar
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


;-----------------------------------------------------------
; Returns:
;    eax - pointer to the widechar string.
;    ecx - length of the widechar string in characters.
;-----------------------------------------------------------
proc utf8ToWideChar, .hString
begin
        push    edx edi

        stdcall StrLen, [.hString]
        mov     ecx, eax

        mov     edx, eax
        shl     edx, 2
        stdcall GetMem, edx
        mov     edi, eax

        stdcall StrPtr, [.hString]

        sar     edx, 1
        invoke  MultiByteToWideChar, CP_UTF8, 0, eax, ecx, edi, edx
        mov     ecx, eax
        mov     eax, edi

        pop     edi edx
        return
endp




proc WideCharToUtf8, .ptrWideChar
begin
        push    ebx ecx edx edi
        invoke  WideCharToMultiByte, CP_UTF8, 0, [.ptrWideChar], -1, 0, 0, 0, 0
        test    eax, eax
        jz      .error

        mov     ebx, eax
        stdcall GetMem, ebx
        mov     edi, eax

        invoke  WideCharToMultiByte, CP_UTF8, 0, [.ptrWideChar], -1, edi, ebx, 0, 0
        stdcall StrDup, edi

        push    eax
        stdcall FreeMem, edi
        pop     eax

        clc
.finish:
        pop     edi edx ecx ebx
        return

.error:
        stc
        jmp     .finish
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































Deleted freshlib/data/all.asm.

1
2
3
4
5
6
include 'arrays.asm'
include 'strlib.asm'
include 'uconfig.asm'
include 'memstream.asm'
include 'markdown.asm'
include 'md5lib.asm'
<
<
<
<
<
<












Deleted freshlib/data/arrays.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: OS independent dynamic arrays library.
;
;  Target OS: Any
;
;  Dependencies: memory.asm
;
;  Notes:
;_________________________________________________________________________________________

module "Arrays library"

struct TArray
  .count     dd ?           ; Count of elements in dynamic array
  .capacity  dd ?           ; Capacity of the array allocated memory.
  .itemsize  dd ?           ; Size of one element in dynamic array. Aligned on dword.
  .lparam    dd ?           ; User defined value.
  label .array dword
ends


; ____________________________________________________________________
;|                                                                    |
;| Creates dynamic array.                                             |
;|                                                                    |
;| Arguments:                                                         |
;|                                                                    |
;|   .ItemSize: size in bytes of one array element.                   |
;|              This size will be aligned to dword.                   |
;|                                                                    |
;| Return:                                                            |
;|   if CF=1 the memory can't be allocated.                           |
;|   if CF=0 eax contains pointer to the created array.               |
;|____________________________________________________________________|

proc CreateArray, .ItemSize
begin
        push    ecx edx
        mov     ecx, [.ItemSize]
        add     ecx, 3
        and     cl, $fc
        mov     edx, ecx

        imul    ecx, cInitialCapacity
        add     ecx, sizeof.TArray
        stdcall GetMem, ecx
.retaddr:
        jc      .finish

        mov     [eax+TArray.itemsize], edx
        mov     [eax+TArray.capacity], cInitialCapacity
        clc

.finish:
        pop     edx ecx
        return
endp


; returns a pointer to the array item.
; Arguments:
;  .array - pointer to TArray
;  .index - index of the array element.
;
; Returns:
;   CF=0; EAX = pointer to the array element.
;   CF=1 - indicates that [.index] is bigger than the array element count;
;          in this case EAX = points after the last element of the array.

proc GetArrayItem, .array, .index
begin
        push    ecx esi

        mov     esi, [.array]
        mov     eax, [.index]
        mov     ecx, [esi+TArray.count]

        cmp     eax, ecx
        cmovae  eax, ecx

        imul    eax, [esi+TArray.itemsize]
        lea     eax, [esi+TArray.array+eax]

; set CF
        sub     ecx, 1
        jc      @f
        cmp     ecx, [.index]
@@:
        pop     esi ecx
        return
endp



;____________________________________________________________________
;
;  proc AddArrayItems - adds new item at the end of TArray
;                      dynamic array.
;  Arguments:
;
;    .ptrArray - pointer to dword variable containing pointer
;               to TArray structure.
;    .count - count of the elements to be added.
;
;  Returns:
;    CF=1 if error: edx - pointer to the original array.
;
;    CF=0 if OK:    eax - pointer to new created element.
;                   edx - pointer to the array.
;
;  Notes:
;    The procedure returns in edx pointer to the TArray. This pointer
;    can differs from .ptrArray argument, if the memory was
;    reallocated. The user should save the pointer for future access
;    to the array. It is safe to save the pointer before check of CF
;    for error, because the procedure returns original pointer in case
;    of memory allocation error.
;____________________________________________________________________

proc AddArrayItems, .ptrArray, .count
begin
        push    ebx ecx

        mov     edx, [.ptrArray]
        test    edx, edx
        jnz     @f

        stc
        pop     ecx ebx
        return

@@:
        mov     eax, [edx+TArray.count]
        mov     ecx, [edx+TArray.capacity]
        add     eax, [.count]
        cmp     ecx, eax
        jae     .memallocated

; enlarge the array. Strategy here is not clear.
        mov     ecx, eax
        call    dword [ResizeIt]
        jc      .finish

        mov     ebx, ecx
        imul    ecx, [edx+TArray.itemsize]
        add     ecx, sizeof.TArray

        stdcall ResizeMem, edx, ecx
.readdr:
        jc      .finish

        mov     edx, eax
        mov     [edx+TArray.capacity], ebx

.memallocated:
        mov     eax, [edx+TArray.count]
        mov     ecx, [.count]
        add     [edx+TArray.count], ecx

        imul    eax, [edx+TArray.itemsize]
        lea     eax, [edx+eax+TArray.array]
        clc

.finish:
        pop     ecx ebx
        return
endp


;____________________________________________________________________
;
;  proc InsertArrayItems - inserts new item in the array.
;
;  Arguments:
;
;    .ptrArray - pointer to TArray structure.
;    .iElement - on what index to be inserted the new elements.
;    .count    - how many elements to be inserted.
;
;  Returns:
;    CF=1 if error: edx - pointer to the original array; new elements are
;                         not inserted.
;
;    CF=0 if OK:    eax - pointer to the first of the new inserted elements.
;                   edx - pointer to the array.
;
;  Notes:
;    If .iElement is larger or equal to [TArray.count] the elements are
;    appended at the end of the array. Otherwise, all elements are moved
;    to make room for the new elements. If the capacity of the array is
;    not enough to hold the new elements, the array is resized.
;
;    The procedure returns in edx pointer to the TArray. This pointer
;    can differs from .ptrArray argument, if the memory was
;    reallocated. The user should save the pointer for future access
;    to the array. It is safe to save the pointer before check of CF
;    for error, because the procedure returns original pointer in case
;    of memory allocation error.
;____________________________________________________________________

proc InsertArrayItems, .ptrArray, .iElement, .count
begin
        stdcall AddArrayItems, [.ptrArray], [.count]
        jc      .end1

        push    ecx

        mov     ecx, [.iElement]
        add     ecx, [.count]
        cmp     ecx, [edx+TArray.count]
        jae     .end2

        push    esi edi

        imul    ecx, [edx+TArray.itemsize]
        lea     ecx, [edx+ecx+TArray.array]

        lea     esi, [eax-4]                    ; the last element.
        mov     edi, [edx+TArray.count]
        imul    edi, [edx+TArray.itemsize]
        lea     edi, [edx+edi+TArray.array]     ; end of the array.

        mov     eax, ecx
        sub     eax, [edx+TArray.itemsize]

        sub     ecx, edi
        neg     ecx
        shr     ecx, 2

        sub     edi, 4

        std

; scroll the data.
        rep movsd

; clear the new items.
        mov     ecx, [edx+TArray.itemsize]
        imul    ecx, [.count]
        shr     ecx, 2
        xor     eax, eax
        rep stosd

        lea     eax, [edi+4]
        cld

        pop     edi esi

.end2:
        pop     ecx
.end1:
        return
endp


;**************************************************************
;  proc DeleteArrayItems - deletes the items with the specified
;                          index and specified count from TArray
;                          dynamic array.
;  If the capacity of the array is bigger than the recomended
;  for the new count, then the array is resized.
;  The recomended size is calculated using ResizeIt procedure
;  from memory library.
;
;  Arguments:
;    .ptrArray - pointer to TArray structure.
;    .iElement - index of the element to be deleted.
;    .count    - how many elements to be deleted.
;
;  Returns: edx - pointer to the TArray. In the most cases
;                 this pointer will not be changed, but this
;                 also depends on the current OS memory
;                 allocation API, so it is safer to store
;                 the pointer for future use instead of
;                 passed to the procedure.
;
;  Notes:
;           This function can't fail, because delete is
;           always possible in already allocated array.
;           in some cases shrinking resize possibly can fail
;           but this will not affect the data in the array.
;
;           if [.iElement]+[.count] is bigger that the [TArray.count]
;           of the array, only the elements to the end of the array
;           will be deleted.
;
;*******************************************************
proc DeleteArrayItems, .ptrArray, .iElement, .count
begin
        push    edi esi ecx ebx eax

        mov     edx, [.ptrArray]
        test    edx, edx
        jz      .exit

        mov     ecx, [.iElement]
        mov     eax, [edx+TArray.count]

        test    ecx, ecx
        js      .exit

        cmp     ecx, eax
        jae     .exit                   ; index greater or equal to the count...

        add     ecx, [.count]
        cmp     ecx, eax
        jae     .movedone               ; if there is no more elements after the last deleted element, don't move

        mov     eax, [edx+TArray.itemsize]

        imul    ecx, eax
        lea     esi, [edx+ecx+TArray.array]     ; the first after deleted

        mov     ecx, [.iElement]
        imul    ecx, eax                        ; offset of the deleted element.
        lea     edi, [edx+ecx+TArray.array]     ; destination address.

        mov     ecx, [edx+TArray.count]
        imul    ecx, eax
        lea     ecx, [ecx+edx+TArray.array]
        sub     ecx, esi                        ; bytes to be moved. It should be dword aligned count.

        shr     ecx, 2
        rep movsd                               ; move the data.

.movedone:
        mov     ecx, [edx+TArray.count]
        mov     eax, [.iElement]
        sub     ecx, [.count]
        cmp     ecx, eax
        ja      @f
        mov     ecx, eax
@@:
        mov     [edx+TArray.count], ecx

        call    [ResizeIt]
        jc      .exit                           ; the array is OK, but the resize failed.

        cmp     ecx, [edx+TArray.capacity]
        jae     .exit                           ; the array have smaller capacity than recomended, so don't resize.

        mov     eax, ecx
        imul    eax, [edx+TArray.itemsize]
        add     eax, sizeof.TArray
        stdcall ResizeMem, edx, eax
        jc      .exit                           ; the resize failed, but the array is ok.

        mov     edx, eax
        mov     [edx+TArray.capacity], ecx      ; set new capacity.

.exit:
        pop     eax ebx ecx esi edi
        return
endp



;**************************************************************
;  proc VacuumArray - deletes the reserved memory from the array.
;
;  Arguments:
;    .ptrArray - pointer to TArray structure.
;
;  Returns: edx - pointer to the TArray. In the most cases
;                 this pointer will not be changed, but this
;                 also depends on the current OS memory
;                 allocation API, so it is safer to store
;                 the pointer for future use instead of
;                 passed to the procedure.
;           CF=1 - there is a error on vacuuming. This is not
;                  exactly error, because this case indicates
;                  simply some memory manager unabiliry to reallocate
;                  memory. Although the array will not be changed.
;
; This procedure removes all reserved space in the array.
; Vacuum can save a lot of memory space, but takes time and
; also will make future inserts of new elements
; slower at least for the first add/insert.
;
; it is wise to vacuum the array after it is filled with
; most/all of the needed elements.
;
proc VacuumArray, .ptrArray
begin
        push    eax ecx

        mov     edx, [.ptrArray]
        mov     ecx, [edx+TArray.count]
        mov     eax, [edx+TArray.itemsize]
        add     ecx, 1
        imul    eax, ecx
        add     eax, sizeof.TArray

        stdcall ResizeMem, edx, eax
        jc      .exit

        mov     edx, eax
        mov     [eax+TArray.capacity], ecx

.exit:
        pop     ecx eax
        return

endp





;****************************************************
; Quick sort of the array in the memory.
;
;  ptrArray       - pointer to TArray structure.
;  ptrCompareProc - pointer to procedure that compares two elements.
;
; ptrCompareProc have interface:
;  proc CompareSomething, ptrElement1, ptrElement2
;    returns: c=1 if elements are not properly sorted.
;             c=0 if elements are sorted, i.e.
;                 element1 should be before element2
;****************************************************


proc SortArray, .ptrArray, .ptrCompareProc
begin
        pushad

        mov     esi, [.ptrArray]
        mov     edi, [.ptrCompareProc]
        mov     ebx, [esi+TArray.itemsize]

        mov     eax, [esi+TArray.count]
        dec     eax
        xor     ecx, ecx
        lea     esi, [esi+TArray.array]

        stdcall __DoQSort, ecx, eax

        popad
        return
endp

;*****************************************************
; Procedure for internal call from QSort procedure.
;*****************************************************
proc __DoQSort, .Left, .Right
begin
        push    ecx

        mov     ecx, [.Left]     ; i variable
        mov     eax, ecx
        mov     edx, [.Right]    ; j variable
        add     eax, edx
        sar     eax, 1
        imul    eax, ebx
        imul    ecx, ebx
        imul    edx, ebx
        add     eax, esi
        add     ecx, esi
        add     edx, esi

        call    ___CopyMiddleElement

.repeat:
        sub     ecx, ebx
        add     edx, ebx

.whilei:
        add     ecx, ebx
        stdcall edi, ecx, eax
        jnc     .whilei

.whilej:
        sub     edx, ebx
        stdcall edi, eax, edx
        jnc     .whilej

        cmp     ecx, edx
        jg      .next           ;i>j
        je      .swapok
        call    ___SwapElements
.swapok:
        add     ecx, ebx
        sub     edx, ebx

.next:
        cmp     ecx, edx
        jle     .repeat

        stdcall FreeMem, eax

        mov     eax, edx        ;j
        sub     eax, esi
        cdq
        idiv    ebx

        cmp     [.Left], eax
        jge     .leftok

        stdcall __DoQSort, [.Left], eax

.leftok:
        mov     eax, ecx        ;i
        sub     eax, esi
        cdq
        idiv    ebx

        cmp     eax, [.Right]
        jge     .rightok

        stdcall __DoQSort, eax, [.Right]

.rightok:
        pop     ecx
        return
endp



;********************************************
; Swaps two elements of the array with
; pointers in:
;   Element1 - ecx
;   Element2 - edx
;   ElementSize - ebx
;********************************************
proc ___SwapElements
begin
        pushad

        xor     esi, esi
.loop:
        mov     al, [ecx+esi]
        xchg    al, [edx+esi]
        mov     [ecx+esi], al

        inc     esi
        cmp     esi, ebx
        jne     .loop

        popad
        return
endp


proc ___CopyMiddleElement
begin
        push    ecx esi edi

        mov     esi, eax
        stdcall GetMem, ebx
        mov     edi, eax
        mov     ecx, ebx
        mov     eax, edi

        rep movsb
        pop     edi esi ecx
        return
endp




proc CompareIntAscending, .ptrElement1, .ptrElement2
begin
        push    eax esi edi

        mov     esi, [.ptrElement1]
        mov     edi, [.ptrElement2]

        mov     eax, [esi]
        cmp     eax, [edi]
        jl      .qfalse

        stc
        pop     edi esi eax
        return


.qfalse:
        clc
        pop     edi esi eax
        return
endp







;____________________________________________________________________
;
; proc ListIndexOf, .ptrArray, .item - searches dynamic list for
;                                    the given item.
;
; List is a special case of dynamic array, where the size of the
; elements is dword (4 bytes).
;
; Arguments:
;   .ptrList - pointer to TArray dynamic array.
;   .item    - value of the element.
; Returns:
;   CF = 0 if the element was found. eax contains index of
;          the element.
;   CF = 1 the element is not found.
;____________________________________________________________________

proc ListIndexOf, .ptrList, .Item
begin
        push    edi ecx

        mov     edi, [.ptrList]

        cmp     [edi+TArray.itemsize], 4
        jne     .notfound

        mov     ecx, [edi+TArray.count]
        jecxz   .notfound

        lea     edi, [edi+4*ecx+TArray.array-4] ; from the end
        mov     eax, [.Item]
        std
        repnz scasd
        cld
        jz      .found

.notfound:
        stc
        pop     ecx edi
        return

.found:
        clc
        mov     eax, ecx
        pop     ecx edi
        return
endp


;--------------------------------------------
; Frees all elements of the list calling
; [FreeProc] on every element.
; (proc FreeProc, ptrItem)
; Frees the array of items
;--------------------------------------------
proc ListFree, .ptrList, .FreeProc
begin
        push    edi ebx

        mov     edi, [.ptrList]
        mov     ebx, [edi+TArray.count]

        cmp     [.FreeProc], 0
        je      .endwhile

.freeloop:
        dec     ebx
        js      .endwhile

        stdcall [.FreeProc], [edi+4*ebx+TArray.array]
        jmp     .freeloop

.endwhile:
        stdcall FreeMem, edi

.finish:
        pop     ebx edi
        return
endp


endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/data/markdown.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
module "markdown parser"

struct TMarkdownResults
  .hContent     dd ?
  .hIndex       dd ?
  .hKeywords    dd ?
  .hDescription dd ?
ends



fblkQuote       = 1
fblkTable       = 2


fstateHeader    = $01
fstatePara      = $02
fstateWhite     = $04
fstateBold      = $08
fstateLink      = $10
fstateUnderline = $20
fstateStrikeout = $40
fstateItalic    = $80

fstateTextNow  = $200         ; don't use the second byte for any other flags.
fstateTextPrev = $100

fstateInlineSource    =  $10000
fstateBlockSource     =  $20000
fstateImage           =  $40000
fstateInlineImage     =  $80000
fstateTable           = $100000


; Translates some markdown text to HTML
; Arguments:
;     .markdown - pointer or handler of the markdown text.
;     .procFixLink - [proc .ptrLink] procedure that process the link address and returns
;                    handle to the processed link address. if [.procFixLink]=NULL, the links
;                    are inserted as they are in the HTML.
;     .fBacklinks - flag, that defines whether to insert after the headers back links to the
;                   table of contents item.
; Returns:
;     eax - handler of the HTML formated text.
;     edx - handler of the page index.
;     ebx - handler of the detected keywords.
;     ecx - handler of the detected page description.

proc TranslateMarkdown, .markdown, .procFixLink, .fBacklinks, .pResult

.result      dd ?
.index       dd ?
.keywords    dd ?
.description dd ?

  ; first and second pass local variables
  .IdString        rb  256
  .IdLen           dd  ?

  .cntH2           dd  ?
  .cntH3           dd  ?
  .cntH4           dd  ?
  .cntH5           dd  ?
  .cntH6           dd  ?

.pHashTable dd ?
.pHTML      dd ?
.limit      dd ?

  .blocks rb 1024
  .pblock dd ?

begin
        pushad

        stdcall GetMem, 4*65536
        mov     [.pHashTable], eax
        stdcall GetMem, 16384
        mov     [.pHTML], eax
        add     eax, 8192
        mov     [.limit], eax

        stdcall StrNew
        mov     [.result], eax

        stdcall StrNew
        mov     [.index], eax

        stdcall StrNew
        mov     [.keywords], eax

        stdcall StrNew
        mov     [.description], eax

        stdcall StrPtr, [.markdown]
        mov     esi, eax

        call    .FirstPass

        stdcall StrPtr, [.markdown]
        mov     esi, eax
        call    .SecondPass

        stdcall FreeMem, [.pHTML]
        stdcall FreeMem, [.pHashTable]

        mov     edi, [.pResult]

        mov     eax, [.result]
        mov     edx, [.index]
        mov     ebx, [.keywords]
        mov     ecx, [.description]

        mov     [edi+TMarkdownResults.hContent], eax
        mov     [edi+TMarkdownResults.hIndex], edx
        mov     [edi+TMarkdownResults.hKeywords], ebx
        mov     [edi+TMarkdownResults.hDescription], ecx

        popad
        return

;.... start of .FirstPass ..........................................

.FirstPass:
        mov     edi, [.pHTML]
        mov     [.cntH2], 0
        mov     [.cntH3], 0
        mov     [.cntH4], 0
        mov     [.cntH5], 0
        mov     [.cntH6], 0

.line_start:
        cmp     edi, [.limit]
        jb      @f

        mov     dword [edi], 0
        stdcall StrCat, [.index], [.pHTML]
        mov     edi, [.pHTML]

@@:
        cmp     byte [esi], '#'
        je      .header

        cmp     byte [esi], '['
        je      .link

.skip_to_eol:
        mov     al, [esi]
        lea     esi, [esi+1]
        cmp     al, $0d
        je      .line_start
        cmp     al, $0a
        je      .line_start
        test    al, al
        jnz     .skip_to_eol

.end_of_file:
        mov     dword [edi], 0
        stdcall StrCat, [.index], [.pHTML]

        retn

; ----- return from .FirstPass -------------------

; create table of contents item.
.header:
        xor     ecx, ecx

.scan_level:
        inc     ecx
.scan_space:
        lea     esi, [esi+1]
        mov     al, [esi]
        cmp     al, '#'
        je      .scan_level
        cmp     al, ' '
        je      .scan_space
        cmp     al, $09
        je      .scan_space

        cmp     al, $0d
        je      .line_start
        cmp     al, $0a
        je      .line_start

        cmp     ecx, 6
        jbe     @f
        mov     ecx, 6
@@:
        call    .BuildID

        mov     dword [edi], '<a i'
        lea     edi, [edi+4]
        mov     dword [edi], 'd="B'
        lea     edi, [edi+4]

        call    .InsertID

        mov     dword [edi], '" hr'
        mov     dword [edi+4], 'ef="'
        mov     word  [edi+8], '#H'
        lea     edi, [edi+10]

        call    .InsertID

        mov     dword [edi],    '" st'
        mov     dword [edi+4],  'yle='
        mov     dword [edi+8],  '"pad'
        mov     dword [edi+12], 'ding'
        mov     dword [edi+16], '-lef'
        mov     word [edi+20],  't:'
        lea     edi, [edi+22]

        push    ecx
        mov     eax, ecx
        mov     ecx, 10
        sub     eax, 2
        jns     @f
        xor     eax, eax
@@:
        call    _NumToStrU
        pop     ecx

        mov     dword [edi], 'em">'
        lea     edi, [edi+4]

        cmp     ecx, 1
        je      @f
        call    .InsertID
@@:
; copy the header text

.copy_loop:
        mov     al, [esi]
        lea     esi, [esi+1]
        cmp     al, $0d
        je      .end_header
        cmp     al, $0a
        je      .end_header
        test    al, al
        jz      .end_header

        mov     [edi], al
        lea     edi, [edi+1]
        jmp     .copy_loop

.end_header:
        dec     esi
        mov     dword [edi],   '</a>'
        mov     dword [edi+4], '<br '
        mov     word [edi+8], '/>'
        lea     edi, [edi+10]
        jmp     .line_start

;link processing
.link:
        mov     edx, $811C9DC5   ; 2166136261 ; FNV offset basis
        mov     ecx, esi

.label_loop:
        mov     al, [esi]
        lea     esi, [esi+1]

        cmp     al, $20
        je      .label_loop
        cmp     al, $09
        je      .label_loop

        cmp     al, $0d
        je      .line_start
        cmp     al, $0a
        je      .line_start

        test    al, al
        jz      .end_of_file

        xor     dl, al
        imul    edx, $01000193                  ;   16777619              ; FNV prime
        cmp     al, ']'
        jne     .label_loop

; fold the hash to 16 bit value...
        mov     ebx, edx
        shr     ebx, 16
        xor     ebx, edx
        and     ebx, $ffff
        mov     edx, ebx

; search free slot
.search_slot:
        mov     eax, [.pHashTable]
        xchg    ecx, [eax+4*ebx]
        test    ecx, ecx
        jz      .skip_to_eol

; conflict...
; compare the labels on ecx (the old content of the slot) with [HashTable+4*ebx] (the new pointer)
        push    edi ecx

        mov     edi, [eax+4*ebx]

.first:
        mov     al, [ecx]
        lea     ecx, [ecx+1]

        cmp     al, $20
        je      .first
        cmp     al, $09
        je      .first

.second:
        mov     ah, [edi]
        lea     edi, [edi+1]
        cmp     ah, $20
        je      .second
        cmp     ah, $09
        je      .second

        cmp     al, ah
        jne     .add_not_equal

        cmp     ah, ']'
        jne     .first

        pop     ecx edi
        jmp     .skip_to_eol

; save it to the next slot
.add_not_equal:
        pop     ecx edi

        inc     ebx
        and     ebx, $ffff
        cmp     ebx, edx
        jne     .search_slot

        int3    ; full hash table -> to be implemented error processing

;---- End of .FirstPass --------------------------------


;.... Start of .SecondPass .............................

locals
  ; .SecondPass only local variables
  .state       dd ?
  .last_header dd ?
  .linkID_end  dd ?
endl

.SecondPass:
        mov     edi, [.pHTML]

        xor     eax, eax
        mov     [.state], eax
        mov     [.cntH2], eax
        mov     [.cntH3], eax
        mov     [.cntH4], eax
        mov     [.cntH5], eax
        mov     [.cntH6], eax
        mov     [.pblock], eax


.line_start2:
        shr     byte [.state+1], 1   ; fstateTextPrev = fstateTextNow; fStateTextNow = 0

        cmp     edi, [.limit]
        jb      @f
        mov     dword [edi], 0
        stdcall StrCat, [.result], [.pHTML]
        mov     edi, [.pHTML]
@@:

        test    [.state], fstateBlockSource
        jnz     .copy_source

        cmp     byte [esi], '['
        je      .link_definition

        cmp     byte [esi], '#'
        je      .header2

        cmp     byte [esi], ';'
        je      .block_element

        cmp     dword [esi], '----'
        je      .horiz_rule


.scan_line2:
        mov     al, [esi]
        lea     esi, [esi+1]

        cmp     al, ' '
        je      .white_space
        cmp     al, $09         ; tab
        je      .white_space

        cmp     al, $0d
        je      .end_of_line
        cmp     al, $0a
        je      .end_of_line
        test    al, al
        jz      .end_of_line

; it is not white space character...
        test    [.state], fstateTextPrev or fstateTextNow or fstateHeader
        jz      .start_para

.process_char:
        or      [.state], fstateTextNow

        test    [.state], fstateInlineSource
        jnz     .inline_source

        cmp     al, '*'
        je      .process_bold

        cmp     al, '_'
        je      .process_underline

        cmp     al, '-'
        je      .process_strikeout

        cmp     al, '/'
        je      .process_italic

        cmp     al, '['
        je      .is_link_begin

        cmp     al, ']'
        je      .is_link_end

.inline_source:
        cmp     al, '`'
        je      .process_inline_code


.normal_char:
        and     [.state], not fstateWhite

.markup_ok:

        call    .store_char
        jmp     .scan_line2


; stores the char from al in [edi], and
; replaces the invalid HTML characters
; with their &name; representation.

.store_char:
        cmp     al, 'A'
        jb      @f

        mov     [edi], al
        lea     edi, [edi+1]
        retn

@@:
        cmp     al, '<'
        je      .char_less_then
        cmp     al, '>'
        je      .char_greater_then
        cmp     al, '"'
        je      .char_quote
        cmp     al, '&'
        je      .char_amp
;        cmp     al, "'"
;        je      .char_apos

        mov     [edi], al
        lea     edi, [edi+1]
        retn

.char_less_then:
        mov     dword [edi], '&lt;'
        lea     edi, [edi+4]
        retn

.char_greater_then:
        mov     dword [edi], '&gt;'
        lea     edi, [edi+4]
        retn

.char_quote:
        mov     dword [edi], '&quo'
        mov     word [edi+4], 't;'
        lea     edi, [edi+6]
        retn

;.char_apos:
;        mov     dword [edi], '&apo'
;        mov     word [edi+4], 's;'
;        lea     edi, [edi+6]
;        retn

.char_amp:
        mov     dword [edi], '&amp'
        mov     byte [edi+1], ';'
        lea     edi, [edi+5]
        retn


.start_para:
        test    [.state], fstateTable
        jz      .not_td_open

        mov     dword [edi], '<td>'
        lea     edi, [edi+4]

        cmp     al, '('         ; col, row span
        jne     .td_ok

        dec     edi

        mov     dword [edi], ' col'
        mov     dword [edi+4], 'span'
        mov     word  [edi+8], '="'
        lea     edi, [edi+10]

.copy_span:
        mov     al, [esi]
        lea     esi, [esi+1]
        cmp     al, ','
        je      .row_span
        cmp     al, ')'
        je      .end_span

        call    .store_char
        jmp     .copy_span

.row_span:
        mov     dword [edi],    '" ro'
        mov     dword [edi+4],  'wspa'
        mov     dword [edi+8],  'n="'
        lea     edi, [edi+11]
        jmp     .copy_span

.end_span:
        mov     word [edi], '">'
        lea     edi, [edi+2]

        mov     al, [esi]
        lea     esi, [esi+1]

.td_ok:
        or      [.state], fstatePara
        jmp     .process_char

.not_td_open:
        mov     word [edi], '<p'
        lea     edi, [edi+2]
        or      [.state], fstatePara

; is it bullet list?

        cmp     al, '*'
        jne     .close_p_tag

        cmp     byte [esi], ' '
        jne     .close_p_tag

        mov     dword [edi], ' cla'
        mov     dword [edi+4], 'ss="'
        mov     dword [edi+8], 'uli"'
        lea     edi, [edi+12]

        inc     esi
        mov     al, [esi]
        inc     esi

.close_p_tag:
        mov     byte [edi], '>'
        lea     edi, [edi+1]
        jmp     .process_char

.process_inline_code:
        mov     ecx, fstateInlineSource
        mov     ebx, 'code'
        jmp     .ProcessTag

.process_bold:
        mov     ecx, fstateBold
        mov     ebx, 'b'
        jmp     .ProcessTag


.process_italic:
        mov     ecx, fstateItalic
        mov     ebx, 'i'
        jmp     .ProcessTag

.process_underline:
        mov     ecx, fstateUnderline
        mov     ebx, 'u'
        jmp     .ProcessTag

.process_strikeout:
        mov     ecx, fstateStrikeout
        mov     ebx, 's'

; ecx = state mask
; ebx = html tag
.ProcessTag:
        mov     dl, al

        test    [.state], ecx
        jz      .start_tag

; close tag
        not     ecx
        and     [.state], ecx

        mov     word [edi], '</'
        lea     edi, [edi+2]
        jmp     .finish_tag

.start_tag:
        test    [.state], fstateWhite
        jz      .normal_char
        cmp     byte [esi], $20
        je      .normal_char
        cmp     byte [esi], $09
        je      .normal_char
        cmp     byte [esi], $0d
        je      .normal_char
        cmp     byte [esi], $0a
        je      .normal_char

        or      [.state], ecx

; open tag
        mov     byte [edi], '<'
        lea     edi, [edi+1]

.finish_tag:
        mov     [edi], ebx

.taglen:
        lea     edi, [edi+1]
        shr     ebx, 8
        jnz     .taglen

        mov     byte [edi], '>'
        lea     edi, [edi+1]

        jmp     .scan_line2


.white_space:
        test    [.state], fstateWhite
        jnz     .scan_line2

        or      [.state], fstateWhite
        mov     [edi], al
        lea     edi, [edi+1]
        jmp     .scan_line2

; end of line and end of file processing
.end_of_line:
        test    al, al
        jz      @f

        xor     al, $0d xor $0a
        cmp     [esi], al
        jne     @f
        inc     esi
@@:
        or      [.state], fstateWhite

        test    [.state], fstateTextNow
        jnz     .para_ok

        call    .close_paragraph

.para_ok:
        test    [.state], fstateHeader
        jz      .crlf

; insert back link
        cmp     [.fBacklinks], 0
        je      .backlink_ok

        mov     dword [edi],    '<a c'
        mov     dword [edi+4],  'lass'
        mov     dword [edi+8],  '="ba'
        mov     dword [edi+12], 'ck" '
        lea     edi, [edi+16]

        mov     dword [edi],   'href'
        mov     dword [edi+4], '="#B'
        lea     edi, [edi+8]

        call    .InsertID

        mov     word  [edi], '">'
        mov     dword [edi+2], '</a>'
        lea     edi, [edi+6]

.backlink_ok:
        mov     byte [edi], '<'
        lea     edi, [edi+1]

        mov     ecx, [.last_header]
        add     ecx, '/h0>'
        mov     [edi], ecx
        lea     edi, [edi+4]

        and     [.state], not (fstateHeader or fstateTextNow)   ; For the paragraph flow, the header loops like empty line.

.crlf:
        test    [.state], fstateTextPrev or fstateTextNow
        jz     @f
        mov     word [edi], $0a0d
        lea     edi, [edi+2]
@@:
        test    al, al
        jnz     .line_start2

.finish:
        mov     dword [edi], 0
        stdcall StrCat, [.result], [.pHTML]
        retn


.is_link_begin:
        test    [.state], fstateWhite
        jz      .normal_char

.searchID:
        dec     esi

;.SearchLink:
        push    edi
        push    esi

; first compute the hash for the link label
        mov     edx, $811C9DC5                  ; 2166136261              ; FNV offset basis

.hashloop:
        mov     al, [esi]
        lea     esi, [esi+1]

        cmp     al, $20
        je      .hashloop
        cmp     al, $09
        je      .hashloop

        cmp     al, $0d
        je      .not_a_link
        cmp     al, $0a
        je      .not_a_link
        test    al, al
        je      .not_a_link

        xor     dl, al
        imul    edx, $01000193                  ;   16777619              ; FNV prime
        cmp     al, ']'
        jne     .hashloop

; fold the hash to 16 bit value...
        mov     [.linkID_end], esi

        mov     ebx, edx
        shr     ebx, 16
        xor     ebx, edx
        dec     ebx

.hash_table_loop:
        lea     ebx, [ebx+1]
        and     ebx, $ffff

        mov     eax, [.pHashTable]
        mov     edi, [eax+4*ebx]
        mov     esi, [esp]

        test    edi, edi
        jnz     .cmp_labels

.inline_link:                   ; the linkID was not found in the hash table. So, it should be inline link address.
        lea     edi, [esi+1]    ; the address of the link is in esi
        mov     esi, [.linkID_end] ; the address of the end of the linkID.
        jmp     .create_link

.not_a_link:
        pop     esi edi
        mov     al, [esi]
        lea     esi, [esi+1]
        jmp     .normal_char    ; the link address was not found, so it is not link at all.

.cmp_labels:
        mov     al, [esi]
        lea     esi, [esi+1]

        cmp     al, ' '
        je      .cmp_labels
        cmp     al, $09
        je      .cmp_labels

.target:
        mov     ah, [edi]
        lea     edi, [edi+1]

        cmp     ah, ' '
        je      .target
        cmp     ah, $09
        je      .target

        cmp     al, ah
        jne     .hash_table_loop      ; it is not the same label - try again.

        cmp     ah, ']'
        jne     .cmp_labels

; the labels are equal, so search the address.

.create_link:
        or      [.state], fstateLink
        mov     edx, [esp]              ; the start of the linkID.
        cmp     byte [esi], '['         ; is the link has separate ID and text?
        jne     @f
        mov     [esp], esi              ; replace the source address.
@@:
        inc     edx
        cmp     byte [edx], '#'       ; is it internal link?
        je      .internal_link_address

        cmp     byte [edx], '?'       ; is it inline image?
        jne     .maybe_block_image

        xor     [.state], fstateInlineImage or fstateLink
        jmp     .firstnw

.maybe_block_image:
        cmp     byte [edx], '!'       ; is it an image?
        jne     .firstnw
        xor     [.state], fstateImage or fstateLink

.firstnw:
        mov     al, [edi]
        lea     edi, [edi+1]
        cmp     al, ' '
        je      .firstnw
        cmp     al, $09
        je      .firstnw

        dec     edi
        mov     edx, edi

.internal_link_address:
        pop     esi edi

        test    [.state], fstateLink
        jnz     .it_is_link

; it is image.
        mov     dword [edi],    '<img'
        mov     dword [edi+4],  ' cla'
        mov     dword [edi+8],  'ss="'

        test    [.state], fstateImage
        jnz     .block_image

        mov     dword [edi+12], 'ico"'
        jmp     .img_tag_end

.block_image:
        mov     dword [edi+12], 'txt"'

.img_tag_end:
        mov     dword [edi+16], ' src'
        mov     word [edi+20],  '="'
        lea     edi, [edi+22]
        jmp     .link_tag_ok

; yes the link was found.
.it_is_link:
        mov     dword [edi],   '<a h'
        mov     dword [edi+4], 'ref='
        mov     byte [edi+8], '"'
        lea     edi, [edi+9]

.link_tag_ok:
        push    ecx esi
        mov     esi, edx

        cmp     byte [esi], '?'
        je      .skip_img_char

        cmp     byte [esi], '!'
        jne     .copy_link_pre

.skip_img_char:
        inc     esi

.copy_link_pre:
        cmp     [.procFixLink], 0
        je      .copy_link_loop

        stdcall [.procFixLink], esi, edi
        mov     edi, eax
        mov     esi, edx

.copy_link_loop:
        mov     al, [esi]
        lea     esi, [esi+1]

        cmp     al, $0d
        je      .end_link
        cmp     al, $0a
        je      .end_link
        cmp     al, ']'
        je      .end_link
        test    al, al
        jz      .end_link

        mov     [edi], al
        lea     edi, [edi+1]
        jmp     .copy_link_loop

.end_link:
        pop     esi ecx

        test    [.state], fstateImage or fstateInlineImage
        jnz     .finalize_image

        mov     word [edi], '">'
        lea     edi, [edi+2]

.go_link_text:
        and     [.state], not fstateWhite
        inc     esi
        cmp     byte [esi], '#'
        jne     .scan_line2
        inc     esi
        jmp     .scan_line2

.finalize_image:
        mov     dword [edi],   '" al'
        mov     dword [edi+4], 't="'
        lea     edi, [edi+7]
        and     [.state], not fstateWhite
        jmp     .go_link_text

;....................................................................

.is_link_end:
        test    [.state], fstateLink
        jnz     .close_link_tag

        test    [.state], fstateImage or fstateInlineImage
        jz      .normal_char

; close the image tag
        mov     dword [edi], '" />'
        lea     edi, [edi+4]

        and     [.state], not (fstateImage or fstateInlineImage)
        jmp     .scan_line2

.close_link_tag:
        mov     dword [edi], '</a>'
        lea     edi, [edi+4]

        and     [.state], not fstateLink
        jmp     .scan_line2

;....................................................................
; Processing of block source code
.copy_source:

.source_line:

        cmp     edi, [.limit]
        jb      @f
        mov     dword [edi], 0
        stdcall StrCat, [.result], [.pHTML]
        mov     edi, [.pHTML]
@@:

        cmp     dword [esi], ';end'
        je      .end_source_block

.copy_source_line:
        mov     al, [esi]
        lea     esi, [esi+1]

        call    .store_char

        test    al, al
        jz      .end_source_block2

        cmp     al, $0d
        je      .end_source_line
        cmp     al, $0a
        jne     .copy_source_line

.end_source_line:
        xor     al, $0d xor $0a
        cmp     [esi], al
        jne     .source_line

        inc     esi
        mov     [edi], al
        lea     edi, [edi+1]
        jmp     .source_line

.end_source_block2:
        dec     esi

.end_source_block:
        mov     dword [edi],   '</pr'
        mov     dword [edi+4], 'e></'
        mov     dword [edi+8], 'div>'
        mov     word  [edi+12], $0a0d
        lea     edi, [edi+14]

        and     [.state], not fstateBlockSource
        jmp     .skip2

;....................................................................

.close_paragraph:
        test    [.state], fstatePara
        jz      .close_para_ok

        test    [.state], fstateTable
        jnz     .close_td

        mov     dword [edi], '</p>'
        lea     edi, [edi+4]
        jmp     .close_para_ok

.close_td:
        mov     dword [edi], '</td'
        mov     dword [edi+4], '>'+($0a0d shl 8)
        lea     edi, [edi+7]

.close_para_ok:
        and     [.state], not fstatePara
        retn

;....................................................................
; horizontal rule element

.horiz_rule:
        call    .close_paragraph

        mov     dword [edi], '<hr '
        mov     dword [edi+4], '/>'+($0a0d shl 16)
        lea     edi, [edi+8]
        jmp     .skip2

;....................................................................
; Processing of the block elements.

.block_element:
        cmp     dword [esi], ';end'
        je      .end_block

        cmp     dword [esi], ';beg'
        jne     .not_code
        cmp     word [esi+4], 'in'
        jne     .not_code

; code block
        call    .close_paragraph

        mov     dword [edi],    '<div'
        mov     dword [edi+4],  ' cla'
        mov     dword [edi+8],  'ss="'
        mov     dword [edi+12], 'code'
        mov     dword [edi+16], '"><p'
        mov     dword [edi+20], 're>'
        lea     edi, [edi+23]
        or      [.state], fstateBlockSource
        jmp     .skip2


.not_code:
        cmp     dword [esi], ';tab'
        jne     .not_table
        cmp     word [esi+4], 'le'
        jne     .not_table

; table block;
        call    .close_paragraph

        mov     al, fblkTable
        call    .PushBlock

        mov     dword [edi], '<tab'
        mov     dword [edi+4], 'le c'
        mov     dword [edi+8], 'lass'
        mov     dword [edi+12],'="tx'
        mov     dword [edi+16], 't"><'
        mov     dword [edi+20], 'tr>'+($0d shl 24)
        mov     byte  [edi+24], $0a
        lea     edi,  [edi+25]

        or      [.state], fstateTable
        jmp     .skip2


.not_table:
        cmp     dword [esi], ';---'
        jne     .not_row

.table_row:
        call    .close_paragraph

        mov     dword [edi],   '</tr'
        mov     dword [edi+4], '><tr'
        mov     byte  [edi+8], '>'
        lea     edi, [edi+9]
        jmp     .skip2


.not_row:
        cmp     dword [esi], ';quo'
        jne     .not_quote
        cmp     word [esi+4], 'te'
        jne     .not_quote

; block quote
        call    .close_paragraph

        mov     al, fblkQuote
        call    .PushBlock

        mov     dword [edi],   '<div'
        mov     dword [edi+4], ' cla'
        mov     dword [edi+8], 'ss="'
        mov     dword [edi+12],'bq">'
        lea     edi, [edi+16]

        jmp     .skip2


.not_quote:
        cmp     dword [esi], ';key'
        jne     .not_keywords
        cmp     dword [esi+4], 'word'
        jne     .not_keywords
        cmp     byte [esi+8], 's'
        jne     .not_keywords

        add     esi, 9
        mov     ecx, [.keywords]
        jmp     .append_line_to_string

.not_keywords:
        cmp     dword [esi], ';des'
        jne     .not_desc
        cmp     dword [esi+4], 'crip'
        jne     .not_desc
        cmp     dword [esi+8], 'tion'
        jne     .not_desc

        add     esi, 12
        mov     ecx, [.description]

.append_line_to_string:


        push    esi     ; first argument of

        nop

.seek_eoa:
        mov     al, [esi]
        lea     esi, [esi+1]

        test    al, al
        jz      .end_of_appended

        cmp     al, $0d
        je      .end_of_appended

        cmp     al, $0a
        jne     .seek_eoa

.end_of_appended:
        dec     esi
        mov     byte [esi], 0

        stdcall StrCat, ecx ; start address from the stack
        mov     [esi], al   ; restore the text
        jmp     .skip2


.not_desc:
        jmp     .skip2          ; ";" at the begining without keyword is comment. The line is ignored.


.end_block:
        call    .close_paragraph

.do_end_block:
        call    .PopBlock

        cmp     eax, fblkQuote
        je      .end_quote
        cmp     eax, fblkTable
        je      .end_table

        jmp     .skip2

.end_quote:
        mov     dword [edi], '</di'
        mov     word  [edi+4], 'v>'
        lea     edi, [edi+6]
        jmp     .skip2

.end_table:

        mov     dword [edi], '</tr'
        mov     dword [edi+4], '>'+($0a0d shl 8)
        mov     dword [edi+7], '</ta'
        mov     dword [edi+11],'ble>'
        mov     word  [edi+15], $0a0d
        lea     edi, [edi+17]
        and     [.state], not fstateTable
        jmp     .skip2

;....................................................................
.PushBlock:
        push    ecx
        mov     ecx, [.pblock]
        mov     [.blocks+ecx], al
        inc     ecx
        cmp     ecx, 1024
        jb      @f
        dec     ecx
@@:
        mov     [.pblock], ecx
        pop     ecx
        retn

.PopBlock:
        mov     eax, [.pblock]
        dec     eax
        jns     @f
        xor     eax, eax
        mov     [.pblock], eax
        retn
@@:
        mov     [.pblock], eax
        movzx   eax, [.blocks+eax]
        retn

;....................................................................
; processing link definitions in the second pass.
.link_definition:

        mov     al, [esi+1]
        cmp     al, '#'
        je      .define_anchor

        cmp     al, '^'
        jne     .skip2


;.define_footnote:

        jmp     .skip2                  ; any other variant should be
                                        ; stripped from the text.

.define_anchor:
        add     esi, 2
        mov     dword [edi], '<p>'
        lea     edi, [edi+3]
        or      [.state], fstatePara or fstateTextNow

        mov     dword [edi],    '<a c'
        mov     dword [edi+4],  'lass'
        mov     dword [edi+8],  '="a"'
        mov     dword [edi+12], ' id='
        mov     byte [edi+16],  '"'
        lea     edi, [edi+17]

        push    esi
        call    .copy_id

        mov     dword [edi],   '" hr'
        mov     dword [edi+4], 'ef="'
        mov     byte [edi+8], '#'
        lea     edi, [edi+9]

        pop     esi
        call    .copy_id

        mov     word [edi], '">'
        lea     edi, [edi+2]

        mov     dword [edi], '</a>'
        lea     edi, [edi+4]

        mov     al, [esi]
        jmp     .normal_char

.copy_id:
        mov     al, [esi]
        lea     esi, [esi+1]
        cmp     al, ']'
        je      .cpid_ok
        cmp     al, $0d
        je      .cpid_ok
        cmp     al, $0a
        je      .cpid_ok
        test    al, al
        jz      .cpid_ok

        mov     [edi], al
        lea     edi, [edi+1]
        jmp     .copy_id

.cpid_ok:
        retn

;....................................................................

; processing header items and building of the table of contents.

.header2:
        xor     ecx, ecx

.scan_level2:
        inc     ecx
.scan_space2:
        lea     esi, [esi+1]
        mov     al, [esi]
        cmp     al, '#'
        je      .scan_level2
        cmp     al, ' '
        je      .scan_space2
        cmp     al, $09
        je      .scan_space2

        cmp     al, $0d
        je      .end_of_line
        cmp     al, $0a
        je      .end_of_line

        cmp     ecx, 6
        jbe     @f
        mov     ecx, 6
@@:

; create ID
        call    .BuildID

        shl     ecx, 16
        mov     [.last_header], ecx

        add     ecx, '<h0 '
        mov     [edi], ecx
        mov     dword [edi+4], 'id="'
        mov     byte [edi+8], 'H'
        lea     edi, [edi+9]

; insert the id here.

        call    .InsertID

        mov     word [edi], '">'
        lea     edi, [edi+2]

        cmp     [.last_header], 1 shl 16
        je      @f
        call    .InsertID
        mov     dword [edi], '&nbs'
        mov     word [edi+4], 'p;'
        lea     edi, [edi+6]
@@:
        or      [.state], fstateHeader
        jmp     .scan_line2

.skip2:
        mov     al, [esi]
        lea     esi, [esi+1]

        test    al, al
        jz      .finish
        cmp     al, $0d
        je      .skip_eol
        cmp     al, $0a
        jne     .skip2

.skip_eol:
        xor     al, $0d xor $0a
        cmp     [esi], al
        jne     .line_start2
        inc     esi
        jmp     .line_start2

;----- End of .SecondPass ------------------------------


; ecx - level of the header 1..6
.BuildID:
        push    eax ebx ecx edx edi

        lea     edi, [.IdString]
        cmp     ecx, 1
        jbe     .main

        sub     ecx, 2
        push    ecx

        inc     [.cntH2+4*ecx]

.zero:
        inc     ecx
        cmp     ecx, 5
        je      .end_zero
        mov     [.cntH2+4*ecx], 0
        jmp     .zero

.end_zero:
        xor     ebx, ebx
        mov     ecx, 10

.loop_numbers:
        mov     eax, [.cntH2+4*ebx]
        call    _NumToStrU
        mov     al, '.'
        stosb
        inc     ebx
        cmp     ebx, [esp]
        jbe     .loop_numbers

        pop     ecx
        jmp     .finID

.main:
        mov     eax, 'main'
        stosd

.finID:
        lea     eax, [.IdString]
        sub     edi, eax
        mov     [.IdLen], edi

        pop     edi edx ecx ebx eax
        retn

.InsertID:
        push    ecx esi

        lea     esi, [.IdString]
        mov     ecx, [.IdLen]

        rep movsb

        pop     esi ecx
        retn
endp









endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/data/md5lib.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: OS independent MD5 library.
;
;  Target OS: Any
;
;  Dependencies: memory.asm
;
;  Notes: The original code is from iblis. I changed it a bit, maybe losing performance,
;         but making it more structured.
;
;_________________________________________________________________________________________

module "MD5 library"

struct TContextMD5
    .__cntx rb 88
    .value  rb 16
ends


iglobal
  if used ___MD5InternalData
    ___MD5InternalData db     0,1,1,5,5,3,0,7, \
                              7,5,5,5,5,4,5,6, \
                              4,7,5,7,6,4,5,6
  end if
endg


uglobal
  if used ___MD5SineTable
    ___MD5SineTable  rd       65
  end if
endg



if used md5_open
initialize ___md5_init
begin
        xor     eax, eax
        finit
        pushd   4F800000h
        pushd   0
        fstcw   word [esp+2]
        fstcw   word [esp]
        or      word [esp], 0F3Fh
        fldcw   word [esp]
        push    1
    @@: fild    dword [esp]
        fsin
        fabs
        fmul    dword [esp+8]
        fistp   qword [eax*4+___MD5SineTable]
        inc     dword [esp]
        inc     eax
        test    al, 40h
        jz      @b
        fldcw   word [esp+6]
        add     esp, 12
        return
endp
end if




;******************************************************
; Computes MD5 hash of the data block from [.pData] with
; length in [.pLen]
; Returns new string handle in eax containing the hash of
; the data.
;******************************************************
proc DataMD5, .pData, .pLen
begin
        push    ebx esi edi

        stdcall md5_open
        mov     ebx, eax

        stdcall md5_read, ebx, [.pData], [.pLen]
        stdcall md5_getvalue, ebx

        stdcall StrNew
        mov     edi, eax
        lea     esi, [ebx+TContextMD5.value]
        mov     ecx, 16

.loop:
        movzx   eax, byte [esi]
        inc     esi
        stdcall NumToStr, eax, ntsUnsigned or ntsHex or ntsFixedWidth + 2
        push    eax
        stdcall StrCat, edi, eax
        stdcall StrDel ; from the stack
        loop    .loop

        stdcall StrLCase, edi
        stdcall FreeMem, ebx

        mov     eax, edi
        pop     edi esi ebx
        return
endp






;............................................................................
; md5_open is  used to allocate and initialize TContextMD5 structure for use with
; subsequent processing.
;
; Arguments:
;   no
;
; Return Value: EAX - pointer to the allocated TContextMD5 structure.
;
; Modifies Registers: EAX
;............................................................................
proc md5_open
begin
        push    edi

        stdcall GetMem, sizeof.TContextMD5
        mov     edi, eax
        push    eax

        mov     al, 01h

    @@: stosb
        add     al, 22h
        jnc     @b

        mov     al, 0FEh
    @@: stosb
        sub     al, 22h
        jnc     @b

        xor     eax, eax
        stosd
        stosd

        pop     eax edi
        return
endp




;............................................................................
; MD5_Read scans a  block of data and  updates the  working context.  Call it
; once on a single  block of data, or  call it multiple  times on consecutive
; blocks of data, before retrieving the MD5 signature with MD5_Digest
;
; Arguments:
;   lpMD5CTXT - address of an initialized MD5CTXT structure
;   lpBuf     - address of a contiguous block of data
;   bufLen    - the size, in bytes, of the block of data
;
; Return Value: None
;
; Modifies Registers: None
;............................................................................
proc md5_read ;, .lpMD5CTXT, .lpBuf, .bufLen
begin
        pushad
        mov     esi, [esp+40]
        mov     ebp, [esp+36]
        lea     edi, [ebp+24]
        mov     edx, [esp+44]
        mov     ebx, edi
        mov     eax, edx
        shl     eax, 3
        mov     ecx, edx
        shr     ecx, 29
        push    dword [ebp+16]
        add     [ebp+16], eax
        adc     [ebp+20], ecx
        pop     eax
        shr     eax, 3
        and     eax, 3Fh
   .mn: xor     ecx, ecx
        mov     cl, 40h
        sub     ecx, eax
        cmp     ecx, edx
        jbe     @f
        mov     ecx, edx
    @@: sub     edx, ecx
        add     edi, eax
        add     eax, ecx
        rep     movsb
        mov     edi, ebx
        cmp     eax, 40h
        jb      @f

        stdcall ___md5_BTrnsf, ebx, edi

    @@: xor     eax, eax
        or      edx, edx
        jnz     .mn
        popad
        ret     12
endp




;............................................................................
; md5_getvalue is used to retrieve the MD5 hash for the working context. It may
; be called at any point during a buffer read to get the current MD5 hash for
; all data scanned up to that point.  It does not modify the contexutal data,
; so this procedure may be called as many times as needed.
; The value is stored in the context structure TContextMD5.value
;
; Arguments:
;   .pContextMD5 - address of an TContextMD5 structure
;
; Return Value: None
;
; Modifies Registers: None
;............................................................................
proc md5_getvalue   ;, .pContextMD5
begin
        pushad
        mov     esi, dword [esp+36]
        lea     edi, [esi+TContextMD5.value]
        lea     ebp, [esi+16]
        mov     ebx, edi
        sub     esp, 64
        movsd
        movsd
        movsd
        movsd
        lodsd
        shr     eax, 3
        add     esi, 4
        and     eax, 3Fh
        mov     edi, esp
        mov     ecx, eax
        rep     movsb
        inc     eax
        sub     ecx, eax
        mov     al, 80h
        stosb
        xor     eax, eax
        cmp     ecx, -56
        jae     @f
        xor     eax, eax
        add     ecx, 64
        rep     stosb
        mov     edi, esp

        stdcall ___md5_BTrnsf, ebx, edi

    @@: xor     eax, eax
        add     ecx, 56
        rep     stosb
        mov     esi, ebp
        movsd
        movsd

        stdcall ___md5_BTrnsf, ebx, esp

        add     esp, 64
        popad
        ret     4
endp




proc ___md5_BTrnsf   ;, .phash, .lpBlock
begin
        pushad
        mov     eax, dword [esp+36]
        xor     ecx, ecx
        mov     cl, 4
    @@: push    dword [eax]
        add     eax, 4
        loop    @b
   .mn: mov     ebp, ecx
        shr     ebp, 12
        add     dl, dh
        and     dl, 0Fh
        test    ch, 03h
        jnz     @f
        xor     cl, cl
        test    ch, 0Fh
        jnz     @f
        mov     esi, ___MD5InternalData
        mov     edx, dword [esi+ebp*2]
        mov     ebx, dword [esi+ebp*4+8]
    @@: add     cl, bl
        ror     ebx, 8
        push    edx
        push    ecx
        push    ebx
        mov     ebx, dword [esp+20]
        mov     ecx, dword [esp+16]
        mov     edx, dword [esp+12]
        test    ebp, 02h
        jnz     .hi
        test    ebp, 01h
        jnz     @f
        mov     eax, ebx
        and     ebx, ecx
        not     eax
        and     eax, edx
        or      eax, ebx
        jmp     .fghi
    @@: mov     eax, edx
        and     edx, ebx
        not     eax
        and     eax, ecx
        or      eax, edx
        jmp     .fghi
   .hi: test    ebp, 01h
        jnz     @f
        mov     eax, ebx
        xor     eax, ecx
        xor     eax, edx
        jmp     .fghi
    @@: mov     eax, edx
        not     eax
        or      eax, ebx
        xor     eax, ecx
 .fghi: pop     ebx
        pop     ecx
        pop     edx
        add     eax, dword [esp+12]
        mov     esi, dword [esp+56]
        movzx   edi, dl
        add     eax, dword [esi+edi*4]
        movzx   esi, ch
        add     eax, dword [___MD5SineTable+esi*4]
        rol     eax, cl
        add     eax, dword [esp+8]
        mov     dword [esp+12], eax
        mov     esi, esp
        mov     edi, esp
        lodsd
        movsd
        movsd
        movsd
        stosd
        inc     ch
        test    ch, 40h
        jz      .mn
        mov     eax, dword [esp+52]
        xor     ecx, ecx
        mov     cl, 4
        sub     eax, ecx
    @@: pop     edx
        add     dword [eax+ecx*4], edx
        loop    @b
        popad
        ret     8
endp


endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/data/memstream.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
struct TMemoryStream
  .size    dd   ?
  .offset  dd   ?
  label .data byte
ends


;------------------------------------------------------------
; Returns: ebx - base addr
;          edi - offset to put data.
;------------------------------------------------------------
proc GetStreamRoom, .ptrVarStream, .room
begin
        push    esi ecx

        mov     esi, [.ptrVarStream]
        mov     ebx, [esi]              ; pointer to the array

        mov     edi, [ebx+TMemoryStream.offset]
        mov     eax, [ebx+TMemoryStream.size]
        sub     eax, edi
        cmp     eax, [.room]      ; check for enough room
        jge     .sizeok

        mov     ecx, [ebx+TMemoryStream.size]
        call    [ResizeIt]
        push    ecx

        stdcall ResizeMem, ebx, ecx
        mov     ebx, eax
        mov     [esi], eax  ; new pointer
        jc      .exit

        mov     [ebx+TMemoryStream.size], ecx   ; new size.

.sizeok:
        mov     eax, [.room]
        add     [ebx+TMemoryStream.offset], eax

.exit:
        pop     ecx esi
        return
endp




proc SetStreamOfs, .ptrVarStream, .offset
begin
        push    esi edi ebx

        mov     edi, [.ptrVarStream]
        mov     eax, [edi]
        mov     ebx, [.offset]
        mov     esi, [eax+TMemoryStream.size]

        cmp     ebx, esi
        jl      .sizeok

        lea     esi, [ebx+$1000]        ; new size
        stdcall ResizeMem, eax, esi
        mov     [edi], eax

.sizeok:
        mov     [eax+TMemoryStream.size], esi
        mov     [eax+TMemoryStream.offset], ebx
        pop     ebx edi esi
        return
endp





proc CreateMemoryStream, .ptrVarStream, .initsize
begin
        push    ebx esi

        mov     ebx, [.initsize]
        mov     esi, [.ptrVarStream]
        add     ebx, sizeof.TMemoryStream

        stdcall GetMem, ebx
        mov     [esi], eax
        mov     [eax+TMemoryStream.size], ebx
        mov     [eax+TMemoryStream.offset], TMemoryStream.data

        pop     esi ebx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































Deleted freshlib/data/strlib.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: OS independent string manipulation library.
;
;  Target OS: Any
;
;  Dependencies: memory.asm; arrays.asm
;
;  Notes:
;
;_________________________________________________________________________________________

module "String library"

STR_MINSTRLEN = 127      ; must be N*8-1
STR_SEARCH_ONE_ATEMPT = 100

struc string {
  .capacity dd ?
  .len      dd ?
  label .data byte
}

virtual at -(sizeof.string)
  string string
  sizeof.string = $-string
end virtual


; NumToStr flags
ntsSigned       = $00000
ntsUnsigned     = $10000
ntsFixedWidth   = $20000


ntsBin  = $0200
ntsQuad = $0400
ntsOct  = $0800
ntsDec  = $0a00
ntsHex  = $1000


; Global variable, storing parameters of dynamic strings list.
uglobal
  if used InitStrings
    ptrStrTable       dd  ?      ; StrLib strings arrray. Contains pointers to the memory allocated for strings.
    StrMutex         dd  ?      ; mutex that allows thread safety of StrLib
  end if
endg



; < OS independent library functions >

;************************************************************************************
; Allocates memory for string table and allocates memory for strings.
; Start it before any work with strings. (Or better use InitializeAll macro)
; Returns 0 if failed to allocate needed memory.
;************************************************************************************
if used ptrStrTable
initialize InitStrings
begin
        StrLib = 1

        stdcall MutexCreate, 0, StrMutex

        stdcall CreateArray, 4
        jc      .finish

        mov     [ptrStrTable], eax
        mov     [eax+TArray.lparam], 0     ; lParam is the last allocated handle number

.finish:
        stdcall MutexRelease, StrMutex
        return
endp
end if

;**************************************************************************************
; Frees all memory used for strings library
; Call it before exit of the program or use FinalizeAll macro.
;**************************************************************************************
if used InitStrings
finalize FreeStrings
begin
        stdcall WaitForMutex, StrMutex, -1

        mov     esi, [ptrStrTable]
        mov     ecx, [esi+TArray.count]
        xor     ebx,ebx

.freeloop:
        dec     ecx
        js      .endloop

        cmp     [esi+TArray.array+4*ecx], ebx
        je      .freeloop

        stdcall FreeMem, [esi+TArray.array+4*ecx]
        jmp     .freeloop

.endloop:
        stdcall FreeMem, esi
        mov     [ptrStrTable], ebx

        stdcall MutexDestroy, StrMutex
        return
endp
end if



;**************************************************************************************
;  Returns:
;    CF=0 no error; eax = pointer in memory of the hString
;    CF=1 on error - hString is handle, but is not in the table.*
;**************************************************************************************
proc StrPtr, .hString
begin
        stdcall WaitForMutex, StrMutex, -1

        mov     eax, [.hString]

        xor     eax, $c0000000
        test    eax, $c0000000
        jnz     .pointer

        push    ebx

        mov     ebx, [ptrStrTable]
        cmp     eax, [ebx+TArray.count]
        jae     .notfound

        mov     eax, [ebx+TArray.array+4*eax]
        test    eax, eax
        jz      .notfound

        add     eax, sizeof.string
        pop     ebx

.finok:
        clc
.finish:
        stdcall MutexRelease, StrMutex
        return

.pointer:
        xor     eax, $c0000000
        jmp     .finok

.notfound:
        stc
        pop     ebx
        jmp     .finish
endp

;**************************************************************************************
;  Creates new empty string and returns handle
;  Return: handle of the new created string.
;**************************************************************************************
proc StrNew
begin
        push    ecx edx esi

        stdcall WaitForMutex, StrMutex, -1

; Search for first empty place.
        mov     edx, [ptrStrTable]
        mov     ecx, STR_SEARCH_ONE_ATEMPT       ; search only limited count of items
        cmp     ecx, [edx+TArray.count]
        jb      @f
        mov     ecx, [edx+TArray.count]
@@:
;        cmp     [flagStringFastAdd], 0
;        jne     .notfound

        mov     esi,[edx+TArray.lparam]
        xor     eax,eax

.search:
        dec     ecx
        js      .notfound

        inc     esi
        cmp     esi, [edx+TArray.count]
        jne     @f
        xor     esi,esi
@@:
        cmp     [edx+TArray.array+4*esi], eax
        je      .found
        jmp     .search

.notfound:
        mov     [edx+TArray.lparam], esi        ; store the place where the search ends this time.
        mov     esi, [edx+TArray.count]
        stdcall AddArrayItems, edx, 1
        mov     [ptrStrTable], edx

.found:
        mov     [edx+TArray.lparam], esi
        stdcall GetMem, STR_MINSTRLEN + sizeof.string + 1
        mov     [edx+TArray.array+4*esi], eax
        mov     [eax+sizeof.string+string.capacity], STR_MINSTRLEN

        mov     eax, esi
        or      eax, $c0000000

        stdcall MutexRelease, StrMutex
        pop     esi edx ecx
        return
endp


;**************************************************************************
; Deletes the string if it is possible.
;**************************************************************************
proc StrDel, .hString
begin
        push    eax ecx esi

        stdcall WaitForMutex, StrMutex, -1

        mov     esi, [ptrStrTable]
        mov     ecx, [.hString]
        jecxz   .finish

        xor     ecx, $c0000000
        test    ecx, $c0000000
        jnz     .pointer

        cmp     ecx, [esi+TArray.count]
        jae     .finish

.free:
        stdcall FreeMem, [esi+TArray.array+4*ecx]
        mov     [esi+TArray.array+4*ecx], 0

.finish:
        stdcall MutexRelease, StrMutex
        pop     esi ecx eax
        return

.pointer:
        xor     ecx, $c0000000

; search the pointer in the table.
        lea     eax, [ecx-sizeof.string]
        mov     ecx, [esi+TArray.count]

.search:
        dec     ecx
        js      .finish
        cmp     [esi+TArray.array+4*ecx], eax
        jne     .search
        jmp     .free
endp


;**************************************************************************
; Duplicates given string, and returns a handle to new one
;**************************************************************************
proc StrDup, .hSource
begin
        stdcall StrNew
        stdcall StrCopy, eax, [.hSource]
        return
endp


;**************************************************************************
; Arguments:
;  hString - handle or pointer to the string (static or dynamic)
; Returns:
;   CF=0; eax = length of the string in bytes.
;   CF=1; eax = 0 in case, the handle of the string can't be found in the
;               string table or the pointer is NULL.
;
; If pointer is passed the the procedure, it should be dword aligned and
; all bytes of the string including zero terminator to be accessed on
; qword boundary. Although, the zero terminator can be single byte zero.
;
; The performance of the procedure is high for pointers and
; instant for handles (the StrLib created string doesn't need any
; search, because the length is precomputed)
;**************************************************************************

proc StrLen, .hString    ; proc StrLen [hString]
begin
        mov     eax, [.hString]
        xor     eax, $c0000000
        test    eax, $c0000000
        jnz     .pointer

        stdcall StrPtr, [.hString]
        jc      .error

        mov     eax, [eax+string.len]
        clc
        return

.error:
        xor     eax, eax
        stc
        return

.pointer:
        push    ecx edx esi edi

        xor     eax, $c0000000

; align on dword
.byte1:
        test    eax, 3
        jz      .scan

        cmp     byte [eax], 0
        je      .found

        inc     eax
        jmp     .byte1

.scan:
        mov     ecx, [eax]
        mov     edx, [eax+4]

        lea     eax, [eax+8]

        lea     esi, [ecx-$01010101]
        lea     edi, [edx-$01010101]

        not     ecx
        not     edx

        and     esi, ecx
        and     edi, edx

        and     esi, $80808080
        and     edi, $80808080

        or      esi, edi
        jz      .scan

        sub     eax, 9

; byte 0 was found: so search by bytes.
.byteloop:
        lea     eax, [eax+1]
        cmp     byte [eax], 0
        jne     .byteloop

.found:
        sub     eax, [.hString]
        clc
        pop     edi esi edx ecx
        return
endp





; This procedure calculates the length of zero terminated string and "fixes" [string.len] field.
; StrFixLen should be call when the content of the string is created by call to external to StrLib
; procedures - for example Win32 API functions.
;
proc StrFixLen, .hstring
begin
        push    eax ecx
        stdcall StrPtr, [.hstring]
        mov     ecx, eax
        stdcall StrLen, eax
        mov     [ecx+string.len], eax
        pop     ecx eax
        return
endp




;***************************************************************************
; If the hString is larger than length - do nothing
; If the hString is smaller than length -> set the length of string to length
; returns pointer to the new (old) string
;
; Arguments:
;   hString - string handle. /not pointer!/
;   capacity - new string length.
; Returns:
;   eax: pointer to the string.
;   CF: error flag. If 1 the pointer to the string is returned, but
;       the capacity is not changed.
;***************************************************************************
proc StrSetCapacity, .hString, .capacity
begin
        push    ebx ecx esi

        stdcall WaitForMutex, StrMutex, -1

        mov     eax, [.hString]

        xor     eax, $c0000000
        test    eax, $c0000000
        jnz     .pointer

        mov     esi, eax

        mov     ebx, [ptrStrTable]
        cmp     esi, [ebx+TArray.count]
        jae     .pointer

        mov     eax, [ebx+TArray.array+4*esi]   ; pointer to the string.
        mov     ecx, [.capacity]
        cmp     ecx, STR_MINSTRLEN
        jge     @f
        mov     ecx, STR_MINSTRLEN
@@:
        cmp     [eax+sizeof.string+string.capacity], ecx
        jae     .sizeok

        shl     ecx, 1
        add     ecx, sizeof.string+4+7
        and     cl,  $f8                ; align the size to 8 bytes

        stdcall ResizeMem, eax, ecx
        jc      .error

        lea     ecx, [ecx-(sizeof.string+4)]
        mov     [ebx+TArray.array+4*esi], eax
        mov     [eax+sizeof.string+string.capacity], ecx

.sizeok:
        add     eax, sizeof.string

.finish:
        stdcall MutexRelease, StrMutex
        pop     esi ecx ebx
        return

.error:
        int3
        add     eax, sizeof.string
        stc
        jmp     .finish

.pointer:
        xor     eax, $c0000000
        stc
        jmp     .finish
endp


;***************************************************************************************
;  Copies source to destination string.
;  Arguments:
;     dest - destination string (handle only)
;     source -  source string (handle or pointer)
;  Returns: nothing
;***************************************************************************************
proc StrCopy, .dest, .source
begin
        push    esi edi eax ecx

        stdcall StrLen, [.source]
        mov     ecx, eax

        stdcall StrSetCapacity, [.dest], ecx
        mov     edi, eax
        jc      .error

        stdcall StrPtr, [.source]
        mov     esi, eax

        mov     [edi+string.len], ecx

        inc     ecx
        mov     eax, ecx
        shr     ecx, 2
        rep movsd
        mov     ecx, eax
        and     ecx, 3
        rep movsb
        clc

.finish:
        pop     ecx eax edi esi
        return

.error:
        int3
        jmp     .finish

endp



proc CharLCase, .char
begin
        mov     eax, [.char]
        cmp     eax, 'A'
        jb      .end
        cmp     eax, 'Z'
        ja      .end

        add     eax, 'a'-'A'
.end:
        return
endp


;***************************************************************************************
; Compares two strings for greater, equal or less.
; Returns eax = 0 if the strings are equal.
;         eax = 1 if .str1 is grater than .str2
;         eax = -1 if .str1 is less than .str2
;***************************************************************************************
proc StrCompSort2, .str1, .str2, .fCaseSensitive
begin
        push    ebx ecx esi edi

        mov     eax, [.str1]
        mov     ecx, [.str2]

        cmp     eax, ecx
        je      .equal

        stdcall StrPtr, [.str1]
        mov     esi,eax
        stdcall StrPtr, [.str2]
        mov     edi,eax


.cmp_loop:
        stdcall DecodeUtf8, [esi]
        add     esi, edx
        cmp     [.fCaseSensitive], 0
        jne     @f
        stdcall CharLCase, eax
@@:
        mov     ecx, eax

        stdcall DecodeUtf8, [edi]
        add     edi, edx
        cmp     [.fCaseSensitive], 0
        jne     @f
        stdcall CharLCase, eax
@@:
        test    ecx, ecx
        jz      .endstr
        test    eax, eax
        jz      .endstr

        cmp     ecx, eax
        je      .cmp_loop

        ja      .greater
        jmp     .less

.endstr:
        cmp     ecx, eax
        ja      .greater
        jb      .less

.equal:
        xor     eax, eax

.finish:
        pop     edi esi ecx ebx
        return

.greater:
        mov     eax, 1
        jmp     .finish

.less:
        mov     eax, -1
        jmp     .finish
endp






;***************************************************************************************
; Compares two strings - case sensitive.
; Returns CARRY = 1 if the strings are equal.
; Returns CARRY = 0 if the strings are different.
;
; As long as this function uses StrLen, it will be very fast on handles and relatively
; slow on pointers.
;***************************************************************************************
proc StrCompCase, .str1, .str2
begin
        push    eax ecx esi edi

        mov     eax, [.str1]
        mov     ecx, [.str2]

        cmp     eax, ecx
        je      .equal

        test    eax, eax
        jz      .noteq

        test    ecx, ecx
        jz      .noteq

        stdcall StrLen, eax
        push    eax
        stdcall StrLen, ecx

        pop     ecx
        cmp     eax, ecx
        jne     .noteq

        stdcall StrPtr, [.str1]
        mov     esi,eax
        stdcall StrPtr, [.str2]
        mov     edi,eax

        mov     eax, ecx
        shr     ecx, 2
        repe cmpsd
        jne     .noteq
        mov     ecx, eax
        and     ecx, 3
        repe cmpsb
        jne     .noteq

.equal:
        stc
        pop     edi esi ecx eax
        return

.noteq:
        clc
        pop     edi esi ecx eax
        return
endp


;***************************************************************************************
; Compares two strings - case NOT sensitive.
; Returns CARRY = 1 if the strings are equal.
; Returns CARRY = 0 if the strings are different.
;
; relatively slow, especially on equal strings, passed as pointers - this is the worst
; case. The nontrivial best case is "strings with different lengths passed as handles."
;***************************************************************************************
proc StrCompNoCase, .str1, .str2
begin
        push    eax ebx ecx edx esi edi

        mov     eax, [.str1]
        mov     ecx, [.str2]

        cmp     eax, ecx
        je      .equal

        test    eax, eax
        jz      .noteq

        test    ecx, ecx
        jz      .noteq

        stdcall StrLen, eax
        push    eax
        stdcall StrLen, ecx

        pop     ecx
        cmp     eax, ecx
        jne     .noteq

        stdcall StrPtr, [.str1]
        mov     esi,eax
        stdcall StrPtr, [.str2]
        mov     edi,eax


        mov     ebx, ecx
        shr     ecx, 2
        and     ebx, 3

.dword:
        dec     ecx
        js      .byte

        mov     eax, [esi]
        mov     edx, [edi]

        and     eax, $40404040
        and     edx, $40404040
        shr     eax, 1
        shr     edx, 1
        or      eax, [esi]
        or      edx, [edi]

        lea     esi, [esi+4]
        lea     edi, [edi+4]

        cmp     eax, edx
        jne     .noteq
        jmp     .dword

.byte:
        dec     ebx
        js      .equal

        mov     al, [esi]
        mov     ah, [edi]

        and     eax, $ffff
        mov     edx, eax
        and     eax, $4040
        shr     eax, 1
        or      eax, edx

        inc     esi
        inc     edi

        cmp     al, ah
        je      .byte

.noteq:
        clc
        pop     edi esi edx ecx ebx eax
        return

.equal:
        stc
        pop     edi esi edx ecx ebx eax
        return

endp



;**********************************************************
;  Creates string and assigns it to variable. If variable
;  already contains string handle, the old string will be
;  used.
;  Arguments:
;    [ptrHString] - variable containing string handle.
;    ptrSource - pointer to the source for string.
;**********************************************************
proc SetString, .ptrHString, .ptrSource
begin
        push    eax esi
        mov     esi, [.ptrHString]

        mov     eax, [esi]
        test    eax, eax
        jnz     @f
        stdcall StrNew
@@:
        mov     [esi], eax
        stdcall StrPtr, eax
        mov     dword [eax], 0
        mov     [eax+string.len], 0

        cmp     [.ptrSource], 0
        je      .finish

        stdcall StrCopy, [esi], [.ptrSource]

.finish:
        pop     esi eax
        return
endp


;**********************************************************************************
; StrCat appends one string to another
; Arguments:
;   dest - destination string (handle only)
;   source - source string
;**********************************************************************************
proc StrCat, .dest, .source
begin
        push    eax ebx ecx esi edi

        stdcall StrLen, [.dest]
        mov     ebx,eax                 ; store dest length in ebx

        stdcall StrLen, [.source]
        mov     esi, eax
        lea     ecx, [eax+ebx]

        stdcall StrSetCapacity, [.dest], ecx

        mov     [eax+string.len], ecx
        lea     edi, [eax+ebx]

        stdcall StrPtr, [.source]
        lea     ecx, [esi+1]
        mov     esi, eax

        mov     ebx, ecx
        shr     ecx, 2
        rep movsd
        mov     ecx, ebx
        and     ecx, 3
        rep movsb

        pop     edi esi ecx ebx eax
        return
endp


;**********************************************************************************
; StrCharPos returns a pointer to the first occurence of a given char
;   in specified string
; Arguments:
;   Char - char to look for
;   hString -  string to search
; Returns: a pointer to the char in source, or NULL if char doesn't occur
;   in given string
;**********************************************************************************
proc StrCharPos, .hString, .char
begin
        push    esi

        stdcall StrPtr, [.hString]
        mov     esi,eax

        mov     ah, byte [.char]
;        xchg    al,ah

.search:
        mov     al,[esi]
        inc     esi
        or      al,al
        jz      .not_found
        cmp     al,ah
        jne     .search

        mov     eax, esi
        dec     eax
        pop     esi
        return

.not_found:
        xor     eax,eax
        pop     esi
        return
endp


;**********************************************************************************
; StrPos returns a pointer to the first occurence of a pattern string
;   in another string
; Arguments:
;   hPattern - 'pattern' string
;   hString -  string to search
; Returns: a pointer to the pattern string in source , or NULL if pattern string
; doesn't occur in the string to search
;**********************************************************************************
proc StrPos, .hString, .hPattern
begin
        push    ebx ecx edx esi edi     ; esp = esp -20
        mov     esi,[.hPattern]         ; mov esi,[hPattern]
        mov     edi,[.hString]          ; mov edi,[hString]
        stdcall StrLen, edi
        mov     ebx,eax                 ; now ebx holds lenght of the string to search
        stdcall StrLen, esi
        mov     edx,eax                 ; now edx holds length of the pattern string

        cmp     edx, ebx
        ja      .not_found              ; if the pattern is longer than the string

        stdcall StrPtr, esi
        mov     esi,eax                 ; put pointer to the pattern str in esi
        stdcall StrPtr,edi
        mov     edi,eax                 ; put pointer to the search str in edi
        lodsb                           ; load first character of the pattern
        mov     ecx,ebx                 ;
        mov     ebx,edx                 ; put str_len(pattern)-1 in ebx
        dec     ebx                     ;
        sub     ecx, ebx                ; there is no need to search to the end, but only to len(string)-len(pattern)-1

.search:
        repne   scasb
        jne     .not_found
;        cmp     ecx,ebx
;        jb      .not_found
        push    edi esi ecx
        or      ebx,ebx                 ; ebx==0 means that we were searching for one
        jz      .got_it                 ; character. We found it, so we stop.
        mov     ecx,ebx
        repe    cmpsb
        jne     .not_match

.got_it:
        pop     ecx esi edi
        dec     edi
        mov     eax,edi

.ret:
        pop     edi esi edx ecx ebx
        return

.not_match:
        pop     ecx esi edi
        jmp     .search

.not_found:
        xor     eax,eax
        jmp     .ret
endp





proc StrCopyPart, .dest, .source, .pos, .len
begin
        push    eax ecx esi edi

        stdcall StrPtr, [.source]
        mov     esi, eax
        stdcall StrLen, [.source]
        mov     ecx, eax

        mov     eax, [.pos]
        cmp     eax, ecx
        jae     .cleardest      ;

        sub     ecx, [.pos]
        mov     eax, [.len]

; ecx = min(ecx, eax)
        sub     eax, ecx
        sbb     edi, edi
        and     edi, eax
        add     ecx, edi

        add     esi, [.pos]

        stdcall StrSetCapacity, [.dest], ecx
        jc      .finish

        mov     edi, eax
        mov     [edi+string.len], ecx

        push    ecx
        shr     ecx, 2
        rep movsd
        pop     ecx
        and     ecx, 3
        rep movsb

        lea     ecx, [edi+3]
        and     cl, $fc
        sub     ecx, edi
        xor     eax, eax
        rep stosb

.finish:
        pop     edi esi ecx eax
        return

.cleardest:
        stdcall StrSetCapacity, [.dest], STR_MINSTRLEN
        mov     [eax+string.len], 0
        mov     dword [eax], 0
        jmp     .finish
endp




;**********************************************************************************
; StrExtract copies the part of [string] from [index] with lenght in [len]
; Returns handle to new created string.
;**********************************************************************************
proc StrExtract, .string, .pos, .len
begin
        stdcall StrNew
        stdcall StrCopyPart, eax, [.string], [.pos], [.len]
        return
endp




;__________________________________________________________________________________
; Splits the string on two strings, at position [.pos]
; Arguments:
;   .pString - pointer to string to be splitted.
;   .pos     - position where to split the string.
; Returns:
;   eax - handle to the new created string with second part of the string.
;         the original string does not reallocate memory and it's capacity
;         and the pointer will remains the same.
;__________________________________________________________________________________

proc StrSplit, .hString, .pos
begin
        stdcall StrExtract, [.hString], [.pos], -1
        stdcall StrTrim, [.hString], [.pos]
        return
endp




;__________________________________________________________________________________
; Trims the string at position [.pos]
; Arguments:
;   .pString - pointer to string to be splitted.
;   .pos     - position where to split the string.
; Returns:   nothing.
;__________________________________________________________________________________
proc StrTrim, .hString, .pos
begin
        push    eax ecx edi

        mov     ecx, [.pos]
        stdcall StrLen, [.hString]
        cmp     eax, ecx
        jbe     .endtrim

        stdcall StrPtr, [.hString]

        mov     [eax+string.len], ecx   ; new length of the source string.
        add     eax, ecx
        mov     edi, eax

        lea     ecx, [eax+3]
        and     cl, $fc
        sub     ecx, eax
        jnz     @f
        inc     ecx
@@:
        xor     eax, eax
        cld
        rep stosb

.endtrim:
        pop     edi ecx eax
        return
endp



;__________________________________________________________________________________
; StrInsert inserts one string into another at specified pos
; Arguments:
;   dest - destination where the source will be inserted.
;   source -  string to insert
;   pos    - where to insert.
; Returns:
;   nothing.
;__________________________________________________________________________________
proc StrInsert, .dest, .source, .pos
begin
        push    eax

        stdcall StrSplit, [.dest], [.pos]
        push    eax eax

        stdcall StrCat, [.dest], [.source]
        stdcall StrCat, [.dest] ; source from the stack.
        stdcall StrDel; from the stack.

        pop     eax
        return
endp


; TODO:
; String case functions are giving weird results in linux, so
; here are two functons I wrote some time ago.
; I have tested the following functions in win32 and worked well
; Perhaps it is time to fully support UTF encoded strings.
; These functions here are faster (20-25%), but the results are
; exactly the same as the strlib ones.
;                                    pelaillo

; -----------------------------------------------
; str_ucase:
;         Author: pelaillo
;           Date: Jan. 16, 2002
;    Converts also accented characters: ÑÚ <--> ñú
; -----------------------------------------------

proc StrUCase2, .hString
begin
        push    eax edx edi

        stdcall StrPtr, [.hString]
        mov     edi, eax
.str_ucase:
                mov     eax, [edi]
                mov     edx, eax
                and     edx, 40404040h
                ror     edx, 1
                xor     edx, -1
                and     eax, edx
                mov     [edi], eax
                add     edi, 4
                lea     edx, [eax-01010101h]
                xor     eax, edx
                and     eax, 80808080h
                jz      .str_ucase
                and     eax, edx
                jz      .str_ucase

        pop     edi edx eax
        return
endp

; -----------------------------------------------
; str_lcase:
;         Author: pelaillo
;           Date: Jan. 16, 2002
;    Converts also accented characters: ÑÚ <--> ñú
; -----------------------------------------------

proc StrLCase2, .hString
begin
        push    eax edx edi

        stdcall StrPtr, [.hString]
        mov     edi, eax
.str_lcase:
        mov     eax, [edi]
        mov     edx, eax
        and     edx, 40404040h
        ror     edx, 1
        or      eax, edx
        mov     [edi], eax
        add     edi, 4
        lea     edx, [eax-01010101h]
        xor     eax, edx
        and     eax, 80808080h
        jz      .str_lcase
        and     eax, edx
        jz      .str_lcase

        pop     edi edx eax
        return
endp


;**********************************************************************************
; Converts strings to Lower Case
;**********************************************************************************
proc StrLCase, .hString
begin
        push    eax ebx ecx edx edi

        stdcall StrPtr, [.hString]
        mov     edi, eax

        stdcall StrLen, [.hString]
        mov     ecx, eax
        mov     ebx, edi

        and     ebx, 3
        sub     ecx, ebx
        jbe     .byte2          ; the string is small enough, so process it by bytes.

.byte1:
        test    edi, 3
        jz      .ddword

        mov     al, [edi]
        and     al, $40
        shr     al, 1
        or      byte [edi], al

        inc     edi
        jmp     .byte1

.ddword:
        mov     ebx, ecx
        and     ebx, 3
        shr     ecx, 2
        jecxz   .byte

.qword:
        mov     eax, [edi]
        mov     edx, [edi+4]

        and     eax, $40404040
        and     edx, $40404040

        shr     eax, 1
        shr     edx, 1

        or      [edi], eax
        or      [edi+4], edx

        add     edi, 8
        dec     ecx
        jnz     .qword

.byte:
        dec     ebx
        js      .finish

        mov     al, [edi]
        and     al, $40
        shr     al, 1
        or      byte [edi], al

        inc     edi
        jmp     .byte

.byte2:
        mov     ebx, ecx
        jmp     .byte

.finish:
        pop     edi edx ecx ebx eax
        return
endp


;**********************************************************************************
; Converts strings to Upper Case
; First parameter = String to Convert to upper case
;**********************************************************************************
proc StrUCase, .hString
begin
        push    eax ebx ecx edx edi

        stdcall StrPtr, [.hString]
        mov     edi, eax

        stdcall StrLen, [.hString]
        mov     ecx, eax
        mov     ebx, edi

        and     ebx, 3
        sub     ecx, ebx
        jbe     .byte2          ; the string is small enough, so process it by bytes.

.byte1:
        test    edi, 3
        jz      .ddword

        mov     al, [edi]
        and     al, $40
        shr     al, 1
        not     al
        and     byte [edi], al

        inc     edi
        jmp     .byte1

.ddword:
        mov     ebx, ecx
        and     ebx, 3
        shr     ecx, 2
        jecxz   .byte

.qword:
        mov     eax, [edi]
        mov     edx, [edi+4]

        and     eax, $40404040
        and     edx, $40404040

        shr     eax, 1
        shr     edx, 1

        not     eax
        not     edx

        and     [edi], eax
        and     [edi+4], edx

        add     edi, 8
        dec     ecx
        jnz     .qword

.byte:
        dec     ebx
        js      .finish

        mov     al, [edi]
        and     al, $40
        shr     al, 1
        not     al
        and     byte [edi], al

        inc     edi
        jmp     .byte

.byte2:
        mov     ebx, ecx
        jmp     .byte

.finish:
        pop     edi edx ecx ebx eax
        return
endp




;**********************************************************************************
; _NumToStr converts the number in eax to the string in any radix approx. [2..26]
; Arguments:
;   [edi] - pointer to the string buffer
;   ecx - radix
;   eax - number to convert.
; There is no parameter check, so be careful.
; returns: edi points to the end of a converted number
;**********************************************************************************
proc _NumToStr
begin
    test  eax,eax
    jns   _NumToStrU
    neg   eax
    mov   byte [edi],"-"
    inc   edi
endp

proc _NumToStrU
begin
    cmp   eax,ecx
    jb    .lessA
    xor   edx,edx
    div   ecx
    push  edx
    call  _NumToStrU
    pop   eax
.lessA:
    cmp   al, 10
    sbb   al, 69h
    das
    stosb
    return
endp



;*****************************************************
; NumToStrF:
;   Converts signed integer value to string.
; NumToStrUF:
;   Converts unsigned integer value to string.
;
; edi - pointer to string buffer
; eax - Number to convert
; ecx - radix from 2 to $ff
; esi - length of the number in chars
;
; returns: edi - pointer to the end of converted num
;
; Note: Don't use 1 as radix.
;*****************************************************
proc _NumToStrF
begin
        test    eax,eax
        jns     _NumToStrUF
        neg     eax
        mov     byte [edi],'-'
        push    esi
        dec     esi
        add     edi, esi
        push    edi
        jmp     _NumToStrUF.loopc
endp

proc _NumToStrUF
begin
        push    esi
        add     edi, esi
        push    edi
        dec     edi
.loopc:
        xor     edx,edx
        div     ecx
        xchg    al,dl
        cmp     al,$0a
        sbb     al,$69
        das
        mov     [edi],al
        dec     edi
        xchg    al,dl
        dec     esi
        jnz     .loopc
        pop     edi
        pop     esi
        return
endp


;***********************************************************
; NumToStr - converts number to any radix.
; num - number to convert
; str - handle of the string. If NULL - creates new string.
; index - Offset in string where to put converted number.
; flags:
;   byte 0 - number of digits if ntsFixedWidth is set.
;   byte 1 - contains radix for the convertion.
;   byte 2,3 - flags.
; Returns:
;   eax - handle of the string.
;***********************************************************
proc NumToStr, .num, .flags
begin
        push    ebx ecx edx esi edi

        stdcall StrNew
        push    eax

        stdcall StrSetCapacity, eax, 40
        mov     edi, eax
        push    eax             ; pointer for the length.

; determine which conversion func to use
        movzx   eax, byte [.flags+2]    ; signed/fixed
        and     eax, (ntsUnsigned or ntsFixedWidth) shr 16
        mov     ebx, [.NumToStrFunc+4*eax]

        movzx   ecx, byte [.flags+1]       ; load radix into ecx
        movzx   esi, byte [.flags]
        mov     eax, [.num]
        call    ebx                     ; call low-level convertion routine
        mov     dword [edi], 0

        pop     eax
        sub     edi, eax
        mov     [eax+string.len], edi

        pop     eax
        pop     edi esi edx ecx ebx
        return

.NumToStrFunc dd _NumToStr, _NumToStrU, _NumToStrF, _NumToStrUF

endp




;-------------------------------------------------------
; function StrToNum
;   Converts specified string into a number
;
; Arguments:
;   hString - handle/pointer of the string containing
;     number to convert. It doesn't have to be ended by
;     NULL, any other character will stop conversion.
;     Number to convert must be decimal.
;
; Return:
;   eax - converted number
;   edx - offset to the byte where convertion ended.
;
; Note: in case of failture (first char of given pointer
;   isn't a number) function returns -1.
;-------------------------------------------------------
proc StrToNum, .hString
begin
        push    ebx esi edi
        xor     ebx,ebx         ; ebx will store our number

        stdcall StrPtr, [.hString]
        mov     edi, eax
        mov     esi,eax
        xor     eax,eax
        mov     al,[esi]
        cmp     al,'0'
        jb      .error
        cmp     al,'9'
        jbe     .digit
        jmp     .error
     .digit:
        sub     al,'0'
        add     ebx,eax
        inc     esi
        mov     al,[esi]
        cmp     al,'0'
        jb      .finish
        cmp     al,'9'
        ja      .finish
        mov     edx,ebx         ; multiply ebx by 10
        shl     ebx,3
        add     ebx,edx
        add     ebx,edx
        jmp     .digit
     .finish:

        mov     eax, ebx
        mov     edx, esi
        sub     edx, edi
        clc
        pop     edi esi ebx
        return

     .error:
        mov     eax, -1
        stc
        pop     edi esi ebx
        return
endp






proc StrToNumEx, .hstring
.sign dd ?
begin
        push    ebx edx esi edi

        stdcall StrLen, [.hstring]
        mov     edx, eax
        test    eax, eax
        jz      .invalid_number

        stdcall StrPtr, [.hstring]

        mov     esi, eax
        lea     edi, [eax+edx]

; sign?
        mov     [.sign], 0
        cmp     byte [esi], '-'
        jne     .radix

        mov     [.sign], -1
        inc     esi

; determine what is the radix.
.radix:
        cmp     byte [esi], '$'
        je      .hex
        cmp     word [esi], '0x'
        jne     .postfix
        inc     esi
.hex:
        inc     esi
        mov     edx, 16
        jmp     .decode

.postfix:
; search for 'h' or 'b' or 'o'
        mov     al, [edi-1]
        or      al, $40

        mov     edx, 16
        cmp     al, 'h'
        je      .postok

        mov     edx, 8
        cmp     al, 'o'
        je      .postok

        mov     edx, 2
        cmp     al, 'b'
        je      .postok

        mov     edx, 10
        inc     edi

.postok:
        dec     edi

; here, edx contains the radix, esi - begin of the number; edi - end of the number.
.decode:
        xor     ebx, ebx
        cmp     esi, edi
        jae     .invalid_number

.decode_loop:
        lodsb

        cmp     al, '0'
        jb      .invalid_number
        cmp     al, '9'
        jbe     .digit

        or      al, $40
        cmp     al, 'z'         ; common
        ja      .invalid_number
        cmp     al, 'a'
        jb      .invalid_number

        sub     al, 'a'-'0'-10

.digit:
        sub     al, '0'
        movzx   eax, al

        cmp     eax, edx
        jae     .invalid_number

        imul    ebx, edx
        add     ebx, eax

        cmp     esi, edi
        jne     .decode_loop

; set the sign:
        xor     ebx, [.sign]
        sub     ebx, [.sign]

        clc
        mov     eax, ebx
        pop     edi esi edx ebx
        return

.invalid_number:
        xor     eax, eax
        stc
        pop     edi esi edx ebx
        return
endp








;-------------------------------------------------------
; function StrCharCat
;   Appends up to 4 chard at the end of the string.
;
; Arguments:
;   hString - string to append
;   char - char(s) to add
; Returns:
;   nothing
;-------------------------------------------------------
proc StrCharCat, .hString, .char
begin
        push    eax ecx

        stdcall StrLen, [.hString]
        mov     ecx, eax
        add     eax, 8

        stdcall StrSetCapacity, [.hString], eax
        jnc     @f
        int3
@@:

        pushd   [.char]
        popd    [eax+ecx]
        mov     dword [eax+ecx+4], 0
        dec     ecx
.goend:
        inc     ecx
        cmp     byte [eax+ecx], 0
        jne     .goend

        mov     [eax+string.len], ecx

        pop     ecx eax
        return
endp


;------------------------------------------------------------
; function StrInsertChar
;   Inserts up to 4 chars into the given position of the string
;
; Arguments:
;   hString - string to append
;   char    - char to add
;   pos     - position where to add the char
;-------------------------------------------------------------
proc StrCharInsert, .hString, .char, .pos
.str rd 4
begin
        push    eax
        push    [.char]
        pop     [.str]
        mov     [.str+4], 0
        mov     [.str+8], 0

        lea     eax, [.str]
        stdcall StrInsert, [.hString], eax, [.pos]
        pop     eax
        return
endp



;_______________________________________________________________________
; proc StrClipSpacesR
;   Removes the spaces from the right of the string.
; Arguments:
;   hString - string to be processed
; Returns:
;   CF=1 - invalid string handle.
;_______________________________________________________________________
proc StrClipSpacesR, .hString
begin
        push    eax ecx

        stdcall StrPtr, [.hString]
        jc      .finish

        mov     ecx, [eax+string.len]
        jecxz   .exit
.loop:
        cmp     byte [eax+ecx-1], ' '
        jne     .exit
        dec     ecx
        jnz     .loop
.exit:
        mov     [eax+string.len], ecx
        mov     dword [eax+ecx], 0

.finish:
        pop     ecx eax
        return
endp


;_______________________________________________________________________
; proc StrClipSpacesL
;   Removes the spaces from the left of the string.
; Arguments:
;   hString - string to be processed
; Returns:
;   CF=1 - invalid string handle.
;_______________________________________________________________________
proc StrClipSpacesL, .hString
begin
        push    esi edi eax ecx

        stdcall StrPtr, [.hString]
        jc      .finish

        mov     ecx, [eax+string.len]
        mov     esi, eax
        mov     edi, eax

.loop:
        jecxz   .copy
        cmp     byte [esi], ' '
        jne     .copy

        inc     esi
        dec     ecx
        jmp     .loop

.copy:
        mov     [edi+string.len], ecx
        jecxz   .finish
        cmp     esi, edi
        je      .finish

        add     ecx, 4
        rep movsb

.finish:
        pop     ecx eax edi esi
        return
endp



;_______________________________________________________________________
; proc StrCleanDupSpaces
;   Removes duplicating spaces from the string.
; Arguments:
;   hString - string to be processed
; Returns:
;   CF=1 - invalid string handle.
;_______________________________________________________________________
proc StrCleanDupSpaces, .hString
begin
        push    esi edi eax ecx edx

        stdcall StrPtr, [.hString]
        jc      .finish

        mov     ecx, [eax+string.len]
        lea     edx, [eax+string.len]
        mov     esi, eax
        mov     edi, eax

        jecxz   .endcopy

.loop:
        lodsb
        cmp     al, ' '
        jne     .store
        cmp     byte [esi], ' '
        jne     .store
; skip
        dec     dword [edx]
        jmp     .next

.store:
        stosb

.next:
        dec     ecx
        jnz     .loop

.endcopy:
        xor     eax, eax
        stosd

.finish:
        pop     edx ecx eax edi esi
        return
endp






;_______________________________________________________________________
;
; proc StrHash
;   Computes 32 bit hash value from the string.
;   This procedure implements the hash algoritm: FNV-1b
;
; Arguments:
;   .hString - handle of string.
;
; Return:
;   eax - 32bit hash value.
;
; Changes:
;   eax
;_______________________________________________________________________
proc StrHash, .hString
begin
        stdcall StrLen, [.hString]
        push    eax
        stdcall StrPtr, [.hString]
        push    eax
        call    DataHash
        return
endp


proc DataHash, .ptrData, .len
begin
        push    ecx edx esi

        mov     esi, [.ptrData]
        mov     ecx, [.len]
        mov     eax, $811C9DC5                  ; 2166136261              ; FNV offset basis
        inc     ecx

.hashloop:
        dec     ecx
        jz      .exit
        movzx   edx, byte [esi]
        xor     eax, edx
        inc     esi
        imul    eax, $01000193                  ;   16777619              ; FNV prime
        jmp     .hashloop

.exit:
        pop     esi edx ecx
        return
endp



proc StrURLEncode, .hstr
.res dd ?
begin
        push    ebx ecx edx esi edi
        stdcall StrPtr, [.hstr]
        mov     esi, eax

        stdcall StrLen, esi
        mov     ecx, eax
        lea     edx, [2*eax+eax]        ; the encoded string can be max 3x long as original string.

        stdcall StrNew
        mov     [.res], eax
        jecxz   .finish

        stdcall StrSetCapacity, eax, edx
        mov     edi, eax
        xor     edx, edx
        xor     ebx, ebx

        push    eax
.encode:
        lodsb
        cmp     al, $80
        jae     .store          ; it is a hack, but I hope save enough.

        mov     dl, al
        mov     bl, al
        shr     edx, 5
        and     ebx, $1f
        bt      dword [.URLCharTable+4*edx], ebx
        jnc     .store

        mov     ah, al
        mov     al, '%'
        stosb
        mov     al, ah
        shr     al, 4
        cmp     al, $0a
        sbb     al, $69
        das
        stosb
        mov     al, ah
        and     al, $0f
        cmp     al, $0a
        sbb     al, $69
        das

.store:
        stosb
        loop    .encode

        xor     al, al
        mov     [edi], al

        pop     eax
        sub     edi, eax
        mov     [eax+string.len], edi

.finish:
        mov     eax, [.res]
        pop     edi esi edx ecx ebx
        return

; Contains 1 where the character must be % encoded and 0 where it is save to pass it directly
.URLCharTable db 11111111b       ;
              db 11111111b       ;
              db 11111111b       ;
              db 11111111b       ; 0..31 -control chars | encoded
              db 11111111b       ; $27 - $20: '&%$#"!   | encoded
              db 11111111b       ; $2f - $28: /.-,+*)(  | encoded
              db 00000000b       ; $37 - $30: 76543210  | not encoded
              db 11111100b       ; $3f - $38: ?>=<;:98  | partially
              db 00000001b       ; $47 - $40: GFEDCBA@  | partially
              db 00000000b       ; $4f - $48: ONMLKJIH  | not encoded
              db 00000000b       ; $57 - $50: WVUTSRQP  | not encoded
              db 11111000b       ; $5f - $58: _^]\[ZYX  | partially
              db 00000001b       ; $67 - $60: gfedcba`  | partially
              db 00000000b       ; $6f - $68: onmlkjih  | not encoded
              db 00000000b       ; $77 - $70: wvutsrqp  | not encoded
              db 11111000b       ; $7f - $78:  ~}|{zyx  | partially
endp



proc StrURLDecode, .hstring
begin
        pushad

        stdcall StrLen, [.hstring]
        mov     ecx, eax
        jecxz   .finish

        stdcall StrPtr, [.hstring]
        mov     esi, eax
        mov     edi, eax
        mov     ebx, eax

.loop:
        lodsb

        test    al, al
        jz      .end_of_string

        cmp     al, '+'
        je      .space

        cmp     al, '%'
        jne     .store

        lodsb
        cmp     al, '9'
        jbe     @f
        add     al, $09
@@:
        shl     al, 4
        mov     ah, al

        lodsb
        cmp     al, '9'
        jbe     @f
        add     al, $09
@@:
        and     al, $0f
        or      al, ah
        jmp     .store

.space:
        mov     al, ' '

.store:
        stosb
        loop    .loop

.end_of_string:
        mov     ecx, edi
        sub     ecx, ebx
        xor     eax, eax
        stosd

        mov     [ebx+string.len], ecx

.finish:
        popad
        return

endp


; UTF-8 support functions.
; Some of the above functions also need some revision in order to support
; utf-8 strings properly.


;  Bug - on [.len]=-1 sometimes in Linux returns error on normal strings.

proc StrLenUtf8, .hString, .len
.maxptr dd ?
begin
        push    esi ecx edx

        stdcall StrPtr, [.hString]
        mov     esi, eax
        mov     eax, [.len]
        cmp     eax, -1
        je      @f
        add     eax, esi
@@:
        mov     [.maxptr], eax
        xor     ecx, ecx

.loop:
        cmp     esi, [.maxptr]
        jae     .endofstring

        mov     eax, [esi]
        stdcall DecodeUtf8, eax
        jc      .error

        test    eax, eax
        jz      .endofstring

        add     esi, edx
        inc     ecx
        jmp     .loop

.endofstring:
        mov     eax, ecx
        pop     edx ecx esi
        clc
        return

.error:
        pop     edx ecx esi
        return
endp



proc StrOffsUtf8, .hString, .pos
begin
        push    edx esi

        stdcall StrPtr, [.hString]
        mov     esi, eax

.loop:
        dec     [.pos]
        js      .finish

        stdcall DecodeUtf8, [esi]
        jc      .error

        test    eax, eax
        jz      .finish

        add     esi, edx
        jmp     .loop

.finish:
        clc
        mov     eax, esi
        pop     esi edx
        return

.error:
        xor     eax, eax
        pop     esi edx
        return
endp



; decodes 4 bytes in [.chars] to UNICODE dword value.
; returns:
;   CF=0 - no error
;     eax - unicode value.
;     edx - byte count of the char. [1..4]
;   CF=1 - invalid utf-8 char;
;     eax = edx = 0  the character can not be decoded.
;     edx <> 0 -> eax = the overlong encoded character. edx = byte count of the char.
;
;  Note: When CF=1 and [.chars] are overlong encoded char.
;        eax contains the proper value and edx contains the proper length.
;        But it is still invalid character, according to the standards.
proc DecodeUtf8, .chars
begin
        push    ebx ecx

        xor     ecx, ecx

.loop1:
        shl     byte [.chars], 1
        jnc     .countok
        inc     ecx
        jmp     .loop1

.countok:
        jecxz   .ascii

        cmp     ecx, 1
        je      .error          ; internal byte
        cmp     ecx, 4
        ja      .error          ; more than 4 bytes

        mov     edx, 1
        xor     ebx, ebx
        movzx   eax, byte [.chars]
        shr     eax, cl
        shr     eax, 1

.loop2:
        mov     bl, byte [.chars+edx]
        and     bl, $c0
        cmp     bl, $80
        jne     .error
        mov     bl, byte [.chars+edx]
        and     bl, $3f
        shl     eax, 6
        or      eax, ebx
        inc     edx
        cmp     edx, ecx
        jne     .loop2

        and     eax, $1fffff
        cmp     eax, $10ffff
        ja      .error

        cmp     eax, [._minimal+4*edx-8]
        jb      .overlong   ; overlong coding.

        clc
        pop     ecx ebx
        return

.ascii:
        movzx   eax, byte [.chars]
        shr     eax, 1
        mov     edx, 1
        pop     ecx ebx
        clc
        return

.error:
        xor     eax, eax
        xor     edx, edx
.overlong:
        stc
        pop     ecx ebx
        return

._minimal dd $80, $800, $10000

endp



proc ScanForwardUtf8
begin
        push    eax

        mov     al, [esi]
        test    al, al
        jns     .finish

        and     al, 11000000b
        cmp     al, 11000000b
        je      .finish

; inc forward
.loopf:
        inc     esi
        mov     al, [esi]
        and     al, 11000000b
        cmp     al, 10000000b
        je      .loopf

.finish:
        pop     eax
        return
endp



proc ScanBackUtf8
begin
        push    eax

        mov     al, [esi]
        test    al, al
        jns     .finish

        and     al, 11000000b
        cmp     al, 11000000b
        je      .finish

; inc back
.loopf:
        dec     esi
        mov     al, [esi]
        and     al, 11000000b
        cmp     al, 10000000b
        je      .loopf

.finish:
        pop     eax
        return
endp



proc ExpandTabs, .hstring, .tabstop
.start dd ?
.count dd ?
.correction dd ?
begin
        pushad

        mov     [.count], 0
        mov     [.correction], 0

        stdcall StrLen, [.hstring]
        mov     ecx, eax
        stdcall StrPtr, [.hstring]
        mov     [.start], eax
        mov     esi, eax
        add     ecx, eax
        xor     ebx, ebx

        jecxz   .end_scan

.scan_loop:
        stdcall DecodeUtf8, [esi]
        cmp     eax, $09
        jne     .next

        mov     byte [esi], $20

        push    edx
        mov     eax, ebx
        cdq
        div     [.tabstop]
        imul    eax, [.tabstop]
        pop     edx
        add     eax, [.tabstop]
        sub     eax, ebx
        dec     eax
        jz      .next

        add     ebx, eax
        add     [.correction], eax
        push    eax             ; space count

        mov     eax, esi
        sub     eax, [.start]
        push    eax             ; offset

        inc     [.count]

.next:
        inc     ebx
        add     esi, edx
        cmp     esi, ecx
        jb      .scan_loop

.end_scan:
        cmp     [.count], 0
        je      .finish

.expand:
        pop     ebx             ; offset
        pop     eax             ; count

.ins_spc:
        stdcall StrCharInsert, [.hstring], ' ', ebx
        dec     eax
        jnz     .ins_spc

.next_tab:
        dec     [.count]
        jnz     .expand

.finish:
        popad
        mov     eax, [.correction]
        return
endp



proc StrIP2Num, .hString
begin
        push    ebx edx esi

        xor     ebx, ebx
        stdcall StrPtr, [.hString]
        mov     esi, eax

; string to IP
.iploop:
        stdcall StrToNum, esi
        cmp     eax, $100
        jae     .invalid_ip

        cmp     ebx, $1000000
        jae     .invalid_ip

        shl     ebx, 8
        or      bl, al

        cmp     byte [esi+edx], 0
        je      .end_of_ip

        cmp     byte [esi+edx], '.'
        jne     .invalid_ip

        lea     esi, [esi+edx+1]
        jmp     .iploop

.invalid_ip:
        stc
        mov     eax, ebx
        pop     esi ebx
        return

.end_of_ip:
        clc
        mov     eax, ebx
        pop     esi edx ebx
        return
endp



proc IP2Str, .ip
begin
        push    ebx

        movzx   eax, byte [.ip+3]
        stdcall NumToStr, eax, ntsDec or ntsUnsigned
        mov     ebx, eax
        stdcall StrCharCat, ebx, '.'

        movzx   eax, byte [.ip+2]
        stdcall NumToStr, eax, ntsDec or ntsUnsigned
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax
        stdcall StrCharCat, ebx, '.'

        movzx   eax, byte [.ip+1]
        stdcall NumToStr, eax, ntsDec or ntsUnsigned
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax
        stdcall StrCharCat, ebx, '.'

        movzx   eax, byte [.ip]
        stdcall NumToStr, eax, ntsDec or ntsUnsigned
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax

        mov     eax, ebx
        pop     ebx
        return
endp


proc StrEncodeHTML, .hString
begin
        push    esi edi

        stdcall StrNew
        mov     edi, eax

        stdcall StrPtr, [.hString]
        mov     esi, eax

.loop:
        movzx   eax, byte [esi]
        inc     esi

        test    eax, eax
        jz      .end_of_string

        cmp     al, '<'
        je      .char_less_then
        cmp     al, '>'
        je      .char_greater_then
        cmp     al, '"'
        je      .char_quote
        cmp     al, '&'
        je      .char_amp
;        cmp     al, "'"
;        je      .char_apos

.store:
        stdcall StrCharCat, edi, eax
        jmp     .loop

.end_of_string:
        mov     eax, edi
        pop     edi esi
        return

.char_less_then:
        mov     eax, '&lt;'
        jmp     .store

.char_greater_then:
        mov     eax, '&gt;'
        jmp     .store

.char_quote:
        stdcall StrCharCat, edi, '&quo'
        mov     eax, 't;'
        jmp     .store

;.char_apos:
;        stdcall StrCharCat, edi, '&apo'
;        mov     eax, 's;'
;        jmp     .store

.char_amp:
        stdcall StrCharCat, edi, '&amp'
        mov     eax, ';'
        jmp     .store
endp




proc StrDecodeHTML, .hString
begin
        pushad

        stdcall StrPtr, [.hString]
        mov     esi, eax
        mov     edi, eax
        mov     ebx, eax

.loop:
        lodsb

        test    al, al
        jz      .end_of_string

        cmp     al, '&'
        je      .collapse

.store:
        stosb
        jmp     .loop

.collapse:
        cmp     dword [esi], 'nbsp'
        jne     .not_nbsp
        cmp     byte [esi+4], ';'
        jne     .not_nbsp

        add     esi, 5
        mov     al, ' '
        jmp     .store

.not_nbsp:
        mov     ecx, [esi]
        and     ecx, $ffffff

        cmp     ecx, 'lt;'
        je      .lessthen
        cmp     ecx, 'gt;'
        jne     .not_gt

        add     esi, 3
        mov     al, '>'
        jmp     .store

.lessthen:
        add     esi, 3
        mov     al, '<'
        jmp     .store

.not_gt:
        cmp     dword [esi], 'quot'
        jne     .not_quote
        cmp     byte [esi+4], ';'
        jne     .not_quote

        add     esi, 5
        mov     al, '"'
        jmp     .store

.not_quote:
        cmp     dword [esi], 'apos'
        jne     .not_apos
        cmp     byte [esi+4], ';'
        jne     .not_apos

        add     esi, 5
        mov     al, "'"
        jmp     .store

.not_apos:
        cmp     dword [esi], 'amp;'
        jne     .store

        add     esi, 4
        mov     al, '&'
        jmp     .store


.end_of_string:
        mov     dword [edi], 0
        sub     edi, ebx
        mov     [ebx+string.len], edi

        popad
        return
endp




proc DateTimeToStr, .pDateTime, .format
begin
        push    ebx esi

        mov     esi, [.pDateTime]

; date
        stdcall NumToStr, [esi+TDateTime.date], ntsUnsigned or ntsFixedWidth or ntsDec + 2
        mov     ebx, eax
        stdcall StrCharCat, ebx, '.'
        stdcall NumToStr, [esi+TDateTime.month], ntsUnsigned or ntsFixedWidth or ntsDec + 2
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax
        stdcall StrCharCat, ebx, '.'
        stdcall NumToStr, [esi+TDateTime.year], ntsSigned or ntsFixedWidth or ntsDec + 4
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax
        stdcall StrCharCat, ebx, '  '

; time
        stdcall NumToStr, [esi+TDateTime.hour], ntsUnsigned or ntsFixedWidth or ntsDec + 2
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax
        stdcall StrCharCat, ebx, ':'
        stdcall NumToStr, [esi+TDateTime.minute], ntsUnsigned or ntsFixedWidth or ntsDec + 2
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax
        stdcall StrCharCat, ebx, ':'
        stdcall NumToStr, [esi+TDateTime.second], ntsUnsigned or ntsFixedWidth or ntsDec + 2
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax

        mov     eax, ebx
        pop     esi ebx
        return
endp



proc StrExtractFilename, .hFilename
begin
        push    ebx ecx esi

        stdcall StrLen, [.hFilename]
        mov     ecx, eax

        stdcall StrPtr, [.hFilename]
        lea     esi, [eax+ecx]
        mov     ebx, eax

.loop:
        cmp     esi, ebx
        je      .found2

        dec     esi
        mov     al, [esi]

        cmp     al, '/'
        je      .found
        cmp     al, '\'
        je      .found
        jmp     .loop

.found:
        inc     esi

.found2:
        stdcall StrExtract, esi, 0, $7fffffff

        pop     esi ecx ebx
        return
endp



proc StrChangeExt, .hFilename, .hNewExt
begin





        return
endp




;******************************************************
; Computes MD5 hash of the string .hString and returns
; new string handle in eax containing the hash of the
; string.
;******************************************************
proc StrMD5, .hString
begin
        stdcall StrLen, [.hString]
        push    eax
        stdcall StrPtr, [.hString]
        stdcall DataMD5, eax ; length from the stack.
        return
endp



include '%TargetOS%/utf8.asm'



endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/data/uConfig.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: OS independent micro configuration files library.
;
;  Target OS: Any
;
;  Dependencies: memory.asm; strlib.asm; arrays.asm; files.asm
;
;  Notes:
;
;_________________________________________________________________________________________
module "uConfig library"


; Structure of the file of uConfig:
;
; offset  | size  |   description
; --------+-------+-----------------------------------------------------------------------
;   0     |  4    |   Signature
;   4     |  4    |   $0a1a0a0d (CR, LF, EOF, 00)
;   8     |  4    |   Hash of the whole file including file length of the next field
;   12    |  4    |   Chunk data length (N)
;   16    |  N    |   Data chunks
; --------+-------+-----------------------------------------------------------------------
;
; Every data chunk have following structure:
;
; offset  | size  |   description
; --------+-------+-----------------------------------------------------------------------
;    0    |  4    |  Key name 4xASCII chars.
;    4    |  4    |  Length of the data in bytes (K)
;    8    |  4    |  Data type. Constant of cdtXXXXX (see definitions below)
;   12    |  K    |  Chunk data.
; --------+-------+-----------------------------------------------------------------------
;


cdtNULL     = 0
cdtInteger  = 1   ; 32bit integer value.
cdtString   = 2   ; utf-8 string.
cdtBlob     = 3   ; arbitraty sized array of bytes.
cdtConfig   = 4

cdtMaxAlowed = cdtConfig

struct TConfigHeader
  .signature dd ?
  .filler    dd ?
  .hash      dd ?
  .length    dd ?
  .chunks:
ends


struct TChunkHeader
  .KeyName dd ?
  .length  dd ?         ; length of the data without the size of the header and checksum.
  .type    dd ?
ends


struct TConfigRecord
  .KeyName  dd ?
  .DataSize dd ?
  .Type     dd ?
  .Data     dd ?
ends


; loads the file representation from the memory and expands it to the database tree structure.
; returns pointer to TArray of TConfigRecord structures.
proc LoadConfigDB, .ptrSource, .signature
begin
        push    ecx edx esi

        mov     esi, [.ptrSource]
        test    esi, esi
        jnz     .process_source

        stdcall CreateArray, sizeof.TConfigRecord
        jmp     .db_ok

.process_source:
; check 8 bytes signature
        mov     edx, [esi+TConfigHeader.signature]

        cmp     [.signature], -1
        je      .signatureok

        cmp     edx, [.signature]
        jne     .error_bad_signature

.signatureok:
        mov     [.signature], edx

        cmp     dword [esi+TConfigHeader.filler], $001a0a0d
        jne     .error_bad_signature

        mov     ecx, [esi+TConfigHeader.length]
        lea     esi, [esi+TConfigHeader.length]
        add     ecx, 4                                  ;(the length itself)
        stdcall DataHash, esi, ecx
        cmp     eax, [esi-4]
        jne     .error_bad_hash

        add     esi, 4
        sub     ecx, 4
        stdcall __DoRecurseConfigSource, esi, ecx

.db_ok:
        pushd   [.signature]
        popd    [eax+TArray.lparam]     ; store the signature to the .lparam field of the root TArray
        clc

.finish:
        pop     esi edx ecx
        return

.error_bad_signature:
        mov     eax, -1
        stc
        jmp     .finish

.error_bad_hash:
        mov     eax, -2
        stc
        jmp     .finish
endp



proc __DoRecurseConfigSource, .ptrSource, .length
.array  dd ?
begin
        pushad

        stdcall CreateArray, sizeof.TConfigRecord
        mov     [.array], eax

        mov     esi, [.ptrSource]
        mov     ecx, [.length]

.chunk_loop:
        cmp     ecx, sizeof.TConfigRecord
        jb      .finish

        stdcall AddArrayItems, [.array], 1
        mov     [.array], edx
        mov     edi, eax

        mov     eax, [esi+TChunkHeader.KeyName]
        mov     edx, [esi+TChunkHeader.length]
        mov     [edi+TConfigRecord.KeyName], eax
        mov     [edi+TConfigRecord.DataSize], edx

        mov     eax, [esi+TChunkHeader.type]
        mov     [edi+TConfigRecord.Type], eax

        add     esi, sizeof.TChunkHeader
        sub     ecx, sizeof.TChunkHeader

        and     eax, $7
        movzx   eax, [.type_handlers+eax]
        add     eax, .type_handlers
        call    eax
        mov     [edi+TConfigRecord.Data], eax

.next_chunk:
        mov     eax, [edi+TConfigRecord.DataSize]
        add     eax, 3
        and     al, $fc

        add     esi, eax
        sub     ecx, eax
        jmp     .chunk_loop

.finish:
        popad
        mov     eax, [.array]
        return

.type_handlers db .handle_null   - .type_handlers
               db .handle_int    - .type_handlers
               db .handle_string - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_config - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_blob   - .type_handlers

.handle_config:
        stdcall __DoRecurseConfigSource, esi, edx
.handle_null:
        retn

.handle_int:
        mov     eax, [esi]
        retn

.handle_string:
        stdcall StrNew
        stdcall StrCopyPart, eax, esi, 0, edx
        retn

.handle_blob:
        stdcall   GetMem, edx
        push      esi edi ecx
        mov       edi, eax
        mov       ecx, edx
        rep movsb
        pop       ecx edi esi
        retn
endp


; creates memory image (TArray) of the file of the config database.

proc SaveConfigFile, .ptrRoot, .signature
begin
        push    edx ecx

        stdcall CreateArray, 4
        mov     edx, eax

        mov     ecx, [.ptrRoot]
        stdcall AddArrayItems, edx, sizeof.TConfigHeader/4
        pushd   [.signature] $001a0a0d
        popd    [eax+TConfigHeader.filler] [eax+TConfigHeader.signature]

        stdcall __DoSaveParamArray, edx, [.ptrRoot]
        push    edx

        mov     ecx, [edx+TArray.count]
        shl     ecx, 2
        lea     edx, [edx+TArray.array+TConfigHeader.length]
        sub     ecx, sizeof.TConfigHeader
        mov     [edx], ecx
        add     ecx, 4 ; .length field
        stdcall DataHash, edx, ecx
        mov     [edx-4], eax            ; -4 if the offset to TConfigHeader.hash relative to TConfigHeader.length

        pop     eax
        pop     ecx edx
        return
endp



proc __DoSaveParamArray, .stream, .array
.count dd ?
begin
        pushad

        mov     ebx, [.array]
        mov     ecx, [ebx+TArray.count]
        lea     ebx, [ebx+TArray.array-sizeof.TConfigRecord]
        mov     [.count], ecx

.loop:
        add     ebx, sizeof.TConfigRecord
        dec     [.count]
        js      .end_save

        stdcall AddArrayItems, [.stream], 3
        mov     [.stream], edx

        pushd   [ebx+TConfigRecord.KeyName] [ebx+TConfigRecord.DataSize] [ebx+TConfigRecord.Type]
        popd    [eax+TChunkHeader.type] [eax+TChunkHeader.length] [eax+TChunkHeader.KeyName]

        movzx   eax, byte [ebx+TConfigRecord.Type]
        and     al, $07
        movzx   eax, [.type_handlers+eax]
        add     eax, .type_handlers
        call    eax
        jc      .loop

; align to dword
        mov     ecx, [ebx+TConfigRecord.DataSize]
        add     ecx, 3
        and     cl, $fc
        shr     ecx, 2
        stdcall AddArrayItems, [.stream], ecx
        mov     [.stream], edx
        mov     edi, eax

        rep movsd
        jmp     .loop

.end_save:
        popad
        mov     edx, [.stream]
        return

.type_handlers db .handle_null   - .type_handlers
               db .handle_int    - .type_handlers
               db .handle_string - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_config - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_blob   - .type_handlers

.handle_int:
        lea     esi, [ebx+TConfigRecord.Data]
        clc
        retn

.handle_string:
        stdcall StrPtr, [ebx+TConfigRecord.Data]
        mov     esi, eax
        clc
        retn

.handle_blob:
        mov     esi, [ebx+TConfigRecord.Data]
        clc
        retn

.handle_config:
        mov     eax, [.stream]
        mov     eax, [eax+TArray.count]
        push    eax
        stdcall __DoSaveParamArray, [.stream], [ebx+TConfigRecord.Data]
        mov     [.stream], edx

        pop     eax     ; old size
        mov     ecx, [edx+TArray.count]
        sub     ecx, eax
        lea     edx, [edx+TArray.array+4*eax-sizeof.TChunkHeader]
        shl     ecx, 2
        mov     [edx+TChunkHeader.length], ecx

.handle_null:
        stc
        retn
endp



proc FreeConfigDB, .ptrRoot
.dummy TConfigRecord
begin
        push    eax

        cmp     [.ptrRoot], 0
        je      .exit

        mov     [.dummy.Type], cdtConfig
        mov     eax, [.ptrRoot]
        mov     [.dummy.Data], eax

        lea     eax, [.dummy]
        stdcall __FreeConfigRecord, eax

.exit:
        pop     eax
        return
endp



; searches the tree for the given path and returns a pointer to the variable, containing pointer to TArray of the directory.
proc __GetParamArray, .ptrVarRoot, .pDirectory, .create
begin
        push    ebx edx esi

        mov     esi, [.pDirectory]
        mov     ebx, [.ptrVarRoot]

        test    esi, esi
        jz      .found

.loop:
        cmp     dword [esi], 0
        je      .found

        stdcall __ScanParamArray, [ebx], [esi]
        jc      .err_not_found
        cmp     [eax+TConfigRecord.Type], cdtConfig
        jne     .err_not_directory

.next:
        lea     ebx, [eax+TConfigRecord.Data]
        add     esi, 4
        jmp     .loop

.found:
        mov      eax, ebx
        clc
        pop     esi edx ebx
        return

.err_not_found:
        cmp     [.create], 0
        je      .no_create

        stdcall AddArrayItems, [ebx], 1
        mov     [ebx], edx
        mov     edx, eax
        pushd   [esi]
        popd    [edx+TConfigRecord.KeyName]
        mov     [edx+TConfigRecord.Type], cdtConfig
        stdcall CreateArray, sizeof.TConfigRecord
        mov     [edx+TConfigRecord.Data], eax
        mov     eax, edx
        jmp     .next

.no_create:
        xor     eax, eax
.error:
        stc
        pop     esi edx ebx
        return

.err_not_directory:
        xor     eax, eax
        dec     eax
        jmp     .error
endp




; returns:
;   CF=0 and eax = pointer to TConfigRecord
;            ecx = index of the record in the array.
;   CF=1 and eax = 0 - the key was not found.
proc __ScanParamArray, .ptrArray, .name
begin
        push    ecx esi
        mov     esi, [.ptrArray]
        test    esi, esi
        jz      .not_found

        mov     ecx, [esi+TArray.count]
        lea     esi, [esi+TArray.array]
        jecxz   .not_found

        xor     edx, edx
.loop:
        mov     eax, [esi+TConfigRecord.KeyName]
        cmp     eax, [.name]
        je      .found

        add     esi, sizeof.TConfigRecord
        inc     edx
        loop    .loop

.not_found:
        xor     eax, eax
        stc
        pop     esi ecx
        return

.found:
        mov     eax, esi
        clc
        pop     esi ecx
        return
endp


; returns
;   eax - poiner to the TConfigRecord or NULL if missing
proc GetConfigParam, .ptrConfig, .pDirectory, .name
begin
        push    edx
        lea     eax, [.ptrConfig]
        stdcall __GetParamArray, eax, [.pDirectory], 0
        stdcall __ScanParamArray, [eax], [.name]
        pop     edx
        return
endp


proc GetConfigParam.AsString, .ptrConfig, .pDirectory, .name
begin
        push    edx

        stdcall GetConfigParam, [.ptrConfig], [.pDirectory], [.name]
        jc      .finish

        movzx   edx, byte [eax+TConfigRecord.Type]
        and     dl, $07
        movzx   edx, [.type_handlers+edx]
        add     edx, .type_handlers
        call    edx

.finish:
        pop     edx
        return

.type_handlers db .handle_null   - .type_handlers
               db .handle_int    - .type_handlers
               db .handle_string - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_config - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_blob   - .type_handlers

.handle_null:
        stdcall StrDup, .txtNULL
        retn

.handle_int:
        stdcall NumToStr, [eax+TConfigRecord.Data], ntsSigned or ntsDec
        retn

.handle_string:
        stdcall StrDup, [eax+TConfigRecord.Data]
        retn

.handle_config:
        stdcall StrDup, .txtDir
        retn

.handle_blob:
        stdcall StrDup, .txtBlob
        retn

.txtNULL db 'NULL', 0
.txtDir  db 'SDIR', 0
.txtBlob db 'BLOB', 0

endp



proc __FreeConfigRecord, .ptrRecord
begin
        pushad

        mov     esi, [.ptrRecord]
        movzx   eax, byte [esi+TConfigRecord.Type]

        and     al, $07
        mov     al, [.type_handlers+eax]
        add     eax, .type_handlers
        call    eax

        xor     eax, eax
        mov     [esi+TConfigRecord.Type], eax
        mov     [esi+TConfigRecord.Data], eax
        mov     [esi+TConfigRecord.DataSize], eax
        popad
        return

.type_handlers db .handle_null   - .type_handlers
               db .handle_int    - .type_handlers
               db .handle_string - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_config - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_blob   - .type_handlers

.handle_config:
        mov     eax, [esi+TConfigRecord.Data]
        mov     ecx, [eax+TArray.count]
        lea     eax, [eax+TArray.array]
        jecxz   .handle_blob

.loop:
        stdcall __FreeConfigRecord, eax
        add     eax, sizeof.TConfigRecord
        loop    .loop

.handle_blob:
        stdcall FreeMem, [esi+TConfigRecord.Data]
        retn

.handle_string:
        stdcall StrDel, [esi+TConfigRecord.Data]
.handle_null:
.handle_int:
        retn
endp





proc DelCongigParam, .ptrVarConfig, .pDirectory, .name
begin
        pushad

        stdcall __GetParamArray, [.ptrVarConfig], [.pDirectory], 0
        jc      .deleted
        mov     esi, eax

        stdcall __ScanParamArray, [esi], [.name]
        jc      .deleted

        stdcall __FreeConfigRecord, eax
        stdcall DeleteArrayItems, [esi], edx, 1
        mov     [esi], edx

.deleted:
        popad
        return
endp


; set the value of the given config parameter.
; if the parameter exists, the value will be changed.
; if the parameter does not exists, it will be created.
proc SetConfigParam, .ptrVarConfig, .pDirectory, .name, .type, .value, .size
begin
        push    eax ecx edx esi edi

        stdcall __GetParamArray, [.ptrVarConfig], [.pDirectory], 1
        jc      .missing_directory

        mov     esi, eax

        stdcall __ScanParamArray, [esi], [.name]
        jnc     .record_ok

        stdcall AddArrayItems, [esi], 1
        mov     [esi], edx
        push    [.name]
        pop     [eax+TConfigRecord.KeyName]

.record_ok:
        mov     esi, eax

        stdcall __FreeConfigRecord, esi

        movzx   ecx, byte [.type]
        and     cl, $7
        mov     [esi+TConfigRecord.Type], ecx
        movzx   ecx, [.type_handlers+ecx]
        add     ecx, .type_handlers

        call    ecx
        clc
.finish:
        pop     edi esi edx ecx eax
        return

.missing_directory:
        stc
        jmp     .finish

.type_handlers db .handle_null   - .type_handlers
               db .handle_int    - .type_handlers
               db .handle_string - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_config - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_blob   - .type_handlers
               db .handle_blob   - .type_handlers

.handle_int:
        mov     [esi+TConfigRecord.DataSize], 4
        push    [.value]
        pop     [esi+TConfigRecord.Data]

.handle_null:
        retn

.handle_string:
        stdcall StrDup, [.value]
        mov     [esi+TConfigRecord.Data], eax
        stdcall StrLen, eax
        mov     [esi+TConfigRecord.DataSize], eax
        retn

.handle_config:
        stdcall CreateArray, sizeof.TConfigRecord
        mov     [esi+TConfigRecord.Data], eax
        mov     [esi+TConfigRecord.DataSize], 4
        retn

.handle_blob:
        mov     ecx, [.size]
        stdcall GetMem, ecx
        mov     [esi+TConfigRecord.Data], eax
        mov     [esi+TConfigRecord.DataSize], ecx

        push    esi
        mov     edi, eax
        mov     esi, [.value]
        rep movsb
        pop     esi
        retn
endp




endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/equates/Linux/XftCompat.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
; 
;  * $Id: XftCompat.h,v 1.4 2005/07/03 07:00:57 daniels Exp $
;  *
;  * Copyright © 2001 Keith Packard
;  *
;  * Permission to use, copy, modify, distribute, and sell this software and its
;  * documentation for any purpose is hereby granted without fee, provided that
;  * the above copyright notice appear in all copies and that both that
;  * copyright notice and this permission notice appear in supporting
;  * documentation, and that the name of Keith Packard not be used in
;  * advertising or publicity pertaining to distribution of the software without
;  * specific, written prior permission.  Keith Packard makes no
;  * representations about the suitability of this software for any purpose.  It
;  * is provided "as is" without express or implied warranty.
;  *
;  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
;  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
;  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
;  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
;  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
;  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
;  * PERFORMANCE OF THIS SOFTWARE.
;  

if ~defined  _XFTCOMPAT_H_ | defined @f
@@:
_XFTCOMPAT_H_	=	1
include	"X11/Xfuncproto.h"  


; 
;  * Compatibility definitions -- map Fc names to Xft names
;  

XftChar8	equ	 FcChar8	   
XftChar16	equ	 FcChar16   
XftChar32	equ	 FcChar32   

XFT_FAMILY	equ	FC_FAMILY
XFT_STYLE	equ	FC_STYLE
XFT_SLANT	equ	FC_SLANT
XFT_WEIGHT	equ	FC_WEIGHT
XFT_SIZE	equ	FC_SIZE
XFT_PIXEL_SIZE	equ	FC_PIXEL_SIZE
XFT_SPACING	equ	FC_SPACING
XFT_FOUNDRY	equ	FC_FOUNDRY
XFT_ANTIALIAS	equ	FC_ANTIALIAS
XFT_FILE	equ	FC_FILE
XFT_INDEX	equ	FC_INDEX
XFT_RASTERIZER	equ	FC_RASTERIZER
XFT_OUTLINE	equ	FC_OUTLINE
XFT_SCALABLE	equ	FC_SCALABLE
XFT_RGBA	equ	FC_RGBA

;  defaults from resources 
XFT_SCALE	equ	FC_SCALE
XFT_MINSPACE	equ	FC_MINSPACE
XFT_DPI	equ	FC_DPI

;  specific to FreeType rasterizer 
XFT_CHAR_WIDTH	equ	FC_CHAR_WIDTH
XFT_CHAR_HEIGHT	equ	FC_CHAR_HEIGHT
XFT_MATRIX	equ	FC_MATRIX

XFT_WEIGHT_LIGHT	equ	FC_WEIGHT_LIGHT
XFT_WEIGHT_MEDIUM	equ	FC_WEIGHT_MEDIUM
XFT_WEIGHT_DEMIBOLD	equ	FC_WEIGHT_DEMIBOLD
XFT_WEIGHT_BOLD	equ	FC_WEIGHT_BOLD
XFT_WEIGHT_BLACK	equ	FC_WEIGHT_BLACK

XFT_SLANT_ROMAN	equ	FC_SLANT_ROMAN
XFT_SLANT_ITALIC	equ	FC_SLANT_ITALIC
XFT_SLANT_OBLIQUE	equ	FC_SLANT_OBLIQUE

XFT_PROPORTIONAL	equ	FC_PROPORTIONAL
XFT_MONO	equ	FC_MONO
XFT_CHARCELL	equ	FC_CHARCELL

XFT_RGBA_UNKNOWN	equ	FC_RGBA_UNKNOWN
XFT_RGBA_RGB	equ	FC_RGBA_RGB
XFT_RGBA_BGR	equ	FC_RGBA_BGR
XFT_RGBA_VRGB	equ	FC_RGBA_VRGB
XFT_RGBA_VBGR	equ	FC_RGBA_VBGR
XFT_RGBA_NONE	equ	FC_RGBA_NONE

; 
;  * Old constants
;  
XFT_ENCODING	equ	"encoding"

XftType	equ	 FcType

XftMatrix	equ	 FcMatrix


XftResult	equ	 FcResult   

XftResultMatch	equ	FcResultMatch
XftResultNoMatch	equ	FcResultNoMatch
XftResultTypeMismatch	equ	FcResultTypeMismatch
XftResultNoId	equ	FcResultNoId

XftValue	equ	 FcValue	
XftPattern	equ	 FcPattern
XftFontSet	equ	 FcFontSet
XftObjectSet	equ	 FcObjectSet

XftGlyphExists	equ	XftCharExists

XftObjectSetCreate	equ	FcObjectSetCreate
XftObjectSetAdd	equ	FcObjectSetAdd
XftObjectSetDestroy	equ	FcObjectSetDestroy
XftObjectSetVaBuild	equ	FcObjectSetVaBuild
XftObjectSetBuild	equ	FcObjectSetBuild

XftFontSetMatch	equ	FcFontSetMatch
XftFontSetDestroy	equ	FcFontSetDestroy

XftMatrixEqual	equ	FcMatrixEqual
XftMatrixMultiply	equ	FcMatrixMultiply
XftMatrixRotate	equ	FcMatrixRotate
XftMatrixScale	equ	FcMatrixScale
XftMatrixShear	equ	FcMatrixShear

XftPatternCreate	equ	FcPatternCreate
XftPatternDuplicate	equ	FcPatternDuplicate
XftValueDestroy	equ	FcValueDestroy
XftValueListDestroy	equ	FcValueListDestroy
XftPatternDestroy	equ	FcPatternDestroy
XftPatternFind	equ	FcPatternFind
XftPatternAdd	equ	FcPatternAdd
XftPatternGet	equ	FcPatternGet
XftPatternDel	equ	FcPatternDel
XftPatternAddInteger	equ	FcPatternAddInteger
XftPatternAddDouble	equ	FcPatternAddDouble
XftPatternAddMatrix	equ	FcPatternAddMatrix
XftPatternAddBool	equ	FcPatternAddBool
XftPatternGetInteger	equ	FcPatternGetInteger
XftPatternGetDouble	equ	FcPatternGetDouble
XftPatternGetMatrix	equ	FcPatternGetMatrix
XftPatternGetBool	equ	FcPatternGetBool
XftPatternVaBuild	equ	FcPatternVaBuild
XftPatternBuild	equ	FcPatternBuild

XftUtf8ToUcs	=	4
		FcUtf8ToUcs4
XftUtf	=	8
Len		FcUtf8Len

XftTypeVoid	equ	FcTypeVoid
XftTypeInteger	equ	FcTypeInteger
XftTypeDouble	equ	FcTypeDouble
XftTypeString	equ	FcTypeString
XftTypeBool	equ	FcTypeBool
XftTypeMatrix	equ	FcTypeMatrix





end if
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































Deleted freshlib/equates/Linux/Xrender.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
; 
;  *
;  * Copyright © 2000 SuSE, Inc.
;  *
;  * Permission to use, copy, modify, distribute, and sell this software and its
;  * documentation for any purpose is hereby granted without fee, provided that
;  * the above copyright notice appear in all copies and that both that
;  * copyright notice and this permission notice appear in supporting
;  * documentation, and that the name of SuSE not be used in advertising or
;  * publicity pertaining to distribution of the software without specific,
;  * written prior permission.  SuSE makes no representations about the
;  * suitability of this software for any purpose.  It is provided "as is"
;  * without express or implied warranty.
;  *
;  * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
;  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
;  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
;  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
;  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
;  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
;  *
;  * Author:  Keith Packard, SuSE, Inc.
;  

if ~defined  _XRENDER_H_ | defined @f
@@:
_XRENDER_H_	=	1

include	"X11/Xlib.h"  

include	"X11/Xfuncproto.h"  

include	"X11/Xosdefs.h"  

include	"X11/Xutil.h"  


include	"X11/extensions/render.h"  


struct
{

	.red:		rw 1
	.redMask:		rw 1
	.green:		rw 1
	.greenMask:		rw 1
	.blue:		rw 1
	.blueMask:		rw 1
	.alpha:		rw 1
	.alphaMask:		rw 1

}


struct
{

    PictFormat		id;
	.type:		rd 1
	.depth:		rd 1
    XRenderDirectFormat	direct;
    Colormap		colormap;

}



struc	_XRenderPictureAttributes
{

	.repeat:		rd 1
    Picture		alpha_map;
	.alpha_x_origin:		rd 1
	.alpha_y_origin:		rd 1
	.clip_x_origin:		rd 1
	.clip_y_origin:		rd 1
    Pixmap		clip_mask;
    Bool		graphics_exposures;
	.subwindow_mode:		rd 1
	.poly_edge:		rd 1
	.poly_mode:		rd 1
    Atom		dither;
    Bool		component_alpha;

	_XRenderPictureAttributes_size	=	$ - .
}


struct
{

	.red:		rw 1
	.green:		rw 1
	.blue:		rw 1
	.alpha:		rw 1

}


struc	_XGlyphInfo
{

	.width:		rw 1
	.height:		rw 1
	.x:		rw 1
	.y:		rw 1
	.xOff:		rw 1
	.yOff:		rw 1

	_XGlyphInfo_size	=	$ - .
}


struc	_XGlyphElt8
{

    GlyphSet		    glyphset;
	.chars:		rd 1
	.nchars:		rd 1
	.xOff:		rd 1
	.yOff:		rd 1

	_XGlyphElt8_size	=	$ - .
}


struc	_XGlyphElt16
{

    GlyphSet		    glyphset;
	.chars:		rd 1
	.nchars:		rd 1
	.xOff:		rd 1
	.yOff:		rd 1

	_XGlyphElt16_size	=	$ - .
}


struc	_XGlyphElt32
{

    GlyphSet		    glyphset;
	.chars:		rd 1
	.nchars:		rd 1
	.xOff:		rd 1
	.yOff:		rd 1

	_XGlyphElt32_size	=	$ - .
}


XDouble	equ	 double

struc	_XPointDouble
{

	.x:		rq 1
	.y:		rq 1

	_XPointDouble_size	=	$ - .
}



XFixed	equ	 int

struc	_XPointFixed
{

    XFixed  x;
    XFixed  y;

	_XPointFixed_size	=	$ - .
}


struc	_XLineFixed
{

    XPointFixed p1;
    XPointFixed p2;

	_XLineFixed_size	=	$ - .
}


struc	_XTriangle
{

    XPointFixed p1;
    XPointFixed p2;
    XPointFixed p3;

	_XTriangle_size	=	$ - .
}


struc	_XCircle
{

    XFixed x;
    XFixed y;
    XFixed radius;

	_XCircle_size	=	$ - .
}


struc	_XTrapezoid
{

    XFixed  top;
    XFixed  bottom;
    XLineFixed left;
    XLineFixed right;

	_XTrapezoid_size	=	$ - .
}


struc	_XTransform
{

    XFixed  matrix[3][3];

	_XTransform_size	=	$ - .
}


struc	_XFilters
{

	.nfilter:		rd 1
	.filter:		rd 1
	.nalias:		rd 1
	.alias:		rd 1

	_XFilters_size	=	$ - .
}


struc	_XIndexValue
{

	.pixel:		rd 1
	.red:		rw 1
	.green:		rw 1
	.blue:		rw 1
	.alpha:		rw 1

	_XIndexValue_size	=	$ - .
}


struc	_XAnimCursor
{

    Cursor	    cursor;
	.delay:		rd 1

	_XAnimCursor_size	=	$ - .
}


struc	_XSpanFix
{

    XFixed left;
    XFixed right;
    XFixed y;

	_XSpanFix_size	=	$ - .
}


struc	_XTrap
{

    XSpanFix top;
    XSpanFix bottom;

	_XTrap_size	=	$ - .
}


struc	_XLinearGradient
{

    XPointFixed p1;
    XPointFixed p2;

	_XLinearGradient_size	=	$ - .
}


struc	_XRadialGradient
{

    XCircle inner;
    XCircle outer;

	_XRadialGradient_size	=	$ - .
}


struc	_XConicalGradient
{

    XPointFixed center;
    XFixed angle;  ;  in degrees 

	_XConicalGradient_size	=	$ - .
}










PictStandardARGB32	=	0

PictStandardRGB24	=	1

PictStandardA8	=	2

PictStandardA4	=	3

PictStandardA1	=	4

PictStandardNUM	=	5








































end if
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/equates/Linux/_XLib.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: XLib specific constants and structures.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


; X Protocol
 X_PROTOCOL              =       11
 X_PROTOCOL_REVISION     =       0

;X Constants

None            =       0
ParentRelative  =       1
CopyFromParent  =       0
PointerWindow   =       0
InputFocus      =       1
PointerRoot     =       1
AnyPropertyType =       0
AnyKey          =       0
AnyButton       =       0
AllTemporary    =       0
CurrentTime     =       0
NoSymbol        =       0

;Event Masks

NoEventMask              =       0h
KeyPressMask             =       1h
KeyReleaseMask           =       2h
ButtonPressMask          =       4h
ButtonReleaseMask        =       8h
EnterWindowMask          =      10h
LeaveWindowMask          =      20h
PointerMotionMask        =      40h
PointerMotionHintMask    =      80h
Button1MotionMask        =     100h
Button2MotionMask        =     200h
Button3MotionMask        =     400h
Button4MotionMask        =     800h
Button5MotionMask        =    1000h
ButtonMotionMask         =    2000h
KeymapStateMask          =    4000h
ExposureMask             =    8000h
VisibilityChangeMask     =   10000h
StructureNotifyMask      =   20000h
ResizeRedirectMask       =   40000h
SubstructureNotifyMask   =   80000h
SubstructureRedirectMask =  100000h
FocusChangeMask          =  200000h
PropertyChangeMask       =  400000h
ColormapChangeMask       =  800000h
OwnerGrabButtonMask      = 1000000h

AllEventsMask            = 1fbff7fh   ;1ffffffh




;Event           Names

KeyPress                =       2
KeyRelease              =       3
ButtonPress             =       4
ButtonRelease           =       5
MotionNotify            =       6
EnterNotify             =       7
LeaveNotify             =       8
FocusIn                 =       9
FocusOut                =       10
KeymapNotify            =       11
Expose                  =       12
GraphicsExpose          =       13
NoExpose                =       14
VisibilityNotify        =       15
CreateNotify            =       16
DestroyNotify           =       17
UnmapNotify             =       18
MapNotify               =       19
MapRequest              =       20
ReparentNotify          =       21
ConfigureNotify         =       22
ConfigureRequest        =       23
GravityNotify           =       24
ResizeRequest           =       25
CirculateNotify         =       26
CirculateRequest        =       27
PropertyNotify          =       28
SelectionClear          =       29
SelectionRequest        =       30
SelectionNotify         =       31
ColormapNotify          =       32
ClientMessage           =       33
MappingNotify           =       34
LASTEvent               =       35

;Key             Masks

ShiftMask       =       1h
LockMask        =       2h
ControlMask     =       4h
Mod1Mask        =       8h
Mod2Mask        =       10h
Mod3Mask        =       20h
Mod4Mask        =       40h
Mod5Mask        =       80h

;Modifier                Names

ShiftMapIndex   =       0
LockMapIndex    =       1
ControlMapIndex =       2
Mod1MapIndex    =       3
Mod2MapIndex    =       4
Mod3MapIndex    =       5
Mod4MapIndex    =       6
Mod5MapIndex    =       7

;Button          Masks

Button1Mask     =       100h
Button2Mask     =       200h
Button3Mask     =       400h
Button4Mask     =       800h
Button5Mask     =       1000h
AnyModifier     =       10000h

;Button          Names

Button1         =       1
Button2         =       2
Button3         =       3
Button4         =       4
Button5         =       5

;Notify          Modes
NotifyNormal    =       0
NotifyGrab      =       1
NotifyUngrab    =       2
NotifyWhileGrabbed      =       3
NotifyHint      =       1

;Notify          Detail

NotifyAncestor  =       0
NotifyVirtual   =       1
NotifyInferior  =       2
NotifyNonlinear =       3
NotifyNonlinearVirtual  =       4
NotifyPointer   =       5
NotifyPointerRoot       =       6
NotifyDetailNone        =       7

;Visibility              Notify

VisibilityUnobscured    =       0
VisibilityPartiallyObscured     =       1
VisibilityFullyObscured =       2

;Circulation             request

PlaceOnTop      =       0
PlaceOnBottom   =       1

;Protocol                Families

FamilyInternet  =       0
FamilyDECnet    =       1
FamilyChaos     =       2
FamilyInternet6 =       6

;Unspecific              authentication  families

FamilyServerInterpreted =       5

;Property       Notification

PropertyNewValue        =       0
PropertyDelete  =       1

;Color           Map     notification

ColormapUninstalled     =       0
ColormapInstalled       =       1

;Grab            Modes
GrabModeSync    =       0
GrabModeAsync   =       1

;Grab            reply   status
GrabSuccess     =       0
AlreadyGrabbed  =       1
GrabInvalidTime =       2
GrabNotViewable =       3
GrabFrozen      =       4

;AllowEvents             modes
AsyncPointer    =       0
SyncPointer     =       1
ReplayPointer   =       2
AsyncKeyboard   =       3
SyncKeyboard    =       4
ReplayKeyboard  =       5
AsyncBoth       =       6
SyncBoth        =       7

;InputFocus              specific

RevertToNone    =       None
RevertToPointerRoot     =       PointerRoot
RevertToParent  =       2

;Error           Codes
Success                 =       0
BadRequest              =       1
BadValue                =       2
BadWindow               =       3
BadPixmap               =       4
BadAtom                 =       5
BadCursor               =       6
BadFont                 =       7
BadMatch                =       8
BadDrawable             =       9
BadAccess               =       10
BadAlloc                =       11
BadColor                =       12
BadGC                   =       13
BadIDChoice             =       14
BadName                 =       15
BadLength               =       16
BadImplementation       =       17
FirstExtensionError     =       128
LastExtensionError      =       255

;Window          Classes

InputOutput     =       1
InputOnly       =       2

;Window          Attributes
CWBackPixmap    =       1h
CWBackPixel     =       2h
CWBorderPixmap  =       4h
CWBorderPixel   =       8h
CWBitGravity    =       10h
CWWinGravity    =       20h
CWBackingStore  =       40h
CWBackingPlanes =       80h
CWBackingPixel  =       100h
CWOverrideRedirect =    200h
CWSaveUnder     =       400h
CWEventMask     =       800h
CWDontPropagate =       1000h
CWColormap      =       2000h
CWCursor        =       4000h

;ConfigureWindow         Structure
CWX             =       1h
CWY             =       2h
CWWidth         =       4h
CWHeight        =       8h
CWBorderWidth   =       10h
CWSibling       =       20h
CWStackMode     =       40h

;Bit             Gravity
ForgetGravity           =       0
NorthWestGravity        =       1
NorthGravity            =       2
NorthEastGravity        =       3
WestGravity             =       4
CenterGravity           =       5
EastGravity             =       6
SouthWestGravity        =       7
SouthGravity            =       8
SouthEastGravity        =       9
StaticGravity           =       10

;Window          Gravity
UnmapGravity    =       0

;CreateWindow            backing-store   hint
NotUseful       =       0
WhenMapped      =       1
Always  =       2

;GetWindowAttributes             reply
IsUnmapped      =       0
IsUnviewable    =       1
IsViewable      =       2

;Used            in      ChangeSaveSet
SetModeInsert   =       0
SetModeDelete   =       1

;Used            in      ChangeCloseDownMode
DestroyAll      =       0
RetainPermanent =       1
RetainTemporary =       2

;Window          stacking        method  (in     configureWindow)
Above   =       0
Below   =       1
TopIf   =       2
BottomIf        =       3
Opposite        =       4

;Circulation             direction
RaiseLowest     =       0
LowerHighest    =       1

;Property                modes
PropModeReplace =       0
PropModePrepend =       1
PropModeAppend  =       2

;Graphics Functions
GXclear         =       0
GXand           =       1
GXandReverse    =       2
GXcopy          =       3
GXandInverted   =       4
GXnoop          =       5
GXxor           =       6
GXor            =       7
GXnor           =       8
GXequiv         =       9
GXinvert        =       10
GXorReverse     =       11
GXcopyInverted  =       12
GXorInverted    =       13
GXnand          =       14
GXset           =       15

;LineStyle
LineSolid       =       0
LineOnOffDash   =       1
LineDoubleDash  =       2

;capStyle
CapNotLast      =       0
CapButt         =       1
CapRound        =       2
CapProjecting   =       3

;joinStyle
JoinMiter       =       0
JoinRound       =       1
JoinBevel       =       2

;fillStyle
FillSolid       =       0
FillTiled       =       1
FillStippled    =       2
FillOpaqueStippled      =       3

;fillRule

EvenOddRule     =       0
WindingRule     =       1

;subwindow               mode

ClipByChildren  =       0
IncludeInferiors        =       1

;SetClipRectangles               ordering

Unsorted        =       0
YSorted =       1
YXSorted        =       2
YXBanded        =       3

;CoordinateMode          for     drawing routines

CoordModeOrigin =       0
CoordModePrevious       =       1

;Polygon         shapes

Complex =       0
Nonconvex       =       1
Convex  =       2

;Arc             modes   for     PolyFillArc

ArcChord        =       0
ArcPieSlice     =       1

;GC              components

GCFunction      =       1h
GCPlaneMask     =       2h
GCForeground    =       4h
GCBackground    =       8h
GCLineWidth     =       10h
GCLineStyle     =       20h
GCCapStyle      =       40h
GCJoinStyle     =       80h
GCFillStyle     =       100h
GCFillRule      =       200h
GCTile  =       400h
GCStipple       =       800h
GCTileStipXOrigin       =       1000h
GCTileStipYOrigin       =       2000h
GCFont  =       4000h
GCSubwindowMode =       8000h
GCGraphicsExposures     =       10000h
GCClipXOrigin   =       20000h
GCClipYOrigin   =       40000h
GCClipMask      =       80000h
GCDashOffset    =       100000h
GCDashList      =       200000h
GCArcMode       =       400000h

GCLastBit       =       22

GCAll = (1 shl (GCLastBit+1)) -1

struct XGCValues
  .function    dd ?                     ;  logical operation
  .plane_mask  dd ?                     ;  plane mask
  .foreground  dd ?                     ;  foreground pixel
  .background  dd ?                     ;  background pixel
  .line_width  dd ?                     ;  line width (in pixels)
  .line_style  dd ?                     ;  LineSolid, LineOnOffDash, LineDoubleDash
  .cap_style   dd ?                     ;  CapNotLast, CapButt, CapRound, CapProjecting
  .join_style  dd ?                     ;  JoinMiter, JoinRound, JoinBevel
  .fill_style  dd ?                     ;  FillSolid, FillTiled, FillStippled FillOpaqueStippled
  .fill_rule   dd ?                     ;  EvenOddRule, WindingRule
  .arc_mode    dd ?                     ;  ArcChord, ArcPieSlice
  .tile        dd ?                     ;  tile pixmap for tiling operations
  .stipple     dd ?                     ;  stipple 1 plane pixmap for stippling
  .ts_x_origin dd ?                     ;  offset for tile or stipple operations
  .ts_y_origin dd ?
  .font        dd ?                     ;  default text font for text operations
  .subwindow_mode dd ?                  ;  ClipByChildren, IncludeInferiors
  .fraphics_exposures dd ?              ;  boolean, should exposures be generated
  .clip_x_origin dd ?                   ;  origin for clipping
  .clip_y_origin dd ?
  .clip_mask   dd ?                     ;  bitmap clipping; other calls for rects
  .dash_offset dd ?                     ;  patterned/dashed line information
  .dashes      dd ?
ends


;used            in      QueryFont       --      draw    direction

FontLeftToRight =       0
FontRightToLeft =       1

FontChange      =       255

;ImageFormat             --      PutImage,       GetImage

XYBitmap        =       0
XYPixmap        =       1
ZPixmap =       2

;For             CreateColormap

AllocNone       =       0
AllocAll        =       1


;Flags           used    in      StoreNamedColor,        StoreColors

DoRed   =       1h
DoGreen =       2h
DoBlue  =       4h

;QueryBestSize           Class

CursorShape     =       0
TileShape       =       1
StippleShape    =       2

;Keyboard                pointer stuff

AutoRepeatModeOff       =       0
AutoRepeatModeOn        =       1
AutoRepeatModeDefault   =       2

LedModeOff      =       0
LedModeOn       =       1

;masks           for     ChangeKeyboardControl

KBKeyClickPercent       =       1h
KBBellPercent   =       2h
KBBellPitch     =       4h
KBBellDuration  =       8h
KBLed   =       10h
KBLedMode       =       20h
KBKey   =       40h
KBAutoRepeatMode        =       80h

MappingSuccess  =       0
MappingBusy     =       1
MappingFailed   =       2

MappingModifier =       0
MappingKeyboard =       1
MappingPointer  =       2

;Screensaver             stuff

DontPreferBlanking      =       0
PreferBlanking  =       1
DefaultBlanking =       2

DisableScreenSaver      =       0
DisableScreenInterval   =       0

DontAllowExposures      =       0
AllowExposures  =       1
DefaultExposures        =       2

;for             ForceScreenSaver

ScreenSaverReset        =       0
ScreenSaverActive       =       1

;for             ChangeHosts

HostInsert      =       0
HostDelete      =       1

;for             ChangeAccessControl

EnableAccess    =       1
DisableAccess   =       0

;display         classes

StaticGray      =       0
GrayScale       =       1
StaticColor     =       2
PseudoColor     =       3
TrueColor       =       4
DirectColor     =       5


;Byte            order           used    in      imageByteOrder  and     bitmapBitOrder

LSBFirst        =       0
MSBFirst        =       1

;Keyboard and Pointer Event Structures

struct   XButtonEvent
  .type         rd    1
  .serial       rd    1
  .send_event   rd    1
  .display      rd    1
  .window       rd    1
  .root         rd    1
  .subwindow    rd    1
  .time         rd    1
  .x            rd    1
  .y            rd    1
  .x_root       rd    1
  .y_root       rd    1
  .state        rd    1
  .button       rd    1
  .same_screen  rd    1
ends


virtual at 0
XButtonPressedEvent  XButtonEvent
end virtual

virtual at 0
XButtonReleasedEvent XButtonEvent
end virtual

struct   XKeyEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .root                           rd    1
        .subwindow                      rd    1
        .time                           rd    1
        .x                              rd    1
        .y                              rd    1
        .x_root                         rd    1
        .y_root                         rd    1
        .state                          rd    1
        .keycode                        rd    1
        .same_screen                    rd    1
ends


virtual at 0
XKeyPressedEvent   XKeyEvent
end virtual

virtual at 0
XKeyReleasedEvent  XKeyEvent
end virtual


struct   XMotionEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .root                           rd    1
        .subwindow                      rd    1
        .time                           rd    1
        .x                              rd    1
        .y                              rd    1
        .x_root                         rd    1
        .y_root                         rd    1
        .state                          rd    1
        .is_hint                        rb    1
        .same_screen                    rd    1
ends


virtual at 0
XPointerMovedEvent  XMotionEvent
end virtual

;Window Entry/Exit Events

struct   XCrossingEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .root                           rd    1
        .subwindow                      rd    1
        .time                           rd    1
        .x                              rd    1
        .y                              rd    1
        .x_root                         rd    1
        .y_root                         rd    1
        .mode                           rd    1
        .detail                         rd    1
        .same_screen                    rd    1
        .focus                          rd    1
        .state                          rd    1
ends

virtual at 0
XEnterWindowEvent  XCrossingEvent
end virtual

virtual at 0
XLeaveWindowEvent  XCrossingEvent
end virtual

;       Input           Focus   Events

struct   XFocusChangeEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .mode                           rd    1
        .detail                         rd    1
ends



virtual at 0
XFocusInEvent  XFocusChangeEvent
end virtual

virtual at 0
XFocusOutEvent  XFocusChangeEvent
end virtual

;       Keymap          Notification    Events

struct   XKeymapEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .key_vector                     rb    32
ends

;       Exposure/Update         Events

struct   XExposeEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .x                              rd    1
        .y                              rd    1
        .width                          rd    1
        .height                         rd    1
        .count                          rd    1
ends


struct   XGraphicsExposeEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .drawable                       rd    1
        .x                              rd    1
        .y                              rd    1
        .width                          rd    1
        .height                         rd    1
        .count                          rd    1
        .major_code                     rd    1
        .minor_code                     rd    1
ends


struct   XNoExposeEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .drawable                       rd    1
        .major_code                     rd    1
        .minor_code                     rd    1
ends


;       CirculateNotify         Events

struct   XCirculateEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
        .place                          rd    1
ends


struct   XCirculateRequestEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .parent                         rd    1
        .window                         rd    1
        .place                          rd    1
ends

;       Configuration           Change  Events

struct   XConfigureEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
        .x                              rd    1
        .y                              rd    1
        .width                          rd    1
        .height                         rd    1
        .border_width                   rd    1
        .above                          rd    1
        .override_redirect              rd    1
ends

struct   XConfigureRequestEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .parent                         rd    1
        .window                         rd    1
        .x                              rd    1
        .y                              rd    1
        .width                          rd    1
        .height                         rd    1
        .border_width                   rd    1
        .above                          rd    1
        .detail                         rd    1
        .value_mask                     rd    1
ends

struct   XPropertyEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .atom                           rd    1
        .time                           rd    1
        .state                          rd    1
ends

struct   XResizeEvent
        .type                           rd    1
        .serial                         rd    1
        .display                        rd    1
        .window                         rd    1
        .width                          rd    1
        .height                         rd    1
ends

struct   XColormapEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .colormap                       rd    1
        .new                            rd    1
        .state                          rd    1
ends

;       Creation/Destruction            Notifications

struct   XCreateWindowEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .parent                         rd    1
        .window                         rd    1
        .x                              rd    1
        .y                              rd    1
        .width                          rd    1
        .heigth                         rd    1
        .border_width                   rd    1
        .override_redirect              rd    1
ends


struct   XDestroyWindowEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
ends

;       Parent          Movement        Events

struct   XGravityEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
        .x                              rd    1
        .y                              rd    1
ends

;       Mapping         Events

struct   XMapEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
        .override_redirect              rd    1
ends

struct   XMappingEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .request                        rd    1
        .first_keycode                  rd    1
        .count                          rd    1
ends


struct   XMapRequestEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .parent                         rd    1
        .window                         rd    1
ends

;       Parent          Change  Events

struct   XReparentEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
        .parent                         rd    1
        .x                              rd    1
        .y                              rd    1
        .override_redirect              rd    1
ends

struct   XSelectionClearEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .selection                      rd    1
        .time                           rd    1
ends

struct   XSelectionRequestEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .owner                          rd    1
        .requestor                      rd    1
        .selection                      rd    1
        .target                         rd    1
        .property                       rd    1
        .time                           rd    1
ends

struct   XSelectionEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .requestor                      rd    1
        .selection                      rd    1
        .target                         rd    1
        .property                       rd    1
        .time                           rd    1
ends

;       Hidden          Window  Events

struct   XUnmapEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .event                          rd    1
        .window                         rd    1
        .from_configure                 rd    1
ends

struct   XVisibilityEvent
        .type                           rd    1
        .serial                         rd    1
        .send_event                     rd    1
        .display                        rd    1
        .window                         rd    1
        .state                          rd    1
ends

;       Client          Messages        (XSendEvent)

struct   XClientMessageEvent
  .type                           rd    1
  .serial                         rd    1
  .send_event                     rd    1
  .display                        rd    1
  .window                         rd    1
  .message_type                   rd    1
  .format                         rd    1
  .data                           rb    20
ends


struct   XErrorEvent
  .type         dd    ?
  .display      dd    ?
  .resourceid   dd    ?
  .serial       dd    ?
  .error_code   db    ?
  .request_code db    ?
  .minor_code   db    ?
ends



struct XAnyEvent
  .type         rd    1
  .serial       rd    1
  .send_event   rd    1
  .display      rd    1
  .window       rd    1
ends


struct XEvent
  .xany XAnyEvent
  .pad  rb 24*4 - sizeof.XAnyEvent

  virtual at .xany
  . XAnyEvent
  end virtual


  virtual at .xany
  .xkey XKeyEvent
  end virtual

  virtual at .xany
  .xbutton XButtonEvent
  end virtual

  virtual at .xany
  .xmotion XMotionEvent
  end virtual

  virtual at .xany
  .xcrossing XCrossingEvent
  end virtual

  virtual at .xany
  .xfocus XFocusChangeEvent
  end virtual

  virtual at .xany
  .xexpose XExposeEvent
  end virtual

  virtual at .xany
  .xgraphicsexpose XGraphicsExposeEvent
  end virtual

  virtual at .xany
  .xnoexpose XNoExposeEvent
  end virtual

  virtual at .xany
  .xvisibility XVisibilityEvent
  end virtual

  virtual at .xany
  .xcreatewindow XCreateWindowEvent
  end virtual

  virtual at .xany
  .xdestroywindow XDestroyWindowEvent
  end virtual

  virtual at .xany
  .xunmap XUnmapEvent
  end virtual

  virtual at .xany
  .xmap XMapEvent
  end virtual

  virtual at .xany
  .xmaprequest XMapRequestEvent
  end virtual

  virtual at .xany
  .xreparent XReparentEvent
  end virtual

  virtual at .xany
  .xconfigure XConfigureEvent
  end virtual

  virtual at .xany
  .xgravity XGravityEvent
  end virtual

  virtual at .xany
  .xresizerequest XResizeEvent
  end virtual

  virtual at .xany
  .xconfigurerequest XConfigureRequestEvent
  end virtual

  virtual at .xany
  .xcirculate XCirculateEvent
  end virtual

  virtual at .xany
  .xcirculaterequest XCirculateRequestEvent
  end virtual

  virtual at .xany
  .xproperty XPropertyEvent
  end virtual

  virtual at .xany
  .xselectionclear XSelectionClearEvent
  end virtual

  virtual at .xany
  .xselectionrequest XSelectionRequestEvent
  end virtual

  virtual at .xany
  .xselection XSelectionEvent
  end virtual

  virtual at .xany
  .xcolormap XColormapEvent
  end virtual

  virtual at .xany
  .xclient XClientMessageEvent
  end virtual

  virtual at .xany
  .xmapping XMappingEvent
  end virtual

  virtual at .xany
  .xerror XErrorEvent
  end virtual

  virtual at .xany
  .xkeymap XKeymapEvent
  end virtual
ends


;       Misc.           Structures

struct   XKeyboardControl
        .key_click_percent              rd    1
        .bell_percent                   rd    1
        .bell_pitch                     rd    1
        .bell_duration                  rd    1
        .led                            rd    1
        .led_mode                       rd    1
        .key                            rd    1
        .auto_repeat_mode               rd    1
ends



struct   XModifierKeymap
        .max_keypermod                  rd    1
        .modifiermap                    rd    1
ends




struct XWindowAttributes
  .x                     dd  ?     ; location of window
  .y                     dd  ?     ;
  .width                 dd  ?     ; width and height of window
  .height                dd  ?     ;
  .border_width          dd  ?     ; border width of window
  .depth                 dd  ?     ; depth of window
  .pVisual               dd  ?     ; the associated visual structure
  .root                  dd  ?     ; root of screen containing window
  .class                 dd  ?     ; InputOutput, InputOnly

  .bit_gravity           dd  ?     ; one of the bit gravity values
  .win_gravity           dd  ?     ; one of the window gravity values
  .backing_store         dd  ?     ; NotUseful, WhenMapped, Always
  .backing_planes        dd  ?     ; planes to be preserved if possible
  .backing_pixel         dd  ?     ; value to be used when restoring planes
  .save_under            dd  ?     ; boolean, should bits under be saved?
  .colormap              dd  ?     ; color map to be associated with window
  .map_installed         dd  ?     ; boolean, is color map currently installed
  .map_state             dd  ?     ; IsUnmapped, IsUnviewable, IsViewable
  .all_event_masks       dd  ?    ; set of events all people have interest in
  .your_event_mask       dd  ?          ; my event mask
  .do_not_propagate_mask dd  ?    ; set of events that should not propagate
  .override_redirect     dd  ?    ; boolean value for override-redirect
  .pScreen               dd  ?  ; back pointer to correct screen
ends


struct XSetWindowAttributes
  .background_pixmap    dd  ?           ; background, None, or ParentRelative
  .background_pixel     dd  ?           ; background pixel
  .border_pixmap        dd  ?           ; border of the window or CopyFromParent
  .border_pixel         dd  ?           ; border pixel value
  .bit_gravity          dd  ?           ; one of bit gravity values
  .win_gravity          dd  ?           ; one of the window gravity values
  .backing_store        dd  ?           ; NotUseful, WhenMapped, Always
  .backing_planes       dd  ?           ; planes to be preserved if possible
  .backing_pixel        dd  ?           ; value to use in restoring planes
  .save_under           dd  ?           ; should bits under be saved? (popups)
  .event_mask           dd  ?           ; set of events that should be saved
  .do_not_propagate_mask dd ?           ; set of events that should not propagate
  .override_redirect    dd  ?           ; boolean value for override_redirect
  .colormap             dd  ?           ; color map to be associated with window
  .cursor               dd  ?           ; cursor to be displayed (or None)
ends



struct XCharStruct
  .lbearing   dw ?       ; origin to left edge of raster
  .rbearing   dw ?       ; origin to right edge of raster
  .width      dw ?       ; advance to next char's origin
  .ascent     dw ?       ; baseline to top edge of raster
  .descent    dw ?       ; baseline to bottom edge of raster
  .attributes dw ?       ; per char flags (not predefined)
ends


struct XFontStruct
  .ext_data          dd   ?       ; hook for extension to hang data
  .fid               dd   ?       ; Font id for this font
  .direction         dd   ?       ; hint about the direction font is painted
  .min_char_or_byte2 dd   ?       ; first character
  .max_char_or_byte2 dd   ?       ; last character
  .min_byte1         dd   ?       ; first row that exists
  .max_byte1         dd   ?       ; last row that exists
  .all_chars_exist   dd   ?       ; flag if all characters have nonzero size
  .default_char      dd   ?       ; char to print for undefined character
  .n_properties      dd   ?       ; how many properties there are
  .properties        dd   ?       ; pointer to array of additional properties
  .min_bounds        XCharStruct  ; minimum bounds over all existing char
  .max_bounds        XCharStruct  ; maximum bounds over all existing char
  .per_char          dd   ?       ; first_char to last_char information
  .ascent            dd   ?       ; logical extent above baseline for spacing
  .descent           dd   ?       ; logical decent below baseline for spacing
ends


struct XWindowChanges
  .x            dd ?
  .y            dd ?
  .width        dd ?
  .height       dd ?
  .border_width dd ?
  .sibling      dd ?
  .stack_mode   dd ?
ends


struct XImage
  .width        dd ?                         ; size of image
  .height       dd ?
  .xoffset      dd ?                         ; number of pixels offset in X direction
  .format       dd ?                         ; XYBitmap, XYPixmap, ZPixmap
  .pData        dd ?                         ; pointer to image data
  .byte_order   dd ?                         ; data byte order, LSBFirst=0, MSBFirst=1
  .bitmap_unit  dd ?                         ; quantity of scan line 8, 16, 32
  .bitmap_bit_order dd ?                     ; LSBFirst, MSBFirst
  .bitmap_pad   dd ?                         ; 8, 16, 32 either XY or ZPixmap
  .depth        dd ?                         ; depth of image
  .bytes_per_line dd ?                       ; accelerator to next line
  .bits_per_pixel dd ?                       ; bits per pixel (ZPixmap)
  .red_mask       dd ?                       ; bits in z arrangment
  .green_mask     dd ?                       ; bits in z arrangment
  .blue_mask      dd ?                       ; bits in z arrangment
  .ptrObData      dd ?                       ; hook for object routines to hang on

  .funcCreateImage dd ?                      ; image manipulation routines
  .funcDestroyImage dd ?                     ;
  .funcGetPixel     dd ?
  .funcPutPixel     dd ?
  .funcSubImage     dd ?
  .funcAddPixel     dd ?
ends


struct XWMHints
  .flags dd ?
  .input dd ?
  .initial_state dd ?
  .icon_pixmap   dd ?
  .icon_window   dd ?
  .icon_x        dd ?
  .icon_y        dd ?
  .icon_mask     dd ?
  .window_group  dd ?
ends


InputHint       =       1
StateHint       =       2
IconPixmapHint  =       4
IconWindowHint  =       8
IconPositionHint=       16
IconMaskHint    =       32
WindowGroupHint =       64
UrgencyHint     =       128
AllHints = InputHint or StateHint or IconPixmapHint or IconWindowHint or IconPositionHint or IconMaskHint or WindowGroupHint or UrgencyHint


WithdrawnState  = 0
NormalState = 1
IconicState = 3


; RequestCodes
Xrequests = 0
.CreateWindow            =1
.ChangeWindowAttributes  =2
.GetWindowAttributes     =3
.DestroyWindow           =4
.DestroySubwindows       =5
.ChangeSaveSet           =6
.ReparentWindow          =7
.MapWindow               =8
.MapSubwindows           =9
.UnmapWindow             =10
.UnmapSubwindows         =11
.ConfigureWindow         =12
.CirculateWindow         =13
.GetGeometry             =14
.QueryTree               =15
.InternAtom              =16
.GetAtomName             =17
.ChangeProperty          =18
.DeleteProperty          =19
.GetProperty             =20
.ListProperties          =21
.SetSelectionOwner       =22
.GetSelectionOwner       =23
.ConvertSelection        =24
.SendEvent               =25
.GrabPointer             =26
.UngrabPointer           =27
.GrabButton              =28
.UngrabButton            =29
.ChangeActivePointerGrab =30
.GrabKeyboard            =31
.UngrabKeyboard          =32
.GrabKey                 =33
.UngrabKey               =34
.AllowEvents             =35
.GrabServer              =36
.UngrabServer            =37
.QueryPointer            =38
.GetMotionEvents         =39
.TranslateCoords         =40
.WarpPointer             =41
.SetInputFocus           =42
.GetInputFocus           =43
.QueryKeymap             =44
.OpenFont                =45
.CloseFont               =46
.QueryFont               =47
.QueryTextExtents        =48
.ListFonts               =49
.ListFontsWithInfo       =50
.SetFontPath             =51
.GetFontPath             =52
.CreatePixmap            =53
.FreePixmap              =54
.CreateGC                =55
.ChangeGC                =56
.CopyGC                  =57
.SetDashes               =58
.SetClipRectangles       =59
.FreeGC                  =60
.ClearArea               =61
.CopyArea                =62
.CopyPlane               =63
.PolyPoint               =64
.PolyLine                =65
.PolySegment             =66
.PolyRectangle           =67
.PolyArc                 =68
.FillPoly                =69
.PolyFillRectangle       =70
.PolyFillArc             =71
.PutImage                =72
.GetImage                =73
.PolyText8               =74
.PolyText16              =75
.ImageText8              =76
.ImageText16             =77
.CreateColormap          =78
.FreeColormap            =79
.CopyColormapAndFree     =80
.InstallColormap         =81
.UninstallColormap       =82
.ListInstalledColormaps  =83
.AllocColor              =84
.AllocNamedColor         =85
.AllocColorCells         =86
.AllocColorPlanes        =87
.FreeColors              =88
.StoreColors             =89
.StoreNamedColor         =90
.QueryColors             =91
.LookupColor             =92
.CreateCursor            =93
.CreateGlyphCursor       =94
.FreeCursor              =95
.RecolorCursor           =96
.QueryBestSize           =97
.QueryExtension          =98
.ListExtensions          =99
.ChangeKeyboardMapping   =100
.GetKeyboardMapping      =101
.ChangeKeyboardControl   =102
.GetKeyboardControl      =103
.Bell                    =104
.ChangePointerControl    =105
.GetPointerControl       =106
.SetScreenSaver          =107
.GetScreenSaver          =108
.ChangeHosts             =109
.ListHosts               =110
.SetAccessControl        =111
.SetCloseDownMode        =112
.KillClient              =113
.RotateProperties        =114
.ForceScreenSaver        =115
.SetPointerMapping       =116
.GetPointerMapping       =117
.SetModifierMapping      =118
.GetModifierMapping      =119
.NoOperation             =127


; Predefined atoms from the X server.

XA_PRIMARY      = 1
XA_SECONDARY    = 2
XA_ARC          = 3
XA_ATOM         = 4
XA_BITMAP       = 5
XA_CARDINAL     = 6
XA_COLORMAP     = 7
XA_CURSOR       = 8
XA_CUT_BUFFER0  = 9
XA_CUT_BUFFER1  = 10
XA_CUT_BUFFER2  = 11
XA_CUT_BUFFER3  = 12
XA_CUT_BUFFER4  = 13
XA_CUT_BUFFER5  = 14
XA_CUT_BUFFER6  = 15
XA_CUT_BUFFER7  = 16
XA_DRAWABLE     = 17
XA_FONT         = 18
XA_INTEGER      = 19
XA_PIXMAP       = 20
XA_POINT        = 21
XA_RECTANGLE    = 22
XA_RESOURCE_MANAGER = 23
XA_RGB_COLOR_MAP = 24
XA_RGB_BEST_MAP  = 25
XA_RGB_BLUE_MAP = 26
XA_RGB_DEFAULT_MAP = 27
XA_RGB_GRAY_MAP = 28
XA_RGB_GREEN_MAP = 29
XA_RGB_RED_MAP  = 30
XA_STRING       = 31
XA_VISUALID     = 32
XA_WINDOW       = 33
XA_WM_COMMAND   = 34
XA_WM_HINTS     = 35
XA_WM_CLIENT_MACHINE = 36
XA_WM_ICON_NAME = 37
XA_WM_ICON_SIZE = 38
XA_WM_NAME      = 39
XA_WM_NORMAL_HINTS = 40
XA_WM_SIZE_HINTS = 41
XA_WM_ZOOM_HINTS = 42
XA_MIN_SPACE     = 43
XA_NORM_SPACE    = 44
XA_MAX_SPACE     = 45
XA_END_SPACE     = 46
XA_SUPERSCRIPT_X = 47
XA_SUPERSCRIPT_Y = 48
XA_SUBSCRIPT_X   = 49
XA_SUBSCRIPT_Y   = 50
XA_UNDERLINE_POSITION = 51
XA_UNDERLINE_THICKNESS = 52
XA_STRIKEOUT_ASCENT = 53
XA_STRIKEOUT_DESCENT = 54
XA_ITALIC_ANGLE  = 55
XA_X_HEIGHT      = 56
XA_QUAD_WIDTH    = 57
XA_WEIGHT        = 58
XA_POINT_SIZE    = 59
XA_RESOLUTION    = 60
XA_COPYRIGHT     = 61
XA_NOTICE        = 62
XA_FONT_NAME     = 63
XA_FAMILY_NAME   = 64
XA_FULL_NAME     = 65
XA_CAP_HEIGHT    = 66
XA_WM_CLASS      = 67
XA_WM_TRANSIENT_FOR = 68

XA_LAST_PREDEFINED = 68
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/equates/Linux/_geometry.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Different geometry structures.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


struct RECT
  .left   dd ?
  .top    dd ?
  .right  dd ?
  .bottom dd ?
ends

struct POINT
  .x  dd ?
  .y  dd ?
ends

struct XRectangle
  .x       dw  ?
  .y       dw  ?
  .width   dw  ?
  .height  dw  ?
ends
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































Deleted freshlib/equates/Linux/_linux.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Common Linux equates.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

; Error numbers from the kernel

EPERM       =     1      ; Operation not permitted
ENOENT      =     2      ; No such file or directory
ESRCH       =     3      ; No such process
EINTR       =     4      ; Interrupted system call
EIO         =     5      ; I/O error
ENXIO       =     6      ; No such device or address
E2BIG       =     7      ; Argument list too long
ENOEXEC     =     8      ; Exec format error
EBADF       =     9      ; Bad file number
ECHILD      =    10      ; No child processes
EAGAIN      =    11      ; Try again
ENOMEM      =    12      ; Out of memory
EACCES      =    13      ; Permission denied
EFAULT      =    14      ; Bad address
ENOTBLK     =    15      ; Block device required
EBUSY       =    16      ; Device or resource busy
EEXIST      =    17      ; File exists
EXDEV       =    18      ; Cross-device link
ENODEV      =    19      ; No such device
ENOTDIR     =    20      ; Not a directory
EISDIR      =    21      ; Is a directory
EINVAL      =    22      ; Invalid argument
ENFILE      =    23      ; File table overflow
EMFILE      =    24      ; Too many open files
ENOTTY      =    25      ; Not a typewriter
ETXTBSY     =    26      ; Text file busy
EFBIG       =    27      ; File too large
ENOSPC      =    28      ; No space left on device
ESPIPE      =    29      ; Illegal seek
EROFS       =    30      ; Read-only file system
EMLINK      =    31      ; Too many links
EPIPE       =    32      ; Broken pipe
EDOM        =    33      ; Math argument out of domain of func
ERANGE      =    34      ; Math result not representable

EDEADLK       =  35      ; Resource deadlock would occur
ENAMETOOLONG  =  36      ; File name too long
ENOLCK        =  37      ; No record locks available
ENOSYS        =  38      ; Function not implemented
ENOTEMPTY     =  39      ; Directory not empty
ELOOP         =  40      ; Too many symbolic links encountered
EWOULDBLOCK   =  EAGAIN  ; Operation would block
ENOMSG        =  42      ; No message of desired type
EIDRM         =  43      ; Identifier removed
ECHRNG        =  44      ; Channel number out of range
EL2NSYNC      =  45      ; Level 2 not synchronized
EL3HLT        =  46      ; Level 3 halted
EL3RST        =  47      ; Level 3 reset
ELNRNG        =  48      ; Link number out of range
EUNATCH       =  49      ; Protocol driver not attached
ENOCSI        =  50      ; No CSI structure available
EL2HLT        =  51      ; Level 2 halted
EBADE         =  52      ; Invalid exchange
EBADR         =  53      ; Invalid request descriptor
EXFULL        =  54      ; Exchange full
ENOANO        =  55      ; No anode
EBADRQC       =  56      ; Invalid request code
EBADSLT       =  57      ; Invalid slot

EDEADLOCK     =  EDEADLK

EBFONT        =  59      ; Bad font file format
ENOSTR        =  60      ; Device not a stream
ENODATA       =  61      ; No data available
ETIME         =  62      ; Timer expired
ENOSR         =  63      ; Out of streams resources
ENONET        =  64      ; Machine is not on the network
ENOPKG        =  65      ; Package not installed
EREMOTE       =  66      ; Object is remote
ENOLINK       =  67      ; Link has been severed
EADV          =  68      ; Advertise error
ESRMNT        =  69      ; Srmount error
ECOMM         =  70      ; Communication error on send
EPROTO        =  71      ; Protocol error
EMULTIHOP     =  72      ; Multihop attempted
EDOTDOT       =  73      ; RFS specific error
EBADMSG       =  74      ; Not a data message
EOVERFLOW     =  75      ; Value too large for defined data type
ENOTUNIQ      =  76      ; Name not unique on network
EBADFD        =  77      ; File descriptor in bad state
EREMCHG       =  78      ; Remote address changed
ELIBACC       =  79      ; Can not access a needed shared library
ELIBBAD       =  80      ; Accessing a corrupted shared library
ELIBSCN       =  81      ; .lib section in a.out corrupted
ELIBMAX       =  82      ; Attempting to link in too many shared libraries
ELIBEXEC      =  83      ; Cannot exec a shared library directly
EILSEQ        =  84      ; Illegal byte sequence
ERESTART      =  85      ; Interrupted system call should be restarted
ESTRPIPE      =  86      ; Streams pipe error
EUSERS        =  87      ; Too many users
ENOTSOCK      =  88      ; Socket operation on non-socket
EDESTADDRREQ  =  89      ; Destination address required
EMSGSIZE      =  90      ; Message too long
EPROTOTYPE    =  91      ; Protocol wrong type for socket
ENOPROTOOPT   =  92      ; Protocol not available
EPROTONOSUPPORT =93      ; Protocol not supported
ESOCKTNOSUPPORT =94      ; Socket type not supported
EOPNOTSUPP      =95      ; Operation not supported on transport endpoint
EPFNOSUPPORT  =  96      ; Protocol family not supported
EAFNOSUPPORT  =  97      ; Address family not supported by protocol
EADDRINUSE    =  98      ; Address already in use
EADDRNOTAVAIL =  99      ; Cannot assign requested address
ENETDOWN      =  100     ; Network is down
ENETUNREACH   =  101     ; Network is unreachable
ENETRESET     =  102     ; Network dropped connection because of reset
ECONNABORTED  =  103     ; Software caused connection abort
ECONNRESET    =  104     ; Connection reset by peer
ENOBUFS       =  105     ; No buffer space available
EISCONN       =  106     ; Transport endpoint is already connected
ENOTCONN      =  107     ; Transport endpoint is not connected
ESHUTDOWN     =  108     ; Cannot send after transport endpoint shutdown
ETOOMANYREFS  =  109     ; Too many references: cannot splice
ETIMEDOUT     =  110     ; Connection timed out
ECONNREFUSED  =  111     ; Connection refused
EHOSTDOWN     =  112     ; Host is down
EHOSTUNREACH  =  113     ; No route to host
EALREADY      =  114     ; Operation already in progress
EINPROGRESS   =  115     ; Operation now in progress
ESTALE        =  116     ; Stale NFS file handle
EUCLEAN       =  117     ; Structure needs cleaning
ENOTNAM       =  118     ; Not a XENIX named type file
ENAVAIL       =  119     ; No XENIX semaphores available
EISNAM        =  120     ; Is a named type file
EREMOTEIO     =  121     ; Remote I/O error
EDQUOT        =  122     ; Quota exceeded

ENOMEDIUM     =  123     ; No medium found
EMEDIUMTYPE   =  124     ; Wrong medium type
ECANCELED     =  125     ; Operation Canceled
ENOKEY        =  126     ; Required key not available
EKEYEXPIRED   =  127     ; Key has expired
EKEYREVOKED   =  128     ; Key has been revoked
EKEYREJECTED  =  129     ; Key was rejected by service

; for robust mutexes
EOWNERDEAD     = 130     ; Owner died
ENOTRECOVERABLE= 131     ; State not recoverable





; System functions ( int $80 )

;         Name              EAX

sys_restart_syscall      =  $00
sys_exit                 =  $01
sys_fork                 =  $02
sys_read                 =  $03
sys_write                =  $04
sys_open                 =  $05
sys_close                =  $06
sys_waitpid              =  $07
sys_creat                =  $08
sys_link                 =  $09
sys_unlink               =  $0a
sys_execve               =  $0b
sys_chdir                =  $0c
sys_time                 =  $0d
sys_mknod                =  $0e
sys_chmod                =  $0f
sys_lchown16             =  $10
sys_stat                 =  $12
sys_lseek                =  $13
sys_getpid               =  $14
sys_mount                =  $15
sys_oldumount            =  $16
sys_setuid16             =  $17
sys_getuid16             =  $18
sys_stime                =  $19
sys_ptrace               =  $1a
sys_alarm                =  $1b
sys_fstat                =  $1c
sys_pause                =  $1d
sys_utime                =  $1e
sys_access               =  $21
sys_nice                 =  $22
sys_sync                 =  $24
sys_kill                 =  $25
sys_rename               =  $26
sys_mkdir                =  $27
sys_rmdir                =  $28
sys_dup                  =  $29
sys_pipe                 =  $2a
sys_times                =  $2b
sys_brk                  =  $2d
sys_setgid16             =  $2e
sys_getgid16             =  $2f
sys_signal               =  $30
sys_geteuid16            =  $31
sys_getegid16            =  $32
sys_acct                 =  $33
sys_umount               =  $34
sys_ioctl                =  $36
sys_fcntl                =  $37
sys_setpgid              =  $39
sys_olduname             =  $3b
sys_umask                =  $3c
sys_chroot               =  $3d
sys_ustat                =  $3e
sys_dup2                 =  $3f
sys_getppid              =  $40
sys_getpgrp              =  $41
sys_setsid               =  $42
sys_sigaction            =  $43
sys_sgetmask             =  $44
sys_ssetmask             =  $45
sys_setreuid16           =  $46
sys_setregid16           =  $47
sys_sigsuspend           =  $48
sys_sigpending           =  $49
sys_sethostname          =  $4a
sys_setrlimit            =  $4b
sys_old_getrlimit        =  $4c
sys_getrusage            =  $4d
sys_gettimeofday         =  $4e
sys_settimeofday         =  $4f
sys_getgroups16          =  $50
sys_setgroups16          =  $51
sys_old_select           =  $52
sys_symlink              =  $53
sys_lstat                =  $54
sys_readlink             =  $55
sys_uselib               =  $56
sys_swapon               =  $57
sys_reboot               =  $58
sys_old_readdir          =  $59
sys_old_mmap             =  $5a
sys_munmap               =  $5b
sys_truncate             =  $5c
sys_ftruncate            =  $5d
sys_fchmod               =  $5e
sys_fchown16             =  $5f
sys_getpriority          =  $60
sys_setpriority          =  $61
sys_statfs               =  $63
sys_fstatfs              =  $64
sys_ioperm               =  $65
sys_socketcall           =  $66
sys_syslog               =  $67
sys_setitimer            =  $68
sys_getitimer            =  $69
sys_newstat              =  $6a
sys_newlstat             =  $6b
sys_newfstat             =  $6c
sys_uname                =  $6d
sys_iopl                 =  $6e
sys_vhangup              =  $6f
sys_vm86old              =  $71
sys_wait4                =  $72
sys_swapoff              =  $73
sys_sysinfo              =  $74
sys_ipc                  =  $75
sys_fsync                =  $76
sys_sigreturn            =  $77
sys_clone                =  $78
sys_setdomainname        =  $79
sys_newuname             =  $7a
sys_modify_ldt           =  $7b
sys_adjtimex             =  $7c
sys_mprotect             =  $7d
sys_sigprocmask          =  $7e
sys_init_module          =  $80
sys_delete_module        =  $81
sys_quotactl             =  $83
sys_getpgid              =  $84
sys_fchdir               =  $85
sys_bdflush              =  $86
sys_sysfs                =  $87
sys_personality          =  $88
sys_setfsuid16           =  $8a
sys_setfsgid16           =  $8b
sys_llseek               =  $8c
sys_getdents             =  $8d
sys_select               =  $8e
sys_flock                =  $8f
sys_msync                =  $90
sys_readv                =  $91
sys_writev               =  $92
sys_getsid               =  $93
sys_fdatasync            =  $94
sys_sysctl               =  $95
sys_mlock                =  $96
sys_munlock              =  $97
sys_mlockall             =  $98
sys_munlockall           =  $99
sys_sched_setparam       =  $9a
sys_sched_getparam       =  $9b
sys_sched_setscheduler   =  $9c
sys_sched_getscheduler   =  $9d
sys_sched_yield          =  $9e
sys_sched_get_priority_m =  $9f
sys_sched_get_priority_m =  $a0
sys_sched_rr_get_interva =  $a1
sys_nanosleep            =  $a2
sys_mremap               =  $a3
sys_setresuid16          =  $a4
sys_getresuid16          =  $a5
sys_vm86                 =  $a6
sys_poll                 =  $a8
sys_nfsservctl           =  $a9
sys_setresgid16          =  $aa
sys_getresgid16          =  $ab
sys_prctl                =  $ac
sys_rt_sigreturn         =  $ad
sys_rt_sigaction         =  $ae
sys_rt_sigprocmask       =  $af
sys_rt_sigpending        =  $b0
sys_rt_sigtimedwait      =  $b1
sys_rt_sigqueueinfo      =  $b2
sys_rt_sigsuspend        =  $b3
sys_pread64              =  $b4
sys_pwrite64             =  $b5
sys_chown16              =  $b6
sys_getcwd               =  $b7
sys_capget               =  $b8
sys_capset               =  $b9
sys_sigaltstack          =  $ba
sys_sendfile             =  $bb
sys_vfork                =  $be
sys_getrlimit            =  $bf
sys_mmap_pgoff           =  $c0
sys_truncate64           =  $c1
sys_ftruncate64          =  $c2
sys_stat64               =  $c3
sys_lstat64              =  $c4
sys_fstat64              =  $c5
sys_lchown               =  $c6
sys_getuid               =  $c7
sys_getgid               =  $c8
sys_geteuid              =  $c9
sys_getegid              =  $ca
sys_setreuid             =  $cb
sys_setregid             =  $cc
sys_getgroups            =  $cd
sys_setgroups            =  $ce
sys_fchown               =  $cf
sys_setresuid            =  $d0
sys_getresuid            =  $d1
sys_setresgid            =  $d2
sys_getresgid            =  $d3
sys_chown                =  $d4
sys_setuid               =  $d5
sys_setgid               =  $d6
sys_setfsuid             =  $d7
sys_setfsgid             =  $d8
sys_pivot_root           =  $d9
sys_mincore              =  $da
sys_madvise              =  $db
sys_getdents64           =  $dc
sys_fcntl64              =  $dd
sys_gettid               =  $e0
sys_readahead            =  $e1
sys_setxattr             =  $e2
sys_lsetxattr            =  $e3
sys_fsetxattr            =  $e4
sys_getxattr             =  $e5
sys_lgetxattr            =  $e6
sys_fgetxattr            =  $e7
sys_listxattr            =  $e8
sys_llistxattr           =  $e9
sys_flistxattr           =  $ea
sys_removexattr          =  $eb
sys_lremovexattr         =  $ec
sys_fremovexattr         =  $ed
sys_tkill                =  $ee
sys_sendfile64           =  $ef
sys_futex                =  $f0
sys_sched_setaffinity    =  $f1
sys_sched_getaffinity    =  $f2
sys_set_thread_area      =  $f3
sys_get_thread_area      =  $f4
sys_io_setup             =  $f5
sys_io_destroy           =  $f6
sys_io_getevents         =  $f7
sys_io_submit            =  $f8
sys_io_cancel            =  $f9
sys_fadvise64            =  $fa
sys_exit_group           =  $fc
sys_lookup_dcookie       =  $fd
sys_epoll_create         =  $fe
sys_epoll_ctl            =  $ff
sys_epoll_wait           =  $100
sys_remap_file_pages     =  $101
sys_set_tid_address      =  $102
sys_timer_create         =  $103
sys_timer_settime        =  $104
sys_timer_gettime        =  $105
sys_timer_getoverrun     =  $106
sys_timer_delete         =  $107
sys_clock_settime        =  $108
sys_clock_gettime        =  $109
sys_clock_getres         =  $10a
sys_clock_nanosleep      =  $10b
sys_statfs64             =  $10c
sys_fstatfs64            =  $10d
sys_tgkill               =  $10e
sys_utimes               =  $10f
sys_fadvise64_64         =  $110
sys_mbind                =  $112
sys_get_mempolicy        =  $113
sys_set_mempolicy        =  $114
sys_mq_open              =  $115
sys_mq_unlink            =  $116
sys_mq_timedsend         =  $117
sys_mq_timedreceive      =  $118
sys_mq_notify            =  $119
sys_mq_getsetattr        =  $11a
sys_kexec_load           =  $11b
sys_waitid               =  $11c
sys_add_key              =  $11e
sys_request_key          =  $11f
sys_keyctl               =  $120
sys_ioprio_set           =  $121
sys_ioprio_get           =  $122
sys_inotify_init         =  $123
sys_inotify_add_watch    =  $124
sys_inotify_rm_watch     =  $125
sys_migrate_pages        =  $126
sys_openat               =  $127
sys_mkdirat              =  $128
sys_mknodat              =  $129
sys_fchownat             =  $12a
sys_futimesat            =  $12b
sys_fstatat64            =  $12c
sys_unlinkat             =  $12d
sys_renameat             =  $12e
sys_linkat               =  $12f
sys_symlinkat            =  $130
sys_readlinkat           =  $131
sys_fchmodat             =  $132
sys_faccessat            =  $133
sys_pselect6             =  $134
sys_ppoll                =  $135
sys_unshare              =  $136
sys_set_robust_list      =  $137
sys_get_robust_list      =  $138
sys_splice               =  $139
sys_sync_file_range      =  $13a
sys_tee                  =  $13b
sys_vmsplice             =  $13c
sys_move_pages           =  $13d
sys_getcpu               =  $13e
sys_epoll_pwait          =  $13f
sys_utimensat            =  $140
sys_signalfd             =  $141
sys_timerfd_create       =  $142
sys_eventfd              =  $143
sys_fallocate            =  $144
sys_timerfd_settime      =  $145
sys_timerfd_gettime      =  $146
sys_signalfd4            =  $147
sys_eventfd2             =  $148
sys_epoll_create1        =  $149
sys_dup3                 =  $14a
sys_pipe2                =  $14b
sys_inotify_init1        =  $14c
sys_preadv               =  $14d
sys_pwritev              =  $14e
sys_rt_tgsigqueueinfo    =  $14f
sys_perf_event_open      =  $150
sys_recvmmsg             =  $151

;socket commands

SYS_SOCKET      = 1
SYS_BIND        = 2
SYS_CONNECT     = 3
SYS_LISTEN      = 4
SYS_ACCEPT      = 5
SYS_GETSOCKNAME = 6
SYS_GETPEERNAME = 7
SYS_SOCKETPAIR  = 8
SYS_SEND        = 9
SYS_RECV        = 10
SYS_SENDTO      = 11
SYS_RECVFROM    = 12
SYS_SHUTDOWN    = 13
SYS_SETSOCKOPT  = 14
SYS_GETSOCKOPT  = 15
SYS_SENDMSG     = 16
SYS_RECVMSG     = 17

;socket constants

AF_UNSPEC       = 0
AF_UNIX         = 1
AF_LOCAL        = 1
AF_INET         = 2
AF_AX25         = 3
AF_IPX          = 4
AF_APPLETALK    = 5
AF_NETROM       = 6
AF_BRIDGE       = 7
AF_ATMPVC       = 8
AF_X25          = 9
AF_INET6        = 10
AF_ROSE         = 11
AF_DECnet       = 12
AF_NETBEUI      = 13
AF_SECURITY     = 14
AF_KEY          = 15
AF_NETLINK      = 16
AF_ROUTE        = AF_NETLINK
AF_PACKET       = 17
AF_ASH          = 18
AF_ECONET       = 19
AF_ATMSVC       = 20
AF_SNA          = 22
AF_IRDA         = 23
AF_PPPOX        = 24
AF_WANPIPE      = 25
AF_LLC          = 26
AF_TIPC         = 30
AF_BLUETOOTH    = 31
AF_MAX          = 32

PF_UNSPEC       = AF_UNSPEC
PF_UNIX         = AF_UNIX
PF_LOCAL        = AF_LOCAL
PF_INET         = AF_INET
PF_AX25         = AF_AX25
PF_IPX          = AF_IPX
PF_APPLETALK    = AF_APPLETALK
PF_NETROM       = AF_NETROM
PF_BRIDGE       = AF_BRIDGE
PF_ATMPVC       = AF_ATMPVC
PF_X25          = AF_X25
PF_INET6        = AF_INET6
PF_ROSE         = AF_ROSE
PF_DECnet       = AF_DECnet
PF_NETBEUI      = AF_NETBEUI
PF_SECURITY     = AF_SECURITY
PF_KEY          = AF_KEY
PF_NETLINK      = AF_NETLINK
PF_ROUTE        = AF_ROUTE
PF_PACKET       = AF_PACKET
PF_ASH          = AF_ASH
PF_ECONET       = AF_ECONET
PF_ATMSVC       = AF_ATMSVC
PF_SNA          = AF_SNA
PF_IRDA         = AF_IRDA
PF_PPPOX        = AF_PPPOX
PF_WANPIPE      = AF_WANPIPE
PF_LLC          = AF_LLC
PF_TIPC         = AF_TIPC
PF_BLUETOOTH    = AF_BLUETOOTH
PF_MAX          = AF_MAX

SOCK_STREAM     = 1
SOCK_DGRAM      = 2
SOCK_RAW        = 3
SOCK_RDM        = 4
SOCK_SEQPACKET  = 5
SOCK_DCCP       = 6
SOCK_PACKET     = 10


; socket flags
MSG_OOB         = 1
MSG_PEEK        = 2
MSG_DONTROUTE   = 4
MSG_TRYHARD     = 4
MSG_CTRUNC      = 8
MSG_PROBE       = 0x10
MSG_TRUNC       = 0x20
MSG_DONTWAIT    = 0x40
MSG_EOR         = 0x80
MSG_WAITALL     = 0x100
MSG_FIN         = 0x200
MSG_SYN         = 0x400
MSG_CONFIRM     = 0x800
MSG_RST         = 0x1000
MSG_ERRQUEUE    = 0x2000
MSG_NOSIGNAL    = 0x4000
MSG_MORE        = 0x8000


SOL_SOCKET      = 1

SO_DEBUG        = 1
SO_REUSEADDR    = 2
SO_TYPE         = 3
SO_ERROR        = 4
SO_DONTROUTE    = 5
SO_BROADCAST    = 6
SO_SNDBUF       = 7
SO_RCVBUF       = 8
SO_SNDBUFFORCE  = 32
SO_RCVBUFFORCE  = 33
SO_KEEPALIVE    = 9
SO_OOBINLINE    = 10
SO_NO_CHECK     = 11
SO_PRIORITY     = 12
SO_LINGER       = 13
SO_BSDCOMPAT    = 14
SO_PASSCRED     = 16
SO_PEERCRED     = 17
SO_RCVLOWAT     = 18
SO_SNDLOWAT     = 19
SO_RCVTIMEO     = 20
SO_SNDTIMEO     = 21



; Signal values
; default action is: "Term" - terminate; "Core" - terminate with core dump; "Ign" - ignore; "Stop" - stop the process; "Cont" - continue the process.

macro signal name, value {
  name = value
  .mask = 1 shl value
}

signal SIGHUP   ,  1    ; Term    Hangup detected on controlling terminal or death of controlling process
signal SIGINT   ,  2    ; Term    Interrupt from keyboard
signal SIGQUIT  ,  3    ; Core    Quit from keyboard
signal SIGILL   ,  4    ; Core    Illegal Instruction
signal SIGTRAP  ,  5    ; Core    Trace/breakpoint trap
signal SIGABRT  ,  6    ; Core    Abort signal from abort(3)
signal SIGIOT   ,  6    ; Core    IOT trap. A synonym for SIGABRT
signal SIGBUS   ,  7    ; Core    Bus error (bad memory access)
signal SIGFPE   ,  8    ; Core    Floating point exception
signal SIGKILL  ,  9    ; Term    Kill signal
signal SIGUSR1  , 10    ; Term    User-defined signal 1
signal SIGSEGV  , 11    ; Core    Invalid memory reference
signal SIGUSR2  , 12    ; Term    User-defined signal 2
signal SIGPIPE  , 13    ; Term    Broken pipe: write to pipe with no readers
signal SIGALRM  , 14    ; Term    Timer signal from alarm(2)
signal SIGTERM  , 15    ; Term    Termination signal
signal SIGSTKFLT, 16    ; Term    Stack fault on coprocessor (unused)
signal SIGCHLD  , 17    ; Ign     Child stopped or terminated
signal SIGCONT  , 18    ; Cont    Continue if stopped
signal SIGSTOP  , 19    ; Stop    Stop process
signal SIGTSTP  , 20    ; Stop    Stop typed at tty
signal SIGTTIN  , 21    ; Stop    tty input for background process
signal SIGTTOU  , 22    ; Stop    tty output for background process
signal SIGURG   , 23    ; Ign     Urgent condition on socket (4.2BSD)
signal SIGXCPU  , 24    ; Core    CPU time limit exceeded (4.2BSD)
signal SIGXFSZ  , 25    ; Core    File size limit exceeded (4.2BSD)
signal SIGVTALRM, 26    ; Term    Virtual alarm clock (4.2BSD)
signal SIGPROF  , 27    ; Term    Profiling timer expired
signal SIGWINCH , 28    ; Ign     Window resize signal (4.3BSD, Sun)
signal SIGIO    , 29    ; Term    I/O now possible (4.2BSD)
signal SIGPWR   , 30    ; Term    Power failure (System V)
signal SIGSYS   , 31    ; Core    Bad argument to routine (SVr4)
signal SIGUNUSED, 31    ; Core    Synonymous with SIGSYS

SIGRTMIN = 34
SIGRTMAX = 64

; signal flags

SA_ONSTACK    =  $00000001      ;  Call the signal handler on an alternate signal stack provided by
                                ;  sigaltstack(2).  If an alternate stack is not available, the
                                ;  default stack will be used.  This flag is only meaningful when
                                ;  establishing a signal handler.



SA_RESETHAND  =  $00000004      ;  Restore the signal action to the default state once the signal
                                ;  handler has been called.  This flag is only meaningful when
                                ;  establishing a signal handler.  SA_ONESHOT is an obsolete,
                                ;  nonstandard synonym for this flag.


SA_NOCLDSTOP  =  $00000008      ; If signum is SIGCHLD, do not receive notification when child
                                ; processes stop (i.e., when they receive one of SIGSTOP, SIGTSTP,
                                ; SIGTTIN or SIGTTOU) or resume (i.e., they receive SIGCONT) (see
                                ; wait(2)).  This flag is only meaningful when establishing a handler
                                ; for SIGCHLD.


SA_SIGINFO    =  $00000010      ;  The signal handler takes 3 arguments, not one.  In this case,
                                ;  sa_sigaction should be set instead of sa_handler.  This flag is
                                ;  only meaningful when establishing a signal handler.


SA_NODEFER    =  $00000020      ; Do not prevent the signal from being received from within its own
                                ; signal handler.  This flag is only meaningful when establishing a
                                ; signal handler.  SA_NOMASK is an obsolete, nonstandard synonym for
                                ; this flag.


SA_RESTART    =  $00000040      ;  Provide behavior compatible with BSD signal semantics by making
                                ;  certain system calls restartable across signals.  This flag is only
                                ;  meaningful when establishing a signal handler.  See signal(7) for a
                                ;  discussion of system call restarting.


SA_NOCLDWAIT  =  $00000080      ; If signum is SIGCHLD, do not transform children into zombies when
                                ; they terminate.  See also waitpid(2).  This flag is only meaningful
                                ; when establishing a handler for SIGCHLD, or when setting that
                                ; signal's disposition to SIG_DFL.
                                ;
                                ; If the SA_NOCLDWAIT flag is set when establishing a handler for
                                ; SIGCHLD, POSIX.1 leaves it unspecified whether a SIGCHLD signal is
                                ; generated when a child process terminates.  On Linux, a SIGCHLD
                                ; signal is generated in this case; on some other implementations, it
                                ; is not.


SA_NOMASK     =  SA_NODEFER
SA_ONESHOT    =  SA_RESETHAND
SA_INTERRUPT  =  $20000000      ; dummy -- ignored
SA_RESTORER   =  $04000000      ; obsolete -- ignored

; Signals hanlers constants

SIG_DFL = 0     ; default signal handling
SIG_IGN = 1     ; ignore signal
SIG_ERR = -1    ; error return from signal


; Interval timers structures

ITIMER_REAL    = 0
ITIMER_VIRTUAL = 1
ITIMER_PROF    = 2


struct lnx_sigaction
  .sa_handler   dd ?      ; SIG_DFL, SIG_IGN or ptr proc Handler, .signal
  .sa_sigaction dd ?      ; ptr proc SigAction, .signal, .ptrSignalInfo, .ptr
  .sa_mask      dd ?      ; mask of the signals
  .sa_flags     dd ?      ;
  .sa_restorer  dd ?      ; obsolete, don't use
ends



struct lnx_timeval
  .tv_sec  dd ?
  .tv_usec dd ?
ends

struct lnx_timezone
  .tz_minuteswest dd ?
  .tz_dsttime     dd ?
ends



struct lnx_itimerval
  .it_interval lnx_timeval
  .it_value    lnx_timeval
ends


; structures and equates for timer_xxxx POSIX functions


CLOCK_REALTIME            =  0 ; Identifier for system-wide realtime clock.
CLOCK_MONOTONIC           =  1 ; Monotonic system-wide clock.
CLOCK_PROCESS_CPUTIME_ID  =  2 ; High-resolution timer from the CPU.
CLOCK_THREAD_CPUTIME_ID   =  3 ; Thread-specific CPU-time clock.

SIGEV_SIGNAL = 0     ; Notify via signal.
SIGEV_NONE   = 1     ; Other notification: meaningless.
SIGEV_THREAD = 2     ; Deliver via thread creation.
SIGEV_THREAD_ID = 4  ; Send signal to specific thread.


struct lnx_sigevent
  .notify           dd ?
  .signo            dd ?
  .value            dd ?
  .ptr_notify_proc  dd ?
  .ptr_notify_attr  dd ?
  .notify_thread_id dd ?
ends

struct lnx_timespec
  .tv_sec  dd ?   ; time in seconds
  .tv_nsec dd ?   ; time is nano seconds
ends


struct lnx_itimerspec
  .it_interval lnx_timespec
  .it_value    lnx_timespec
ends


; sys_clone function flags

CLONE_VM                =  $00000100      ; set if VM shared between processes
CLONE_FS                =  $00000200      ; set if fs info shared between processes
CLONE_FILES             =  $00000400      ; set if open files shared between processes
CLONE_SIGHAND           =  $00000800      ; set if signal handlers and blocked signals shared
CLONE_PTRACE            =  $00002000      ; set if we want to let tracing continue on the child too
CLONE_VFORK             =  $00004000      ; set if the parent wants the child to wake it up on mm_release
CLONE_PARENT            =  $00008000      ; set if we want to have the same parent as the cloner
CLONE_THREAD            =  $00010000      ; Same thread group?
CLONE_NEWNS             =  $00020000      ; New namespace group?
CLONE_SYSVSEM           =  $00040000      ; share system V SEM_UNDO semantics
CLONE_SETTLS            =  $00080000      ; create a new TLS for the child
CLONE_PARENT_SETTID     =  $00100000      ; set the TID in the parent
CLONE_CHILD_CLEARTID    =  $00200000      ; clear the TID in the child
CLONE_DETACHED          =  $00400000      ; Unused, ignored
CLONE_UNTRACED          =  $00800000      ; set if the tracing process can't force CLONE_PTRACE on this clone
CLONE_CHILD_SETTID      =  $01000000      ; set the TID in the child
CLONE_STOPPED           =  $02000000      ; Start in stopped state
CLONE_NEWUTS            =  $04000000      ; New utsname group?
CLONE_NEWIPC            =  $08000000      ; New ipcs
CLONE_NEWUSER           =  $10000000      ; New user namespace
CLONE_NEWPID            =  $20000000      ; New pid namespace
CLONE_NEWNET            =  $40000000      ; New network namespace
CLONE_IO                =  $80000000      ; Clone io context


; Memory constants

; Protections are chosen from these bits, OR'd together.  The
;   implementation does not necessarily support PROT_EXEC or PROT_WRITE
;   without PROT_READ.  The only guarantees are that no writing will be
;   allowed without PROT_WRITE and no access will be allowed for PROT_NONE.

PROT_READ       =  $1             ; Page can be read.
PROT_WRITE      =  $2             ; Page can be written.
PROT_EXEC       =  $4             ; Page can be executed.
PROT_NONE       =  $0             ; Page can not be accessed.
PROT_GROWSDOWN  =  $01000000      ; Extend change to start of
                                        ; growsdown vma (mprotect only).
PROT_GROWSUP    =  $02000000      ; Extend change to start of
                                        ; growsup vma (mprotect only).

; Sharing types (must choose one and only one of these).
MAP_SHARED      =  $01            ; Share changes.
MAP_PRIVATE     =  $02            ; Changes are private.
MAP_TYPE        =  $0f            ; Mask for type of mapping.


; Other flags.
MAP_FIXED       =  $10            ; Interpret addr exactly.
MAP_ANONYMOUS   =  $20            ; Don't use a file.
MAP_32BIT       =  $40            ; Only give out 32-bit addresses.


; These are Linux-specific.
MAP_GROWSDOWN  =  $00100          ; Stack-like segment.
MAP_DENYWRITE  =  $00800          ; ETXTBSY
MAP_EXECUTABLE =  $01000          ; Mark it as an executable.
MAP_LOCKED     =  $02000          ; Lock the mapping.
MAP_NORESERVE  =  $04000          ; Don't check for reservations.
MAP_POPULATE   =  $08000          ; Populate (prefault) pagetables.
MAP_NONBLOCK   =  $10000          ; Do not block on IO.
MAP_STACK      =  $20000          ; Allocation is for a stack.


; Flags to `msync'.
MS_ASYNC       = 1                ; Sync memory asynchronously.
MS_SYNC        = 4                ; Synchronous memory sync.
MS_INVALIDATE  = 2                ; Invalidate the caches.


; Flags for `mlockall'.
MCL_CURRENT    = 1                ; Lock all currently mapped pages.
MCL_FUTURE     = 2                ; Lock all additions to address space.

; Flags for `mremap'.
MREMAP_MAYMOVE = 1
MREMAP_FIXED   = 2

; Advice to `madvise'.
MADV_NORMAL     = 0      ; No further special treatment.
MADV_RANDOM     = 1      ; Expect random page references.
MADV_SEQUENTIAL = 2      ; Expect sequential page references.
MADV_WILLNEED   = 3      ; Will need these pages.
MADV_DONTNEED   = 4      ; Don't need these pages.
MADV_REMOVE     = 9      ; Remove these pages and resources.
MADV_DONTFORK   = 10     ; Do not inherit across fork.
MADV_DOFORK     = 11     ; Do inherit across fork.


; The POSIX people had to invent similar names for the same things.
POSIX_MADV_NORMAL      = 0 ; No further special treatment.
POSIX_MADV_RANDOM      = 1 ; Expect random page references.
POSIX_MADV_SEQUENTIAL  = 2 ; Expect sequential page references.
POSIX_MADV_WILLNEED    = 3 ; Will need these pages.
POSIX_MADV_DONTNEED    = 4 ; Don't need these pages.



; sys_futex constants


FUTEX_WAIT             = 0
FUTEX_WAKE             = 1
FUTEX_FD               = 2
FUTEX_REQUEUE          = 3
FUTEX_CMP_REQUEUE      = 4
FUTEX_WAKE_OP          = 5
FUTEX_LOCK_PI          = 6
FUTEX_UNLOCK_PI        = 7
FUTEX_TRYLOCK_PI       = 8
FUTEX_WAIT_BITSET      = 9
FUTEX_WAKE_BITSET      = 10


; sys_fstat and similar structures

struct STAT
  .st_dev     dw  ?     ; ID of device containing file
  .pad1       dw  ?
  .st_ino     dd  ?     ; inode number
  .st_mode    dw  ?     ; protection
  .st_nlink   dw  ?     ; number of hard links
  .st_uid     dw  ?     ; user ID of owner
  .st_gid     dw  ?     ; group ID of owner
  .st_rdev    dw  ?     ; device ID (if special file)
  .pad2       dw  ?
  .st_size    dd  ?     ; total size, in bytes
  .st_blksize dd  ?     ; block size
  .st_blocks  dd  ?

  .st_atime   dd  ?     ; time of last access
  .unused1    dd  ?

  .st_mtime   dd  ?     ; time of last modification
  .unused2    dd  ?

  .st_ctime   dd  ?     ; time of last status change
  .unused3    dd  ?
  .unused4    dd  ?
  .unused5    dd  ?
ends


; sys_getdents

; it is variable length structure.
struct linux_dirent
  .d_ino dd ?
  .d_off dd ?
  .d_reclen dw ?
  label .d_name byte
ends

; file types for the above structure.
; this value is written at the last byte of the structure. (linux_dirent.d_reclen-1)

DT_UNKNOWN   =   0
DT_FIFO      =   1
DT_CHR       =   2
DT_DIR       =   4
DT_BLK       =   6
DT_REG       =   8      ; regular file
DT_LNK       =   10
DT_SOCK      =   12
DT_WHT       =   14

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/equates/Linux/_pthreads.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Equates for pthread library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

; mutex types.

PTHREAD_MUTEX_NORMAL        = 0
PTHREAD_MUTEX_RECURSIVE     = 1
PTHREAD_MUTEX_ERRORCHECK    = 2
PTHREAD_MUTEX_ERRORCHECK_NP = PTHREAD_MUTEX_ERRORCHECK
PTHREAD_MUTEX_RECURSIVE_NP  = PTHREAD_MUTEX_RECURSIVE
PTHREAD_MUTEX_DEFAULT       = PTHREAD_MUTEX_NORMAL

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































Deleted freshlib/equates/Linux/_xft.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: XFT library constants and structures.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________



struct XRenderColor
  .red   dw ?
  .green dw ?
  .blue  dw ?
  .alpha dw ?
ends


XFT_MAJOR       =       2
XFT_MINOR       =       1
XFT_REVISION    =       8
XftVersion      equ     XFT_VERSION

XFT_CORE                equ     "core"
XFT_RENDER              equ     "render"
XFT_XLFD                equ     "xlfd"
XFT_MAX_GLYPH_MEMORY    equ     "maxglyphmemory"
XFT_MAX_UNREF_FONTS     equ     "maxunreffonts"


FcTypeVoid      = 0
FcTypeInteger   = 1
FcTypeDouble    = 2
FcTypeString    = 3
FcTypeBool      = 4
FcTypeMatrix    = 5
FcTypeCharSet   = 6
FcTypeFTFace    = 7
FcTypeLangSet   = 8

XftTypeVoid      =  FcTypeVoid
XftTypeInteger   =  FcTypeInteger
XftTypeDouble    =  FcTypeDouble
XftTypeString    =  FcTypeString
XftTypeBool      =  FcTypeBool
XftTypeMatrix    =  FcTypeMatrix
XftTypeCharSet   =  FcTypeCharSet
XftTypeFTFace    =  FcTypeFTFace
XftTypeLangSet   =  FcTypeLangSet

FC_SLANT_ROMAN   = 0
FC_SLANT_ITALIC  = 100
FC_SLANT_OBLIQUE = 110

XFT_SLANT_ROMAN   =  FC_SLANT_ROMAN
XFT_SLANT_ITALIC  =  FC_SLANT_ITALIC
XFT_SLANT_OBLIQUE =  FC_SLANT_OBLIQUE

FC_PROPORTIONAL         =  0
FC_DUAL                 =  90
FC_MONO                 =  100
FC_CHARCELL             =  110

XFT_PROPORTIONAL         =  FC_PROPORTIONAL
XFT_DUAL                 =  FC_DUAL
XFT_MONO                 =  FC_MONO
XFT_CHARCELL             =  FC_CHARCELL


struct   _XftFont
  .ascent                dd ?
  .descent               dd ?
  .height                dd ?
  .max_advance_width     dd ?
  .charset               dd ?
  .pattern               dd ?
ends


struct  _XftColor
  .pixel  dd ?
  .color  XRenderColor
ends


struct _XftCharSpec
  .ucs4  dd ?
  .x:    dw ?
  .y:    dw ?
ends


struct   _XftCharFontSpec
  .font  dd ?
  .ucs4  dd ?
  .x     dw ?
  .y     dw ?
ends


struct _XftGlyphSpec
  .glyph  dd ?
  .x      dw ?
  .y      dw ?
ends


struct _XftGlyphFontSpec
  .font   dd ?
  .glyph  dd ?
  .x      dw ?
  .y      dw ?
ends


struct _XGlyphInfo
  .width  dw ?
  .height dw ?
  .x      dw ?
  .y      dw ?
  .xOff   dw ?
  .yOff   dw ?
ends
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































Deleted freshlib/equates/Linux/allequates.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Combined include of all Linux equates.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

; Linux programming constants
include '_geometry.inc'
include '_linux.inc'
include '_XLib.inc'
include '_xft.inc'
include '_pthreads.inc'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted freshlib/equates/Win32/_COMCTL32.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: COMCTL32.DLL structures and constants
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

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 ?
ends

struct IMAGEINFO
  .hbmImage dd ?
  .hbmMask  dd ?
  .Unused1  dd ?
  .Unused2  dd ?
  .rcImage  dd ?
ends

struct HDITEM
  .mask       dd ?
  .cxy        dd ?
  .pszText    dd ?
  .hbm        dd ?
  .cchTextMax dd ?
  .fmt        dd ?
  .lParam     dd ?
ends

struct HDLAYOUT
  .prc   dd ?
  .pwpos dd ?
ends

struct HDHITTESTINFO
  .pt    POINT
  .flags dd ?
  .iItem dd ?
ends

struct HDNOTIFY
  .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 TOOLTOPTEXT
  .hdr      NMHDR
  .lpszText dd ?
  .szText   rb 80
  .hinst    dd ?
  .uFlags   dd ?
ends

struct UDACCEL
  .nSec dd ?
  .nInc dd ?
ends

struct NMUPDOWN
  .hdr    NMHDR
  .iPos   dd ?
  .iDelta dd ?
ends

struct LVITEM
  .mask       dd ?
  .iItem      dd ?
  .iSubItem   dd ?
  .state      dd ?
  .stateMask  dd ?
  .pszText    dd ?
  .cchTextMax dd ?
  .iImage     dd ?
  .lParam     dd ?
  .iIndent    dd ?
ends

struct LVFINDINFO
  .flags       dd ?
  .psz         dd ?
  .lParam      dd ?
  .pt          POINT
  .vkDirection dd ?
ends

struct LVHITTESTINFO
  .pt    POINT
  .flags dd ?
  .iItem dd ?
ends

struct LVCOLUMN
  .mask       dd ?
  .fmt        dd ?
  .cx         dd ?
  .pszText    dd ?
  .cchTextMax dd ?
  .iSubItem   dd ?
ends

struct NMLISTVIEW
  .hdr       NMHDR
  .iItem     dd ?
  .iSubItem  dd ?
  .uNewState dd ?
  .uOldState dd ?
  .uChanged  dd ?
  .ptAction  POINT
  .lParam    dd ?
ends

struct NMCACHEHINT
  .hdr   NMHDR
  .iFrom dd ?
  .iTo   dd ?
ends

struct NMFINDITEM
  .hdr    NMHDR
  .iStart dd ?
  .lvfi   LVFINDINFO
ends

struct LVDISPINFO
  .hdr  NMHDR
  .item LVITEM
ends

struct LVKEYDOWN
  .hdr   NMHDR
  .wVKey dw ?
  .flags dd ?
ends

struct TVITEM
  .mask           dd ?
  .hItem          dd ?
  .state          dd ?
  .stateMask      dd ?
  .pszText        dd ?
  .cchTextMax     dd ?
  .iImage         dd ?
  .iSelectedImage dd ?
  .cChildren      dd ?
  .lParam         dd ?
ends

struct TVINSERTSTRUCT
  .hParent      dd ?
  .hInsertAfter dd ?
  .item         TVITEM
ends

struct TVHITTESTINFO
  .pt    POINT
  .flags dd ?
  .hItem dd ?
ends

struct TVSORTCB
  .hParent     dd ?
  .lpfnCompare dd ?
  .lParam      dd ?
ends

struct NMTREEVIEW
  .hdr     NMHDR
  .action  dd ?
  .itemOld TVITEM
  .itemNew TVITEM
  .ptDrag  POINT
ends

struct TVDISPINFO
  .hdr  NMHDR
  .item TVITEM
ends

struct TVKEYDOWN
  .hdr   NMHDR
  .wVKey dw ?
  .flags dd ?
ends

struct TCITEMHEADER
  .mask        dd ?
  .lpReserved1 dd ?
  .lpReserved2 dd ?
  .pszText     dd ?
  .cchTextMax  dd ?
  .iImage      dd ?
ends

struct TCITEM
  .mask        dd ?
  .lpReserved1 dd ?
  .lpReserved2 dd ?
  .pszText     dd ?
  .cchTextMax  dd ?
  .iImage      dd ?
  .lParam      dd ?
ends

struct TCHITTESTINFO
  .pt    POINT
  .flags dd ?
ends

struct TCKEYDOWN
  .hdr   NMHDR
  .wVKey dw ?
  .flags dd ?
ends

struct MCHITTESTINFO
  .cbSize dd ?
  .pt     POINT
  .uHit   dd ?
  .st     SYSTEMTIME
ends

struct NMSELCHANGE
  .nmhdr      NMHDR
  .stSelStart SYSTEMTIME
  .stSelEnd   SYSTEMTIME
ends

struct NMDAYSTATE
  .nmhdr       NMHDR
  .stStart     SYSTEMTIME
  .cDayState   dd ?
  .prgDayState dd ?
ends

struct NMDATETIMECHANGE
  .nmhdr   NMHDR
  .dwFlags dd ?
  .st      SYSTEMTIME
ends

struct NMDATETIMESTRING
  .nmhdr         NMHDR
  .pszUserString dd ?
  .st            SYSTEMTIME
  .dwFlags       dd ?
ends

struct NMDATETIMEWMKEYDOWN
  .nmhdr     NMHDR
  .nVirtKey  dd ?
  .pszFormat dd ?
  .st        SYSTEMTIME
ends

struct NMDATETIMEFORMAT
  .nmhdr      NMHDR
  .pszFormat  dd ?
  .st         SYSTEMTIME
  .pszDisplay dd ?
  .szDisplay  rb 64
ends

struct NMDATETIMEFORMATQUERY
  .nmhdr     NMHDR
  .pszFormat dd ?
  .szMax     SIZE
ends

struct NMCUSTOMDRAW
  .hdr         NMHDR
  .dwDrawStage dd ?
  .hdc         dd ?
  .rc          RECT
  .dwItemSpec  dd ?
  .uItemState  dd ?
  .lItemlParam dd ?
ends

struct NMLVCUSTOMDRAW
  .nmcd        NMCUSTOMDRAW
  .clrText     dd ?
  .clrTextBk   dd ?
  .iSubItem    dd ?
  .dwItemType  dd ?
  .clrFace     dd ?
  .iIconEffect dd ?
  .iIconPhase  dd ?
  .iPartId     dd ?
  .iStateId    dd ?
  .rcText      RECT
  .uAlign      dd ?
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_AUTOSIZE    = 0010h     ; automatically calculate width of the button
TBSTYLE_NOPREFIX    = 0020h     ; if this button should not have accel prefix

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

; tooltip structures

struct TOOLTIPTEXT
  .hdr      NMHDR
  .lpszText dd ?
  .char     rb 80
  .hinst    dd ?
  .uFlags   dd ?
ends





; 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

; Progress bar styles

PBS_SMOOTH = 1
PBS_VERTICAL = 4


; 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
LVS_EX_BORDERSELECT     = 8000h

; 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

; List view item structure flags

LVIF_TEXT       = 0001h
LVIF_IMAGE      = 0002h
LVIF_PARAM      = 0004h
LVIF_STATE      = 0008h
LVIF_INDENT     = 0010h
LVIF_DI_SETITEM = 1000h

; List view item states

LVIS_FOCUSED        = 00001h
LVIS_SELECTED       = 00002h
LVIS_CUT            = 00004h
LVIS_DROPHILITED    = 00008h
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_ITEMACTIVATE    = LVN_FIRST - 14
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      = 01h
TVS_HASLINES        = 02h
TVS_LINESATROOT     = 04h
TVS_EDITLABELS      = 08h
TVS_DISABLEDRAGDROP = 10h
TVS_SHOWSELALWAYS   = 20h
TVS_RTLREADING      = 40h
TVS_NOTOOLTIPS      = 80h
TVS_CHECKBOXES      = 100h
TVS_TRACKSELECT     = 200h
TVS_SINGLEEXPAND    = 400h
TVS_INFOTIP         = 800h
TVS_FULLROWSELECT   = 1000h
TVS_NOSCROLL        = 2000h
TVS_NONEVENHEIGHT   = 4000h
TVS_NOHSCROLL       = 8000h

; 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  = 0FFFF0000h
TVI_FIRST = 0FFFF0001h
TVI_LAST  = 0FFFF0002h
TVI_SORT  = 0FFFF0003h

; 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     = 8

; 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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/equates/Win32/_COMDLG32.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: COMDLG32.DLL structures and constants
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________



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




















































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/equates/Win32/_GDI32.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: GDI32.DLL structures and constants
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

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        db ?
  .tmLastChar         db ?
  .tmDefaultChar      db ?
  .tmBreakChar        db ?
  .tmItalic           db ?
  .tmUnderlined       db ?
  .tmStruckOut        db ?
  .tmPitchAndFamily   db ?
  .tmCharSet          db ?
  .__align            rb 7
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       rb 32
ends

struct ENUMLOGFONT
  .elfLogFont  LOGFONT
  .elfFullName rb 64
  .elfStyle    rb 32
ends

struct ENUMLOGFONTEX
  .elfLogFont  LOGFONT
  .elfFullName rb 64
  .elfStyle    rb 32
  .elfScript   rb 32
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

; 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

DIB_RGB_COLORS = 0
DIB_PAL_COLORS = 1

; Object types for GetCurrentObject

OBJ_PEN     = 1
OBJ_BRUSH   = 2
OBJ_PAL     = 5
OBJ_FONT    = 6
OBJ_BITMAP  = 7

; Additional constants for GetObjectType
OBJ_DC      = $03
OBJ_MEMDC   = $0a
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/equates/Win32/_HTMLHELP.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: HtmlHelp constants and structures.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

; Commands to pass to HtmlHelp()

HH_DISPLAY_TOPIC        = 0x0000
HH_HELP_FINDER          = 0x0000  ; WinHelp equivalent
HH_DISPLAY_TOC          = 0x0001
HH_DISPLAY_INDEX        = 0x0002
HH_DISPLAY_SEARCH       = 0x0003
HH_SET_WIN_TYPE         = 0x0004
HH_GET_WIN_TYPE         = 0x0005
HH_GET_WIN_HANDLE       = 0x0006
HH_ENUM_INFO_TYPE       = 0x0007  ; Get Info type name, call repeatedly to enumerate, -1 at end
HH_SET_INFO_TYPE        = 0x0008  ; Add Info type to filter.
HH_SYNC                 = 0x0009
HH_RESERVED1            = 0x000A
HH_RESERVED2            = 0x000B
HH_RESERVED3            = 0x000C
HH_KEYWORD_LOOKUP       = 0x000D
HH_DISPLAY_TEXT_POPUP   = 0x000E  ; display string resource id or text in a popup window
HH_HELP_CONTEXT         = 0x000F  ; display mapped numeric value in dwData
HH_TP_HELP_CONTEXTMENU  = 0x0010  ; text popup help, same as WinHelp HELP_CONTEXTMENU
HH_TP_HELP_WM_HELP      = 0x0011  ; text popup help, same as WinHelp HELP_WM_HELP
HH_CLOSE_ALL            = 0x0012  ; close all windows opened directly or indirectly by the caller
HH_ALINK_LOOKUP         = 0x0013  ; ALink version of HH_KEYWORD_LOOKUP
HH_GET_LAST_ERROR       = 0x0014  ; not currently implemented // See HHERROR.h
HH_ENUM_CATEGORY        = 0x0015  ; Get category name, call repeatedly to enumerate, -1 at end
HH_ENUM_CATEGORY_IT     = 0x0016  ; Get category info type members, call repeatedly to enumerate, -1 at end
HH_RESET_IT_FILTER      = 0x0017  ; Clear the info type filter of all info types.
HH_SET_INCLUSIVE_FILTER = 0x0018  ; set inclusive filtering method for untyped topics to be included in display
HH_SET_EXCLUSIVE_FILTER = 0x0019  ; set exclusive filtering method for untyped topics to be excluded from display
HH_INITIALIZE           = 0x001C  ; Initializes the help system.
HH_UNINITIALIZE         = 0x001D  ; Uninitializes the help system.
HH_PRETRANSLATEMESSAGE  = 0x00fd  ; Pumps messages. (NULL, NULL, MSG*).
HH_SET_GLOBAL_PROPERTY  = 0x00fc  ; Set a global property. (NULL, NULL, HH_GPROP)

HHWIN_PROP_TAB_AUTOHIDESHOW = 1 shl 0    ; Automatically hide/show tri-pane window
HHWIN_PROP_ONTOP            = 1 shl 1    ; Top-most window
HHWIN_PROP_NOTITLEBAR       = 1 shl 2    ; no title bar
HHWIN_PROP_NODEF_STYLES     = 1 shl 3    ; no default window styles (only HH_WINTYPE.dwStyles)
HHWIN_PROP_NODEF_EXSTYLES   = 1 shl 4    ; no default extended window styles (only HH_WINTYPE.dwExStyles)
HHWIN_PROP_TRI_PANE         = 1 shl 5    ; use a tri-pane window
HHWIN_PROP_NOTB_TEXT        = 1 shl 6    ; no text on toolbar buttons
HHWIN_PROP_POST_QUIT        = 1 shl 7    ; post WM_QUIT message when window closes
HHWIN_PROP_AUTO_SYNC        = 1 shl 8    ; automatically ssync contents and index
HHWIN_PROP_TRACKING         = 1 shl 9    ; send tracking notification messages
HHWIN_PROP_TAB_SEARCH       = 1 shl 10   ; include search tab in navigation pane
HHWIN_PROP_TAB_HISTORY      = 1 shl 11   ; include history tab in navigation pane
HHWIN_PROP_TAB_FAVORITES    = 1 shl 12   ; include favorites tab in navigation pane
HHWIN_PROP_CHANGE_TITLE     = 1 shl 13   ; Put current HTML title in title bar
HHWIN_PROP_NAV_ONLY_WIN     = 1 shl 14   ; Only display the navigation window
HHWIN_PROP_NO_TOOLBAR       = 1 shl 15   ; Don't display a toolbar
HHWIN_PROP_MENU             = 1 shl 16   ; Menu
HHWIN_PROP_TAB_ADVSEARCH    = 1 shl 17   ; Advanced FTS UI.
HHWIN_PROP_USER_POS         = 1 shl 18   ; After initial creation, user controls window size/position
HHWIN_PROP_TAB_CUSTOM1      = 1 shl 19   ; Use custom tab #1
HHWIN_PROP_TAB_CUSTOM2      = 1 shl 20   ; Use custom tab #2
HHWIN_PROP_TAB_CUSTOM3      = 1 shl 21   ; Use custom tab #3
HHWIN_PROP_TAB_CUSTOM4      = 1 shl 22   ; Use custom tab #4
HHWIN_PROP_TAB_CUSTOM5      = 1 shl 23   ; Use custom tab #5
HHWIN_PROP_TAB_CUSTOM6      = 1 shl 24   ; Use custom tab #6
HHWIN_PROP_TAB_CUSTOM7      = 1 shl 25   ; Use custom tab #7
HHWIN_PROP_TAB_CUSTOM8      = 1 shl 26   ; Use custom tab #8
HHWIN_PROP_TAB_CUSTOM9      = 1 shl 27   ; Use custom tab #9
HHWIN_TB_MARGIN             = 1 shl 28   ; the window type has a margin

HHWIN_PARAM_PROPERTIES      = 1 shl 1    ; valid fsWinProperties
HHWIN_PARAM_STYLES          = 1 shl 2    ; valid dwStyles
HHWIN_PARAM_EXSTYLES        = 1 shl 3    ; valid dwExStyles
HHWIN_PARAM_RECT            = 1 shl 4    ; valid rcWindowPos
HHWIN_PARAM_NAV_WIDTH       = 1 shl 5    ; valid iNavWidth
HHWIN_PARAM_SHOWSTATE       = 1 shl 6    ; valid nShowState
HHWIN_PARAM_INFOTYPES       = 1 shl 7    ; valid apInfoTypes
HHWIN_PARAM_TB_FLAGS        = 1 shl 8    ; valid fsToolBarFlags
HHWIN_PARAM_EXPANSION       = 1 shl 9    ; valid fNotExpanded
HHWIN_PARAM_TABPOS          = 1 shl 10   ; valid tabpos
HHWIN_PARAM_TABORDER        = 1 shl 11   ; valid taborder
HHWIN_PARAM_HISTORY_COUNT   = 1 shl 12   ; valid cHistory
HHWIN_PARAM_CUR_TAB         = 1 shl 13   ; valid curNavType

HHWIN_BUTTON_EXPAND         = 1 shl 1    ; Expand/contract button
HHWIN_BUTTON_BACK           = 1 shl 2    ; Back button
HHWIN_BUTTON_FORWARD        = 1 shl 3    ; Forward button
HHWIN_BUTTON_STOP           = 1 shl 4    ; Stop button
HHWIN_BUTTON_REFRESH        = 1 shl 5    ; Refresh button
HHWIN_BUTTON_HOME           = 1 shl 6    ; Home button
HHWIN_BUTTON_BROWSE_FWD     = 1 shl 7    ; not implemented
HHWIN_BUTTON_BROWSE_BCK     = 1 shl 8    ; not implemented
HHWIN_BUTTON_NOTES          = 1 shl 9    ; not implemented
HHWIN_BUTTON_CONTENTS       = 1 shl 10   ; not implemented
HHWIN_BUTTON_SYNC           = 1 shl 11   ; Sync button
HHWIN_BUTTON_OPTIONS        = 1 shl 12   ; Options button
HHWIN_BUTTON_PRINT          = 1 shl 13   ; Print button
HHWIN_BUTTON_INDEX          = 1 shl 14   ; not implemented
HHWIN_BUTTON_SEARCH         = 1 shl 15   ; not implemented
HHWIN_BUTTON_HISTORY        = 1 shl 16   ; not implemented
HHWIN_BUTTON_FAVORITES      = 1 shl 17   ; not implemented
HHWIN_BUTTON_JUMP1          = 1 shl 18
HHWIN_BUTTON_JUMP2          = 1 shl 19
HHWIN_BUTTON_ZOOM           = 1 shl 20
HHWIN_BUTTON_TOC_NEXT       = 1 shl 21
HHWIN_BUTTON_TOC_PREV       = 1 shl 22

HHWIN_DEF_BUTTONS =HHWIN_BUTTON_EXPAND or HHWIN_BUTTON_BACK or HHWIN_BUTTON_OPTIONS or HHWIN_BUTTON_PRINT

; Button IDs
IDTB_EXPAND             = 200
IDTB_CONTRACT           = 201
IDTB_STOP               = 202
IDTB_REFRESH            = 203
IDTB_BACK               = 204
IDTB_HOME               = 205
IDTB_SYNC               = 206
IDTB_PRINT              = 207
IDTB_OPTIONS            = 208
IDTB_FORWARD            = 209
IDTB_NOTES              = 210 ; not implemented
IDTB_BROWSE_FWD         = 211
IDTB_BROWSE_BACK        = 212
IDTB_CONTENTS           = 213 ; not implemented
IDTB_INDEX              = 214 ; not implemented
IDTB_SEARCH             = 215 ; not implemented
IDTB_HISTORY            = 216 ; not implemented
IDTB_FAVORITES          = 217 ; not implemented
IDTB_JUMP1              = 218
IDTB_JUMP2              = 219
IDTB_CUSTOMIZE          = 221
IDTB_ZOOM               = 222
IDTB_TOC_NEXT           = 223
IDTB_TOC_PREV           = 224

; Notification codes

HHN_FIRST = 0-860
HHN_LAST  = 0-879

HHN_NAVCOMPLETE   = HHN_FIRST-0
HHN_TRACK         = HHN_FIRST-1
HHN_WINDOW_CREATE = HHN_FIRST-2

struct HHN_NOTIFY
    .hdr    dd ?
    .pszUrl dd ? ; Multi-byte, null-terminated string
ends

struct HH_POPUP
    .cbStruct      dd ?     ; sizeof this structure
    .hinst         dd ?     ; instance handle for string resource
    .idString      dd ?     ; string resource id, or text id if pszFile is specified in HtmlHelp call
    .pszText       dd ?     ; used if idString is zero
    .pt            POINT    ; top center of popup window
    .clrForeground dd ?     ; use -1 for default
    .clrBackground dd ?     ; use -1 for default
    .rcMargins     RECT     ; amount of space between edges of window and text, -1 for each member to ignore
    .pszFont       dd ?     ; facename, point size, char set, BOLD ITALIC UNDERLINE
ends

struct HH_AKLINK
    .cbStruct     dd ?     ; sizeof this structure
    .fReserved    dd ?     ; must be FALSE (really!)
    .pszKeywords  dd ?     ; semi-colon separated keywords
    .pszUrl       dd ?     ; URL to jump to if no keywords found (may be NULL)
    .pszMsgText   dd ?     ; Message text to display in MessageBox if pszUrl is NULL and no keyword match
    .pszMsgTitle  dd ?     ; Message text to display in MessageBox if pszUrl is NULL and no keyword match
    .pszWindow    dd ?     ; Window to display URL in
    .fIndexOnFail dd ?     ; Displays index if keyword lookup fails.
ends


HHWIN_NAVTYPE_TOC          = 0
HHWIN_NAVTYPE_INDEX        = 1
HHWIN_NAVTYPE_SEARCH       = 2
HHWIN_NAVTYPE_FAVORITES    = 3
HHWIN_NAVTYPE_HISTORY      = 4  ; not implemented
HHWIN_NAVTYPE_AUTHOR       = 5
HHWIN_NAVTYPE_CUSTOM_FIRST = 11


IT_INCLUSIVE = 0
IT_EXCLUSIVE = 1
IT_HIDDEN    = 2


struct HH_ENUM_IT
    .cbStruct         dd ?       ; size of this structure
    .iType            dd ?       ; the type of the information type ie. Inclusive, Exclusive, or Hidden
    .pszCatName       dd ?       ; Set to the name of the Category to enumerate the info types in a category; else NULL
    .pszITName        dd ?       ; volitile pointer to the name of the infotype. Allocated by call. Caller responsible for freeing
    .pszITDescription dd ?       ; volitile pointer to the description of the infotype.
ends

struct HH_ENUM_CAT
    .cbStruct          dd ?     ; size of this structure
    .pszCatName        dd ?     ; volitile pointer to the category name
    .pszCatDescription dd ?     ; volitile pointer to the category description
ends

struct HH_SET_INFOTYPE
    .cbStruct        dd ?        ; the size of this structure
    .pszCatName      dd ?        ; the name of the category, if any, the InfoType is a member of.
    .pszInfoTypeName dd ?        ; the name of the info type to add to the filter
ends


HHWIN_NAVTAB_TOP    = 0
HHWIN_NAVTAB_LEFT   = 1
HHWIN_NAVTAB_BOTTOM = 2


HH_MAX_TABS = 19  ; maximum number of tabs


HH_TAB_CONTENTS     = 0
HH_TAB_INDEX        = 1
HH_TAB_SEARCH       = 2
HH_TAB_FAVORITES    = 3
HH_TAB_HISTORY      = 4
HH_TAB_AUTHOR       = 5
HH_TAB_CUSTOM_FIRST = 11
HH_TAB_CUSTOM_LAST  = HH_MAX_TABS


HH_MAX_TABS_CUSTOM  = HH_TAB_CUSTOM_LAST - HH_TAB_CUSTOM_FIRST + 1

; HH_DISPLAY_SEARCH Command Related Structures and Constants

HH_FTS_DEFAULT_PROXIMITY = -1

struct HH_FTS_QUERY
   .cbStruct        dd ?   ; Sizeof structure in bytes.
   .fUniCodeStrings dd ?   ; TRUE if all strings are unicode.
   .pszSearchQuery  dd ?   ; String containing the search query.
   .iProximity      dd ?   ; Word proximity.
   .fStemmedSearch  dd ?   ; TRUE for StemmedSearch only.
   .fTitleOnly      dd ?   ; TRUE for Title search only.
   .fExecute        dd ?   ; TRUE to initiate the search.
   .pszWindow       dd ?   ; Window to display in
ends

; HH_WINTYPE Structure

struct HH_WINTYPE
    .cbStruct        dd ? ; IN: size of this structure including all Information Types
    .fUniCodeStrings dd ? ; IN/OUT: TRUE if all strings are in UNICODE
    .pszType         dd ? ; IN/OUT: Name of a type of window
    .fsValidMembers  dd ? ; IN: Bit flag of valid members (HHWIN_PARAM_)
    .fsWinProperties dd ? ; IN/OUT: Properties/attributes of the window (HHWIN_)
    .pszCaption      dd ?  ; IN/OUT: Window title
    .dwStyles        dd ?  ; IN/OUT: Window styles
    .dwExStyles      dd ?  ; IN/OUT: Extended Window styles
    .rcWindowPos     RECT  ; IN: Starting position, OUT: current position
    .nShowState      dd ?  ; IN: show state (e.g., SW_SHOW)
    .hwndHelp        dd ?    ; OUT: window handle
    .hwndCaller      dd ?    ; OUT: who called this window
    .paInfoTypes     dd ?    ; IN: Pointer to an array of Information Types
    ; The following members are only valid if HHWIN_PROP_TRI_PANE is set
    .hwndToolBar     dd ?  ; OUT: toolbar window in tri-pane window
    .hwndNavigation  dd ?  ; OUT: navigation window in tri-pane window
    .hwndHTML        dd ?  ; OUT: window displaying HTML in tri-pane window
    .iNavWidth       dd ?  ; IN/OUT: width of navigation window
    .rcHTML          RECT  ; OUT: HTML window coordinates
    .pszToc          dd ?  ; IN: Location of the table of contents file
    .pszIndex        dd ? ; IN: Location of the index file
    .pszFile         dd ? ; IN: Default location of the html file
    .pszHome         dd ? ; IN/OUT: html file to display when Home button is clicked
    .fsToolBarFlags  dd ? ; IN: flags controling the appearance of the toolbar
    .fNotExpanded    dd ? ; IN: TRUE/FALSE to contract or expand, OUT: current state
    .curNavType      dd ? ; IN/OUT: UI to display in the navigational pane
    .tabpos          dd ? ; IN/OUT: HHWIN_NAVTAB_TOP, HHWIN_NAVTAB_LEFT, or HHWIN_NAVTAB_BOTTOM
    .idNotify        dd ? ; IN: ID to use for WM_NOTIFY messages
    .tabOrder        rb HH_MAX_TABS + 1    ; IN/OUT: tab order: Contents, Index, Search, History, Favorites, Reserved 1-5, Custom tabs
    .cHistory        dd ? ; IN/OUT: number of history items to keep (default is 30)
    .pszJump1        dd ? ; Text for HHWIN_BUTTON_JUMP1
    .pszJump2        dd ? ; Text for HHWIN_BUTTON_JUMP2
    .pszUrlJump1     dd ? ; URL for HHWIN_BUTTON_JUMP1
    .pszUrlJump2     dd ? ; URL for HHWIN_BUTTON_JUMP2
    .rcMinSize       RECT ; Minimum size for window (ignored in version 1)
    .cbInfoTypes     dd ? ; size of paInfoTypes;
    .pszCustomTabs   dd ? ; multiple zero-terminated strings
ends

HHACT_TAB_CONTENTS  = 0
HHACT_TAB_INDEX     = 1
HHACT_TAB_SEARCH    = 2
HHACT_TAB_HISTORY   = 3
HHACT_TAB_FAVORITES = 4

HHACT_EXPAND    = 0
HHACT_CONTRACT  = 1
HHACT_BACK      = 2
HHACT_FORWARD   = 3
HHACT_STOP      = 4
HHACT_REFRESH   = 5
HHACT_HOME      = 6
HHACT_SYNC      = 7
HHACT_OPTIONS   = 8
HHACT_PRINT     = 9
HHACT_HIGHLIGHT = 10
HHACT_CUSTOMIZE = 11
HHACT_JUMP1     = 12
HHACT_JUMP2     = 13
HHACT_ZOOM      = 14
HHACT_TOC_NEXT  = 15
HHACT_TOC_PREV  = 16
HHACT_NOTES     = 17
HHACT_LAST_ENUM = 18


struct HHNTRACK
    .hdr        dd ?
    .pszCurUrl  dd ?  ; Multi-byte, null-terminated string
    .idAction   dd ?  ; HHACT_ value
    .phhWinType dd ?  ; Current window type structure
ends


HH_GPROPID_SINGLETHREAD=1      ; VARIANT_BOOL: True for single thread
HH_GPROPID_TOOLBAR_MARGIN=2    ; long: Provides a left/right margin around the toolbar.
HH_GPROPID_UI_LANGUAGE=3       ; long: LangId of the UI.
HH_GPROPID_CURRENT_SUBSET=4    ; BSTR: Current subset.
HH_GPROPID_CONTENT_LANGUAGE=5  ; long: LandId for desired content.


struct HH_GLOBAL_PROPERTY
    .id  dd ?
    .var dd ?
ends
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/equates/Win32/_KERNEL32.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: KERNEL32.DLL structures and constants
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


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        rb 128
ends

struct MEMORYSTATUS
  .dwiLength       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 FINDDATA
  .dwFileAttributes   dd ?
  .ftCreationTime     FILETIME
  .ftLastAccessTime   FILETIME
  .ftLastWriteTime    FILETIME
  .nFileSizeHigh      dd ?
  .nFileSizeLow       dd ?
  .dwReserved0        dd ?
  .dwReserved1        dd ?
  .cFileName          rb 260
  .cAlternateFileName rb 14
ends

struct FINDDATAW
  .dwFileAttributes   dd ?
  .ftCreationTime     FILETIME
  .ftLastAccessTime   FILETIME
  .ftLastWriteTime    FILETIME
  .nFileSizeHigh      dd ?
  .nFileSizeLow       dd ?
  .dwReserved0        dd ?
  .dwReserved1        dd ?
  .cFileName          rw 260
  .cAlternateFileName rw 14
ends

; findnext error

ERROR_NO_MORE_FILES = 18


struct PROCESSINFO
   .hProcess    dd ?
   .hThread     dd ?
   .dwProcessId dd ?
   .dwThreadId  dd ?
ends



struct TIME_ZONE_INFORMATION
  .bias         dd ?
  .StandardName rw 32
  .StandardDate SYSTEMTIME
  .StandardBias dd ?
  .DaylightName rw 32
  .DaylightDate SYSTEMTIME
  .DaylightBias dd ?
ends

TIME_ZODE_ID_UNKNOWN  = 0
TIME_ZONE_ID_STANDARD = 1
TIME_ZONE_ID_DAYLIGHT = 2


; General constants

NULL  = 0
TRUE  = 1
FALSE = 0

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

; file/pipe error codes

ERROR_MORE_DATA = 234

; 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

; 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

; 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


; MultiByteToWideChar constants

CP_ACP = 0
CP_OEMCP = 1
CP_MACCP = 2
CP_THREAD_ACP = 3
CP_SYMBOL = 42
CP_UTF7 = 65000
CP_UTF8 = 65001

; .flags:
MB_PRECOMPOSED       = $00000001     ; use precomposed chars
MB_COMPOSITE         = $00000002     ; use composite chars
MB_USEGLYPHCHARS     = $00000004     ; use glyph chars, not ctrl chars
MB_ERR_INVALID_CHARS = $00000008     ; error for invalid chars
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/equates/Win32/_ODBC32.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: ODBC constants and structures.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

SQL_NULL_DATA                   =  -1
SQL_DATA_AT_EXEC                =  -2
SQL_SUCCESS                     =  0
SQL_SUCCESS_WITH_INFO           =  1
SQL_NODATA                      =  100
SQL_ERROR                       =  -1
SQL_INVALID_HANDLE              =  -2
SQL_STILL_EXECUTING             =  2
SQL_NEED_DATA                   =  99
SQL_NTS                         =  -3
SQL_NTSL                        =  -3
SQL_MAX_MESSAGE_LENGTH          =  512
SQL_DATE_LEN                    =  10
SQL_TIME_LEN                    =  8
SQL_TIMESTAMP_LEN               =  19
SQL_HANDLE_ENV                  =  1
SQL_HANDLE_DBC                  =  2
SQL_HANDLE_STMT                 =  3
SQL_HANDLE_DESC                 =  4
SQL_ATTR_OUTPUT_NTS             =  10001
SQL_ATTR_AUTO_IPD               =  10001
SQL_ATTR_METADATA_ID            =  10014
SQL_ATTR_APP_ROW_DESC           =  10010
SQL_ATTR_APP_PARAM_DESC         =  10011
SQL_ATTR_IMP_ROW_DESC           =  10012
SQL_ATTR_IMP_PARAM_DESC         =  10013
SQL_ATTR_CURSOR_SCROLLABLE      =  -1
SQL_ATTR_CURSOR_SENSITIVITY     =  -2
SQL_NONSCROLLABLE               =  0
SQL_SCROLLABLE                  =  1
SQL_DESC_COUNT                  =  1001
SQL_DESC_TYPE                   =  1002
SQL_DESC_LENGTH                 =  1003
SQL_DESC_OCTET_LENGTH_PTR       =  1004
SQL_DESC_PRECISION              =  1005
SQL_DESC_SCALE                  =  1006
SQL_DESC_DATETIME_INTERVAL_CODE =  1007
SQL_DESC_NULLABLE               =  1008
SQL_DESC_INDICATOR_PTR          =  1009
SQL_DESC_DATA_PTR               =  1010
SQL_DESC_NAME                   =  1011
SQL_DESC_UNNAMED                =  1012
SQL_DESC_OCTET_LENGTH           =  1013
SQL_DESC_ALLOC_TYPE             =  1099
SQL_DIAG_RETURNCODE             =  1
SQL_DIAG_NUMBER                 =  2
SQL_DIAG_ROW_COUNT              =  3
SQL_DIAG_SQLSTATE               =  4
SQL_DIAG_NATIVE                 =  5
SQL_DIAG_MESSAGE_TEXT           =  6
SQL_DIAG_DYNAMIC_FUNCTION       =  7
SQL_DIAG_CLASS_ORIGIN           =  8
SQL_DIAG_SUBCLASS_ORIGIN        =  9
SQL_DIAG_CONNECTION_NAME        =  10
SQL_DIAG_SERVER_NAME            =  11
SQL_DIAG_DYNAMIC_FUNCTION_CODE  =  12
SQL_DIAG_ALTER_DOMAIN           =  3
SQL_DIAG_ALTER_TABLE            =  4
SQL_DIAG_CALL                   =  7
SQL_DIAG_CREATE_ASSERTION       =  6
SQL_DIAG_CREATE_CHARACTER_SET   =  8
SQL_DIAG_CREATE_COLLATION       =  10
SQL_DIAG_CREATE_DOMAIN          =  23
SQL_DIAG_CREATE_INDEX           =  -1
SQL_DIAG_CREATE_SCHEMA          =  64
SQL_DIAG_CREATE_TABLE           =  77
SQL_DIAG_CREATE_TRANSLATION     =  79
SQL_DIAG_CREATE_VIEW            =  84
SQL_DIAG_DELETE_WHERE           =  19
SQL_DIAG_DROP_ASSERTION         =  24
SQL_DIAG_DROP_CHARACTER_SET     =  25
SQL_DIAG_DROP_COLLATION         =  26
SQL_DIAG_DROP_DOMAIN            =  27
SQL_DIAG_DROP_INDEX             =  -2
SQL_DIAG_DROP_SCHEMA            =  31
SQL_DIAG_DROP_TABLE             =  32
SQL_DIAG_DROP_TRANSLATION       =  33
SQL_DIAG_DROP_VIEW              =  36
SQL_DIAG_DYNAMIC_DELETE_CURSOR  =  38
SQL_DIAG_DYNAMIC_UPDATE_CURSOR  =  81
SQL_DIAG_GRANT                  =  48
SQL_DIAG_INSERT                 =  50
SQL_DIAG_REVOKE                 =  59
SQL_DIAG_SELECT_CURSOR          =  85
SQL_DIAG_UNKNOWN_STATEMENT      =  0
SQL_DIAG_UPDATE_WHERE           =  82
SQL_UNKNOWN_TYPE                =  0
SQL_CHAR                        =  1
SQL_NUMERIC                     =  2
SQL_DECIMAL                     =  3
SQL_INTEGER                     =  4
SQL_SMALLINT                    =  5
SQL_FLOAT                       =  6
SQL_REAL                        =  7
SQL_DOUBLE                      =  8
SQL_DATETIME                    =  9
SQL_VARCHAR                     =  12
SQL_TYPE_DATE                   =  91
SQL_TYPE_TIME                   =  92
SQL_TYPE_TIMESTAMP              =  93
SQL_UNSPECIFIED                 =  0
SQL_INSENSITIVE                 =  1
SQL_SENSITIVE                   =  2
SQL_ALL_TYPES                   =  0
SQL_DEFAULT                     =  99
SQL_ARD_TYPE                    =  -99
SQL_CODE_DATE                   =  1
SQL_CODE_TIME                   =  2
SQL_CODE_TIMESTAMP              =  3
SQL_FALSE                       =  0
SQL_TRUE                        =  1
SQL_NO_NULLS                    =  0
SQL_NULLABLE                    =  1
SQL_NULLABLE_UNKNOWN            =  2
SQL_PRED_NONE                   =  0
SQL_PRED_CHAR                   =  1
SQL_PRED_BASIC                  =  2
SQL_NAMED                       =  0
SQL_UNNAMED                     =  1
SQL_DESC_ALLOC_AUTO             =  1
SQL_DESC_ALLOC_USER             =  2
SQL_CLOSE                       =  0
SQL_DROP                        =  1
SQL_UNBIND                      =  2
SQL_RESET_PARAMS                =  3
SQL_FETCH_NEXT                  =  1
SQL_FETCH_FIRST                 =  2
SQL_FETCH_LAST                  =  3
SQL_FETCH_PRIOR                 =  4
SQL_FETCH_ABSOLUTE              =  5
SQL_FETCH_RELATIVE              =  6
SQL_COMMIT                      =  0
SQL_ROLLBACK                    =  1
SQL_NULL_HENV                   =  0
SQL_NULL_HDBC                   =  0
SQL_NULL_HSTMT                  =  0
SQL_NULL_HDESC                  =  0
SQL_NULL_HANDLE                 =  0
SQL_SCOPE_CURROW                =  0
SQL_SCOPE_TRANSACTION           =  1
SQL_SCOPE_SESSION               =  2
SQL_PC_UNKNOWN                  =  0
SQL_PC_NON_PSEUDO               =  1
SQL_PC_PSEUDO                   =  2
SQL_ROW_IDENTIFIER              =  1
SQL_INDEX_UNIQUE                =  0
SQL_INDEX_ALL                   =  1
SQL_INDEX_CLUSTERED             =  1
SQL_INDEX_HASHED                =  2
SQL_INDEX_OTHER                 =  3
SQL_API_SQLALLOCCONNECT         =  1
SQL_API_SQLALLOCENV             =  2
SQL_API_SQLALLOCHANDLE          =  1001
SQL_API_SQLALLOCSTMT            =  3
SQL_API_SQLBINDCOL              =  4
SQL_API_SQLBINDPARAM            =  1002
SQL_API_SQLCANCEL               =  5
SQL_API_SQLCLOSECURSOR          =  1003
SQL_API_SQLCOLATTRIBUTE         =  6
SQL_API_SQLCOLUMNS              =  40
SQL_API_SQLCONNECT              =  7
SQL_API_SQLCOPYDESC             =  1004
SQL_API_SQLDATASOURCES          =  57
SQL_API_SQLDESCRIBECOL          =  8
SQL_API_SQLDISCONNECT           =  9
SQL_API_SQLENDTRAN              =  1005
SQL_API_SQLERROR                =  10
SQL_API_SQLEXECDIRECT           =  11
SQL_API_SQLEXECUTE              =  12
SQL_API_SQLFETCH                =  13
SQL_API_SQLFETCHSCROLL          =  1021
SQL_API_SQLFREECONNECT          =  14
SQL_API_SQLFREEENV              =  15
SQL_API_SQLFREEHANDLE           =  1006
SQL_API_SQLFREESTMT             =  16
SQL_API_SQLGETCONNECTATTR       =  1007
SQL_API_SQLGETCONNECTOPTION     =  42
SQL_API_SQLGETCURSORNAME        =  17
SQL_API_SQLGETDATA              =  43
SQL_API_SQLGETDESCFIELD         =  1008
SQL_API_SQLGETDESCREC           =  1009
SQL_API_SQLGETDIAGFIELD         =  1010
SQL_API_SQLGETDIAGREC           =  1011
SQL_API_SQLGETENVATTR           =  1012
SQL_API_SQLGETFUNCTIONS         =  44
SQL_API_SQLGETINFO              =  45
SQL_API_SQLGETSTMTATTR          =  1014
SQL_API_SQLGETSTMTOPTION        =  46
SQL_API_SQLGETTYPEINFO          =  47
SQL_API_SQLNUMRESULTCOLS        =  18
SQL_API_SQLPARAMDATA            =  48
SQL_API_SQLPREPARE              =  19
SQL_API_SQLPUTDATA              =  49
SQL_API_SQLROWCOUNT             =  20
SQL_API_SQLSETCONNECTATTR       =  1016
SQL_API_SQLSETCONNECTOPTION     =  50
SQL_API_SQLSETCURSORNAME        =  21
SQL_API_SQLSETDESCFIELD         =  1017
SQL_API_SQLSETDESCREC           =  1018
SQL_API_SQLSETENVATTR           =  1019
SQL_API_SQLSETPARAM             =  22
SQL_API_SQLSETSTMTATTR          =  1020
SQL_API_SQLSETSTMTOPTION        =  51
SQL_API_SQLSPECIALCOLUMNS       =  52
SQL_API_SQLSTATISTICS           =  53
SQL_API_SQLTABLES               =  54
SQL_API_SQLTRANSACT             =  23
SQL_MAX_DRIVER_CONNECTIONS      =  0
SQL_MAXIMUM_DRIVER_CONNECTIONS  =  SQL_MAX_DRIVER_CONNECTIONS
SQL_MAX_CONCURRENT_ACTIVITIES   =  1
SQL_MAXIMUM_CONCURRENT_ACTIVITIES =  SQL_MAX_CONCURRENT_ACTIVITIES
SQL_DATA_SOURCE_NAME            =  2
SQL_FETCH_DIRECTION             =  8
SQL_SERVER_NAME                 =  13
SQL_SEARCH_PATTERN_ESCAPE       =  14
SQL_DBMS_NAME                   =  17
SQL_DBMS_VER                    =  18
SQL_ACCESSIBLE_TABLES           =  19
SQL_ACCESSIBLE_PROCEDURES       =  20
SQL_CURSOR_COMMIT_BEHAVIOR      =  23
SQL_DATA_SOURCE_READ_ONLY       =  25
SQL_DEFAULT_TXN_ISOLATION       =  26
SQL_IDENTIFIER_CASE             =  28
SQL_IDENTIFIER_QUOTE_CHAR       =  29
SQL_MAX_COLUMN_NAME_LEN         =  30
SQL_MAXIMUM_COLUMN_NAME_LENGTH  =  SQL_MAX_COLUMN_NAME_LEN
SQL_MAX_CURSOR_NAME_LEN         =  31
SQL_MAXIMUM_CURSOR_NAME_LENGTH  =  SQL_MAX_CURSOR_NAME_LEN
SQL_MAX_SCHEMA_NAME_LEN         =  32
SQL_MAXIMUM_SCHEMA_NAME_LENGTH  =  SQL_MAX_SCHEMA_NAME_LEN
SQL_MAX_CATALOG_NAME_LEN        =  34
SQL_MAXIMUM_CATALOG_NAME_LENGTH =  SQL_MAX_CATALOG_NAME_LEN
SQL_MAX_TABLE_NAME_LEN          =  35
SQL_SCROLL_CONCURRENCY          =  43
SQL_TXN_CAPABLE                 =  46
SQL_TRANSACTION_CAPABLE         =  SQL_TXN_CAPABLE
SQL_USER_NAME                   =  47
SQL_TXN_ISOLATION_OPTION        =  72
SQL_TRANSACTION_ISOLATION_OPTION =  SQL_TXN_ISOLATION_OPTION
SQL_INTEGRITY                   =  73
SQL_GETDATA_EXTENSIONS          =  81
SQL_NULL_COLLATION              =  85
SQL_ALTER_TABLE                 =  86
SQL_ORDER_BY_COLUMNS_IN_SELECT  =  90
SQL_SPECIAL_CHARACTERS          =  94
SQL_MAX_COLUMNS_IN_GROUP_BY     =  97
SQL_MAXIMUM_COLUMNS_IN_GROUP_BY =  SQL_MAX_COLUMNS_IN_GROUP_BY
SQL_MAX_COLUMNS_IN_INDEX        =  98
SQL_MAXIMUM_COLUMNS_IN_INDEX    =  SQL_MAX_COLUMNS_IN_INDEX
SQL_MAX_COLUMNS_IN_ORDER_BY     =  99
SQL_MAXIMUM_COLUMNS_IN_ORDER_BY =  SQL_MAX_COLUMNS_IN_ORDER_BY
SQL_MAX_COLUMNS_IN_SELECT       =  100
SQL_MAXIMUM_COLUMNS_IN_SELECT   =  SQL_MAX_COLUMNS_IN_SELECT
SQL_MAX_COLUMNS_IN_TABLE        =  101
SQL_MAX_INDEX_SIZE              =  102
SQL_MAXIMUM_INDEX_SIZE          =  SQL_MAX_INDEX_SIZE
SQL_MAX_ROW_SIZE                =  104
SQL_MAXIMUM_ROW_SIZE            =  SQL_MAX_ROW_SIZE
SQL_MAX_STATEMENT_LEN           =  105
SQL_MAXIMUM_STATEMENT_LENGTH    =  SQL_MAX_STATEMENT_LEN
SQL_MAX_TABLES_IN_SELECT        =  106
SQL_MAXIMUM_TABLES_IN_SELECT    =  SQL_MAX_TABLES_IN_SELECT
SQL_MAX_USER_NAME_LEN           =  107
SQL_MAXIMUM_USER_NAME_LENGTH    =  SQL_MAX_USER_NAME_LEN
SQL_OJ_CAPABILITIES             =  115
SQL_OUTER_JOIN_CAPABILITIES     =  SQL_OJ_CAPABILITIES
SQL_XOPEN_CLI_YEAR              =  10000
SQL_CURSOR_SENSITIVITY          =  10001
SQL_DESCRIBE_PARAMETER          =  10002
SQL_CATALOG_NAME                =  10003
SQL_COLLATION_SEQ               =  10004
SQL_MAX_IDENTIFIER_LEN          =  10005
SQL_MAXIMUM_IDENTIFIER_LENGTH   =  SQL_MAX_IDENTIFIER_LEN
SQL_AT_ADD_COLUMN               =  1
SQL_AT_DROP_COLUMN              =  2
SQL_AT_ADD_CONSTRAINT           =  8
SQL_AT_COLUMN_SINGLE            =  20h
SQL_AT_ADD_COLUMN_DEFAULT       =  40h
SQL_AT_ADD_COLUMN_COLLATION     =  80h
SQL_AT_SET_COLUMN_DEFAULT       =  100h
SQL_AT_DROP_COLUMN_DEFAULT      =  200h
SQL_AT_DROP_COLUMN_CASCADE      =  400h
SQL_AT_DROP_COLUMN_RESTRICT     =  800h
SQL_AT_ADD_TABLE_CONSTRAINT     =  1000h
SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE =  2000h
SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT =  4000h
SQL_AT_CONSTRAINT_NAME_DEFINITION =  8000h
SQL_AT_CONSTRAINT_INITIALLY_DEFERRED =  10000h
SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE =  20000h
SQL_AT_CONSTRAINT_DEFERRABLE =  40000h
SQL_AT_CONSTRAINT_NON_DEFERRABLE =  80000h
SQL_AM_NONE                     =  0
SQL_AM_CONNECTION               =  1
SQL_AM_STATEMENT                =  2
SQL_CB_DELETE                   =  0
SQL_CB_CLOSE                    =  1
SQL_CB_PRESERVE                 =  2
SQL_FD_FETCH_NEXT               =  1
SQL_FD_FETCH_FIRST              =  2
SQL_FD_FETCH_LAST               =  4
SQL_FD_FETCH_PRIOR              =  8
SQL_FD_FETCH_ABSOLUTE           =  10h
SQL_FD_FETCH_RELATIVE           =  20h
SQL_GD_ANY_COLUMN               =  1
SQL_GD_ANY_ORDER                =  2
SQL_IC_UPPER                    =  1
SQL_IC_LOWER                    =  2
SQL_IC_SENSITIVE                =  3
SQL_IC_MIXED                    =  4
SQL_OJ_LEFT                     =  1
SQL_OJ_RIGHT                    =  2
SQL_OJ_FULL                     =  4
SQL_OJ_NESTED                   =  8
SQL_OJ_NOT_ORDERED              =  10h
SQL_OJ_INNER                    =  20h
SQL_OJ_ALL_COMPARISON_OPS       =  40h
SQL_SCCO_READ_ONLY              =  1
SQL_SCCO_LOCK                   =  2
SQL_SCCO_OPT_ROWVER             =  4
SQL_SCCO_OPT_VALUES             =  8
SQL_TC_NONE                     =  0
SQL_TC_DML                      =  1
SQL_TC_ALL                      =  2
SQL_TC_DDL_COMMIT               =  3
SQL_TC_DDL_IGNORE               =  4
SQL_TXN_READ_UNCOMMITTED        =  1
SQL_TRANSACTION_READ_UNCOMMITTED = SQL_TXN_READ_UNCOMMITTED
SQL_TXN_READ_COMMITTED          =  2
SQL_TRANSACTION_READ_COMMITTED  =  SQL_TXN_READ_COMMITTED
SQL_TXN_REPEATABLE_READ         =  4
SQL_TRANSACTION_REPEATABLE_READ =  SQL_TXN_REPEATABLE_READ
SQL_TXN_SERIALIZABLE            =  8
SQL_TRANSACTION_SERIALIZABLE    =  SQL_TXN_SERIALIZABLE
SQL_NC_HIGH                     =  0
SQL_NC_LOW                      =  1


SQL_SPEC_MAJOR                  =  3
SQL_SPEC_MINOR                  =  51
SQL_SPEC_STRING                 =  "03.51"
SQL_SQLSTATE_SIZE               =  5
SQL_MAX_DSN_LENGTH              =  32
SQL_MAX_OPTION_STRING_LENGTH    =  256
SQL_NODATAFOUND               =  SQL_NODATA
SQL_HANDLE_SENV                 =  5
SQL_ATTR_ODBC_VERSION           =  200
SQL_ATTR_CONNECTION_POOLING     =  201
SQL_ATTR_CP_MATCH               =  202
SQL_CP_OFF                      =  0
SQL_CP_ONE_PER_DRIVER           =  1
SQL_CP_ONE_PER_HENV             =  2
SQL_CP_DEFAULT                  =  SQL_CP_OFF
SQL_CP_STRICT_MATCH             =  0
SQL_CP_RELAXED_MATCH            =  1
SQL_CP_MATCH_DEFAULT            =  SQL_CP_STRICT_MATCH
SQL_OV_ODBC2                    =  2
SQL_OV_ODBC3                    =  3
SQL_ACCESS_MODE                 =  101
SQL_AUTOCOMMIT                  =  102
SQL_LOGIN_TIMEOUT               =  103
SQL_OPT_TRACE                   =  104
SQL_OPT_TRACEFILE               =  105
SQL_TRANSLATE_DLL               =  106
SQL_TRANSLATE_OPTION            =  107
SQL_TXN_ISOLATION               =  108
SQL_CURRENT_QUALIFIER           =  109
SQL_ODBC_CURSORS                =  110
SQL_QUIET_MODE                  =  111
SQL_PACKET_SIZE                 =  112
SQL_ATTR_ACCESS_MODE            =  SQL_ACCESS_MODE
SQL_ATTR_AUTOCOMMIT             =  SQL_AUTOCOMMIT
SQL_ATTR_CONNECTION_TIMEOUT     =  113
SQL_ATTR_CURRENT_CATALOG        =  SQL_CURRENT_QUALIFIER
SQL_ATTR_DISCONNECT_BEHAVIOR    =  114
SQL_ATTR_ENLIST_IN_DTC          =  1207
SQL_ATTR_ENLIST_IN_XA           =  1208
SQL_ATTR_LOGIN_TIMEOUT          =  SQL_LOGIN_TIMEOUT
SQL_ATTR_ODBC_CURSORS           =  SQL_ODBC_CURSORS
SQL_ATTR_PACKET_SIZE            =  SQL_PACKET_SIZE
SQL_ATTR_QUIET_MODE             =  SQL_QUIET_MODE
SQL_ATTR_TRACE                  =  SQL_OPT_TRACE
SQL_ATTR_TRACEFILE              =  SQL_OPT_TRACEFILE
SQL_ATTR_TRANSLATE_LIB          =  SQL_TRANSLATE_DLL
SQL_ATTR_TRANSLATE_OPTION       =  SQL_TRANSLATE_OPTION
SQL_ATTR_TXN_ISOLATION          =  SQL_TXN_ISOLATION
SQL_ATTR_CONNECTION_DEAD        =  1209
SQL_ATTR_ANSI_APP               =  115
SQL_MODE_READ_WRITE             =  0
SQL_MODE_READ_ONLY              =  1
SQL_MODE_DEFAULT                =  SQL_MODE_READ_WRITE
SQL_AUTOCOMMIT_OFF              =  0
SQL_AUTOCOMMIT_ON               =  1
SQL_AUTOCOMMIT_DEFAULT          =  SQL_AUTOCOMMIT_ON
SQL_LOGIN_TIMEOUT_DEFAULT       =  15
SQL_OPT_TRACE_OFF               =  0
SQL_OPT_TRACE_ON                =  1
SQL_OPT_TRACE_DEFAULT           =  SQL_OPT_TRACE_OFF
SQL_OPT_TRACE_FILE_DEFAULT      equ  "\\SQL.LOG"
SQL_CUR_USE_IF_NEEDED           =  0
SQL_CUR_USE_ODBC                =  1
SQL_CUR_USE_DRIVER              =  2
SQL_CUR_DEFAULT                 =  SQL_CUR_USE_DRIVER
SQL_DB_RETURN_TO_POOL           =  0
SQL_DB_DISCONNECT               =  1
SQL_DB_DEFAULT                  =  SQL_DB_RETURN_TO_POOL
SQL_DTC_DONE                    =  0
SQL_CD_TRUE                     =  1
SQL_CD_FALSE                    =  0
SQL_AA_TRUE                     =  1
SQL_AA_FALSE                    =  0
SQL_QUERY_TIMEOUT               =  0
SQL_MAX_ROWS                    =  1
SQL_NOSCAN                      =  2
SQL_MAX_LENGTH                  =  3
SQL_ASYNC_ENABLE                =  4
SQL_BIND_TYPE                   =  5
SQL_CURSOR_TYPE                 =  6
SQL_CONCURRENCY                 =  7
SQL_KEYSET_SIZE                 =  8
SQL_ROWSET_SIZE                 =  9
SQL_SIMULATE_CURSOR             =  10
SQL_RETRIEVE_DATA               =  11
SQL_USE_BOOKMARKS               =  12
SQL_GET_BOOKMARK                =  13
SQL_ROW_NUMBER                  =  14
SQL_ATTR_ASYNC_ENABLE           =  4
SQL_ATTR_CONCURRENCY            =  SQL_CONCURRENCY
SQL_ATTR_CURSOR_TYPE            =  SQL_CURSOR_TYPE
SQL_ATTR_ENABLE_AUTO_IPD        =  15
SQL_ATTR_FETCH_BOOKMARK_PTR     =  16
SQL_ATTR_KEYSET_SIZE            =  SQL_KEYSET_SIZE
SQL_ATTR_MAX_LENGTH             =  SQL_MAX_LENGTH
SQL_ATTR_MAX_ROWS               =  SQL_MAX_ROWS
SQL_ATTR_NOSCAN                 =  SQL_NOSCAN
SQL_ATTR_PARAM_BIND_OFFSET_PTR  =  17
SQL_ATTR_PARAM_BIND_TYPE        =  18
SQL_ATTR_PARAM_OPERATION_PTR    =  19
SQL_ATTR_PARAM_STATUS_PTR       =  20
SQL_ATTR_PARAMS_PROCESSED_PTR   =  21
SQL_ATTR_PARAMSET_SIZE          =  22
SQL_ATTR_QUERY_TIMEOUT          =  SQL_QUERY_TIMEOUT
SQL_ATTR_RETRIEVE_DATA          =  SQL_RETRIEVE_DATA
SQL_ATTR_ROW_BIND_OFFSET_PTR    =  23
SQL_ATTR_ROW_BIND_TYPE          =  SQL_BIND_TYPE
SQL_ATTR_ROW_NUMBER             =  SQL_ROW_NUMBER
SQL_ATTR_ROW_OPERATION_PTR      =  24
SQL_ATTR_ROW_STATUS_PTR         =  25
SQL_ATTR_ROWS_FETCHED_PTR       =  26
SQL_ATTR_ROW_ARRAY_SIZE         =  27
SQL_ATTR_SIMULATE_CURSOR        =  SQL_SIMULATE_CURSOR
SQL_ATTR_USE_BOOKMARKS          =  SQL_USE_BOOKMARKS
SQL_COL_PRED_CHAR               =  SQL_LIKE_ONLY
SQL_COL_PRED_BASIC              =  SQL_ALL_EXCEPT_LIKE
SQL_IS_POINTER                  =  -4
SQL_IS_UINTEGER                 =  -5
SQL_IS_INTEGER                  =  -6
SQL_IS_USMALLINT                =  -7
SQL_IS_SMALLINT                 =  -8
SQL_PARAM_BIND_BY_COLUMN        =  0
SQL_PARAM_BIND_TYPE_DEFAULT     =  SQL_PARAM_BIND_BY_COLUMN
SQL_QUERY_TIMEOUT_DEFAULT       =  0
SQL_MAX_ROWS_DEFAULT            =  0
SQL_NOSCAN_OFF                  =  0
SQL_NOSCAN_ON                   =  1
SQL_NOSCAN_DEFAULT              =  SQL_NOSCAN_OFF
SQL_MAX_LENGTH_DEFAULT          =  0
SQL_ASYNC_ENABLE_OFF            =  0
SQL_ASYNC_ENABLE_ON             =  1
SQL_ASYNC_ENABLE_DEFAULT        =  SQL_ASYNC_ENABLE_OFF
SQL_BIND_BY_COLUMN              =  0
SQL_BIND_TYPE_DEFAULT           =  SQL_BIND_BY_COLUMN
SQL_CONCUR_READ_ONLY            =  1
SQL_CONCUR_LOCK                 =  2
SQL_CONCUR_ROWVER               =  3
SQL_CONCUR_VALUES               =  4
SQL_CONCUR_DEFAULT              =  SQL_CONCUR_READ_ONLY
SQL_CURSOR_FORWARD_ONLY         =  0
SQL_CURSOR_KEYSET_DRIVEN        =  1
SQL_CURSOR_DYNAMIC              =  2
SQL_CURSOR_STATIC               =  3
SQL_CURSOR_TYPE_DEFAULT         =  SQL_CURSOR_FORWARD_ONLY
SQL_ROWSET_SIZE_DEFAULT         =  1
SQL_KEYSET_SIZE_DEFAULT         =  0
SQL_SC_NON_UNIQUE               =  0
SQL_SC_TRY_UNIQUE               =  1
SQL_SC_UNIQUE                   =  2
SQL_RD_OFF                      =  0
SQL_RD_ON                       =  1
SQL_RD_DEFAULT                  =  SQL_RD_ON
SQL_UB_OFF                      =  0
SQL_UB_ON                       =  01
SQL_UB_DEFAULT                  =  SQL_UB_OFF
SQL_UB_FIXED                    =  SQL_UB_ON
SQL_UB_VARIABLE                 =  2
SQL_DESC_ARRAY_SIZE             =  20
SQL_DESC_ARRAY_STATUS_PTR       =  21
SQL_DESC_AUTO_UNIQUE_VALUE      =  SQL_COLUMN_AUTO_INCREMENT
SQL_DESC_BASE_COLUMN_NAME       =  22
SQL_DESC_BASE_TABLE_NAME        =  23
SQL_DESC_BIND_OFFSET_PTR        =  24
SQL_DESC_BIND_TYPE              =  25
SQL_DESC_CASE_SENSITIVE         =  SQL_COLUMN_CASE_SENSITIVE
SQL_DESC_CATALOG_NAME           =  SQL_COLUMN_QUALIFIER_NAME
SQL_DESC_CONCISE_TYPE           =  SQL_COLUMN_TYPE
SQL_DESC_DATETIME_INTERVAL_PRECISION =  26
SQL_DESC_DISPLAY_SIZE           =  SQL_COLUMN_DISPLAY_SIZE
SQL_DESC_FIXED_PREC_SCALE       =  SQL_COLUMN_MONEY
SQL_DESC_LABEL                  =  SQL_COLUMN_LABEL
SQL_DESC_LITERAL_PREFIX         =  27
SQL_DESC_LITERAL_SUFFIX         =  28
SQL_DESC_LOCAL_TYPE_NAME        =  29
SQL_DESC_MAXIMUM_SCALE          =  30
SQL_DESC_MINIMUM_SCALE          =  31
SQL_DESC_NUM_PREC_RADIX         =  32
SQL_DESC_PARAMETER_TYPE         =  33
SQL_DESC_ROWS_PROCESSED_PTR     =  34
SQL_DESC_ROWVER                 =  35
SQL_DESC_SCHEMA_NAME            =  SQL_COLUMN_OWNER_NAME
SQL_DESC_SEARCHABLE             =  SQL_COLUMN_SEARCHABLE
SQL_DESC_TYPE_NAME              =  SQL_COLUMN_TYPE_NAME
SQL_DESC_TABLE_NAME             =  SQL_COLUMN_TABLE_NAME
SQL_DESC_UNSIGNED               =  SQL_COLUMN_UNSIGNED
SQL_DESC_UPDATABLE              =  SQL_COLUMN_UPDATABLE
SQL_DIAG_CURSOR_ROW_COUNT       =  -1249
SQL_DIAG_ROW_NUMBER             =  -1248
SQL_DIAG_COLUMN_NUMBER          =  -1247
SQL_DATE                        =  9
SQL_INTERVAL                    =  10
SQL_TIME                        =  10
SQL_TIMESTAMP                   =  11
SQL_LONGVARCHAR                 =  -1
SQL_BINARY                      =  -2
SQL_VARBINARY                   =  -3
SQL_LONGVARBINARY               =  -4
SQL_BIGINT                      =  -5
SQL_TINYINT                     =  -6
SQL_BIT                         =  -7
SQL_GUID                        =  -11
SQL_CODE_YEAR                   =  1
SQL_CODE_MONTH                  =  2
SQL_CODE_DAY                    =  3
SQL_CODE_HOUR                   =  4
SQL_CODE_MINUTE                 =  5
SQL_CODE_SECOND                 =  6
SQL_CODE_YEAR_TO_MONTH          =  7
SQL_CODE_DAY_TO_HOUR            =  8
SQL_CODE_DAY_TO_MINUTE          =  9
SQL_CODE_DAY_TO_SECOND          =  10
SQL_CODE_HOUR_TO_MINUTE         =  11
SQL_CODE_HOUR_TO_SECOND         =  12
SQL_CODE_MINUTE_TO_SECOND       =  13
SQL_INTERVAL_YEAR               =  100 + SQL_CODE_YEAR
SQL_INTERVAL_MONTH              =  100 + SQL_CODE_MONTH
SQL_INTERVAL_DAY                =  100 + SQL_CODE_DAY
SQL_INTERVAL_HOUR               =  100 + SQL_CODE_HOUR
SQL_INTERVAL_MINUTE             =  100 + SQL_CODE_MINUTE
SQL_INTERVAL_SECOND             =  100 + SQL_CODE_SECOND
SQL_INTERVAL_YEAR_TO_MONTH      =  100 + SQL_CODE_YEAR_TO_MONTH
SQL_INTERVAL_DAY_TO_HOUR        =  100 + SQL_CODE_DAY_TO_HOUR
SQL_INTERVAL_DAY_TO_MINUTE      =  100 + SQL_CODE_DAY_TO_MINUTE
SQL_INTERVAL_DAY_TO_SECOND      =  100 + SQL_CODE_DAY_TO_SECOND
SQL_INTERVAL_HOUR_TO_MINUTE     =  100 + SQL_CODE_HOUR_TO_MINUTE
SQL_INTERVAL_HOUR_TO_SECOND     =  100 + SQL_CODE_HOUR_TO_SECOND
SQL_INTERVAL_MINUTE_TO_SECOND   =  100 + SQL_CODE_MINUTE_TO_SECOND

;???? SQL_UNICODE                     =  SQL_WCHAR
;???? SQL_UNICODE_VARCHAR             =  SQL_WVARCHAR
;???? SQL_UNICODE_LONGVARCHAR         =  SQL_WLONGVARCHAR
;???? SQL_UNICODE_CHAR                =  SQL_WCHAR

SQL_C_CHAR                      =  SQL_CHAR
SQL_C_LONG                      =  SQL_INTEGER
SQL_C_SHORT                     =  SQL_SMALLINT
SQL_C_FLOAT                     =  SQL_REAL
SQL_C_DOUBLE                    =  SQL_DOUBLE
SQL_C_NUMERIC                   =  SQL_NUMERIC
SQL_C_DEFAULT                   =  99
SQL_SIGNED_OFFSET               =  -20
SQL_UNSIGNED_OFFSET             =  -22
SQL_C_DATE                      =  SQL_DATE
SQL_C_TIME                      =  SQL_TIME
SQL_C_TIMESTAMP                 =  SQL_TIMESTAMP
SQL_C_TYPE_DATE                 =  SQL_TYPE_DATE
SQL_C_TYPE_TIME                 =  SQL_TYPE_TIME
SQL_C_TYPE_TIMESTAMP            =  SQL_TYPE_TIMESTAMP
SQL_C_INTERVAL_YEAR             =  SQL_INTERVAL_YEAR
SQL_C_INTERVAL_MONTH            =  SQL_INTERVAL_MONTH
SQL_C_INTERVAL_DAY              =  SQL_INTERVAL_DAY
SQL_C_INTERVAL_HOUR             =  SQL_INTERVAL_HOUR
SQL_C_INTERVAL_MINUTE           =  SQL_INTERVAL_MINUTE
SQL_C_INTERVAL_SECOND           =  SQL_INTERVAL_SECOND
SQL_C_INTERVAL_YEAR_TO_MONTH    =  SQL_INTERVAL_YEAR_TO_MONTH
SQL_C_INTERVAL_DAY_TO_HOUR      =  SQL_INTERVAL_DAY_TO_HOUR
SQL_C_INTERVAL_DAY_TO_MINUTE    =  SQL_INTERVAL_DAY_TO_MINUTE
SQL_C_INTERVAL_DAY_TO_SECOND    =  SQL_INTERVAL_DAY_TO_SECOND
SQL_C_INTERVAL_HOUR_TO_MINUTE   =  SQL_INTERVAL_HOUR_TO_MINUTE
SQL_C_INTERVAL_HOUR_TO_SECOND   =  SQL_INTERVAL_HOUR_TO_SECOND
SQL_C_INTERVAL_MINUTE_TO_SECOND =  SQL_INTERVAL_MINUTE_TO_SECOND
SQL_C_BINARY                    =  SQL_BINARY
SQL_C_BIT                       =  SQL_BIT
SQL_C_SBIGINT                   =  SQL_BIGINT+SQL_SIGNED_OFFSET
SQL_C_UBIGINT                   =  SQL_BIGINT+SQL_UNSIGNED_OFFSET
SQL_C_TINYINT                   =  SQL_TINYINT
SQL_C_SLONG                     =  SQL_C_LONG+SQL_SIGNED_OFFSET
SQL_C_SSHORT                    =  SQL_C_SHORT+SQL_SIGNED_OFFSET
SQL_C_STINYINT                  =  SQL_TINYINT+SQL_SIGNED_OFFSET
SQL_C_ULONG                     =  SQL_C_LONG+SQL_UNSIGNED_OFFSET
SQL_C_USHORT                    =  SQL_C_SHORT+SQL_UNSIGNED_OFFSET
SQL_C_UTINYINT                  =  SQL_TINYINT+SQL_UNSIGNED_OFFSET
SQL_C_BOOKMARK                  =  SQL_C_ULONG
SQL_C_GUID                      =  SQL_GUID
SQL_TYPE_NULL                   =  0
SQL_C_VARBOOKMARK               =  SQL_C_BINARY
SQL_NO_ROW_NUMBER               =  -1
SQL_NO_COLUMN_NUMBER            =  -1
SQL_ROW_NUMBER_UNKNOWN          =  -2
SQL_COLUMN_NUMBER_UNKNOWN       =  -2
SQL_DEFAULT_PARAM               =  -5
SQL_IGNORE                      =  -6
SQL_COLUMN_IGNORE               =  SQL_IGNORE
SQL_LEN_DATA_AT_EXEC_OFFSET     =  -100
SQL_LEN_BINARY_ATTR_OFFSET      =  -100
SQL_PARAM_TYPE_DEFAULT          =  SQL_PARAM_INPUT_OUTPUT
SQL_SETPARAM_VALUE_MAX          =  -1
SQL_COLUMN_COUNT                =  0
SQL_COLUMN_NAME                 =  1
SQL_COLUMN_TYPE                 =  2
SQL_COLUMN_LENGTH               =  3
SQL_COLUMN_PRECISION            =  4
SQL_COLUMN_SCALE                =  5
SQL_COLUMN_DISPLAY_SIZE         =  6
SQL_COLUMN_NULLABLE             =  7
SQL_COLUMN_UNSIGNED             =  8
SQL_COLUMN_MONEY                =  9
SQL_COLUMN_UPDATABLE            =  10
SQL_COLUMN_AUTO_INCREMENT       =  11
SQL_COLUMN_CASE_SENSITIVE       =  12
SQL_COLUMN_SEARCHABLE           =  13
SQL_COLUMN_TYPE_NAME            =  14
SQL_COLUMN_TABLE_NAME           =  15
SQL_COLUMN_OWNER_NAME           =  16
SQL_COLUMN_QUALIFIER_NAME       =  17
SQL_COLUMN_LABEL                =  18
SQL_COLATT_OPT_MAX              =  SQL_COLUMN_LABEL
SQL_COLATT_OPT_MIN              =  SQL_COLUMN_COUNT
SQL_ATTR_READONLY               =  0
SQL_ATTR_WRITE                  =  1
SQL_ATTR_READWRITE_UNKNOWN      =  2
SQL_UNSEARCHABLE                =  0
SQL_LIKE_ONLY                   =  1
SQL_ALL_EXCEPT_LIKE             =  2
SQL_SEARCHABLE                  =  3
SQL_PRED_SEARCHABLE             =  SQL_SEARCHABLE
SQL_NO_TOTAL                    =  -4
SQL_API_SQLALLOCHANDLESTD       =  73
SQL_API_SQLBULKOPERATIONS       =  24
SQL_API_SQLBINDPARAMETER        =  72
SQL_API_SQLBROWSECONNECT        =  55
SQL_API_SQLCOLATTRIBUTES        =  6
SQL_API_SQLCOLUMNPRIVILEGES     =  56
SQL_API_SQLDESCRIBEPARAM        =  58
SQL_API_SQLDRIVERCONNECT        =  41
SQL_API_SQLDRIVERS              =  71
SQL_API_SQLEXTENDEDFETCH        =  59
SQL_API_SQLFOREIGNKEYS          =  60
SQL_API_SQLMORERESULTS          =  61
SQL_API_SQLNATIVESQL            =  62
SQL_API_SQLNUMPARAMS            =  63
SQL_API_SQLPARAMOPTIONS         =  64
SQL_API_SQLPRIMARYKEYS          =  65
SQL_API_SQLPROCEDURECOLUMNS     =  66
SQL_API_SQLPROCEDURES           =  67
SQL_API_SQLSETPOS               =  68
SQL_API_SQLSETSCROLLOPTIONS     =  69
SQL_API_SQLTABLEPRIVILEGES      =  70
SQL_API_ALL_FUNCTIONS           =  0
SQL_API_LOADBYORDINAL           =  199
SQL_API_ODBC3_ALL_FUNCTIONS     =  999
SQL_API_ODBC3_ALL_FUNCTIONS_SIZE =  250
SQL_INFO_FIRST                  =  0
SQL_ACTIVE_CONNECTIONS          =  0
SQL_ACTIVE_STATEMENTS           =  1
SQL_DRIVER_HDBC                 =  3
SQL_DRIVER_HENV                 =  4
SQL_DRIVER_HSTMT                =  5
SQL_DRIVER_NAME                 =  6
SQL_DRIVER_VER                  =  7
SQL_ODBC_API_CONFORMANCE        =  9
SQL_ODBC_VER                    =  10
SQL_ROW_UPDATES                 =  11
SQL_ODBC_SAG_CLI_CONFORMANCE    =  12
SQL_ODBC_SQL_CONFORMANCE        =  15
SQL_PROCEDURES                  =  21
SQL_CONCAT_NULL_BEHAVIOR        =  22
SQL_CURSOR_ROLLBACK_BEHAVIOR    =  24
SQL_EXPRESSIONS_IN_ORDERBY      =  27
SQL_MAX_OWNER_NAME_LEN          =  32
SQL_MAX_PROCEDURE_NAME_LEN      =  33
SQL_MAX_QUALIFIER_NAME_LEN      =  34
SQL_MULT_RESULT_SETS            =  36
SQL_MULTIPLE_ACTIVE_TXN         =  37
SQL_OUTER_JOINS                 =  38
SQL_OWNER_TERM                  =  39
SQL_PROCEDURE_TERM              =  40
SQL_QUALIFIER_NAME_SEPARATOR    =  41
SQL_QUALIFIER_TERM              =  42
SQL_SCROLL_OPTIONS              =  44
SQL_TABLE_TERM                  =  45
SQL_CONVERT_FUNCTIONS           =  48
SQL_NUMERIC_FUNCTIONS           =  49
SQL_STRING_FUNCTIONS            =  50
SQL_SYSTEM_FUNCTIONS            =  51
SQL_TIMEDATE_FUNCTIONS          =  52
SQL_CONVERT_BIGINT              =  53
SQL_CONVERT_BINARY              =  54
SQL_CONVERT_BIT                 =  55
SQL_CONVERT_CHAR                =  56
SQL_CONVERT_DATE                =  57
SQL_CONVERT_DECIMAL             =  58
SQL_CONVERT_DOUBLE              =  59
SQL_CONVERT_FLOAT               =  60
SQL_CONVERT_INTEGER             =  61
SQL_CONVERT_LONGVARCHAR         =  62
SQL_CONVERT_NUMERIC             =  63
SQL_CONVERT_REAL                =  64
SQL_CONVERT_SMALLINT            =  65
SQL_CONVERT_TIME                =  66
SQL_CONVERT_TIMESTAMP           =  67
SQL_CONVERT_TINYINT             =  68
SQL_CONVERT_VARBINARY           =  69
SQL_CONVERT_VARCHAR             =  70
SQL_CONVERT_LONGVARBINARY       =  71
SQL_ODBC_SQL_OPT_IEF            =  73
SQL_CORRELATION_NAME            =  74
SQL_NON_NULLABLE_COLUMNS        =  75
SQL_DRIVER_HLIB                 =  76
SQL_DRIVER_ODBC_VER             =  77
SQL_LOCK_TYPES                  =  78
SQL_POS_OPERATIONS              =  79
SQL_POSITIONED_STATEMENTS       =  80
SQL_BOOKMARK_PERSISTENCE        =  82
SQL_STATIC_SENSITIVITY          =  83
SQL_FILE_USAGE                  =  84
SQL_COLUMN_ALIAS                =  87
SQL_GROUP_BY                    =  88
SQL_KEYWORDS                    =  89
SQL_OWNER_USAGE                 =  91
SQL_QUALIFIER_USAGE             =  92
SQL_QUOTED_IDENTIFIER_CASE      =  93
SQL_SUBQUERIES                  =  95
SQL_UNION                       =  96
SQL_MAX_ROW_SIZE_INCLUDES_LONG  =  103
SQL_MAX_CHAR_LITERAL_LEN        =  108
SQL_TIMEDATE_ADD_INTERVALS      =  109
SQL_TIMEDATE_DIFF_INTERVALS     =  110
SQL_NEED_LONG_DATA_LEN          =  111
SQL_MAX_BINARY_LITERAL_LEN      =  112
SQL_LIKE_ESCAPE_CLAUSE          =  113
SQL_QUALIFIER_LOCATION          =  114
SQL_ACTIVE_ENVIRONMENTS         =  116
SQL_ALTER_DOMAIN                =  117
SQL_SQL_CONFORMANCE             =  118
SQL_DATETIME_LITERALS           =  119
SQL_ASYNC_MODE                  =  10021
SQL_BATCH_ROW_COUNT             =  120
SQL_BATCH_SUPPORT               =  121
SQL_CATALOG_LOCATION            =  SQL_QUALIFIER_LOCATION
SQL_CATALOG_NAME_SEPARATOR      =  SQL_QUALIFIER_NAME_SEPARATOR
SQL_CATALOG_TERM                =  SQL_QUALIFIER_TERM
SQL_CATALOG_USAGE               =  SQL_QUALIFIER_USAGE
SQL_CONVERT_WCHAR               =  122
SQL_CONVERT_INTERVAL_DAY_TIME   =  123
SQL_CONVERT_INTERVAL_YEAR_MONTH =  124
SQL_CONVERT_WLONGVARCHAR        =  125
SQL_CONVERT_WVARCHAR            =  126
SQL_CREATE_ASSERTION            =  127
SQL_CREATE_CHARACTER_SET        =  128
SQL_CREATE_COLLATION            =  129
SQL_CREATE_DOMAIN               =  130
SQL_CREATE_SCHEMA               =  131
SQL_CREATE_TABLE                =  132
SQL_CREATE_TRANSLATION          =  133
SQL_CREATE_VIEW                 =  134
SQL_DRIVER_HDESC                =  135
SQL_DROP_ASSERTION              =  136
SQL_DROP_CHARACTER_SET          =  137
SQL_DROP_COLLATION              =  138
SQL_DROP_DOMAIN                 =  139
SQL_DROP_SCHEMA                 =  140
SQL_DROP_TABLE                  =  141
SQL_DROP_TRANSLATION            =  142
SQL_DROP_VIEW                   =  143
SQL_DYNAMIC_CURSOR_ATTRIBUTES1  =  144
SQL_DYNAMIC_CURSOR_ATTRIBUTES2  =  145
SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 =  146
SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 =  147
SQL_INDEX_KEYWORDS              =  148
SQL_INFO_SCHEMA_VIEWS           =  149
SQL_KEYSET_CURSOR_ATTRIBUTES1   =  150
SQL_KEYSET_CURSOR_ATTRIBUTES2   =  151
SQL_MAX_ASYNC_CONCURRENT_STATEMENTS =  10022
SQL_ODBC_INTERFACE_CONFORMANCE  =  152
SQL_PARAM_ARRAY_ROW_COUNTS      =  153
SQL_PARAM_ARRAY_SELECTS         =  154
SQL_SCHEMA_TERM                 =  SQL_OWNER_TERM
SQL_SCHEMA_USAGE                =  SQL_OWNER_USAGE
SQL_SQL92_DATETIME_FUNCTIONS    =  155
SQL_SQL92_FOREIGN_KEY_DELETE_RULE =  156
SQL_SQL92_FOREIGN_KEY_UPDATE_RULE =  157
SQL_SQL92_GRANT                 =  158
SQL_SQL92_NUMERIC_VALUE_FUNCTIONS =  159
SQL_SQL92_PREDICATES            =  160
SQL_SQL92_RELATIONAL_JOIN_OPERATORS =  161
SQL_SQL92_REVOKE                =  162
SQL_SQL92_ROW_VALUE_CONSTRUCTOR =  163
SQL_SQL92_STRING_FUNCTIONS      =  164
SQL_SQL92_VALUE_EXPRESSIONS     =  165
SQL_STANDARD_CLI_CONFORMANCE    =  166
SQL_STATIC_CURSOR_ATTRIBUTES1   =  167
SQL_STATIC_CURSOR_ATTRIBUTES2   =  168
SQL_AGGREGATE_FUNCTIONS         =  169
SQL_DDL_INDEX                   =  170
SQL_DM_VER                      =  171
SQL_INSERT_STATEMENT            =  172
SQL_UNION_STATEMENT             =  SQL_UNION
SQL_DTC_TRANSITION_COST         =  1750
SQL_AT_ADD_COLUMN_SINGLE        =  20h
SQL_CVT_CHAR                    =  1
SQL_CVT_NUMERIC                 =  2
SQL_CVT_DECIMAL                 =  4
SQL_CVT_INTEGER                 =  8
SQL_CVT_SMALLINT                =  10h
SQL_CVT_FLOAT                   =  20h
SQL_CVT_REAL                    =  40h
SQL_CVT_DOUBLE                  =  80h
SQL_CVT_VARCHAR                 =  100h
SQL_CVT_LONGVARCHAR             =  200h
SQL_CVT_BINARY                  =  400h
SQL_CVT_VARBINARY               =  800h
SQL_CVT_BIT                     =  1000h
SQL_CVT_TINYINT                 =  2000h
SQL_CVT_BIGINT                  =  4000h
SQL_CVT_DATE                    =  8000h
SQL_CVT_TIME                    =  10000h
SQL_CVT_TIMESTAMP               =  20000h
SQL_CVT_LONGVARBINARY           =  40000h
SQL_CVT_INTERVAL_YEAR_MONTH     =  80000h
SQL_CVT_INTERVAL_DAY_TIME       =  100000h
SQL_CVT_WCHAR                   =  200000h
SQL_CVT_WLONGVARCHAR            =  400000h
SQL_CVT_WVARCHAR                =  800000h
SQL_FN_CVT_CONVERT              =  1
SQL_FN_CVT_CAST                 =  2
SQL_FN_STR_CONCAT               =  1
SQL_FN_STR_INSERT               =  2
SQL_FN_STR_LEFT                 =  4
SQL_FN_STR_LTRIM                =  8
SQL_FN_STR_LENGTH               =  10h
SQL_FN_STR_LOCATE               =  20h
SQL_FN_STR_LCASE                =  40h
SQL_FN_STR_REPEAT               =  80h
SQL_FN_STR_REPLACE              =  100h
SQL_FN_STR_RIGHT                =  200h
SQL_FN_STR_RTRIM                =  400h
SQL_FN_STR_SUBSTRING            =  800h
SQL_FN_STR_UCASE                =  1000h
SQL_FN_STR_ASCII                =  2000h
SQL_FN_STR_CHAR                 =  4000h
SQL_FN_STR_DIFFERENCE           =  8000h
SQL_FN_STR_LOCATE_2             =  10000h
SQL_FN_STR_SOUNDEX              =  20000h
SQL_FN_STR_SPACE                =  40000h
SQL_FN_STR_BIT_LENGTH           =  80000h
SQL_FN_STR_CHAR_LENGTH          =  100000h
SQL_FN_STR_CHARACTER_LENGTH     =  200000h
SQL_FN_STR_OCTET_LENGTH         =  400000h
SQL_FN_STR_POSITION             =  800000h
SQL_SSF_CONVERT                 =  1
SQL_SSF_LOWER                   =  2
SQL_SSF_UPPER                   =  4
SQL_SSF_SUBSTRING               =  8
SQL_SSF_TRANSLATE               =  10h
SQL_SSF_TRIM_BOTH               =  20h
SQL_SSF_TRIM_LEADING            =  40h
SQL_SSF_TRIM_TRAILING           =  80h
SQL_FN_NUM_ABS                  =  1
SQL_FN_NUM_ACOS                 =  2
SQL_FN_NUM_ASIN                 =  4
SQL_FN_NUM_ATAN                 =  8
SQL_FN_NUM_ATAN2                =  10h
SQL_FN_NUM_CEILING              =  20h
SQL_FN_NUM_COS                  =  40h
SQL_FN_NUM_COT                  =  80h
SQL_FN_NUM_EXP                  =  100h
SQL_FN_NUM_FLOOR                =  200h
SQL_FN_NUM_LOG                  =  400h
SQL_FN_NUM_MOD                  =  800h
SQL_FN_NUM_SIGN                 =  1000h
SQL_FN_NUM_SIN                  =  2000h
SQL_FN_NUM_SQRT                 =  4000h
SQL_FN_NUM_TAN                  =  8000h
SQL_FN_NUM_PI                   =  10000h
SQL_FN_NUM_RAND                 =  20000h
SQL_FN_NUM_DEGREES              =  40000h
SQL_FN_NUM_LOG10                =  80000h
SQL_FN_NUM_POWER                =  100000h
SQL_FN_NUM_RADIANS              =  200000h
SQL_FN_NUM_ROUND                =  400000h
SQL_FN_NUM_TRUNCATE             =  800000h
SQL_SNVF_BIT_LENGTH             =  1
SQL_SNVF_CHAR_LENGTH            =  2
SQL_SNVF_CHARACTER_LENGTH       =  4
SQL_SNVF_EXTRACT                =  8
SQL_SNVF_OCTET_LENGTH           =  10h
SQL_SNVF_POSITION               =  20h
SQL_FN_TD_NOW                   =  1
SQL_FN_TD_CURDATE               =  2
SQL_FN_TD_DAYOFMONTH            =  4
SQL_FN_TD_DAYOFWEEK             =  8
SQL_FN_TD_DAYOFYEAR             =  10h
SQL_FN_TD_MONTH                 =  20h
SQL_FN_TD_QUARTER               =  40h
SQL_FN_TD_WEEK                  =  80h
SQL_FN_TD_YEAR                  =  100h
SQL_FN_TD_CURTIME               =  200h
SQL_FN_TD_HOUR                  =  400h
SQL_FN_TD_MINUTE                =  800h
SQL_FN_TD_SECOND                =  1000h
SQL_FN_TD_TIMESTAMPADD          =  2000h
SQL_FN_TD_TIMESTAMPDIFF         =  4000h
SQL_FN_TD_DAYNAME               =  8000h
SQL_FN_TD_MONTHNAME             =  10000h
SQL_FN_TD_CURRENT_DATE          =  20000h
SQL_FN_TD_CURRENT_TIME          =  40000h
SQL_FN_TD_CURRENT_TIMESTAMP     =  80000h
SQL_FN_TD_EXTRACT               =  100000h
SQL_SDF_CURRENT_DATE            =  1
SQL_SDF_CURRENT_TIME            =  2
SQL_SDF_CURRENT_TIMESTAMP       =  4
SQL_FN_SYS_USERNAME             =  1
SQL_FN_SYS_DBNAME               =  2
SQL_FN_SYS_IFNULL               =  4
SQL_FN_TSI_FRAC_SECOND          =  1
SQL_FN_TSI_SECOND               =  2
SQL_FN_TSI_MINUTE               =  4
SQL_FN_TSI_HOUR                 =  8
SQL_FN_TSI_DAY                  =  10h
SQL_FN_TSI_WEEK                 =  20h
SQL_FN_TSI_MONTH                =  40h
SQL_FN_TSI_QUARTER              =  80h
SQL_FN_TSI_YEAR                 =  100h
SQL_CA1_NEXT                    =  1
SQL_CA1_ABSOLUTE                =  2
SQL_CA1_RELATIVE                =  4
SQL_CA1_BOOKMARK                =  8
SQL_CA1_LOCK_NO_CHANGE          =  40h
SQL_CA1_LOCK_EXCLUSIVE          =  80h
SQL_CA1_LOCK_UNLOCK             =  100h
SQL_CA1_POS_POSITION            =  200h
SQL_CA1_POS_UPDATE              =  400h
SQL_CA1_POS_DELETE              =  800h
SQL_CA1_POS_REFRESH             =  1000h
SQL_CA1_POSITIONED_UPDATE       =  2000h
SQL_CA1_POSITIONED_DELETE       =  4000h
SQL_CA1_SELECT_FOR_UPDATE       =  8000h
SQL_CA1_BULK_ADD                =  10000h
SQL_CA1_BULK_UPDATE_BY_BOOKMARK =  20000h
SQL_CA1_BULK_DELETE_BY_BOOKMARK =  40000h
SQL_CA1_BULK_FETCH_BY_BOOKMARK  =  80000h
SQL_CA2_READ_ONLY_CONCURRENCY   =  1
SQL_CA2_LOCK_CONCURRENCY        =  2
SQL_CA2_OPT_ROWVER_CONCURRENCY  =  4
SQL_CA2_OPT_VALUES_CONCURRENCY  =  8
SQL_CA2_SENSITIVITY_ADDITIONS   =  10h
SQL_CA2_SENSITIVITY_DELETIONS   =  20h
SQL_CA2_SENSITIVITY_UPDATES     =  40h
SQL_CA2_MAX_ROWS_SELECT         =  80h
SQL_CA2_MAX_ROWS_INSERT         =  100h
SQL_CA2_MAX_ROWS_DELETE         =  200h
SQL_CA2_MAX_ROWS_UPDATE         =  400h
SQL_CA2_MAX_ROWS_CATALOG        =  800h
SQL_CA2_MAX_ROWS_AFFECTS_ALL    =  SQL_CA2_MAX_ROWS_SELECT + \
                                   SQL_CA2_MAX_ROWS_INSERT + \
                                   SQL_CA2_MAX_ROWS_DELETE + \
                                   SQL_CA2_MAX_ROWS_UPDATE + \
                                   SQL_CA2_MAX_ROWS_CATALOG
SQL_CA2_CRC_EXACT               =  1000h
SQL_CA2_CRC_APPROXIMATE         =  2000h
SQL_CA2_SIMULATE_NON_UNIQUE     =  4000h
SQL_CA2_SIMULATE_TRY_UNIQUE     =  8000h
SQL_CA2_SIMULATE_UNIQUE         =  10000h
SQL_OAC_NONE                    =  0
SQL_OAC_LEVEL1                  =  1
SQL_OAC_LEVEL2                  =  2
SQL_OSCC_NOT_COMPLIANT          =  0
SQL_OSCC_COMPLIANT              =  1
SQL_OSC_MINIMUM                 =  0
SQL_OSC_CORE                    =  1
SQL_OSC_EXTENDED                =  2
SQL_CB_NULL                     =  0
SQL_CB_NON_NULL                 =  1
SQL_SO_FORWARD_ONLY             =  1
SQL_SO_KEYSET_DRIVEN            =  2
SQL_SO_DYNAMIC                  =  4
SQL_SO_MIXED                    =  8
SQL_SO_STATIC                   =  10h
SQL_FD_FETCH_BOOKMARK           =  80h
SQL_CN_NONE                     =  0
SQL_CN_DIFFERENT                =  1
SQL_CN_ANY                      =  2
SQL_NNC_NULL                    =  0
SQL_NNC_NON_NULL                =  1
SQL_NC_START                    =  2
SQL_NC_END                      =  4
SQL_FILE_NOT_SUPPORTED          =  0
SQL_FILE_TABLE                  =  1
SQL_FILE_QUALIFIER              =  2
SQL_FILE_CATALOG                =  SQL_FILE_QUALIFIER
SQL_GD_BLOCK                    =  4
SQL_GD_BOUND                    =  8
SQL_PS_POSITIONED_DELETE        =  1
SQL_PS_POSITIONED_UPDATE        =  2
SQL_PS_SELECT_FOR_UPDATE        =  4
SQL_GB_NOT_SUPPORTED            =  0

ALS_SELECT                      =  1
SQL_GB_GROUP_BY_ = ALS_SELECT

SQL_GB_GROUP_BY_CONTAINS_SELECT =  2
SQL_GB_NO_RELATION              =  3
SQL_GB_COLLATE                  =  4
SQL_OU_DML_STATEMENTS           =  1
SQL_OU_PROCEDURE_INVOCATION     =  2
SQL_OU_TABLE_DEFINITION         =  4
SQL_OU_INDEX_DEFINITION         =  8
SQL_OU_PRIVILEGE_DEFINITION     =  10h
SQL_SU_DML_STATEMENTS           =  SQL_OU_DML_STATEMENTS
SQL_SU_PROCEDURE_INVOCATION     =  SQL_OU_PROCEDURE_INVOCATION
SQL_SU_TABLE_DEFINITION         =  SQL_OU_TABLE_DEFINITION
SQL_SU_INDEX_DEFINITION         =  SQL_OU_INDEX_DEFINITION
SQL_SU_PRIVILEGE_DEFINITION     =  SQL_OU_PRIVILEGE_DEFINITION
SQL_QU_DML_STATEMENTS           =  1
SQL_QU_PROCEDURE_INVOCATION     =  2
SQL_QU_TABLE_DEFINITION         =  4
SQL_QU_INDEX_DEFINITION         =  8
SQL_QU_PRIVILEGE_DEFINITION     =  10h
SQL_CU_DML_STATEMENTS           =  SQL_QU_DML_STATEMENTS
SQL_CU_PROCEDURE_INVOCATION     =  SQL_QU_PROCEDURE_INVOCATION
SQL_CU_TABLE_DEFINITION         =  SQL_QU_TABLE_DEFINITION
SQL_CU_INDEX_DEFINITION         =  SQL_QU_INDEX_DEFINITION
SQL_CU_PRIVILEGE_DEFINITION     =  SQL_QU_PRIVILEGE_DEFINITION
SQL_SQ_COMPARISON               =  1
SQL_SQ_EXISTS                   =  2
SQL_SQ_IN                       =  4
SQL_SQ_QUANTIFIED               =  8
SQL_SQ_CORRELATED_SUBQUERIES    =  10h
SQL_U_UNION                     =  1
SQL_U_UNION_ALL                 =  2
SQL_BP_CLOSE                    =  1
SQL_BP_DELETE                   =  2
SQL_BP_DROP                     =  4
SQL_BP_TRANSACTION              =  8
SQL_BP_UPDATE                   =  10h
SQL_BP_OTHER_HSTMT              =  20h
SQL_BP_SCROLL                   =  40h
SQL_SS_ADDITIONS                =  1
SQL_SS_DELETIONS                =  2
SQL_SS_UPDATES                  =  4
SQL_CV_CREATE_VIEW              =  1
SQL_CV_CHECK_OPTION             =  2
SQL_CV_CASCADED                 =  4
SQL_CV_LOCAL                    =  8
SQL_LCK_NO_CHANGE               =  1
SQL_LCK_EXCLUSIVE               =  2
SQL_LCK_UNLOCK                  =  4
SQL_POS_POSITION                =  1
SQL_POS_REFRESH                 =  2
SQL_POS_UPDATE                  =  4
SQL_POS_DELETE                  =  8
SQL_POS_ADD                     =  10h
SQL_QL_START                    =  1
SQL_QL_END                      =  2
SQL_AF_AVG                      =  1
SQL_AF_COUNT                    =  2
SQL_AF_MAX                      =  4
SQL_AF_MIN                      =  8
SQL_AF_SUM                      =  10h
SQL_AF_DISTINCT                 =  20h
SQL_AF_ALL                      =  40h
SQL_SC_SQL92_ENTRY              =  1
SQL_SC_FIPS127_2_TRANSITIONAL   =  2
SQL_SC_SQL92_INTERMEDIATE       =  4
SQL_SC_SQL92_FULL               =  8
SQL_DL_SQL92_DATE               =  1
SQL_DL_SQL92_TIME               =  2
SQL_DL_SQL92_TIMESTAMP          =  4
SQL_DL_SQL92_INTERVAL_YEAR      =  8
SQL_DL_SQL92_INTERVAL_MONTH     =  10h
SQL_DL_SQL92_INTERVAL_DAY       =  20h
SQL_DL_SQL92_INTERVAL_HOUR      =  40h
SQL_DL_SQL92_INTERVAL_MINUTE    =  80h
SQL_DL_SQL92_INTERVAL_SECOND    =  100h
SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH =  200h
SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR   =  400h
SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE =  800h
SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND =  1000h
SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE =  2000h
SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND =  4000h
SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND =  8000h
SQL_CL_START                    =  SQL_QL_START
SQL_CL_END                      =  SQL_QL_END
SQL_BRC_PROCEDURES              =  1
SQL_BRC_EXPLICIT                =  2
SQL_BRC_ROLLED_UP               =  4
SQL_BS_SELECT_EXPLICIT          =  1
SQL_BS_ROW_COUNT_EXPLICIT       =  2
SQL_BS_SELECT_PROC              =  4
SQL_BS_ROW_COUNT_PROC           =  8
SQL_PARC_BATCH                  =  1
SQL_PARC_NO_BATCH               =  2
SQL_PAS_BATCH                   =  1
SQL_PAS_NO_BATCH                =  2
SQL_PAS_NO_SELECT               =  3
SQL_IK_NONE                     =  0
SQL_IK_ASC                      =  1
SQL_IK_DESC                     =  2
SQL_IK_ALL                      =  SQL_IK_ASC + SQL_IK_DESC
SQL_ISV_ASSERTIONS              =  1
SQL_ISV_CHARACTER_SETS          =  2
SQL_ISV_CHECK_CONSTRAINTS       =  4
SQL_ISV_COLLATIONS              =  8
SQL_ISV_COLUMN_DOMAIN_USAGE     =  10h
SQL_ISV_COLUMN_PRIVILEGES       =  20h
SQL_ISV_COLUMNS                 =  40h
SQL_ISV_CONSTRAINT_COLUMN_USAGE =  80h
SQL_ISV_CONSTRAINT_TABLE_USAGE  =  100h
SQL_ISV_DOMAIN_CONSTRAINTS      =  200h
SQL_ISV_DOMAINS                 =  400h
SQL_ISV_KEY_COLUMN_USAGE        =  800h
SQL_ISV_REFERENTIAL_CONSTRAINTS =  1000h
SQL_ISV_SCHEMATA                =  2000h
SQL_ISV_SQL_LANGUAGES           =  4000h
SQL_ISV_TABLE_CONSTRAINTS       =  8000h
SQL_ISV_TABLE_PRIVILEGES        =  10000h
SQL_ISV_TABLES                  =  20000h
SQL_ISV_TRANSLATIONS            =  40000h
SQL_ISV_USAGE_PRIVILEGES        =  80000h
SQL_ISV_VIEW_COLUMN_USAGE       =  100000h
SQL_ISV_VIEW_TABLE_USAGE        =  200000h
SQL_ISV_VIEWS                   =  400000h
SQL_AM_NONE                     =  0
SQL_AD_CONSTRAINT_NAME_DEFINITION =  1
SQL_AD_ADD_DOMAIN_CONSTRAINT    =  2
SQL_AD_DROP_DOMAIN_CONSTRAINT   =  4
SQL_AD_ADD_DOMAIN_DEFAULT       =  8
SQL_AD_DROP_DOMAIN_DEFAULT      =  10h
SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED =  20h
SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE =  40h
SQL_AD_ADD_CONSTRAINT_DEFERRABLE =  80h
SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE =  100h
SQL_CS_CREATE_SCHEMA            =  1
SQL_CS_AUTHORIZATION            =  2
SQL_CS_DEFAULT_CHARACTER_SET    =  4
SQL_CTR_CREATE_TRANSLATION      =  1
SQL_CA_CREATE_ASSERTION         =  1
SQL_CA_CONSTRAINT_INITIALLY_DEFERRED =  10h
SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE =  20h
SQL_CA_CONSTRAINT_DEFERRABLE    =  40h
SQL_CA_CONSTRAINT_NON_DEFERRABLE =  80h
SQL_CCS_CREATE_CHARACTER_SET    =  1
SQL_CCS_COLLATE_CLAUSE          =  2
SQL_CCS_LIMITED_COLLATION       =  4
SQL_CCOL_CREATE_COLLATION       =  1
SQL_CDO_CREATE_DOMAIN           =  1
SQL_CDO_DEFAULT                 =  2
SQL_CDO_CONSTRAINT              =  4
SQL_CDO_COLLATION               =  8
SQL_CDO_CONSTRAINT_NAME_DEFINITION =  10h
SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED =  20h
SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE =  40h
SQL_CDO_CONSTRAINT_DEFERRABLE   =  80h
SQL_CDO_CONSTRAINT_NON_DEFERRABLE =  100h
SQL_CT_CREATE_TABLE             =  1
SQL_CT_COMMIT_PRESERVE          =  2
SQL_CT_COMMIT_DELETE            =  4
SQL_CT_GLOBAL_TEMPORARY         =  8
SQL_CT_LOCAL_TEMPORARY          =  10h
SQL_CT_CONSTRAINT_INITIALLY_DEFERRED =  20h
SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE =  40h
SQL_CT_CONSTRAINT_DEFERRABLE    =  80h
SQL_CT_CONSTRAINT_NON_DEFERRABLE =  100h
SQL_CT_COLUMN_CONSTRAINT        =  200h
SQL_CT_COLUMN_DEFAULT           =  400h
SQL_CT_COLUMN_COLLATION         =  800h
SQL_CT_TABLE_CONSTRAINT         =  1000h
SQL_CT_CONSTRAINT_NAME_DEFINITION =  2000h
SQL_DI_CREATE_INDEX             =  1
SQL_DI_DROP_INDEX               =  2
SQL_DC_DROP_COLLATION           =  1
SQL_DD_DROP_DOMAIN              =  1
SQL_DD_RESTRICT                 =  2
SQL_DD_CASCADE                  =  4
SQL_DS_DROP_SCHEMA              =  1
SQL_DS_RESTRICT                 =  2
SQL_DS_CASCADE                  =  4
SQL_DCS_DROP_CHARACTER_SET      =  1
SQL_DA_DROP_ASSERTION           =  1
SQL_DT_DROP_TABLE               =  1
SQL_DT_RESTRICT                 =  2
SQL_DT_CASCADE                  =  4
SQL_DTR_DROP_TRANSLATION        =  1
SQL_DV_DROP_VIEW                =  1
SQL_DV_RESTRICT                 =  2
SQL_DV_CASCADE                  =  4
SQL_IS_INSERT_LITERALS          =  1
SQL_IS_INSERT_SEARCHED          =  2
SQL_IS_SELECT_INTO              =  4
SQL_OIC_CORE                    =  1
SQL_OIC_LEVEL1                  =  2
SQL_OIC_LEVEL2                  =  3
SQL_SFKD_CASCADE                =  1
SQL_SFKD_NO_ACTION              =  2
SQL_SFKD_SET_DEFAULT            =  4
SQL_SFKD_SET_NULL               =  8
SQL_SFKU_CASCADE                =  1
SQL_SFKU_NO_ACTION              =  2
SQL_SFKU_SET_DEFAULT            =  4
SQL_SFKU_SET_NULL               =  8
SQL_SG_USAGE_ON_DOMAIN          =  1
SQL_SG_USAGE_ON_CHARACTER_SET   =  2
SQL_SG_USAGE_ON_COLLATION       =  4
SQL_SG_USAGE_ON_TRANSLATION     =  8
SQL_SG_WITH_GRANT_OPTION        =  10h
SQL_SG_DELETE_TABLE             =  20h
SQL_SG_INSERT_TABLE             =  40h
SQL_SG_INSERT_COLUMN            =  80h
SQL_SG_REFERENCES_TABLE         =  100h
SQL_SG_REFERENCES_COLUMN        =  200h
SQL_SG_SELECT_TABLE             =  400h
SQL_SG_UPDATE_TABLE             =  800h
SQL_SG_UPDATE_COLUMN            =  1000h
SQL_SP_EXISTS                   =  1
SQL_SP_ISNOTNULL                =  2
SQL_SP_ISNULL                   =  4
SQL_SP_MATCH_FULL               =  8
SQL_SP_MATCH_PARTIAL            =  10h
SQL_SP_MATCH_UNIQUE_FULL        =  20h
SQL_SP_MATCH_UNIQUE_PARTIAL     =  40h
SQL_SP_OVERLAPS                 =  80h
SQL_SP_UNIQUE                   =  100h
SQL_SP_LIKE                     =  200h
SQL_SP_IN                       =  400h
SQL_SP_BETWEEN                  =  800h
SQL_SP_COMPARISON               =  1000h
SQL_SP_QUANTIFIED_COMPARISON    =  2000h
SQL_SRJO_CORRESPONDING_CLAUSE   =  1
SQL_SRJO_CROSS_JOIN             =  2
SQL_SRJO_EXCEPT_JOIN            =  4
SQL_SRJO_FULL_OUTER_JOIN        =  8
SQL_SRJO_INNER_JOIN             =  10h
SQL_SRJO_INTERSECT_JOIN         =  20h
SQL_SRJO_LEFT_OUTER_JOIN        =  40h
SQL_SRJO_NATURAL_JOIN           =  80h
SQL_SRJO_RIGHT_OUTER_JOIN       =  100h
SQL_SRJO_UNION_JOIN             =  200h
SQL_SR_USAGE_ON_DOMAIN          =  1
SQL_SR_USAGE_ON_CHARACTER_SET   =  2
SQL_SR_USAGE_ON_COLLATION       =  4
SQL_SR_USAGE_ON_TRANSLATION     =  8
SQL_SR_GRANT_OPTION_FOR         =  10h
SQL_SR_CASCADE                  =  20h
SQL_SR_RESTRICT                 =  40h
SQL_SR_DELETE_TABLE             =  80h
SQL_SR_INSERT_TABLE             =  100h
SQL_SR_INSERT_COLUMN            =  200h
SQL_SR_REFERENCES_TABLE         =  400h
SQL_SR_REFERENCES_COLUMN        =  800h
SQL_SR_SELECT_TABLE             =  1000h
SQL_SR_UPDATE_TABLE             =  2000h
SQL_SR_UPDATE_COLUMN            =  4000h
SQL_SRVC_VALUE_EXPRESSION       =  1
SQL_SRVC_NULL                   =  2
SQL_SRVC_DEFAULT                =  4
SQL_SRVC_ROW_SUBQUERY           =  8
SQL_SVE_CASE                    =  1
SQL_SVE_CAST                    =  2
SQL_SVE_COALESCE                =  4
SQL_SVE_NULLIF                  =  8
SQL_SCC_XOPEN_CLI_VERSION1      =  1
SQL_SCC_ISO92_CLI               =  2
SQL_US_UNION                    =  SQL_U_UNION
SQL_US_UNION_ALL                =  SQL_U_UNION_ALL
SQL_DTC_ENLIST_EXPENSIVE        =  1
SQL_DTC_UNENLIST_EXPENSIVE      =  2
SQL_FETCH_FIRST_USER            =  31
SQL_FETCH_FIRST_SYSTEM          =  32
SQL_ENTIRE_ROWSET               =  0
SQL_POSITION                    =  0
SQL_REFRESH                     =  1
SQL_UPDATE                      =  2
SQL_DELETE                      =  3
SQL_ADD                         =  4
SQL_SETPOS_MAX_OPTION_VALUE     =  SQL_ADD
SQL_UPDATE_BY_BOOKMARK          =  5
SQL_DELETE_BY_BOOKMARK          =  6
SQL_FETCH_BY_BOOKMARK           =  7
SQL_LOCK_NO_CHANGE              =  0
SQL_LOCK_EXCLUSIVE              =  1
SQL_LOCK_UNLOCK                 =  2
SQL_SETPOS_MAX_LOCK_VALUE       =  SQL_LOCK_UNLOCK
SQL_BEST_ROWID                  =  1
SQL_ROWVER                      =  2
SQL_PC_NOT_PSEUDO               =  1
SQL_QUICK                       =  0
SQL_ENSURE                      =  1
SQL_TABLE_STAT                  =  0

SQL_ALL_CATALOGS  equ  "%"
SQL_ALL_SCHEMAS  equ  "%"
SQL_ALL_TABLE_TYPES equ  "%"

SQL_DRIVER_NOPROMPT             =  0
SQL_DRIVER_COMPLETE             =  1
SQL_DRIVER_PROMPT               =  2
IRED  =  3
SQL_DRIVER_COMPLETE_R = IRED

SQL_FETCH_BOOKMARK              =  8
SQL_ROW_SUCCESS                 =  0
SQL_ROW_DELETED                 =  1
SQL_ROW_UPDATED                 =  2
SQL_ROW_NOROW                   =  3
SQL_ROW_ADDED                   =  4
SQL_ROW_ERROR                   =  5
SQL_ROW_SUCCESS_WITH_INFO       =  6
SQL_ROW_PROCEED                 =  0
SQL_ROW_IGNORE                  =  1
SQL_PARAM_SUCCESS               =  0
SQL_PARAM_SUCCESS_WITH_INFO     =  6
SQL_PARAM_ERROR                 =  5
SQL_PARAM_UNUSED                =  7
SQL_PARAM_DIAG_UNAVAILABLE      =  1
SQL_PARAM_PROCEED               =  0
SQL_PARAM_IGNORE                =  1
SQL_CASCADE                     =  0
SQL_RESTRICT                    =  1
SQL_SET_NULL                    =  2
SQL_NO_ACTION                   =  3
SQL_SET_DEFAULT                 =  4
SQL_INITIALLY_DEFERRED          =  5
SQL_INITIALLY_IMMEDIATE         =  6
SQL_NOT_DEFERRABLE              =  7
SQL_PARAM_TYPE_UNKNOWN          =  0
SQL_PARAM_INPUT                 =  1
SQL_PARAM_INPUT_OUTPUT          =  2
SQL_RESULT_COL                  =  3
SQL_PARAM_OUTPUT                =  4
SQL_RETURN_VALUE                =  5
SQL_PT_UNKNOWN                  =  0
SQL_PT_PROCEDURE                =  1
SQL_PT_FUNCTION                 =  2
SQL_YEAR                        =  SQL_CODE_YEAR
SQL_MONTH                       =  SQL_CODE_MONTH
SQL_DAY                         =  SQL_CODE_DAY
SQL_HOUR                        =  SQL_CODE_HOUR
SQL_MINUTE                      =  SQL_CODE_MINUTE
SQL_SECOND                      =  SQL_CODE_SECOND
SQL_YEAR_TO_MONTH               =  SQL_CODE_YEAR_TO_MONTH
SQL_DAY_TO_HOUR                 =  SQL_CODE_DAY_TO_HOUR
SQL_DAY_TO_MINUTE               =  SQL_CODE_DAY_TO_MINUTE
SQL_DAY_TO_SECOND               =  SQL_CODE_DAY_TO_SECOND
SQL_HOUR_TO_MINUTE              =  SQL_CODE_HOUR_TO_MINUTE
SQL_HOUR_TO_SECOND              =  SQL_CODE_HOUR_TO_SECOND
SQL_MINUTE_TO_SECOND            =  SQL_CODE_MINUTE_TO_SECOND
SQL_DATABASE_NAME               =  16
SQL_FD_FETCH_PREV               =  SQL_FD_FETCH_PRIOR
SQL_FETCH_PREV                  =  SQL_FETCH_PRIOR
SQL_CONCUR_TIMESTAMP            =  SQL_CONCUR_ROWVER
SQL_SCCO_OPT_TIMESTAMP          =  SQL_SCCO_OPT_ROWVER
SQL_CC_DELETE                   =  SQL_CB_DELETE
SQL_CR_DELETE                   =  SQL_CB_DELETE
SQL_CC_CLOSE                    =  SQL_CB_CLOSE
SQL_CR_CLOSE                    =  SQL_CB_CLOSE
SQL_CC_PRESERVE                 =  SQL_CB_PRESERVE
SQL_CR_PRESERVE                 =  SQL_CB_PRESERVE
SQL_SCROLL_FORWARD_ONLY         =  0
SQL_SCROLL_KEYSET_DRIVEN        =  -1
SQL_SCROLL_DYNAMIC              =  -2
SQL_SCROLL_STATIC               =  -3
TRACE_VERSION                   =  1000
TRACE_ON                        =  1
TRACE_VS_EVENT_ON               =  2
ODBC_VS_FLAG_UNICODE_ARG        =  1
ODBC_VS_FLAG_UNICODE_COR        =  2
ODBC_VS_FLAG_RETCODE            =  4
ODBC_VS_FLAG_STOP               =  8



struct DATESTRUCT
  .year  dw ?
  .month dw ?
  .day   dw ?
ends

SQL_DATE_STRUCT  equ  DATESTRUCT

struct TIME_STRUCT
  .hour   dw ?
  .minute dw ?
  .second dw ?
ends

SQL_TIME_STRUCT  equ  TIME_STRUCT

struct TIMESTAMPSTRUCT
  .year     dw ?
  .month    dw ?
  .day      dw ?
  .hour     dw ?
  .minute   dw ?
  .second   dw ?
  .fraction dd ?
ends

SQL_TIMESTAMP_STRUCT  equ  TIMESTAMPSTRUCT


SQL_IS_YEAR             =  1
SQL_IS_MONTH            =  2
SQL_IS_DAY              =  3
SQL_IS_HOUR             =  4
SQL_IS_MINUTE           =  5
SQL_IS_SECOND           =  6
SQL_IS_YEAR_TO_MONTH    =  7
SQL_IS_DAY_TO_HOUR      =  8
SQL_IS_DAY_TO_MINUTE    =  9
SQL_IS_DAY_TO_SECOND    =  10
SQL_IS_HOUR_TO_MINUTE   =  11
SQL_IS_HOUR_TO_SECOND   =  12
SQL_IS_MINUTE_TO_SECOND =  13

struct SQL_YEAR_MONTH_STRUCT
  .year  dw ?
  .month dw ?
ends


struct SQL_DAY_SECOND_STRUCT
  .day      dw ?
  .hour     dw ?
  .minute   dw ?
  .second   dw ?
  .fraction dw ?
ends


SQL_MAX_NUMERIC_LEN  =  16

struct SQL_NUMERIC_STRUCT
  .precision db ?
  .scale     db ?
  .sign      db ?
  .val       rb SQL_MAX_NUMERIC_LEN
ends

struct SQLGUID
  .Data1 dd ?
  .Data2 dw ?
  .Data3 dw ?
  .Data4  rb 8
ends
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/equates/Win32/_RichEdit32.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: RichEdit32.dll constants and structures.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


MAX_TAB_STOPS = 32


struct CHARFORMAT
  .cbSize          dd ?
  .dwMask          dd ?
  .dwEffects       dd ?
  .yHeight         dd ?
  .yOffset         dd ?
  .crTextColor     dd ?
  .bCharSet        db ?
  .bPitchAndFamily db ?
  .szFaceName      rb 32
  ._wPad2          dw ?
ends


struct CHARFORMAT2
  .cbSize       dd ?
  .dwMask       dd ?
  .dwEffects    dd ?
  .yHeight      dd ?
  .yOffset      dd ?
  .crTextColor  dd ?
  .bCharSet     db ?
  .bPitchAndFamily db ?
  .szFaceName   rb 32
  ._wPad2       dw ?
  .wWeight      dw ?
  .sSpacing     dw ?
  .crBackColor  dd ?
  .lcid         dd ?
  .dwReserved   dd ?
  .sStyle       dw ?
  .wKerning     dw ?
  .bUnderlineType db ?
  .bAnimation     db ?
  .bRevAuthor     db ?
  .bReserved1     db ?
ends


struct SETTEXTEX
  .flags dd ?
  .codepage dd ?
ends

struct CHARRANGE
  .cpMin dd ?
  .cpMax dd ?
ends


struct ENLINK
  .nmhdr   NMHDR
  .msg     dd ?
  .wParam  dd ?
  .lParam  dd ?
  .chrg    CHARRANGE
ends

struct TEXTRANGE
  .chrg      CHARRANGE
  .lpstrText dd ?
ends


struct PARAFORMAT2
  .cbSize           dd  ?
  .dwMask           dd  ?
  .wNumbering       dw  ?
  .wEffects         dw  ?
  .dxStartIndent    dd  ?
  .dxRightIndent    dd  ?
  .dxOffset         dd  ?
  .wAlignment       dw  ?
  .cTabCount        dw  ?
  .rgxTabs          rd  MAX_TAB_STOPS
  .dySpaceBefore    dd  ?
  .dySpaceAfter     dd  ?
  .dyLineSpacing    dd  ?
  .sStyle           dw  ?
  .bLineSpacingRule db  ?
  .bOutlineLevel    db  ?
  .wShadingWeight   dw  ?
  .wShadingStyle    dw  ?
  .wNumberingStart  dw  ?
  .wNumberingStyle  dw  ?
  .wNumberingTab    dw  ?
  .wBorderSpace     dw  ?
  .wBorderWidth     dw  ?
  .wBorders         dw  ?
ends

ES_NOOLEDRAGDROP        = 000000008h
ES_DISABLENOSCROLL      = 000002000h
ES_SUNKEN               = 000004000h
ES_SAVESEL              = 000008000h
ES_SELFIME              = 000040000h
ES_NOIME                = 000080000h
ES_VERTICAL             = 000400000h
ES_SELECTIONBAR         = 001000000h

ES_EX_NOCALLOLEINIT     = 001000000h

EM_CANPASTE             = WM_USER + 50
EM_DISPLAYBAND          = WM_USER + 51
EM_EXGETSEL             = WM_USER + 52
EM_EXLIMITTEXT          = WM_USER + 53
EM_EXLINEFROMCHAR       = WM_USER + 54
EM_EXSETSEL             = WM_USER + 55
EM_FINDTEXT             = WM_USER + 56
EM_FORMATRANGE          = WM_USER + 57
EM_GETCHARFORMAT        = WM_USER + 58
EM_GETEVENTMASK         = WM_USER + 59
EM_GETOLEINTERFACE      = WM_USER + 60
EM_GETPARAFORMAT        = WM_USER + 61
EM_GETSELTEXT           = WM_USER + 62
EM_HIDESELECTION        = WM_USER + 63
EM_PASTESPECIAL         = WM_USER + 64
EM_REQUESTRESIZE        = WM_USER + 65
EM_SELECTIONTYPE        = WM_USER + 66
EM_SETBKGNDCOLOR        = WM_USER + 67
EM_SETCHARFORMAT        = WM_USER + 68
EM_SETEVENTMASK         = WM_USER + 69
EM_SETOLECALLBACK       = WM_USER + 70
EM_SETPARAFORMAT        = WM_USER + 71
EM_SETTARGETDEVICE      = WM_USER + 72
EM_STREAMIN             = WM_USER + 73
EM_STREAMOUT            = WM_USER + 74
EM_GETTEXTRANGE         = WM_USER + 75
EM_FINDWORDBREAK        = WM_USER + 76
EM_SETOPTIONS           = WM_USER + 77
EM_GETOPTIONS           = WM_USER + 78
EM_FINDTEXTEX           = WM_USER + 79
EM_GETWORDBREAKPROCEX   = WM_USER + 80
EM_SETWORDBREAKPROCEX   = WM_USER + 81
EM_SETUNDOLIMIT         = WM_USER + 82
EM_REDO                 = WM_USER + 84
EM_CANREDO              = WM_USER + 85
EM_GETUNDONAME          = WM_USER + 86
EM_GETREDONAME          = WM_USER + 87
EM_STOPGROUPTYPING      = WM_USER + 88
EM_SETTEXTMODE          = WM_USER + 89
EM_GETTEXTMODE          = WM_USER + 90
EM_AUTOURLDETECT        = WM_USER + 91
EM_GETAUTOURLDETECT     = WM_USER + 92
EM_SETPALETTE           = WM_USER + 93
EM_GETTEXTEX            = WM_USER + 94
EM_GETTEXTLENGTHEX      = WM_USER + 95
EM_SHOWSCROLLBAR        = WM_USER + 96
EM_SETTEXTEX            = WM_USER + 97
EM_SETPUNCTUATION       = WM_USER + 100
EM_GETPUNCTUATION       = WM_USER + 101
EM_SETWORDWRAPMODE      = WM_USER + 102
EM_GETWORDWRAPMODE      = WM_USER + 103
EM_SETIMECOLOR          = WM_USER + 104
EM_GETIMECOLOR          = WM_USER + 105
EM_SETIMEOPTIONS        = WM_USER + 106
EM_GETIMEOPTIONS        = WM_USER + 107
EM_CONVPOSITION         = WM_USER + 108
EM_SETLANGOPTIONS       = WM_USER + 120
EM_GETLANGOPTIONS       = WM_USER + 121
EM_GETIMECOMPMODE       = WM_USER + 122
EM_FINDTEXTW            = WM_USER + 123
EM_FINDTEXTEXW          = WM_USER + 124
EM_RECONVERSION         = WM_USER + 125
EM_SETIMEMODEBIAS       = WM_USER + 126
EM_GETIMEMODEBIAS       = WM_USER + 127
EM_SETBIDIOPTIONS       = WM_USER + 200
EM_GETBIDIOPTIONS       = WM_USER + 201
EM_SETTYPOGRAPHYOPTIONS = WM_USER + 202
EM_GETTYPOGRAPHYOPTIONS = WM_USER + 203
EM_SETEDITSTYLE         = WM_USER + 204
EM_GETEDITSTYLE         = WM_USER + 205
EM_OUTLINE              = WM_USER + 220
EM_GETSCROLLPOS         = WM_USER + 221
EM_SETSCROLLPOS         = WM_USER + 222
EM_SETFONTSIZE          = WM_USER + 223
EM_GETZOOM              = WM_USER + 224
EM_SETZOOM              = WM_USER + 225

CFM_BOLD        = 00000001h
CFM_ITALIC      = 00000002h
CFM_UNDERLINE   = 00000004h
CFM_STRIKEOUT   = 00000008h
CFM_PROTECTED   = 00000010h
CFM_LINK        = 00000020h
CFM_SMALLCAPS   = 00000040h
CFM_ALLCAPS     = 00000080h
CFM_HIDDEN      = 00000100h
CFM_OUTLINE     = 00000200h
CFM_SHADOW      = 00000400h
CFM_EMBOSS      = 00000800h
CFM_IMPRINT     = 00001000h
CFM_DISABLED    = 00002000h
CFM_REVISED     = 00004000h
CFM_REVAUTHOR   = 00008000h
CFM_SUBSCRIPT   = CFE_SUBSCRIPT or CFE_SUPERSCRIPT ; = 00030000h
CFM_ANIMATION   = 00040000h
CFM_STYLE       = 00080000h
CFM_KERNING     = 00100000h
CFM_SPACING     = 00200000h
CFM_WEIGHT      = 00400000h
CFM_UNDERLINETYPE=00800000h
;                = 01000000h
CFM_LCID        = 02000000h
CFM_BACKCOLOR   = 04000000h
CFM_CHARSET     = 08000000h
CFM_OFFSET      = 10000000h
CFM_FACE        = 20000000h
CFM_COLOR       = 40000000h
CFM_SIZE        = 80000000h


CFE_BOLD        = 00000001h
CFE_ITALIC      = 00000002h
CFE_UNDERLINE   = 00000004h
CFE_STRIKEOUT   = 00000008h
CFE_PROTECTED   = 00000010h
CFE_PROTECTED   = 00000010h
CFE_LINK        = 00000020h
CFE_ALLCAPS     = CFM_ALLCAPS
CFE_HIDDEN      = CFM_HIDDEN
CFE_OUTLINE     = CFM_OUTLINE
CFE_SHADOW      = CFM_SHADOW
CFE_EMBOSS      = CFM_EMBOSS
CFE_IMPRINT     = CFM_IMPRINT
CFE_DISABLED    = CFM_DISABLED
CFE_REVISED     = CFM_REVISED
CFE_AUTOBACKCOLOR = CFM_BACKCOLOR

CFE_SUBSCRIPT   = 00010000h
CFE_SUPERSCRIPT = 00020000h

CFE_AUTOCOLOR   = 40000000h



SCF_SELECTION = 0001h
SCF_WORD      = 0002h

SF_TEXT       = 0001h
SF_RTF        = 0002h
SF_RTFNOOBJS  = 0003h
SF_TEXTIZED   = 0004h

SFF_SELECTION = 8000h
SFF_PLAINRTF  = 4000h

ST_DEFAULT      = 0
ST_KEEPUNDO     = 1
ST_SELECTION    = 2
ST_NEWCHARS     = 4


EN_LINK = $0000070b


ENM_NONE = 000000000h
ENM_CHANGE = 000000001h
ENM_UPDATE = 000000002h
ENM_SCROLL = 000000004h
ENM_SCROLLEVENTS = 000000008h
ENM_DRAGDROPDONE = 000000010h
ENM_PARAGRAPHEXPANDED = 000000020h
ENM_PAGECHANGE = 000000040h
ENM_KEYEVENTS = 000010000h
ENM_MOUSEEVENTS = 000020000h
ENM_REQUESTRESIZE = 000040000h
ENM_SELCHANGE = 000080000h
ENM_DROPFILES = 000100000h
ENM_PROTECTED = 000200000h
ENM_CORRECTTEXT = 000400000h
ENM_IMECHANGE = 000800000h
ENM_LANGCHANGE = 001000000h
ENM_OBJECTPOSITIONS = 002000000h
ENM_LINK = 004000000h
ENM_LOWFIRTF = 008000000h

TM_PLAINTEXT            = 1
TM_RICHTEXT             = 2
TM_SINGLELEVELUNDO      = 4
TM_MULTILEVELUNDO       = 8
TM_SINGLECODEPAGE       = 16
TM_MULTICODEPAGE        = 32


PFM_STARTINDENT         = 000000001h
PFM_RIGHTINDENT         = 000000002h
PFM_OFFSET              = 000000004h
PFM_ALIGNMENT           = 000000008h
PFM_TABSTOPS            = 000000010h
PFM_NUMBERING           = 000000020h
PFM_OFFSETINDENT        = 080000000h
PFM_SPACEBEFORE         = 000000040h
PFM_SPACEAFTER          = 000000080h
PFM_LINESPACING         = 000000100h
PFM_STYLE               = 000000400h
PFM_BORDER              = 000000800h
PFM_SHADING             = 000001000h
PFM_NUMBERINGSTYLE      = 000002000h
PFM_NUMBERINGTAB        = 000004000h
PFM_NUMBERINGSTART      = 000008000h
PFM_RTLPARA             = 000010000h
PFM_KEEP                = 000020000h
PFM_KEEPNEXT            = 000040000h
PFM_PAGEBREAKBEFORE     = 000080000h
PFM_NOLINENUMBER        = 000100000h
PFM_NOWIDOWCONTROL      = 000200000h
PFM_DONOTHYPHEN         = 000400000h
PFM_SIDEBYSIDE          = 000800000h
PFM_TABLE               = 040000000h
PFM_TEXTWRAPPINGBREAK   = 020000000h
PFM_TABLEROWDELIMITER   = 010000000h
PFM_COLLAPSED           = 001000000h
PFM_OUTLINELEVEL        = 002000000h
PFM_BOX                 = 004000000h
PFM_RESERVED2           = 008000000h
PFM_ALL                 = PFM_STARTINDENT or PFM_RIGHTINDENT or         \
                          PFM_OFFSET or PFM_ALIGNMENT or                \
                          PFM_TABSTOPS or PFM_NUMBERING or              \
                          PFM_OFFSETINDENT or PFM_RTLPARA

PFM_EFFECTS             = PFM_RTLPARA or PFM_KEEP or PFM_KEEPNEXT or    \
                          PFM_TABLE or PFM_PAGEBREAKBEFORE or           \
                          PFM_NOLINENUMBER or PFM_NOWIDOWCONTROL or     \
                          PFM_DONOTHYPHEN or PFM_SIDEBYSIDE or          \
                          PFM_TABLE or PFM_TABLEROWDELIMITER

PFM_ALL2                = PFM_ALL or PFM_EFFECTS or PFM_SPACEBEFORE or  \
                          PFM_SPACEAFTER or PFM_LINESPACING or          \
                          PFM_STYLE or PFM_SHADING or PFM_BORDER or     \
                          PFM_NUMBERINGTAB or PFM_NUMBERINGSTART or     \
                          PFM_NUMBERINGSTYLE
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/equates/Win32/_SHELL32.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: SHELL32.DLL structures and constants
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


struct NOTIFYICONDATA
   .cbSize           dd ?
   .hWnd             dd ?
   .uID              dd ?
   .uFlags           dd ?
   .uCallbackMessage dd ?
   .hIcon            dd ?
   .szTip            du 64
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


; for SHBrowseForFolder

struct BROWSEINFO
    .hwndOwner          dd ?
    .pidlRoot           dd ?
    .pszDisplayName     dd ?
    .lpszTitle          dd ?
    .ulFlags            dd ?
    .lpfn               dd ?
    .lParam             dd ?
    .iImage             dd ?
ends

BIF_RETURNONLYFSDIRS   = $0001
BIF_DONTGOBELOWDOMAIN  = $0002
BIF_STATUSTEXT         = $0004
BIF_RETURNFSANCESTORS  = $0008
BIF_EDITBOX            = $0010
BIF_VALIDATE           = $0020

BFFM_INITIALIZED       = 1
BFFM_SELCHANGED        = 2
BFFM_VALIDATEFAILEDA   = 3      ; lParam:szPath ret:TRUE(cont), FALSE(EndDialog)
BFFM_VALIDATEFAILEDW   = 4      ; lParam:wzPath ret:TRUE(cont), FALSE(EndDialog)

; messages to browser

BFFM_SETSTATUSTEXTA    = WM_USER + 100
BFFM_ENABLEOK          = WM_USER + 101
BFFM_SETSELECTIONA     = WM_USER + 102
BFFM_SETSELECTIONW     = WM_USER + 103
BFFM_SETSTATUSTEXTW    = WM_USER + 104

BFFM_SETSTATUSTEXT     = BFFM_SETSTATUSTEXTA
BFFM_SETSELECTION      = BFFM_SETSELECTIONA


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































Deleted freshlib/equates/Win32/_USER32.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: USER32.DLL structures and constants
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


struct POINT
   .x dd ?
   .y dd ?
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 rb 32
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 ?
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

; 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   = $00000000
WS_ICONICPOPUP  = $C0000000
WS_POPUP        = $80000000
WS_CHILD        = $40000000
WS_MINIMIZE     = $20000000
WS_VISIBLE      = $10000000
WS_DISABLED     = $08000000
WS_CLIPSIBLINGS = $04000000
WS_CLIPCHILDREN = $02000000
WS_MAXIMIZE     = $01000000
WS_CAPTION      = $00C00000
WS_BORDER       = $00800000
WS_DLGFRAME     = $00400000
WS_VSCROLL      = $00200000
WS_HSCROLL      = $00100000
WS_SYSMENU      = $00080000
WS_THICKFRAME   = $00040000
WS_HREDRAW      = $00020000
WS_VREDRAW      = $00010000
WS_GROUP        = $00020000
WS_TABSTOP      = $00010000
WS_MINIMIZEBOX  = $00020000
WS_MAXIMIZEBOX  = $00010000

; 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 = 8000h

; 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_NOSENDCHANGING = 0400h
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_SETTINGCHANGE          = WM_WININICHANGE
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_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_NCHITTEST result constants
HTBORDER = 18
HTBOTTOM = 15
HTBOTTOMLEFT = 16
HTBOTTOMRIGHT = 17
HTCAPTION = 2
HTCLIENT = 1
HTERROR = -2
HTGROWBOX = 4
HTHSCROLL = 6
HTLEFT = 10
HTMAXBUTTON = 9
HTMENU = 5
HTMINBUTTON = 8
HTNOWHERE = 0
HTRIGHT = 11
HTSYSMENU = 3
HTTOP = 12
HTTOPLEFT = 13
HTTOPRIGHT = 14
HTVSCROLL = 7
HTTRANSPARENT = -1
HTOBJECT = 19
HTCLOSE = 20
HTHELP = 21


; 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

; 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_SIZEALL     = 32646
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

; CB_DIR message flags

DDL_READWRITE   = 0h
DDL_READONLY    = 1h
DDL_HIDDEN      = 2h
DDL_SYSTEM      = 4h
DDL_DIRECTORY   = 10h
DDL_ARCHIVE     = 20h
DDL_POSTMSGS    = 2000h
DDL_DRIVES      = 4000h
DDL_EXCLUSIVE   = 8000h


; 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

; Layered window attributes

LWA_COLORKEY = 1
LWA_ALPHA    = 2

; UpdateLayeredWindow flags

ULW_COLORKEY = 1
ULW_ALPHA    = 2
ULW_OPAQUE   = 4

DLGWINDOWEXTRA = 30

; SystemParametersInfo

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
SPIF_UPDATEINIFILE      = 1
SPIF_SENDWININICHANGE   = 2

SPI_GETACTIVEWINDOWTRACKING         = $1000
SPI_SETACTIVEWINDOWTRACKING         = $1001
SPI_GETMENUANIMATION                = $1002
SPI_SETMENUANIMATION                = $1003
SPI_GETCOMBOBOXANIMATION            = $1004
SPI_SETCOMBOBOXANIMATION            = $1005
SPI_GETLISTBOXSMOOTHSCROLLING       = $1006
SPI_SETLISTBOXSMOOTHSCROLLING       = $1007
SPI_GETGRADIENTCAPTIONS             = $1008
SPI_SETGRADIENTCAPTIONS             = $1009
SPI_GETKEYBOARDCUES                 = $100A
SPI_SETKEYBOARDCUES                 = $100B
SPI_GETMENUUNDERLINES               = SPI_GETKEYBOARDCUES
SPI_SETMENUUNDERLINES               = SPI_SETKEYBOARDCUES
SPI_GETACTIVEWNDTRKZORDER           = $100C
SPI_SETACTIVEWNDTRKZORDER           = $100D
SPI_GETHOTTRACKING                  = $100E
SPI_SETHOTTRACKING                  = $100F
SPI_GETMENUFADE                     = $1012
SPI_SETMENUFADE                     = $1013
SPI_GETSELECTIONFADE                = $1014
SPI_SETSELECTIONFADE                = $1015
SPI_GETTOOLTIPANIMATION             = $1016
SPI_SETTOOLTIPANIMATION             = $1017
SPI_GETTOOLTIPFADE                  = $1018
SPI_SETTOOLTIPFADE                  = $1019
SPI_GETCURSORSHADOW                 = $101A
SPI_SETCURSORSHADOW                 = $101B

SPI_GETMOUSESONAR                   = $101C
SPI_SETMOUSESONAR                   = $101D
SPI_GETMOUSECLICKLOCK               = $101E
SPI_SETMOUSECLICKLOCK               = $101F
SPI_GETMOUSEVANISH                  = $1020
SPI_SETMOUSEVANISH                  = $1021
SPI_GETFLATMENU                     = $1022
SPI_SETFLATMENU                     = $1023
SPI_GETDROPSHADOW                   = $1024
SPI_SETDROPSHADOW                   = $1025
SPI_GETBLOCKSENDINPUTRESETS         = $1026
SPI_SETBLOCKSENDINPUTRESETS         = $1027

SPI_GETUIEFFECTS                    = $103E
SPI_SETUIEFFECTS                    = $103F

SPI_GETFOREGROUNDLOCKTIMEOUT        = $2000
SPI_SETFOREGROUNDLOCKTIMEOUT        = $2001
SPI_GETACTIVEWNDTRKTIMEOUT          = $2002
SPI_SETACTIVEWNDTRKTIMEOUT          = $2003
SPI_GETFOREGROUNDFLASHCOUNT         = $2004
SPI_SETFOREGROUNDFLASHCOUNT         = $2005
SPI_GETCARETWIDTH                   = $2006
SPI_SETCARETWIDTH                   = $2007

SPI_GETMOUSECLICKLOCKTIME           = $2008
SPI_SETMOUSECLICKLOCKTIME           = $2009
SPI_GETFONTSMOOTHINGTYPE            = $200A
SPI_SETFONTSMOOTHINGTYPE            = $200B

; constants for SPI_GETFONTSMOOTHINGTYPE and SPI_SETFONTSMOOTHINGTYPE:
FE_FONTSMOOTHINGSTANDARD            = $0001
FE_FONTSMOOTHINGCLEARTYPE           = $0002
FE_FONTSMOOTHINGDOCKING             = $8000

SPI_GETFONTSMOOTHINGCONTRAST           = $200C
SPI_SETFONTSMOOTHINGCONTRAST           = $200D

SPI_GETFOCUSBORDERWIDTH             = $200E
SPI_SETFOCUSBORDERWIDTH             = $200F
SPI_GETFOCUSBORDERHEIGHT            = $2010
SPI_SETFOCUSBORDERHEIGHT            = $2011

SPI_GETFONTSMOOTHINGORIENTATION           = $2012
SPI_SETFONTSMOOTHINGORIENTATION           = $2013

; constants for SPI_GETFONTSMOOTHINGORIENTATION and SPI_SETFONTSMOOTHINGORIENTATION:
FE_FONTSMOOTHINGORIENTATIONBGR   = $0000
FE_FONTSMOOTHINGORIENTATIONRGB   = $0001

;
; Flags
;
SPIF_UPDATEINIFILE    = $0001
SPIF_SENDWININICHANGE = $0002
SPIF_SENDCHANGE       = SPIF_SENDWININICHANGE


; LoadBitmap system images
OBM_LFARROWI    =   32734
OBM_RGARROWI    =   32735
OBM_DNARROWI    =   32736
OBM_UPARROWI    =   32737
OBM_COMBO       =   32738
OBM_MNARROW     =   32739
OBM_LFARROWD    =   32740
OBM_RGARROWD    =   32741
OBM_DNARROWD    =   32742
OBM_UPARROWD    =   32743
OBM_RESTORED    =   32744
OBM_ZOOMD       =   32745
OBM_REDUCED     =   32746
OBM_RESTORE     =   32747
OBM_ZOOM        =   32748
OBM_REDUCE      =   32749
OBM_LFARROW     =   32750
OBM_RGARROW     =   32751
OBM_DNARROW     =   32752
OBM_UPARROW     =   32753
OBM_CLOSE       =   32754

OBM_OLD_RESTORE =   32755
OBM_OLD_ZOOM    =   32756
OBM_OLD_REDUCE  =   32757
OBM_BTNCORNERS  =   32758
OBM_CHECKBOXES  =   32759
OBM_CHECK       =   32760
OBM_BTSIZE      =   32761
OBM_OLD_LFARROW =   32762
OBM_OLD_RGARROW =   32763
OBM_OLD_DNARROW =   32764
OBM_OLD_UPARROW =   32765
OBM_SIZE        =   32766
OBM_OLD_CLOSE   =   32767
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/equates/Win32/_WSOCK32.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: WSOCK32.DLL structures and constants
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


struct WSADATA
  .wVersion       dw ?
  .wHighVersion   dw ?
  .szDescription  rb 256+1
  .szSystemStatus rb 128+1
  .iMaxSockets    dw ?
  .iMaxUdpDg      dw ?
  .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   rb 8
ends

struct sockaddr
   .sa_family dw ?
   .sa_data rb 14
ends

; Socket error

SOCKET_ERROR = -1
INVALID_SOCKET = -1


; 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

; commands for ioctlsocket

FIONBIO         = 8004667Eh
FIONSYNC        = 8004667Dh
FIONREAD        = 4004667Fh


; flags

MSG_OOB       = 1
MSG_PEEK      = 2
MSG_DONTROUTE = 4
MSG_MAXIOVLEN = 16
MSG_PARTIAL   = 0x8000

; options

SOL_SOCKET = $FFFF

SO_DEBUG       =   1
SO_ACCEPTCONN  =   2
SO_REUSEADDR   =   4
SO_KEEPALIVE   =   8
SO_DONTROUTE   =  16
SO_BROADCAST   =  32
SO_USELOOPBACK =  64
SO_LINGER      = 128
SO_OOBINLINE   = 256
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































Deleted freshlib/equates/Win32/_exceptions.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Exception handling constants and structures.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


EXCEPTION_MAXIMUM_PARAMETERS = 15

DBG_CONTINUE                         = 00010002h
DBG_TERMINATE_THREAD                 = 40010003h
DBG_TERMINATE_PROCESS                = 40010004h
DBG_CONTROL_C                        = 40010005h
DBG_CONTROL_BREAK                    = 40010008h
DBG_EXCEPTION_NOT_HANDLED            = 80010001h

EXCEPTION_DEBUG_EVENT                = 1
CREATE_THREAD_DEBUG_EVENT            = 2
CREATE_PROCESS_DEBUG_EVENT           = 3
EXIT_THREAD_DEBUG_EVENT              = 4
EXIT_PROCESS_DEBUG_EVENT             = 5
LOAD_DLL_DEBUG_EVENT                 = 6
UNLOAD_DLL_DEBUG_EVENT               = 7
OUTPUT_DEBUG_STRING_EVENT            = 8
RIP_EVENT                            = 9

CONTEXT_i386 = 00010000h
CONTEXT_i486 = 00010000h
CONTEXT_CONTROL = CONTEXT_i386 OR 00000001h
CONTEXT_INTEGER = CONTEXT_i386 OR 00000002h
CONTEXT_SEGMENTS = CONTEXT_i386 OR 00000004h
CONTEXT_FLOATING_POINT = CONTEXT_i386 OR 00000008h
CONTEXT_DEBUG_REGISTERS = CONTEXT_i386 OR 00000010h
CONTEXT_FULL = CONTEXT_CONTROL OR CONTEXT_INTEGER OR CONTEXT_SEGMENTS



struct EXCEPTION_RECORD
  .ExceptionCode      dd ?
  .ExceptionFlags     dd ?
  .ptrExceptionRecord dd ?
  .ExceptionAddress   dd ?
  .NumberParameters   dd ?
  .ExceptionInformation rd EXCEPTION_MAXIMUM_PARAMETERS
ends

struct EXCEPTION_DEBUG_INFO
  .ExceptionRecord EXCEPTION_RECORD
  .dwFirstChance dd ?
ends

struct CREATE_THREAD_DEBUG_INFO
  .hThread               dd  ?
  .lpThreadLocalBase     dd  ?
  .lpStartAddress        dd  ?
ends

struct CREATE_PROCESS_DEBUG_INFO
  .hFile                 dd  ?
  .hProcess              dd  ?
  .hThread               dd  ?
  .lpBaseOfImage         dd  ?
  .dwDebugInfoFileOffset dd  ?
  .nDebugInfoSize        dd  ?
  .lpThreadLocalBase     dd  ?
  .lpStartAddress        dd  ?
  .lpImageName           dd  ?
  .fUnicode              dw  ?
ends


struct EXIT_THREAD_DEBUG_INFO
  .dwExitCode  dd      ?
ends

struct EXIT_PROCESS_DEBUG_INFO
  .dwExitCode  dd      ?
ends


struct LOAD_DLL_DEBUG_INFO
  .hFile                     dd   ?
  .lpBaseOfDll               dd   ?
  .dwDebugInfoFileOffset     dd   ?
  .nDebugInfoSize            dd   ?
  .lpImageName               dd   ?
  .fUnicode                  dw   ?
ends


struct UNLOAD_DLL_DEBUG_INFO
  .lpBaseOfDll  dd  ?
ends


struct OUTPUT_DEBUG_STRING_INFO
  .lpDebugStringData     dd    ?
  .fUnicode              dw    ?
  .nDebugStringiLength   dw    ?
ends


struct RIP_INFO
  .dwError  dd  ?
  .dwType   dd  ?
ends


SIZE_OF_80387_REGISTERS   = 80
MAXIMUM_SUPPORTED_EXTENSION = 512

struct FLOATING_SAVE_AREA
  .ControlWord   dd      ?
  .StatusWord    dd      ?
  .TagWord       dd      ?
  .ErrorOffset   dd      ?
  .ErrorSelector dd      ?
  .DataOffset    dd      ?
  .DataSelector  dd      ?
  .RegisterArea  rb SIZE_OF_80387_REGISTERS
  .Cr0NpxState   dd      ?
ends

struct CONTEXT
  .ContextFlags  dd      ?
  .iDr0          dd      ?
  .iDr1          dd      ?
  .iDr2          dd      ?
  .iDr3          dd      ?
  .iDr6          dd      ?
  .iDr7          dd      ?
  .FloatSave     FLOATING_SAVE_AREA
  .regGs         dd      ?
  .regFs         dd      ?
  .regEs         dd      ?
  .regDs         dd      ?
  .regEdi        dd      ?
  .regEsi        dd      ?
  .regEbx        dd      ?
  .regEdx        dd      ?
  .regEcx        dd      ?
  .regEax        dd      ?
  .regEbp        dd      ?
  .regEip        dd      ?
  .regCs         dd      ?
  .regFlag       dd      ?
  .regEsp        dd      ?
  .regSs         dd      ?
  .ExtendedRegisters rb MAXIMUM_SUPPORTED_EXTENSION
ends


struct SECURITY_ATTRIBUTES
  .nLength              dd ?
  .lpSecurityDescriptor dd ?
  .bInheritHandle       dd ?
ends





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































Deleted freshlib/equates/Win32/allequates.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Combined include of all Win32 equate files.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

include '_kernel32.inc'
include '_user32.inc'
include '_gdi32.inc'
include '_comctl32.inc'
include '_comdlg32.inc'
include '_shell32.inc'
include '_wsock32.inc'
include '_RichEdit32.inc'
include '_ODBC32.inc'
include '_HTMLHelp.inc'
include '_exceptions.inc'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































Deleted freshlib/equates/_sqlite3.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: SQLite equates definitions.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

; SQLite result codes

SQLITE_OK         =  0   ; Successful result
SQLITE_ERROR      =  1   ; SQL error or missing database
SQLITE_INTERNAL   =  2   ; An internal logic error in SQLite
SQLITE_PERM       =  3   ; Access permission denied
SQLITE_ABORT      =  4   ; Callback routine requested an abort
SQLITE_BUSY       =  5   ; The database file is locked
SQLITE_LOCKED     =  6   ; A table in the database is locked
SQLITE_NOMEM      =  7   ; A malloc() failed
SQLITE_READONLY   =  8   ; Attempt to write a readonly database
SQLITE_INTERRUPT  =  9   ; Operation terminated by sqlite_interrupt()
SQLITE_IOERR      = 10   ; Some kind of disk I/O error occurred
SQLITE_CORRUPT    = 11   ; The database disk image is malformed
SQLITE_NOTFOUND   = 12   ; (Internal Only) Table or record not found
SQLITE_FULL       = 13   ; Insertion failed because database is full
SQLITE_CANTOPEN   = 14   ; Unable to open the database file
SQLITE_PROTOCOL   = 15   ; Database lock protocol error
SQLITE_EMPTY      = 16   ; (Internal Only) Database table is empty
SQLITE_SCHEMA     = 17   ; The database schema changed
SQLITE_TOOBIG     = 18   ; Too much data for one row of a table
SQLITE_CONSTRAINT = 19   ; Abort due to constraint violation
SQLITE_MISMATCH   = 20   ; Data type mismatch
SQLITE_MISUSE     = 21   ; Library used incorrectly
SQLITE_NOLFS      = 22   ; Uses OS features not supported on host
SQLITE_AUTH       = 23   ; Authorization denied
SQLITE_ROW        = 100  ; sqlite_step() has another row ready
SQLITE_DONE       = 101  ; sqlite_step() has finished executing


SQLITE_CREATE_INDEX        =  1 ;   // Index Name      Table Name      */
SQLITE_CREATE_TABLE        =  2 ;   // Table Name      NULL            */
SQLITE_CREATE_TEMP_INDEX   =  3 ;   // Index Name      Table Name      */
SQLITE_CREATE_TEMP_TABLE   =  4 ;   // Table Name      NULL            */
SQLITE_CREATE_TEMP_TRIGGER =  5 ;   // Trigger Name    Table Name      */
SQLITE_CREATE_TEMP_VIEW    =  6 ;   // View Name       NULL            */
SQLITE_CREATE_TRIGGER      =  7 ;   // Trigger Name    Table Name      */
SQLITE_CREATE_VIEW         =  8 ;   // View Name       NULL            */
SQLITE_DELETE              =  9 ;   // Table Name      NULL            */
SQLITE_DROP_INDEX          = 10 ;   // Index Name      Table Name      */
SQLITE_DROP_TABLE          = 11 ;   // Table Name      NULL            */
SQLITE_DROP_TEMP_INDEX     = 12 ;   // Index Name      Table Name      */
SQLITE_DROP_TEMP_TABLE     = 13 ;   // Table Name      NULL            */
SQLITE_DROP_TEMP_TRIGGER   = 14 ;   // Trigger Name    Table Name      */
SQLITE_DROP_TEMP_VIEW      = 15 ;   // View Name       NULL            */
SQLITE_DROP_TRIGGER        = 16 ;   // Trigger Name    Table Name      */
SQLITE_DROP_VIEW           = 17 ;   // View Name       NULL            */
SQLITE_INSERT              = 18 ;   // Table Name      NULL            */
SQLITE_PRAGMA              = 19 ;   // Pragma Name     1st arg or NULL */
SQLITE_READ                = 20 ;   // Table Name      Column Name     */
SQLITE_SELECT              = 21 ;   // NULL            NULL            */
SQLITE_TRANSACTION         = 22 ;   // NULL            NULL            */
SQLITE_UPDATE              = 23 ;   // Table Name      Column Name     */
SQLITE_ATTACH              = 24 ;   // Filename        NULL            */
SQLITE_DETACH              = 25 ;   // Database Name   NULL            */

SQLITE_DENY   = 1       ;   // Abort the SQL statement with an error */
SQLITE_IGNORE = 2       ;   // Don't allow access, but don't generate an error */


; These are the allowed values for the eTextRep argument to
; sqliteCreateCollation and sqliteCreateFunction.

SQLITE_UTF8       = 1
SQLITE_UTF16LE    = 2
SQLITE_UTF16BE    = 3
SQLITE_UTF16      = 4   ;   Use native byte order
SQLITE_ANY        = 5

; values returned by sqliteColumnType
SQLITE_INTEGER    = 1
SQLITE_FLOAT      = 2
SQLITE_TEXT       = 3
SQLITE_BLOB       = 4
SQLITE_NULL       = 5


SQLITE_STATIC     = 0
SQLITE_TRANSIENT  = -1
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































Deleted freshlib/equates/_zlib1.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Constants and structures definitions for ZLIB library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

; zlib.h -- interface of the 'zlib' general purpose compression library
;  version 1.2.3, July 18th, 2005
;
;  Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
;
;  This software is provided 'as-is', without any express or implied
;  warranty.  In no event will the authors be held liable for any damages
;  arising from the use of this software.
;
;  Permission is granted to anyone to use this software for any purpose,
;  including commercial applications, and to alter it and redistribute it
;  freely, subject to the following restrictions:
;
;  1. The origin of this software must not be misrepresented; you must not
;     claim that you wrote the original software. If you use this software
;     in a product, an acknowledgment in the product documentation would be
;     appreciated but is not required.
;  2. Altered source versions must be plainly marked as such, and must not be
;     misrepresented as being the original software.
;  3. This notice may not be removed or altered from any source distribution.
;
;  Jean-loup Gailly        Mark Adler
;  jloup@gzip.org          madler@alumni.caltech.edu
;
;
;  The data format used by the zlib library is described by RFCs (Request for
;  Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
;  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
;


; zconf.h -- configuration of the zlib compression library
; Copyright (C) 1995-2005 Jean-loup Gailly.
; For conditions of distribution and use, see copyright notice in zlib.h
;

MAX_MEM_LEVEL = 9
MAX_WBITS     = 15 ; 32K LZ77 window

ZLIB_VERSION equ "1.2.3"
ZLIB_VERNUM = $1230


struct z_stream

    ptrNextIn   dd      ?    ;  next input byte
    AvailIn     dd      ?    ;  number of bytes available at next_in
    TotalIn     dd  ?    ;  total nb of input bytes read so far

    ptrNextOut  dd  ?    ;  next output byte should be put there
    AvailOut    dd  ?    ;  remaining free space at next_out
    TotalOut    dd  ?    ;  total nb of bytes output so far

    ptrMsg      dd  ?    ;  last error message, NULL if no error

    ptrState    dd  ?    ;  not visible by applications

    zalloc      dd  ?    ;  used to allocate the internal state
    zfree       dd  ?    ;  used to free the internal state
    opaque      dd  ?    ;  private data object passed to zalloc and zfree

    data_type   dd  ?    ;  best guess about the data type: binary or text
    adler       dd  ?    ;  adler32 value of the uncompressed data
    reserved    dd  ?    ;  reserved for future use
ends


; constants

; Allowed flush values; see deflate() and inflate() below for details
Z_NO_FLUSH      =       0
Z_PARTIAL_FLUSH =       1       ; will be removed, use Z_SYNC_FLUSH instead
Z_SYNC_FLUSH    =       2
Z_FULL_FLUSH    =       3
Z_FINISH        =       4
Z_BLOCK         =       5

; Return codes for the compression/decompression functions. Negative
; values are errors, positive values are used for special but normal events.

Z_OK            =       0
Z_STREAM_END    =       1
Z_NEED_DICT     =       2
Z_ERRNO         =       -1
Z_STREAM_ERROR  =       -2
Z_DATA_ERROR    =       -3
Z_MEM_ERROR     =       -4
Z_BUF_ERROR     =       -5
Z_VERSION_ERROR =       -6

; compression levels
Z_NO_COMPRESSION        =       0
Z_BEST_SPEED            =       1
Z_BEST_COMPRESSION      =       9
Z_DEFAULT_COMPRESSION   =       -1

; compression strategy; see deflateInit2() below for details */

Z_FILTERED              =       1
Z_HUFFMAN_ONLY          =       2
Z_RLE                   =       3
Z_FIXED                 =       4
Z_DEFAULT_STRATEGY      =       0


; Possible values of the data_type field (though see inflate()) */

Z_BINARY        =       0
Z_TEXT          =       1
Z_ASCII         =       Z_TEXT   ; for compatibility with 1.2.2 and earlier
Z_UNKNOWN       =       2

; The deflate compression method (the only one supported in this version)
Z_DEFLATED      =       8

Z_NULL          =       0  ; for initializing zalloc, zfree, opaque

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































Deleted freshlib/equates/allequates.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Combined include of all equates.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

TRUE = 1
FALSE = 0

NULL = 0

include '%TargetOS%/allequates.inc'

include '_sqlite3.inc'
include '_zlib1.inc'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































Deleted freshlib/freshlib.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: FreshLib amalgamation include file for the library code.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

include 'simpledebug/debug.asm'

include 'system/all.asm'
include 'data/all.asm'

match =NEW, LIB_MODE {
  include 'graphics/all.asm'
  include 'gui/all.asm'

;  include 'FreshEdit/FreshEdit.asm'
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































Deleted freshlib/freshlib.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: FreshLib amalgamation include file for the non code definitions.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

LIB_MODE equ NEW

include 'macros/allmacros.inc'
include 'equates/allequates.inc'

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































Deleted freshlib/graphics/Linux/backbuffer.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Provides raster bitmap, to be used for double buffer painting.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________



proc CreateBackBuffer, .hwin, .width, .height
begin
        push    ebx ecx edx

        stdcall GetMem, sizeof.TBackBuffer
        mov     ebx, eax

        mov     ecx, [.width]
        mov     edx, [.height]

        xor     eax, eax
        inc     eax

        cmp     ecx, eax
        jge     @f
        mov     ecx, eax
@@:
        cmp     edx, eax
        jge     @f
        mov     edx, eax
@@:
        mov     [ebx+TBackBuffer.width], ecx
        mov     [ebx+TBackBuffer.height], edx

        cinvoke XCreatePixmap, [hApplicationDisplay], [.hwin], [ebx+TBackBuffer.width], [ebx+TBackBuffer.height], 24
        mov     [ebx+TBackBuffer.raster], eax
        mov     eax, ebx
        pop     edx ecx ebx
        return
endp




proc DestroyBackBuffer, .pBackBuffer
begin
        push    eax ecx edx
        mov     eax, [.pBackBuffer]
        push    eax
        cinvoke XFreePixmap, [hApplicationDisplay], [eax+TBackBuffer.raster]
        stdcall FreeMem ; from the stack
        pop     edx ecx eax
        return
endp






proc DrawBackBuffer, .context, .pBackBuffer, .x, .y
begin
        push    eax ecx edx
        mov     eax, [.pBackBuffer]
        mov     ecx, [.context]

        cinvoke XCopyArea, [hApplicationDisplay], [eax+TBackBuffer.raster], [ecx+TContext.raster], [ecx+TContext.handle], 0, 0, [eax+TBackBuffer.width], [eax+TBackBuffer.height], [.x], [.y]

        pop     edx ecx eax
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































Deleted freshlib/graphics/Linux/context.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Context is a object that represents drawing surface in FreshLib
;
;  Target OS: Linux
;
;  Dependencies: memory.asm
;
;  Notes:
;_________________________________________________________________________________________

uses libX11

cmClear       =       GXclear
cmAnd         =       GXand
cmAndReverse  =       GXandReverse
cmCopy        =       GXcopy
cmAndInverted =       GXandInverted
cmNoOp        =       GXnoop
cmXor         =       GXxor
cmOr          =       GXor
cmNor         =       GXnor
cmEquiv       =       GXequiv
cmInvert      =       GXinvert
cmXorReverse  =       GXorReverse
cmCopyInverted =      GXcopyInverted
cmOrInverted   =      GXorInverted
cmNand         =      GXnand
cmSet          =      GXset


image_pointer_context = 2

proc AllocateContext, .raster
begin
        push    ebx ecx edx

        stdcall GetMem, sizeof.TContext
        jc      .error
        mov     ebx, eax

        mov     eax, [.raster]
        mov     [ebx+TContext.raster], eax

        cinvoke XCreateGC, [hApplicationDisplay], [ebx+TContext.raster], 0, 0
        mov     [ebx+TContext.handle], eax
        mov     eax, ebx

.exit:
        pop     edx ecx ebx
        clc
        return

.error:
        DebugMsg 'Error allocating context.'
        xor     eax, eax
        pop     edx ecx ebx
        stc
        return
endp




proc ReleaseContext, .context
begin
        push    eax ebx ecx edx
        mov     ebx, [.context]
        cinvoke XFlush, [hApplicationDisplay]
        cinvoke XFreeGC, [hApplicationDisplay], [ebx+TContext.handle]
        cmp     [ebx+TContext.clipregion], 0
        je      @f
        cinvoke XDestroyRegion, [ebx+TContext.clipregion]
@@:
        stdcall FreeMem, ebx

        clc
        pop     edx ecx ebx eax
        return
endp



proc SetLineStyle, .context, .pLineStyle
.color dd ?
begin
        push    eax ebx ecx edx esi

        mov     ebx, [.context]
        mov     esi, [.pLineStyle]

        mov     eax, [esi+TLineStyle.flags]
        mov     ecx, eax
        shr     ecx, 8
        and     eax, $ff        ; cap_style
        and     ecx, $ff        ; join_style

        mov     edx, LineSolid
        cmp     [esi+TLineStyle.DashCount], 0
        je      @f
        mov     edx, LineDoubleDash
@@:
        cinvoke XSetLineAttributes, [hApplicationDisplay], [ebx+TContext.handle], [esi+TLineStyle.width], edx, eax, ecx
        cinvoke XSetForeground,     [hApplicationDisplay], [ebx+TContext.handle], [esi+TLineStyle.color]

        cmp     [esi+TLineStyle.DashCount], 0
        je      .exit

        lea     ecx, [esi+TLineStyle.DashItems]
        cinvoke XSetDashes, [hApplicationDisplay], [ebx+TContext.handle], 0, ecx, [esi+TLineStyle.DashCount]
        cinvoke XSetBackground, [hApplicationDisplay], [ebx+TContext.handle], [esi+TLineStyle.clSpace]

.exit:
        pop     esi edx ecx ebx eax
        return
endp


proc  SetDrawMode, .context, .mode
begin
        push    eax ecx edx
        mov     eax, [.context]
        cinvoke XSetFunction, [hApplicationDisplay], [eax+TContext.handle], [.mode]
        pop     edx ecx eax
        return
endp





proc SetClipRectangle, .context, .pBounds
.rect XRectangle
begin
        push    eax ecx edx esi

        mov     esi, [.context]

        cmp     [esi+TContext.clipregion], 0
        je      @f
        cinvoke XDestroyRegion, [esi+TContext.clipregion]
@@:
        cinvoke XCreateRegion
        mov     [esi+TContext.clipregion], eax

        mov     edx, [.pBounds]
        test    edx, edx
        jz      .remove

        mov     eax, [edx+TBounds.x]
        mov     [.rect.x], ax

        mov     eax, [edx+TBounds.y]
        mov     [.rect.y], ax

        mov     eax, [edx+TBounds.width]
        mov     [.rect.width], ax

        mov     eax, [edx+TBounds.height]
        mov     [.rect.height], ax

        lea     edx, [.rect]
        cinvoke XUnionRectWithRegion, edx, [esi+TContext.clipregion], [esi+TContext.clipregion]
        cinvoke XSetRegion, [hApplicationDisplay], [esi+TContext.handle], [esi+TContext.clipregion]

.exit:
        pop     esi edx ecx eax
        return

.remove:
        cinvoke XSetClipMask, [hApplicationDisplay], [esi+TContext.handle], None
        jmp     .exit
endp




proc IsDrawable, .raster
begin

;       cinvoke  XSetErrorHandler,





endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































Deleted freshlib/graphics/Linux/draw.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Draw library contains procedures for drawing oprtations.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

lsEndCapRound = CapRound
lsEndCapSquare = CapButt
lsEndCapFlat   = CapProjecting

lsJoinRound = JoinRound shl 8
lsJoinBevel = JoinBevel shl 8
lsJoinMiter = JoinMiter shl 8



proc DrawLine, .context, .x1, .y1, .x2, .y2
begin
        push    eax ebx ecx edx

        mov     ebx, [.context]
        cinvoke XDrawLine, [hApplicationDisplay], [ebx+TContext.raster], [ebx+TContext.handle], [.x1], [.y1], [.x2], [.y2]
        pop     edx ecx ebx eax
        return
endp


proc DrawFillRect, .context, .x, .y, .width, .height, .color
begin
        push    eax ebx ecx edx
        mov     ebx, [.context]
        cinvoke XSetForeground, [hApplicationDisplay], [ebx+TContext.handle], [.color]
        cinvoke XFillRectangle, [hApplicationDisplay], [ebx+TContext.raster], [ebx+TContext.handle], [.x], [.y], [.width], [.height]
        pop     edx ecx ebx eax
        return
endp



macro Outline [type, x, y] {
  common
local ..types, ..points, ..count
     dd  ..count
     dd  ..types
     dd  ..points
  common
    label ..types byte
  forward
     db type
  common
    label ..points dword
  forward
    dd  x
    dd  y
}



;proc Draw, .context, .pDrawPoints
;begin
;
;        return
;endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































Deleted freshlib/graphics/Linux/fonts.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Fonts managing library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


proc FontCreate, .fontname, .size, .weight, .flags
begin
        push    ebx ecx edx
        stdcall StrDup, [.fontname]
        mov     ebx, eax

        test    [.flags], ffMonospaced
        jz      @f
        stdcall StrCat, ebx, FontAttr.mono
@@:
        sub     [.size], 2
        cmp     [.size], 0
        jle     @f

        stdcall StrCat, ebx, FontAttr.size
        stdcall NumToStr, [.size], ntsDec or ntsUnsigned
        push    eax
        stdcall StrCat, ebx, eax
        stdcall StrDel ; from the stack
@@:
        cmp     [.weight], 0
        je      @f
        shr     [.weight], 2
        stdcall StrCat, ebx, FontAttr.weight
        stdcall NumToStr, [.weight], ntsDec or ntsUnsigned
        push    eax
        stdcall StrCat, ebx, eax
        stdcall StrDel ; from the stack

@@:
        test    [.flags], ffItalic
        jz      @f
        stdcall StrCat, ebx, FontAttr.italic
@@:

        stdcall StrPtr, ebx
        cinvoke XftFontOpenName, [hApplicationDisplay], 0, eax

        stdcall StrDel, ebx
        pop     edx ecx ebx
        return
endp


iglobal
  if used FontCreate
    label FontAttr byte
    .mono db ',Mono', 0
    .size db ':pixelsize=', 0
    .weight db ':weight=', 0
    .italic db ':slant=italic', 0
  end if
endg










macro XftPushArg field, type, value {
      push value
      push type
      push field
      add  ebx, 12
}

macro XftStartArguments {
      push 0
      mov  ebx, 4
}

XftFamily  text 'family'
XftStyle   text 'style'
XftSpacing text 'spacing'
XftSlant   text 'slant'
XftWeight  text 'weight'
XftWidth   text 'width'
XftPixelSize text 'pixelsize'
XftAntialias text 'antialias'
XftAutohint  text 'autohint'
XftHintStyle text 'hintstyle'
XftHinting   text 'hinting'
XftRGBA      text 'rgba'


proc FontCreate3, .fontname, .size, .weight, .flags
begin
        push    ebx ecx edx


        XftStartArguments

        cmp     [.fontname], 0
        je      @f
        stdcall StrPtr, [.fontname]
        XftPushArg XftFamily, XftTypeString, eax
@@:

        cmp     [.size], 2
        jle     @f
        sub     [.size], 2
        XftPushArg XftPixelSize, XftTypeInteger, [.size]
@@:

        cmp     [.weight], 0
        jle     @f
        shr     [.weight], 1
        XftPushArg XftWeight,    XftTypeInteger, [.weight]
@@:

        test    [.flags], ffItalic
        jz      @f
        XftPushArg XftSlant, XftTypeInteger, XFT_SLANT_ITALIC
@@:

        test    [.flags], ffMonospaced
        jz      @f
        XftPushArg XftSpacing, XftTypeInteger, XFT_MONO
@@:
        XftPushArg XftAntialias, XftTypeBool, 0
        XftPushArg XftHinting, XftTypeBool, 0
        XftPushArg XftHintStyle, XftTypeInteger, 0
        XftPushArg XftRGBA, XftTypeInteger, 5
        XftPushArg XftWidth, XftTypeInteger, 100

        invoke  XftFontOpen, [hApplicationDisplay], 0
        add     ebx, 8
        add     esp, ebx

        pop     edx ecx ebx
        return
endp




proc FontDestroy, .font
begin
        stdcall XftFontClose, [hApplicationDisplay], [.font]
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































Deleted freshlib/graphics/Linux/images.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Memory based images manipulation library.
;
;  Target OS: Linux
;
;  Dependencies: memory.asm
;
;  Notes:
;_________________________________________________________________________________________

; only 16, 24 and 32 bpp are supported.
; It is stupid to support palleted modes and even 24bpp is not good...
proc CreateImage, .width, .height, .bpp
.scanline dd ?
begin
        push    ebx ecx edx esi

        stdcall GetMem, sizeof.TImage
        jc      .finish

        mov     esi, eax

        cmp     [.width], 0
        jg     @f
        mov     [.width], 1
@@:
        cmp     [.height], 0
        jg     @f
        mov     [.height], 1
@@:

        push    [.width] [.height] [.bpp]
        pop     [esi+TImage.bpp] [esi+TImage.height] [esi+TImage.width]

; allocate image data

        mov     ecx, [.bpp]
        mov     eax, [.height]
        shr     ecx, 3
        imul    ecx, [.width]
        add     ecx, 3
        and     ecx, $fffffffc  ; align scanline to dword.
        mov     [.scanline], ecx
        imul    eax, ecx

        stdcall GetMem, eax
        jc      .error_free
        mov     [esi+TImage.pData], eax

; IMPORTANT!
; The depth - 3rd argument MUST be $18 - I tested it on 16bpp and 32bpp screen setting and it works.
; in all other settings XPutImage fails with segmentation fault or with BadMatch error.
; This procedure is tested only with 32bit images - [.bpp]=32.
; This issue needs some more research, but the documentation is pretty obscure and I am not so good in Linux programming.
        mov     eax, [.bpp]
        add     eax, $0f
        and     eax, $f0
        cinvoke XCreateImage, [hApplicationDisplay], 0, $18, ZPixmap, 0, [esi+TImage.pData], [.width], [.height], eax, [.scanline]
        mov     [esi+TImage.raster], eax

        clc
        mov     eax, esi
.finish:
        pop     esi edx ecx ebx
        return

.error_free:
        stdcall FreeMem, esi
        stc
        jmp     .finish
endp




proc DestroyImage, .ptrImage
begin
        push    eax ecx edx esi

        mov     esi, [.ptrImage]
        test    esi, esi
        jz      @f

        cinvoke XDestroyImage, [esi+TImage.raster]
        stdcall FreeMem, esi
@@:
        pop     esi edx ecx eax
        return
endp




proc DrawImage, .context, .pImage, .x, .y
begin
        push    eax ecx edx

        mov     eax, [.pImage]
        test    eax, eax
        jz      .exit

        mov     ecx, [.context]
        cinvoke XPutImage, [hApplicationDisplay], [ecx+TContext.raster], [ecx+TContext.handle], [eax+TImage.raster], 0, 0, [.x], [.y], [eax+TImage.width], [eax+TImage.height]
.exit:
        pop     edx ecx eax
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































Deleted freshlib/graphics/Linux/text.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Text drawing library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes: Uses XFT library to renter the text.
;_________________________________________________________________________________________

uses libXft

proc __ColorToRender, .color, .rendercolor
begin
        push    eax ecx edx

        mov     edx, [.rendercolor]

        xor     eax, eax
        xor     ecx, ecx

        mov     ah, byte [.color]
        mov     ch, byte [.color+1]

        mov     [edx+_XftColor.color.blue], ax
        mov     [edx+_XftColor.color.green], cx

        mov     ah, byte [.color+2]
        mov     ch, byte [.color+3]
        xor     ch, $ff
        mov     [edx+_XftColor.color.red], ax
        mov     [edx+_XftColor.color.alpha], cx

        pop     edx ecx eax
        return
endp



proc DrawString, .context, .ptrString, .len, .x, .y, .font, .color
  .cltxt   _XftColor
begin
        push    eax ebx ecx edx esi edi

        cmp     [.font], 0
        jne     @f

        mov     eax, [_SystemFont]
        mov     [.font], eax

@@:
        cinvoke XDefaultVisual, [hApplicationDisplay], 0
        mov     ecx, [.context]
        cinvoke XftDrawCreate, [hApplicationDisplay], [ecx+TContext.raster], eax, 0
        mov     ebx, eax

        mov     ecx, [.context]
        cinvoke XftDrawSetClip, ebx, [ecx+TContext.clipregion]

        lea     eax, [.cltxt]
        stdcall __ColorToRender, [.color], eax

        cinvoke XftDrawStringUtf8, ebx, eax, [.font], [.x], [.y], [.ptrString], [.len]
        cinvoke XftDrawDestroy, ebx

        pop     edi esi edx ecx ebx eax
        return
endp




proc DrawStringOpaque, .context, .ptrString, .len, .x, .y, .font, .color, .background
  .cltxt   _XftColor
begin
        push    eax ebx ecx edx esi edi

        cmp     [.font], 0
        jne     @f

        mov     eax, [_SystemFont]
        mov     [.font], eax

@@:
        cinvoke XDefaultVisual, [hApplicationDisplay], 0
        mov     ecx, [.context]
        cinvoke XftDrawCreate, [hApplicationDisplay], [ecx+TContext.raster], eax, 0
        mov     ebx, eax

        mov     ecx, [.context]
        cinvoke XftDrawSetClip, ebx, [ecx+TContext.clipregion]

        lea     eax, [.cltxt]
        stdcall __ColorToRender, [.color], eax

        cinvoke XftDrawStringUtf8, ebx, eax, [.font], [.x], [.y], [.ptrString], [.len]
        cinvoke XftDrawDestroy, ebx

        pop     edi esi edx ecx ebx eax
        return
endp



proc DrawColoredString, .context, .ptrString, .pCharAttr, .str_len_bytes, .x, .y, .char_offs, .fontwidth, .fontheight
.xbeg   dd ?
.cltxt  _XftColor
.char   dd ?
.height dd ?
.offs   dd ?
.skip   dd ?
begin
        push    eax ebx ecx edx esi edi

        mov     esi, [.pCharAttr]

        mov     eax, [.x]
        mov     [.xbeg], eax

        cinvoke XDefaultVisual, [hApplicationDisplay], 0
        mov     ecx, [.context]
        cinvoke XftDrawCreate, [hApplicationDisplay], [ecx+TContext.raster], eax, 0
        mov     ebx, eax

        mov     ecx, [.context]
        cinvoke XftDrawSetClip, ebx, [ecx+TContext.clipregion]

        lea     edi, [.cltxt]

        stdcall GetTextBounds, [.context], __HeightProbeString, __HeightProbeString.length, [esi+TCharAttr.font]
        mov     [.height], edx

        stdcall GetTextOffset, [.context], __HeightProbeString, __HeightProbeString.length, [esi+TCharAttr.font]
        mov     [.offs], edx

.skip_offset:
        mov     ecx, [.char_offs]
        mov     [.skip], ecx

.drawloop:
        cmp     [.str_len_bytes], 0
        jle     .enddraw

        mov     ecx, [.ptrString]
        stdcall DecodeUtf8, [ecx]
        mov     [.char], edx

        cmp     eax, $01        ; word wrap character
        je      .wrapline

        cmp     [.skip], 0
        jg      .drawok

;        mov     ecx, [.y]
;        sub     ecx, [.offs]
;        sub     ecx, 2
;        stdcall DrawFillRect, [.context], [.x], ecx, [.fontwidth], [.height], [esi+TCharAttr.backbround]

        stdcall __ColorToRender, [esi+TCharAttr.color], edi
        cinvoke XftDrawStringUtf8, ebx, edi, [esi+TCharAttr.font], [.x], [.y], [.ptrString], [.char]

        mov     eax, [.fontwidth]
        add     [.x], eax
;        sub     [.width], eax
;        js      .enddraw

.drawok:
        dec     [.skip]
        mov     eax, [.char]
        add     [.ptrString], eax
        sub     [.str_len_bytes], eax

        add     esi, sizeof.TCharAttr
        jne     .drawloop

.enddraw:
        cinvoke XftDrawDestroy, ebx
        pop     edi esi edx ecx ebx eax
        return

.wrapline:
        mov     eax, [.fontheight]
        add     [.y], eax
        mov     eax, [.xbeg]
        mov     [.x], eax

        mov     eax, [.char]
        add     [.ptrString], eax
        sub     [.str_len_bytes], eax

        add     esi, sizeof.TCharAttr
        jmp     .skip_offset

endp







; returns:
;       eax - width of the string in pixels.
;       edx - heigth of the string in pixels.


proc GetTextBounds, .context, .ptrString, .len, .font
.extents _XGlyphInfo
begin
        push    esi ecx

        cmp     [.font], 0
        jne     @f

        mov     eax, [_SystemFont]
        mov     [.font], eax

@@:
        lea     esi, [.extents]
        cinvoke   XftTextExtentsUtf8, [hApplicationDisplay], [.font], [.ptrString], [.len], esi

        movzx   eax, [esi+_XGlyphInfo.xOff]
        movzx   edx, [esi+_XGlyphInfo.height]
        add     edx, 2

        pop     ecx esi
        return
endp


; returns:
;       eax - x offset of the baseline of the string.
;       edx - y offset of the baseline of the string.

proc GetTextOffset, .context, .ptrString, .len, .font
.extents _XGlyphInfo
begin
        push    esi ecx

        cmp     [.font], 0
        jne     @f

        mov     eax, [_SystemFont]
        mov     [.font], eax

@@:
        lea     esi, [.extents]
        cinvoke   XftTextExtentsUtf8, [hApplicationDisplay], [.font], [.ptrString], [.len], esi

        movzx   eax, [esi+_XGlyphInfo.x]
        movzx   edx, [esi+_XGlyphInfo.y]
        add     edx, 2

        pop     ecx esi
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































Deleted freshlib/graphics/Win32/backbuffer.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Provides raster bitmap, to be used for double buffer painting.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________



proc CreateBackBuffer, .hwin, .width, .height
begin
        push    ebx ecx edx

        stdcall GetMem, sizeof.TBackBuffer
        mov     ebx, eax

        mov     ecx, [.width]
        mov     edx, [.height]

        test    ecx, ecx
        jns     @f
        xor     ecx, ecx
@@:
        test    edx, edx
        jns     @f
        xor     edx, edx
@@:
        mov     [ebx+TBackBuffer.width], ecx
        mov     [ebx+TBackBuffer.height], edx

        invoke  GetDC, [.hwin]
        push    eax
        invoke  CreateCompatibleBitmap, eax, [ebx+TBackBuffer.width], [ebx+TBackBuffer.height]
        mov     [ebx+TBackBuffer.raster], eax

        invoke  ReleaseDC, [.hwin] ; from the stack

        mov     eax, ebx
        pop     edx ecx ebx
        return
endp



proc DestroyBackBuffer, .pBackBuffer
begin
        push    eax ecx edx
        mov     eax, [.pBackBuffer]
        push    eax
        invoke  DeleteObject, [eax+TBackBuffer.raster]
        stdcall FreeMem ; from the stack
        pop     edx ecx eax
        return
endp



proc DrawBackBuffer, .context, .pBackBuffer, .x, .y
begin
        push    eax ecx edx esi edi
        mov     esi, [.pBackBuffer]

        stdcall AllocateContext, [esi+TBackBuffer.raster]
        jc      .exit
        mov     edi, eax

        mov     ecx, [.context]
        invoke  BitBlt, [ecx+TContext.handle], [.x], [.y], [esi+TBackBuffer.width], [esi+TBackBuffer.height], [edi+TContext.handle], 0, 0, SRCCOPY

        stdcall ReleaseContext, edi

.exit:
        pop     edi esi edx ecx eax
        return


endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































Deleted freshlib/graphics/Win32/context.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Context is a object that represents drawing surface in FreshLib
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

uses user32, gdi32

; Some of these constants are probably wrong!
cmClear       =     R2_BLACK
cmAnd         =     R2_MASKPEN
cmAndReverse  =     R2_NOTMASKPEN
cmCopy        =     R2_COPYPEN
cmAndInverted =     R2_MASKPENNOT
cmNoOp        =     R2_NOP
cmXor         =     R2_XORPEN
cmOr          =     R2_MERGEPEN
cmNor         =     R2_NOTMERGEPEN
cmEquiv       =     R2_NOTXORPEN
cmInvert      =     R2_NOT
cmXorReverse  =     R2_NOTXORPEN
cmCopyInverted =    R2_NOTCOPYPEN
cmOrInverted   =    R2_NOTMERGEPEN
cmNand         =    R2_NOTMASKPEN
cmSet          =    R2_WHITE


proc AllocateContext, .raster
begin
        push    ebx ecx edx

        stdcall GetMem, sizeof.TContext
        mov     ebx, eax

        push    [.raster]
        pop     [ebx+TContext.raster]

        invoke  IsWindow, [.raster]
        test    eax, eax
        jz      .not_window

        invoke  GetDC, [.raster]
        mov     [ebx+TContext.handle], eax
        test    eax, eax
        jz      .error

        invoke  SaveDC, [ebx+TContext.handle]

.exit_ok:
        clc
        mov     eax, ebx
        pop     edx ecx ebx
        return

.not_window:    ; then it must be handle to image bitmap...
        invoke  GetObjectType, [.raster]
        cmp     eax, OBJ_BITMAP
        jne     .error

        invoke  CreateCompatibleDC, 0
        mov     [ebx+TContext.handle], eax
        test    eax, eax
        jz      .error

        invoke  SaveDC, ebx
        invoke  SelectObject, [ebx+TContext.handle], [.raster]
        jmp     .exit_ok

.error:
        stc
        pop     edx ecx ebx
        return
endp




proc ReleaseContext, .context
begin
        push    eax ebx ecx edx

        mov     ebx, [.context]

; delete all selected objects...
        invoke  GetCurrentObject, [ebx+TContext.handle], OBJ_PEN
        push    eax
        invoke  GetCurrentObject, [ebx+TContext.handle], OBJ_BRUSH
        push    eax
        invoke  GetCurrentObject, [ebx+TContext.handle], OBJ_FONT
        push    eax

        invoke  RestoreDC, [ebx+TContext.handle], -1

        invoke  DeleteObject ; from the stack
        invoke  DeleteObject ; from the stack
        invoke  DeleteObject ; from the stack

        invoke  GetObjectType, [ebx+TContext.handle]
        cmp     eax, OBJ_MEMDC
        je      .delete

        cmp     eax, OBJ_DC
        je      .release

        stc
.exit:
        pop     edx ecx ebx eax
        return

.delete:
        invoke  DeleteDC, [ebx+TContext.handle]
        jmp     .free

.release:
        invoke  ReleaseDC, [ebx+TContext.raster] , [ebx+TContext.handle]

.free:
        stdcall FreeMem, ebx
        clc
        jmp     .exit
endp



proc  SetDrawMode, .context, .mode
begin
        push    eax ebx ecx edx
        mov     ebx, [.context]
        test    ebx, ebx
        jz      .finish

        push    [.mode]
        pop     [ebx+TContext.drawmode]
        invoke  SetROP2, [ebx+TContext.handle], [.mode]

.finish:
        pop     edx ecx ebx eax
        return
endp




proc SetLineStyle, .context, .pLineStyle
begin
        push    eax ebx ecx edx esi

        mov     ebx, [.pLineStyle]
        mov     esi, [.context]

        mov     eax, [ebx+TLineStyle.color]
        bswap   eax                             ; FreshLib uses Linux type color - red in the MSB
        ror     eax, 8

        mov     edx, PS_SOLID
        cmp     [ebx+TLineStyle.DashCount], 0
        je      @f
        mov     edx, PS_DOT
        mov     [ebx+TLineStyle.width], 0
@@:
        invoke  CreatePen, edx, [ebx+TLineStyle.width], eax     ;[ebx+TLineStyle.color]
        invoke  SelectObject, [esi+TContext.handle], eax
        invoke  DeleteObject, eax

        cmp     [ebx+TLineStyle.DashCount], 0
        je      .exit

        mov     eax, [ebx+TLineStyle.clSpace]
        bswap   eax                             ; FreshLib uses Linux type color - red in the MSB
        ror     eax, 8

        invoke  SetBkColor, [esi+TContext.handle], eax
        invoke  SetBkMode, [esi+TContext.handle], OPAQUE


.exit:
        pop     esi edx ecx ebx eax
        return
endp






proc SetClipRectangle, .context, .pBounds
begin
        push    eax ebx ecx edx

        xor     ebx, ebx
        mov     edx, [.pBounds]
        test    edx, edx
        jz      .setit

        mov     eax, [edx+TBounds.width]
        mov     ecx, [edx+TBounds.height]
        add     eax, [edx+TBounds.x]
        add     ecx, [edx+TBounds.y]
        invoke  CreateRectRgn, [edx+TBounds.x], [edx+TBounds.y], eax, ecx
        mov     ebx, eax

.setit:
        mov     edx, [.context]
        invoke  SelectClipRgn, [edx+TContext.handle], ebx

        test    ebx, ebx
        jz      .exit
        invoke  DeleteObject, ebx
.exit:
        pop     edx ecx ebx eax
        return
endp




;proc SetLineStyle, .context, .pLineStyle
;.brush LOGBRUSH
;.width dd ?
;.dashcount dd ?
;.dashes rd 16
;begin
;        push    eax ebx ecx edx esi
;
;        mov     ebx, [.pLineStyle]
;        mov     esi, [.context]
;
;        mov     ecx, [ebx+TLineStyle.DashCount]
;        cmp     ecx, 16
;        jbe     @f
;        mov     ecx, 16
;@@:
;        mov     [.dashcount], ecx
;
;.dashloop:
;        dec     ecx
;        js      .enddash
;        movzx   eax, byte [ebx+TLineStyle.DashItems+ecx]
;        mov     [.dashes+4*ecx], eax
;        jmp     .dashloop
;
;.enddash:
;        push    [ebx+TLineStyle.width]
;        pop     [.width]
;
;        mov     [.brush.lbStyle], BS_SOLID
;        mov     eax, [ebx+TLineStyle.color]
;        bswap   eax                             ; FreshLib uses Linux type color - red in the MSB
;        ror     eax, 8
;
;        mov     [.brush.lbColor], eax
;
;        mov     edx, PS_SOLID
;        xor     ecx, ecx
;        cmp     [.dashcount], 0
;        je      @f
;        mov     edx, PS_USERSTYLE
;        lea     ecx, [.dashes]
;@@:
;
;        or      edx, PS_GEOMETRIC
;        cmp     [.width], 0
;        jne     @f
;        and     edx, not PS_GEOMETRIC
;        inc     [.width]
;@@:
;        or      edx, [ebx+TLineStyle.flags]
;        lea     eax, [.brush]
;
;        invoke  ExtCreatePen, edx, [.width], eax, [.dashcount], ecx
;        invoke  SelectObject, [esi+TContext.handle], eax
;
;
;        invoke  SetBkMode, [esi+TContext.handle], OPAQUE
;
;        mov     eax, [ebx+TLineStyle.color]
;        cmp     [ebx+TLineStyle.DashCount], 0
;        je      @f
;        mov     eax, [ebx+TLineStyle.clSpace]
;@@:
;        bswap   eax                             ; FreshLib uses Linux type color - red in the MSB
;        ror     eax, 8
;
;        invoke  SetBkColor, [esi+TContext.handle], eax
;
;        pop     esi edx ecx ebx eax
;        return
;endp
;


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































Deleted freshlib/graphics/Win32/draw.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Draw library contains procedures for drawing oprtations.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

lsEndCapRound = PS_ENDCAP_ROUND
lsEndCapSquare = PS_ENDCAP_SQUARE
lsEndCapFlat   = PS_ENDCAP_FLAT

lsJoinRound = PS_JOIN_ROUND
lsJoinBevel = PS_JOIN_BEVEL
lsJoinMiter = PS_JOIN_MITER



proc DrawLine, .context, .x1, .y1, .x2, .y2
begin
        push    eax ebx ecx edx
        mov     ebx, [.context]

        invoke  MoveToEx, [ebx+TContext.handle], [.x1], [.y1], 0
        invoke  LineTo, [ebx+TContext.handle], [.x2], [.y2]

        pop     edx ecx ebx eax
        return
endp




proc DrawFillRect, .context, .x, .y, .width, .height, .color
begin
        push    eax ebx ecx edx esi

        mov     ebx, [.context]

        mov     eax, [.color]
        bswap   eax
        ror     eax, 8
        mov     esi, eax
        invoke  CreateSolidBrush, esi
        invoke  SelectObject, [ebx+TContext.handle], eax
        push    eax

        invoke  CreatePen, PS_SOLID, 0, esi
        invoke  SelectObject, [ebx+TContext.handle], eax
        push    eax

        mov     eax, [.x]
        mov     ecx, [.y]
        add     eax, [.width]
        add     ecx, [.height]

        cmp     [.width], 1
        je      .line1
        cmp     [.height], 1
        jne     .rect

        dec     ecx
        jmp     .line

.line1:
        dec     eax
.line:
        invoke  MoveToEx, [ebx+TContext.handle], eax, ecx, 0
        invoke  LineTo, [ebx+TContext.handle], [.x], [.y]
        inc     [.x]
        invoke  LineTo, [ebx+TContext.handle],[.x], [.y]
        jmp     .free

.rect:
        invoke  Rectangle, [ebx+TContext.handle], [.x], [.y], eax, ecx

;        lea     ecx, [.x]
;        invoke  FillRect, [ebx+TContext.handle], ecx, eax
.free:
        invoke  SelectObject, [ebx+TContext.handle] ; from the stack.
        invoke  DeleteObject, eax
        invoke  SelectObject, [ebx+TContext.handle] ; from the stack.
        invoke  DeleteObject, eax
        pop     esi edx ecx ebx eax
        return
endp





macro Outline [type, x, y] {
  common
local ..types, ..points, ..count
     dd  ..count
     dd  ..types
     dd  ..points
  common
    label ..types byte
  forward
     db type
  common
    label ..points dword
  forward
    dd  x
    dd  y
}




proc Draw, .raster, .pDrawPoints
begin

        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































Deleted freshlib/graphics/Win32/fonts.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Fonts managing library.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


proc FontCreate, .fontface, .size, .weight, .flags
.pwc dd ?
begin
        push    ebx ecx edx esi edi

        neg     [.size]

        stdcall StrLen, [.fontface]
        mov     ebx, eax

        stdcall StrPtr, [.fontface]
        mov     [.fontface], eax

        lea     ecx, [8*ebx]
        stdcall GetMem, ecx
        mov     edi, eax

        invoke  MultiByteToWideChar, CP_UTF8, 0, [.fontface], ebx, edi, ecx

        mov     eax, [.flags]
        mov     ebx, eax
        mov     ecx, eax
        mov     edx, eax
        and     ebx, ffItalic
        and     ecx, ffUnderline
        and     edx, ffStrikeOut
        and     eax, ffMonospaced
        jz      @f
        mov     eax, FIXED_PITCH
@@:
        invoke  CreateFontW, [.size], 0, 0, 0, [.weight], ebx, ecx, edx,         \
                                    DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,        \
                                    CLIP_DEFAULT_PRECIS, PROOF_QUALITY, eax,  \
                                    edi

        stdcall FreeMem, edi
        pop     edi esi edx ecx ebx
        return
endp


proc FontDestroy, .font
begin
        push    eax ecx edx
        invoke  DeleteObject, [.font]
        pop     edx ecx eax
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































Deleted freshlib/graphics/Win32/images.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Memory based images manipulation library.
;
;  Target OS: Win32
;
;  Dependencies: memory.asm
;
;  Notes:
;_________________________________________________________________________________________


; only 16, 24 and 32 bpp are supported.
; It is stupid to support palleted modes and even 24bpp is not good...
proc CreateImage, .width, .height, .bpp
.bmi BITMAPINFOHEADER
begin
        push    ebx ecx edx esi

        stdcall GetMem, sizeof.TImage
        jc      .finish

        mov     esi, eax

        cmp     [.width], 0
        jge     @f
        mov     [.width], 0
@@:
        cmp     [.height], 0
        jge     @f
        mov     [.height], 0
@@:
        push    [.width] [.height] [.bpp]
        pop     [esi+TImage.bpp] [esi+TImage.height] [esi+TImage.width]

        lea     eax, [.bmi]
        mov     [eax+BITMAPINFOHEADER.biSize], sizeof.BITMAPINFOHEADER
        mov     [eax+BITMAPINFOHEADER.biPlanes], 1
        mov     [eax+BITMAPINFOHEADER.biCompression], BI_RGB
        mov     [eax+BITMAPINFOHEADER.biSizeImage], 0
        mov     [eax+BITMAPINFOHEADER.biXPelsPerMeter], 96      ; ???
        mov     [eax+BITMAPINFOHEADER.biYPelsPerMeter], 96      ; ???
        mov     [eax+BITMAPINFOHEADER.biClrUsed], 0
        mov     [eax+BITMAPINFOHEADER.biClrImportant], 0

        mov     ecx, [.bpp]
        mov     [eax+BITMAPINFOHEADER.biBitCount], cx
        push    [.width] [.height]
        neg     dword [esp]
        pop     [eax+BITMAPINFOHEADER.biHeight] [eax+BITMAPINFOHEADER.biWidth]

        lea     ecx, [esi+TImage.pData]
        invoke  CreateDIBSection, 0, eax, DIB_RGB_COLORS, ecx, 0, 0
        mov     [esi+TImage.raster], eax

        clc
        mov     eax, esi

.finish:
        pop     esi edx ecx ebx
        return
endp


proc DestroyImage, .ptrImage
begin
        push    eax ecx edx esi

        mov     esi, [.ptrImage]
        cmp     esi, 0
        je      @f
        invoke  DeleteObject, [esi+TImage.raster]
        stdcall FreeMem, esi
@@:
        pop     esi edx ecx eax
        return
endp




proc DrawImage, .context, .pImage, .x, .y
begin
        push    eax ecx edx esi edi
        mov     esi, [.pImage]
        test    esi, esi
        jz      .exit

        stdcall AllocateContext, [esi+TImage.raster]
        jc      .exit
        mov     edi, eax

        mov     ecx, [.context]
        mov     eax, [ecx+TContext.drawmode]
        dec     eax
        and     eax, $0f
        invoke  BitBlt, [ecx+TContext.handle], [.x], [.y], [esi+TImage.width], [esi+TImage.height], [edi+TContext.handle], 0, 0, [4*eax+__RopTable]

        stdcall ReleaseContext, edi

.exit:
        pop     edi esi edx ecx eax
        return
endp

; NEEDS some edit to fill the zeroes.

if used __RopTable
__RopTable dd  BLACKNESS, PATPAINT,    0,          NOTSRCCOPY, \
               0,         DSTINVERT,   SRCINVERT,  SRCERASE,   \
               SRCAND,    0,           0,          0,          \
               SRCCOPY,   MERGEPAINT,  SRCPAINT,   WHITENESS
end if


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































Deleted freshlib/graphics/Win32/text.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Text drawing library.
;
;  Target OS: Win32
;
;  Dependencies: memory.asm
;
;  Notes:
;_________________________________________________________________________________________



proc DrawString, .context, .ptrString, .len, .x, .y, .font, .color
.pwc dd ?
.pwl dd ?
.buffer  rb 256
.charlen dd ?
begin
        push    eax ebx ecx edx

; first convert the string:
        lea     eax, [.buffer]
        mov     ecx, [.len]
        shl     ecx, 3
        cmp     ecx, $100
        jbe     @f

        stdcall GetMem, ecx

@@:
        mov     [.pwl], ecx
        mov     [.pwc], eax

        invoke  MultiByteToWideChar, CP_UTF8, 0, [.ptrString], [.len], [.pwc], ecx
        mov     [.charlen], eax

        mov     ebx, [.context]

        cmp     [.font], 0
        jne     @f

        invoke  GetStockObject, DEFAULT_GUI_FONT
        mov     [.font], eax

@@:
        invoke  SelectObject, [ebx+TContext.handle], [.font]
        push    eax

        invoke  SetBkMode, [ebx+TContext.handle], TRANSPARENT
        invoke  SetTextAlign, [ebx+TContext.handle], TA_NOUPDATECP or TA_LEFT or TA_BASELINE

        mov     eax, [.color]
        bswap   eax
        ror     eax, 8
        invoke  SetTextColor, [ebx+TContext.handle], eax
        invoke  TextOutW, [ebx+TContext.handle], [.x], [.y], [.pwc], [.charlen]

        invoke  SelectObject, [ebx+TContext.handle] ; old font from the stack.

        cmp     [.pwl], $100
        jbe     @f
        stdcall FreeMem, [.pwc]
@@:
        pop     edx ecx ebx eax
        return
endp



proc DrawStringOpaque, .context, .ptrString, .len, .x, .y, .font, .color, .background
.pwc dd ?
.pwl dd ?
.buffer  rb 256
.charlen dd ?
begin
        push    eax ebx ecx edx

; first convert the string:
        lea     eax, [.buffer]
        mov     ecx, [.len]
        shl     ecx, 2
        cmp     ecx, $100
        jbe     @f

        stdcall GetMem, ecx

@@:
        mov     [.pwl], ecx
        mov     [.pwc], eax

        invoke  MultiByteToWideChar, CP_UTF8, 0, [.ptrString], [.len], [.pwc], ecx
        mov     [.charlen], eax

        mov     ebx, [.context]

        cmp     [.font], 0
        jne     @f

        invoke  GetStockObject, DEFAULT_GUI_FONT
        mov     [.font], eax

@@:
        invoke  SelectObject, [ebx+TContext.handle], [.font]
        push    eax

        invoke  SetBkMode, [ebx+TContext.handle], OPAQUE
        mov     eax, [.background]
        bswap   eax
        ror     eax, 8
        invoke  SetBkColor, [ebx+TContext.handle], eax
        invoke  SetTextAlign, [ebx+TContext.handle], TA_NOUPDATECP or TA_LEFT or TA_BASELINE

        mov     eax, [.color]
        bswap   eax
        ror     eax, 8
        invoke  SetTextColor, [ebx+TContext.handle], eax
        invoke  TextOut, [ebx+TContext.handle], [.x], [.y], [.pwc], [.charlen]

        invoke  SelectObject, [ebx+TContext.handle] ; old font from the stack.

        cmp     [.pwl], $100
        jbe     @f
        stdcall FreeMem, [.pwc]
@@:
        pop     edx ecx ebx eax
        return
endp




proc DrawColoredString, .context, .ptrString, .pCharAttr, .str_len_bytes, .x, .y, .char_offs, .fontwidth, .fontheight
.xbeg    dd ?
;.wbeg    dd ?
.pwc     dd ?
.charlen dd ?
.point   POINT
begin
        push    eax ebx ecx edx esi edi

        mov     eax, [.x]
;        mov     ecx, [.width]
        mov     [.xbeg], eax
;        mov     [.wbeg], ecx

; first convert the string:
        mov     ecx, [.str_len_bytes]
        shl     ecx, 2
        stdcall GetMem, ecx
        mov     esi, eax
        mov     [.pwc], eax

        invoke  MultiByteToWideChar, CP_UTF8, 0, [.ptrString], [.str_len_bytes], esi, ecx
        mov     [.charlen], eax

        mov     ebx, [.context]
        mov     edi, [.pCharAttr]

        invoke  SaveDC, [ebx+TContext.handle]

        invoke  SetBkMode,    [ebx+TContext.handle], TRANSPARENT
        invoke  SetTextAlign, [ebx+TContext.handle], TA_LEFT or TA_BASELINE

.skip_offset:
        mov     ecx, [.char_offs]

.offsloop:
        jecxz   .loop

        lodsw
        add     edi, sizeof.TCharAttr
        dec     [.charlen]
        jz      .endline

        dec     ecx
        cmp     eax, $01
        jne     .offsloop

        mov     eax, [.fontheight]
        add     [.y], eax
        jmp     .skip_offset

.loop:
        cmp     word [esi], $01
        je      .wrapline

        mov     eax, [edi+TCharAttr.font]
        test    eax, eax
        jnz     @f

        invoke  GetStockObject, DEFAULT_GUI_FONT
@@:
        invoke  SelectObject, [ebx+TContext.handle], eax
        mov     eax, [edi+TCharAttr.background]
        bswap   eax
        ror     eax, 8
        invoke  SetBkColor, [ebx+TContext.handle], $ff0000

        mov     eax, [edi+TCharAttr.color]
        bswap   eax
        ror     eax, 8
        invoke  SetTextColor, [ebx+TContext.handle], eax

        invoke  TextOutW, [ebx+TContext.handle], [.x], [.y], esi, 1

        mov     eax, [.fontwidth]
        add     [.x], eax
;        sub     [.width], eax
;        jl      .endline

.nextchar:
        add     esi, 2
        add     edi, sizeof.TCharAttr
        dec     [.charlen]
        jnz     .loop

.endline:
        invoke  RestoreDC, [ebx+TContext.handle], -1
        stdcall FreeMem, [.pwc]
        pop     edi esi edx ecx ebx eax
        return

.wrapline:
        mov     eax, [.fontheight]
        add     [.y], eax
        mov     eax, [.xbeg]
;        mov     ecx, [.wbeg]
        mov     [.x], eax
;        mov     [.width], ecx

        add     esi, 2
        add     edi, sizeof.TCharAttr
        dec     [.charlen]
        jnz     .skip_offset
        jmp     .endline
endp






proc GetTextBounds, .context, .ptrString, .len, .font
.size SIZE
.pwc dd ?
.charlen dd ?
begin
        push    ebx ecx

; first convert the string:
        mov     ecx, [.len]
        shl     ecx, 3
        stdcall GetMem, ecx
        mov     [.pwc], eax
        invoke  MultiByteToWideChar, CP_UTF8, 0, [.ptrString], [.len], [.pwc], ecx
        mov     [.charlen], eax

        mov     ebx, [.context]

        cmp     [.font], 0
        jne     @f
        invoke  GetStockObject, DEFAULT_GUI_FONT
        mov     [.font], eax

@@:
        invoke  SelectObject, [ebx+TContext.handle], [.font]
        push    eax

        lea     eax, [.size]
        invoke  GetTextExtentPoint32W, [ebx+TContext.handle], [.pwc], [.charlen], eax
        invoke  SelectObject, [ebx+TContext.handle] ; from the stack.

        mov     eax, [.size.cx]
        mov     edx, [.size.cy]

        stdcall FreeMem, [.pwc]
        pop     ecx ebx
        return
endp


; returns:
;       eax - x offset of the baseline of the string.
;       edx - y offset of the baseline of the string.

proc GetTextOffset, .context, .ptrString, .len, .font
.metrics TEXTMETRIC
.pwc dd ?
.charlen dd ?
begin
        push    ebx ecx

; first convert the string:
        mov     ecx, [.len]
        shl     ecx, 3
        stdcall GetMem, ecx
        mov     [.pwc], eax
        invoke  MultiByteToWideChar, CP_UTF8, 0, [.ptrString], [.len], [.pwc], ecx
        mov     [.charlen], eax

        mov     ebx, [.context]

        cmp     [.font], 0
        jne     @f
        invoke  GetStockObject, DEFAULT_GUI_FONT
        mov     [.font], eax

@@:
        invoke  SelectObject, [ebx+TContext.handle], [.font]
        push    eax

        lea     eax, [.metrics]
        invoke  GetTextMetricsW, [ebx+TContext.handle], eax
        invoke  SelectObject, [ebx+TContext.handle] ; from the stack.

        xor     eax, eax
        mov     edx, [.metrics.tmAscent]
        sub     edx, [.metrics.tmInternalLeading]

        stdcall FreeMem, [.pwc]
        pop     ecx ebx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































Deleted freshlib/graphics/all.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Graphics amalgamation include file.
;               Includes all graphic libraries of FreshLib
;
;  Target OS: Any
;_________________________________________________________________________________________


include 'context.asm'
include 'images.asm'
include 'backbuffer.asm'
include 'draw.asm'
include 'giflib.asm'
include 'fonts.asm'
include 'text.asm'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































Deleted freshlib/graphics/backbuffer.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Provides raster bitmap, to be used for double buffer painting.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________
module "BackBuffer library"

; should be equal to the first 3 members of TImage in order to use the same draw procedure.

struct TBackBuffer
  .width  dd ?
  .height dd ?
  .raster dd ?
ends


include '%TargetOS%/backbuffer.asm'

endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































Deleted freshlib/graphics/context.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Context is a object that represents drawing surface in FreshLib
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: This file contains OS independent part and includes OS dependent files.
;_________________________________________________________________________________________
module "Graphic context library"

struct TBounds
  .x      dd ?
  .y      dd ?
  .width  dd ?
  .height dd ?
ends



struct TContext
  .raster     dd ?          ; handle to raster object (depends on TargetOS)
  .handle     dd ?          ; handle to context object (depends on TargetOS)
  .clipregion dd ?          ; clipping region.
  .drawmode   dd ?
ends


struct TDashListItem
  .dash  dd ?
  .space dd ?
ends


struct TLineStyle
  .width dd ?                   ; width of the line in pixels. Width 0 is 1px width. It have special meaning in Linux for example.
  .color dd ?                   ; color of the line in format (from LSB to MSB) bb, gg, rr, aa ; Use of alpha value is something not very clear for all implementations...
  .flags dd ?                   ; set of lsEndCapXXX; lsJoinXXX
  .clSpace dd ?                 ; space color.
  .DashCount dd ?               ; count of dash items in the dash list. For solid lines DashCount=0
  .DashItems:                   ; arbitrary count of TDashListItem
ends


; Creates static TLineStyle structure in design time.

struc LineStyle width*, color*, flags, spacecolor, [dash, space] {
common
local ..count, ..dashcount
  ..count = 0

common
  dd width
  dd color
  if flags eq
    dd lsEndCapRound or lsJoinRound
  else
    dd flags
  end if

  if spacecolor eq
    dd 0
  else
    dd spacecolor
  end if

  dd ..dashcount

forward
  if ~dash eq
    db dash, space
    ..count = ..count + 2
  end if

common
  ..dashcount = ..count
}



proc SetSimpleLine, .context, .color
.style TLineStyle
       rd 16
begin
        push    eax

        lea     eax, [.style]
        mov     [eax+TLineStyle.width], 0
        mov     [eax+TLineStyle.flags], 0
        mov     [eax+TLineStyle.DashCount], 0
        mov     [eax+TLineStyle.clSpace],0

        push    [.color]
        pop     [eax+TLineStyle.color]


        stdcall SetLineStyle, [.context], eax
        pop     eax
        return
endp



include '%TargetOS%/context.asm'

endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































Deleted freshlib/graphics/draw.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Draw library contains procedures for drawing oprtations.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: This file contains OS independent part and includes OS dependent files.
;_________________________________________________________________________________________
module "Draw library"


include "%TargetOS%/draw.asm"


proc DrawRectangle, .context, .pBounds, .color
begin
        push    eax ecx edx

        mov     edx, [.pBounds]

        mov     eax, [edx+TBounds.x]
        mov     ecx, [edx+TBounds.y]
        add     eax, [edx+TBounds.width]
        add     ecx, [edx+TBounds.height]
        dec     eax
        dec     ecx

        stdcall SetSimpleLine, [.context], [.color]
        stdcall DrawLine, [.context], [edx+TBounds.x], [edx+TBounds.y], eax, [edx+TBounds.y]
        stdcall DrawLine, [.context], eax, [edx+TBounds.y], eax, ecx
        stdcall DrawLine, [.context], [edx+TBounds.x], ecx, eax, ecx
        stdcall DrawLine, [.context], [edx+TBounds.x], [edx+TBounds.y], [edx+TBounds.x], ecx

        pop     edx ecx eax
        return
endp


endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































Deleted freshlib/graphics/fonts.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Fonts managing library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: This file contains OS independent part of the library and includes respective
;         OS dependent files.
;_________________________________________________________________________________________
module "Fonts library"

ffItalic    = 1
ffUnderline = 2
ffStrikeOut = 4

ffMonospaced = $80


include '%TargetOS%/fonts.asm'

endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































Deleted freshlib/graphics/giflib.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: GIF images decoding library.
;
;  Target OS: Any
;
;  Dependencies: memory.asm; files.asm
;
;  Notes:
;         Original source code by Exagone
;         http://exagone.cjb.net | http://www.exagone.org
;         _thomas_@mailroom.com
;_________________________________________________________________________________________
module "GIF library"

struct TGifInfo
;--- Header ---
  .GIFVersion       rb      3    ; 3 byte string (not 0-terminated) that identifies
                                 ; the GIF Version (like 97a or 98a)
; --- Logical screen descriptor ---
  .dwLSWidth        dd      ?    ; Logical screen width
  .dwLSHeight       dd      ?    ; Logical screen height
                                 ; NOTE: Use ImageWidth/Height to find the dimensions,
                                 ; This one can be different from the logical screen
                                 ; width and height.
; --- Color info ---
  .lpColorTable     dd      ?    ; Pointer to the color table
  .ColorCount       dd      ?    ; Number of colors in image (and color table)
  .fTransparent     dd      ?    ; if TRUE - the image have transparent color.
  .iTrasparentColor dd      ?    ; index of transparent color in the color table.

; --- Image info ---
  .dwImageWidth     dd      ?    ; Width of image
  .dwImageHeight    dd      ?    ; Height of image

; --- Image data ---
  .lpImageData      dd      ?    ; Pointer to the actual image data

; --- Input data ---
  .lpGIFData        dd      ?    ; Pointer to the GIF File data
  .dwGIFDataSize    dd      ?    ; Size of GIF Data

; --- Internal data ---
; Don't touch this data below, it is used internally by GIFLIB
  .lpLZWTable       dd      ?    ; Pointer to LZW Table
  .dwLZWTableSize   dd      ?    ; Current maximum size of table
                                 ; This size is dynamic and changes
                                 ; if the codesize exceeds 9 bits

  .dwLZWTableCount  dd      ?    ; Current nr of entries in the LZW table
  .fGlobalCTable    db      ?    ; If set, the GIF file has a global color table
  .dbGCTableSize    db      ?    ; Size of the global color table, if available
  .fLocalCTable     db      ?    ; If set, the first image has a local color table
  .dbLCTableSize    db      ?    ; Size of the local color table, if available
  .lpGIFImage       dd      ?    ; Pointer to the first real image data(Table based image data)
  .lpCurrentByte    dd      ?    ; Pointer to the current byte (used with decompression)
                                 ; note: if this value is -1, end of the file is reached and
                                 ; the code-supplier returns 0 as padding

  .dbBitsAvailable  db      ?    ; Nr of codebits currently available
  .dbCurBitSize     db      ?    ; Current LZW code size
  .dbInitBitSize    db      ?    ; Initial LZW code size
  .lpLastEOSB       dd      ?    ; Pointer to end of current subblock (used with decompression)
  .dwLZWClear       dd      ?    ; Value of LZW Clear code (CC)
  .CurrentBits      dd      ?    ; Holds the current bits loaded
  .IsFirstCode      db      ?    ; Indicates if the first code is being read now
  .PixelCounter     dd      ?    ; Counts nr of PIXELS outputted
ends


EXTENSIONBLOCK           =  021h
IMAGEDESCRIPTOR          =  02Ch
GRAPHICCONTROLEXTENSTION =  0F9h
COMMENTEXTENSION         =  0FEh
PLAINTEXTEXTENSION       =  001h
APPLICATIONEXTENSION     =  0FFh


; Creates TImage from the compressed GIF image.
; Arguments:
;   pGifImage - pointer to memory, where compressed image resides.
;   DataSize  - size of the image.
; Returns:
;   CF=1 if error;
;   CF=0 and eax=TImage if success.
proc    CreateImageGIF, .pGifImage, .DataSize   ;
.gifinfo TGifInfo
begin
        push    ecx edx esi edi

        lea     esi, [.gifinfo]

        push    [.DataSize] [.pGifImage]
        pop     [esi+TGifInfo.lpGIFData] [esi+TGifInfo.dwGIFDataSize]

        stdcall _GIFLoadHeader, esi
        jz      .quit

        stdcall _GIFInitalizeDecoder, esi
        jz       .quit

        stdcall CreateImage, [esi+TGifInfo.dwImageWidth], [esi+TGifInfo.dwImageHeight], 32
        jc      .error
        mov     edi, eax

        push    [edi+TImage.pData]
        pop     [esi+TGifInfo.lpImageData]

        stdcall _GIFDecompress, esi
        jz      .quit

        stdcall _GIFCleanup, esi

        mov     eax, edi

.quit:
.error:
        pop     edi esi edx ecx
        return
endp


;===============================================================================
;       GIFLoadFile
;===============================================================================
; Loads gif data from a file
; returns pointer to TImage
proc ImageGifLoafFromFile, .lpFile
begin
        push    ecx

        stdcall LoadBinaryFile, [.lpFile]
        push    eax

        stdcall CreateImageGIF, eax, ecx
        stdcall FreeMem ; from the stack
        pop     ecx
        return
endp



;===============================================================================
;       GIFCleanup
;===============================================================================
; Cleanup
;
proc _GIFCleanup, .lpGifInfo
begin
        push    esi
        mov     esi, [.lpGifInfo]
        stdcall FreeMem, [esi+TGifInfo.lpLZWTable]
        pop     esi
        return
endp


;===============================================================================
;       GIFDecompress
;===============================================================================
; Decompresses the gif and outputs
; returns:
; 0  - color format not allowed
; 1  - success
; -1 - failed
proc _GIFDecompress, .lpGifInfo
begin
        push    esi edi ebx

        mov     esi, [.lpGifInfo]
        mov     edi, [esi+TGifInfo.lpImageData]

        ; --- Initially, load 4 bytes ---
        mov     [esi+TGifInfo.CurrentBits], 0
        mov     [esi+TGifInfo.dbBitsAvailable], 0

        mov     ebx, 4
.while:
        stdcall _LoadNextByte, esi
        dec     ebx
        jne     .while

        stdcall _DECInitialize, esi
        stdcall _DECDecodeGIF, [.lpGifInfo]

        xor     eax, eax
        inc     eax
        pop     ebx edi esi
        return

.qfalse:
        xor     eax, eax
        pop     ebx edi esi
        return
endp

;===============================================================================
;       _DECDecodeGIF
;===============================================================================
; The actual decoder
;
proc _DECDecodeGIF, .lpGifInfo
 .OldCode            dd ?
 .FirstCharOfOldCode db ?
 .FirstCharOfCode    db ?
 .dummyalign         dw ?
 .NrCodesToOutput    dd ?
begin
        push    esi edi ebx

        mov     esi, [.lpGifInfo]

        ; --- set counters ---
        mov     [esi+TGifInfo.PixelCounter], 0   ;0 codes outputted
        mov     eax, [esi+TGifInfo.dwImageWidth]
        mul     [esi+TGifInfo.dwImageHeight]
        mov     [.NrCodesToOutput], eax    ;this is an OUTPUT CODE counter, not nr of compressed codes

; LZW Decompression
;     [1] Initialize string table;
;     [2] get first code: <code>;
;     [3] output the string for <code> to the charstream;
;     [4] <old> = <code>;
;     [5] <code> <- next code in codestream;
;     [6] does <code> exist in the string table?
;      (yes: output the string for <code> to the charstream;            (A)
;            [...] <- translation for <old>;                            (B)
;            K <- first character of translation for <code>;            (C)
;            add [...]K to the string table;                            (D)
;                        <old> <- <code>;  )                            (E)
;      (no: [...] <- translation for <old>;                             (F)
;           K <- first character of [...];                              (G)
;           output [...]K to charstream and add it to string table;     (H)
;           <old> <- <code>                                             (I)
;      )
;     [7] go to [5];

.mainloop:
        mov     eax, [.NrCodesToOutput]
        cmp     eax, [esi+TGifInfo.PixelCounter]
        je      .endloop

        stdcall _GetNextCode, esi                        ; [1] and [5]
        mov     ebx, eax
        cmp     ebx, [esi+TGifInfo.dwLZWClear]          ; Check for clearcode
        jne     .noclear

        stdcall _DECResetLZW, esi                ; Reset LZW
        jmp     .mainloop

.noclear:
       cmp      [esi+TGifInfo.IsFirstCode], 1   ; Checks if steps [1]-[4] have to be done
       jne      .notfirst

       dec      [esi+TGifInfo.IsFirstCode]      ;[2]
       stdcall  _DECOutputString, esi, ebx       ;[3]
       mov      [.FirstCharOfOldCode], al       ; saved for (G)
       mov      [.OldCode], ebx                 ;[4]
       jmp      .mainloop

.notfirst:
       cmp     [esi+TGifInfo.dwLZWTableCount], ebx  ; [6]   ; DECIsCodeInTable replacement
       jbe     .notintable

       stdcall  _DECOutputString, esi, ebx           ;(B)
       mov      [.FirstCharOfCode], al              ;(C)
       mov      [.FirstCharOfOldCode], al           ; saved for (G)
       stdcall  _DECAddToTable, esi, [.OldCode], eax ;(D)
       mov      [.OldCode], ebx
       jmp      .mainloop

.notintable:                                        ;(F)-(I)
       mov      al, [.FirstCharOfOldCode]           ; (G)
       stdcall  _DECAddToTable, esi, [.OldCode], eax ;(H)
       stdcall  _DECOutputString, esi, ebx           ;(H)
       mov      [.FirstCharOfOldCode], al           ; saved for (G)
       mov      [.OldCode], ebx
       jmp      .mainloop

.endloop:
       xor     eax, eax
       inc     eax
       pop     ebx edi esi
       return
endp


;===============================================================================
; DECAddToTable
;===============================================================================
; Adds an entry to the LZW Table
; The enry consists of a prefix and a suffix (size is calculated automatically)
; returns the code for the new entry
proc _DECAddToTable, .lpGifInfo, .dwPrefix, .dbSuffix
begin
        push    esi edi ebx

        mov     esi, [.lpGifInfo]

        ; --- Check if enough space in the table left
        mov     ecx, [esi+TGifInfo.dwLZWTableSize]
        mov     ebx, [esi+TGifInfo.dwLZWTableCount]

        push    ebx
        shl     ebx, 2

        ; --- If no space left, make the table bigger:
        cmp     ebx, ecx
        jne     .sizeok

        shl     ecx, 1          ;Table size doubles
        mov     [esi+TGifInfo.dwLZWTableSize], ecx

        ; --- Reallocate memory ---
        stdcall ResizeMem, [esi+TGifInfo.lpLZWTable], ecx
        mov     [esi+TGifInfo.lpLZWTable], eax

.sizeok:
        ; --- Create pointer to first free entry ---
        add     ebx, [esi+TGifInfo.lpLZWTable]

        ; --- Find out the size of the string ---
        mov     eax, [.dwPrefix]
        shl     eax, 2
        add     eax, [esi+TGifInfo.lpLZWTable]
        mov     eax, [eax]
        shr     eax, 8
        and     eax, 0FFFh      ;eax now holds the size of the prefix string
        inc     eax

        ; --- Create the entry DWORD ---
        ; (see DECResetLZW for the format)
        mov     ecx, [.dwPrefix]
        shl     ecx, 20
        shl     eax, 8
        or      ecx, eax
        mov     eax, [.dbSuffix]
        and     eax, 0ffh
        or      ecx, eax

        ; --- Store entry ---
        mov     [ebx], ecx

        inc     [esi+TGifInfo.dwLZWTableCount]

        pop     ebx     ;get saved code of new entry

        mov     cl, [esi+TGifInfo.dbCurBitSize]
        xor     eax, eax
        inc     eax
        shl     eax, cl
        dec     eax
        cmp     eax, ebx
        jne     @f

        ;bitsize should be increased
        inc     [esi+TGifInfo.dbCurBitSize]   ;increase bitsize

@@:
        mov     eax, ebx
        pop     ebx edi esi
        return
endp


;===============================================================================
; DECOutputString
;===============================================================================
; Writes the string of dwCode to the output stream
; returns the first character of the string in al
;
proc _DECOutputString, .lpGifInfo, .dwCode
.LastChar     db ?
begin
        push    esi edi ebx

        mov     esi, [.lpGifInfo]
        mov     edi, [esi+TGifInfo.lpLZWTable]  ; --- Set basepointer ---

        mov     eax, [.dwCode]                   ; --- Get entry ---

        mov     ebx, [edi+4*eax]                ; --- Get size of string ---
        shr     ebx, 8                          ; See the description of LZW table below.
        and     ebx, $0fff

; --- Output all codes backwards ---
        mov     edx, [esi+TGifInfo.PixelCounter]
        shl     edx, 2
        add     edx, [esi+TGifInfo.lpImageData]         ; edx is base pointer in the image data.

        add     [esi+TGifInfo.PixelCounter], ebx        ; update the pixel counter.
        dec     ebx                                     ; ebx is the counter and index in image data.

        mov     esi, [esi+TGifInfo.lpColorTable]        ; We don't need TGifInfo anymore.

.outloop:
        mov     eax, [edi+4*eax]
        mov     [.LastChar], al

; Get the color from the color table - esi points to 3 byte  palette array.
        movzx   ecx, al
        lea     ecx, [ecx+2*ecx]  ; = 3*ecx
        mov     ecx, [esi+ecx]
        bswap   ecx
        shr     ecx, 8

; Draw the pixel.
        mov     [edx+4*ebx], ecx

        shr     eax, 20         ; Get the prefix index in the LZW table.
        and     eax, $0fff

        dec     ebx
        jns     .outloop

        mov     al, [.LastChar]
        pop     ebx edi esi
        return
endp



;===============================================================================
; GetNextCode
;===============================================================================
; retrieves the next code from the compressed data stream and loads new bits
; if needed.
proc _GetNextCode, .lpGifInfo
begin
        push    esi edi ebx

        mov     esi, [.lpGifInfo]
        mov     ebx, [esi+TGifInfo.CurrentBits]

        ; --- Create bitmask for current nr of bits ---
        mov     cl, [esi+TGifInfo.dbCurBitSize]
        xor     eax, eax
        inc     eax
        shl     eax, cl
        dec     eax

        ; --- AND ebx with bitmask ---
        and     ebx, eax

        ; --- Shift used bits ---
        mov     cl, [esi+TGifInfo.dbCurBitSize]
        shr     [esi+TGifInfo.CurrentBits], cl

        ; --- Decrease # of bits available ---
        sub     [esi+TGifInfo.dbBitsAvailable], cl

        ; --- Load as many bits as possible ---
.while:
        cmp     [esi+TGifInfo.dbBitsAvailable], 24
        ja      .endwhile
        stdcall _LoadNextByte, esi
        jmp     .while

.endwhile:
        ; --- Return bits ---
        mov     eax, ebx
        pop     ebx edi esi
        return
endp


;===============================================================================
; LoadNextByte
;===============================================================================
; Loads the currentbits entry with new bits
;
proc _LoadNextByte, .lpGifInfo
begin
        push    esi edi ebx
        mov     esi, [.lpGifInfo]

        ; --- Get next byte from datastream ---
        mov     edi, [esi+TGifInfo.lpCurrentByte]
        cmp     edi, -1
        jne     .notend

;end of data already reached
        xor     al, al  ;return 0 as padding
        jmp     .gotbyte

;End of subblock reached?
.notend:
        cmp      edi, [esi+TGifInfo.lpLastEOSB]
        jne      .noteosb

        xor      eax, eax
        mov      al, [edi]       ; new subblock size
        test     al,al
        jnz      .sizeok

        ; if size=0, end of data
        mov      [esi+TGifInfo.lpCurrentByte], -1 ;EOF indicator
        jmp      .gotbyte

.sizeok:
        inc      edi             ; new subblock with size al
        add      eax, edi
        mov      [esi+TGifInfo.lpLastEOSB], eax  ;set new end of subblock
        add      [esi+TGifInfo.lpCurrentByte], 2
        mov      al, [edi]
        jmp      .gotbyte

.noteosb:
        mov      al, [edi]                       ;get next byte
        inc      [esi+TGifInfo.lpCurrentByte]    ;increase for next read

        ; --- Got the new byte from the datasteam ---
.gotbyte:
        mov      cl, [esi+TGifInfo.dbBitsAvailable] ;Get nr of bits available
        mov      edx, [esi+TGifInfo.CurrentBits]    ;Get current bits
        and      eax, 0ffh                          ;eax = al
        shl      eax, cl                            ;Shift bits to right position
        or       edx, eax                           ;OR new bits with current bits
        mov      [esi+TGifInfo.CurrentBits], edx    ;Save bits
        add      [esi+TGifInfo.dbBitsAvailable], 8  ;Set new bits avaialble

        pop     ebx edi esi
        return
endp


;===============================================================================
;       DECInitialize
;===============================================================================
; Initializes the decoder (table for LZW etc)
;
proc _DECInitialize, .lpGifInfo
begin
        push    esi edi

        mov     esi, [.lpGifInfo]
        mov     edi, [esi+TGifInfo.lpGIFImage]

        ; --- Get initial LZW code size ---
        mov     cl, [edi]
        inc     cl
        mov     [esi+TGifInfo.dbInitBitSize], cl

        ; --- Set current bit size to initial bitsize ---
        mov     [esi+TGifInfo.dbCurBitSize], cl

        ; --- Set size of LZW table ---

        cmp     cl, 8
        jae     @f    ;if initial code size is less than 8-bits,
        mov     cl, 8 ;set to 8-bits, if higher, don't change it
@@:
        ; Calculate size of codetable:
        xor     eax, eax
        inc     eax
        add     cl, 2           ; bitsize + 2
        shl     eax, cl         ; eax = 2 ^ (bitsize + 2) = 4 * (2^bitsize)
        mov     [esi+TGifInfo.dwLZWTableSize], eax

        ; --- Allocate memory for LZW Table and store pointer ---
        stdcall GetMem, eax
        mov     [esi+TGifInfo.lpLZWTable], eax

        ; --- Reset LZW ---
        stdcall _DECResetLZW, esi

        xor     eax, eax
        inc     eax
        pop     edi esi
        return
endp



;===============================================================================
; DECResetLZW
;===============================================================================
; Resets the LZW Table and variables (this is the proper action for a clear
; code (CC) in data
proc _DECResetLZW, .lpGifInfo
begin
        push    esi edi ebx
        mov     esi, [.lpGifInfo]

; The LZW table has the following format:
; An array of DWORDS represents an array of string entries
; One entry consists of a prefix code (which is an index to
; another entry that should prefix the entry), a string length,
; and the suffix byte (this byte should be added to the prefix
; to get the full string).
; DWORD:
; | AAAA AAAA | AAAA BBBB | BBBB BBBB | CCCC CCCC |
; ^                                               ^
; MSB                                           LSB
; AAAAAAAAAAAA:  12-bit index in the LZW Table that indicates the prefix
; BBBBBBBBBBBB:  12-bit length of the string
; CCCCCCCC    :   8-bit suffix byte

        ; --- reset LZW Table ---
        ; Reset bit size:

        mov     cl, [esi+TGifInfo.dbInitBitSize]
        mov     [esi+TGifInfo.dbCurBitSize], cl

        ; Get initial nr of entries
        ;mov            eax, [esi].ColorCount
        ;NOTE: THE LINE ABOVE WAS PREVIOUSLY USED TO GET THE NR OF ROOT ENTRIES
        ; THIS DIDN'T WORK BECAUSE 1-BIT GIF'S ARE FOR AN UNKNOWN REASON CODED
        ; AS 2-BIT GIFS, SO THE NR OF ROOT ENTRIES HAS TO BE DETERMINED FROM THE
        ; INITIAL BITSIZE
        dec     cl
        xor     eax, eax
        inc     eax
        shl     eax, cl         ; 2**codesize
        add     eax, 2
        mov     [esi+TGifInfo.dwLZWTableCount], eax
        mov     edx, [esi+TGifInfo.lpLZWTable]
        ; Fill first {2**codcesize+2} entries
        shl     eax, 2
        add     eax, edx
        xor     ecx, ecx
        inc     ch                      ;size of sting is set to 1

.fill:
        mov     [edx], ecx
        inc     cl
        add     edx, 4
        cmp     edx, eax
        jb      .fill

        ; --- set clear code ---
        mov     eax, [esi+TGifInfo.dwLZWTableCount]
        sub     eax, 2
        mov     [esi+TGifInfo.dwLZWClear], eax
        mov     [esi+TGifInfo.IsFirstCode], 1

        ;lpLZWTable             dd      ?   ; Pointer to LZW Table
        ;dwLZWTableSize         dd      ?   ; Current maximum size of table
        ;dwLZWTableCount        dd      ?   ; Current nr of entries in the LZW table
        ;dbCurBitSize           db      ?   ; Current LZW code size
        ;dbInitBitSize          db      ?   ; Initial LZW code size
        ;dwLZWClear             dd      ?   ; Value of LZW Clear code (CC)

        xor     eax, eax
        inc     eax
        pop     ebx edi esi
        return
endp



;===============================================================================
;       GIFLoadHeader
;===============================================================================
; Loads header and logical screen descriptor
;
proc _GIFLoadHeader, .lpGifInfo
begin
        push    esi edi ebx
        mov     esi, [.lpGifInfo]

        ; --- EDI points to GIF Data, EBX is size of data ---
        mov     edi, [esi+TGifInfo.lpGIFData]
        mov     ebx, [esi+TGifInfo.dwGIFDataSize]

        cmp     ebx, 11
        jb      .failed ; ebx smaller than header & Logical screen descr. -> invalid GIF

        ; --- Check first 3 bytes ("GIF" signature) ---
        mov     eax, [edi]
        and     eax, $00ffffff
        cmp     eax, 'GIF'
        jne     .failed

        ; --- Copy version number ---
        lea     ecx, [esi+TGifInfo.GIFVersion]
        mov     ax, [edi+3]
        mov     [ecx], ax
        mov     al, [edi+5]
        mov     [ecx+2], al

        ; --- Copy logical screen sizes ---
        xor     eax, eax
        mov     ax, [edi+6]                     ;Get Logical screen width
        mov     [esi+TGifInfo.dwLSWidth], eax
        mov     ax, [edi+8]                     ;Get Logical screen width
        mov     [esi+TGifInfo.dwLSHeight], eax

        ; --- Set global color table flag and size ---
        mov     cl, [edi+10]
        mov     al, cl
        rol     al, 1
        and     al, 1
        mov     [esi+TGifInfo.fGlobalCTable], al
        and     cl, 111b
        mov     [esi+TGifInfo.dbGCTableSize], cl

        xor     eax, eax
        inc     eax
        pop     ebx edi esi
        return

.failed:
        xor     eax, eax
        pop     ebx edi esi
        return
endp



;===============================================================================
;       GIFInitalizeDecoder
;===============================================================================
; Initializes decoder
;
proc _GIFInitalizeDecoder, .lpGifInfo
begin
        push    esi edi ebx
        mov     esi, [.lpGifInfo]

        ; --- EDI points to GIF Data, EBX to end of data ---
        mov     edi, [esi+TGifInfo.lpGIFData]
        mov     ebx, [esi+TGifInfo.dwGIFDataSize]
        add     ebx, edi

        add     edi, 13         ; skip header and local screen descriptor

        ; --- Get global color tablesize in bytes ---
        mov     cl, [esi+TGifInfo.dbGCTableSize]
        inc     cl
        xor     eax, eax
        inc     eax
        shl     eax, cl
        mov     ecx, eax
        shl     ecx, 1          ;--+--> ecx * 3
        add     ecx, eax        ;--+

        ; --- Skip global color table if available ---
        cmp     [esi+TGifInfo.fGlobalCTable], 0
        je      @f
        add     edi, ecx
@@:
        cmp     edi, ebx
        jae     .failed

        ; --- Search through the GIF blocks for the first graphic block ---
.scanloop:
        cmp     edi, ebx
        jae     .failed

        mov     al, [edi]
        cmp     al, EXTENSIONBLOCK
        jne     .maybe

        stdcall _SkipExtension, edi, ebx
        mov     edi, eax
        jmp     .scanloop

.maybe:
        cmp     al, IMAGEDESCRIPTOR
        jne     .scanloop               ; BUG: loop forever on some circumstances...

        stdcall _ProcessImageDescriptor, [.lpGifInfo], edi, ebx
        add     edi, 11
        stdcall _SkipSubBlocks, edi

        xor     eax, eax
        inc     eax
.quit:
        pop     ebx edi esi
        return

.failed:
        xor     eax, eax
        jmp     .quit
endp



;===============================================================================
; ProcessImageDescriptor
;===============================================================================
; Processes an image desriptor block
proc _ProcessImageDescriptor, .lpGifInfo, .lpStart, .lpEOF
begin
        push    esi edi
        mov     esi, [.lpGifInfo]

        mov     edx, [.lpStart]
        xor     eax, eax

        ; --- copy image width & height ---
        mov     ax, [edx+5]
        mov     [esi+TGifInfo.dwImageWidth], eax
        mov     ax, [edx+7]
        mov     [esi+TGifInfo.dwImageHeight], eax

        ; --- look for local color table ---
        mov     cl, [edx+9]
        mov     al, cl
        rol     cl, 1
        and     cl, 1
        mov     [esi+TGifInfo.fLocalCTable], cl
        and     al, 111b
        mov     [esi+TGifInfo.dbLCTableSize], al

        ; --- Find out which color table to use ---
        cmp     cl, 1
        jne     .setglobal

        ;local color table available
        ; --- Set color count ---
        mov     cl, [esi+TGifInfo.dbLCTableSize]
        inc     cl
        xor     eax, eax
        inc     eax
        shl     eax, cl
        mov     [esi+TGifInfo.ColorCount], eax
        ; --- Set color table pointer ---
        mov     eax, edx
        add     eax, 10 ;move to the local color table
        mov     [esi+TGifInfo.lpColorTable], eax
        jmp     .ctableok

.setglobal:
        ;no local color table, use global color table
        ; --- Set color count ---
        mov     cl, [esi+TGifInfo.dbGCTableSize]
        inc     cl
        xor     eax, eax
        inc     eax
        shl     eax, cl
        mov     [esi+TGifInfo.ColorCount], eax
        ; --- Set color table pointer ---
        mov     eax, [esi+TGifInfo.lpGIFData]
        add     eax, 13 ;move to the global color table (at offset 13 in file)
        mov     [esi+TGifInfo.lpColorTable], eax

.ctableok:
        ; --- Set pointer to real image data (table based image data)
        mov     eax, edx
        add     eax, 10                                 ;Skip image descriptor

        cmp     [esi+TGifInfo.fLocalCTable], 0
        je      .setptr

        mov     ecx, [esi+TGifInfo.ColorCount]   ;-+
        add     eax, ecx                         ; + add size of colortable
        shl     ecx, 1                           ; + (colorcount * 3)
        add     eax, ecx                         ;-+

.setptr:
        mov     [esi+TGifInfo.lpGIFImage], eax

        ; --- Set some pointers to initialize the decompressor
        inc     eax
        mov     [esi+TGifInfo.lpLastEOSB], eax
        mov     [esi+TGifInfo.lpCurrentByte], eax

        xor     eax, eax
        inc     eax
        pop     edi esi
        return
endp



;=====================================================================
; Skips an extension block that starts at lpStart. EOF is at lpEnd.
; returns pointer to the end of block + 1
; or 0 if failed
; esi points at TGifInfo structure.
proc _SkipExtension, .lpStart, .lpEnd
begin
        ; --- Get type of extension ---
        mov     edx, [.lpStart]
        mov     al, [edx+1]

        ; --- Skip each type seperately ---
        cmp     al, GRAPHICCONTROLEXTENSTION
        jne     @f

        ; Get transparent color and flag.
        movzx   eax, byte [edx+3]
        and     eax, 1
        mov     [esi+TGifInfo.fTransparent], eax
        mov     al, [edx+6]
        mov     [esi+TGifInfo.iTrasparentColor], eax

        ; Graphic control extension, has a fixed size of 8 bytes
        add     edx, 8
        mov     eax, edx
        jmp     .endext

@@:
        cmp     al, COMMENTEXTENSION
        jne     @f

        ; Comment extension, consists of subblocks of text
        add     edx, 2  ;move to first subblock
        stdcall _SkipSubBlocks, edx
        jmp     .endext

@@:
        cmp     al, PLAINTEXTEXTENSION
        jne     @f

        ; Plain text extension, 15 header bytes and subblocks follow
        add     edx, 15
        stdcall _SkipSubBlocks, edx
        jmp     .endext

@@:
        cmp     al, APPLICATIONEXTENSION
        jne     .endext

        ; Application extension, 14 header bytes and subblocks follow
        add     edx, 14
        stdcall _SkipSubBlocks, edx
.endext:
        return
endp


;===============================================================================
;       SkipSubBlocks
;===============================================================================
; Skips a sequence of subblocks until a block-terminator is found.
; returns a pointer to the end of the block + 1.
; lpStart points to the start of the subblocks
;
proc _SkipSubBlocks, .lpStart
begin
        mov     eax, [.lpStart]
        xor     ecx, ecx
.skiploop:
        mov     cl, [eax]       ; get size of subblock
        test    cl, cl
        jz      .endloop   ; size=0 means terminator
        inc     eax
        add     eax, ecx        ; add size to pointer
        jmp     .skiploop

.endloop:
        inc     eax
        return
endp


endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/graphics/images.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Memory based images manipulation library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Include respective OS dependent files.
;_________________________________________________________________________________________
module "Images library"

struct TImage
  .width  dd ?  ; width in pixels.
  .height dd ?  ; height in pixels.
  .bpp    dd ?  ; bits per pixel.
  .pData  dd ?  ; pointer to memory buffer with scanlines. all scanlines are aligned on dword.
  .raster dd ?  ; OS handle to be used with procedures from other graphics libraries.
ends


proc DrawMaskedImage, .context, .mask, .image, .x, .y
begin
        stdcall SetDrawMode, [.context], cmAnd
        stdcall DrawImage, [.context], [.mask], [.x], [.y]
        stdcall SetDrawMode, [.context], cmXor
        stdcall DrawImage, [.context], [.image], [.x], [.y]
        return
endp


include '%TargetOS%/images.asm'

endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































Deleted freshlib/graphics/text.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Text drawing library.
;
;  Target OS: Any
;
;  Dependencies: StrLib
;
;  Notes: This file contains OS independent part of the library and includes respective
;         OS dependent files.
;_________________________________________________________________________________________
module "Text library"

include "%TargetOS%/text.asm"


macro min a, b, use {
        sub     b, a
        sbb     use, use
        and     use, b
        add     a, use
}

macro max a, b, use {
        sub     b, a
        sbb     use, use
        not     use
        and     use, b
        add     a, use
}


struct TTextExtent
  .width  dd ?
  .height dd ?
  .OffsX  dd ?
  .OffsY  dd ?
ends


struct TCharAttr
  .font       dd ?
  .color      dd ?
  .background dd ?
  .flags      dd ?      ; for free use of the client.
ends


; dtfXXX means "draw text flag"

; horizontal align
dtfAlignLeft    = 0
dtfAlignRight   = 1
dtfAlignCenter  = 2
dtfAlignJustify = 3

; vertical align
dtfAlignTop    = 0 shl 2
dtfAlignBottom = 1 shl 2
dtfAlignMiddle = 2 shl 2

; Text layout
dtfCRLF         = $0100
dtfWordWrap     = $0200
dtfTableTabs    = $0400


struct _TTextChunk
  .y      dd ?
  .width  dd ?
  .height dd ?
  .len    dd ?
  .ptr    dd ?
ends

__HeightProbeString text '18ilj.Xygl[_|"`g'
__NumberProbeString text '8888888888888888'

; returns: eax - mean width
; returns: edx - height
; returns: ecx - descent
proc FontGetCharSize, .raster, .font, .probe
begin
        push    ebx

        stdcall AllocateContext, [.raster]
        mov     ebx, eax

        stdcall GetTextOffset, ebx, [.probe], 16, [.font]
        mov     ecx, edx

;        DebugMsg "Text offset y:"
;        OutputRegister regECX, 10

        stdcall GetTextBounds, ebx, [.probe], 16, [.font]
        stdcall ReleaseContext, ebx

        sub     ecx, edx
        shr     eax, 4
        neg     ecx
        pop     ebx
        return
endp




proc AdjustCountUtf8
begin
        push    esi
        lea     esi, [esi+ebx]
        stdcall ScanBackUtf8
        mov     ebx, esi
        pop     esi
        sub     ebx, esi
        return
endp


proc DrawTextBox, .context, .text, .bounds, .flags, .font, .color
.len   dd ?
.count dd ?
.height dd ?
.y      dd ?

.low  dd  ?
.high dd  ?

.linew     dd ?
.lineh     dd ?

.DrawProc dd ?
begin
        pushad

        mov     ecx, DrawString

        mov     eax, [.flags]
        and     eax, $03
        cmp     eax, dtfAlignJustify
        jne     @f
        mov     ecx, DrawStringJustified
@@:
        mov     [.DrawProc], ecx

        stdcall StrLen, [.text]
        mov     [.len], eax

        stdcall StrPtr, [.text]
        mov     esi, eax

        mov     edi, [.bounds]
        mov     eax, [edi+TBounds.height]
;        mov     ecx, [edi+TBounds.y]
        mov     [.height], eax
        mov     [.y], 0 ;ecx

; slice the string on chunks, depending on flags, rectangle width and the string content.
; push _TTextChunk for every chunk in stack.
        mov     [.count], 0
.slice:
        mov     ecx, [.len]

        test    [.flags], dtfCRLF
        jz      .cropit

        xor     ecx, ecx

.scanCRLF:
        cmp     ecx, [.len]
        jae     .cropit

        mov     al, [esi+ecx]

        cmp     al, $0d
        je      .cropit
        cmp     al, $0a
        je      .cropit
        inc     ecx
        jmp     .scanCRLF

.cropit:
        mov     ebx, ecx  ; high limit

        stdcall AdjustCountUtf8
        stdcall GetTextBounds, [.context], esi, ebx, [.font]

        cmp     edx, [.height]
        jg      .drawchunks

        mov     [.lineh], edx

        cmp     eax, [edi+TBounds.width]
        jle     .itfits

        mov     [.high], ebx
        mov     [.low], 0

.croploop:
        mov     ebx, [.low]
        add     ebx, [.high]
        shr     ebx, 1

        stdcall AdjustCountUtf8
        stdcall GetTextBounds, [.context], esi, ebx, [.font]
        cmp     eax, [edi+TBounds.width]
        je      .itfits

        jg      .above

        cmp     ebx, [.low]
        je      .itfits

        mov     [.low], ebx
        jmp     .croploop

.above:
        mov     [.high], ebx
        jmp     .croploop

.itfits: ; here ebx contains the len of string that fits in the rectangle.
        mov     ecx, ebx
        mov     [.linew], eax

        test    [.flags], dtfWordWrap
        jz      .pushit

; search the last space or tab that separates words:
        mov     edx, ecx
        cmp     byte [esi+edx], $0d
        je      .found
        cmp     byte [esi+edx], $0a
        je      .found

.searchword:
        cmp     byte [esi+edx], 0
        je      .found
        cmp     byte [esi+edx], ' '
        je      .found
        cmp     byte [esi+edx], $09
        je      .found
        cmp     byte [esi+edx], $0d
        je      .found
        cmp     byte [esi+edx], $0a
        je      .found

        dec     edx
        jnz     .searchword

        mov     edx, ecx

.found:
        push    ebx
        mov     ebx, edx
        stdcall AdjustCountUtf8
        stdcall GetTextBounds, [.context], esi, ebx, [.font]
        mov     [.linew], eax
        mov     [.lineh], edx
        mov     ecx, ebx
        pop     ebx

.pushit:
        push    esi             ; pointer to the string.
        push    ecx             ; length of the string.
        push    [.lineh]        ; height of the line.
        push    [.linew]        ; width of the line.
        push    [.y]            ;

        inc     [.count]

        mov     eax, [.lineh]
        add     [.y], eax
        sub     [.height], eax

        lea     esi, [esi+ecx]
        sub     [.len], ecx
        jz      .drawchunks

        xor     ecx, ecx

; search for the whitespace that have to be skip
.skiploop:
        mov     al, [esi]
        cmp     al, $0d
        je      .skipcrlf
        cmp     al, $0a
        je      .skipcrlf
        cmp     al, $20
        je      .skipspace
        cmp     al, $09
        je      .skipspace

        jmp     .slice

.skipspace:
        inc     esi
        dec     [.len]
        jnz     .skiploop
        jmp     .drawchunks

.skipcrlf:
        inc     esi
        dec     [.len]
        xor     al, $0d xor $0a
        cmp     [esi], al
        jne     .slice
        inc     esi
        dec     [.len]
        jnz     .slice

; pop the _TTextChunk structures and draw, depending on flags.
.drawchunks:
        mov     ebx, esp
        stdcall GetTextOffset, [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.font]
        mov     eax, [ebx+_TTextChunk.height]
        sub     eax, edx        ; it should be the line y descent
        test    [.flags], dtfAlignBottom
        jnz     @f
        sub     [.y], eax
@@:
        mov     edx, [.flags]
        and     edx, dtfAlignBottom or dtfAlignMiddle

        mov     ecx, [edi+TBounds.height]
        sub     ecx, [.y]

        cmp     edx, dtfAlignBottom
        je      .yalignok

        sar     ecx, 1
        cmp     edx, dtfAlignMiddle
        je      .yalignok

        xor     ecx, ecx

.yalignok:
.drawloop:
        cmp     [.count], 0
        je      .finish

        mov     ebx, esp

        mov     eax, [edi+TBounds.width]
        sub     eax, [ebx+_TTextChunk.width]

        mov     edx, [.flags]
        and     edx, $03

        cmp     edx, dtfAlignRight
        je      .hready

        shr     eax, 1
        cmp     edx, dtfAlignCenter
        je      .hready

        xor     eax, eax

.hready:
        add     eax, [edi+TBounds.x]

        push    eax
        stdcall GetTextOffset, [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.font]
        add     edx, ecx
        add     edx, [ebx+_TTextChunk.y]
        add     edx, [edi+TBounds.y]
        pop     eax

        stdcall [.DrawProc], [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], eax, edx, [.font], [.color]

; draws lines on every row of text. For debug purposes.
iglobal
  if used __UnderlineStyle
    __UnderlineStyle LineStyle 0, $808080
  end if
endg

if defined options.DebugMode & options.DebugMode
        stdcall SetLineStyle, [.context], __UnderlineStyle
        stdcall DrawLine, [.context], [edi+TBounds.x], edx, [edi+TBounds.width], edx
end if
; end debug code


        add     esp, sizeof._TTextChunk
        dec     [.count]
        jmp     .drawloop

.finish:
        popad
        return
endp




proc DrawStringJustified, .raster, .ptrString, .len, .x, .y, .font, .color
.XX    dd ?
.rem   dd ?
.crem  dd ?
.endptr dd ?
begin
        pushad

        mov     esi, [.ptrString]
        mov     eax, [.len]
        add     eax, esi
        mov     [.endptr], eax

        stdcall StrLenUtf8, esi, [.len]
        mov     ecx, eax
        dec     ecx
        jg      @f
        mov     ecx, 1
@@:

        stdcall GetTextBounds, [.raster], esi, [.len], [.font]

        sub     eax, [edi+TBounds.width]
        neg     eax

        cdq
        div    ecx

        cmp     eax, 4
        jge     .cantjustify    ; the needed space is too big for justify, so just draw it left aligned

        mov     ecx, eax
        mov     [.rem], edx
        mov     [.crem], edx

        mov     ebx, [.len]
        push    [.x]
        pop     [.XX]

.drawloop:
        cmp     esi, [.endptr]
        jae     .finish

        stdcall DecodeUtf8, [esi]
        jc      .finish

        push    edx
        stdcall DrawString, [.raster], esi, edx, [.XX], [.y], [.font], [.color]
        stdcall GetTextBounds, [.raster], esi, edx, [.font]
        pop     edx
        add     esi, edx
        add     [.XX], eax
        add     [.XX], ecx

        cmp     [.crem], 0
        je      .drawloop

        sub     ebx, [.rem]
        jge     .drawloop

        inc     [.XX]
        dec     [.crem]
        mov     ebx, [.len]
        sub     ebx, [.rem]
        jmp     .drawloop

.finish:
        popad
        return

.cantjustify:
        stdcall DrawString, [.raster], [.ptrString], [.len], [.x], [.y], [.font], [.color]
        jmp     .finish
endp



endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/gui/Linux/Main.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Main procedure of GUI application library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes: Organize the main message/event loop needed by every GUI engine.
;_________________________________________________________________________________________

uglobal
  if used fGlobalTerminate
    fGlobalTerminate dd ?
  end if
endg


proc ProcessSystemEvents
  .event  XEvent
begin
        push    ebx ecx edx

.event_loop:
; check for quit
        mov     eax, [pApplication]
        mov     eax, [eax+TApplication.MainWindow]
        test    eax, eax
        jz      .continue     ; ???????????

        cmp     dword [eax], 0
        jne     .continue

        cinvoke XFlush, [hApplicationDisplay]
        xor     eax, eax
        mov     [fGlobalTerminate], 1
        stc
        pop     edx ecx ebx
        return

.continue:
        cinvoke XPending, [hApplicationDisplay]
        test    eax, eax
        jz      .noevents

        lea     ebx, [.event]
        cinvoke  XNextEvent, [hApplicationDisplay], ebx
        stdcall  __ProcessOneSystemEvent, ebx
        jmp      .event_loop

.noevents:
        clc
        pop     edx ecx ebx
        return

endp




proc WaitForSystemEvent
.event XEvent
begin
        push    eax ecx edx
        lea     eax, [.event]
        cinvoke XPeekEvent, [hApplicationDisplay], eax
        pop     edx ecx eax
        return
endp




;proc EventsQueued, .pWin
;begin
;        push    eax ecx edx
;        cinvoke XQLength, [hApplicationDisplay]
;        test    eax, eax
;        clc
;        jz      @f
;        stc
;@@:
;        pop     edx ecx eax
;        return
;endp




proc __ProcessOneSystemEvent, .linux_event
.event  rd 64
begin
        push    eax ebx ecx edx esi edi

        mov     ebx, [.linux_event]

        stdcall _GetWindowStruct, [ebx+XEvent.window]
        mov     esi, eax
        lea     edi, [.event]
        mov     eax, [ebx+XEvent.type]

        cmp     eax, DestroyNotify
        je      .destroy

        test    esi, esi
        jz      .notprocessed

        cmp     eax, MotionNotify
        je      .mousemove

        cmp     eax, EnterNotify
        je      .mouseenter

        cmp     eax, LeaveNotify
         je      .mouseleave

        cmp     eax, ButtonPress
        je      .mouse_btn_press

        cmp     eax, ButtonRelease
        je      .mouse_btn_release

        cmp     eax, Expose
        je      .paint_window

        cmp     eax, ClientMessage        ; event from the window manager - button close for example.
        je      .clientmessage

        cmp     eax, KeyPress
        je      .key_press

        cmp     eax, KeyRelease
        je      .key_release

        cmp     eax, MappingNotify
        je      .mapping_notify

        cmp     eax, FocusIn
        je      .focusin

        cmp     eax, FocusOut
        je      .focusout

        cmp     eax, ConfigureNotify
        je      .moveresize

.notprocessed:
        pop     edi esi edx ecx ebx eax
        stc
        return

.exec_event:
        pushad
        stdcall ExecEvent, esi, edi
        popad

.finish:
        pop     edi esi edx ecx ebx eax
        clc
        return

;.........................................................................
; Resize events
.moveresize:
locals
  .xevent XConfigureEvent
endl
        lea     eax, [.xevent]
        cinvoke XCheckTypedWindowEvent, [hApplicationDisplay], [ebx+XConfigureEvent.window], ConfigureNotify, eax
        test    eax, eax
        jz      .process

        lea     eax, [.xevent]
        cinvoke XPutBackEvent, [hApplicationDisplay], eax

        mov     eax, [.xevent.x]
        cmp     eax, [ebx+XConfigureEvent.x]
        jne     .finish

        mov     eax, [.xevent.y]
        cmp     eax, [ebx+XConfigureEvent.y]
        jne     .finish

        mov     eax, [.xevent.width]
        cmp     eax, [ebx+XConfigureEvent.width]
        jne     .finish

        mov     eax, [.xevent.height]
        cmp     eax, [ebx+XConfigureEvent.height]
        jne     .finish

.process:
        mov     [edi+TMoveResizeEvent.event], seMoveResize

        mov     eax, [ebx+XConfigureEvent.x]
        mov     ecx, [ebx+XConfigureEvent.y]
        mov     [edi+TMoveResizeEvent.newX], eax
        mov     [edi+TMoveResizeEvent.newY], ecx

        cmp     [ebx+XConfigureEvent.height], 100
        jl      @f
;        DebugMsg "NewX NewY"
;        OutputRegister regEAX, 10
;        OutputRegister regECX, 10
@@:
        mov     eax, [ebx+XConfigureEvent.width]
        mov     ecx, [ebx+XConfigureEvent.height]
        mov     [edi+TMoveResizeEvent.newWidth], eax
        mov     [edi+TMoveResizeEvent.newHeight], ecx

        cmp     [ebx+XConfigureEvent.height], 100
        jl      @f
;        DebugMsg "NewW NewH"
;        OutputRegister regEAX, 10
;        OutputRegister regECX, 10
@@:
        jmp     .exec_event

;.........................................................................
; Focus events
.focusout:
        mov     [edi+TFocusOutEvent.event], seFocusOut
        jmp     .setIC

.focusin:
        mov     [edi+TFocusInEvent.event], seFocusIn

.setIC:
        cinvoke XSetICValues, [hInputContext], XNFocusWindow, [esi+TWindow.handle], 0
        jmp     .exec_event

;.........................................................................
; DestroyNotify handler it invalidates the handle in TWindow structure and then destroys TWindow.
.destroy:
        DebugMsg "Destroy notify"
        OutputNumber [ebx+XDestroyWindowEvent.window], 16, 8
        DebugMsg "h <<< Window handle"

        test    esi, esi
        jz      .finish

        DebugMsg "Destroy the object"

        mov     [esi+TWindow.handle], 0
        stdcall Destroy, esi
        jmp     .finish

;.........................................................................
; Mouse event handlers

.mouseleave:
        mov     [edi+TMouseEnterEvent.event], seMouseLeave
        jmp     .exec_event

.mouseenter:
        mov     [edi+TMouseEnterEvent.event], seMouseEnter
        jmp     .exec_event

.mousemove:
        mov     [edi+TMouseMoveEvent.event], seMouseMove
        mov     eax, [ebx+XMotionEvent.x]
        mov     ecx, [ebx+XMotionEvent.y]
        mov     [edi+TMouseMoveEvent.x], eax
        mov     [edi+TMouseMoveEvent.y], ecx
        jmp     .exec_event

.mouse_btn_press:
.mouse_btn_release:

        mov     eax, [ebx+XButtonEvent.type]
        mov     [edi+TMouseButtonEvent.event], eax      ; seMouseBtnPress=ButtonPress and seMouseBtnRelease = ButtonRelease

        mov     eax, [ebx+XButtonEvent.button]
        dec     eax

        cmp     [edi+TScrollEvent.event], seMouseBtnRelease
        je      @f

        cmp     eax, 3
        jge     .wheelscroll

@@:
        mov     [edi+TMouseButtonEvent.Button], eax

        mov     eax, [ebx+XButtonEvent.state]
        mov     [edi+TMouseButtonEvent.kbdStatus], eax

        mov     eax, [ebx+XButtonEvent.x]
        mov     ecx, [ebx+XButtonEvent.y]
        mov     [edi+TMouseButtonEvent.x], eax
        mov     [edi+TMouseButtonEvent.y], ecx

        jmp     .exec_event

.wheelscroll:
        mov     ecx, scWheelUp
        je      @f
        mov     ecx, scWheelDn
@@:
        mov     [edi+TScrollEvent.event], seScroll
        mov     [edi+TScrollEvent.ScrollBar], scrollY
        mov     [edi+TScrollEvent.ScrollCmd], ecx
        mov     [edi+TScrollEvent.Value], 1
        jmp     .exec_event

;.........................................................................
; Window paint event

.paint_window:
;        cmp     [ebx+XExposeEvent.count], 0
;        jne     .finish

        lea     eax, [ebx+XExposeEvent.x]
        stdcall __PaintWindow, esi, eax

        jmp     .finish

;.........................................................................
; Keyboard events.

locals
  .utf8buff rb 16
endl

.key_press:
        mov     ecx, seKbdKeyPress
        mov     [edi+TKeyboardEvent.event], ecx
        mov     ecx, [ebx+XKeyEvent.state]
        mov     [edi+TKeyboardEvent.kbdStatus], ecx

        mov     dword [.utf8buff], 0
        lea     eax, [.utf8buff]
        cinvoke Xutf8LookupString, [hInputContext], ebx, eax, 16, 0, 0

; here, .utg8buff contains the utf-8 string with the character typed on the keyboard.
        mov     eax, dword [.utf8buff]
        mov     [edi+TKeyboardEvent.key], eax

.scancode:
        mov     eax, [ebx+XKeyEvent.keycode]
        cinvoke XKeycodeToKeysym, [hApplicationDisplay], eax, 0
        mov     [edi+TKeyboardEvent.scancode], eax
        jmp     .exec_event


.key_release:
        mov     ecx, seKbdKeyRelease
        mov     eax, [ebx+XKeyEvent.state]

        mov     [edi+TKeyboardEvent.event], ecx
        mov     [edi+TKeyboardEvent.kbdStatus], eax
        mov     [edi+TKeyboardEvent.key], 0
        jmp     .scancode



; refreshes keyboard mapping information, stored locally in XLib.
.mapping_notify:
        cinvoke XRefreshKeyboardMapping, ebx
        jmp     .finish


;.........................................................................
; This event is sent from the window manager, when the user click on the close button of the
; window or close it some other way. So, the window have to decide whether to close or not.

.clientmessage:
        mov     eax, dword [ebx+XClientMessageEvent.data]
        cmp     eax, [atomWMDelete]
        jne     .finish

; The window is closed by click on close button or by pressing Alt+F4 or by other WM method
;.close_from_wm:
        mov     [edi+TCloseEvent.event], seCloseRequest
        mov     [edi+TCloseEvent.reason], cerFromUser
        jmp     .exec_event
endp








proc __PaintWindow, .pWindow, .ptrBounds
.event TPaintEvent
.caret dd ?
begin
        push    eax ebx ecx edx esi edi

        lea     edi, [.event]
        mov     esi, [.pWindow]

if defined Caret
        mov     [.caret], -1
        cmp     esi, [Caret.pWindow]
        jne     @f
        stdcall CaretShow, FALSE
        mov     [.caret], eax
@@:
end if
        mov     [edi+TPaintEvent.event], sePaint

        stdcall AllocateContext, [esi+TWindow.handle]
        mov     ebx, eax
        mov     [edi+TPaintEvent.context], eax

        xor     eax, eax
        mov     [edi+TPaintEvent.rect.left], eax
        mov     [edi+TPaintEvent.rect.top], eax
        mov     eax, $7fffffff
        mov     [edi+TPaintEvent.rect.right], eax
        mov     [edi+TPaintEvent.rect.bottom], eax

        mov     edx, [.ptrBounds]
        test    edx, edx
        jz      .rectok

        mov     eax, [edx+TBounds.x]
        mov     ecx, [edx+TBounds.y]

        mov     [edi+TPaintEvent.rect.left], eax
        mov     [edi+TPaintEvent.rect.top], ecx

        mov     eax, [edx+TBounds.width]
        mov     ecx, [edx+TBounds.height]
        add     eax, [edi+TPaintEvent.rect.left]
        add     ecx, [edi+TPaintEvent.rect.top]
        mov     [edi+TPaintEvent.rect.right], eax
        mov     [edi+TPaintEvent.rect.bottom], ecx

.rectok:
        pushad
        stdcall ExecEvent, esi, edi
        popad

        stdcall ReleaseContext, ebx

if defined Caret
        cmp     [.caret], -1
        je      @f
        stdcall CaretShow, [.caret]
@@:
end if
        pop     edi esi edx ecx ebx eax
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/gui/Linux/TApplication.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TApplication object class.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes: TApplication by the idea is the base of GUI application, but the implementation
;         somehow need fixing...
;_________________________________________________________________________________________


uglobal
  if used CApplication
    hApplicationDisplay dd ?
    hRootWindow         dd ?

    hInputMethod        dd ?
    hInputContext       dd ?

    _SystemFont         dd ?

    atomWMDelete        dd ?
  end if
endg

;cDefaultFont text 'Tahoma-8'
cDefaultFont text 'Liberation Sans-9'
cDefaultFontSize = 9
;cDefaultFont text 'Ubuntu-9:rgba=rgb'
;cDefaultFont text 'Unifont-12' ; this one have unicode support;


; String constants needed for XLib
; Why, they needed so many strings????????????????? For arguments!??????????
_cWinDeleteName   text 'WM_DELETE_WINDOW'

XNVaNestedList                text "XNVaNestedList"
XNSeparatorofNestedList       text "separatorofNestedList"
XNQueryInputStyle             text "queryInputStyle"
XNClientWindow                text "clientWindow"
XNInputStyle                  text "inputStyle"
XNFocusWindow                 text "focusWindow"
XNResourceName                text "resourceName"
XNResourceClass               text "resourceClass"
XNGeometryCallback            text "geometryCallback"
XNDestroyCallback             text "destroyCallback"
XNFilterEvents                text "filterEvents"
XNPreeditStartCallback        text "preeditStartCallback"
XNPreeditDoneCallback         text "preeditDoneCallback"
XNPreeditDrawCallback         text "preeditDrawCallback"
XNPreeditCaretCallback        text "preeditCaretCallback"
XNPreeditStateNotifyCallback  text "preeditStateNotifyCallback"
XNPreeditAttributes           text "preeditAttributes"
XNStatusStartCallback         text "statusStartCallback"
XNStatusDoneCallback          text "statusDoneCallback"
XNStatusDrawCallback          text "statusDrawCallback"
XNStatusAttributes            text "statusAttributes"
XNArea                        text "area"
XNAreaNeeded                  text "areaNeeded"
XNSpotLocation                text "spotLocation"
XNColormap                    text "colorMap"
XNStdColormap                 text "stdColorMap"
XNForeground                  text "foreground"
XNBackground                  text "background"
XNBackgroundPixmap            text "backgroundPixmap"
XNFontSet                     text "fontSet"
XNLineSpace                   text "lineSpace"
XNCursor                      text "cursor"
XNQueryIMValuesList           text "queryIMValuesList"
XNQueryICValuesList           text "queryICValuesList"
XNStringConversionCallback    text "stringConversionCallback"
XNStringConversion            text "stringConversion"
XNResetState                  text "resetState"
XNHotKey                      text "hotkey"
XNHotKeyState                 text "hotkeyState"
XNPreeditState                text "preeditState"
XNVisiblePosition             text "visiblePosition"
XNR6PreeditCallbackBehavior   text "r6PreeditCallback"
XNRequiredCharSet             text "requiredCharSet"
XNQueryOrientation            text "queryOrientation"
XNDirectionalDependentDrawing text "directionalDependentDrawing"
XNContextualDrawing           text "contextualDrawing"
XNBaseFontName                text "baseFontName"
XNMissingCharSet              text "missingCharSet"
XNDefaultString               text "defaultString"
XNOrientation                 text "orientation"
XNFontInfo                    text "fontInfo"
XNOMAutomatic                 text "omAutomatic"



proc TApplication.Create, .obj
.ptr dd ?
begin
        push    eax ecx edx

        cinvoke XInitThreads
        test    eax, eax
        jz      .exit_error

        cinvoke XSetErrorHandler, __FreshXErrorHandler

        cinvoke XOpenDisplay, 0
        test    eax, eax
        jz      .second_try

.continue:
        DebugMsg 'Display opened.'

        mov     [hApplicationDisplay], eax

        cinvoke XDefaultRootWindow, eax
        mov     [hRootWindow], eax

        cinvoke XOpenIM, [hApplicationDisplay], 0, 0, 0
        mov     [hInputMethod], eax

        lea     eax, [.ptr]
        cinvoke XGetIMValues, [hInputMethod], XNQueryInputStyle, eax, 0

        mov     eax, [.ptr]
        mov     eax, [eax+4]
        cinvoke XCreateIC, [hInputMethod], XNInputStyle, [eax], 0
        mov     [hInputContext], eax

        cinvoke XFree, [.ptr]

        stdcall InitMouseCursors

; Creating internal atoms that to be used with Window manager of the application windows...
; Maybe this code should reside somewhere else, not in application. In initialize TWindow???

        cinvoke XInternAtom, [hApplicationDisplay], _cWinDeleteName, 0
        mov     [atomWMDelete], eax

        cinvoke XftFontOpenName, [hApplicationDisplay], 0, cDefaultFont
        mov     [_SystemFont], eax


; clipboard initialization.
if __UseClipboard = 1
        stdcall   __InitLinuxClipboard
end if

        clc
        pop     edx ecx eax
        return

.second_try:
        stdcall Sleep, 200      ; wait a little.

        cinvoke XOpenDisplay, 0
        test    eax, eax
        jnz     .continue

.exit_error:
        Message 'Error open display.'
        stc
        pop     edx ecx eax
        return




endp




proc TApplication.Get, .obj, .paramID
begin
        stc
        return
endp



proc TApplication.Set, .obj, .paramID, .value
begin
        stc
        return
endp



proc TApplication.SysEventHandler
begin
        clc
        return
endp




cXErrorMsg text 'X server error:'
cXErrorMsg2 text 10, 0
cXErrorMsg3 text 'Request: '
cXErrorMsg4 text 'Minor code: '
cXErrorMsg5 text 'ResourceID: $'

proc __FreshXErrorHandler, .display, .error
.buff rb 256
begin
if (defined options.DebugMode) & options.DebugMode
        cmp     [fGlobalTerminate], 0
        jne     .exit

        stdcall Output, cXErrorMsg
        mov      ebx, [.error]

        movzx    eax, [ebx+XErrorEvent.error_code]
        lea      ecx, [.buff]
        cinvoke XGetErrorText, [.display], eax, ecx, 256

        lea     ecx, [.buff]
        stdcall Output, ecx
        stdcall Output, cXErrorMsg2

        stdcall Output, cXErrorMsg3
        movzx    eax, [ebx+XErrorEvent.request_code]
        stdcall OutputNumber, eax, 10, 3
        stdcall Output, cXErrorMsg2

        stdcall Output, cXErrorMsg4
        movzx    eax, [ebx+XErrorEvent.minor_code]
        stdcall OutputNumber, eax, 10, 3
        stdcall Output, cXErrorMsg2

        stdcall Output, cXErrorMsg5
        stdcall OutputNumber, [ebx+XErrorEvent.resourceid], 16, 8
        stdcall Output, cXErrorMsg2
        stdcall Output, cXErrorMsg2
end if
.exit:
        cret
endp




; This code and data possibly will be used in FreshLib, but I hope, not very soon. :)

;        cinvoke XInternAtom, [hApplicationDisplay], _cWinSyncRequest, 0
;        mov     [atomSyncRequest], eax
;
;
;        cinvoke XInternAtom, [hApplicationDisplay], _cAtomTypeAtom, 0
;        mov     [atomTypeATOM], eax
;
;; _NET_WM_WINDOW_TYPE
;        cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeAtomName, 0
;        mov     [atomWMType], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeDlg, 0
;        mov     [atomWinTypeDlg], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeTool, 0
;        mov     [atomWinTypeTool], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeDock, 0
;        mov     [atomWinTypeDock], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeNormal, 0
;        mov     [atomWinTypeNormal], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], atomAllowedActions.text, 0
;        mov     [atomAllowedActions], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], atomAllowedActions.minimize.text, 0
;        mov     [atomAllowedActions.minimize], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], atomAllowedActions.close.text, 0
;        mov     [atomAllowedActions.close], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], atomWMState.text, 0
;        mov     [atomWMState], eax
;
;        cinvoke XInternAtom, [hApplicationDisplay], atomWMState.modal.text, 0
;        mov     [atomWMState.modal], eax
;

;_cWinTypeAtomName text '_NET_WM_WINDOW_TYPE'
;  _cWinTypeDlg      text '_NET_WM_WINDOW_TYPE_DIALOG'
;  _cWinTypeTool     text '_NET_WM_WINDOW_TYPE_TOOLBAR'          ; it is with normal toolbar, but with only close button.
;  _cWinTypeDock     text '_NET_WM_WINDOW_TYPE_DOCK'             ; without title bar and above all other windows???
;  _cWinTypeNormal   text '_NET_WM_WINDOW_TYPE_NORMAL'

;_cWinSyncRequest  text '_NET_WM_SYNC_REQUEST'
;_cAtomTypeAtom  text 'ATOM'

; notes on different types, regarding XFWM window manager:
;  _NET_WM_WINDOW_TYPE_SPLASH - no title, goes up on activation.
;  _NET_WM_WINDOW_TYPE_DOCK   - no title, always on top
;  _NET_WM_WINDOW_TYPE_DROPDOWN_MENU - ???
;  _NET_WM_WINDOW_TYPE_NOTIFICATION - ???
;  _
;


;macro atomset lbl, name, [valname, value] {
;common
;  lbl dd ?
;forward
;  valname dd ?
;common
;  lbl#.text text `name
;forward
;  lbl#valname#.text text `value
;}
;

;uglobal
;  atomSyncRequest dd ?
;
;  atomTypeATOM  dd ?
;
;  atomWMType          dd ?
;    atomWinTypeDlg      dd ?
;    atomWinTypeTool     dd ?
;    atomWinTypeDock     dd ?
;    atomWinTypeNormal   dd ?
;endg
;
;
;iglobal
;  atomset atomAllowedActions, _NET_WM_ALLOWED_ACTIONS,    \
;            .move, _NET_WM_ACTION_MOVE,                     \
;            .resize, _NET_WM_ACTION_RESIZE,                 \
;            .minimize, _NET_WM_ACTION_MINIMIZE,             \
;            .shade, _NET_WM_ACTION_SHADE,                   \
;            .stick, _NET_WM_ACTION_STICK,                   \
;            .maximize_horz, _NET_WM_ACTION_MAXIMIZE_HORZ,   \
;            .maximize_vert, _NET_WM_ACTION_MAXIMIZE_VERT,   \
;            .fullscreen, _NET_WM_ACTION_FULLSCREEN,         \
;            .change_desktop, _NET_WM_ACTION_CHANGE_DESKTOP, \
;            .close, _NET_WM_ACTION_CLOSE
;
;  atomset atomWMState, _NET_WM_STATE,           \
;            .modal, _NET_WM_STATE_MODAL
;
;endg
;
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/gui/Linux/keycodes.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: This file contains scan code values for control keyboard keys.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

keyHomeNumpad   = $ff95
keyUpNumpad     = $ff97
keyPgUpNumpad   = $ff9a
keyLeftNumpad   = $ff96
key5Numpad      = $ff9d
keyRightNumpad  = $ff98
keyEndNumpad    = $ff9c
keyDownNumpad   = $ff99
keyPgDnNumpad   = $ff9b
keyInsNumpad    = $ff9e
keyDelNumpad    = $ff9f
keyEnterNumpad  = $ff8d
keyPlusNumpad   = $ffab
keyMinusNumpad  = $ffad
keyAsteriskNumpad = $ffaa
keySlashNumpad  = $ffaf

keyNumLock      = $ff7f
keyScrollLock   = $ff14
keyPause        = $ff13


keyLeft         = $ff51
keyRight        = $ff53
keyUp           = $ff52
keyDown         = $ff54

keyInsert       = $ff63
keyDelete       = $ffff
keyHome         = $ff50
keyEnd          = $ff57
keyPgUp         = $ff55
keyPgDown       = $ff56

keyF1           =  $ffbe
keyF2           =  $ffbf
keyF3           =  $ffc0
keyF4           =  $ffc1

keyF5           =  $ffc2
keyF6           =  $ffc3
keyF7           =  $ffc4
keyF8           =  $ffc5

keyF9           =  $ffc6
keyF10          =  $ffc7
keyF11          =  $ffc8
keyF12          =  $ffc9

keyCapsLock     = $ffe5
keyShiftLeft    = $ffe1
keyCtrlLeft     = $ffe3
;keyWndLeft     =
;keyWndRight    =
keyAltLeft      = $ffe9
keyAltRight     = $ffea
keyPopupMenu    = $ff67
keyShiftRight   = $ffe2
keyCtrlRight    = $ffe4
keyBackSpace    = $ff08
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































Deleted freshlib/gui/Linux/mouse.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Provides unified access to standard mouse cursors.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

iglobal
  if used _Xcursors
    _Xcursors db 68, 152, 34, 108, 116, 40, 40, 150   ; X standard cursor font
  end if
endg


uglobal
  if used StockCursors
    StockCursors rd mcCount
  end if
endg


proc InitMouseCursors
begin
        push    eax ecx edx ebx
        mov     ebx, mcCount-1

.create_cursor_loop:
        movzx   eax, [_Xcursors+ebx]
        cinvoke XCreateFontCursor, [hApplicationDisplay], eax
        mov     [StockCursors+4*ebx], eax

        dec     ebx
        jns     .create_cursor_loop
        pop     ebx edx ecx eax
        return
endp



if used InitMouseCursors
finalize FinalizeMouseCursors
begin
        mov     ebx, mcCount-1
        cmp     [hApplicationDisplay], 0
        je      .exit

.free_cursor_loop:
        cinvoke XFreeCursor, [hApplicationDisplay], [StockCursors+4*ebx]
        dec     ebx
        jns     .free_cursor_loop

.exit:
        return
endp
end if


proc SetMouseCursor, .hCursor
begin
        push    eax ecx edx
        cinvoke XDefineCursor, [hApplicationDisplay], [hRootWindow], [.hCursor]
        pop     edx ecx eax
        return
endp



proc GetStockCursor, .index
begin
        mov     eax, [.index]
        and     eax, 7
        mov     eax, [StockCursors+4*eax]
        return
endp


proc MouseCapture, .hwnd
begin
        push    eax ecx edx
        cmp     [.hwnd], 0
        je      .release

        cinvoke XGrabPointer, [hApplicationDisplay], [.hwnd], FALSE, PointerMotionMask or ButtonPressMask or ButtonReleaseMask, \
                              GrabModeAsync, GrabModeAsync, None, None, CurrentTime

.finish:
        pop     edx ecx eax
        return

.release:
        cinvoke XUngrabPointer, [hApplicationDisplay], CurrentTime
        jmp     .finish
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































Deleted freshlib/gui/Linux/windows.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Window management OS interface functions.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


proc _CreateNullWindow
.attr XSetWindowAttributes
begin
        push    ecx edx esi

        lea     eax, [.attr]
        mov     [eax+XSetWindowAttributes.override_redirect], 1
        mov     [eax+XSetWindowAttributes.backing_store], NotUseful
        mov     [eax+XSetWindowAttributes.background_pixmap], None
        cinvoke XCreateWindow, [hApplicationDisplay], [hRootWindow], 0, 0, 1, 1, 0, CopyFromParent, InputOutput, CopyFromParent,  CWBackingStore or CWOverrideRedirect or CWBackPixmap, eax
        mov     esi, eax
        test    eax, eax
        jz      .exit

        cinvoke XSelectInput, [hApplicationDisplay], esi, ExposureMask or StructureNotifyMask or FocusChangeMask or   \
                                                          KeyPressMask or KeyReleaseMask or            \
                                                          ButtonPressMask or ButtonReleaseMask or      \
                                                          EnterWindowMask or LeaveWindowMask or        \
                                                          PointerMotionMask

        cinvoke XSetWMProtocols, [hApplicationDisplay], esi, atomWMDelete, 1
        mov     eax, esi
.exit:
        pop     esi edx ecx
        return
endp



;_________________________________________________________________________________________



proc _DestroyWindow, .hwnd
begin
        push    eax ecx edx
        stdcall _SetWindowStruct, [.hwnd], 0
        cinvoke XDestroyWindow, [hApplicationDisplay], [.hwnd]
        pop     edx ecx eax
        return
endp



;_________________________________________________________________________________________



proc _GetParent, .hwnd
.root dd ?
.parent dd ?
.children dd ?
.count    dd ?
begin
        push    ecx edx esi

        lea     esi, [.count]
        lea     edx, [.children]
        lea     ecx, [.parent]
        lea     eax, [.root]
        cinvoke XQueryTree, [hApplicationDisplay], [.hwnd], eax, ecx, edx, esi
        test    eax, eax
        jz      .exit   ; function failed

        cinvoke XFree, [.children]

        mov     eax, [.parent]

.exit:
        pop     esi edx ecx
        return
endp



;_________________________________________________________________________________________


proc _GetChildren, .hwnd
  .root dd ?
  .parent dd ?
  .children dd ?
  .count    dd ?
begin
        push    ebx ecx edx esi


        lea     ebx, [.count]
        lea     edx, [.children]
        lea     ecx, [.parent]
        lea     eax, [.root]
        cinvoke XQueryTree, [hApplicationDisplay], [.hwnd], eax, ecx, edx, ebx
        test    eax, eax
        jz      .exit   ; function failed

        xor     ebx, ebx
        mov     esi, [.children]
        test    esi, esi
        jz      .endchildren

        stdcall CreateArray, sizeof.TWinArrayItem
        mov     ebx, eax
        mov     ecx, [.count]

.loophwnd:
        dec     ecx
        js      .endchildren_free

        stdcall AddArrayItems, ebx, 1
        mov     ebx, edx

        mov     edx, [esi+4*ecx]
        mov     [eax+TWinArrayItem.handle], edx

        jmp     .loophwnd

.endchildren_free:
        cinvoke XFree, esi

.endchildren:
        mov     eax, ebx
.exit:
        pop     esi edx ecx ebx
        return
endp


;_________________________________________________________________________________________



proc _GetVisible, .hwnd
.attr XWindowAttributes
begin
        push    ebx ecx edx

        lea     ebx, [.attr]
        cinvoke XGetWindowAttributes, [hApplicationDisplay], [.hwnd], ebx
        mov     eax, [ebx+XWindowAttributes.map_state]
        test    eax, eax
        jz      @f
        mov     eax, 1
@@:
        pop     edx ecx ebx
        return
endp

;_________________________________________________________________________________________


proc _GetWindowBounds, .hwnd, .pBounds
begin
        push    eax ecx edx

        int3
        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc _SetWindowBounds, .hwnd, .pBounds
  .wch XWindowChanges
begin
        push    eax ecx edx

        lea     eax, [.wch]
        mov     edx, [.pBounds]

        push    [edx+TBounds.x] [edx+TBounds.y] [edx+TBounds.width] [edx+TBounds.height]
        pop     [.wch.height] [.wch.width] [.wch.y] [.wch.x]

        cmp     [.wch.width], 0
        jnz     @f
        inc     [.wch.width]
@@:
        cmp     [.wch.height], 0
        jnz     @f
        inc     [.wch.height]
@@:
        cinvoke XConfigureWindow, [hApplicationDisplay], [.hwnd], CWX or CWY or CWWidth or CWHeight, eax

        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________



proc _SetWindowBorder, .hwnd, .brdType
  .attr XSetWindowAttributes
begin
        push    eax ecx edx

        mov     [.attr.override_redirect], 1
        cmp     [.brdType], borderNone
        je      @f
        mov     [.attr.override_redirect], 0
@@:
        lea     eax, [.attr]
        cinvoke XChangeWindowAttributes, [hApplicationDisplay], [.hwnd], CWOverrideRedirect, eax

        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________


proc _ShowWindow, .hwnd, .flag
begin
        push    eax ecx edx

        mov     ecx, XUnmapWindow
        cmp     [.flag], 0
        je      @f
        mov     ecx, XMapWindow
@@:
        push    [.hwnd] [hApplicationDisplay]
        call    dword [ecx]
        add     esp, 8

        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc _RefreshWindow, .hwnd
begin
        push    eax ecx edx
        cinvoke XClearArea, [hApplicationDisplay], [.hwnd], 0, 0, 0, 0, TRUE
        cinvoke XFlush, [hApplicationDisplay]
        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc _SetFocus, .hwnd
begin
        push    eax ecx edx
        cinvoke XSetInputFocus, [hApplicationDisplay], [.hwnd], RevertToParent, CurrentTime
        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________

proc _AddChild, .hwnd, .child
begin
        push    eax ecx edx
        cinvoke XReparentWindow, [hApplicationDisplay], [.child], [.hwnd], 10, 10
        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________


proc _SetWindowTextUtf8, .hwnd, .ptrUtf8
begin
        push    eax ecx edx
        cinvoke XStoreName, [hApplicationDisplay], [.hwnd], [.ptrUtf8]
        pop     edx ecx eax
        return
endp



;_________________________________________________________________________________________



proc _GetWindowTextUtf8, .hwnd, .ptrUtf8
begin
        return
endp




;_________________________________________________________________________________________

proc _EnableWindow, .hwnd, .flag
begin
        push    eax ecx edx

        stdcall _GetChildren, [.hwnd]
        test    eax, eax
        jz      .children_ok

        mov     edx, [eax+TArray.count]
.child_loop:
        dec     edx
        js      .end_children

        stdcall _EnableWindow, [eax+TArray.array+sizeof.TWinArrayItem*edx+TWinArrayItem.handle], [.flag]
        jmp     .child_loop

.end_children:
        stdcall FreeMem, eax

.children_ok:
        mov     ecx, ExposureMask or StructureNotifyMask or EnterWindowMask or LeaveWindowMask or PointerMotionMask
        cmp     [.flag], 0
        je      @f
        or      ecx, FocusChangeMask or KeyPressMask or KeyReleaseMask or    \
                     ButtonPressMask or ButtonReleaseMask
@@:
        cinvoke XSelectInput, [hApplicationDisplay], [.hwnd], ecx

        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________

proc _SetModalTowards, .hwnd, .hwndParent
begin
        push    eax ecx edx
        cinvoke XSetTransientForHint, [hApplicationDisplay], [.hwnd], [.hwndParent]
        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________

proc _FinalizeModal, .hwnd, .hwndParent
  .flushevent XEvent
begin
        push    eax ecx edx

        DebugMsg "Finalize modal"

; dirty hack, but the button receives LeaveNotify after DestroyNotify
        cinvoke XSync, [hApplicationDisplay], FALSE
.loop_flush:
        lea     eax, [.flushevent]
        cinvoke XCheckMaskEvent, [hApplicationDisplay], LeaveWindowMask, eax
        test    eax, eax
        jnz     .loop_flush

        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


win_structure_context = 1


proc _GetWindowStruct, .hwin
  .user_data dd ?
begin
        push    ecx edx
        lea     eax, [.user_data]
        cinvoke XFindContext, [hApplicationDisplay], [.hwin], win_structure_context, eax
        test    eax, eax
        jnz     .error

        mov     eax, [.user_data]
        clc
        pop     edx ecx
        return

.error:
        DebugMsg 'FreshLib: Error find context.'
        mov      edx, [ebp+4]
        OutputRegister regEDX, 16

        xor      eax, eax
        pop      edx ecx
        return
endp




;_________________________________________________________________________________________



proc _SetWindowStruct, .hwin, .value
begin
        push    eax ecx edx
        cinvoke XSaveContext, [hApplicationDisplay], [.hwin], win_structure_context, [.value]
        pop     edx ecx eax
        return
endp






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/gui/Main.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Main procedure of GUI application library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Organize the main message/event loop needed by every GUI engine.
;         This file contains only OS independent part and includes OS dependent files.
;_________________________________________________________________________________________
module "Main library"

uglobal
  if used pApplication
    pApplication dd ?
  end if
endg


proc Run
begin
.mainloop:
        stdcall ProcessSystemEvents
        jc      .terminate

        mov     eax, [pApplication]
        test    eax, eax
        jz      .eventok

        cmp     [eax+TApplication.OnIdle], 0
        je      .eventok

        pushad
        stdcall [eax+TApplication.OnIdle], eax
        popad

.eventok:
        stdcall WaitForSystemEvent
        jmp     .mainloop

.terminate:
        return
endp




proc ShowModal, .pForm, .pParent
.prev dd ?
begin
        push    ecx edx
        mov     ecx, [.pParent]
        mov     edx, [.pForm]

        jecxz   @f
        stdcall _SetModalTowards, [edx+TForm.handle], [ecx+TWindow.handle]
@@:
        stdcall Set, edx, TForm.Visible, TRUE

        jecxz   @f
        stdcall _EnableWindow, [ecx+TWindow.handle], FALSE
@@:

        mov     [edx+TForm.ModalResult], 0

        stdcall Get, edx, TForm.OnClose
        mov     [.prev], eax
        stdcall Set, edx, TForm.OnClose, __ModalOnClose

.modal_loop:
        stdcall ProcessSystemEvents
        jc      .exit_modal

        cmp     [edx+TForm.ModalResult], 0
        jne     .exit_modal

        stdcall Get, edx, TWindow.Visible
        test    eax, eax
        jz      .exit_modal

.vis_ok:
        stdcall WaitForSystemEvent
        jmp     .modal_loop

.exit_modal:
        jecxz   @f
        stdcall _EnableWindow, [ecx+TWindow.handle], TRUE
@@:

        stdcall Set, edx, TForm.OnClose, [.prev]
        stdcall Set, edx, TForm.Visible, FALSE

        jecxz   @f
        mov     ecx, [ecx+TWindow.handle]
@@:
        stdcall _FinalizeModal, [edx+TForm.handle], ecx

        mov     eax, [edx+TForm.ModalResult]
        pop     edx ecx
        return
endp


; prevent destroy of the form from the close button or Alt+F4
proc __ModalOnClose, .self, .reason
begin
        push    eax
        mov     eax, [.self]
        mov     [eax+TForm.ModalResult], mrCancel
        stc
        pop     eax
        return
endp





include '%TargetOS%/Main.asm'

endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































Deleted freshlib/gui/ObjTemplates.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Objects template engine
;
;  Target OS: Any
;
;  Dependencies: objects.asm
;
;  Notes:
;_________________________________________________________________________________________
module "Templates library"

tfChild  = 0
tfParent = 1
tfEnd    = 2


struct TObjTemplate
  .flags     dd  ?         ; tfParent; tfEnd
  .class     dd  ?
  .ptrVar    dd  ?         ; can be NULL
  .paramsize dd  ?
  .params:
ends


macro ObjTemplate  flags, class, name, [id, param] {
common
local ..paramsize, ..prms
      dd  flags
      dd  C#class
      dd  name
      dd  ..paramsize
..prms:
forward
local ..value
      dd  T#class#.#id
      dd  ..value
common
      dd  -1
forward
  if param eqtype 2
    ..value = param
  else
    ..value db param, 0
  end if
common
  name dd ?
  ..paramsize = $ - ..prms
}


; returns the last created window in ebx.

proc CreateFromTemplate, .ptrTemplate, .parent
begin
        push    esi

        mov     esi, [.ptrTemplate]
        stdcall _DoCreateFromTemplate, [.parent]

        pop     esi
        return
endp


proc _DoCreateFromTemplate, .parent
begin
        push    eax ecx edx

.createloop:
        stdcall Create, [esi+TObjTemplate.class]
        execute [.parent], TObject.AddChild, ebx

        lea     ecx, [esi+TObjTemplate.params]

.paramloop:
        cmp     dword [ecx], -1
        je      .paramsok

        push    ebx ecx edx esi edi
        stdcall Set, ebx, [ecx], [ecx+4]
        pop     edi esi edx ecx ebx
        add     ecx, 8
        jmp     .paramloop

.paramsok:
        mov     eax, [esi+TObjTemplate.ptrVar]
        test    eax, eax
        jz      .oncreate

        mov     [ebx+TObject.ptrVar], eax       ; back link to the object instance variable.
        mov     [eax], ebx      ; returned pointer/handle to the object.

.oncreate:
        cmp     [ebx+TObject.OnCreate], 0
        je      .gonext

; execute user OnCreate event.
        pushad
        stdcall [ebx+TObject.OnCreate], ebx
        popad

.gonext:
        mov     edx, [esi+TObjTemplate.flags]

        mov     eax, sizeof.TObjTemplate
        add     eax, [esi+TObjTemplate.paramsize]
        add     esi, eax

        test    edx, tfParent
        jz      .childrenok

        push    ebx
        stdcall _DoCreateFromTemplate, ebx
        pop     ebx

.childrenok:
        test    edx, tfEnd
        jz      .createloop

.exit:
        pop     edx ecx eax
        return
endp


endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































Deleted freshlib/gui/TAction.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Actions management library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: "Action" is set of executable code, combined with user interface attributes -
;         caption, accelerator keys, enable/disable status flag etc.
;         Different UI elements, such as buttons, menu items etc. can be attached to
;         the action object and to use its attributes. When the programmer changes
;         something in the action, all UI elements are updated automatically.
;_________________________________________________________________________________________

struc TAction caption, hint, icon, FastKey, enabled, OnExecute, OnIdle {
common
  .Text      dd  caption    ; handle or pointer to the caption string.
  .Hint      dd  hint       ; handle or pointer to the Hint text.
  .icon      dd  icon       ; pointer to TImage
  .FastKey   dd  FastKey    ; pointer to keyboard accelerator combination.
  .Enabled   dd  enabled    ; if FALSE, the action is not active.
  .OnExecute dd  OnExecute  ; pointer to procedure to be executed on activation of the action.
  .OnIdle    dd  OnIdle     ; pointer to procedure that to be executed once, when there is no other events in the queue.
}

virtual at 0
  TAction TAction ?, ?, ?, ?, ?, ?, ?
end virtual


struc TFastKey flags, key, action {
  .flags  dd flags
  .key    dd key
  .action dd action
}
virtual at 0
  TFastKey TFastKey ?, ?, ?
end virtual


struct TActionList
  .count dd ?
  .accelerators dd ?
  .actions:
ends



macro ActionList name, [actname, caption, hint, icon, FastKey, OnExecute, OnIdle] {
common
  local i, count, acclist
  i = 0
  label name dword
  .count dd count
  .accelerators dd acclist
forward
  local .accitem, txtlbl, hintlbl

  txtlbl text caption
  hintlbl text hint

  actname TAction txtlbl, hintlbl, icon, accitem, 1, OnExecute, OnIdle

  i = i + 1
common
  count = i
  label acclist dword

forward
  if FastKey eq NONE
    accitem = 0
  else
    .accitem TFastKey FastKey, name#actname
  end if
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































Deleted freshlib/gui/TApplication.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TApplication object class.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: TApplication by the idea is the base of GUI application, but the implementation
;         somehow need fixing...
;_________________________________________________________________________________________
module "TApplication library"

ObjectClass Application,        \
    Object,                     \
    TApplication.Create,        \
    0,                          \
    TApplication.Get,           \
    TApplication.Set,           \
    0,                          \
    TApplication.SysEventHandler



; The root object in the application.
; every other object will be child on the TApplication.MainWindow.
; only one instance of TApplication should be created.
;
object TApplication, TObject
  .MainWindow   dd ?    ; pointer to a variable that contains pointer to the main window of the application. When this variable becomes 0 the application terminates.
  .Accelerators dd ?    ; table of application wide hot keys.
  .OnIdle       dd ?    ; user event handler for idle state.
endobj


include '%TargetOS%/TApplication.asm'


endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































Deleted freshlib/gui/TButton.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TButton object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Represents GUI button.
;_________________________________________________________________________________________
module "TButton library"

ObjectClass Button,                     \
            Window,                     \
            0,                          \
            0,                          \
            TButton.Get,                \
            TButton.Set,                \
            0,                          \
            TButton.SysEventHandler


; Button states for the field TButton.state
btnNormal    = 0
btnPressed   = 1
btnPointed   = 2
btnChecked   = 3




object TButton, TWindow
  .state      dd ?
  .Ficon      dd ?
  .FiconAlign dd ?
  .Ftextalign dd ?

  .ModalResult dd ?
  .OnClick dd ?

  param .TextAlign
  param .Icon
  param .IconPosition
endobj



proc TButton.Get, .obj, .paramID
begin
        mov     eax, [.obj]

        stdcall IsObject, eax, CButton
        jc      .exit

        cmp     [.paramID], TButton.TextAlign
        je      .gettextalign

        cmp     [.paramID], TButton.IconPosition
        je      .geticonposition

        cmp     [.paramID], TButton.Icon
        je      .geticon

        stc
.exit:
        return

.geticonposition:
        mov     eax, [eax+TButton.FiconAlign]
        clc
        return

.geticon:
        mov     eax, [eax+TButton.Ficon]
        clc
        return

.gettextalign:
        mov     eax, [eax+TButton.Ftextalign]
        clc
        return
endp





dproc TButton.Set, .obj, .paramID, .value
begin
        push    eax ecx
        mov     ecx, [.obj]

dispatch [.paramID]

        stc
        pop     ecx eax
        return

.refresh:
        execute [.obj], TWindow.Refresh
        clc
        pop     ecx eax
        return


oncase TButton.TextAlign
        push    [.value]
        pop     [ecx+TButton.Ftextalign]
        jmp     .refresh


oncase TButton.Icon
        push    [.value]
        pop     [ecx+TButton.Ficon]
        jmp     .refresh


oncase TButton.IconPosition
        push    [.value]
        pop     [ecx+TButton.FiconAlign]
        jmp     .refresh

enddp




dproc TButton.SysEventHandler, .pObj, .pEvent
begin
        pushad

        mov     esi, [.pObj]
        mov     ebx, [.pEvent]

        dispatch [ebx+TSysEvent.event]

.finish:
        stc
        popad
        return


;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

oncase sePaint
; PAINT event is very important.
        mov     edx, bxFlat
        mov     edi, [clButtonBk]       ; background
        mov     ecx, [clButtonTxt]      ; text

        cmp     [esi+TButton.state], btnNormal
        je      .drawit

        mov     edx, bxRaised
        mov     edi, [clButtonHotBk]
        mov     ecx, [clButtonHotTxt]

        cmp     [esi+TButton.state], btnPointed
        je      .drawit

        mov     edx, bxSunken
        mov     edi, [clButtonBk]
        mov     ecx, [clButtonHotTxt]

        cmp     [esi+TButton.state], btnPressed
        je      .drawit

        mov     edx, bxFlat

.drawit:
locals
 .bounds TBounds
 .clTxt dd ?
endl
        mov     [.clTxt], ecx

        mov     ecx, [esi+TButton._width]
        mov     eax, [esi+TButton._height]
        mov     [.bounds.x], 0
        mov     [.bounds.y], 0
        mov     [.bounds.width], ecx
        mov     [.bounds.height], eax
        lea     eax, [.bounds]
        stdcall [DrawBox], [ebx+TPaintEvent.context], eax, edi, edx

; first draw the icon and then resize bounds for the text.
        mov     edi, [esi+TButton.Ficon]
        test    edi, edi
        jz      .draw_text

        cmp     [esi+TButton.FiconAlign], AlignLeft
        jne     @f

; align left
        mov     eax, [.bounds.x]
        mov     ecx, [.bounds.height]
        add     eax, 2
        sub     ecx, [edi+TImage.height]
        sar     ecx, 1
        add     ecx, [.bounds.y]

        mov     edx, [edi+TImage.width]
        add     edx, 4
        add     [.bounds.x], edx
        sub     [.bounds.width], edx
        jmp     .draw_icon

@@:
        cmp     [esi+TButton.FiconAlign], AlignRight
        jne     @f

; align right
        mov     edx, [edi+TImage.width]

        mov     eax, [.bounds.x]
        add     eax, [.bounds.width]
        sub     eax, edx
        sub     eax, 2
        sub     [.bounds.width], edx
        sub     [.bounds.width], 4

        mov     ecx, [.bounds.height]
        sub     ecx, [edi+TImage.height]
        sar     ecx, 1
        add     ecx, [.bounds.y]
        jmp     .draw_icon

@@:
        cmp     [esi+TButton.FiconAlign], AlignTop
        jne     @f

; align top
        mov     ecx, [.bounds.y]
        add     ecx, 2
        mov     eax, [.bounds.width]
        sub     eax, [edi+TImage.width]
        sar     eax, 1
        add     eax, [.bounds.x]

        mov     edx, [edi+TImage.height]
        add     edx, 4
        add     [.bounds.y], edx
        sub     [.bounds.height], edx
        jmp     .draw_icon

@@:
        cmp     [esi+TButton.FiconAlign], AlignBottom
        jne     .draw_text

; align bottom
        mov     edx, [edi+TImage.height]

        mov     ecx, [.bounds.y]
        add     ecx, [.bounds.height]
        sub     ecx, edx
        sub     ecx, 2
        sub     [.bounds.height], edx
        sub     [.bounds.height], 4

        mov     eax, [.bounds.width]
        sub     eax, [edi+TImage.width]
        sar     eax, 1
        add     eax, [.bounds.x]

.draw_icon:
        stdcall DrawImage, [ebx+TPaintEvent.context], [esi+TButton.Ficon], eax, ecx

.draw_text:
        stdcall Get, esi, TWindow.Caption
        test    eax, eax
        jz      .finish

        push    eax eax
        stdcall StrLen, eax
        mov     ecx, eax
        pop     eax
        lea     edx, [.bounds]
        stdcall DrawTextBox, [ebx+TPaintEvent.context], eax, edx, [esi+TButton.Ftextalign], 0, [.clTxt]
        stdcall StrDel ; from the stack
        jmp     .finish


;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

oncase seMouseEnter
        mov     [esi+TButton.state], btnPointed
        execute esi, TButton.Refresh
        jmp     .finish


;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


oncase seMouseLeave
        mov     [esi+TButton.state], btnNormal
        execute esi, TButton.Refresh
        jmp     .finish


;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


oncase seMouseBtnPress
        mov     [esi+TButton.state], btnPressed
        execute esi, TWindow.Refresh
        jmp     .finish


;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


oncase seMouseBtnRelease

        cmp     [esi+TButton.state], btnPressed
        jne     .finish

        mov     [esi+TButton.state], btnPointed
        execute esi, TButton.Refresh

        cmp     [esi+TButton.ModalResult], mrNone
        je      @f

        stdcall Get, esi, TButton.Parent
        stdcall IsObject, eax, CForm
        jc      @f

        push    [esi+TButton.ModalResult]
        pop     [eax+TForm.ModalResult]

@@:
        cmp     [esi+TButton.OnClick], 0
        je      .finish

        stdcall [esi+TButton.OnClick], esi, [ebx+TMouseButtonEvent.Button]
        jmp     .finish
enddp


endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/gui/TEdit.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TEdit object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Represents single line edit control.
;_________________________________________________________________________________________
module "TEdit library"

ObjectClass Edit,                       \
            Window,                     \
            TEdit.Create,               \
            TEdit.Destroy,              \
            TEdit.Get,                  \
            TEdit.Set,                  \
            0,                          \
            TEdit.SysEventHandler


object TEdit, TWindow
  ._Text  dd ?
  ._Len   dd ?  ; the length of the string in characters. (UTF-8)
  ._Start dd ?  ; Where the string begins to be displayed in the edit window.
  ._Pos   dd ?  ; Position of the caret in the string.
  ._Sel   dd ?  ; Position of the selction in the string.

  ._MarginLeft dd ?
  ._MarginRight dd ?

  ._Focused dd ? ; flag

  param .Text
endobj


proc TEdit.Create, .obj
begin
        push    ecx eax
        stdcall StrNew
        mov     ecx, [.obj]
        mov     [ecx+TEdit._Text], eax

; for test. Normal value is 0 for these fields.
;        mov     [ecx+TEdit._MarginLeft], 8
;        mov     [ecx+TEdit._MarginRight], 16

        mov     [ecx+TEdit._cursor], mcText

        pop     eax ecx
        clc
        return
endp


proc TEdit.Destroy, .obj
begin
        mov     eax, [.obj]
        stdcall StrDel, [eax+TEdit._Text]
        return
endp


proc TEdit.Get, .obj, .paramID
begin
        stdcall IsObject, [.obj], CEdit
        jc      .exit

        cmp     [.paramID], TEdit.Text
        je      .gettext

        stc
.exit:
        return

.gettext:
        mov     eax, [.obj]
        stdcall StrDup, [eax+TEdit._Text]
        clc
        return
endp




proc TEdit.Set, .obj, .paramID, .value
begin
        push    esi

        mov     esi, [.obj]

        cmp     [.paramID], TEdit.Text
        je      .settext

        stc
        pop     esi
        return

.settext:
        push    eax
        mov     [esi+TEdit._Start], 0
        mov     [esi+TEdit._Pos], 0
        mov     [esi+TEdit._Sel], 0

        lea     eax, [esi+TEdit._Text]
        stdcall SetString, eax, [.value]
        stdcall StrLenUtf8, [esi+TEdit._Text], -1
        mov     [esi+TEdit._Len], eax

        execute esi, TEdit.Refresh
        clc
        pop     eax
        pop     esi
        return
endp






proc TEdit.SysEventHandler, .pObj, .pEvent
.changes dd ?
.prevpos dd ?
.PosChanged  = 1
.NeedRefresh = 2
.ShowCaret   = 4
begin
        push    eax ebx ecx edx esi edi

        mov     [.changes], 0
        mov     esi, [.pObj]
        mov     ebx, [.pEvent]
        mov     eax, [ebx+TSysEvent.event]

        cmp     eax, sePaint
        je      .onpaint

        cmp     eax, seKbdKeyPress
        je      .keypress

        cmp     eax, seFocusIn
        je      .focusin

        cmp     eax, seFocusOut
        je      .focusout

.finish:
        stc
        pop     edi esi edx ecx ebx eax
        return

;............................................................................................

.focusin:
        mov     [esi+TEdit._Focused], TRUE
        stdcall CaretAttach, esi
        or      [.changes], .PosChanged or .ShowCaret
        jmp     .endmove

.focusout:
        stdcall CaretShow, FALSE
        mov     [esi+TEdit._Focused], FALSE
        or      [.changes], .PosChanged
        jmp     .endmove

;............................................................................................

.keypress:
;        mov     eax, [ebx+TKeyboardEvent.kbdStatus]
;        OutputRegister regEAX, 16

        mov     eax, [esi+TEdit._Pos]
        mov     [.prevpos], eax

        mov     eax, [ebx+TKeyboardEvent.key]
        test    eax, eax
        jz      .no_char

        cmp     eax, $20
        jb      .no_char

        cmp     eax, $7f
        je      .no_char

        push    eax

        call    .ClearSelection

        stdcall StrPtr, [esi+TEdit._Text]
        mov     ecx, eax
        stdcall StrOffsUtf8, eax, [esi+TEdit._Pos]
        sub     ecx, eax
        neg     ecx

        pop     eax
        stdcall StrCharInsert, [esi+TEdit._Text], eax, ecx
        inc     [esi+TEdit._Len]

        mov     [ebx+TKeyboardEvent.kbdStatus], 0
        or      [.changes], .NeedRefresh
        jmp     .right

.no_char:
        mov     eax, [ebx+TKeyboardEvent.scancode]

        cmp     eax, keyLeftNumpad
        je      .left
        cmp     eax, keyLeft
        je      .left

        cmp     eax, keyRightNumpad
        je      .right
        cmp     eax, keyRight
        je      .right

        cmp     eax, keyHomeNumpad
        je      .home
        cmp     eax, keyHome
        je      .home

        cmp     eax, keyEndNumpad
        je      .end
        cmp     eax, keyEnd
        je      .end

        cmp     eax, keyDelNumpad
        je      .del
        cmp     eax, keyDelete
        je      .del

        cmp     eax, keyBackSpace
        je      .backdel

        jmp     .finish

.left:
        cmp     [esi+TEdit._Pos], 0
        jle     .endmove

        or      [.changes], .PosChanged
        dec     [esi+TEdit._Pos]
        jmp     .endmove

.right:
        mov     eax, [esi+TEdit._Pos]
        cmp     eax, [esi+TEdit._Len]
        jae     .finish

        or      [.changes], .PosChanged
        inc     [esi+TEdit._Pos]
        jmp     .endmove

.home:
        mov     [esi+TEdit._Pos], 0
        mov     [esi+TEdit._Start], 0
        mov     [.changes], .PosChanged or .NeedRefresh
        jmp     .endmove

.end:
        mov     eax, [esi+TEdit._Len]
        mov     [esi+TEdit._Pos], eax
        or      [.changes], .PosChanged
        jmp     .endmove

.backdel:
        call    .ClearSelection
        jnc     .endmove

        cmp     [esi+TEdit._Pos], 0
        jle     .endmove

        or      [.changes], .PosChanged
        dec     [esi+TEdit._Pos]

.del:
        call    .ClearSelection
        jnc     .endmove

        mov     eax, [esi+TEdit._Pos]
        cmp     eax, [esi+TEdit._Len]
        jae     .finish                ; can't delete after the end of string.

        stdcall StrPtr, [esi+TEdit._Text]

        mov     ecx, eax
        stdcall StrOffsUtf8, eax, [esi+TEdit._Pos]
        sub     eax, ecx

        stdcall StrSplit, [esi+TEdit._Text], eax
        mov     ebx, eax

        stdcall StrPtr, ebx
        stdcall DecodeUtf8, [eax]

        stdcall StrCopyPart, ebx, ebx, edx, -1
        stdcall StrCat, [esi+TEdit._Text], ebx
        stdcall StrDel, ebx

        dec     [esi+TEdit._Len]
        or      [.changes], .NeedRefresh

.endmove:
        mov     ebx, [.pEvent]
        mov     eax, [esi+TEdit._Pos]
        cmp     [ebx+TSysEvent.event], seKbdKeyPress
        jne     .setselection

        test    [ebx+TKeyboardEvent.kbdStatus], maskShift
        jnz     .refresh

.setselection:
        mov     ecx, [.prevpos]
        cmp     ecx, [esi+TEdit._Sel]
        je      @f
        or      [.changes], .NeedRefresh
@@:
        mov     [esi+TEdit._Sel], eax

        test    [.changes], .NeedRefresh
        jz      .caretmove

.refresh:
        execute [.pObj], TEdit.Refresh

.caretmove:
        cmp     [esi+TEdit._Focused], 0
        je      .finish

        test    [.changes], .PosChanged
        jz      .showcaret

        mov     eax, [esi+TEdit._Pos]
        cmp     eax, [esi+TEdit._Start]
        jl      .scroll

        stdcall StrPtr, [esi+TEdit._Text]
        mov     edi, eax

        stdcall StrOffsUtf8, edi, [esi+TEdit._Pos]
        mov     ecx, eax

        stdcall StrOffsUtf8, edi, [esi+TEdit._Start]
        sub     ecx, eax                           ; offset to char under cursor.
        jns     .leftok

.scroll:
        mov     eax, [esi+TEdit._Start]
        sub     eax, 8
        test    eax, eax
        jns         @f
        xor     eax, eax
@@:
        mov     [esi+TEdit._Start], eax
        mov     [.changes], .PosChanged or .NeedRefresh
        jmp     .endmove

.leftok:
        mov     edi, eax                           ; pointer to start of the text.

        stdcall AllocateContext, [esi+TEdit.handle]
        push    eax

        stdcall GetTextBounds, eax, edi, ecx, 0
        lea     ecx, [eax+2]       ; x coordinate of the cursor.
        add     ecx, [esi+TEdit._MarginLeft]

        stdcall ReleaseContext ; from the stack.

        mov     eax, [esi+TEdit._width]
        sub     eax, [esi+TEdit._MarginRight]
        sub     eax, ecx
        cmp     eax, 2
        jge     .caretok

        mov     eax, [esi+TEdit._Start]
        add     eax, 8
        cmp     eax, [esi+TEdit._Len]
        jle     @f
        mov     eax, [esi+TEdit._Len]
@@:
        mov     [esi+TEdit._Start], eax

        mov     [.changes], .PosChanged or .NeedRefresh
        jmp     .endmove


.caretok:
        mov     edx, [esi+TEdit._height]
        sub     edx, 4

        stdcall CaretChange, ecx, 2, 1, edx

.showcaret:
        test    [.changes], .ShowCaret
        jz      .finish

        stdcall CaretShow, TRUE
        jmp     .finish

;............................................................................................

.onpaint:
locals
 .bounds TBounds
 .selbeg dd ?
 .selend dd ?
 .ypos   dd ?
endl
        mov     eax, [esi+TEdit._Pos]
        mov     ecx, [esi+TEdit._Sel]
        cmp     eax,ecx
        jle     @f
        xchg    eax, ecx
@@:
        mov     [.selbeg], eax
        mov     [.selend], ecx

        mov     ecx, [esi+TEdit._width]
        mov     eax, [esi+TEdit._height]

        mov     [.bounds.x], 0
        mov     [.bounds.y], 0
        mov     [.bounds.width], ecx
        mov     [.bounds.height], eax

        lea     eax, [.bounds]
        stdcall [DrawBox], [ebx+TPaintEvent.context], eax, [clEditBk], bxSunken

        mov     eax, [esi+TEdit._MarginLeft]
        mov     ecx, [esi+TEdit._MarginRight]
        add     [.bounds.x], eax
        sub     [.bounds.width], eax
        sub     [.bounds.width], ecx
        cmp     [.bounds.width], 0
        jle     .finish

        mov     ecx, [esi+TEdit._Start]

        stdcall StrOffsUtf8, [esi+TEdit._Text], ecx
        mov     edi, eax

        mov     eax, [.bounds.y]
        add     eax, [.bounds.height]
        sub     eax, 4
        mov     [.ypos], eax   ; y position of the characters.

.drawloop:
        stdcall DecodeUtf8, [edi]
        jc      .finish

        test    eax, eax
        jz      .eraseremaining

        mov     eax, [clEditTxt]
        cmp     ecx, [.selbeg]
        jl      .colorok
        cmp     ecx, [.selend]
        jge     .colorok
        mov     eax, [clEditSelTxt]
.colorok:
        push    eax  0 [.ypos] [.bounds.x] edx edi

        push    0 edx edi
        add     edi, edx
        stdcall GetTextBounds, [ebx+TPaintEvent.context] ; remaining from the stack

        sub     [.bounds.width], eax
        js      .nodraw

        cmp     ecx, [.selbeg]
        jl      .drawtxt
        cmp     ecx, [.selend]
        jge     .drawtxt

        mov     esi, [.ypos]
        sub     esi, edx
        add     edx, 2
        stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], eax, [.bounds.height], [clEditSel]

.drawtxt:
        add     [.bounds.x], eax
        stdcall DrawString, [ebx+TPaintEvent.context] ; remaining from the stack

        inc     ecx
        jmp     .drawloop

.nodraw:
        add     esp, 24 ; 6*4
        jmp     .finish

.eraseremaining:
        stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], [clEditBk]
        jmp     .finish

.ClearSelection:
        mov     eax, [esi+TEdit._Pos]
        mov     ecx, [esi+TEdit._Sel]
        cmp     eax, [esi+TEdit._Sel]
        je      .noselection            ; there is no selection.
        jg      @f
        xchg    eax, ecx        ; eax=end_selection; ecx=beg_selection
@@:
        add     [esi+TEdit._Len], ecx
        sub     [esi+TEdit._Len], eax
        mov     [esi+TEdit._Pos], ecx
        mov     [esi+TEdit._Sel], ecx

        push    -1
        stdcall StrOffsUtf8, [esi+TEdit._Text], eax
        push    eax
        stdcall StrOffsUtf8, [esi+TEdit._Text], ecx
        push    eax
        stdcall StrPtr, [esi+TEdit._Text]
        sub     [esp], eax     ; begin of the selection
        sub     [esp+4], eax
        mov     eax, [esp]
        sub     [esp+4], eax   ; length of the selection

        stdcall StrSplit, [esi+TEdit._Text]  ; position from the stack
        mov     ecx, eax
        stdcall StrCopyPart, ecx, ecx   ; pos and length from the stack.
        stdcall StrCat, [esi+TEdit._Text], ecx
        stdcall StrDel, ecx

        or      [.changes], .PosChanged or .NeedRefresh
        clc
        retn

.noselection:
        stc
        retn
endp


endmodule


;        stdcall DecodeUtf8, [edi]
;        jc      .finish
;
;        test    eax, eax
;        jz      .eraseremaining
;
;        mov     eax, [clEditTxt]
;        mov     esi, [clEditBk]
;        cmp     ecx, [.selbeg]
;        jl      .colorok
;        cmp     ecx, [.selend]
;        jge     .colorok
;        mov     eax, [clEditSelTxt]
;        mov     esi, [clEditSel]
;.colorok:
;        push    eax  0 [.ypos] [.bounds.x] edx edi
;
;        push    0 edx edi
;        add     edi, edx
;        stdcall GetTextBounds, [ebx+TPaintEvent.context] ; remaining from the stack
;
;        add     eax, 2
;        stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], eax, [.bounds.height], esi
;        sub     eax, 2
;
;        add     [.bounds.x], eax
;        sub     [.bounds.width], eax
;        jc      .nodraw
;
;        stdcall DrawString, [ebx+TPaintEvent.context] ; remaining from the stack
;
;        inc     ecx
;        jmp     .drawloop
;
;.nodraw:
;        add     esp, 24 ; 6*4
;        jmp     .finish
;
;.eraseremaining:
;        stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], [clEditBk]
;        jmp     .finish
;
;endp
;
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/gui/TForm.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TForm object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Represents form window that to serve as parent window for other controls.
;_________________________________________________________________________________________
module "TForm library"


ObjectClass Form,                       \
            Window,                     \
            TForm.Create,               \
            0,                          \
            TForm.Get,                  \
            TForm.Set,                  \
            0,                          \
            TForm.SysEventHandler


mrNone   = 0
mrOK     = 1
mrCancel = 2
mrAbort  = 3
mrRetry  = 4
mrIgnore = 5
mrYes    = 6
mrNo     = 7
mrMaybe  = 8


object TForm, TWindow

  .ModalResult  dd ?

  .OnClose dd ?         ; On close window event handler.

  param .type
endobj


proc TForm.Create, .obj
begin
        stdcall Set, [.obj], TWindow.borderKind, borderFull
        return
endp


; OS independent code.

proc TForm.Get, .obj, .paramID
begin
        stc
        return
endp



proc TForm.Set, .obj, .paramID, .value
begin
        stc
        return
endp



proc TForm.SysEventHandler, .pObj, .pEvent
begin
        push    ebx esi
        mov     ebx, [.pEvent]
        cmp     [ebx+TSysEvent.event], sePaint
        je      .onpaint

        cmp     [ebx+TSysEvent.event], seCloseRequest
        je      .close_request

.finish:
        stc
        pop     esi ebx
        return

.onpaint:
        mov     esi, [.pObj]

        mov     eax, [esi+TWindow._width]
        mov     ecx, [esi+TWindow._height]

        stdcall DrawFillRect, [ebx+TPaintEvent.context], 0, 0, eax, ecx, [clDialogBk]
        jmp     .finish

.close_request:
;        DebugMsg "Close request"
        cmp     [esi+TForm.OnClose], 0
        je      @f

        stdcall [esi+TForm.OnClose], esi, [ebx+TCloseEvent.reason]      ; if OnClose return CF=0 the form is destroyed. Else, the form is not destroyed.
        jc      .finish

@@:
        stdcall Set, [.pObj], TForm.Visible, FALSE
        stdcall Destroy, [.pObj]

        DebugMsg "Form destroyed"

.destroyed:
        clc
        pop     esi ebx
        return
endp


endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































Deleted freshlib/gui/TImageLabel.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TImageLabel object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Represents GUI picture or image.
;_________________________________________________________________________________________
module "TImageLabel library"

ObjectClass ImageLabel,                 \
            Window,                     \
            0,                          \
            0,                          \
            TImageLabel.Get,            \
            TImageLabel.Set,                \
            0,                          \
            TImageLabel.SysEventHandler

iaLeft = 0
iaRight = 1
iaCenter = 2
iaStretchH = 3

iaTop = $0
iaBottom = $100
iaMiddle = $200
iaStrechV = $300

object TImageLabel, TWindow
  .FImageAlign dd ?
  .FImage      dd ?
  .FMask       dd ?
  .FBackground dd ?

  param .ImageAlign       ; image align flags.
  param .Image            ; TImage object
  param .Mask
endobj



proc TImageLabel.Get, .obj, .paramID
begin
        mov     eax, [.obj]

        stdcall IsObject, eax, CImageLabel
        jc      .exit

        cmp     [.paramID], TImageLabel.ImageAlign
        je      .getimagealign

        cmp     [.paramID], TImageLabel.Image
        je      .getimage

        cmp     [.paramID], TImageLabel.Mask
        je      .getmask

        stc
.exit:
        return

.getimagealign:
        mov     eax, [eax+TImageLabel.FImageAlign]
        clc
        return

.getimage:
        mov     eax, [eax+TImageLabel.FImage]
        clc
        return

.getmask:
        mov     eax, [eax+TImageLabel.FMask]
        clc
        return
endp



proc TImageLabel.Set, .obj, .paramID, .value
begin
        push    eax

        mov     eax, [.obj]
        stdcall IsObject, eax, CImageLabel
        jc      .exit

        cmp     [.paramID], TImageLabel.ImageAlign
        je      .setimagealign

        cmp     [.paramID], TImageLabel.Image
        je      .setimage

        cmp     [.paramID], TImageLabel.Mask
        je      .setmask

        stc
.exit:
        pop     eax
        return

.setimage:
        push    [.value]
        pop     [eax+TImageLabel.FImage]
        jmp     .refresh

.setmask:
        push    [.value]
        pop     [eax+TImageLabel.FMask]
        jmp     .refresh

.setimagealign:
        push    [.value]
        pop     [eax+TImageLabel.FImageAlign]

.refresh:
        execute [.obj], TWindow.Refresh
        clc
        pop     eax
        return
endp



proc TImageLabel.SysEventHandler, .pObj, .pEvent
begin
        push    eax ebx ecx edx esi

        mov     esi, [.pObj]
        mov     ebx, [.pEvent]
        mov     eax, [ebx+TSysEvent.event]

        cmp     eax, sePaint
        je      .onpaint

.finish:
        stc
        pop     esi edx ecx ebx eax
        return

.onpaint:
  locals
   .bounds TBounds
  endl
        mov     ecx, [esi+TImageLabel._width]
        mov     eax, [esi+TImageLabel._height]
        mov     [.bounds.x], 0
        mov     [.bounds.y], 0
        mov     [.bounds.width], ecx
        mov     [.bounds.height], eax

        stdcall SetDrawMode, [ebx+TPaintEvent.context], cmCopy
        stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], [clDialogBk]

        mov     eax, [esi+TImageLabel.FImage]
        mov     ecx, [.bounds.width]
        mov     edx, [.bounds.height]
        sub     ecx, [eax+TImage.width]
        sub     edx, [eax+TImage.height]

        mov     eax, [esi+TImageLabel.FImageAlign]

        cmp     al, iaRight
        je      .x_ok
        cmp     al, iaCenter
        je      .x_center
        xor     ecx, ecx
        jmp     .x_ok
.x_center:
        sar     ecx, 1
.x_ok:
        cmp     ah, iaBottom /256
        je      .y_ok
        cmp     ah, iaMiddle / 256
        je      .y_center
        xor     edx, edx
        jmp     .y_ok
.y_center:
        sar     edx, 1
.y_ok:
        stdcall DrawMaskedImage, [ebx+TPaintEvent.context], [esi+TImageLabel.FMask], [esi+TImageLabel.FImage], ecx, edx
        jmp     .finish
endp








endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































Deleted freshlib/gui/TLabel.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TLabel object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Not finished.
;_________________________________________________________________________________________
module "TLabel library"

ObjectClass Label,           \
            Window,          \
            0,               \
            0,               \
            TLabel.Get,      \
            TLabel.Set,      \
            0,               \
            TLabel.SysEventHandler


object TLabel, TWindow
  .Ftextalign dd ?

  param .TextAlign        ; text align flags.
  param .Control          ; control that to be activated
endobj



proc TLabel.Get, .obj, .paramID
begin
        mov     eax, [.obj]

        stdcall IsObject, eax, CLabel
        jc      .exit

        cmp     [.paramID], TLabel.TextAlign
        je      .gettextalign

        stc
.exit:
        return

.gettextalign:
        mov     eax, [eax+TLabel.Ftextalign]
        clc
        return
endp



proc TLabel.Set, .obj, .paramID, .value
begin
        push    eax

        mov     eax, [.obj]
        stdcall IsObject, eax, CLabel
        jc      .exit

        cmp     [.paramID], TLabel.TextAlign
        je      .settextalign

        stc
.exit:
        pop     eax
        return

.settextalign:
        push    [.value]
        pop     [eax+TLabel.Ftextalign]

.refresh:
        execute [.obj], TWindow.Refresh
        clc
        pop     eax
        return
endp



proc TLabel.SysEventHandler, .pObj, .pEvent
begin
        push    eax ebx ecx edx esi

        mov     esi, [.pObj]
        mov     ebx, [.pEvent]
        mov     eax, [ebx+TSysEvent.event]

        cmp     eax, sePaint
        je      .onpaint

.finish:
        stc
        pop     esi edx ecx ebx eax
        return

.onpaint:
  locals
   .bounds TBounds
  endl

        mov     ecx, [esi+TLabel._width]
        mov     eax, [esi+TLabel._height]
        mov     [.bounds.x], 0
        mov     [.bounds.y], 0
        mov     [.bounds.width], ecx
        mov     [.bounds.height], eax
        lea     eax, [.bounds]
        stdcall [DrawBox], [ebx+TPaintEvent.context], eax, [clDialogBk], bxNone

        stdcall Get, esi, TWindow.Caption
        test    eax, eax
        jz      .finish

        push    eax eax
        stdcall StrLen, eax
        mov     ecx, eax
        pop     eax
        lea     edx, [.bounds]
        stdcall DrawTextBox, [ebx+TPaintEvent.context], eax, edx, [esi+TLabel.Ftextalign], 0, [clDialogTxt]
        stdcall StrDel ; from the stack
        jmp     .finish
endp







endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































Deleted freshlib/gui/TMenu.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TMenu object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Represents main menu or popup menu objects.
;_________________________________________________________________________________________
module "TMenu library"

ObjectClass Menu,         \
            Window,       \
            TMenu.Create, \
            TMenu.Destroy,\
            TMenu.Get,    \
            TMenu.Set,    \
            TMenu.ExecCmd,\
            TMenu.SysEventHandler

; The inherited TWindow.caption serves as a menu item caption in the parent menu.
; The children TMenu objects are reparent to the root, and their pointers are stored in the
; list of TMenuItem elements.
object TMenu, TWindow
  .pForm  dd ?       ; pointer to TForm object. If NULL, the menu is popup menu.
  .pItems dd ?       ;

  method .Show, .parent, .kind
endobj



proc TMenu.Create, .obj
begin
        return
endp


proc TMenu.Destroy, .obj
begin
        return
endp


proc TMenu.Get, .obj, .param
begin
        return
endp


proc TMenu.Set, .obj, .param
begin

        return
endp


proc TMenu.ExecCmd, .obj, .method
begin
        cmp     [.method], TMenu.Show
        je      .show

        stc
        return

; Method show
.show:
virtual at esi
  .parent dd ?
  .kind   dd ?
end virtual

        mov     ebx, [.obj]
; First check item count and set proper size of the menu window.




        return
endp


proc TMenu.SysEventHandler, .obj, .event
begin

        return
endp



endmodule


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































Deleted freshlib/gui/TMenuItem.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TMenuItem object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: TMenuItems are the items of the GUI menu objects.
;_________________________________________________________________________________________
module "TMenuItem library"

ObjectClass MenuItem,     \
            Object,       \
            TMenu.Create, \
            TMenu.Destroy,\
            TMenu.Get,    \
            TMenu.Set,    \
            TMenu.ExecCmd,\
            TMenu.SysEventHandler

mikCommand   = 0
mikSubmenu   = 1
mikSeparator = 2


object TMenuItem, TObject
  .parent   dd ?        ; pointer to TMenu object.
  .kind     dd ?        ; mikCommand, mikSubmenu or mikSeparator
  .pAction  dd ?        ; depending on the kind. Pointer to TAction or handle of string with the text.
  .child    dd ?        ; pointer to the child TMenu object

  method Paint, .context, .x, .y, .width, .height
endobj


endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































Deleted freshlib/gui/TObject.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TObject object class.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: TObject is the root member of FreshLib objects tree.
;_________________________________________________________________________________________
module "TObject library"

ObjectClass  Object,                    \
             Root,                      \
             0,                         \
             TObject.Destroy,           \
             0,                         \
             0,                         \
             0,                         \
             0


object TObject
  .ptrClass     dd ?    ; pointer to the object class structure.

  .mxAccess     dd ?    ; access mutex. Procedures from objects.asm will use it to ensure thread safety.
  .ptrVar       dd ?    ; pointer to the variable that keep the pointer to the object. This field can be 0. If not, Destroy procedure will set it to 0 on destroy.

  .OnCreate     dd ?    ; user event handlers.
  .OnDestroy    dd ?

  method .AddChild, .objchild    ; this method is not implemented in TObject, but every descendent can implement it's own parent/child system.
endobj



proc TObject.Destroy, .obj
begin
        push    eax
        mov     eax, [.obj]

        cmp     [eax+TObject.OnDestroy], 0
        je      .exit

        pushad
        stdcall [eax+TObject.OnDestroy], eax
        popad

.exit:
        pop     eax
        return
endp



endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































Deleted freshlib/gui/TProgressbar.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TProgressBar object class; Simple progress bar control.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________
module "TProgressbar library"

ObjectClass Progress,                   \
            Window,                     \
            0,                          \
            0,                          \
            TProgress.Get,              \
            TProgress.Set,              \
            TProgress.ExecCmd,          \
            TProgress.SysEventHandler

object TProgress, TWindow
  ._Pos   dd ?
  ._Max   dd ?
  ._Color dd ?

  param .Pos
  param .Max
  param .Color

  method .Step
endobj



proc TProgress.Get, .pobj, .paramID
begin
        push    ecx

        stdcall IsObject, [.pobj], CProgress
        jc      .exit

        mov     eax, [.pobj]
        mov     ecx, [.paramID]

        cmp     ecx, TProgress.Pos
        jb      .exit
        cmp     ecx, TProgress.Color
        ja      .exit

        sub     ecx, TProgress.Pos
        pushd   [eax+TProgress._Pos+4*ecx]
        pop     eax

        clc
        pop     ecx
        return

.exit:
        stc
        pop     ecx
        return
endp



proc TProgress.Set, .pobj, .paramID, .value
begin
        push    eax ecx

        stdcall IsObject, [.pobj], CProgress
        jc      .exit

        mov     eax, [.pobj]
        mov     ecx, [.paramID]

        cmp     ecx, TProgress.Pos
        jb      .exit
        cmp     ecx, TProgress.Color
        ja      .exit

        sub     ecx, TProgress.Pos
        pushd   [.value]
        popd    [eax+TProgress._Pos+4*ecx]

        execute [.pobj], TProgress.Refresh

        clc
        pop     ecx eax
        return

.exit:
        stc
        pop     ecx eax
        return
endp


proc TProgress.SysEventHandler, .pobj, .pEvent
begin
        push    eax ebx ecx esi

        mov     ebx, [.pEvent]
        cmp     [ebx+TSysEvent.event], sePaint
        je      .paint

.finish:
        stc
        pop     esi ecx ebx eax
        return

.paint:
locals
  .bounds TBounds
  .style TLineStyle
endl
        mov     [.bounds.x], 0
        mov     [.bounds.y], 0
        mov     eax, [esi+TProgress._width]
        mov     ecx, [esi+TProgress._height]
        mov     [.bounds.width], eax
        mov     [.bounds.height], ecx

        lea     eax, [.bounds]
        stdcall [DrawBox], [ebx+TPaintEvent.context], eax, 0, bxSunken or bxNoFill

        stdcall DrawRectangle, [ebx+TPaintEvent.context], eax, [clDialogBk]

        inc     [.bounds.x]
        inc     [.bounds.y]
        sub     [.bounds.width], 2
        sub     [.bounds.height], 2

        mov     eax, [esi+TProgress._Pos]
        mov     ecx, [esi+TProgress._Max]
        test    ecx, ecx
        jnz     @f
        inc     ecx
@@:
        cmp     eax, ecx
        jle     @f
        mov     eax, ecx
@@:
        imul    eax, [.bounds.width]
        cdq
        idiv    ecx

        stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], eax, [.bounds.height], [esi+TProgress._Color]
        sub     [.bounds.width], eax
        inc     eax
        inc     [.bounds.width]
        stdcall DrawFillRect, [ebx+TPaintEvent.context], eax, [.bounds.y], [.bounds.width], [.bounds.height], [clDialogBk]

        jmp     .finish
endp




proc TProgress.ExecCmd, .self, .method
begin
        cmp     [.method], TProgress.Step
        je      .step
        stc
        return

;-------------------------------------------------------------------------
.step:
        push    eax ecx

        mov     eax, [.self]
        mov     ecx, [eax+TProgress._Pos]
        cmp     ecx, [eax+TProgress._Max]
        jge     .exit

        inc     [eax+TProgress._Pos]
        execute eax, TProgress.Refresh

.exit:
        pop     ecx eax
        clc
        return
endp



endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































Deleted freshlib/gui/TScrollWindow.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TScrollWindow object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: TScrollWindow is window that may have scrollers to scroll the client area.
;_________________________________________________________________________________________
module "TScrollWindow library"

ObjectClass ScrollWindow,               \
            Window,                     \
            TScrollWindow.Create,       \
            0,                          \
            TScrollWindow.Get,          \
            TScrollWindow.Set,          \
            TScrollWindow.ExecCmd,      \
            TScrollWindow.SysEventHandler


struct TScrollbar
  .Max  dd  ?
  .Page dd  ?
  .Pos  dd  ?

  ._Drag dd ?
ends



object TScrollWindow, TWindow
  ._HScroller TScrollbar
  ._VScroller TScrollbar

  method HScrollSet, .Pos, .Max, .Page   ; only params >=0 are set. If<0 ignored.
  method VScrollSet, .Pos, .Max, .Page
endobj


ScrollBarWidth = 16
MinScrollBarWidth = 12

;_________________________________________________________________________________________

proc TScrollWindow.Create, .pobj
begin
;        push    eax
;        mov     eax, [.pobj]

;        mov     [eax+TScrollWindow._HScroller.Max], 255
;        mov     [eax+TScrollWindow._HScroller.Page], 1
;        mov     [eax+TScrollWindow._HScroller.Pos], 10

;        mov     [eax+TScrollWindow._VScroller.Max], 1000
;        mov     [eax+TScrollWindow._VScroller.Page], 1
;        mov     [eax+TScrollWindow._VScroller.Pos], 450

;        pop     eax
        return
endp



;_________________________________________________________________________________________


proc TScrollWindow.Get, .pobj, .paramID
begin
        stc
        return
endp


;_________________________________________________________________________________________


proc TScrollWindow.Set, .pobj, .paramID, .value
begin

        stc
        return
endp


;_________________________________________________________________________________________


proc TScrollWindow.SysEventHandler, .pobj, .pEvent
  .event TScrollEvent
begin
        push    eax ebx edx esi edi
        mov     esi, [.pobj]
        mov     ecx, [.pEvent]

        cmp     [ecx+TSysEvent.event], sePaint
        je      .paint

        cmp     [ecx+TSysEvent.event], seMouseBtnPress
        je      .btnpress

        cmp     [ecx+TSysEvent.event], seMouseBtnRelease
        je      .btnrelease

        cmp     [ecx+TSysEvent.event], seMouseMove
        je      .mousemove

.continue:
        stc
.finish:
        pop     edi esi edx ebx eax
        return


;.........................................................................................

.paint:
locals
  .recth TBounds
  .rectv TBounds
  .rectx TBounds
endl
        stdcall Get, esi, TScrollWindow.FreeArea
        mov     ebx, eax

        mov     eax, [ebx+TBounds.x]
        mov     edx, [ebx+TBounds.y]
        mov     [.recth.x], eax
        mov     [.rectv.y], edx

        add     eax, [ebx+TBounds.width]
        add     edx, [ebx+TBounds.height]
        mov     [.rectv.x], eax
        mov     [.recth.y], edx

        inc     edx
        inc     eax
        mov     [.rectx.y], edx
        mov     [.rectx.x], eax

        mov     [.recth.height], ScrollBarWidth
        mov     [.rectv.width], ScrollBarWidth
        mov     [.rectx.width], ScrollBarWidth-1
        mov     [.rectx.height], ScrollBarWidth-1

        mov     eax, [ebx+TBounds.width]
        mov     edx, [ebx+TBounds.height]
        inc     eax
        inc     edx
        mov     [.recth.width], eax
        mov     [.rectv.height], edx

        lea     eax, [.rectx]
        stdcall [DrawBox], [ecx+TPaintEvent.context], eax, [clDialogBk], bxNone

        lea     eax, [.recth]
        stdcall [DrawBox], [ecx+TPaintEvent.context], eax, [clScrollBk], bxSunken or bxNoFill

        lea     eax, [.rectv]
        stdcall [DrawBox], [ecx+TPaintEvent.context], eax, [clScrollBk], bxSunken or bxNoFill

        lea     eax, [esi+TScrollWindow._HScroller]
        stdcall _SliderPixels, eax, [.recth.width]

        push    esi
        stdcall DrawFillRect, [ecx+TPaintEvent.context], [.recth.x], [.recth.y], eax, [.recth.height], [clScrollBk]
        mov     esi, [.recth.width]
        sub     esi, eax
        sub     esi, edx

        add     eax, [.recth.x]
        lea     edi, [eax+edx]
        stdcall DrawFillRect, [ecx+TPaintEvent.context], edi, [.recth.y], esi, [.recth.height], [clScrollBk]
        pop     esi

        mov     [.rectx.x], eax

        mov     [.rectx.width], edx
        push    [.recth.y] [.recth.height]
        pop     [.rectx.height] [.rectx.y]

        lea     eax, [.rectx]
        stdcall [DrawSlider], [ecx+TPaintEvent.context], eax, [clScrollSlider], sliderHorizontal

        lea     eax, [esi+TScrollWindow._VScroller]
        stdcall _SliderPixels, eax, [.rectv.height]

        push    esi
        stdcall DrawFillRect, [ecx+TPaintEvent.context], [.rectv.x], [.rectv.y], [.rectv.width], eax, [clScrollBk]
        mov     esi, [.rectv.height]
        sub     esi, eax
        sub     esi, edx

        add     eax, [.rectv.y]
        lea     edi, [eax+edx]
        stdcall DrawFillRect, [ecx+TPaintEvent.context], [.rectv.x], edi, [.rectv.width], esi, [clScrollBk]
        pop     esi

        mov     [.rectx.y], eax

        mov     [.rectx.height], edx
        push    [.rectv.x] [.rectv.width]
        pop     [.rectx.width] [.rectx.x]

        lea     eax, [.rectx]
        stdcall [DrawSlider], [ecx+TPaintEvent.context], eax, [clScrollSlider], sliderVertical

        clc
        jmp     .finish

;.........................................................................................

.btnpress:
        stdcall __ScrollSetCursor, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]

        cmp     [ecx+TMouseButtonEvent.Button], mbLeft
        jne     .continue

        stdcall _WhatScrollbar, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
        jc      .continue         ; not found

; here ecx=height of the scrollbar
;      edi= ptr to TScrollbar structure
;      ebx= coordinate of the mouse in the scrollbar

        stdcall _SliderPixels, edi, ecx
        sub     ebx, eax
        jl      .before
        cmp     ebx, edx
        jg      .after

; inside the slider - capture the mouse.
        mov     [edi+TScrollbar._Drag], ebx
        stdcall MouseCapture, [esi+TWindow.handle]
        jmp     .continue

.before:
.after:
        jmp     .continue

;.........................................................................................

.btnrelease:
        stdcall __ScrollSetCursor, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]

        xor     eax, eax
        mov     [esi+TScrollWindow._HScroller._Drag], eax
        mov     [esi+TScrollWindow._VScroller._Drag], eax

        stdcall MouseCapture, eax
        jmp     .continue

;.........................................................................................

.mousemove:
        mov     ecx, [.pEvent]
        stdcall __ScrollSetCursor, esi, [ecx+TMouseMoveEvent.x], [ecx+TMouseMoveEvent.y]

        mov     ecx, [.pEvent]
        lea     edi, [esi+TScrollWindow._HScroller]
        mov     eax, [ecx+TMouseMoveEvent.x]
        mov     ecx, [esi+TScrollWindow._width]
        mov     [.event.ScrollBar], scrollX
        cmp     [edi+TScrollbar._Drag], 0
        jne     .found

        mov     ecx, [.pEvent]
        lea     edi, [esi+TScrollWindow._VScroller]
        mov     eax, [ecx+TMouseMoveEvent.y]
        mov     ecx, [esi+TScrollWindow._height]
        mov     [.event.ScrollBar], scrollY
        cmp     [edi+TScrollbar._Drag], 0

        je      .continue


.found:
        mov     [.event.event], seScroll
        mov     [.event.ScrollCmd], scTrack

        sub     ecx, ScrollBarWidth
        sub     eax, 2
        sub     eax, [edi+TScrollbar._Drag]
        stdcall _SetSliderPos, edi, eax, ecx
        jc      .endmove

        mov     eax, [edi+TScrollbar.Pos]
        mov     [.event.Value], eax

        lea     eax, [.event]
        stdcall ExecEvent, esi, eax
        jnc     .finish

; ?????? Do we need this?
;        execute esi, TScrollWindow.Refresh

.endmove:
        clc
        jmp     .finish

endp


;_________________________________________________________________________________________


proc TScrollWindow.ExecCmd, .self, .method
begin
        cmp     [.method], TScrollWindow._ComputeFreeArea
        je      .computefreearea

        stc
        return


.computefreearea:
        mov     ecx, [.self]
        sub     [ecx+TScrollWindow._FreeArea.width], ScrollBarWidth
        jns     @f
        mov     [ecx+TScrollWindow._FreeArea.width], 0
@@:
        sub     [ecx+TScrollWindow._FreeArea.height], ScrollBarWidth
        jns     @f
        mov     [ecx+TScrollWindow._FreeArea.height], 0
@@:
        stc
        return
endp


;_________________________________________________________________________________________



proc _SetSliderPos, .pScrollbar, .x, .lengthpx
begin
        push    eax ecx edx

        mov     ecx, [.pScrollbar]
        stdcall _SliderPixels, [.pScrollbar], [.lengthpx]

        sub     [.lengthpx], edx
        jz      .zero

        mov     eax, [ecx+TScrollbar.Max]
        imul    [.x]
        idiv    [.lengthpx]

        cmp     eax, 0
        jge     .ok
        mov     eax, 0
.ok:
        cmp     eax, [ecx+TScrollbar.Max]
        jle     .ok2
        mov     eax, [ecx+TScrollbar.Max]
.ok2:
        cmp     [ecx+TScrollbar.Pos], eax
        stc
        je      @f
        clc
@@:
        mov     [ecx+TScrollbar.Pos], eax
        pop     edx ecx eax
        return

.zero:
        xor     eax, eax
        jmp     .ok2
endp



; returns:
;   eax - position in pixels
;   edx - size in pixels

proc _SliderPixels, .pScrollbar, .length
begin
        push    ecx esi

        mov     ecx, [.pScrollbar]

; page size in pixels.
        mov     esi, [ecx+TScrollbar.Max]
        mov     eax, [.length]
        add     esi, [ecx+TScrollbar.Page]
        test    esi, esi
        jz      .lengthok

        imul     [ecx+TScrollbar.Page]
        idiv     esi

.lengthok:
        cmp     eax, MinScrollBarWidth
        jge     @f
        mov     eax, MinScrollBarWidth
@@:
        cmp     eax, [.length]
        jle     @f
        mov     eax, [.length]
@@:
        push    eax

; position in pixels

        sub     eax, [.length]
        mov     esi, [ecx+TScrollbar.Max]
        test    esi, esi
        jnz     @f
        inc     esi
@@:
        neg     eax
        mul     [ecx+TScrollbar.Pos]
        div     esi

        pop     edx   ; width

        pop     esi ecx
        return
endp


proc __ScrollSetCursor, .window, .x, .y
begin
        pushad

        mov     esi, [.window]
        mov     eax, [esi+TWindow._cursor]
        stdcall _WhatScrollbar, esi, [.x], [.y]
        jc      @f

        mov     eax, mcArrow
@@:
        test    eax, $ffffff00
        jnz     @f
        stdcall GetStockCursor, eax
@@:
        stdcall SetMouseCursor, eax

        popad
        return
endp



; returns:
;      ecx = height of the scrollbar
;      edi = ptr to TScrollbar structure
;      ebx = coordinate of the mouse in the scrollbar
;
; CF=1 if the cursor is not in scrollbar

proc _WhatScrollbar, .window, .x, .y
begin
        push    eax edx esi

        mov     esi, [.window]


        mov     eax, [.x]
        mov     edx, [.y]

        mov     eax, [esi+TWindow._width]
        mov     edx, [esi+TWindow._height]

        sub     eax, ScrollBarWidth
        sub     edx, ScrollBarWidth

        cmp     [.x], eax
        jl      .checkh

        cmp     [.y], edx
        jg      .notfound     ; we are in the dead square.

; mouse in vscrollbar
        mov     ebx, [.y]
        mov     ecx, edx
        lea     edi, [esi+TScrollWindow._VScroller]
        jmp     .found

.checkh:
        cmp     [.y], edx
        jl      .notfound     ; in the client area

; mouse in hscrollbar
        mov     ebx, [.x]
        mov     ecx, eax
        lea     edi, [esi+TScrollWindow._HScroller]

.found:
        clc
        pop     esi edx eax
        return

.notfound:
        stc
        pop     esi edx eax
        return
endp



endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/gui/TTreeView.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TTreeView object class
;
;  Target OS: Any
;
;  Dependencies:
;  Notes:
;_________________________________________________________________________________________
module "TreeView library"

ObjectClass TreeView,                    \
            ScrollWindow,                \
            TTreeView.Create,           \
            TTreeView.Destroy,          \
            TTreeView.Get,              \
            TTreeView.Set,              \
            TTreeView.ExecCmd,          \
            TTreeView.SysEventHandler

; tree-view item state flags.
tvisExpanded = 1
tvisSelected = 2
tvisFocused  = 4


struct TTreeViewItem
  .level      dd ?        ; the level of the element in the tree.

  .caption    dd ?        ; hString of the name.
  .state      dd ?        ; one or more state flags.
  .imgNormal  dd ?        ; index to the icon for normal state
  .iSelected  dd ?        ; index to the icon for selected state

  .pObject    dd ?        ; the object attached to the item
  align 32
  .shift = 5
ends


object TTreeView, TScrollWindow
  ._items dd ?    ; TArray with
  ._first dd ?    ; index of the fisrt visible item.
  ._pShadow dd ?  ; pointer to TBackBuffer

  .OnItemDelete  dd ? ; procedure to be call when the item is deleted. It should free the objects attached to the item.

  param .Focused

  method .AddItem, .iParent
  method .DelItem, .iItem  ;deletes the item and all children.
  method .GetItem, .index
endobj


proc TTreeView.Create, .pobj
begin
        mov     ebx, [.pobj]

        stdcall CreateBackBuffer, [ebx+TTreeView.handle], 1, 1
        mov     [ebx+TTreeView._pShadow], eax

        stdcall CreateArray, sizeof.TTreeViewItem
        mov     [ebx+TTreeView._items], eax

        clc
        return
endp


proc TTreeView.Destroy, .pobj
begin
        mov     ebx, [.pobj]

        stdcall DestroyBackBuffer, [ebx+TTreeView._pShadow]
        execute ebx, TTreeView.DelItem, -1
        stdcall FreeMem, [ebx+TTreeView._items]

        clc
        return
endp


proc TTreeView.Get, .pobj, .paramID
begin
        stc
        return
endp


proc TTreeView.Set, .pobj, .paramID, .value
begin
        stc
        return
endp


proc TTreeView.ExecCmd, .self, .method
begin
        stc
        return
endp


proc TTreeView.SysEventHandler, .pobj, .pEvent
begin
        pushad

        mov     ebx, [.pEvent]
        mov     esi, [.pobj]
        mov     eax, [ebx+TSysEvent.event]

        cmp     eax, sePaint
        je      .paint

        cmp     eax, seMoveResize
        je      .moveresize

.continue:
        popad
        stc
        return

.paint:
        stdcall SetClipRectangle, [ebx+TPaintEvent.context], 0
        stdcall TScrollWindow.SysEventHandler, [.pobj], [.pEvent]
        stdcall DrawBackBuffer, [ebx+TPaintEvent.context], [esi+TTreeView._pShadow], 0, 0
        jmp     .continue

.moveresize:
        stdcall Get, esi, TTreeView.FreeArea

        stdcall DestroyBackBuffer, [esi+TTreeView._pShadow]
        stdcall CreateBackBuffer, [esi+TTreeView.handle], [esi+TTreeView._FreeArea.width], [esi+TTreeView._FreeArea.height]
        mov     [esi+TTreeView._pShadow], eax
        jmp     .continue

endp


endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































Deleted freshlib/gui/TWindow.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TWindow object class
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: TWindow is the common ancestor of all visible on the screen controls.
;         This file contains only OS independent part of the library and includes
;         the OS dependent files.
;_________________________________________________________________________________________
module "TWindow library"

ObjectClass Window,             \
            Object,             \
            TWindow.Create,     \
            TWindow.Destroy,    \
            TWindow.Get,        \
            TWindow.Set,        \
            TWindow.ExecCmd,    \
            TWindow.SysEventHandler

; The elements of the array returned by .GetSiblings param
; if handle<>0 and pWindow=0 - it is a native window, not added by FreshLib
struct TWinArrayItem
  .handle   dd ?      ; The native OS handle of the window.
  .pWindow  dd ?      ; pointer to TWindow descendent structure.
ends

; Border kind of window.
borderNone    = 0
borderFull    = 1
borderModal   = 2
borderToolbox = 3

struct __TInternalAlign
  .client        TBounds
  .pClientWindow dd ?
ends
; assign X = 01
; assign Y = 10

; adjheight = 01
; topleft  = 00
; bottomright = 10

;            00 - adjwidht + bottomright

; Window align values.
waNone   = 0
waLeft   = 1
waTop    = 2
waRight  = 3
waBottom = 4
waClient = 5


object TWindow, TObject

  .handle       dd ?   ; it is handle to the system provided window.

  ._x           dd ?
  ._y           dd ?
  ._width       dd ?
  ._height      dd ?

  ._visible     dd ?

  ._bounds_changed dd ?

  ._border      dd ?

  ._align       dd ?         ; window horizontal alignment

  ._FreeArea    TBounds      ; the window area that remains free after all children aligned. [1]

  ._caption     dd ?    ; string handle with window caption.
  ._cursor      dd ?    ; it is a handle to the mouse cursor.

  .OnKeyPress   dd ?    ; key press user handler.

; parameters
  param .x
  param .y
  param .width
  param .height

  param .Align

  param .FreeArea       ; read only.

  param .borderKind
  param .Zorder

  param .Visible
  param .Caption
  param .Parent
  param .Cursor
  param .Children       ; read only. returns array with all children; See the notes [2] below.

  method .Refresh
  method .Focus
  method .AlignChildren
  method .ToBack
  method .ToFront

  method ._ComputeFreeArea
endobj

; NOTES:
; [1]  FreeArea field
;
; [2] The param .children returns an array of TWinArrayItem filled with information about
;     all siblings of the given window.
;     This array is allocated with CreateArray and needs to be free with FreeMem after use.
;     TArray.lparam of the array contains a pointer to the element containing current window


; OS dependend code
include '%TargetOS%/windows.asm'


; OS independent code.


;_________________________________________________________________________________________


proc TWindow.Create, .obj
begin
        push    eax ecx edx
        mov     ebx, [.obj]
        stdcall _CreateNullWindow
        mov     [ebx+TWindow.handle], eax
        stdcall _SetWindowStruct, eax, ebx

        pop     edx ecx eax
        clc
        return
endp


;_________________________________________________________________________________________



proc TWindow.Destroy, .obj
begin
        push    eax
        mov     eax, [.obj]
        cmp     [eax+TWindow.handle], 0
        je      @f
        stdcall _DestroyWindow, [eax+TWindow.handle]
@@:
        pop     eax
        return
endp



;_________________________________________________________________________________________


proc TWindow.Get, .obj, .paramID
.rect RECT
begin
        push    edx esi

        stdcall IsObject, [.obj], CWindow
        jc      .not_processed

        mov     esi, [.obj]
        mov     eax, [.paramID]

        test    eax, maskParameter
        jz      .field

        cmp     eax, TWindow.x
        je      .getrect
        cmp     eax, TWindow.y
        je      .getrect
        cmp     eax, TWindow.width
        je      .getrect
        cmp     eax, TWindow.height
        je      .getrect

        cmp     eax, TWindow.FreeArea
        je      .getfreearea

        cmp     eax, TWindow.Visible
        je      .getvisible

        cmp     eax, TWindow.Caption
        je      .getcaption

        cmp     eax, TWindow.borderKind
        je      .getborder

        cmp     eax, TWindow.Children
        je      .getchildren

        cmp     eax, TWindow.Parent
        je      .getparent


.not_processed:
        stc
        pop     esi edx
        return


.field:
        mov     eax, [esi+eax]


.finish:
        clc
        pop     esi edx
        return

;.........................................................................................

.getparent:
        stdcall _GetParent, [esi+TWindow.handle]
        test    eax, eax
        jz      .finish
        stdcall _GetWindowStruct, eax
        jmp     .finish

;.........................................................................................

.getchildren:
        stdcall _GetChildren, [esi+TWindow.handle]
        test    eax, eax
        jz      .finish

        push    ebx edi

        mov     ebx, eax
        mov     ecx, [ebx+TArray.count]

.loop:
        jecxz   .endloop
        dec     ecx

        stdcall _GetWindowStruct, [ebx+TArray.array+8*ecx+TWinArrayItem.handle]

        mov     [ebx+TArray.array+8*ecx+TWinArrayItem.pWindow], eax
        jmp     .loop

.endloop:
        mov     eax, ebx

        pop     edi ebx
        jmp     .finish


;.........................................................................................


.getfreearea:
        mov     [esi+TWindow._FreeArea.x], 0
        mov     [esi+TWindow._FreeArea.y], 0
        mov     eax, [esi+TWindow._width]
        mov     ecx, [esi+TWindow._height]
        mov     [esi+TWindow._FreeArea.width], eax
        mov     [esi+TWindow._FreeArea.height], ecx

        execute esi, TWindow._ComputeFreeArea

        lea     eax, [esi+TWindow._FreeArea]
        jmp     .finish


;.........................................................................................


.getborder:
        mov     eax, [esi+TWindow._border]
        jmp     .finish


;.........................................................................................


.getcaption:
        stdcall StrDup, [esi+TWindow._caption]
        jmp     .finish

;.........................................................................................

.getvisible:
        mov     eax, [esi+TWindow._visible]
;        stdcall _GetVisible, [esi+TWindow.handle]
        jmp     .finish

;.........................................................................................


.getrect:
        mov     eax, [.paramID]
        sub     eax, TWindow.x
        mov     eax, [esi+TWindow._x+4*eax]
        jmp     .finish
endp


;_________________________________________________________________________________________



proc TWindow.Set, .obj, .paramID, .value
begin
        stdcall IsObject, [.obj], CWindow
        jc      .fault

        push    eax esi

        mov     esi, [.obj]
        mov     eax, [.paramID]

        test    eax, maskParameter
        jz      .field

        cmp     eax, TWindow.x
        je      .setrect
        cmp     eax, TWindow.y
        je      .setrect
        cmp     eax, TWindow.width
        je      .setrect
        cmp     eax, TWindow.height
        je      .setrect

        cmp     eax, TWindow.Visible
        je      .setvisible

        cmp     eax, TWindow.Caption
        je      .setcaption

        cmp     eax, TWindow.borderKind
        je      .setborder

        cmp     eax, TWindow.Align
        je      .setalign

        pop     esi eax
.fault:
        stc
        return

.field:
        pushd   [.value]
        popd    [esi+eax]

.finish:
        clc
        pop     esi eax
        return

;.........................................................................................
.setalign:
locals
  .bounds TBounds
endl
        mov     eax, [.value]
        cmp     eax, [esi+TWindow._align]
        je      .finish

        mov     [esi+TWindow._align], eax

        stdcall Get, esi, TWindow.Parent
        test    eax, eax
        jz      .finish

        execute eax, TWindow.AlignChildren

        jmp     .finish

;.........................................................................................


.setborder:
        mov     eax, [.value]
        xchg    eax, [esi+TWindow._border]
        cmp     eax, [esi+TWindow._border]
        je      .finish

        stdcall _SetWindowBorder, [esi+TWindow.handle], [esi+TWindow._border]
        jmp     .finish

;.........................................................................................

.setcaption:
        lea     eax, [esi+TWindow._caption]
        stdcall SetString, eax, [.value]
        stdcall StrPtr, [eax]

        stdcall _SetWindowTextUtf8, [esi+TWindow.handle], eax
        jmp     .finish

;.........................................................................................

.setvisible:
        mov     eax, [.value]
        xchg    [esi+TWindow._visible], eax
        cmp     [esi+TWindow._visible], eax
        je      .finish

        stdcall _ShowWindow, [esi+TWindow.handle], [.value]

        cmp     [.value], 0
        je      .finish

        cmp     [esi+TWindow._align], waNone
        je      .finish

        stdcall Get, esi, TWindow.Parent
        test    eax, eax
        jz      .finish

        execute eax, TWindow.AlignChildren
        jmp     .finish

;.........................................................................................

.setrect:
        mov     eax, [.paramID]
        sub     eax, TWindow.x

        mov     ecx, [.value]
        cmp     ecx, [esi+TWindow._x+4*eax]
        je      .finish

        mov     [esi+TWindow._x+4*eax], ecx

        lea     eax, [esi+TWindow._x]
        stdcall _SetWindowBounds, [esi+TWindow.handle], eax
        mov     [esi+TWindow._bounds_changed], 0

        jmp     .finish
endp


;_________________________________________________________________________________________




proc TWindow.ExecCmd, .self, .method
begin
        push    eax edx

        cmp     [.method], TWindow.Refresh
        je      .refresh

        cmp     [.method], TWindow._ComputeFreeArea
        je      .computefreearea

        cmp     [.method], TWindow.AlignChildren
        je      .alignchildren

        cmp     [.method], TWindow.Focus
        je      .focus

        cmp     [.method], TWindow.AddChild
        je      .addchild

.error:
        stc
        pop     edx eax
        return

;.........................................................................................

.refresh:
        mov     eax, [.self]
        cmp     [eax+TWindow._visible], 0
        je      .finish
        stdcall _RefreshWindow, [eax+TWindow.handle]
.finish:
        clc
        pop     edx eax
        return

;.........................................................................................

.computefreearea:



        jmp     .finish

;.........................................................................................

.alignchildren:
locals
  .winalign  __TInternalAlign
endl
; THIS METHOD is not written very good. It should be revised some day in order to make
; alignment fast and smooth for all OS supported!
        push    esi edi

        stdcall Get, [.self],  TWindow.Children
        test    eax, eax
        jz      .endalign

        mov     edi, eax
        lea     esi, [.winalign]
        mov     ecx, [.self]

        push    [ecx+TWindow._width] [ecx+TWindow._height]
        pop     [esi+__TInternalAlign.client.height] [esi+__TInternalAlign.client.width]

        xor     ecx,ecx

        mov     [esi+__TInternalAlign.client.y], ecx
        mov     [esi+__TInternalAlign.client.x], ecx
        mov     [esi+__TInternalAlign.pClientWindow], ecx

.loop:
        cmp     ecx, [edi+TArray.count]
        je      .endloop

        stdcall __DoAlignOne, [edi+TArray.array+8*ecx+TWinArrayItem.pWindow]
        inc     ecx
        jmp     .loop

.endloop:
        mov     ecx, [.winalign.pClientWindow]
        jecxz   .updatewindows

        mov     eax, [esi+__TInternalAlign.client.x]
        mov     edx, [esi+__TInternalAlign.client.y]
        sub     eax, [ecx+TWindow._x]
        sub     edx, [ecx+TWindow._y]
        mov     ebx, eax
        or      ebx, edx

        mov     eax, [esi+__TInternalAlign.client.width]
        mov     edx, [esi+__TInternalAlign.client.height]
        sub     eax, [ecx+TWindow._width]
        sub     edx, [ecx+TWindow._height]
        or      ebx, eax
        or      ebx, edx
        mov     [ecx+TWindow._bounds_changed], ebx

        push    [esi+__TInternalAlign.client.height] [esi+__TInternalAlign.client.width] [esi+__TInternalAlign.client.y] [esi+__TInternalAlign.client.x]
        pop     [ecx+TWindow._x] [ecx+TWindow._y] [ecx+TWindow._width] [ecx+TWindow._height]

.updatewindows:
        mov     ecx, [edi+TArray.count]

.updateloop:
        dec     ecx
        js      .endupdate

        mov     eax, [edi+8*ecx+TArray.array+TWinArrayItem.pWindow]
        cmp     [eax+TWindow._bounds_changed], 0
        je      .refresh_only

        lea     edx, [eax+TWindow._x]
;        mov     [eax+TWindow._bounds_changed], 0         - it will be zeroed in the seMoveResize event handler.
        stdcall _SetWindowBounds, [eax+TWindow.handle], edx

.refresh_only:
        stdcall _RefreshWindow, [eax+TWindow.handle]
        jmp     .updateloop

.endupdate:
        stdcall FreeMem, edi
        mov     eax, [.self]
        stdcall _RefreshWindow, [eax+TWindow.handle]

.endalign:
        pop     edi esi
        jmp     .finish

;.........................................................................................

.focus:
        mov     eax, [.self]
        stdcall _SetFocus, [eax+TWindow.handle]
        jmp     .finish

;.........................................................................................

.addchild:
; method parameter.
virtual at ebx
  .child dd ?
end virtual
        stdcall IsObject, [.child], CWindow
        jne     .add_non_window

        mov     ebx, [.child]
        mov     eax, [.self]

        stdcall _AddChild, [eax+TWindow.handle], [ebx+TWindow.handle]
        jmp     .finish

.add_non_window:        ; this is possible, but not implemented for now.
        jmp     .error
endp



;_________________________________________________________________________________________


proc TWindow.SysEventHandler, .pObj, .pEvent
begin
        push    eax ecx edx esi edi

        mov     esi, [.pObj]
        mov     ebx, [.pEvent]
        mov     eax, [ebx+TSysEvent.event]

        cmp     eax, seMouseEnter
        je      .mouseenter

        cmp     eax, seMouseLeave
        je      .mouseleave

        cmp     eax, seMouseBtnPress
        je      .btnpress

        cmp     eax, seMoveResize
        je      .moveresize

        cmp     eax, seKbdKeyPress
        je      .keypress

        stc
.finish:
        pop     edi esi edx ecx eax
        return

;.........................................................................................
.moveresize:
        mov     eax, [ebx+TMoveResizeEvent.newX]
        mov     ecx, [ebx+TMoveResizeEvent.newY]
        mov     [esi+TWindow._x], eax
        mov     [esi+TWindow._y], ecx

        mov     eax, [ebx+TMoveResizeEvent.newWidth]
        mov     ecx, [ebx+TMoveResizeEvent.newHeight]
        xchg    [esi+TWindow._width], eax
        xchg    [esi+TWindow._height], ecx
        sub     eax, [esi+TWindow._width]
        sub     ecx, [esi+TWindow._height]
        or      eax, ecx
        jnz     .alignchildren          ; when the resize is as a result of internal windows align, the _width and _height fields are already set.
                                        ; it must be this way, because the resize should be fast, but in Linux there is no DeferWindowPos function like in Win32

        cmp     [esi+TWindow._bounds_changed], 0
        je      .endresize

.alignchildren:
        execute esi, TWindow.AlignChildren
        mov     [esi+TWindow._bounds_changed], 0

.endresize:
        clc
        jmp     .finish

;.........................................................................................

.btnpress:
        execute esi, TWindow.Focus
        clc
        jmp     .finish

;.........................................................................................

.mouseenter:
        mov     eax, [esi+TWindow._cursor]
        test    eax, $ffffff00
        jnz     @f
        stdcall GetStockCursor, eax
@@:
        stdcall SetMouseCursor, eax
        clc
        jmp     .finish

;.........................................................................................
.mouseleave:
        stdcall GetStockCursor, mcArrow
        stdcall SetMouseCursor, eax
        clc
        jmp     .finish

;.........................................................................................

.keypress:
        cmp     [esi+TWindow.OnKeyPress], 0
        je      @f
        stdcall [esi+TWindow.OnKeyPress], esi, ebx
@@:
        clc
        jmp     .finish
endp



proc __DoAlignOne, .pWindow
.bounds TBounds
.align  dd ?
begin
        pushad

        mov     ebx, [.pWindow]
        cmp     [ebx+TWindow._align], waNone
        je      .exit
        cmp     [ebx+TWindow._align], waClient
        ja      .exit

        stdcall Get, ebx, TWindow.Visible
        test    eax, eax
        jz      .exit

        cmp     [ebx+TWindow._align], waClient
        jne     .doalign

; only one window with waClient may exists.
        cmp     [esi+__TInternalAlign.pClientWindow], 0
        jne     .exit

        mov     [esi+__TInternalAlign.pClientWindow], ebx
        jmp     .exit

.doalign:
        mov     eax, [ebx+TWindow._align]
        dec     eax
        mov     [.align], eax

; save the old bounds in order to detect change.
        mov     eax, [ebx+TWindow._x]
        mov     ecx, [ebx+TWindow._y]
        mov     [.bounds.x], eax
        mov     [.bounds.y], ecx
        mov     eax, [ebx+TWindow._width]
        mov     ecx, [ebx+TWindow._height]
        mov     [.bounds.width], eax
        mov     [.bounds.height], ecx

        mov     ecx, TBounds.width
        mov     edx, [ebx+TWindow._height]
        mov     edi, TBounds.y
        bt      [.align], 0     ; 0 - width; 1 - height
        jc      @f
        mov     ecx, TBounds.height
        mov     edx, [ebx+TWindow._width]
        mov     edi, TBounds.x
@@:
        mov     eax, [esi+__TInternalAlign.client+ecx]
        mov     [ebx+TWindow._x+ecx], eax

        mov     eax, [esi+__TInternalAlign.client.x]
        mov     ecx, [esi+__TInternalAlign.client.y]

        bt      [.align], 1     ; 0 - left/top; 1-right/bottom
        jnc     @f

        add     eax, [esi+__TInternalAlign.client.width]
        add     ecx, [esi+__TInternalAlign.client.height]
        sub     eax, [ebx+TWindow._width]
        sub     ecx, [ebx+TWindow._height]
        neg     edx
        add     edi, 8

@@:
        mov     [ebx+TWindow._x], eax
        mov     [ebx+TWindow._y], ecx
        add     [esi+__TInternalAlign.client+edi], edx
        test    edx, edx
        js      @f
        sub     [esi+__TInternalAlign.client+edi+8], edx
@@:
        mov     eax, [ebx+TWindow._x]
        mov     ecx, [ebx+TWindow._y]
        mov     edx, [ebx+TWindow._width]
        mov     edi, [ebx+TWindow._height]
        sub     eax, [.bounds.x]
        sub     ecx, [.bounds.y]
        sub     edx, [.bounds.width]
        sub     edi, [.bounds.height]
        or      ecx, eax
        or      edx, edi
        or      ecx, edx
        mov     [ebx+TWindow._bounds_changed], ecx

.exit:
        popad
        return
endp




endmodule

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/gui/ThemeGUI.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: This file contains procedures and data, that form the appearance of the
;               FreshLib GUI application. Colors, control borders, backgrownd drawing etc.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: The user should be able to change these settings and if he uses external
;         procedures, then the code from this library should not be compiled.
;_________________________________________________________________________________________
module "GUI theme data and code library"

; Box border type
bxNone   = 0
bxRaised = 1
bxSunken = 2
bxFlat   = 3
bxNoFill = $80000000

; Default colors
iglobal
  var clBorderLight   = $ffffff
  var clBorderDark    = $606060 ; soft shadow
  var clBorderNeutral = $a0a0a8

  var clEditBk        = $fffff0
  var clEditTxt       = $000000
  var clEditSel       = $0000a0
  var clEditSelTxt    = $ffffff

  var clButtonBk      = $d0d0d8
  var clButtonTxt     = $000000

  var clButtonHotBk   = $e0e0e8
  var clButtonHotTxt  = $0000ff

  var clDialogBk      = $d0d0d8
  var clDialogTxt     = $000000

  var clScrollBk      = $a0a0a0
  var clScrollSlider  = $d0d0d8

  if ~defined DrawBox | defined ___DrawBox
    var DrawBox = DrawBoxDefault
    ___DrawBox = 1
  end if

  if ~defined DrawSlider | defined ___DrawSlider
    var DrawSlider = DrawSliderDefault
    ___DrawSlider = 1
  end if


endg





; Midnight colors
;iglobal
;  var clBorderLight   = $0000ff
;  var clBorderDark    = $000000
;  var clBorderNeutral = $808080
;
;  var clEditBk        = $0000c0
;  var clEditTxt       = $ffffff
;  var clEditSel       = $0000ff
;  var clEditSelTxt    = $000000
;
;  var clButtonBk      = $000080
;  var clButtonTxt     = $ffffff
;
;  var clButtonHotBk   = $0000a0
;  var clButtonHotTxt  = $ffffff
;
;  var clDialogBk      = $000080
;  var clDialogTxt     = $ffffff
;endg




proc DrawBoxDefault, .context, .pBounds, .bkground, .border
  .brd RECT
begin
        push    eax ecx edx esi


        stdcall SetDrawMode, [.context], cmCopy

        mov     esi, [.pBounds]

        mov     edx, [.border]
        and     edx, $ff
        jz      .borderok

        mov     eax, [esi+TBounds.x]
        mov     ecx, [esi+TBounds.y]
        mov     [.brd.left], eax
        mov     [.brd.top], ecx

        add     eax, [esi+TBounds.width]
        add     ecx, [esi+TBounds.height]
        dec     eax
        dec     ecx
        mov     [.brd.right], eax
        mov     [.brd.bottom], ecx

        sub     [esi+TBounds.width], 2
        sub     [esi+TBounds.height], 2
        inc     [esi+TBounds.x]
        inc     [esi+TBounds.y]

        mov     eax, [clBorderLight]
        mov     ecx, [clBorderDark]

        cmp     edx, bxRaised
        je      .colorok

        xchg    eax, ecx

        cmp     edx, bxSunken
        je      .colorok

        mov     eax, [clBorderNeutral]
        mov     ecx, eax

.colorok:
        stdcall SetSimpleLine, [.context], eax
        stdcall DrawLine, [.context], [.brd.left],  [.brd.top], [.brd.left], [.brd.bottom]
        stdcall DrawLine, [.context], [.brd.left],  [.brd.top], [.brd.right], [.brd.top]

        stdcall SetSimpleLine, [.context], ecx
        stdcall DrawLine, [.context], [.brd.left], [.brd.bottom], [.brd.right], [.brd.bottom]
        inc      [.brd.bottom]
        stdcall DrawLine, [.context], [.brd.right], [.brd.top], [.brd.right], [.brd.bottom]

.borderok:
        bt      [.border], 31
        jc      .fillok
        stdcall DrawFillRect, [.context], [esi+TBounds.x], [esi+TBounds.y], [esi+TBounds.width], [esi+TBounds.height], [.bkground]

; additional 1px margin
        sub     [esi+TBounds.width], 2
        sub     [esi+TBounds.height], 2
        inc     [esi+TBounds.x]
        inc     [esi+TBounds.y]

.fillok:
        pop     esi edx ecx eax
        return
endp


sliderHorizontal = 0
sliderVertical   = 1

proc DrawSliderDefault, .context, .pBounds, .bkground, .type
begin
        stdcall [DrawBox], [.context], [.pBounds], [.bkground], bxRaised
        return
endp



endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































Deleted freshlib/gui/Win32/Main.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Main procedure of GUI application library.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes: Organize the main message/event loop needed by every GUI engine.
;_________________________________________________________________________________________

proc ProcessSystemEvents
.msg MSG
begin
        push    ecx edx esi

.msgloop:
        lea     esi, [.msg]
        xor     eax, eax

        invoke  PeekMessageW, esi, eax, eax, eax, PM_REMOVE
        test    eax, eax
        jz      .exitok

        cmp     [.msg.message], WM_TIMER
        je      .translate                      ; express dispatching of the timer messages.

        cmp     [.msg.message], WM_QUIT
        je      .terminate

        stdcall __ProcessOneSystemEvent, [esi+MSG.hwnd], [esi+MSG.message], [esi+MSG.wParam], [esi+MSG.lParam]
        jnc     .msgloop                ; the message is translated to system event and the event is executed by the object SysEvent handler.

; the message is for window that is not an FreshLib object, so process with standard windows behaviour.
;        invoke  TranslateMessage, esi
.translate:
        invoke  DispatchMessageW, esi
        jmp     .msgloop


.exitok:
        clc
        pop     esi edx ecx
        return


.terminate:
        mov     eax, [.msg.wParam]
        stc
        pop     esi edx ecx
        return
endp



proc WaitForSystemEvent
begin
        push    eax ecx edx
        invoke  WaitMessage
        pop     edx ecx eax
        return
endp




;proc EventsQueued, .pWin
;.msg MSG
;begin
;        push    eax ecx edx
;        mov     eax, [.pWin]
;        mov     ecx, [eax+TWindow.handle]
;        lea     eax, [.msg]
;        invoke  PeekMessage, eax, ecx, 0, 0, PM_NOREMOVE
;        test    eax, eax
;        clc
;        jz      @f
;        stc
;@@:
;        pop     edx ecx eax
;        return
;endp
;

;----------------------------------------------------------------------------------------------------------
; This procedure makes following:
;   1. Takes as arguments one windows message
;   2. Converts this message to FreshLib system event (or not, depending on the message)
;   3. Calls SysEventHandler procedures for the given object (if any) with the created event structure.
;   4. returns CF=0 if the event was properly processed.
;   5. returns CF=1 if the event was not processed.
;
; The event can be not processed in the following cases:
;   1. The window that receives the message is not FreshLib object.
;   2. TObjectClass.procSysEventHandler = 0 for the given class and all parents.
;   3. All procSysEventHandler procedures refuse to process the event (CF=1)
;----------------------------------------------------------------------------------------------------------
uglobal
  if used __LatestPointedObj
    __LatestPointedObj dd ?
  end if
endg


dproc __ProcessOneSystemEvent, .hwnd, .wmsg, .wparam, .lparam
.event  rb 32
begin
        push    eax ebx ecx edx esi edi

        stdcall _GetWindowStruct, [.hwnd]
        test    eax, eax
        jz      .ondefault

        mov     esi, eax
        lea     edi, [.event]

        dispatch [.wmsg]

.ondefault:
        pop     edi esi edx ecx ebx eax
        stc
        return

;.........................................................................................

.exec_event:
        stdcall ExecEvent, esi, edi

.finish:
        pop     edi esi edx ecx ebx eax
        clc
        return

;.........................................................................................

oncase WM_MOUSEWHEEL

          mov   eax, [.wparam]
          sar   eax, 16
          mov   ecx, scWheelUp
          test  eax, eax
          jns   @f
          mov   ecx, scWheelDn
          neg   eax
@@:
          mov   [edi+TScrollEvent.event], seScroll
          mov   [edi+TScrollEvent.ScrollBar], scrollY
          mov   [edi+TScrollEvent.ScrollCmd], ecx

          xor   edx, edx
          mov   ecx, 120
          idiv  ecx
          mov   [edi+TScrollEvent.Value], eax

          jmp   .exec_event

;.........................................................................................

oncase WM_WINDOWPOSCHANGED

locals
  .rect RECT
endl
        mov     ebx, [.lparam]

        lea     eax, [edi+TMoveResizeEvent.newX]
        invoke  GetClientRect, [.hwnd], eax

        mov     eax, [ebx+WINDOWPOS.x]
        mov     ecx, [ebx+WINDOWPOS.y]
        mov     [edi+TMoveResizeEvent.newX], eax
        mov     [edi+TMoveResizeEvent.newY], ecx

        mov     [edi+TMoveResizeEvent.event], seMoveResize
        jmp     .exec_event



;.........................................................................................

oncase WM_SYSKEYDOWN
oncase WM_SYSKEYUP
oncase WM_KEYDOWN
oncase WM_KEYUP
locals
  .keyboard rb 256
  .unicode rw 16
  .utf8    rb 16
endl
        lea     ebx, [.keyboard]
        invoke  GetKeyboardState, ebx
        mov     eax, [.lparam]
        mov     ecx, eax
        shr     eax, 16
        and     ecx, $80000000
        and     eax, $ff
        mov     [edi+TKeyboardEvent.scancode], eax
        or      eax, ecx
        lea     edx, [.unicode]
        invoke  ToUnicode, [.wparam], eax, ebx, edx, 16, 0
        xor     ecx, ecx
        test    eax, eax
        jz      .key_translated    ; the key can not be translated.
        js      .key_translated    ; it is a dead key. What we have to do???

        lea     edx, [.utf8]
        xor     ecx, ecx
        mov     [edx], ecx
        mov     [edx+4], ecx
        lea     ecx, [.unicode]
        invoke  WideCharToMultiByte, CP_UTF8, 0, ecx, eax, edx, 8, 0, 0
        xor     ecx, ecx
        test    eax, eax
        jz      .key_translated

        mov     ecx, dword [.utf8]

.key_translated:
        mov     [edi+TKeyboardEvent.key], ecx

        mov     ecx, seKbdKeyPress
        cmp     [.wmsg], WM_KEYDOWN
        je      @f
        cmp     [.wmsg], WM_SYSKEYDOWN
        je      @f
        mov     ecx, seKbdKeyRelease
@@:
        mov     [edi+TKeyboardEvent.event], ecx

        xor     eax, eax
        test    [.keyboard+VK_CONTROL], $80
        jz      @f
        or      eax, maskCtrl
@@:
        test    [.keyboard+VK_SHIFT], $80
        jz      @f
        or      eax, maskShift
@@:
        test    [.keyboard+VK_MENU], $80
        jz      @f
        or      eax, maskAlt
@@:
        test    [.keyboard+VK_SCROLL], $01
        jz      @f
        or      eax, maskScrLk
@@:
        test    [.keyboard+VK_CAPITAL], $01
        jz      @f
        or      eax, maskCapsLock
@@:

;        or      eax, [__MouseButtonMask]
;        OutputRegister regEAX, 16

        mov     [edi+TKeyboardEvent.kbdStatus], eax
        jmp     .exec_event


;.........................................................................................


oncase WM_SETFOCUS
        mov     [edi+TFocusInEvent.event], seFocusIn
        jmp     .exec_event


;.........................................................................................


oncase WM_KILLFOCUS
        mov     [edi+TFocusOutEvent.event], seFocusOut
        jmp     .exec_event


;.........................................................................................


oncase WM_SETCURSOR

        movzx   eax, word [.lparam]
        cmp     eax, HTCLIENT
        jne     .ondefault

        mov     eax, [esi+TWindow._cursor]
        test    eax, $ffffff00
        jnz     .customcursor

        stdcall GetStockCursor, eax

.customcursor:
        stdcall SetMouseCursor, eax
        jmp     .finish


;.........................................................................................


oncase WM_MOUSEMOVE
        cmp     esi, [__LatestPointedObj]
        je      .normal_mouse_move

        mov     [edi+TMouseEnterEvent.event], seMouseLeave
        xchg    esi, [__LatestPointedObj]
        test    esi, esi
        jz      .leaveok
        stdcall ExecEvent, esi, edi

.leaveok:
        mov     esi, [__LatestPointedObj]
        mov     [edi+TMouseEnterEvent.event], seMouseEnter
        stdcall ExecEvent, esi, edi

.normal_mouse_move:
        mov     [edi+TMouseMoveEvent.event], seMouseMove
        movsx   eax, word [.lparam]
        movsx   ecx, word [.lparam+2]
        mov     [edi+TMouseMoveEvent.x], eax
        mov     [edi+TMouseMoveEvent.y], ecx
        jmp     .exec_event



;.........................................................................................

oncase WM_PAINT
locals
  .ps PAINTSTRUCT
  .context TContext
  .caret   dd ?
  .rect2    RECT
endl
        lea     eax, [.rect2]
        invoke  GetUpdateRect, [.hwnd], eax, FALSE
        test    eax, eax
        jz      .endpaint

        lea     eax, [.ps]
        invoke  BeginPaint, [.hwnd], eax

if defined Caret
        mov     [.caret], -1
        cmp     esi, [Caret.pWindow]
        jne     @f

        stdcall CaretShow, FALSE
        mov     [.caret], eax
@@:
end if

        mov     [edi+TPaintEvent.event], sePaint
        push    [.ps.hdc]
        pop     [.context.handle]
        push    [.hwnd]
        pop     [.context.raster]

        lea     eax, [.context]
        mov     [edi+TPaintEvent.context], eax

; ?????????????????????????????
;        push    [.ps.rcPaint.left] [.ps.rcPaint.top]
        push     [.rect2.left] [.rect2.top]
        pop     [edi+TPaintEvent.rect.top] [edi+TPaintEvent.rect.left]
;        push    [.ps.rcPaint.right] [.ps.rcPaint.bottom]
         push    [.rect2.right] [.rect2.bottom]
        pop     [edi+TPaintEvent.rect.bottom] [edi+TPaintEvent.rect.right]

        stdcall ExecEvent, esi, edi

        lea     eax, [.ps]
        invoke  EndPaint, [.hwnd], eax

if defined Caret
        cmp     [.caret], -1
        je      @f
        stdcall CaretShow, [.caret]
@@:
end if

.endpaint:
        pop     edi esi edx ecx ebx eax
        clc
        return


;.........................................................................................


oncase WM_CLOSE
        mov     eax, [pApplication]
        mov     eax, [eax+TApplication.MainWindow]
        cmp     [eax], esi
        jne     @f

DebugMsg "Quit message posted."
        invoke  PostQuitMessage, 0

@@:
        mov     [edi+TCloseEvent.event], seCloseRequest
        mov     [edi+TCloseEvent.reason], cerFromUser
        jmp     .exec_event

oncase WM_DESTROY
        cmp     esi, [__LatestPointedObj]
        jne     .ondefault

        mov     [__LatestPointedObj], 0
        jmp     .ondefault

;.........................................................................................


oncase WM_LBUTTONUP
oncase WM_RBUTTONUP
oncase WM_MBUTTONUP
oncase WM_LBUTTONDOWN
oncase WM_RBUTTONDOWN
oncase WM_MBUTTONDOWN
oncase WM_LBUTTONDBLCLK
oncase WM_RBUTTONDBLCLK
oncase WM_MBUTTONDBLCLK

        stdcall __MouseButton, [.wmsg]
        mov     [edi+TMouseButtonEvent.event], ecx
        mov     [edi+TMouseButtonEvent.Button], eax
        stdcall __KeyStatus, [.wparam]
        mov     [edi+TMouseButtonEvent.kbdStatus], eax

        movsx   eax, word [.lparam]
        movsx   ecx, word [.lparam+2]
        mov     [edi+TMouseButtonEvent.x], eax
        mov     [edi+TMouseButtonEvent.y], ecx


        jmp     .exec_event
enddp



proc __MouseButton, .msg
begin
        mov     eax, [.msg]
        sub     eax, WM_LBUTTONDOWN
        movzx   ecx, byte [__mouse_event_table+eax]
        movzx   eax, byte [__mouse_button_table+eax]
        return
endp


iglobal
  if used __mouse_button_table
  __mouse_button_table db mbLeft,        mbLeft,       mbLeft
                       db mbRight,       mbRight,      mbRight
                       db mbMiddle,      mbMiddle,     mbMiddle
  end if

  if used __mouse_event_table
  __mouse_event_table  db seMouseBtnPress, seMouseBtnRelease, seMouseBtnDblClick
                       db seMouseBtnPress, seMouseBtnRelease, seMouseBtnDblClick
                       db seMouseBtnPress, seMouseBtnRelease, seMouseBtnDblClick
  end if
endg


;.........................................................................................



proc __KeyStatus, .status
begin
        xor     eax, eax
        test    [.status], MK_LBUTTON
        jz      @f
        or      eax, maskBtnLeft
@@:
        test    [.status], MK_RBUTTON
        jz      @f
        or      eax, maskBtnRight
@@:
        test    [.status], MK_MBUTTON
        jz      @f
        or      eax, maskBtnMiddle
@@:
        test    [.status], MK_SHIFT
        jz      @f
        or      eax, maskCtrl
@@:
        test    [.status], MK_CONTROL
        jz      @f
        or      eax, maskCtrl
@@:
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/gui/Win32/TApplication.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: TApplication object class.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes: TApplication by the idea is the base of GUI application, but the implementation
;         somehow need fixing...
;_________________________________________________________________________________________

uglobal
  if used hInstance
    hInstance dd ?
  end if
endg


proc TApplication.Create, .obj
begin
        push    eax ecx edx
        invoke  GetModuleHandleW, 0
        mov     [hInstance], eax

        clc
        pop     edx ecx eax
        return
endp



proc TApplication.Get, .obj, .paramID
begin
        stc
        return
endp




proc TApplication.Set, .obj, .paramID, .value
begin
        stc
        return
endp



proc TApplication.SysEventHandler, .obj, .event
begin
        stc
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































Deleted freshlib/gui/Win32/keycodes.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: This file contains scan code values for control keyboard keys.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

keyHomeNumpad  = $47
keyUpNumpad    = $48
keyPgUpNumpad  = $49
keyLeftNumpad  = $4b
key5Numpad     = $4c
keyRightNumpad = $4d
keyEndNumpad   = $4f
keyDownNumpad  = $50
keyPgDnNumpad  = $51
keyInsNumpad   = $52
keyDelNumpad   = $53
keyEnterNumpad = $1c    ; it is ASCII $0d
keyPlusNumpad  = $4e
keyMinusNumpad = $4a
keyAsteriskNumpad = $37
keySlashNumpad = $35

keyNumLock     = $45
keyScrollLock  = $46
keyPause       = $45
keyPrtScr      = $37


keyLeft =  $4b
keyRight = $4d
keyUp    = $48
keyDown  = $50

keyInsert  = $52
keyDelete  = $53
keyHome    = $47
keyEnd     = $4f
keyPgUp    = $49
keyPgDown  = $51

keyF1   =  $3b
keyF2   =  $3c
keyF3   =  $3d
keyF4   =  $3e

keyF5   =  $3f
keyF6   =  $40
keyF7   =  $41
keyF8   =  $42

keyF9   =  $43
keyF10  =  $44 ; used for menu and does not generate WM_KEYDOWN.
keyF11  =  $57
keyF12  =  $58

keyCapsLock   = $3a
keyShiftLeft  = $2a
keyCtrlLeft   = $1d
keyWndLeft    = $5b
keyWndRight   = $5c
keyAltLeft    = $38
keyAltRight   = $38
keyPopupMenu  = $5d
keyShiftRight = $36
keyCtrlRight  = $1d

keyBackSpace  = $0e

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































Deleted freshlib/gui/Win32/mouse.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Provides unified access to standard mouse cursors.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

; ToDo: Arbitrary mouse cursors, B&W for the begining.


proc SetMouseCursor, .hCursor
begin
        push    ecx edx
        invoke  SetCursor, [.hCursor]
        pop     edx ecx
        return
endp



proc GetStockCursor, .index
begin
        push    ecx edx
        mov     eax, [.index]
        and     eax, 7
        movzx   eax, [_cursors+2*eax]
        invoke  LoadCursorW, 0, eax
        pop     edx ecx
        return
endp

if used _cursors
  _cursors dw IDC_ARROW, IDC_IBEAM, IDC_CROSS, IDC_SIZEWE, IDC_SIZENS, IDC_SIZENWSE, IDC_SIZENESW, IDC_WAIT
end if



proc MouseCapture, .hwnd
begin
        push    eax ecx edx
        cmp     [.hwnd], 0
        je      .release

        invoke  SetCapture, [.hwnd]

.finish:
        pop     edx ecx eax
        return

.release:
        invoke  ReleaseCapture
        jmp     .finish
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































Deleted freshlib/gui/Win32/windows.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Window management OS interface functions.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

iglobal
if used cWindowClassName
  cWindowClassName du 'FreshWin', 0
end if
endg

nWindowExtraBytes = 32
ofsWindowStruct = nWindowExtraBytes - 4

;_________________________________________________________________________________________
;
; Registers common window class
; Call only once
;_________________________________________________________________________________________

if used _CreateNullWindow
initialize __RegisterWindowClass

.wc WNDCLASS

begin
        xor     eax, eax
        lea     edi, [.wc]
        mov     ecx, sizeof.WNDCLASS / 4
        rep stosd

        mov     [.wc.style], CS_OWNDC or CS_DBLCLKS; or CS_VREDRAW or CS_HREDRAW
        mov     [.wc.lpfnWndProc], __CommonWindowProc
        mov     [.wc.cbWndExtra], nWindowExtraBytes

;        invoke  CreateSolidBrush, $0000ff
;        mov     [.wc.hbrBackground], eax

        mov     eax,[hInstance]
        mov     [.wc.hInstance],eax
        mov     [.wc.lpszClassName], cWindowClassName

        lea     eax, [.wc]
        invoke  RegisterClassW, eax

        return
endp
end if



;_________________________________________________________________________________________


proc _CreateNullWindow
begin
        push    ecx edx
        invoke  CreateWindowExW, 0, cWindowClassName, 0, WS_CLIPSIBLINGS or WS_CLIPCHILDREN, 0, 0, 0, 0, 0, 0, 0, 0
        pop     edx ecx
        return
endp

;_________________________________________________________________________________________



proc _DestroyWindow, .hwnd
begin
        push    eax ecx edx
        invoke  DestroyWindow, [.hwnd]
        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc _GetParent, .hwnd
begin
        push    ecx edx
        invoke  GetParent, [.hwnd]
        pop     edx ecx
        return
endp

;_________________________________________________________________________________________


proc _GetChildren, .hwnd
begin
        push    ebx ecx edx

        xor     ebx, ebx

        invoke  GetWindow, [.hwnd], GW_CHILD
        mov     ecx, eax
        jecxz   .endchildren

        stdcall CreateArray, sizeof.TWinArrayItem
        mov     ebx, eax

.loophwnd:
        stdcall AddArrayItems, ebx, 1
        mov     ebx, edx

        mov     [eax+TWinArrayItem.handle], ecx

        invoke  GetWindow, ecx, GW_HWNDNEXT
        mov     ecx, eax
        jecxz   .endchildren
        jmp     .loophwnd

.endchildren:
        mov     eax, ebx
        pop     edx ecx ebx
        return
endp


;_________________________________________________________________________________________



proc _GetVisible, .hwnd
begin
        push    ecx edx
        invoke  IsWindowVisible, [.hwnd]
        pop     edx ecx
        return
endp

;_________________________________________________________________________________________


proc _GetWindowBounds, .hwnd, .pBounds
begin
        push    eax ecx edx

        invoke  GetClientRect, [.hwnd], [.pBounds]
        invoke  GetParent, [.hwnd]
        invoke  MapWindowPoints, [.hwnd], eax, [.pBounds], 2

        mov     edx, [.pBounds]
        mov     eax, [edx+TBounds.width]
        mov     ecx, [edx+TBounds.height]
        sub     eax, [edx+TBounds.x]
        sub     ecx, [edx+TBounds.y]
        mov     [edx+TBounds.width], eax
        mov     [edx+TBounds.height], ecx

        pop     edx ecx eax
        return
endp



;_________________________________________________________________________________________


proc _SetWindowBounds, .hwnd, .pBounds
.rect RECT
begin
        push    eax ecx edx

        mov     eax, [.pBounds]
        push    [eax+TBounds.width] [eax+TBounds.height]
        pop     [.rect.bottom] [.rect.right]
        mov     [.rect.left], 0
        mov     [.rect.top], 0

        invoke  GetWindowLongW, [.hwnd], GWL_EXSTYLE
        push    eax
        push    FALSE
        invoke  GetWindowLongW, [.hwnd], GWL_STYLE
        push    eax

        lea     eax, [.rect]
        invoke  AdjustWindowRectEx, eax ; and from the stack

        mov     eax, [.rect.right]
        mov     ecx, [.rect.bottom]
        sub     eax, [.rect.left]
        sub     ecx, [.rect.top]

        mov     edx, [.pBounds]
        invoke  SetWindowPos, [.hwnd], 0, [edx+TBounds.x], [edx+TBounds.y], eax, ecx, SWP_NOZORDER or SWP_NOREDRAW

        pop     edx ecx eax
        return
endp





;_________________________________________________________________________________________
wsNoneWindowBorder = WS_POPUP
wsFullWindowBorder = WS_BORDER or WS_CAPTION or WS_SYSMENU or WS_SIZEBOX or WS_MINIMIZEBOX or WS_MAXIMIZEBOX
wsModalWindowBorder  = WS_CAPTION or WS_DLGFRAME or WS_SYSMENU
wsToolboxWindowBorder = WS_BORDER or WS_CAPTION or WS_SYSMENU or WS_SIZEBOX

wsAllWindowBorder = wsNoneWindowBorder or wsFullWindowBorder or wsModalWindowBorder or wsToolboxWindowBorder

proc _SetWindowBorder, .hwnd, .brdType
.bounds TBounds
begin
        push    eax ebx ecx edx esi

        invoke  GetWindowLongW, [.hwnd], GWL_STYLE
        mov     ebx, eax

        mov     esi, [.brdType]
        and     esi, 3

        invoke  SetWindowLongW, [.hwnd], GWL_EXSTYLE, [.exstyles+4*esi]

        and     ebx, not wsAllWindowBorder
        or      ebx, [.styles+4*esi]
        invoke  SetWindowLongW, [.hwnd], GWL_STYLE, ebx

        lea     esi, [.bounds]
        stdcall _GetWindowBounds, [.hwnd], esi
        stdcall _SetWindowBounds, [.hwnd], esi

        pop     esi edx ecx ebx eax
        return

.styles dd wsNoneWindowBorder
        dd wsFullWindowBorder
        dd wsModalWindowBorder
        dd wsToolboxWindowBorder

.exstyles dd 0
          dd WS_EX_APPWINDOW
          dd WS_EX_DLGMODALFRAME
          dd WS_EX_TOOLWINDOW

endp

;_________________________________________________________________________________________

proc _ShowWindow, .hwnd, .flag
begin
        push    eax ecx edx
        invoke  ShowWindow, [.hwnd], [.flag]
        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc _RefreshWindow, .hwnd
.rect RECT
begin
        push    eax ecx edx

;        lea     eax, [.rect]
;        invoke  GetClientRect, [.hwnd], eax
;        lea     eax, [.rect]
        invoke  InvalidateRect, [.hwnd], 0, FALSE

        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc _SetFocus, .hwnd
begin
        push    eax ecx edx

        invoke  SetFocus, [.hwnd]

        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________

proc _AddChild, .hwnd, .child
begin
        push    eax ecx edx

        invoke  GetWindowLongW, [.child], GWL_STYLE
        or      eax, WS_CHILD
        and     eax, not (WS_DLGFRAME or WS_BORDER)
        invoke  SetWindowLongW, [.child], GWL_STYLE, eax
        invoke  SetParent, [.child], [.hwnd]

        pop     edx ecx eax
        return
endp

;_________________________________________________________________________________________


; Common utility procedures.


;_________________________________________________________________________________________
;
; Returns the window TObject structure, from the window handle.
;_________________________________________________________________________________________

proc _GetWindowStruct, .hwin
begin
        push    ecx edx
        invoke  GetWindowLongW, [.hwin], ofsWindowStruct
        pop     edx ecx
        return
endp



;_________________________________________________________________________________________



proc _SetWindowStruct, .hwin, .value
begin
        push    eax ecx edx
        invoke  SetWindowLongW, [.hwin], ofsWindowStruct, [.value]
        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________



proc _SetWindowTextUtf8, .hwnd, .ptrUtf8
.pwc dd ?
.charlen dd ?
begin
        stdcall StrLen, [.ptrUtf8]
        lea     ecx, [eax*4]

        stdcall GetMem, ecx
        mov     [.pwc], eax

        invoke  MultiByteToWideChar, CP_UTF8, 0, [.ptrUtf8], -1, [.pwc], ecx
        mov     [.charlen], eax

        invoke  SendMessageW, [.hwnd], WM_SETTEXT, 0, [.pwc]
        stdcall FreeMem, [.pwc]
        return
endp



;_________________________________________________________________________________________



proc _GetWindowTextUtf8, .hwnd, .ptrUtf8
.pwc dd ?
.charlen dd ?
begin
        push    ebx ecx edx edi
        stdcall StrNew
        mov     ebx, eax

        invoke  SendMessage, [.hwnd], WM_GETTEXTLENGTH, 0, 0
        mov     [.charlen], eax
        lea     ecx, [eax*4]

        stdcall StrSetCapacity, ebx, ecx
        mov     edi, eax

        stdcall GetMem, ecx
        mov     [.pwc], eax

        invoke  SendMessage, [.hwnd], WM_GETTEXT, [.charlen], [.pwc]
        invoke  WideCharToMultiByte, CP_UTF8, 0, [.pwc], -1, edi, [edi+string.capacity], 0, 0
        stdcall FreeMem, [.pwc]
        stdcall StrFixLen, ebx
        mov     eax, ebx
        pop     edi edx ecx ebx
        return
endp



;_________________________________________________________________________________________


proc _EnableWindow, .hwnd, .flag
begin
        push    eax ecx edx
        invoke  EnableWindow, [.hwnd], [.flag]
        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc _SetModalTowards, .hwnd, .hwndParent
begin
        push    eax ecx edx
        stdcall _SetWindowBorder, [.hwnd], borderModal
        invoke  SetWindowLongW, [.hwnd], GWL_HWNDPARENT, [.hwndParent]

        pop     edx ecx eax
        return
endp


;_________________________________________________________________________________________


proc _FinalizeModal, .hwnd, .hwndParent
begin
        return
endp


;_________________________________________________________________________________________


proc __CommonWindowProc, .hwnd, .wmsg, .wparam, .lparam
begin
        stdcall __ProcessOneSystemEvent, [.hwnd], [.wmsg], [.wparam], [.lparam]         ; sometimes windows calls winproc directly instead of using postmessage.
        jnc     .finish

        invoke  DefWindowProcW, [.hwnd], [.wmsg], [.wparam], [.lparam]

.finish:
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/gui/all.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: All GUI libraries combined include.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Includes all GUI libraries at once.
;_________________________________________________________________________________________

AlignLeft   = 0
AlignRight  = 1
AlignTop    = 2
AlignBottom = 3

include 'sysevents.asm'

include 'mouse.asm'
include 'textcaret.asm'

; OS independent support code
include 'objects.asm'
include 'TAction.asm'

; OS independent template engine.
include 'ObjTemplates.asm'

; OS independent components
include 'TObject.asm'
include 'TWindow.asm'
include 'TScrollWindow.asm'

include 'TApplication.asm'
include 'TForm.asm'
include 'TButton.asm'
include 'TEdit.asm'
include 'TLabel.asm'
include 'TImageLabel.asm'
include 'TMenuItem.asm'
include 'TMenu.asm'
include 'TProgressbar.asm'
include 'TTreeView.asm'

include 'ThemeGUI.asm'

include 'dialogs.asm'

; OS independent main procedures.
include 'Main.asm'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































Deleted freshlib/gui/dialogs.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Common dialogs procedures library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________
module "Common dialogs library"


iglobal
   getfile _DlgIconError,       '%lib%/gui/images/error.gif'
   getfile _DlgIconInformation, '%lib%/gui/images/information.gif'
   getfile _DlgIconQuestion,    '%lib%/gui/images/question.gif'
   getfile _DlgIconWarning,     '%lib%/gui/images/warning.gif'
   getfile _DlgMaskDialogIcons, '%lib%/gui/images/icon_mask.gif'

   if used _CommonDialogTemplate
    _CommonDialogTemplate:
        ObjTemplate  tfParent or tfEnd, Form, frmCommonDialog, x, 200, y, 100, width, 480, height, 100
           ObjTemplate tfChild, ImageLabel, .imgIcon,  x, 4, y, 4, width, 50, height, 50, Visible, TRUE, ImageAlign, iaCenter or iaMiddle
           ObjTemplate tfChild, Label,  .LblText,   x,58, y, 4, width, 10, height, 10, TextAlign, dtfAlignLeft or dtfAlignMiddle or dtfWordWrap or dtfCRLF, Visible, TRUE

           ObjTemplate tfChild, Button, .btnOK,     x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'OK',     ModalResult, mrOK
           ObjTemplate tfChild, Button, .btnCancel, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Cancel', ModalResult, mrCancel
           ObjTemplate tfChild, Button, .btnAbort,  x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Abort',  ModalResult, mrAbort
           ObjTemplate tfChild, Button, .btnRetry,  x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Retry',  ModalResult, mrRetry
           ObjTemplate tfChild, Button, .btnIgnore, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Ignore', ModalResult, mrIgnore
           ObjTemplate tfChild, Button, .btnYes,    x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Yes',    ModalResult, mrYes
           ObjTemplate tfChild, Button, .btnNo,     x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'No',     ModalResult, mrNo
           ObjTemplate tfChild, Button, .btnMaybe,  x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Maybe',  ModalResult, mrMaybe
           ObjTemplate tfEnd,   Button, .btnHelp,   x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter  or dtfAlignMiddle, Caption, 'Help',   ModalResult, mrNone
   end if
endg


; buttons flags used:
smbOK     = $01
smbCancel = $02
smbAbort  = $04
smbRetry  = $08
smbIgnore = $10
smbYes    = $20
smbNo     = $40
smbMaybe  = $80
smbHelp   = $100
smbMaxButton = smbHelp

smiError       = 0
smiInformation = 1
smiQuestion    = 2
smiWarning     = 3



proc ShowMessage, .parent, .icon, .hTitle, .hMessage, .maskButtons
.xrow dd ?
.yrow dd ?
.hicon dd ?
.hmask dd ?
begin
        push    ebx ecx edx esi
        stdcall CreateFromTemplate, _CommonDialogTemplate, 0

; First set the position and size of the dialog box, depending on the flags, and the size of the message.



; Set the message text:
        stdcall Set, [frmCommonDialog.LblText], TLabel.Caption, [.hMessage]

; Set the message title:
        stdcall  Set, ebx, TForm.Caption, [.hTitle]

; arrange the buttons
        mov     eax, [.maskButtons]
        mov     ecx, 32
        xor     edx, edx
.count:
        rol     eax, 1
        adc     edx, 0
        loop    .count

        mov     ecx, edx
        imul    edx, 64         ; button width
        jecxz   @f
        dec     ecx
        imul    ecx, 16
@@:
        add     edx, ecx        ; edx contains the width of the button row in pixels.

        stdcall Get, ebx, TForm.width
        cmp     eax, edx
        jge     .widthok

        lea     eax, [edx+32]
        stdcall Set, ebx, TForm.width, eax

.widthok:
        sub     eax, edx
        sar     eax, 1  ; eax is the begin X coordinate of the row
        mov     [.xrow], eax

        stdcall Get, ebx, TForm.height
        sub     eax, 24+8
        mov     [.yrow], eax

        mov     edx, .btnTable
        mov     ecx, $1

.btnLoop:
        test    [.maskButtons], ecx
        jz      @f

        mov     esi, [edx]
        stdcall Set, [esi], TButton.x, [.xrow]
        stdcall Set, [esi], TButton.y, [.yrow]
        stdcall Set, [esi], TButton.Visible, TRUE
        add     [.xrow], 64+16

@@:
        add     edx, 4
        shl     ecx, 1
        cmp     ecx, smbMaxButton
        jbe     .btnLoop

; set the icon
        mov     eax, [.icon]
        cmp     eax, .iconCount
        jb      @f
        xor     eax, eax
@@:
        stdcall CreateImageGIF, [.iconTable+4*eax], [.iconSizes+4*eax]
        OutputRegister regEAX, 16
        mov     [.hicon], eax
        stdcall Set, [frmCommonDialog.imgIcon], TImageLabel.Image, eax

        stdcall CreateImageGIF, _DlgMaskDialogIcons, _DlgMaskDialogIcons.size
        OutputRegister regEAX, 16
        mov     [.hmask], eax
        stdcall Set, [frmCommonDialog.imgIcon], TImageLabel.Mask, eax

; set the text position and size.
        mov     ecx, [.yrow]
        sub     ecx, 8
        stdcall Set, [frmCommonDialog.LblText], TLabel.height, ecx
        stdcall Set, [frmCommonDialog.imgIcon], TImageLabel.height, ecx

        stdcall Get, [frmCommonDialog], TForm.width
        sub     eax, 66
        stdcall Set, [frmCommonDialog.LblText], TLabel.width, eax

        stdcall ShowModal, ebx, [.parent]
        stdcall Destroy, ebx
        stdcall DestroyImage, [.hicon]
        stdcall DestroyImage, [.hmask]

        pop     esi edx ecx ebx
        return

.btnTable dd frmCommonDialog.btnOK,     \
             frmCommonDialog.btnCancel, \
             frmCommonDialog.btnAbort,  \
             frmCommonDialog.btnRetry,  \
             frmCommonDialog.btnIgnore, \
             frmCommonDialog.btnYes,    \
             frmCommonDialog.btnNo,     \
             frmCommonDialog.btnMaybe,  \
             frmCommonDialog.btnHelp

.iconTable dd _DlgIconError, _DlgIconInformation, _DlgIconQuestion, _DlgIconWarning
.iconCount = ($ - .iconTable)/4
.iconSizes dd _DlgIconError.size, _DlgIconInformation.size, _DlgIconQuestion.size, _DlgIconWarning.size

endp


proc InputString, .parent
begin


        return
endp






endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































Deleted freshlib/gui/images/error.gif.

cannot compute difference between binary files

Deleted freshlib/gui/images/icon_mask.gif.

cannot compute difference between binary files

Deleted freshlib/gui/images/information.gif.

cannot compute difference between binary files

Deleted freshlib/gui/images/question.gif.

cannot compute difference between binary files

Deleted freshlib/gui/images/theme_rhomb/Icons.odg.

cannot compute difference between binary files

Deleted freshlib/gui/images/theme_rhomb/myown/error.gif.

cannot compute difference between binary files

Deleted freshlib/gui/images/theme_rhomb/myown/information.gif.

cannot compute difference between binary files

Deleted freshlib/gui/images/theme_rhomb/myown/mask.gif.

cannot compute difference between binary files

Deleted freshlib/gui/images/theme_rhomb/myown/question.gif.

cannot compute difference between binary files

Deleted freshlib/gui/images/theme_rhomb/myown/warning.gif.

cannot compute difference between binary files

Deleted freshlib/gui/images/warning.gif.

cannot compute difference between binary files

Deleted freshlib/gui/mouse.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Provides unified access to standard mouse cursors.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: This file contains OS independent part and includes OS dependent files.
;_________________________________________________________________________________________
module "Mouse library"

mcArrow = 0
mcText  = 1
mcCross = 2
mcSizeH = 3
mcSizeV = 4
mcSizeUL_LR = 5
mcSizeLL_UR = 6
mcWait      = 7

mcCount = 8

include '%TargetOS%/mouse.asm'

endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































Deleted freshlib/gui/objects.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Contains the base procedures for the FreshLib OOP framework
;
;  Target OS: Any
;
;  Dependencies: memory.asm
;
;  Notes:
;
;  TODO: Thread safety! The whole FreshLib should be thread safe. GUI part,as long as
;        uses memory objects should be thread safe. This can be achieved by locking
;        objects, during processing. objects.asm is the proper place for such lock mechanism.
;        The lock should be provided by some kind of mutex objects, associated with the objects.
;
;_________________________________________________________________________________________
module "Objects library"

struct TObjectClass
  .ptrParent        dd 0   ; pointer to the parent TObjectClass
  .dataSize         dd 0   ; size of TObject structure.
  .procCreate       dd 0
  .procDestroy      dd 0
  .procGetParam     dd 0
  .procSetParam     dd 0
  .procExecCmd      dd 0   ; executes method in chain.
  .procSysEventHandler dd 0
ends



macro ObjectClass name*, parent*, procCreate*, procDestroy*, procGetParam*, procSetParam*,  procExecCmd*, procSysEvents* {
  if used C#name
    C#name TObjectClass
    store dword C#parent at C#name#.ptrParent
    store dword sizeof.T#name at C#name#.dataSize
    store dword procCreate at C#name#.procCreate
    store dword procDestroy at C#name#.procDestroy
    store dword procGetParam at C#name#.procGetParam
    store dword procSetParam at C#name#.procSetParam
    store dword procExecCmd at C#name#.procExecCmd
    store dword procSysEvents at C#name#.procSysEventHandler
  end if
}


CRoot = 0


maskParameter = $80000000
Sequence param, maskParameter


macro method name*, [arg] {
common
 local ..argcount
 ..argcount = 0
   param name
 forward
   if ~arg eq
   ..argcount = ..argcount + 1
   end if
 common
   name#.argcount = ..argcount
}


macro execute obj*, meth*, [arg] {
reverse
  if ~arg eq
    pushd arg
  end if
common
  pushd meth#.argcount
  pushd meth
  pushd obj
  call  __Exec
}


macro object name*, parent {
  macro name@object \{ name name \}
  macro size@object \{ sizeof.#name = $ \}
  struc name \{
    param.current = maskParameter
    if ~parent eq
      . parent
    end if
}

endobj fix } obj_helper

macro obj_helper {
  virtual at 0
    name@object
    size@object
  end virtual
  purge name@object
  purge size@object
}


mxTimeout = 1000        ; 1s timeout for the access mutex objects.

; common object procedures
; These procedures work with every TObject descendent object type.


;_________________________________________________________________________________________
;
; proc Create, .class - creates an instance from the given class.
;
; Arguments:
;   .class - pointer to TObjectClass structure for needed object.
;
; Returns:
;   ebx = pointer to the instance of the object.
;
; This procedure calls procCreate for the given object class and all
; parent classes in reverce order.
;_________________________________________________________________________________________

proc Create, .class
begin
        push    eax ecx

        mov     ecx, [.class]
        stdcall GetMem, [ecx+TObjectClass.dataSize]
        mov     ebx, eax
        mov     [eax+TObject.ptrClass], ecx

        lea     eax, [eax+TObject.mxAccess]
        stdcall MutexCreate, 0, eax

        push    0

.loop:
        cmp     [ecx+TObjectClass.procCreate], 0
        je      .parent

        push    [ecx+TObjectClass.procCreate]

.parent:
        mov     ecx, [ecx+TObjectClass.ptrParent]
        test    ecx, ecx
        jnz     .loop

.loop2:
        pop     ecx
        jecxz   .endcreate

        push    ebx
        stdcall ecx, ebx
        pop     ebx
        jmp     .loop2

.endcreate:
        lea     eax, [ebx+TObject.mxAccess]
        stdcall MutexRelease, eax
        pop     ecx eax
        return
endp



;_________________________________________________________________________________________
;
; proc Destroy, .obj - destroys the object instance.
;
; Arguments:
;   .obj - pointer to TObject descendent object.
;
; Returns:
;   nothing.
;
; This procedure calls procDestroy for the given object class and all
; parent classes. Note that the memory is freed only by the last
; destroy handled from CObject class.
;_________________________________________________________________________________________

proc Destroy, .obj
begin
        push    eax ebx

        mov     ebx, [.obj]
        test    ebx, ebx
        jz      .error

        stdcall _LockObject, [.obj]

        mov     ebx, [ebx+TObject.ptrClass]

.loop:
        cmp     [ebx+TObjectClass.procDestroy], 0
        je      .parent

        mov      eax, [ebx+TObjectClass.procDestroy]

        push    ebx
        stdcall [ebx+TObjectClass.procDestroy], [.obj]
        pop     ebx

.parent:
        mov     ebx, [ebx+TObjectClass.ptrParent]
        test    ebx, ebx
        jnz     .loop

        mov     ebx, [.obj]
        lea     eax, [ebx+TObject.mxAccess]

        mov     ebx, [ebx+TObject.ptrVar]
        test    ebx, ebx
        jz      @f
        mov     dword [ebx], 0
@@:
        stdcall MutexDestroy, eax
        stdcall FreeMem, [.obj]
        clc
        pop     ebx eax
        return

.error:
        stdcall _UnlockObject, [.obj]
        stc
        pop     ebx eax
        return
endp




;_________________________________________________________________________________________
;
; proc Get, .obj, .paramID - returns the value of given parameter
;
; Arguments:
;   .obj - pointer to TObject descendent object.
;   .paramID - ID number of the parameter being read.
; Returns:
;   CF=0; eax = parameter value.
;   CF=1; the parameter is unknown and can not be retrived.
;
; This procedure calls procGet for the given object class and
; if the procedure returns CF=1; tries to call the parents procedure
; procGet, until the value is retrived, or the root level of inheritance
; is reached.
;_________________________________________________________________________________________

proc Get, .obj, .paramID
begin
        push    ecx


        stdcall _LockObject, [.obj]

        mov     ecx, [.obj]
.loop0:
        stc
        jecxz   .finish

.loop:
        mov     ecx, [ecx]      ; TObject.ptrClass = TObjectClass.ptrParent = 0
        jecxz   .finish

        cmp     [ecx+TObjectClass.procGetParam], 0
        je      .loop0

        push    ecx
        stdcall [ecx+TObjectClass.procGetParam], [.obj], [.paramID]
        pop     ecx
        jc      .loop

.finish:
        stdcall _UnlockObject, [.obj]
        pop     ecx
        return
endp



;_________________________________________________________________________________________
;
; proc Set, .obj, .paramID - sets the value of given parameter
;
; Arguments:
;   .obj - pointer to TObject descendent object.
;   .paramID - ID number of the parameter being read.
;   .value   - value of the parameter that should be set.
; Returns:
;   CF=0 - the value is successfully set.
;   CF=1; the value is not set, because the parameter is unknown.
;
; This procedure calls procSet for the given object class and
; if the procedure returns CF=1; tries to call the parents procedures
; procSet, until the value is set, or the root level of inheritance
; is reached.
;_________________________________________________________________________________________

proc Set, .obj, .paramID, .value
begin
        push    ecx

        stdcall _LockObject, [.obj]
        mov     ecx, [.obj]
.loop0:
        stc
        jecxz   .finish

.loop:
        mov     ecx, [ecx]      ; TObject.ptrClass = TObjectClass.ptrParent = 0
        jecxz   .finish

        cmp     [ecx+TObjectClass.procSetParam], 0
        je      .loop0

        push    ecx
        stdcall [ecx+TObjectClass.procSetParam], [.obj], [.paramID], [.value]
        pop     ecx
        jc      .loop

.finish:
        stdcall _UnlockObject, [.obj]
        pop     ecx
        return
endp





;_________________________________________________________________________________________
;
; proc ExecEvent, .obj, .event
; Arguments:
;   .obj - pointer to the TObject descendent object.
;   .event - pointer to TSysEvent descendent structure.
;_________________________________________________________________________________________

proc ExecEvent, .obj, .event
begin
        push    ecx

        stdcall _LockObject, [.obj]
        mov     ecx, [.obj]
.loop0:
        stc
        jecxz   .finish

.loop:
        mov     ecx, [ecx]      ; TObject.ptrClass = TObjectClass.ptrParent = 0
        jecxz   .finish

        cmp     [ecx+TObjectClass.procSysEventHandler], 0
        je      .loop0

        push    ecx
        stdcall [ecx+TObjectClass.procSysEventHandler], [.obj], [.event]
        pop     ecx
        jc      .loop

.finish:
        stdcall _UnlockObject, [.obj]
        pop     ecx
        return
endp




;_________________________________________________________________________________________
;
; proc IsObject, .class - returns CF=0 if the given object belongs to
;                         the given class. Else returns CF=1
;_________________________________________________________________________________________
proc IsObject   ; , .obj, .class
virtual at esp+8
  .obj dd ?
  .class dd ?
end virtual
begin
        push    ecx
        lea     ecx, [.obj]

.loop:
        stc
        mov     ecx, [ecx]      ; TObject.ptrClass = TObjectClass.ptrParent = 0
        jecxz   .finish

        cmp     ecx, [.class]   ; the first cmp will always fail because ecx contains pointer to obj that can't be equal to a class.
        jne     .loop

.finish:
        pop     ecx
        retn 8
endp



;_________________________________________________________________________________________
;
; Executes a method of given class.
; This procedure have arbitrary count of arguments
; it calls in chain procExecCmd the classes and passes
; a pointer to the arguments in esi.
; It first calls the procExecCmd of the childs and then of the parents.
; If some class have 0 in [procExecCmd] this class is skiped and
; the execution continues on its parent.
; If there is no proper handler back to the root, then the procedure
; returns CF=1
;_________________________________________________________________________________________

proc __Exec ;, .obj, .method, .argcount, ..
begin
virtual at ebp+8
  .obj dd ?
  .method dd ?
  .argcount dd ?
  .arguments:
end virtual
        push    ebp
        mov     ebp, esp        ; now ebp+8 points to the arguments.

        push    ecx ebx

        xor     ebx, ebx
        cmp     [.argcount], 0
        je      @f
        lea     ebx, [.arguments]
@@:
        mov     ecx, [.obj]

.loop0:
        stc
        jecxz   .exit

.loop:
        mov     ecx, [ecx]      ; TObject.ptrClass = TObjectClass.ptrParent = 0
        jecxz   .exit

        cmp     [ecx+TObjectClass.procExecCmd], 0
        je      .loop0

        push    ecx ebx
        stdcall [ecx+TObjectClass.procExecCmd], [.obj], [.method]
        pop     ebx ecx
        jc      .loop

.exit:
        pop     ebx ecx

        ; experimental return from procedure with arbitrary count of arguments.
        ; with keeping all registers unchanged.
        mov     esp, ebp
        push    ecx
        mov     ebp, [.argcount]
        lea     ebp, [esp+8+4*ebp+12]      ; the place where the return address should be placed. (Exec have 3 more arguments, including .argcount)
        mov     ecx, [esp+8]               ; return address
        mov     [ebp], ecx                 ; move the return address to the proper place.
        pop     ecx                        ; restore ecx
        pop     esp                        ; old value of ebp
        xchg    esp, ebp                   ; restore ebp and set esp to the proper value
        retn
endp




proc _LockObject, .obj
begin
        push    eax

        mov     eax, [.obj]
        lea     eax, [eax+TObject.mxAccess]
        stdcall WaitForMutex, eax, mxTimeout
        jc      .stop

        pop     eax
        return

.stop:
        int3
        pop     eax
        return

endp




proc _UnlockObject, .obj
begin
        pushf
        push    eax

        mov     eax, [.obj]
        lea     eax, [eax+TObject.mxAccess]
        stdcall MutexRelease, eax

        pop     eax
        popf
        return
endp





endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/gui/sysevents.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Defines constants and structures for system events of FreshLib
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________
module "System events library"

seMouseMove        = $0001
seMouseEnter       = $0002
seMouseLeave       = $0003
seMouseBtnPress    = $0004
seMouseBtnRelease  = $0005
seMouseBtnClick    = $0006
seMouseBtnDblClick = $0007
seTimer            = $0008
seKbdKeyPress      = $0009
seKbdKeyRelease    = $000a
seKbdStatusChanged = $000b
seKbdChar          = $000c

seScroll           = $000d


sePaint            = $0100
seCloseRequest     = $0101

seFocusIn          = $0102
seFocusOut         = $0103

seMoveResize       = $0104


struct TSysEvent
  .event  dd  ?
ends


struct TMouseMoveEvent
  . TSysEvent
  .x         dd ?
  .y         dd ?
ends

mbLeft   = 0
mbMiddle = 1
mbRight  = 2

maskBtnLeft   = $0100
maskBtnMiddle = $0200
maskBtnRight  = $0400
maskShift     = $1
maskCapsLock  = $2
maskCtrl      = $4
maskAlt       = $8
maskScrLk     = $10


struct TMouseButtonEvent
  . TSysEvent
  .Button    dd ?
  .kbdStatus dd ?
  .x         dd ?   ; coordinates of the mouse pointer in the client
  .y         dd ?
ends


struct TMouseEnterEvent
  . TSysEvent
ends


; These are scan codes for the non character keys. They are OS dependent and should be used by
; their names.
include '%TargetOS%/keycodes.inc'


struct TKeyboardEvent
  . TSysEvent
  .key       dd  ?      ; 1..4 bytes UTF-8 character typed by the keyboard, or 0 if non character key is pressed/released.
  .scancode  dd  ?      ; scan code of the pressed key.
  .kbdStatus dd  ?      ; same as mouse button event - contains mouse buttons and Ctrl, Shift and Alt keys status.
ends


scTrack   = 1
scUp      = 2
scDown    = 3
scWheelUp = 4
scWheelDn = 5

scrollX = 0
scrollY = 1


struct TScrollEvent
  . TSysEvent
  .ScrollBar  dd ?      ; 0
  .ScrollCmd  dd ?      ;
  .Value      dd ?      ; Distance for scUp and scDown and position for scTrack
ends


struct TTimerEvent
  . TSysEvent
  .timer dd ?
ends


struct TPaintEvent
  . TSysEvent

  .context dd ?  ; pointer to TContext structure, properly initialized.
  .rect   RECT
ends


struct TCloseEvent
  . TSysEvent
  .reason dd ?          ; how the close was requested?
ends

cerFromUser = 0         ; user pressed X button on the window header, pressed alt+F4 from the keyboard, or choose "Close" from the title menu.
cerFromProgram = 1      ; Method Close was executed from the program.


struct TFocusInEvent
  . TSysEvent
ends

struct TFocusOutEvent
  . TSysEvent
ends


struct TMoveResizeEvent
  . TSysEvent
  .newX  dd ?
  .newY  dd ?
  .newWidth  dd ?
  .newHeight dd ?
ends



; creates and returns a string with the textual identifier of the pressed/released key.
proc CreateKeyName, .pKeyEvent
begin
        push    ebx ecx esi edi

        stdcall StrDup, .strkey
        mov     ebx, eax

        mov     edi, [.pKeyEvent]
        test    [edi+TKeyboardEvent.kbdStatus], maskCtrl
        jz      @f

        stdcall StrCharCat, ebx, 'Ctrl'
        stdcall StrCharCat, ebx, '+'
@@:
        test    [edi+TKeyboardEvent.kbdStatus], maskAlt
        jz      @f
        stdcall StrCharCat, ebx, 'Alt+'
@@:
        test    [edi+TKeyboardEvent.kbdStatus], maskShift
        jz      @f
        stdcall StrCharCat, ebx, 'Shif'
        stdcall StrCharCat, ebx, 't+'
@@:
        mov     ecx, [edi+TKeyboardEvent.key]
        jecxz   .searchlist

        cmp     ecx, ' '
        jne     @f
        mov     ecx, 'Spc'
@@:
        cmp     ecx, ' '
        jae     @f
        add     ecx, '@'
@@:
        cmp     ecx, 'a'
        jb      @f
        cmp     ecx, 'z'
        ja      @f
        xor     ecx, $20
@@:
        stdcall StrCharCat, ebx, ecx

.exitok:
        mov     eax, ebx
        clc

.finish:
        pop     edi esi ecx ebx
        return

.searchlist:
        mov     esi, __FunctionalKeyNames

.loop:
        movzx   ecx, word [esi]
        jecxz   .notfound
        cmp     ecx, [edi+TKeyboardEvent.scancode]
        je      .found
        add     esi, 4
        jmp     .loop

.found:
        movsx   eax, word [esi+2]
        add     esi, eax
        stdcall StrCat, ebx, esi
        jmp     .exitok

.notfound:
        stdcall StrDel, ebx
        xor     eax, eax
        stc
        jmp     .finish

.strkey db 'key', 0
endp


macro keynames lbl, [scancode, name] {
common
  label lbl word
forward
  local pname
        dw scancode
        dw pname - $ + 2
common
        dw 0
forward
  pname db name, 0
}


iglobal
  if used __FunctionalKeyNames
  keynames  __FunctionalKeyNames,                        \
            keyHomeNumpad,     'Home',                   \
            keyUpNumpad,       'Up',                     \
            keyPgUpNumpad,     'PgUp',                   \
            keyLeftNumpad,     'Left',                   \
            key5Numpad,        'Num5',                   \
            keyRightNumpad,    'Right',                  \
            keyEndNumpad,      'End',                    \
            keyDownNumpad,     'Down',                   \
            keyPgDnNumpad,     'PgDn',                   \
            keyInsNumpad,      'Ins',                    \
            keyDelNumpad,      'Del',                    \
            keyEnterNumpad,    'Enter',                  \
            keyNumLock,        'NumLock',                \
            keyScrollLock,     'ScrLock',                \
            keyPause,          'Pause',                  \
            keyLeft,           'Left',                   \
            keyRight,          'Right',                  \
            keyUp,             'Up',                     \
            keyDown,           'Down',                   \
            keyInsert,         'Ins',                    \
            keyDelete,         'Del',                    \
            keyHome,           'Home',                   \
            keyEnd,            'End',                    \
            keyPgUp,           'PgUp',                   \
            keyPgDown,         'PgDn',                   \
            keyF1,             'F1',                     \
            keyF2,             'F2',                     \
            keyF3,             'F3',                     \
            keyF4,             'F4',                     \
            keyF5,             'F5',                     \
            keyF6,             'F6',                     \
            keyF7,             'F7',                     \
            keyF8,             'F8',                     \
            keyF9,             'F9',                     \
            keyF10,            'F10',                    \
            keyF11,            'F11',                    \
            keyF12,            'F12',                    \
            keyCapsLock,       'CapsLock',               \
            keyShiftLeft,      'ShiftL',                 \
            keyCtrlLeft,       'CtrlL',                  \
            keyAltLeft,        'AltL',                   \
            keyAltRight,       'AltR',                   \
            keyPopupMenu,      'PopupMenu',              \
            keyShiftRight,     'ShiftR',                 \
            keyCtrlRight,      'CtrlR',                  \
            keyBackSpace,      'BackSp'
  end if
endg

endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































Deleted freshlib/gui/textcaret.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Text caret control library.
;
;  Target OS: Any
;
;  Dependencies: timers.asm; graphics libraries.
;
;  Notes: Text caret have always only one instance.
;_________________________________________________________________________________________
module "Text caret library"

; the caret is shared resource and can exists only in one instance
struct TCaret
  .pWindow   dd ?
  .visible   dd ?
  .state     dd ?       ; 1 if the caret is displayed 0 if not.
  .Pos       TBounds
  .OldPos    TBounds
  .timer     dd ?
  .sync      dd ?
ends



uglobal
  if used CaretAttach
    Caret TCaret
  end if
endg

iglobal
  if used CaretTimes
    CaretTimes dd 200, 300
  end if
endg


if used CaretAttach

initialize InitCaretTimer
begin
        stdcall TimerCreate
        mov     [eax+TTimer.interval], 200
        mov     [eax+TTimer.Callback], __CaretTimerProc
        mov     [eax+TTimer.flags], tmfCallProc
        mov     [Caret.timer], eax
        return
endp


finalize DestroyCaretTimer
begin
        stdcall CaretAttach, 0
        mov     eax, [Caret.timer]
        and     [eax+TTimer.flags], not tmfRunning
        stdcall TimerDestroy, eax
        return
endp

end if


; Attaches the caret to the window, if the window needs caret.
proc CaretAttach, .pWindow
begin
        mov     eax,[.pWindow]
        cmp     eax, [Caret.pWindow]
        je      .exit

        mov     eax, -1
@@:
        xchg    [Caret.sync], eax
        test    eax, eax
        jnz     @b

        stdcall __DrawCaret, 0  ; hide the caret.

        mov     eax, [.pWindow]
        xchg    [Caret.pWindow], eax
        push    eax

        xor     eax, eax
        mov     [Caret.visible], eax
        mov     [Caret.Pos.x], eax
        mov     [Caret.Pos.y], eax
        mov     [Caret.Pos.height], eax
        mov     [Caret.Pos.width], eax

.finish:
        mov     [Caret.sync], 0
        pop     eax     ; the old window.
.exit:
        return
endp




proc CaretChange, .x, .y, .width, .height
begin
        push    eax

        mov     eax, -1
@@:
        xchg    [Caret.sync], eax
        test    eax, eax
        jnz     @b

        stdcall __DrawCaret, 0

        push    [.x] [.y]
        pop     [Caret.Pos.y] [Caret.Pos.x]

        cmp     [.width], 0
        je      .endchange

        push    [.width] [.height]
        pop     [Caret.Pos.height] [Caret.Pos.width]

        stdcall __DrawCaret, 1

.endchange:
        mov     [Caret.sync], 0

        pop     eax
        return
endp


; returns the old mode.
proc __CaretShow, .visible
begin
        mov     eax, [.visible]
        cmp     eax, [Caret.visible]       ; old vs new mode.
        je      .exit

        push    [Caret.visible]
        mov     [Caret.visible], eax

        push    ecx edx

        mov     ecx, [Caret.timer]
        mov     edx, [ecx+TTimer.flags]

        or      edx, tmfRunning
        test    eax, eax
        jnz     .timerok
        and     edx, not tmfRunning
.timerok:
        mov     [ecx+TTimer.flags], edx

        stdcall __DrawCaret, [Caret.visible]
        pop     edx ecx

        pop     eax
.exit:
        return
endp


proc CaretShow, .visible
begin
        mov     eax, -1
@@:
        xchg    [Caret.sync], eax
        test    eax, eax
        jnz     @b

        stdcall __CaretShow, [.visible]
        mov     [Caret.sync], 0

        return
endp



proc __CaretTimerProc, .timer
begin
        cmp     [Caret.pWindow], 0
        je      .exit

        mov     eax, -1
        xchg    [Caret.sync], eax
        test    eax, eax
        jnz     .exit                   ; don't wait for lock.

        cmp     [Caret.visible], 0
        je      @f
        mov     eax, 2
@@:
        stdcall __DrawCaret, eax

        mov     [Caret.sync], 0

.exit:
        return
endp



proc __DrawCaret, .operation    ; 0 - erase; 1-draw; 2-change
begin
        push    ecx esi

        mov     eax, [Caret.state]
        cmp     eax, [.operation]
        je      .exit

        cmp     [Caret.pWindow], 0
        je      .exit

        push    $ffffff

        xor     eax, 1
        mov     [Caret.state], eax

        mov     ecx, [Caret.timer]
        mov     eax, [Caret.state]
        mov     eax, [CaretTimes+4*eax]
        mov     [ecx+TTimer.interval], eax
        mov     [ecx+TTimer.value], 0

        test    eax, eax
        jnz     .draw
; clear
        push    [Caret.OldPos.height]
        push    [Caret.OldPos.width]
        push    [Caret.OldPos.y]
        push    [Caret.OldPos.x]
        jmp     .drawit

.draw:
        push    [Caret.Pos.height] [Caret.Pos.width] [Caret.Pos.y] [Caret.Pos.x]
        push    [Caret.Pos.height] [Caret.Pos.width] [Caret.Pos.y] [Caret.Pos.x]
        pop     [Caret.OldPos.x] [Caret.OldPos.y] [Caret.OldPos.width] [Caret.OldPos.height]

.drawit:
        mov     eax, [Caret.pWindow]
        stdcall AllocateContext, [eax+TWindow.handle]
        test    eax, eax
        jz      .exit

        mov     esi, eax

        stdcall SetDrawMode, esi, cmXor
        stdcall DrawFillRect, esi  ; arguments from the stack
        stdcall ReleaseContext, esi

.exit:
        pop     esi ecx
        return
endp




endmodule


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































Deleted freshlib/imports/Linux/libX11.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: libX11 (XLib) import library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes: Needs editing of the function arguments
;_________________________________________________________________________________________


import_proto 'libX11.so.6',                                                                                                                             \
        XActivateScreenSaver                    ,<NONE>,                                    'XActivateScreenSaver',                                     \
        XAddConnectionWatch                     ,<NONE>,                                    'XAddConnectionWatch',                                      \
        XAddExtension                           ,<NONE>,                                    'XAddExtension',                                            \
        XAddHost                                ,<NONE>,                                    'XAddHost',                                                 \
        XAddHosts                               ,<NONE>,                                    'XAddHosts',                                                \
        XAddPixel                               ,<NONE>,                                    'XAddPixel',                                                \
        XAddToExtensionList                     ,<NONE>,                                    'XAddToExtensionList',                                      \
        XAddToSaveSet                           ,<NONE>,                                    'XAddToSaveSet',                                            \
        XAllPlanes                              ,<NONE>,                                    'XAllPlanes',                                               \
        XAllocClassHint                         ,<NONE>,                                    'XAllocClassHint',                                          \
        XAllocColor                             ,<NONE>,                                    'XAllocColor',                                              \
        XAllocColorCells                        ,<NONE>,                                    'XAllocColorCells',                                         \
        XAllocColorPlanes                       ,<NONE>,                                    'XAllocColorPlanes',                                        \
        XAllocIconSize                          ,<NONE>,                                    'XAllocIconSize',                                           \
        XAllocNamedColor                        ,<NONE>,                                    'XAllocNamedColor',                                         \
        XAllocSizeHints                         ,<NONE>,                                    'XAllocSizeHints',                                          \
        XAllocStandardColormap                  ,<NONE>,                                    'XAllocStandardColormap',                                   \
        XAllocWMHints                           ,<NONE>,                                    'XAllocWMHints',                                            \
        XAllowEvents                            ,<NONE>,                                    'XAllowEvents',                                             \
        XAutoRepeatOff                          ,<NONE>,                                    'XAutoRepeatOff',                                           \
        XAutoRepeatOn                           ,<NONE>,                                    'XAutoRepeatOn',                                            \
        XBaseFontNameListOfFontSet              ,<NONE>,                                    'XBaseFontNameListOfFontSet',                               \
        XBell                                   ,<NONE>,                                    'XBell',                                                    \
        XBitmapBitOrder                         ,<NONE>,                                    'XBitmapBitOrder',                                          \
        XBitmapPad                              ,<NONE>,                                    'XBitmapPad',                                               \
        XBitmapUnit                             ,<NONE>,                                    'XBitmapUnit',                                              \
        XBlackPixel                             ,<NONE>,                                    'XBlackPixel',                                              \
        XBlackPixelOfScreen                     ,<NONE>,                                    'XBlackPixelOfScreen',                                      \
        XCellsOfScreen                          ,<NONE>,                                    'XCellsOfScreen',                                           \
        XChangeActivePointerGrab                ,<NONE>,                                    'XChangeActivePointerGrab',                                 \
        XChangeGC                               ,<NONE>,                                    'XChangeGC',                                                \
        XChangeKeyboardControl                  ,<NONE>,                                    'XChangeKeyboardControl',                                   \
        XChangeKeyboardMapping                  ,<NONE>,                                    'XChangeKeyboardMapping',                                   \
        XChangePointerControl                   ,<NONE>,                                    'XChangePointerControl',                                    \
        XChangeProperty                         ,<NONE>,                                    'XChangeProperty',                                          \
        XChangeSaveSet                          ,<NONE>,                                    'XChangeSaveSet',                                           \
        XChangeWindowAttributes                 ,<.display, .hwnd, .valmask, .pSetWinAttr>, 'XChangeWindowAttributes',                                  \
        XCheckIfEvent                           ,<NONE>,                                    'XCheckIfEvent',                                            \
        XCheckMaskEvent                         ,<NONE>,                                    'XCheckMaskEvent',                                          \
        XCheckTypedEvent                        ,<.display, .event_type, .pEvent>,          'XCheckTypedEvent',                                         \
        XCheckTypedWindowEvent                  ,<NONE>,                                    'XCheckTypedWindowEvent',                                   \
        XCheckWindowEvent                       ,<NONE>,                                    'XCheckWindowEvent',                                        \
        XCirculateSubwindows                    ,<NONE>,                                    'XCirculateSubwindows',                                     \
        XCirculateSubwindowsDown                ,<NONE>,                                    'XCirculateSubwindowsDown',                                 \
        XCirculateSubwindowsUp                  ,<NONE>,                                    'XCirculateSubwindowsUp',                                   \
        XClearArea                              ,<NONE>,                                    'XClearArea',                                               \
        XClearWindow                            ,<NONE>,                                    'XClearWindow',                                             \
        XClipBox                                ,<NONE>,                                    'XClipBox',                                                 \
        XCloseDisplay                           ,<NONE>,                                    'XCloseDisplay',                                            \
        XCloseIM                                ,<NONE>,                                    'XCloseIM',                                                 \
        XCloseOM                                ,<NONE>,                                    'XCloseOM',                                                 \
        XConfigureWindow                        ,<NONE>,                                    'XConfigureWindow',                                         \
        XConnectionNumber                       ,<NONE>,                                    'XConnectionNumber',                                        \
        XContextDependentDrawing                ,<NONE>,                                    'XContextDependentDrawing',                                 \
        XContextualDrawing                      ,<NONE>,                                    'XContextualDrawing',                                       \
        XConvertCase                            ,<NONE>,                                    'XConvertCase',                                             \
        XConvertSelection                       ,<.display, .selection, .target, .property, .requestor, .time>, 'XConvertSelection',                    \
        XCopyArea                               ,<NONE>,                                                'XCopyArea',                                    \
        XCopyColormapAndFree                    ,<NONE>,                                                'XCopyColormapAndFree',                         \
        XCopyGC                                 ,<NONE>,                                                'XCopyGC',                                      \
        XCopyPlane                              ,<NONE>,                                                'XCopyPlane',                                   \
        XCreateBitmapFromData                   ,<NONE>,                                                'XCreateBitmapFromData',                        \
        XCreateColormap                         ,<NONE>,                                                'XCreateColormap',                              \
        XCreateFontCursor                       ,<NONE>,                                                'XCreateFontCursor',                            \
        XCreateFontSet                          ,<NONE>,                                                'XCreateFontSet',                               \
        XCreateGC                               ,<NONE>,                                                'XCreateGC',                                    \
        XCreateGlyphCursor                      ,<NONE>,                                                'XCreateGlyphCursor',                           \
        XCreateIC                               ,<NONE>,                                                'XCreateIC',                                    \
        XCreateImage                            ,<NONE>,                                                'XCreateImage',                                 \
        XCreateOC                               ,<NONE>,                                                'XCreateOC',                                    \
        XCreatePixmap                           ,<NONE>,                                                'XCreatePixmap',                                \
        XCreatePixmapCursor                     ,<NONE>,                                                'XCreatePixmapCursor',                          \
        XCreatePixmapFromBitmapData             ,<NONE>,                                                'XCreatePixmapFromBitmapData',                  \
        XCreateRegion                           ,<NONE>,                                                'XCreateRegion',                                \
        XCreateSimpleWindow                     ,<.display, .parent, .x, .y, .width, .height, .widthBorder, .clBorder, .clBackground>, 'XCreateSimpleWindow',                    \
        XCreateWindow                           ,<.display, .parent, .x, .y, .width, .height, .widthBorder, .depth, .class, .visual, .valuemask, .pAttributes>, 'XCreateWindow', \
        XDefaultColormap                        ,<NONE>,                                                'XDefaultColormap',                             \
        XDefaultColormapOfScreen                ,<NONE>,                                                'XDefaultColormapOfScreen',                     \
        XDefaultDepth                           ,<NONE>,                                                'XDefaultDepth',                                \
        XDefaultDepthOfScreen                   ,<NONE>,                                                'XDefaultDepthOfScreen',                        \
        XDefaultGC                              ,<NONE>,                                                'XDefaultGC',                                   \
        XDefaultGCOfScreen                      ,<NONE>,                                                'XDefaultGCOfScreen',                           \
        XDefaultRootWindow                      ,<NONE>,                                                'XDefaultRootWindow',                           \
        XDefaultScreen                          ,<NONE>,                                                'XDefaultScreen',                               \
        XDefaultScreenOfDisplay                 ,<NONE>,                                                'XDefaultScreenOfDisplay',                      \
        XDefaultString                          ,<NONE>,                                                'XDefaultString',                               \
        XDefaultVisual                          ,<NONE>,                                                'XDefaultVisual',                               \
        XDefaultVisualOfScreen                  ,<NONE>,                                                'XDefaultVisualOfScreen',                       \
        XDefineCursor                           ,<NONE>,                                                'XDefineCursor',                                \
        XDeleteContext                          ,<NONE>,                                                'XDeleteContext',                               \
        XDeleteModifiermapEntry                 ,<NONE>,                                                'XDeleteModifiermapEntry',                      \
        XDeleteProperty                         ,<NONE>,                                                'XDeleteProperty',                              \
        XDestroyIC                              ,<NONE>,                                                'XDestroyIC',                                   \
        XDestroyImage                           ,<NONE>,                                                'XDestroyImage',                                \
        XDestroyOC                              ,<NONE>,                                                'XDestroyOC',                                   \
        XDestroyRegion                          ,<NONE>,                                                'XDestroyRegion',                               \
        XDestroySubwindows                      ,<NONE>,                                                'XDestroySubwindows',                           \
        XDestroyWindow                          ,<NONE>,                                                'XDestroyWindow',                               \
        XDirectionalDependentDrawing            ,<NONE>,                                                'XDirectionalDependentDrawing',                 \
        XDisableAccessControl                   ,<NONE>,                                                'XDisableAccessControl',                        \
        XDisplayCells                           ,<NONE>,                                                'XDisplayCells',                                \
        XDisplayHeight                          ,<NONE>,                                                'XDisplayHeight',                               \
        XDisplayHeightMM                        ,<NONE>,                                                'XDisplayHeightMM',                             \
        XDisplayKeycodes                        ,<NONE>,                                                'XDisplayKeycodes',                             \
        XDisplayMotionBufferSize                ,<NONE>,                                                'XDisplayMotionBufferSize',                     \
        XDisplayName                            ,<NONE>,                                                'XDisplayName',                                 \
        XDisplayOfIM                            ,<NONE>,                                                'XDisplayOfIM',                                 \
        XDisplayOfOM                            ,<NONE>,                                                'XDisplayOfOM',                                 \
        XDisplayOfScreen                        ,<NONE>,                                                'XDisplayOfScreen',                             \
        XDisplayPlanes                          ,<NONE>,                                                'XDisplayPlanes',                               \
        XDisplayString                          ,<NONE>,                                                'XDisplayString',                               \
        XDisplayWidth                           ,<NONE>,                                                'XDisplayWidth',                                \
        XDisplayWidthMM                         ,<NONE>,                                                'XDisplayWidthMM',                              \
        XDoesBackingStore                       ,<NONE>,                                                'XDoesBackingStore',                            \
        XDoesSaveUnders                         ,<NONE>,                                                'XDoesSaveUnders',                              \
        XDrawArc                                ,<NONE>,                                                'XDrawArc',                                     \
        XDrawArcs                               ,<NONE>,                                                'XDrawArcs',                                    \
        XDrawImageString                        ,<NONE>,                                                'XDrawImageString',                             \
        XDrawImageString16                      ,<NONE>,                                                'XDrawImageString16',                           \
        XDrawLine                               ,<NONE>,                                                'XDrawLine',                                    \
        XDrawLines                              ,<NONE>,                                                'XDrawLines',                                   \
        XDrawPoint                              ,<NONE>,                                                'XDrawPoint',                                   \
        XDrawPoints                             ,<NONE>,                                                'XDrawPoints',                                  \
        XDrawRectangle                          ,<NONE>,                                                'XDrawRectangle',                               \
        XDrawRectangles                         ,<NONE>,                                                'XDrawRectangles',                              \
        XDrawSegments                           ,<NONE>,                                                'XDrawSegments',                                \
        XDrawString                             ,<NONE>,                                                'XDrawString',                                  \
        XDrawString16                           ,<NONE>,                                                'XDrawString16',                                \
        XDrawText                               ,<NONE>,                                                'XDrawText',                                    \
        XDrawText16                             ,<NONE>,                                                'XDrawText16',                                  \
        XEHeadOfExtensionList                   ,<NONE>,                                                'XEHeadOfExtensionList',                        \
        XESetBeforeFlush                        ,<NONE>,                                                'XESetBeforeFlush',                             \
        XESetCloseDisplay                       ,<NONE>,                                                'XESetCloseDisplay',                            \
        XESetCopyGC                             ,<NONE>,                                                'XESetCopyGC',                                  \
        XESetCreateFont                         ,<NONE>,                                                'XESetCreateFont',                              \
        XESetCreateGC                           ,<NONE>,                                                'XESetCreateGC',                                \
        XESetError                              ,<NONE>,                                                'XESetError',                                   \
        XESetErrorString                        ,<NONE>,                                                'XESetErrorString',                             \
        XESetEventToWire                        ,<NONE>,                                                'XESetEventToWire',                             \
        XESetFlushGC                            ,<NONE>,                                                'XESetFlushGC',                                 \
        XESetFreeFont                           ,<NONE>,                                                'XESetFreeFont',                                \
        XESetFreeGC                             ,<NONE>,                                                'XESetFreeGC',                                  \
        XESetPrintErrorValues                   ,<NONE>,                                                'XESetPrintErrorValues',                        \
        XESetWireToError                        ,<NONE>,                                                'XESetWireToError',                             \
        XESetWireToEvent                        ,<NONE>,                                                'XESetWireToEvent',                             \
        XEmptyRegion                            ,<NONE>,                                                'XEmptyRegion',                                 \
        XEnableAccessControl                    ,<NONE>,                                                'XEnableAccessControl',                         \
        XEqualRegion                            ,<NONE>,                                                'XEqualRegion',                                 \
        XEventMaskOfScreen                      ,<NONE>,                                                'XEventMaskOfScreen',                           \
        XEventsQueued                           ,<NONE>,                                                'XEventsQueued',                                \
        XExtendedMaxRequestSize                 ,<NONE>,                                                'XExtendedMaxRequestSize',                      \
        XExtentsOfFontSet                       ,<NONE>,                                                'XExtentsOfFontSet',                            \
        XFetchBuffer                            ,<.display, .nbytes_return, .buffer>,                   'XFetchBuffer',                                 \
        XFetchBytes                             ,<.display, .nbytes_return>,                            'XFetchBytes',                                  \
        XFetchName                              ,<.display, .window, .window_name_return>,              'XFetchName',                                   \
        XFillArc                                ,<NONE>,                                                'XFillArc',                                     \
        XFillArcs                               ,<NONE>,                                                'XFillArcs',                                    \
        XFillPolygon                            ,<NONE>,                                                'XFillPolygon',                                 \
        XFillRectangle                          ,<NONE>,                                                'XFillRectangle',                               \
        XFillRectangles                         ,<NONE>,                                                'XFillRectangles',                              \
        XFilterEvent                            ,<NONE>,                                                'XFilterEvent',                                 \
        XFindContext                            ,<NONE>,                                                'XFindContext',                                 \
        XFindOnExtensionList                    ,<NONE>,                                                'XFindOnExtensionList',                         \
        XFlush                                  ,<NONE>,                                                'XFlush',                                       \
        XFlushGC                                ,<NONE>,                                                'XFlushGC',                                     \
        XFontsOfFontSet                         ,<NONE>,                                                'XFontsOfFontSet',                              \
        XForceScreenSaver                       ,<NONE>,                                                'XForceScreenSaver',                            \
        XFree                                   ,<.ptr>,                                                'XFree',                                        \
        XFreeColormap                           ,<NONE>,                                                'XFreeColormap',                                \
        XFreeColors                             ,<NONE>,                                                'XFreeColors',                                  \
        XFreeCursor                             ,<NONE>,                                                'XFreeCursor',                                  \
        XFreeExtensionList                      ,<NONE>,                                                'XFreeExtensionList',                           \
        XFreeFont                               ,<NONE>,                                                'XFreeFont',                                    \
        XFreeFontInfo                           ,<NONE>,                                                'XFreeFontInfo',                                \
        XFreeFontNames                          ,<NONE>,                                                'XFreeFontNames',                               \
        XFreeFontPath                           ,<NONE>,                                                'XFreeFontPath',                                \
        XFreeFontSet                            ,<NONE>,                                                'XFreeFontSet',                                 \
        XFreeGC                                 ,<NONE>,                                                'XFreeGC',                                      \
        XFreeModifiermap                        ,<NONE>,                                                'XFreeModifiermap',                             \
        XFreePixmap                             ,<NONE>,                                                'XFreePixmap',                                  \
        XFreeStringList                         ,<NONE>,                                                'XFreeStringList',                              \
        XGContextFromGC                         ,<NONE>,                                                'XGContextFromGC',                              \
        XGeometry                               ,<NONE>,                                                'XGeometry',                                    \
        XGetAtomName                            ,<NONE>,                                                'XGetAtomName',                                 \
        XGetAtomNames                           ,<NONE>,                                                'XGetAtomNames',                                \
        XGetClassHint                           ,<NONE>,                                                'XGetClassHint',                                \
        XGetCommand                             ,<NONE>,                                                'XGetCommand',                                  \
        XGetDefault                             ,<NONE>,                                                'XGetDefault',                                  \
        XGetErrorDatabaseText                   ,<NONE>,                                                'XGetErrorDatabaseText',                        \
        XGetErrorText                           ,<NONE>,                                                'XGetErrorText',                                \
        XGetFontPath                            ,<NONE>,                                                'XGetFontPath',                                 \
        XGetFontProperty                        ,<NONE>,                                                'XGetFontProperty',                             \
        XGetGCValues                            ,<NONE>,                                                'XGetGCValues',                                 \
        XGetGeometry                            ,<NONE>,                                                'XGetGeometry',                                 \
        XGetICValues                            ,<NONE>,                                                'XGetICValues',                                 \
        XGetIMValues                            ,<NONE>,                                                'XGetIMValues',                                 \
        XGetIconName                            ,<NONE>,                                                'XGetIconName',                                 \
        XGetIconSizes                           ,<NONE>,                                                'XGetIconSizes',                                \
        XGetImage                               ,<NONE>,                                                'XGetImage',                                    \
        XGetInputFocus                          ,<NONE>,                                                'XGetInputFocus',                               \
        XGetKeyboardControl                     ,<NONE>,                                                'XGetKeyboardControl',                          \
        XGetKeyboardMapping                     ,<NONE>,                                                'XGetKeyboardMapping',                          \
        XGetModifierMapping                     ,<NONE>,                                                'XGetModifierMapping',                          \
        XGetMotionEvents                        ,<NONE>,                                                'XGetMotionEvents',                             \
        XGetNormalHints                         ,<NONE>,                                                'XGetNormalHints',                              \
        XGetOCValues                            ,<NONE>,                                                'XGetOCValues',                                 \
        XGetOMValues                            ,<NONE>,                                                'XGetOMValues',                                 \
        XGetPixel                               ,<NONE>,                                                'XGetPixel',                                    \
        XGetPointerControl                      ,<NONE>,                                                'XGetPointerControl',                           \
        XGetPointerMapping                      ,<NONE>,                                                'XGetPointerMapping',                           \
        XGetRGBColormaps                        ,<NONE>,                                                'XGetRGBColormaps',                             \
        XGetScreenSaver                         ,<NONE>,                                                'XGetScreenSaver',                              \
        XGetSelectionOwner                      ,<.display, .selection>,                                'XGetSelectionOwner',                           \
        XGetSizeHints                           ,<NONE>,                                                'XGetSizeHints',                                \
        XGetStandardColormap                    ,<NONE>,                                                'XGetStandardColormap',                         \
        XGetSubImage                            ,<NONE>,                                                'XGetSubImage',                                 \
        XGetTextProperty                        ,<NONE>,                                                'XGetTextProperty',                             \
        XGetTransientForHint                    ,<NONE>,                                                'XGetTransientForHint',                         \
        XGetVisualInfo                          ,<NONE>,                                                'XGetVisualInfo',                               \
        XGetWMClientMachine                     ,<NONE>,                                                'XGetWMClientMachine',                          \
        XGetWMColormapWindows                   ,<NONE>,                                                'XGetWMColormapWindows',                        \
        XGetWMHints                             ,<NONE>,                                                'XGetWMHints',                                  \
        XGetWMIconName                          ,<NONE>,                                                'XGetWMIconName',                               \
        XGetWMName                              ,<NONE>,                                                'XGetWMName',                                   \
        XGetWMNormalHints                       ,<NONE>,                                                'XGetWMNormalHints',                            \
        XGetWMProtocols                         ,<NONE>,                                                'XGetWMProtocols',                              \
        XGetWMSizeHints                         ,<NONE>,                                                'XGetWMSizeHints',                              \
        XGetWindowAttributes                    ,<.display, .hwin, .pWinAttr>,                          'XGetWindowAttributes',                         \
        XGetWindowProperty                      ,<.display, .hwin, .property, .offset, .length, .delete, .req_type, .pTypeRet, .pFormatRet, .pNItemsRet, .pRemainsRet, .pDataRet>, 'XGetWindowProperty', \
        XGetZoomHints                           ,<NONE>,                                                'XGetZoomHints',                                \
        XGrabButton                             ,<NONE>,                                                'XGrabButton',                                  \
        XGrabKey                                ,<NONE>,                                                'XGrabKey',                                     \
        XGrabKeyboard                           ,<NONE>,                                                'XGrabKeyboard',                                \
        XGrabPointer                            ,<NONE>,                                                'XGrabPointer',                                 \
        XGrabServer                             ,<NONE>,                                                'XGrabServer',                                  \
        XHeightMMOfScreen                       ,<NONE>,                                                'XHeightMMOfScreen',                            \
        XHeightOfScreen                         ,<NONE>,                                                'XHeightOfScreen',                              \
        XIMOfIC                                 ,<NONE>,                                                'XIMOfIC',                                      \
        XIconifyWindow                          ,<NONE>,                                                'XIconifyWindow',                               \
        XIfEvent                                ,<NONE>,                                                'XIfEvent',                                     \
        XImageByteOrder                         ,<NONE>,                                                'XImageByteOrder',                              \
        XInitExtension                          ,<NONE>,                                                'XInitExtension',                               \
        XInitImage                              ,<NONE>,                                                'XInitImage',                                   \
        XInitThreads                            ,<NONE>,                                                'XInitThreads',                                 \
        XInsertModifiermapEntry                 ,<NONE>,                                                'XInsertModifiermapEntry',                      \
        XInstallColormap                        ,<NONE>,                                                'XInstallColormap',                             \
        XInternAtom                             ,<.disply, .atom_name, .only_if_exists>,                'XInternAtom',                                  \
        XInternAtoms                            ,<.disply, .names, .count, .only_if_exists, .atoms_return>,'XInternAtoms',                              \
        XInternalConnectionNumbers              ,<NONE>,                                                'XInternalConnectionNumbers',                   \
        XIntersectRegion                        ,<NONE>,                                                'XIntersectRegion',                             \
        XKeycodeToKeysym                        ,<NONE>,                                                'XKeycodeToKeysym',                             \
        XKeysymToKeycode                        ,<NONE>,                                                'XKeysymToKeycode',                             \
        XKeysymToString                         ,<NONE>,                                                'XKeysymToString',                              \
        XKillClient                             ,<NONE>,                                                'XKillClient',                                  \
        XLastKnownRequestProcessed              ,<NONE>,                                                'XLastKnownRequestProcessed',                   \
        XListDepths                             ,<NONE>,                                                'XListDepths',                                  \
        XListExtensions                         ,<NONE>,                                                'XListExtensions',                              \
        XListFonts                              ,<NONE>,                                                'XListFonts',                                   \
        XListFontsWithInfo                      ,<NONE>,                                                'XListFontsWithInfo',                           \
        XListHosts                              ,<NONE>,                                                'XListHosts',                                   \
        XListInstalledColormaps                 ,<NONE>,                                                'XListInstalledColormaps',                      \
        XListPixmapFormats                      ,<NONE>,                                                'XListPixmapFormats',                           \
        XListProperties                         ,<NONE>,                                                'XListProperties',                              \
        XLoadFont                               ,<NONE>,                                                'XLoadFont',                                    \
        XLoadQueryFont                          ,<NONE>,                                                'XLoadQueryFont',                               \
        XLocaleOfFontSet                        ,<NONE>,                                                'XLocaleOfFontSet',                             \
        XLocaleOfIM                             ,<NONE>,                                                'XLocaleOfIM',                                  \
        XLocaleOfOM                             ,<NONE>,                                                'XLocaleOfOM',                                  \
        XLockDisplay                            ,<NONE>,                                                'XLockDisplay',                                 \
        XLookupColor                            ,<NONE>,                                                'XLookupColor',                                 \
        XLookupKeysym                           ,<NONE>,                                                'XLookupKeysym',                                \
        XLookupString                           ,<NONE>,                                                'XLookupString',                                \
        XLowerWindow                            ,<NONE>,                                                'XLowerWindow',                                 \
        XMapRaised                              ,<NONE>,                                                'XMapRaised',                                   \
        XMapSubwindows                          ,<NONE>,                                                'XMapSubwindows',                               \
        XMapWindow                              ,<NONE>,                                                'XMapWindow',                                   \
        XMaskEvent                              ,<.display, .event_mask, .pEventReturn>,                'XMaskEvent',                                   \
        XMatchVisualInfo                        ,<NONE>,                                                'XMatchVisualInfo',                             \
        XMaxCmapsOfScreen                       ,<NONE>,                                                'XMaxCmapsOfScreen',                            \
        XMaxRequestSize                         ,<NONE>,                                                'XMaxRequestSize',                              \
        XMinCmapsOfScreen                       ,<NONE>,                                                'XMinCmapsOfScreen',                            \
        XMoveResizeWindow                       ,<NONE>,                                                'XMoveResizeWindow',                            \
        XMoveWindow                             ,<NONE>,                                                'XMoveWindow',                                  \
        XNewModifiermap                         ,<NONE>,                                                'XNewModifiermap',                              \
        XNextEvent                              ,<NONE>,                                                'XNextEvent',                                   \
        XNextRequest                            ,<NONE>,                                                'XNextRequest',                                 \
        XNoOp                                   ,<NONE>,                                                'XNoOp',                                        \
        XOMOfOC                                 ,<NONE>,                                                'XOMOfOC',                                      \
        XOffsetRegion                           ,<NONE>,                                                'XOffsetRegion',                                \
        XOpenDisplay                            ,<NONE>,                                                'XOpenDisplay',                                 \
        XOpenIM                                 ,<NONE>,                                                'XOpenIM',                                      \
        XOpenOM                                 ,<NONE>,                                                'XOpenOM',                                      \
        XParseColor                             ,<NONE>,                                                'XParseColor',                                  \
        XParseGeometry                          ,<NONE>,                                                'XParseGeometry',                               \
        XPeekEvent                              ,<NONE>,                                                'XPeekEvent',                                   \
        XPeekIfEvent                            ,<NONE>,                                                'XPeekIfEvent',                                 \
        XPending                                ,<NONE>,                                                'XPending',                                     \
        XPlanesOfScreen                         ,<NONE>,                                                'XPlanesOfScreen',                              \
        XPointInRegion                          ,<NONE>,                                                'XPointInRegion',                               \
        XPolygonRegion                          ,<NONE>,                                                'XPolygonRegion',                               \
        XProcessInternalConnection              ,<NONE>,                                                'XProcessInternalConnection',                   \
        XProtocolRevision                       ,<NONE>,                                                'XProtocolRevision',                            \
        XProtocolVersion                        ,<NONE>,                                                'XProtocolVersion',                             \
        XPutBackEvent                           ,<NONE>,                                                'XPutBackEvent',                                \
        XPutImage                               ,<NONE>,                                                'XPutImage',                                    \
        XPutPixel                               ,<NONE>,                                                'XPutPixel',                                    \
        XQLength                                ,<NONE>,                                                'XQLength',                                     \
        XQueryBestCursor                        ,<NONE>,                                                'XQueryBestCursor',                             \
        XQueryBestSize                          ,<NONE>,                                                'XQueryBestSize',                               \
        XQueryBestStipple                       ,<NONE>,                                                'XQueryBestStipple',                            \
        XQueryBestTile                          ,<NONE>,                                                'XQueryBestTile',                               \
        XQueryColor                             ,<NONE>,                                                'XQueryColor',                                  \
        XQueryColors                            ,<NONE>,                                                'XQueryColors',                                 \
        XQueryExtension                         ,<NONE>,                                                'XQueryExtension',                              \
        XQueryFont                              ,<NONE>,                                                'XQueryFont',                                   \
        XQueryKeymap                            ,<NONE>,                                                'XQueryKeymap',                                 \
        XQueryPointer                           ,<NONE>,                                                'XQueryPointer',                                \
        XQueryTextExtents                       ,<NONE>,                                                'XQueryTextExtents',                            \
        XQueryTextExtents16                     ,<NONE>,                                                'XQueryTextExtents16',                          \
        XQueryTree                              ,<NONE>,                                                'XQueryTree',                                   \
        XRaiseWindow                            ,<NONE>,                                                'XRaiseWindow',                                 \
        XReadBitmapFile                         ,<NONE>,                                                'XReadBitmapFile',                              \
        XReadBitmapFileData                     ,<NONE>,                                                'XReadBitmapFileData',                          \
        XRebindKeysym                           ,<NONE>,                                                'XRebindKeysym',                                \
        XRecolorCursor                          ,<NONE>,                                                'XRecolorCursor',                               \
        XReconfigureWMWindow                    ,<NONE>,                                                'XReconfigureWMWindow',                         \
        XRectInRegion                           ,<NONE>,                                                'XRectInRegion',                                \
        XRefreshKeyboardMapping                 ,<NONE>,                                                'XRefreshKeyboardMapping',                      \
        XRegisterIMInstantiateCallback          ,<NONE>,                                                'XRegisterIMInstantiateCallback',               \
        XRemoveConnectionWatch                  ,<NONE>,                                                'XRemoveConnectionWatch',                       \
        XRemoveFromSaveSet                      ,<NONE>,                                                'XRemoveFromSaveSet',                           \
        XRemoveHost                             ,<NONE>,                                                'XRemoveHost',                                  \
        XRemoveHosts                            ,<NONE>,                                                'XRemoveHosts',                                 \
        XReparentWindow                         ,<NONE>,                                                'XReparentWindow',                              \
        XResetScreenSaver                       ,<NONE>,                                                'XResetScreenSaver',                            \
        XResizeWindow                           ,<NONE>,                                                'XResizeWindow',                                \
        XResourceManagerString                  ,<NONE>,                                                'XResourceManagerString',                       \
        XRestackWindows                         ,<NONE>,                                                'XRestackWindows',                              \
        XRootWindow                             ,<NONE>,                                                'XRootWindow',                                  \
        XRootWindowOfScreen                     ,<NONE>,                                                'XRootWindowOfScreen',                          \
        XRotateBuffers                          ,<NONE>,                                                'XRotateBuffers',                               \
        XRotateWindowProperties                 ,<NONE>,                                                'XRotateWindowProperties',                      \
        XSaveContext                            ,<NONE>,                                                'XSaveContext',                                 \
        XScreenCount                            ,<NONE>,                                                'XScreenCount',                                 \
        XScreenNumberOfScreen                   ,<NONE>,                                                'XScreenNumberOfScreen',                        \
        XScreenOfDisplay                        ,<NONE>,                                                'XScreenOfDisplay',                             \
        XScreenResourceString                   ,<NONE>,                                                'XScreenResourceString',                        \
        XSelectInput                            ,<NONE>,                                                'XSelectInput',                                 \
        XSendEvent                              ,<NONE>,                                                'XSendEvent',                                   \
        XServerVendor                           ,<NONE>,                                                'XServerVendor',                                \
        XSetAccessControl                       ,<NONE>,                                                'XSetAccessControl',                            \
        XSetAfterFunction                       ,<NONE>,                                                'XSetAfterFunction',                            \
        XSetArcMode                             ,<NONE>,                                                'XSetArcMode',                                  \
        XSetAuthorization                       ,<NONE>,                                                'XSetAuthorization',                            \
        XSetBackground                          ,<NONE>,                                                'XSetBackground',                               \
        XSetClassHint                           ,<NONE>,                                                'XSetClassHint',                                \
        XSetClipMask                            ,<NONE>,                                                'XSetClipMask',                                 \
        XSetClipOrigin                          ,<NONE>,                                                'XSetClipOrigin',                               \
        XSetClipRectangles                      ,<NONE>,                                                'XSetClipRectangles',                           \
        XSetCloseDownMode                       ,<NONE>,                                                'XSetCloseDownMode',                            \
        XSetCommand                             ,<NONE>,                                                'XSetCommand',                                  \
        XSetDashes                              ,<NONE>,                                                'XSetDashes',                                   \
        XSetErrorHandler                        ,<NONE>,                                                'XSetErrorHandler',                             \
        XSetFillRule                            ,<NONE>,                                                'XSetFillRule',                                 \
        XSetFillStyle                           ,<NONE>,                                                'XSetFillStyle',                                \
        XSetFont                                ,<NONE>,                                                'XSetFont',                                     \
        XSetFontPath                            ,<NONE>,                                                'XSetFontPath',                                 \
        XSetForeground                          ,<NONE>,                                                'XSetForeground',                               \
        XSetFunction                            ,<NONE>,                                                'XSetFunction',                                 \
        XSetGraphicsExposures                   ,<NONE>,                                                'XSetGraphicsExposures',                        \
        XSetICFocus                             ,<NONE>,                                                'XSetICFocus',                                  \
        XSetICValues                            ,<NONE>,                                                'XSetICValues',                                 \
        XSetIMValues                            ,<NONE>,                                                'XSetIMValues',                                 \
        XSetIOErrorHandler                      ,<NONE>,                                                'XSetIOErrorHandler',                           \
        XSetIconName                            ,<NONE>,                                                'XSetIconName',                                 \
        XSetIconSizes                           ,<NONE>,                                                'XSetIconSizes',                                \
        XSetInputFocus                          ,<NONE>,                                                'XSetInputFocus',                               \
        XSetLineAttributes                      ,<NONE>,                                                'XSetLineAttributes',                           \
        XSetLocaleModifiers                     ,<NONE>,                                                'XSetLocaleModifiers',                          \
        XSetModifierMapping                     ,<NONE>,                                                'XSetModifierMapping',                          \
        XSetNormalHints                         ,<NONE>,                                                'XSetNormalHints',                              \
        XSetOCValues                            ,<NONE>,                                                'XSetOCValues',                                 \
        XSetOMValues                            ,<NONE>,                                                'XSetOMValues',                                 \
        XSetPlaneMask                           ,<NONE>,                                                'XSetPlaneMask',                                \
        XSetPointerMapping                      ,<NONE>,                                                'XSetPointerMapping',                           \
        XSetRGBColormaps                        ,<NONE>,                                                'XSetRGBColormaps',                             \
        XSetRegion                              ,<NONE>,                                                'XSetRegion',                                   \
        XSetScreenSaver                         ,<NONE>,                                                'XSetScreenSaver',                              \
        XSetSelectionOwner                      ,<.display, .selection, .owner, .time>,                 'XSetSelectionOwner',                           \
        XSetSizeHints                           ,<NONE>,                                                'XSetSizeHints',                                \
        XSetStandardColormap                    ,<NONE>,                                                'XSetStandardColormap',                         \
        XSetStandardProperties                  ,<NONE>,                                                'XSetStandardProperties',                       \
        XSetState                               ,<NONE>,                                                'XSetState',                                    \
        XSetStipple                             ,<NONE>,                                                'XSetStipple',                                  \
        XSetSubwindowMode                       ,<NONE>,                                                'XSetSubwindowMode',                            \
        XSetTSOrigin                            ,<NONE>,                                                'XSetTSOrigin',                                 \
        XSetTextProperty                        ,<NONE>,                                                'XSetTextProperty',                             \
        XSetTile                                ,<NONE>,                                                'XSetTile',                                     \
        XSetTransientForHint                    ,<NONE>,                                                'XSetTransientForHint',                         \
        XSetWMClientMachine                     ,<NONE>,                                                'XSetWMClientMachine',                          \
        XSetWMColormapWindows                   ,<NONE>,                                                'XSetWMColormapWindows',                        \
        XSetWMHints                             ,<NONE>,                                                'XSetWMHints',                                  \
        XSetWMIconName                          ,<NONE>,                                                'XSetWMIconName',                               \
        XSetWMName                              ,<NONE>,                                                'XSetWMName',                                   \
        XSetWMNormalHints                       ,<NONE>,                                                'XSetWMNormalHints',                            \
        XSetWMProperties                        ,<NONE>,                                                'XSetWMProperties',                             \
        XSetWMProtocols                         ,<NONE>,                                                'XSetWMProtocols',                              \
        XSetWMSizeHints                         ,<NONE>,                                                'XSetWMSizeHints',                              \
        XSetWindowBackground                    ,<NONE>,                                                'XSetWindowBackground',                         \
        XSetWindowBackgroundPixmap              ,<NONE>,                                                'XSetWindowBackgroundPixmap',                   \
        XSetWindowBorder                        ,<NONE>,                                                'XSetWindowBorder',                             \
        XSetWindowBorderPixmap                  ,<NONE>,                                                'XSetWindowBorderPixmap',                       \
        XSetWindowBorderWidth                   ,<NONE>,                                                'XSetWindowBorderWidth',                        \
        XSetWindowColormap                      ,<NONE>,                                                'XSetWindowColormap',                           \
        XSetZoomHints                           ,<NONE>,                                                'XSetZoomHints',                                \
        XShrinkRegion                           ,<NONE>,                                                'XShrinkRegion',                                \
        XStoreBuffer                            ,<NONE>,                                                'XStoreBuffer',                                 \
        XStoreBytes                             ,<NONE>,                                                'XStoreBytes',                                  \
        XStoreColor                             ,<NONE>,                                                'XStoreColor',                                  \
        XStoreColors                            ,<NONE>,                                                'XStoreColors',                                 \
        XStoreName                              ,<NONE>,                                                'XStoreName',                                   \
        XStoreNamedColor                        ,<NONE>,                                                'XStoreNamedColor',                             \
        XStringListToTextProperty               ,<NONE>,                                                'XStringListToTextProperty',                    \
        XStringToKeysym                         ,<NONE>,                                                'XStringToKeysym',                              \
        XSubImage                               ,<NONE>,                                                'XSubImage',                                    \
        XSubtractRegion                         ,<NONE>,                                                'XSubtractRegion',                              \
        XSupportsLocale                         ,<NONE>,                                                'XSupportsLocale',                              \
        XSync                                   ,<NONE>,                                                'XSync',                                        \
        XSynchronize                            ,<NONE>,                                                'XSynchronize',                                 \
        XTextExtents                            ,<NONE>,                                                'XTextExtents',                                 \
        XTextExtents16                          ,<NONE>,                                                'XTextExtents16',                               \
        XTextPropertyToStringList               ,<NONE>,                                                'XTextPropertyToStringList',                    \
        XTextWidth                              ,<NONE>,                                                'XTextWidth',                                   \
        XTextWidth16                            ,<NONE>,                                                'XTextWidth16',                                 \
        XTranslateCoordinates                   ,<NONE>,                                                'XTranslateCoordinates',                        \
        XUndefineCursor                         ,<NONE>,                                                'XUndefineCursor',                              \
        XUngrabButton                           ,<NONE>,                                                'XUngrabButton',                                \
        XUngrabKey                              ,<NONE>,                                                'XUngrabKey',                                   \
        XUngrabKeyboard                         ,<NONE>,                                                'XUngrabKeyboard',                              \
        XUngrabPointer                          ,<NONE>,                                                'XUngrabPointer',                               \
        XUngrabServer                           ,<NONE>,                                                'XUngrabServer',                                \
        XUninstallColormap                      ,<NONE>,                                                'XUninstallColormap',                           \
        XUnionRectWithRegion                    ,<NONE>,                                                'XUnionRectWithRegion',                         \
        XUnionRegion                            ,<NONE>,                                                'XUnionRegion',                                 \
        XUnloadFont                             ,<NONE>,                                                'XUnloadFont',                                  \
        XUnlockDisplay                          ,<NONE>,                                                'XUnlockDisplay',                               \
        XUnmapSubwindows                        ,<NONE>,                                                'XUnmapSubwindows',                             \
        XUnmapWindow                            ,<NONE>,                                                'XUnmapWindow',                                 \
        XUnregisterIMInstantiateCallback        ,<NONE>,                                                'XUnregisterIMInstantiateCallback',             \
        XUnsetICFocus                           ,<NONE>,                                                'XUnsetICFocus',                                \
        XVaCreateNestedList                     ,<NONE>,                                                'XVaCreateNestedList',                          \
        XVendorRelease                          ,<NONE>,                                                'XVendorRelease',                               \
        XVisualIDFromVisual                     ,<NONE>,                                                'XVisualIDFromVisual',                          \
        XWMGeometry                             ,<NONE>,                                                'XWMGeometry',                                  \
        XWarpPointer                            ,<NONE>,                                                'XWarpPointer',                                 \
        XWhitePixel                             ,<NONE>,                                                'XWhitePixel',                                  \
        XWhitePixelOfScreen                     ,<NONE>,                                                'XWhitePixelOfScreen',                          \
        XWidthMMOfScreen                        ,<NONE>,                                                'XWidthMMOfScreen',                             \
        XWidthOfScreen                          ,<NONE>,                                                'XWidthOfScreen',                               \
        XWindowEvent                            ,<.display, .hwin, .event_mask, .pEvent>,               'XWindowEvent',                                 \
        XWithdrawWindow                         ,<NONE>,                                                'XWithdrawWindow',                              \
        XWriteBitmapFile                        ,<NONE>,                                                'XWriteBitmapFile',                             \
        XXorRegion                              ,<NONE>,                                                'XXorRegion',                                   \
        XcmsAddColorSpace                       ,<NONE>,                                                'XcmsAddColorSpace',                            \
        XcmsAddFunctionSet                      ,<NONE>,                                                'XcmsAddFunctionSet',                           \
        XcmsAllocColor                          ,<NONE>,                                                'XcmsAllocColor',                               \
        XcmsAllocNamedColor                     ,<NONE>,                                                'XcmsAllocNamedColor',                          \
        XcmsCCCOfColormap                       ,<NONE>,                                                'XcmsCCCOfColormap',                            \
        XcmsCIELabClipL                         ,<NONE>,                                                'XcmsCIELabClipL',                              \
        XcmsCIELabClipLab                       ,<NONE>,                                                'XcmsCIELabClipLab',                            \
        XcmsCIELabClipab                        ,<NONE>,                                                'XcmsCIELabClipab',                             \
        XcmsCIELabColorSpace                    ,<NONE>,                                                'XcmsCIELabColorSpace',                         \
        XcmsCIELabQueryMaxC                     ,<NONE>,                                                'XcmsCIELabQueryMaxC',                          \
        XcmsCIELabQueryMaxL                     ,<NONE>,                                                'XcmsCIELabQueryMaxL',                          \
        XcmsCIELabQueryMaxLC                    ,<NONE>,                                                'XcmsCIELabQueryMaxLC',                         \
        XcmsCIELabQueryMinL                     ,<NONE>,                                                'XcmsCIELabQueryMinL',                          \
        XcmsCIELabToCIEXYZ                      ,<NONE>,                                                'XcmsCIELabToCIEXYZ',                           \
        XcmsCIELabWhiteShiftColors              ,<NONE>,                                                'XcmsCIELabWhiteShiftColors',                   \
        XcmsCIELuvClipL                         ,<NONE>,                                                'XcmsCIELuvClipL',                              \
        XcmsCIELuvClipLuv                       ,<NONE>,                                                'XcmsCIELuvClipLuv',                            \
        XcmsCIELuvClipuv                        ,<NONE>,                                                'XcmsCIELuvClipuv',                             \
        XcmsCIELuvColorSpace                    ,<NONE>,                                                'XcmsCIELuvColorSpace',                         \
        XcmsCIELuvQueryMaxC                     ,<NONE>,                                                'XcmsCIELuvQueryMaxC',                          \
        XcmsCIELuvQueryMaxL                     ,<NONE>,                                                'XcmsCIELuvQueryMaxL',                          \
        XcmsCIELuvQueryMaxLC                    ,<NONE>,                                                'XcmsCIELuvQueryMaxLC',                         \
        XcmsCIELuvQueryMinL                     ,<NONE>,                                                'XcmsCIELuvQueryMinL',                          \
        XcmsCIELuvToCIEuvY                      ,<NONE>,                                                'XcmsCIELuvToCIEuvY',                           \
        XcmsCIELuvWhiteShiftColors              ,<NONE>,                                                'XcmsCIELuvWhiteShiftColors',                   \
        XcmsCIEXYZColorSpace                    ,<NONE>,                                                'XcmsCIEXYZColorSpace',                         \
        XcmsCIEXYZToCIELab                      ,<NONE>,                                                'XcmsCIEXYZToCIELab',                           \
        XcmsCIEXYZToCIEuvY                      ,<NONE>,                                                'XcmsCIEXYZToCIEuvY',                           \
        XcmsCIEXYZToCIExyY                      ,<NONE>,                                                'XcmsCIEXYZToCIExyY',                           \
        XcmsCIEXYZToRGBi                        ,<NONE>,                                                'XcmsCIEXYZToRGBi',                             \
        XcmsCIEuvYColorSpace                    ,<NONE>,                                                'XcmsCIEuvYColorSpace',                         \
        XcmsCIEuvYToCIELuv                      ,<NONE>,                                                'XcmsCIEuvYToCIELuv',                           \
        XcmsCIEuvYToCIEXYZ                      ,<NONE>,                                                'XcmsCIEuvYToCIEXYZ',                           \
        XcmsCIEuvYToTekHVC                      ,<NONE>,                                                'XcmsCIEuvYToTekHVC',                           \
        XcmsCIExyYColorSpace                    ,<NONE>,                                                'XcmsCIExyYColorSpace',                         \
        XcmsCIExyYToCIEXYZ                      ,<NONE>,                                                'XcmsCIExyYToCIEXYZ',                           \
        XcmsClientWhitePointOfCCC               ,<NONE>,                                                'XcmsClientWhitePointOfCCC',                    \
        XcmsConvertColors                       ,<NONE>,                                                'XcmsConvertColors',                            \
        XcmsCreateCCC                           ,<NONE>,                                                'XcmsCreateCCC',                                \
        XcmsDefaultCCC                          ,<NONE>,                                                'XcmsDefaultCCC',                               \
        XcmsDisplayOfCCC                        ,<NONE>,                                                'XcmsDisplayOfCCC',                             \
        XcmsFormatOfPrefix                      ,<NONE>,                                                'XcmsFormatOfPrefix',                           \
        XcmsFreeCCC                             ,<NONE>,                                                'XcmsFreeCCC',                                  \
        XcmsLinearRGBFunctionSet                ,<NONE>,                                                'XcmsLinearRGBFunctionSet',                     \
        XcmsLookupColor                         ,<NONE>,                                                'XcmsLookupColor',                              \
        XcmsPrefixOfFormat                      ,<NONE>,                                                'XcmsPrefixOfFormat',                           \
        XcmsQueryBlack                          ,<NONE>,                                                'XcmsQueryBlack',                               \
        XcmsQueryBlue                           ,<NONE>,                                                'XcmsQueryBlue',                                \
        XcmsQueryColor                          ,<NONE>,                                                'XcmsQueryColor',                               \
        XcmsQueryColors                         ,<NONE>,                                                'XcmsQueryColors',                              \
        XcmsQueryGreen                          ,<NONE>,                                                'XcmsQueryGreen',                               \
        XcmsQueryRed                            ,<NONE>,                                                'XcmsQueryRed',                                 \
        XcmsQueryWhite                          ,<NONE>,                                                'XcmsQueryWhite',                               \
        XcmsRGBColorSpace                       ,<NONE>,                                                'XcmsRGBColorSpace',                            \
        XcmsRGBToRGBi                           ,<NONE>,                                                'XcmsRGBToRGBi',                                \
        XcmsRGBiColorSpace                      ,<NONE>,                                                'XcmsRGBiColorSpace',                           \
        XcmsRGBiToCIEXYZ                        ,<NONE>,                                                'XcmsRGBiToCIEXYZ',                             \
        XcmsRGBiToRGB                           ,<NONE>,                                                'XcmsRGBiToRGB',                                \
        XcmsScreenNumberOfCCC                   ,<NONE>,                                                'XcmsScreenNumberOfCCC',                        \
        XcmsScreenWhitePointOfCCC               ,<NONE>,                                                'XcmsScreenWhitePointOfCCC',                    \
        XcmsSetCCCOfColormap                    ,<NONE>,                                                'XcmsSetCCCOfColormap',                         \
        XcmsSetCompressionProc                  ,<NONE>,                                                'XcmsSetCompressionProc',                       \
        XcmsSetWhiteAdjustProc                  ,<NONE>,                                                'XcmsSetWhiteAdjustProc',                       \
        XcmsSetWhitePoint                       ,<NONE>,                                                'XcmsSetWhitePoint',                            \
        XcmsStoreColor                          ,<NONE>,                                                'XcmsStoreColor',                               \
        XcmsStoreColors                         ,<NONE>,                                                'XcmsStoreColors',                              \
        XcmsTekHVCClipC                         ,<NONE>,                                                'XcmsTekHVCClipC',                              \
        XcmsTekHVCClipV                         ,<NONE>,                                                'XcmsTekHVCClipV',                              \
        XcmsTekHVCClipVC                        ,<NONE>,                                                'XcmsTekHVCClipVC',                             \
        XcmsTekHVCColorSpace                    ,<NONE>,                                                'XcmsTekHVCColorSpace',                         \
        XcmsTekHVCQueryMaxC                     ,<NONE>,                                                'XcmsTekHVCQueryMaxC',                          \
        XcmsTekHVCQueryMaxV                     ,<NONE>,                                                'XcmsTekHVCQueryMaxV',                          \
        XcmsTekHVCQueryMaxVC                    ,<NONE>,                                                'XcmsTekHVCQueryMaxVC',                         \
        XcmsTekHVCQueryMaxVSamples              ,<NONE>,                                                'XcmsTekHVCQueryMaxVSamples',                   \
        XcmsTekHVCQueryMinV                     ,<NONE>,                                                'XcmsTekHVCQueryMinV',                          \
        XcmsTekHVCToCIEuvY                      ,<NONE>,                                                'XcmsTekHVCToCIEuvY',                           \
        XcmsTekHVCWhiteShiftColors              ,<NONE>,                                                'XcmsTekHVCWhiteShiftColors',                   \
        XcmsUNDEFINEDColorSpace                 ,<NONE>,                                                'XcmsUNDEFINEDColorSpace',                      \
        XcmsVisualOfCCC                         ,<NONE>,                                                'XcmsVisualOfCCC',                              \
        XkbAddDeviceLedInfo                     ,<NONE>,                                                'XkbAddDeviceLedInfo',                          \
        XkbAddGeomColor                         ,<NONE>,                                                'XkbAddGeomColor',                              \
        XkbAddGeomDoodad                        ,<NONE>,                                                'XkbAddGeomDoodad',                             \
        XkbAddGeomKey                           ,<NONE>,                                                'XkbAddGeomKey',                                \
        XkbAddGeomKeyAlias                      ,<NONE>,                                                'XkbAddGeomKeyAlias',                           \
        XkbAddGeomOutline                       ,<NONE>,                                                'XkbAddGeomOutline',                            \
        XkbAddGeomOverlay                       ,<NONE>,                                                'XkbAddGeomOverlay',                            \
        XkbAddGeomOverlayKey                    ,<NONE>,                                                'XkbAddGeomOverlayKey',                         \
        XkbAddGeomOverlayRow                    ,<NONE>,                                                'XkbAddGeomOverlayRow',                         \
        XkbAddGeomProperty                      ,<NONE>,                                                'XkbAddGeomProperty',                           \
        XkbAddGeomRow                           ,<NONE>,                                                'XkbAddGeomRow',                                \
        XkbAddGeomSection                       ,<NONE>,                                                'XkbAddGeomSection',                            \
        XkbAddGeomShape                         ,<NONE>,                                                'XkbAddGeomShape',                              \
        XkbAddKeyType                           ,<NONE>,                                                'XkbAddKeyType',                                \
        XkbAllocClientMap                       ,<NONE>,                                                'XkbAllocClientMap',                            \
        XkbAllocCompatMap                       ,<NONE>,                                                'XkbAllocCompatMap',                            \
        XkbAllocControls                        ,<NONE>,                                                'XkbAllocControls',                             \
        XkbAllocDeviceInfo                      ,<NONE>,                                                'XkbAllocDeviceInfo',                           \
        XkbAllocGeomColors                      ,<NONE>,                                                'XkbAllocGeomColors',                           \
        XkbAllocGeomDoodads                     ,<NONE>,                                                'XkbAllocGeomDoodads',                          \
        XkbAllocGeomKeyAliases                  ,<NONE>,                                                'XkbAllocGeomKeyAliases',                       \
        XkbAllocGeomKeys                        ,<NONE>,                                                'XkbAllocGeomKeys',                             \
        XkbAllocGeomOutlines                    ,<NONE>,                                                'XkbAllocGeomOutlines',                         \
        XkbAllocGeomOverlayKeys                 ,<NONE>,                                                'XkbAllocGeomOverlayKeys',                      \
        XkbAllocGeomOverlayRows                 ,<NONE>,                                                'XkbAllocGeomOverlayRows',                      \
        XkbAllocGeomOverlays                    ,<NONE>,                                                'XkbAllocGeomOverlays',                         \
        XkbAllocGeomPoints                      ,<NONE>,                                                'XkbAllocGeomPoints',                           \
        XkbAllocGeomProps                       ,<NONE>,                                                'XkbAllocGeomProps',                            \
        XkbAllocGeomRows                        ,<NONE>,                                                'XkbAllocGeomRows',                             \
        XkbAllocGeomSectionDoodads              ,<NONE>,                                                'XkbAllocGeomSectionDoodads',                   \
        XkbAllocGeomSections                    ,<NONE>,                                                'XkbAllocGeomSections',                         \
        XkbAllocGeomShapes                      ,<NONE>,                                                'XkbAllocGeomShapes',                           \
        XkbAllocGeometry                        ,<NONE>,                                                'XkbAllocGeometry',                             \
        XkbAllocIndicatorMaps                   ,<NONE>,                                                'XkbAllocIndicatorMaps',                        \
        XkbAllocKeyboard                        ,<NONE>,                                                'XkbAllocKeyboard',                             \
        XkbAllocNames                           ,<NONE>,                                                'XkbAllocNames',                                \
        XkbAllocServerMap                       ,<NONE>,                                                'XkbAllocServerMap',                            \
        XkbApplyCompatMapToKey                  ,<NONE>,                                                'XkbApplyCompatMapToKey',                       \
        XkbApplyVirtualModChanges               ,<NONE>,                                                'XkbApplyVirtualModChanges',                    \
        XkbBell                                 ,<NONE>,                                                'XkbBell',                                      \
        XkbBellEvent                            ,<NONE>,                                                'XkbBellEvent',                                 \
        XkbChangeDeviceInfo                     ,<NONE>,                                                'XkbChangeDeviceInfo',                          \
        XkbChangeEnabledControls                ,<NONE>,                                                'XkbChangeEnabledControls',                     \
        XkbChangeKeycodeRange                   ,<NONE>,                                                'XkbChangeKeycodeRange',                        \
        XkbChangeMap                            ,<NONE>,                                                'XkbChangeMap',                                 \
        XkbChangeNames                          ,<NONE>,                                                'XkbChangeNames',                               \
        XkbChangeTypesOfKey                     ,<NONE>,                                                'XkbChangeTypesOfKey',                          \
        XkbComputeEffectiveMap                  ,<NONE>,                                                'XkbComputeEffectiveMap',                       \
        XkbComputeRowBounds                     ,<NONE>,                                                'XkbComputeRowBounds',                          \
        XkbComputeSectionBounds                 ,<NONE>,                                                'XkbComputeSectionBounds',                      \
        XkbComputeShapeBounds                   ,<NONE>,                                                'XkbComputeShapeBounds',                        \
        XkbComputeShapeTop                      ,<NONE>,                                                'XkbComputeShapeTop',                           \
        XkbCopyKeyType                          ,<NONE>,                                                'XkbCopyKeyType',                               \
        XkbCopyKeyTypes                         ,<NONE>,                                                'XkbCopyKeyTypes',                              \
        XkbDeviceBell                           ,<NONE>,                                                'XkbDeviceBell',                                \
        XkbDeviceBellEvent                      ,<NONE>,                                                'XkbDeviceBellEvent',                           \
        XkbFindOverlayForKey                    ,<NONE>,                                                'XkbFindOverlayForKey',                         \
        XkbForceBell                            ,<NONE>,                                                'XkbForceBell',                                 \
        XkbForceDeviceBell                      ,<NONE>,                                                'XkbForceDeviceBell',                           \
        XkbFreeClientMap                        ,<NONE>,                                                'XkbFreeClientMap',                             \
        XkbFreeCompatMap                        ,<NONE>,                                                'XkbFreeCompatMap',                             \
        XkbFreeComponentList                    ,<NONE>,                                                'XkbFreeComponentList',                         \
        XkbFreeControls                         ,<NONE>,                                                'XkbFreeControls',                              \
        XkbFreeDeviceInfo                       ,<NONE>,                                                'XkbFreeDeviceInfo',                            \
        XkbFreeGeomColors                       ,<NONE>,                                                'XkbFreeGeomColors',                            \
        XkbFreeGeomDoodads                      ,<NONE>,                                                'XkbFreeGeomDoodads',                           \
        XkbFreeGeomKeyAliases                   ,<NONE>,                                                'XkbFreeGeomKeyAliases',                        \
        XkbFreeGeomKeys                         ,<NONE>,                                                'XkbFreeGeomKeys',                              \
        XkbFreeGeomOutlines                     ,<NONE>,                                                'XkbFreeGeomOutlines',                          \
        XkbFreeGeomOverlayKeys                  ,<NONE>,                                                'XkbFreeGeomOverlayKeys',                       \
        XkbFreeGeomOverlayRows                  ,<NONE>,                                                'XkbFreeGeomOverlayRows',                       \
        XkbFreeGeomOverlays                     ,<NONE>,                                                'XkbFreeGeomOverlays',                          \
        XkbFreeGeomPoints                       ,<NONE>,                                                'XkbFreeGeomPoints',                            \
        XkbFreeGeomProperties                   ,<NONE>,                                                'XkbFreeGeomProperties',                        \
        XkbFreeGeomRows                         ,<NONE>,                                                'XkbFreeGeomRows',                              \
        XkbFreeGeomSections                     ,<NONE>,                                                'XkbFreeGeomSections',                          \
        XkbFreeGeomShapes                       ,<NONE>,                                                'XkbFreeGeomShapes',                            \
        XkbFreeGeometry                         ,<NONE>,                                                'XkbFreeGeometry',                              \
        XkbFreeIndicatorMaps                    ,<NONE>,                                                'XkbFreeIndicatorMaps',                         \
        XkbFreeKeyboard                         ,<NONE>,                                                'XkbFreeKeyboard',                              \
        XkbFreeNames                            ,<NONE>,                                                'XkbFreeNames',                                 \
        XkbFreeServerMap                        ,<NONE>,                                                'XkbFreeServerMap',                             \
        XkbGetAutoRepeatRate                    ,<NONE>,                                                'XkbGetAutoRepeatRate',                         \
        XkbGetAutoResetControls                 ,<NONE>,                                                'XkbGetAutoResetControls',                      \
        XkbGetCompatMap                         ,<NONE>,                                                'XkbGetCompatMap',                              \
        XkbGetControls                          ,<NONE>,                                                'XkbGetControls',                               \
        XkbGetDetectableAutoRepeat              ,<NONE>,                                                'XkbGetDetectableAutoRepeat',                   \
        XkbGetDeviceButtonActions               ,<NONE>,                                                'XkbGetDeviceButtonActions',                    \
        XkbGetDeviceInfo                        ,<NONE>,                                                'XkbGetDeviceInfo',                             \
        XkbGetDeviceInfoChanges                 ,<NONE>,                                                'XkbGetDeviceInfoChanges',                      \
        XkbGetDeviceLedInfo                     ,<NONE>,                                                'XkbGetDeviceLedInfo',                          \
        XkbGetGeometry                          ,<NONE>,                                                'XkbGetGeometry',                               \
        XkbGetIndicatorMap                      ,<NONE>,                                                'XkbGetIndicatorMap',                           \
        XkbGetIndicatorState                    ,<NONE>,                                                'XkbGetIndicatorState',                         \
        XkbGetKeyActions                        ,<NONE>,                                                'XkbGetKeyActions',                             \
        XkbGetKeyBehaviors                      ,<NONE>,                                                'XkbGetKeyBehaviors',                           \
        XkbGetKeyExplicitComponents             ,<NONE>,                                                'XkbGetKeyExplicitComponents',                  \
        XkbGetKeyModifierMap                    ,<NONE>,                                                'XkbGetKeyModifierMap',                         \
        XkbGetKeySyms                           ,<NONE>,                                                'XkbGetKeySyms',                                \
        XkbGetKeyTypes                          ,<NONE>,                                                'XkbGetKeyTypes',                               \
        XkbGetKeyVirtualModMap                  ,<NONE>,                                                'XkbGetKeyVirtualModMap',                       \
        XkbGetKeyboard                          ,<NONE>,                                                'XkbGetKeyboard',                               \
        XkbGetKeyboardByName                    ,<NONE>,                                                'XkbGetKeyboardByName',                         \
        XkbGetMap                               ,<NONE>,                                                'XkbGetMap',                                    \
        XkbGetMapChanges                        ,<NONE>,                                                'XkbGetMapChanges',                             \
        XkbGetNamedDeviceIndicator              ,<NONE>,                                                'XkbGetNamedDeviceIndicator',                   \
        XkbGetNamedGeometry                     ,<NONE>,                                                'XkbGetNamedGeometry',                          \
        XkbGetNamedIndicator                    ,<NONE>,                                                'XkbGetNamedIndicator',                         \
        XkbGetNames                             ,<NONE>,                                                'XkbGetNames',                                  \
        XkbGetPerClientControls                 ,<NONE>,                                                'XkbGetPerClientControls',                      \
        XkbGetState                             ,<NONE>,                                                'XkbGetState',                                  \
        XkbGetUpdatedMap                        ,<NONE>,                                                'XkbGetUpdatedMap',                             \
        XkbGetVirtualMods                       ,<NONE>,                                                'XkbGetVirtualMods',                            \
        XkbGetXlibControls                      ,<NONE>,                                                'XkbGetXlibControls',                           \
        XkbIgnoreExtension                      ,<NONE>,                                                'XkbIgnoreExtension',                           \
        XkbInitCanonicalKeyTypes                ,<NONE>,                                                'XkbInitCanonicalKeyTypes',                     \
        XkbKeyTypesForCoreSymbols               ,<NONE>,                                                'XkbKeyTypesForCoreSymbols',                    \
        XkbKeycodeToKeysym                      ,<NONE>,                                                'XkbKeycodeToKeysym',                           \
        XkbKeysymToModifiers                    ,<NONE>,                                                'XkbKeysymToModifiers',                         \
        XkbLatchGroup                           ,<NONE>,                                                'XkbLatchGroup',                                \
        XkbLatchModifiers                       ,<NONE>,                                                'XkbLatchModifiers',                            \
        XkbLibraryVersion                       ,<NONE>,                                                'XkbLibraryVersion',                            \
        XkbListComponents                       ,<NONE>,                                                'XkbListComponents',                            \
        XkbLockGroup                            ,<NONE>,                                                'XkbLockGroup',                                 \
        XkbLockModifiers                        ,<NONE>,                                                'XkbLockModifiers',                             \
        XkbLookupKeyBinding                     ,<NONE>,                                                'XkbLookupKeyBinding',                          \
        XkbLookupKeySym                         ,<NONE>,                                                'XkbLookupKeySym',                              \
        XkbNoteControlsChanges                  ,<NONE>,                                                'XkbNoteControlsChanges',                       \
        XkbNoteDeviceChanges                    ,<NONE>,                                                'XkbNoteDeviceChanges',                         \
        XkbNoteMapChanges                       ,<NONE>,                                                'XkbNoteMapChanges',                            \
        XkbNoteNameChanges                      ,<NONE>,                                                'XkbNoteNameChanges',                           \
        XkbOpenDisplay                          ,<NONE>,                                                'XkbOpenDisplay',                               \
        XkbQueryExtension                       ,<NONE>,                                                'XkbQueryExtension',                            \
        XkbRefreshKeyboardMapping               ,<NONE>,                                                'XkbRefreshKeyboardMapping',                    \
        XkbResizeDeviceButtonActions            ,<NONE>,                                                'XkbResizeDeviceButtonActions',                 \
        XkbResizeKeyActions                     ,<NONE>,                                                'XkbResizeKeyActions',                          \
        XkbResizeKeySyms                        ,<NONE>,                                                'XkbResizeKeySyms',                             \
        XkbResizeKeyType                        ,<NONE>,                                                'XkbResizeKeyType',                             \
        XkbSelectEventDetails                   ,<NONE>,                                                'XkbSelectEventDetails',                        \
        XkbSelectEvents                         ,<NONE>,                                                'XkbSelectEvents',                              \
        XkbSetAtomFuncs                         ,<NONE>,                                                'XkbSetAtomFuncs',                              \
        XkbSetAutoRepeatRate                    ,<NONE>,                                                'XkbSetAutoRepeatRate',                         \
        XkbSetAutoResetControls                 ,<NONE>,                                                'XkbSetAutoResetControls',                      \
        XkbSetCompatMap                         ,<NONE>,                                                'XkbSetCompatMap',                              \
        XkbSetControls                          ,<NONE>,                                                'XkbSetControls',                               \
        XkbSetDebuggingFlags                    ,<NONE>,                                                'XkbSetDebuggingFlags',                         \
        XkbSetDetectableAutoRepeat              ,<NONE>,                                                'XkbSetDetectableAutoRepeat',                   \
        XkbSetDeviceButtonActions               ,<NONE>,                                                'XkbSetDeviceButtonActions',                    \
        XkbSetDeviceInfo                        ,<NONE>,                                                'XkbSetDeviceInfo',                             \
        XkbSetDeviceLedInfo                     ,<NONE>,                                                'XkbSetDeviceLedInfo',                          \
        XkbSetGeometry                          ,<NONE>,                                                'XkbSetGeometry',                               \
        XkbSetIgnoreLockMods                    ,<NONE>,                                                'XkbSetIgnoreLockMods',                         \
        XkbSetIndicatorMap                      ,<NONE>,                                                'XkbSetIndicatorMap',                           \
        XkbSetMap                               ,<NONE>,                                                'XkbSetMap',                                    \
        XkbSetNamedDeviceIndicator              ,<NONE>,                                                'XkbSetNamedDeviceIndicator',                   \
        XkbSetNamedIndicator                    ,<NONE>,                                                'XkbSetNamedIndicator',                         \
        XkbSetNames                             ,<NONE>,                                                'XkbSetNames',                                  \
        XkbSetPerClientControls                 ,<NONE>,                                                'XkbSetPerClientControls',                      \
        XkbSetServerInternalMods                ,<NONE>,                                                'XkbSetServerInternalMods',                     \
        XkbSetXlibControls                      ,<NONE>,                                                'XkbSetXlibControls',                           \
        XkbToControl                            ,<NONE>,                                                'XkbToControl',                                 \
        XkbTranslateKey                         ,<NONE>,                                                'XkbTranslateKey',                              \
        XkbTranslateKeyCode                     ,<NONE>,                                                'XkbTranslateKeyCode',                          \
        XkbTranslateKeySym                      ,<NONE>,                                                'XkbTranslateKeySym',                           \
        XkbUpdateActionVirtualMods              ,<NONE>,                                                'XkbUpdateActionVirtualMods',                   \
        XkbUpdateKeyTypeVirtualMods             ,<NONE>,                                                'XkbUpdateKeyTypeVirtualMods',                  \
        XkbUpdateMapFromCore                    ,<NONE>,                                                'XkbUpdateMapFromCore',                         \
        XkbUseExtension                         ,<NONE>,                                                'XkbUseExtension',                              \
        XkbVirtualModsToReal                    ,<NONE>,                                                'XkbVirtualModsToReal',                         \
        XkbXlibControlsImplemented              ,<NONE>,                                                'XkbXlibControlsImplemented',                   \
        XmbDrawImageString                      ,<NONE>,                                                'XmbDrawImageString',                           \
        XmbDrawString                           ,<NONE>,                                                'XmbDrawString',                                \
        XmbDrawText                             ,<NONE>,                                                'XmbDrawText',                                  \
        XmbLookupString                         ,<NONE>,                                                'XmbLookupString',                              \
        XmbResetIC                              ,<NONE>,                                                'XmbResetIC',                                   \
        XmbSetWMProperties                      ,<NONE>,                                                'XmbSetWMProperties',                           \
        XmbTextEscapement                       ,<NONE>,                                                'XmbTextEscapement',                            \
        XmbTextExtents                          ,<NONE>,                                                'XmbTextExtents',                               \
        XmbTextListToTextProperty               ,<NONE>,                                                'XmbTextListToTextProperty',                    \
        XmbTextPerCharExtents                   ,<NONE>,                                                'XmbTextPerCharExtents',                        \
        XmbTextPropertyToTextList               ,<NONE>,                                                'XmbTextPropertyToTextList',                    \
        Xpermalloc                              ,<NONE>,                                                'Xpermalloc',                                   \
        XrmCombineDatabase                      ,<NONE>,                                                'XrmCombineDatabase',                           \
        XrmCombineFileDatabase                  ,<NONE>,                                                'XrmCombineFileDatabase',                       \
        XrmDestroyDatabase                      ,<NONE>,                                                'XrmDestroyDatabase',                           \
        XrmEnumerateDatabase                    ,<NONE>,                                                'XrmEnumerateDatabase',                         \
        XrmGetDatabase                          ,<NONE>,                                                'XrmGetDatabase',                               \
        XrmGetFileDatabase                      ,<NONE>,                                                'XrmGetFileDatabase',                           \
        XrmGetResource                          ,<NONE>,                                                'XrmGetResource',                               \
        XrmGetStringDatabase                    ,<NONE>,                                                'XrmGetStringDatabase',                         \
        XrmInitialize                           ,<NONE>,                                                'XrmInitialize',                                \
        XrmLocaleOfDatabase                     ,<NONE>,                                                'XrmLocaleOfDatabase',                          \
        XrmMergeDatabases                       ,<NONE>,                                                'XrmMergeDatabases',                            \
        XrmParseCommand                         ,<NONE>,                                                'XrmParseCommand',                              \
        XrmPermStringToQuark                    ,<NONE>,                                                'XrmPermStringToQuark',                         \
        XrmPutFileDatabase                      ,<NONE>,                                                'XrmPutFileDatabase',                           \
        XrmPutLineResource                      ,<NONE>,                                                'XrmPutLineResource',                           \
        XrmPutResource                          ,<NONE>,                                                'XrmPutResource',                               \
        XrmPutStringResource                    ,<NONE>,                                                'XrmPutStringResource',                         \
        XrmQGetResource                         ,<NONE>,                                                'XrmQGetResource',                              \
        XrmQGetSearchList                       ,<NONE>,                                                'XrmQGetSearchList',                            \
        XrmQGetSearchResource                   ,<NONE>,                                                'XrmQGetSearchResource',                        \
        XrmQPutResource                         ,<NONE>,                                                'XrmQPutResource',                              \
        XrmQPutStringResource                   ,<NONE>,                                                'XrmQPutStringResource',                        \
        XrmQuarkToString                        ,<NONE>,                                                'XrmQuarkToString',                             \
        XrmSetDatabase                          ,<NONE>,                                                'XrmSetDatabase',                               \
        XrmStringToBindingQuarkList             ,<NONE>,                                                'XrmStringToBindingQuarkList',                  \
        XrmStringToQuark                        ,<NONE>,                                                'XrmStringToQuark',                             \
        XrmStringToQuarkList                    ,<NONE>,                                                'XrmStringToQuarkList',                         \
        XrmUniqueQuark                          ,<NONE>,                                                'XrmUniqueQuark',                               \
        Xutf8DrawImageString                    ,<NONE>,                                                'Xutf8DrawImageString',                         \
        Xutf8DrawString                         ,<NONE>,                                                'Xutf8DrawString',                              \
        Xutf8DrawText                           ,<NONE>,                                                'Xutf8DrawText',                                \
        Xutf8LookupString                       ,<NONE>,                                                'Xutf8LookupString',                            \
        Xutf8ResetIC                            ,<NONE>,                                                'Xutf8ResetIC',                                 \
        Xutf8SetWMProperties                    ,<NONE>,                                                'Xutf8SetWMProperties',                         \
        Xutf8TextEscapement                     ,<NONE>,                                                'Xutf8TextEscapement',                          \
        Xutf8TextExtents                        ,<NONE>,                                                'Xutf8TextExtents',                             \
        Xutf8TextListToTextProperty             ,<NONE>,                                                'Xutf8TextListToTextProperty',                  \
        Xutf8TextPerCharExtents                 ,<NONE>,                                                'Xutf8TextPerCharExtents',                      \
        Xutf8TextPropertyToTextList             ,<NONE>,                                                'Xutf8TextPropertyToTextList',                  \
        XwcDrawImageString                      ,<NONE>,                                                'XwcDrawImageString',                           \
        XwcDrawString                           ,<NONE>,                                                'XwcDrawString',                                \
        XwcDrawText                             ,<NONE>,                                                'XwcDrawText',                                  \
        XwcFreeStringList                       ,<NONE>,                                                'XwcFreeStringList',                            \
        XwcLookupString                         ,<NONE>,                                                'XwcLookupString',                              \
        XwcResetIC                              ,<NONE>,                                                'XwcResetIC',                                   \
        XwcTextEscapement                       ,<NONE>,                                                'XwcTextEscapement',                            \
        XwcTextExtents                          ,<NONE>,                                                'XwcTextExtents',                               \
        XwcTextListToTextProperty               ,<NONE>,                                                'XwcTextListToTextProperty',                    \
        XwcTextPerCharExtents                   ,<NONE>,                                                'XwcTextPerCharExtents',                        \
        XwcTextPropertyToTextList               ,<NONE>,                                                'XwcTextPropertyToTextList',                    \
        XUniqueContext                          ,<NONE>,                                                'XUniqueContext'




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/imports/Linux/libXft.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: libXft import library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes: Needs editing of the function arguments
;_________________________________________________________________________________________

import_proto  'libXft.so.2',                                    \
    XftCharExists           ,<NONE>, 'XftCharExists',           \
    XftCharFontSpecRender   ,<NONE>, 'XftCharFontSpecRender',   \
    XftCharIndex            ,<NONE>, 'XftCharIndex',            \
    XftCharSpecRender       ,<NONE>, 'XftCharSpecRender',       \
    XftColorAllocName       ,<NONE>, 'XftColorAllocName',       \
    XftColorAllocValue      ,<NONE>, 'XftColorAllocValue',      \
    XftColorFree            ,<NONE>, 'XftColorFree',            \
    XftDefaultHasRender     ,<NONE>, 'XftDefaultHasRender',     \
    XftDefaultSet           ,<NONE>, 'XftDefaultSet',           \
    XftDefaultSubstitute    ,<NONE>, 'XftDefaultSubstitute',    \
    XftDrawChange           ,<NONE>, 'XftDrawChange',           \
    XftDrawCharFontSpec     ,<NONE>, 'XftDrawCharFontSpec',     \
    XftDrawCharSpec         ,<NONE>, 'XftDrawCharSpec',         \
    XftDrawColormap         ,<NONE>, 'XftDrawColormap',         \
    XftDrawCreate           ,<NONE>, 'XftDrawCreate',           \
    XftDrawCreateAlpha      ,<NONE>, 'XftDrawCreateAlpha',      \
    XftDrawCreateBitmap     ,<NONE>, 'XftDrawCreateBitmap',     \
    XftDrawDestroy          ,<NONE>, 'XftDrawDestroy',          \
    XftDrawDisplay          ,<NONE>, 'XftDrawDisplay',          \
    XftDrawDrawable         ,<NONE>, 'XftDrawDrawable',         \
    XftDrawGlyphFontSpec    ,<NONE>, 'XftDrawGlyphFontSpec',    \
    XftDrawGlyphSpec        ,<NONE>, 'XftDrawGlyphSpec',        \
    XftDrawGlyphs           ,<NONE>, 'XftDrawGlyphs',           \
    XftDrawPicture          ,<NONE>, 'XftDrawPicture',          \
    XftDrawRect             ,<NONE>, 'XftDrawRect',             \
    XftDrawSetClip          ,<NONE>, 'XftDrawSetClip',          \
    XftDrawSetClipRectangles,<NONE>, 'XftDrawSetClipRectangles',\
    XftDrawSetSubwindowMode ,<NONE>, 'XftDrawSetSubwindowMode', \
    XftDrawSrcPicture       ,<NONE>, 'XftDrawSrcPicture',       \
    XftDrawString16         ,<NONE>, 'XftDrawString16',         \
    XftDrawString32         ,<NONE>, 'XftDrawString32',         \
    XftDrawString8          ,<NONE>, 'XftDrawString8',          \
    XftDrawStringUtf16      ,<NONE>, 'XftDrawStringUtf16',      \
    XftDrawStringUtf8       ,<NONE>, 'XftDrawStringUtf8',       \
    XftDrawVisual           ,<NONE>, 'XftDrawVisual',           \
    XftFontCheckGlyph       ,<NONE>, 'XftFontCheckGlyph',       \
    XftFontClose            ,<NONE>, 'XftFontClose',            \
    XftFontCopy             ,<NONE>, 'XftFontCopy',             \
    XftFontInfoCreate       ,<NONE>, 'XftFontInfoCreate',       \
    XftFontInfoDestroy      ,<NONE>, 'XftFontInfoDestroy',      \
    XftFontInfoEqual        ,<NONE>, 'XftFontInfoEqual',        \
    XftFontInfoHash         ,<NONE>, 'XftFontInfoHash',         \
    XftFontLoadGlyphs       ,<NONE>, 'XftFontLoadGlyphs',       \
    XftFontMatch            ,<NONE>, 'XftFontMatch',            \
    XftFontOpen             ,<NONE>, 'XftFontOpen',             \
    XftFontOpenInfo         ,<NONE>, 'XftFontOpenInfo',         \
    XftFontOpenName         ,<NONE>, 'XftFontOpenName',         \
    XftFontOpenPattern      ,<NONE>, 'XftFontOpenPattern',      \
    XftFontOpenXlfd         ,<NONE>, 'XftFontOpenXlfd',         \
    XftFontUnloadGlyphs     ,<NONE>, 'XftFontUnloadGlyphs',     \
    XftGetVersion           ,<NONE>, 'XftGetVersion',           \
    XftGlyphExtents         ,<NONE>, 'XftGlyphExtents',         \
    XftGlyphFontSpecRender  ,<NONE>, 'XftGlyphFontSpecRender',  \
    XftGlyphRender          ,<NONE>, 'XftGlyphRender',          \
    XftGlyphSpecRender      ,<NONE>, 'XftGlyphSpecRender',      \
    XftInit                 ,<NONE>, 'XftInit',                 \
    XftInitFtLibrary        ,<NONE>, 'XftInitFtLibrary',        \
    XftListFonts            ,<NONE>, 'XftListFonts',            \
    XftLockFace             ,<NONE>, 'XftLockFace',             \
    XftNameParse            ,<NONE>, 'XftNameParse',            \
    XftNameUnparse          ,<NONE>, 'XftNameUnparse',          \
    XftTextExtents16        ,<NONE>, 'XftTextExtents16',        \
    XftTextExtents32        ,<NONE>, 'XftTextExtents32',        \
    XftTextExtents8         ,<NONE>, 'XftTextExtents8',         \
    XftTextExtentsUtf16     ,<NONE>, 'XftTextExtentsUtf16',     \
    XftTextExtentsUtf8      ,<NONE>, 'XftTextExtentsUtf8',      \
    XftTextRender16         ,<NONE>, 'XftTextRender16',         \
    XftTextRender16BE       ,<NONE>, 'XftTextRender16BE',       \
    XftTextRender16LE       ,<NONE>, 'XftTextRender16LE',       \
    XftTextRender32         ,<NONE>, 'XftTextRender32',         \
    XftTextRender32BE       ,<NONE>, 'XftTextRender32BE',       \
    XftTextRender32LE       ,<NONE>, 'XftTextRender32LE',       \
    XftTextRender8          ,<NONE>, 'XftTextRender8',          \
    XftTextRenderUtf16      ,<NONE>, 'XftTextRenderUtf16',      \
    XftTextRenderUtf8       ,<NONE>, 'XftTextRenderUtf8',       \
    XftUnlockFace           ,<NONE>, 'XftUnlockFace',           \
    XftXlfdParse            ,<NONE>, 'XftXlfdParse'


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































Deleted freshlib/imports/Linux/libc.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: LibC import library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes: Include only small amount of exported functions.
;_________________________________________________________________________________________

import_proto 'libc.so.6',                                                           \ ; LibC
  puts                                    ,<NONE>,                      'puts',     \
  exit                                    ,<.exit_code>,                'exit',     \
  malloc                                  ,<.size>,                     'malloc',   \
  free                                    ,<.ptr>,                      'free',     \
  realloc                                 ,<.ptr, .newsize>,            'realloc',  \
  stime                                   ,<NONE>,                      'stime',    \
  strerror_r                              ,<.errnum, .pBuff, .BufLen>,  'strerror_r'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































Deleted freshlib/imports/Linux/pthreads.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: libpthread (posix threads) import library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes: Needs editing of the function arguments
;_________________________________________________________________________________________

import_proto  'libpthread.so.0',                                                                                         \
fork                              ,<NONE>,                                      'fork',                                  \
longjmp                           ,<NONE>,                                      'longjmp',                               \
pthread_atfork                    ,<NONE>,                                      'pthread_atfork',                        \
pthread_attr_destroy              ,<NONE>,                                      'pthread_attr_destroy',                  \
pthread_attr_getaffinity_np       ,<NONE>,                                      'pthread_attr_getaffinity_np',           \
pthread_attr_getdetachstate       ,<NONE>,                                      'pthread_attr_getdetachstate',           \
pthread_attr_getguardsize         ,<NONE>,                                      'pthread_attr_getguardsize',             \
pthread_attr_getinheritsched      ,<NONE>,                                      'pthread_attr_getinheritsched',          \
pthread_attr_getschedparam        ,<NONE>,                                      'pthread_attr_getschedparam',            \
pthread_attr_getschedpolicy       ,<NONE>,                                      'pthread_attr_getschedpolicy',           \
pthread_attr_getscope             ,<NONE>,                                      'pthread_attr_getscope',                 \
pthread_attr_getstack             ,<NONE>,                                      'pthread_attr_getstack',                 \
pthread_attr_getstackaddr         ,<NONE>,                                      'pthread_attr_getstackaddr',             \
pthread_attr_getstacksize         ,<NONE>,                                      'pthread_attr_getstacksize',             \
pthread_attr_init                 ,<NONE>,                                      'pthread_attr_init',                     \
pthread_attr_setaffinity_np       ,<NONE>,                                      'pthread_attr_setaffinity_np',           \
pthread_attr_setdetachstate       ,<NONE>,                                      'pthread_attr_setdetachstate',           \
pthread_attr_setguardsize         ,<NONE>,                                      'pthread_attr_setguardsize',             \
pthread_attr_setinheritsched      ,<NONE>,                                      'pthread_attr_setinheritsched',          \
pthread_attr_setschedparam        ,<NONE>,                                      'pthread_attr_setschedparam',            \
pthread_attr_setschedpolicy       ,<NONE>,                                      'pthread_attr_setschedpolicy',           \
pthread_attr_setscope             ,<NONE>,                                      'pthread_attr_setscope',                 \
pthread_attr_setstack             ,<NONE>,                                      'pthread_attr_setstack',                 \
pthread_attr_setstackaddr         ,<NONE>,                                      'pthread_attr_setstackaddr',             \
pthread_attr_setstacksize         ,<NONE>,                                      'pthread_attr_setstacksize',             \
pthread_barrier_destroy           ,<NONE>,                                      'pthread_barrier_destroy',               \
pthread_barrier_init              ,<NONE>,                                      'pthread_barrier_init',                  \
pthread_barrier_wait              ,<NONE>,                                      'pthread_barrier_wait',                  \
pthread_barrierattr_destroy       ,<NONE>,                                      'pthread_barrierattr_destroy',           \
pthread_barrierattr_getpshared    ,<NONE>,                                      'pthread_barrierattr_getpshared',        \
pthread_barrierattr_init          ,<NONE>,                                      'pthread_barrierattr_init',              \
pthread_barrierattr_setpshared    ,<NONE>,                                      'pthread_barrierattr_setpshared',        \
pthread_cancel                    ,<NONE>,                                      'pthread_cancel',                        \
pthread_cond_broadcast            ,<NONE>,                                      'pthread_cond_broadcast',                \
pthread_cond_destroy              ,<NONE>,                                      'pthread_cond_destroy',                  \
pthread_cond_init                 ,<NONE>,                                      'pthread_cond_init',                     \
pthread_cond_signal               ,<NONE>,                                      'pthread_cond_signal',                   \
pthread_cond_timedwait            ,<NONE>,                                      'pthread_cond_timedwait',                \
pthread_cond_wait                 ,<NONE>,                                      'pthread_cond_wait',                     \
pthread_condattr_destroy          ,<NONE>,                                      'pthread_condattr_destroy',              \
pthread_condattr_getclock         ,<NONE>,                                      'pthread_condattr_getclock',             \
pthread_condattr_getpshared       ,<NONE>,                                      'pthread_condattr_getpshared',           \
pthread_condattr_init             ,<NONE>,                                      'pthread_condattr_init',                 \
pthread_condattr_setclock         ,<NONE>,                                      'pthread_condattr_setclock',             \
pthread_condattr_setpshared       ,<NONE>,                                      'pthread_condattr_setpshared',           \
pthread_create                    ,<.pThreadID, .attr, .pThreadProc, .argument>,'pthread_create',                        \
pthread_detach                    ,<NONE>,                                      'pthread_detach',                        \
pthread_equal                     ,<NONE>,                                      'pthread_equal',                         \
pthread_exit                      ,<NONE>,                                      'pthread_exit',                          \
pthread_getaffinity_np            ,<NONE>,                                      'pthread_getaffinity_np',                \
pthread_getattr_np                ,<NONE>,                                      'pthread_getattr_np',                    \
pthread_getconcurrency            ,<NONE>,                                      'pthread_getconcurrency',                \
pthread_getcpuclockid             ,<NONE>,                                      'pthread_getcpuclockid',                 \
pthread_getschedparam             ,<NONE>,                                      'pthread_getschedparam',                 \
pthread_getspecific               ,<NONE>,                                      'pthread_getspecific',                   \
pthread_join                      ,<NONE>,                                      'pthread_join',                          \
pthread_key_create                ,<NONE>,                                      'pthread_key_create',                    \
pthread_key_delete                ,<NONE>,                                      'pthread_key_delete',                    \
pthread_kill                      ,<.ThreadID, .signal>,                        'pthread_kill',                          \
pthread_kill_other_threads_np     ,<NONE>,                                      'pthread_kill_other_threads_np',         \
pthread_mutex_consistent_np       ,<NONE>,                                      'pthread_mutex_consistent_np',           \
pthread_mutex_destroy             ,<.pMutex>,                                   'pthread_mutex_destroy',                 \
pthread_mutex_getprioceiling      ,<NONE>,                                      'pthread_mutex_getprioceiling',          \
pthread_mutex_init                ,<.pMutex, .pAttr>,                           'pthread_mutex_init',                    \
pthread_mutex_lock                ,<.pMutex>,                                   'pthread_mutex_lock',                    \
pthread_mutex_setprioceiling      ,<NONE>,                                      'pthread_mutex_setprioceiling',          \
pthread_mutex_timedlock           ,<.pMutex, .pTimeout>,                        'pthread_mutex_timedlock',               \
pthread_mutex_trylock             ,<.pMutex>,                                   'pthread_mutex_trylock',                 \
pthread_mutex_unlock              ,<.pMutex>,                                   'pthread_mutex_unlock',                  \
pthread_mutexattr_destroy         ,<.pAttr>,                                    'pthread_mutexattr_destroy',             \
pthread_mutexattr_getkind_np      ,<NONE>,                                      'pthread_mutexattr_getkind_np',          \
pthread_mutexattr_getprioceiling  ,<NONE>,                                      'pthread_mutexattr_getprioceiling',      \
pthread_mutexattr_getprotocol     ,<NONE>,                                      'pthread_mutexattr_getprotocol',         \
pthread_mutexattr_getpshared      ,<NONE>,                                      'pthread_mutexattr_getpshared',          \
pthread_mutexattr_getrobust_np    ,<NONE>,                                      'pthread_mutexattr_getrobust_np',        \
pthread_mutexattr_gettype         ,<NONE>,                                      'pthread_mutexattr_gettype',             \
pthread_mutexattr_init            ,<.pAttr>,                                    'pthread_mutexattr_init',                \
pthread_mutexattr_setkind_np      ,<NONE>,                                      'pthread_mutexattr_setkind_np',          \
pthread_mutexattr_setprioceiling  ,<NONE>,                                      'pthread_mutexattr_setprioceiling',      \
pthread_mutexattr_setprotocol     ,<NONE>,                                      'pthread_mutexattr_setprotocol',         \
pthread_mutexattr_setpshared      ,<NONE>,                                      'pthread_mutexattr_setpshared',          \
pthread_mutexattr_setrobust_np    ,<NONE>,                                      'pthread_mutexattr_setrobust_np',        \
pthread_mutexattr_settype         ,<NONE>,                                      'pthread_mutexattr_settype',             \
pthread_once                      ,<NONE>,                                      'pthread_once',                          \
pthread_rwlock_destroy            ,<NONE>,                                      'pthread_rwlock_destroy',                \
pthread_rwlock_init               ,<NONE>,                                      'pthread_rwlock_init',                   \
pthread_rwlock_rdlock             ,<NONE>,                                      'pthread_rwlock_rdlock',                 \
pthread_rwlock_timedrdlock        ,<NONE>,                                      'pthread_rwlock_timedrdlock',            \
pthread_rwlock_timedwrlock        ,<NONE>,                                      'pthread_rwlock_timedwrlock',            \
pthread_rwlock_tryrdlock          ,<NONE>,                                      'pthread_rwlock_tryrdlock',              \
pthread_rwlock_trywrlock          ,<NONE>,                                      'pthread_rwlock_trywrlock',              \
pthread_rwlock_unlock             ,<NONE>,                                      'pthread_rwlock_unlock',                 \
pthread_rwlock_wrlock             ,<NONE>,                                      'pthread_rwlock_wrlock',                 \
pthread_rwlockattr_destroy        ,<NONE>,                                      'pthread_rwlockattr_destroy',            \
pthread_rwlockattr_getkind_np     ,<NONE>,                                      'pthread_rwlockattr_getkind_np',         \
pthread_rwlockattr_getpshared     ,<NONE>,                                      'pthread_rwlockattr_getpshared',         \
pthread_rwlockattr_init           ,<NONE>,                                      'pthread_rwlockattr_init',               \
pthread_rwlockattr_setkind_np     ,<NONE>,                                      'pthread_rwlockattr_setkind_np',         \
pthread_rwlockattr_setpshared     ,<NONE>,                                      'pthread_rwlockattr_setpshared',         \
pthread_self                      ,<NONE>,                                      'pthread_self',                          \
pthread_setaffinity_np            ,<NONE>,                                      'pthread_setaffinity_np',                \
pthread_setcancelstate            ,<NONE>,                                      'pthread_setcancelstate',                \
pthread_setcanceltype             ,<NONE>,                                      'pthread_setcanceltype',                 \
pthread_setconcurrency            ,<NONE>,                                      'pthread_setconcurrency',                \
pthread_setschedparam             ,<NONE>,                                      'pthread_setschedparam',                 \
pthread_setschedprio              ,<NONE>,                                      'pthread_setschedprio',                  \
pthread_setspecific               ,<NONE>,                                      'pthread_setspecific',                   \
pthread_sigmask                   ,<NONE>,                                      'pthread_sigmask',                       \
pthread_spin_destroy              ,<NONE>,                                      'pthread_spin_destroy',                  \
pthread_spin_init                 ,<NONE>,                                      'pthread_spin_init',                     \
pthread_spin_lock                 ,<NONE>,                                      'pthread_spin_lock',                     \
pthread_spin_trylock              ,<NONE>,                                      'pthread_spin_trylock',                  \
pthread_spin_unlock               ,<NONE>,                                      'pthread_spin_unlock',                   \
pthread_testcancel                ,<NONE>,                                      'pthread_testcancel',                    \
pthread_timedjoin_np              ,<NONE>,                                      'pthread_timedjoin_np',                  \
pthread_tryjoin_np                ,<NONE>,                                      'pthread_tryjoin_np',                    \
pthread_yield                     ,<NONE>,                                      'pthread_yield',                         \
pwrite                            ,<NONE>,                                      'pwrite',                                \
pwrite64                          ,<NONE>,                                      'pwrite64',                              \
raise                             ,<NONE>,                                      'raise',                                 \
read                              ,<NONE>,                                      'read',                                  \
recv                              ,<NONE>,                                      'recv',                                  \
recvfrom                          ,<NONE>,                                      'recvfrom',                              \
recvmsg                           ,<NONE>,                                      'recvmsg',                               \
sem_close                         ,<NONE>,                                      'sem_close',                             \
sem_destroy                       ,<NONE>,                                      'sem_destroy',                           \
sem_getvalue                      ,<NONE>,                                      'sem_getvalue',                          \
sem_init                          ,<NONE>,                                      'sem_init',                              \
sem_open                          ,<NONE>,                                      'sem_open',                              \
sem_post                          ,<NONE>,                                      'sem_post',                              \
sem_timedwait                     ,<NONE>,                                      'sem_timedwait',                         \
sem_trywait                       ,<NONE>,                                      'sem_trywait',                           \
sem_unlink                        ,<NONE>,                                      'sem_unlink',                            \
sem_wait                          ,<NONE>,                                      'sem_wait',                              \
send                              ,<NONE>,                                      'send',                                  \
sendmsg                           ,<NONE>,                                      'sendmsg',                               \
sendto                            ,<NONE>,                                      'sendto',                                \
sigaction                         ,<NONE>,                                      'sigaction',                             \
siglongjmp                        ,<NONE>,                                      'siglongjmp',                            \
sigwait                           ,<NONE>,                                      'sigwait',                               \
system                            ,<NONE>,                                      'system',                                \
tcdrain                           ,<NONE>,                                      'tcdrain',                               \
vfork                             ,<NONE>,                                      'vfork',                                 \
waitpid                           ,<NONE>,                                      'waitpid',                               \
write                             ,<NONE>,                                      'write'



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































Deleted freshlib/imports/Win32/advapi32.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: advapi32.dll API functions.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

;   advapi32.dll API calls (ASCII)
import_proto advapi32,  \
    A_SHAFinal, <NONE>,  'A_SHAFinal',  \
    A_SHAInit, <NONE>,  'A_SHAInit',  \
    A_SHAUpdate, <NONE>,  'A_SHAUpdate',  \
    AbortSystemShutdownA, <.lpMachineName>,  'AbortSystemShutdownA',  \
    AbortSystemShutdownW, <.lpMachineName>,  'AbortSystemShutdownW',  \
    AccessCheck, <.pSecurityDescriptor, .ClientToken, .DesiredAccess, .GenericMapping, .PrivilegeSet, .PrivilegeSetLength, .GrantedAccess,  \
        .Status>,  'AccessCheck',  \
    AccessCheckAndAuditAlarmA, <.SubsystemName, .HandleId, .ObjectTypeName, .ObjectName, .SecurityDescriptor, .DesiredAccess, .GenericMapping,  \
        .ObjectCreation, .GrantedAccess, .AccessStatus, .pfGenerateOnClose>,  'AccessCheckAndAuditAlarmA',  \
    AccessCheckAndAuditAlarmW, <.SubsystemName, .HandleId, .ObjectTypeName, .ObjectName, .SecurityDescriptor, .DesiredAccess, .GenericMapping,  \
        .ObjectCreation, .GrantedAccess, .AccessStatus, .pfGenerateOnClose>,  'AccessCheckAndAuditAlarmW',  \
    AccessCheckByType, <.pSecurityDescriptor, .PrincipalSelfSid, .ClientToken, .DesiredAccess, .ObjectTypeList, .ObjectTypeListLength,  \
        .GenericMapping, .PrivilegeSet, .PrivilegeSetLength, .GrantedAccess, .AccessStatus>,  'AccessCheckByType',  \
    AccessCheckByTypeAndAuditAlarmA, <.SubsystemName, .HandleId, .ObjectTypeName, .ObjectName, .SecurityDescriptor, .PrincipalSelfSid,  \
        .DesiredAccess, .AuditType, .Flags, .ObjectTypeList, .ObjectTypeListLength, .GenericMapping, .ObjectCreation, .GrantedAccess,  \
        .AccessStatus, .pfGenerateOnClose>,  'AccessCheckByTypeAndAuditAlarmA',  \
    AccessCheckByTypeAndAuditAlarmW, <.SubsystemName, .HandleId, .ObjectTypeName, .ObjectName, .SecurityDescriptor, .PrincipalSelfSid,  \
        .DesiredAccess, .AuditType, .Flags, .ObjectTypeList, .ObjectTypeListLength, .GenericMapping, .ObjectCreation, .GrantedAccess,  \
        .AccessStatus, .pfGenerateOnClose>,  'AccessCheckByTypeAndAuditAlarmW',  \
    AccessCheckByTypeResultList, <.pSecurityDescriptor, .PrincipalSelfSid, .ClientToken, .DesiredAccess, .ObjectTypeList, .ObjectTypeListLength,  \
        .GenericMapping, .PrivilegeSet, .PrivilegeSetLength, .GrantedAccessList, .AccessStatusList>,  'AccessCheckByTypeResultList',  \
    AccessCheckByTypeResultListAndAuditAlarmA, <.SubsystemName, .HandleId, .ObjectTypeName, .ObjectName, .SecurityDescriptor, .PrincipalSelfSid,  \
        .DesiredAccess, .AuditType, .Flags, .ObjectTypeList, .ObjectTypeListLength, .GenericMapping, .ObjectCreation, .GrantedAccess,  \
        .AccessStatusList, .pfG>,  'AccessCheckByTypeResultListAndAuditAlarmA',  \
    AccessCheckByTypeResultListAndAuditAlarmByHandleA, <.SubsystemName, .HandleId, .ClientToken, .ObjectTypeName, .ObjectName, .SecurityDescriptor,  \
        .PrincipalSelfSid, .DesiredAccess, .AuditType, .flags, .ObjectTypeList, .ObjectTypeListLength, .GenericMapping, .ObjectCreation,  \
        .GrantedAccess, .AccessibleChildren, .paccContainer, .iChildStart, .cChildren, .rgvarChildren, .pcObtained>,  'AccessCheckByTypeResultListAndAuditAlarmByHandleA',  \
    AccessCheckByTypeResultListAndAuditAlarmByHandleW, <.SubsystemName, .HandleId, .ClientToken, .ObjectTypeName, .ObjectName, .SecurityDescriptor,  \
        .PrincipalSelfSid, .DesiredAccess, .AuditType, .flags, .ObjectTypeList, .ObjectTypeListLength, .GenericMapping, .ObjectCreation,  \
        .GrantedAccess, .AccessibleChildren, .paccContainer, .iChildStart, .cChildren, .rgvarChildren, .pcObtained>,  'AccessCheckByTypeResultListAndAuditAlarmByHandleW',  \
    AccessCheckByTypeResultListAndAuditAlarmW, <.SubsystemName, .HandleId, .ObjectTypeName, .ObjectName, .SecurityDescriptor, .PrincipalSelfSid,  \
        .DesiredAccess, .AuditType, .Flags, .ObjectTypeList, .ObjectTypeListLength, .GenericMapping, .ObjectCreation, .GrantedAccess,  \
        .AccessStatusList, .pfG>,  'AccessCheckByTypeResultListAndAuditAlarmW',  \
    AddAccessAllowedAce, <.pAcl, .dwAceRevision, .AccessMask, .pSid>,  'AddAccessAllowedAce',  \
    AddAccessAllowedAceEx, <.pAcl, .dwAceRevision, .AceFlags, .AccessMask, .pSid>,  'AddAccessAllowedAceEx',  \
    AddAccessAllowedObjectAce, <.pAcl, .dwAceRevision, .AceFlags, .AccessMask, .ObjectTypeGuid, .ByRefheritedObjectTypeGuid, .pSid,  \
      >,  'AddAccessAllowedObjectAce',  \
    AddAccessDeniedAce, <.pAcl, .dwAceRevision, .AccessMask, .pSid>,  'AddAccessDeniedAce',  \
    AddAccessDeniedAceEx, <.pAcl, .dwAceRevision, .AceFlags, .AccessMask, .pSid>,  'AddAccessDeniedAceEx',  \
    AddAccessDeniedObjectAce, <.pAcl, .dwAceRevision, .AceFlags, .AccessMask, .ObjectTypeGuid, .ByRefheritedObjectTypeGuid, .pSid,  \
      >,  'AddAccessDeniedObjectAce',  \
    AddAce, <.pAcl, .dwAceRevision, .dwStartingAceIndex, .pAceList, .nAceListLength>,  'AddAce',  \
    AddAuditAccessAce, <.pAcl, .dwAceRevision, .dwAccessMask, .pSid, .bAuditSuccess, .bAuditFailure>,  'AddAuditAccessAce',  \
    AddAuditAccessAceEx, <.pAcl, .dwAceRevision, .AceFlags, .dwAccessMask, .pSid, .bAuditSuccess, .bAuditFailure>,  'AddAuditAccessAceEx',  \
    AddAuditAccessObjectAce, <.pAcl, .dwAceRevision, .AceFlags, .AccessMask, .ObjectTypeGuid, .ByRefheritedObjectTypeGuid, .pSid, .bAuditSuccess,  \
        .bAuditFailure>,  'AddAuditAccessObjectAce',  \
    AddUsersToEncryptedFile, <.lpFileName, .pUsers>,  'AddUsersToEncryptedFile',  \
    AdjustTokenGroups, <.TokenHandle, .ResetToDefault, .NewState, .BufferLength, .PreviousState, .ReturnLength>,  'AdjustTokenGroups',  \
    AdjustTokenPrivileges, <.TokenHandle, .DisableAllPrivileges, .NewState, .BufferLength, .PreviousState, .ReturnLength>,  'AdjustTokenPrivileges',  \
    AllocateAndInitializeSid, <.pIdentifierAuthority, .nSubAuthorityCount, .nSubAuthority0, .nSubAuthority1, .nSubAuthority2, .nSubAuthority3,  \
        .nSubAuthority4, .nSubAuthority5, .nSubAuthority6, .nSubAuthority7, .lpPSid>,  'AllocateAndInitializeSid',  \
    AllocateLocallyUniqueId, <.Luid>,  'AllocateLocallyUniqueId',  \
    AreAllAccessesGranted, <.GrantedAccess, .DesiredAccess>,  'AreAllAccessesGranted',  \
    AreAnyAccessesGranted, <.GrantedAccess, .DesiredAccess>,  'AreAnyAccessesGranted',  \
    BackupEventLogA, <.hEventLog, .lpBackupFileName>,  'BackupEventLogA',  \
    BackupEventLogW, <.hEventLog, .lpBackupFileName>,  'BackupEventLogW',  \
    BuildExplicitAccessWithNameA, <.pExplicitAccess, .pTrusteeName, .AccessPermissions, .AccessMode, .Inheritance>,  'BuildExplicitAccessWithNameA',  \
    BuildExplicitAccessWithNameW, <.pExplicitAccess, .pTrusteeName, .AccessPermissions, .AccessMode, .Inheritance>,  'BuildExplicitAccessWithNameW',  \
    BuildImpersonateExplicitAccessWithNameA, <.pExplicitAccess, .pTrusteeName, .pTrustee, .AccessPermissions, .AccessMode, .Inheritance,  \
      >,  'BuildImpersonateExplicitAccessWithNameA',  \
    BuildImpersonateExplicitAccessWithNameW, <.pExplicitAccess, .pTrusteeName, .pTrustee, .AccessPermissions, .AccessMode, .Inheritance,  \
      >,  'BuildImpersonateExplicitAccessWithNameW',  \
    BuildImpersonateTrusteeA, <.pTrustee, .pImpersonateTrustee>,  'BuildImpersonateTrusteeA',  \
    BuildImpersonateTrusteeW, <.pTrustee, .pImpersonateTrustee>,  'BuildImpersonateTrusteeW',  \
    BuildSecurityDescriptorA, <.pOwner, .pGroup, .cCountOfAccessEntries, .pListOfAccessEntries, .cCountOfAuditEntries, .pListOfAuditEntries,  \
        .pOldSD, .pSizeNewSD, .pNewSD>,  'BuildSecurityDescriptorA',  \
    BuildSecurityDescriptorW, <.pOwner, .pGroup, .cCountOfAccessEntries, .pListOfAccessEntries, .cCountOfAuditEntries, .pListOfAuditEntries,  \
        .pOldSD, .pSizeNewSD, .pNewSD>,  'BuildSecurityDescriptorW',  \
    BuildTrusteeWithNameA, <.pTrustee, .pname>,  'BuildTrusteeWithNameA',  \
    BuildTrusteeWithNameW, <.pTrustee, .pname>,  'BuildTrusteeWithNameW',  \
    BuildTrusteeWithObjectsAndNameA, <.pTrustee, .pObjName, .ObjectType, .ObjectTypeName, .InheritedObjectTypeName, .name>,  'BuildTrusteeWithObjectsAndNameA',  \
    BuildTrusteeWithObjectsAndNameW, <.pTrustee, .pObjName, .ObjectType, .ObjectTypeName, .InheritedObjectTypeName, .name>,  'BuildTrusteeWithObjectsAndNameW',  \
    BuildTrusteeWithObjectsAndSidA, <.pTrustee, .pObjSid, .pObjectGuid, .pInheritedObjectGuid, .pSid>,  'BuildTrusteeWithObjectsAndSidA',  \
    BuildTrusteeWithObjectsAndSidW, <.pTrustee, .pObjSid, .pObjectGuid, .pInheritedObjectGuid, .pSid>,  'BuildTrusteeWithObjectsAndSidW',  \
    BuildTrusteeWithSidA, <.pTrustee, .pSid>,  'BuildTrusteeWithSidA',  \
    BuildTrusteeWithSidW, <.pTrustee, .pSid>,  'BuildTrusteeWithSidW',  \
    CancelOverlappedAccess, <NONE>,  'CancelOverlappedAccess',  \
    ChangeServiceConfig2A, <.hService, .dwInfoLevel, .lpInfo>,  'ChangeServiceConfig2A',  \
    ChangeServiceConfig2W, <.hService, .dwInfoLevel, .lpInfo>,  'ChangeServiceConfig2W',  \
    ChangeServiceConfigA, <.hService, .dwServiceType, .dwStartType, .dwErrorControl, .lpBinaryPathName, .lpLoadOrderGroup, .lpdwTagId,  \
        .lpDependencies, .lpServiceStartName, .lpPassword, .lpDisplayName>,  'ChangeServiceConfigA',  \
    ChangeServiceConfigW, <.hService, .dwServiceType, .dwStartType, .dwErrorControl, .lpBinaryPathName, .lpLoadOrderGroup, .lpdwTagId,  \
        .lpDependencies, .lpServiceStartName, .lpPassword, .lpDisplayName>,  'ChangeServiceConfigW',  \
    CheckTokenMembership, <.TokenHandle, .SidToCheck, .IsMember>,  'CheckTokenMembership',  \
    ClearEventLogA, <.hEventLog, .lpBackupFileName>,  'ClearEventLogA',  \
    ClearEventLogW, <.hEventLog, .lpBackupFileName>,  'ClearEventLogW',  \
    CloseCodeAuthzLevel, <NONE>,  'CloseCodeAuthzLevel',  \
    CloseEncryptedFileRaw, <.pvContext>,  'CloseEncryptedFileRaw',  \
    CloseEventLog, <.hEventLog>,  'CloseEventLog',  \
    CloseServiceHandle, <.hSCObject>,  'CloseServiceHandle',  \
    CloseTrace, <NONE>,  'CloseTrace',  \
    CommandLineFromMsiDescriptor, <NONE>,  'CommandLineFromMsiDescriptor',  \
    ComputeAccessTokenFromCodeAuthzLevel, <NONE>,  'ComputeAccessTokenFromCodeAuthzLevel',  \
    ControlService, <.hService, .dwControl, .lpServiceStatus>,  'ControlService',  \
    ControlTraceA, <NONE>,  'ControlTraceA',  \
    ControlTraceW, <NONE>,  'ControlTraceW',  \
    ConvertAccessToSecurityDescriptorA, <NONE>,  'ConvertAccessToSecurityDescriptorA',  \
    ConvertAccessToSecurityDescriptorW, <NONE>,  'ConvertAccessToSecurityDescriptorW',  \
    ConvertSDToStringSDRootDomainA, <NONE>,  'ConvertSDToStringSDRootDomainA',  \
    ConvertSDToStringSDRootDomainW, <NONE>,  'ConvertSDToStringSDRootDomainW',  \
    ConvertSecurityDescriptorToAccessA, <NONE>,  'ConvertSecurityDescriptorToAccessA',  \
    ConvertSecurityDescriptorToAccessNamedA, <NONE>,  'ConvertSecurityDescriptorToAccessNamedA',  \
    ConvertSecurityDescriptorToAccessNamedW, <NONE>,  'ConvertSecurityDescriptorToAccessNamedW',  \
    ConvertSecurityDescriptorToAccessW, <NONE>,  'ConvertSecurityDescriptorToAccessW',  \
    ConvertSecurityDescriptorToStringSecurityDescriptorA, <.SecurityDescriptor, .RequestedStringSDRevision, .SecurityInformation, .StringSecurityDescriptor,  \
        .StringSecurityDescriptorLen>,  'ConvertSecurityDescriptorToStringSecurityDescriptorA',  \
    ConvertSecurityDescriptorToStringSecurityDescriptorW, <.SecurityDescriptor, .RequestedStringSDRevision, .SecurityInformation, .StringSecurityDescriptor,  \
        .StringSecurityDescriptorLen>,  'ConvertSecurityDescriptorToStringSecurityDescriptorW',  \
    ConvertSidToStringSidA, <.Sid, .StringSid>,  'ConvertSidToStringSidA',  \
    ConvertSidToStringSidW, <.Sid, .StringSid>,  'ConvertSidToStringSidW',  \
    ConvertStringSDToSDDomainA, <NONE>,  'ConvertStringSDToSDDomainA',  \
    ConvertStringSDToSDDomainW, <NONE>,  'ConvertStringSDToSDDomainW',  \
    ConvertStringSDToSDRootDomainA, <NONE>,  'ConvertStringSDToSDRootDomainA',  \
    ConvertStringSDToSDRootDomainW, <NONE>,  'ConvertStringSDToSDRootDomainW',  \
    ConvertStringSecurityDescriptorToSecurityDescriptorA, <.StringSecurityDescriptor, .StringSDRevision, .SecurityDescriptor, .SecurityDescriptorSize,  \
      >,  'ConvertStringSecurityDescriptorToSecurityDescriptorA',  \
    ConvertStringSecurityDescriptorToSecurityDescriptorW, <.StringSecurityDescriptor, .StringSDRevision, .SecurityDescriptor, .SecurityDescriptorSize,  \
      >,  'ConvertStringSecurityDescriptorToSecurityDescriptorW',  \
    ConvertStringSidToSidA, <.StringSid, .Sid>,  'ConvertStringSidToSidA',  \
    ConvertStringSidToSidW, <.StringSid, .Sid>,  'ConvertStringSidToSidW',  \
    ConvertToAutoInheritPrivateObjectSecurity, <.ParentDescriptor, .CurrentSecurityDescriptor, .NewSecurityDescriptor, .ObjectType,  \
        .IsDirectoryObject, .GenericMapping>,  'ConvertToAutoInheritPrivateObjectSecurity',  \
    CopySid, <.nDestinationSidLength, .pDestinationSid, .pSourceSid>,  'CopySid',  \
    CreateCodeAuthzLevel, <NONE>,  'CreateCodeAuthzLevel',  \
    CreatePrivateObjectSecurity, <.ParentDescriptor, .CreatorDescriptor, .NewDescriptor, .IsDirectoryObject, .Token, .GenericMapping,  \
      >,  'CreatePrivateObjectSecurity',  \
    CreatePrivateObjectSecurityEx, <.ParentDescriptor, .CreatorDescriptor, .NewDescriptor, .ObjectType, .IsContainerObject, .AutoInheritFlags,  \
        .Token, .GenericMapping>,  'CreatePrivateObjectSecurityEx',  \
    CreatePrivateObjectSecurityWithMultipleInheritance, <NONE>,  'CreatePrivateObjectSecurityWithMultipleInheritance',  \
    CreateProcessAsUserA, <.hToken, .lpApplicationName, .lpCommandLine, .lpProcessAttributes, .lpThreadAttributes, .bInheritHandles,  \
        .dwCreationFlags, .lpEnvironment, .lpCurrentDirectory, .lpStartupInfo, .lpProcessInformation>,  'CreateProcessAsUserA',  \
    CreateProcessAsUserSecure, <NONE>,  'CreateProcessAsUserSecure',  \
    CreateProcessAsUserW, <.hToken, .lpApplicationName, .lpCommandLine, .lpProcessAttributes, .lpThreadAttributes, .bInheritHandles,  \
        .dwCreationFlags, .lpEnvironment, .lpCurrentDirectory, .lpStartupInfo, .lpProcessInformation>,  'CreateProcessAsUserW',  \
    CreateProcessWithLogonW, <NONE>,  'CreateProcessWithLogonW',  \
    CreateRestrictedToken, <.ExistingTokenHandle, .Flags, .DisableSidCount, .SidsToDisable, .DeletePrivilegeCount, .PrivilegesToDelete,  \
        .RestrictedSidCount, .SidsToRestrict, .NewTokenHandle>,  'CreateRestrictedToken',  \
    CreateServiceA, <.hSCManager, .lpServiceName, .lpDisplayName, .dwDesiredAccess, .dwServiceType, .dwStartType, .dwErrorControl,  \
        .lpBinaryPathName, .lpLoadOrderGroup, .lpdwTagId, .lpDependencies, .lp, .lpPassword>,  'CreateServiceA',  \
    CreateServiceW, <.hSCManager, .lpServiceName, .lpDisplayName, .dwDesiredAccess, .dwServiceType, .dwStartType, .dwErrorControl,  \
        .lpBinaryPathName, .lpLoadOrderGroup, .lpdwTagId, .lpDependencies, .lp, .lpPassword>,  'CreateServiceW',  \
    CreateTraceInstanceId, <NONE>,  'CreateTraceInstanceId',  \
    CreateWellKnownSid, <NONE>,  'CreateWellKnownSid',  \
    CredDeleteA, <NONE>,  'CredDeleteA',  \
    CredDeleteW, <NONE>,  'CredDeleteW',  \
    CredEnumerateA, <NONE>,  'CredEnumerateA',  \
    CredEnumerateW, <NONE>,  'CredEnumerateW',  \
    CredFree, <NONE>,  'CredFree',  \
    CredGetSessionTypes, <NONE>,  'CredGetSessionTypes',  \
    CredGetTargetInfoA, <NONE>,  'CredGetTargetInfoA',  \
    CredGetTargetInfoW, <NONE>,  'CredGetTargetInfoW',  \
    CredIsMarshaledCredentialA, <NONE>,  'CredIsMarshaledCredentialA',  \
    CredIsMarshaledCredentialW, <NONE>,  'CredIsMarshaledCredentialW',  \
    CredMarshalCredentialA, <NONE>,  'CredMarshalCredentialA',  \
    CredMarshalCredentialW, <NONE>,  'CredMarshalCredentialW',  \
    CredProfileLoaded, <NONE>,  'CredProfileLoaded',  \
    CredReadA, <NONE>,  'CredReadA',  \
    CredReadDomainCredentialsA, <NONE>,  'CredReadDomainCredentialsA',  \
    CredReadDomainCredentialsW, <NONE>,  'CredReadDomainCredentialsW',  \
    CredReadW, <NONE>,  'CredReadW',  \
    CredRenameA, <NONE>,  'CredRenameA',  \
    CredRenameW, <NONE>,  'CredRenameW',  \
    CredUnmarshalCredentialA, <NONE>,  'CredUnmarshalCredentialA',  \
    CredUnmarshalCredentialW, <NONE>,  'CredUnmarshalCredentialW',  \
    CredWriteA, <NONE>,  'CredWriteA',  \
    CredWriteDomainCredentialsA, <NONE>,  'CredWriteDomainCredentialsA',  \
    CredWriteDomainCredentialsW, <NONE>,  'CredWriteDomainCredentialsW',  \
    CredWriteW, <NONE>,  'CredWriteW',  \
    CredpConvertCredential, <NONE>,  'CredpConvertCredential',  \
    CredpConvertTargetInfo, <NONE>,  'CredpConvertTargetInfo',  \
    CredpDecodeCredential, <NONE>,  'CredpDecodeCredential',  \
    CredpEncodeCredential, <NONE>,  'CredpEncodeCredential',  \
    CryptAcquireContextA, <.phProv, .pszContainer, .pszProvider, .dwProvType, .dwFlags>,  'CryptAcquireContextA',  \
    CryptAcquireContextW, <.phProv, .pszContainer, .pszProvider, .dwProvType, .dwFlags>,  'CryptAcquireContextW',  \
    CryptContextAddRef, <.hProv, .pdwReserved, .dwFlags>,  'CryptContextAddRef',  \
    CryptCreateHash, <.hProv, .Algid, .hKey, .dwFlags, .phHash>,  'CryptCreateHash',  \
    CryptDecrypt, <.hKey, .hHash, .Final, .dwFlags, .pbData, .pdwDataLen>,  'CryptDecrypt',  \
    CryptDeriveKey, <.hProv, .Algid, .hBaseData, .dwFlags, .phKey>,  'CryptDeriveKey',  \
    CryptDestroyHash, <.hHash>,  'CryptDestroyHash',  \
    CryptDestroyKey, <.hKey>,  'CryptDestroyKey',  \
    CryptDuplicateHash, <.hHash, .pdwReserved, .dwFlags, .phHash>,  'CryptDuplicateHash',  \
    CryptDuplicateKey, <.hKey, .pdwReserved, .dwFlags, .phKey>,  'CryptDuplicateKey',  \
    CryptEncrypt, <.hKey, .hHash, .Final, .dwFlags, .pbData, .pdwDataLen, .dwBufLen>,  'CryptEncrypt',  \
    CryptEnumProviderTypesA, <.dwIndex, .pdwReserved, .dwFlags, .pdwProvType, .pszTypeName, .pcbTypeName>,  'CryptEnumProviderTypesA',  \
    CryptEnumProviderTypesW, <.dwIndex, .pdwReserved, .dwFlags, .pdwProvType, .pszTypeName, .pcbTypeName>,  'CryptEnumProviderTypesW',  \
    CryptEnumProvidersA, <.dwIndex, .pdwReserved, .dwFlags, .pdwProvType, .pszProvName, .pcbProvName>,  'CryptEnumProvidersA',  \
    CryptEnumProvidersW, <.dwIndex, .pdwReserved, .dwFlags, .pdwProvType, .pszProvName, .pcbProvName>,  'CryptEnumProvidersW',  \
    CryptExportKey, <.hKey, .hExpKey, .dwBlobType, .dwFlags, .pbData, .pdwDataLen>,  'CryptExportKey',  \
    CryptGenKey, <.hProv, .Algid, .dwFlags, .phKey>,  'CryptGenKey',  \
    CryptGenRandom, <.hProv, .dwLen, .pbBuffer>,  'CryptGenRandom',  \
    CryptGetDefaultProviderA, <.dwProvType, .pdwReserved, .dwFlags, .pszProvName, .pcbProvName>,  'CryptGetDefaultProviderA',  \
    CryptGetDefaultProviderW, <.dwProvType, .pdwReserved, .dwFlags, .pszProvName, .pcbProvName>,  'CryptGetDefaultProviderW',  \
    CryptGetHashParam, <.hHash, .dwParam, .pbData, .pdwDataLen, .dwFlags>,  'CryptGetHashParam',  \
    CryptGetKeyParam, <.hKey, .dwParam, .pbData, .pdwDataLen, .dwFlags>,  'CryptGetKeyParam',  \
    CryptGetProvParam, <.hProv, .dwParam, .pbData, .pdwDataLen, .dwFlags>,  'CryptGetProvParam',  \
    CryptGetUserKey, <.hProv, .dwKeySpec, .phUserKey>,  'CryptGetUserKey',  \
    CryptHashData, <.hHash, .pbData, .dwDataLen, .dwFlags>,  'CryptHashData',  \
    CryptHashSessionKey, <.hHash, .hKey, .dwFlags>,  'CryptHashSessionKey',  \
    CryptImportKey, <.hProv, .pbData, .dwDataLen, .hPubKey, .dwFlags, .phKey>,  'CryptImportKey',  \
    CryptReleaseContext, <.hProv, .dwFlags>,  'CryptReleaseContext',  \
    CryptSetHashParam, <.hHash, .dwParam, .pbData, .dwFlags>,  'CryptSetHashParam',  \
    CryptSetKeyParam, <.hKey, .dwParam, .pbData, .dwFlags>,  'CryptSetKeyParam',  \
    CryptSetProvParam, <.hProv, .dwParam, .pbData, .dwFlags>,  'CryptSetProvParam',  \
    CryptSetProviderA, <.pszProvName, .dwProvType>,  'CryptSetProviderA',  \
    CryptSetProviderExA, <.pszProvName, .dwProvType, .pdwReserved, .dwFlags>,  'CryptSetProviderExA',  \
    CryptSetProviderExW, <.pszProvName, .dwProvType, .pdwReserved, .dwFlags>,  'CryptSetProviderExW',  \
    CryptSetProviderW, <.pszProvName, .dwProvType>,  'CryptSetProviderW',  \
    CryptSignHashA, <.hHash, .dwKeySpec, .sDescription, .dwFlags, .pbSignature, .pdwSigLen>,  'CryptSignHashA',  \
    CryptSignHashW, <.hHash, .dwKeySpec, .sDescription, .dwFlags, .pbSignature, .pdwSigLen>,  'CryptSignHashW',  \
    CryptVerifySignatureA, <.hHash, .pbSignature, .dwSigLen, .hPubKey, .sDescription, .dwFlags>,  'CryptVerifySignatureA',  \
    CryptVerifySignatureW, <.hHash, .pbSignature, .dwSigLen, .hPubKey, .sDescription, .dwFlags>,  'CryptVerifySignatureW',  \
    DecryptFileA, <.lpFileName, .dwReserved>,  'DecryptFileA',  \
    DecryptFileW, <.lpFileName, .dwReserved>,  'DecryptFileW',  \
    DeleteAce, <.pAcl, .dwAceIndex>,  'DeleteAce',  \
    DeleteService, <.hService>,  'DeleteService',  \
    DeregisterEventSource, <.hEventLog>,  'DeregisterEventSource',  \
    DestroyPrivateObjectSecurity, <.ObjectDescriptor>,  'DestroyPrivateObjectSecurity',  \
    DuplicateEncryptionInfoFile, <NONE>,  'DuplicateEncryptionInfoFile',  \
    DuplicateToken, <.ExistingTokenHandle, .ImpersonationLevel, .DuplicateTokenHandle>,  'DuplicateToken',  \
    DuplicateTokenEx, <.hExistingToken, .dwDesiredAccess, .lpTokenAttributes, .ImpersonationLevel, .TokenType, .phNewToken>,  'DuplicateTokenEx',  \
    ElfBackupEventLogFileA, <NONE>,  'ElfBackupEventLogFileA',  \
    ElfBackupEventLogFileW, <NONE>,  'ElfBackupEventLogFileW',  \
    ElfChangeNotify, <NONE>,  'ElfChangeNotify',  \
    ElfClearEventLogFileA, <NONE>,  'ElfClearEventLogFileA',  \
    ElfClearEventLogFileW, <NONE>,  'ElfClearEventLogFileW',  \
    ElfCloseEventLog, <NONE>,  'ElfCloseEventLog',  \
    ElfDeregisterEventSource, <NONE>,  'ElfDeregisterEventSource',  \
    ElfFlushEventLog, <NONE>,  'ElfFlushEventLog',  \
    ElfNumberOfRecords, <NONE>,  'ElfNumberOfRecords',  \
    ElfOldestRecord, <NONE>,  'ElfOldestRecord',  \
    ElfOpenBackupEventLogA, <NONE>,  'ElfOpenBackupEventLogA',  \
    ElfOpenBackupEventLogW, <NONE>,  'ElfOpenBackupEventLogW',  \
    ElfOpenEventLogA, <NONE>,  'ElfOpenEventLogA',  \
    ElfOpenEventLogW, <NONE>,  'ElfOpenEventLogW',  \
    ElfReadEventLogA, <NONE>,  'ElfReadEventLogA',  \
    ElfReadEventLogW, <NONE>,  'ElfReadEventLogW',  \
    ElfRegisterEventSourceA, <NONE>,  'ElfRegisterEventSourceA',  \
    ElfRegisterEventSourceW, <NONE>,  'ElfRegisterEventSourceW',  \
    ElfReportEventA, <NONE>,  'ElfReportEventA',  \
    ElfReportEventW, <NONE>,  'ElfReportEventW',  \
    EnableTrace, <NONE>,  'EnableTrace',  \
    EncryptFileA, <.lpFileName>,  'EncryptFileA',  \
    EncryptFileW, <.lpFileName>,  'EncryptFileW',  \
    EncryptedFileKeyInfo, <NONE>,  'EncryptedFileKeyInfo',  \
    EncryptionDisable, <.DirPath, .Disable>,  'EncryptionDisable',  \
    EnumDependentServicesA, <.hService, .dwServiceState, .lpServices, .cbBufSize, .pcbBytesNeeded, .lpServicesReturned>,  'EnumDependentServicesA',  \
    EnumDependentServicesW, <.hService, .dwServiceState, .lpServices, .cbBufSize, .pcbBytesNeeded, .lpServicesReturned>,  'EnumDependentServicesW',  \
    EnumServiceGroupW, <NONE>,  'EnumServiceGroupW',  \
    EnumServicesStatusA, <.hSCManager, .dwServiceType, .dwServiceState, .lpServices, .cbBufSize, .pcbBytesNeeded, .lpServicesReturned,  \
        .lpResumeHandle>,  'EnumServicesStatusA',  \
    EnumServicesStatusExA, <.hSCManager, .InfoLevel, .dwServiceType, .dwServiceState, .lpServices, .cbBufSize, .pcbBytesNeeded, .lpServicesReturned,  \
        .lpResumeHandle, .pszGroupName>,  'EnumServicesStatusExA',  \
    EnumServicesStatusExW, <.hSCManager, .InfoLevel, .dwServiceType, .dwServiceState, .lpServices, .cbBufSize, .pcbBytesNeeded, .lpServicesReturned,  \
        .lpResumeHandle, .pszGroupName>,  'EnumServicesStatusExW',  \
    EnumServicesStatusW, <.hSCManager, .dwServiceType, .dwServiceState, .lpServices, .cbBufSize, .pcbBytesNeeded, .lpServicesReturned,  \
        .lpResumeHandle>,  'EnumServicesStatusW',  \
    EnumerateTraceGuids, <NONE>,  'EnumerateTraceGuids',  \
    EqualDomainSid, <NONE>,  'EqualDomainSid',  \
    EqualPrefixSid, <.pSid1, .pSid2>,  'EqualPrefixSid',  \
    EqualSid, <.pSid1, .pSid2>,  'EqualSid',  \
    FileEncryptionStatusA, <.lpFileName, .lpStatus>,  'FileEncryptionStatusA',  \
    FileEncryptionStatusW, <.lpFileName, .lpStatus>,  'FileEncryptionStatusW',  \
    FindFirstFreeAce, <.pAcl, .pAce>,  'FindFirstFreeAce',  \
    FlushTraceA, <NONE>,  'FlushTraceA',  \
    FlushTraceW, <NONE>,  'FlushTraceW',  \
    FreeEncryptedFileKeyInfo, <NONE>,  'FreeEncryptedFileKeyInfo',  \
    FreeEncryptionCertificateHashList, <.pHashes>,  'FreeEncryptionCertificateHashList',  \
    FreeInheritedFromArray, <.pInheritArray, .AceCnt, .pfnArray>,  'FreeInheritedFromArray',  \
    FreeSid, <.pSid>,  'FreeSid',  \
    GetAccessPermissionsForObjectA, <NONE>,  'GetAccessPermissionsForObjectA',  \
    GetAccessPermissionsForObjectW, <NONE>,  'GetAccessPermissionsForObjectW',  \
    GetAce, <.pAcl, .dwAceIndex, .pAce>,  'GetAce',  \
    GetAclInformation, <.pAcl, .pAclInformation, .nAclInformationLength, .dwAclInformationClass>,  'GetAclInformation',  \
    GetAuditedPermissionsFromAclA, <.pAcl, .pTrustee, .pSuccessfulAuditedRights, .pFailedAuditRights>,  'GetAuditedPermissionsFromAclA',  \
    GetAuditedPermissionsFromAclW, <.pAcl, .pTrustee, .pSuccessfulAuditedRights, .pFailedAuditRights>,  'GetAuditedPermissionsFromAclW',  \
    GetCurrentHwProfileA, <.lpHwProfileInfo>,  'GetCurrentHwProfileA',  \
    GetCurrentHwProfileW, <.lpHwProfileInfo>,  'GetCurrentHwProfileW',  \
    GetEffectiveRightsFromAclA, <.pAcl, .pTrustee, .pAccessRights>,  'GetEffectiveRightsFromAclA',  \
    GetEffectiveRightsFromAclW, <.pAcl, .pTrustee, .pAccessRights>,  'GetEffectiveRightsFromAclW',  \
    GetEventLogInformation, <.hEventLog, .dwInfoLevel, .lpBuffer, .cbBufSize, .pcbBytesNeeded>,  'GetEventLogInformation',  \
    GetExplicitEntriesFromAclA, <.pAcl, .pcCountOfExplicitEntries, .pListOfExplicitEntries>,  'GetExplicitEntriesFromAclA',  \
    GetExplicitEntriesFromAclW, <.pAcl, .pcCountOfExplicitEntries, .pListOfExplicitEntries>,  'GetExplicitEntriesFromAclW',  \
    GetFileSecurityA, <.lpFileName, .RequestedInformation, .pSecurityDescriptor, .nLength, .lpnLengthNeeded>,  'GetFileSecurityA',  \
    GetFileSecurityW, <.lpFileName, .RequestedInformation, .pSecurityDescriptor, .nLength, .lpnLengthNeeded>,  'GetFileSecurityW',  \
    GetInformationCodeAuthzLevelW, <NONE>,  'GetInformationCodeAuthzLevelW',  \
    GetInformationCodeAuthzPolicyW, <NONE>,  'GetInformationCodeAuthzPolicyW',  \
    GetInheritanceSourceA, <.pObjectName, .ObjectType, .SecurityInfo, .Container, .ObjectTypeGuid, .pAcl, .pfnArray, .pGenericMapping,  \
        .pInheritArray>,  'GetInheritanceSourceA',  \
    GetInheritanceSourceW, <.pObjectName, .ObjectType, .SecurityInfo, .Container, .ObjectTypeGuid, .pAcl, .pfnArray, .pGenericMapping,  \
        .pInheritArray>,  'GetInheritanceSourceW',  \
    GetKernelObjectSecurity, <.Handle, .RequestedInformation, .pSecurityDescriptor, .nLength, .lpnLengthNeeded>,  'GetKernelObjectSecurity',  \
    GetLengthSid, <.pSid>,  'GetLengthSid',  \
    GetLocalManagedApplicationData, <NONE>,  'GetLocalManagedApplicationData',  \
    GetLocalManagedApplications, <NONE>,  'GetLocalManagedApplications',  \
    GetManagedApplicationCategories, <NONE>,  'GetManagedApplicationCategories',  \
    GetManagedApplications, <NONE>,  'GetManagedApplications',  \
    GetMultipleTrusteeA, <.pTrustee>,  'GetMultipleTrusteeA',  \
    GetMultipleTrusteeOperationA, <.pTrustee>,  'GetMultipleTrusteeOperationA',  \
    GetMultipleTrusteeOperationW, <.pTrustee>,  'GetMultipleTrusteeOperationW',  \
    GetMultipleTrusteeW, <.pTrustee>,  'GetMultipleTrusteeW',  \
    GetNamedSecurityInfoA, <.pObjectName, .ObjectType, .SecurityInfo, .ppsidOwner, .ppsidGroup, .ppDacl, .ppSacl, .ppSecurityDescriptor,  \
      >,  'GetNamedSecurityInfoA',  \
    GetNamedSecurityInfoExA, <NONE>,  'GetNamedSecurityInfoExA',  \
    GetNamedSecurityInfoExW, <NONE>,  'GetNamedSecurityInfoExW',  \
    GetNamedSecurityInfoW, <.pObjectName, .ObjectType, .SecurityInfo, .ppsidOwner, .ppsidGroup, .ppDacl, .ppSacl, .ppSecurityDescriptor,  \
      >,  'GetNamedSecurityInfoW',  \
    GetNumberOfEventLogRecords, <.hEventLog, .NumberOfRecords>,  'GetNumberOfEventLogRecords',  \
    GetOldestEventLogRecord, <.hEventLog, .OldestRecord>,  'GetOldestEventLogRecord',  \
    GetOverlappedAccessResults, <NONE>,  'GetOverlappedAccessResults',  \
    GetPrivateObjectSecurity, <.ObjectDescriptor, .SecurityInformation, .ResultantDescriptor, .DescriptorLength, .ReturnLength>,  'GetPrivateObjectSecurity',  \
    GetSecurityDescriptorControl, <.pSecurityDescriptor, .pControl, .lpdwRevision>,  'GetSecurityDescriptorControl',  \
    GetSecurityDescriptorDacl, <.pSecurityDescriptor, .lpbDaclPresent, .pDacl, .lpbDaclDefaulted>,  'GetSecurityDescriptorDacl',  \
    GetSecurityDescriptorGroup, <.pSecurityDescriptor, .pGroup, .lpbGroupDefaulted>,  'GetSecurityDescriptorGroup',  \
    GetSecurityDescriptorLength, <.pSecurityDescriptor>,  'GetSecurityDescriptorLength',  \
    GetSecurityDescriptorOwner, <.pSecurityDescriptor, .pOwner, .lpbOwnerDefaulted>,  'GetSecurityDescriptorOwner',  \
    GetSecurityDescriptorRMControl, <.SecurityDescriptor, .RMControl>,  'GetSecurityDescriptorRMControl',  \
    GetSecurityDescriptorSacl, <.pSecurityDescriptor, .lpbSaclPresent, .pSacl, .lpbSaclDefaulted>,  'GetSecurityDescriptorSacl',  \
    GetSecurityInfo, <.Handle, .ObjectType, .SecurityInfo, .ppsidOwner, .ppsidGroup, .ppDacl, .ppSacl, .ppSecurityDescriptor>,  'GetSecurityInfo',  \
    GetSecurityInfoExA, <NONE>,  'GetSecurityInfoExA',  \
    GetSecurityInfoExW, <NONE>,  'GetSecurityInfoExW',  \
    GetServiceDisplayNameA, <.hSCManager, .lpServiceName, .lpDisplayName, .lpcchBuffer>,  'GetServiceDisplayNameA',  \
    GetServiceDisplayNameW, <.hSCManager, .lpServiceName, .lpDisplayName, .lpcchBuffer>,  'GetServiceDisplayNameW',  \
    GetServiceKeyNameA, <.hSCManager, .lpDisplayName, .lpServiceName, .lpcchBuffer>,  'GetServiceKeyNameA',  \
    GetServiceKeyNameW, <.hSCManager, .lpDisplayName, .lpServiceName, .lpcchBuffer>,  'GetServiceKeyNameW',  \
    GetSidIdentifierAuthority, <.pSid>,  'GetSidIdentifierAuthority',  \
    GetSidLengthRequired, <.nSubAuthorityCount>,  'GetSidLengthRequired',  \
    GetSidSubAuthority, <.pSid, .nSubAuthority>,  'GetSidSubAuthority',  \
    GetSidSubAuthorityCount, <.pSid>,  'GetSidSubAuthorityCount',  \
    GetTokenInformation, <.TokenHandle, .TokenInformationClass, .TokenInformation, .TokenInformationLength, .ReturnLength>,  'GetTokenInformation',  \
    GetTraceEnableFlags, <NONE>,  'GetTraceEnableFlags',  \
    GetTraceEnableLevel, <NONE>,  'GetTraceEnableLevel',  \
    GetTraceLoggerHandle, <NONE>,  'GetTraceLoggerHandle',  \
    GetTrusteeFormA, <.pTrustee>,  'GetTrusteeFormA',  \
    GetTrusteeFormW, <.pTrustee>,  'GetTrusteeFormW',  \
    GetTrusteeNameA, <.pTrustee>,  'GetTrusteeNameA',  \
    GetTrusteeNameW, <.pTrustee>,  'GetTrusteeNameW',  \
    GetTrusteeTypeA, <.pTrustee>,  'GetTrusteeTypeA',  \
    GetTrusteeTypeW, <.pTrustee>,  'GetTrusteeTypeW',  \
    GetUserNameA, <.lpBuffer, .nSize>,  'GetUserNameA',  \
    GetUserNameW, <.lpBuffer, .nSize>,  'GetUserNameW',  \
    GetWindowsAccountDomainSid, <NONE>,  'GetWindowsAccountDomainSid',  \
    I_ScGetCurrentGroupStateW, <NONE>,  'I_ScGetCurrentGroupStateW',  \
    I_ScIsSecurityProcess, <NONE>,  'I_ScIsSecurityProcess',  \
    I_ScPnPGetServiceName, <NONE>,  'I_ScPnPGetServiceName',  \
    I_ScSendTSMessage, <NONE>,  'I_ScSendTSMessage',  \
    I_ScSetServiceBitsA, <NONE>,  'I_ScSetServiceBitsA',  \
    I_ScSetServiceBitsW, <NONE>,  'I_ScSetServiceBitsW',  \
    IdentifyCodeAuthzLevelW, <NONE>,  'IdentifyCodeAuthzLevelW',  \
    ImpersonateAnonymousToken, <.ThreadHandle>,  'ImpersonateAnonymousToken',  \
    ImpersonateLoggedOnUser, <.hToken>,  'ImpersonateLoggedOnUser',  \
    ImpersonateNamedPipeClient, <.hNamedPipe>,  'ImpersonateNamedPipeClient',  \
    ImpersonateSelf, <.ImpersonationLevel>,  'ImpersonateSelf',  \
    InitializeAcl, <.pAcl, .nAclLength, .dwAclRevision>,  'InitializeAcl',  \
    InitializeSecurityDescriptor, <.pSecurityDescriptor, .dwRevision>,  'InitializeSecurityDescriptor',  \
    InitializeSid, <.Sid, .pIdentifierAuthority, .nSubAuthorityCount>,  'InitializeSid',  \
    InitiateSystemShutdownA, <.lpMachineName, .lpMessage, .dwTimeout, .bForceAppsClosed, .bRebootAfterShutdown>,  'InitiateSystemShutdownA',  \
    InitiateSystemShutdownExA, <.lpMachineName, .lpMessage, .dwTimeout, .bForceAppsClosed, .bRebootAfterShutdown, .dwReason>,  'InitiateSystemShutdownExA',  \
    InitiateSystemShutdownExW, <.lpMachineName, .lpMessage, .dwTimeout, .bForceAppsClosed, .bRebootAfterShutdown, .dwReason>,  'InitiateSystemShutdownExW',  \
    InitiateSystemShutdownW, <.lpMachineName, .lpMessage, .dwTimeout, .bForceAppsClosed, .bRebootAfterShutdown>,  'InitiateSystemShutdownW',  \
    InstallApplication, <NONE>,  'InstallApplication',  \
    IsTextUnicode, <.lpBuffer, .cb, .lpi>,  'IsTextUnicode',  \
    IsTokenRestricted, <.TokenHandle>,  'IsTokenRestricted',  \
    IsTokenUntrusted, <NONE>,  'IsTokenUntrusted',  \
    IsValidAcl, <.pAcl>,  'IsValidAcl',  \
    IsValidSecurityDescriptor, <.pSecurityDescriptor>,  'IsValidSecurityDescriptor',  \
    IsValidSid, <.pSid>,  'IsValidSid',  \
    IsWellKnownSid, <NONE>,  'IsWellKnownSid',  \
    LockServiceDatabase, <.hSCManager>,  'LockServiceDatabase',  \
    LogonUserA, <.lpszUsername, .lpszDomain, .lpszPassword, .dwLogonType, .dwLogonProvider, .phToken>,  'LogonUserA',  \
    LogonUserExA, <NONE>,  'LogonUserExA',  \
    LogonUserExW, <NONE>,  'LogonUserExW',  \
    LogonUserW, <.lpszUsername, .lpszDomain, .lpszPassword, .dwLogonType, .dwLogonProvider, .phToken>,  'LogonUserW',  \
    LookupAccountNameA, <.lpSystemName, .lpAccountName, .Sid, .cbSid, .ReferencedDomainName, .cbReferencedDomainName, .peUse>,  'LookupAccountNameA',  \
    LookupAccountNameW, <.lpSystemName, .lpAccountName, .Sid, .cbSid, .ReferencedDomainName, .cbReferencedDomainName, .peUse>,  'LookupAccountNameW',  \
    LookupAccountSidA, <.lpSystemName, .Sid, .Name, .cbName, .ReferencedDomainName, .cbReferencedDomainName, .peUse>,  'LookupAccountSidA',  \
    LookupAccountSidW, <.lpSystemName, .Sid, .Name, .cbName, .ReferencedDomainName, .cbReferencedDomainName, .peUse>,  'LookupAccountSidW',  \
    LookupPrivilegeDisplayNameA, <.lpSystemName, .lpName, .lpDisplayName, .cbDisplayName, .lpLanguageID>,  'LookupPrivilegeDisplayNameA',  \
    LookupPrivilegeDisplayNameW, <.lpSystemName, .lpName, .lpDisplayName, .cbDisplayName, .lpLanguageID>,  'LookupPrivilegeDisplayNameW',  \
    LookupPrivilegeNameA, <.lpSystemName, .lpLuid, .lpName, .cbName>,  'LookupPrivilegeNameA',  \
    LookupPrivilegeNameW, <.lpSystemName, .lpLuid, .lpName, .cbName>,  'LookupPrivilegeNameW',  \
    LookupPrivilegeValueA, <.lpSystemName, .lpName, .lpLuid>,  'LookupPrivilegeValueA',  \
    LookupPrivilegeValueW, <.lpSystemName, .lpName, .lpLuid>,  'LookupPrivilegeValueW',  \
    LookupSecurityDescriptorPartsA, <.pOwner, .pGroup, .cCountOfAccessEntries, .pListOfAccessEntries, .cCountOfAuditEntries, .pListOfAuditEntries,  \
        .pSD>,  'LookupSecurityDescriptorPartsA',  \
    LookupSecurityDescriptorPartsW, <.pOwner, .pGroup, .cCountOfAccessEntries, .pListOfAccessEntries, .cCountOfAuditEntries, .pListOfAuditEntries,  \
        .pSD>,  'LookupSecurityDescriptorPartsW',  \
    LsaAddAccountRights, <.PolicyHandle, .AccountSid, .UserRights, .CountOfRights>,  'LsaAddAccountRights',  \
    LsaAddPrivilegesToAccount, <NONE>,  'LsaAddPrivilegesToAccount',  \
    LsaClearAuditLog, <NONE>,  'LsaClearAuditLog',  \
    LsaClose, <.ObjectHandle>,  'LsaClose',  \
    LsaCreateAccount, <NONE>,  'LsaCreateAccount',  \
    LsaCreateSecret, <NONE>,  'LsaCreateSecret',  \
    LsaCreateTrustedDomain, <NONE>,  'LsaCreateTrustedDomain',  \
    LsaCreateTrustedDomainEx, <.PolicyHandle, .TrustedDomainInformation, .AuthenticationInformation, .DesiredAccess, .TrustedDomainHandle,  \
      >,  'LsaCreateTrustedDomainEx',  \
    LsaDelete, <NONE>,  'LsaDelete',  \
    LsaDeleteTrustedDomain, <.PolicyHandle, .TrustedDomainSid>,  'LsaDeleteTrustedDomain',  \
    LsaEnumerateAccountRights, <.PolicyHandle, .AccountSid, .UserRights, .CountOfRights>,  'LsaEnumerateAccountRights',  \
    LsaEnumerateAccounts, <NONE>,  'LsaEnumerateAccounts',  \
    LsaEnumerateAccountsWithUserRight, <.PolicyHandle, .UserRights, .EnumerationBuffer, .CountReturned>,  'LsaEnumerateAccountsWithUserRight',  \
    LsaEnumeratePrivileges, <NONE>,  'LsaEnumeratePrivileges',  \
    LsaEnumeratePrivilegesOfAccount, <NONE>,  'LsaEnumeratePrivilegesOfAccount',  \
    LsaEnumerateTrustedDomains, <.PolicyHandle, .EnumerationContext, .buffer, .PreferedMaximumLength, .CountReturned>,  'LsaEnumerateTrustedDomains',  \
    LsaEnumerateTrustedDomainsEx, <.PolicyHandle, .EnumerationContext, .buffer, .PreferedMaximumLength, .CountReturned>,  'LsaEnumerateTrustedDomainsEx',  \
    LsaFreeMemory, <.buffer>,  'LsaFreeMemory',  \
    LsaGetQuotasForAccount, <NONE>,  'LsaGetQuotasForAccount',  \
    LsaGetRemoteUserName, <NONE>,  'LsaGetRemoteUserName',  \
    LsaGetSystemAccessAccount, <NONE>,  'LsaGetSystemAccessAccount',  \
    LsaGetUserName, <NONE>,  'LsaGetUserName',  \
    LsaICLookupNames, <NONE>,  'LsaICLookupNames',  \
    LsaICLookupNamesWithCreds, <NONE>,  'LsaICLookupNamesWithCreds',  \
    LsaICLookupSids, <NONE>,  'LsaICLookupSids',  \
    LsaICLookupSidsWithCreds, <NONE>,  'LsaICLookupSidsWithCreds',  \
    LsaLookupNames, <.PolicyHandle, .count, .Names, .ReferencedDomains, .Sids>,  'LsaLookupNames',  \
    LsaLookupNames2, <NONE>,  'LsaLookupNames2',  \
    LsaLookupPrivilegeDisplayName, <NONE>,  'LsaLookupPrivilegeDisplayName',  \
    LsaLookupPrivilegeName, <NONE>,  'LsaLookupPrivilegeName',  \
    LsaLookupPrivilegeValue, <NONE>,  'LsaLookupPrivilegeValue',  \
    LsaLookupSids, <.PolicyHandle, .count, .Sids, .ReferencedDomains, .Names>,  'LsaLookupSids',  \
    LsaNtStatusToWinError, <.Status>,  'LsaNtStatusToWinError',  \
    LsaOpenAccount, <NONE>,  'LsaOpenAccount',  \
    LsaOpenPolicy, <.SystemName, .ObjectAttributes, .DesiredAccess, .PolicyHandle>,  'LsaOpenPolicy',  \
    LsaOpenPolicySce, <NONE>,  'LsaOpenPolicySce',  \
    LsaOpenSecret, <NONE>,  'LsaOpenSecret',  \
    LsaOpenTrustedDomain, <NONE>,  'LsaOpenTrustedDomain',  \
    LsaOpenTrustedDomainByName, <.PolicyHandle, .TrustedDomainName, .DesiredAccess, .TrustedDomainHandle>,  'LsaOpenTrustedDomainByName',  \
    LsaQueryDomainInformationPolicy, <.PolicyHandle, .InformationClass, .buffer>,  'LsaQueryDomainInformationPolicy',  \
    LsaQueryForestTrustInformation, <NONE>,  'LsaQueryForestTrustInformation',  \
    LsaQueryInfoTrustedDomain, <NONE>,  'LsaQueryInfoTrustedDomain',  \
    LsaQueryInformationPolicy, <.PolicyHandle, .InformationClass, .buffer>,  'LsaQueryInformationPolicy',  \
    LsaQuerySecret, <NONE>,  'LsaQuerySecret',  \
    LsaQuerySecurityObject, <NONE>,  'LsaQuerySecurityObject',  \
    LsaQueryTrustedDomainInfo, <.PolicyHandle, .TrustedDomainSid, .InformationClass, .buffer>,  'LsaQueryTrustedDomainInfo',  \
    LsaQueryTrustedDomainInfoByName, <.PolicyHandle, .TrustedDomainName, .InformationClass, .buffer>,  'LsaQueryTrustedDomainInfoByName',  \
    LsaRemoveAccountRights, <.PolicyHandle, .AccountSid, .AllRights, .UserRights, .CountOfRights>,  'LsaRemoveAccountRights',  \
    LsaRemovePrivilegesFromAccount, <NONE>,  'LsaRemovePrivilegesFromAccount',  \
    LsaRetrievePrivateData, <.PolicyHandle, .KeyName, .PrivateData>,  'LsaRetrievePrivateData',  \
    LsaSetDomainInformationPolicy, <.PolicyHandle, .InformationClass, .buffer>,  'LsaSetDomainInformationPolicy',  \
    LsaSetForestTrustInformation, <NONE>,  'LsaSetForestTrustInformation',  \
    LsaSetInformationPolicy, <.PolicyHandle, .InformationClass, .buffer>,  'LsaSetInformationPolicy',  \
    LsaSetInformationTrustedDomain, <NONE>,  'LsaSetInformationTrustedDomain',  \
    LsaSetQuotasForAccount, <NONE>,  'LsaSetQuotasForAccount',  \
    LsaSetSecret, <NONE>,  'LsaSetSecret',  \
    LsaSetSecurityObject, <NONE>,  'LsaSetSecurityObject',  \
    LsaSetSystemAccessAccount, <NONE>,  'LsaSetSystemAccessAccount',  \
    LsaSetTrustedDomainInfoByName, <.PolicyHandle, .TrustedDomainName, .InformationClass, .buffer>,  'LsaSetTrustedDomainInfoByName',  \
    LsaSetTrustedDomainInformation, <.PolicyHandle, .TrustedDomainSid, .InformationClass, .buffer>,  'LsaSetTrustedDomainInformation',  \
    LsaStorePrivateData, <.PolicyHandle, .KeyName, .PrivateData>,  'LsaStorePrivateData',  \
    MD4Final, <NONE>,  'MD4Final',  \
    MD4Init, <NONE>,  'MD4Init',  \
    MD4Update, <NONE>,  'MD4Update',  \
    MD5Final, <NONE>,  'MD5Final',  \
    MD5Init, <NONE>,  'MD5Init',  \
    MD5Update, <NONE>,  'MD5Update',  \
    MSChapSrvChangePassword, <NONE>,  'MSChapSrvChangePassword',  \
    MSChapSrvChangePassword2, <NONE>,  'MSChapSrvChangePassword2',  \
    MakeAbsoluteSD, <.pSelfRelativeSecurityDescriptor, .pAbsoluteSecurityDescriptor, .lpdwAbsoluteSecurityDescriptorSize, .pDacl, .lpdwDaclSize,  \
        .pSacl, .lpdwSaclSize, .pOwner, .lpdwOwnerSize, .pPrimaryGroup, .lpdwPrimaryGroupSize>,  'MakeAbsoluteSD',  \
    MakeAbsoluteSD2, <.pSelfRelativeSecurityDescriptor, .lpdwBufferSize>,  'MakeAbsoluteSD2',  \
    MakeSelfRelativeSD, <.pAbsoluteSecurityDescriptor, .pSelfRelativeSecurityDescriptor, .lpdwBufferLength>,  'MakeSelfRelativeSD',  \
    MapGenericMask, <.AccessMask, .GenericMapping>,  'MapGenericMask',  \
    NotifyBootConfigStatus, <.BootAcceptable>,  'NotifyBootConfigStatus',  \
    NotifyChangeEventLog, <.hEventLog, .hEvent>,  'NotifyChangeEventLog',  \
    ObjectCloseAuditAlarmA, <.SubsystemName, .HandleId, .GenerateOnClose>,  'ObjectCloseAuditAlarmA',  \
    ObjectCloseAuditAlarmW, <.SubsystemName, .HandleId, .GenerateOnClose>,  'ObjectCloseAuditAlarmW',  \
    ObjectDeleteAuditAlarmA, <.SubsystemName, .HandleId, .GenerateOnClose>,  'ObjectDeleteAuditAlarmA',  \
    ObjectDeleteAuditAlarmW, <.SubsystemName, .HandleId, .GenerateOnClose>,  'ObjectDeleteAuditAlarmW',  \
    ObjectOpenAuditAlarmA, <.SubsystemName, .HandleId, .ObjectTypeName, .ObjectName, .pSecurityDescriptor, .ClientToken, .DesiredAccess,  \
        .GrantedAccess, .Privileges, .ObjectCreation, .AccessGranted, .GenerateOnClose>,  'ObjectOpenAuditAlarmA',  \
    ObjectOpenAuditAlarmW, <.SubsystemName, .HandleId, .ObjectTypeName, .ObjectName, .pSecurityDescriptor, .ClientToken, .DesiredAccess,  \
        .GrantedAccess, .Privileges, .ObjectCreation, .AccessGranted, .GenerateOnClose>,  'ObjectOpenAuditAlarmW',  \
    ObjectPrivilegeAuditAlarmA, <.SubsystemName, .HandleId, .ClientToken, .DesiredAccess, .Privileges, .AccessGranted>,  'ObjectPrivilegeAuditAlarmA',  \
    ObjectPrivilegeAuditAlarmW, <.SubsystemName, .HandleId, .ClientToken, .DesiredAccess, .Privileges, .AccessGranted>,  'ObjectPrivilegeAuditAlarmW',  \
    OpenBackupEventLogA, <.lpUNCServerName, .lpFileName>,  'OpenBackupEventLogA',  \
    OpenBackupEventLogW, <.lpUNCServerName, .lpFileName>,  'OpenBackupEventLogW',  \
    OpenEncryptedFileRawA, <.lpFileName, .ulFlags, .pvContext>,  'OpenEncryptedFileRawA',  \
    OpenEncryptedFileRawW, <.lpFileName, .ulFlags, .pvContext>,  'OpenEncryptedFileRawW',  \
    OpenEventLogA, <.lpUNCServerName, .lpSourceName>,  'OpenEventLogA',  \
    OpenEventLogW, <.lpUNCServerName, .lpSourceName>,  'OpenEventLogW',  \
    OpenProcessToken, <.ProcessHandle, .DesiredAccess, .TokenHandle>,  'OpenProcessToken',  \
    OpenSCManagerA, <.lpMachineName, .lpDatabaseName, .dwDesiredAccess>,  'OpenSCManagerA',  \
    OpenSCManagerW, <.lpMachineName, .lpDatabaseName, .dwDesiredAccess>,  'OpenSCManagerW',  \
    OpenServiceA, <.hSCManager, .lpServiceName, .dwDesiredAccess>,  'OpenServiceA',  \
    OpenServiceW, <.hSCManager, .lpServiceName, .dwDesiredAccess>,  'OpenServiceW',  \
    OpenThreadToken, <.ThreadHandle, .DesiredAccess, .OpenAsSelf, .TokenHandle>,  'OpenThreadToken',  \
    OpenTraceA, <NONE>,  'OpenTraceA',  \
    OpenTraceW, <NONE>,  'OpenTraceW',  \
    PrivilegeCheck, <.ClientToken, .RequiredPrivileges, .pfResult>,  'PrivilegeCheck',  \
    PrivilegedServiceAuditAlarmA, <.SubsystemName, .ServiceName, .ClientToken, .Privileges, .AccessGranted>,  'PrivilegedServiceAuditAlarmA',  \
    PrivilegedServiceAuditAlarmW, <.SubsystemName, .ServiceName, .ClientToken, .Privileges, .AccessGranted>,  'PrivilegedServiceAuditAlarmW',  \
    ProcessIdleTasks, <NONE>,  'ProcessIdleTasks',  \
    ProcessTrace, <NONE>,  'ProcessTrace',  \
    QueryAllTracesA, <NONE>,  'QueryAllTracesA',  \
    QueryAllTracesW, <NONE>,  'QueryAllTracesW',  \
    QueryRecoveryAgentsOnEncryptedFile, <.lpFileName, .pRecoveryAgents>,  'QueryRecoveryAgentsOnEncryptedFile',  \
    QueryServiceConfig2A, <.hService, .dwInfoLevel, .lpBuffer, .cbBufSize, .pcbBytesNeeded>,  'QueryServiceConfig2A',  \
    QueryServiceConfig2W, <.hService, .dwInfoLevel, .lpBuffer, .cbBufSize, .pcbBytesNeeded>,  'QueryServiceConfig2W',  \
    QueryServiceConfigA, <.hService, .lpServiceConfig, .cbBufSize, .pcbBytesNeeded>,  'QueryServiceConfigA',  \
    QueryServiceConfigW, <.hService, .lpServiceConfig, .cbBufSize, .pcbBytesNeeded>,  'QueryServiceConfigW',  \
    QueryServiceLockStatusA, <.hSCManager, .lpLockStatus, .cbBufSize, .pcbBytesNeeded>,  'QueryServiceLockStatusA',  \
    QueryServiceLockStatusW, <.hSCManager, .lpLockStatus, .cbBufSize, .pcbBytesNeeded>,  'QueryServiceLockStatusW',  \
    QueryServiceObjectSecurity, <.hService, .dwSecurityInformation, .lpSecurityDescriptor, .cbBufSize, .pcbBytesNeeded>,  'QueryServiceObjectSecurity',  \
    QueryServiceStatus, <.hService, .lpServiceStatus>,  'QueryServiceStatus',  \
    QueryServiceStatusEx, <.hService, .InfoLevel, .lpBuffer, .cbBufSize, .pcbBytesNeeded>,  'QueryServiceStatusEx',  \
    QueryTraceA, <NONE>,  'QueryTraceA',  \
    QueryTraceW, <NONE>,  'QueryTraceW',  \
    QueryUsersOnEncryptedFile, <.lpFileName, .pUsers>,  'QueryUsersOnEncryptedFile',  \
    QueryWindows31FilesMigration, <NONE>,  'QueryWindows31FilesMigration',  \
    ReadEncryptedFileRaw, <.pfExportCallback, .pvCallbackContext, .pvContext>,  'ReadEncryptedFileRaw',  \
    ReadEventLogA, <.hEventLog, .dwReadFlags, .dwRecordOffset, .lpBuffer, .nNumberOfBytesToRead, .pnBytesRead, .pnMinNumberOfBytesNeeded,  \
      >,  'ReadEventLogA',  \
    ReadEventLogW, <.hEventLog, .dwReadFlags, .dwRecordOffset, .lpBuffer, .nNumberOfBytesToRead, .pnBytesRead, .pnMinNumberOfBytesNeeded,  \
      >,  'ReadEventLogW',  \
    RegCloseKey, <.hKey>,  'RegCloseKey',  \
    RegConnectRegistryA, <.lpMachineName, .hKey, .phkResult>,  'RegConnectRegistryA',  \
    RegConnectRegistryW, <.lpMachineName, .hKey, .phkResult>,  'RegConnectRegistryW',  \
    RegCreateKeyA, <.hKey, .lpSubKey, .phkResult>,  'RegCreateKeyA',  \
    RegCreateKeyExA, <.hKey, .lpSubKey, .Reserved, .lpClass, .dwOptions, .samDesired, .lpSecurityAttributes, .phkResult, .lpdwDisposition,  \
      >,  'RegCreateKeyExA',  \
    RegCreateKeyExW, <.hKey, .lpSubKey, .Reserved, .lpClass, .dwOptions, .samDesired, .lpSecurityAttributes, .phkResult, .lpdwDisposition,  \
      >,  'RegCreateKeyExW',  \
    RegCreateKeyW, <.hKey, .lpSubKey, .phkResult>,  'RegCreateKeyW',  \
    RegDeleteKeyA, <.hKey, .lpSubKey>,  'RegDeleteKeyA',  \
    RegDeleteKeyW, <.hKey, .lpSubKey>,  'RegDeleteKeyW',  \
    RegDeleteValueA, <.hKey, .lpValueName>,  'RegDeleteValueA',  \
    RegDeleteValueW, <.hKey, .lpValueName>,  'RegDeleteValueW',  \
    RegDisablePredefinedCache, <VOID>,  'RegDisablePredefinedCache',  \
    RegDisablePredefinedCacheEx, <NONE>,  'RegDisablePredefinedCacheEx',  \
    RegEnumKeyA, <.hKey, .dwIndex, .lpName, .cbName>,  'RegEnumKeyA',  \
    RegEnumKeyExA, <.hKey, .dwIndex, .lpName, .lpcbName, .lpReserved, .lpClass, .lpcbClass, .lpftLastWriteTime>,  'RegEnumKeyExA',  \
    RegEnumKeyExW, <.hKey, .dwIndex, .lpName, .lpcbName, .lpReserved, .lpClass, .lpcbClass, .lpftLastWriteTime>,  'RegEnumKeyExW',  \
    RegEnumKeyW, <.hKey, .dwIndex, .lpName, .cbName>,  'RegEnumKeyW',  \
    RegEnumValueA, <.hKey, .dwIndex, .lpValueName, .lpcbValueName, .lpReserved, .lpType, .lpData, .lpcbData>,  'RegEnumValueA',  \
    RegEnumValueW, <.hKey, .dwIndex, .lpValueName, .lpcbValueName, .lpReserved, .lpType, .lpData, .lpcbData>,  'RegEnumValueW',  \
    RegFlushKey, <.hKey>,  'RegFlushKey',  \
    RegGetKeySecurity, <.hKey, .SecurityInformation, .pSecurityDescriptor, .lpcbSecurityDescriptor>,  'RegGetKeySecurity',  \
    RegLoadKeyA, <.hKey, .lpSubKey, .lpFile>,  'RegLoadKeyA',  \
    RegLoadKeyW, <.hKey, .lpSubKey, .lpFile>,  'RegLoadKeyW',  \
    RegNotifyChangeKeyValue, <.hKey, .bWatchSubtree, .dwNotifyFilter, .hEvent, .fAsynchronus>,  'RegNotifyChangeKeyValue',  \
    RegOpenCurrentUser, <.samDesired, .phkResult>,  'RegOpenCurrentUser',  \
    RegOpenKeyA, <.hKey, .lpSubKey, .phkResult>,  'RegOpenKeyA',  \
    RegOpenKeyExA, <.hKey, .lpSubKey, .ulOptions, .samDesired, .phkResult>,  'RegOpenKeyExA',  \
    RegOpenKeyExW, <.hKey, .lpSubKey, .ulOptions, .samDesired, .phkResult>,  'RegOpenKeyExW',  \
    RegOpenKeyW, <.hKey, .lpSubKey, .phkResult>,  'RegOpenKeyW',  \
    RegOpenUserClassesRoot, <.hToken, .dwOptions, .samDesired, .phkResult>,  'RegOpenUserClassesRoot',  \
    RegOverridePredefKey, <.hKey, .hNewHKey>,  'RegOverridePredefKey',  \
    RegQueryInfoKeyA, <.hKey, .lpClass, .lpcbClass, .lpReserved, .lpcSubKeys, .lpcbMaxSubKeyLen, .lpcbMaxClassLen, .lpcValues, .lpcbMaxValueNameLen,  \
        .lpcbMaxValueLen, .lpcbSecurityDescriptor, .lpftLastWriteTime>,  'RegQueryInfoKeyA',  \
    RegQueryInfoKeyW, <.hKey, .lpClass, .lpcbClass, .lpReserved, .lpcSubKeys, .lpcbMaxSubKeyLen, .lpcbMaxClassLen, .lpcValues, .lpcbMaxValueNameLen,  \
        .lpcbMaxValueLen, .lpcbSecurityDescriptor, .lpftLastWriteTime>,  'RegQueryInfoKeyW',  \
    RegQueryMultipleValuesA, <.hKey, .val_list, .num_vals, .lpValueBuf, .ldwTotsize>,  'RegQueryMultipleValuesA',  \
    RegQueryMultipleValuesW, <.hKey, .val_list, .num_vals, .lpValueBuf, .ldwTotsize>,  'RegQueryMultipleValuesW',  \
    RegQueryValueA, <.hKey, .lpSubKey, .lpValue, .lpcbValue>,  'RegQueryValueA',  \
    RegQueryValueExA, <.hKey, .lpValueName, .lpReserved, .lpType, .lpData, .lpcbData>,  'RegQueryValueExA',  \
    RegQueryValueExW, <.hKey, .lpValueName, .lpReserved, .lpType, .lpData, .lpcbData>,  'RegQueryValueExW',  \
    RegQueryValueW, <.hKey, .lpSubKey, .lpValue, .lpcbValue>,  'RegQueryValueW',  \
    RegReplaceKeyA, <.hKey, .lpSubKey, .lpNewFile, .lpOldFile>,  'RegReplaceKeyA',  \
    RegReplaceKeyW, <.hKey, .lpSubKey, .lpNewFile, .lpOldFile>,  'RegReplaceKeyW',  \
    RegRestoreKeyA, <.hKey, .lpFile, .dwFlags>,  'RegRestoreKeyA',  \
    RegRestoreKeyW, <.hKey, .lpFile, .dwFlags>,  'RegRestoreKeyW',  \
    RegSaveKeyA, <.hKey, .lpFile, .lpSecurityAttributes>,  'RegSaveKeyA',  \
    RegSaveKeyExA, <NONE>,  'RegSaveKeyExA',  \
    RegSaveKeyExW, <NONE>,  'RegSaveKeyExW',  \
    RegSaveKeyW, <.hKey, .lpFile, .lpSecurityAttributes>,  'RegSaveKeyW',  \
    RegSetKeySecurity, <.hKey, .SecurityInformation, .pSecurityDescriptor>,  'RegSetKeySecurity',  \
    RegSetValueA, <.hKey, .lpSubKey, .dwType, .lpData, .cbData>,  'RegSetValueA',  \
    RegSetValueExA, <.hKey, .lpValueName, .Reserved, .dwType, .lpData, .cbData>,  'RegSetValueExA',  \
    RegSetValueExW, <.hKey, .lpValueName, .Reserved, .dwType, .lpData, .cbData>,  'RegSetValueExW',  \
    RegSetValueW, <.hKey, .lpSubKey, .dwType, .lpData, .cbData>,  'RegSetValueW',  \
    RegUnLoadKeyA, <.hKey, .lpSubKey>,  'RegUnLoadKeyA',  \
    RegUnLoadKeyW, <.hKey, .lpSubKey>,  'RegUnLoadKeyW',  \
    RegisterEventSourceA, <.lpUNCServerName, .lpSourceName>,  'RegisterEventSourceA',  \
    RegisterEventSourceW, <.lpUNCServerName, .lpSourceName>,  'RegisterEventSourceW',  \
    RegisterIdleTask, <NONE>,  'RegisterIdleTask',  \
    RegisterServiceCtrlHandlerA, <.lpServiceName, .lpHandlerProc>,  'RegisterServiceCtrlHandlerA',  \
    RegisterServiceCtrlHandlerExA, <.lpServiceName, .lpHandlerProc, .lpContext>,  'RegisterServiceCtrlHandlerExA',  \
    RegisterServiceCtrlHandlerExW, <.lpServiceName, .lpHandlerProc, .lpContext>,  'RegisterServiceCtrlHandlerExW',  \
    RegisterServiceCtrlHandlerW, <.lpServiceName, .lpHandlerProc>,  'RegisterServiceCtrlHandlerW',  \
    RegisterTraceGuidsA, <NONE>,  'RegisterTraceGuidsA',  \
    RegisterTraceGuidsW, <NONE>,  'RegisterTraceGuidsW',  \
    RemoveTraceCallback, <NONE>,  'RemoveTraceCallback',  \
    RemoveUsersFromEncryptedFile, <.lpFileName, .pHashes>,  'RemoveUsersFromEncryptedFile',  \
    ReportEventA, <.hEventLog, .wType, .wCategory, .dwEventID, .lpUserSid, .wNumStrings, .dwDataSize, .lpStrings, .lpRawData>,  'ReportEventA',  \
    ReportEventW, <.hEventLog, .wType, .wCategory, .dwEventID, .lpUserSid, .wNumStrings, .dwDataSize, .lpStrings, .lpRawData>,  'ReportEventW',  \
    RevertToSelf, <VOID>,  'RevertToSelf',  \
    SaferCloseLevel, <NONE>,  'SaferCloseLevel',  \
    SaferComputeTokenFromLevel, <NONE>,  'SaferComputeTokenFromLevel',  \
    SaferCreateLevel, <NONE>,  'SaferCreateLevel',  \
    SaferGetLevelInformation, <NONE>,  'SaferGetLevelInformation',  \
    SaferGetPolicyInformation, <NONE>,  'SaferGetPolicyInformation',  \
    SaferIdentifyLevel, <NONE>,  'SaferIdentifyLevel',  \
    SaferRecordEventLogEntry, <NONE>,  'SaferRecordEventLogEntry',  \
    SaferSetLevelInformation, <NONE>,  'SaferSetLevelInformation',  \
    SaferSetPolicyInformation, <NONE>,  'SaferSetPolicyInformation',  \
    SaferiChangeRegistryScope, <NONE>,  'SaferiChangeRegistryScope',  \
    SaferiCompareTokenLevels, <NONE>,  'SaferiCompareTokenLevels',  \
    SaferiIsExecutableFileType, <NONE>,  'SaferiIsExecutableFileType',  \
    SaferiPopulateDefaultsInRegistry, <NONE>,  'SaferiPopulateDefaultsInRegistry',  \
    SaferiRecordEventLogEntry, <NONE>,  'SaferiRecordEventLogEntry',  \
    SaferiReplaceProcessThreadTokens, <NONE>,  'SaferiReplaceProcessThreadTokens',  \
    SaferiSearchMatchingHashRules, <NONE>,  'SaferiSearchMatchingHashRules',  \
    SetAclInformation, <.pAcl, .pAclInformation, .nAclInformationLength, .dwAclInformationClass>,  'SetAclInformation',  \
    SetEntriesInAccessListA, <NONE>,  'SetEntriesInAccessListA',  \
    SetEntriesInAccessListW, <NONE>,  'SetEntriesInAccessListW',  \
    SetEntriesInAclA, <.cCountOfExplicitEntries, .pListOfExplicitEntries, .OldAcl, .NewAcl>,  'SetEntriesInAclA',  \
    SetEntriesInAclW, <.cCountOfExplicitEntries, .pListOfExplicitEntries, .OldAcl, .NewAcl>,  'SetEntriesInAclW',  \
    SetEntriesInAuditListA, <NONE>,  'SetEntriesInAuditListA',  \
    SetEntriesInAuditListW, <NONE>,  'SetEntriesInAuditListW',  \
    SetFileSecurityA, <.lpFileName, .SecurityInformation, .pSecurityDescriptor>,  'SetFileSecurityA',  \
    SetFileSecurityW, <.lpFileName, .SecurityInformation, .pSecurityDescriptor>,  'SetFileSecurityW',  \
    SetInformationCodeAuthzLevelW, <NONE>,  'SetInformationCodeAuthzLevelW',  \
    SetInformationCodeAuthzPolicyW, <NONE>,  'SetInformationCodeAuthzPolicyW',  \
    SetKernelObjectSecurity, <.Handle, .SecurityInformation, .SecurityDescriptor>,  'SetKernelObjectSecurity',  \
    SetNamedSecurityInfoA, <.pObjectName, .ObjectType, .SecurityInfo, .psidOwner, .psidGroup, .pDacl, .pSacl>,  'SetNamedSecurityInfoA',  \
    SetNamedSecurityInfoExA, <NONE>,  'SetNamedSecurityInfoExA',  \
    SetNamedSecurityInfoExW, <NONE>,  'SetNamedSecurityInfoExW',  \
    SetNamedSecurityInfoW, <.pObjectName, .ObjectType, .SecurityInfo, .psidOwner, .psidGroup, .pDacl, .pSacl>,  'SetNamedSecurityInfoW',  \
    SetPrivateObjectSecurity, <.SecurityInformation, .ModificationDescriptor, .ObjectsSecurityDescriptor, .GenericMapping, .Token,  \
      >,  'SetPrivateObjectSecurity',  \
    SetPrivateObjectSecurityEx, <.SecurityInformation, .ModificationDescriptor, .ObjectsSecurityDescriptor, .AutoInheritFlags, .GenericMapping,  \
        .Token>,  'SetPrivateObjectSecurityEx',  \
    SetSecurityDescriptorControl, <.pSecurityDescriptor, .ControlBitsOfInterest, .ControlBitsToSet>,  'SetSecurityDescriptorControl',  \
    SetSecurityDescriptorDacl, <.pSecurityDescriptor, .bDaclPresent, .pDacl, .bDaclDefaulted>,  'SetSecurityDescriptorDacl',  \
    SetSecurityDescriptorGroup, <.pSecurityDescriptor, .pGroup, .bGroupDefaulted>,  'SetSecurityDescriptorGroup',  \
    SetSecurityDescriptorOwner, <.pSecurityDescriptor, .pOwner, .bOwnerDefaulted>,  'SetSecurityDescriptorOwner',  \
    SetSecurityDescriptorRMControl, <.SecurityDescriptor, .RMControl>,  'SetSecurityDescriptorRMControl',  \
    SetSecurityDescriptorSacl, <.pSecurityDescriptor, .bSaclPresent, .pSacl, .bSaclDefaulted>,  'SetSecurityDescriptorSacl',  \
    SetSecurityInfo, <.handle, .ObjectType, .SecurityInfo, .psidOwner, .psidGroup, .pDacl, .pSacl>,  'SetSecurityInfo',  \
    SetSecurityInfoExA, <NONE>,  'SetSecurityInfoExA',  \
    SetSecurityInfoExW, <NONE>,  'SetSecurityInfoExW',  \
    SetServiceBits, <.hServiceStatus, .dwServiceBits, .bSetBitsOn, .bUpdateImmediately>,  'SetServiceBits',  \
    SetServiceObjectSecurity, <.hService, .dwSecurityInformation, .lpSecurityDescriptor>,  'SetServiceObjectSecurity',  \
    SetServiceStatus, <.hServiceStatus, .lpServiceStatus>,  'SetServiceStatus',  \
    SetThreadToken, <.Thread, .Token>,  'SetThreadToken',  \
    SetTokenInformation, <.TokenHandle, .TokenInformationClass, .TokenInformation, .TokenInformationLength>,  'SetTokenInformation',  \
    SetTraceCallback, <NONE>,  'SetTraceCallback',  \
    SetUserFileEncryptionKey, <.pEncryptionCertificate>,  'SetUserFileEncryptionKey',  \
    StartServiceA, <.hService, .dwNumServiceArgs, .lpServiceArgVectors>,  'StartServiceA',  \
    StartServiceCtrlDispatcherA, <.lpServiceStartTable>,  'StartServiceCtrlDispatcherA',  \
    StartServiceCtrlDispatcherW, <.lpServiceStartTable>,  'StartServiceCtrlDispatcherW',  \
    StartServiceW, <.hService, .dwNumServiceArgs, .lpServiceArgVectors>,  'StartServiceW',  \
    StartTraceA, <NONE>,  'StartTraceA',  \
    StartTraceW, <NONE>,  'StartTraceW',  \
    StopTraceA, <NONE>,  'StopTraceA',  \
    StopTraceW, <NONE>,  'StopTraceW',  \
    SynchronizeWindows31FilesAndWindowsNTRegistry, <NONE>,  'SynchronizeWindows31FilesAndWindowsNTRegistry',  \
    SystemFunction001, <NONE>,  'SystemFunction001',  \
    SystemFunction002, <NONE>,  'SystemFunction002',  \
    SystemFunction003, <NONE>,  'SystemFunction003',  \
    SystemFunction004, <NONE>,  'SystemFunction004',  \
    SystemFunction005, <NONE>,  'SystemFunction005',  \
    SystemFunction006, <NONE>,  'SystemFunction006',  \
    SystemFunction007, <NONE>,  'SystemFunction007',  \
    SystemFunction008, <NONE>,  'SystemFunction008',  \
    SystemFunction009, <NONE>,  'SystemFunction009',  \
    SystemFunction010, <NONE>,  'SystemFunction010',  \
    SystemFunction011, <NONE>,  'SystemFunction011',  \
    SystemFunction012, <NONE>,  'SystemFunction012',  \
    SystemFunction013, <NONE>,  'SystemFunction013',  \
    SystemFunction014, <NONE>,  'SystemFunction014',  \
    SystemFunction015, <NONE>,  'SystemFunction015',  \
    SystemFunction016, <NONE>,  'SystemFunction016',  \
    SystemFunction017, <NONE>,  'SystemFunction017',  \
    SystemFunction018, <NONE>,  'SystemFunction018',  \
    SystemFunction019, <NONE>,  'SystemFunction019',  \
    SystemFunction020, <NONE>,  'SystemFunction020',  \
    SystemFunction021, <NONE>,  'SystemFunction021',  \
    SystemFunction022, <NONE>,  'SystemFunction022',  \
    SystemFunction023, <NONE>,  'SystemFunction023',  \
    SystemFunction024, <NONE>,  'SystemFunction024',  \
    SystemFunction025, <NONE>,  'SystemFunction025',  \
    SystemFunction026, <NONE>,  'SystemFunction026',  \
    SystemFunction027, <NONE>,  'SystemFunction027',  \
    SystemFunction028, <NONE>,  'SystemFunction028',  \
    SystemFunction029, <NONE>,  'SystemFunction029',  \
    SystemFunction030, <NONE>,  'SystemFunction030',  \
    SystemFunction031, <NONE>,  'SystemFunction031',  \
    SystemFunction032, <NONE>,  'SystemFunction032',  \
    SystemFunction033, <NONE>,  'SystemFunction033',  \
    SystemFunction034, <NONE>,  'SystemFunction034',  \
    SystemFunction035, <NONE>,  'SystemFunction035',  \
    SystemFunction036, <NONE>,  'SystemFunction036',  \
    SystemFunction040, <NONE>,  'SystemFunction040',  \
    SystemFunction041, <NONE>,  'SystemFunction041',  \
    TraceEvent, <NONE>,  'TraceEvent',  \
    TraceEventInstance, <NONE>,  'TraceEventInstance',  \
    TraceMessage, <NONE>,  'TraceMessage',  \
    TraceMessageVa, <NONE>,  'TraceMessageVa',  \
    TreeResetNamedSecurityInfoA, <.pObjectName, .ObjectType, .SecurityInfo, .pOwner, .pGroup, .pDacl, .pSacl, .KeepExplicit, .fnProgress,  \
        .ProgressInvokeSetting, .Args>,  'TreeResetNamedSecurityInfoA',  \
    TreeResetNamedSecurityInfoW, <.pObjectName, .ObjectType, .SecurityInfo, .pOwner, .pGroup, .pDacl, .pSacl, .KeepExplicit, .fnProgress,  \
        .ProgressInvokeSetting, .Args>,  'TreeResetNamedSecurityInfoW',  \
    TrusteeAccessToObjectA, <NONE>,  'TrusteeAccessToObjectA',  \
    TrusteeAccessToObjectW, <NONE>,  'TrusteeAccessToObjectW',  \
    UninstallApplication, <NONE>,  'UninstallApplication',  \
    UnlockServiceDatabase, <.ScLock>,  'UnlockServiceDatabase',  \
    UnregisterIdleTask, <NONE>,  'UnregisterIdleTask',  \
    UnregisterTraceGuids, <NONE>,  'UnregisterTraceGuids',  \
    UpdateTraceA, <NONE>,  'UpdateTraceA',  \
    UpdateTraceW, <NONE>,  'UpdateTraceW',  \
    WdmWmiServiceMain, <NONE>,  'WdmWmiServiceMain',  \
    WmiCloseBlock, <NONE>,  'WmiCloseBlock',  \
    WmiCloseTraceWithCursor, <NONE>,  'WmiCloseTraceWithCursor',  \
    WmiConvertTimestamp, <NONE>,  'WmiConvertTimestamp',  \
    WmiDevInstToInstanceNameA, <NONE>,  'WmiDevInstToInstanceNameA',  \
    WmiDevInstToInstanceNameW, <NONE>,  'WmiDevInstToInstanceNameW',  \
    WmiEnumerateGuids, <NONE>,  'WmiEnumerateGuids',  \
    WmiExecuteMethodA, <NONE>,  'WmiExecuteMethodA',  \
    WmiExecuteMethodW, <NONE>,  'WmiExecuteMethodW',  \
    WmiFileHandleToInstanceNameA, <NONE>,  'WmiFileHandleToInstanceNameA',  \
    WmiFileHandleToInstanceNameW, <NONE>,  'WmiFileHandleToInstanceNameW',  \
    WmiFreeBuffer, <NONE>,  'WmiFreeBuffer',  \
    WmiGetFirstTraceOffset, <NONE>,  'WmiGetFirstTraceOffset',  \
    WmiGetNextEvent, <NONE>,  'WmiGetNextEvent',  \
    WmiGetTraceHeader, <NONE>,  'WmiGetTraceHeader',  \
    WmiMofEnumerateResourcesA, <NONE>,  'WmiMofEnumerateResourcesA',  \
    WmiMofEnumerateResourcesW, <NONE>,  'WmiMofEnumerateResourcesW',  \
    WmiNotificationRegistrationA, <NONE>,  'WmiNotificationRegistrationA',  \
    WmiNotificationRegistrationW, <NONE>,  'WmiNotificationRegistrationW',  \
    WmiOpenBlock, <NONE>,  'WmiOpenBlock',  \
    WmiOpenTraceWithCursor, <NONE>,  'WmiOpenTraceWithCursor',  \
    WmiParseTraceEvent, <NONE>,  'WmiParseTraceEvent',  \
    WmiQueryAllDataA, <NONE>,  'WmiQueryAllDataA',  \
    WmiQueryAllDataMultipleA, <NONE>,  'WmiQueryAllDataMultipleA',  \
    WmiQueryAllDataMultipleW, <NONE>,  'WmiQueryAllDataMultipleW',  \
    WmiQueryAllDataW, <NONE>,  'WmiQueryAllDataW',  \
    WmiQueryGuidInformation, <NONE>,  'WmiQueryGuidInformation',  \
    WmiQuerySingleInstanceA, <NONE>,  'WmiQuerySingleInstanceA',  \
    WmiQuerySingleInstanceMultipleA, <NONE>,  'WmiQuerySingleInstanceMultipleA',  \
    WmiQuerySingleInstanceMultipleW, <NONE>,  'WmiQuerySingleInstanceMultipleW',  \
    WmiQuerySingleInstanceW, <NONE>,  'WmiQuerySingleInstanceW',  \
    WmiReceiveNotificationsA, <NONE>,  'WmiReceiveNotificationsA',  \
    WmiReceiveNotificationsW, <NONE>,  'WmiReceiveNotificationsW',  \
    WmiSetSingleInstanceA, <NONE>,  'WmiSetSingleInstanceA',  \
    WmiSetSingleInstanceW, <NONE>,  'WmiSetSingleInstanceW',  \
    WmiSetSingleItemA, <NONE>,  'WmiSetSingleItemA',  \
    WmiSetSingleItemW, <NONE>,  'WmiSetSingleItemW',  \
    Wow64Win32ApiEntry, <NONE>,  'Wow64Win32ApiEntry',  \
    WriteEncryptedFileRaw, <.pfImportCallback, .pvCallbackContext, .pvContext>,  'WriteEncryptedFileRaw'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/imports/Win32/comctl32.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: comctl32.dll API calls
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

import_proto comctl32,  \
    AddMRUStringW, <NONE>,  'AddMRUStringW',  \
    CreateMRUListW, <NONE>,  'CreateMRUListW',  \
    CreateMappedBitmap, <.hInstance, .idBitmap, .wFlags, .lpColorMap, .ByValumMaps>,  'CreateMappedBitmap',  \
    CreatePropertySheetPage, <.lpcpropsheetpagea>,  'CreatePropertySheetPage',  \
    CreatePropertySheetPageA, <.lpcpropsheetpagea>,  'CreatePropertySheetPageA',  \
    CreatePropertySheetPageW, <.lpcpropsheetpagea>,  'CreatePropertySheetPageW',  \
    CreateStatusWindow, <.dwStyle, .lpszText, .hWndParent, .wID>,  'CreateStatusWindow',  \
    CreateStatusWindowA, <.dwStyle, .lpszText, .hWndParent, .wID>,  'CreateStatusWindowA',  \
    CreateStatusWindowW, <.dwStyle, .lpszText, .hWndParent, .wID>,  'CreateStatusWindowW',  \
    CreateToolbar, <NONE>,  'CreateToolbar',  \
    CreateToolbarEx, <.hWndParent, .dwStyle, .wID, .nBitmaps, .hBMInst, .wBMID, .lpButtons, .iNumButtons, .dxButton, .dyButton, .dxBitmap,  \
        .dyBitmap, .uStructSize>,  'CreateToolbarEx',  \
    CreateUpDownControl, <.dwStyle, .x, .y, .cx, .cy, .hParent, .nID, .hInst, .hBuddy, .nUpper, .nLower, .nPos>,  'CreateUpDownControl',  \
    DPA_Create, <NONE>,  'DPA_Create',  \
    DPA_DeleteAllPtrs, <NONE>,  'DPA_DeleteAllPtrs',  \
    DPA_DeletePtr, <NONE>,  'DPA_DeletePtr',  \
    DPA_Destroy, <NONE>,  'DPA_Destroy',  \
    DPA_DestroyCallback, <NONE>,  'DPA_DestroyCallback',  \
    DPA_EnumCallback, <NONE>,  'DPA_EnumCallback',  \
    DPA_GetPtr, <NONE>,  'DPA_GetPtr',  \
    DPA_InsertPtr, <NONE>,  'DPA_InsertPtr',  \
    DPA_Search, <NONE>,  'DPA_Search',  \
    DPA_SetPtr, <NONE>,  'DPA_SetPtr',  \
    DPA_Sort, <NONE>,  'DPA_Sort',  \
    DSA_Create, <NONE>,  'DSA_Create',  \
    DSA_DeleteAllItems, <NONE>,  'DSA_DeleteAllItems',  \
    DSA_Destroy, <NONE>,  'DSA_Destroy',  \
    DSA_DestroyCallback, <NONE>,  'DSA_DestroyCallback',  \
    DSA_GetItemPtr, <NONE>,  'DSA_GetItemPtr',  \
    DSA_InsertItem, <NONE>,  'DSA_InsertItem',  \
    DefSubclassProc, <NONE>,  'DefSubclassProc',  \
    DestroyPropertySheetPage, <.hpropsheetpage>,  'DestroyPropertySheetPage',  \
    DrawInsert, <.handParent, .hLB, .nItem>,  'DrawInsert',  \
    DrawStatusText, <.hDC, .lprc, .pszText, .uFlags>,  'DrawStatusText',  \
    DrawStatusTextA, <.hDC, .lprc, .pszText, .uFlags>,  'DrawStatusTextA',  \
    DrawStatusTextW, <.hDC, .lprc, .pszText, .uFlags>,  'DrawStatusTextW',  \
    EnumMRUListW, <NONE>,  'EnumMRUListW',  \
    FlatSB_EnableScrollBar, <.hwnd, .ByValt, .uint>,  'FlatSB_EnableScrollBar',  \
    FlatSB_GetScrollInfo, <.hwnd, .code, .lpscrollinfo>,  'FlatSB_GetScrollInfo',  \
    FlatSB_GetScrollPos, <.hwnd, .code>,  'FlatSB_GetScrollPos',  \
    FlatSB_GetScrollProp, <.hwnd, .propIndex, .lpint>,  'FlatSB_GetScrollProp',  \
    FlatSB_GetScrollRange, <.hwnd, .code, .lpint>,  'FlatSB_GetScrollRange',  \
    FlatSB_SetScrollInfo, <.hwnd, .code, .lpscrollinfo, .fRedraw>,  'FlatSB_SetScrollInfo',  \
    FlatSB_SetScrollPos, <.hwnd, .code, .pos, .fRedraw>,  'FlatSB_SetScrollPos',  \
    FlatSB_SetScrollProp, <.hwnd, .index, .newValue, .bool>,  'FlatSB_SetScrollProp',  \
    FlatSB_SetScrollRange, <.hwnd, .code, .min, .max, .fRedraw>,  'FlatSB_SetScrollRange',  \
    FlatSB_ShowScrollBar, <.hwnd, .code, .bool>,  'FlatSB_ShowScrollBar',  \
    FreeMRUList, <NONE>,  'FreeMRUList',  \
    GetEffectiveClientRect, <.hWnd, .lprc, .lpInfo>,  'GetEffectiveClientRect',  \
    GetMUILanguage, <VOID>,  'GetMUILanguage',  \
    ImageList_Add, <.himl, .hbmImage, .hbmMask>,  'ImageList_Add',  \
    ImageList_AddIcon, <NONE>,  'ImageList_AddIcon',  \
    ImageList_AddMasked, <.himl, .hbmImage, .crMask>,  'ImageList_AddMasked',  \
    ImageList_BeginDrag, <.himlTrack, .iTrack, .dxHotspot, .dyHotspot>,  'ImageList_BeginDrag',  \
    ImageList_Copy, <.himlDst, .iDst, .himlSrc, .iSrc, .uFlags>,  'ImageList_Copy',  \
    ImageList_Create, <.cx, .cy, .flags, .cInitial, .cGrow>,  'ImageList_Create',  \
    ImageList_Destroy, <.himl>,  'ImageList_Destroy',  \
    ImageList_DragEnter, <.hwndLock, .x, .y>,  'ImageList_DragEnter',  \
    ImageList_DragLeave, <.hWndOwner>,  'ImageList_DragLeave',  \
    ImageList_DragMove, <.x, .y>,  'ImageList_DragMove',  \
    ImageList_DragShowNolock, <.fBoolean>,  'ImageList_DragShowNolock',  \
    ImageList_Draw, <.himl, .i, .hdcDst, .x, .y, .fStyle>,  'ImageList_Draw',  \
    ImageList_DrawEx, <.himl, .i, .hdcDst, .x, .y, .dx, .dy, .rgbBk, .rgbFg, .fStyle>,  'ImageList_DrawEx',  \
    ImageList_DrawIndirect, <.pimldp>,  'ImageList_DrawIndirect',  \
    ImageList_Duplicate, <.himl>,  'ImageList_Duplicate',  \
    ImageList_EndDrag, <VOID>,  'ImageList_EndDrag',  \
    ImageList_GetBkColor, <.himl>,  'ImageList_GetBkColor',  \
    ImageList_GetDragImage, <.ppt, .pptHotspot>,  'ImageList_GetDragImage',  \
    ImageList_GetFlags, <NONE>,  'ImageList_GetFlags',  \
    ImageList_GetIcon, <.himl, .i, .flags>,  'ImageList_GetIcon',  \
    ImageList_GetIconSize, <.himl, .cx, .cy>,  'ImageList_GetIconSize',  \
    ImageList_GetImageCount, <.himl>,  'ImageList_GetImageCount',  \
    ImageList_GetImageInfo, <.himl, .i, .pImageInfo>,  'ImageList_GetImageInfo',  \
    ImageList_GetImageRect, <NONE>,  'ImageList_GetImageRect',  \
    ImageList_LoadImage, <.hInst, .lpszbmp, .cx, .cGrow, .crMask, .uType, .uFlags>,  'ImageList_LoadImage',  \
    ImageList_LoadImageA, <.hInst, .lpszbmp, .cx, .cGrow, .crMask, .uType, .uFlags>,  'ImageList_LoadImageA',  \
    ImageList_LoadImageW, <.hInst, .lpszbmp, .cx, .cGrow, .crMask, .uType, .uFlags>,  'ImageList_LoadImageW',  \
    ImageList_Merge, <.himl1, .i1, .himl2, .i2, .dx, .dy>,  'ImageList_Merge',  \
    ImageList_Read, <.pstm>,  'ImageList_Read',  \
    ImageList_Remove, <.himl, .i>,  'ImageList_Remove',  \
    ImageList_Replace, <.himl, .i, .hbmImage, .hbmMask>,  'ImageList_Replace',  \
    ImageList_ReplaceIcon, <.himl, .i, .hicon>,  'ImageList_ReplaceIcon',  \
    ImageList_SetBkColor, <.himl, .clrBk>,  'ImageList_SetBkColor',  \
    ImageList_SetDragCursorImage, <.himlDrag, .iDrag, .dxHotspot, .dyHotspot>,  'ImageList_SetDragCursorImage',  \
    ImageList_SetFilter, <NONE>,  'ImageList_SetFilter',  \
    ImageList_SetFlags, <NONE>,  'ImageList_SetFlags',  \
    ImageList_SetIconSize, <.himl, .cx, .cy>,  'ImageList_SetIconSize',  \
    ImageList_SetImageCount, <.himl, .uNewCount>,  'ImageList_SetImageCount',  \
    ImageList_SetOverlayImage, <.himl, .iImage, .iOverlay>,  'ImageList_SetOverlayImage',  \
    ImageList_Write, <.himl, .pstm>,  'ImageList_Write',  \
    InitCommonControls, <VOID>,  'InitCommonControls',  \
    InitCommonControlsEx, <.pIcce>,  'InitCommonControlsEx',  \
    InitMUILanguage, <.uiLang>,  'InitMUILanguage',  \
    InitializeFlatSB, <.hwnd>,  'InitializeFlatSB',  \
    LBItemFromPt, <.hLB, .pt, .bAutoScroll>,  'LBItemFromPt',  \
    MakeDragList, <.hLB>,  'MakeDragList',  \
    MenuHelp, <.uMsg, .wParam, .lParam, .hMainMenu, .hInst, .hwndStatus, .lpwIDs>,  'MenuHelp',  \
    PropertySheet, <.lpcpropsheetheadera>,  'PropertySheet',  \
    PropertySheetA, <.lpcpropsheetheadera>,  'PropertySheetA',  \
    PropertySheetW, <.lpcpropsheetheadera>,  'PropertySheetW',  \
    RemoveWindowSubclass, <NONE>,  'RemoveWindowSubclass',  \
    SetWindowSubclass, <NONE>,  'SetWindowSubclass',  \
    ShowHideMenuCtl, <.hWnd, .uFlags, .lpInfo>,  'ShowHideMenuCtl',  \
    Str_SetPtrW, <NONE>,  'Str_SetPtrW',  \
    UninitializeFlatSB, <.hwnd>,  'UninitializeFlatSB',  \
    _TrackMouseEvent, <NONE>,  '_TrackMouseEvent'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































Deleted freshlib/imports/Win32/comdlg32.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: comdlg32.dll API calls
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

import_proto comdlg32,  \
    ChooseColorA, <.pChoosecolor>,  'ChooseColorA',  \
    ChooseColorW, <.pChoosecolor>,  'ChooseColorW',  \
    ChooseFontA, <.pChoosefont>,  'ChooseFontA',  \
    ChooseFontW, <.pChoosefont>,  'ChooseFontW',  \
    CommDlgExtendedError, <VOID>,  'CommDlgExtendedError',  \
    FindTextA, <.pFindreplace>,  'FindTextA',  \
    FindTextW, <.pFindreplace>,  'FindTextW',  \
    GetFileTitleA, <.lpszFile, .lpszTitle, .cbBuf>,  'GetFileTitleA',  \
    GetFileTitleW, <.lpszFile, .lpszTitle, .cbBuf>,  'GetFileTitleW',  \
    GetOpenFileNameA, <.pOpenfilename>,  'GetOpenFileNameA',  \
    GetOpenFileNameW, <.pOpenfilename>,  'GetOpenFileNameW',  \
    GetSaveFileNameA, <.pOpenfilename>,  'GetSaveFileNameA',  \
    GetSaveFileNameW, <.pOpenfilename>,  'GetSaveFileNameW',  \
    LoadAlterBitmap, <NONE>,  'LoadAlterBitmap',  \
    PageSetupDlgA, <.pPagesetupdlg>,  'PageSetupDlgA',  \
    PageSetupDlgW, <.pPagesetupdlg>,  'PageSetupDlgW',  \
    PrintDlgA, <.pPrintdlg>,  'PrintDlgA',  \
    PrintDlgExA, <.TLPPRINTDLGEXA>,  'PrintDlgExA',  \
    PrintDlgExW, <.TLPPRINTDLGEXA>,  'PrintDlgExW',  \
    PrintDlgW, <.pPrintdlg>,  'PrintDlgW',  \
    ReplaceTextA, <.pFindreplace>,  'ReplaceTextA',  \
    ReplaceTextW, <.pFindreplace>,  'ReplaceTextW',  \
    Ssync_ANSI_UNICODE_Struct_For_WOW, <NONE>,  'Ssync_ANSI_UNICODE_Struct_For_WOW',  \
    WantArrows, <NONE>,  'WantArrows',  \
    dwLBSubclass, <NONE>,  'dwLBSubclass',  \
    dwOKSubclass, <NONE>,  'dwOKSubclass'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































Deleted freshlib/imports/Win32/crtdll.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: crtdll.dll API calls
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


import_proto crtdll,  \
    _CIacos, <NONE>,  '_CIacos',  \
    _CIasin, <NONE>,  '_CIasin',  \
    _CIatan, <NONE>,  '_CIatan',  \
    _CIatan2, <NONE>,  '_CIatan2',  \
    _CIcos, <NONE>,  '_CIcos',  \
    _CIcosh, <NONE>,  '_CIcosh',  \
    _CIexp, <NONE>,  '_CIexp',  \
    _CIfmod, <NONE>,  '_CIfmod',  \
    _CIlog, <NONE>,  '_CIlog',  \
    _CIlog10, <NONE>,  '_CIlog10',  \
    _CIpow, <NONE>,  '_CIpow',  \
    _CIsin, <NONE>,  '_CIsin',  \
    _CIsinh, <NONE>,  '_CIsinh',  \
    _CIsqrt, <NONE>,  '_CIsqrt',  \
    _CItan, <NONE>,  '_CItan',  \
    _CItanh, <NONE>,  '_CItanh',  \
    _HUGE_dll, <NONE>,  '_HUGE_dll',  \
    _XcptFilter, <NONE>,  '_XcptFilter',  \
    __GetMainArgs, <NONE>,  '__GetMainArgs',  \
    __argc_dll, <NONE>,  '__argc_dll',  \
    __argv_dll, <NONE>,  '__argv_dll',  \
    __dllonexit, <NONE>,  '__dllonexit',  \
    __doserrno, <NONE>,  '__doserrno',  \
    __fpecode, <NONE>,  '__fpecode',  \
    __isascii, <NONE>,  '__isascii',  \
    __iscsym, <NONE>,  '__iscsym',  \
    __iscsymf, <NONE>,  '__iscsymf',  \
    __mb_cur_max_dll, <NONE>,  '__mb_cur_max_dll',  \
    __pxcptinfoptrs, <NONE>,  '__pxcptinfoptrs',  \
    __threadhandle, <NONE>,  '__threadhandle',  \
    __threadid, <NONE>,  '__threadid',  \
    __toascii, <NONE>,  '__toascii',  \
    _abnormal_termination, <NONE>,  '_abnormal_termination',  \
    _access, <NONE>,  '_access',  \
    _acmdln_dll, <NONE>,  '_acmdln_dll',  \
    _aexit_rtn_dll, <NONE>,  '_aexit_rtn_dll',  \
    _amsg_exit, <NONE>,  '_amsg_exit',  \
    _assert, <NONE>,  '_assert',  \
    _basemajor_dll, <NONE>,  '_basemajor_dll',  \
    _baseminor_dll, <NONE>,  '_baseminor_dll',  \
    _baseversion_dll, <NONE>,  '_baseversion_dll',  \
    _beep, <NONE>,  '_beep',  \
    _beginthread, <NONE>,  '_beginthread',  \
    _c_exit, <NONE>,  '_c_exit',  \
    _cabs, <NONE>,  '_cabs',  \
    _cexit, <NONE>,  '_cexit',  \
    _cgets, <NONE>,  '_cgets',  \
    _chdir, <NONE>,  '_chdir',  \
    _chdrive, <NONE>,  '_chdrive',  \
    _chgsign, <NONE>,  '_chgsign',  \
    _chmod, <NONE>,  '_chmod',  \
    _chsize, <NONE>,  '_chsize',  \
    _clearfp, <NONE>,  '_clearfp',  \
    _commit, <NONE>,  '_commit',  \
    _commode_dll, <NONE>,  '_commode_dll',  \
    _control87, <NONE>,  '_control87',  \
    _controlfp, <NONE>,  '_controlfp',  \
    _copysign, <NONE>,  '_copysign',  \
    _cprintf, <NONE>,  '_cprintf',  \
    _cpumode_dll, <NONE>,  '_cpumode_dll',  \
    _cputs, <NONE>,  '_cputs',  \
    _cscanf, <NONE>,  '_cscanf',  \
    _ctype, <NONE>,  '_ctype',  \
    _cwait, <NONE>,  '_cwait',  \
    _daylight_dll, <NONE>,  '_daylight_dll',  \
    _dup, <NONE>,  '_dup',  \
    _dup2, <NONE>,  '_dup2',  \
    _ecvt, <NONE>,  '_ecvt',  \
    _endthread, <NONE>,  '_endthread',  \
    _environ_dll, <NONE>,  '_environ_dll',  \
    _eof, <NONE>,  '_eof',  \
    _errno, <NONE>,  '_errno',  \
    _except_handler2, <NONE>,  '_except_handler2',  \
    _execl, <NONE>,  '_execl',  \
    _execle, <NONE>,  '_execle',  \
    _execlp, <NONE>,  '_execlp',  \
    _execlpe, <NONE>,  '_execlpe',  \
    _execv, <NONE>,  '_execv',  \
    _execve, <NONE>,  '_execve',  \
    _execvp, <NONE>,  '_execvp',  \
    _execvpe, <NONE>,  '_execvpe',  \
    _exit, <NONE>,  '_exit',  \
    _expand, <NONE>,  '_expand',  \
    _fcloseall, <NONE>,  '_fcloseall',  \
    _fcvt, <NONE>,  '_fcvt',  \
    _fdopen, <NONE>,  '_fdopen',  \
    _fgetchar, <NONE>,  '_fgetchar',  \
    _fgetwchar, <NONE>,  '_fgetwchar',  \
    _filbuf, <NONE>,  '_filbuf',  \
    _fileinfo_dll, <NONE>,  '_fileinfo_dll',  \
    _filelength, <NONE>,  '_filelength',  \
    _fileno, <NONE>,  '_fileno',  \
    _findclose, <NONE>,  '_findclose',  \
    _findfirst, <NONE>,  '_findfirst',  \
    _findnext, <NONE>,  '_findnext',  \
    _finite, <NONE>,  '_finite',  \
    _flsbuf, <NONE>,  '_flsbuf',  \
    _flushall, <NONE>,  '_flushall',  \
    _fmode_dll, <NONE>,  '_fmode_dll',  \
    _fpclass, <NONE>,  '_fpclass',  \
    _fpieee_flt, <NONE>,  '_fpieee_flt',  \
    _fpreset, <NONE>,  '_fpreset',  \
    _fputchar, <NONE>,  '_fputchar',  \
    _fputwchar, <NONE>,  '_fputwchar',  \
    _fsopen, <NONE>,  '_fsopen',  \
    _fstat, <NONE>,  '_fstat',  \
    _ftime, <NONE>,  '_ftime',  \
    _ftol, <NONE>,  '_ftol',  \
    _fullpath, <NONE>,  '_fullpath',  \
    _futime, <NONE>,  '_futime',  \
    _gcvt, <NONE>,  '_gcvt',  \
    _get_osfhandle, <NONE>,  '_get_osfhandle',  \
    _getch, <NONE>,  '_getch',  \
    _getche, <NONE>,  '_getche',  \
    _getcwd, <NONE>,  '_getcwd',  \
    _getdcwd, <NONE>,  '_getdcwd',  \
    _getdiskfree, <NONE>,  '_getdiskfree',  \
    _getdllprocaddr, <NONE>,  '_getdllprocaddr',  \
    _getdrive, <NONE>,  '_getdrive',  \
    _getdrives, <NONE>,  '_getdrives',  \
    _getpid, <NONE>,  '_getpid',  \
    _getsystime, <NONE>,  '_getsystime',  \
    _getw, <NONE>,  '_getw',  \
    _global_unwind2, <NONE>,  '_global_unwind2',  \
    _heapchk, <NONE>,  '_heapchk',  \
    _heapmin, <NONE>,  '_heapmin',  \
    _heapset, <NONE>,  '_heapset',  \
    _heapwalk, <NONE>,  '_heapwalk',  \
    _hypot, <NONE>,  '_hypot',  \
    _initterm, <NONE>,  '_initterm',  \
    _iob, <NONE>,  '_iob',  \
    _isatty, <NONE>,  '_isatty',  \
    _isctype, <NONE>,  '_isctype',  \
    _ismbbalnum, <NONE>,  '_ismbbalnum',  \
    _ismbbalpha, <NONE>,  '_ismbbalpha',  \
    _ismbbgraph, <NONE>,  '_ismbbgraph',  \
    _ismbbkalnum, <NONE>,  '_ismbbkalnum',  \
    _ismbbkana, <NONE>,  '_ismbbkana',  \
    _ismbbkpunct, <NONE>,  '_ismbbkpunct',  \
    _ismbblead, <NONE>,  '_ismbblead',  \
    _ismbbprint, <NONE>,  '_ismbbprint',  \
    _ismbbpunct, <NONE>,  '_ismbbpunct',  \
    _ismbbtrail, <NONE>,  '_ismbbtrail',  \
    _ismbcalpha, <NONE>,  '_ismbcalpha',  \
    _ismbcdigit, <NONE>,  '_ismbcdigit',  \
    _ismbchira, <NONE>,  '_ismbchira',  \
    _ismbckata, <NONE>,  '_ismbckata',  \
    _ismbcl0, <NONE>,  '_ismbcl0',  \
    _ismbcl1, <NONE>,  '_ismbcl1',  \
    _ismbcl2, <NONE>,  '_ismbcl2',  \
    _ismbclegal, <NONE>,  '_ismbclegal',  \
    _ismbclower, <NONE>,  '_ismbclower',  \
    _ismbcprint, <NONE>,  '_ismbcprint',  \
    _ismbcspace, <NONE>,  '_ismbcspace',  \
    _ismbcsymbol, <NONE>,  '_ismbcsymbol',  \
    _ismbcupper, <NONE>,  '_ismbcupper',  \
    _ismbslead, <NONE>,  '_ismbslead',  \
    _ismbstrail, <NONE>,  '_ismbstrail',  \
    _isnan, <NONE>,  '_isnan',  \
    _itoa, <NONE>,  '_itoa',  \
    _itow, <NONE>,  '_itow',  \
    _j0, <NONE>,  '_j0',  \
    _j1, <NONE>,  '_j1',  \
    _jn, <NONE>,  '_jn',  \
    _kbhit, <NONE>,  '_kbhit',  \
    _lfind, <NONE>,  '_lfind',  \
    _loaddll, <NONE>,  '_loaddll',  \
    _local_unwind2, <NONE>,  '_local_unwind2',  \
    _locking, <NONE>,  '_locking',  \
    _logb, <NONE>,  '_logb',  \
    _lrotl, <NONE>,  '_lrotl',  \
    _lrotr, <NONE>,  '_lrotr',  \
    _lsearch, <NONE>,  '_lsearch',  \
    _ltoa, <NONE>,  '_ltoa',  \
    _ltow, <NONE>,  '_ltow',  \
    _makepath, <NONE>,  '_makepath',  \
    _matherr, <NONE>,  '_matherr',  \
    _mbbtombc, <NONE>,  '_mbbtombc',  \
    _mbbtype, <NONE>,  '_mbbtype',  \
    _mbccpy, <NONE>,  '_mbccpy',  \
    _mbcjistojms, <NONE>,  '_mbcjistojms',  \
    _mbcjmstojis, <NONE>,  '_mbcjmstojis',  \
    _mbclen, <NONE>,  '_mbclen',  \
    _mbctohira, <NONE>,  '_mbctohira',  \
    _mbctokata, <NONE>,  '_mbctokata',  \
    _mbctolower, <NONE>,  '_mbctolower',  \
    _mbctombb, <NONE>,  '_mbctombb',  \
    _mbctoupper, <NONE>,  '_mbctoupper',  \
    _mbctype, <NONE>,  '_mbctype',  \
    _mbsbtype, <NONE>,  '_mbsbtype',  \
    _mbscat, <NONE>,  '_mbscat',  \
    _mbschr, <NONE>,  '_mbschr',  \
    _mbscmp, <NONE>,  '_mbscmp',  \
    _mbscpy, <NONE>,  '_mbscpy',  \
    _mbscspn, <NONE>,  '_mbscspn',  \
    _mbsdec, <NONE>,  '_mbsdec',  \
    _mbsdup, <NONE>,  '_mbsdup',  \
    _mbsicmp, <NONE>,  '_mbsicmp',  \
    _mbsinc, <NONE>,  '_mbsinc',  \
    _mbslen, <NONE>,  '_mbslen',  \
    _mbslwr, <NONE>,  '_mbslwr',  \
    _mbsnbcat, <NONE>,  '_mbsnbcat',  \
    _mbsnbcmp, <NONE>,  '_mbsnbcmp',  \
    _mbsnbcnt, <NONE>,  '_mbsnbcnt',  \
    _mbsnbcpy, <NONE>,  '_mbsnbcpy',  \
    _mbsnbicmp, <NONE>,  '_mbsnbicmp',  \
    _mbsnbset, <NONE>,  '_mbsnbset',  \
    _mbsncat, <NONE>,  '_mbsncat',  \
    _mbsnccnt, <NONE>,  '_mbsnccnt',  \
    _mbsncmp, <NONE>,  '_mbsncmp',  \
    _mbsncpy, <NONE>,  '_mbsncpy',  \
    _mbsnextc, <NONE>,  '_mbsnextc',  \
    _mbsnicmp, <NONE>,  '_mbsnicmp',  \
    _mbsninc, <NONE>,  '_mbsninc',  \
    _mbsnset, <NONE>,  '_mbsnset',  \
    _mbspbrk, <NONE>,  '_mbspbrk',  \
    _mbsrchr, <NONE>,  '_mbsrchr',  \
    _mbsrev, <NONE>,  '_mbsrev',  \
    _mbsset, <NONE>,  '_mbsset',  \
    _mbsspn, <NONE>,  '_mbsspn',  \
    _mbsspnp, <NONE>,  '_mbsspnp',  \
    _mbsstr, <NONE>,  '_mbsstr',  \
    _mbstok, <NONE>,  '_mbstok',  \
    _mbstrlen, <NONE>,  '_mbstrlen',  \
    _mbsupr, <NONE>,  '_mbsupr',  \
    _memccpy, <NONE>,  '_memccpy',  \
    _memicmp, <NONE>,  '_memicmp',  \
    _mkdir, <NONE>,  '_mkdir',  \
    _mktemp, <NONE>,  '_mktemp',  \
    _msize, <NONE>,  '_msize',  \
    _nextafter, <NONE>,  '_nextafter',  \
    _onexit, <NONE>,  '_onexit',  \
    _open_osfhandle, <NONE>,  '_open_osfhandle',  \
    _osmajor_dll, <NONE>,  '_osmajor_dll',  \
    _osminor_dll, <NONE>,  '_osminor_dll',  \
    _osmode_dll, <NONE>,  '_osmode_dll',  \
    _osver_dll, <NONE>,  '_osver_dll',  \
    _osversion_dll, <NONE>,  '_osversion_dll',  \
    _pclose, <NONE>,  '_pclose',  \
    _pctype_dll, <NONE>,  '_pctype_dll',  \
    _pgmptr_dll, <NONE>,  '_pgmptr_dll',  \
    _pipe, <NONE>,  '_pipe',  \
    _popen, <NONE>,  '_popen',  \
    _purecall, <NONE>,  '_purecall',  \
    _putch, <NONE>,  '_putch',  \
    _putenv, <NONE>,  '_putenv',  \
    _putw, <NONE>,  '_putw',  \
    _pwctype_dll, <NONE>,  '_pwctype_dll',  \
    _rmdir, <NONE>,  '_rmdir',  \
    _rmtmp, <NONE>,  '_rmtmp',  \
    _rotl, <NONE>,  '_rotl',  \
    _rotr, <NONE>,  '_rotr',  \
    _scalb, <NONE>,  '_scalb',  \
    _searchenv, <NONE>,  '_searchenv',  \
    _seterrormode, <NONE>,  '_seterrormode',  \
    _setjmp, <NONE>,  '_setjmp',  \
    _setmode, <NONE>,  '_setmode',  \
    _setsystime, <NONE>,  '_setsystime',  \
    _sleep, <NONE>,  '_sleep',  \
    _snprintf, <NONE>,  '_snprintf',  \
    _snwprintf, <NONE>,  '_snwprintf',  \
    _sopen, <NONE>,  '_sopen',  \
    _spawnl, <NONE>,  '_spawnl',  \
    _spawnle, <NONE>,  '_spawnle',  \
    _spawnlp, <NONE>,  '_spawnlp',  \
    _spawnlpe, <NONE>,  '_spawnlpe',  \
    _spawnv, <NONE>,  '_spawnv',  \
    _spawnve, <NONE>,  '_spawnve',  \
    _spawnvp, <NONE>,  '_spawnvp',  \
    _spawnvpe, <NONE>,  '_spawnvpe',  \
    _splitpath, <NONE>,  '_splitpath',  \
    _stat, <NONE>,  '_stat',  \
    _statusfp, <NONE>,  '_statusfp',  \
    _strcmpi, <NONE>,  '_strcmpi',  \
    _strdate, <NONE>,  '_strdate',  \
    _strdec, <NONE>,  '_strdec',  \
    _strdup, <NONE>,  '_strdup',  \
    _strerror, <NONE>,  '_strerror',  \
    _stricmp, <NONE>,  '_stricmp',  \
    _stricoll, <NONE>,  '_stricoll',  \
    _strinc, <NONE>,  '_strinc',  \
    _strlwr, <NONE>,  '_strlwr',  \
    _strncnt, <NONE>,  '_strncnt',  \
    _strnextc, <NONE>,  '_strnextc',  \
    _strnicmp, <NONE>,  '_strnicmp',  \
    _strninc, <NONE>,  '_strninc',  \
    _strnset, <NONE>,  '_strnset',  \
    _strrev, <NONE>,  '_strrev',  \
    _strset, <NONE>,  '_strset',  \
    _strspnp, <NONE>,  '_strspnp',  \
    _strtime, <NONE>,  '_strtime',  \
    _strupr, <NONE>,  '_strupr',  \
    _swab, <NONE>,  '_swab',  \
    _sys_errlist, <NONE>,  '_sys_errlist',  \
    _sys_nerr_dll, <NONE>,  '_sys_nerr_dll',  \
    _tell, <NONE>,  '_tell',  \
    _tempnam, <NONE>,  '_tempnam',  \
    _timezone_dll, <NONE>,  '_timezone_dll',  \
    _tolower, <NONE>,  '_tolower',  \
    _toupper, <NONE>,  '_toupper',  \
    _tzname, <NONE>,  '_tzname',  \
    _tzset, <NONE>,  '_tzset',  \
    _ultoa, <NONE>,  '_ultoa',  \
    _ultow, <NONE>,  '_ultow',  \
    _umask, <NONE>,  '_umask',  \
    _ungetch, <NONE>,  '_ungetch',  \
    _unlink, <NONE>,  '_unlink',  \
    _unloaddll, <NONE>,  '_unloaddll',  \
    _utime, <NONE>,  '_utime',  \
    _vsnprintf, <NONE>,  '_vsnprintf',  \
    _vsnwprintf, <NONE>,  '_vsnwprintf',  \
    _wcsdup, <NONE>,  '_wcsdup',  \
    _wcsicmp, <NONE>,  '_wcsicmp',  \
    _wcsicoll, <NONE>,  '_wcsicoll',  \
    _wcslwr, <NONE>,  '_wcslwr',  \
    _wcsnicmp, <NONE>,  '_wcsnicmp',  \
    _wcsnset, <NONE>,  '_wcsnset',  \
    _wcsrev, <NONE>,  '_wcsrev',  \
    _wcsset, <NONE>,  '_wcsset',  \
    _wcsupr, <NONE>,  '_wcsupr',  \
    _winmajor_dll, <NONE>,  '_winmajor_dll',  \
    _winminor_dll, <NONE>,  '_winminor_dll',  \
    _winver_dll, <NONE>,  '_winver_dll',  \
    _wtoi, <NONE>,  '_wtoi',  \
    _wtol, <NONE>,  '_wtol',  \
    _y0, <NONE>,  '_y0',  \
    _y1, <NONE>,  '_y1',  \
    _yn, <NONE>,  '_yn',  \
    abort, <NONE>,  'abort',  \
    abs, <NONE>,  'abs',  \
    acos, <NONE>,  'acos',  \
    asctime, <NONE>,  'asctime',  \
    asin, <NONE>,  'asin',  \
    atan, <NONE>,  'atan',  \
    atan2, <NONE>,  'atan2',  \
    atexit, <NONE>,  'atexit',  \
    atof, <NONE>,  'atof',  \
    atoi, <NONE>,  'atoi',  \
    atol, <NONE>,  'atol',  \
    bsearch, <NONE>,  'bsearch',  \
    calloc, <NONE>,  'calloc',  \
    ceil, <NONE>,  'ceil',  \
    clearerr, <NONE>,  'clearerr',  \
    clock, <NONE>,  'clock',  \
    cos, <NONE>,  'cos',  \
    cosh, <NONE>,  'cosh',  \
    ctime, <NONE>,  'ctime',  \
    difftime, <NONE>,  'difftime',  \
    div, <NONE>,  'div',  \
    exit, <NONE>,  'exit',  \
    exp, <NONE>,  'exp',  \
    fabs, <NONE>,  'fabs',  \
    fclose, <NONE>,  'fclose',  \
    feof, <NONE>,  'feof',  \
    ferror, <NONE>,  'ferror',  \
    fflush, <NONE>,  'fflush',  \
    fgetc, <NONE>,  'fgetc',  \
    fgetpos, <NONE>,  'fgetpos',  \
    fgets, <NONE>,  'fgets',  \
    fgetwc, <NONE>,  'fgetwc',  \
    floor, <NONE>,  'floor',  \
    fmod, <NONE>,  'fmod',  \
    fopen, <NONE>,  'fopen',  \
    fprintf, <NONE>,  'fprintf',  \
    fputc, <NONE>,  'fputc',  \
    fputs, <NONE>,  'fputs',  \
    fputwc, <NONE>,  'fputwc',  \
    fread, <NONE>,  'fread',  \
    free, <.TM_aKey>,  'free',  \
    freopen, <NONE>,  'freopen',  \
    frexp, <NONE>,  'frexp',  \
    fscanf, <NONE>,  'fscanf',  \
    fseek, <NONE>,  'fseek',  \
    fsetpos, <NONE>,  'fsetpos',  \
    ftell, <NONE>,  'ftell',  \
    fwprintf, <NONE>,  'fwprintf',  \
    fwrite, <NONE>,  'fwrite',  \
    fwscanf, <NONE>,  'fwscanf',  \
    getc, <NONE>,  'getc',  \
    getchar, <NONE>,  'getchar',  \
    getenv, <NONE>,  'getenv',  \
    gets, <NONE>,  'gets',  \
    gmtime, <NONE>,  'gmtime',  \
    hread, <.hFile, .lpBuffer, .lBytes>,  'hread',  \
    hwrite, <.hFile, .lpBuffer, .lBytes>,  'hwrite',  \
    is_wctype, <NONE>,  'is_wctype',  \
    isalnum, <NONE>,  'isalnum',  \
    isalpha, <NONE>,  'isalpha',  \
    iscntrl, <NONE>,  'iscntrl',  \
    isdigit, <NONE>,  'isdigit',  \
    isgraph, <NONE>,  'isgraph',  \
    isleadbyte, <NONE>,  'isleadbyte',  \
    islower, <NONE>,  'islower',  \
    isprint, <NONE>,  'isprint',  \
    ispunct, <NONE>,  'ispunct',  \
    isspace, <NONE>,  'isspace',  \
    isupper, <NONE>,  'isupper',  \
    iswalnum, <NONE>,  'iswalnum',  \
    iswalpha, <NONE>,  'iswalpha',  \
    iswascii, <NONE>,  'iswascii',  \
    iswcntrl, <NONE>,  'iswcntrl',  \
    iswctype, <NONE>,  'iswctype',  \
    iswdigit, <NONE>,  'iswdigit',  \
    iswgraph, <NONE>,  'iswgraph',  \
    iswlower, <NONE>,  'iswlower',  \
    iswprint, <NONE>,  'iswprint',  \
    iswpunct, <NONE>,  'iswpunct',  \
    iswspace, <NONE>,  'iswspace',  \
    iswupper, <NONE>,  'iswupper',  \
    iswxdigit, <NONE>,  'iswxdigit',  \
    isxdigit, <NONE>,  'isxdigit',  \
    labs, <NONE>,  'labs',  \
    lclose, <.hFile>,  'lclose',  \
    lcreat, <.lpPathName, .iAttribute>,  'lcreat',  \
    ldexp, <NONE>,  'ldexp',  \
    ldiv, <NONE>,  'ldiv',  \
    llseek, <.hFile, .lOffset, .iOrigin>,  'llseek',  \
    localeconv, <NONE>,  'localeconv',  \
    localtime, <NONE>,  'localtime',  \
    log, <NONE>,  'log',  \
    log10, <NONE>,  'log10',  \
    longjmp, <NONE>,  'longjmp',  \
    lopen, <.lpPathName, .iReadWrite>,  'lopen',  \
    malloc, <NONE>,  'malloc',  \
    mblen, <NONE>,  'mblen',  \
    mbstowcs, <NONE>,  'mbstowcs',  \
    mbtowc, <NONE>,  'mbtowc',  \
    memchr, <NONE>,  'memchr',  \
    memcmp, <NONE>,  'memcmp',  \
    memcpy, <NONE>,  'memcpy',  \
    memmove, <.pVoid, .FunctionCall>,  'memmove',  \
    memset, <NONE>,  'memset',  \
    mktime, <NONE>,  'mktime',  \
    modf, <NONE>,  'modf',  \
    perror, <NONE>,  'perror',  \
    pow, <NONE>,  'pow',  \
    printf, <NONE>,  'printf',  \
    putc, <NONE>,  'putc',  \
    putchar, <NONE>,  'putchar',  \
    puts, <NONE>,  'puts',  \
    qsort, <NONE>,  'qsort',  \
    raise, <NONE>,  'raise',  \
    rand, <NONE>,  'rand',  \
    realloc, <NONE>,  'realloc',  \
    remove, <NONE>,  'remove',  \
    rename, <NONE>,  'rename',  \
    rewind, <NONE>,  'rewind',  \
    scanf, <NONE>,  'scanf',  \
    setbuf, <NONE>,  'setbuf',  \
    setlocale, <NONE>,  'setlocale',  \
    setvbuf, <NONE>,  'setvbuf',  \
    signal, <NONE>,  'signal',  \
    sin, <NONE>,  'sin',  \
    sinh, <NONE>,  'sinh',  \
    sprintf, <NONE>,  'sprintf',  \
    sqrt, <NONE>,  'sqrt',  \
    srand, <NONE>,  'srand',  \
    sscanf, <NONE>,  'sscanf',  \
    strcat, <NONE>,  'strcat',  \
    strchr, <.lpStart, .wMatch>,  'strchr',  \
    strcmp, <NONE>,  'strcmp',  \
    strcoll, <NONE>,  'strcoll',  \
    strcpy, <NONE>,  'strcpy',  \
    strcspn, <.lpStr, .lpSet>,  'strcspn',  \
    strerror, <NONE>,  'strerror',  \
    strftime, <NONE>,  'strftime',  \
    strlen, <NONE>,  'strlen',  \
    strncat, <.psz1, .psz2, .cchMax>,  'strncat',  \
    strncmp, <NONE>,  'strncmp',  \
    strncpy, <NONE>,  'strncpy',  \
    strpbrk, <.psz, .pszSet>,  'strpbrk',  \
    strrchr, <.lpStart, .lpEnd, .wMatch>,  'strrchr',  \
    strspn, <.psz, .pszSet>,  'strspn',  \
    strstr, <.lpFirst, .lpSrch>,  'strstr',  \
    strtod, <NONE>,  'strtod',  \
    strtok, <NONE>,  'strtok',  \
    strtol, <NONE>,  'strtol',  \
    strtoul, <NONE>,  'strtoul',  \
    strxfrm, <NONE>,  'strxfrm',  \
    swprintf, <NONE>,  'swprintf',  \
    swscanf, <NONE>,  'swscanf',  \
    system, <NONE>,  'system',  \
    tan, <NONE>,  'tan',  \
    tanh, <NONE>,  'tanh',  \
    time, <NONE>,  'time',  \
    tmpfile, <NONE>,  'tmpfile',  \
    tmpnam, <NONE>,  'tmpnam',  \
    tolower, <NONE>,  'tolower',  \
    toupper, <NONE>,  'toupper',  \
    towlower, <NONE>,  'towlower',  \
    towupper, <NONE>,  'towupper',  \
    ungetc, <NONE>,  'ungetc',  \
    ungetwc, <NONE>,  'ungetwc',  \
    vfprintf, <NONE>,  'vfprintf',  \
    vfwprintf, <NONE>,  'vfwprintf',  \
    vprintf, <NONE>,  'vprintf',  \
    vsprintf, <NONE>,  'vsprintf',  \
    vswprintf, <NONE>,  'vswprintf',  \
    vwprintf, <NONE>,  'vwprintf',  \
    wcscat, <NONE>,  'wcscat',  \
    wcschr, <NONE>,  'wcschr',  \
    wcscmp, <NONE>,  'wcscmp',  \
    wcscoll, <NONE>,  'wcscoll',  \
    wcscpy, <NONE>,  'wcscpy',  \
    wcscspn, <NONE>,  'wcscspn',  \
    wcsftime, <NONE>,  'wcsftime',  \
    wcslen, <NONE>,  'wcslen',  \
    wcsncat, <NONE>,  'wcsncat',  \
    wcsncmp, <NONE>,  'wcsncmp',  \
    wcsncpy, <NONE>,  'wcsncpy',  \
    wcspbrk, <NONE>,  'wcspbrk',  \
    wcsrchr, <NONE>,  'wcsrchr',  \
    wcsspn, <NONE>,  'wcsspn',  \
    wcsstr, <NONE>,  'wcsstr',  \
    wcstod, <NONE>,  'wcstod',  \
    wcstok, <NONE>,  'wcstok',  \
    wcstol, <NONE>,  'wcstol',  \
    wcstombs, <NONE>,  'wcstombs',  \
    wcstoul, <NONE>,  'wcstoul',  \
    wcsxfrm, <NONE>,  'wcsxfrm',  \
    wctomb, <NONE>,  'wctomb',  \
    wprintf, <NONE>,  'wprintf',  \
    wscanf, <NONE>,  'wscanf'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/imports/Win32/gdi32.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: gdi32.dll API calls
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

import_proto gdi32,  \
    AbortDoc, <.hdc>,  'AbortDoc',  \
    AbortPath, <.hdc>,  'AbortPath',  \
    AddFontMemResourceEx, <.pvoid, .dword, .pDword>,  'AddFontMemResourceEx',  \
    AddFontResourceA, <.lpFileName>,  'AddFontResourceA',  \
    AddFontResourceExA, <.lpcstr, .dword>,  'AddFontResourceExA',  \
    AddFontResourceExW, <.lpcstr, .dword>,  'AddFontResourceExW',  \
    AddFontResourceTracking, <NONE>,  'AddFontResourceTracking',  \
    AddFontResourceW, <.lpFileName>,  'AddFontResourceW',  \
    AngleArc, <.hdc, .x, .y, .dwRadius, .eStartAngle, .eSweepAngle>,  'AngleArc',  \
    AnimatePalette, <.hPalette, .wStartIndex, .wNumEntries, .lpPaletteColors>,  'AnimatePalette',  \
    AnyLinkedFonts, <NONE>,  'AnyLinkedFonts',  \
    Arc, <.hdc, .X1, .Y1, .X2, .Y2, .X3, .Y3, .X4, .Y4>,  'Arc',  \
    ArcTo, <.hdc, .X1, .Y1, .X2, .Y2, .X3, .Y3, .X4, .Y4>,  'ArcTo',  \
    BRUSHOBJ_hGetColorTransform, <NONE>,  'BRUSHOBJ_hGetColorTransform',  \
    BRUSHOBJ_pvAllocRbrush, <NONE>,  'BRUSHOBJ_pvAllocRbrush',  \
    BRUSHOBJ_pvGetRbrush, <NONE>,  'BRUSHOBJ_pvGetRbrush',  \
    BRUSHOBJ_ulGetBrushColor, <NONE>,  'BRUSHOBJ_ulGetBrushColor',  \
    BeginPath, <.hdc>,  'BeginPath',  \
    BitBlt, <.hDestDC, .x, .y, .nWidth, .nHeight, .hSrcDC, .xSrc, .ySrc, .dwRop>,  'BitBlt',  \
    CLIPOBJ_bEnum, <NONE>,  'CLIPOBJ_bEnum',  \
    CLIPOBJ_cEnumStart, <NONE>,  'CLIPOBJ_cEnumStart',  \
    CLIPOBJ_ppoGetPath, <NONE>,  'CLIPOBJ_ppoGetPath',  \
    CancelDC, <.hdc>,  'CancelDC',  \
    CheckColorsInGamut, <.hdc, .lpv, .lpv2, .dw>,  'CheckColorsInGamut',  \
    ChoosePixelFormat, <.hDC, .pPixelFormatDescriptor>,  'ChoosePixelFormat',  \
    Chord, <.hdc, .X1, .Y1, .X2, .Y2, .X3, .Y3, .X4, .Y4>,  'Chord',  \
    ClearBitmapAttributes, <NONE>,  'ClearBitmapAttributes',  \
    ClearBrushAttributes, <NONE>,  'ClearBrushAttributes',  \
    CloseEnhMetaFile, <.hdc>,  'CloseEnhMetaFile',  \
    CloseFigure, <.hdc>,  'CloseFigure',  \
    CloseMetaFile, <.hMF>,  'CloseMetaFile',  \
    ColorCorrectPalette, <.hdc, .hpalette, .dword>,  'ColorCorrectPalette',  \
    ColorMatchToTarget, <.hdc, .hdc2, .dw>,  'ColorMatchToTarget',  \
    CombineRgn, <.hDestRgn, .hSrcRgn1, .hSrcRgn2, .nCombineMode>,  'CombineRgn',  \
    CombineTransform, <.lpxformResult, .lpxform1, .lpxform2>,  'CombineTransform',  \
    CopyEnhMetaFileA, <.hemfSrc, .lpszFile>,  'CopyEnhMetaFileA',  \
    CopyEnhMetaFileW, <.hemfSrc, .lpszFile>,  'CopyEnhMetaFileW',  \
    CopyMetaFileA, <.hMF, .lpFileName>,  'CopyMetaFileA',  \
    CopyMetaFileW, <.hMF, .lpFileName>,  'CopyMetaFileW',  \
    CreateBitmap, <.nWidth, .nHeight, .nPlanes, .nBitCount, .lpBits>,  'CreateBitmap',  \
    CreateBitmapIndirect, <.lpBitmap>,  'CreateBitmapIndirect',  \
    CreateBrushIndirect, <.lpLogBrush>,  'CreateBrushIndirect',  \
    CreateColorSpaceA, <.lplogcolorspace>,  'CreateColorSpaceA',  \
    CreateColorSpaceW, <.lplogcolorspace>,  'CreateColorSpaceW',  \
    CreateCompatibleBitmap, <.hdc, .nWidth, .nHeight>,  'CreateCompatibleBitmap',  \
    CreateCompatibleDC, <.hdc>,  'CreateCompatibleDC',  \
    CreateDCA, <.lpDriverName, .lpDeviceName, .lpOutput, .lpInitData>,  'CreateDCA',  \
    CreateDCW, <.lpDriverName, .lpDeviceName, .lpOutput, .lpInitData>,  'CreateDCW',  \
    CreateDIBPatternBrush, <.hPackedDIB, .wUsage>,  'CreateDIBPatternBrush',  \
    CreateDIBPatternBrushPt, <.lpPackedDIB, .iUsage>,  'CreateDIBPatternBrushPt',  \
    CreateDIBSection, <.hDC, .pBitmapInfo, .un, .lplpVoid, .handle, .dw>,  'CreateDIBSection',  \
    CreateDIBitmap, <.hdc, .lpInfoHeader, .dwUsage, .lpInitBits, .lpInitInfo, .wUsage>,  'CreateDIBitmap',  \
    CreateDiscardableBitmap, <.hdc, .nWidth, .nHeight>,  'CreateDiscardableBitmap',  \
    CreateEllipticRgn, <.X1, .Y1, .X2, .Y2>,  'CreateEllipticRgn',  \
    CreateEllipticRgnIndirect, <.lpRect>,  'CreateEllipticRgnIndirect',  \
    CreateEnhMetaFileA, <.hdcRef, .lpFileName, .lpRect, .lpDescription>,  'CreateEnhMetaFileA',  \
    CreateEnhMetaFileW, <.hdcRef, .lpFileName, .lpRect, .lpDescription>,  'CreateEnhMetaFileW',  \
    CreateFontA, <.H, .W, .E, .O, .I, .u, .S, .C, .OP, .CP, .Q, .PAF, .F>,  'CreateFontA',  \
    CreateFontIndirectA, <.lpLogFont>,  'CreateFontIndirectA',  \
    CreateFontIndirectExA, <.ENUMLOGFONTEXDVA>,  'CreateFontIndirectExA',  \
    CreateFontIndirectExW, <.ENUMLOGFONTEXDVA>,  'CreateFontIndirectExW',  \
    CreateFontIndirectW, <.lpLogFont>,  'CreateFontIndirectW',  \
    CreateFontW, <.H, .W, .E, .O, .I, .u, .S, .C, .OP, .CP, .Q, .PAF, .F>,  'CreateFontW',  \
    CreateHalftonePalette, <.hdc>,  'CreateHalftonePalette',  \
    CreateHatchBrush, <.nIndex, .crColor>,  'CreateHatchBrush',  \
    CreateICA, <.lpDriverName, .lpDeviceName, .lpOutput, .lpInitData>,  'CreateICA',  \
    CreateICW, <.lpDriverName, .lpDeviceName, .lpOutput, .lpInitData>,  'CreateICW',  \
    CreateMetaFileA, <.lpString>,  'CreateMetaFileA',  \
    CreateMetaFileW, <.lpString>,  'CreateMetaFileW',  \
    CreatePalette, <.lpLogPalette>,  'CreatePalette',  \
    CreatePatternBrush, <.hBitmap>,  'CreatePatternBrush',  \
    CreatePen, <.nPenStyle, .nWidth, .crColor>,  'CreatePen',  \
    CreatePenIndirect, <.lpLogPen>,  'CreatePenIndirect',  \
    CreatePolyPolygonRgn, <.lpPoint, .lpPolyCounts, .nCount, .nPolyFillMode>,  'CreatePolyPolygonRgn',  \
    CreatePolygonRgn, <.lpPoint, .nCount, .nPolyFillMode>,  'CreatePolygonRgn',  \
    CreateRectRgn, <.X1, .Y1, .X2, .Y2>,  'CreateRectRgn',  \
    CreateRectRgnIndirect, <.lpRect>,  'CreateRectRgnIndirect',  \
    CreateRoundRectRgn, <.X1, .Y1, .X2, .Y2, .X3, .Y3>,  'CreateRoundRectRgn',  \
    CreateScalableFontResourceA, <.fHidden, .lpszResourceFile, .lpszFontFile, .lpszCurrentPath>,  'CreateScalableFontResourceA',  \
    CreateScalableFontResourceW, <.fHidden, .lpszResourceFile, .lpszFontFile, .lpszCurrentPath>,  'CreateScalableFontResourceW',  \
    CreateSolidBrush, <.crColor>,  'CreateSolidBrush',  \
    DPtoLP, <.hdc, .lpPoint, .nCount>,  'DPtoLP',  \
    DdEntry0, <NONE>,  'DdEntry0',  \
    DdEntry1, <NONE>,  'DdEntry1',  \
    DdEntry10, <NONE>,  'DdEntry10',  \
    DdEntry11, <NONE>,  'DdEntry11',  \
    DdEntry12, <NONE>,  'DdEntry12',  \
    DdEntry13, <NONE>,  'DdEntry13',  \
    DdEntry14, <NONE>,  'DdEntry14',  \
    DdEntry15, <NONE>,  'DdEntry15',  \
    DdEntry16, <NONE>,  'DdEntry16',  \
    DdEntry17, <NONE>,  'DdEntry17',  \
    DdEntry18, <NONE>,  'DdEntry18',  \
    DdEntry19, <NONE>,  'DdEntry19',  \
    DdEntry2, <NONE>,  'DdEntry2',  \
    DdEntry20, <NONE>,  'DdEntry20',  \
    DdEntry21, <NONE>,  'DdEntry21',  \
    DdEntry22, <NONE>,  'DdEntry22',  \
    DdEntry23, <NONE>,  'DdEntry23',  \
    DdEntry24, <NONE>,  'DdEntry24',  \
    DdEntry25, <NONE>,  'DdEntry25',  \
    DdEntry26, <NONE>,  'DdEntry26',  \
    DdEntry27, <NONE>,  'DdEntry27',  \
    DdEntry28, <NONE>,  'DdEntry28',  \
    DdEntry29, <NONE>,  'DdEntry29',  \
    DdEntry3, <NONE>,  'DdEntry3',  \
    DdEntry30, <NONE>,  'DdEntry30',  \
    DdEntry31, <NONE>,  'DdEntry31',  \
    DdEntry32, <NONE>,  'DdEntry32',  \
    DdEntry33, <NONE>,  'DdEntry33',  \
    DdEntry34, <NONE>,  'DdEntry34',  \
    DdEntry35, <NONE>,  'DdEntry35',  \
    DdEntry36, <NONE>,  'DdEntry36',  \
    DdEntry37, <NONE>,  'DdEntry37',  \
    DdEntry38, <NONE>,  'DdEntry38',  \
    DdEntry39, <NONE>,  'DdEntry39',  \
    DdEntry4, <NONE>,  'DdEntry4',  \
    DdEntry40, <NONE>,  'DdEntry40',  \
    DdEntry41, <NONE>,  'DdEntry41',  \
    DdEntry42, <NONE>,  'DdEntry42',  \
    DdEntry43, <NONE>,  'DdEntry43',  \
    DdEntry44, <NONE>,  'DdEntry44',  \
    DdEntry45, <NONE>,  'DdEntry45',  \
    DdEntry46, <NONE>,  'DdEntry46',  \
    DdEntry47, <NONE>,  'DdEntry47',  \
    DdEntry48, <NONE>,  'DdEntry48',  \
    DdEntry49, <NONE>,  'DdEntry49',  \
    DdEntry5, <NONE>,  'DdEntry5',  \
    DdEntry50, <NONE>,  'DdEntry50',  \
    DdEntry51, <NONE>,  'DdEntry51',  \
    DdEntry52, <NONE>,  'DdEntry52',  \
    DdEntry53, <NONE>,  'DdEntry53',  \
    DdEntry54, <NONE>,  'DdEntry54',  \
    DdEntry55, <NONE>,  'DdEntry55',  \
    DdEntry56, <NONE>,  'DdEntry56',  \
    DdEntry6, <NONE>,  'DdEntry6',  \
    DdEntry7, <NONE>,  'DdEntry7',  \
    DdEntry8, <NONE>,  'DdEntry8',  \
    DdEntry9, <NONE>,  'DdEntry9',  \
    DeleteColorSpace, <.hcolorspace>,  'DeleteColorSpace',  \
    DeleteDC, <.hdc>,  'DeleteDC',  \
    DeleteEnhMetaFile, <.hemf>,  'DeleteEnhMetaFile',  \
    DeleteMetaFile, <.hMF>,  'DeleteMetaFile',  \
    DeleteObject, <.hObject>,  'DeleteObject',  \
    DescribePixelFormat, <.hDC, .n, .un, .lpPixelFormatDescriptor>,  'DescribePixelFormat',  \
    DeviceCapabilitiesExA, <NONE>,  'DeviceCapabilitiesExA',  \
    DeviceCapabilitiesExW, <NONE>,  'DeviceCapabilitiesExW',  \
    DrawEscape, <.hdc, .nEscape, .cbInput, .lpszInData>,  'DrawEscape',  \
    Ellipse, <.hdc, .X1, .Y1, .X2, .Y2>,  'Ellipse',  \
    EnableEUDC, <NONE>,  'EnableEUDC',  \
    EndDoc, <.hDC>,  'EndDoc',  \
    EndFormPage, <.hdc>,  'EndFormPage',  \
    EndPage, <.hdc>,  'EndPage',  \
    EndPath, <.hdc>,  'EndPath',  \
    EngAcquireSemaphore, <NONE>,  'EngAcquireSemaphore',  \
    EngAlphaBlend, <NONE>,  'EngAlphaBlend',  \
    EngAssociateSurface, <NONE>,  'EngAssociateSurface',  \
    EngBitBlt, <NONE>,  'EngBitBlt',  \
    EngCheckAbort, <NONE>,  'EngCheckAbort',  \
    EngComputeGlyphSet, <NONE>,  'EngComputeGlyphSet',  \
    EngCopyBits, <NONE>,  'EngCopyBits',  \
    EngCreateBitmap, <NONE>,  'EngCreateBitmap',  \
    EngCreateClip, <NONE>,  'EngCreateClip',  \
    EngCreateDeviceBitmap, <NONE>,  'EngCreateDeviceBitmap',  \
    EngCreateDeviceSurface, <NONE>,  'EngCreateDeviceSurface',  \
    EngCreatePalette, <NONE>,  'EngCreatePalette',  \
    EngCreateSemaphore, <NONE>,  'EngCreateSemaphore',  \
    EngDeleteClip, <NONE>,  'EngDeleteClip',  \
    EngDeletePalette, <NONE>,  'EngDeletePalette',  \
    EngDeletePath, <NONE>,  'EngDeletePath',  \
    EngDeleteSemaphore, <NONE>,  'EngDeleteSemaphore',  \
    EngDeleteSurface, <NONE>,  'EngDeleteSurface',  \
    EngEraseSurface, <NONE>,  'EngEraseSurface',  \
    EngFillPath, <NONE>,  'EngFillPath',  \
    EngFindResource, <NONE>,  'EngFindResource',  \
    EngFreeModule, <NONE>,  'EngFreeModule',  \
    EngGetCurrentCodePage, <NONE>,  'EngGetCurrentCodePage',  \
    EngGetDriverName, <NONE>,  'EngGetDriverName',  \
    EngGetPrinterDataFileName, <NONE>,  'EngGetPrinterDataFileName',  \
    EngGradientFill, <NONE>,  'EngGradientFill',  \
    EngLineTo, <NONE>,  'EngLineTo',  \
    EngLoadModule, <NONE>,  'EngLoadModule',  \
    EngLockSurface, <NONE>,  'EngLockSurface',  \
    EngMarkBandingSurface, <NONE>,  'EngMarkBandingSurface',  \
    EngMultiByteToUnicodeN, <NONE>,  'EngMultiByteToUnicodeN',  \
    EngMultiByteToWideChar, <NONE>,  'EngMultiByteToWideChar',  \
    EngPaint, <NONE>,  'EngPaint',  \
    EngPlgBlt, <NONE>,  'EngPlgBlt',  \
    EngQueryEMFInfo, <NONE>,  'EngQueryEMFInfo',  \
    EngQueryLocalTime, <NONE>,  'EngQueryLocalTime',  \
    EngReleaseSemaphore, <NONE>,  'EngReleaseSemaphore',  \
    EngStretchBlt, <NONE>,  'EngStretchBlt',  \
    EngStretchBltROP, <NONE>,  'EngStretchBltROP',  \
    EngStrokeAndFillPath, <NONE>,  'EngStrokeAndFillPath',  \
    EngStrokePath, <NONE>,  'EngStrokePath',  \
    EngTextOut, <NONE>,  'EngTextOut',  \
    EngTransparentBlt, <NONE>,  'EngTransparentBlt',  \
    EngUnicodeToMultiByteN, <NONE>,  'EngUnicodeToMultiByteN',  \
    EngUnlockSurface, <NONE>,  'EngUnlockSurface',  \
    EngWideCharToMultiByte, <NONE>,  'EngWideCharToMultiByte',  \
    EnumEnhMetaFile, <.hdc, .hemf, .lpEnhMetaFunc, .lpData, .lpRect>,  'EnumEnhMetaFile',  \
    EnumFontFamiliesA, <.hdc, .lpszFamily, .lpEnumFontFamProc, .lParam>,  'EnumFontFamiliesA',  \
    EnumFontFamiliesExA, <.hdc, .lpLogFont, .lpEnumFontProc, .lParam, .dw>,  'EnumFontFamiliesExA',  \
    EnumFontFamiliesExW, <.hdc, .lpLogFont, .lpEnumFontProc, .lParam, .dw>,  'EnumFontFamiliesExW',  \
    EnumFontFamiliesW, <.hdc, .lpszFamily, .lpEnumFontFamProc, .lParam>,  'EnumFontFamiliesW',  \
    EnumFontsA, <.hDC, .lpsz, .lpFontEnumProc, .lParam>,  'EnumFontsA',  \
    EnumFontsW, <.hDC, .lpsz, .lpFontEnumProc, .lParam>,  'EnumFontsW',  \
    EnumICMProfilesA, <.hdc, .icmEnumProc, .lParam>,  'EnumICMProfilesA',  \
    EnumICMProfilesW, <.hdc, .icmEnumProc, .lParam>,  'EnumICMProfilesW',  \
    EnumMetaFile, <.hDC, .hMetafile, .lpMFEnumProc, .lParam>,  'EnumMetaFile',  \
    EnumObjects, <.hDC, .n, .lpGOBJEnumProc, .lpVoid>,  'EnumObjects',  \
    EqualRgn, <.hSrcRgn1, .hSrcRgn2>,  'EqualRgn',  \
    Escape, <.hdc, .nEscape, .nCount, .lpInData, .lpOutData>,  'Escape',  \
    EudcLoadLinkW, <NONE>,  'EudcLoadLinkW',  \
    EudcUnloadLinkW, <NONE>,  'EudcUnloadLinkW',  \
    ExcludeClipRect, <.hdc, .X1, .Y1, .X2, .Y2>,  'ExcludeClipRect',  \
    ExtCreatePen, <.dwPenStyle, .dwWidth, .lplb, .dwStyleCount, .lpStyle>,  'ExtCreatePen',  \
    ExtCreateRegion, <.lpXform, .nCount, .lpRgnData>,  'ExtCreateRegion',  \
    ExtEscape, <.hdc, .nEscape, .cbInput, .lpszInData, .cbOutput, .lpszOutData>,  'ExtEscape',  \
    ExtFloodFill, <.hdc, .x, .y, .crColor, .wFillType>,  'ExtFloodFill',  \
    ExtSelectClipRgn, <.hdc, .hRgn, .fnMode>,  'ExtSelectClipRgn',  \
    ExtTextOutA, <.hdc, .x, .y, .wOptions, .lpRect, .lpString, .nCount, .lpDx>,  'ExtTextOutA',  \
    ExtTextOutW, <.hdc, .x, .y, .wOptions, .lpRect, .lpString, .nCount, .lpDx>,  'ExtTextOutW',  \
    FONTOBJ_cGetAllGlyphHandles, <NONE>,  'FONTOBJ_cGetAllGlyphHandles',  \
    FONTOBJ_cGetGlyphs, <NONE>,  'FONTOBJ_cGetGlyphs',  \
    FONTOBJ_pQueryGlyphAttrs, <NONE>,  'FONTOBJ_pQueryGlyphAttrs',  \
    FONTOBJ_pfdg, <NONE>,  'FONTOBJ_pfdg',  \
    FONTOBJ_pifi, <NONE>,  'FONTOBJ_pifi',  \
    FONTOBJ_pvTrueTypeFontFile, <NONE>,  'FONTOBJ_pvTrueTypeFontFile',  \
    FONTOBJ_pxoGetXform, <NONE>,  'FONTOBJ_pxoGetXform',  \
    FONTOBJ_vGetInfo, <NONE>,  'FONTOBJ_vGetInfo',  \
    FillPath, <.hdc>,  'FillPath',  \
    FillRgn, <.hdc, .hRgn, .hBrush>,  'FillRgn',  \
    FixBrushOrgEx, <.hDC, .n1, .n2, .lpPoint>,  'FixBrushOrgEx',  \
    FlattenPath, <.hdc>,  'FlattenPath',  \
    FloodFill, <.hdc, .x, .y, .crColor>,  'FloodFill',  \
    FontIsLinked, <NONE>,  'FontIsLinked',  \
    FrameRgn, <.hdc, .hRgn, .hBrush, .nWidth, .nHeight>,  'FrameRgn',  \
    GdiAddFontResourceW, <NONE>,  'GdiAddFontResourceW',  \
    GdiAddGlsBounds, <NONE>,  'GdiAddGlsBounds',  \
    GdiAddGlsRecord, <NONE>,  'GdiAddGlsRecord',  \
    GdiAlphaBlend, <NONE>,  'GdiAlphaBlend',  \
    GdiArtificialDecrementDriver, <NONE>,  'GdiArtificialDecrementDriver',  \
    GdiCleanCacheDC, <NONE>,  'GdiCleanCacheDC',  \
    GdiComment, <.hdc, .cbSize, .lpData>,  'GdiComment',  \
    GdiConsoleTextOut, <NONE>,  'GdiConsoleTextOut',  \
    GdiConvertAndCheckDC, <NONE>,  'GdiConvertAndCheckDC',  \
    GdiConvertBitmap, <NONE>,  'GdiConvertBitmap',  \
    GdiConvertBitmapV5, <NONE>,  'GdiConvertBitmapV5',  \
    GdiConvertBrush, <NONE>,  'GdiConvertBrush',  \
    GdiConvertDC, <NONE>,  'GdiConvertDC',  \
    GdiConvertEnhMetaFile, <NONE>,  'GdiConvertEnhMetaFile',  \
    GdiConvertFont, <NONE>,  'GdiConvertFont',  \
    GdiConvertMetaFilePict, <NONE>,  'GdiConvertMetaFilePict',  \
    GdiConvertPalette, <NONE>,  'GdiConvertPalette',  \
    GdiConvertRegion, <NONE>,  'GdiConvertRegion',  \
    GdiConvertToDevmodeW, <NONE>,  'GdiConvertToDevmodeW',  \
    GdiCreateLocalEnhMetaFile, <NONE>,  'GdiCreateLocalEnhMetaFile',  \
    GdiCreateLocalMetaFilePict, <NONE>,  'GdiCreateLocalMetaFilePict',  \
    GdiDeleteLocalDC, <NONE>,  'GdiDeleteLocalDC',  \
    GdiDeleteSpoolFileHandle, <NONE>,  'GdiDeleteSpoolFileHandle',  \
    GdiDescribePixelFormat, <NONE>,  'GdiDescribePixelFormat',  \
    GdiDllInitialize, <NONE>,  'GdiDllInitialize',  \
    GdiDrawStream, <NONE>,  'GdiDrawStream',  \
    GdiEndDocEMF, <NONE>,  'GdiEndDocEMF',  \
    GdiEndPageEMF, <NONE>,  'GdiEndPageEMF',  \
    GdiEntry1, <NONE>,  'GdiEntry1',  \
    GdiEntry10, <NONE>,  'GdiEntry10',  \
    GdiEntry11, <NONE>,  'GdiEntry11',  \
    GdiEntry12, <NONE>,  'GdiEntry12',  \
    GdiEntry13, <NONE>,  'GdiEntry13',  \
    GdiEntry14, <NONE>,  'GdiEntry14',  \
    GdiEntry15, <NONE>,  'GdiEntry15',  \
    GdiEntry16, <NONE>,  'GdiEntry16',  \
    GdiEntry2, <NONE>,  'GdiEntry2',  \
    GdiEntry3, <NONE>,  'GdiEntry3',  \
    GdiEntry4, <NONE>,  'GdiEntry4',  \
    GdiEntry5, <NONE>,  'GdiEntry5',  \
    GdiEntry6, <NONE>,  'GdiEntry6',  \
    GdiEntry7, <NONE>,  'GdiEntry7',  \
    GdiEntry8, <NONE>,  'GdiEntry8',  \
    GdiEntry9, <NONE>,  'GdiEntry9',  \
    GdiFixUpHandle, <NONE>,  'GdiFixUpHandle',  \
    GdiFlush, <VOID>,  'GdiFlush',  \
    GdiFullscreenControl, <NONE>,  'GdiFullscreenControl',  \
    GdiGetBatchLimit, <VOID>,  'GdiGetBatchLimit',  \
    GdiGetBitmapBitsSize, <NONE>,  'GdiGetBitmapBitsSize',  \
    GdiGetCharDimensions, <NONE>,  'GdiGetCharDimensions',  \
    GdiGetCodePage, <NONE>,  'GdiGetCodePage',  \
    GdiGetDC, <NONE>,  'GdiGetDC',  \
    GdiGetDevmodeForPage, <NONE>,  'GdiGetDevmodeForPage',  \
    GdiGetLocalBrush, <NONE>,  'GdiGetLocalBrush',  \
    GdiGetLocalDC, <NONE>,  'GdiGetLocalDC',  \
    GdiGetLocalFont, <NONE>,  'GdiGetLocalFont',  \
    GdiGetPageCount, <NONE>,  'GdiGetPageCount',  \
    GdiGetPageHandle, <NONE>,  'GdiGetPageHandle',  \
    GdiGetSpoolFileHandle, <NONE>,  'GdiGetSpoolFileHandle',  \
    GdiGetSpoolMessage, <NONE>,  'GdiGetSpoolMessage',  \
    GdiGradientFill, <NONE>,  'GdiGradientFill',  \
    GdiInitSpool, <NONE>,  'GdiInitSpool',  \
    GdiInitializeLanguagePack, <NONE>,  'GdiInitializeLanguagePack',  \
    GdiIsMetaFileDC, <NONE>,  'GdiIsMetaFileDC',  \
    GdiIsMetaPrintDC, <NONE>,  'GdiIsMetaPrintDC',  \
    GdiIsPlayMetafileDC, <NONE>,  'GdiIsPlayMetafileDC',  \
    GdiPlayDCScript, <NONE>,  'GdiPlayDCScript',  \
    GdiPlayEMF, <NONE>,  'GdiPlayEMF',  \
    GdiPlayJournal, <NONE>,  'GdiPlayJournal',  \
    GdiPlayPageEMF, <NONE>,  'GdiPlayPageEMF',  \
    GdiPlayPrivatePageEMF, <NONE>,  'GdiPlayPrivatePageEMF',  \
    GdiPlayScript, <NONE>,  'GdiPlayScript',  \
    GdiPrinterThunk, <NONE>,  'GdiPrinterThunk',  \
    GdiProcessSetup, <NONE>,  'GdiProcessSetup',  \
    GdiQueryFonts, <NONE>,  'GdiQueryFonts',  \
    GdiQueryTable, <NONE>,  'GdiQueryTable',  \
    GdiRealizationInfo, <NONE>,  'GdiRealizationInfo',  \
    GdiReleaseDC, <NONE>,  'GdiReleaseDC',  \
    GdiReleaseLocalDC, <NONE>,  'GdiReleaseLocalDC',  \
    GdiResetDCEMF, <NONE>,  'GdiResetDCEMF',  \
    GdiSetAttrs, <NONE>,  'GdiSetAttrs',  \
    GdiSetBatchLimit, <.dwLimit>,  'GdiSetBatchLimit',  \
    GdiSetLastError, <NONE>,  'GdiSetLastError',  \
    GdiSetPixelFormat, <NONE>,  'GdiSetPixelFormat',  \
    GdiSetServerAttr, <NONE>,  'GdiSetServerAttr',  \
    GdiStartDocEMF, <NONE>,  'GdiStartDocEMF',  \
    GdiStartPageEMF, <NONE>,  'GdiStartPageEMF',  \
    GdiSwapBuffers, <NONE>,  'GdiSwapBuffers',  \
    GdiTransparentBlt, <NONE>,  'GdiTransparentBlt',  \
    GdiValidateHandle, <NONE>,  'GdiValidateHandle',  \
    GetArcDirection, <.hdc>,  'GetArcDirection',  \
    GetAspectRatioFilterEx, <.hdc, .lpAspectRatio>,  'GetAspectRatioFilterEx',  \
    GetBitmapAttributes, <NONE>,  'GetBitmapAttributes',  \
    GetBitmapBits, <.hBitmap, .dwCount, .lpBits>,  'GetBitmapBits',  \
    GetBitmapDimensionEx, <.hBitmap, .lpDimension>,  'GetBitmapDimensionEx',  \
    GetBkColor, <.hdc>,  'GetBkColor',  \
    GetBkMode, <.hdc>,  'GetBkMode',  \
    GetBoundsRect, <.hdc, .lprcBounds, .flags>,  'GetBoundsRect',  \
    GetBrushAttributes, <NONE>,  'GetBrushAttributes',  \
    GetBrushOrgEx, <.hDC, .lpPoint>,  'GetBrushOrgEx',  \
    GetCharABCWidthsA, <.hdc, .uFirstChar, .uLastChar, .lpabc>,  'GetCharABCWidthsA',  \
    GetCharABCWidthsFloatA, <.hdc, .iFirstChar, .iLastChar, .lpABCF>,  'GetCharABCWidthsFloatA',  \
    GetCharABCWidthsFloatW, <.hdc, .iFirstChar, .iLastChar, .lpABCF>,  'GetCharABCWidthsFloatW',  \
    GetCharABCWidthsI, <.hdc, .uint, .lpword, .lpabc>,  'GetCharABCWidthsI',  \
    GetCharABCWidthsW, <.hdc, .uFirstChar, .uLastChar, .lpabc>,  'GetCharABCWidthsW',  \
    GetCharWidth32A, <.hdc, .iFirstChar, .iLastChar, .lpBuffer>,  'GetCharWidth32A',  \
    GetCharWidth32W, <.hdc, .iFirstChar, .iLastChar, .lpBuffer>,  'GetCharWidth32W',  \
    GetCharWidthA, <.hdc, .wFirstChar, .wLastChar, .lpBuffer>,  'GetCharWidthA',  \
    GetCharWidthFloatA, <.hdc, .iFirstChar, .iLastChar, .pxBuffer>,  'GetCharWidthFloatA',  \
    GetCharWidthFloatW, <.hdc, .iFirstChar, .iLastChar, .pxBuffer>,  'GetCharWidthFloatW',  \
    GetCharWidthI, <.hdc, .uint, .lpword, .lpint>,  'GetCharWidthI',  \
    GetCharWidthInfo, <NONE>,  'GetCharWidthInfo',  \
    GetCharWidthW, <.hdc, .wFirstChar, .wLastChar, .lpBuffer>,  'GetCharWidthW',  \
    GetCharacterPlacementA, <.hdc, .lpsz, .n1, .n2, .lpGcpResults, .dw>,  'GetCharacterPlacementA',  \
    GetCharacterPlacementW, <.hdc, .lpsz, .n1, .n2, .lpGcpResults, .dw>,  'GetCharacterPlacementW',  \
    GetClipBox, <.hdc, .lpRect>,  'GetClipBox',  \
    GetClipRgn, <.hdc, .hRgn>,  'GetClipRgn',  \
    GetColorAdjustment, <.hdc, .lpca>,  'GetColorAdjustment',  \
    GetColorSpace, <.hdc>,  'GetColorSpace',  \
    GetCurrentObject, <.hdc, .uObjectType>,  'GetCurrentObject',  \
    GetCurrentPositionEx, <.hdc, .lpPoint>,  'GetCurrentPositionEx',  \
    GetDCBrushColor, <.hdc>,  'GetDCBrushColor',  \
    GetDCOrgEx, <.hdc, .lpPoint>,  'GetDCOrgEx',  \
    GetDCPenColor, <.hdc>,  'GetDCPenColor',  \
    GetDIBColorTable, <.hDC, .un1, .un2, .pRGBQuad>,  'GetDIBColorTable',  \
    GetDIBits, <.aHDC, .hBitmap, .nStartScan, .nNumScans, .lpBits, .lpBI, .wUsage>,  'GetDIBits',  \
    GetDeviceCaps, <.hdc, .nIndex>,  'GetDeviceCaps',  \
    GetDeviceGammaRamp, <.hdc, .lpv>,  'GetDeviceGammaRamp',  \
    GetETM, <NONE>,  'GetETM',  \
    GetEUDCTimeStamp, <NONE>,  'GetEUDCTimeStamp',  \
    GetEUDCTimeStampExW, <NONE>,  'GetEUDCTimeStampExW',  \
    GetEnhMetaFileA, <.lpszMetaFile>,  'GetEnhMetaFileA',  \
    GetEnhMetaFileBits, <.hemf, .cbBuffer, .lpbBuffer>,  'GetEnhMetaFileBits',  \
    GetEnhMetaFileDescriptionA, <.hemf, .cchBuffer, .lpszDescription>,  'GetEnhMetaFileDescriptionA',  \
    GetEnhMetaFileDescriptionW, <.hemf, .cchBuffer, .lpszDescription>,  'GetEnhMetaFileDescriptionW',  \
    GetEnhMetaFileHeader, <.hemf, .cbBuffer, .lpemh>,  'GetEnhMetaFileHeader',  \
    GetEnhMetaFilePaletteEntries, <.hemf, .cEntries, .lppe>,  'GetEnhMetaFilePaletteEntries',  \
    GetEnhMetaFilePixelFormat, <.henhmetafile, .uint, .PIXELFORMATDESCRIPTOR>,  'GetEnhMetaFilePixelFormat',  \
    GetEnhMetaFileW, <.lpszMetaFile>,  'GetEnhMetaFileW',  \
    GetFontAssocStatus, <NONE>,  'GetFontAssocStatus',  \
    GetFontData, <.hdc, .dwTable, .dwOffset, .lpvBuffer, .cbData>,  'GetFontData',  \
    GetFontLanguageInfo, <.hdc>,  'GetFontLanguageInfo',  \
    GetFontResourceInfoW, <NONE>,  'GetFontResourceInfoW',  \
    GetFontUnicodeRanges, <.hdc, .LPGLYPHSET>,  'GetFontUnicodeRanges',  \
    GetGlyphIndicesA, <.hdc, .lpcstr, .ByValt, .lpword, .dword>,  'GetGlyphIndicesA',  \
    GetGlyphIndicesW, <.hdc, .lpcstr, .ByValt, .lpword, .dword>,  'GetGlyphIndicesW',  \
    GetGlyphOutline, <.hdc, .uChar, .fuFormat, .lpgm, .cbBuffer, .lpBuffer, .lpmat2>,  'GetGlyphOutline',  \
    GetGlyphOutlineA, <.hdc, .uChar, .fuFormat, .lpgm, .cbBuffer, .lpBuffer, .lpmat2>,  'GetGlyphOutlineA',  \
    GetGlyphOutlineW, <.hdc, .uChar, .fuFormat, .lpgm, .cbBuffer, .lpBuffer, .lpmat2>,  'GetGlyphOutlineW',  \
    GetGlyphOutlineWow, <NONE>,  'GetGlyphOutlineWow',  \
    GetGraphicsMode, <.hdc>,  'GetGraphicsMode',  \
    GetHFONT, <NONE>,  'GetHFONT',  \
    GetICMProfileA, <.hdc, .dw, .lpStr>,  'GetICMProfileA',  \
    GetICMProfileW, <.hdc, .dw, .lpStr>,  'GetICMProfileW',  \
    GetKerningPairs, <.hdc, .cPairs, .lpkrnpair>,  'GetKerningPairs',  \
    GetKerningPairsA, <.hdc, .cPairs, .lpkrnpair>,  'GetKerningPairsA',  \
    GetKerningPairsW, <.hdc, .cPairs, .lpkrnpair>,  'GetKerningPairsW',  \
    GetLayout, <.hdc>,  'GetLayout',  \
    GetLogColorSpaceA, <.hcolorspace, .lplogcolorspace, .dw>,  'GetLogColorSpaceA',  \
    GetLogColorSpaceW, <.hcolorspace, .lplogcolorspace, .dw>,  'GetLogColorSpaceW',  \
    GetMapMode, <.hdc>,  'GetMapMode',  \
    GetMetaFileA, <.lpFileName>,  'GetMetaFileA',  \
    GetMetaFileBitsEx, <.hMF, .nSize, .lpvData>,  'GetMetaFileBitsEx',  \
    GetMetaFileW, <.lpFileName>,  'GetMetaFileW',  \
    GetMetaRgn, <.hdc, .hRgn>,  'GetMetaRgn',  \
    GetMiterLimit, <.hdc, .peLimit>,  'GetMiterLimit',  \
    GetNearestColor, <.hdc, .crColor>,  'GetNearestColor',  \
    GetNearestPaletteIndex, <.hPalette, .crColor>,  'GetNearestPaletteIndex',  \
    GetObjectA, <.hObject, .nCount, .lpObject>,  'GetObjectA',  \
    GetObjectType, <.hgdiobj>,  'GetObjectType',  \
    GetObjectW, <.hObject, .nCount, .lpObject>,  'GetObjectW',  \
    GetOutlineTextMetricsA, <.hdc, .cbData, .lpotm>,  'GetOutlineTextMetricsA',  \
    GetOutlineTextMetricsW, <.hdc, .cbData, .lpotm>,  'GetOutlineTextMetricsW',  \
    GetPaletteEntries, <.hPalette, .wStartIndex, .wNumEntries, .lpPaletteEntries>,  'GetPaletteEntries',  \
    GetPath, <.hdc, .lpPoint, .lpTypes, .nSize>,  'GetPath',  \
    GetPixel, <.hdc, .x, .y>,  'GetPixel',  \
    GetPixelFormat, <.hDC>,  'GetPixelFormat',  \
    GetPolyFillMode, <.hdc>,  'GetPolyFillMode',  \
    GetROP2, <.hdc>,  'GetROP2',  \
    GetRandomRgn, <.hdc, .hrgn, .ByValt>,  'GetRandomRgn',  \
    GetRasterizerCaps, <.lpraststat, .cb>,  'GetRasterizerCaps',  \
    GetRegionData, <.hRgn, .dwCount, .lpRgnData>,  'GetRegionData',  \
    GetRelAbs, <NONE>,  'GetRelAbs',  \
    GetRgnBox, <.hRgn, .lpRect>,  'GetRgnBox',  \
    GetStockObject, <.fnObject>,  'GetStockObject',  \
    GetStretchBltMode, <.hdc>,  'GetStretchBltMode',  \
    GetStringBitmapA, <NONE>,  'GetStringBitmapA',  \
    GetStringBitmapW, <NONE>,  'GetStringBitmapW',  \
    GetSystemPaletteEntries, <.hdc, .wStartIndex, .wNumEntries, .lpPaletteEntries>,  'GetSystemPaletteEntries',  \
    GetSystemPaletteUse, <.hdc>,  'GetSystemPaletteUse',  \
    GetTextAlign, <.hdc>,  'GetTextAlign',  \
    GetTextCharacterExtra, <.hdc>,  'GetTextCharacterExtra',  \
    GetTextCharset, <.hdc>,  'GetTextCharset',  \
    GetTextCharsetInfo, <.hdc, .lpSig, .dwFlags>,  'GetTextCharsetInfo',  \
    GetTextColor, <.hdc>,  'GetTextColor',  \
    GetTextExtentExPointA, <.hdc, .lpszStr, .cchString, .nMaxExtent, .lpnFit, .alpDx, .lpSize>,  'GetTextExtentExPointA',  \
    GetTextExtentExPointI, <.hdc, .lpword, .ByValt, .lpint, .lpsize>,  'GetTextExtentExPointI',  \
    GetTextExtentExPointW, <.hdc, .lpszStr, .cchString, .nMaxExtent, .lpnFit, .alpDx, .lpSize>,  'GetTextExtentExPointW',  \
    GetTextExtentExPointWPri, <NONE>,  'GetTextExtentExPointWPri',  \
    GetTextExtentPoint32A, <.hdc, .lpsz, .cbString, .lpSize>,  'GetTextExtentPoint32A',  \
    GetTextExtentPoint32W, <.hdc, .lpsz, .cbString, .lpSize>,  'GetTextExtentPoint32W',  \
    GetTextExtentPointA, <.hdc, .lpszString, .cbString, .lpSize>,  'GetTextExtentPointA',  \
    GetTextExtentPointI, <.hdc, .lpword, .ByValt, .lpsize>,  'GetTextExtentPointI',  \
    GetTextExtentPointW, <.hdc, .lpszString, .cbString, .lpSize>,  'GetTextExtentPointW',  \
    GetTextFaceA, <.hdc, .nCount, .lpFacename>,  'GetTextFaceA',  \
    GetTextFaceAliasW, <NONE>,  'GetTextFaceAliasW',  \
    GetTextFaceW, <.hdc, .nCount, .lpFacename>,  'GetTextFaceW',  \
    GetTextMetricsA, <.hdc, .lpMetrics>,  'GetTextMetricsA',  \
    GetTextMetricsW, <.hdc, .lpMetrics>,  'GetTextMetricsW',  \
    GetTransform, <NONE>,  'GetTransform',  \
    GetViewportExtEx, <.hdc, .lpSize>,  'GetViewportExtEx',  \
    GetViewportOrgEx, <.hdc, .lpPoint>,  'GetViewportOrgEx',  \
    GetWinMetaFileBits, <.hemf, .cbBuffer, .lpbBuffer, .fnMapMode, .hdcRef>,  'GetWinMetaFileBits',  \
    GetWindowExtEx, <.hdc, .lpSize>,  'GetWindowExtEx',  \
    GetWindowOrgEx, <.hdc, .lpPoint>,  'GetWindowOrgEx',  \
    GetWorldTransform, <.hdc, .lpXform>,  'GetWorldTransform',  \
    HT_Get8BPPFormatPalette, <NONE>,  'HT_Get8BPPFormatPalette',  \
    HT_Get8BPPMaskPalette, <NONE>,  'HT_Get8BPPMaskPalette',  \
    IntersectClipRect, <.hdc, .X1, .Y1, .X2, .Y2>,  'IntersectClipRect',  \
    InvertRgn, <.hdc, .hRgn>,  'InvertRgn',  \
    IsValidEnhMetaRecord, <NONE>,  'IsValidEnhMetaRecord',  \
    IsValidEnhMetaRecordOffExt, <NONE>,  'IsValidEnhMetaRecordOffExt',  \
    LPtoDP, <.hdc, .lpPoint, .nCount>,  'LPtoDP',  \
    LineDDA, <.ByValt, .pLineddaproc, .lparam>,  'LineDDA',  \
    LineTo, <.hdc, .x, .y>,  'LineTo',  \
    MaskBlt, <.hdcDest, .nXDest, .nYDest, .nWidth, .nHeight, .hdcSrc, .nXSrc, .nYSrc, .hbmMask, .xMask, .yMask, .dwRop>,  'MaskBlt',  \
    MirrorRgn, <NONE>,  'MirrorRgn',  \
    ModifyWorldTransform, <.hdc, .lpXform, .iMode>,  'ModifyWorldTransform',  \
    MoveToEx, <.hdc, .x, .y, .lpPoint>,  'MoveToEx',  \
    NamedEscape, <NONE>,  'NamedEscape',  \
    OffsetClipRgn, <.hdc, .x, .y>,  'OffsetClipRgn',  \
    OffsetRgn, <.hRgn, .x, .y>,  'OffsetRgn',  \
    OffsetViewportOrgEx, <.hdc, .nX, .nY, .lpPoint>,  'OffsetViewportOrgEx',  \
    OffsetWindowOrgEx, <.hdc, .nX, .nY, .lpPoint>,  'OffsetWindowOrgEx',  \
    PATHOBJ_bEnum, <NONE>,  'PATHOBJ_bEnum',  \
    PATHOBJ_bEnumClipLines, <NONE>,  'PATHOBJ_bEnumClipLines',  \
    PATHOBJ_vEnumStart, <NONE>,  'PATHOBJ_vEnumStart',  \
    PATHOBJ_vEnumStartClipLines, <NONE>,  'PATHOBJ_vEnumStartClipLines',  \
    PATHOBJ_vGetBounds, <NONE>,  'PATHOBJ_vGetBounds',  \
    PaintRgn, <.hdc, .hRgn>,  'PaintRgn',  \
    PatBlt, <.hdc, .x, .y, .nWidth, .nHeight, .dwRop>,  'PatBlt',  \
    PathToRegion, <.hdc>,  'PathToRegion',  \
    Pie, <.hdc, .X1, .Y1, .X2, .Y2, .X3, .Y3, .X4, .Y4>,  'Pie',  \
    PlayEnhMetaFile, <.hdc, .hemf, .lpRect>,  'PlayEnhMetaFile',  \
    PlayEnhMetaFileRecord, <.hdc, .lpHandletable, .lpEnhMetaRecord, .nHandles>,  'PlayEnhMetaFileRecord',  \
    PlayMetaFile, <.hdc, .hMF>,  'PlayMetaFile',  \
    PlayMetaFileRecord, <.hdc, .lpHandletable, .lpMetaRecord, .nHandles>,  'PlayMetaFileRecord',  \
    PlgBlt, <.hdcDest, .lpPoint, .hdcSrc, .nXSrc, .nYSrc, .nWidth, .nHeight, .hbmMask, .xMask, .yMask>,  'PlgBlt',  \
    PolyBezier, <.hdc, .lppt, .cPoints>,  'PolyBezier',  \
    PolyBezierTo, <.hdc, .lppt, .cCount>,  'PolyBezierTo',  \
    PolyDraw, <.hdc, .lppt, .lpbTypes, .cCount>,  'PolyDraw',  \
    PolyPatBlt, <NONE>,  'PolyPatBlt',  \
    PolyPolygon, <.hdc, .lpPoint, .lpPolyCounts, .nCount>,  'PolyPolygon',  \
    PolyPolyline, <.hdc, .lppt, .lpdwPolyPoints, .cCount>,  'PolyPolyline',  \
    PolyTextOutA, <.hdc, .pptxt, .cStrings>,  'PolyTextOutA',  \
    PolyTextOutW, <.hdc, .pptxt, .cStrings>,  'PolyTextOutW',  \
    Polygon, <.hdc, .lpPoint, .nCount>,  'Polygon',  \
    Polyline, <.hdc, .lpPoint, .nCount>,  'Polyline',  \
    PolylineTo, <.hdc, .lppt, .cCount>,  'PolylineTo',  \
    PtInRegion, <.hRgn, .x, .y>,  'PtInRegion',  \
    PtVisible, <.hdc, .x, .y>,  'PtVisible',  \
    QueryFontAssocStatus, <NONE>,  'QueryFontAssocStatus',  \
    RealizePalette, <.hdc>,  'RealizePalette',  \
    RectInRegion, <.hRgn, .lpRect>,  'RectInRegion',  \
    RectVisible, <.hdc, .lpRect>,  'RectVisible',  \
    Rectangle, <.hdc, .X1, .Y1, .X2, .Y2>,  'Rectangle',  \
    RemoveFontMemResourceEx, <.handle>,  'RemoveFontMemResourceEx',  \
    RemoveFontResourceA, <.lpFileName>,  'RemoveFontResourceA',  \
    RemoveFontResourceExA, <.lpcstr, .dword, .DESIGNVECTOR>,  'RemoveFontResourceExA',  \
    RemoveFontResourceExW, <.lpcstr, .dword, .DESIGNVECTOR>,  'RemoveFontResourceExW',  \
    RemoveFontResourceTracking, <NONE>,  'RemoveFontResourceTracking',  \
    RemoveFontResourceW, <.lpFileName>,  'RemoveFontResourceW',  \
    ResetDCA, <.hdc, .lpInitData>,  'ResetDCA',  \
    ResetDCW, <.hdc, .lpInitData>,  'ResetDCW',  \
    ResizePalette, <.hPalette, .nNumEntries>,  'ResizePalette',  \
    RestoreDC, <.hdc, .nSavedDC>,  'RestoreDC',  \
    RoundRect, <.hdc, .X1, .Y1, .X2, .Y2, .X3, .Y3>,  'RoundRect',  \
    STROBJ_bEnum, <NONE>,  'STROBJ_bEnum',  \
    STROBJ_bEnumPositionsOnly, <NONE>,  'STROBJ_bEnumPositionsOnly',  \
    STROBJ_bGetAdvanceWidths, <NONE>,  'STROBJ_bGetAdvanceWidths',  \
    STROBJ_dwGetCodePage, <NONE>,  'STROBJ_dwGetCodePage',  \
    STROBJ_vEnumStart, <NONE>,  'STROBJ_vEnumStart',  \
    SaveDC, <.hdc>,  'SaveDC',  \
    ScaleViewportExtEx, <.hdc, .nXnum, .nXdenom, .nYnum, .nYdenom, .lpSize>,  'ScaleViewportExtEx',  \
    ScaleWindowExtEx, <.hdc, .nXnum, .nXdenom, .nYnum, .nYdenom, .lpSize>,  'ScaleWindowExtEx',  \
    SelectBrushLocal, <NONE>,  'SelectBrushLocal',  \
    SelectClipPath, <.hdc, .iMode>,  'SelectClipPath',  \
    SelectClipRgn, <.hdc, .hRgn>,  'SelectClipRgn',  \
    SelectFontLocal, <NONE>,  'SelectFontLocal',  \
    SelectObject, <.hdc, .hObject>,  'SelectObject',  \
    SelectPalette, <.hdc, .hPalette, .bForceBackground>,  'SelectPalette',  \
    SetAbortProc, <.hDC, .lpAbortProc>,  'SetAbortProc',  \
    SetArcDirection, <.hdc, .ArcDirection>,  'SetArcDirection',  \
    SetBitmapAttributes, <NONE>,  'SetBitmapAttributes',  \
    SetBitmapBits, <.hBitmap, .dwCount, .lpBits>,  'SetBitmapBits',  \
    SetBitmapDimensionEx, <.hbm, .nX, .nY, .lpSize>,  'SetBitmapDimensionEx',  \
    SetBkColor, <.hdc, .crColor>,  'SetBkColor',  \
    SetBkMode, <.hdc, .nBkMode>,  'SetBkMode',  \
    SetBoundsRect, <.hdc, .lprcBounds, .flags>,  'SetBoundsRect',  \
    SetBrushAttributes, <NONE>,  'SetBrushAttributes',  \
    SetBrushOrgEx, <.hdc, .nXOrg, .nYOrg, .lppt>,  'SetBrushOrgEx',  \
    SetColorAdjustment, <.hdc, .lpca>,  'SetColorAdjustment',  \
    SetColorSpace, <.hdc, .hcolorspace>,  'SetColorSpace',  \
    SetDCBrushColor, <.hdc, .colorref>,  'SetDCBrushColor',  \
    SetDCPenColor, <.hdc, .colorref>,  'SetDCPenColor',  \
    SetDIBColorTable, <.hDC, .un1, .un2, .pcRGBQuad>,  'SetDIBColorTable',  \
    SetDIBits, <.hdc, .hBitmap, .nStartScan, .nNumScans, .lpBits, .lpBI, .wUsage>,  'SetDIBits',  \
    SetDIBitsToDevice, <.hdc, .x, .y, .dx, .dy, .SrcX, .SrcY, .Scan, .NumScans, .Bits, .BitsInfo, .wUsage>,  'SetDIBitsToDevice',  \
    SetDeviceGammaRamp, <.hdc, .lpv>,  'SetDeviceGammaRamp',  \
    SetEnhMetaFileBits, <.cbBuffer, .lpData>,  'SetEnhMetaFileBits',  \
    SetFontEnumeration, <NONE>,  'SetFontEnumeration',  \
    SetGraphicsMode, <.hdc, .iMode>,  'SetGraphicsMode',  \
    SetICMMode, <.hdc, .n>,  'SetICMMode',  \
    SetICMProfileA, <.hdc, .lpStr>,  'SetICMProfileA',  \
    SetICMProfileW, <.hdc, .lpStr>,  'SetICMProfileW',  \
    SetLayout, <.hdc, .dword>,  'SetLayout',  \
    SetLayoutWidth, <NONE>,  'SetLayoutWidth',  \
    SetMagicColors, <NONE>,  'SetMagicColors',  \
    SetMapMode, <.hdc, .nMapMode>,  'SetMapMode',  \
    SetMapperFlags, <.hdc, .dwFlag>,  'SetMapperFlags',  \
    SetMetaFileBitsEx, <.nSize, .lpData>,  'SetMetaFileBitsEx',  \
    SetMetaRgn, <.hdc>,  'SetMetaRgn',  \
    SetMiterLimit, <.hdc, .eNewLimit, .peOldLimit>,  'SetMiterLimit',  \
    SetPaletteEntries, <.hPalette, .wStartIndex, .wNumEntries, .lpPaletteEntries>,  'SetPaletteEntries',  \
    SetPixel, <.hdc, .x, .y, .crColor>,  'SetPixel',  \
    SetPixelFormat, <.hDC, .n, .pcPixelFormatDescriptor>,  'SetPixelFormat',  \
    SetPixelV, <.hdc, .x, .y, .crColor>,  'SetPixelV',  \
    SetPolyFillMode, <.hdc, .nPolyFillMode>,  'SetPolyFillMode',  \
    SetROP2, <.hdc, .nDrawMode>,  'SetROP2',  \
    SetRectRgn, <.hRgn, .X1, .Y1, .X2, .Y2>,  'SetRectRgn',  \
    SetRelAbs, <NONE>,  'SetRelAbs',  \
    SetStretchBltMode, <.hdc, .nStretchMode>,  'SetStretchBltMode',  \
    SetSystemPaletteUse, <.hdc, .wUsage>,  'SetSystemPaletteUse',  \
    SetTextAlign, <.hdc, .fMode>,  'SetTextAlign',  \
    SetTextCharacterExtra, <.hdc, .nCharExtra>,  'SetTextCharacterExtra',  \
    SetTextColor, <.hdc, .crColor>,  'SetTextColor',  \
    SetTextJustification, <.hdc, .nBreakExtra, .nBreakCount>,  'SetTextJustification',  \
    SetViewportExtEx, <.hdc, .nX, .nY, .lpSize>,  'SetViewportExtEx',  \
    SetViewportOrgEx, <.hdc, .nX, .nY, .lpPoint>,  'SetViewportOrgEx',  \
    SetVirtualResolution, <NONE>,  'SetVirtualResolution',  \
    SetWinMetaFileBits, <.cbBuffer, .lpbBuffer, .hdcRef, .lpmfp>,  'SetWinMetaFileBits',  \
    SetWindowExtEx, <.hdc, .nX, .nY, .lpSize>,  'SetWindowExtEx',  \
    SetWindowOrgEx, <.hdc, .nX, .nY, .lpPoint>,  'SetWindowOrgEx',  \
    SetWorldTransform, <.hdc, .lpXform>,  'SetWorldTransform',  \
    StartDocA, <.hdc, .lpdi>,  'StartDocA',  \
    StartDocW, <.hdc, .lpdi>,  'StartDocW',  \
    StartFormPage, <.hdc>,  'StartFormPage',  \
    StartPage, <.hdc>,  'StartPage',  \
    StretchBlt, <.hdc, .x, .y, .nWidth, .nHeight, .hSrcDC, .xSrc, .ySrc, .nSrcWidth, .nSrcHeight, .dwRop>,  'StretchBlt',  \
    StretchDIBits, <.hdc, .x, .y, .dx, .dy, .SrcX, .SrcY, .wSrcWidth, .wSrcHeight, .lpBits, .lpBitsInfo, .wUsage, .dwRop>,  'StretchDIBits',  \
    StrokeAndFillPath, <.hdc>,  'StrokeAndFillPath',  \
    StrokePath, <.hdc>,  'StrokePath',  \
    SwapBuffers, <.hDC>,  'SwapBuffers',  \
    TextOutA, <.hdc, .x, .y, .lpString, .nCount>,  'TextOutA',  \
    TextOutW, <.hdc, .x, .y, .lpString, .nCount>,  'TextOutW',  \
    TranslateCharsetInfo, <.lpSrc, .lpcs, .dwFlags>,  'TranslateCharsetInfo',  \
    UnloadNetworkFonts, <NONE>,  'UnloadNetworkFonts',  \
    UnrealizeObject, <.hObject>,  'UnrealizeObject',  \
    UpdateColors, <.hdc>,  'UpdateColors',  \
    UpdateICMRegKeyA, <.dword, .lpstr, .uint>,  'UpdateICMRegKeyA',  \
    UpdateICMRegKeyW, <.dword, .lpstr, .uint>,  'UpdateICMRegKeyW',  \
    WidenPath, <.hdc>,  'WidenPath',  \
    XFORMOBJ_bApplyXform, <NONE>,  'XFORMOBJ_bApplyXform',  \
    XFORMOBJ_iGetXform, <NONE>,  'XFORMOBJ_iGetXform',  \
    XLATEOBJ_cGetPalette, <NONE>,  'XLATEOBJ_cGetPalette',  \
    XLATEOBJ_hGetColorTransform, <NONE>,  'XLATEOBJ_hGetColorTransform',  \
    XLATEOBJ_iXlate, <NONE>,  'XLATEOBJ_iXlate',  \
    XLATEOBJ_piVector, <NONE>,  'XLATEOBJ_piVector',  \
    bInitSystemAndFontsDirectoriesW, <NONE>,  'bInitSystemAndFontsDirectoriesW',  \
    bMakePathNameW, <NONE>,  'bMakePathNameW',  \
    cGetTTFFromFOT, <NONE>,  'cGetTTFFromFOT',  \
    gdiPlaySpoolStream, <NONE>,  'gdiPlaySpoolStream'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/imports/Win32/kernel32.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: kernel32.dll API calls
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


import_proto kernel32,  \
    ActivateActCtx, <NONE>,  'ActivateActCtx',  \
    AddAtomA, <.lpString>,  'AddAtomA',  \
    AddAtomW, <.lpString>,  'AddAtomW',  \
    AddConsoleAliasA, <NONE>,  'AddConsoleAliasA',  \
    AddConsoleAliasW, <NONE>,  'AddConsoleAliasW',  \
    AddLocalAlternateComputerNameA, <NONE>,  'AddLocalAlternateComputerNameA',  \
    AddLocalAlternateComputerNameW, <NONE>,  'AddLocalAlternateComputerNameW',  \
    AddRefActCtx, <NONE>,  'AddRefActCtx',  \
    AddVectoredExceptionHandler, <NONE>,  'AddVectoredExceptionHandler',  \
    AllocConsole, <VOID>,  'AllocConsole',  \
    AllocateUserPhysicalPages, <.hProcess, .NumberOfPages, .PageArray>,  'AllocateUserPhysicalPages',  \
    AreFileApisANSI, <VOID>,  'AreFileApisANSI',  \
    AssignProcessToJobObject, <.hJob, .hProcess>,  'AssignProcessToJobObject',  \
    AttachConsole, <NONE>,  'AttachConsole',  \
    BackupRead, <.hFile, .lpBuffer, .nNumberOfBytesToRead, .lpNumberOfBytesRead, .bAbort, .bProcessSecurity, .lpContext>,  'BackupRead',  \
    BackupSeek, <.hFile, .dwLowBytesToSeek, .dwHighBytesToSeek, .lpdwLowByteSeeked, .lpdwHighByteSeeked, .lpContext>,  'BackupSeek',  \
    BackupWrite, <.hFile, .lpBuffer, .nNumberOfBytesToWrite, .lpNumberOfBytesWritten, .bAbort, .bProcessSecurity, .lpContext>,  'BackupWrite',  \
    BaseCheckAppcompatCache, <NONE>,  'BaseCheckAppcompatCache',  \
    BaseCleanupAppcompatCache, <NONE>,  'BaseCleanupAppcompatCache',  \
    BaseCleanupAppcompatCacheSupport, <NONE>,  'BaseCleanupAppcompatCacheSupport',  \
    BaseDumpAppcompatCache, <NONE>,  'BaseDumpAppcompatCache',  \
    BaseFlushAppcompatCache, <NONE>,  'BaseFlushAppcompatCache',  \
    BaseInitAppcompatCache, <NONE>,  'BaseInitAppcompatCache',  \
    BaseInitAppcompatCacheSupport, <NONE>,  'BaseInitAppcompatCacheSupport',  \
    BaseProcessInitPostImport, <NONE>,  'BaseProcessInitPostImport',  \
    BaseQueryModuleData, <NONE>,  'BaseQueryModuleData',  \
    BaseUpdateAppcompatCache, <NONE>,  'BaseUpdateAppcompatCache',  \
    BasepCheckWinSaferRestrictions, <NONE>,  'BasepCheckWinSaferRestrictions',  \
    Beep, <.dwFreq, .dwDuration>,  'Beep',  \
    BeginUpdateResourceA, <.pFileName, .bDeleteExistingResources>,  'BeginUpdateResourceA',  \
    BeginUpdateResourceW, <.pFileName, .bDeleteExistingResources>,  'BeginUpdateResourceW',  \
    BindIoCompletionCallback, <.FileHandle, .lFunction, .Flags>,  'BindIoCompletionCallback',  \
    BuildCommDCBA, <.lpDef, .lpDCB>,  'BuildCommDCBA',  \
    BuildCommDCBAndTimeoutsA, <.lpDef, .lpDCB, .lpCommTimeouts>,  'BuildCommDCBAndTimeoutsA',  \
    BuildCommDCBAndTimeoutsW, <.lpDef, .lpDCB, .lpCommTimeouts>,  'BuildCommDCBAndTimeoutsW',  \
    BuildCommDCBW, <.lpDef, .lpDCB>,  'BuildCommDCBW',  \
    CallNamedPipeA, <.lpNamedPipeName, .lpInBuffer, .nInBufferSize, .lpOutBuffer, .nOutBufferSize, .lpBytesRead, .nTimeOut>,  'CallNamedPipeA',  \
    CallNamedPipeW, <.lpNamedPipeName, .lpInBuffer, .nInBufferSize, .lpOutBuffer, .nOutBufferSize, .lpBytesRead, .nTimeOut>,  'CallNamedPipeW',  \
    CancelDeviceWakeupRequest, <.hDevice>,  'CancelDeviceWakeupRequest',  \
    CancelIo, <.hFile>,  'CancelIo',  \
    CancelTimerQueueTimer, <.TimerQueue, .Timer>,  'CancelTimerQueueTimer',  \
    CancelWaitableTimer, <.hTimer>,  'CancelWaitableTimer',  \
    ChangeTimerQueueTimer, <.TimerQueue, .Timer, .DueTime, .Period>,  'ChangeTimerQueueTimer',  \
    CheckNameLegalDOS8Dot3A, <NONE>,  'CheckNameLegalDOS8Dot3A',  \
    CheckNameLegalDOS8Dot3W, <NONE>,  'CheckNameLegalDOS8Dot3W',  \
    CheckRemoteDebuggerPresent, <NONE>,  'CheckRemoteDebuggerPresent',  \
    ClearCommBreak, <.nCid>,  'ClearCommBreak',  \
    ClearCommError, <.hFile, .lpErrors, .lpStat>,  'ClearCommError',  \
    CloseConsoleHandle, <NONE>,  'CloseConsoleHandle',  \
    CloseHandle, <.hObject>,  'CloseHandle',  \
    CloseProfileUserMapping, <NONE>,  'CloseProfileUserMapping',  \
    CmdBatNotification, <NONE>,  'CmdBatNotification',  \
    CommConfigDialogA, <.lpszName, .hWnd, .lpCC>,  'CommConfigDialogA',  \
    CommConfigDialogW, <.lpszName, .hWnd, .lpCC>,  'CommConfigDialogW',  \
    CompareFileTime, <.lpFileTime1, .lpFileTime2>,  'CompareFileTime',  \
    CompareStringA, <.Locale, .dwCmpFlags, .lpString1, .cchCount1, .lpString2, .cchCount2>,  'CompareStringA',  \
    CompareStringW, <.Locale, .dwCmpFlags, .lpString1, .cchCount1, .lpString2, .cchCount2>,  'CompareStringW',  \
    ConnectNamedPipe, <.hNamedPipe, .lpOverlapped>,  'ConnectNamedPipe',  \
    ConsoleMenuControl, <NONE>,  'ConsoleMenuControl',  \
    ContinueDebugEvent, <.dwProcessId, .dwThreadId, .dwContinueStatus>,  'ContinueDebugEvent',  \
    ConvertDefaultLocale, <.Locale>,  'ConvertDefaultLocale',  \
    ConvertFiberToThread, <NONE>,  'ConvertFiberToThread',  \
    ConvertThreadToFiber, <.lpParameter>,  'ConvertThreadToFiber',  \
    CopyFileA, <.lpExistingFileName, .lpNewFileName, .bFailIfExists>,  'CopyFileA',  \
    CopyFileExA, <.lpExistingFileName, .lpNewFileName, .lpProgressRoutine, .lpData, .pbCancel, .dwCopyFlags>,  'CopyFileExA',  \
    CopyFileExW, <.lpExistingFileName, .lpNewFileName, .lpProgressRoutine, .lpData, .pbCancel, .dwCopyFlags>,  'CopyFileExW',  \
    CopyFileW, <.lpExistingFileName, .lpNewFileName, .bFailIfExists>,  'CopyFileW',  \
    CopyLZFile, <.n1, .n2>,  'CopyLZFile',  \
    CreateActCtxA, <NONE>,  'CreateActCtxA',  \
    CreateActCtxW, <NONE>,  'CreateActCtxW',  \
    CreateConsoleScreenBuffer, <.dwDesiredAccess, .dwShareMode, .lpSecurityAttributes, .dwFlags, .lpScreenBufferData>,  'CreateConsoleScreenBuffer',  \
    CreateDirectoryA, <.lpPathName, .lpSecurityAttributes>,  'CreateDirectoryA',  \
    CreateDirectoryExA, <.lpTemplateDirectory, .lpNewDirectory, .lpSecurityAttributes>,  'CreateDirectoryExA',  \
    CreateDirectoryExW, <.lpTemplateDirectory, .lpNewDirectory, .lpSecurityAttributes>,  'CreateDirectoryExW',  \
    CreateDirectoryW, <.lpPathName, .lpSecurityAttributes>,  'CreateDirectoryW',  \
    CreateEventA, <.lpEventAttributes, .bManualReset, .bInitialState, .lpName>,  'CreateEventA',  \
    CreateEventW, <.lpEventAttributes, .bManualReset, .bInitialState, .lpName>,  'CreateEventW',  \
    CreateFiber, <.dwStackSize, .lpStartAddress, .lpParameter>,  'CreateFiber',  \
    CreateFiberEx, <NONE>,  'CreateFiberEx',  \
    CreateFileA, <.lpFileName, .dwDesiredAccess, .dwShareMode, .lpSecurityAttributes, .dwCreationDisposition, .dwFlagsAndAttributes,  \
        .hTemplateFile>,  'CreateFileA',  \
    CreateFileMappingA, <.hFile, .lpFileMappigAttributes, .flProtect, .dwMaximumSizeHigh, .dwMaximumSizeLow, .lpName>,  'CreateFileMappingA',  \
    CreateFileMappingW, <.hFile, .lpFileMappigAttributes, .flProtect, .dwMaximumSizeHigh, .dwMaximumSizeLow, .lpName>,  'CreateFileMappingW',  \
    CreateFileW, <.lpFileName, .dwDesiredAccess, .dwShareMode, .lpSecurityAttributes, .dwCreationDisposition, .dwFlagsAndAttributes,  \
        .hTemplateFile>,  'CreateFileW',  \
    CreateHardLinkA, <.lpFileName, .lpExistingFileName, .lpSecurityAttributes>,  'CreateHardLinkA',  \
    CreateHardLinkW, <.lpFileName, .lpExistingFileName, .lpSecurityAttributes>,  'CreateHardLinkW',  \
    CreateIoCompletionPort, <.FileHandle, .ExistingCompletionPort, .CompletionKey, .NumberOfConcurrentThreads>,  'CreateIoCompletionPort',  \
    CreateJobObjectA, <.lpJobAttributes, .lpName>,  'CreateJobObjectA',  \
    CreateJobObjectW, <.lpJobAttributes, .lpName>,  'CreateJobObjectW',  \
    CreateJobSet, <NONE>,  'CreateJobSet',  \
    CreateMailslotA, <.lpName, .nMaxMessageSize, .lReadTimeout, .lpSecurityAttributes>,  'CreateMailslotA',  \
    CreateMailslotW, <.lpName, .nMaxMessageSize, .lReadTimeout, .lpSecurityAttributes>,  'CreateMailslotW',  \
    CreateMemoryResourceNotification, <NONE>,  'CreateMemoryResourceNotification',  \
    CreateMutexA, <.lpMutexAttributes, .bInitialOwner, .lpName>,  'CreateMutexA',  \
    CreateMutexW, <.lpMutexAttributes, .bInitialOwner, .lpName>,  'CreateMutexW',  \
    CreateNamedPipeA, <.lpName, .dwOpenMode, .dwPipeMode, .nMaxInstances, .nOutBufferSize, .nInBufferSize, .nDefaultTimeOut, .lpSecurityAttributes,  \
      >,  'CreateNamedPipeA',  \
    CreateNamedPipeW, <.lpName, .dwOpenMode, .dwPipeMode, .nMaxInstances, .nOutBufferSize, .nInBufferSize, .nDefaultTimeOut, .lpSecurityAttributes,  \
      >,  'CreateNamedPipeW',  \
    CreateNlsSecurityDescriptor, <NONE>,  'CreateNlsSecurityDescriptor',  \
    CreatePipe, <.phReadPipe, .phWritePipe, .lpPipeAttributes, .nSize>,  'CreatePipe',  \
    CreateProcessA, <.lpApplicationName, .lpCommandLine, .lpProcessAttributes, .lpThreadAttributes, .bInheritHandles, .dwCreationFlags,  \
        .lpEnvironment, .lpCurrentDriectory, .lpStartupInfo, .lpProcessInformation>,  'CreateProcessA',  \
    CreateProcessInternalA, <NONE>,  'CreateProcessInternalA',  \
    CreateProcessInternalW, <NONE>,  'CreateProcessInternalW',  \
    CreateProcessInternalWSecure, <NONE>,  'CreateProcessInternalWSecure',  \
    CreateProcessW, <.lpApplicationName, .lpCommandLine, .lpProcessAttributes, .lpThreadAttributes, .bInheritHandles, .dwCreationFlags,  \
        .lpEnvironment, .lpCurrentDriectory, .lpStartupInfo, .lpProcessInformation>,  'CreateProcessW',  \
    CreateRemoteThread, <.hProcess, .lpThreadAttributes, .dwStackSize, .lpStartAddress, .lpParameter, .dwCreationFlags, .lpThreadId,  \
      >,  'CreateRemoteThread',  \
    CreateSemaphoreA, <.lpSemaphoreAttributes, .lInitialCount, .lMaximumCount, .lpName>,  'CreateSemaphoreA',  \
    CreateSemaphoreW, <.lpSemaphoreAttributes, .lInitialCount, .lMaximumCount, .lpName>,  'CreateSemaphoreW',  \
    CreateSocketHandle, <NONE>,  'CreateSocketHandle',  \
    CreateTapePartition, <.hDevice, .dwPartitionMethod, .dwCount, .dwSize>,  'CreateTapePartition',  \
    CreateThread, <.lpThreadAttributes, .dwStackSize, .lpStartAddress, .lpParameter, .dwCreationFlags, .lpThreadId>,  'CreateThread',  \
    CreateTimerQueue, <VOID>,  'CreateTimerQueue',  \
    CreateTimerQueueTimer, <NONE>,  'CreateTimerQueueTimer',  \
    CreateToolhelp32Snapshot, <.dwFlags, .th32ProcessID>,  'CreateToolhelp32Snapshot',  \
    CreateVirtualBuffer, <NONE>,  'CreateVirtualBuffer',  \
    CreateWaitableTimerA, <.lpTimerAttributes, .bManualReset, .lpTimerName>,  'CreateWaitableTimerA',  \
    CreateWaitableTimerW, <.lpTimerAttributes, .bManualReset, .lpTimerName>,  'CreateWaitableTimerW',  \
    DeactivateActCtx, <NONE>,  'DeactivateActCtx',  \
    DebugActiveProcess, <.dwProcessId>,  'DebugActiveProcess',  \
    DebugActiveProcessStop, <NONE>,  'DebugActiveProcessStop',  \
    DebugBreak, <VOID>,  'DebugBreak',  \
    DebugBreakProcess, <NONE>,  'DebugBreakProcess',  \
    DebugSetProcessKillOnExit, <NONE>,  'DebugSetProcessKillOnExit',  \
    DecodePointer, <NONE>,  'DecodePointer',  \
    DecodeSystemPointer, <NONE>,  'DecodeSystemPointer',  \
    DefineDosDeviceA, <.dwFlags, .lpDeviceName, .lpTargetPath>,  'DefineDosDeviceA',  \
    DefineDosDeviceW, <.dwFlags, .lpDeviceName, .lpTargetPath>,  'DefineDosDeviceW',  \
    DelayLoadFailureHook, <NONE>,  'DelayLoadFailureHook',  \
    DeleteAtom, <.nAtom>,  'DeleteAtom',  \
    DeleteCriticalSection, <.lpCriticalSection>,  'DeleteCriticalSection',  \
    DeleteFiber, <.lpFiber>,  'DeleteFiber',  \
    DeleteFileA, <.lpFileName>,  'DeleteFileA',  \
    DeleteFileW, <.lpFileName>,  'DeleteFileW',  \
    DeleteTimerQueue, <.TimerQueue>,  'DeleteTimerQueue',  \
    DeleteTimerQueueEx, <.TimerQueue, .CompletionEvent>,  'DeleteTimerQueueEx',  \
    DeleteTimerQueueTimer, <.TimerQueue, .Timer, .CompletionEvent>,  'DeleteTimerQueueTimer',  \
    DeleteVolumeMountPointA, <.lpszVolumeMountPoint>,  'DeleteVolumeMountPointA',  \
    DeleteVolumeMountPointW, <.lpszVolumeMountPoint>,  'DeleteVolumeMountPointW',  \
    DeviceIoControl, <.hDevice, .dwIoControlCode, .lpInBuffer, .nInBufferSize, .lpOutBuffer, .nOutBufferSize, .lpBytesReturned, .lpOverlapped,  \
      >,  'DeviceIoControl',  \
    DisableThreadLibraryCalls, <.hLibModule>,  'DisableThreadLibraryCalls',  \
    DisconnectNamedPipe, <.hNamedPipe>,  'DisconnectNamedPipe',  \
    DnsHostnameToComputerNameA, <.Hostname, .ComputerName, .nSize>,  'DnsHostnameToComputerNameA',  \
    DnsHostnameToComputerNameW, <.Hostname, .ComputerName, .nSize>,  'DnsHostnameToComputerNameW',  \
    DosDateTimeToFileTime, <.wFatDate, .wFatTime, .lpFileTime>,  'DosDateTimeToFileTime',  \
    DosPathToSessionPathA, <.SessionId, .pInPath, .ppOutPath>,  'DosPathToSessionPathA',  \
    DosPathToSessionPathW, <.SessionId, .pInPath, .ppOutPath>,  'DosPathToSessionPathW',  \
    DuplicateConsoleHandle, <NONE>,  'DuplicateConsoleHandle',  \
    DuplicateHandle, <.hSourceProcessHandle, .hSourceHandle, .hTargetProcessHandle, .lpTargetHandle, .dwDesiredAccess, .bInheritHandle,  \
        .dwOptions>,  'DuplicateHandle',  \
    EncodePointer, <NONE>,  'EncodePointer',  \
    EncodeSystemPointer, <NONE>,  'EncodeSystemPointer',  \
    EndUpdateResourceA, <.hUpdate, .fDiscard>,  'EndUpdateResourceA',  \
    EndUpdateResourceW, <.hUpdate, .fDiscard>,  'EndUpdateResourceW',  \
    EnterCriticalSection, <.lpCriticalSection>,  'EnterCriticalSection',  \
    EnumCalendarInfoA, <.lpCalInfoEnumProc, .Locale, .Calendar, .CalType>,  'EnumCalendarInfoA',  \
    EnumCalendarInfoExA, <.lpCalInfoEnumProcEx, .Locale, .Calendar, .CalType>,  'EnumCalendarInfoExA',  \
    EnumCalendarInfoExW, <.lpCalInfoEnumProcEx, .Locale, .Calendar, .CalType>,  'EnumCalendarInfoExW',  \
    EnumCalendarInfoW, <.lpCalInfoEnumProc, .Locale, .Calendar, .CalType>,  'EnumCalendarInfoW',  \
    EnumDateFormatsA, <.lpDateFmtEnumProc, .Locale, .dwFlags>,  'EnumDateFormatsA',  \
    EnumDateFormatsExA, <.lpDateFmtEnumProcEx, .Locale, .dwFlags>,  'EnumDateFormatsExA',  \
    EnumDateFormatsExW, <.lpDateFmtEnumProcEx, .Locale, .dwFlags>,  'EnumDateFormatsExW',  \
    EnumDateFormatsW, <.lpDateFmtEnumProc, .Locale, .dwFlags>,  'EnumDateFormatsW',  \
    EnumLanguageGroupLocalesA, <.lpLangGroupLocaleEnumProc, .LanguageGroup, .dwFlags, .lParam>,  'EnumLanguageGroupLocalesA',  \
    EnumLanguageGroupLocalesW, <.lpLangGroupLocaleEnumProc, .LanguageGroup, .dwFlags, .lParam>,  'EnumLanguageGroupLocalesW',  \
    EnumResourceLanguagesA, <.hModule, .lpType, .lpName, .lpEnumFunc, .lParam>,  'EnumResourceLanguagesA',  \
    EnumResourceLanguagesW, <.hModule, .lpType, .lpName, .lpEnumFunc, .lParam>,  'EnumResourceLanguagesW',  \
    EnumResourceNamesA, <.hModule, .lpType, .lpEnumFunc, .lParam>,  'EnumResourceNamesA',  \
    EnumResourceNamesW, <.hModule, .lpType, .lpEnumFunc, .lParam>,  'EnumResourceNamesW',  \
    EnumResourceTypesA, <.hModule, .lpEnumFunc, .lParam>,  'EnumResourceTypesA',  \
    EnumResourceTypesW, <.hModule, .lpEnumFunc, .lParam>,  'EnumResourceTypesW',  \
    EnumSystemCodePagesA, <.lpCodePageEnumProc, .dwFlags>,  'EnumSystemCodePagesA',  \
    EnumSystemCodePagesW, <.lpCodePageEnumProc, .dwFlags>,  'EnumSystemCodePagesW',  \
    EnumSystemGeoID, <NONE>,  'EnumSystemGeoID',  \
    EnumSystemLanguageGroupsA, <.lpLanguageGroupEnumProc, .dwFlags, .lParam>,  'EnumSystemLanguageGroupsA',  \
    EnumSystemLanguageGroupsW, <.lpLanguageGroupEnumProc, .dwFlags, .lParam>,  'EnumSystemLanguageGroupsW',  \
    EnumSystemLocalesA, <.lpLocaleEnumProc, .dwFlags>,  'EnumSystemLocalesA',  \
    EnumSystemLocalesW, <.lpLocaleEnumProc, .dwFlags>,  'EnumSystemLocalesW',  \
    EnumTimeFormatsA, <.lpTimeFmtEnumProc, .Locale, .dwFlags>,  'EnumTimeFormatsA',  \
    EnumTimeFormatsW, <.lpTimeFmtEnumProc, .Locale, .dwFlags>,  'EnumTimeFormatsW',  \
    EnumUILanguagesA, <.lpUILanguageEnumProc, .dwFlags, .lParam>,  'EnumUILanguagesA',  \
    EnumUILanguagesW, <.lpUILanguageEnumProc, .dwFlags, .lParam>,  'EnumUILanguagesW',  \
    EnumerateLocalComputerNamesA, <NONE>,  'EnumerateLocalComputerNamesA',  \
    EnumerateLocalComputerNamesW, <NONE>,  'EnumerateLocalComputerNamesW',  \
    EraseTape, <.hDevice, .dwEraseType, .bimmediate>,  'EraseTape',  \
    EscapeCommFunction, <.nCid, .nFunc>,  'EscapeCommFunction',  \
    ExitProcess, <.uExitCode>,  'ExitProcess',  \
    ExitThread, <.dwExitCode>,  'ExitThread',  \
    ExitVDM, <NONE>,  'ExitVDM',  \
    ExpandEnvironmentStringsA, <.lpSrc, .lpDst, .nSize>,  'ExpandEnvironmentStringsA',  \
    ExpandEnvironmentStringsW, <.lpSrc, .lpDst, .nSize>,  'ExpandEnvironmentStringsW',  \
    ExpungeConsoleCommandHistoryA, <NONE>,  'ExpungeConsoleCommandHistoryA',  \
    ExpungeConsoleCommandHistoryW, <NONE>,  'ExpungeConsoleCommandHistoryW',  \
    ExtendVirtualBuffer, <NONE>,  'ExtendVirtualBuffer',  \
    FatalAppExitA, <.uAction, .lpMessageText>,  'FatalAppExitA',  \
    FatalAppExitW, <.uAction, .lpMessageText>,  'FatalAppExitW',  \
    FatalExit, <.code>,  'FatalExit',  \
    FileTimeToDosDateTime, <.lpFileTime, .lpFatDate, .lpFatTime>,  'FileTimeToDosDateTime',  \
    FileTimeToLocalFileTime, <.lpFileTime, .lpLocalFileTime>,  'FileTimeToLocalFileTime',  \
    FileTimeToSystemTime, <.lpFileTime, .lpSystemTime>,  'FileTimeToSystemTime',  \
    FillConsoleOutputAttribute, <.hConsoleOutput, .wAttribute, .nLength, .dwWriteCoord, .lpNumberOfAttrsWritten>,  'FillConsoleOutputAttribute',  \
    FillConsoleOutputCharacterA, <.hConsoleOutput, .cCharacter, .nLength, .dwWriteCoord, .lpNumberOfCharsWritten>,  'FillConsoleOutputCharacterA',  \
    FillConsoleOutputCharacterW, <.hConsoleOutput, .cCharacter, .nLength, .dwWriteCoord, .lpNumberOfCharsWritten>,  'FillConsoleOutputCharacterW',  \
    FindActCtxSectionGuid, <NONE>,  'FindActCtxSectionGuid',  \
    FindActCtxSectionStringA, <NONE>,  'FindActCtxSectionStringA',  \
    FindActCtxSectionStringW, <NONE>,  'FindActCtxSectionStringW',  \
    FindAtomA, <.lpString>,  'FindAtomA',  \
    FindAtomW, <.lpString>,  'FindAtomW',  \
    FindClose, <.hFindFile>,  'FindClose',  \
    FindCloseChangeNotification, <.hChangeHandle>,  'FindCloseChangeNotification',  \
    FindFirstChangeNotificationA, <.lpPathName, .bWatchSubtree, .dwNotifyFilter>,  'FindFirstChangeNotificationA',  \
    FindFirstChangeNotificationW, <.lpPathName, .bWatchSubtree, .dwNotifyFilter>,  'FindFirstChangeNotificationW',  \
    FindFirstFileA, <.lpFileName, .lpFindFileData>,  'FindFirstFileA',  \
    FindFirstFileExA, <.lpFileName, .fInfoLevelId, .lpFindFileData, .fSearchOp, .lpSearchFilter, .dwAdditionalFlags>,  'FindFirstFileExA',  \
    FindFirstFileExW, <.lpFileName, .fInfoLevelId, .lpFindFileData, .fSearchOp, .lpSearchFilter, .dwAdditionalFlags>,  'FindFirstFileExW',  \
    FindFirstFileW, <.lpFileName, .lpFindFileData>,  'FindFirstFileW',  \
    FindFirstVolumeA, <.lpszVolumeName, .cchBufferLength>,  'FindFirstVolumeA',  \
    FindFirstVolumeMountPointA, <.lpszRootPathName, .lpszVolumeMountPoint, .cchBufferLength>,  'FindFirstVolumeMountPointA',  \
    FindFirstVolumeMountPointW, <.lpszRootPathName, .lpszVolumeMountPoint, .cchBufferLength>,  'FindFirstVolumeMountPointW',  \
    FindFirstVolumeW, <.lpszVolumeName, .cchBufferLength>,  'FindFirstVolumeW',  \
    FindNextChangeNotification, <.hChangeHandle>,  'FindNextChangeNotification',  \
    FindNextFileA, <.hFindFile, .lpFindFileData>,  'FindNextFileA',  \
    FindNextFileW, <.hFindFile, .lpFindFileData>,  'FindNextFileW',  \
    FindNextVolumeA, <.hFindVolume, .lpszVolumeName, .cchBufferLength>,  'FindNextVolumeA',  \
    FindNextVolumeMountPointA, <.hFindVolumeMountPoint, .lpszVolumeMountPoint, .cchBufferLength>,  'FindNextVolumeMountPointA',  \
    FindNextVolumeMountPointW, <.hFindVolumeMountPoint, .lpszVolumeMountPoint, .cchBufferLength>,  'FindNextVolumeMountPointW',  \
    FindNextVolumeW, <.hFindVolume, .lpszVolumeName, .cchBufferLength>,  'FindNextVolumeW',  \
    FindResourceA, <.hInstance, .lpName, .lpType>,  'FindResourceA',  \
    FindResourceExA, <.hModule, .lpType, .lpName, .wLanguage>,  'FindResourceExA',  \
    FindResourceExW, <.hModule, .lpType, .lpName, .wLanguage>,  'FindResourceExW',  \
    FindResourceW, <.hInstance, .lpName, .lpType>,  'FindResourceW',  \
    FindVolumeClose, <.hFindVolume>,  'FindVolumeClose',  \
    FindVolumeMountPointClose, <.hFindVolumeMountPoint>,  'FindVolumeMountPointClose',  \
    FlushConsoleInputBuffer, <.hConsoleInput>,  'FlushConsoleInputBuffer',  \
    FlushFileBuffers, <.hFile>,  'FlushFileBuffers',  \
    FlushInstructionCache, <.hProcess, .lpBaseAddress, .dwSize>,  'FlushInstructionCache',  \
    FlushViewOfFile, <.lpBaseAddress, .dwNumberOfBytesToFlush>,  'FlushViewOfFile',  \
    FoldStringA, <.dwMapFlags, .lpSrcStr, .cchSrc, .lpDestStr, .cchDest>,  'FoldStringA',  \
    FoldStringW, <.dwMapFlags, .lpSrcStr, .cchSrc, .lpDestStr, .cchDest>,  'FoldStringW',  \
    FormatMessageA, <.dwFlags, .lpSource, .dwMessageId, .dwLanguageId, .lpBuffer, .nSize, .Arguments>,  'FormatMessageA',  \
    FormatMessageW, <.dwFlags, .lpSource, .dwMessageId, .dwLanguageId, .lpBuffer, .nSize, .Arguments>,  'FormatMessageW',  \
    FreeConsole, <VOID>,  'FreeConsole',  \
    FreeEnvironmentStringsA, <.lpsz>,  'FreeEnvironmentStringsA',  \
    FreeEnvironmentStringsW, <.lpsz>,  'FreeEnvironmentStringsW',  \
    FreeLibrary, <.hLibModule>,  'FreeLibrary',  \
    FreeLibraryAndExitThread, <.hLibModule, .dwExitCode>,  'FreeLibraryAndExitThread',  \
    FreeResource, <.hResData>,  'FreeResource',  \
    FreeUserPhysicalPages, <.hProcess, .NumberOfPages, .PageArray>,  'FreeUserPhysicalPages',  \
    FreeVirtualBuffer, <NONE>,  'FreeVirtualBuffer',  \
    GenerateConsoleCtrlEvent, <.dwCtrlEvent, .dwProcessGroupId>,  'GenerateConsoleCtrlEvent',  \
    GetACP, <VOID>,  'GetACP',  \
    GetAtomNameA, <.nAtom, .lpBuffer, .nSize>,  'GetAtomNameA',  \
    GetAtomNameW, <.nAtom, .lpBuffer, .nSize>,  'GetAtomNameW',  \
    GetBinaryType, <.lpApplicationName, .lpBinaryType>,  'GetBinaryType',  \
    GetBinaryTypeA, <.lpApplicationName, .lpBinaryType>,  'GetBinaryTypeA',  \
    GetBinaryTypeW, <.lpApplicationName, .lpBinaryType>,  'GetBinaryTypeW',  \
    GetCPFileNameFromRegistry, <NONE>,  'GetCPFileNameFromRegistry',  \
    GetCPInfo, <.CodePage, .lpCPInfo>,  'GetCPInfo',  \
    GetCPInfoExA, <.CodePage, .dwFlags, .lpCPInfoEx>,  'GetCPInfoExA',  \
    GetCPInfoExW, <.CodePage, .dwFlags, .lpCPInfoEx>,  'GetCPInfoExW',  \
    GetCalendarInfoA, <.Locale, .Calendar, .CalType, .lpCalData, .cchData, .lpValue>,  'GetCalendarInfoA',  \
    GetCalendarInfoW, <.Locale, .Calendar, .CalType, .lpCalData, .cchData, .lpValue>,  'GetCalendarInfoW',  \
    GetComPlusPackageInstallStatus, <NONE>,  'GetComPlusPackageInstallStatus',  \
    GetCommConfig, <.hCommDev, .lpCC, .lpdwSize>,  'GetCommConfig',  \
    GetCommMask, <.hFile, .lpEvtMask>,  'GetCommMask',  \
    GetCommModemStatus, <.hFile, .lpModemStat>,  'GetCommModemStatus',  \
    GetCommProperties, <.hFile, .lpCommProp>,  'GetCommProperties',  \
    GetCommState, <.nCid, .lpDCB>,  'GetCommState',  \
    GetCommTimeouts, <.hFile, .lpCommTimeouts>,  'GetCommTimeouts',  \
    GetCommandLineA, <VOID>,  'GetCommandLineA',  \
    GetCommandLineW, <VOID>,  'GetCommandLineW',  \
    GetCompressedFileSizeA, <.lpFileName, .lpFileSizeHigh>,  'GetCompressedFileSizeA',  \
    GetCompressedFileSizeW, <.lpFileName, .lpFileSizeHigh>,  'GetCompressedFileSizeW',  \
    GetComputerNameA, <.lpBuffer, .nSize>,  'GetComputerNameA',  \
    GetComputerNameExA, <.NameType, .lpBuffer, .nSize>,  'GetComputerNameExA',  \
    GetComputerNameExW, <.NameType, .lpBuffer, .nSize>,  'GetComputerNameExW',  \
    GetComputerNameW, <.lpBuffer, .nSize>,  'GetComputerNameW',  \
    GetConsoleAliasA, <NONE>,  'GetConsoleAliasA',  \
    GetConsoleAliasExesA, <NONE>,  'GetConsoleAliasExesA',  \
    GetConsoleAliasExesLengthA, <NONE>,  'GetConsoleAliasExesLengthA',  \
    GetConsoleAliasExesLengthW, <NONE>,  'GetConsoleAliasExesLengthW',  \
    GetConsoleAliasExesW, <NONE>,  'GetConsoleAliasExesW',  \
    GetConsoleAliasW, <NONE>,  'GetConsoleAliasW',  \
    GetConsoleAliasesA, <NONE>,  'GetConsoleAliasesA',  \
    GetConsoleAliasesLengthA, <NONE>,  'GetConsoleAliasesLengthA',  \
    GetConsoleAliasesLengthW, <NONE>,  'GetConsoleAliasesLengthW',  \
    GetConsoleAliasesW, <NONE>,  'GetConsoleAliasesW',  \
    GetConsoleCP, <VOID>,  'GetConsoleCP',  \
    GetConsoleCharType, <NONE>,  'GetConsoleCharType',  \
    GetConsoleCommandHistoryA, <NONE>,  'GetConsoleCommandHistoryA',  \
    GetConsoleCommandHistoryLengthA, <NONE>,  'GetConsoleCommandHistoryLengthA',  \
    GetConsoleCommandHistoryLengthW, <NONE>,  'GetConsoleCommandHistoryLengthW',  \
    GetConsoleCommandHistoryW, <NONE>,  'GetConsoleCommandHistoryW',  \
    GetConsoleCursorInfo, <.hConsoleOutput, .lpConsoleCursorInfo>,  'GetConsoleCursorInfo',  \
    GetConsoleCursorMode, <NONE>,  'GetConsoleCursorMode',  \
    GetConsoleDisplayMode, <NONE>,  'GetConsoleDisplayMode',  \
    GetConsoleFontInfo, <NONE>,  'GetConsoleFontInfo',  \
    GetConsoleFontSize, <NONE>,  'GetConsoleFontSize',  \
    GetConsoleHardwareState, <NONE>,  'GetConsoleHardwareState',  \
    GetConsoleInputExeNameA, <NONE>,  'GetConsoleInputExeNameA',  \
    GetConsoleInputExeNameW, <NONE>,  'GetConsoleInputExeNameW',  \
    GetConsoleInputWaitHandle, <NONE>,  'GetConsoleInputWaitHandle',  \
    GetConsoleKeyboardLayoutNameA, <NONE>,  'GetConsoleKeyboardLayoutNameA',  \
    GetConsoleKeyboardLayoutNameW, <NONE>,  'GetConsoleKeyboardLayoutNameW',  \
    GetConsoleMode, <.hConsoleHandle, .lpMode>,  'GetConsoleMode',  \
    GetConsoleNlsMode, <NONE>,  'GetConsoleNlsMode',  \
    GetConsoleOutputCP, <VOID>,  'GetConsoleOutputCP',  \
    GetConsoleProcessList, <NONE>,  'GetConsoleProcessList',  \
    GetConsoleScreenBufferInfo, <.hConsoleOutput, .lpConsoleScreenBufferInfo>,  'GetConsoleScreenBufferInfo',  \
    GetConsoleSelectionInfo, <NONE>,  'GetConsoleSelectionInfo',  \
    GetConsoleTitleA, <.lpConsoleTitle, .nSize>,  'GetConsoleTitleA',  \
    GetConsoleTitleW, <.lpConsoleTitle, .nSize>,  'GetConsoleTitleW',  \
    GetConsoleWindow, <NONE>,  'GetConsoleWindow',  \
    GetCurrencyFormatA, <.Locale, .dwFlags, .lpValue, .lpFormat, .lpCurrencyStr, .cchCurrency>,  'GetCurrencyFormatA',  \
    GetCurrencyFormatW, <.Locale, .dwFlags, .lpValue, .lpFormat, .lpCurrencyStr, .cchCurrency>,  'GetCurrencyFormatW',  \
    GetCurrentActCtx, <NONE>,  'GetCurrentActCtx',  \
    GetCurrentConsoleFont, <NONE>,  'GetCurrentConsoleFont',  \
    GetCurrentDirectoryA, <.nBufferLength, .lpBuffer>,  'GetCurrentDirectoryA',  \
    GetCurrentDirectoryW, <.nBufferLength, .lpBuffer>,  'GetCurrentDirectoryW',  \
    GetCurrentProcess, <VOID>,  'GetCurrentProcess',  \
    GetCurrentProcessId, <VOID>,  'GetCurrentProcessId',  \
    GetCurrentThread, <VOID>,  'GetCurrentThread',  \
    GetCurrentThreadId, <VOID>,  'GetCurrentThreadId',  \
    GetDateFormatA, <.Locale, .dwFlags, .lpDate, .lpFormat, .lpDateStr, .cchDate>,  'GetDateFormatA',  \
    GetDateFormatW, <.Locale, .dwFlags, .lpDate, .lpFormat, .lpDateStr, .cchDate>,  'GetDateFormatW',  \
    GetDefaultCommConfigA, <.lpszName, .lpCC, .lpdwSize>,  'GetDefaultCommConfigA',  \
    GetDefaultCommConfigW, <.lpszName, .lpCC, .lpdwSize>,  'GetDefaultCommConfigW',  \
    GetDefaultSortkeySize, <NONE>,  'GetDefaultSortkeySize',  \
    GetDevicePowerState, <.hDevice, .pfOn>,  'GetDevicePowerState',  \
    GetDiskFreeSpaceA, <.lpRootPathName, .lpSectorsPerCluster, .lpBytesPerSector, .lpNumberOfFreeClusters, .lpTotalNumberOfClusters,  \
      >,  'GetDiskFreeSpaceA',  \
    GetDiskFreeSpaceExA, <.lpDirectoryName, .lpFreeBytesAvailableToCaller, .lpTotalNumberOfBytes, .lpTotalNumberOfFreeBytes>,  'GetDiskFreeSpaceExA',  \
    GetDiskFreeSpaceExW, <.lpDirectoryName, .lpFreeBytesAvailableToCaller, .lpTotalNumberOfBytes, .lpTotalNumberOfFreeBytes>,  'GetDiskFreeSpaceExW',  \
    GetDiskFreeSpaceW, <.lpRootPathName, .lpSectorsPerCluster, .lpBytesPerSector, .lpNumberOfFreeClusters, .lpTotalNumberOfClusters,  \
      >,  'GetDiskFreeSpaceW',  \
    GetDllDirectoryA, <NONE>,  'GetDllDirectoryA',  \
    GetDllDirectoryW, <NONE>,  'GetDllDirectoryW',  \
    GetDriveTypeA, <.nDrive>,  'GetDriveTypeA',  \
    GetDriveTypeW, <.nDrive>,  'GetDriveTypeW',  \
    GetEnvironmentStrings, <VOID>,  'GetEnvironmentStrings',  \
    GetEnvironmentStringsA, <VOID>,  'GetEnvironmentStringsA',  \
    GetEnvironmentStringsW, <VOID>,  'GetEnvironmentStringsW',  \
    GetEnvironmentVariableA, <.lpName, .lpBuffer, .nSize>,  'GetEnvironmentVariableA',  \
    GetEnvironmentVariableW, <.lpName, .lpBuffer, .nSize>,  'GetEnvironmentVariableW',  \
    GetExitCodeProcess, <.hProcess, .lpExitCode>,  'GetExitCodeProcess',  \
    GetExitCodeThread, <.hThread, .lpExitCode>,  'GetExitCodeThread',  \
    GetExpandedNameA, <.lpszSource, .lpszBuffer>,  'GetExpandedNameA',  \
    GetExpandedNameW, <.lpszSource, .lpszBuffer>,  'GetExpandedNameW',  \
    GetFileAttributesA, <.lpFileName>,  'GetFileAttributesA',  \
    GetFileAttributesExA, <.lpFileName, .fInfoLevelId, .lpFileInformation>,  'GetFileAttributesExA',  \
    GetFileAttributesExW, <.lpFileName, .fInfoLevelId, .lpFileInformation>,  'GetFileAttributesExW',  \
    GetFileAttributesW, <.lpFileName>,  'GetFileAttributesW',  \
    GetFileInformationByHandle, <.hFile, .lpFileInformation>,  'GetFileInformationByHandle',  \
    GetFileSize, <.hFile, .lpFileSizeHigh>,  'GetFileSize',  \
    GetFileSizeEx, <.hFile, .lpFileSize>,  'GetFileSizeEx',  \
    GetFileTime, <.hFile, .lpCreationTime, .lpLastAccessTime, .lpLastWriteTime>,  'GetFileTime',  \
    GetFileType, <.hFile>,  'GetFileType',  \
    GetFirmwareEnvironmentVariableA, <NONE>,  'GetFirmwareEnvironmentVariableA',  \
    GetFirmwareEnvironmentVariableW, <NONE>,  'GetFirmwareEnvironmentVariableW',  \
    GetFullPathNameA, <.lpFileName, .nBufferLength, .lpBuffer, .lpFilePart>,  'GetFullPathNameA',  \
    GetFullPathNameW, <.lpFileName, .nBufferLength, .lpBuffer, .lpFilePart>,  'GetFullPathNameW',  \
    GetGeoInfoA, <NONE>,  'GetGeoInfoA',  \
    GetGeoInfoW, <NONE>,  'GetGeoInfoW',  \
    GetHandleContext, <NONE>,  'GetHandleContext',  \
    GetHandleInformation, <.hObject, .lpdwFlags>,  'GetHandleInformation',  \
    GetLargestConsoleWindowSize, <.hConsoleOutput>,  'GetLargestConsoleWindowSize',  \
    GetLastError, <VOID>,  'GetLastError',  \
    GetLinguistLangSize, <NONE>,  'GetLinguistLangSize',  \
    GetLocalTime, <.lpSystemTime>,  'GetLocalTime',  \
    GetLocaleInfoA, <.Locale, .LCType, .lpLCData, .cchData>,  'GetLocaleInfoA',  \
    GetLocaleInfoW, <.Locale, .LCType, .lpLCData, .cchData>,  'GetLocaleInfoW',  \
    GetLogicalDriveStringsA, <.nBufferLength, .lpBuffer>,  'GetLogicalDriveStringsA',  \
    GetLogicalDriveStringsW, <.nBufferLength, .lpBuffer>,  'GetLogicalDriveStringsW',  \
    GetLogicalDrives, <VOID>,  'GetLogicalDrives',  \
    GetLogicalProcessorInformation, <NONE>,  'GetLogicalProcessorInformation',  \
    GetLongPathNameA, <.lpszShortPath, .lpszLongPath, .cchBuffer>,  'GetLongPathNameA',  \
    GetLongPathNameW, <.lpszShortPath, .lpszLongPath, .cchBuffer>,  'GetLongPathNameW',  \
    GetMailslotInfo, <.hMailslot, .lpMaxMessageSize, .lpNextSize, .lpMessageCount, .lpReadTimeout>,  'GetMailslotInfo',  \
    GetModuleFileNameA, <.hModule, .lpFileName, .nSize>,  'GetModuleFileNameA',  \
    GetModuleFileNameW, <.hModule, .lpFileName, .nSize>,  'GetModuleFileNameW',  \
    GetModuleHandleA, <.lpModuleName>,  'GetModuleHandleA',  \
    GetModuleHandleExA, <NONE>,  'GetModuleHandleExA',  \
    GetModuleHandleExW, <NONE>,  'GetModuleHandleExW',  \
    GetModuleHandleW, <.lpModuleName>,  'GetModuleHandleW',  \
    GetNamedPipeHandleStateA, <.hNamedPipe, .lpState, .lpCurInstances, .lpMaxCollectionCount, .lpCollectDataTimeout, .lpUserName, .nMaxUserNameSize,  \
      >,  'GetNamedPipeHandleStateA',  \
    GetNamedPipeHandleStateW, <.hNamedPipe, .lpState, .lpCurInstances, .lpMaxCollectionCount, .lpCollectDataTimeout, .lpUserName, .nMaxUserNameSize,  \
      >,  'GetNamedPipeHandleStateW',  \
    GetNamedPipeInfo, <.hNamedPipe, .lpFlags, .lpOutBufferSize, .lpInBufferSize, .lpMaxInstances>,  'GetNamedPipeInfo',  \
    GetNativeSystemInfo, <NONE>,  'GetNativeSystemInfo',  \
    GetNextVDMCommand, <NONE>,  'GetNextVDMCommand',  \
    GetNlsSectionName, <NONE>,  'GetNlsSectionName',  \
    GetNumaAvailableMemory, <NONE>,  'GetNumaAvailableMemory',  \
    GetNumaAvailableMemoryNode, <NONE>,  'GetNumaAvailableMemoryNode',  \
    GetNumaHighestNodeNumber, <NONE>,  'GetNumaHighestNodeNumber',  \
    GetNumaNodeProcessorMask, <NONE>,  'GetNumaNodeProcessorMask',  \
    GetNumaProcessorMap, <NONE>,  'GetNumaProcessorMap',  \
    GetNumaProcessorNode, <NONE>,  'GetNumaProcessorNode',  \
    GetNumberFormatA, <.Locale, .dwFlags, .lpValue, .lpFormat, .lpNumberStr, .cchNumber>,  'GetNumberFormatA',  \
    GetNumberFormatW, <.Locale, .dwFlags, .lpValue, .lpFormat, .lpNumberStr, .cchNumber>,  'GetNumberFormatW',  \
    GetNumberOfConsoleFonts, <NONE>,  'GetNumberOfConsoleFonts',  \
    GetNumberOfConsoleInputEvents, <.hConsoleInput, .lpNumberOfEvents>,  'GetNumberOfConsoleInputEvents',  \
    GetNumberOfConsoleMouseButtons, <.lpNumberOfMouseButtons>,  'GetNumberOfConsoleMouseButtons',  \
    GetOEMCP, <VOID>,  'GetOEMCP',  \
    GetOverlappedResult, <.hFile, .lpOverlapped, .lpNumberOfBytesTransferred, .bWait>,  'GetOverlappedResult',  \
    GetPriorityClass, <.hProcess>,  'GetPriorityClass',  \
    GetPrivateProfileIntA, <.lpApplicationName, .lpKeyName, .nDefault, .lpFileName>,  'GetPrivateProfileIntA',  \
    GetPrivateProfileIntW, <.lpApplicationName, .lpKeyName, .nDefault, .lpFileName>,  'GetPrivateProfileIntW',  \
    GetPrivateProfileSectionA, <.lpAppName, .lpReturnedString, .nSize, .lpFileName>,  'GetPrivateProfileSectionA',  \
    GetPrivateProfileSectionNamesA, <.lpszReturnBuffer, .nSize, .lpFileName>,  'GetPrivateProfileSectionNamesA',  \
    GetPrivateProfileSectionNamesW, <.lpszReturnBuffer, .nSize, .lpFileName>,  'GetPrivateProfileSectionNamesW',  \
    GetPrivateProfileSectionW, <.lpAppName, .lpReturnedString, .nSize, .lpFileName>,  'GetPrivateProfileSectionW',  \
    GetPrivateProfileStringA, <.lpApplicationName, .lpKeyName, .lpDefault, .lpReturnedString, .nSize, .lpFileName>,  'GetPrivateProfileStringA',  \
    GetPrivateProfileStringW, <.lpApplicationName, .lpKeyName, .lpDefault, .lpReturnedString, .nSize, .lpFileName>,  'GetPrivateProfileStringW',  \
    GetPrivateProfileStructA, <.lpszSection, .lpszKey, .lpStruct, .uSizeStruct, .szFile>,  'GetPrivateProfileStructA',  \
    GetPrivateProfileStructW, <.lpszSection, .lpszKey, .lpStruct, .uSizeStruct, .szFile>,  'GetPrivateProfileStructW',  \
    GetProcAddress, <.hModule, .lpProcName>,  'GetProcAddress',  \
    GetProcessAffinityMask, <.hProcess, .lpProcessAffinityMask, .SystemAffinityMask>,  'GetProcessAffinityMask',  \
    GetProcessDEPPolicy, <NONE>,  'GetProcessDEPPolicy',  \
    GetProcessHandleCount, <NONE>,  'GetProcessHandleCount',  \
    GetProcessHeap, <VOID>,  'GetProcessHeap',  \
    GetProcessHeaps, <.NumberOfHeaps, .ProcessHeaps>,  'GetProcessHeaps',  \
    GetProcessId, <NONE>,  'GetProcessId',  \
    GetProcessIoCounters, <.hProcess, .lpIoCounters>,  'GetProcessIoCounters',  \
    GetProcessPriorityBoost, <.hProcess, .pDisablePriorityBoost>,  'GetProcessPriorityBoost',  \
    GetProcessShutdownParameters, <.lpdwLevel, .lpdwFlags>,  'GetProcessShutdownParameters',  \
    GetProcessTimes, <.hProcess, .lpCreationTime, .lpExitTime, .lpKernelTime, .lpUserTime>,  'GetProcessTimes',  \
    GetProcessVersion, <.ProcessId>,  'GetProcessVersion',  \
    GetProcessWorkingSetSize, <.hProcess, .lpMinimumWorkingSetSize, .lpMaximumWorkingSetSize>,  'GetProcessWorkingSetSize',  \
    GetProfileIntA, <.lpAppName, .lpKeyName, .nDefault>,  'GetProfileIntA',  \
    GetProfileIntW, <.lpAppName, .lpKeyName, .nDefault>,  'GetProfileIntW',  \
    GetProfileSectionA, <.lpAppName, .lpReturnedString, .nSize>,  'GetProfileSectionA',  \
    GetProfileSectionW, <.lpAppName, .lpReturnedString, .nSize>,  'GetProfileSectionW',  \
    GetProfileStringA, <.lpAppName, .lpKeyName, .lpDefault, .lpReturnedString, .nSize>,  'GetProfileStringA',  \
    GetProfileStringW, <.lpAppName, .lpKeyName, .lpDefault, .lpReturnedString, .nSize>,  'GetProfileStringW',  \
    GetQueuedCompletionStatus, <.CompletionPort, .lpNumberOfBytesTransferred, .lpCompletionKey, .lpOverlapped, .dwMilliseconds>,  'GetQueuedCompletionStatus',  \
    GetShortPathNameA, <.lpszLongPath, .lpszShortPath, .cchBuffer>,  'GetShortPathNameA',  \
    GetShortPathNameW, <.lpszLongPath, .lpszShortPath, .cchBuffer>,  'GetShortPathNameW',  \
    GetStartupInfoA, <.lpStartupInfo>,  'GetStartupInfoA',  \
    GetStartupInfoW, <.lpStartupInfo>,  'GetStartupInfoW',  \
    GetStdHandle, <.nStdHandle>,  'GetStdHandle',  \
    GetStringTypeA, <.Locale, .dwInfoType, .lpSrcStr, .cchSrc, .lpCharType>,  'GetStringTypeA',  \
    GetStringTypeExA, <.Locale, .dwInfoType, .lpSrcStr, .cchSrc, .lpCharType>,  'GetStringTypeExA',  \
    GetStringTypeExW, <.Locale, .dwInfoType, .lpSrcStr, .cchSrc, .lpCharType>,  'GetStringTypeExW',  \
    GetStringTypeW, <.Locale, .dwInfoType, .lpSrcStr, .cchSrc, .lpCharType>,  'GetStringTypeW',  \
    GetSystemDEPPolicy, <NONE>,  'GetSystemDEPPolicy',  \
    GetSystemDefaultLCID, <VOID>,  'GetSystemDefaultLCID',  \
    GetSystemDefaultLangID, <VOID>,  'GetSystemDefaultLangID',  \
    GetSystemDefaultUILanguage, <VOID>,  'GetSystemDefaultUILanguage',  \
    GetSystemDirectoryA, <.lpBuffer, .nSize>,  'GetSystemDirectoryA',  \
    GetSystemDirectoryW, <.lpBuffer, .nSize>,  'GetSystemDirectoryW',  \
    GetSystemInfo, <.lpSystemInfo>,  'GetSystemInfo',  \
    GetSystemPowerStatus, <.lpSystemPowerStatus>,  'GetSystemPowerStatus',  \
    GetSystemRegistryQuota, <NONE>,  'GetSystemRegistryQuota',  \
    GetSystemTime, <.lpSystemTime>,  'GetSystemTime',  \
    GetSystemTimeAdjustment, <.lpTimeAdjustment, .lpTimeIncrement, .lpTimeAdjustmentDisabled>,  'GetSystemTimeAdjustment',  \
    GetSystemTimeAsFileTime, <.lpSystemTimeAsFileTime>,  'GetSystemTimeAsFileTime',  \
    GetSystemTimes, <NONE>,  'GetSystemTimes',  \
    GetSystemWindowsDirectoryA, <.lpBuffer, .uSize>,  'GetSystemWindowsDirectoryA',  \
    GetSystemWindowsDirectoryW, <.lpBuffer, .uSize>,  'GetSystemWindowsDirectoryW',  \
    GetSystemWow64DirectoryA, <NONE>,  'GetSystemWow64DirectoryA',  \
    GetSystemWow64DirectoryW, <NONE>,  'GetSystemWow64DirectoryW',  \
    GetTapeParameters, <.hDevice, .dwOperation, .lpdwSize, .lpTapeInformation>,  'GetTapeParameters',  \
    GetTapePosition, <.hDevice, .dwPositionType, .lpdwPartition, .lpdwOffsetLow, .lpdwOffsetHigh>,  'GetTapePosition',  \
    GetTapeStatus, <.hDevice>,  'GetTapeStatus',  \
    GetTempFileNameA, <.lpszPath, .lpPrefixString, .wUnique, .lpTempFileName>,  'GetTempFileNameA',  \
    GetTempFileNameW, <.lpszPath, .lpPrefixString, .wUnique, .lpTempFileName>,  'GetTempFileNameW',  \
    GetTempPathA, <.nBufferLength, .lpBuffer>,  'GetTempPathA',  \
    GetTempPathW, <.nBufferLength, .lpBuffer>,  'GetTempPathW',  \
    GetThreadContext, <.hThread, .lpContext>,  'GetThreadContext',  \
    GetThreadIOPendingFlag, <NONE>,  'GetThreadIOPendingFlag',  \
    GetThreadLocale, <VOID>,  'GetThreadLocale',  \
    GetThreadPriority, <.hThread>,  'GetThreadPriority',  \
    GetThreadPriorityBoost, <.hThread, .pDisablePriorityBoost>,  'GetThreadPriorityBoost',  \
    GetThreadSelectorEntry, <.hThread, .dwSelector, .lpSelectorEntry>,  'GetThreadSelectorEntry',  \
    GetThreadTimes, <.hThread, .lpCreationTime, .lpExitTime, .lpKernelTime, .lpUserTime>,  'GetThreadTimes',  \
    GetTickCount, <VOID>,  'GetTickCount',  \
    GetTimeFormatA, <.Locale, .dwFlags, .lpTime, .lpFormat, .lpTimeStr, .cchTime>,  'GetTimeFormatA',  \
    GetTimeFormatW, <.Locale, .dwFlags, .lpTime, .lpFormat, .lpTimeStr, .cchTime>,  'GetTimeFormatW',  \
    GetTimeZoneInformation, <.lpTimeZoneInformation>,  'GetTimeZoneInformation',  \
    GetUserDefaultLCID, <VOID>,  'GetUserDefaultLCID',  \
    GetUserDefaultLangID, <VOID>,  'GetUserDefaultLangID',  \
    GetUserDefaultUILanguage, <VOID>,  'GetUserDefaultUILanguage',  \
    GetUserGeoID, <NONE>,  'GetUserGeoID',  \
    GetVDMCurrentDirectories, <NONE>,  'GetVDMCurrentDirectories',  \
    GetVersion, <VOID>,  'GetVersion',  \
    GetVersionExA, <.lpVersionInformation>,  'GetVersionExA',  \
    GetVersionExW, <.lpVersionInformation>,  'GetVersionExW',  \
    GetVolumeInformationA, <.lpRootPathName, .lpVolumeNameBuffer, .nVolumeNameSize, .lpVolumeSerialNumber, .lpMaximumComponentLength,  \
        .lpFileSystemFlags, .lpFileSystemNameBuffer, .nFileSystemNameSize>,  'GetVolumeInformationA',  \
    GetVolumeInformationW, <.lpRootPathName, .lpVolumeNameBuffer, .nVolumeNameSize, .lpVolumeSerialNumber, .lpMaximumComponentLength,  \
        .lpFileSystemFlags, .lpFileSystemNameBuffer, .nFileSystemNameSize>,  'GetVolumeInformationW',  \
    GetVolumeNameForVolumeMountPointA, <.lpszVolumeMountPoint, .lpszVolumeName, .cchBufferLength>,  'GetVolumeNameForVolumeMountPointA',  \
    GetVolumeNameForVolumeMountPointW, <.lpszVolumeMountPoint, .lpszVolumeName, .cchBufferLength>,  'GetVolumeNameForVolumeMountPointW',  \
    GetVolumePathNameA, <.lpszFileName, .lpszVolumePathName, .cchBufferLength>,  'GetVolumePathNameA',  \
    GetVolumePathNameW, <.lpszFileName, .lpszVolumePathName, .cchBufferLength>,  'GetVolumePathNameW',  \
    GetVolumePathNamesForVolumeNameA, <NONE>,  'GetVolumePathNamesForVolumeNameA',  \
    GetVolumePathNamesForVolumeNameW, <NONE>,  'GetVolumePathNamesForVolumeNameW',  \
    GetWindowsDirectoryA, <.lpBuffer, .nSize>,  'GetWindowsDirectoryA',  \
    GetWindowsDirectoryW, <.lpBuffer, .nSize>,  'GetWindowsDirectoryW',  \
    GetWriteWatch, <.dwFlags, .lpBaseAddress, .dwRegionSize, .lpAddresses, .lpdwCount, .lpdwGranularity>,  'GetWriteWatch',  \
    GlobalAddAtomA, <.lpString>,  'GlobalAddAtomA',  \
    GlobalAddAtomW, <.lpString>,  'GlobalAddAtomW',  \
    GlobalAlloc, <.uFlags, .dwBytes>,  'GlobalAlloc',  \
    GlobalCompact, <.dwMinFree>,  'GlobalCompact',  \
    GlobalDeleteAtom, <.nAtom>,  'GlobalDeleteAtom',  \
    GlobalFindAtomA, <.lpString>,  'GlobalFindAtomA',  \
    GlobalFindAtomW, <.lpString>,  'GlobalFindAtomW',  \
    GlobalFix, <.hMem>,  'GlobalFix',  \
    GlobalFlags, <.hMem>,  'GlobalFlags',  \
    GlobalFree, <.hMem>,  'GlobalFree',  \
    GlobalGetAtomNameA, <.nAtom, .lpBuffer, .nSize>,  'GlobalGetAtomNameA',  \
    GlobalGetAtomNameW, <.nAtom, .lpBuffer, .nSize>,  'GlobalGetAtomNameW',  \
    GlobalHandle, <.wMem>,  'GlobalHandle',  \
    GlobalLock, <.hMem>,  'GlobalLock',  \
    GlobalMemoryStatus, <.lpBuffer>,  'GlobalMemoryStatus',  \
    GlobalMemoryStatusEx, <.lpBuffer>,  'GlobalMemoryStatusEx',  \
    GlobalReAlloc, <.hMem, .dwBytes, .wFlags>,  'GlobalReAlloc',  \
    GlobalSize, <.hMem>,  'GlobalSize',  \
    GlobalUnWire, <.hMem>,  'GlobalUnWire',  \
    GlobalUnfix, <.hMem>,  'GlobalUnfix',  \
    GlobalUnlock, <.hMem>,  'GlobalUnlock',  \
    GlobalWire, <.hMem>,  'GlobalWire',  \
    Heap32First, <.lphe, .th32ProcessID, .th32HeapID>,  'Heap32First',  \
    Heap32ListFirst, <.hSnapshot, .lphl>,  'Heap32ListFirst',  \
    Heap32ListNext, <.hSnapshot, .lphl>,  'Heap32ListNext',  \
    Heap32Next, <.lphe>,  'Heap32Next',  \
    HeapAlloc, <.hHeap, .dwFlags, .dwBytes>,  'HeapAlloc',  \
    HeapCompact, <.hHeap, .dwFlags>,  'HeapCompact',  \
    HeapCreate, <.flOptions, .dwInitialSize, .dwMaximumSize>,  'HeapCreate',  \
    HeapCreateTagsW, <NONE>,  'HeapCreateTagsW',  \
    HeapDestroy, <.hHeap>,  'HeapDestroy',  \
    HeapExtend, <NONE>,  'HeapExtend',  \
    HeapFree, <.hHeap, .dwFlags, .lpMem>,  'HeapFree',  \
    HeapLock, <.hHeap>,  'HeapLock',  \
    HeapQueryInformation, <NONE>,  'HeapQueryInformation',  \
    HeapQueryTagW, <NONE>,  'HeapQueryTagW',  \
    HeapReAlloc, <.hHeap, .dwFlags, .lpMem, .dwBytes>,  'HeapReAlloc',  \
    HeapSetInformation, <NONE>,  'HeapSetInformation',  \
    HeapSize, <.hHeap, .dwFlags, .lpMem>,  'HeapSize',  \
    HeapSummary, <NONE>,  'HeapSummary',  \
    HeapUnlock, <.hHeap>,  'HeapUnlock',  \
    HeapUsage, <NONE>,  'HeapUsage',  \
    HeapValidate, <.hHeap, .dwFlags, .lpMem>,  'HeapValidate',  \
    HeapWalk, <.hHeap, .lpEntry>,  'HeapWalk',  \
    InitAtomTable, <.nSize>,  'InitAtomTable',  \
    InitializeCriticalSection, <.lpCriticalSection>,  'InitializeCriticalSection',  \
    InitializeCriticalSectionAndSpinCount, <.lpCriticalSection, .dwSpinCount>,  'InitializeCriticalSectionAndSpinCount',  \
    InitializeSListHead, <NONE>,  'InitializeSListHead',  \
    InterlockedCompareExchange, <.Destination, .Exchange, .Comperand>,  'InterlockedCompareExchange',  \
    InterlockedDecrement, <.lpAddend>,  'InterlockedDecrement',  \
    InterlockedExchange, <.Target, .Value>,  'InterlockedExchange',  \
    InterlockedExchangeAdd, <.Addend, .Value>,  'InterlockedExchangeAdd',  \
    InterlockedFlushSList, <NONE>,  'InterlockedFlushSList',  \
    InterlockedIncrement, <.lpAddend>,  'InterlockedIncrement',  \
    InterlockedPopEntrySList, <NONE>,  'InterlockedPopEntrySList',  \
    InterlockedPushEntrySList, <NONE>,  'InterlockedPushEntrySList',  \
    InvalidateConsoleDIBits, <NONE>,  'InvalidateConsoleDIBits',  \
    IsBadCodePtr, <.lpfn>,  'IsBadCodePtr',  \
    IsBadHugeReadPtr, <.lp, .ucb>,  'IsBadHugeReadPtr',  \
    IsBadHugeWritePtr, <.lp, .ucb>,  'IsBadHugeWritePtr',  \
    IsBadReadPtr, <.lp, .ucb>,  'IsBadReadPtr',  \
    IsBadStringPtrA, <.lpsz, .ucchMax>,  'IsBadStringPtrA',  \
    IsBadStringPtrW, <.lpsz, .ucchMax>,  'IsBadStringPtrW',  \
    IsBadWritePtr, <.lp, .ucb>,  'IsBadWritePtr',  \
    IsDBCSLeadByte, <.bTestChar>,  'IsDBCSLeadByte',  \
    IsDBCSLeadByteEx, <.CodePage, .TestChar>,  'IsDBCSLeadByteEx',  \
    IsDebuggerPresent, <VOID>,  'IsDebuggerPresent',  \
    IsProcessInJob, <NONE>,  'IsProcessInJob',  \
    IsProcessorFeaturePresent, <.ProcessorFeature>,  'IsProcessorFeaturePresent',  \
    IsSystemResumeAutomatic, <VOID>,  'IsSystemResumeAutomatic',  \
    IsValidCodePage, <.CodePage>,  'IsValidCodePage',  \
    IsValidLanguageGroup, <.LanguageGroup, .dwFlags>,  'IsValidLanguageGroup',  \
    IsValidLocale, <.Locale, .dwFlags>,  'IsValidLocale',  \
    IsValidUILanguage, <NONE>,  'IsValidUILanguage',  \
    IsWow64Process, <NONE>,  'IsWow64Process',  \
    LCMapStringA, <.Locale, .dwMapFlags, .lpSrcStr, .cchSrc, .lpDestStr, .cchDest>,  'LCMapStringA',  \
    LCMapStringW, <.Locale, .dwMapFlags, .lpSrcStr, .cchSrc, .lpDestStr, .cchDest>,  'LCMapStringW',  \
    LZClose, <.hfFile>,  'LZClose',  \
    LZCloseFile, <NONE>,  'LZCloseFile',  \
    LZCopy, <.hfSource, .hfDest>,  'LZCopy',  \
    LZCreateFileW, <NONE>,  'LZCreateFileW',  \
    LZDone, <VOID>,  'LZDone',  \
    LZInit, <.hfSrc>,  'LZInit',  \
    LZOpenFileA, <.lpszFile, .lpOf, .style>,  'LZOpenFileA',  \
    LZOpenFileW, <.lpszFile, .lpOf, .style>,  'LZOpenFileW',  \
    LZRead, <.hfFile, .lpvBuf, .cbread>,  'LZRead',  \
    LZSeek, <.hfFile, .lOffset, .nOrigin>,  'LZSeek',  \
    LZStart, <VOID>,  'LZStart',  \
    LeaveCriticalSection, <.lpCriticalSection>,  'LeaveCriticalSection',  \
    LoadLibraryA, <.lpLibFileName>,  'LoadLibraryA',  \
    LoadLibraryExA, <.lpLibFileName, .hFile, .dwFlags>,  'LoadLibraryExA',  \
    LoadLibraryExW, <.lpLibFileName, .hFile, .dwFlags>,  'LoadLibraryExW',  \
    LoadLibraryW, <.lpLibFileName>,  'LoadLibraryW',  \
    LoadModule, <.lpModuleName, .lpParameterBlock>,  'LoadModule',  \
    LoadResource, <.hInstance, .hResInfo>,  'LoadResource',  \
    LocalAlloc, <.wFlags, .wBytes>,  'LocalAlloc',  \
    LocalCompact, <.uMinFree>,  'LocalCompact',  \
    LocalFileTimeToFileTime, <.lpLocalFileTime, .lpFileTime>,  'LocalFileTimeToFileTime',  \
    LocalFlags, <.hMem>,  'LocalFlags',  \
    LocalFree, <.hMem>,  'LocalFree',  \
    LocalHandle, <.wMem>,  'LocalHandle',  \
    LocalLock, <.hMem>,  'LocalLock',  \
    LocalReAlloc, <.hMem, .wBytes, .wFlags>,  'LocalReAlloc',  \
    LocalShrink, <.hMem, .cbNewSize>,  'LocalShrink',  \
    LocalSize, <.hMem>,  'LocalSize',  \
    LocalUnlock, <.hMem>,  'LocalUnlock',  \
    LockFile, <.hFile, .dwFileOffsetLow, .dwFileOffsetHigh, .nNumberOfBytesToLockLow, .nNumberOfBytesToLockHigh>,  'LockFile',  \
    LockFileEx, <.hFile, .dwFlags, .dwReserved, .nNumberOfBytesToLockLow, .nNumberOfBytesToLockHigh, .lpOverlapped>,  'LockFileEx',  \
    LockResource, <.hResData>,  'LockResource',  \
    MapUserPhysicalPages, <.VirtualAddress, .NumberOfPages, .PageArray>,  'MapUserPhysicalPages',  \
    MapUserPhysicalPagesScatter, <.VirtualAddresses, .NumberOfPages, .PageArray>,  'MapUserPhysicalPagesScatter',  \
    MapViewOfFile, <.hFileMappingObject, .dwDesiredAccess, .dwFileOffsetHigh, .dwFileOffsetLow, .dwNumberOfBytesToMap>,  'MapViewOfFile',  \
    MapViewOfFileEx, <.hFileMappingObject, .dwDesiredAccess, .dwFileOffsetHigh, .dwFileOffsetLow, .dwNumberOfBytesToMap, .lpBaseAddress,  \
      >,  'MapViewOfFileEx',  \
    Module32First, <.hSnapshot, .lpme>,  'Module32First',  \
    Module32FirstW, <.hSnapshot, .lpme>,  'Module32FirstW',  \
    Module32Next, <.hSnapshot, .lpme>,  'Module32Next',  \
    Module32NextW, <.hSnapshot, .lpme>,  'Module32NextW',  \
    MoveFileA, <.lpExistingFileName, .lpNewFileName>,  'MoveFileA',  \
    MoveFileExA, <.lpExistingFileName, .lpNewFileName, .dwFlags>,  'MoveFileExA',  \
    MoveFileExW, <.lpExistingFileName, .lpNewFileName, .dwFlags>,  'MoveFileExW',  \
    MoveFileW, <.lpExistingFileName, .lpNewFileName>,  'MoveFileW',  \
    MoveFileWithProgressA, <.lpExistingFileName, .lpNewFileName, .lpProgressRoutine, .lpData, .dwFlags>,  'MoveFileWithProgressA',  \
    MoveFileWithProgressW, <.lpExistingFileName, .lpNewFileName, .lpProgressRoutine, .lpData, .dwFlags>,  'MoveFileWithProgressW',  \
    MulDiv, <.nNumber, .nNumerator, .nDenominator>,  'MulDiv',  \
    MultiByteToWideChar, <.CodePage, .dwFlags, .lpMultiByteStr, .cchMultiByte, .lpWideCharStr, .cchWideChar>,  'MultiByteToWideChar',  \
    NlsConvertIntegerToString, <NONE>,  'NlsConvertIntegerToString',  \
    NlsGetCacheUpdateCount, <NONE>,  'NlsGetCacheUpdateCount',  \
    NlsResetProcessLocale, <NONE>,  'NlsResetProcessLocale',  \
    NumaVirtualQueryNode, <NONE>,  'NumaVirtualQueryNode',  \
    OpenConsoleW, <NONE>,  'OpenConsoleW',  \
    OpenDataFile, <NONE>,  'OpenDataFile',  \
    OpenEventA, <.dwDesiredAccess, .bInheritHandle, .lpName>,  'OpenEventA',  \
    OpenEventW, <.dwDesiredAccess, .bInheritHandle, .lpName>,  'OpenEventW',  \
    OpenFile, <.lpFileName, .lpReOpenBuff, .wStyle>,  'OpenFile',  \
    OpenFileMappingA, <.dwDesiredAccess, .bInheritHandle, .lpName>,  'OpenFileMappingA',  \
    OpenFileMappingW, <.dwDesiredAccess, .bInheritHandle, .lpName>,  'OpenFileMappingW',  \
    OpenJobObjectA, <.dwDesiredAccess, .bInheritHandle, .lpName>,  'OpenJobObjectA',  \
    OpenJobObjectW, <.dwDesiredAccess, .bInheritHandle, .lpName>,  'OpenJobObjectW',  \
    OpenMutexA, <.dwDesiredAccess, .bInheritHandle, .lpName>,  'OpenMutexA',  \
    OpenMutexW, <.dwDesiredAccess, .bInheritHandle, .lpName>,  'OpenMutexW',  \
    OpenProcess, <.dwDesiredAccess, .bInheritHandle, .dwProcessId>,  'OpenProcess',  \
    OpenProfileUserMapping, <NONE>,  'OpenProfileUserMapping',  \
    OpenSemaphoreA, <.dwDesiredAccess, .bInheritHandle, .lpName>,  'OpenSemaphoreA',  \
    OpenSemaphoreW, <.dwDesiredAccess, .bInheritHandle, .lpName>,  'OpenSemaphoreW',  \
    OpenThread, <.dwDesiredAccess, .bInheritHandle, .dwThreadId>,  'OpenThread',  \
    OpenWaitableTimerA, <.dwDesiredAccess, .bInheritHandle, .lpTimerName>,  'OpenWaitableTimerA',  \
    OpenWaitableTimerW, <.dwDesiredAccess, .bInheritHandle, .lpTimerName>,  'OpenWaitableTimerW',  \
    OutputDebugStringA, <.lpOutputString>,  'OutputDebugStringA',  \
    OutputDebugStringW, <.lpOutputString>,  'OutputDebugStringW',  \
    PeekConsoleInputA, <.hConsoleInput, .lpBuffer, .nLength, .lpNumberOfEventsRead>,  'PeekConsoleInputA',  \
    PeekConsoleInputW, <.hConsoleInput, .lpBuffer, .nLength, .lpNumberOfEventsRead>,  'PeekConsoleInputW',  \
    PeekNamedPipe, <.hNamedPipe, .lpBuffer, .nBufferSize, .lpBytesRead, .lpTotalBytesAvail, .lpBytesLeftThisMessage>,  'PeekNamedPipe',  \
    PostQueuedCompletionStatus, <.CompletionPort, .dwNumberOfBytesTransferred, .dwCompletionKey, .lpOverlapped>,  'PostQueuedCompletionStatus',  \
    PrepareTape, <.hDevice, .dwOperation, .bimmediate>,  'PrepareTape',  \
    PrivCopyFileExW, <NONE>,  'PrivCopyFileExW',  \
    PrivMoveFileIdentityW, <NONE>,  'PrivMoveFileIdentityW',  \
    Process32First, <.hSnapshot, .lppe>,  'Process32First',  \
    Process32FirstW, <.hSnapshot, .lppe>,  'Process32FirstW',  \
    Process32Next, <.hSnapshot, .lppe>,  'Process32Next',  \
    Process32NextW, <.hSnapshot, .lppe>,  'Process32NextW',  \
    ProcessIdToSessionId, <.dwProcessId, .pSessionId>,  'ProcessIdToSessionId',  \
    PulseEvent, <.hEvent>,  'PulseEvent',  \
    PurgeComm, <.hFile, .dwFlags>,  'PurgeComm',  \
    QueryActCtxW, <NONE>,  'QueryActCtxW',  \
    QueryDepthSList, <NONE>,  'QueryDepthSList',  \
    QueryDosDeviceA, <.lpDeviceName, .lpTargetPath, .ucchMax>,  'QueryDosDeviceA',  \
    QueryDosDeviceW, <.lpDeviceName, .lpTargetPath, .ucchMax>,  'QueryDosDeviceW',  \
    QueryInformationJobObject, <.hJob, .JobObjectInformationClass, .lpJobObjectInformation, .cbJobObjectInformationLength, .lpReturnLength,  \
      >,  'QueryInformationJobObject',  \
    QueryMemoryResourceNotification, <NONE>,  'QueryMemoryResourceNotification',  \
    QueryPerformanceCounter, <.lpPerformanceCount>,  'QueryPerformanceCounter',  \
    QueryPerformanceFrequency, <.lpFrequency>,  'QueryPerformanceFrequency',  \
    QueryWin31IniFilesMappedToRegistry, <NONE>,  'QueryWin31IniFilesMappedToRegistry',  \
    QueueUserAPC, <.pfnAPC, .hThread, .dwData>,  'QueueUserAPC',  \
    QueueUserWorkItem, <.lFunction, .Context, .Flags>,  'QueueUserWorkItem',  \
    RaiseException, <.dwExceptionCode, .dwExceptionFlags, .nNumberOfArguments, .lpArguments>,  'RaiseException',  \
    ReadConsoleA, <.hConsoleInput, .lpBuffer, .nNumberOfCharsToRead, .lpNumberOfCharsRead, .lpReserved>,  'ReadConsoleA',  \
    ReadConsoleInputA, <.hConsoleInput, .lpBuffer, .nLength, .lpNumberOfEventsRead>,  'ReadConsoleInputA',  \
    ReadConsoleInputExA, <NONE>,  'ReadConsoleInputExA',  \
    ReadConsoleInputExW, <NONE>,  'ReadConsoleInputExW',  \
    ReadConsoleInputW, <.hConsoleInput, .lpBuffer, .nLength, .lpNumberOfEventsRead>,  'ReadConsoleInputW',  \
    ReadConsoleOutputA, <.hConsoleOutput, .lpBuffer, .dwBufferSize, .dwBufferCoord, .lpReadRegion>,  'ReadConsoleOutputA',  \
    ReadConsoleOutputAttribute, <.hConsoleOutput, .lpAttribute, .nLength, .dwReadCoord, .lpNumberOfAttrsRead>,  'ReadConsoleOutputAttribute',  \
    ReadConsoleOutputCharacterA, <.hConsoleOutput, .lpCharacter, .nLength, .dwReadCoord, .lpNumberOfCharsRead>,  'ReadConsoleOutputCharacterA',  \
    ReadConsoleOutputCharacterW, <.hConsoleOutput, .lpCharacter, .nLength, .dwReadCoord, .lpNumberOfCharsRead>,  'ReadConsoleOutputCharacterW',  \
    ReadConsoleOutputW, <.hConsoleOutput, .lpBuffer, .dwBufferSize, .dwBufferCoord, .lpReadRegion>,  'ReadConsoleOutputW',  \
    ReadConsoleW, <.hConsoleInput, .lpBuffer, .nNumberOfCharsToRead, .lpNumberOfCharsRead, .lpReserved>,  'ReadConsoleW',  \
    ReadDirectoryChangesW, <NONE>,  'ReadDirectoryChangesW',  \
    ReadFile, <.hFile, .lpBuffer, .nNumberOfBytesToRead, .lpNumberOfBytesRead, .lpOverlapped>,  'ReadFile',  \
    ReadFileEx, <.hFile, .lpBuffer, .nNumberOfBytesToRead, .lpOverlapped, .lpCompletionRoutine>,  'ReadFileEx',  \
    ReadFileScatter, <.hFile, .aSegmentArray, .nNumberOfBytesToRead, .lpReserved, .lpOverlapped>,  'ReadFileScatter',  \
    ReadProcessMemory, <.hProcess, .lpBaseAddress, .lpBuffer, .nSize, .lpNumberOfBytesWritten>,  'ReadProcessMemory',  \
    RegisterConsoleIME, <NONE>,  'RegisterConsoleIME',  \
    RegisterConsoleOS2, <NONE>,  'RegisterConsoleOS2',  \
    RegisterConsoleVDM, <NONE>,  'RegisterConsoleVDM',  \
    RegisterWaitForInputIdle, <NONE>,  'RegisterWaitForInputIdle',  \
    RegisterWaitForSingleObject, <.phNewWaitObject, .hObject, .Callback, .Context, .dwMilliseconds, .dwFlags>,  'RegisterWaitForSingleObject',  \
    RegisterWaitForSingleObjectEx, <.hObject, .Callback, .Context, .dwMilliseconds, .dwFlags>,  'RegisterWaitForSingleObjectEx',  \
    RegisterWowBaseHandlers, <NONE>,  'RegisterWowBaseHandlers',  \
    RegisterWowExec, <NONE>,  'RegisterWowExec',  \
    ReleaseActCtx, <NONE>,  'ReleaseActCtx',  \
    ReleaseMutex, <.hMutex>,  'ReleaseMutex',  \
    ReleaseSemaphore, <.hSemaphore, .lReleaseCount, .lpPreviousCount>,  'ReleaseSemaphore',  \
    RemoveDirectoryA, <.lpPathName>,  'RemoveDirectoryA',  \
    RemoveDirectoryW, <.lpPathName>,  'RemoveDirectoryW',  \
    RemoveLocalAlternateComputerNameA, <NONE>,  'RemoveLocalAlternateComputerNameA',  \
    RemoveLocalAlternateComputerNameW, <NONE>,  'RemoveLocalAlternateComputerNameW',  \
    RemoveVectoredExceptionHandler, <NONE>,  'RemoveVectoredExceptionHandler',  \
    ReplaceFile, <.lpReplacedFileName, .lpReplacementFileName, .lpBackupFileName, .dwReplaceFlags, .lpExclude, .lpReserved>,  'ReplaceFile',  \
    ReplaceFileA, <.lpReplacedFileName, .lpReplacementFileName, .lpBackupFileName, .dwReplaceFlags, .lpExclude, .lpReserved>,  'ReplaceFileA',  \
    ReplaceFileW, <.lpReplacedFileName, .lpReplacementFileName, .lpBackupFileName, .dwReplaceFlags, .lpExclude, .lpReserved>,  'ReplaceFileW',  \
    RequestDeviceWakeup, <.hDevice>,  'RequestDeviceWakeup',  \
    RequestWakeupLatency, <.latency>,  'RequestWakeupLatency',  \
    ResetEvent, <.hEvent>,  'ResetEvent',  \
    ResetWriteWatch, <.lpBaseAddress, .dwRegionSize>,  'ResetWriteWatch',  \
    RestoreLastError, <NONE>,  'RestoreLastError',  \
    ResumeThread, <.hThread>,  'ResumeThread',  \
    RtlCaptureContext, <NONE>,  'RtlCaptureContext',  \
    RtlCaptureStackBackTrace, <NONE>,  'RtlCaptureStackBackTrace',  \
    RtlFillMemory, <.Destination, .Length, .Fill>,  'RtlFillMemory',  \
    RtlMoveMemory, <.dest, .source, .numBytes>,  'RtlMoveMemory',  \
    RtlUnwind, <NONE>,  'RtlUnwind',  \
    RtlZeroMemory, <.dest, .numBytes>,  'RtlZeroMemory',  \
    ScrollConsoleScreenBufferA, <.hConsoleOutput, .lpScrollRectangle, .lpClipRectangle, .dwDestinationOrigin, .lpFill>,  'ScrollConsoleScreenBufferA',  \
    ScrollConsoleScreenBufferW, <.hConsoleOutput, .lpScrollRectangle, .lpClipRectangle, .dwDestinationOrigin, .lpFill>,  'ScrollConsoleScreenBufferW',  \
    SearchPathA, <.lpPath, .lpFileName, .lpExtension, .nBufferLength, .lpBuffer, .lpFilePart>,  'SearchPathA',  \
    SearchPathW, <.lpPath, .lpFileName, .lpExtension, .nBufferLength, .lpBuffer, .lpFilePart>,  'SearchPathW',  \
    SetCPGlobal, <NONE>,  'SetCPGlobal',  \
    SetCalendarInfoA, <.Locale, .Calendar, .CalType, .lpCalData>,  'SetCalendarInfoA',  \
    SetCalendarInfoW, <.Locale, .Calendar, .CalType, .lpCalData>,  'SetCalendarInfoW',  \
    SetClientTimeZoneInformation, <NONE>,  'SetClientTimeZoneInformation',  \
    SetComPlusPackageInstallStatus, <NONE>,  'SetComPlusPackageInstallStatus',  \
    SetCommBreak, <.nCid>,  'SetCommBreak',  \
    SetCommConfig, <.hCommDev, .lpCC, .dwSize>,  'SetCommConfig',  \
    SetCommMask, <.hFile, .dwEvtMask>,  'SetCommMask',  \
    SetCommState, <.hCommDev, .lpDCB>,  'SetCommState',  \
    SetCommTimeouts, <.hFile, .lpCommTimeouts>,  'SetCommTimeouts',  \
    SetComputerNameA, <.lpComputerName>,  'SetComputerNameA',  \
    SetComputerNameExA, <.NameType, .lpBuffer>,  'SetComputerNameExA',  \
    SetComputerNameExW, <.NameType, .lpBuffer>,  'SetComputerNameExW',  \
    SetComputerNameW, <.lpComputerName>,  'SetComputerNameW',  \
    SetConsoleActiveScreenBuffer, <.hConsoleOutput>,  'SetConsoleActiveScreenBuffer',  \
    SetConsoleCP, <.wCodePageID>,  'SetConsoleCP',  \
    SetConsoleCommandHistoryMode, <NONE>,  'SetConsoleCommandHistoryMode',  \
    SetConsoleCtrlHandler, <.HandlerRoutine, .Add>,  'SetConsoleCtrlHandler',  \
    SetConsoleCursor, <NONE>,  'SetConsoleCursor',  \
    SetConsoleCursorInfo, <.hConsoleOutput, .lpConsoleCursorInfo>,  'SetConsoleCursorInfo',  \
    SetConsoleCursorMode, <NONE>,  'SetConsoleCursorMode',  \
    SetConsoleCursorPosition, <.hConsoleOutput, .dwCursorPosition>,  'SetConsoleCursorPosition',  \
    SetConsoleDisplayMode, <NONE>,  'SetConsoleDisplayMode',  \
    SetConsoleFont, <NONE>,  'SetConsoleFont',  \
    SetConsoleHardwareState, <NONE>,  'SetConsoleHardwareState',  \
    SetConsoleIcon, <NONE>,  'SetConsoleIcon',  \
    SetConsoleInputExeNameA, <NONE>,  'SetConsoleInputExeNameA',  \
    SetConsoleInputExeNameW, <NONE>,  'SetConsoleInputExeNameW',  \
    SetConsoleKeyShortcuts, <NONE>,  'SetConsoleKeyShortcuts',  \
    SetConsoleLocalEUDC, <NONE>,  'SetConsoleLocalEUDC',  \
    SetConsoleMaximumWindowSize, <NONE>,  'SetConsoleMaximumWindowSize',  \
    SetConsoleMenuClose, <NONE>,  'SetConsoleMenuClose',  \
    SetConsoleMode, <.hConsoleHandle, .dwMode>,  'SetConsoleMode',  \
    SetConsoleNlsMode, <NONE>,  'SetConsoleNlsMode',  \
    SetConsoleNumberOfCommandsA, <NONE>,  'SetConsoleNumberOfCommandsA',  \
    SetConsoleNumberOfCommandsW, <NONE>,  'SetConsoleNumberOfCommandsW',  \
    SetConsoleOS2OemFormat, <NONE>,  'SetConsoleOS2OemFormat',  \
    SetConsoleOutputCP, <.wCodePageID>,  'SetConsoleOutputCP',  \
    SetConsolePalette, <NONE>,  'SetConsolePalette',  \
    SetConsoleScreenBufferSize, <.hConsoleOutput, .dwSize>,  'SetConsoleScreenBufferSize',  \
    SetConsoleTextAttribute, <.hConsoleOutput, .wAttributes>,  'SetConsoleTextAttribute',  \
    SetConsoleTitleA, <.lpConsoleTitle>,  'SetConsoleTitleA',  \
    SetConsoleTitleW, <.lpConsoleTitle>,  'SetConsoleTitleW',  \
    SetConsoleWindowInfo, <.hConsoleOutput, .bAbsolute, .lpConsoleWindow>,  'SetConsoleWindowInfo',  \
    SetCriticalSectionSpinCount, <.lpCriticalSection, .dwSpinCount>,  'SetCriticalSectionSpinCount',  \
    SetCurrentDirectoryA, <.lpPathName>,  'SetCurrentDirectoryA',  \
    SetCurrentDirectoryW, <.lpPathName>,  'SetCurrentDirectoryW',  \
    SetDefaultCommConfigA, <.lpszName, .lpCC, .dwSize>,  'SetDefaultCommConfigA',  \
    SetDefaultCommConfigW, <.lpszName, .lpCC, .dwSize>,  'SetDefaultCommConfigW',  \
    SetDllDirectoryA, <NONE>,  'SetDllDirectoryA',  \
    SetDllDirectoryW, <NONE>,  'SetDllDirectoryW',  \
    SetEndOfFile, <.hFile>,  'SetEndOfFile',  \
    SetEnvironmentVariableA, <.lpName, .lpValue>,  'SetEnvironmentVariableA',  \
    SetEnvironmentVariableW, <.lpName, .lpValue>,  'SetEnvironmentVariableW',  \
    SetErrorMode, <.wMode>,  'SetErrorMode',  \
    SetEvent, <.hEvent>,  'SetEvent',  \
    SetFileApisToANSI, <VOID>,  'SetFileApisToANSI',  \
    SetFileApisToOEM, <VOID>,  'SetFileApisToOEM',  \
    SetFileAttributesA, <.lpFileName, .dwFileAttributes>,  'SetFileAttributesA',  \
    SetFileAttributesW, <.lpFileName, .dwFileAttributes>,  'SetFileAttributesW',  \
    SetFilePointer, <.hFile, .lDistanceToMove, .lpDistanceToMoveHigh, .dwMoveMethod>,  'SetFilePointer',  \
    SetFilePointerEx, <.hFile, .liDistanceToMove, .lpNewFilePointer, .dwMoveMethod>,  'SetFilePointerEx',  \
    SetFileShortNameA, <NONE>,  'SetFileShortNameA',  \
    SetFileShortNameW, <NONE>,  'SetFileShortNameW',  \
    SetFileTime, <.hFile, .lpCreationTime, .lpLastAccessTime, .lpLastWriteTime>,  'SetFileTime',  \
    SetFileValidData, <NONE>,  'SetFileValidData',  \
    SetFirmwareEnvironmentVariableA, <NONE>,  'SetFirmwareEnvironmentVariableA',  \
    SetFirmwareEnvironmentVariableW, <NONE>,  'SetFirmwareEnvironmentVariableW',  \
    SetHandleContext, <NONE>,  'SetHandleContext',  \
    SetHandleCount, <.wNumber>,  'SetHandleCount',  \
    SetHandleInformation, <.hObject, .dwMask, .dwFlags>,  'SetHandleInformation',  \
    SetInformationJobObject, <.hJob, .JobObjectInformationClass, .lpJobObjectInformation, .cbJobObjectInformationLength>,  'SetInformationJobObject',  \
    SetLastConsoleEventActive, <NONE>,  'SetLastConsoleEventActive',  \
    SetLastError, <.dwErrCode>,  'SetLastError',  \
    SetLocalPrimaryComputerNameA, <NONE>,  'SetLocalPrimaryComputerNameA',  \
    SetLocalPrimaryComputerNameW, <NONE>,  'SetLocalPrimaryComputerNameW',  \
    SetLocalTime, <.lpSystemTime>,  'SetLocalTime',  \
    SetLocaleInfoA, <.Locale, .LCType, .lpLCData>,  'SetLocaleInfoA',  \
    SetLocaleInfoW, <.Locale, .LCType, .lpLCData>,  'SetLocaleInfoW',  \
    SetMailslotInfo, <.hMailslot, .lReadTimeout>,  'SetMailslotInfo',  \
    SetMessageWaitingIndicator, <.hMsgIndicator, .ulMsgCount>,  'SetMessageWaitingIndicator',  \
    SetNamedPipeHandleState, <.hNamedPipe, .lpMode, .lpMaxCollectionCount, .lpCollectDataTimeout>,  'SetNamedPipeHandleState',  \
    SetPriorityClass, <.hProcess, .dwPriorityClass>,  'SetPriorityClass',  \
    SetProcessAffinityMask, <.hProcess, .dwProcessAffinityMask>,  'SetProcessAffinityMask',  \
    SetProcessDEPPolicy, <NONE>,  'SetProcessDEPPolicy',  \
    SetProcessPriorityBoost, <.hProcess, .bDisablePriorityBoost>,  'SetProcessPriorityBoost',  \
    SetProcessShutdownParameters, <.dwLevel, .dwFlags>,  'SetProcessShutdownParameters',  \
    SetProcessWorkingSetSize, <.hProcess, .dwMinimumWorkingSetSize, .dwMaximumWorkingSetSize>,  'SetProcessWorkingSetSize',  \
    SetStdHandle, <.nStdHandle, .nHandle>,  'SetStdHandle',  \
    SetSystemPowerState, <.fSuspend, .fForce>,  'SetSystemPowerState',  \
    SetSystemTime, <.lpSystemTime>,  'SetSystemTime',  \
    SetSystemTimeAdjustment, <.dwTimeAdjustment, .bTimeAdjustmentDisabled>,  'SetSystemTimeAdjustment',  \
    SetTapeParameters, <.hDevice, .dwOperation, .lpTapeInformation>,  'SetTapeParameters',  \
    SetTapePosition, <.hDevice, .dwPositionMethod, .dwPartition, .dwOffsetLow, .dwOffsetHigh, .bimmediate>,  'SetTapePosition',  \
    SetTermsrvAppInstallMode, <NONE>,  'SetTermsrvAppInstallMode',  \
    SetThreadAffinityMask, <.hThread, .dwThreadAffinityMask>,  'SetThreadAffinityMask',  \
    SetThreadContext, <.hThread, .lpContext>,  'SetThreadContext',  \
    SetThreadExecutionState, <.esFlags>,  'SetThreadExecutionState',  \
    SetThreadIdealProcessor, <.hThread, .dwIdealProcessor>,  'SetThreadIdealProcessor',  \
    SetThreadLocale, <.Locale>,  'SetThreadLocale',  \
    SetThreadPriority, <.hThread, .nPriority>,  'SetThreadPriority',  \
    SetThreadPriorityBoost, <.hThread, .bDisablePriorityBoost>,  'SetThreadPriorityBoost',  \
    SetThreadUILanguage, <NONE>,  'SetThreadUILanguage',  \
    SetTimeZoneInformation, <.lpTimeZoneInformation>,  'SetTimeZoneInformation',  \
    SetTimerQueueTimer, <.TimerQueue, .Callback, .Parameter, .DueTime, .Period, .PreferIo>,  'SetTimerQueueTimer',  \
    SetUnhandledExceptionFilter, <.lpTopLevelExceptionFilter>,  'SetUnhandledExceptionFilter',  \
    SetUserGeoID, <NONE>,  'SetUserGeoID',  \
    SetVDMCurrentDirectories, <NONE>,  'SetVDMCurrentDirectories',  \
    SetVolumeLabelA, <.lpRootPathName, .lpVolumeName>,  'SetVolumeLabelA',  \
    SetVolumeLabelW, <.lpRootPathName, .lpVolumeName>,  'SetVolumeLabelW',  \
    SetVolumeMountPointA, <.lpszVolumeMountPoint, .lpszVolumeName>,  'SetVolumeMountPointA',  \
    SetVolumeMountPointW, <.lpszVolumeMountPoint, .lpszVolumeName>,  'SetVolumeMountPointW',  \
    SetWaitableTimer, <.hTimer, .lpDueTime, .lPeriod, .pfnCompletionRoutine, .lpArgToCompletionRoutine, .fResume>,  'SetWaitableTimer',  \
    SetupComm, <.hFile, .dwInQueue, .dwOutQueue>,  'SetupComm',  \
    ShowConsoleCursor, <NONE>,  'ShowConsoleCursor',  \
    SignalObjectAndWait, <.hObjectToSignal, .hObjectToWaitOn, .dwMilliseconds, .bAlertable>,  'SignalObjectAndWait',  \
    SizeofResource, <.hInstance, .hResInfo>,  'SizeofResource',  \
    Sleep, <.dwMilliseconds>,  'Sleep',  \
    SleepEx, <.dwMilliseconds, .bAlertable>,  'SleepEx',  \
    SuspendThread, <.hThread>,  'SuspendThread',  \
    SwitchToFiber, <.lpFiber>,  'SwitchToFiber',  \
    SwitchToThread, <VOID>,  'SwitchToThread',  \
    SystemTimeToFileTime, <.lpSystemTime, .lpFileTime>,  'SystemTimeToFileTime',  \
    SystemTimeToTzSpecificLocalTime, <.lpTimeZoneInformation, .lpUniversalTime, .lpLocalTime>,  'SystemTimeToTzSpecificLocalTime',  \
    TerminateJobObject, <.hJob, .uExitCode>,  'TerminateJobObject',  \
    TerminateProcess, <.hProcess, .uExitCode>,  'TerminateProcess',  \
    TerminateThread, <.hThread, .dwExitCode>,  'TerminateThread',  \
    TermsrvAppInstallMode, <NONE>,  'TermsrvAppInstallMode',  \
    Thread32First, <.hSnapshot, .lpte>,  'Thread32First',  \
    Thread32Next, <.hSnapshot, .lpte>,  'Thread32Next',  \
    TlsAlloc, <VOID>,  'TlsAlloc',  \
    TlsFree, <.dwTlsIndex>,  'TlsFree',  \
    TlsGetValue, <.dwTlsIndex>,  'TlsGetValue',  \
    TlsSetValue, <.dwTlsIndex, .lpTlsValue>,  'TlsSetValue',  \
    Toolhelp32ReadProcessMemory, <.th32ProcessID, .lpBaseAddress, .lpBuffer, .cbRead, .lpNumberOfBytesRead>,  'Toolhelp32ReadProcessMemory',  \
    TransactNamedPipe, <.hNamedPipe, .lpInBuffer, .nInBufferSize, .lpOutBuffer, .nOutBufferSize, .lpBytesRead, .lpOverlapped>,  'TransactNamedPipe',  \
    TransmitCommChar, <.nCid, .cChar>,  'TransmitCommChar',  \
    TrimVirtualBuffer, <NONE>,  'TrimVirtualBuffer',  \
    TryEnterCriticalSection, <.lpCriticalSection>,  'TryEnterCriticalSection',  \
    TzSpecificLocalTimeToSystemTime, <NONE>,  'TzSpecificLocalTimeToSystemTime',  \
    UTRegister, <NONE>,  'UTRegister',  \
    UTUnRegister, <NONE>,  'UTUnRegister',  \
    UnhandledExceptionFilter, <.ExceptionInfo>,  'UnhandledExceptionFilter',  \
    UnlockFile, <.hFile, .dwFileOffsetLow, .dwFileOffsetHigh, .nNumberOfBytesToUnlockLow, .nNumberOfBytesToUnlockHigh>,  'UnlockFile',  \
    UnlockFileEx, <.hFile, .dwReserved, .nNumberOfBytesToUnlockLow, .nNumberOfBytesToUnlockHigh, .lpOverlapped>,  'UnlockFileEx',  \
    UnmapViewOfFile, <.lpBaseAddress>,  'UnmapViewOfFile',  \
    UnregisterConsoleIME, <NONE>,  'UnregisterConsoleIME',  \
    UnregisterWait, <.WaitHandle>,  'UnregisterWait',  \
    UnregisterWaitEx, <.WaitHandle, .CompletionEvent>,  'UnregisterWaitEx',  \
    UpdateResourceA, <.hUpdate, .lpType, .lpName, .wLanguage, .lpData, .cbData>,  'UpdateResourceA',  \
    UpdateResourceW, <.hUpdate, .lpType, .lpName, .wLanguage, .lpData, .cbData>,  'UpdateResourceW',  \
    VDMConsoleOperation, <NONE>,  'VDMConsoleOperation',  \
    VDMOperationStarted, <NONE>,  'VDMOperationStarted',  \
    ValidateLCType, <NONE>,  'ValidateLCType',  \
    ValidateLocale, <NONE>,  'ValidateLocale',  \
    VerLanguageNameA, <.wLang, .szLang, .nSize>,  'VerLanguageNameA',  \
    VerLanguageNameW, <.wLang, .szLang, .nSize>,  'VerLanguageNameW',  \
    VerSetConditionMask, <.ConditionMask, .TypeMask, .Condition>,  'VerSetConditionMask',  \
    VerifyConsoleIoHandle, <NONE>,  'VerifyConsoleIoHandle',  \
    VerifyVersionInfoA, <.lpVersionInformation, .dwTypeMask, .dwlConditionMask>,  'VerifyVersionInfoA',  \
    VerifyVersionInfoW, <.lpVersionInformation, .dwTypeMask, .dwlConditionMask>,  'VerifyVersionInfoW',  \
    VirtualAlloc, <.lpAddress, .dwSize, .flAllocationType, .flProtect>,  'VirtualAlloc',  \
    VirtualAllocEx, <.hProcess, .lpAddress, .dwSize, .flAllocationType, .flProtect>,  'VirtualAllocEx',  \
    VirtualBufferExceptionHandler, <NONE>,  'VirtualBufferExceptionHandler',  \
    VirtualFree, <.lpAddress, .dwSize, .dwFreeType>,  'VirtualFree',  \
    VirtualFreeEx, <.hProcess, .lpAddress, .dwSize, .dwFreeType>,  'VirtualFreeEx',  \
    VirtualLock, <.lpAddress, .dwSize>,  'VirtualLock',  \
    VirtualProtect, <.lpAddress, .dwSize, .flNewProtect, .lpflOldProtect>,  'VirtualProtect',  \
    VirtualProtectEx, <.hProcess, .lpAddress, .dwSize, .flNewProtect, .lpflOldProtect>,  'VirtualProtectEx',  \
    VirtualQuery, <.lpAddress, .lpBuffer, .dwLength>,  'VirtualQuery',  \
    VirtualQueryEx, <.hProcess, .lpAddress, .lpBuffer, .dwLength>,  'VirtualQueryEx',  \
    VirtualUnlock, <.lpAddress, .dwSize>,  'VirtualUnlock',  \
    WTSGetActiveConsoleSessionId, <NONE>,  'WTSGetActiveConsoleSessionId',  \
    WaitCommEvent, <.hFile, .lpEvtMask, .lpOverlapped>,  'WaitCommEvent',  \
    WaitForDebugEvent, <.lpDebugEvent, .dwMilliseconds>,  'WaitForDebugEvent',  \
    WaitForMultipleObjects, <.nCount, .lpHandles, .bWaitAll, .dwMilliseconds>,  'WaitForMultipleObjects',  \
    WaitForMultipleObjectsEx, <.nCount, .lpHandles, .bWaitAll, .dwMilliseconds, .bAlertable>,  'WaitForMultipleObjectsEx',  \
    WaitForSingleObject, <.hHandle, .dwMilliseconds>,  'WaitForSingleObject',  \
    WaitForSingleObjectEx, <.hHandle, .dwMilliseconds, .bAlertable>,  'WaitForSingleObjectEx',  \
    WaitNamedPipeA, <.lpNamedPipeName, .nTimeOut>,  'WaitNamedPipeA',  \
    WaitNamedPipeW, <.lpNamedPipeName, .nTimeOut>,  'WaitNamedPipeW',  \
    WideCharToMultiByte, <.CodePage, .dwFlags, .lpWideCharStr, .cchWideChar, .lpMultiByteStr, .cchMultiByte, .lpDefaultChar, .lpUsedDefaultChar,  \
      >,  'WideCharToMultiByte',  \
    WinExec, <.lpCmdLine, .nCmdShow>,  'WinExec',  \
    WriteConsoleA, <.hConsoleOutput, .lpBuffer, .nNumberOfCharsToWrite, .lpNumberOfCharsWritten, .lpReserved>,  'WriteConsoleA',  \
    WriteConsoleInputA, <.hConsoleInput, .lpBuffer, .nLength, .lpNumberOfEventsWritten>,  'WriteConsoleInputA',  \
    WriteConsoleInputVDMA, <NONE>,  'WriteConsoleInputVDMA',  \
    WriteConsoleInputVDMW, <NONE>,  'WriteConsoleInputVDMW',  \
    WriteConsoleInputW, <.hConsoleInput, .lpBuffer, .nLength, .lpNumberOfEventsWritten>,  'WriteConsoleInputW',  \
    WriteConsoleOutputA, <.hConsoleOutput, .lpBuffer, .dwBufferSize, .dwBufferCoord, .lpWriteRegion>,  'WriteConsoleOutputA',  \
    WriteConsoleOutputAttribute, <.hConsoleOutput, .lpAttribute, .nLength, .dwWriteCoord, .lpNumberOfAttrsWritten>,  'WriteConsoleOutputAttribute',  \
    WriteConsoleOutputCharacterA, <.hConsoleOutput, .lpCharacter, .nLength, .dwWriteCoord, .lpNumberOfCharsWritten>,  'WriteConsoleOutputCharacterA',  \
    WriteConsoleOutputCharacterW, <.hConsoleOutput, .lpCharacter, .nLength, .dwWriteCoord, .lpNumberOfCharsWritten>,  'WriteConsoleOutputCharacterW',  \
    WriteConsoleOutputW, <.hConsoleOutput, .lpBuffer, .dwBufferSize, .dwBufferCoord, .lpWriteRegion>,  'WriteConsoleOutputW',  \
    WriteConsoleW, <.hConsoleOutput, .lpBuffer, .nNumberOfCharsToWrite, .lpNumberOfCharsWritten, .lpReserved>,  'WriteConsoleW',  \
    WriteFile, <.hFile, .lpBuffer, .nNumberOfBytesToWrite, .lpNumberOfBytesWritten, .lpOverlapped>,  'WriteFile',  \
    WriteFileEx, <.hFile, .lpBuffer, .nNumberOfBytesToWrite, .lpOverlapped, .lpCompletionRoutine>,  'WriteFileEx',  \
    WriteFileGather, <.hFile, .aSegmentArray, .nNumberOfBytesToWrite, .lpReserved, .lpOverlapped>,  'WriteFileGather',  \
    WritePrivateProfileSectionA, <.lpAppName, .lpString, .lpFileName>,  'WritePrivateProfileSectionA',  \
    WritePrivateProfileSectionW, <.lpAppName, .lpString, .lpFileName>,  'WritePrivateProfileSectionW',  \
    WritePrivateProfileStringA, <.lpApplicationName, .lpKeyName, .lpString, .lpFileName>,  'WritePrivateProfileStringA',  \
    WritePrivateProfileStringW, <.lpApplicationName, .lpKeyName, .lpString, .lpFileName>,  'WritePrivateProfileStringW',  \
    WritePrivateProfileStructA, <.lpszSection, .lpszKey, .lpStruct, .uSizeStruct, .szFile>,  'WritePrivateProfileStructA',  \
    WritePrivateProfileStructW, <.lpszSection, .lpszKey, .lpStruct, .uSizeStruct, .szFile>,  'WritePrivateProfileStructW',  \
    WriteProcessMemory, <.hProcess, .lpBaseAddress, .lpBuffer, .nSize, .lpNumberOfBytesWritten>,  'WriteProcessMemory',  \
    WriteProfileSectionA, <.lpAppName, .lpString>,  'WriteProfileSectionA',  \
    WriteProfileSectionW, <.lpAppName, .lpString>,  'WriteProfileSectionW',  \
    WriteProfileStringA, <.lpszSection, .lpszKeyName, .lpszString>,  'WriteProfileStringA',  \
    WriteProfileStringW, <.lpszSection, .lpszKeyName, .lpszString>,  'WriteProfileStringW',  \
    WriteTapemark, <.hDevice, .dwTapemarkType, .dwTapemarkCount, .bimmediate>,  'WriteTapemark',  \
    ZombifyActCtx, <NONE>,  'ZombifyActCtx',  \
    _hread, <NONE>,  '_hread',  \
    _hwrite, <NONE>,  '_hwrite',  \
    _lclose, <NONE>,  '_lclose',  \
    _lcreat, <NONE>,  '_lcreat',  \
    _llseek, <NONE>,  '_llseek',  \
    _lopen, <NONE>,  '_lopen',  \
    _lread, <NONE>,  '_lread',  \
    _lwrite, <NONE>,  '_lwrite',  \
    lstrcat, <.lpString1, .lpString2>,  'lstrcat',  \
    lstrcatA, <.lpString1, .lpString2>,  'lstrcatA',  \
    lstrcatW, <.lpString1, .lpString2>,  'lstrcatW',  \
    lstrcmp, <.lpString1, .lpString2>,  'lstrcmp',  \
    lstrcmpA, <.lpString1, .lpString2>,  'lstrcmpA',  \
    lstrcmpW, <.lpString1, .lpString2>,  'lstrcmpW',  \
    lstrcmpi, <.lpString1, .lpString2>,  'lstrcmpi',  \
    lstrcmpiA, <.lpString1, .lpString2>,  'lstrcmpiA',  \
    lstrcmpiW, <.lpString1, .lpString2>,  'lstrcmpiW',  \
    lstrcpy, <.lpString1, .lpString2>,  'lstrcpy',  \
    lstrcpyA, <.lpString1, .lpString2>,  'lstrcpyA',  \
    lstrcpyW, <.lpString1, .lpString2>,  'lstrcpyW',  \
    lstrcpyn, <.lpString1, .lpString2, .iMaxLength>,  'lstrcpyn',  \
    lstrcpynA, <.lpString1, .lpString2, .iMaxLength>,  'lstrcpynA',  \
    lstrcpynW, <.lpString1, .lpString2, .iMaxLength>,  'lstrcpynW',  \
    lstrlen, <.lpString>,  'lstrlen',  \
    lstrlenA, <.lpString>,  'lstrlenA',  \
    lstrlenW, <.lpString>,  'lstrlenW'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/imports/Win32/msimg32.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: msimg32.dll API calls
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


import_proto msimg32,  \
    AlphaBlend, <.hdc, .lInt, .BLENDFUNCT>,  'AlphaBlend',  \
    GradientFill, <.hdc, .PTRIVERTEX, .ulong, .pvoid>,  'GradientFill',  \
    TransparentBlt, <.hdc, .t, .uint>,  'TransparentBlt',  \
    vSetDdrawflag, <NONE>,  'vSetDdrawflag'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted freshlib/imports/Win32/odbc32.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: odbc32.dll API calls
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

import_proto odbc32,  \
    CloseODBCPerfData, <NONE>,  'CloseODBCPerfData',  \
    CollectODBCPerfData, <NONE>,  'CollectODBCPerfData',  \
    CursorLibLockDbc, <NONE>,  'CursorLibLockDbc',  \
    CursorLibLockDesc, <NONE>,  'CursorLibLockDesc',  \
    CursorLibLockStmt, <NONE>,  'CursorLibLockStmt',  \
    CursorLibTransact, <NONE>,  'CursorLibTransact',  \
    GetODBCSharedData, <NONE>,  'GetODBCSharedData',  \
    LockHandle, <NONE>,  'LockHandle',  \
    MpHeapAlloc, <NONE>,  'MpHeapAlloc',  \
    MpHeapCompact, <NONE>,  'MpHeapCompact',  \
    MpHeapCreate, <NONE>,  'MpHeapCreate',  \
    MpHeapDestroy, <NONE>,  'MpHeapDestroy',  \
    MpHeapFree, <NONE>,  'MpHeapFree',  \
    MpHeapReAlloc, <NONE>,  'MpHeapReAlloc',  \
    MpHeapSize, <NONE>,  'MpHeapSize',  \
    MpHeapValidate, <NONE>,  'MpHeapValidate',  \
    ODBCGetTryWaitValue, <VOID>,  'ODBCGetTryWaitValue',  \
    ODBCInternalConnectW, <NONE>,  'ODBCInternalConnectW',  \
    ODBCQualifyFileDSNW, <NONE>,  'ODBCQualifyFileDSNW',  \
    ODBCSetTryWaitValue, <.dwValue>,  'ODBCSetTryWaitValue',  \
    OpenODBCPerfData, <NONE>,  'OpenODBCPerfData',  \
    PostComponentError, <NONE>,  'PostComponentError',  \
    PostODBCComponentError, <NONE>,  'PostODBCComponentError',  \
    PostODBCError, <NONE>,  'PostODBCError',  \
    SQLAllocConnect, <.henv, .phdbc>,  'SQLAllocConnect',  \
    SQLAllocEnv, <.phenv>,  'SQLAllocEnv',  \
    SQLAllocHandle, <.HandleType, .InputHandle, .OutputHandle>,  'SQLAllocHandle',  \
    SQLAllocHandleStd, <.fHandleType, .hInput, .phOutput>,  'SQLAllocHandleStd',  \
    SQLAllocStmt, <.hdbc, .phstmt>,  'SQLAllocStmt',  \
    SQLBindCol, <.hstmt, .icol, .fCType, .rgbValue, .cbValueMax, .pcbValue>,  'SQLBindCol',  \
    SQLBindParam, <.StatementHandle, .ParameterNumber, .ValueType, .ParameterType, .LengthPrecision, .ParameterScale, .ParameterValue,  \
        .StrLen_or_Ind>,  'SQLBindParam',  \
    SQLBindParameter, <.hstmt, .ipar, .fParamType, .fCType, .fSqlType, .cbColDef, .ibScale, .rgbValue, .cbValueMax, .pcbValue>,  'SQLBindParameter',  \
    SQLBrowseConnect, <.hdbc, .szConnStrIn, .cbConnStrIn, .szConnStrOut, .cbConnStrOutMax, .pcbConnStrOut>,  'SQLBrowseConnect',  \
    SQLBrowseConnectA, <.hdbc, .szConnStrIn, .cbConnStrIn, .szConnStrOut, .cbConnStrOutMax, .pcbConnStrOut>,  'SQLBrowseConnectA',  \
    SQLBrowseConnectW, <.hdbc, .szConnStrIn, .cbConnStrIn, .szConnStrOut, .cbConnStrOutMax, .pcbConnStrOut>,  'SQLBrowseConnectW',  \
    SQLBulkOperations, <.StatementHandle, .Operation>,  'SQLBulkOperations',  \
    SQLCancel, <.hstmt>,  'SQLCancel',  \
    SQLCloseCursor, <.StatementHandle>,  'SQLCloseCursor',  \
    SQLColAttribute, <.hstmt, .iCol, .iField, .pCharAttr, .cbCharAttrMax, .pcbCharAttr, .pNumAttr>,  'SQLColAttribute',  \
    SQLColAttributeA, <.hstmt, .iCol, .iField, .pCharAttr, .cbCharAttrMax, .pcbCharAttr, .pNumAttr>,  'SQLColAttributeA',  \
    SQLColAttributeW, <.hstmt, .iCol, .iField, .pCharAttr, .cbCharAttrMax, .pcbCharAttr, .pNumAttr>,  'SQLColAttributeW',  \
    SQLColAttributes, <.hstmt, .icol, .fDescType, .rgbDesc, .cbDescMax, .pcbDesc, .pfDesc>,  'SQLColAttributes',  \
    SQLColAttributesA, <.hstmt, .icol, .fDescType, .rgbDesc, .cbDescMax, .pcbDesc, .pfDesc>,  'SQLColAttributesA',  \
    SQLColAttributesW, <.hstmt, .icol, .fDescType, .rgbDesc, .cbDescMax, .pcbDesc, .pfDesc>,  'SQLColAttributesW',  \
    SQLColumnPrivileges, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName, .szColumnName,  \
        .cbColumnName>,  'SQLColumnPrivileges',  \
    SQLColumnPrivilegesA, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName, .szColumnName,  \
        .cbColumnName>,  'SQLColumnPrivilegesA',  \
    SQLColumnPrivilegesW, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName, .szColumnName,  \
        .cbColumnName>,  'SQLColumnPrivilegesW',  \
    SQLColumns, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName, .szColumnName, .cbColumnName,  \
      >,  'SQLColumns',  \
    SQLColumnsA, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName, .szColumnName,  \
        .cbColumnName>,  'SQLColumnsA',  \
    SQLColumnsW, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName, .szColumnName,  \
        .cbColumnName>,  'SQLColumnsW',  \
    SQLConnect, <.hdbc, .szDSN, .cbDSN, .szUID, .cbUID, .szAuthStr, .cbAuthStr>,  'SQLConnect',  \
    SQLConnectA, <.hdbc, .szDSN, .cbDSN, .szUID, .cbUID, .szAuthStr, .cbAuthStr>,  'SQLConnectA',  \
    SQLConnectW, <.hdbc, .szDSN, .cbDSN, .szUID, .cbUID, .szAuthStr, .cbAuthStr>,  'SQLConnectW',  \
    SQLCopyDesc, <.SourceDescHandle, .TargetDescHandle>,  'SQLCopyDesc',  \
    SQLDataSources, <.henv, .fDirection, .szDSN, .cbDSNMax, .pcbDSN, .szDescription, .cbDescriptionMax, .pcbDescription>,  'SQLDataSources',  \
    SQLDataSourcesA, <.henv, .fDirection, .szDSN, .cbDSNMax, .pcbDSN, .szDescription, .cbDescriptionMax, .pcbDescription>,  'SQLDataSourcesA',  \
    SQLDataSourcesW, <.henv, .fDirection, .szDSN, .cbDSNMax, .pcbDSN, .szDescription, .cbDescriptionMax, .pcbDescription>,  'SQLDataSourcesW',  \
    SQLDescribeCol, <.hstmt, .icol, .szColName, .cbColNameMax, .pcbColName, .pfSqlType, .pcbColDef, .pibScale, .pfNullable>,  'SQLDescribeCol',  \
    SQLDescribeColA, <.hstmt, .icol, .szColName, .cbColNameMax, .pcbColName, .pfSqlType, .pcbColDef, .pibScale, .pfNullable>,  'SQLDescribeColA',  \
    SQLDescribeColW, <.hstmt, .icol, .szColName, .cbColNameMax, .pcbColName, .pfSqlType, .pcbColDef, .pibScale, .pfNullable>,  'SQLDescribeColW',  \
    SQLDescribeParam, <.hstmt, .ipar, .pfSqlType, .pcbParamDef, .pibScale, .pfNullable>,  'SQLDescribeParam',  \
    SQLDisconnect, <.hdbc>,  'SQLDisconnect',  \
    SQLDriverConnect, <.hdbc, .hwnd, .szConnStrIn, .cbConnStrIn, .szConnStrOut, .cbConnStrOutMax, .pcbConnStrOut, .fDriverCompletion,  \
      >,  'SQLDriverConnect',  \
    SQLDriverConnectA, <.hdbc, .hwnd, .szConnStrIn, .cbConnStrIn, .szConnStrOut, .cbConnStrOutMax, .pcbConnStrOut, .fDriverCompletion,  \
      >,  'SQLDriverConnectA',  \
    SQLDriverConnectW, <.hdbc, .hwnd, .szConnStrIn, .cbConnStrIn, .szConnStrOut, .cbConnStrOutMax, .pcbConnStrOut, .fDriverCompletion,  \
      >,  'SQLDriverConnectW',  \
    SQLDrivers, <.henv, .fDirection, .szDriverDesc, .cbDriverDescMax, .pcbDriverDesc, .szDriverAttributes, .cbDrvrAttrMax, .pcbDrvrAttr,  \
      >,  'SQLDrivers',  \
    SQLDriversA, <.henv, .fDirection, .szDriverDesc, .cbDriverDescMax, .pcbDriverDesc, .szDriverAttributes, .cbDrvrAttrMax, .pcbDrvrAttr,  \
      >,  'SQLDriversA',  \
    SQLDriversW, <.henv, .fDirection, .szDriverDesc, .cbDriverDescMax, .pcbDriverDesc, .szDriverAttributes, .cbDrvrAttrMax, .pcbDrvrAttr,  \
      >,  'SQLDriversW',  \
    SQLEndTran, <.HandleType, .handle, .CompletionType>,  'SQLEndTran',  \
    SQLError, <.henv, .hdbc, .hstmt, .szSqlState, .pfNativeError, .szErrorMsg, .cbErrorMsgMax, .pcbErrorMsg>,  'SQLError',  \
    SQLErrorA, <.henv, .hdbc, .hstmt, .szSqlState, .pfNativeError, .szErrorMsg, .cbErrorMsgMax, .pcbErrorMsg>,  'SQLErrorA',  \
    SQLErrorW, <.henv, .hdbc, .hstmt, .szSqlState, .pfNativeError, .szErrorMsg, .cbErrorMsgMax, .pcbErrorMsg>,  'SQLErrorW',  \
    SQLExecDirect, <.hstmt, .szSqlStr, .cbSqlStr>,  'SQLExecDirect',  \
    SQLExecDirectA, <.hstmt, .szSqlStr, .cbSqlStr>,  'SQLExecDirectA',  \
    SQLExecDirectW, <.hstmt, .szSqlStr, .cbSqlStr>,  'SQLExecDirectW',  \
    SQLExecute, <.hstmt>,  'SQLExecute',  \
    SQLExtendedFetch, <.hstmt, .fFetchType, .irow, .pcrow, .rgfRowStatus>,  'SQLExtendedFetch',  \
    SQLFetch, <.hstmt>,  'SQLFetch',  \
    SQLFetchScroll, <.StatementHandle, .FetchOrientation, .FetchOffset>,  'SQLFetchScroll',  \
    SQLForeignKeys, <.hstmt, .szPkCatalogName, .cbPkCatalogName, .szPkSchemaName, .cbPkSchemaName, .szPkTableName, .cbPkTableName,  \
        .szFkCatalogName, .cbFkCatalogName, .szFkSchemaName, .cbFkSchemaName, .szFkTableName, .cbFkTableName>,  'SQLForeignKeys',  \
    SQLForeignKeysA, <.hstmt, .szPkCatalogName, .cbPkCatalogName, .szPkSchemaName, .cbPkSchemaName, .szPkTableName, .cbPkTableName,  \
        .szFkCatalogName, .cbFkCatalogName, .szFkSchemaName, .cbFkSchemaName, .szFkTableName, .cbFkTableName>,  'SQLForeignKeysA',  \
    SQLForeignKeysW, <.hstmt, .szPkCatalogName, .cbPkCatalogName, .szPkSchemaName, .cbPkSchemaName, .szPkTableName, .cbPkTableName,  \
        .szFkCatalogName, .cbFkCatalogName, .szFkSchemaName, .cbFkSchemaName, .szFkTableName, .cbFkTableName>,  'SQLForeignKeysW',  \
    SQLFreeConnect, <.hdbc>,  'SQLFreeConnect',  \
    SQLFreeEnv, <.henv>,  'SQLFreeEnv',  \
    SQLFreeHandle, <.HandleType, .handle>,  'SQLFreeHandle',  \
    SQLFreeStmt, <.hstmt, .fOption>,  'SQLFreeStmt',  \
    SQLGetConnectAttr, <.ConnectionHandle, .lAttribute, .lValue, .BufferLength, .StringLength>,  'SQLGetConnectAttr',  \
    SQLGetConnectAttrA, <.ConnectionHandle, .lAttribute, .lValue, .BufferLength, .StringLength>,  'SQLGetConnectAttrA',  \
    SQLGetConnectAttrW, <.ConnectionHandle, .lAttribute, .lValue, .BufferLength, .StringLength>,  'SQLGetConnectAttrW',  \
    SQLGetConnectOption, <.hdbc, .fOption, .pvParam>,  'SQLGetConnectOption',  \
    SQLGetConnectOptionA, <.hdbc, .fOption, .pvParam>,  'SQLGetConnectOptionA',  \
    SQLGetConnectOptionW, <.hdbc, .fOption, .pvParam>,  'SQLGetConnectOptionW',  \
    SQLGetCursorName, <.hstmt, .szCursor, .cbCursorMax, .pcbCursor>,  'SQLGetCursorName',  \
    SQLGetCursorNameA, <.hstmt, .szCursor, .cbCursorMax, .pcbCursor>,  'SQLGetCursorNameA',  \
    SQLGetCursorNameW, <.hstmt, .szCursor, .cbCursorMax, .pcbCursor>,  'SQLGetCursorNameW',  \
    SQLGetData, <.hstmt, .icol, .fCType, .rgbValue, .cbValueMax, .pcbValue>,  'SQLGetData',  \
    SQLGetDescField, <.hdesc, .iRecord, .iField, .rgbValue, .cbValueMax, .pcbValue>,  'SQLGetDescField',  \
    SQLGetDescFieldA, <.hdesc, .iRecord, .iField, .rgbValue, .cbValueMax, .pcbValue>,  'SQLGetDescFieldA',  \
    SQLGetDescFieldW, <.hdesc, .iRecord, .iField, .rgbValue, .cbValueMax, .pcbValue>,  'SQLGetDescFieldW',  \
    SQLGetDescRec, <.hdesc, .iRecord, .szName, .cbNameMax, .pcbName, .pfType, .pfSubType, .pLength, .pPrecision, .pScale, .pNullable,  \
      >,  'SQLGetDescRec',  \
    SQLGetDescRecA, <.hdesc, .iRecord, .szName, .cbNameMax, .pcbName, .pfType, .pfSubType, .pLength, .pPrecision, .pScale, .pNullable,  \
      >,  'SQLGetDescRecA',  \
    SQLGetDescRecW, <.hdesc, .iRecord, .szName, .cbNameMax, .pcbName, .pfType, .pfSubType, .pLength, .pPrecision, .pScale, .pNullable,  \
      >,  'SQLGetDescRecW',  \
    SQLGetDiagField, <.HandleType, .handle, .RecNumber, .DiagIdentifier, .DiagInfo, .BufferLength, .StringLength>,  'SQLGetDiagField',  \
    SQLGetDiagFieldA, <.HandleType, .handle, .RecNumber, .DiagIdentifier, .DiagInfo, .BufferLength, .StringLength>,  'SQLGetDiagFieldA',  \
    SQLGetDiagFieldW, <.HandleType, .handle, .RecNumber, .DiagIdentifier, .DiagInfo, .BufferLength, .StringLength>,  'SQLGetDiagFieldW',  \
    SQLGetDiagRec, <.fHandleType, .handle, .iRecord, .szSqlState, .pfNativeError, .szErrorMsg, .cbErrorMsgMax, .pcbErrorMsg>,  'SQLGetDiagRec',  \
    SQLGetDiagRecA, <.fHandleType, .handle, .iRecord, .szSqlState, .pfNativeError, .szErrorMsg, .cbErrorMsgMax, .pcbErrorMsg>,  'SQLGetDiagRecA',  \
    SQLGetDiagRecW, <.fHandleType, .handle, .iRecord, .szSqlState, .pfNativeError, .szErrorMsg, .cbErrorMsgMax, .pcbErrorMsg>,  'SQLGetDiagRecW',  \
    SQLGetEnvAttr, <.EnvironmentHandle, .lAttribute, .lValue, .BufferLength, .StringLength>,  'SQLGetEnvAttr',  \
    SQLGetFunctions, <.hdbc, .fFunction, .pfExists>,  'SQLGetFunctions',  \
    SQLGetInfo, <.hdbc, .fInfoType, .rgbInfoValue, .cbInfoValueMax, .pcbInfoValue>,  'SQLGetInfo',  \
    SQLGetInfoA, <.hdbc, .fInfoType, .rgbInfoValue, .cbInfoValueMax, .pcbInfoValue>,  'SQLGetInfoA',  \
    SQLGetInfoW, <.hdbc, .fInfoType, .rgbInfoValue, .cbInfoValueMax, .pcbInfoValue>,  'SQLGetInfoW',  \
    SQLGetStmtAttr, <.hstmt, .fAttribute, .rgbValue, .cbValueMax, .pcbValue>,  'SQLGetStmtAttr',  \
    SQLGetStmtAttrA, <.hstmt, .fAttribute, .rgbValue, .cbValueMax, .pcbValue>,  'SQLGetStmtAttrA',  \
    SQLGetStmtAttrW, <.hstmt, .fAttribute, .rgbValue, .cbValueMax, .pcbValue>,  'SQLGetStmtAttrW',  \
    SQLGetStmtOption, <.hstmt, .fOption, .pvParam>,  'SQLGetStmtOption',  \
    SQLGetTypeInfo, <.hstmt, .fSqlType>,  'SQLGetTypeInfo',  \
    SQLGetTypeInfoA, <.hstmt, .fSqlType>,  'SQLGetTypeInfoA',  \
    SQLGetTypeInfoW, <.hstmt, .fSqlType>,  'SQLGetTypeInfoW',  \
    SQLMoreResults, <.hstmt>,  'SQLMoreResults',  \
    SQLNativeSql, <.hdbc, .szSqlStrIn, .cbSqlStrIn, .szSqlStr, .cbSqlStrMax, .pcbSqlStr>,  'SQLNativeSql',  \
    SQLNativeSqlA, <.hdbc, .szSqlStrIn, .cbSqlStrIn, .szSqlStr, .cbSqlStrMax, .pcbSqlStr>,  'SQLNativeSqlA',  \
    SQLNativeSqlW, <.hdbc, .szSqlStrIn, .cbSqlStrIn, .szSqlStr, .cbSqlStrMax, .pcbSqlStr>,  'SQLNativeSqlW',  \
    SQLNumParams, <.hstmt, .pcpar>,  'SQLNumParams',  \
    SQLNumResultCols, <.hstmt, .pccol>,  'SQLNumResultCols',  \
    SQLParamData, <.hstmt, .prgbValue>,  'SQLParamData',  \
    SQLParamOptions, <.hstmt, .crow, .pirow>,  'SQLParamOptions',  \
    SQLPrepare, <.hstmt, .szSqlStr, .cbSqlStr>,  'SQLPrepare',  \
    SQLPrepareA, <.hstmt, .szSqlStr, .cbSqlStr>,  'SQLPrepareA',  \
    SQLPrepareW, <.hstmt, .szSqlStr, .cbSqlStr>,  'SQLPrepareW',  \
    SQLPrimaryKeys, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName>,  'SQLPrimaryKeys',  \
    SQLPrimaryKeysA, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName>,  'SQLPrimaryKeysA',  \
    SQLPrimaryKeysW, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName>,  'SQLPrimaryKeysW',  \
    SQLProcedureColumns, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szProcName, .cbProcName, .szColumnName,  \
        .cbColumnName>,  'SQLProcedureColumns',  \
    SQLProcedureColumnsA, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szProcName, .cbProcName, .szColumnName,  \
        .cbColumnName>,  'SQLProcedureColumnsA',  \
    SQLProcedureColumnsW, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szProcName, .cbProcName, .szColumnName,  \
        .cbColumnName>,  'SQLProcedureColumnsW',  \
    SQLProcedures, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szProcName, .cbProcName>,  'SQLProcedures',  \
    SQLProceduresA, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szProcName, .cbProcName>,  'SQLProceduresA',  \
    SQLProceduresW, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szProcName, .cbProcName>,  'SQLProceduresW',  \
    SQLPutData, <.hstmt, .rgbValue, .cbValue>,  'SQLPutData',  \
    SQLRowCount, <.hstmt, .pcrow>,  'SQLRowCount',  \
    SQLSetConnectAttr, <.hdbc, .fAttribute, .rgbValue, .cbValue>,  'SQLSetConnectAttr',  \
    SQLSetConnectAttrA, <.hdbc, .fAttribute, .rgbValue, .cbValue>,  'SQLSetConnectAttrA',  \
    SQLSetConnectAttrW, <.hdbc, .fAttribute, .rgbValue, .cbValue>,  'SQLSetConnectAttrW',  \
    SQLSetConnectOption, <.hdbc, .fOption, .vParam>,  'SQLSetConnectOption',  \
    SQLSetConnectOptionA, <.hdbc, .fOption, .vParam>,  'SQLSetConnectOptionA',  \
    SQLSetConnectOptionW, <.hdbc, .fOption, .vParam>,  'SQLSetConnectOptionW',  \
    SQLSetCursorName, <.hstmt, .szCursor, .cbCursor>,  'SQLSetCursorName',  \
    SQLSetCursorNameA, <.hstmt, .szCursor, .cbCursor>,  'SQLSetCursorNameA',  \
    SQLSetCursorNameW, <.hstmt, .szCursor, .cbCursor>,  'SQLSetCursorNameW',  \
    SQLSetDescField, <.DescriptorHandle, .RecNumber, .FieldIdentifier, .Value, .BufferLength>,  'SQLSetDescField',  \
    SQLSetDescFieldA, <.DescriptorHandle, .RecNumber, .FieldIdentifier, .Value, .BufferLength>,  'SQLSetDescFieldA',  \
    SQLSetDescFieldW, <.DescriptorHandle, .RecNumber, .FieldIdentifier, .Value, .BufferLength>,  'SQLSetDescFieldW',  \
    SQLSetDescRec, <.DescriptorHandle, .RecNumber, .lType, .SubType, .Length, .Precision, .kScale, .Data, .StringLength, .Indicator,  \
      >,  'SQLSetDescRec',  \
    SQLSetEnvAttr, <.EnvironmentHandle, .lAttribute, .Value, .StringLength>,  'SQLSetEnvAttr',  \
    SQLSetParam, <.hstmt, .ipar, .fCType, .fSqlType, .cbParamDef, .ibScale, .rgbValue, .pcbValue>,  'SQLSetParam',  \
    SQLSetPos, <.hstmt, .irow, .fOption, .fLock>,  'SQLSetPos',  \
    SQLSetScrollOptions, <.hstmt, .fConcurrency, .crowKeyset, .crowRowset>,  'SQLSetScrollOptions',  \
    SQLSetStmtAttr, <.StatementHandle, .lAttribute, .Value, .StringLength>,  'SQLSetStmtAttr',  \
    SQLSetStmtAttrA, <.StatementHandle, .lAttribute, .Value, .StringLength>,  'SQLSetStmtAttrA',  \
    SQLSetStmtAttrW, <.StatementHandle, .lAttribute, .Value, .StringLength>,  'SQLSetStmtAttrW',  \
    SQLSetStmtOption, <.hstmt, .fOption, .vParam>,  'SQLSetStmtOption',  \
    SQLSpecialColumns, <.hstmt, .fColType, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName,  \
        .fScope, .fNullable>,  'SQLSpecialColumns',  \
    SQLSpecialColumnsA, <.hstmt, .fColType, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName,  \
        .fScope, .fNullable>,  'SQLSpecialColumnsA',  \
    SQLSpecialColumnsW, <.hstmt, .fColType, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName,  \
        .fScope, .fNullable>,  'SQLSpecialColumnsW',  \
    SQLStatistics, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName, .fUnique, .fAccuracy,  \
      >,  'SQLStatistics',  \
    SQLStatisticsA, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName, .fUnique, .fAccuracy,  \
      >,  'SQLStatisticsA',  \
    SQLStatisticsW, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName, .fUnique, .fAccuracy,  \
      >,  'SQLStatisticsW',  \
    SQLTablePrivileges, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName>,  'SQLTablePrivileges',  \
    SQLTablePrivilegesA, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName>,  'SQLTablePrivilegesA',  \
    SQLTablePrivilegesW, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName>,  'SQLTablePrivilegesW',  \
    SQLTables, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName, .szTableType, .cbTableType,  \
      >,  'SQLTables',  \
    SQLTablesA, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName, .szTableType, .cbTableType,  \
      >,  'SQLTablesA',  \
    SQLTablesW, <.hstmt, .szCatalogName, .cbCatalogName, .szSchemaName, .cbSchemaName, .szTableName, .cbTableName, .szTableType, .cbTableType,  \
      >,  'SQLTablesW',  \
    SQLTransact, <.henv, .hdbc, .fType>,  'SQLTransact',  \
    SearchStatusCode, <NONE>,  'SearchStatusCode',  \
    VFreeErrors, <NONE>,  'VFreeErrors',  \
    VRetrieveDriverErrorsRowCol, <NONE>,  'VRetrieveDriverErrorsRowCol',  \
    ValidateErrorQueue, <NONE>,  'ValidateErrorQueue',  \
    g_hHeapMalloc, <NONE>,  'g_hHeapMalloc'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































Deleted freshlib/imports/Win32/ole32.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: ole32.dll API calls
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


import_proto ole32,  \
    BindMoniker, <.pmk, .grfOpt, .iidResult, .ppvResult>,  'BindMoniker',  \
    CLIPFORMAT_UserFree, <.pLong, .pClipformat>,  'CLIPFORMAT_UserFree',  \
    CLIPFORMAT_UserMarshal, <.pLong, .pChar, .pClipformat>,  'CLIPFORMAT_UserMarshal',  \
    CLIPFORMAT_UserSize, <.pLong, .lLong, .pClipformat>,  'CLIPFORMAT_UserSize',  \
    CLIPFORMAT_UserUnmarshal, <.pLong, .pChar, .pClipformat>,  'CLIPFORMAT_UserUnmarshal',  \
    CLSIDFromOle1Class, <NONE>,  'CLSIDFromOle1Class',  \
    CLSIDFromProgID, <.TSzProgID, .T>,  'CLSIDFromProgID',  \
    CLSIDFromProgIDEx, <.lpszProgID, .lpclsid>,  'CLSIDFromProgIDEx',  \
    CLSIDFromString, <.lpsz, .pclsid>,  'CLSIDFromString',  \
    CoAddRefServerProcess, <VOID>,  'CoAddRefServerProcess',  \
    CoAllowSetForegroundWindow, <.pUnk, .lpvReserved>,  'CoAllowSetForegroundWindow',  \
    CoBuildVersion, <VOID>,  'CoBuildVersion',  \
    CoCancelCall, <.dwThreadId, .ulTimeout>,  'CoCancelCall',  \
    CoCopyProxy, <.pProxy, .ppCopy>,  'CoCopyProxy',  \
    CoCreateFreeThreadedMarshaler, <.punkOuter, .ppunkMarshal>,  'CoCreateFreeThreadedMarshaler',  \
    CoCreateGuid, <.pguid>,  'CoCreateGuid',  \
    CoCreateInstance, <.rclsid, .pUnkOuter, .dwClsContext, .riid, .ppv>,  'CoCreateInstance',  \
    CoCreateInstanceEx, <.Clsid, .punkOuter, .dwClsCtx, .pServerInfo, .dwCount, .pResults>,  'CoCreateInstanceEx',  \
    CoCreateObjectInContext, <NONE>,  'CoCreateObjectInContext',  \
    CoDeactivateObject, <NONE>,  'CoDeactivateObject',  \
    CoDisableCallCancellation, <.pReserved>,  'CoDisableCallCancellation',  \
    CoDisconnectObject, <.pUnk, .dwReserved>,  'CoDisconnectObject',  \
    CoDosDateTimeToFileTime, <.nDosDate, .nDosTime, .lpFileTime>,  'CoDosDateTimeToFileTime',  \
    CoEnableCallCancellation, <.pReserved>,  'CoEnableCallCancellation',  \
    CoFileTimeNow, <.lpFileTime>,  'CoFileTimeNow',  \
    CoFileTimeToDosDateTime, <.lpFileTime, .lpDosDate, .lpDosTime>,  'CoFileTimeToDosDateTime',  \
    CoFreeAllLibraries, <VOID>,  'CoFreeAllLibraries',  \
    CoFreeLibrary, <.hInst>,  'CoFreeLibrary',  \
    CoFreeUnusedLibraries, <VOID>,  'CoFreeUnusedLibraries',  \
    CoFreeUnusedLibrariesEx, <NONE>,  'CoFreeUnusedLibrariesEx',  \
    CoGetApartmentID, <NONE>,  'CoGetApartmentID',  \
    CoGetCallContext, <.riid, .ppInterface>,  'CoGetCallContext',  \
    CoGetCallerTID, <NONE>,  'CoGetCallerTID',  \
    CoGetCancelObject, <.dwThreadId, .iid, .ppUnk>,  'CoGetCancelObject',  \
    CoGetClassObject, <.rclsid, .dwClsContext, .pvReserved, .riid, .ppv>,  'CoGetClassObject',  \
    CoGetClassVersion, <.pClassSpec, .pdwVersionMS, .pdwVersionLS>,  'CoGetClassVersion',  \
    CoGetComCatalog, <NONE>,  'CoGetComCatalog',  \
    CoGetContextToken, <NONE>,  'CoGetContextToken',  \
    CoGetCurrentLogicalThreadId, <NONE>,  'CoGetCurrentLogicalThreadId',  \
    CoGetCurrentProcess, <VOID>,  'CoGetCurrentProcess',  \
    CoGetDefaultContext, <NONE>,  'CoGetDefaultContext',  \
    CoGetInstanceFromFile, <.pServerInfo, .pClsid, .punkOuter, .dwClsCtx, .grfMode, .pwszName, .dwCount, .pResults>,  'CoGetInstanceFromFile',  \
    CoGetInstanceFromIStorage, <.pServerInfo, .pClsid, .punkOuter, .dwClsCtx, .pstg, .dwCount, .pResults>,  'CoGetInstanceFromIStorage',  \
    CoGetInterceptor, <NONE>,  'CoGetInterceptor',  \
    CoGetInterceptorFromTypeInfo, <NONE>,  'CoGetInterceptorFromTypeInfo',  \
    CoGetInterfaceAndReleaseStream, <.pStm, .iid, .ppv>,  'CoGetInterfaceAndReleaseStream',  \
    CoGetMalloc, <.dwMemContext, .ppMalloc>,  'CoGetMalloc',  \
    CoGetMarshalSizeMax, <.pulSize, .riid, .pUnk, .dwDestContext, .pvDestContext, .mshlflags>,  'CoGetMarshalSizeMax',  \
    CoGetObject, <.pszName, .pBindOptions, .riid, .ppv>,  'CoGetObject',  \
    CoGetObjectContext, <.riid, .ppv>,  'CoGetObjectContext',  \
    CoGetPSClsid, <.riid, .pClsid>,  'CoGetPSClsid',  \
    CoGetProcessIdentifier, <NONE>,  'CoGetProcessIdentifier',  \
    CoGetStandardMarshal, <.riid, .pUnk, .dwDestContext, .pvDestContext, .mshlflags, .ppMarshal>,  'CoGetStandardMarshal',  \
    CoGetState, <NONE>,  'CoGetState',  \
    CoGetStdMarshalEx, <.pUnkOuter, .smexflags, .ppUnkInner>,  'CoGetStdMarshalEx',  \
    CoGetSystemSecurityPermissions, <NONE>,  'CoGetSystemSecurityPermissions',  \
    CoGetTreatAsClass, <.clsidOld, .pClsidNew>,  'CoGetTreatAsClass',  \
    CoImpersonateClient, <VOID>,  'CoImpersonateClient',  \
    CoInitialize, <.pzReserved>,  'CoInitialize',  \
    CoInitializeEx, <.pvReserved, .dwCoInit>,  'CoInitializeEx',  \
    CoInitializeSecurity, <.pSecDesc, .cAuthSvc, .asAuthSvc, .pReserved1, .dwAuthnLevel, .dwImpLevel, .pAuthList, .dwCapabilities,  \
        .pReserved3>,  'CoInitializeSecurity',  \
    CoInitializeWOW, <NONE>,  'CoInitializeWOW',  \
    CoInstall, <.pbc, .dwFlags, .pClassSpec, .pQuery, .pszCodeBase>,  'CoInstall',  \
    CoInvalidateRemoteMachineBindings, <NONE>,  'CoInvalidateRemoteMachineBindings',  \
    CoIsHandlerConnected, <.pUnk>,  'CoIsHandlerConnected',  \
    CoIsOle1Class, <.rclsid>,  'CoIsOle1Class',  \
    CoLoadLibrary, <.lpszLibName, .bAutoFree>,  'CoLoadLibrary',  \
    CoLockObjectExternal, <.pUnk, .fLock, .fLastUnlockReleases>,  'CoLockObjectExternal',  \
    CoMarshalHresult, <.pstm, .hresult>,  'CoMarshalHresult',  \
    CoMarshalInterThreadInterfaceInStream, <.riid, .pUnk, .ppStm>,  'CoMarshalInterThreadInterfaceInStream',  \
    CoMarshalInterface, <.pStm, .riid, .pUnk, .dwDestContext, .pvDestContext, .mshlflags>,  'CoMarshalInterface',  \
    CoPopServiceDomain, <NONE>,  'CoPopServiceDomain',  \
    CoPushServiceDomain, <NONE>,  'CoPushServiceDomain',  \
    CoQueryAuthenticationServices, <.pcAuthSvc, .asAuthSvc>,  'CoQueryAuthenticationServices',  \
    CoQueryClientBlanket, <.pAuthnSvc, .pAuthzSvc, .pServerPrincName, .pAuthnLevel, .pImpLevel, .pPrivs, .pCapabilities>,  'CoQueryClientBlanket',  \
    CoQueryProxyBlanket, <.pProxy, .pwAuthnSvc, .pAuthzSvc, .pServerPrincName, .pAuthnLevel, .pImpLevel, .pAuthInfo, .pCapabilites,  \
      >,  'CoQueryProxyBlanket',  \
    CoQueryReleaseObject, <NONE>,  'CoQueryReleaseObject',  \
    CoReactivateObject, <NONE>,  'CoReactivateObject',  \
    CoRegisterChannelHook, <.ExtensionUuid, .pChannelHook>,  'CoRegisterChannelHook',  \
    CoRegisterClassObject, <.rclsid, .pUnk, .dwClsContext, .flags, .lpdwRegister>,  'CoRegisterClassObject',  \
    CoRegisterInitializeSpy, <NONE>,  'CoRegisterInitializeSpy',  \
    CoRegisterMallocSpy, <.pMallocSpy>,  'CoRegisterMallocSpy',  \
    CoRegisterMessageFilter, <.lpMessageFilter, .lplpMessageFilter>,  'CoRegisterMessageFilter',  \
    CoRegisterPSClsid, <.riid, .rclsid>,  'CoRegisterPSClsid',  \
    CoRegisterSurrogate, <.pSurrogate>,  'CoRegisterSurrogate',  \
    CoRegisterSurrogateEx, <NONE>,  'CoRegisterSurrogateEx',  \
    CoReleaseMarshalData, <.pStm>,  'CoReleaseMarshalData',  \
    CoReleaseServerProcess, <VOID>,  'CoReleaseServerProcess',  \
    CoResumeClassObjects, <VOID>,  'CoResumeClassObjects',  \
    CoRetireServer, <NONE>,  'CoRetireServer',  \
    CoRevertToSelf, <VOID>,  'CoRevertToSelf',  \
    CoRevokeClassObject, <.dwRegister>,  'CoRevokeClassObject',  \
    CoRevokeInitializeSpy, <NONE>,  'CoRevokeInitializeSpy',  \
    CoRevokeMallocSpy, <VOID>,  'CoRevokeMallocSpy',  \
    CoSetCancelObject, <.pUnk>,  'CoSetCancelObject',  \
    CoSetProxyBlanket, <.pProxy, .dwAuthnSvc, .dwAuthzSvc, .pServerPrincName, .dwAuthnLevel, .dwImpLevel, .pAuthInfo, .dwCapabilities,  \
      >,  'CoSetProxyBlanket',  \
    CoSetState, <NONE>,  'CoSetState',  \
    CoSuspendClassObjects, <VOID>,  'CoSuspendClassObjects',  \
    CoSwitchCallContext, <.pNewObject, .ppOldObject>,  'CoSwitchCallContext',  \
    CoTaskMemAlloc, <.cb>,  'CoTaskMemAlloc',  \
    CoTaskMemFree, <.lpIDList>,  'CoTaskMemFree',  \
    CoTaskMemRealloc, <.pv, .cb>,  'CoTaskMemRealloc',  \
    CoTestCancel, <VOID>,  'CoTestCancel',  \
    CoTreatAsClass, <.clsidOld, .clsidNew>,  'CoTreatAsClass',  \
    CoUninitialize, <VOID>,  'CoUninitialize',  \
    CoUnloadingWOW, <NONE>,  'CoUnloadingWOW',  \
    CoUnmarshalHresult, <.pstm, .phresult>,  'CoUnmarshalHresult',  \
    CoUnmarshalInterface, <.pStm, .riid, .ppv>,  'CoUnmarshalInterface',  \
    CoWaitForMultipleHandles, <.dwFlags, .dwTimeout, .cHandles, .pHandles, .lpdwindex>,  'CoWaitForMultipleHandles',  \
    ComPs_CStdStubBuffer_AddRef, <NONE>,  'ComPs_CStdStubBuffer_AddRef',  \
    ComPs_CStdStubBuffer_Connect, <NONE>,  'ComPs_CStdStubBuffer_Connect',  \
    ComPs_CStdStubBuffer_CountRefs, <NONE>,  'ComPs_CStdStubBuffer_CountRefs',  \
    ComPs_CStdStubBuffer_DebugServerQueryInterface, <NONE>,  'ComPs_CStdStubBuffer_DebugServerQueryInterface',  \
    ComPs_CStdStubBuffer_DebugServerRelease, <NONE>,  'ComPs_CStdStubBuffer_DebugServerRelease',  \
    ComPs_CStdStubBuffer_Disconnect, <NONE>,  'ComPs_CStdStubBuffer_Disconnect',  \
    ComPs_CStdStubBuffer_Invoke, <NONE>,  'ComPs_CStdStubBuffer_Invoke',  \
    ComPs_CStdStubBuffer_IsIIDSupported, <NONE>,  'ComPs_CStdStubBuffer_IsIIDSupported',  \
    ComPs_CStdStubBuffer_QueryInterface, <NONE>,  'ComPs_CStdStubBuffer_QueryInterface',  \
    ComPs_IUnknown_AddRef_Proxy, <NONE>,  'ComPs_IUnknown_AddRef_Proxy',  \
    ComPs_IUnknown_QueryInterface_Proxy, <NONE>,  'ComPs_IUnknown_QueryInterface_Proxy',  \
    ComPs_IUnknown_Release_Proxy, <NONE>,  'ComPs_IUnknown_Release_Proxy',  \
    ComPs_NdrCStdStubBuffer2_Release, <NONE>,  'ComPs_NdrCStdStubBuffer2_Release',  \
    ComPs_NdrCStdStubBuffer_Release, <NONE>,  'ComPs_NdrCStdStubBuffer_Release',  \
    ComPs_NdrClientCall2, <NONE>,  'ComPs_NdrClientCall2',  \
    ComPs_NdrClientCall2_va, <NONE>,  'ComPs_NdrClientCall2_va',  \
    ComPs_NdrDllCanUnloadNow, <NONE>,  'ComPs_NdrDllCanUnloadNow',  \
    ComPs_NdrDllGetClassObject, <NONE>,  'ComPs_NdrDllGetClassObject',  \
    ComPs_NdrDllRegisterProxy, <NONE>,  'ComPs_NdrDllRegisterProxy',  \
    ComPs_NdrDllUnregisterProxy, <NONE>,  'ComPs_NdrDllUnregisterProxy',  \
    ComPs_NdrStubCall2, <NONE>,  'ComPs_NdrStubCall2',  \
    ComPs_NdrStubForwardingFunction, <NONE>,  'ComPs_NdrStubForwardingFunction',  \
    CreateAntiMoniker, <.ppmk>,  'CreateAntiMoniker',  \
    CreateBindCtx, <.reserved, .ppbc>,  'CreateBindCtx',  \
    CreateClassMoniker, <.rclsid, .ppmk>,  'CreateClassMoniker',  \
    CreateDataAdviseHolder, <.ppDAHolder>,  'CreateDataAdviseHolder',  \
    CreateDataCache, <.pUnkOuter, .rclsid, .iid, .ppv>,  'CreateDataCache',  \
    CreateErrorInfo, <.pperrinfo>,  'CreateErrorInfo',  \
    CreateFileMoniker, <.lpszPathName, .ppmk>,  'CreateFileMoniker',  \
    CreateGenericComposite, <.pmkFirst, .pmkRest, .ppmkComposite>,  'CreateGenericComposite',  \
    CreateILockBytesOnHGlobal, <.hGlobal, .fDeleteOnRelease, .pplkbyt>,  'CreateILockBytesOnHGlobal',  \
    CreateItemMoniker, <.lpszDelim, .lpszItem, .ppmk>,  'CreateItemMoniker',  \
    CreateObjrefMoniker, <.punk, .ppmk>,  'CreateObjrefMoniker',  \
    CreateOleAdviseHolder, <.ppOAHolder>,  'CreateOleAdviseHolder',  \
    CreatePointerMoniker, <.punk, .ppmk>,  'CreatePointerMoniker',  \
    CreateStdProgressIndicator, <.hwndParent, .pszTitle, .pIbscCaller, .ppIbsc>,  'CreateStdProgressIndicator',  \
    CreateStreamOnHGlobal, <.hGlobal, .fDeleteOnRelease, .ppstm>,  'CreateStreamOnHGlobal',  \
    DcomChannelSetHResult, <NONE>,  'DcomChannelSetHResult',  \
    DoDragDrop, <.pDataObj, .pDropSource, .dwOKEffects, .pdwEffect>,  'DoDragDrop',  \
    EnableHookObject, <NONE>,  'EnableHookObject',  \
    FmtIdToPropStgName, <.pfmtid, .oszName>,  'FmtIdToPropStgName',  \
    FreePropVariantArray, <.cVariants, .rgvars>,  'FreePropVariantArray',  \
    GetClassFile, <.szFilename, .pclsid>,  'GetClassFile',  \
    GetConvertStg, <.pStg>,  'GetConvertStg',  \
    GetDocumentBitStg, <NONE>,  'GetDocumentBitStg',  \
    GetErrorInfo, <.dwReserved, .pperrinfo>,  'GetErrorInfo',  \
    GetHGlobalFromILockBytes, <.plkbyt, .phglobal>,  'GetHGlobalFromILockBytes',  \
    GetHGlobalFromStream, <.pstm, .phglobal>,  'GetHGlobalFromStream',  \
    GetHookInterface, <NONE>,  'GetHookInterface',  \
    GetRunningObjectTable, <.reserved, .pprot>,  'GetRunningObjectTable',  \
    HACCEL_UserFree, <.pLong, .pHaccel>,  'HACCEL_UserFree',  \
    HACCEL_UserMarshal, <.pLong, .pChar, .pHaccel>,  'HACCEL_UserMarshal',  \
    HACCEL_UserSize, <.pLong, .lLong, .pHaccel>,  'HACCEL_UserSize',  \
    HACCEL_UserUnmarshal, <.pLong, .pChar, .pHaccel>,  'HACCEL_UserUnmarshal',  \
    HBITMAP_UserFree, <.pLong, .pHbitmap>,  'HBITMAP_UserFree',  \
    HBITMAP_UserMarshal, <.pLong, .pChar, .pHbitmap>,  'HBITMAP_UserMarshal',  \
    HBITMAP_UserSize, <.pLong, .lLong, .pHbitmap>,  'HBITMAP_UserSize',  \
    HBITMAP_UserUnmarshal, <.pLong, .pChar, .pHbitmap>,  'HBITMAP_UserUnmarshal',  \
    HBRUSH_UserFree, <NONE>,  'HBRUSH_UserFree',  \
    HBRUSH_UserMarshal, <NONE>,  'HBRUSH_UserMarshal',  \
    HBRUSH_UserSize, <NONE>,  'HBRUSH_UserSize',  \
    HBRUSH_UserUnmarshal, <NONE>,  'HBRUSH_UserUnmarshal',  \
    HDC_UserFree, <.pLong, .pHdc>,  'HDC_UserFree',  \
    HDC_UserMarshal, <.pLong, .pChar, .pHdc>,  'HDC_UserMarshal',  \
    HDC_UserSize, <.pLong, .lLong, .pHdc>,  'HDC_UserSize',  \
    HDC_UserUnmarshal, <.pLong, .pChar, .pHdc>,  'HDC_UserUnmarshal',  \
    HENHMETAFILE_UserFree, <NONE>,  'HENHMETAFILE_UserFree',  \
    HENHMETAFILE_UserMarshal, <NONE>,  'HENHMETAFILE_UserMarshal',  \
    HENHMETAFILE_UserSize, <NONE>,  'HENHMETAFILE_UserSize',  \
    HENHMETAFILE_UserUnmarshal, <NONE>,  'HENHMETAFILE_UserUnmarshal',  \
    HGLOBAL_UserFree, <.pLong, .pHglobal>,  'HGLOBAL_UserFree',  \
    HGLOBAL_UserMarshal, <.pLong, .pChar, .pHglobal>,  'HGLOBAL_UserMarshal',  \
    HGLOBAL_UserSize, <.pLong, .lLong, .pHglobal>,  'HGLOBAL_UserSize',  \
    HGLOBAL_UserUnmarshal, <.pLong, .pChar, .pHglobal>,  'HGLOBAL_UserUnmarshal',  \
    HICON_UserFree, <.pLong, .pHicon>,  'HICON_UserFree',  \
    HICON_UserMarshal, <.pLong, .pChar, .pHicon>,  'HICON_UserMarshal',  \
    HICON_UserSize, <.pLong, .llong, .pHicon>,  'HICON_UserSize',  \
    HICON_UserUnmarshal, <.pLong, .pChar, .pHicon>,  'HICON_UserUnmarshal',  \
    HMENU_UserFree, <.pLong, .pHmenu>,  'HMENU_UserFree',  \
    HMENU_UserMarshal, <.pLong, .pChar, .pHmenu>,  'HMENU_UserMarshal',  \
    HMENU_UserSize, <.pLong, .lLong, .pHmenu>,  'HMENU_UserSize',  \
    HMENU_UserUnmarshal, <.pLong, .pChar, .pHmenu>,  'HMENU_UserUnmarshal',  \
    HMETAFILEPICT_UserFree, <NONE>,  'HMETAFILEPICT_UserFree',  \
    HMETAFILEPICT_UserMarshal, <NONE>,  'HMETAFILEPICT_UserMarshal',  \
    HMETAFILEPICT_UserSize, <NONE>,  'HMETAFILEPICT_UserSize',  \
    HMETAFILEPICT_UserUnmarshal, <NONE>,  'HMETAFILEPICT_UserUnmarshal',  \
    HMETAFILE_UserFree, <NONE>,  'HMETAFILE_UserFree',  \
    HMETAFILE_UserMarshal, <NONE>,  'HMETAFILE_UserMarshal',  \
    HMETAFILE_UserSize, <NONE>,  'HMETAFILE_UserSize',  \
    HMETAFILE_UserUnmarshal, <NONE>,  'HMETAFILE_UserUnmarshal',  \
    HPALETTE_UserFree, <.pLong, .pHpalette>,  'HPALETTE_UserFree',  \
    HPALETTE_UserMarshal, <.pLong, .pChar, .pHpalette>,  'HPALETTE_UserMarshal',  \
    HPALETTE_UserSize, <.pLong, .lLong, .pHpalette>,  'HPALETTE_UserSize',  \
    HPALETTE_UserUnmarshal, <.pLong, .pChar, .pHpalette>,  'HPALETTE_UserUnmarshal',  \
    HWND_UserFree, <.pLong, .pHwnd>,  'HWND_UserFree',  \
    HWND_UserMarshal, <.pLong, .pChar, .pHwnd>,  'HWND_UserMarshal',  \
    HWND_UserSize, <.pLong, .lLong, .pHwnd>,  'HWND_UserSize',  \
    HWND_UserUnmarshal, <.pLong, .pChar, .pHwnd>,  'HWND_UserUnmarshal',  \
    HkOleRegisterObject, <NONE>,  'HkOleRegisterObject',  \
    IIDFromString, <.lpsz, .lpiid>,  'IIDFromString',  \
    IsAccelerator, <.hAccel, .cAccelEntries, .lpMsg, .lpwCmd>,  'IsAccelerator',  \
    IsEqualGUID, <NONE>,  'IsEqualGUID',  \
    IsValidIid, <NONE>,  'IsValidIid',  \
    IsValidInterface, <NONE>,  'IsValidInterface',  \
    IsValidPtrIn, <NONE>,  'IsValidPtrIn',  \
    IsValidPtrOut, <NONE>,  'IsValidPtrOut',  \
    MkParseDisplayName, <.pbc, .szUserName, .pchEaten, .ppmk>,  'MkParseDisplayName',  \
    MonikerCommonPrefixWith, <.pmkThis, .pmkOther, .ppmkCommon>,  'MonikerCommonPrefixWith',  \
    MonikerRelativePathTo, <.pmkSrc, .pmkDest, .ppmkRelPath, .dwReserved>,  'MonikerRelativePathTo',  \
    OleBuildVersion, <VOID>,  'OleBuildVersion',  \
    OleConvertIStorageToOLESTREAM, <.pstg, .lpolestream>,  'OleConvertIStorageToOLESTREAM',  \
    OleConvertIStorageToOLESTREAMEx, <.pstg, .cfFormat, .lWidth, .lHeight, .dwSize, .pmedium, .polestm>,  'OleConvertIStorageToOLESTREAMEx',  \
    OleConvertOLESTREAMToIStorage, <.lpolestream, .pstg, .ptd>,  'OleConvertOLESTREAMToIStorage',  \
    OleConvertOLESTREAMToIStorageEx, <.polestm, .pstg, .pcfFormat, .plwWidth, .plHeight, .pdwSize, .pmedium>,  'OleConvertOLESTREAMToIStorageEx',  \
    OleCreate, <.rclsid, .riid, .renderopt, .pFormatEtc, .pClientSite, .pStg, .ppvObj>,  'OleCreate',  \
    OleCreateDefaultHandler, <.clsid, .pUnkOuter, .riid, .lplpObj>,  'OleCreateDefaultHandler',  \
    OleCreateEmbeddingHelper, <.clsid, .pUnkOuter, .flags, .pCF, .riid, .lplpObj>,  'OleCreateEmbeddingHelper',  \
    OleCreateEx, <.rclsid, .riid, .dwFlags, .renderopt, .cFormats, .rgAdvf, .rgFormatEtc, .lpAdviseSink, .rgdwConnection, .pClientSite,  \
        .pStg, .ppvObj>,  'OleCreateEx',  \
    OleCreateFromData, <.pSrcDataObj, .riid, .renderopt, .pFormatEtc, .pClientSite, .pStg, .ppvObj>,  'OleCreateFromData',  \
    OleCreateFromDataEx, <.pSrcDataObj, .riid, .dwFlags, .renderopt, .cFormats, .rgAdvf, .rgFormatEtc, .lpAdviseSink, .rgdwConnection,  \
        .pClientSite, .pStg, .ppvObj>,  'OleCreateFromDataEx',  \
    OleCreateFromFile, <.rclsid, .lpszFileName, .riid, .renderopt, .lpFormatEtc, .pClientSite, .pStg, .ppvObj>,  'OleCreateFromFile',  \
    OleCreateFromFileEx, <.rclsid, .lpszFileName, .riid, .dwFlags, .renderopt, .cFormats, .rgAdvf, .rgFormatEtc, .lpAdviseSink, .rgdwConnection,  \
        .pClientSite, .pStg, .ppvObj>,  'OleCreateFromFileEx',  \
    OleCreateLink, <.pmkLinkSrc, .riid, .renderopt, .lpFormatEtc, .pClientSite, .pStg, .ppvObj>,  'OleCreateLink',  \
    OleCreateLinkEx, <.pmkLinkSrc, .riid, .dwFlags, .renderopt, .cFormats, .rgAdvf, .rgFormatEtc, .lpAdviseSink, .rgdwConnection, .pClientSite,  \
        .pStg, .ppvObj>,  'OleCreateLinkEx',  \
    OleCreateLinkFromData, <.pSrcDataObj, .riid, .renderopt, .pFormatEtc, .pClientSite, .pStg, .ppvObj>,  'OleCreateLinkFromData',  \
    OleCreateLinkFromDataEx, <.pSrcDataObj, .riid, .dwFlags, .renderopt, .cFormats, .rgAdvf, .rgFormatEtc, .lpAdviseSink, .rgdwConnection,  \
        .pClientSite, .pStg, .ppvObj>,  'OleCreateLinkFromDataEx',  \
    OleCreateLinkToFile, <.lpszFileName, .riid, .renderopt, .lpFormatEtc, .pClientSite, .pStg, .ppvObj>,  'OleCreateLinkToFile',  \
    OleCreateLinkToFileEx, <.lpszFileName, .riid, .dwFlags, .renderopt, .cFormats, .rgAdvf, .rgFormatEtc, .lpAdviseSink, .rgdwConnection,  \
        .pClientSite, .pStg, .ppvObj>,  'OleCreateLinkToFileEx',  \
    OleCreateMenuDescriptor, <.hmenuCombined, .lpMenuWidths>,  'OleCreateMenuDescriptor',  \
    OleCreateStaticFromData, <.pSrcDataObj, .iid, .renderopt, .pFormatEtc, .pClientSite, .pStg, .ppvObj>,  'OleCreateStaticFromData',  \
    OleDestroyMenuDescriptor, <.holemenu>,  'OleDestroyMenuDescriptor',  \
    OleDoAutoConvert, <.pStg, .pClsidNew>,  'OleDoAutoConvert',  \
    OleDraw, <.pUnknown, .dwAspect, .hdcDraw, .lprcBounds>,  'OleDraw',  \
    OleDuplicateData, <.hSrc, .cfFormat, .uiFlags>,  'OleDuplicateData',  \
    OleFlushClipboard, <VOID>,  'OleFlushClipboard',  \
    OleGetAutoConvert, <.clsidOld, .pClsidNew>,  'OleGetAutoConvert',  \
    OleGetClipboard, <.ppDataObj>,  'OleGetClipboard',  \
    OleGetIconOfClass, <.rclsid, .lpszLabel, .fUseTypeAsLabel>,  'OleGetIconOfClass',  \
    OleGetIconOfFile, <.lpszPath, .fUseFileAsLabel>,  'OleGetIconOfFile',  \
    OleInitialize, <.pvReserved>,  'OleInitialize',  \
    OleInitializeWOW, <NONE>,  'OleInitializeWOW',  \
    OleIsCurrentClipboard, <.pDataObj>,  'OleIsCurrentClipboard',  \
    OleIsRunning, <.pObject>,  'OleIsRunning',  \
    OleLoad, <.pStg, .riid, .pClientSite, .ppvObj>,  'OleLoad',  \
    OleLoadFromStream, <.pStm, .iidInterface, .ppvObj>,  'OleLoadFromStream',  \
    OleLockRunning, <.pUnknown, .fLock, .fLastUnlockCloses>,  'OleLockRunning',  \
    OleMetafilePictFromIconAndLabel, <.hIcon, .lpszLabel, .lpszSourceFile, .iIconIndex>,  'OleMetafilePictFromIconAndLabel',  \
    OleNoteObjectVisible, <.pUnknown, .fVisible>,  'OleNoteObjectVisible',  \
    OleQueryCreateFromData, <.pSrcDataObject>,  'OleQueryCreateFromData',  \
    OleQueryLinkFromData, <.pSrcDataObject>,  'OleQueryLinkFromData',  \
    OleRegEnumFormatEtc, <.clsid, .dwDirection, .ppenum>,  'OleRegEnumFormatEtc',  \
    OleRegEnumVerbs, <.clsid, .ppenum>,  'OleRegEnumVerbs',  \
    OleRegGetMiscStatus, <.clsid, .dwAspect, .pdwStatus>,  'OleRegGetMiscStatus',  \
    OleRegGetUserType, <.clsid, .dwFormOfType, .pszUserType>,  'OleRegGetUserType',  \
    OleRun, <.pUnknown>,  'OleRun',  \
    OleSave, <.pPS, .pStg, .fSameAsLoad>,  'OleSave',  \
    OleSaveToStream, <.pPStm, .pStm>,  'OleSaveToStream',  \
    OleSetAutoConvert, <.clsidOld, .clsidNew>,  'OleSetAutoConvert',  \
    OleSetClipboard, <.pDataObj>,  'OleSetClipboard',  \
    OleSetContainedObject, <.pUnknown, .fContained>,  'OleSetContainedObject',  \
    OleSetMenuDescriptor, <.holemenu, .hwndFrame, .hwndActiveObject, .lpFrame, .lpActiveObj>,  'OleSetMenuDescriptor',  \
    OleTranslateAccelerator, <.lpFrame, .lpFrameInfo, .lpmsg>,  'OleTranslateAccelerator',  \
    OleUninitialize, <VOID>,  'OleUninitialize',  \
    OpenOrCreateStream, <NONE>,  'OpenOrCreateStream',  \
    ProgIDFromCLSID, <.clsid, .lplpszProgID>,  'ProgIDFromCLSID',  \
    PropStgNameToFmtId, <.oszName, .pfmtid>,  'PropStgNameToFmtId',  \
    PropSysAllocString, <NONE>,  'PropSysAllocString',  \
    PropSysFreeString, <NONE>,  'PropSysFreeString',  \
    PropVariantChangeType, <NONE>,  'PropVariantChangeType',  \
    PropVariantClear, <.pvar>,  'PropVariantClear',  \
    PropVariantCopy, <.pvarDest, .pvarSrc>,  'PropVariantCopy',  \
    ReadClassStg, <.pStg, .pclsid>,  'ReadClassStg',  \
    ReadClassStm, <.pStm, .pclsid>,  'ReadClassStm',  \
    ReadFmtUserTypeStg, <.pstg, .pcf, .lplpszUserType>,  'ReadFmtUserTypeStg',  \
    ReadOleStg, <NONE>,  'ReadOleStg',  \
    ReadStringStream, <NONE>,  'ReadStringStream',  \
    RegisterDragDrop, <.hwnd, .pDropTarget>,  'RegisterDragDrop',  \
    ReleaseStgMedium, <.lpstgmedium>,  'ReleaseStgMedium',  \
    RevokeDragDrop, <.hwnd>,  'RevokeDragDrop',  \
    SNB_UserFree, <.pLong, .pSnb>,  'SNB_UserFree',  \
    SNB_UserMarshal, <.pLong, .pChar, .pSnb>,  'SNB_UserMarshal',  \
    SNB_UserSize, <.pLong, .lLong, .pSnb>,  'SNB_UserSize',  \
    SNB_UserUnmarshal, <.pLong, .pChar, .pSnb>,  'SNB_UserUnmarshal',  \
    STGMEDIUM_UserFree, <.pLong, .pStgmedium>,  'STGMEDIUM_UserFree',  \
    STGMEDIUM_UserMarshal, <.pLong, .pChar, .pStgmedium>,  'STGMEDIUM_UserMarshal',  \
    STGMEDIUM_UserSize, <.pLong, .long, .pStgmedium>,  'STGMEDIUM_UserSize',  \
    STGMEDIUM_UserUnmarshal, <.pLong, .pChar, .pStgmedium>,  'STGMEDIUM_UserUnmarshal',  \
    SetConvertStg, <.pStg, .fConvert>,  'SetConvertStg',  \
    SetDocumentBitStg, <NONE>,  'SetDocumentBitStg',  \
    SetErrorInfo, <.dwReserved, .perrinfo>,  'SetErrorInfo',  \
    StgConvertPropertyToVariant, <NONE>,  'StgConvertPropertyToVariant',  \
    StgConvertVariantToProperty, <NONE>,  'StgConvertVariantToProperty',  \
    StgCreateDocfile, <.pwcsName, .grfMode, .reserved, .ppstgOpen>,  'StgCreateDocfile',  \
    StgCreateDocfileOnILockBytes, <.plkbyt, .grfMode, .reserved, .ppstgOpen>,  'StgCreateDocfileOnILockBytes',  \
    StgCreatePropSetStg, <.pStorage, .dwReserved, .ppPropSetStg>,  'StgCreatePropSetStg',  \
    StgCreatePropStg, <.pUnk, .fmtid, .pclsid, .grfFlags, .dwReserved, .ppPropStg>,  'StgCreatePropStg',  \
    StgCreateStorageEx, <.pwcsName, .grfMode, .stgfmt, .grfAttrs, .pStgOptions, .reserved, .riid, .ppObjectOpen>,  'StgCreateStorageEx',  \
    StgGetIFillLockBytesOnFile, <.pwcsName, .ppflb>,  'StgGetIFillLockBytesOnFile',  \
    StgGetIFillLockBytesOnILockBytes, <.pilb, .ppflb>,  'StgGetIFillLockBytesOnILockBytes',  \
    StgIsStorageFile, <.pwcsName>,  'StgIsStorageFile',  \
    StgIsStorageILockBytes, <.plkbyt>,  'StgIsStorageILockBytes',  \
    StgOpenAsyncDocfileOnIFillLockBytes, <.pflb, .grfMode, .asyncFlags, .ppstgOpen>,  'StgOpenAsyncDocfileOnIFillLockBytes',  \
    StgOpenPropStg, <.pUnk, .fmtid, .grfFlags, .dwReserved, .ppPropStg>,  'StgOpenPropStg',  \
    StgOpenStorage, <.pwcsName, .pstgPriority, .grfMode, .snbExclude, .reserved, .ppstgOpen>,  'StgOpenStorage',  \
    StgOpenStorageEx, <.pwcsName, .grfMode, .stgfmt, .grfAttrs, .pStgOptions, .reserved, .riid, .ppObjectOpen>,  'StgOpenStorageEx',  \
    StgOpenStorageOnHandle, <NONE>,  'StgOpenStorageOnHandle',  \
    StgOpenStorageOnILockBytes, <.plkbyt, .pstgPriority, .grfMode, .snbExclude, .reserved, .ppstgOpen>,  'StgOpenStorageOnILockBytes',  \
    StgPropertyLengthAsVariant, <NONE>,  'StgPropertyLengthAsVariant',  \
    StgSetTimes, <.lpszName, .pctime, .patime, .pmtime>,  'StgSetTimes',  \
    StringFromCLSID, <.rclsid, .lplpsz>,  'StringFromCLSID',  \
    StringFromGUID2, <.rguid, .lpsz, .cchMax>,  'StringFromGUID2',  \
    StringFromIID, <.rclsid, .lplpsz>,  'StringFromIID',  \
    UpdateDCOMSettings, <NONE>,  'UpdateDCOMSettings',  \
    UtConvertDvtd16toDvtd32, <NONE>,  'UtConvertDvtd16toDvtd32',  \
    UtConvertDvtd32toDvtd16, <NONE>,  'UtConvertDvtd32toDvtd16',  \
    UtGetDvtd16Info, <NONE>,  'UtGetDvtd16Info',  \
    UtGetDvtd32Info, <NONE>,  'UtGetDvtd32Info',  \
    WdtpInterfacePointer_UserFree, <NONE>,  'WdtpInterfacePointer_UserFree',  \
    WdtpInterfacePointer_UserMarshal, <NONE>,  'WdtpInterfacePointer_UserMarshal',  \
    WdtpInterfacePointer_UserSize, <NONE>,  'WdtpInterfacePointer_UserSize',  \
    WdtpInterfacePointer_UserUnmarshal, <NONE>,  'WdtpInterfacePointer_UserUnmarshal',  \
    WriteClassStg, <.pStg, .rclsid>,  'WriteClassStg',  \
    WriteClassStm, <.pStm, .rclsid>,  'WriteClassStm',  \
    WriteFmtUserTypeStg, <.pstg, .cf, .lpszUserType>,  'WriteFmtUserTypeStg',  \
    WriteOleStg, <NONE>,  'WriteOleStg',  \
    WriteStringStream, <NONE>,  'WriteStringStream'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/imports/Win32/shell32.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: shell32.dll API calls
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


import_proto shell32,  \
    Activate_RunDLL, <NONE>,  'Activate_RunDLL',  \
    AppCompat_RunDLLW, <NONE>,  'AppCompat_RunDLLW',  \
    CDefFolderMenu_Create, <NONE>,  'CDefFolderMenu_Create',  \
    CDefFolderMenu_Create2, <NONE>,  'CDefFolderMenu_Create2',  \
    CallCPLEntry16, <NONE>,  'CallCPLEntry16',  \
    CheckEscapesA, <NONE>,  'CheckEscapesA',  \
    CheckEscapesW, <NONE>,  'CheckEscapesW',  \
    CommandLineToArgvW, <.lpCmdLine, .pNumArgs>,  'CommandLineToArgvW',  \
    Control_FillCache_RunDLL, <NONE>,  'Control_FillCache_RunDLL',  \
    Control_FillCache_RunDLLA, <NONE>,  'Control_FillCache_RunDLLA',  \
    Control_FillCache_RunDLLW, <NONE>,  'Control_FillCache_RunDLLW',  \
    Control_RunDLL, <NONE>,  'Control_RunDLL',  \
    Control_RunDLLA, <NONE>,  'Control_RunDLLA',  \
    Control_RunDLLAsUserW, <NONE>,  'Control_RunDLLAsUserW',  \
    Control_RunDLLW, <NONE>,  'Control_RunDLLW',  \
    DAD_AutoScroll, <NONE>,  'DAD_AutoScroll',  \
    DAD_DragEnterEx, <NONE>,  'DAD_DragEnterEx',  \
    DAD_DragEnterEx2, <NONE>,  'DAD_DragEnterEx2',  \
    DAD_DragLeave, <NONE>,  'DAD_DragLeave',  \
    DAD_DragMove, <NONE>,  'DAD_DragMove',  \
    DAD_SetDragImage, <NONE>,  'DAD_SetDragImage',  \
    DAD_ShowDragImage, <NONE>,  'DAD_ShowDragImage',  \
    DoEnvironmentSubstA, <.szString, .cbString>,  'DoEnvironmentSubstA',  \
    DoEnvironmentSubstW, <.szString, .cbString>,  'DoEnvironmentSubstW',  \
    DragAcceptFiles, <.hwnd, .fAccept>,  'DragAcceptFiles',  \
    DragFinish, <.hDrop>,  'DragFinish',  \
    DragQueryFile, <.HDROP, .UINT, .lpStr, .ch>,  'DragQueryFile',  \
    DragQueryFileA, <.HDROP, .UINT, .lpStr, .ch>,  'DragQueryFileA',  \
    DragQueryFileAorW, <NONE>,  'DragQueryFileAorW',  \
    DragQueryFileW, <.HDROP, .UINT, .lpStr, .ch>,  'DragQueryFileW',  \
    DragQueryPoint, <.HDROP, .lpPoint>,  'DragQueryPoint',  \
    DriveType, <NONE>,  'DriveType',  \
    DuplicateIcon, <.hInst, .hIcon>,  'DuplicateIcon',  \
    ExtractAssociatedIconA, <.hInst, .lpIconPath, .lpiIcon>,  'ExtractAssociatedIconA',  \
    ExtractAssociatedIconExA, <NONE>,  'ExtractAssociatedIconExA',  \
    ExtractAssociatedIconExW, <NONE>,  'ExtractAssociatedIconExW',  \
    ExtractAssociatedIconW, <.hInst, .lpIconPath, .lpiIcon>,  'ExtractAssociatedIconW',  \
    ExtractIconA, <.hInst, .lpszExeFileName, .nIconIndex>,  'ExtractIconA',  \
    ExtractIconEx, <.lpszFile, .nIconIndex, .phiconLarge, .phiconSmall, .nIcons>,  'ExtractIconEx',  \
    ExtractIconExA, <.lpszFile, .nIconIndex, .phiconLarge, .phiconSmall, .nIcons>,  'ExtractIconExA',  \
    ExtractIconExW, <.lpszFile, .nIconIndex, .phiconLarge, .phiconSmall, .nIcons>,  'ExtractIconExW',  \
    ExtractIconResInfoA, <NONE>,  'ExtractIconResInfoA',  \
    ExtractIconResInfoW, <NONE>,  'ExtractIconResInfoW',  \
    ExtractIconW, <.hInst, .lpszExeFileName, .nIconIndex>,  'ExtractIconW',  \
    ExtractVersionResource16W, <NONE>,  'ExtractVersionResource16W',  \
    FindExeDlgProc, <NONE>,  'FindExeDlgProc',  \
    FindExecutableA, <.lpFile, .lpDirectory, .lpResult>,  'FindExecutableA',  \
    FindExecutableW, <.lpFile, .lpDirectory, .lpResult>,  'FindExecutableW',  \
    FreeIconList, <NONE>,  'FreeIconList',  \
    GetFileNameFromBrowse, <NONE>,  'GetFileNameFromBrowse',  \
    ILAppendID, <NONE>,  'ILAppendID',  \
    ILClone, <NONE>,  'ILClone',  \
    ILCloneFirst, <NONE>,  'ILCloneFirst',  \
    ILCombine, <NONE>,  'ILCombine',  \
    ILCreateFromPath, <NONE>,  'ILCreateFromPath',  \
    ILCreateFromPathA, <NONE>,  'ILCreateFromPathA',  \
    ILCreateFromPathW, <NONE>,  'ILCreateFromPathW',  \
    ILFindChild, <NONE>,  'ILFindChild',  \
    ILFindLastID, <NONE>,  'ILFindLastID',  \
    ILFree, <NONE>,  'ILFree',  \
    ILGetNext, <NONE>,  'ILGetNext',  \
    ILGetSize, <NONE>,  'ILGetSize',  \
    ILIsEqual, <NONE>,  'ILIsEqual',  \
    ILIsParent, <NONE>,  'ILIsParent',  \
    ILLoadFromStream, <NONE>,  'ILLoadFromStream',  \
    ILRemoveLastID, <NONE>,  'ILRemoveLastID',  \
    ILSaveToStream, <NONE>,  'ILSaveToStream',  \
    InternalExtractIconListA, <NONE>,  'InternalExtractIconListA',  \
    InternalExtractIconListW, <NONE>,  'InternalExtractIconListW',  \
    IsLFNDrive, <NONE>,  'IsLFNDrive',  \
    IsLFNDriveA, <NONE>,  'IsLFNDriveA',  \
    IsLFNDriveW, <NONE>,  'IsLFNDriveW',  \
    IsNetDrive, <NONE>,  'IsNetDrive',  \
    IsUserAnAdmin, <NONE>,  'IsUserAnAdmin',  \
    OpenAs_RunDLL, <NONE>,  'OpenAs_RunDLL',  \
    OpenAs_RunDLLA, <NONE>,  'OpenAs_RunDLLA',  \
    OpenAs_RunDLLW, <NONE>,  'OpenAs_RunDLLW',  \
    OpenRegStream, <NONE>,  'OpenRegStream',  \
    Options_RunDLL, <NONE>,  'Options_RunDLL',  \
    Options_RunDLLA, <NONE>,  'Options_RunDLLA',  \
    Options_RunDLLW, <NONE>,  'Options_RunDLLW',  \
    PathCleanupSpec, <NONE>,  'PathCleanupSpec',  \
    PathGetShortPath, <NONE>,  'PathGetShortPath',  \
    PathIsExe, <NONE>,  'PathIsExe',  \
    PathIsSlowA, <NONE>,  'PathIsSlowA',  \
    PathIsSlowW, <NONE>,  'PathIsSlowW',  \
    PathMakeUniqueName, <NONE>,  'PathMakeUniqueName',  \
    PathProcessCommand, <NONE>,  'PathProcessCommand',  \
    PathQualify, <NONE>,  'PathQualify',  \
    PathResolve, <NONE>,  'PathResolve',  \
    PathYetAnotherMakeUniqueName, <NONE>,  'PathYetAnotherMakeUniqueName',  \
    PickIconDlg, <NONE>,  'PickIconDlg',  \
    PifMgr_CloseProperties, <NONE>,  'PifMgr_CloseProperties',  \
    PifMgr_GetProperties, <NONE>,  'PifMgr_GetProperties',  \
    PifMgr_OpenProperties, <NONE>,  'PifMgr_OpenProperties',  \
    PifMgr_SetProperties, <NONE>,  'PifMgr_SetProperties',  \
    PrintersGetCommand_RunDLL, <NONE>,  'PrintersGetCommand_RunDLL',  \
    PrintersGetCommand_RunDLLA, <NONE>,  'PrintersGetCommand_RunDLLA',  \
    PrintersGetCommand_RunDLLW, <NONE>,  'PrintersGetCommand_RunDLLW',  \
    ReadCabinetState, <NONE>,  'ReadCabinetState',  \
    RealDriveType, <NONE>,  'RealDriveType',  \
    RealShellExecuteA, <NONE>,  'RealShellExecuteA',  \
    RealShellExecuteExA, <NONE>,  'RealShellExecuteExA',  \
    RealShellExecuteExW, <NONE>,  'RealShellExecuteExW',  \
    RealShellExecuteW, <NONE>,  'RealShellExecuteW',  \
    RegenerateUserEnvironment, <NONE>,  'RegenerateUserEnvironment',  \
    RestartDialog, <NONE>,  'RestartDialog',  \
    RestartDialogEx, <NONE>,  'RestartDialogEx',  \
    SHAddFromPropSheetExtArray, <NONE>,  'SHAddFromPropSheetExtArray',  \
    SHAddToRecentDocs, <.uFlags, .pv>,  'SHAddToRecentDocs',  \
    SHAlloc, <NONE>,  'SHAlloc',  \
    SHAllocShared, <NONE>,  'SHAllocShared',  \
    SHAppBarMessage, <.dwMessage, .pData>,  'SHAppBarMessage',  \
    SHBindToParent, <.pidl, .riid, .ppv, .ppidlLast>,  'SHBindToParent',  \
    SHBrowseForFolder, <.lpbi>,  'SHBrowseForFolder',  \
    SHBrowseForFolderA, <.lpbi>,  'SHBrowseForFolderA',  \
    SHBrowseForFolderW, <.lpbi>,  'SHBrowseForFolderW',  \
    SHCLSIDFromString, <NONE>,  'SHCLSIDFromString',  \
    SHChangeNotification_Lock, <NONE>,  'SHChangeNotification_Lock',  \
    SHChangeNotification_Unlock, <NONE>,  'SHChangeNotification_Unlock',  \
    SHChangeNotify, <.wEventId, .uFlags, .dwItem1, .dwItem2>,  'SHChangeNotify',  \
    SHChangeNotifyDeregister, <NONE>,  'SHChangeNotifyDeregister',  \
    SHChangeNotifyRegister, <NONE>,  'SHChangeNotifyRegister',  \
    SHChangeNotifySuspendResume, <NONE>,  'SHChangeNotifySuspendResume',  \
    SHCloneSpecialIDList, <NONE>,  'SHCloneSpecialIDList',  \
    SHCoCreateInstance, <NONE>,  'SHCoCreateInstance',  \
    SHCreateDirectory, <NONE>,  'SHCreateDirectory',  \
    SHCreateDirectoryExA, <.hwnd, .pszPath, .psa>,  'SHCreateDirectoryExA',  \
    SHCreateDirectoryExW, <.hwnd, .pszPath, .psa>,  'SHCreateDirectoryExW',  \
    SHCreateFileExtractIconW, <NONE>,  'SHCreateFileExtractIconW',  \
    SHCreateLocalServerRunDll, <NONE>,  'SHCreateLocalServerRunDll',  \
    SHCreateProcessAsUserW, <NONE>,  'SHCreateProcessAsUserW',  \
    SHCreatePropSheetExtArray, <NONE>,  'SHCreatePropSheetExtArray',  \
    SHCreateQueryCancelAutoPlayMoniker, <NONE>,  'SHCreateQueryCancelAutoPlayMoniker',  \
    SHCreateShellFolderView, <NONE>,  'SHCreateShellFolderView',  \
    SHCreateShellFolderViewEx, <NONE>,  'SHCreateShellFolderViewEx',  \
    SHCreateShellItem, <NONE>,  'SHCreateShellItem',  \
    SHCreateStdEnumFmtEtc, <NONE>,  'SHCreateStdEnumFmtEtc',  \
    SHDefExtractIconA, <NONE>,  'SHDefExtractIconA',  \
    SHDefExtractIconW, <NONE>,  'SHDefExtractIconW',  \
    SHDestroyPropSheetExtArray, <NONE>,  'SHDestroyPropSheetExtArray',  \
    SHDoDragDrop, <NONE>,  'SHDoDragDrop',  \
    SHEmptyRecycleBinA, <.hwnd, .pszRootPath, .dwFlags>,  'SHEmptyRecycleBinA',  \
    SHEmptyRecycleBinW, <.hwnd, .pszRootPath, .dwFlags>,  'SHEmptyRecycleBinW',  \
    SHEnableServiceObject, <NONE>,  'SHEnableServiceObject',  \
    SHEnumerateUnreadMailAccountsW, <NONE>,  'SHEnumerateUnreadMailAccountsW',  \
    SHExtractIconsW, <NONE>,  'SHExtractIconsW',  \
    SHFileOperation, <.lpFileOp>,  'SHFileOperation',  \
    SHFileOperationA, <.lpFileOp>,  'SHFileOperationA',  \
    SHFileOperationW, <.lpFileOp>,  'SHFileOperationW',  \
    SHFindFiles, <NONE>,  'SHFindFiles',  \
    SHFind_InitMenuPopup, <NONE>,  'SHFind_InitMenuPopup',  \
    SHFlushClipboard, <NONE>,  'SHFlushClipboard',  \
    SHFlushSFCache, <NONE>,  'SHFlushSFCache',  \
    SHFormatDrive, <NONE>,  'SHFormatDrive',  \
    SHFree, <NONE>,  'SHFree',  \
    SHFreeNameMappings, <.hNameMappings>,  'SHFreeNameMappings',  \
    SHFreeShared, <NONE>,  'SHFreeShared',  \
    SHGetAttributesFromDataObject, <NONE>,  'SHGetAttributesFromDataObject',  \
    SHGetDataFromIDListA, <.psf, .pidl, .nFormat, .pv, .cb>,  'SHGetDataFromIDListA',  \
    SHGetDataFromIDListW, <.psf, .pidl, .nFormat, .pv, .cb>,  'SHGetDataFromIDListW',  \
    SHGetDesktopFolder, <.ppshf>,  'SHGetDesktopFolder',  \
    SHGetDiskFreeSpaceA, <NONE>,  'SHGetDiskFreeSpaceA',  \
    SHGetDiskFreeSpaceExA, <.pszDirectoryName, .pulFreeBytesAvailableToCaller, .pulTotalNumberOfBytes, .pulTotalNumberOfFreeBytes,  \
      >,  'SHGetDiskFreeSpaceExA',  \
    SHGetDiskFreeSpaceExW, <.pszDirectoryName, .pulFreeBytesAvailableToCaller, .pulTotalNumberOfBytes, .pulTotalNumberOfFreeBytes,  \
      >,  'SHGetDiskFreeSpaceExW',  \
    SHGetFileInfo, <.pszPath, .dwFileAttributes, .psfi, .cbFileInfo, .uFlags>,  'SHGetFileInfo',  \
    SHGetFileInfoA, <.pszPath, .dwFileAttributes, .psfi, .cbFileInfo, .uFlags>,  'SHGetFileInfoA',  \
    SHGetFileInfoW, <.pszPath, .dwFileAttributes, .psfi, .cbFileInfo, .uFlags>,  'SHGetFileInfoW',  \
    SHGetFolderLocation, <.hwnd, .csidl, .hToken, .dwFlags, .ppidl>,  'SHGetFolderLocation',  \
    SHGetFolderPathA, <.hwnd, .csidl, .hToken, .dwFlags, .pszPath>,  'SHGetFolderPathA',  \
    SHGetFolderPathAndSubDirA, <NONE>,  'SHGetFolderPathAndSubDirA',  \
    SHGetFolderPathAndSubDirW, <NONE>,  'SHGetFolderPathAndSubDirW',  \
    SHGetFolderPathW, <.hwnd, .csidl, .hToken, .dwFlags, .pszPath>,  'SHGetFolderPathW',  \
    SHGetIconOverlayIndexA, <.pszIconPath, .iIconIndex>,  'SHGetIconOverlayIndexA',  \
    SHGetIconOverlayIndexW, <.pszIconPath, .iIconIndex>,  'SHGetIconOverlayIndexW',  \
    SHGetImageList, <NONE>,  'SHGetImageList',  \
    SHGetInstanceExplorer, <.ppunk>,  'SHGetInstanceExplorer',  \
    SHGetMalloc, <.ppMalloc>,  'SHGetMalloc',  \
    SHGetNewLinkInfo, <.pszLinkto, .pszDir, .pszName, .pfMustCopy, .uFlags>,  'SHGetNewLinkInfo',  \
    SHGetNewLinkInfoA, <.pszLinkto, .pszDir, .pszName, .pfMustCopy, .uFlags>,  'SHGetNewLinkInfoA',  \
    SHGetNewLinkInfoW, <.pszLinkto, .pszDir, .pszName, .pfMustCopy, .uFlags>,  'SHGetNewLinkInfoW',  \
    SHGetPathFromIDList, <.pidl, .pszPath>,  'SHGetPathFromIDList',  \
    SHGetPathFromIDListA, <.pidl, .pszPath>,  'SHGetPathFromIDListA',  \
    SHGetPathFromIDListW, <.pidl, .pszPath>,  'SHGetPathFromIDListW',  \
    SHGetRealIDL, <NONE>,  'SHGetRealIDL',  \
    SHGetSetFolderCustomSettingsW, <NONE>,  'SHGetSetFolderCustomSettingsW',  \
    SHGetSetSettings, <NONE>,  'SHGetSetSettings',  \
    SHGetSettings, <.lpsfs, .dwMask>,  'SHGetSettings',  \
    SHGetShellStyleHInstance, <NONE>,  'SHGetShellStyleHInstance',  \
    SHGetSpecialFolderLocation, <.hwnd, .csidl, .ppidl>,  'SHGetSpecialFolderLocation',  \
    SHGetSpecialFolderPathA, <.hwnd, .pszPath, .csidl, .fCreate>,  'SHGetSpecialFolderPathA',  \
    SHGetSpecialFolderPathW, <.hwnd, .pszPath, .csidl, .fCreate>,  'SHGetSpecialFolderPathW',  \
    SHGetUnreadMailCountW, <NONE>,  'SHGetUnreadMailCountW',  \
    SHHandleUpdateImage, <NONE>,  'SHHandleUpdateImage',  \
    SHHelpShortcuts_RunDLL, <NONE>,  'SHHelpShortcuts_RunDLL',  \
    SHHelpShortcuts_RunDLLA, <NONE>,  'SHHelpShortcuts_RunDLLA',  \
    SHHelpShortcuts_RunDLLW, <NONE>,  'SHHelpShortcuts_RunDLLW',  \
    SHILCreateFromPath, <NONE>,  'SHILCreateFromPath',  \
    SHInvokePrinterCommandA, <.hwnd, .uAction, .lpBuf1, .lpBuf2, .fModal>,  'SHInvokePrinterCommandA',  \
    SHInvokePrinterCommandW, <.hwnd, .uAction, .lpBuf1, .lpBuf2, .fModal>,  'SHInvokePrinterCommandW',  \
    SHIsFileAvailableOffline, <.pwszPath, .pdwStatus>,  'SHIsFileAvailableOffline',  \
    SHLimitInputEdit, <NONE>,  'SHLimitInputEdit',  \
    SHLoadInProc, <.rclsid>,  'SHLoadInProc',  \
    SHLoadNonloadedIconOverlayIdentifiers, <VOID>,  'SHLoadNonloadedIconOverlayIdentifiers',  \
    SHLoadOLE, <NONE>,  'SHLoadOLE',  \
    SHLockShared, <NONE>,  'SHLockShared',  \
    SHMapIDListToImageListIndexAsync, <NONE>,  'SHMapIDListToImageListIndexAsync',  \
    SHMapPIDLToSystemImageListIndex, <NONE>,  'SHMapPIDLToSystemImageListIndex',  \
    SHMultiFileProperties, <NONE>,  'SHMultiFileProperties',  \
    SHObjectProperties, <NONE>,  'SHObjectProperties',  \
    SHOpenFolderAndSelectItems, <NONE>,  'SHOpenFolderAndSelectItems',  \
    SHOpenPropSheetW, <NONE>,  'SHOpenPropSheetW',  \
    SHParseDisplayName, <NONE>,  'SHParseDisplayName',  \
    SHPathPrepareForWriteA, <.hwnd, .punkEnableModless, .pszPath, .dwFlags>,  'SHPathPrepareForWriteA',  \
    SHPathPrepareForWriteW, <.hwnd, .punkEnableModless, .pszPath, .dwFlags>,  'SHPathPrepareForWriteW',  \
    SHPropStgCreate, <NONE>,  'SHPropStgCreate',  \
    SHPropStgReadMultiple, <NONE>,  'SHPropStgReadMultiple',  \
    SHPropStgWriteMultiple, <NONE>,  'SHPropStgWriteMultiple',  \
    SHQueryRecycleBinA, <.pszRootPath, .pSHQueryRBInfo>,  'SHQueryRecycleBinA',  \
    SHQueryRecycleBinW, <.pszRootPath, .pSHQueryRBInfo>,  'SHQueryRecycleBinW',  \
    SHReplaceFromPropSheetExtArray, <NONE>,  'SHReplaceFromPropSheetExtArray',  \
    SHRestricted, <NONE>,  'SHRestricted',  \
    SHRunControlPanel, <NONE>,  'SHRunControlPanel',  \
    SHSetInstanceExplorer, <NONE>,  'SHSetInstanceExplorer',  \
    SHSetLocalizedName, <NONE>,  'SHSetLocalizedName',  \
    SHSetUnreadMailCountW, <NONE>,  'SHSetUnreadMailCountW',  \
    SHShellFolderView_Message, <NONE>,  'SHShellFolderView_Message',  \
    SHSimpleIDListFromPath, <NONE>,  'SHSimpleIDListFromPath',  \
    SHStartNetConnectionDialogW, <NONE>,  'SHStartNetConnectionDialogW',  \
    SHTestTokenMembership, <NONE>,  'SHTestTokenMembership',  \
    SHUnlockShared, <NONE>,  'SHUnlockShared',  \
    SHUpdateImageA, <NONE>,  'SHUpdateImageA',  \
    SHUpdateImageW, <NONE>,  'SHUpdateImageW',  \
    SHUpdateRecycleBinIcon, <NONE>,  'SHUpdateRecycleBinIcon',  \
    SHValidateUNC, <NONE>,  'SHValidateUNC',  \
    SheChangeDirA, <NONE>,  'SheChangeDirA',  \
    SheChangeDirExA, <NONE>,  'SheChangeDirExA',  \
    SheChangeDirExW, <NONE>,  'SheChangeDirExW',  \
    SheChangeDirW, <NONE>,  'SheChangeDirW',  \
    SheConvertPathW, <NONE>,  'SheConvertPathW',  \
    SheFullPathA, <NONE>,  'SheFullPathA',  \
    SheFullPathW, <NONE>,  'SheFullPathW',  \
    SheGetCurDrive, <NONE>,  'SheGetCurDrive',  \
    SheGetDirA, <NONE>,  'SheGetDirA',  \
    SheGetDirExW, <NONE>,  'SheGetDirExW',  \
    SheGetDirW, <NONE>,  'SheGetDirW',  \
    SheGetPathOffsetW, <NONE>,  'SheGetPathOffsetW',  \
    SheRemoveQuotesA, <NONE>,  'SheRemoveQuotesA',  \
    SheRemoveQuotesW, <NONE>,  'SheRemoveQuotesW',  \
    SheSetCurDrive, <NONE>,  'SheSetCurDrive',  \
    SheShortenPathA, <NONE>,  'SheShortenPathA',  \
    SheShortenPathW, <NONE>,  'SheShortenPathW',  \
    ShellAboutA, <.hwnd, .szApp, .szOtherStuff, .hIcon>,  'ShellAboutA',  \
    ShellAboutW, <.hwnd, .szApp, .szOtherStuff, .hIcon>,  'ShellAboutW',  \
    ShellExec_RunDLL, <NONE>,  'ShellExec_RunDLL',  \
    ShellExec_RunDLLA, <NONE>,  'ShellExec_RunDLLA',  \
    ShellExec_RunDLLW, <NONE>,  'ShellExec_RunDLLW',  \
    ShellExecuteA, <.hwnd, .lpOperation, .lpFile, .lpParameters, .lpDirectory, .nCmdShow>,  'ShellExecuteA',  \
    ShellExecuteEx, <.lpExecInfo>,  'ShellExecuteEx',  \
    ShellExecuteExA, <.lpExecInfo>,  'ShellExecuteExA',  \
    ShellExecuteExW, <.lpExecInfo>,  'ShellExecuteExW',  \
    ShellExecuteW, <.hwnd, .lpOperation, .lpFile, .lpParameters, .lpDirectory, .nCmdShow>,  'ShellExecuteW',  \
    ShellHookProc, <NONE>,  'ShellHookProc',  \
    ShellMessageBoxA, <NONE>,  'ShellMessageBoxA',  \
    ShellMessageBoxW, <NONE>,  'ShellMessageBoxW',  \
    Shell_GetCachedImageIndex, <NONE>,  'Shell_GetCachedImageIndex',  \
    Shell_GetImageLists, <NONE>,  'Shell_GetImageLists',  \
    Shell_MergeMenus, <NONE>,  'Shell_MergeMenus',  \
    Shell_NotifyIcon, <.dwMessage, .lpData>,  'Shell_NotifyIcon',  \
    Shell_NotifyIconA, <.dwMessage, .lpData>,  'Shell_NotifyIconA',  \
    Shell_NotifyIconW, <.dwMessage, .lpData>,  'Shell_NotifyIconW',  \
    SignalFileOpen, <NONE>,  'SignalFileOpen',  \
    StrChrA, <.lpStart, .wMatch>,  'StrChrA',  \
    StrChrIA, <.lpStart, .wMatch>,  'StrChrIA',  \
    StrChrIW, <.lpStart, .wMatch>,  'StrChrIW',  \
    StrChrW, <.lpStart, .wMatch>,  'StrChrW',  \
    StrCmpNA, <.lpStr1, .lpStr2, .nChar>,  'StrCmpNA',  \
    StrCmpNIA, <.lpStr1, .lpStr2, .nChar>,  'StrCmpNIA',  \
    StrCmpNIW, <.lpStr1, .lpStr2, .nChar>,  'StrCmpNIW',  \
    StrCmpNW, <.lpStr1, .lpStr2, .nChar>,  'StrCmpNW',  \
    StrCpyNA, <NONE>,  'StrCpyNA',  \
    StrCpyNW, <NONE>,  'StrCpyNW',  \
    StrNCmpA, <NONE>,  'StrNCmpA',  \
    StrNCmpIA, <NONE>,  'StrNCmpIA',  \
    StrNCmpIW, <NONE>,  'StrNCmpIW',  \
    StrNCmpW, <NONE>,  'StrNCmpW',  \
    StrNCpyA, <NONE>,  'StrNCpyA',  \
    StrNCpyW, <NONE>,  'StrNCpyW',  \
    StrRChrA, <.lpStart, .lpEnd, .wMatch>,  'StrRChrA',  \
    StrRChrIA, <.lpStart, .lpEnd, .wMatch>,  'StrRChrIA',  \
    StrRChrIW, <.lpStart, .lpEnd, .wMatch>,  'StrRChrIW',  \
    StrRChrW, <.lpStart, .lpEnd, .wMatch>,  'StrRChrW',  \
    StrRStrA, <NONE>,  'StrRStrA',  \
    StrRStrIA, <.lpSource, .lpLast, .lpSrch>,  'StrRStrIA',  \
    StrRStrIW, <.lpSource, .lpLast, .lpSrch>,  'StrRStrIW',  \
    StrRStrW, <NONE>,  'StrRStrW',  \
    StrStrA, <.lpFirst, .lpSrch>,  'StrStrA',  \
    StrStrIA, <.lpFirst, .lpSrch>,  'StrStrIA',  \
    StrStrIW, <.lpFirst, .lpSrch>,  'StrStrIW',  \
    StrStrW, <.lpFirst, .lpSrch>,  'StrStrW',  \
    WOWShellExecute, <NONE>,  'WOWShellExecute',  \
    Win32DeleteFile, <NONE>,  'Win32DeleteFile',  \
    WriteCabinetState, <NONE>,  'WriteCabinetState'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































































































































Deleted freshlib/imports/Win32/sqlite3.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: sqlite3.dll API calls
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


import_proto sqlite3,  \
    sqliteAggregateContext, <.context, .nbytes>,  'sqlite3_aggregate_context',  \
    sqliteAggregateCount_OLD, <VOID>,  'sqlite3_aggregate_count',  \
    sqliteAutoExtension, <.ptrCallback>,  'sqlite3_auto_extension',  \
    sqliteBackupFinish, <.ptrBackup>,  'sqlite3_backup_finish',  \
    sqliteBackupInit, <.ptrDestDB, .ptrDestName, .ptrSourceDB, .ptrSourceName>,  'sqlite3_backup_init',  \
    sqliteBackupPageCount, <.ptrBackup>,  'sqlite3_backup_pagecount',  \
    sqliteBackupRemaining, <.ptrBackup>,  'sqlite3_backup_remaining',  \
    sqliteBackupStep, <.ptrBackup, .nPage>,  'sqlite3_backup_step',  \
    sqliteBindBlob, <.stmt, .index, .ptrData, .nbytes, .destructor>,  'sqlite3_bind_blob',  \
    sqliteBindDouble, <.stmt, .index, .value>,  'sqlite3_bind_double',  \
    sqliteBindInt, <.stmt, .index, .value>,  'sqlite3_bind_int',  \
    sqliteBindInt64, <.stmt, .index, .valueLo, .valueHi>,  'sqlite3_bind_int64',  \
    sqliteBindNull, <.stmt, .index>,  'sqlite3_bind_null',  \
    sqliteBindParameterCount, <.stmt>,  'sqlite3_bind_parameter_count',  \
    sqliteBindParameterIndex, <.stmt, .paramName>,  'sqlite3_bind_parameter_index',  \
    sqliteBindParameterName, <.stmt, .paramIndex>,  'sqlite3_bind_parameter_name',  \
    sqliteBindText, <.stmt, .index, .ptrText, .nbytes, .destructor>,  'sqlite3_bind_text',  \
    sqliteBindText16, <.stmt, .index, .ptrText, .nbytes, .destructor>,  'sqlite3_bind_text16',  \
    sqliteBindValue, <.stmt, .index, .ptrValue>,  'sqlite3_bind_value',  \
    sqliteBindZeroblob, <.stmt, .index, .size>,  'sqlite3_bind_zeroblob',  \
    sqliteBlobBytes, <.hBlob>,  'sqlite3_blob_bytes',  \
    sqliteBlobClose, <.hBlob>,  'sqlite3_blob_close',  \
    sqliteBlobOpen, <.ptrDB, .DBname, .Table, .Column, .iRow, .flags, .ptrVarBlob>,  'sqlite3_blob_open',  \
    sqliteBlobRead, <.hBlob, .ptrBuffer, .bytes, .iOffset>,  'sqlite3_blob_read',  \
    sqliteBlobWrite, <.hBlob, .ptrBuffer, .bytes, .iOffset>,  'sqlite3_blob_write',  \
    sqliteBusyHandler, <.ptrDB, .ptrProc, .lParam>,  'sqlite3_busy_handler',  \
    sqliteBusyTimeout, <.ptrDB, .time_ms>,  'sqlite3_busy_timeout',  \
    sqliteChanges, <.ptrDB>,  'sqlite3_changes',  \
    sqliteClearBindings, <.stmt>,  'sqlite3_clear_bindings',  \
    sqliteClose, <.ptrDatabase>,  'sqlite3_close',  \
    sqliteCollationNeeded, <.ptrDB, .lparam, .ptrCallback>,  'sqlite3_collation_needed',  \
    sqliteCollationNeeded16, <.ptrDB, .lparam, .ptrCallback>,  'sqlite3_collation_needed16',  \
    sqliteColumnBlob, <.stmt, .iCol>,  'sqlite3_column_blob',  \
    sqliteColumnBytes, <.stmt, .iCol>,  'sqlite3_column_bytes',  \
    sqliteColumnBytes16, <.stmt, .iCol>,  'sqlite3_column_bytes16',  \
    sqliteColumnCount, <.stmt>,  'sqlite3_column_count',  \
    sqliteColumnDatabaseName, <.stmt, .index>,  'sqlite3_column_database_name',  \
    sqliteColumnDatabaseName16, <.stmt, .index>,  'sqlite3_column_database_name16',  \
    sqliteColumnDeclType, <.stmt, .index>,  'sqlite3_column_decltype',  \
    sqliteColumnDeclType16, <.stmt, .index>,  'sqlite3_column_decltype16',  \
    sqliteColumnDouble, <.stmt, .iCol>,  'sqlite3_column_double',  \
    sqliteColumnInt, <.stmt, .iCol>,  'sqlite3_column_int',  \
    sqliteColumnInt64, <.stmt, .iCol>,  'sqlite3_column_int64',  \
    sqliteColumnName, <.stmt, .index>,  'sqlite3_column_name',  \
    sqliteColumnName16, <.stmt, .index>,  'sqlite3_column_name16',  \
    sqliteColumnOriginName, <.stmt, .index>,  'sqlite3_column_origin_name',  \
    sqliteColumnOriginName16, <.stmt, .index>,  'sqlite3_column_origin_name16',  \
    sqliteColumnTableName, <.stmt, .index>,  'sqlite3_column_table_name',  \
    sqliteColumnTableName16, <.stmt, .index>,  'sqlite3_column_table_name16',  \
    sqliteColumnText, <.stmt, .iCol>,  'sqlite3_column_text',  \
    sqliteColumnText16, <.stmt, .iCol>,  'sqlite3_column_text16',  \
    sqliteColumnType, <.stmt, .iCol>,  'sqlite3_column_type',  \
    sqliteColumnValue, <.stmt, .iCol>,  'sqlite3_column_value',  \
    sqliteCommitHook, <.ptrDB, .ptrHook, .lparam>,  'sqlite3_commit_hook',  \
    sqliteCompileOptionGet, <.N>,  'sqlite3_compileoption_get',  \
    sqliteCompileOptionUsed, <.ptrOptName>,  'sqlite3_compileoption_used',  \
    sqliteComplete, <.ptrSQL>,  'sqlite3_complete',  \
    sqliteComplete16, <.ptrSQL>,  'sqlite3_complete16',  \
    sqliteConfig, <.index, ...>,  'sqlite3_config',  \
    sqliteContextDBHandle, <.context>,  'sqlite3_context_db_handle',  \
    sqliteCreateCollation, <.ptrDB, .ptrName, .eTextRep, .lparam, .procCompare>,  'sqlite3_create_collation',  \
    sqliteCreateCollation16, <.ptrDB, .ptrName, .eTextRep, .lparam, .procCompare>,  'sqlite3_create_collation16',  \
    sqliteCreateCollation_v2, <.ptrDB, .ptrName, .eTextRep, .lparam, .procCompare, .ptrDestroy>,  'sqlite3_create_collation_v2',  \
    sqliteCreateFunction, <.ptrDB, .ptrFunctionName, .nArg, .eTextRep, .lparam, .procFunc, .procStep, .procFinal>,  'sqlite3_create_function',  \
    sqliteCreateFunction16, <.ptrDB, .ptrFunctionName, .nArg, .eTextRep, .lparam, .procFunc, .procStep, .procFinal>,  'sqlite3_create_function16',  \
    sqliteCreateFunction_v2, <.ptrDB, .ptrFunctionName, .nArg, .eTextRep, .lparam, .procFunc, .procStep, .procFinal, .procDestroy,  \
      >,  'sqlite3_create_function_v2',  \
    sqliteCreateModule, <.ptrDB, .ptrModuleName, .ptrVTableModule, .lparam>,  'sqlite3_create_module',  \
    sqliteCreateModule_v2, <.ptrDB, .ptrModuleName, .ptrVTableModule, .lparam, .procDestroy>,  'sqlite3_create_module_v2',  \
    sqliteDBConfig, <.ptrDB, .index, ...>,  'sqlite3_db_config',  \
    sqliteDBHandle, <.stmt>,  'sqlite3_db_handle',  \
    sqliteDBMutex, <.ptrDB>,  'sqlite3_db_mutex',  \
    sqliteDBStatus, <.ptrDB, .index, .ptrRetCurrent, .ptrRetHighest, .flagReset>,  'sqlite3_db_status',  \
    sqliteDataCount, <.stmt>,  'sqlite3_data_count',  \
    sqliteDeclareVtab, <.ptrDB, .ptrSQL>,  'sqlite3_declare_vtab',  \
    sqliteEnableLoadExtension, <.ptrDB, .flagEnable>,  'sqlite3_enable_load_extension',  \
    sqliteEnableSharedCache, <.flagEnable>,  'sqlite3_enable_shared_cache',  \
    sqliteErrCode, <.ptrDB>,  'sqlite3_errcode',  \
    sqliteErrMsg, <.ptrDB>,  'sqlite3_errmsg',  \
    sqliteErrMsg16, <.ptrDB>,  'sqlite3_errmsg16',  \
    sqliteExec, <.ptrDB, .ptrSQL, .procCallback, .lparam, .ptrVarErrMsg>,  'sqlite3_exec',  \
    sqliteExpired, <VOID>,  'sqlite3_expired',  \
    sqliteExtendedErrCode, <.ptrDB>,  'sqlite3_extended_errcode',  \
    sqliteExtendedResultCodes, <.ptrDB, .flagEnable>,  'sqlite3_extended_result_codes',  \
    sqliteFileControl, <.ptrDB, .ptrDBName, .wparam, .lparam>,  'sqlite3_file_control',  \
    sqliteFinalize, <.stmt>,  'sqlite3_finalize',  \
    sqliteFree, <.ptrmem>,  'sqlite3_free',  \
    sqliteFreeTable, <.ptrVarResult>,  'sqlite3_free_table',  \
    sqliteGetAutocommit, <.ptrDB>,  'sqlite3_get_autocommit',  \
    sqliteGetAuxdata, <.context, .N>,  'sqlite3_get_auxdata',  \
    sqliteGetTable, <.ptrDB, .ptrSQL, .ptrVarResult, .ptrVarRows, .ptrVarColumns, .ptrVarErrorMsg>,  'sqlite3_get_table',  \
    sqliteGlobalRecover_OLD, <VOID>,  'sqlite3_global_recover',  \
    sqliteInitialize, <VOID>,  'sqlite3_initialize',  \
    sqliteInterrupt, <.ptrDB>,  'sqlite3_interrupt',  \
    sqliteLastInsertRowID, <.ptrDB>,  'sqlite3_last_insert_rowid',  \
    sqliteLibVersion, <VOID>,  'sqlite3_libversion',  \
    sqliteLibversionNumber, <VOID>,  'sqlite3_libversion_number',  \
    sqliteLimit, <.ptrDB, .idLimit, .newVal>,  'sqlite3_limit',  \
    sqliteLoadExtension, <.ptrDB, .nameDLL, .entryProc, .ptrVarErrMsg>,  'sqlite3_load_extension',  \
    sqliteLog, <.iErrCode, .ptrFormat, ...>,  'sqlite3_log',  \
    sqliteMAlloc, <.size>,  'sqlite3_malloc',  \
    sqliteMemoryAlarm_OLD, <VOID>,  'sqlite3_memory_alarm',  \
    sqliteMemoryHighWater, <.flagReset>,  'sqlite3_memory_highwater',  \
    sqliteMemoryUsed, <VOID>,  'sqlite3_memory_used',  \
    sqliteMprintf, <.ptrString, ...>,  'sqlite3_mprintf',  \
    sqliteMutexAlloc, <.type>,  'sqlite3_mutex_alloc',  \
    sqliteMutexEnter, <.hMutex>,  'sqlite3_mutex_enter',  \
    sqliteMutexFree, <.hMutex>,  'sqlite3_mutex_free',  \
    sqliteMutexLeave, <.hMutex>,  'sqlite3_mutex_leave',  \
    sqliteMutexTry, <.hMutex>,  'sqlite3_mutex_try',  \
    sqliteNextStmt, <.ptrDB, .stmt>,  'sqlite3_next_stmt',  \
    sqliteOSEnd, <VOID>,  'sqlite3_os_end',  \
    sqliteOSInit, <VOID>,  'sqlite3_os_init',  \
    sqliteOpen, <.ptrFileName, .ptrVarDB>,  'sqlite3_open',  \
    sqliteOpen16, <.ptrFileName, .ptrVarDB>,  'sqlite3_open16',  \
    sqliteOpen_v2, <.ptrFileName, .ptrVarDB, .flags, .ptrVFSName>,  'sqlite3_open_v2',  \
    sqliteOverloadFunction, <.ptrDB, .ptrFuncName, .lparam>,  'sqlite3_overload_function',  \
    sqlitePrepare, <.ptrDB, .ptrSQL, .lenSQL, .ptrVarStmt, .ptrVarNext>,  'sqlite3_prepare',  \
    sqlitePrepare16, <.ptrDB, .ptrSQL, .lenSQL, .ptrVarStmt, .ptrVarNext>,  'sqlite3_prepare16',  \
    sqlitePrepare16_v2, <.ptrDB, .ptrSQL, .lenSQL, .ptrVarStmt, .ptrVarNext>,  'sqlite3_prepare16_v2',  \
    sqlitePrepare_v2, <.ptrDB, .ptrSQL, .lenSQL, .ptrVarStmt, .ptrVarNext>,  'sqlite3_prepare_v2',  \
    sqliteProfile, <.ptrDB, .procProfiler, .lparam>,  'sqlite3_profile',  \
    sqliteProgressHandler, <.ptrDB, .N, .procProgress, .lparam>,  'sqlite3_progress_handler',  \
    sqliteRandomness, <.bytes, .buffer>,  'sqlite3_randomness',  \
    sqliteReAlloc, <.ptrmem, .newsize>,  'sqlite3_realloc',  \
    sqliteReleaseMemory, <.bytes>,  'sqlite3_release_memory',  \
    sqliteReset, <.stmt>,  'sqlite3_reset',  \
    sqliteResetAutoExtension, <VOID>,  'sqlite3_reset_auto_extension',  \
    sqliteResultBlob, <.context, .ptrdata, .size, .procDestroy>,  'sqlite3_result_blob',  \
    sqliteResultDouble, <.context, .double>,  'sqlite3_result_double',  \
    sqliteResultError, <.context, .ptrErrMsg, .size>,  'sqlite3_result_error',  \
    sqliteResultError16, <.context, .ptrErrMsg, .size>,  'sqlite3_result_error16',  \
    sqliteResultErrorCode, <.context, .errcode>,  'sqlite3_result_error_code',  \
    sqliteResultErrorNoMem, <.context>,  'sqlite3_result_error_nomem',  \
    sqliteResultErrorTooBig, <.context>,  'sqlite3_result_error_toobig',  \
    sqliteResultInt, <.context, .integer>,  'sqlite3_result_int',  \
    sqliteResultInt64, <.context, .int64Lo, .int64Hi>,  'sqlite3_result_int64',  \
    sqliteResultNULL, <.context>,  'sqlite3_result_null',  \
    sqliteResultText, <.context, .ptrText, .size, .procDestroy>,  'sqlite3_result_text',  \
    sqliteResultText16, <.context, .ptrText, .size, .procDestroy>,  'sqlite3_result_text16',  \
    sqliteResultText16be, <.context, .ptrText, .size, .procDestroy>,  'sqlite3_result_text16be',  \
    sqliteResultText16le, <.context, .ptrText, .size, .procDestroy>,  'sqlite3_result_text16le',  \
    sqliteResultValue, <.context, .ptrValue>,  'sqlite3_result_value',  \
    sqliteResultZeroBlob, <.context, .size>,  'sqlite3_result_zeroblob',  \
    sqliteRollbackHook, <.ptrDB, .ptrHook, .lparam>,  'sqlite3_rollback_hook',  \
    sqliteRtreeGeometryCallback, <NONE>,  'sqlite3_rtree_geometry_callback',  \
    sqliteSQL, <.stmt>,  'sqlite3_sql',  \
    sqliteSetAuthorizer, <.ptrDB, .procAuthorizer, .lparam>,  'sqlite3_set_authorizer',  \
    sqliteSetAuxdata, <.context, .N, .ptrData, .procDestructor>,  'sqlite3_set_auxdata',  \
    sqliteShutdown, <VOID>,  'sqlite3_shutdown',  \
    sqliteSleep, <.sleep_ms>,  'sqlite3_sleep',  \
    sqliteSnprintf, <.size, .ptrBuffer, .ptrString, ...>,  'sqlite3_snprintf',  \
    sqliteSoftHeapLimit, <.N>,  'sqlite3_soft_heap_limit',  \
    sqliteSoftHeapLimit64, <.sizeLo, .sizeHi>,  'sqlite3_soft_heap_limit64',  \
    sqliteSourceID, <VOID>,  'sqlite3_sourceid',  \
    sqliteStatus, <.paramIndex, .ptrVarResult, .ptrVarHighwater, .flagReset>,  'sqlite3_status',  \
    sqliteStep, <.stmt>,  'sqlite3_step',  \
    sqliteStmtStatus, <.stmt, .paramIndex, .flagReset>,  'sqlite3_stmt_status',  \
    sqliteStrnicmp, <.ptrStr1, .ptrStr2, .size>,  'sqlite3_strnicmp',  \
    sqliteTableColumnMetadata, <.ptrDB, .ptrDBName, .ptrTableName, .ptrColumnName, .ptrVarDataType, .ptrVarCollSeq, .ptrVarNotNull,  \
        .ptrVarPrimaryKey, .ptrVarAutoInc>,  'sqlite3_table_column_metadata',  \
    sqliteTestControl, <.opCode, ...>,  'sqlite3_test_control',  \
    sqliteThreadCleanup, <VOID>,  'sqlite3_thread_cleanup',  \
    sqliteThreadsafe, <VOID>,  'sqlite3_threadsafe',  \
    sqliteTotalChanges, <.ptrDB>,  'sqlite3_total_changes',  \
    sqliteTrace, <.ptrDB, .procTrace, .lparam>,  'sqlite3_trace',  \
    sqliteTransferBindings, <VOID>,  'sqlite3_transfer_bindings',  \
    sqliteUpdateHook, <.ptrDB, .procUpdateHook, .lparam>,  'sqlite3_update_hook',  \
    sqliteUserData, <.context>,  'sqlite3_user_data',  \
    sqliteValueBlob, <.ptrValue>,  'sqlite3_value_blob',  \
    sqliteValueBytes, <.ptrValue>,  'sqlite3_value_bytes',  \
    sqliteValueBytes16, <.ptrValue>,  'sqlite3_value_bytes16',  \
    sqliteValueDouble, <.ptrValue>,  'sqlite3_value_double',  \
    sqliteValueInt, <.ptrValue>,  'sqlite3_value_int',  \
    sqliteValueInt64, <.ptrValue>,  'sqlite3_value_int64',  \
    sqliteValueNumericType, <.ptrValue>,  'sqlite3_value_numeric_type',  \
    sqliteValueText, <.ptrValue>,  'sqlite3_value_text',  \
    sqliteValueText16, <.ptrValue>,  'sqlite3_value_text16',  \
    sqliteValueText16be, <.ptrValue>,  'sqlite3_value_text16be',  \
    sqliteValueText16le, <.ptrValue>,  'sqlite3_value_text16le',  \
    sqliteValueType, <.ptrValue>,  'sqlite3_value_type',  \
    sqliteVersion, <VOID>,  'sqlite3_version',  \
    sqliteVfsFind, <.ptrVFSName>,  'sqlite3_vfs_find',  \
    sqliteVfsRegister, <.hVFS, .flagDefault>,  'sqlite3_vfs_register',  \
    sqliteVfsUnregister, <.hVFS>,  'sqlite3_vfs_unregister',  \
    sqliteVmprintf, <.ptrString, .va_list>,  'sqlite3_vmprintf',  \
    sqliteWalAutocheckpoint, <.ptrDB, .N>,  'sqlite3_wal_autocheckpoint',  \
    sqliteWalCheckpoint, <.ptrDB, .ptrDBName>,  'sqlite3_wal_checkpoint',  \
    sqliteWalHook, <.ptrDB, .procCommitHook, .lparam>,  'sqlite3_wal_hook',  \
    sqliteWin32_MbcsToUtf8, <NONE>,  'sqlite3_win32_mbcs_to_utf8'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































Deleted freshlib/imports/Win32/user32.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: user32.dll API calls
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

;   user32.dll API calls
import_proto user32,  \
    ActivateKeyboardLayout, <.HKL, .flags>,  'ActivateKeyboardLayout',  \
    AdjustWindowRect, <.lpRect, .dwStyle, .bMenu>,  'AdjustWindowRect',  \
    AdjustWindowRectEx, <.lpRect, .dwStyle, .bMenu, .dwExStyle>,  'AdjustWindowRectEx',  \
    AlignRects, <NONE>,  'AlignRects',  \
    AllowForegroundActivation, <NONE>,  'AllowForegroundActivation',  \
    AllowSetForegroundWindow, <.dwProcessId>,  'AllowSetForegroundWindow',  \
    AnimateWindow, <.hwnd, .dwTime, .dwFlags>,  'AnimateWindow',  \
    AnyPopup, <VOID>,  'AnyPopup',  \
    AppendMenuA, <.hMenu, .wFlags, .wIDNewItem, .lpNewItem>,  'AppendMenuA',  \
    AppendMenuW, <.hMenu, .wFlags, .wIDNewItem, .lpNewItem>,  'AppendMenuW',  \
    ArrangeIconicWindows, <.hwnd>,  'ArrangeIconicWindows',  \
    AttachThreadInput, <.idAttach, .idAttachTo, .fAttach>,  'AttachThreadInput',  \
    BeginDeferWindowPos, <.nNumWindows>,  'BeginDeferWindowPos',  \
    BeginPaint, <.hwnd, .lpPaint>,  'BeginPaint',  \
    BlockInput, <.fBlockIt>,  'BlockInput',  \
    BringWindowToTop, <.hwnd>,  'BringWindowToTop',  \
    BroadcastSystemMessage, <.dw, .pdw, .un, .wParam, .lParam>,  'BroadcastSystemMessage',  \
    BroadcastSystemMessageA, <.dw, .pdw, .un, .wParam, .lParam>,  'BroadcastSystemMessageA',  \
    BroadcastSystemMessageExA, <NONE>,  'BroadcastSystemMessageExA',  \
    BroadcastSystemMessageExW, <NONE>,  'BroadcastSystemMessageExW',  \
    BroadcastSystemMessageW, <.dw, .pdw, .un, .wParam, .lParam>,  'BroadcastSystemMessageW',  \
    BuildReasonArray, <NONE>,  'BuildReasonArray',  \
    CalcMenuBar, <NONE>,  'CalcMenuBar',  \
    CallMsgFilter, <.lpMsg, .ncode>,  'CallMsgFilter',  \
    CallMsgFilterA, <.lpMsg, .ncode>,  'CallMsgFilterA',  \
    CallMsgFilterW, <.lpMsg, .ncode>,  'CallMsgFilterW',  \
    CallNextHookEx, <.hHook, .ncode, .wParam, .lParam>,  'CallNextHookEx',  \
    CallWindowProcA, <.lpPrevWndFunc, .hWnd, .Msg, .wParam, .lParam>,  'CallWindowProcA',  \
    CallWindowProcW, <.lpPrevWndFunc, .hWnd, .Msg, .wParam, .lParam>,  'CallWindowProcW',  \
    CascadeChildWindows, <NONE>,  'CascadeChildWindows',  \
    CascadeWindows, <.hwndParent, .wHow, .lpRect, .cKids, .lpkids>,  'CascadeWindows',  \
    ChangeClipboardChain, <.hwnd, .hWndNext>,  'ChangeClipboardChain',  \
    ChangeDisplaySettingsA, <.lpDevMode, .dwFlags>,  'ChangeDisplaySettingsA',  \
    ChangeDisplaySettingsExA, <.lpszDeviceName, .lpDevMode, .hwnd, .dwflags, .lParam>,  'ChangeDisplaySettingsExA',  \
    ChangeDisplaySettingsExW, <.lpszDeviceName, .lpDevMode, .hwnd, .dwflags, .lParam>,  'ChangeDisplaySettingsExW',  \
    ChangeDisplaySettingsW, <.lpDevMode, .dwFlags>,  'ChangeDisplaySettingsW',  \
    ChangeMenuA, <.hMenu, .cmd, .lpszNewItem, .cmdInsert, .flags>,  'ChangeMenuA',  \
    ChangeMenuW, <.hMenu, .cmd, .lpszNewItem, .cmdInsert, .flags>,  'ChangeMenuW',  \
    CharLowerA, <.lpsz>,  'CharLowerA',  \
    CharLowerBuffA, <.lpsz, .cchLength>,  'CharLowerBuffA',  \
    CharLowerBuffW, <.lpsz, .cchLength>,  'CharLowerBuffW',  \
    CharLowerW, <.lpsz>,  'CharLowerW',  \
    CharNextA, <.lpsz>,  'CharNextA',  \
    CharNextExA, <.CodePage, .lpCurrentChar, .dwFlags>,  'CharNextExA',  \
    CharNextW, <.lpsz>,  'CharNextW',  \
    CharPrevA, <.lpszStart, .lpszCurrent>,  'CharPrevA',  \
    CharPrevExA, <.CodePage, .lpStart, .lpCurrentChar, .dwFlags>,  'CharPrevExA',  \
    CharPrevW, <.lpszStart, .lpszCurrent>,  'CharPrevW',  \
    CharToOemA, <.lpszSrc, .lpszDst>,  'CharToOemA',  \
    CharToOemBuffA, <.lpszSrc, .lpszDst, .cchDstLength>,  'CharToOemBuffA',  \
    CharToOemBuffW, <.lpszSrc, .lpszDst, .cchDstLength>,  'CharToOemBuffW',  \
    CharToOemW, <.lpszSrc, .lpszDst>,  'CharToOemW',  \
    CharUpperA, <.lpsz>,  'CharUpperA',  \
    CharUpperBuffA, <.lpsz, .cchLength>,  'CharUpperBuffA',  \
    CharUpperBuffW, <.lpsz, .cchLength>,  'CharUpperBuffW',  \
    CharUpperW, <.lpsz>,  'CharUpperW',  \
    CheckDlgButton, <.hDlg, .nIDButton, .uCheck>,  'CheckDlgButton',  \
    CheckMenuItem, <.hMenu, .wIDCheckItem, .wCheck>,  'CheckMenuItem',  \
    CheckMenuRadioItem, <.hMenu, .un1, .un2, .un3, .un4>,  'CheckMenuRadioItem',  \
    CheckRadioButton, <.hDlg, .nIDFirstButton, .nIDLastButton, .nIDCheckButton>,  'CheckRadioButton',  \
    ChildWindowFromPoint, <.hWnd, .xPoint, .yPoint>,  'ChildWindowFromPoint',  \
    ChildWindowFromPointEx, <.hWnd, .pt, .un>,  'ChildWindowFromPointEx',  \
    CliImmSetHotKey, <NONE>,  'CliImmSetHotKey',  \
    ClientThreadSetup, <NONE>,  'ClientThreadSetup',  \
    ClientToScreen, <.hwnd, .lpPoint>,  'ClientToScreen',  \
    ClipCursor, <.lpRect>,  'ClipCursor',  \
    CloseClipboard, <VOID>,  'CloseClipboard',  \
    CloseDesktop, <.hDesktop>,  'CloseDesktop',  \
    CloseWindow, <.hwnd>,  'CloseWindow',  \
    CloseWindowStation, <.hWinSta>,  'CloseWindowStation',  \
    CopyAcceleratorTableA, <.hAccelSrc, .lpAccelDst, .cAccelEntries>,  'CopyAcceleratorTableA',  \
    CopyAcceleratorTableW, <.hAccelSrc, .lpAccelDst, .cAccelEntries>,  'CopyAcceleratorTableW',  \
    CopyIcon, <.hIcon>,  'CopyIcon',  \
    CopyImage, <.handle, .un1, .n1, .n2, .un2>,  'CopyImage',  \
    CopyRect, <.lpDestRect, .lpSourceRect>,  'CopyRect',  \
    CountClipboardFormats, <VOID>,  'CountClipboardFormats',  \
    CreateAcceleratorTableA, <.lpaccl, .cEntries>,  'CreateAcceleratorTableA',  \
    CreateAcceleratorTableW, <.lpaccl, .cEntries>,  'CreateAcceleratorTableW',  \
    CreateCaret, <.hwnd, .hBitmap, .nWidth, .nHeight>,  'CreateCaret',  \
    CreateCursor, <.hInstance, .nXhotspot, .nYhotspot, .nWidth, .nHeight, .lpANDbitPlane, .lpXORbitPlane>,  'CreateCursor',  \
    CreateDesktopA, <.lpszDesktop, .lpszDevice, .pDevmode, .dwFlags, .dwDesiredAccess, .lpsa>,  'CreateDesktopA',  \
    CreateDesktopW, <.lpszDesktop, .lpszDevice, .pDevmode, .dwFlags, .dwDesiredAccess, .lpsa>,  'CreateDesktopW',  \
    CreateDialogIndirectParamA, <.hInstance, .lpTemplate, .hWndParent, .lpDialogFunc, .dwInitParam>,  'CreateDialogIndirectParamA',  \
    CreateDialogIndirectParamAorW, <NONE>,  'CreateDialogIndirectParamAorW',  \
    CreateDialogIndirectParamW, <.hInstance, .lpTemplate, .hWndParent, .lpDialogFunc, .dwInitParam>,  'CreateDialogIndirectParamW',  \
    CreateDialogParamA, <.hInstance, .lpName, .hWndParent, .lpDialogFunc, .lParamInit>,  'CreateDialogParamA',  \
    CreateDialogParamW, <.hInstance, .lpName, .hWndParent, .lpDialogFunc, .lParamInit>,  'CreateDialogParamW',  \
    CreateIcon, <.hInstance, .nWidth, .nHeight, .nPlanes, .nBitsPixel, .lpANDbits, .lpXORbits>,  'CreateIcon',  \
    CreateIconFromResource, <.presbits, .dwResSize, .fIcon, .dwVer>,  'CreateIconFromResource',  \
    CreateIconFromResourceEx, <.presbits, .dwResSize, .fIcon, .dwVer, .cxDesired, .cyDesired, .Flags>,  'CreateIconFromResourceEx',  \
    CreateIconIndirect, <.piconinfo>,  'CreateIconIndirect',  \
    CreateMDIWindowA, <.lpClassName, .lpWindowName, .dwStyle, .x, .y, .nWidth, .nHeight, .hWndParent, .hInstance, .lParam>,  'CreateMDIWindowA',  \
    CreateMDIWindowW, <.lpClassName, .lpWindowName, .dwStyle, .x, .y, .nWidth, .nHeight, .hWndParent, .hInstance, .lParam>,  'CreateMDIWindowW',  \
    CreateMenu, <VOID>,  'CreateMenu',  \
    CreatePopupMenu, <VOID>,  'CreatePopupMenu',  \
    CreateSystemThreads, <NONE>,  'CreateSystemThreads',  \
    CreateWindowExA, <.dwExStyle, .lpClassName, .lpWindowName, .dwStyle, .x, .y, .nWidth, .nHeight, .hWndParent, .hMenu, .hInstance,  \
        .lpParam>,  'CreateWindowExA',  \
    CreateWindowExW, <.dwExStyle, .lpClassName, .lpWindowName, .dwStyle, .x, .y, .nWidth, .nHeight, .hWndParent, .hMenu, .hInstance,  \
        .lpParam>,  'CreateWindowExW',  \
    CreateWindowStationA, <.lpwinsta, .dwReserved, .dwDesiredAccess, .lpsa>,  'CreateWindowStationA',  \
    CreateWindowStationW, <.lpwinsta, .dwReserved, .dwDesiredAccess, .lpsa>,  'CreateWindowStationW',  \
    CsrBroadcastSystemMessageExW, <NONE>,  'CsrBroadcastSystemMessageExW',  \
    CtxInitUser32, <NONE>,  'CtxInitUser32',  \
    DdeAbandonTransaction, <.idInst, .hConv, .idTransaction>,  'DdeAbandonTransaction',  \
    DdeAccessData, <.hData, .pcbDataSize>,  'DdeAccessData',  \
    DdeAddData, <.hData, .pSrc, .cb, .cbOff>,  'DdeAddData',  \
    DdeClientTransaction, <.pData, .cbData, .hConv, .hszItem, .wFmt, .wType, .dwTimeout, .pdwResult>,  'DdeClientTransaction',  \
    DdeCmpStringHandles, <.hsz1, .hsz2>,  'DdeCmpStringHandles',  \
    DdeConnect, <.idInst, .hszService, .hszTopic, .pCC>,  'DdeConnect',  \
    DdeConnectList, <.idInst, .hszService, .hszTopic, .hConvList, .pCC>,  'DdeConnectList',  \
    DdeCreateDataHandle, <.idInst, .pSrc, .cb, .cbOff, .hszItem, .wFmt, .afCmd>,  'DdeCreateDataHandle',  \
    DdeCreateStringHandleA, <.idInst, .psz, .iCodePage>,  'DdeCreateStringHandleA',  \
    DdeCreateStringHandleW, <.idInst, .psz, .iCodePage>,  'DdeCreateStringHandleW',  \
    DdeDisconnect, <.hConv>,  'DdeDisconnect',  \
    DdeDisconnectList, <.hConvList>,  'DdeDisconnectList',  \
    DdeEnableCallback, <.idInst, .hConv, .wCmd>,  'DdeEnableCallback',  \
    DdeFreeDataHandle, <.hData>,  'DdeFreeDataHandle',  \
    DdeFreeStringHandle, <.idInst, .hsz>,  'DdeFreeStringHandle',  \
    DdeGetData, <.hData, .pDst, .cbMax, .cbOff>,  'DdeGetData',  \
    DdeGetLastError, <.idInst>,  'DdeGetLastError',  \
    DdeGetQualityOfService, <NONE>,  'DdeGetQualityOfService',  \
    DdeImpersonateClient, <.hConv>,  'DdeImpersonateClient',  \
    DdeInitializeA, <.pidInst, .pfnCallback, .afCmd, .ulRes>,  'DdeInitializeA',  \
    DdeInitializeW, <.pidInst, .pfnCallback, .afCmd, .ulRes>,  'DdeInitializeW',  \
    DdeKeepStringHandle, <.idInst, .hsz>,  'DdeKeepStringHandle',  \
    DdeNameService, <.idInst, .hsz1, .hsz2, .afCmd>,  'DdeNameService',  \
    DdePostAdvise, <.idInst, .hszTopic, .hszItem>,  'DdePostAdvise',  \
    DdeQueryConvInfo, <.hConv, .idTransaction, .pConvInfo>,  'DdeQueryConvInfo',  \
    DdeQueryNextServer, <.hConvList, .hConvPrev>,  'DdeQueryNextServer',  \
    DdeQueryStringA, <.idInst, .hsz, .psz, .cchMax, .iCodePage>,  'DdeQueryStringA',  \
    DdeQueryStringW, <.idInst, .hsz, .psz, .cchMax, .iCodePage>,  'DdeQueryStringW',  \
    DdeReconnect, <.hConv>,  'DdeReconnect',  \
    DdeSetQualityOfService, <.hWndClient, .pqosNew, .pqosPrev>,  'DdeSetQualityOfService',  \
    DdeSetUserHandle, <.hConv, .id, .hUser>,  'DdeSetUserHandle',  \
    DdeUnaccessData, <.hData>,  'DdeUnaccessData',  \
    DdeUninitialize, <.idInst>,  'DdeUninitialize',  \
    DefDlgProcA, <.hDlg, .wMsg, .wParam, .lParam>,  'DefDlgProcA',  \
    DefDlgProcW, <.hDlg, .wMsg, .wParam, .lParam>,  'DefDlgProcW',  \
    DefFrameProcA, <.hwnd, .hWndMDIClient, .wMsg, .wParam, .lParam>,  'DefFrameProcA',  \
    DefFrameProcW, <.hwnd, .hWndMDIClient, .wMsg, .wParam, .lParam>,  'DefFrameProcW',  \
    DefMDIChildProcA, <.hwnd, .wMsg, .wParam, .lParam>,  'DefMDIChildProcA',  \
    DefMDIChildProcW, <.hwnd, .wMsg, .wParam, .lParam>,  'DefMDIChildProcW',  \
    DefRawInputProc, <NONE>,  'DefRawInputProc',  \
    DefWindowProcA, <.hwnd, .wMsg, .wParam, .lParam>,  'DefWindowProcA',  \
    DefWindowProcW, <.hwnd, .wMsg, .wParam, .lParam>,  'DefWindowProcW',  \
    DeferWindowPos, <.hWinPosInfo, .hwnd, .hWndInsertAfter, .x, .y, .cx, .cy, .wFlags>,  'DeferWindowPos',  \
    DeleteMenu, <.hMenu, .nPosition, .wFlags>,  'DeleteMenu',  \
    DeregisterShellHookWindow, <NONE>,  'DeregisterShellHookWindow',  \
    DestroyAcceleratorTable, <.haccel>,  'DestroyAcceleratorTable',  \
    DestroyCaret, <VOID>,  'DestroyCaret',  \
    DestroyCursor, <.hCursor>,  'DestroyCursor',  \
    DestroyIcon, <.hIcon>,  'DestroyIcon',  \
    DestroyMenu, <.hMenu>,  'DestroyMenu',  \
    DestroyReasons, <NONE>,  'DestroyReasons',  \
    DestroyWindow, <.hwnd>,  'DestroyWindow',  \
    DeviceEventWorker, <NONE>,  'DeviceEventWorker',  \
    DialogBoxIndirectParamA, <.hInstance, .hDialogTemplate, .hWndParent, .lpDialogFunc, .dwInitParam>,  'DialogBoxIndirectParamA',  \
    DialogBoxIndirectParamAorW, <NONE>,  'DialogBoxIndirectParamAorW',  \
    DialogBoxIndirectParamW, <.hInstance, .hDialogTemplate, .hWndParent, .lpDialogFunc, .dwInitParam>,  'DialogBoxIndirectParamW',  \
    DialogBoxParamA, <.hInstance, .lpTemplateName, .hWndParent, .lpDialogFunc, .dwInitParam>,  'DialogBoxParamA',  \
    DialogBoxParamW, <.hInstance, .lpTemplateName, .hWndParent, .lpDialogFunc, .dwInitParam>,  'DialogBoxParamW',  \
    DisableProcessWindowsGhosting, <NONE>,  'DisableProcessWindowsGhosting',  \
    DispatchMessageA, <.lpMsg>,  'DispatchMessageA',  \
    DispatchMessageW, <.lpMsg>,  'DispatchMessageW',  \
    DisplayExitWindowsWarnings, <NONE>,  'DisplayExitWindowsWarnings',  \
    DlgDirListA, <.hDlg, .lpPathSpec, .nIDListBox, .nIDStaticPath, .wFileType>,  'DlgDirListA',  \
    DlgDirListComboBoxA, <.hDlg, .lpPathSpec, .nIDComboBox, .nIDStaticPath, .wFileType>,  'DlgDirListComboBoxA',  \
    DlgDirListComboBoxW, <.hDlg, .lpPathSpec, .nIDComboBox, .nIDStaticPath, .wFileType>,  'DlgDirListComboBoxW',  \
    DlgDirListW, <.hDlg, .lpPathSpec, .nIDListBox, .nIDStaticPath, .wFileType>,  'DlgDirListW',  \
    DlgDirSelectComboBoxExA, <.hWndDlg, .lpszPath, .cbPath, .idComboBox>,  'DlgDirSelectComboBoxExA',  \
    DlgDirSelectComboBoxExW, <.hWndDlg, .lpszPath, .cbPath, .idComboBox>,  'DlgDirSelectComboBoxExW',  \
    DlgDirSelectExA, <.hWndDlg, .lpszPath, .cbPath, .idListBox>,  'DlgDirSelectExA',  \
    DlgDirSelectExW, <.hWndDlg, .lpszPath, .cbPath, .idListBox>,  'DlgDirSelectExW',  \
    DragDetect, <.hWnd, .pt>,  'DragDetect',  \
    DragObject, <.hWnd1, .hWnd2, .un, .dw, .hCursor>,  'DragObject',  \
    DrawAnimatedRects, <.hwnd, .idAni, .lprcFrom, .lprcTo>,  'DrawAnimatedRects',  \
    DrawCaption, <.hWnd, .hDC, .pcRect, .uDCFlags>,  'DrawCaption',  \
    DrawCaptionTempA, <NONE>,  'DrawCaptionTempA',  \
    DrawCaptionTempW, <NONE>,  'DrawCaptionTempW',  \
    DrawEdge, <.hdc, .qrc, .edge, .grfFlags>,  'DrawEdge',  \
    DrawFocusRect, <.hdc, .lpRect>,  'DrawFocusRect',  \
    DrawFrame, <NONE>,  'DrawFrame',  \
    DrawFrameControl, <.hDC, .lpRect, .uFrameType, .uFrameState>,  'DrawFrameControl',  \
    DrawIcon, <.hdc, .x, .y, .hIcon>,  'DrawIcon',  \
    DrawIconEx, <.hdc, .xLeft, .yTop, .hIcon, .cxWidth, .cyWidth, .istepIfAniCur, .hbrFlickerFreeDraw, .diFlags>,  'DrawIconEx',  \
    DrawMenuBar, <.hwnd>,  'DrawMenuBar',  \
    DrawMenuBarTemp, <NONE>,  'DrawMenuBarTemp',  \
    DrawStateA, <.hDC, .hBrush, .lpDrawStateProc, .lParam, .wParam, .n1, .n2, .n3, .n4, .un>,  'DrawStateA',  \
    DrawStateW, <.hDC, .hBrush, .lpDrawStateProc, .lParam, .wParam, .n1, .n2, .n3, .n4, .un>,  'DrawStateW',  \
    DrawTextA, <.hdc, .lpStr, .nCount, .lpRect, .wFormat>,  'DrawTextA',  \
    DrawTextExA, <.hDC, .lpsz, .n, .lpRect, .un, .lpDrawTextParams>,  'DrawTextExA',  \
    DrawTextExW, <.hDC, .lpsz, .n, .lpRect, .un, .lpDrawTextParams>,  'DrawTextExW',  \
    DrawTextW, <.hdc, .lpStr, .nCount, .lpRect, .wFormat>,  'DrawTextW',  \
    EditWndProc, <NONE>,  'EditWndProc',  \
    EmptyClipboard, <VOID>,  'EmptyClipboard',  \
    EnableMenuItem, <.hMenu, .wIDEnableItem, .wEnable>,  'EnableMenuItem',  \
    EnableScrollBar, <.hwnd, .wSBflags, .wArrows>,  'EnableScrollBar',  \
    EnableWindow, <.hwnd, .fBoolean>,  'EnableWindow',  \
    EndDeferWindowPos, <.hWinPosInfo>,  'EndDeferWindowPos',  \
    EndDialog, <.hDlg, .nResult>,  'EndDialog',  \
    EndMenu, <VOID>,  'EndMenu',  \
    EndPaint, <.hwnd, .lpPaint>,  'EndPaint',  \
    EndTask, <NONE>,  'EndTask',  \
    EnterReaderModeHelper, <NONE>,  'EnterReaderModeHelper',  \
    EnumChildWindows, <.hWndParent, .lpEnumFunc, .lParam>,  'EnumChildWindows',  \
    EnumClipboardFormats, <.wFormat>,  'EnumClipboardFormats',  \
    EnumDesktopWindows, <.hDesktop, .lpfn, .lParam>,  'EnumDesktopWindows',  \
    EnumDesktopsA, <.hwinsta, .lpEnumFunc, .lParam>,  'EnumDesktopsA',  \
    EnumDesktopsW, <.hwinsta, .lpEnumFunc, .lParam>,  'EnumDesktopsW',  \
    EnumDisplayDevicesA, <.lpDevice, .iDevNum, .lpDisplayDevice, .dwFlags>,  'EnumDisplayDevicesA',  \
    EnumDisplayDevicesW, <.lpDevice, .iDevNum, .lpDisplayDevice, .dwFlags>,  'EnumDisplayDevicesW',  \
    EnumDisplayMonitors, <.hdc, .lprcClip, .lpfnEnum, .dwData>,  'EnumDisplayMonitors',  \
    EnumDisplaySettingsA, <.lpszDeviceName, .iModeNum, .lpDevMode>,  'EnumDisplaySettingsA',  \
    EnumDisplaySettingsExA, <.lpszDeviceName, .iModeNum, .lpDevMode, .dwFlags>,  'EnumDisplaySettingsExA',  \
    EnumDisplaySettingsExW, <.lpszDeviceName, .iModeNum, .lpDevMode, .dwFlags>,  'EnumDisplaySettingsExW',  \
    EnumDisplaySettingsW, <.lpszDeviceName, .iModeNum, .lpDevMode>,  'EnumDisplaySettingsW',  \
    EnumPropsA, <.hWnd, .lpEnumFunc>,  'EnumPropsA',  \
    EnumPropsExA, <.hWnd, .lpEnumFunc, .lParam>,  'EnumPropsExA',  \
    EnumPropsExW, <.hWnd, .lpEnumFunc, .lParam>,  'EnumPropsExW',  \
    EnumPropsW, <.hWnd, .lpEnumFunc>,  'EnumPropsW',  \
    EnumThreadWindows, <.dwThreadId, .lpfn, .lParam>,  'EnumThreadWindows',  \
    EnumWindowStationsA, <.lpEnumFunc, .lParam>,  'EnumWindowStationsA',  \
    EnumWindowStationsW, <.lpEnumFunc, .lParam>,  'EnumWindowStationsW',  \
    EnumWindows, <.lpEnumFunc, .lParam>,  'EnumWindows',  \
    EqualRect, <.lpRect1, .lpRect2>,  'EqualRect',  \
    ExcludeUpdateRgn, <.hdc, .hwnd>,  'ExcludeUpdateRgn',  \
    ExitWindowsEx, <.uFlags, .dwReserved>,  'ExitWindowsEx',  \
    FillRect, <.hdc, .lpRect, .hBrush>,  'FillRect',  \
    FindWindowA, <.lpClassName, .lpWindowName>,  'FindWindowA',  \
    FindWindowExA, <.hWnd1, .hWnd2, .lpsz1, .lpsz2>,  'FindWindowExA',  \
    FindWindowExW, <.hWnd1, .hWnd2, .lpsz1, .lpsz2>,  'FindWindowExW',  \
    FindWindowW, <.lpClassName, .lpWindowName>,  'FindWindowW',  \
    FlashWindow, <.hwnd, .bInvert>,  'FlashWindow',  \
    FlashWindowEx, <.pfwi>,  'FlashWindowEx',  \
    FrameRect, <.hdc, .lpRect, .hBrush>,  'FrameRect',  \
    FreeDDElParam, <.msg, .lParam>,  'FreeDDElParam',  \
    GetActiveWindow, <VOID>,  'GetActiveWindow',  \
    GetAltTabInfo, <.hwnd, .iItem, .pati, .pszItemText, .cchItemText>,  'GetAltTabInfo',  \
    GetAltTabInfoA, <.hwnd, .iItem, .pati, .pszItemText, .cchItemText>,  'GetAltTabInfoA',  \
    GetAltTabInfoW, <.hwnd, .iItem, .pati, .pszItemText, .cchItemText>,  'GetAltTabInfoW',  \
    GetAncestor, <.hwnd, .gaFlags>,  'GetAncestor',  \
    GetAppCompatFlags, <NONE>,  'GetAppCompatFlags',  \
    GetAppCompatFlags2, <NONE>,  'GetAppCompatFlags2',  \
    GetAsyncKeyState, <.vKey>,  'GetAsyncKeyState',  \
    GetCapture, <VOID>,  'GetCapture',  \
    GetCaretBlinkTime, <VOID>,  'GetCaretBlinkTime',  \
    GetCaretPos, <.lpPoint>,  'GetCaretPos',  \
    GetClassInfoA, <.hInstance, .lpClassName, .lpWndClass>,  'GetClassInfoA',  \
    GetClassInfoExA, <.hinstance, .lpcstr, .lpwndclassexa>,  'GetClassInfoExA',  \
    GetClassInfoExW, <.hinstance, .lpcstr, .lpwndclassexa>,  'GetClassInfoExW',  \
    GetClassInfoW, <.hInstance, .lpClassName, .lpWndClass>,  'GetClassInfoW',  \
    GetClassLongA, <.hwnd, .nIndex>,  'GetClassLongA',  \
    GetClassLongW, <.hwnd, .nIndex>,  'GetClassLongW',  \
    GetClassNameA, <.hwnd, .lpClassName, .nMaxCount>,  'GetClassNameA',  \
    GetClassNameW, <.hwnd, .lpClassName, .nMaxCount>,  'GetClassNameW',  \
    GetClassWord, <.hwnd, .nIndex>,  'GetClassWord',  \
    GetClientRect, <.hwnd, .lpRect>,  'GetClientRect',  \
    GetClipCursor, <.lprc>,  'GetClipCursor',  \
    GetClipboardData, <.wFormat>,  'GetClipboardData',  \
    GetClipboardFormatNameA, <.wFormat, .lpString, .nMaxCount>,  'GetClipboardFormatNameA',  \
    GetClipboardFormatNameW, <.wFormat, .lpString, .nMaxCount>,  'GetClipboardFormatNameW',  \
    GetClipboardOwner, <VOID>,  'GetClipboardOwner',  \
    GetClipboardSequenceNumber, <VOID>,  'GetClipboardSequenceNumber',  \
    GetClipboardViewer, <VOID>,  'GetClipboardViewer',  \
    GetComboBoxInfo, <.hwndCombo, .pcbi>,  'GetComboBoxInfo',  \
    GetCursor, <VOID>,  'GetCursor',  \
    GetCursorFrameInfo, <NONE>,  'GetCursorFrameInfo',  \
    GetCursorInfo, <.pci>,  'GetCursorInfo',  \
    GetCursorPos, <.lpPoint>,  'GetCursorPos',  \
    GetDC, <.hwnd>,  'GetDC',  \
    GetDCEx, <.hwnd, .hrgnclip, .fdwOptions>,  'GetDCEx',  \
    GetDesktopWindow, <VOID>,  'GetDesktopWindow',  \
    GetDialogBaseUnits, <VOID>,  'GetDialogBaseUnits',  \
    GetDlgCtrlID, <.hwnd>,  'GetDlgCtrlID',  \
    GetDlgItem, <.hDlg, .nIDDlgItem>,  'GetDlgItem',  \
    GetDlgItemInt, <.hDlg, .nIDDlgItem, .lpTranslated, .bSigned>,  'GetDlgItemInt',  \
    GetDlgItemTextA, <.hDlg, .nIDDlgItem, .lpString, .nMaxCount>,  'GetDlgItemTextA',  \
    GetDlgItemTextW, <.hDlg, .nIDDlgItem, .lpString, .nMaxCount>,  'GetDlgItemTextW',  \
    GetDoubleClickTime, <VOID>,  'GetDoubleClickTime',  \
    GetFocus, <VOID>,  'GetFocus',  \
    GetForegroundWindow, <VOID>,  'GetForegroundWindow',  \
    GetGUIThreadInfo, <.idThread, .pgui>,  'GetGUIThreadInfo',  \
    GetGuiResources, <.hProcess, .uiFlags>,  'GetGuiResources',  \
    GetIconInfo, <.hIcon, .piconinfo>,  'GetIconInfo',  \
    GetInputDesktop, <NONE>,  'GetInputDesktop',  \
    GetInputState, <VOID>,  'GetInputState',  \
    GetInternalWindowPos, <NONE>,  'GetInternalWindowPos',  \
    GetKBCodePage, <VOID>,  'GetKBCodePage',  \
    GetKeyNameTextA, <.lParam, .lpBuffer, .nSize>,  'GetKeyNameTextA',  \
    GetKeyNameTextW, <.lParam, .lpBuffer, .nSize>,  'GetKeyNameTextW',  \
    GetKeyState, <.nVirtKey>,  'GetKeyState',  \
    GetKeyboardLayout, <.dwLayout>,  'GetKeyboardLayout',  \
    GetKeyboardLayoutList, <.nBuff, .lpList>,  'GetKeyboardLayoutList',  \
    GetKeyboardLayoutNameA, <.pwszKLID>,  'GetKeyboardLayoutNameA',  \
    GetKeyboardLayoutNameW, <.pwszKLID>,  'GetKeyboardLayoutNameW',  \
    GetKeyboardState, <.pbKeyState>,  'GetKeyboardState',  \
    GetKeyboardType, <.nTypeFlag>,  'GetKeyboardType',  \
    GetLastActivePopup, <.hwndOwnder>,  'GetLastActivePopup',  \
    GetLastInputInfo, <.plii>,  'GetLastInputInfo',  \
    GetLayeredWindowAttributes, <NONE>,  'GetLayeredWindowAttributes',  \
    GetListBoxInfo, <.hwnd>,  'GetListBoxInfo',  \
    GetMenu, <.hwnd>,  'GetMenu',  \
    GetMenuBarInfo, <.hwnd, .idObject, .idItem, .pmbi>,  'GetMenuBarInfo',  \
    GetMenuCheckMarkDimensions, <VOID>,  'GetMenuCheckMarkDimensions',  \
    GetMenuContextHelpId, <.hMenu>,  'GetMenuContextHelpId',  \
    GetMenuDefaultItem, <.hMenu, .fByPos, .gmdiFlags>,  'GetMenuDefaultItem',  \
    GetMenuInfo, <.hmenu, .LPMENUINFO>,  'GetMenuInfo',  \
    GetMenuItemCount, <.hMenu>,  'GetMenuItemCount',  \
    GetMenuItemID, <.hMenu, .nPos>,  'GetMenuItemID',  \
    GetMenuItemInfoA, <.hMenu, .un, .fBoolean, .lpMenuItemInfo>,  'GetMenuItemInfoA',  \
    GetMenuItemInfoW, <.hMenu, .un, .fBoolean, .lpMenuItemInfo>,  'GetMenuItemInfoW',  \
    GetMenuItemRect, <.hWnd, .hMenu, .uItem, .lprcItem>,  'GetMenuItemRect',  \
    GetMenuState, <.hMenu, .wID, .wFlags>,  'GetMenuState',  \
    GetMenuStringA, <.hMenu, .wIDItem, .lpString, .nMaxCount, .wFlags>,  'GetMenuStringA',  \
    GetMenuStringW, <.hMenu, .wIDItem, .lpString, .nMaxCount, .wFlags>,  'GetMenuStringW',  \
    GetMessageA, <.lpMsg, .hwnd, .wMsgFilterMin, .wMsgFilterMax>,  'GetMessageA',  \
    GetMessageExtraInfo, <VOID>,  'GetMessageExtraInfo',  \
    GetMessagePos, <VOID>,  'GetMessagePos',  \
    GetMessageTime, <VOID>,  'GetMessageTime',  \
    GetMessageW, <.lpMsg, .hwnd, .wMsgFilterMin, .wMsgFilterMax>,  'GetMessageW',  \
    GetMonitorInfoA, <.hMonitor, .lpmi>,  'GetMonitorInfoA',  \
    GetMonitorInfoW, <.hMonitor, .lpmi>,  'GetMonitorInfoW',  \
    GetMouseMovePointsEx, <.cbSize, .lppt, .lpptBuf, .nBufPoints, .resolution>,  'GetMouseMovePointsEx',  \
    GetNextDlgGroupItem, <.hDlg, .hCtl, .bPrevious>,  'GetNextDlgGroupItem',  \
    GetNextDlgTabItem, <.hDlg, .hCtl, .bPrevious>,  'GetNextDlgTabItem',  \
    GetOpenClipboardWindow, <VOID>,  'GetOpenClipboardWindow',  \
    GetParent, <.hwnd>,  'GetParent',  \
    GetPriorityClipboardFormat, <.lpPriorityList, .nCount>,  'GetPriorityClipboardFormat',  \
    GetProcessDefaultLayout, <.pdwDefaultLayout>,  'GetProcessDefaultLayout',  \
    GetProcessWindowStation, <VOID>,  'GetProcessWindowStation',  \
    GetProgmanWindow, <NONE>,  'GetProgmanWindow',  \
    GetPropA, <.hwnd, .lpString>,  'GetPropA',  \
    GetPropW, <.hwnd, .lpString>,  'GetPropW',  \
    GetQueueStatus, <.fuFlags>,  'GetQueueStatus',  \
    GetRawInputBuffer, <NONE>,  'GetRawInputBuffer',  \
    GetRawInputData, <NONE>,  'GetRawInputData',  \
    GetRawInputDeviceInfoA, <NONE>,  'GetRawInputDeviceInfoA',  \
    GetRawInputDeviceInfoW, <NONE>,  'GetRawInputDeviceInfoW',  \
    GetRawInputDeviceList, <NONE>,  'GetRawInputDeviceList',  \
    GetReasonTitleFromReasonCode, <NONE>,  'GetReasonTitleFromReasonCode',  \
    GetRegisteredRawInputDevices, <NONE>,  'GetRegisteredRawInputDevices',  \
    GetScrollBarInfo, <.hwnd, .idObject, .psbi>,  'GetScrollBarInfo',  \
    GetScrollInfo, <.hWnd, .n, .lpScrollInfo>,  'GetScrollInfo',  \
    GetScrollPos, <.hwnd, .nBar>,  'GetScrollPos',  \
    GetScrollRange, <.hwnd, .nBar, .lpMinPos, .lpMaxPos>,  'GetScrollRange',  \
    GetShellWindow, <NONE>,  'GetShellWindow',  \
    GetSubMenu, <.hMenu, .nPos>,  'GetSubMenu',  \
    GetSysColor, <.nSysColor>,  'GetSysColor',  \
    GetSysColorBrush, <.nSysColor>,  'GetSysColorBrush',  \
    GetSystemMenu, <.hwnd, .fBoolean>,  'GetSystemMenu',  \
    GetSystemMetrics, <.nIndex>,  'GetSystemMetrics',  \
    GetTabbedTextExtentA, <.hdc, .lpString, .nCount, .nTabPositions, .lpnTabStopPositions>,  'GetTabbedTextExtentA',  \
    GetTabbedTextExtentW, <.hdc, .lpString, .nCount, .nTabPositions, .lpnTabStopPositions>,  'GetTabbedTextExtentW',  \
    GetTaskmanWindow, <NONE>,  'GetTaskmanWindow',  \
    GetThreadDesktop, <.dwThread>,  'GetThreadDesktop',  \
    GetTitleBarInfo, <.hwnd, .pti>,  'GetTitleBarInfo',  \
    GetTopWindow, <.hwnd>,  'GetTopWindow',  \
    GetUpdateRect, <.hwnd, .lpRect, .bErase>,  'GetUpdateRect',  \
    GetUpdateRgn, <.hwnd, .hRgn, .fErase>,  'GetUpdateRgn',  \
    GetUserObjectInformationA, <.hObj, .nIndex, .pvInfo, .nLength, .lpnLengthNeeded>,  'GetUserObjectInformationA',  \
    GetUserObjectInformationW, <.hObj, .nIndex, .pvInfo, .nLength, .lpnLengthNeeded>,  'GetUserObjectInformationW',  \
    GetUserObjectSecurity, <.hObj, .pSIRequested, .pSd, .nLength, .lpnLengthNeeded>,  'GetUserObjectSecurity',  \
    GetWinStationInfo, <NONE>,  'GetWinStationInfo',  \
    GetWindow, <.hwnd, .wCmd>,  'GetWindow',  \
    GetWindowContextHelpId, <.hWnd>,  'GetWindowContextHelpId',  \
    GetWindowDC, <.hwnd>,  'GetWindowDC',  \
    GetWindowInfo, <.hwnd, .pwi>,  'GetWindowInfo',  \
    GetWindowLongA, <.hwnd, .nIndex>,  'GetWindowLongA',  \
    GetWindowLongW, <.hwnd, .nIndex>,  'GetWindowLongW',  \
    GetWindowModuleFileName, <.hwnd, .pszFileName, .cchFileNameMax>,  'GetWindowModuleFileName',  \
    GetWindowModuleFileNameA, <.hwnd, .pszFileName, .cchFileNameMax>,  'GetWindowModuleFileNameA',  \
    GetWindowModuleFileNameW, <.hwnd, .pszFileName, .cchFileNameMax>,  'GetWindowModuleFileNameW',  \
    GetWindowPlacement, <.hwnd, .lpwndpl>,  'GetWindowPlacement',  \
    GetWindowRect, <.hwnd, .lpRect>,  'GetWindowRect',  \
    GetWindowRgn, <.hWnd, .hRgn>,  'GetWindowRgn',  \
    GetWindowRgnBox, <NONE>,  'GetWindowRgnBox',  \
    GetWindowTextA, <.hwnd, .lpString, .cch>,  'GetWindowTextA',  \
    GetWindowTextLengthA, <.hwnd>,  'GetWindowTextLengthA',  \
    GetWindowTextLengthW, <.hwnd>,  'GetWindowTextLengthW',  \
    GetWindowTextW, <.hwnd, .lpString, .cch>,  'GetWindowTextW',  \
    GetWindowThreadProcessId, <.hwnd, .lpdwProcessId>,  'GetWindowThreadProcessId',  \
    GetWindowWord, <.hwnd, .nIndex>,  'GetWindowWord',  \
    GrayStringA, <.hDC, .hBrush, .lpOutputFunc, .lpData, .nCount, .X, .Y, .nWidth, .nHeight>,  'GrayStringA',  \
    GrayStringW, <.hDC, .hBrush, .lpOutputFunc, .lpData, .nCount, .X, .Y, .nWidth, .nHeight>,  'GrayStringW',  \
    HideCaret, <.hwnd>,  'HideCaret',  \
    HiliteMenuItem, <.hwnd, .hMenu, .wIDHiliteItem, .wHilite>,  'HiliteMenuItem',  \
    IMPGetIMEA, <.hwnd, .LPIMEPROA>,  'IMPGetIMEA',  \
    IMPGetIMEW, <.hwnd, .LPIMEPROA>,  'IMPGetIMEW',  \
    IMPQueryIMEA, <.LPIMEPROA>,  'IMPQueryIMEA',  \
    IMPQueryIMEW, <.LPIMEPROA>,  'IMPQueryIMEW',  \
    IMPSetIMEA, <.hwnd, .LPIMEPROA>,  'IMPSetIMEA',  \
    IMPSetIMEW, <.hwnd, .LPIMEPROA>,  'IMPSetIMEW',  \
    ImpersonateDdeClientWindow, <.hWndClient, .hWndServer>,  'ImpersonateDdeClientWindow',  \
    InSendMessage, <VOID>,  'InSendMessage',  \
    InSendMessageEx, <.lpReserved>,  'InSendMessageEx',  \
    InflateRect, <.lpRect, .x, .y>,  'InflateRect',  \
    InitializeLpkHooks, <NONE>,  'InitializeLpkHooks',  \
    InitializeWin32EntryTable, <NONE>,  'InitializeWin32EntryTable',  \
    InsertMenuA, <.hMenu, .nPosition, .wFlags, .wIDNewItem, .lpNewItem>,  'InsertMenuA',  \
    InsertMenuItemA, <.hMenu, .uItem, .bool, .ByRef>,  'InsertMenuItemA',  \
    InsertMenuItemW, <.hMenu, .uItem, .bool, .ByRef>,  'InsertMenuItemW',  \
    InsertMenuW, <.hMenu, .nPosition, .wFlags, .wIDNewItem, .lpNewItem>,  'InsertMenuW',  \
    InternalGetWindowText, <NONE>,  'InternalGetWindowText',  \
    IntersectRect, <.lpDestRect, .lpSrc1Rect, .lpSrc2Rect>,  'IntersectRect',  \
    InvalidateRect, <.hwnd, .lpRect, .fBoolean>,  'InvalidateRect',  \
    InvalidateRgn, <.hwnd, .hRgn, .bErase>,  'InvalidateRgn',  \
    InvertRect, <.hdc, .lpRect>,  'InvertRect',  \
    IsCharAlphaA, <.cChar>,  'IsCharAlphaA',  \
    IsCharAlphaNumericA, <.cChar>,  'IsCharAlphaNumericA',  \
    IsCharAlphaNumericW, <.cChar>,  'IsCharAlphaNumericW',  \
    IsCharAlphaW, <.cChar>,  'IsCharAlphaW',  \
    IsCharLowerA, <.cChar>,  'IsCharLowerA',  \
    IsCharLowerW, <.cChar>,  'IsCharLowerW',  \
    IsCharUpperA, <.cChar>,  'IsCharUpperA',  \
    IsCharUpperW, <.cChar>,  'IsCharUpperW',  \
    IsChild, <.hWndParent, .hwnd>,  'IsChild',  \
    IsClipboardFormatAvailable, <.wFormat>,  'IsClipboardFormatAvailable',  \
    IsDialogMessage, <.hDlg, .lpMsg>,  'IsDialogMessage',  \
    IsDialogMessageA, <.hDlg, .lpMsg>,  'IsDialogMessageA',  \
    IsDialogMessageW, <.hDlg, .lpMsg>,  'IsDialogMessageW',  \
    IsDlgButtonChecked, <.hDlg, .nIDButton>,  'IsDlgButtonChecked',  \
    IsGUIThread, <NONE>,  'IsGUIThread',  \
    IsHungAppWindow, <NONE>,  'IsHungAppWindow',  \
    IsIconic, <.hwnd>,  'IsIconic',  \
    IsMenu, <.hMenu>,  'IsMenu',  \
    IsRectEmpty, <.lpRect>,  'IsRectEmpty',  \
    IsServerSideWindow, <NONE>,  'IsServerSideWindow',  \
    IsWinEventHookInstalled, <NONE>,  'IsWinEventHookInstalled',  \
    IsWindow, <.hwnd>,  'IsWindow',  \
    IsWindowEnabled, <.hwnd>,  'IsWindowEnabled',  \
    IsWindowInDestroy, <NONE>,  'IsWindowInDestroy',  \
    IsWindowUnicode, <.hwnd>,  'IsWindowUnicode',  \
    IsWindowVisible, <.hwnd>,  'IsWindowVisible',  \
    IsZoomed, <.hwnd>,  'IsZoomed',  \
    KillSystemTimer, <NONE>,  'KillSystemTimer',  \
    KillTimer, <.hwnd, .nIDEvent>,  'KillTimer',  \
    LoadAcceleratorsA, <.hInstance, .lpTableName>,  'LoadAcceleratorsA',  \
    LoadAcceleratorsW, <.hInstance, .lpTableName>,  'LoadAcceleratorsW',  \
    LoadBitmapA, <.hInstance, .lpBitmapName>,  'LoadBitmapA',  \
    LoadBitmapW, <.hInstance, .lpBitmapName>,  'LoadBitmapW',  \
    LoadCursorA, <.hInstance, .lpCursorName>,  'LoadCursorA',  \
    LoadCursorFromFileA, <.lpFileName>,  'LoadCursorFromFileA',  \
    LoadCursorFromFileW, <.lpFileName>,  'LoadCursorFromFileW',  \
    LoadCursorW, <.hInstance, .lpCursorName>,  'LoadCursorW',  \
    LoadIconA, <.hInstance, .lpIconName>,  'LoadIconA',  \
    LoadIconW, <.hInstance, .lpIconName>,  'LoadIconW',  \
    LoadImageA, <.hInst, .lpsz, .uType, .n1, .n2, .uFlags>,  'LoadImageA',  \
    LoadImageW, <.hInst, .lpsz, .uType, .n1, .n2, .uFlags>,  'LoadImageW',  \
    LoadKeyboardLayoutA, <.pwszKLID, .flags>,  'LoadKeyboardLayoutA',  \
    LoadKeyboardLayoutEx, <NONE>,  'LoadKeyboardLayoutEx',  \
    LoadKeyboardLayoutW, <.pwszKLID, .flags>,  'LoadKeyboardLayoutW',  \
    LoadLocalFonts, <NONE>,  'LoadLocalFonts',  \
    LoadMenuA, <.hInstance, .lpString>,  'LoadMenuA',  \
    LoadMenuIndirectA, <.lpMenuTemplate>,  'LoadMenuIndirectA',  \
    LoadMenuIndirectW, <.lpMenuTemplate>,  'LoadMenuIndirectW',  \
    LoadMenuW, <.hInstance, .lpString>,  'LoadMenuW',  \
    LoadRemoteFonts, <NONE>,  'LoadRemoteFonts',  \
    LoadStringA, <.hInstance, .wID, .lpBuffer, .nBufferMax>,  'LoadStringA',  \
    LoadStringW, <.hInstance, .wID, .lpBuffer, .nBufferMax>,  'LoadStringW',  \
    LockSetForegroundWindow, <.uLockCode>,  'LockSetForegroundWindow',  \
    LockWindowStation, <NONE>,  'LockWindowStation',  \
    LockWindowUpdate, <.hwndLock>,  'LockWindowUpdate',  \
    LockWorkStation, <VOID>,  'LockWorkStation',  \
    LookupIconIdFromDirectory, <.presbits, .fIcon>,  'LookupIconIdFromDirectory',  \
    LookupIconIdFromDirectoryEx, <.presbits, .fIcon, .cxDesired, .cyDesired, .Flags>,  'LookupIconIdFromDirectoryEx',  \
    MBToWCSEx, <NONE>,  'MBToWCSEx',  \
    MB_GetString, <NONE>,  'MB_GetString',  \
    MapDialogRect, <.hDlg, .lpRect>,  'MapDialogRect',  \
    MapVirtualKeyA, <.wCode, .wMapType>,  'MapVirtualKeyA',  \
    MapVirtualKeyExA, <.uCode, .uMapType, .dwhkl>,  'MapVirtualKeyExA',  \
    MapVirtualKeyExW, <.uCode, .uMapType, .dwhkl>,  'MapVirtualKeyExW',  \
    MapVirtualKeyW, <.wCode, .wMapType>,  'MapVirtualKeyW',  \
    MapWindowPoints, <.hwndFrom, .hwndTo, .lppt, .cPoints>,  'MapWindowPoints',  \
    MenuItemFromPoint, <.hWnd, .hMenu, .ptScreen>,  'MenuItemFromPoint',  \
    MenuWindowProcA, <NONE>,  'MenuWindowProcA',  \
    MenuWindowProcW, <NONE>,  'MenuWindowProcW',  \
    MessageBeep, <.wType>,  'MessageBeep',  \
    MessageBoxA, <.hwnd, .lpText, .lpCaption, .wType>,  'MessageBoxA',  \
    MessageBoxExA, <.hwnd, .lpText, .lpCaption, .wType, .wLanguageId>,  'MessageBoxExA',  \
    MessageBoxExW, <.hwnd, .lpText, .lpCaption, .wType, .wLanguageId>,  'MessageBoxExW',  \
    MessageBoxIndirectA, <.lpMsgBoxParams>,  'MessageBoxIndirectA',  \
    MessageBoxIndirectW, <.lpMsgBoxParams>,  'MessageBoxIndirectW',  \
    MessageBoxTimeoutA, <NONE>,  'MessageBoxTimeoutA',  \
    MessageBoxTimeoutW, <NONE>,  'MessageBoxTimeoutW',  \
    MessageBoxW, <.hwnd, .lpText, .lpCaption, .wType>,  'MessageBoxW',  \
    ModifyMenuA, <.hMenu, .nPosition, .wFlags, .wIDNewItem, .lpString>,  'ModifyMenuA',  \
    ModifyMenuW, <.hMenu, .nPosition, .wFlags, .wIDNewItem, .lpString>,  'ModifyMenuW',  \
    MonitorFromPoint, <.pt, .dwFlags>,  'MonitorFromPoint',  \
    MonitorFromRect, <.lprc, .dwFlags>,  'MonitorFromRect',  \
    MonitorFromWindow, <.hwnd, .dwFlags>,  'MonitorFromWindow',  \
    MoveWindow, <.hwnd, .x, .y, .nWidth, .nHeight, .fBoolean>,  'MoveWindow',  \
    MsgWaitForMultipleObjects, <.nCount, .pHandles, .fWaitAll, .dwMilliseconds, .dwWakeMask>,  'MsgWaitForMultipleObjects',  \
    MsgWaitForMultipleObjectsEx, <.nCount, .pHandles, .dwMilliseconds, .dwWakeMask, .dwFlags>,  'MsgWaitForMultipleObjectsEx',  \
    NotifyWinEvent, <.lEvent, .hwnd, .idObject, .idChild>,  'NotifyWinEvent',  \
    OemKeyScan, <.wOemChar>,  'OemKeyScan',  \
    OemToCharA, <.lpszSrc, .lpszDst>,  'OemToCharA',  \
    OemToCharBuffA, <.lpszSrc, .lpszDst, .cchDstLength>,  'OemToCharBuffA',  \
    OemToCharBuffW, <.lpszSrc, .lpszDst, .cchDstLength>,  'OemToCharBuffW',  \
    OemToCharW, <.lpszSrc, .lpszDst>,  'OemToCharW',  \
    OffsetRect, <.lpRect, .x, .y>,  'OffsetRect',  \
    OpenClipboard, <.hwnd>,  'OpenClipboard',  \
    OpenDesktopA, <.lpszDesktop, .dwFlags, .fInherit, .dwDesiredAccess>,  'OpenDesktopA',  \
    OpenDesktopW, <.lpszDesktop, .dwFlags, .fInherit, .dwDesiredAccess>,  'OpenDesktopW',  \
    OpenIcon, <.hwnd>,  'OpenIcon',  \
    OpenInputDesktop, <.dwFlags, .fInherit, .dwDesiredAccess>,  'OpenInputDesktop',  \
    OpenWindowStationA, <.lpszWinSta, .fInherit, .dwDesiredAccess>,  'OpenWindowStationA',  \
    OpenWindowStationW, <.lpszWinSta, .fInherit, .dwDesiredAccess>,  'OpenWindowStationW',  \
    PackDDElParam, <.msg, .uiLo, .uiHi>,  'PackDDElParam',  \
    PaintDesktop, <.hdc>,  'PaintDesktop',  \
    PaintMenuBar, <NONE>,  'PaintMenuBar',  \
    PeekMessageA, <.lpMsg, .hwnd, .wMsgFilterMin, .wMsgFilterMax, .wRemoveMsg>,  'PeekMessageA',  \
    PeekMessageW, <.lpMsg, .hwnd, .wMsgFilterMin, .wMsgFilterMax, .wRemoveMsg>,  'PeekMessageW',  \
    PostMessageA, <.hwnd, .wMsg, .wParam, .lParam>,  'PostMessageA',  \
    PostMessageW, <.hwnd, .wMsg, .wParam, .lParam>,  'PostMessageW',  \
    PostQuitMessage, <.nExitCode>,  'PostQuitMessage',  \
    PostThreadMessageA, <.idThread, .msg, .wParam, .lParam>,  'PostThreadMessageA',  \
    PostThreadMessageW, <.idThread, .msg, .wParam, .lParam>,  'PostThreadMessageW',  \
    PrintWindow, <.hWnd, .hdcBlt, .nFlags>,  'PrintWindow',  \
    PrivateExtractIconExA, <NONE>,  'PrivateExtractIconExA',  \
    PrivateExtractIconExW, <NONE>,  'PrivateExtractIconExW',  \
    PrivateExtractIconsA, <NONE>,  'PrivateExtractIconsA',  \
    PrivateExtractIconsW, <NONE>,  'PrivateExtractIconsW',  \
    PrivateSetDbgTag, <NONE>,  'PrivateSetDbgTag',  \
    PrivateSetRipFlags, <NONE>,  'PrivateSetRipFlags',  \
    PtInRect, <.lpRect, .x, .y>,  'PtInRect',  \
    QuerySendMessage, <NONE>,  'QuerySendMessage',  \
    QueryUserCounters, <NONE>,  'QueryUserCounters',  \
    RealChildWindowFromPoint, <.hwndParent, .ptParentClientCoords>,  'RealChildWindowFromPoint',  \
    RealGetWindowClass, <.hwnd, .pszType, .cchType>,  'RealGetWindowClass',  \
    RealGetWindowClassA, <.hwnd, .pszType, .cchType>,  'RealGetWindowClassA',  \
    RealGetWindowClassW, <.hwnd, .pszType, .cchType>,  'RealGetWindowClassW',  \
    ReasonCodeNeedsBugID, <NONE>,  'ReasonCodeNeedsBugID',  \
    ReasonCodeNeedsComment, <NONE>,  'ReasonCodeNeedsComment',  \
    RecordShutdownReason, <NONE>,  'RecordShutdownReason',  \
    RedrawWindow, <.hwnd, .lprcUpdate, .hrgnUpdate, .fuRedraw>,  'RedrawWindow',  \
    RegisterClassA, <.Class>,  'RegisterClassA',  \
    RegisterClassExA, <.pcWndClassEx>,  'RegisterClassExA',  \
    RegisterClassExW, <.pcWndClassEx>,  'RegisterClassExW',  \
    RegisterClassW, <.Class>,  'RegisterClassW',  \
    RegisterClipboardFormatA, <.lpString>,  'RegisterClipboardFormatA',  \
    RegisterClipboardFormatW, <.lpString>,  'RegisterClipboardFormatW',  \
    RegisterDeviceNotificationA, <.hRecipient, .NotificationFilter, .Flags>,  'RegisterDeviceNotificationA',  \
    RegisterDeviceNotificationW, <.hRecipient, .NotificationFilter, .Flags>,  'RegisterDeviceNotificationW',  \
    RegisterHotKey, <.hwnd, .id, .fsModifiers, .vk>,  'RegisterHotKey',  \
    RegisterLogonProcess, <NONE>,  'RegisterLogonProcess',  \
    RegisterMessagePumpHook, <NONE>,  'RegisterMessagePumpHook',  \
    RegisterRawInputDevices, <NONE>,  'RegisterRawInputDevices',  \
    RegisterServicesProcess, <NONE>,  'RegisterServicesProcess',  \
    RegisterShellHookWindow, <NONE>,  'RegisterShellHookWindow',  \
    RegisterSystemThread, <NONE>,  'RegisterSystemThread',  \
    RegisterTasklist, <NONE>,  'RegisterTasklist',  \
    RegisterUserApiHook, <NONE>,  'RegisterUserApiHook',  \
    RegisterWindowMessageA, <.lpString>,  'RegisterWindowMessageA',  \
    RegisterWindowMessageW, <.lpString>,  'RegisterWindowMessageW',  \
    ReleaseCapture, <VOID>,  'ReleaseCapture',  \
    ReleaseDC, <.hwnd, .hdc>,  'ReleaseDC',  \
    RemoveMenu, <.hMenu, .nPosition, .wFlags>,  'RemoveMenu',  \
    RemovePropA, <.hwnd, .lpString>,  'RemovePropA',  \
    RemovePropW, <.hwnd, .lpString>,  'RemovePropW',  \
    ReplyMessage, <.lReply>,  'ReplyMessage',  \
    ResolveDesktopForWOW, <NONE>,  'ResolveDesktopForWOW',  \
    ReuseDDElParam, <.lParam, .msgIn, .msgOut, .uiLo, .uiHi>,  'ReuseDDElParam',  \
    ScreenToClient, <.hwnd, .lpPoint>,  'ScreenToClient',  \
    ScrollChildren, <NONE>,  'ScrollChildren',  \
    ScrollDC, <.hdc, .dx, .dy, .lprcScroll, .lprcClip, .hrgnUpdate, .lprcUpdate>,  'ScrollDC',  \
    ScrollWindow, <.hWnd, .XAmount, .YAmount, .lpRect, .lpClipRect>,  'ScrollWindow',  \
    ScrollWindowEx, <.hwnd, .dx, .dy, .lprcScroll, .lprcClip, .hrgnUpdate, .lprcUpdate, .fuScroll>,  'ScrollWindowEx',  \
    SendDlgItemMessageA, <.hDlg, .nIDDlgItem, .wMsg, .wParam, .lParam>,  'SendDlgItemMessageA',  \
    SendDlgItemMessageW, <.hDlg, .nIDDlgItem, .wMsg, .wParam, .lParam>,  'SendDlgItemMessageW',  \
    SendIMEMessageExA, <.hwnd, .lparam>,  'SendIMEMessageExA',  \
    SendIMEMessageExW, <.hwnd, .lparam>,  'SendIMEMessageExW',  \
    SendInput, <.cInputs, .pInputs, .cbSize>,  'SendInput',  \
    SendMessageA, <.hwnd, .wMsg, .wParam, .lParam>,  'SendMessageA',  \
    SendMessageCallbackA, <.hwnd, .wMsg, .wParam, .lParam, .lpResultCallBack, .dwData>,  'SendMessageCallbackA',  \
    SendMessageCallbackW, <.hwnd, .wMsg, .wParam, .lParam, .lpResultCallBack, .dwData>,  'SendMessageCallbackW',  \
    SendMessageTimeoutA, <.hwnd, .msg, .wParam, .lParam, .fuFlags, .uTimeout, .lpdwResult>,  'SendMessageTimeoutA',  \
    SendMessageTimeoutW, <.hwnd, .msg, .wParam, .lParam, .fuFlags, .uTimeout, .lpdwResult>,  'SendMessageTimeoutW',  \
    SendMessageW, <.hwnd, .wMsg, .wParam, .lParam>,  'SendMessageW',  \
    SendNotifyMessageA, <.hwnd, .msg, .wParam, .lParam>,  'SendNotifyMessageA',  \
    SendNotifyMessageW, <.hwnd, .msg, .wParam, .lParam>,  'SendNotifyMessageW',  \
    SetActiveWindow, <.hwnd>,  'SetActiveWindow',  \
    SetCapture, <.hwnd>,  'SetCapture',  \
    SetCaretBlinkTime, <.wMSeconds>,  'SetCaretBlinkTime',  \
    SetCaretPos, <.x, .y>,  'SetCaretPos',  \
    SetClassLongA, <.hwnd, .nIndex, .dwNewLong>,  'SetClassLongA',  \
    SetClassLongW, <.hwnd, .nIndex, .dwNewLong>,  'SetClassLongW',  \
    SetClassWord, <.hwnd, .nIndex, .wNewWord>,  'SetClassWord',  \
    SetClipboardData, <.uFormat, .hMem>,  'SetClipboardData',  \
    SetClipboardViewer, <.hwnd>,  'SetClipboardViewer',  \
    SetConsoleReserveKeys, <NONE>,  'SetConsoleReserveKeys',  \
    SetCursor, <.hCursor>,  'SetCursor',  \
    SetCursorContents, <NONE>,  'SetCursorContents',  \
    SetCursorPos, <.x, .y>,  'SetCursorPos',  \
    SetDebugErrorLevel, <.dwLevel>,  'SetDebugErrorLevel',  \
    SetDeskWallpaper, <NONE>,  'SetDeskWallpaper',  \
    SetDlgItemInt, <.hDlg, .nIDDlgItem, .wValue, .bSigned>,  'SetDlgItemInt',  \
    SetDlgItemTextA, <.hDlg, .nIDDlgItem, .lpString>,  'SetDlgItemTextA',  \
    SetDlgItemTextW, <.hDlg, .nIDDlgItem, .lpString>,  'SetDlgItemTextW',  \
    SetDoubleClickTime, <.wCount>,  'SetDoubleClickTime',  \
    SetFocus, <.hwnd>,  'SetFocus',  \
    SetForegroundWindow, <.hwnd>,  'SetForegroundWindow',  \
    SetInternalWindowPos, <NONE>,  'SetInternalWindowPos',  \
    SetKeyboardState, <.lppbKeyState>,  'SetKeyboardState',  \
    SetLastErrorEx, <.dwErrCode, .dwType>,  'SetLastErrorEx',  \
    SetLayeredWindowAttributes, <.hwnd, .crKey, .bAlpha, .dwFlags>,  'SetLayeredWindowAttributes',  \
    SetLogonNotifyWindow, <NONE>,  'SetLogonNotifyWindow',  \
    SetMenu, <.hwnd, .hMenu>,  'SetMenu',  \
    SetMenuContextHelpId, <.hMenu, .dw>,  'SetMenuContextHelpId',  \
    SetMenuDefaultItem, <.hMenu, .uItem, .fByPos>,  'SetMenuDefaultItem',  \
    SetMenuInfo, <.hmenu, .LPCMENUINFO>,  'SetMenuInfo',  \
    SetMenuItemBitmaps, <.hMenu, .nPosition, .wFlags, .hBitmapUnchecked, .hBitmapChecked>,  'SetMenuItemBitmaps',  \
    SetMenuItemInfoA, <.hMenu, .un, .fBoolean, .lpcMenuItemInfo>,  'SetMenuItemInfoA',  \
    SetMenuItemInfoW, <.hMenu, .un, .fBoolean, .lpcMenuItemInfo>,  'SetMenuItemInfoW',  \
    SetMessageExtraInfo, <.lParam>,  'SetMessageExtraInfo',  \
    SetMessageQueue, <.cMessagesMax>,  'SetMessageQueue',  \
    SetParent, <.hWndChild, .hWndNewParent>,  'SetParent',  \
    SetProcessDefaultLayout, <.dwDefaultLayout>,  'SetProcessDefaultLayout',  \
    SetProcessWindowStation, <.hWinSta>,  'SetProcessWindowStation',  \
    SetProgmanWindow, <NONE>,  'SetProgmanWindow',  \
    SetPropA, <.hwnd, .lpString, .hData>,  'SetPropA',  \
    SetPropW, <.hwnd, .lpString, .hData>,  'SetPropW',  \
    SetRect, <.lpRect, .X1, .Y1, .X2, .Y2>,  'SetRect',  \
    SetRectEmpty, <.lpRect>,  'SetRectEmpty',  \
    SetScrollInfo, <.hWnd, .n, .lpcScrollInfo, .bool>,  'SetScrollInfo',  \
    SetScrollPos, <.hwnd, .nBar, .nPos, .fBoolean>,  'SetScrollPos',  \
    SetScrollRange, <.hwnd, .nBar, .nMinPos, .nMaxPos, .bRedraw>,  'SetScrollRange',  \
    SetShellWindow, <NONE>,  'SetShellWindow',  \
    SetShellWindowEx, <NONE>,  'SetShellWindowEx',  \
    SetSysColors, <.nChanges, .lpSysColor, .lpColorValues>,  'SetSysColors',  \
    SetSysColorsTemp, <NONE>,  'SetSysColorsTemp',  \
    SetSystemCursor, <.hcur, .id>,  'SetSystemCursor',  \
    SetSystemMenu, <NONE>,  'SetSystemMenu',  \
    SetSystemTimer, <NONE>,  'SetSystemTimer',  \
    SetTaskmanWindow, <NONE>,  'SetTaskmanWindow',  \
    SetThreadDesktop, <.hDesktop>,  'SetThreadDesktop',  \
    SetTimer, <.hWnd, .nIDEvent, .uElapse, .lpTimerFunc>,  'SetTimer',  \
    SetUserObjectInformationA, <.hObj, .nIndex, .pvInfo, .nLength>,  'SetUserObjectInformationA',  \
    SetUserObjectInformationW, <.hObj, .nIndex, .pvInfo, .nLength>,  'SetUserObjectInformationW',  \
    SetUserObjectSecurity, <.hObj, .pSIRequested, .pSd>,  'SetUserObjectSecurity',  \
    SetWinEventHook, <.eventMin, .eventMax, .hmodWinEventProc, .pfnWinEventProc, .idProcess, .idThread, .dwFlags>,  'SetWinEventHook',  \
    SetWindowContextHelpId, <.hWnd, .dw>,  'SetWindowContextHelpId',  \
    SetWindowLongA, <.hwnd, .nIndex, .dwNewLong>,  'SetWindowLongA',  \
    SetWindowLongW, <.hwnd, .nIndex, .dwNewLong>,  'SetWindowLongW',  \
    SetWindowPlacement, <.hwnd, .lpwndpl>,  'SetWindowPlacement',  \
    SetWindowPos, <.hwnd, .hWndInsertAfter, .x, .y, .cx, .cy, .wFlags>,  'SetWindowPos',  \
    SetWindowRgn, <.hWnd, .hRgn, .bRedraw>,  'SetWindowRgn',  \
    SetWindowStationUser, <NONE>,  'SetWindowStationUser',  \
    SetWindowTextA, <.hwnd, .lpString>,  'SetWindowTextA',  \
    SetWindowTextW, <.hwnd, .lpString>,  'SetWindowTextW',  \
    SetWindowWord, <.hwnd, .nIndex, .wNewWord>,  'SetWindowWord',  \
    SetWindowsHookA, <.nFilterType, .pfnFilterProc>,  'SetWindowsHookA',  \
    SetWindowsHookExA, <.idHook, .lpfn, .hmod, .dwThreadId>,  'SetWindowsHookExA',  \
    SetWindowsHookExW, <.idHook, .lpfn, .hmod, .dwThreadId>,  'SetWindowsHookExW',  \
    SetWindowsHookW, <.nFilterType, .pfnFilterProc>,  'SetWindowsHookW',  \
    ShowCaret, <.hwnd>,  'ShowCaret',  \
    ShowCursor, <.bShow>,  'ShowCursor',  \
    ShowOwnedPopups, <.hwnd, .fBoolean>,  'ShowOwnedPopups',  \
    ShowScrollBar, <.hwnd, .wBar, .bShow>,  'ShowScrollBar',  \
    ShowStartGlass, <NONE>,  'ShowStartGlass',  \
    ShowWindow, <.hwnd, .nCmdShow>,  'ShowWindow',  \
    ShowWindowAsync, <.hWnd, .nCmdShow>,  'ShowWindowAsync',  \
    SoftModalMessageBox, <NONE>,  'SoftModalMessageBox',  \
    SubtractRect, <.lprcDst, .lprcSrc1, .lprcSrc2>,  'SubtractRect',  \
    SwapMouseButton, <.bSwap>,  'SwapMouseButton',  \
    SwitchDesktop, <.hDesktop>,  'SwitchDesktop',  \
    SwitchToThisWindow, <NONE>,  'SwitchToThisWindow',  \
    SystemParametersInfoA, <.uAction, .uParam, .ByRef, .fuWinIni>,  'SystemParametersInfoA',  \
    SystemParametersInfoW, <.uAction, .uParam, .ByRef, .fuWinIni>,  'SystemParametersInfoW',  \
    TabbedTextOutA, <.hdc, .x, .y, .lpString, .nCount, .nTabPositions, .lpnTabStopPositions, .nTabOrigin>,  'TabbedTextOutA',  \
    TabbedTextOutW, <.hdc, .x, .y, .lpString, .nCount, .nTabPositions, .lpnTabStopPositions, .nTabOrigin>,  'TabbedTextOutW',  \
    TileChildWindows, <NONE>,  'TileChildWindows',  \
    TileWindows, <.hwndParent, .wHow, .lpRect, .cKids, .lpKids>,  'TileWindows',  \
    ToAscii, <.uVirtKey, .uScanCode, .lpbKeyState, .lpwTransKey, .fuState>,  'ToAscii',  \
    ToAsciiEx, <.uVirtKey, .uScanCode, .lpKeyState, .lpChar, .uFlags, .dwhkl>,  'ToAsciiEx',  \
    ToUnicode, <.wVirtKey, .wScanCode, .lpKeyState, .pwszBuff, .cchBuff, .wFlags>,  'ToUnicode',  \
    ToUnicodeEx, <.wVirtKey, .wScanCode, .lpKeyState, .pwszBuff, .cchBuff, .wFlags, .dwhkl>,  'ToUnicodeEx',  \
    TrackMouseEvent, <.lpEventTrack>,  'TrackMouseEvent',  \
    TrackPopupMenu, <.hMenu, .uFlags, .x, .y, .nReserved, .hwnd, .lprc>,  'TrackPopupMenu',  \
    TrackPopupMenuEx, <.hMenu, .un, .n1, .n2, .hWnd, .lpTPMParams>,  'TrackPopupMenuEx',  \
    TranslateAccelerator, <.hwnd, .hAccTable, .lpMsg>,  'TranslateAccelerator',  \
    TranslateAcceleratorA, <.hwnd, .hAccTable, .lpMsg>,  'TranslateAcceleratorA',  \
    TranslateAcceleratorW, <.hwnd, .hAccTable, .lpMsg>,  'TranslateAcceleratorW',  \
    TranslateMDISysAccel, <.hWndClient, .lpMsg>,  'TranslateMDISysAccel',  \
    TranslateMessage, <.lpMsg>,  'TranslateMessage',  \
    TranslateMessageEx, <NONE>,  'TranslateMessageEx',  \
    UnhookWinEvent, <.hWinEventHook>,  'UnhookWinEvent',  \
    UnhookWindowsHook, <.nCode, .pfnFilterProc>,  'UnhookWindowsHook',  \
    UnhookWindowsHookEx, <.hHook>,  'UnhookWindowsHookEx',  \
    UnionRect, <.lpDestRect, .lpSrc1Rect, .lpSrc2Rect>,  'UnionRect',  \
    UnloadKeyboardLayout, <.HKL>,  'UnloadKeyboardLayout',  \
    UnlockWindowStation, <NONE>,  'UnlockWindowStation',  \
    UnpackDDElParam, <.msg, .lParam, .puiLo, .puiHi>,  'UnpackDDElParam',  \
    UnregisterClassA, <.lpClassName, .hInstance>,  'UnregisterClassA',  \
    UnregisterClassW, <.lpClassName, .hInstance>,  'UnregisterClassW',  \
    UnregisterDeviceNotification, <.Handle>,  'UnregisterDeviceNotification',  \
    UnregisterHotKey, <.hwnd, .id>,  'UnregisterHotKey',  \
    UnregisterMessagePumpHook, <NONE>,  'UnregisterMessagePumpHook',  \
    UnregisterUserApiHook, <NONE>,  'UnregisterUserApiHook',  \
    UpdateLayeredWindow, <.hWnd, .hdcDst, .pptDst, .psize, .hdcSrc, .pptSrc, .crKey, .pblend, .dwFlags>,  'UpdateLayeredWindow',  \
    UpdatePerUserSystemParameters, <NONE>,  'UpdatePerUserSystemParameters',  \
    UpdateWindow, <.hwnd>,  'UpdateWindow',  \
    User32InitializeImmEntryTable, <NONE>,  'User32InitializeImmEntryTable',  \
    UserClientDllInitialize, <NONE>,  'UserClientDllInitialize',  \
    UserHandleGrantAccess, <.hUserHandle, .hJob, .bGrant>,  'UserHandleGrantAccess',  \
    UserLpkPSMTextOut, <NONE>,  'UserLpkPSMTextOut',  \
    UserLpkTabbedTextOut, <NONE>,  'UserLpkTabbedTextOut',  \
    UserRealizePalette, <NONE>,  'UserRealizePalette',  \
    UserRegisterWowHandlers, <NONE>,  'UserRegisterWowHandlers',  \
    VRipOutput, <NONE>,  'VRipOutput',  \
    VTagOutput, <NONE>,  'VTagOutput',  \
    ValidateRect, <.hwnd, .lpRect>,  'ValidateRect',  \
    ValidateRgn, <.hwnd, .hRgn>,  'ValidateRgn',  \
    VkKeyScanA, <.cChar>,  'VkKeyScanA',  \
    VkKeyScanExA, <.ch, .dwhkl>,  'VkKeyScanExA',  \
    VkKeyScanExW, <.ch, .dwhkl>,  'VkKeyScanExW',  \
    VkKeyScanW, <.cChar>,  'VkKeyScanW',  \
    WCSToMBEx, <NONE>,  'WCSToMBEx',  \
    WINNLSEnableIME, <.hwnd, .bool>,  'WINNLSEnableIME',  \
    WINNLSGetEnableStatus, <.hwnd>,  'WINNLSGetEnableStatus',  \
    WINNLSGetIMEHotkey, <.hwnd>,  'WINNLSGetIMEHotkey',  \
    WaitForInputIdle, <.hProcess, .dwMilliseconds>,  'WaitForInputIdle',  \
    WaitMessage, <VOID>,  'WaitMessage',  \
    Win32PoolAllocationStats, <NONE>,  'Win32PoolAllocationStats',  \
    WinHelpA, <.hwnd, .lpHelpFile, .wCommand, .dwData>,  'WinHelpA',  \
    WinHelpW, <.hwnd, .lpHelpFile, .wCommand, .dwData>,  'WinHelpW',  \
    WindowFromDC, <.hdc>,  'WindowFromDC',  \
    WindowFromPoint, <.xPoint, .yPoint>,  'WindowFromPoint',  \
    keybd_event, <.bVk, .bScan, .dwFlags, .dwExtraInfo>,  'keybd_event',  \
    mouse_event, <.dwFlags, .dx, .dy, .cButtons, .dwExtraInfo>,  'mouse_event',  \
    wsprintfA, <.lpOut, .lpFmt, .etc>,  'wsprintfA',  \
    wsprintfW, <.lpOut, .lpFmt, .etc>,  'wsprintfW',  \
    wvsprintfA, <NONE>,  'wvsprintfA',  \
    wvsprintfW, <NONE>,  'wvsprintfW'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/imports/Win32/wsock32.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: wsock32.dll API calls
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


import_proto wsock32,  \
    AcceptEx, <.sListenSocket, .sAcceptSocket, .lpOutputBuffer, .dwReceiveDataLength, .dwLocalAddressLength, .dwRemoteAddressLength,  \
        .lpdwBytesReceived, .lpOverlapped>,  'AcceptEx',  \
    EnumProtocolsA, <.lpiProtocols, .lpProtocolBuffer, .lpdwBufferLength>,  'EnumProtocolsA',  \
    EnumProtocolsW, <.lpiProtocols, .lpProtocolBuffer, .lpdwBufferLength>,  'EnumProtocolsW',  \
    GetAcceptExSockaddrs, <.lpOutputBuffer, .dwReceiveDataLength, .dwLocalAddressLength, .dwRemoteAddressLength, .LocalSockaddr, .LocalSockaddrLength,  \
        .RemoteSockaddr, .RemoteSockaddrLength>,  'GetAcceptExSockaddrs',  \
    GetAddressByNameA, <.dwNameSpace, .lpServiceType, .lpServiceName, .lpiProtocols, .dwResolution, .lpServiceAs, .lpCsaddrBuffer,  \
        .lpdwBufferLength, .lpAliasBuffer, .lpdwAliasBufferLength>,  'GetAddressByNameA',  \
    GetAddressByNameW, <.dwNameSpace, .lpServiceType, .lpServiceName, .lpiProtocols, .dwResolution, .lpServiceAs, .lpCsaddrBuffer,  \
        .lpdwBufferLength, .lpAliasBuffer, .lpdwAliasBufferLength>,  'GetAddressByNameW',  \
    GetNameByTypeA, <.lpServiceType, .lpServiceName, .dwNameLength>,  'GetNameByTypeA',  \
    GetNameByTypeW, <.lpServiceType, .lpServiceName, .dwNameLength>,  'GetNameByTypeW',  \
    GetServiceA, <.dwNameSpace, .lpGuid, .lpServiceName, .dwProperties, .lpBuffer, .lpdwBufferSize, .lpServiceAs>,  'GetServiceA',  \
    GetServiceW, <.dwNameSpace, .lpGuid, .lpServiceName, .dwProperties, .lpBuffer, .lpdwBufferSize, .lpServiceAs>,  'GetServiceW',  \
    GetTypeByNameA, <.lpServiceName, .lpServiceType>,  'GetTypeByNameA',  \
    GetTypeByNameW, <.lpServiceName, .lpServiceType>,  'GetTypeByNameW',  \
    MigrateWinsockConfiguration, <NONE>,  'MigrateWinsockConfiguration',  \
    NPLoadNameSpaces, <NONE>,  'NPLoadNameSpaces',  \
    SetServiceA, <.dwNameSpace, .dwOperation, .dwFlags, .lpServiceInfo, .lpServiceAsyncInfo, .lpdwStatusFlags>,  'SetServiceA',  \
    SetServiceW, <.dwNameSpace, .dwOperation, .dwFlags, .lpServiceInfo, .lpServiceAsyncInfo, .lpdwStatusFlags>,  'SetServiceW',  \
    TransmitFile, <.hSocket, .hFile, .nNumberOfBytesToWrite, .nNumberOfBytesPerSend, .lpOverlapped, .lpTransmitBuffers, .dwReserved,  \
      >,  'TransmitFile',  \
    WEP, <NONE>,  'WEP',  \
    WSAAsyncGetHostByAddr, <.hWnd, .wMsg, .addr, .lLen, .lType, .buf, .buflen>,  'WSAAsyncGetHostByAddr',  \
    WSAAsyncGetHostByName, <.hWnd, .wMsg, .name, .buf, .buflen>,  'WSAAsyncGetHostByName',  \
    WSAAsyncGetProtoByName, <.hWnd, .wMsg, .name, .buf, .buflen>,  'WSAAsyncGetProtoByName',  \
    WSAAsyncGetProtoByNumber, <.hWnd, .wMsg, .number, .buf, .buflen>,  'WSAAsyncGetProtoByNumber',  \
    WSAAsyncGetServByName, <.hWnd, .wMsg, .name, .proto, .buf, .buflen>,  'WSAAsyncGetServByName',  \
    WSAAsyncGetServByPort, <.hWnd, .wMsg, .port, .proto, .buf, .buflen>,  'WSAAsyncGetServByPort',  \
    WSAAsyncSelect, <.s, .hWnd, .wMsg, .lEvent>,  'WSAAsyncSelect',  \
    WSACancelAsyncRequest, <.hAsyncTaskHandle>,  'WSACancelAsyncRequest',  \
    WSACancelBlockingCall, <VOID>,  'WSACancelBlockingCall',  \
    WSACleanup, <VOID>,  'WSACleanup',  \
    WSAGetLastError, <VOID>,  'WSAGetLastError',  \
    WSAIsBlocking, <VOID>,  'WSAIsBlocking',  \
    WSARecvEx, <.s, .buf, .lLen, .flags>,  'WSARecvEx',  \
    WSASetBlockingHook, <.lpBlockFunc>,  'WSASetBlockingHook',  \
    WSASetLastError, <.iError>,  'WSASetLastError',  \
    WSAStartup, <.wVersionRequired, .lpWSAData>,  'WSAStartup',  \
    WSAUnhookBlockingHook, <VOID>,  'WSAUnhookBlockingHook',  \
    WSApSetPostRoutine, <NONE>,  'WSApSetPostRoutine',  \
    __WSAFDIsSet, <NONE>,  '__WSAFDIsSet',  \
    accept, <.s, .addr, .addrlen>,  'accept',  \
    bind, <.s, .addr, .namelen>,  'bind',  \
    closesocket, <.s>,  'closesocket',  \
    connect, <.s, .name, .namelen>,  'connect',  \
    dn_expand, <NONE>,  'dn_expand',  \
    gethostbyaddr, <.addr, .len, .type>,  'gethostbyaddr',  \
    gethostbyname, <.name>,  'gethostbyname',  \
    gethostname, <.name, .namelen>,  'gethostname',  \
    getnetbyname, <NONE>,  'getnetbyname',  \
    getpeername, <.s, .name, .namelen>,  'getpeername',  \
    getprotobyname, <.name>,  'getprotobyname',  \
    getprotobynumber, <.number>,  'getprotobynumber',  \
    getservbyname, <.name, .proto>,  'getservbyname',  \
    getservbyport, <.port, .proto>,  'getservbyport',  \
    getsockname, <.s, .name, .namelen>,  'getsockname',  \
    getsockopt, <.s, .level, .optname, .optval, .optlen>,  'getsockopt',  \
    htonl, <.hostlong>,  'htonl',  \
    htons, <.hostshort>,  'htons',  \
    inet_addr, <.cp>,  'inet_addr',  \
    inet_network, <NONE>,  'inet_network',  \
    inet_ntoa, <.lIn>,  'inet_ntoa',  \
    ioctlsocket, <.s, .cmd, .argp>,  'ioctlsocket',  \
    listen, <.s, .backlog>,  'listen',  \
    ntohl, <.netlong>,  'ntohl',  \
    ntohs, <.netshort>,  'ntohs',  \
    rcmd, <NONE>,  'rcmd',  \
    recv, <.s, .buf, .lLen, .flags>,  'recv',  \
    recvfrom, <.s, .buf, .lLen, .flags, .from, .fromlen>,  'recvfrom',  \
    rexec, <NONE>,  'rexec',  \
    rresvport, <NONE>,  'rresvport',  \
    s_perror, <NONE>,  's_perror',  \
    select, <NONE>,  'select',  \
    send, <.s, .buf, .lLen, .flags>,  'send',  \
    sendto, <.s, .buf, .lLen, .flags, .to, .tolen>,  'sendto',  \
    sethostname, <NONE>,  'sethostname',  \
    setsockopt, <.s, .level, .optname, .optval, .optlen>,  'setsockopt',  \
    shutdown, <.s, .how>,  'shutdown',  \
    socket, <.af, .lType, .protocol>,  'socket'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































Deleted freshlib/macros/Linux/_elf.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: ELF format macros. Used internally in _import.inc
;
;  Target OS: Linux (ELF)
;
;  Dependencies:
;
;  Notes: The form and use of these macros is somehow unsystematic.
;_________________________________________________________________________________________


macro Elf32_Sym name,value,size,bind,type,other,shndx
{
 dd name+0
 dd value+0
 dd size+0
 db (bind+0) shl 4 + (type+0)
 db other+0
 dw shndx+0
}

virtual at 0
 Elf32_Sym
 sizeof.Elf32_Sym = $
end virtual

macro Elf32_Rel offset,symbol,type
{
  dd offset+0
  dd (symbol+0) shl 8 + (type+0)
}

virtual at 0
 Elf32_Rel
 sizeof.Elf32_Rel = $
end virtual

macro Elf32_Rela offset,symbol,type,addend
{
  dd offset+0
  dd (symbol+0) shl 8 + (type+0)
  dd addend+0
}

virtual at 0
 Elf32_Rela
 sizeof.Elf32_Rela = $
end virtual

macro Elf64_Sym name,value,size,bind,type,other,shndx
{
 dd name+0
 db (bind+0) shl 4 + (type+0)
 db other+0
 dw shndx+0
 dq value+0
 dq size+0
}

virtual at 0
 Elf64_Sym
 sizeof.Elf64_Sym = $
end virtual

macro Elf64_Rel offset,symbol,type
{
  dq offset+0
  dq (symbol+0) shl 32 + (type+0)
}

virtual at 0
 Elf64_Rel
 sizeof.Elf64_Rel = $
end virtual

macro Elf64_Rela offset,symbol,type,addend
{
  dq offset+0
  dq (symbol+0) shl 32 + (type+0)
  dq addend+0
}

virtual at 0
 Elf64_Rela
 sizeof.Elf64_Rela = $
end virtual

DT_NULL    = 0
DT_NEEDED  = 1
DT_HASH    = 4
DT_STRTAB  = 5
DT_SYMTAB  = 6
DT_RELA    = 7
DT_RELASZ  = 8
DT_RELAENT = 9
DT_STRSZ   = 10
DT_SYMENT  = 11
DT_REL     = 17
DT_RELSZ   = 18
DT_RELENT  = 19

STB_LOCAL  = 0
STB_GLOBAL = 1
STB_WEAK   = 2

STT_NOTYPE  = 0
STT_OBJECT  = 1
STT_FUNC    = 2
STT_SECTION = 3
STT_FILE    = 4

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




















































































































































































































































































































Deleted freshlib/macros/Linux/_executable.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Executable file formating macro library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

TargetOS equ Linux

macro @BinaryType type {
  if type eq GUI
    format ELF executable 3
    entry start
  end if

  if type eq console
    format ELF executable 3
    entry start
  end if

  if type eq DLL
    format ELF executable  ; is it correct???
  end if

  segment readable writeable executable
}


macro @AllDataSection {
segment readable writeable
IncludeAllGlobals
}

macro @AllDataEmbeded {
IncludeAllGlobals
}

macro __create_all_imports {
  segment interpreter readable
  __importdata:

  rept DynamicLibList@count i:1 \{
    match name:filename, DynamicLibList\#i \\{
      \\include filename
    \\}
  \}

  interpreter '/lib/ld-linux.so.2'

  __ImportAll

  DispSize 'ELF Import data:', $-__importdata
}


macro @AllImportSection {
  __create_all_imports
}


macro @AllImportEmbeded {
  __create_all_imports
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































Deleted freshlib/macros/Linux/_import.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Macros for importing functions in Linux
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


include '_elf.inc'


macro interpreter [library]
{
 db library,0
}


; creates symbols list with needed libraries.
macro import_proto library, [iname, arg, ename]
{
  common
    local str, cnt, use
    match needed,needed@dynamic \{ define needed@dynamic needed, str:cnt:use:library \}
    match ,needed@dynamic \{ define needed@dynamic str:cnt:use:library \}

  forward
    match imported, imported@dynamic \{ define imported@dynamic imported, cnt:iname:ename \}
    match ,imported@dynamic \{ define imported@dynamic cnt:iname:ename \}
    define iname#@arg arg
}

define needed@dynamic
define imported@dynamic



macro __define_import_arguments_var [argument] {
common
  local ..start
  virtual at ebp+8
  ..start:
forward
  if ~argument eq ...
    argument dd ?
  else
    label .more… dword
  end if
common
  .__info.argsize = $ - ..start
  end virtual
}


macro __define_import_arguments name {
common
  if name#@arg eq VOID
    .__info.argtype=1
  else
    if name#@arg eq NONE
      .__info.argtype = 0
    else
      match A, name#@arg \{ __define_import_arguments_var A \}
      .__info.argtype = 2
    end if
  end if
}





macro __do_import [cntandnames]
{
common
  local strtab,strsz,symtab,rel,relsz,hash
  segment dynamic readable

  match needed, needed@dynamic \{
    irp item, needed \\{
      match str:cnt:use:library, item \\\{
        cnt = 0
        if use > 0
          dd DT_NEEDED, str-strtab
        end if
      \\\}
    \\}
  \}

  dd DT_STRTAB, strtab
  dd DT_STRSZ, strsz
  dd DT_SYMTAB, symtab
  dd DT_SYMENT, sizeof.Elf32_Sym
  dd DT_REL, rel
  dd DT_RELSZ, relsz
  dd DT_RELENT, sizeof.Elf32_Rel
  dd DT_HASH, hash
  dd DT_NULL, 0

  segment readable writeable
  symtab: Elf32_Sym

forward
  match cnt:iname:ename, cntandnames \{
    if used iname
      local fstr
      Elf32_Sym fstr-strtab,0,0,STB_GLOBAL,STT_FUNC,0,0
      cnt = cnt + 1
    end if
  \}

common
  rel:
  local counter
  counter = 1

forward
  match cnt:iname:ename, cntandnames \{
    if used iname
      Elf32_Rel iname, counter, R_386_32
      counter = counter + 1
    end if
  \}

common
  relsz = $-rel
  hash:
  dd 1, counter
  dd 0

  repeat counter
   if %=counter
    dd 0
   else
    dd %
   end if
  end repeat
  strtab db 0

forward
  match cnt:iname:ename, cntandnames \{
    if used iname
      fstr db ename, 0
    end if
  \}

common
  match needed, needed@dynamic \{
    irp item, needed \\{
      match str:cnt:use:library,item \\\{
        use = cnt
        if use > 0
          str db library, 0
        end if
      \\\}
    \\}
  \}
  strsz = $-strtab

forward
  match cnt:iname:ename, cntandnames \{
    label iname dword
    if used iname
       dd 0
    end if
   __define_import_arguments iname
  \}
}


macro __ImportAll {
  match arguments, __do_import imported@dynamic \{ arguments \}
}


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































Deleted freshlib/macros/Linux/_linproc.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Linux variant or return instruction for thread procedures.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

macro thread_return {
  cret
}




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































Deleted freshlib/macros/Linux/allmacros.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Combined include of all Linux specific macros.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

include '_import.inc'
include '_linproc.inc'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































Deleted freshlib/macros/Win32/_exceptions.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Win32 exception handling macros.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

..TryLevel = 0

macro beginTry {
  common
    ptrExceptionContext equ esp+$0c
    ptrExceptionRecord  equ esp+$04

    local ..handler, ..endtry
    end@try equ ..endtry

  if defined ..handler
        ..TryLevel = ..TryLevel+1
        pushd   ..handler
        pushd   [fs:0]
        mov     [fs:0], esp
  end if

  macro onException \{
        jmp     ..endtry
    ..handler:
  \}

  macro Ignore \{
        mov     eax, [ptrExceptionContext]
        mov     [eax+CONTEXT.regEip], ..endtry
        xor     eax, eax
        retn
  \}

  macro Retry \{
        xor     eax, eax
        retn
  \}


  macro Next \{
        mov     eax, 1
        retn
  \}
}



macro endTry {
common
  label end@try
  if ..TryLevel > 0
        popd    [fs:0]
        add     esp, 4
        ..TryLevel = ..TryLevel - 1
  end if
  purge onException
  purge Ignore
  purge Next
  purge Retry
  restore end@try
  restore ptrExceptionContext
  restore ptrExceptionRecord
}




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































Deleted freshlib/macros/Win32/_executable.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Executable file formating macro library.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

TargetOS equ Win32

macro @BinaryType type {
  if type eq GUI
    format PE GUI 4.0
    entry start
  end if

  if type eq console
    format PE Console 4.0
    entry start
  end if

  if type eq DLL
    format PE GUI 4.0 DLL
    entry EntryPoint
  end if

  section '.code' code readable writeable executable
}


macro @AllDataSection {
  section '.data' data readable writeable
  IncludeAllGlobals
}


macro @AllDataEmbeded {
  IncludeAllGlobals
}


macro __create_dll_list {
  DynamicLibList equ
  rept DynamicLibList@count i:1 \{
    match any, DynamicLibList \\{
      match name:filename, DynamicLibList\\#i \\\{
        DynamicLibList equ DynamicLibList, name, \\\`name\\\#'.dll'
      \\\}
    \\}

    match , DynamicLibList \\{
      match name:filename, DynamicLibList\\#i \\\{
        DynamicLibList equ name, \\\`name\\\#'.dll'
      \\\}
    \\}
  \}
}

macro __create_all_imports {
   __create_dll_list

   match liblist, DynamicLibList \{
     library liblist
   \}

  rept DynamicLibList@count i:1 \{
    match name:filename, DynamicLibList\#i \\{
      \\include filename
    \\}
  \}
}


macro @AllImportSection {
  section '.idata' import readable
    __create_all_imports
}


macro @AllImportEmbeded {
  data import
    __create_all_imports
  end data
}






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































Deleted freshlib/macros/Win32/_export.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Win32 export sections creating macros.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

; macroinstruction for making export section

macro export dllname,[label,string]     ; strings must be sorted
 { 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 }
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































Deleted freshlib/macros/Win32/_import.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Win32 import macros.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes: Only import_proto should be used in portable applications. Here we have some
;         old macros that needs revision or even removing.
;_________________________________________________________________________________________

; macroinstruction for making import section
macro library [name,string] {
forward
    local _label
    if name#.needed
    dd 0,0,0,RVA _label,RVA name
    end if
common
    dd 0,0,0,0,0
forward
    if name#.needed
    _label db string,0
    end if
 }


macro import name, [lbl, string]
 { common
    name:
   forward
    if used lbl
     local _label
     lbl dd RVA _label
    end if
   common
    if $ > name
     name#.needed = TRUE
     dd 0
    else
     name#.needed = FALSE
    end if
   forward
    if used lbl
    _label dw 0
           db string,0
    end if
  }



macro define_import_arguments [argument] {
common
  virtual at ebp+8
forward
  if ~ argument eq ...
    argument dd ?
  else
    label .more… dword
  end if
common
  end virtual
}



macro import_proto name, [lbl, arg, string] {
common
    name:
forward
    local ..lbl, ..used

    @label equ lbl

    ..used = 0
    if used lbl
      lbl dd RVA ..lbl
      ..used = 1
    else
      label lbl dword at 0
    end if

    if ~(arg eq NONE)
      if arg eq VOID
        .__info.argtype = 1
      else
        define_import_arguments arg
        .__info.argtype = 2
      end if
    else
     .__info.argtype = 0
    end if

common
    if $ > name
     name#.needed = TRUE
     dd 0
    else
     name#.needed = FALSE
    end if

forward
    if ..used
    ..lbl dw 0
          db string,0
    end if
}




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































Deleted freshlib/macros/Win32/_winproc.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Win32 specific macros. winproc is procedure for message handling.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes: Actually these macros are not OS dependent, but their usefulness for other
;         OS is unclear. Maybe they need some refactoring in order to be used OS
;         independently.
;_________________________________________________________________________________________

macro thread_return {
  return
}

;-----------------------------------------
; This file is part of Fresh standard
; macro library.
;-----------------------------------------


macro winproc name, [arg] {
common
  \err@endp

  macro err@endp \{
    end if
    Missing 'endwp' before the procedure.
  \}


  if ~ used name
    if defined options.ShowSkipped & options.ShowSkipped
      display 1,'Message procedure skipped: ',`name, $0d, $0a
    end if
  else

 name:
    .__info.id = 2
    .__info.start = $

  if arg eq
    virtual at ebp+8
      .hwnd dd ?
      .wmsg dd ?
      .wparam dd ?
      .lparam dd ?
      .__info.argsize = 16
    end virtual
  else
    virtual at ebp+8
      forward
        arg dd ?
        if ~ defined name#arg
          ERROR! the argument `arg MUST begin with dot
        end if
      common
        .__info.argsize = $ - ebp - 8
    end virtual
  end if

  if .__info.argsize <> 16
    Error! The count of `name arguments MUST be 4 dwords.
  end if

  virtual at ebp - .__info.commonframe.size
  .__info.commonframe.begin:
}



macro ondefault {  ; begins procedure instructions
common
        dispatch [ebp+12]
.ondefault:
}


macro onmessage message {
  .#message:
  .#message#.__info.id = 3
  .#message#.__info.number = casecounter
  oncase message
}


macro endwp {
common
    .__info.msgcount = casecounter
  enddp
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































Deleted freshlib/macros/Win32/allmacros.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Combined include of all Win32 specific macros.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

include '_winproc.inc'
include '_import.inc'
include '_export.inc'
include '_exceptions.inc'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































Deleted freshlib/macros/_datamacros.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Several data definition/manipulation macros.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

macro getfile lblname*, filename* {
  if used lblname
    lblname file filename
    .size = $ - lblname
  end if
}

macro StringTable [string] {
  forward
    local ..lbl
    dd  ..lbl
  common
    dd  0
  forward
..lbl db string, 0
}


macro IndexedStrings [lparam, string] {
  forward
    local ..lbl
    dd  ..lbl, lparam
  common
    dd  0
  forward
..lbl db string, 0
}


macro Sequence [seqname*, initvalue*] {
forward
  seqname#.current = initvalue
  macro seqname [name] \{
    name = seqname#.current
    seqname#.current = seqname#.current + 1
    if defined seqname#.display & seqname#.display
      disp iconInfo, `seqname, ' value: ', \`#name, ' = $', <name, 16>, $0d
    end if
  \}
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































Deleted freshlib/macros/_display.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Macro library for displaying compile time messages.
;
;  Target OS: Any (FASM compiler)
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

iconWarning = 1
iconError = 2
iconInfo = 3
iconFind = 4
iconNone  = 5
iconDebug = 6


macro __digit num
{
   if num < 10
    display '0'+num
   else
    display 'A'+num-10
   end if
}


macro _disp arg1, arg2
{
   if arg2 eq
    display arg1
   else
    local ..tmp
    ..tmp = arg1
    virtual at 0
     repeat 32
      if ..tmp > 0
       db ..tmp mod arg2
       ..tmp = ..tmp / arg2
      end if
     end repeat
     repeat $
      load ..tmp byte from $-%
      __digit ..tmp
     end repeat
     if $ = 0
      display '0'
     end if
    end virtual
   end if
}

macro disp [arg] { _disp arg }


macro DispSize Text, Sz {
  local size, suffix
  size = Sz;
  if defined options.ShowSizes & options.ShowSizes
    if Text eqtype "A"
      disp 3,"Sizeof [", Text, "] is: "
    else
      disp 3,"Sizeof [", `Text, "] is: "
    end if

    suffix = 'bytes'
    if Sz>10000
      size = size / 1024
      disp <size,10>, 'K',$0d,$0a
    else
      disp <size,10>, ' bytes.',$0d,$0a
    end if
  end if
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































Deleted freshlib/macros/_executable.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Executable file formating macro library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Includes OS dependent versions of the library.
;_________________________________________________________________________________________

include '%TargetOS%/_executable.inc'

macro module name {
  ___StartLibAddress = $
  ___LibraryName equ name
}

macro endmodule {
  DispSize ___LibraryName, $-___StartLibAddress
  restore ___LibraryName
}


macro uses [libname] {
forward
  local nm, fn
  nm equ libname
  fn equ '%lib%/imports/%TargetOS%/'#`libname#'.inc'
  match name:filename, libname \{
    nm equ name
    fn equ filename
  \}
  ppAddUniqueList DynamicLibList, nm#:#fn
}

ppInitList DynamicLibList


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































Deleted freshlib/macros/_globals.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;   Description: Macto library for global variables handling.
;
;   Target OS: Any
;
;   Dependencies:
;
;   Notes:
;_________________________________________________________________________________________

;------------------------------------------------------------------
; use "iglobal" for inserting initialized global data definitions.
;------------------------------------------------------------------
macro iglobal {
  IGlobals equ IGlobals,
  macro __IGlobalBlock \{
}


;-------------------------------------------------------------
; use 'uglobal' for inserting uninitialized global definitions.
; even when you define some data values, these variables
; will be stored as uninitialized data.
;-------------------------------------------------------------
macro uglobal {
  UGlobals equ UGlobals,
  macro __UGlobalBlock \{
}

; Use endg for ending iglobal and uglobal blocks.
endg fix }


macro IncludeIGlobals {
  macro IGlobals dummy, [n] \{
    __IGlobalBlock
    purge __IGlobalBlock
  \}
  match I, IGlobals \{
    I
  \}
}


macro IncludeUGlobals {
  macro UGlobals dummy, [n] \{
    \common
      \local begin, size
      begin = $
      virtual at $
    \forward
        __UGlobalBlock
        purge __UGlobalBlock
    \common
        size = $ - begin
      end virtual
      rb size
  \}
  match U, UGlobals \{
    U
  \}
}




;macro __InitStringsEngine {
;  local r,v,c
;  c equ 0
;
;  struc text [val] \{
;    \common
;      if ~val eqtype 1
;      virtual at 0
;    \forward
;        db val
;    \common
;      .length = $
;      end virtual
;      end if
;    rept 1 x:c+1 \\{
;      c equ x
;      r\\#x equ .
;      v\\#x equ val
;    \\}
;  \}
;
;  macro __IncludeAllStrings \{
;    \common
;    \local ..start, len, i, j, f, ch1, ch2
;    label ..start byte
;    if defined options.ShowSizes and options.ShowSizes
;      disp 3, 'String data address: $', <..start, 16>, 13
;      disp 3, 'String count: ', <c, 10>, 13
;    end if
;
;    rept c x \\{
;      if used r\\#x
;        if ~v\\#x eqtype 1
;          r\\#x db v\\#x, 0
;        else
;          label r\\#x byte at v\\#x
;        end if
;      end if
;    \\}
;  \}
;}


macro __InitStringEngine {
local ..hashtable, ..strbase, strlist

  virtual at 0
    ..hashtable::
         dd 65536 dup ($ffffffff)
  end virtual

  strlist equ 0

  struc text [arg] \{
  \common
    rept 1 x:strlist+1 \\{
      strlist equ x
      strlist\\#x equ ., arg
    \\}
  \}

  macro __add_one_str lbl, [dta] \{
  \common
    \local ..buff, sz, h, sh, ch1, ch2, i, f
    if used lbl
      virtual at 0
        ..buff::
            db dta, 0
            sz = $-1
      end virtual

      h = $811C9DC5
      repeat sz
        load ch1 byte from ..buff:(%-1)
        h = ((h xor ch1) * $01000193) and $ffffffff
      end repeat

      h = ((h shr 16) xor h) and $ffff
      sh = h

      while 1
        load i dword from ..hashtable: h*4
        if i = $ffffffff
          break
        else
          f = 1
          repeat sz/8
            load ch1 qword from ..buff:((%-1)*8)
            load ch2 qword from i+(%-1)*8
            if ch1<>ch2
              f = 0
              break
            end if
          end repeat
          if f
            repeat sz mod 8
              load ch1 byte from ..buff:((sz and $fffffff8)+(%-1))
              load ch2 byte from i+(sz and $fffffff8)+(%-1)
              if ch1<>ch2
                f = 0
                break
              end if
            end repeat
          end if
          if f
            break
          end if
        end if
        h = (h+1) and $ffff
        if h = sh
          err "Hash table full."
        end if
      end while
      if i = $ffffffff
        store dword $ at ..hashtable:4*h
        lbl db dta, 0
        align 4
      else
        label lbl byte at i
      end if
    else
      if defined options.ShowSkipped & options.ShowSkipped
        display 1, 'String <', dta, '> skipped, because not used.', 13
      end if
    end if
  \}

  macro __IncludeAllStrings \{
    ..strbase:
;    match x, strlist \\{ display 1, 'Strings count:', \\`x, 13 \\}
    rept strlist x \\{
      match onestr, __add_one_str strlist\\#x \\\{ onestr \\\}
    \\}
  \}
}


__InitStringEngine


macro IncludeAllGlobals {
  local begin

  begin = $
  disp 3, 'Initialized data address: $', <begin, 16>, 13
  IncludeIGlobals
  DispSize 'Initialized data', ($ - begin)

  begin = $
  disp 3, 'Strings address: $', <$, 16>, 13
  __IncludeAllStrings
  DispSize 'String data', ($ - begin)

  begin = $
  IncludeUGlobals
  DispSize 'Uninitialized data', ($ - begin)
}



macro var expr {
common
  match name==value, expr \{
    if used name
      name dd value
    else
      name = 0
    end if
  \}
}



iglobal
endg

uglobal
endg
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































Deleted freshlib/macros/_stdcall.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Macros for create and call of high level procedures.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


macro locals {
  local ..locsize
  locsize equ ..locsize
  virtual at ebp - ..locsize - .__info.commonframe.size
  @@:
}


macro endl {
  rb (4 - ($- @b) and 11b) and 11b
  locsize = $ - @b
  if $-@b > maxsize
    maxsize = $-@b
  end if
  end virtual
  restore locsize
}


macro err@endp { }


macro proc name, [arg] {
  common
    \err@endp

    macro err@endp \{
      end if
      Missing 'endp' before the procedure.
    \}

  if defined options.AlignCode & options.AlignCode
    align 16
  end if

  name:
    .__info.id = 1
    .__info.start = $

    virtual at ebp+8
      if ~ arg eq
        forward
          arg dd ?
          if ~ defined name#arg
            ERROR! the argument `arg MUST begins with dot
          end if
        common
      end if
        .__info.argsize = $-ebp-8
    end virtual

    if ~ used name
      if defined options.ShowSkipped & options.ShowSkipped
        display 1,'Procedure skipped: ',`name, $0d, $0a
      end if
    else

    virtual at ebp - .__info.commonframe.size
    .__info.commonframe.begin:
}


macro begin {
      rb (4 - ($ - .__info.commonframe.begin) and 11b) and 11b
      .__info.commonframe.size = $ - .__info.commonframe.begin
    end virtual

    local ..maxsize
    maxsize equ ..maxsize
    ..maxsize = 0

    if .__info.framesize
      if defined options.FastEnter & options.FastEnter
        push ebp
        mov  ebp, esp
        sub  esp, .__info.framesize
      else
        enter .__info.framesize, 0
      end if
    else
      if .__info.argsize
        push ebp
        mov  ebp, esp
      end if
    end if
}


macro cret {
  if .__info.argsize | .__info.framesize
    if defined options.FastEnter & options.FastEnter
      mov   esp, ebp
      pop   ebp
    else
      leave
    end if
  end if
  retn
}


macro return {
  if .__info.argsize | .__info.framesize
    if defined options.FastEnter & options.FastEnter
      mov   esp, ebp
      pop   ebp
    else
      leave
    end if
  end if

  if .__info.argsize
    retn .__info.argsize
  else
    retn
  end if
}



macro endp {
    .__info.framesize = maxsize + .__info.commonframe.size
    .__info.codesize = $ - .__info.start
  end if
  restore maxsize
  purge err@endp
}


; dispatch procedure

macro dproc name, [arg] {
common

  \err@endp

  macro err@endp \{
    end if
    Missing 'enddp' before this procedure.
  \}


  if ~ used name
    if defined options.ShowSkipped & options.ShowSkipped
      display 1,'Dispatch procedure skipped: ',`name, $0d, $0a
    end if
  else

  name:
    .__info.id = 2
    .__info.start = $

  virtual at ebp+8
    forward
      arg dd ?
      if ~ defined name#arg
        ERROR! the argument `arg MUST begin with dot
      end if
    common
      .__info.argsize = $ - ebp - 8
  end virtual

  virtual at ebp - .__info.commonframe.size
  .__info.commonframe.begin:
}



macro dispatch arg {  ; begins procedure instructions
  common
    local ..casecounter, ..caselist, ..caseaddr
    casecounter equ ..casecounter
    caselist equ ..caselist
    caseaddr equ ..caseaddr

    ..casecounter = 0

    mov  eax, arg

    ..caselist:
    ..caseaddr = $

    rb .__info.casesize
}


macro oncase idname {
common
     local offset

     if idname >= -128 & idname <= 127
       store word $f883 at caseaddr ; cmp eax, byte imm
       store byte idname at caseaddr + 2
       caseaddr = caseaddr + 3
     else
       store byte $3d at caseaddr  ; cmp eax, dword imm
       store dword idname at caseaddr+1
       caseaddr = caseaddr + 5
     end if

     offset = $ - caseaddr - 2
     if offset >= -128 & offset <=127
        store byte $74 at caseaddr
        store byte offset at caseaddr+1
        caseaddr = caseaddr + 2
     else
        store word $840f at caseaddr
        store dword offset - 4 at caseaddr+2
        caseaddr = caseaddr + 6
     end if

  casecounter = casecounter + 1
}


macro enddp {
    .__info.casecount = casecounter
    .__info.framesize = maxsize + .__info.commonframe.size
    .__info.codesize = $ - .__info.start
    .__info.casesize = caseaddr - caselist
  end if
  restore maxsize, casecounter, caselist, caseaddr
  purge err@endp
}






macro __InitInitializeEngine {
  local i,f,ci,cf
  ci equ 0
  cf equ 0

  macro initialize procname \{
    \common
    rept 1 x:ci+1 \\{
      ci equ x
      i\\#x equ procname
      proc procname
    \\}
  \}

  macro finalize procname \{
    \common
    rept 1 x:cf+1 \\{
      cf equ x
      f\\#x equ procname
      proc procname
    \\}
  \}


  macro InitializeAll \{
    \common
    rept ci x \\{
      \\forward
      if defined i\\#x
        call i\\#x
      end if
    \\}
  \}

  macro FinalizeAll \{
    \common
    rept cf x \\{
      \\reverse
      if defined f\\#x
        call f\\#x
      end if
    \\}
  \}
}

__InitInitializeEngine



;*****************************************
; Call macroses
;*****************************************


macro pushx [arg] {
common
  local f1, f2, cnt
  cnt = 0
  f1 = 1
  f2 equ FALSE
forward
  local sz

  match any, arg \{
    match `arg, arg \\{ f2 equ TRUE \\}
  \}

  cnt = cnt + 1
  if arg eqtype ''
    virtual at 0
      db arg
      sz = $
    end virtual
    if (sz > 4) | (cnt>1)
      f1 = 0
    end if
  end if
common
  local lbl

  if f1
    pushd arg
  else
    pushd lbl
  end if
  match =TRUE, f2 \{ lbl text arg \}
}




macro stdcall proc, [arg] {    ; call procedure
common
  local ..argsize
  ..argsize = 0
  if ~ arg eq
reverse
    pushx arg
    ..argsize = ..argsize + 4
common
  end if
  if defined options.CheckArguments & options.CheckArguments
    if (defined proc#.__info.argsize) & (proc#.__info.argsize <> ..argsize)
      ERROR! wrong argument count for procedure call.
    end if
  end if

  call proc
}


macro invoke proc,[arg] {   ; invoke procedure (indirect)
common
  if ~ arg eq
reverse
    pushx arg
common
  end if
  call [proc]
}


macro ccall proc,[arg]  {                ; call procedure in C calling convention
common local ..size
   ..size = 0
reverse
   pushx arg
   ..size = ..size+4
common
   call proc
   if defined proc#.__info.argsize
     if proc#.__info.argsize > 0
       add esp, proc#.__info.argsize
     end if
   else
     if ..size > 0
       add esp,..size
     end if
   end if
}


macro cinvoke proc, [arg] {               ; invoke procedure (indirect)
common local ..size
   ..size = 0
   if ~ arg eq
reverse
   pushx arg
   ..size = ..size+4
common
   end if

   call [proc]

   if defined proc#.__info.argsize
     if proc#.__info.argsize > 0
       add esp, proc#.__info.argsize
     end if
   else
     if ..size > 0
       add esp, ..size
     end if
   end if
}

;****************************************
; INT3 break point, when first = second.
;****************************************

macro BreakEq first, second {
  local .lbl
  push  eax
  mov   eax, first
  cmp   eax, second
  pop   eax
  jne   .lbl

  int3

.lbl:
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/macros/_struct.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Macro to make complex data structures.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

macro struct name {
  macro name@struct \{ name name \}
  macro size@struct \{ sizeof.#name = $ \}
  struc name \{
}


ends fix } struct_helper


macro struct_helper {
  virtual at 0
    name@struct
    size@struct
  end virtual
  purge name@struc
  purge size@struct
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































Deleted freshlib/macros/_uniquelists.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
; list - name of the list.
; list@count - count of the list items.

macro __search_list flag, list, item {
forward
  flag equ FALSE
  rept list#@count i:1 \{ match iitem, item \\{ match =iitem, list\\#i \\\{ define flag TRUE \\\} \\} \}
}


macro ppAddUniqueList list, [listitem] {
forward
  local fFound
  __search_list fFound, list, listitem
  match =FALSE, fFound \{
    rept 1 x:list#\@count+1 \\{
      list\\#@count equ x
      list\\#x equ listitem
    \\}
  \}
}

macro ppInitList list {
  list#@count equ 0
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































Deleted freshlib/macros/allmacros.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Includes all macro libraries at once.
;
;  Target OS:
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

include '_uniquelists.inc'
include '_executable.inc'
include '_struct.inc'
include '_stdcall.inc'
include '_display.inc'
include '_globals.inc'
include '_datamacros.inc'

include '%TargetOS%/allmacros.inc'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































Deleted freshlib/readme.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 _______________________________________________________________________________________
|                                                                                       |
| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
|                                                                                       |
| (c)2003, 2004, 2005, 2010, 2011 Fresh developement team                               |
|_______________________________________________________________________________________|

FreshLib is standard Fresh IDE library. FreshLib contains macros, 
equates and code to allow writing of portable applications.

FreshLib is free, open source project, distributed under the terms of 
"Fresh artistic license". 
The text of the license is in the file "License.txt"

FreshLib is created and maintained by Fresh development team. Every member of the team
have some contribution to the project. Here is the list of people contributed to the
project (in order of appearance; newer first):

pelaillo
scientica (Fredrik Klasson)
tommy 	  (Tommy Lilehagen)
VeSCeRa	  (Yunus Sina Gulsen)
roticv	  (Victor Loh)
decard 	  (Mateusz Tymek)
John Found 

Special thanks to Tomasz Grysztar for creating FASM.
Tomasz also provided some really useful macros.
_________________________________________________________________________________________

For additional information about Fresh and FreshLib, look at following locations:

http://fresh.flatassembler.net	- main site of the project Fresh.
http://board.flatassembler.net	- Flat assembler message board.
_________________________________________________________________________________________

The test project for FreshLib is "TestFreshLib.fpr"
You can compile and run it as Win32, or as Linux application. 
Use Fresh IDE or compile TestLib.asm file with FASM compiler.

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































Deleted freshlib/simpledebug/Linux/debug.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: SimpleDebug library.
;
;  Target OS: Linux
;
;  Dependencies: Not dependent on other libraries.
;
;  Notes:
;_________________________________________________________________________________________



proc Output, .ptrStr
begin
        pushad

        stdcall __simpStrLength, [.ptrStr]
        mov     edx, ecx

        mov     eax, 4
        mov     ebx, 1
        mov     ecx, [.ptrStr]
        int     $80

        popad
        return
endp


macro Output string {
if defined options.DebugMode & options.DebugMode = 1
        stdcall Output, string
end if
}


proc GetTimestamp
begin
        pushad
        mov     eax, 78
        mov     ebx, _timestamp
        xor     ecx, ecx
        int     $80

        mov     eax,dword [_timestamp]
        mov     ecx,1000
        mul     ecx
        mov     ebx,eax
        mov     eax,dword [_timestamp+4]
        div     ecx
        add     eax,ebx

        mov     [esp+4*regEAX], eax
        popad
        return

endp


uglobal
  if used _timestamp
   _timestamp dq 0
  end if
endg


macro OutputEvent event {
if defined options.DebugMode & options.DebugMode
        stdcall __OutputEvent, event
end if
}

proc __OutputEvent, .pEvent
begin
        pushad
        stdcall Output, cEventLabel
        mov     esi, [.pEvent]
        mov     eax, [esi+XEvent.type]
        cmp     eax, 2
        jl      .bynumber
        cmp     eax, 35
        jg      .bynumber

        sub     eax, 2
        mov     eax, [__EventStrings+4*eax]
        stdcall Output, eax
        stdcall Output, cEventLabel1

.window:
        mov     eax, [esi+XEvent.type]
        stdcall OutputNumber, eax, 10, 3
        stdcall Output, cEventLabel2
        stdcall OutputNumber, [esi+XEvent.window], 16, 8
        stdcall Output, cEventLabel3

        popad
        return

.bynumber:
        stdcall OutputNumber, eax, 10, 3
        jmp     .window

endp

if used __OutputEvent
  cEventLabel db 'X event: "', 0
  cEventLabel1 db ' (', 0
  cEventLabel2 db ')" for window: $', 0
  cEventLabel3 db 10, 0

  ; From number 2..35
  __EventStrings:
  StringTable              \
  `KeyPress, `KeyRelease, `ButtonPress, `ButtonRelease, `MotionNotify, `EnterNotify, \
  `LeaveNotify, `FocusIn, `FocusOut, `KeymapNotify, `Expose, `GraphicsExpose, `NoExpose, \
  `VisibilityNotify, `CreateNotify, `DestroyNotify, `UnmapNotify, `MapNotify, `MapRequest, \
  `ReparentNotify, `ConfigureNotify, `ConfigureRequest, `GravityNotify, `ResizeRequest,    \
  `CirculateNotify, `CirculateRequest, `PropertyNotify, `SelectionClear, `SelectionRequest, \
  `SelectionNotify, `ColormapNotify, `ClientMessage, `MappingNotify, `LASTEvent
end if
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































Deleted freshlib/simpledebug/Win32/debug.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: SimpleDebug library.
;
;  Target OS: Win32
;
;  Dependencies: Not dependent on other libraries.
;
;  Notes:
;_________________________________________________________________________________________


uglobal
  if used debug_con_handle
    debug_con_handle dd ?
  end if
endg


iglobal
  if used cConsoleTitle
    cConsoleTitle du 'Fresh simple debug console.', 0
  end if
endg


if (defined options.DebugMode & options.DebugMode) | used Output
initialize InitDebugConsole
begin
        invoke  AllocConsole
        invoke  GetStdHandle, STD_ERROR_HANDLE
        mov     [debug_con_handle], eax
        invoke  SetConsoleTitleW, cConsoleTitle
        return
endp
end if



proc Output, .ptrStr
.dummy dd ?
begin
        pushad

        stdcall __simpStrLength, [.ptrStr]
        lea     eax, [.dummy]

if GlobalAPI eq ascii
        invoke  WriteConsole, [debug_con_handle], [.ptrStr], ecx, eax, 0
else
        invoke  WriteConsoleA, [debug_con_handle], [.ptrStr], ecx, eax, 0
end if


        popad
        return
endp



proc GetTimestamp
begin
        pushad
        invoke  GetTickCount
        mov     [esp+4*regEAX], eax
        popad
        return
endp




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































Deleted freshlib/simpledebug/debug.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: SimpleDebug library. Provides simple debugging macros and code.
;
;  Target OS: Any
;
;  Dependencies: Not dependent on other libraries.
;
;  Notes: use options.DebugMode={1|0} to enable/disable debug output of this library.
;_________________________________________________________________________________________
module "Simple debug library"

SimpleDebugLoaded = 1

include "%TargetOS%/debug.asm"


macro DebugMsg msg {
common
if defined options.DebugMode & options.DebugMode
  local ..msg, ..skip

        stdcall Output, ..msg
        jmp     ..skip
  ..msg db msg, 10, 0

  label ..skip
end if
}


macro Message msg {
common
  local ..msg, ..skip

        stdcall Output, ..msg
        jmp     ..skip
  ..msg db msg, 10, 0

  label ..skip
}



proc OutputMemory, .ptr, .size
begin
        pushad

        mov     esi, [.ptr]
        mov     edx, [.size]

.loop:
        stdcall OutputNumber, esi, 16, 8
        stdcall Output, .cSimpDbgSep1

        mov     ecx, 4

.lineloop:
        stdcall OutputNumber, [esi], 16, 8
        stdcall Output, .cSimpDbgSep2
        lea     esi, [esi+4]

        sub     edx, 4
        cmp     edx, 0
        jle     .exit

        dec     ecx
        jnz     .lineloop

.exit:
        stdcall Output, .cSimpDbgNewLine

        cmp     edx, 0
        jg      .loop

        stdcall Output, .cSimpDbgNewLine

        popad
        return

.cSimpDbgSep1 db ': ',0
.cSimpDbgSep2 db '  ',0
.cSimpDbgNewLine db 13,10,0


endp

macro OutputMemory pointer, size {
if defined options.DebugMode & options.DebugMode
        stdcall OutputMemory, pointer, size
end if
}





proc OutputNumber, .number, .radix, .digits
begin
        pushad

        cld
        mov     edi, _simpdebugstr

        mov     eax, [.number]
        mov     ecx, [.radix]
        mov     esi, [.digits]

        call    __simpNumToStrUF
        xor     eax, eax
        stosd

        stdcall Output, _simpdebugstr

.exit:
        popad
        return
endp


macro OutputNumber number, radix, digits {
if defined options.DebugMode & options.DebugMode
        stdcall OutputNumber, number, radix, digits
end if
}


regEDI = 0
regESI = 1
regEBP = 2
regESP = 3
regEBX = 4
regEDX = 5
regECX = 6
regEAX = 7


proc OutputRegister, .reg, .radix
begin
        pushad

        cmp     [.reg], 7
        ja      .exit

        cld
        mov     edi, _simpdebugstr
        mov     ebx, [.reg]

        mov     eax, [.regnames+4*ebx]
        stosd

        mov     eax, [esp+4*ebx]
        mov     ecx, [.radix]
        mov     esi, 8

        call    __simpNumToStrUF
        mov     eax, $0a
        stosd

        stdcall Output, _simpdebugstr

.exit:
        popad
        return

  .regnames:
        dd      'edi='
        dd      'esi='
        dd      'ebp='
        dd      'esp='
        dd      'ebx='
        dd      'edx='
        dd      'ecx='
        dd      'eax='
endp



macro OutputRegister reg, radix {
if defined options.DebugMode & options.DebugMode
        stdcall OutputRegister, reg, radix
end if
}



uglobal
  if used _simpdebugstr
    _simpdebugstr rb 256
  end if
endg



proc __simpStrLength;, .pString
begin
        mov     ecx, [esp+4]
.scan:
        cmp     byte [ecx], 0
        lea     ecx, [ecx+1]
        jne     .scan

        stc
        sbb     ecx, [esp+4]
        retn 4
endp


;*****************************************************
; NumToStrF:
;   Converts signed integer value to string.
; NumToStrUF:
;   Converts unsigned integer value to string.
;
; edi - pointer to string buffer
; eax - Number to convert
; ecx - radix from 2 to $ff
; esi - length of the number in chars
;
; returns: edi - pointer to the end of converted num
;
; Note: Don't use 1 as radix.
;*****************************************************
proc __simpNumToStrF
begin
        test    eax,eax
        jns     NumToStrUF
        neg     eax
        mov     byte [edi],'-'
        push    esi
        dec     esi
        add     edi,esi
        push    edi
        jmp     __simpNumToStrUF.loopc
endp

proc __simpNumToStrUF
begin
        push    esi
        add     edi, esi
        push    edi
        dec     edi
.loopc:
        xor     edx,edx
        div     ecx
        xchg    al,dl
        cmp     al,$0a
        sbb     al,$69
        das
        mov     [edi],al
        dec     edi
        xchg    al,dl
        dec     esi
        jnz     .loopc
        pop     edi
        pop     esi
        return
endp



endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































Deleted freshlib/sqlite/sqlite.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
;-------------------------------------------------------------------
; Procedures for convenient work with SQLite database angine.
;-------------------------------------------------------------------

;-------------------------------------------------------------------
; If the file in [.ptrFileName] exists, the function opens it.
; if the file does not exists, new database is created and the
; initialization script from [.ptrInitScript] is executed on it.
;
; Returns:
;    CF: 0 - database was open successfully
;      eax = 0 - Existing database was open successfuly.
;      eax = 1 - New database was created and init script was
;                executed successfully.
;      eax = 2 - New database was created but init script exits
;                with error.
;    CF: 1 - the database could not be open. (error)
;-------------------------------------------------------------------
proc OpenOrCreate, .ptrFileName, .ptrDatabase, .ptrInitScript
   .hSQL dd ?
.ptrNext dd ?
begin
        push    esi ebx

        mov     esi, [.ptrDatabase]
        cinvoke sqliteOpen, [.ptrFileName], esi
        test    eax, eax
        jz      .openok
        stc
        pop     esi
        return

.openok:
        xor     ebx, ebx
        cinvoke sqliteExec, [esi], .sqlCheckEmpty, .AbortCallback, ebx, ebx
        cmp     eax, SQLITE_ABORT
        je      .finish

        cinvoke sqliteExec, [esi], [.ptrInitScript], -1, ebx, ebx, ebx
        inc     ebx
        test    eax, eax     ; SQLITE_OK
        jz      .finish

        inc     ebx

.finish:
        cinvoke sqliteFinalize, [.hSQL]
        mov     eax, ebx
        clc
        pop     ebx esi
        return

.AbortCallback:
        xor     eax, eax
        inc     eax
        retn

.sqlCheckEmpty db 'select * from sqlite_master',0

endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































Deleted freshlib/system/Linux/clipboard.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Clipboard management library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


if used ClipboardRead | used ClipboardWrite
  __UseClipboard = 1
else
  __UseClipboard = 0
end if



proc ClipboardRead
.result dd ?

.event XEvent

.return_type    dd ?
.return_format  dd ?
.return_items   dd ?
.return_remains dd ?
.return_data    dd ?

begin
        pushad
        mov     [.result], 0

        cinvoke XGetSelectionOwner, [hApplicationDisplay], [atomSelClipboard]
        test    eax, eax
        jz      .finish

        cinvoke XConvertSelection, [hApplicationDisplay], [atomSelClipboard], [atomUTF8], [atomUTF8], [hClipboardWindow], CurrentTime

.wait_loop:
        lea     eax, [.event]
        cinvoke XCheckTypedEvent, [hApplicationDisplay], SelectionNotify, eax
        test    eax, eax
        jz      .wait_loop

        cmp     [.event+XSelectionEvent.property], None
        je      .finish

        lea     eax, [.return_data]
        lea     ecx, [.return_remains]
        lea     edx, [.return_items]

        push    eax
        push    ecx
        push    edx

        lea     eax, [.return_format]
        lea     ecx, [.return_type]
        push    eax
        push    ecx

        push    AnyPropertyType
        push    FALSE
        push    $7fffffff
        push    0
        push    [.event+XSelectionEvent.property]
        push    [.event+XSelectionEvent.requestor]
        push    [hApplicationDisplay]
        call    [XGetWindowProperty]
        add     esp, 12*4

        mov     eax, [.return_type]
        cmp     eax, [atomUTF8]
        jne     .finish

        mov      eax, [.return_data]
        test     eax, eax
        jz       .finish

        stdcall StrDup, eax
        mov     [.result], eax

        cinvoke XFree, [.return_data]

.finish:
        popad
        mov     eax, [.result]
        return
endp



proc ClipboardWrite, .hstring
begin



        return
endp




uglobal
  var atomSelClipboard = 0
  var atomUTF8 = 0
  var hClipboardWindow = 0
endg

cAtomClipboard text 'CLIPBOARD'
cAtomUTF8 text 'UTF8_STRING'


proc __InitLinuxClipboard
begin
        cinvoke XInternAtom, [hApplicationDisplay], cAtomClipboard, FALSE
        mov     [atomSelClipboard], eax

        cinvoke XInternAtom, [hApplicationDisplay], cAtomUTF8, FALSE
        mov     [atomUTF8], eax

        cinvoke XCreateWindow, [hApplicationDisplay], [hRootWindow], 0, 0, 1, 1, 0, CopyFromParent, InputOnly, CopyFromParent, 0, 0
        mov     [hClipboardWindow], eax
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































Deleted freshlib/system/Linux/environment.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Linux environment management library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


uglobal
  var _ptrEnvironment = ?
endg


if used _ptrEnvironment
initialize LinuxEnvironmentLibrary
begin
        lea     eax, [esp+4]
        mov     [_ptrEnvironment], eax

        return
endp
end if



proc GetAllEnvironment
.return dd ?
begin
        pushad

        mov     [.return], 0
        mov     eax, [_ptrEnvironment]
        mov     ecx, [eax]              ; argument count

        lea     eax, [eax+4*ecx+8]      ; env table.

        mov     esi, [eax]
        test    esi, esi
        jz      .finish

        push    esi

.end_loop:
        cmp     word [esi], 0
        lea     esi, [esi+1]
        jne     .end_loop

        stc
        sbb     esi, [esp]
        lea     ecx, [esi+8]

        stdcall GetMem, ecx
        mov     [.return], eax
        mov     edi, eax
        mov     ecx, esi
        pop     esi
        rep movsb
        xor     eax, eax
        stosd

.finish:
        popad
        mov     eax, [.return]
        return
endp



proc GetEnvVariable, .varname
begin
        push    ebx ecx esi edi

        mov     esi, [_ptrEnvironment]
        mov     eax, [esi]
        mov     esi, [esi+4*eax+8]

        stdcall StrPtr, [.varname]
        mov     ebx, eax

.outer:
        cmp     byte [esi], 0
        je      .not_found

        mov     edi, ebx
.inner:
        mov     al, [esi]
        mov     ah, [edi]
        lea     esi, [esi+1]
        lea     edi, [edi+1]

        test    ah, ah
        jnz     .check_al

        cmp     al, '='
        je      .found

.check_al:
        test    al, al
        jz      .outer

        cmp     al, ah
        je      .inner

; skip to next record
.skip:
        cmp     byte [esi], 0
        lea     esi, [esi+1]
        jne     .skip
        jmp     .outer

.not_found:
        xor     eax, eax
        stc
        pop     edi esi ecx ebx
        return

.found:
        stdcall StrDup, esi
        pop     edi esi ecx ebx
        clc
        return

endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































Deleted freshlib/system/Linux/files.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Files manipulation library. Linux part.
;
;  Target OS: Linux
;
;  Dependencies: Uses system calls for file processing and memory.asm for memory
;                allocations.
;
;  Notes:
;_________________________________________________________________________________________

DIR_SLASH equ '/'

fsFromBegin     = 0
fsFromEnd       = 2
fsFromCurrent   = 1

sys_read        = 03h
sys_write       = 04h
sys_open        = 05h
sys_close       = 06h
sys_unlink      = 0Ah
sys_lseek       = 013h

;   file access bits:
O_ACCMODE       = 0003o
O_RDONLY        = 00o
O_WRONLY        = 01o
O_RDWR          = 02o
O_CREAT         = 0100o
O_EXCL          = 0200o
O_NOCTTY        = 0400o
O_TRUNC         = 01000o
O_APPEND        = 02000o
O_NONBLOCK      = 04000o
O_NDELAY        = O_NONBLOCK
O_SYNC          = 010000o ;specific to ext2 fs and block devices
FASYNC          = 020000o ;fcntl, for BSD compatibility
O_DIRECT        = 040000o ;direct disk access hint - currently ignored
O_LARGEFILE     = 0100000o
O_DIRECTORY     = 0200000o ;must be a directory
O_NOFOLLOW      = 0400000o ;don't follow links

;   file permissions flags
S_ISUID         = 04000o ;set user ID on execution
S_ISGID         = 02000o ;set group ID on execution
S_ISVTX         = 01000o ;sticky bit
S_IRUSR         = 00400o ;read by owner (S_IREAD)
S_IWUSR         = 00200o ;write by owner (S_IWRITE)
S_IXUSR         = 00100o ;execute/search by owner (S_IEXEC)
S_IRGRP         = 00040o ;read by group
S_IWGRP         = 00020o ;write by group
S_IXGRP         = 00010o ;execute/search by group
S_IROTH         = 00004o ;read by others (R_OK)
S_IWOTH         = 00002o ;write by others (W_OK)
S_IXOTH         = 00001o ;execute/search by others (X_OK)


initialize InitStdHandles
begin
  if used STDIN
        mov     dword [__std_handle_in], 0
  end if

  if used STDOUT
        mov     dword [__std_handle_out], 1
  end if

  if used STDERR
        mov     dword [__std_handle_err], 2
  end if
        return
endp





;--------------------------------------
; if CF = 0, eax is handle to the file.
; if CF = 1, eax is error code.
;--------------------------------------
proc FileOpen, .filename
begin
        push    edx ecx ebx

        if defined ptrStrTable
          stdcall StrPtr, [.filename]
          mov     ebx, eax
        else
          mov   ebx, [.filename]
        end if

        mov     eax, sys_open
        mov     ecx, O_RDONLY;O_RDWR
        mov     edx, S_IWUSR+S_IWGRP+S_IWOTH
        int     $80
        cmp     eax, -1
        jle     .error
        clc
        pop     ebx ecx edx
        return

.error:
        neg     eax

if defined options.DebugMode & options.DebugMode = 1
        stdcall __FileErrorDisplay, eax, [.filename]
end if

        stc
        pop     ebx ecx edx
        return
endp



;--------------------------------------
; if CF = 0, eax is handle to the file.
; if CF = 1, eax is error code.
;--------------------------------------
proc FileCreate, .filename
begin
        push    edx ecx ebx

if defined ptrStrTable
        stdcall StrPtr, [.filename]
        mov     ebx, eax
else
        mov     ebx, [.filename]
end if

        mov     eax, sys_open
        mov     ecx, O_CREAT+O_TRUNC+O_RDWR
        mov     edx, S_IRUSR+S_IWUSR+S_IRGRP+S_IROTH
        int     $80
        cmp     eax, -1
        jle     .error
        clc
        pop     ebx ecx edx
        return
.error:
        neg     eax
        stc
        pop     ebx ecx edx
        return
endp




;--------------------------------------
; if CF = 0, the file was closed.
; if CF = 1, eax is error code.
;--------------------------------------
proc FileClose, .handle
begin
        push    ebx
        mov     eax, sys_close
        mov     ebx, [.handle]
        int     $80
        cmp     eax, -1
        jle     .error
        clc
        pop     ebx
        return
.error:
        neg     eax
        stc
        pop     ebx
        return
endp


; returns 32bit file size in eax
proc FileSize, .handle
.stat STAT
begin
        push    edx ecx ebx

        mov     eax, sys_newfstat
        mov     ebx, [.handle]
        lea     ecx, [.stat]
        int     $80

        cmp     eax, -1
        jle     .error

        mov     eax, [.stat.st_size]
        clc
        pop     ebx ecx edx
        return

.error:
        neg     eax
        stc
        pop     ebx ecx edx
        return
endp



proc FileRead, .handle, .buffer, .count
begin
        push    edx ecx ebx
        mov     eax, sys_read
        mov     ebx, [.handle]
        mov     ecx, [.buffer]
        mov     edx, [.count]
        int     $80
        cmp     eax, -1
        jle     .error
        clc
        pop     ebx ecx edx
        return

.error:
        neg     eax
        stc
        pop     ebx ecx edx
        return
endp


proc FileWrite, .handle, .buffer, .count
begin
        push    edx ecx ebx
        mov     eax, sys_write
        mov     ebx, [.handle]
        mov     ecx, [.buffer]
        mov     edx, [.count]
        int     $80
        cmp     eax, -1
        jle     .error
        clc
        pop     ebx ecx edx
        return

.error:
        neg     eax
        stc
        pop     ebx ecx edx
        return
endp


;----------------------------------------------------
; if CF = 0, eax is the new possition in the file
; if CF = 1, eax is error code.
;----------------------------------------------------
proc FileSeek, .handle, .dist, .direction
begin
        push    edx ecx ebx
        mov     eax,sys_lseek
        mov     ebx,[.handle]
        mov     ecx,[.dist]
        mov     edx,[.direction]
        int     $80
        cmp     eax,-1
        jle     .error
        clc
        pop     ebx ecx edx
        return

.error:
        neg     eax
        stc
        pop     ebx ecx edx
        return
endp



;--------------------------------------
; if CF = 0, the file was deleted.
; if CF = 1, eax is error code.
;--------------------------------------
proc FileDelete, .filename
begin
        push    ebx

        if defined ptrStrTable
          stdcall StrPtr, [.filename]
          mov     ebx, eax
        else
          mov   ebx, [.filename]
        end if

        mov     eax,sys_unlink
        int     $80
        cmp     eax,-1
        jle     .error
        clc
        pop     ebx
        return

.error:
        neg     eax
        stc
        pop     ebx
        return
endp



proc GetErrorString, .code
.buff dd ?
begin
        push    ecx edx
        cinvoke strerror_r, [.code], 0, 0       ; it is somewhat not clear about the returned string. Should we free it???
        pop     edx ecx
        clc
        return
endp




proc FreeErrorString, .ptrString
begin
        return
endp




ftDirectory  =  DT_DIR
ftUnknown    =  DT_UNKNOWN
ftFile       =  DT_REG


; reads all items of the directory and fills them in the TArray of type TDirItem.
; arguments:
;   dir - string with the path to the directory.
;
; returns:
;   if not error: CF=0; eax = pointer to TArray of TDirItem;
;   if error:     CF=1; eax = error code;

proc DirectoryRead, .dir
.buffer rb 1024
.size   dd ?
begin
        push    ebx ecx edx edi

        stdcall CreateArray, sizeof.TDirItem
        mov     edi, eax

; open the file
        if defined ptrStrTable
          stdcall StrPtr, [.dir]
          mov     ebx, eax
        else
          mov   ebx, [.dir]
        end if

        mov     eax, sys_open
        mov     ecx, O_RDONLY or O_DIRECTORY
        mov     edx, S_IWUSR+S_IWGRP+S_IWOTH
        int     $80
        test    eax, eax
        js      .error

        mov     ebx, eax

.read_loop:

        mov     eax, sys_getdents
        lea     ecx, [.buffer]
        mov     edx, 1024
        int     $80

; process read information

        test    eax, eax
        jz      .end_of_directory
        js      .error

        mov     [.size], eax

        xor     ecx, ecx

.buffer_parse:
        lea     eax, [.buffer+linux_dirent.d_name+ecx]
        stdcall StrDup, eax
        push    eax

        stdcall AddArrayItems, edi, 1
        mov     edi, edx

        pop     [eax+TDirItem.hFilename]

        movzx   edx, word [.buffer+ecx+linux_dirent.d_reclen]
        add     ecx, edx

        movzx   edx, byte [.buffer+ecx-1]       ; file type.
        mov     [eax+TDirItem.Type], edx

        cmp     ecx, [.size]
        jb      .buffer_parse

        jmp     .read_loop

.end_of_directory:

        mov     eax, sys_close
        int     $80


        mov     eax, edi
        pop     edi edx ecx ebx
        clc
        return

.error:
        neg     eax
        pop     edi edx ecx ebx
        stc
        return
endp





proc GetFileInfo, .hFile, .ptrFileInfo
.fstat STAT
begin
        push    edi ebx ecx eax

        lea     edi, [.fstat]
        mov     ecx, sizeof.STAT / 4
        xor     eax, eax
        rep stosd

        mov     eax, sys_newfstat
        mov     ebx, [.hFile]
        lea     ecx, [.fstat]
        int     $80

        test    eax, eax
        jnz     .error

        lea     ecx, [.fstat]
        mov     ebx, [.ptrFileInfo]

        mov     eax, [ecx+STAT.st_atime]
        cdq
        mov     dword [ebx+TFileInfo.timeAccessed], eax
        mov     dword [ebx+TFileInfo.timeAccessed+4], edx

        mov     eax, [ecx+STAT.st_mtime]
        cdq
        mov     dword [ebx+TFileInfo.timeModified], eax
        mov     dword [ebx+TFileInfo.timeModified+4], edx
; linux does not support creation time, so we set it as the modified time.
        mov     dword [ebx+TFileInfo.timeCreated], eax
        mov     dword [ebx+TFileInfo.timeCreated+4], edx

        pop     eax ecx ebx edi
        clc
        return

.error:
        neg     eax
        mov     [esp], eax

        pop     eax ecx ebx edi
        stc
        return

endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/system/Linux/memory.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Dynamic memory management library. Linux part.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes: Uses libc (malloc etc.) heap management functions.
;_________________________________________________________________________________________

uses libc

if used SpaceAllocate & ~ used GetMem
initialize ReserveAddressSpace
begin
        mov     eax, sys_brk
        xor     ebx, ebx
        int     $80
        mov     [_MemoryFreeSpace], eax
        return
endp
end if



proc GetMem, .size
begin
        push    ebx ecx edx esi edi

        mov     ebx, [.size]
        add     ebx, 3
        and     bl, $fc          ; align to dword.

        cinvoke malloc, ebx
        test    eax, eax
        jz      .error
        push    eax

        cld
        mov     edi, eax
        mov     ecx, ebx
        shr     ecx, 2
        xor     eax, eax
        rep stosd

        pop     eax
        clc
        pop     edi esi edx ecx ebx
        return

.error:
        stc
        pop     edi esi edx ecx ebx
        return

endp



proc FreeMem, .ptr
begin
        cmp     [.ptr], 0
        je      @f
        pushad
        cinvoke free, [.ptr]
        popad
@@:
        clc
        return
endp




proc ResizeMem, .ptr, .newsize
begin
        push    ebx ecx edx esi edi

        mov     ebx, [.newsize]
        add     ebx, 3
        and     bl, $fc          ; align to dword.

        cinvoke realloc, [.ptr], ebx
        test    eax, eax
        jz      .error

        clc
        pop     edi esi edx ecx ebx
        return

.error:
        stc
        pop     edi esi edx ecx ebx
        return
endp




proc SpaceAllocate, .size
begin
        push ebx

        mov     eax, sys_brk
        mov     ebx, [_MemoryFreeSpace]
        add     ebx, [.size]
        int     $80
        pop  ebx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































Deleted freshlib/system/Linux/network.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: OS dependent part of the network library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


serrAccess              = EACCES
serrNoMemory            = ENOMEM
serrProtocolNotSupported= EPROTONOSUPPORT

serrAddessInUse         = EADDRINUSE
serrNotASocket          = ENOTSOCK

serrWouldBlock          = EWOULDBLOCK
serrBadSocket           = EBADF
serrConnRefused         = ECONNREFUSED
serrConnReset           = ECONNRESET
serrDestAddrReq         = EDESTADDRREQ
serrInvalidAddress      = EFAULT
serrInterrupt           = EINTR
serrInvalidArgument     = EINVAL
serrIsConnected         = EISCONN



proc __SocketError
begin
        test    eax, eax
        jns     .no_error
        neg     eax
        stc
        return

.no_error:
        clc
        return
endp


proc SocketCreate, .protocol_family, .socket_type, .protocol
begin
        push    ebx ecx edx

        mov     eax, sys_socketcall
        mov     ebx, SYS_SOCKET
        lea     ecx, [.protocol_family]
        int     $80

        call    __SocketError

        pop     edx ecx ebx
        return
endp



proc SocketClose, .hSocket
;.buffer rb 1024
;.params rd 2
begin
        push    ebx ecx edx

;        push    [.hSocket]
;        pop     [.params]
;        mov     [.params+4], 1
;
;        mov     eax, sys_socketcall
;        mov     ebx, SYS_SHUTDOWN
;        lea     ecx, [.params]
;        int     $80
;        call    __SocketError
;        jc      .finish
;
;.loop:
;        lea     ecx, [.buffer]
;        stdcall SocketReceive, [.hSocket], ecx, 1024, 0
;        jc      .finish
;        test    eax, eax
;        jnz     .loop
;
;.finish:
        mov     eax, sys_close
        mov     ebx, [.hSocket]
        int     $80
        call    __SocketError

        pop     edx ecx ebx
        return
endp



proc SocketConnect, .hSocket, .pAddress
.sock dd ?
.addr dd ?
.size dd ?
begin
        push    ebx ecx edx

        push    [.hSocket] [.pAddress]
        pop     [.addr] [.sock]
        mov     [.size], sizeof.TSocketAddress

        mov     eax, sys_socketcall
        mov     ebx, SYS_CONNECT
        lea     ecx, [.sock]
        int     $80

        call    __SocketError
        pop     edx ecx ebx
        return
endp



proc SocketBind, .hSocket, .pAddressIn
.sock dd ?
.addr dd ?
.size dd ?
begin
        push    ebx ecx edx

        push    [.hSocket] [.pAddressIn]
        pop     [.addr] [.sock]
        mov     [.size], sizeof.TSocketAddressIn

        mov     eax, sys_socketcall
        mov     ebx, SYS_BIND
        lea     ecx, [.sock]
        int     $80

        call    __SocketError
        pop     edx ecx ebx
        return
endp



proc SocketListen, .hSocket, .maxPending
begin
        push    ebx ecx edx

        mov     eax, sys_socketcall
        mov     ebx, SYS_LISTEN
        lea     ecx, [.hSocket]
        int     $80

        call    __SocketError
        pop     edx ecx ebx
        return
endp



proc SocketAccept, .hSocket, .pAddress
.sock    dd ?
.addr    dd ?
.addrlen dd ?
begin
        push    ebx edx

        push    [.hSocket] [.pAddress]
        pop     [.addr] [.sock]
        mov     [.addrlen], sizeof.TSocketAddress

        cmp     [.addr], 0
        jne     @f
        mov     [.addrlen], 0
@@:
        mov     eax, sys_socketcall
        mov     ebx, SYS_ACCEPT
        lea     ecx, [.sock]
        int     $80

        call    __SocketError
        mov     ecx, [.addrlen]

        pop     edx ebx
        return
endp



proc SocketSend, .hSocket, .pBuffer, .DataLen, .flags
begin
        push    ebx ecx edx
        mov     eax, sys_socketcall
        mov     ebx, SYS_SEND
        lea     ecx, [.hSocket]
        int     $80
        call    __SocketError
        pop     edx ecx ebx
        return
endp


proc SocketReceive, .hSocket, .pBuffer, .BufferSize, .flags
begin
        push    ebx ecx edx
        mov     eax, sys_socketcall
        mov     ebx, SYS_RECV
        lea     ecx, [.hSocket]
        int     $80
        call    __SocketError
        pop     edx ecx ebx
        return
endp


proc SocketSendTo, .hSocket, .pBuffer, .DataLen, .flags, .pAddressTo
.sock  dd ?
.buff  dd ?
.len   dd ?
.flgs  dd ?
.addr  dd ?
.alen  dd ?
begin
        push    ebx ecx edx

        lea     ecx, [.sock]
        mov     edx, 16

.copy:
        mov     eax, [.hSocket+4*edx]
        mov     [ecx+4*edx], eax
        dec     edx
        jns     .copy
        mov     [.alen], sizeof.TSocketAddress

        mov     eax, sys_socketcall
        mov     ebx, SYS_SENDTO
        int     $80
        call    __SocketError

        pop     edx ecx ebx
        return
endp


proc SocketReceiveFrom, .hSocket, .pBuffer, .BufferSize, .flags, .pAddressFrom
.sock  dd ?
.buff  dd ?
.len   dd ?
.flgs  dd ?
.addr  dd ?
.alen  dd ?
begin
        push    ebx edx

        lea     ecx, [.sock]
        mov     edx, 16

.copy:
        mov     eax, [.hSocket+4*edx]
        mov     [ecx+4*edx], eax
        dec     edx
        jns     .copy
        mov     [.alen], sizeof.TSocketAddress

        mov     eax, sys_socketcall
        mov     ebx, SYS_RECVFROM
        int     $80
        call    __SocketError
        mov     ecx, [.alen]
        pop     edx ebx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































Deleted freshlib/system/Linux/process.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Process management library. Linux part
;
;  Target OS: Linux
;
;  Dependencies: Uses pthreads library for thread creation.
;
;  Notes:
;_________________________________________________________________________________________

uses pthreads

; Terminate current process
; Returns: eax = 0
proc Terminate,.exit_code
begin
        mov     eax, sys_exit
        mov     ebx, [.exit_code]
        int     0x80
        return
endp



proc GetCmdArguments
begin
        push    ecx edx esi

        mov     esi, [_ptrEnvironment]

        mov     ecx, [esi]
        add     esi, 4

        stdcall CreateArray, 4
        mov     edx, eax
        jecxz   .array_ok

        stdcall AddArrayItems, eax, ecx

.array_ok:
        push    edx
        jecxz   .arg_ok

        lea     edx, [edx+TArray.array]

.loop:
        lodsd
        stdcall StrDup, eax
        mov     [edx], eax
        add     edx, 4
        loop    .loop

.arg_ok:
        pop     eax
        pop     esi edx ecx
        return
endp





proc ThreadCreate, .ptrFunction, .ptrArguments
.threadid dd ?
begin
        push    ecx edx
        lea     eax, [.threadid]
        mov     [.threadid], 0
        cinvoke pthread_create, eax, NULL, [.ptrFunction], [.ptrArguments]
        test    eax, eax
        jnz     .error

        cinvoke pthread_detach, [.threadid]
        mov     eax, [.threadid]
        clc
        pop     edx ecx
        return

.error:
        stc
        pop     edx ecx
        return
endp


proc FreeThreadID, .ThreadID
begin
        return
endp



; MUTEX functions
;_________________________________________________________________________________________

proc MutexCreate, .ptrName, .ptrMutex
.attr dq ?
begin
        push    eax ecx edx edi

        stdcall GetMem, 256
        mov     edi, [.ptrMutex]
        mov     dword [edi], eax

        lea     ecx, [.attr]
        cinvoke pthread_mutexattr_init, ecx
        cinvoke pthread_mutexattr_settype, ecx, PTHREAD_MUTEX_RECURSIVE

        cinvoke pthread_mutex_init, [edi], ecx

        cinvoke pthread_mutexattr_destroy, ecx
        pop     edi edx ecx eax
        return
endp




proc WaitForMutex, .ptrMutex, .timeout
.time lnx_timespec
begin
        push    eax ecx edx edi

        mov     edi, [.ptrMutex]

        mov     eax, [.timeout]
        test    eax, eax
        js      .no_timeout

        mov     ecx, 1000
        cdq
        div     ecx
        imul    edx, 1000000

        lea     ecx, [.time]
        mov     [ecx+lnx_timespec.tv_sec], eax
        mov     [ecx+lnx_timespec.tv_nsec], edx

        cinvoke pthread_mutex_timedlock, [edi], ecx
        jmp     .finish

.no_timeout:
        cinvoke pthread_mutex_lock, [edi]

.finish:
        clc
        pop     edi edx ecx eax
        return
endp




proc MutexRelease, .ptrMutex
begin
        pushf
        push    eax ecx edx
        mov     ecx, [.ptrMutex]
        cinvoke pthread_mutex_unlock, [ecx]
        pop     edx ecx eax
        popf
        return
endp



proc MutexDestroy, .ptrMutex
begin
        push    eax ecx edx
        mov     ecx, [.ptrMutex]
        jecxz   .exit

        cinvoke pthread_mutex_destroy, [ecx]

        mov     ecx, [.ptrMutex]
        stdcall FreeMem, [ecx]
        mov     dword [ecx], 0

.exit:
        pop     edx ecx eax
        return
endp









;__ThreadStackSize = 1024 * 1024  ; 1Mbyte for the thread stack
;
;; Creates a new execution thread
;; Returns: CF=1 if error.
;;          CF=0, eax = pid of the new process being created
;proc ThreadCreate, .ptr_to_function, .ptr_to_args
;begin
;        push    ebx ecx edx esi edi
;
;        push    ebp
;        mov     eax, sys_mmap_pgoff
;        xor     ebx, ebx
;        mov     ecx, __ThreadStackSize
;        mov     edx, PROT_READ or PROT_WRITE
;        mov     esi, MAP_ANONYMOUS or MAP_PRIVATE or MAP_GROWSDOWN or MAP_STACK
;        mov     edi, -1
;        xor     ebp, ebp
;        int $80
;        pop     ebp
;
;        cmp     eax, $ffffff00
;        jae     .error
;
;        lea     ecx, [eax+__ThreadStackSize-8]
;
;; transfer arguments in the new stack.
;        mov     eax, [.ptr_to_function]
;        mov     [ecx], eax
;        mov     eax, [.ptr_to_args]
;        mov     [ecx+4], eax
;
;        mov     eax, sys_clone
;        mov     ebx, CLONE_VM or CLONE_FILES or CLONE_SIGHAND or CLONE_IO or CLONE_THREAD
;        int 0x80
;
;        cmp     eax,-1
;        je      .error
;
;        test    eax, eax
;        jz      .is_clone
;
;        clc
;        pop     edi esi edx ecx ebx
;        return
;
;; The stack is not allocated or sys_clone exits with error.
;.error:
;        stc
;        pop     edi esi edx ecx ebx
;        return
;
;; this is the clone process - call the thread.
;.is_clone:
;        pop     eax
;        call    eax       ; the argument is already in the stack.
;        mov     esi, eax  ; the thread procedure can return exit code. Save it in esi.
;
;; release the stack.
;        mov     eax, sys_munmap
;        lea     ebx, [esp-__ThreadStackSize]
;        mov     ecx, __ThreadStackSize
;        int $80
;
;; and exit the process  - the question is - how to execute int $80 without a stack ??? However, by some magic, it works...
;        mov     ebx, esi
;        mov     eax, sys_exit
;        int     0x80
;endp
;
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































Deleted freshlib/system/Linux/timers.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Asynchronous timer library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes: Linux port of the library uses independent thread to manage timers.
;_________________________________________________________________________________________

__sys_time_slice = 10 ;[ms]


uglobal
  if used TimerCreate
    __InternalTimerID     dd ?
    __InternalTimerThread dd ?
    __FlagTimerTerminate  dd ?
  end if
endg



if used TimerCreate
  if ~(defined options.DebugMode & options.DebugMode=1)

initialize InitLinuxTimers
  .action lnx_sigaction
  .timer lnx_sigevent
  .time  lnx_itimerspec
begin
; set the signal handler.
        mov     eax, sys_sigaction
        mov     ebx, SIGALRM
        lea     ecx, [.action]
        mov     [ecx+lnx_sigaction.sa_handler], __TimerProc
        mov     [ecx+lnx_sigaction.sa_mask], 0
        mov     [ecx+lnx_sigaction.sa_flags], 0
        xor     edx, edx

        int $80

;        DebugMsg 'Signal hadler set.'

; create the interval timer
        mov     eax, sys_timer_create
        mov     ebx, CLOCK_REALTIME

        lea     ecx, [.timer]
        mov     [ecx+lnx_sigevent.notify], SIGEV_SIGNAL
        mov     [ecx+lnx_sigevent.signo], SIGALRM
        mov     [ecx+lnx_sigevent.value], 0             ; not used but must be set - the function fails without it...
        mov     edx, __InternalTimerID

        int $80

;        DebugMsg 'Interval timer created.'

; then start a thread that will process timer expiration events.

        stdcall ThreadCreate, __TimerHandler, 0

;        DebugMsg 'Timer thread created'

        mov     [__InternalTimerThread], eax

; start the timer
        mov     ebx, [__InternalTimerID]
        mov     eax, sys_timer_settime
        lea     edx, [.time]
        mov     [edx+lnx_itimerspec.it_interval.tv_sec], 0
        mov     [edx+lnx_itimerspec.it_interval.tv_nsec], __sys_time_slice*1000000
        mov     [edx+lnx_itimerspec.it_value.tv_sec], 0
        mov     [edx+lnx_itimerspec.it_value.tv_nsec], __sys_time_slice*1000000
        xor     esi, esi
        int $80

;        DebugMsg 'Timer started'

        return
endp




finalize FreeLinuxTimers
begin
; stop the timer
        mov     eax, sys_timer_delete
        mov     ebx, [__InternalTimerID]
        int $80

;        DebugMsg 'Timer stopped.'

        cmp     [__InternalTimerThread], 0
        je      .finish

; then stop the handling thread
        mov     [__FlagTimerTerminate], 1
        cinvoke pthread_kill, [__InternalTimerThread], SIGRTMAX

; waiting to timer thread to finish. This is bad implementation,
;here should be timer wait with signal terminate on timeout.
@@:
        cmp     [__InternalTimerThread], 0
        jne     @b

;        DebugMsg 'Timer thread terminated.'

.finish:
        return
endp
  end if
end if




; This procedure is called by the system on every time quantum.
; It is Linux signal handler, so the actions this procedure can
; perform are limited.

proc __TimerProc, .signal
begin
        push    ebx edi

        cmp     [fGlobalTerminate], 0
        jne     .exit

        lea     eax, [__ptrFirstTimer]
        xor     edi, edi

.loop:
        mov     eax, [eax+TTimer.next]
        test    eax, eax
        jz      .end_timers

        test    [eax+TTimer.flags], tmfRunning
        jz      .loop

        mov     ecx, [eax+TTimer.value]
        add     ecx, __sys_time_slice

        mov     [eax+TTimer.value], ecx
        cmp     ecx, [eax+TTimer.interval]
        jl     .loop

@@:
        inc     [eax+TTimer.Expired]
        inc     edi

        mov     ecx, [eax+TTimer.interval]
        sub     [eax+TTimer.value], ecx
        cmp     [eax+TTimer.value], ecx
        jge     @b
        jmp     .loop


.end_timers:
        test    edi, edi
        jz      .exit
        cinvoke pthread_kill, [__InternalTimerThread], SIGRTMAX
.exit:
        pop     edi ebx
        cret
endp



; This is thread procedure, that checks the timer expiration and then executes the timer callback procedure (if any)

proc __TimerHandler, .argument
.remain dd ?
.action lnx_sigaction
begin
        mov     eax, sys_sigaction
        mov     ebx, SIGRTMAX
        lea     ecx, [.action]
        mov     [ecx+lnx_sigaction.sa_handler], __continue_proc
        mov     [ecx+lnx_sigaction.sa_mask], 0
        mov     [ecx+lnx_sigaction.sa_flags], 0;SA_NODEFER
        xor     edx, edx
        int $80

        mov     [__FlagTimerTerminate], 0

.from_begin:
        cmp     [__FlagTimerTerminate], 0
        jne     .quit

        mov     [.remain], 0
        lea     eax, [__ptrFirstTimer]

.listloop:
        mov     eax, [eax+TTimer.next]

.listloop2:
        test    eax, eax
        jz      .end_list

        mov     ecx, [eax+TTimer.Expired]
        jecxz   .listloop

        dec     ecx
        mov     [eax+TTimer.Expired], ecx
        add     [.remain], ecx

        cmp     [eax+TTimer.Callback], 0
        je      .listloop

        mov     ecx, [eax+TTimer.flags]
        and     ecx, $0f
        cmp     ecx, tmfDoNothing
        je      .end_event

; call the callback procedure.
        pushad
        push    eax
        cinvoke XLockDisplay, [hApplicationDisplay]
        pop     eax
        stdcall [eax+TTimer.Callback], eax
        cinvoke XUnlockDisplay, [hApplicationDisplay]
        popad

.end_event:
        test    [eax+TTimer.flags], tmfSyncDestroy
        jz      .listloop

        push    eax
        mov     eax, [eax+TTimer.next]  ; after the destruction, this pointer will be lost.
        stdcall TimerDestroy ; pointer from the stack.
        jmp     .listloop2


.end_list:
        cmp     [.remain], 0
        jne     .from_begin

; wait for signal
        mov     eax, sys_pause
        int $80
        jmp     .from_begin

.quit:
        mov     [__InternalTimerThread], 0

        stdcall Terminate, 0
endp



proc __continue_proc, .signal
begin
        cret
endp


; this procedure provides easy way to make time delays
; it is independent and does not lead to including whole timer library.

proc Sleep, .msec
.time lnx_timespec
begin
        pushad

        mov     eax, [.msec]
        xor     edx, edx
        mov     ecx, 1000
        div     eax

        mov     [.time.tv_sec], eax     ; seconds
        imul    edx, 1000000
        mov     [.time.tv_nsec], edx

        mov     eax, sys_nanosleep
        lea     ebx, [.time]
        xor     ecx, ecx
        int $80

        popad
        return
endp




proc GetTime
begin
        push    ebx

        mov     eax, sys_time
        xor     ebx, ebx
        int     $80

        cdq
        pop     ebx
        return
endp



struct lnx_timeb
  .time    dd ?
  .millitm dd ?
  .timezone dd ?
  .dstflag  dd ?
ends


proc GetLocalTimeOffset
;.time lnx_timespec
begin
;        stdcall GetTime
;        push    eax
;
;        mov     eax, sys_clock_gettime
;        mov     ebx, CLOCK_REALTIME
;        lea     ecx, [.time]
;
;        int     $80
;
;
;        pop     edx
;        mov     eax, [.time.tv_sec]
;
;        OutputRegister regEAX, 10
;        OutputRegister regEDX, 10
;        int3

        xor     eax, eax
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/system/Win32/clipboard.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Clipboard management library.
;
;  Target OS: Win32
;
;  Dependencies:
;_________________________________________________________________________________________
uses kernel32, user32

; returns eax = handle to string with the clipboard data.
proc ClipboardRead
.result dd ?
begin
        pushad
        xor     eax, eax
        mov     [.result], eax

        invoke  OpenClipboard, eax
        test    eax, eax
        jz      .finish

        invoke  GetClipboardData, CF_UNICODETEXT
        test    eax, eax
        jz      .close

        mov     ebx, eax

        invoke  GlobalSize, ebx
        mov     edi, eax

        invoke  GlobalLock, ebx
        mov     esi, eax

        lea     ecx, [8*edi]

        stdcall GetMem, ecx
        jc      .close3
        mov     edi, eax

        invoke  WideCharToMultiByte, CP_UTF8, 0, esi, -1, edi, ecx, 0, 0
        test    eax, eax
        jz      .close2

        mov     dword [edi+eax], 0

        stdcall StrDup, edi
        mov     [.result], eax

.close2:
        stdcall FreeMem, edi
.close3:
        invoke  GlobalUnlock, ebx
.close:
        invoke  CloseClipboard
        popad
.finish:
        mov     eax, [.result]
        return
endp



; writes the string .hstring to the clipboard.
; returns nothing.

proc ClipboardWrite, .hstring
begin
        pushad
        xor     eax, eax
        invoke  OpenClipboard, eax
        test    eax, eax
        jz      .finish

        invoke  EmptyClipboard

        stdcall utf8ToWideChar, [.hstring]
        mov     esi, eax
        shl     ecx, 3

        invoke  GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT or GMEM_DDESHARE, ecx
        test    eax, eax
        jz      .close
        mov     ebx, eax

        invoke  GlobalLock, ebx
        mov     edi, eax
        invoke  lstrcpyW, edi, esi
        invoke  GlobalUnlock, ebx

        invoke  SetClipboardData, CF_UNICODETEXT, ebx

.close:
        stdcall FreeMem, esi
        invoke  CloseClipboard
.finish:
        popad
        return
endp


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































Deleted freshlib/system/Win32/environment.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Win32 environment management library.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________
uses kernel32, user32

proc GetAllEnvironment
.return dd ?
begin
        pushad

        invoke  GetEnvironmentStringsA
        push    eax
        mov     esi, eax

.end_loop:
        cmp     word [esi], 0
        lea     esi, [esi+1]
        jne     .end_loop

        stc
        sbb     esi, [esp]
        lea     ecx, [esi+8]

        stdcall GetMem, ecx
        mov     [.return], eax
        mov     edi, eax
        mov     ecx, esi
        mov     esi, [esp]
        rep movsb
        xor     eax, eax
        stosd

        invoke  FreeEnvironmentStringsW ; from the stack
        popad
        mov     eax, [.return]
        return
endp



proc GetEnvVariable, .varname
.buffer rb 1024
begin
        push    ebx ecx edx

        stdcall utf8ToWideChar, [.varname]
        mov     [.varname], eax

        lea     ebx, [.buffer]
        invoke  GetEnvironmentVariableW, [.varname], ebx, 1024
        test    eax, eax
        jz      .missing

        stdcall FreeMem, [.varname]
        stdcall WideCharToUtf8, ebx
        clc
        pop     edx ecx ebx
        return

.missing:
        stdcall FreeMem, [.varname]
        stc
        pop     edx ecx ebx
        return


endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































Deleted freshlib/system/Win32/files.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Files manipulation library. Win32 part.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

uses kernel32

DIR_SLASH equ '\'

fsFromBegin     = FILE_BEGIN
fsFromEnd       = FILE_END
fsFromCurrent   = FILE_CURRENT

if used STDIN | used STDOUT | used STDERR

  initialize InitStdHandles
  begin
    if used STDIN
          invoke  GetStdHandle, STD_INPUT_HANDLE
          mov     [__std_handle_in], eax
    end if

    if used STDOUT
          invoke  GetStdHandle, STD_OUTPUT_HANDLE
          mov     [__std_handle_out], eax
    end if

    if used STDERR
          invoke  GetStdHandle, STD_ERROR_HANDLE
          mov     [__std_handle_err], eax
    end if
          return
  endp

end if

;--------------------------------------
; if CF = 0, eax is handle to the file.
; if CF = 1, eax is error code.
;--------------------------------------
proc FileOpen, .filename
begin
        push    edx ecx

        stdcall utf8ToWideChar, [.filename]
        push    eax
        invoke  CreateFileW, eax, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0
        stdcall FreeMem ; from the stack

        cmp     eax, INVALID_HANDLE_VALUE
        je      .error

        clc
        pop     ecx edx
        return

.error:
if used GetErrorString
        invoke  GetLastError
end if

if defined options.DebugMode & options.DebugMode = 1
        stdcall __FileErrorDisplay, eax, [.filename]
end if

        stc
        pop     ecx edx
        return
endp



proc FileCreate, .filename
begin
        push    edx ecx

        stdcall utf8ToWideChar, [.filename]
        push    eax
        invoke  CreateFileW, eax, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0
        stdcall FreeMem ; from the stack

        cmp     eax, INVALID_HANDLE_VALUE
        je      .error

        clc
        pop     ecx edx
        return

.error:
if used GetErrorString
        invoke  GetLastError
end if
        stc
        pop     ecx edx
        return
endp




proc FileClose, .handle
begin
        push    edx ecx eax
        invoke  CloseHandle, [.handle]
        test    eax, eax
        jz      .error

        clc
        pop     eax ecx edx
        return

.error:
        pop     eax
if used GetErrorString
        invoke  GetLastError
end if
        stc
        pop     ecx edx
        return
endp


; returns 32bit file size in eax
proc FileSize, .handle
begin
        push    edx ecx

        xor     eax, eax
        invoke  GetFileSize, [.handle], eax
        cmp     eax, -1
        je      .error

        clc
        pop     ecx edx
        return

.error:
if used GetErrorString
        invoke  GetLastError
end if
        stc
        pop     ecx edx
        return
endp



proc FileRead, .handle, .buffer, .count
.read dd ?
begin
        push    edx ecx

        lea     eax, [.read]
        invoke  ReadFile, [.handle], [.buffer], [.count], eax, 0
        test    eax, eax
        jz      .error

        mov     eax, [.read]
        clc
        pop     ecx edx
        return

.error:
if used GetErrorString
        invoke  GetLastError
end if
        stc
        pop     ecx edx
        return
endp




proc FileWrite, .handle, .buffer, .count
.bytes dd ?
begin
        push    edx ecx

        lea     ecx, [.bytes]
        invoke  WriteFile, [.handle], [.buffer], [.count], ecx, NULL
        test    eax, eax
        jz      .error

        mov     eax, [.bytes]
        clc
        pop     ecx edx
        return

.error:
if used GetErrorString
        invoke  GetLastError
end if
        stc
        pop     ecx edx
        return
endp




;----------------------------------------------------
; if CF = 0, eax is the new possition in the file
; if CF = 1, eax is error code.
;----------------------------------------------------
proc FileSeek, .handle, .dist, .direction
begin
        push    edx ecx
        invoke  SetFilePointer, [.handle], [.dist], 0, [.direction]
        cmp     eax, -1
        je      .error

        clc
        pop     ecx edx
        return

.error:
if used GetErrorString
        invoke  GetLastError
end if
        stc
        pop     ecx edx
        return
endp



;----------------------------------------------------
; if CF = 0 - the file was deleted
; if CF = 1, eax is error code.
;----------------------------------------------------
proc FileDelete, .filename
begin
        push    ecx edx eax

        stdcall utf8ToWideChar, [.filename]
        push    eax
        invoke  DeleteFileW, eax
        stdcall FreeMem ; from the stack

        test    eax, eax
        jz      .error
        clc
        pop     eax edx ecx
        return

.error:
        pop     eax
if used GetErrorString
        invoke  GetLastError
end if
        stc
        pop     edx ecx
        return
endp







proc GetErrorString, .code
.buff dd ?
begin
        push    edx ecx
        lea     eax, [.buff]
        invoke  FormatMessageW, FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM, 0, [.code], LANG_NEUTRAL or SUBLANG_DEFAULT, eax, 0, 0

        stdcall WideCharToUtf8, [.buff]
        push    eax

        invoke  LocalFree, [.buff]

        pop     eax
        clc
        pop     ecx edx
        return
endp



proc FreeErrorString, .ptrString
begin
        push    edx ecx
        stdcall StrDel, [.ptrString]
        pop     ecx edx
        return
endp



ftUnknown    =  0
ftDirectory  =  1
ftFile       =  2



; reads all items of the directory and fills them in the TArray of type TDirItem.
; arguments:
;   dir - string with the path to the directory.
;
; returns:
;   if not error: CF=0; eax = pointer to TArray of TDirItem;
;   if error:     CF=1; eax = error code;

proc DirectoryRead, .dir
.finddata FINDDATAW
.size   dd ?
begin
        push    ebx ecx edx edi

; open the file
        stdcall StrDup, [.dir]
        push    eax
        stdcall StrCat, eax, .searchall

        stdcall utf8ToWideChar, eax
        stdcall StrDel ; from the stack

        push    eax

        lea     ecx, [.finddata]
        invoke  FindFirstFileW, eax, ecx
        stdcall FreeMem ; from the stack

        cmp     eax, INVALID_HANDLE_VALUE
        je      .error

        mov     ebx, eax

        stdcall CreateArray, sizeof.TDirItem
        mov     edi, eax

.addloop:
        lea     eax, [.finddata.cFileName]
        stdcall WideCharToUtf8, eax
        push    eax

        stdcall AddArrayItems, edi, 1
        mov     edi, edx

        pop     [eax+TDirItem.hFilename]

        mov     ecx, ftDirectory
        test    [.finddata.dwFileAttributes], FILE_ATTRIBUTE_DIRECTORY
        jnz     .typeok
        mov     ecx, ftFile
.typeok:
        mov     [eax+TDirItem.Type], ecx

        lea     eax, [.finddata]
        invoke  FindNextFileW, ebx, eax
        test    eax, eax
        jnz     .addloop

        invoke  GetLastError
        push    eax

.end_of_directory:

        invoke  FindClose, ebx

        pop     eax
        cmp     eax, ERROR_NO_MORE_FILES
        jne     .finish_error

        mov     eax, edi
        pop     edi edx ecx ebx
        clc
        return

.error:
        invoke  GetLastError

.finish_error:
        pop     edi edx ecx ebx
        stc
        return

.searchall db '\*.*', 0
endp




proc GetFileInfo, .hFile, .ptrFileInfo
begin
        pushad

        mov     esi, [.ptrFileInfo]
        lea     ecx, [esi+TFileInfo.timeAccessed]
        lea     edx, [esi+TFileInfo.timeModified]

        invoke  GetFileTime, [.hFile], esi, ecx, edx
        test    eax, eax
        jz      .error

        mov     eax, dword [esi+TFileInfo.timeCreated]
        mov     edx, dword [esi+TFileInfo.timeCreated+4]
        call    FileTimeToUnixTime
        mov     dword [esi+TFileInfo.timeCreated], eax
        mov     dword [esi+TFileInfo.timeCreated+4], edx

        mov     eax, dword [esi+TFileInfo.timeAccessed]
        mov     edx, dword [esi+TFileInfo.timeAccessed+4]
        call    FileTimeToUnixTime
        mov     dword [esi+TFileInfo.timeAccessed], eax
        mov     dword [esi+TFileInfo.timeAccessed+4], edx

        mov     eax, dword [esi+TFileInfo.timeModified]
        mov     edx, dword [esi+TFileInfo.timeModified+4]
        call    FileTimeToUnixTime
        mov     dword [esi+TFileInfo.timeModified], eax
        mov     dword [esi+TFileInfo.timeModified+4], edx

        clc
        popad
        return

.error:
        stc
        popad
        return

endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/system/Win32/memory.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Dynamic memory management library. Win32 part.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes: Uses Heap functions of Win32 API. Also contains some debug and profiling code,
;         that needs some revision in order to be either removed, or legalized.
;_________________________________________________________________________________________

uses kernel32

uglobal
  var _hHeap=?
endg


uglobal
  var ptrMemoryList  = ?
  var MemMutex       = ?
endg


if DebugMemory

    struct TMemoryItem
      .next     dd ?
      .pointer  dd ?
      .resized  dd ?
      .callfrom dd ?
    ends

    proc InitAllocStack
    begin
            stdcall MutexCreate, 0, MemMutex
            stdcall MutexRelease, MemMutex
            return
    endp

end if


if used SpaceAllocate & ~ used GetMem
initialize ReserveAddressSpace
begin
        invoke  VirtualAlloc, 0, 1024*1024*1024, MEM_RESERVE, PAGE_READWRITE
        mov     [_MemoryFreeSpace], eax
        return
endp
end if


if used GetMem & ~ used SpaceAllocate
initialize InitMemoryManager
begin
        invoke  GetProcessHeap
        mov     [_hHeap], eax

if DebugMemory
        call    InitAllocStack
end if
        return
endp
end if



if DebugMemory
finalize FinalizeMemoryManager
begin
        stdcall MutexDestroy, MemMutex

        mov     eax, [ptrMemoryList]

        int3
        return
endp
end if



; Allocates memory block with given size.
; Returns: CF=1 if error.
;          if CF=0, eax = pointer to the memory block allocated.

proc GetMem, .size
begin
        push    ecx edx
        if defined options.NoZeroMemory & options.NoZeroMemory = 1
          invoke  HeapAlloc, [_hHeap], 0, [.size]
        else
          invoke  HeapAlloc, [_hHeap], HEAP_ZERO_MEMORY, [.size]
        end if
        test    eax, eax
        jz      .error

if DebugMemory
            pushad

            mov     esi, eax    ; allocated address

            stdcall WaitForMutex, MemMutex, -1


            invoke  HeapAlloc, [_hHeap], HEAP_ZERO_MEMORY, sizeof.TMemoryItem
            mov     edi, eax

            mov     [edi+TMemoryItem.pointer], esi

            mov     ecx, [esp+11*4]
            cmp     ecx, CreateArray.retaddr
            jne     @f
            mov     ecx, [esp+11*4+5*4]
@@:
            mov     [edi+TMemoryItem.callfrom], ecx

            mov     ecx, edi
            xchg    [ptrMemoryList], ecx
            mov     [edi+TMemoryItem.next], ecx

            stdcall MutexRelease, MemMutex
            popad
end if
        clc
        pop     edx ecx
        return

.error:
        stc
        pop     edx ecx
        return
endp



proc FreeMem, .ptr
begin
        push    eax ecx edx

if DebugMemory
            pushad

            stdcall WaitForMutex, MemMutex, -1

            mov     ebx, ptrMemoryList
            mov     esi, [ptrMemoryList]
            mov     eax, [.ptr]

    .loop:
            test    esi, esi
            jz      .notfound

            cmp     [esi+TMemoryItem.pointer], eax
            je      .found

            mov     ebx, esi
            mov     esi, [esi+TMemoryItem.next]
            jmp     .loop

    .notfound:
            int3
            jmp     .exit2

    .found:
            mov     eax, [esi+TMemoryItem.next]
            mov     [ebx+TMemoryItem.next], eax

            invoke  HeapFree, [_hHeap], 0, esi

    .exit2:
            stdcall MutexRelease, MemMutex
            popad
end if

        invoke  HeapFree, [_hHeap], 0 , [.ptr]
        test    eax, eax
        jnz     @f
        int3
@@:
        pop     edx ecx eax
        return
endp




proc ResizeMem, .ptr, .newsize
begin
        push    ecx edx

        invoke  HeapReAlloc, [_hHeap], HEAP_ZERO_MEMORY, [.ptr], [.newsize]
        test    eax, eax
        jz      .error

if DebugMemory
            pushad

            stdcall WaitForMutex, MemMutex, -1

            mov     esi, [ptrMemoryList]
            mov     ecx, [.ptr]

    .loop:
            test    esi, esi
            jz      .notfound

            cmp     [esi+TMemoryItem.pointer], ecx
                        je      .found

            mov     esi, [esi+TMemoryItem.next]
            jmp     .loop

    .notfound:
            int3
            jmp     .exit2

    .found:
            mov     [esi+TMemoryItem.pointer], eax
            inc     [esi+TMemoryItem.resized]
            mov     ecx, [esp+11*4]
            cmp     ecx, AddArrayItems.readdr
            jne     @f
            mov     ecx, [esp+11*4+6*4]
@@:
            mov     [esi+TMemoryItem.callfrom], ecx

    .exit2:
            stdcall MutexRelease, MemMutex
            popad
end if

        clc
        pop     edx ecx
        return

.error:
        mov     eax, [.ptr]
        stc
        pop     edx ecx
        return
endp



;
;proc GetMemSize, .ptr
;begin
;        push    ecx edx
;        invoke  HeapSize, [_hHeap], 0, [.ptr]
;        cmp     eax, -1
;        je      .error
;        clc
;        pop     edx ecx
;        return
;
;.error:
;        stc
;        pop     edx ecx
;        return
;endp



proc SpaceAllocate, .size
begin
        push    ecx edx
        invoke  VirtualAlloc, [_MemoryFreeSpace], [.size], MEM_COMMIT, PAGE_READWRITE
        test    eax, eax
        pop     edx ecx
        return
endp


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































Deleted freshlib/system/Win32/network.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: OS dependent part of the network library.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes: This library follows the rules of Berkley sockets library with some small
;         differences (for example in the return values)
;_________________________________________________________________________________________

uses wsock32

uglobal
  __wsaData WSADATA
endg


initialize InitWindowsSockets
begin
        invoke  WSAStartup, $0101, __wsaData
        test    eax, eax
        jz      @f
        int3
@@:
        return
endp

finalize FinishWindowsSockets
begin
        invoke  WSACleanup
        return
endp


proc __SocketError
begin
        cmp     eax, SOCKET_ERROR
        jne     .no_error

        push    ecx edx
        invoke  WSAGetLastError
        pop     edx ecx
        stc
        return

.no_error:
        clc
        return
endp


proc SocketCreate, .protocol_family, .socket_type, .protocol
begin
        push    ecx edx
        invoke  socket, [.protocol_family], [.socket_type], [.protocol]
        call    __SocketError
        pop     edx ecx
        return
endp



proc SocketClose, .hSocket
.buffer rb 1024
begin
        push    ecx edx
        invoke  shutdown, [.hSocket], 1
        call    __SocketError
        jc      .finish

.loop:
        lea     ecx, [.buffer]
        invoke  recv, [.hSocket], ecx, 1024, 0
        call    __SocketError
        jc      .finish
        test    eax, eax
        jnz     .loop

        invoke  closesocket, [.hSocket]
        call    __SocketError

.finish:
        pop     edx ecx
        return
endp



proc SocketConnect, .hSocket, .pAddress
begin
        push    ecx edx
        invoke  connect, [.hSocket], [.pAddress], sizeof.TSocketAddress
        call    __SocketError
        pop     edx ecx
        return
endp



proc SocketBind, .hSocket, .pAddressIn
begin
        push    ecx edx
        invoke  bind, [.hSocket], [.pAddressIn], sizeof.TSocketAddressIn
        call    __SocketError
        pop     edx ecx
        return
endp



proc SocketListen, .hSocket, .maxPending
begin
        push    ecx edx
        invoke  listen, [.hSocket], [.maxPending]
        call    __SocketError
        pop     edx ecx
        return
endp



proc SocketAccept, .hSocket, .pAddress
.addrlen dd ?
begin
        push    edx
        mov     [.addrlen], 0
        mov     [.addrlen], sizeof.TSocketAddress
        lea     ecx, [.addrlen]
        cmp     [.pAddress], 0
        jne     @f
        xor     ecx, ecx
@@:
        invoke  accept, [.hSocket], [.pAddress], ecx
        mov     ecx, [.addrlen]
        call    __SocketError
        pop     edx
        return
endp



proc SocketSend, .hSocket, .pBuffer, .DataLen, .flags
begin
        push    ecx edx
        invoke  send, [.hSocket], [.pBuffer], [.DataLen], [.flags]
        call    __SocketError
        pop     edx ecx
        return
endp


proc SocketReceive, .hSocket, .pBuffer, .BufferSize, .flags
begin
        push    ecx edx
        invoke  recv, [.hSocket], [.pBuffer], [.BufferSize], [.flags]
        call    __SocketError
        pop     edx ecx
        return
endp


proc SocketSendTo, .hSocket, .pBuffer, .DataLen, .flags, .pAddressTo
begin
        push    ecx edx
        invoke  sendto, [.hSocket], [.pBuffer], [.DataLen], [.flags], [.pAddressTo], sizeof.TSocketAddress
        call    __SocketError
        pop     edx ecx
        return
endp


proc SocketReceiveFrom, .hSocket, .pBuffer, .BufferSize, .flags, .pAddressFrom
.addrlen dd ?
begin
        push    edx
        mov     [.addrlen], sizeof.SocketAddress
        lea     ecx,  [.addrlen]
        invoke  recvfrom, [.hSocket], [.pBuffer], [.BufferSize], [.flags], [.pAddressFrom], ecx
        call    __SocketError
        mov     ecx, [.addrlen]
        pop     edx
        return
endp


;proc SetLinger, .hSocket, .fLinger, .timeout
;begin
;        push    ecx edx
;        lea     ecx, [.fLinger]
;        invoke  setsockopt, [.hSocket], SOL_SOCKET, SO_LINGER, ecx, 8
;        call    __SocketError
;        pop     edx ecx
;        return
;endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































Deleted freshlib/system/Win32/process.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Process management library. Win32 part.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

uses kernel32, shell32

; Terminate current process
; Returns: eax = 0

proc Terminate,.exit_code
begin
        invoke ExitProcess, [.exit_code]
        return
endp



proc GetCmdArguments
.argc dd ?
.array dd ?
begin
        pushad
        invoke  GetCommandLineW
        lea     ecx, [.argc]
        invoke  CommandLineToArgvW, eax, ecx
        test    eax, eax
        jz      .error

        push    eax
        mov     esi, eax

        stdcall CreateArray, 4
        mov     [.array], eax

.argloop:
        cmp     [.argc], 0
        je      .endarg

        stdcall WideCharToUtf8, [esi]
        push    eax
        stdcall AddArrayItems, [.array], 1
        mov     [.array], edx
        pop     dword [eax]

        add     esi, 4
        dec     [.argc]
        jmp     .argloop

.endarg:
        invoke  LocalFree ; from the stack...
        popad
        mov     eax, [.array]
        clc
        return

.error:
        popad
        stc
        return
endp



; Creates a new execution thread
; Returns: CF=1 if error.
;          CF=0, eax = pid of the new process being created

proc ThreadCreate, .ptr_to_function, .ptr_to_args
begin
        push    ecx edx

        invoke  CreateThread,NULL,0,[.ptr_to_function],[.ptr_to_args],0,0
        test    eax, eax
        jz      .error

        clc
        pop     edx ecx
        return

.error:
        stc
        pop     edx ecx
        return
endp



proc FreeThreadID, .ThreadID
begin
        push    eax ecx edx
        invoke  CloseHandle, [.ThreadID]
        pop     edx ecx eax
        return
endp



; MUTEX functions
;_________________________________________________________________________________________

proc MutexCreate, .ptrName, .ptrMutex
begin
        push    eax ecx edx

        invoke  CreateMutexW, 0, TRUE, 0
        mov     ecx, [.ptrMutex]
        mov     [ecx], eax
        pop     edx ecx eax
        return
endp




proc WaitForMutex, .ptrMutex, .timeout
begin
        push    eax ecx edx
        mov     ecx, [.ptrMutex]
        invoke  WaitForSingleObject, [ecx], [.timeout]
        cmp     eax, WAIT_TIMEOUT
        clc
        jne     @f
        stc
@@:
        pop     edx ecx eax
        return
endp




proc MutexRelease, .ptrMutex
begin
        pushf
        push    eax ecx edx

        mov     eax, [.ptrMutex]
        invoke  ReleaseMutex, [eax]

        pop     edx ecx eax
        popf
        return
endp



proc MutexDestroy, .ptrMutex
begin
        push    eax ecx edx
        mov     eax, [.ptrMutex]
        pushd   [eax]
        mov     dword [eax], 0
        invoke  CloseHandle ; from the stack
        pop     edx ecx eax
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































Deleted freshlib/system/Win32/timers.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Asynchronous timer library.
;
;  Target OS: Win32
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

uses user32

__sys_time_slice = 10 ;[ms]


uglobal
  if used TimerCreate
    __InternalTimerID     dd ?
    __InternalTimerThread dd ?
  end if
endg



if used TimerCreate

initialize InitWin32Timers
begin
        invoke  SetTimer, 0, 0, __sys_time_slice, __TimerProc
        mov     [__InternalTimerID], eax

        return
endp



finalize FreeWin32Timers
begin
; stop the timer
        invoke  KillTimer, 0, [__InternalTimerID]
        return
endp

end if


; This procedure is called by the system on every time quantum.
; this procedure is Win32 TimerProc

proc __TimerProc, .hwnd, .msg, .timerID, .time
begin
        lea     eax, [__ptrFirstTimer]

.loop:
        mov     eax, [eax+TTimer.next]
.loop2:
        test    eax, eax
        jz      .end_timers

        test    [eax+TTimer.flags], tmfRunning
        jz      .loop

        mov     ecx, [eax+TTimer.value]
        add     ecx, __sys_time_slice
        mov     [eax+TTimer.value], ecx

        cmp     ecx, [eax+TTimer.interval]
        jl      .loop

.exploop:
        inc     [eax+TTimer.Expired]

        mov     ecx, [eax+TTimer.interval]
        sub     [eax+TTimer.value], ecx
        cmp     [eax+TTimer.value], ecx
        jge     .exploop

        cmp     [eax+TTimer.Callback], 0
        je      .end_event

        mov     ecx, [eax+TTimer.flags]
        and     ecx, $0f
        cmp     ecx, tmfDoNothing
        je      .end_event

; call the callback procedure.
.execloop:
        pushad
        stdcall [eax+TTimer.Callback], eax
        popad

        sub     [eax+TTimer.Expired], 1
        jg      .execloop

.end_event:
        test    [eax+TTimer.flags], tmfSyncDestroy
        jz      .loop

        push    eax
        mov     eax, [eax+TTimer.next]  ; after the destruction, this pointer will be lost.
        stdcall TimerDestroy ; pointer from the stack.
        jmp     .loop2

.end_timers:
        return
endp






proc GetSysTime
.time dq ?
begin
        pushad

        lea     eax, [.time]
        invoke  GetSystemTimeAsFileTime, eax


        popad
        return
endp



__filetimeOffset = $19DB1DED53E8000


proc FileTimeToUnixTime
begin
        push    ebx ecx

        sub     eax, __filetimeOffset and $ffffffff
        sbb     edx, __filetimeOffset shr 32

        mov     ebx, eax
        mov     ecx, 10000000   ; 100 ns -> s

        mov     eax, edx
        cdq
        idiv    ecx

        xchg    eax, ebx

        idiv    ecx
        mov     edx, ebx

        pop     ecx ebx
        return
endp



proc GetTime
.time dq ?
begin
        push    ecx

        lea     eax, [.time]
        invoke  GetSystemTimeAsFileTime, eax

        mov     eax, dword [.time]
        mov     edx, dword [.time+4]

        call    FileTimeToUnixTime

        pop     ecx
        return
endp



proc GetLocalTimeOffset
.info TIME_ZONE_INFORMATION
begin
        push    ecx edx

        lea     eax, [.info]
        invoke  GetTimeZoneInformation, eax
        mov     ecx, [.info.bias]

        cmp     eax, TIME_ZONE_ID_DAYLIGHT
        jne     @f
        add     ecx, [.info.DaylightBias]
@@:

        cmp     eax, TIME_ZONE_ID_STANDARD
        jne     @f
        add     ecx, [.info.StandardBias]
@@:

        imul    ecx, 60
        neg     ecx

        mov     eax, ecx
        pop     edx ecx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































Deleted freshlib/system/all.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: System amalgamation include file. Includes all system libraries of FreshLib
;
;  Target OS: Any
;_________________________________________________________________________________________


include 'process.asm'
include 'memory.asm'
include 'files.asm'
include 'clipboard.asm'
include 'environment.asm'
include 'timers.asm'
include 'network.asm'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































Deleted freshlib/system/clipboard.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Clipboard functions for inter-program communications.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: This file contains the OS independent part of the library and includes the
;         respective OS dependent file.
;_________________________________________________________________________________________

module "Clipboard library"


include '%TargetOS%/clipboard.asm'










endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































Deleted freshlib/system/environment.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: OS environment functions.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: This file contains the OS independent part of the library and includes the
;         respective OS dependent file.
;_________________________________________________________________________________________

module "Environment library"


include '%TargetOS%/environment.asm'


endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































Deleted freshlib/system/files.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Files manipulation library.
;
;  Target OS: Any
;
;  Dependencies: Uses memory.asm for memory allocations.
;
;  Notes: This file contains OS independent part of the library and also include
;         the respective OS dependent part.
;_________________________________________________________________________________________
module "Files library"

struct TFileInfo
  .timeCreated   dq ?
  .timeAccessed  dq ?
  .timeModified  dq ?
ends

iglobal
__std_handle_in:
  var STDIN  = 0
__std_handle_out:
  var STDOUT = 1
__std_handle_err:
  var STDERR = 2
endg

;--------------------------------------------------------------------
; Allocates needed memory and loads the entire file in this memory.
; Returns pointer to memory block or NULL if there is error.
; Returns size in ecx
;--------------------------------------------------------------------
proc LoadBinaryFile, .ptrFileName
begin
        push    esi edi ebx

        stdcall FileOpen, [.ptrFileName]
        jc      .error

        mov     edi, eax

        stdcall FileSize, edi
        jc      .errorclose

        mov     ebx, eax
        lea     ecx, [eax+8]    ; It is for the case that the file is
                                ; text and we want to use it as null terminated
                                ; string.

        stdcall GetMem, ecx
        jc      .errorclose
        mov     esi, eax

        stdcall FileRead, edi, esi, ebx
        jc      .errorclosemem

        mov     ecx, eax

        stdcall FileClose, edi

        mov     eax, esi
        clc
        pop     ebx edi esi
        return


.errorclosemem:
        stdcall FreeMem, esi

.errorclose:
        push    eax
        stdcall FileClose, edi
        pop     eax

.error:
        xor     ecx, ecx
        stc
        pop     ebx edi esi
        return
endp



;--------------------------------------------------------------------
; Saves to the file [size] bytes from given [ptr] address.
; returns CF=1 if error and CF=0 if OK.
;--------------------------------------------------------------------
proc SaveBinaryFile, .ptrFileName, .aptr, .size
begin
        push    edi

        stdcall FileCreate, [.ptrFileName]
        jc      .error

        mov     edi, eax
        stdcall FileWrite, edi, [.aptr], [.size]
        jc      .errorclose

        push    eax
        stdcall FileClose, edi
        pop     eax

        clc
        pop     edi
        return

.errorclose:
        push    eax
        stdcall FileClose, edi
        pop     eax

.error:
        stc
        pop     edi
        return
endp


; reads a line from the text file and positions the file pointer to the begining of
; the next line.
; returns string handle with the line in EAX
; returns CF=1 and EAX=error code on error.

proc FileReadLine, .hfile
.result dd ?
.buffer rb 1028
begin
        pushad

        stdcall StrNew
        mov     [.result], eax

.read_loop:
        lea     esi, [.buffer]
        stdcall FileRead, [.hfile], esi, 1024
        jc      .error_read
        test    eax, eax
        jz      .end_of_file

        mov     ebx, eax
        mov     dword [esi+ebx], 0

        cmp     word [esi], $bbef
        jne     .proceed
        cmp     byte [esi+2], $bf
        jne     .proceed

        add     esi, 3

.proceed:
        mov     edi, esi        ; start of the line

.char_loop:
        mov     al, [esi]
        lea     esi, [esi+1]

        cmp     al, $0d
        je      .found
        cmp     al, $0a
        je      .found
        test    al, al
        jnz     .char_loop

.found:
        mov     byte [esi-1], 0
        stdcall StrCat, [.result], edi

        test    al, al
        jnz     .end_of_line
        cmp     ebx, 1024
        je      .read_loop
        jmp     .file_ok

.end_of_line:
        xor     al, $0d xor $0a
        cmp     byte [esi], al
        jne     .eol_ok
        inc     esi
.eol_ok:
        lea     eax, [.buffer]
        sub     esi, eax
        sub     esi, ebx
        jz      .file_ok

        stdcall FileSeek, [.hfile], esi, fsFromCurrent

.file_ok:
        popad
        mov     eax, [.result]
        clc
        return

.error_read:
        stdcall StrDel, [.result]
        stc
        popad
        return

.end_of_file:
        stdcall StrLen, [.result]
        test    eax, eax
        jnz     .file_ok

        stdcall StrDel, [.result]
        popad
        xor     eax, eax
        clc
        return

endp



proc FileWriteString, .file, .hString
begin
        push    ecx

        stdcall StrLen, [.hString]
        mov     ecx, eax
        stdcall StrPtr, [.hString]
        stdcall FileWrite, [.file], eax, ecx

        pop     ecx
        return
endp




; Returns:
; CF=1 if the file NOT EXISTS
; CF=0 if the file EXISTS

proc FileExists, .ptrFileName
begin
        push    eax

        stdcall FileOpen, [.ptrFileName]
        jc      .exit
        stdcall FileClose, eax
        clc
.exit:
        pop     eax
        return
endp




; This structure contains one directory item information.
;

struct TDirItem
  .hFilename dd ?       ; handle of string with the filename.
  .Type      dd ?       ; type of the file. Value of type ftXXXXXX (defined in the OS depending library).
ends



proc FreeDirArray, .pDirArray
begin
        push    eax ecx

        mov     eax, [.pDirArray]
        mov     ecx, [eax+TArray.count]

.freelist:
        dec     ecx
        js      .exit

        stdcall StrDel, [eax+TArray.array+sizeof.TDirItem*ecx+TDirItem.hFilename]
        jmp     .freelist
.exit:
        stdcall FreeMem, eax
        pop     ecx eax
        return
endp



fdsByName = 1
fdsByType = 2

fdsDescending = $80

proc SortDirArray, .pDirArray, .HowToSort
begin
        push    ebx ecx esi

        mov     esi, [.pDirArray]
        xor     ecx, ecx
.outer:

        mov     ebx, ecx
.inner:
        inc     ebx
        cmp     ebx, [esi+TArray.count]
        jae     .next_outer

        test    [.HowToSort], fdsByType
        jz      .by_name

        mov     eax, [esi+TArray.array+8*ecx+TDirItem.Type]
        cmp     eax, [esi+TArray.array+8*ebx+TDirItem.Type]
        ja      .swap
        jb      .inner

.by_name:
        test    [.HowToSort], fdsByName
        jz      .inner

        stdcall StrCompSort2, [esi+TArray.array+8*ecx+TDirItem.hFilename], [esi+TArray.array+8*ebx+TDirItem.hFilename], FALSE
        test    [.HowToSort], fdsDescending
        jnz     @f
        neg     eax
@@:
        test    eax, eax
        jns     .inner

.swap:
        push    [esi+TArray.array+8*ecx+TDirItem.hFilename]
        push    [esi+TArray.array+8*ecx+TDirItem.Type]

        push    [esi+TArray.array+8*ebx+TDirItem.hFilename]
        push    [esi+TArray.array+8*ebx+TDirItem.Type]

        pop     [esi+TArray.array+8*ecx+TDirItem.Type]
        pop     [esi+TArray.array+8*ecx+TDirItem.hFilename]

        pop     [esi+TArray.array+8*ebx+TDirItem.Type]
        pop     [esi+TArray.array+8*ebx+TDirItem.hFilename]
        jmp     .inner

.next_outer:
        inc     ecx
        mov     eax, [esi+TArray.count]
        dec     eax
        cmp     ecx, eax
        jb      .outer

        pop     esi ecx ebx
        return

endp




proc __FileErrorDisplay, .error_code, .filename
begin
        pushad

        stdcall NumToStr, [.error_code], ntsDec or ntsUnsigned
        mov     ebx, eax

        stdcall StrDup, .cErrorOpenString
        push    eax
        stdcall StrCat, eax, ebx
        stdcall StrCharCat, eax, $0a0d
        stdcall StrDel, ebx

        stdcall StrPtr, eax
        stdcall Output, eax
        stdcall StrDel ; from the stack.

        stdcall GetErrorString, [.error_code]
        push    eax
        stdcall StrPtr, eax
        stdcall Output, eax
        stdcall Output, .ccrlf
        stdcall FreeErrorString ; from the stack

        cmp     [.filename], 0
        je      .finish

        stdcall Output, .cErrorFilename
        stdcall StrPtr, [.filename]
        stdcall Output, eax
        stdcall Output, .ccrlf

.finish:
        popad
        return

        .cErrorOpenString db "Error code:", 0
        .cErrorFilename   db "Filename: ", 0
        .ccrlf            db 13, 10, 0
endp


include '%TargetOS%/files.asm'

endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/system/memory.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Dynamic memory management library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: This file contains the OS independent part of the library and includes the
;         respective OS dependent file.
;_________________________________________________________________________________________

module "Memory library"

DebugMemory = 0
cInitialCapacity = 10


include '%TargetOS%/memory.asm'


  ;___________________________________________________________________________
  ;
  ; This is a pointer to the active resize strategy procedure.
  ; There can be many different strategies for resizing dynamic memory objects.
  ; ResizeIt points to a procedure that resizes ecx, according to the particular
  ; strategy.
  ; The resize procedure returns CF=1 if the resize can not be provided.
  ;____________________________________________________________________________
  if used ResizeIt
    ResizeIt dd StrategyGentle
  end if

uglobal
  var _MemoryFreeSpace=?
endg

;____________________________
;
; NewSize = (OldSize+1)*2
; Very aggressive strategy.
;____________________________

proc StrategyAgressive
begin
        add     ecx, 1
        jc      @f
        shl     ecx, 1
@@:
        return
endp



;____________________________
;
; NewSize = (OldSize+2)*1.5
; Normal strategy.
;____________________________

proc StrategyMedium
begin
        push    ecx
        add     ecx, 1
        jc      .exit
        shr     ecx, 1
        add     [esp], ecx
        pop     ecx

        cmp     ecx, cInitialCapacity
        jae     .exit
        mov     ecx, cInitialCapacity
        clc
.exit:
        return
endp


;____________________________
;
; NewSize = (OldSize+2)*1.25
; Memory spare strategy.
;____________________________

proc StrategyGentle
begin
        push    ecx
        add     ecx, 1
        jc      .exit
        shr     ecx, 2
        add     [esp], ecx
        pop     ecx

        cmp     ecx, cInitialCapacity
        jae     .exit
        mov     ecx, cInitialCapacity
        clc
.exit:
        return
endp


endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































Deleted freshlib/system/network.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Network library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________

module "Network library"


struct TSocketAddress
  .saFamily  dw ?
  .saAddress rb 14
ends


struct TSocketAddressIn
  .saFamily  dw ?
  .saPort    dw ?
  .saAddress dd ?
  .saZero    rb 8
ends


include "%TargetOS%/network.asm"





endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































Deleted freshlib/system/process.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Process management library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: Includes the proper OS dependent part of the library.
;_________________________________________________________________________________________
module "Process library"

include '%TargetOS%/process.asm'

endmodule
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































Deleted freshlib/system/timers.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: Asynchronous timer library.
;
;  Target OS: Any
;
;  Dependencies: memory.asm
;
;  Notes: This is OS independent part. Includes OS dependent part files as well.
;_________________________________________________________________________________________
module "Timers library"

tmfDoNothing  = 0       ; when the timer expires no action should be performed. .Expired field of the timer will be incremented.
tmfCallProc   = 1       ; [.callback] contains pointer to procedure that to be executed once per timer expiration.

tmfSyncDestroy = $10    ; If this flag is set, the timer will be destroyed on the next timer expiration. In this case, the configured event is fired and then the timer is destroyed.
                        ; The flag is checked after the event returns, so the event handler can reset this flag and thus to prevent destruction.

tmfRunning     = $80    ; If this flag is set, the timer runs. If the event handler resets this flag, the timer will fire only once and will be suspended.



struct TTimer
; internal pointers of the linked list. The field .next MUST have offset = 0
  .next dd ?            ; don't touch this

; timers parameters.
  .interval dd ?        ; in ms
  .value    dd ?        ; current value in ms. When this value becomes higher than [.interval] an event is fired and the value becomes 0.
                        ; the value is incremented by the system dependent time - probably something like 1..100ms

  .flags    dd ?        ; set of tmfXXXX values.
  .Callback dd ?        ; callback - proc Timer, .ptrTimer; TWindow or 0
  .Expired  dd ?        ; count of the timer expirations.
  .tag      dd ?        ; user value associated with the timer.
ends


struct TDateTime
  .date    dd ?         ; [1..31] depending on month
  .month   dd ?         ; [1..12]
  .year    dd ?         ;
  .hour    dd ?         ; [0..23]
  .minute  dd ?         ; [0..59]
  .second  dd ?         ; [0..59]
  .day     dd ?         ; [0..6] == [monday..sanday]
ends



uglobal
  if used __ptrFirstTimer
    __ptrFirstTimer dd ?
  end if
endg



; Creates a timer and returns pointer to TTimer structure.
; the timer is created suspended. The user can set or reset tmfRunning in [.flags] in order to start or stop the timer.
; also, the user have to enter proper values in the remaining fields.
proc TimerCreate
begin
        push    ecx

        stdcall GetMem, sizeof.TTimer
        jc      .finish

        mov     ecx, [__ptrFirstTimer]
        mov     [eax+TTimer.next], ecx
        mov     [__ptrFirstTimer], eax
        clc

.finish:
        pop     ecx
        return
endp





proc TimerDestroy, .ptrTimer
begin
        push    eax ecx

        mov     eax, [__ptrFirstTimer]
        mov     ecx, __ptrFirstTimer

        test    eax, eax
        jz      .finish                 ; if the list is empty - returns no error.

.loop:
        cmp     eax, [.ptrTimer]
        je      .found

        mov     ecx, eax
        mov     eax, [eax+TTimer.next]
        test    eax, eax
        jnz     .loop

;not found
        pop     ecx eax
        stc
        return

.found:
        push    [eax+TTimer.next]
        pop     [ecx+TTimer.next]       ; if this is the first timer, ecx == __ptrFirstTimer

        stdcall FreeMem, eax

.finish:
        pop     ecx eax
        clc
        return
endp



SECONDS_PER_DAY = 24*60*60
YEAR_EPOCH_START     = 1970


proc TimeToDateTime, .pTime, .pDateTime
.days   dd ?
begin
        pushad

        mov     edi, [.pDateTime]
        mov     esi, [.pTime]

        mov     eax, [esi+4]
        cdq

        mov     ecx, SECONDS_PER_DAY

        idiv    ecx

        mov     eax, [esi]

        idiv    ecx

        test    edx, edx
        jns     @f
        add     edx, SECONDS_PER_DAY
        sub     eax, 1
@@:
        mov     [.days], eax  ; dword [esi] := time div SECONDS_PER_DAY

        mov     eax, edx
        mov     ecx, 60
        cdq                    ; the time should be positive here...

        idiv    ecx
        mov     [edi+TDateTime.second], edx

        cdq
        idiv    ecx
        mov     [edi+TDateTime.minute], edx
        mov     [edi+TDateTime.hour], eax

; date processing. I will assume it is 32bit
; some time in the future, it will overflow (around the 5000000 year), so it will needs a fix. ;)

        mov     edx, [.days]    ; days after YEAR_EPOCH_START
        xor     ebx, ebx        ; years after YEAR_EPOCH_START

.year_loop:
        test    edx, edx
        jns     .positive
; negative days

        dec     ebx
        lea     eax, [ebx+YEAR_EPOCH_START]
        stdcall DaysPerYear, eax
        add     edx, eax
        jmp     .year_loop

.positive:
        lea     eax, [ebx+YEAR_EPOCH_START]
        stdcall DaysPerYear, eax

        cmp     edx, eax
        jb      .finish_year

        sub     edx, eax
        inc     ebx
        jmp     .year_loop

.finish_year:
        add     ebx, YEAR_EPOCH_START
        mov     [edi+TDateTime.year], ebx

; edx contains the days since the current year. It is positive here.
        xor     ebx, ebx

.months_loop:
        stdcall DaysPerMonth, ebx, [edi+TDateTime.year]
        cmp     edx, eax
        jb      .month_ok

        sub     edx, eax
        inc     ebx
        jmp     .months_loop

.month_ok:
        inc     edx
        inc     ebx
        mov     [edi+TDateTime.date], edx
        mov     [edi+TDateTime.month], ebx

; day of the week.

        mov     eax, [.days]      ; days after YEAR_EPOCH_START
        add     eax, 3  ; it was Thursday on 1.1.1970
        cdq
        mov     ecx, 7
        idiv    ecx
        mov     [edi+TDateTime.day], edx

        popad
        return
endp


; redurns the days in the given month or CF=1 on invalid month.
; month should be in [0..11] range.

proc DaysPerMonth, .month, .year
begin
        push    ecx

        mov     ecx, [.month]
        cmp     ecx, 11
        ja      .error

        movzx   ecx, byte [.month_list+ecx]
        cmp     ecx, 28
        jne     .finish

        stdcall DaysPerYear, [.year]
        cmp     eax, 365
        je      .finish

        inc     ecx

.finish:
        mov     eax, ecx
        clc
        pop     ecx
        return

.error:
        xor     eax, eax
        stc
        pop     ecx
        return

.month_list db 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
endp


proc DaysPerYear, .year
begin
        push    ebx ecx edx

        mov     eax, [.year]
        mov     ecx, 400
        cdq
        idiv    ecx

        test    edx, edx
        jz      .leap

        mov     eax, edx
        mov     ecx, 100
        cdq
        idiv    ecx
        test    edx, edx
        jz      .not_leap

        test    edx, $03
        jz      .leap

.not_leap:
        mov     eax, 365
        pop     edx ecx ebx
        return

.leap:
        mov     eax, 366
        pop     edx ecx ebx
        return
endp




include '%TargetOS%/timers.asm'


endmodule



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































Deleted freshlib/test_code/FreshLibUse.fpr.

cannot compute difference between binary files

Deleted freshlib/test_code/FreshLibUse2.fpr.

cannot compute difference between binary files

Deleted freshlib/test_code/FreshLibUse3.fpr.

cannot compute difference between binary files

Deleted freshlib/test_code/main.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
include '%lib%/freshlib.inc'

@BinaryType console

include '%lib%/freshlib.asm'

start:
        InitializeAll

uglobal
ttime dq ?

file_info TFileInfo
endg

.loop:
        stdcall GetTime

        stdcall NumToStr, eax, ntsDec or ntsSigned
        stdcall StrCharCat, eax, $0a

        push    eax eax

        stdcall StrLen, eax
        mov     ecx, eax

        stdcall StrPtr ; from the stack

        stdcall FileWrite, [STDOUT], eax, ecx
        stdcall StrDel ; from the stack

        stdcall FileOpen, filename
        mov     ebx, eax

        stdcall GetFileInfo, ebx, file_info
        jc      .show_error

        mov     eax, dword [file_info.timeModified]

.show_error:
        stdcall NumToStr, eax, ntsDec or ntsSigned
        stdcall StrCharCat, eax, $0a0a

        push    eax eax

        stdcall StrLen, eax
        mov     ecx, eax

        stdcall StrPtr ; from the stack

        stdcall FileWrite, [STDOUT], eax, ecx
        stdcall StrDel ; from the stack

        stdcall FileClose, ebx

        stdcall Sleep, 1000
        jmp     .loop

        FinalizeAll
        stdcall Terminate, 0

filename text 'eve.asm'

uglobal
  buffer rb 1000
endg


@AllImportEmbeded
@AllDataEmbeded
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































Deleted freshlib/test_code/main2.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
include '%lib%/freshlib.inc'

@BinaryType console

include '%lib%/freshlib.asm'

__filetimeoffset = 116444736000000000
__filetimescale  = 10000000             ; 100ns -> 1s

start:

        InitializeAll

.main_loop:
        invoke  GetSystemTimeAsFileTime, time64
        mov     eax, dword [time64]
        mov     edx, dword [time64+4]

        sub     eax, __filetimeoffset and $ffffffff
        sbb     edx, __filetimeoffset shr 32

        mov     ecx, __filetimescale

        mov     ebx, eax
        mov     eax, edx
        cdq

        idiv    ecx
        xchg    eax, ebx        ; hi part is in ebx now
        idiv    ecx
        mov     edx, ebx

; here the unix time is in edx:eax


        stdcall NumToStr, eax, ntsDec or ntsSigned
        mov     ecx, eax

        stdcall StrLen, ecx
        push    eax
        stdcall StrPtr, ecx
        push    eax
        stdcall FileWrite, [STDOUT]

        stdcall FileWrite, [STDOUT], message, message.length
        stdcall FileRead,  [STDIN],  buffer, 100
        cmp     byte [buffer], 'q'
        jne     .main_loop

        FinalizeAll
        stdcall Terminate, 0

message text 13, 10

uglobal
  buffer rb 1000

  time64 dq ?
endg


@AllImportEmbeded


@AllDataEmbeded
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































Deleted freshlib/test_code/main3.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
include '%lib%/freshlib.inc'

@BinaryType console

include '%lib%/freshlib.asm'

options.AlignCode = 0

LOOP_COUNT = 1000000000

start:
        InitializeAll

        stdcall GetTimestamp
        mov     ebx, eax

        mov     ecx, LOOP_COUNT

.loop1:
        stdcall Dispatch1, $02345678, 1, 1
        dec     ecx
        jnz     .loop1

        stdcall GetTimestamp
        sub     eax, ebx

        stdcall NumToStr, eax, ntsDec or ntsUnsigned
        mov     esi, eax

        stdcall FileWriteString, [STDOUT], cMessage1
        stdcall FileWriteString, [STDOUT], esi
        stdcall FileWriteString, [STDOUT], cCRLF

; cmp based dispatch

        stdcall GetTimestamp
        mov     ebx, eax

        mov     ecx, LOOP_COUNT

.loop2:
        stdcall Dispatch2,  $02345678, 1, 1
        dec     ecx
        jnz     .loop2

        stdcall GetTimestamp
        sub     eax, ebx

        stdcall NumToStr, eax, ntsDec or ntsUnsigned
        mov     esi, eax

        stdcall FileWriteString, [STDOUT], cMessage2
        stdcall FileWriteString, [STDOUT], esi
        stdcall FileWriteString, [STDOUT], cCRLF

        stdcall FileReadLine, [STDIN]
        stdcall StrDel, eax

        FinalizeAll
        stdcall Terminate, 0


cMessage1 text 'dproc based dispatch time: '
cMessage2 text 'cmp based dispatch time: '
cCRLF     text 13, 10


dproc Dispatch1, .arg1, .arg2, .arg3
begin
        dispatch [.arg1]
        return

oncase $12345678
       return
       rb 256

oncase $12345679
       return
       rb 256

oncase $12345680
       return
       rb 256

oncase $12345681
       return
       rb 256

enddp


proc Dispatch2, .arg1, .arg2, .arg3
begin
        mov     eax, [.arg1]

        cmp     eax, $12345678
        je      .case1

        cmp     eax, $12345679
        je      .case2

        cmp     eax, $12345680
        je      .case3

        cmp     eax, $12345681
        je      .case4

        return

.case1:
        return
        rb 256

.case2:
        return
        rb 256

.case3:
        return
        rb 256

.case4:
        return
        rb 256

endp


proc Dispatch3, .arg1, .arg2, .arg3
begin
        cmp     [.arg1], $12345678
        je      .case1

        cmp     [.arg1], $12345679
        je      .case2

        cmp     [.arg1], $12345680
        je      .case3

        cmp     [.arg1], $12345681
        je      .case4

        return

.case1:
        return
        rb 256

.case2:
        return
        rb 256

.case3:
        return
        rb 256

.case4:
        return
        rb 256

endp

call Dispatch2
call Dispatch3

; Dispatch1.__info.codesize = $442
; Dispatch2.__info.codesize = $442
; Dispatch3.__info.codesize = $447


@AllImportEmbeded
@AllDataEmbeded
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































Deleted freshlib/test_code/md5_test/MD5_test.fpr.

cannot compute difference between binary files

Deleted freshlib/test_code/md5_test/md5_test.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
include "%lib%/freshlib.inc"
@BinaryType console

include "%lib%/freshlib.asm"

start:
        int3
        InitializeAll

        stdcall GetCmdArguments
        mov     esi, eax

        stdcall FileWriteString, [STDOUT], [esi+TArray.array+4]
        stdcall FileWriteString, [STDOUT], cSeparator

        stdcall StrMD5, [esi+TArray.array+4]
        stdcall FileWriteString, [STDOUT], eax

cSeparator text '>>>'

        FinalizeAll
        stdcall Terminate, 0



@AllImportEmbeded
@AllDataEmbeded
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































Deleted freshlib/test_code0/TestGround.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;   Description: Very simple test application for FreshLib.
;                The content may change arbitrary.
;
;   Target OS: All/Linux/Win32 - depending on current test needs.
;
;   Dependencies:
;
;   Notes: The main test program calls "PrepareDemo" procedure.
;_________________________________________________________________________________________

__TestGround:

; Global data...
iglobal

__TestData:

frmMainForm:
        ObjTemplate  tfParent or tfEnd, Form, frmMain, \
                     x, 300,        \
                     y, 250,        \
                     width, 360,    \
                     height, 240,   \
                     Visible, TRUE, \
                     Caption, 'FreshLib minimal application test.'

           ObjTemplate tfChild or tfEnd, Button, btnOpenModal,                      \
                       x, 50,                                                       \
                       y, 50,                                                       \
                       width, 120,                                                  \
                       height, 75,                                                  \
                       Visible, TRUE,                                               \
                       TextAlign, dtfAlignCenter or dtfAlignMiddle or dtfWordWrap , \
                       Caption, 'Click to check your assembly skills.',             \
                       OnClick, OpenModalForm


__TestDataSize = $ - __TestData
endg




proc PrepareDemo
begin
        stdcall CreateFromTemplate, frmMainForm, 0
        mov     ecx, [pApplication]
        mov     [ecx+TApplication.MainWindow], frmMain

        return
endp


proc OpenModalForm, .self, .button
begin
        push    ebx

        stdcall ShowMessage, [frmMain], smiQuestion,                                    \
                'One question test:',                                                   \
                'Are you agree, that FlatAssembler is the best assembler world-wide?',  \
                smbYes or smbNo or smbMaybe ; or smbAbort or smbRetry or smbIgnore or smbYes or smbNo or smbHelp

        mov     esi, .msgYes
        mov     ecx, smiInformation
        cmp     eax, mrYes
        je      .finish

        mov     esi, .msgNo
        mov     ecx, smiError
        cmp     eax, mrNo
        je      .finish

        mov     esi, .msgMaybe
        mov     ecx, smiQuestion
        cmp     eax, mrMaybe
        je      .finish

        mov     esi, .msgRefuse
        mov     ecx, smiWarning
.finish:
        stdcall ShowMessage, [frmMain], ecx, 'Test results', esi, smbOK

        pop     ebx
        return

OpenModalForm.msgYes    text "You really understand the spirit of the assembly!", 13, "Congratulations!"
OpenModalForm.msgNo     text "So, go write some C# and don't mess with assembly. It is not for you."
OpenModalForm.msgMaybe  text "You should forget about your doubts and reject these HLL temptations, or your soul will be lost forever! Go, write some assembly and feel the power!"
OpenModalForm.msgRefuse text "It is wrong to avoid to answer, only because you are not sure..."

endp






DispSize 'Test ground dummy code:', ($-__TestGround)+__TestDataSize
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































Deleted freshlib/test_code0/TestGroundComplex.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;   Description: Complex test application for FreshLib the content may change arbitrary.
;
;   Target OS: All/Linux/Win32 - depending on current test needs.
;
;   Dependencies:
;
;   Notes: The main test program calls "PrepareDemo" procedure.
;_________________________________________________________________________________________

__TestGround:

iglobal

__TestData:
; This is a form template.
; It will be created by the visual editor.
; This template engine can contains any count of properties for every
; component of the template. Also it can contains non visual components
; such as action lists, image lists, etc.

TemplateMainForm:
        ObjTemplate  tfParent or tfEnd, Form, frmMain, \
                     x, 100,        \
                     y, 50,         \
                     width, 656,    \
                     height, 496,   \
                     Visible, TRUE, \
                     OnDestroy, FormOnDestroy,  \
                     Caption, 'Fresh portable Win32/Linux application test.'

          ObjTemplate  tfChild, Button, btnChild1,          \
                     x, 48,         \
                     y, 48,         \
                     width, 80,     \
                     height, 48,    \
                     TextAlign, dtfAlignLeft or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption, 'Button1',        \
                     Visible, TRUE, \
                     OnClick, Button1Click

          ObjTemplate  tfChild, Button, btnChild3,          \
                     x, 48,         \
                     y, 112,         \
                     width, 80,     \
                     height, 48,    \
                     TextAlign, dtfAlignCenter or dtfAlignMiddle or dtfWordWrap,\
                     Caption, 'Stop/Start timer1',        \
                     Visible, TRUE, \
                     OnClick, Button3Click

          ObjTemplate  tfChild, Button, btnChild4,          \
                     x, 48,         \
                     y, 162,         \
                     width, 80,     \
                     height, 48,    \
                     TextAlign, dtfAlignCenter or dtfAlignMiddle or dtfWordWrap,\
                     Caption, 'Stop/Start timer2',        \
                     Visible, TRUE, \
                     OnClick, Button4Click

          ObjTemplate  tfChild, Edit, editChild1,          \
                     x, 48,         \
                     y, 8,         \
                     width, 294,     \
                     height, 21,    \
                     Caption, 'Edit1',        \
                     Visible, TRUE, \
                     Text, utf8_string

         ObjTemplate tfChild, Progress, Progress1,      \
                     x, 48, y, 262,                      \
                     width, 294, height, 21,              \
                     Color, $000080,                      \
                     Max, 1000, Pos, 350,                  \
                     Align, waBottom,                      \
                     Visible, TRUE

         ObjTemplate  tfChild or tfEnd, Button, btnChild2,          \
                     x, 140,         \
                     y, 48,         \
                     width, 202,     \
                     height, 202,        \
                     TextAlign, dtfAlignJustify or dtfAlignMiddle or dtfCRLF or dtfWordWrap,\
                     Caption, utf8_long,       \
                     Visible, TRUE,  \
                     OnClick, Button2Click


include "UTF8_examples.asm"


  cGifIcon file '_test_images/icon.gif'
  sizeof.cGifIcon = $ - cGifIcon


; example of menu structure - it is typical File menu.
; It should be created with CreateFromTemplate procedure.
; If can be child of some form as well and then it should
; appears as a main menu in the form.

;menuFile:
;    ObjTemplate tfParent or tfEnd, Menu, .PopupMenu1,        \
;                  caption, 'File'
;      ObjTemplate tfChild, MenuItem, .menuItemNew,  \
;                  kind, mikCommand,             \
;                  pAction, FileActions.actFileNew
;      ObjTemplate tfChild, MenuItem, .menuItemOpen,  \
;                  kind, mikCommand,      \
;                  pAction, FileActions.actFileOpen
;      ObjTemplate tfChild or tfParent, Menu, .menuReopen, \
;                  caption, 'Reopen'
;
;            ObjTemplate tfChild, MenuItem, .menuItemCleanup,     \
;                        kind, mikCommand,                         \
;                        pAction, FileActions.actReopenMenuCleanup
;
;            ObjTemplate tfChild or tfEnd, MenuItem, .menuSep1,   \
;                        kind, mikSeparator
;      ObjTemplate tfChild, MenuItem, .menuSep2,      \
;                  kind, mikSeparator
;      ObjTemplate tfChild, MenuItem, .menuItemSave,  \
;                  kind, mikCommand,                 \
;                  pAction, FileActions.actSave
;      ObjTemplate tfChild, MenuItem, .menuItemSaveAs,  \
;                  kind, mikCommand,                 \
;                  pAction, FileActions.actSaveAs
;      ObjTemplate tfChild, MenuItem, .menuItemSaveAll,  \
;                  kind, mikCommand,                 \
;                  pAction, FileActions.actSaveAll
;      ObjTemplate tfChild, MenuItem, .separator2,      \
;                  kind, mikSeparator
;      ObjTemplate tfChild or tfEnd, MenuItem, .menuItemExit,  \
;                  kind, mikCommand,                 \
;                  pAction, FileActions.actExit
;
; just for test

;ActionList FileActions,                                                     \
;  .actFileNew, '&New', 'Creates new file', 0, <Ctrl, 'N'>, NONE, NONE,      \
;  .actFileOpen, '&Open', 'Open file from disk', 0, <Ctrl, 'O'>, NONE, NONE, \
;  .actReopenMenuCleanup, 'Cleanup list', 'Cleans the reopen list.', 0, NONE, NONE, NONE, \
;  .actSave, '&Save', 'Save current file', 0, <Ctrl, 'S'>, NONE, NONE, \
;  .actSaveAs, 'Sa&ve as', 'Save current file with new name.', 0, <Ctrl+Alt, 'S'>, NONE, NONE, \
;  .actSaveAll, 'Save &All', 'Save all changed files.', 0, <Ctrl+Shift, 'S'>, NONE, NONE, \
;  .actExit, 'E&xit', 'Exit application', 0, <Alt, 'X'>, NONE, NONE


__TestDataSize = $ - __TestData

endg





; Sample event handlers. They work with other objects on the form.

proc FormOnDestroy, .self
begin
        DebugMsg "MainForm destroy event handler."
        stdcall TimerDestroy, [test_timer1]
        stdcall TimerDestroy, [test_timer2]
        return
endp


proc Button4Click, .self, .button
begin
        mov     ecx, [test_timer2]
        xor     [ecx+TTimer.flags], tmfRunning

        stdcall Set, [Progress1], TProgress.Pos, 0

        DebugMsg 'Button4 clicked'
        return
endp



proc Button3Click, .self, .button
begin
        mov     eax, [test_timer1]
        xor     [eax+TTimer.flags], tmfRunning

        DebugMsg 'Button3 clicked'
        return

        mov     ebx, [frmMain]

        stdcall Get, ebx, TWindow.x
        push    eax
        stdcall Get, ebx, TWindow.y
        push    eax

        stdcall Get, ebx, TWindow.borderKind
        xor     eax, 1
        stdcall Set, ebx, TWindow.borderKind, eax
        stdcall Set, [.self], TWindow.Caption, [_dual_caption+4*eax]

iglobal
  _dual_caption dd _cCaption1, _cCaption2

  _cCaption1 text 'Remove the title'
  _cCaption2 text 'Restore the title'
endg

; The old coordinates must be restored, because the window manager moves the window
; when restoring the title bar.
        stdcall Set, ebx, TWindow.y ; from the stack
        stdcall Set, ebx, TWindow.x ; from the stack

        return
endp




proc Button1Click, .self, .button
begin
        DebugMsg 'Button1 clicked'

        stdcall Get, [btnChild2], TButton.TextAlign
        mov     ecx, eax
        and     ecx, not $03
        inc     eax
        and     eax, 3
        or      eax, ecx
        stdcall Set, [btnChild2], TButton.TextAlign, eax

        stdcall Get, [btnChild1], TButton.Caption
        stdcall Set, [editChild1], TEdit.Text, eax
        stdcall StrDel, eax

iglobal
  cGifFile file '_test_images/test.gif'
  sizeof.cGifFile = $ - cGifFile
endg

        stdcall CreateImageGIF, cGifFile, sizeof.cGifFile
        mov     esi, eax

        mov     eax, [frmMain]
        stdcall AllocateContext, [eax+TWindow.handle]
        jc      .end
        push    eax
        stdcall SetDrawMode, eax, cmCopy
        stdcall DrawImage, eax, esi, 394, 0
        stdcall ReleaseContext ; from the stack

.end:
        stdcall DestroyImage, esi
        return
endp



proc Button2Click, .self, .button
begin
       DebugMsg 'Button2 clicked'

        stdcall Get, [btnChild1], TButton.IconPosition
        inc     eax
        and     eax, 3
        stdcall Set, [btnChild1], TButton.IconPosition, eax

        mov     eax, [_text_align_for_icon+4*eax]
        stdcall Set, [btnChild1], TButton.TextAlign, eax

iglobal
  _text_align_for_icon dd dtfAlignLeft or dtfAlignMiddle
                       dd dtfAlignRight or dtfAlignMiddle
                       dd dtfAlignCenter or dtfAlignTop
                       dd dtfAlignCenter or dtfAlignBottom
endg

        stdcall Get, [btnChild2], TButton.Caption
        stdcall Set, [editChild1], TEdit.Text, eax
        stdcall StrDel, eax

        return
endp



uglobal
  test_timer1 dd ?
  test_timer2 dd ?
endg



proc procTestTimer1, .ptrTimer
begin
        stdcall Get, [btnChild1], TButton.IconPosition
        and     eax, 3
        mov     eax, [__align4+4*eax]
        stdcall Set, [btnChild1], TButton.IconPosition, eax

        mov     eax, [_text_align_for_icon+4*eax]
        stdcall Set, [btnChild1], TButton.TextAlign, eax
        return
endp

iglobal
  __align4 dd AlignTop, AlignBottom, AlignRight, AlignLeft
endg

uglobal
  Flag dd ?
  .Y dd ?
  .X dd ?
  .incX dd ?
  .incY dd ?
endg




proc procTestTimer2, .ptrTimer
.width dd ?
.height dd ?
begin

        execute [Progress1], TProgress.Step
;        stdcall Get, [Progress1], TProgress.Pos
;        mov     ecx, eax
;        stdcall Get, [Progress1], TProgress.Max
;
;        inc     ecx
;        cmp     ecx, eax
;        jle     @f
;        xor     ecx, ecx
;@@:
;        stdcall Set, [Progress1], TProgress.Pos, ecx

;        DebugMsg "Timer2 enter"

        mov     eax, [frmMain]
        stdcall AllocateContext, [eax+TWindow.handle]
        jc      .exit
        mov     ebx, eax

        stdcall Get, [frmMain], TWindow.width
        sub     eax, 16
        mov     [.width], eax
        stdcall Get, [frmMain], TWindow.height
        sub     eax, 16
        mov     [.height], eax

        stdcall DrawFillRect, ebx, [Flag.X], [Flag.Y], 16, 16, $ff0000  ;c0c0c0

        mov     eax, [Flag.X]
        add     eax, [Flag.incX]
        js      .backx
        cmp     eax, [.width]
        jg      .backx

        mov     [Flag.X], eax
        jmp     .xok

.backx:
        neg     [Flag.incX]

.xok:
        mov     eax, [Flag.Y]
        add     eax, [Flag.incY]
        js      .backy
        cmp     eax, [.height]
        jg      .backy

        mov     [Flag.Y], eax
        jmp     .yok

.backy:
        neg     [Flag.incY]
.yok:
        stdcall SetDrawMode, ebx, cmCopy
        stdcall DrawImage, ebx, [Flag], [Flag.X], [Flag.Y]

        stdcall ReleaseContext, ebx

;        DebugMsg "Timer2 exit"
.exit:
        return
endp






proc PrepareDemo
begin
;        stdcall CaretAttach, 0

        stdcall CreateFromTemplate, TemplateMainForm, 0
        mov     ecx, [pApplication]
        mov     [ecx+TApplication.MainWindow], frmMain

        stdcall CreateImageGIF, cGifIcon, sizeof.cGifIcon
        stdcall Set, [btnChild1], TButton.Icon, eax
        stdcall Set, [btnChild1], TButton.IconPosition, AlignLeft

; the timers must be created before application start.
; I don't know why.
; Maybe it is safe to create timers in some event handlers... should be checked.
;
        stdcall CreateImageGIF, cGifIcon, sizeof.cGifIcon
        mov     [Flag], eax

        mov     [Flag.X], 120
        mov     [Flag.Y], 0
        mov     [Flag.incX], 1
        mov     [Flag.incY], 1


        stdcall TimerCreate
        mov     [test_timer1], eax
        mov     [eax+TTimer.interval], 100
        mov     [eax+TTimer.Callback], procTestTimer1
        mov     [eax+TTimer.flags], tmfCallProc

        stdcall TimerCreate
        mov     [test_timer2], eax
        mov     [eax+TTimer.interval], 2
        mov     [eax+TTimer.value], 0
        mov     [eax+TTimer.Callback], procTestTimer2
        mov     [eax+TTimer.flags], tmfCallProc

;
;        mov     eax, [test_timer1]
;        or     [eax+TTimer.flags], tmfRunning
;        mov     eax, [test_timer2]
;        or     [eax+TTimer.flags], tmfRunning
        return
endp


DispSize 'Test ground dummy code:', ($-__TestGround)+__TestDataSize
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/test_code0/TestGroundConfig.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568


iglobal
frmMainForm:
; The form
        ObjTemplate  tfParent or tfEnd, Form, frmMain, x, 100, y, 50, width, 640, height, 340, Visible, TRUE, Caption, 'FreshLib uConfig files editor.'

            ; log window
            ObjTemplate tfChild, FreshEdit, editLog, x, 330, y, 0, width, 240, height, 200, Visible, TRUE, Align, waClient, _fReadOnly, froReadOnlyNoCaret

            ObjTemplate  tfParent or tfEnd, Form, frmToolPanel, borderKind, borderNone, Align, waLeft,x ,0, y, 0, width, 200, height, 340, Visible, TRUE

                ; file buttons
                ObjTemplate tfChild, Button, btnNewDB, x, 4,   y, 2, width, 64, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle,  Caption, 'New', OnClick, procOnNewDB
                ObjTemplate tfChild, Button, btnOpenDB, x, 67,  y, 2, width, 64, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Open', OnClick, procOnOpenDB
                ObjTemplate tfChild, Button, btnSaveDB, x, 130, y, 2, width, 64, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Save', OnClick, procOnSaveDB

                ; record buttons
                ObjTemplate tfChild, Button, btnReadRecord, x, 4, y, 194, width, 60, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Read', OnClick, procOnRead
                ObjTemplate tfChild, Button, btnWriteRecord, x, 69, y, 194, width, 60, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Write', OnClick, procOnWrite
                ObjTemplate tfChild, Button, btnDeleteRecord, x, 134, y, 194, width, 60, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Delete', OnClick, procOnDelete

                ; type buttons
                ObjTemplate tfChild, Label,  lblDataType,   x, 69, y, 224,  width, 60, height, 60, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'cdtString'
                ObjTemplate tfChild, Button, btnTypeString,  x, 4, y, 224, width,  60, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'String', OnClick, procOnType
                ObjTemplate tfChild, Button, btnTypeInt,     x, 4, y, 244, width,  60, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Number', OnClick, procOnType
                ObjTemplate tfChild, Button, btnTypeNull,    x, 4, y, 264, width,  60, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Null', OnClick, procOnType

                ; log buttons
                ObjTemplate tfChild, Button, btnListTree, x, 134, y, 244, width, 60, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'List >>>', OnClick, procOnListTree
                ObjTemplate tfChild, Button, btnClearLog, x, 134, y, 264, width, 60, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Clear >>>', OnClick, procOnClearLog

                ; edit boxes
                ObjTemplate tfChild, Label, lblFilename,   x, 4, y, 24,  width, 100, height, 19, Visible, TRUE, TextAlign, dtfAlignLeft or dtfAlignBottom, Caption, 'File name:'
                ObjTemplate tfChild, Edit,  editFilename,  x, 4, y, 44,  width, 190, height, 19, Visible, TRUE, Text, '../phWeb.conf'

                ObjTemplate tfChild, Label, lblSignature,  x, 4, y, 64,  width, 100, height, 19, Visible, TRUE, TextAlign, dtfAlignLeft or dtfAlignBottom, Caption, 'Signature:'
                ObjTemplate tfChild, Edit,  editSignature, x, 4, y, 84,  width, 190, height, 19, Visible, TRUE

                ObjTemplate tfChild, Label, lblKey,  x, 4, y, 104,  width, 100, height, 19, Visible, TRUE, TextAlign, dtfAlignLeft or dtfAlignBottom, Caption, 'Full key name:'
                ObjTemplate tfChild, Edit,  editKey, x, 4, y, 124,  width, 190, height, 19, Visible, TRUE

                ObjTemplate tfChild,          Label, lblValue, x, 4, y, 144,  width, 100, height, 19, Visible, TRUE, TextAlign, dtfAlignLeft or dtfAlignBottom, Caption, 'Value:'
                ObjTemplate tfChild or tfEnd, Edit,  editValue,    x, 4, y, 164,  width, 190, height, 19, Visible, TRUE
endg



proc PrepareDemo
begin
        stdcall CreateFromTemplate, frmMainForm, 0
        mov     ecx, [pApplication]
        mov     [ecx+TApplication.MainWindow], frmMain
        execute [frmMain], TForm.AlignChildren
        return
endp



uglobal
  DataBase dd ?
endg

iglobal
  DataType dd cdtString
endg


proc procOnType, .self, .button
begin
        mov     eax, [.self]
        cmp     eax, [btnTypeString]
        je      .string

        cmp     eax, [btnTypeInt]
        je      .int

        cmp     eax, [btnTypeNull]
        je      .null

        int3

.string:
        mov     [DataType], cdtString
        mov     eax, .txtString
        jmp     .finish

.int:
        mov     [DataType], cdtInteger
        mov     eax, .txtInteger
        jmp     .finish

.null:
        mov     [DataType], cdtNULL
        mov     eax, .txtNull

.finish:
        stdcall Set, [lblDataType], TLabel.Caption, eax
        execute [lblDataType], TLabel.Refresh
        return

.txtString db 'cdtString',0
.txtInteger db 'cdtInteger', 0
.txtNull    db 'cdtNULL', 0
endp


proc procOnClearLog, .self, .button
begin
        execute [editLog], TFreshEdit.Clear
        return
endp


proc procOnListTree, .self, .button
.prolog dd ?
begin
        push    esi

        mov     esi, [DataBase]
        test    esi, esi
        jz      .finish

        execute [editLog], TFreshEdit.Clear

        stdcall StrNew
;        stdcall StrCharCat, eax, $9c94e2
;        stdcall StrCharCat, eax, $8094e2
        stdcall __DoListTree, esi, eax

        execute [editLog], TFreshEdit.Refresh
        stdcall TFreshEdit.__UpdateScrollBars, [editLog]

.finish:
        pop     esi
        return
endp


proc __DoInsChar, .char
begin
        pushad
        execute [editLog], TFreshEdit.InsertChar, [.char]
        popad
        return
endp


proc __DoInsString, .str
begin
        pushad
        execute [editLog], TFreshEdit.InsertString, [.str]
        popad
        return
endp


proc __DoListTree, .array, .prolog
begin
        pushad

        mov     esi, [.array]
        mov     ecx, [esi+TArray.count]
        lea     esi, [esi+TArray.array]

.main_loop:
        test    ecx, ecx
        jz      .finish

        stdcall __DoInsString, [.prolog]

        mov     eax, $9c94e2
        cmp     ecx, 1
        jne     @f
        mov     eax, $9494e2
@@:
        stdcall __DoInsChar, eax
        stdcall __DoInsChar, $8094e2

        mov     ebx, [esi+TConfigRecord.KeyName]

.keynameloop:
        movzx   edx, bl
        stdcall __DoInsChar, edx
        shr     ebx, 8
        jnz     .keynameloop

        cmp     [esi+TConfigRecord.Type], cdtConfig
        je      .next_row

        stdcall __DoInsChar, '='

        cmp     [esi+TConfigRecord.Type], cdtString
        je      .handle_string

        cmp     [esi+TConfigRecord.Type], cdtInteger
        je      .handle_integer

        cmp     [esi+TConfigRecord.Type], cdtNULL
        je      .handle_null

        cmp     [esi+TConfigRecord.Type], cdtBlob
        jne     .next_row
; handle blobs
        stdcall __DoInsString, cBlobValue
        jmp     .next_row

cBlobValue text 'BLOB()'
cNULLValue text 'NULL'

.handle_null:
        stdcall __DoInsString, cNULLValue
        jmp     .next_row

.handle_integer:
        stdcall NumToStr, [esi+TConfigRecord.Data], ntsHex or ntsUnsigned
        push    eax
        stdcall __DoInsChar, '$'
        stdcall __DoInsString, eax
        stdcall StrDel ; from the stack
        jmp     .next_row

.handle_string:
        stdcall __DoInsChar, '"'
        stdcall __DoInsString, [esi+TConfigRecord.Data]
        stdcall __DoInsChar, '"'

.next_row:
        stdcall __DoInsChar, $0d

        cmp     [esi+TConfigRecord.Type], cdtConfig
        jne     .next

        stdcall StrLen, [.prolog]
        push    eax

        mov     eax, $8294e2  ;'|'
        cmp     ecx, 1
        jne     @f
        mov     eax, ' '
@@:
        stdcall StrCharCat, [.prolog], eax
        stdcall StrCharCat, [.prolog], ' '

        stdcall __DoListTree, [esi+TConfigRecord.Data], [.prolog]
        pop     edx

        stdcall StrPtr, [.prolog]
        mov     [eax+string.len], edx
        mov     dword [eax+edx], 0

.next:
        add     esi, sizeof.TConfigRecord
        dec     ecx
        jmp     .main_loop

.finish:
        mov     eax, [editLog]
        push    [eax+TFreshEdit._xCaret] [eax+TFreshEdit._yCaret]
        pop     [eax+TFreshEdit._ySelection] [eax+TFreshEdit._xSelection]
        popad
        return
endp



proc UpdateEdits, .config
.str rd 2
begin
        push    esi
        mov     esi, [.config]

        mov     eax, [esi+TArray.lparam]
        mov     [.str], eax
        mov     [.str+4], 0
        lea     eax, [.str]
        stdcall Set, [editSignature], TEdit.Text, eax

        pop     esi
        return
endp


proc procOnNewDB, .self, .button
begin
        stdcall FreeConfigDB, [DataBase]
        stdcall LoadConfigDB, 0, 'TEST'
        mov     [DataBase], eax

        stdcall UpdateEdits, eax

        stdcall LogMessage, cNewDatabase
        return
endp

cNewDatabase text 'New database created.', 13

proc procOnOpenDB, .self, .button
begin
        stdcall Get, [editFilename], TEdit.Text
        push    eax
        stdcall StrPtr, eax
        stdcall LoadBinaryFile, eax
        jc      .error_file

        mov     esi, eax
        stdcall StrDel ; from the stack

        stdcall FreeConfigDB, [DataBase]
        mov     [DataBase], 0
        stdcall LoadConfigDB, esi, -1
        jnc     .load_ok

        stdcall LogMessage, cErrorLoad

        stdcall FreeMem, esi
        return

.load_ok:
        mov     [DataBase], eax
        stdcall FreeMem, esi
        stdcall UpdateEdits, [DataBase]
        stdcall LogMessage, cLoadedOK
        return

.error_file:
        stdcall LogMessage, cErrorLoadFile
        return
endp

cErrorLoadFile text 'Error loading config database.', 13
cErrorLoad text 'Error parsing config database.', 13
cLoadedOK  text 'Database loaded successfully.', 13

proc LogMessage, .string
begin
        push    eax
        execute [editLog], TFreshEdit.InsertString, [.string]
        mov     eax, [editLog]
        push    [eax+TFreshEdit._xCaret] [eax+TFreshEdit._yCaret]
        pop     [eax+TFreshEdit._ySelection] [eax+TFreshEdit._xSelection]
        execute [editLog], TFreshEdit.Refresh
        stdcall TFreshEdit.__UpdateScrollBars, [editLog]        ; not this
        pop     eax
        return
endp


proc procOnSaveDB, .self, .button
.signature dd ?
begin
        stdcall Get, [editSignature], TEdit.Text
        push    eax
        stdcall StrPtr, eax
        mov     eax, [eax]
        mov     [.signature], eax
        stdcall StrDel ; from the stack

        stdcall Get, [editFilename], TEdit.Text
        mov     ecx, eax
        stdcall StrPtr, ecx
        mov     edx, eax

        stdcall SaveConfigFile, [DataBase], [.signature]
        mov     esi, eax
        lea     eax, [eax+TArray.array]

        mov     ebx, [esi+TArray.count]
        shl     ebx, 2
        stdcall SaveBinaryFile, edx, eax, ebx

        stdcall StrDel, ecx
        stdcall FreeMem, esi

.finish:
        return
endp


; returns edx - array to the directory.
; eax - the key name.

proc __DecodeDirectory, .hstring
begin
        push    ebx ecx esi

        stdcall CreateArray, 4
        mov     edx, eax

        stdcall StrPtr, [.hstring]
        mov     esi, eax

.main_loop:
        mov     ecx, 4
        xor     ebx, ebx

.byteloop:
        lodsb

        cmp     al, '|'
        je      .end_key
        cmp     al, 0
        je      .end_key

        ror     ebx, 8
        mov     bl, al

        loop    .byteloop

.end_key:
        inc     ecx
        shl     ecx, 3
        ror     ebx, cl

        test    al, al
        jz      .finish

        cmp     al, '|'
        je      .nameok

.search:
        lodsb
        test    al, al
        jz      .finish
        cmp     al, '|'
        jne     .search

.nameok:
        stdcall AddArrayItems, edx, 1
        mov     [eax], ebx
        jmp     .main_loop

.finish:
        stdcall AddArrayItems, edx, 1
        mov     dword [eax], 0
        mov     eax, ebx

        pop     esi ecx ebx
        return
endp





proc procOnWrite, .self, .button
begin
        push    eax ebx ecx edx

        cmp     [DataBase], 0
        je      .finish

; value
        stdcall Get, [editValue], TEdit.Text
        mov     ebx, eax

        cmp     [DataType], cdtNULL
        je      .null_handling

        cmp     [DataType], cdtInteger
        je      .int_handling

        cmp     [DataType], cdtString
        jne     .finish

; string handling.
        xor     ecx, ecx
        jmp     .continue

.int_handling:
        stdcall StrToNumEx, ebx
        stdcall StrDel, ebx
        mov     ebx, eax
        mov     ecx, 4
        jmp     .continue

.null_handling:
        stdcall StrDel, ebx
        xor     ebx, ebx
        xor     ecx, ecx

; key
.continue:
        stdcall Get, [editKey], TEdit.Text
        push    eax

        stdcall __DecodeDirectory, eax
        stdcall StrDel ; from the stack

        push    edx
        lea     edx, [edx+TArray.array]
        stdcall SetConfigParam, DataBase, edx, eax, [DataType], ebx, ecx
        stdcall FreeMem ; from the stack

        cmp     [DataType], cdtString
        jne     @f
        stdcall StrDel, ebx
@@:
        stdcall Set, [editValue], TEdit.Text, 0

.finish:
        pop     edx ecx ebx eax
        return
endp


proc procOnRead, .self, .button
begin
        push    eax
        cmp     [DataBase], 0
        je      .finish

; key
        stdcall Get, [editKey], TEdit.Text
        push    eax
        stdcall __DecodeDirectory, eax
        stdcall StrDel ; from the stack

        push    edx
        lea     edx, [edx+TArray.array]
        stdcall GetConfigParam.AsString, [DataBase], edx, eax
        stdcall FreeMem ; from the stack

        test    eax, eax
        jz      .not_found

        push    eax
        stdcall Set, [editValue], TEdit.Text, eax
        stdcall StrDel ; from the stack.

.finish:
        pop     eax
        return

.not_found:
        stdcall Set, [editValue], TEdit.Text, cNotAvailable
        jmp     .finish
endp

cNotAvailable text 'Not available'


proc procOnDelete, .self, .button
begin
        push    eax ebx ecx edx

        cmp     [DataBase], 0
        je      .finish

; key
        stdcall Get, [editKey], TEdit.Text
        push    eax

        stdcall __DecodeDirectory, eax
        stdcall StrDel ; from the stack

        push    edx
        lea     edx, [edx+TArray.array]
        stdcall DelCongigParam, DataBase, edx, eax
        stdcall FreeMem ; from the stack

.finish:
        pop     edx ecx ebx eax
        return
endp



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/test_code0/TestGroundDirFunctions.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145


iglobal
frmMainForm:
; The form
        ObjTemplate  tfParent or tfEnd, Form, frmMain, x, 100, y, 50, width, 640, height, 340, Visible, TRUE, Caption, 'FreshLib directory functions test.'

            ; log window
            ObjTemplate tfChild, FreshEdit, editLog, x, 330, y, 0, width, 240, height, 200, Visible, TRUE, Align, waClient, _fReadOnly, froReadOnlyWithCaret

            ObjTemplate  tfParent or tfEnd, Form, frmToolPanel, borderKind, borderNone, Align, waLeft,x ,0, y, 0, width, 200, height, 340, Visible, TRUE

                ; file buttons
                ObjTemplate tfChild, Button, btnReadFile, x, 4,  y, 2, width, 64, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'ReadLine', OnClick, procOnReadFile
                ObjTemplate tfChild, Button, btnReadDir, x, 67,  y, 2, width, 64, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'ReadDir', OnClick, procOnReadDir

                ; log buttons
                ObjTemplate tfChild, Button, btnClearLog, x, 134, y, 264, width, 60, height, 19, Visible, TRUE, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Clear >>>', OnClick, procOnClearLog

                ; edit boxes
                ObjTemplate tfChild, Label, lblFilename,   x, 4, y, 24,  width, 100, height, 19, Visible, TRUE, TextAlign, dtfAlignLeft or dtfAlignBottom, Caption, 'File name:'
                ObjTemplate tfChild or tfEnd, Edit,  editFilename,  x, 4, y, 44,  width, 190, height, 19, Visible, TRUE, Text, '_doc'

endg



proc PrepareDemo
begin

        stdcall CreateFromTemplate, frmMainForm, 0
        mov     ecx, [pApplication]
        mov     [ecx+TApplication.MainWindow], frmMain
        execute [frmMain], TForm.AlignChildren

        return
endp



proc procOnClearLog, .self, .button
begin
        execute [editLog], TFreshEdit.Clear
        return
endp



proc procOnReadDir, .self, .button
begin
        pushad

        stdcall Get, [editFilename], TEdit.Text
        mov     esi, eax

        stdcall DirectoryRead, eax
        jc      .error

        mov     esi, eax

        stdcall SortDirArray, esi, fdsByType or fdsByName ;or fdsDescending


        mov     ecx, [esi+TArray.count]
        xor     ebx, ebx

.list_loop:
        stdcall LogMessage, [esi+TArray.array+8*ebx+TDirItem.hFilename]
        stdcall LogMessage, cNewLine
        inc     ebx
        loop    .list_loop

        stdcall FreeDirArray, esi
        popad
        return

.error:
        stdcall LogMessage, cErrorRead
        stdcall GetErrorString, eax
        stdcall LogMessage, eax
        stdcall FreeErrorString, eax
        popad
        return

endp

cNewLine   text '',13
cErrorRead text 'Error read directory: '
cErrorFile text 'Error read file: '


proc procOnReadFile, .self, .button
begin
        pushad

        stdcall Get, [editFilename], TEdit.Text
        mov     esi, eax

        stdcall FileOpen, esi
        jc      .error
        mov     ebx, eax

.loop:
        stdcall FileReadLine, ebx
        jc      .error
        test    eax, eax
        jz      .end_of_file

        stdcall LogMessage, eax
        stdcall StrDel, eax
        stdcall LogMessage, cNewLine
        jmp     .loop

.end_of_file:
        stdcall FileClose, ebx
        popad
        return

.error:
        stdcall LogMessage, cErrorFile
        stdcall GetErrorString, eax
        stdcall LogMessage, eax
        stdcall FreeErrorString, eax
        stdcall LogMessage, cNewLine
        popad
        return

endp



proc LogMessage, .string
begin
        pushad
        execute [editLog], TFreshEdit.InsertString, [.string]
        mov     eax, [editLog]
        push    [eax+TFreshEdit._xCaret] [eax+TFreshEdit._yCaret]
        pop     [eax+TFreshEdit._ySelection] [eax+TFreshEdit._xSelection]
        execute [editLog], TFreshEdit.Refresh
        stdcall TFreshEdit.__UpdateScrollBars, [editLog]        ; not this
        popad
        return
endp


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































Deleted freshlib/test_code0/TestGroundFreshEdit.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;                                                                                        |
;   Description: Test program for TFreshEdit control.                                    |
;                                                                                        |
;   Target OS: All/Linux/Win32 - depending on current test needs.                        |
;                                                                                        |
;   Dependencies:                                                                        |
;                                                                                        |
;   Notes: The main test program calls "PrepareDemo" procedure.                          |
;________________________________________________________________________________________|


__TestGround:

; Global data...
iglobal

__TestData:

frmMainForm:
        ObjTemplate  tfParent or tfEnd, Form, frmMain, \
                     x, 100,        \
                     y, 50,         \
                     width, 640,    \
                     height, 480,   \
                     borderKind, borderFull,    \
                     Visible, TRUE, \
                     Caption, 'FreshEdit test application.'

        ObjTemplate  tfParent, Form, Toolbar,           \
                     x, 0, y, 0,                        \
                     width, 100, height, 20,            \
                     Align, waBottom,                   \
                     borderKind, borderNone,         \
                     Visible, TRUE

        ObjTemplate  tfChild, Button, btnOpen,  \
                     x, 112, y, 2,                        \
                     width, 64, height, 21,            \
                     Align, waLeft,                     \
                     Caption, 'Open',                   \
                     TextAlign, dtfAlignCenter or dtfAlignMiddle,       \
                     OnClick, OnOpenFile,         \
                     Visible, TRUE

        ObjTemplate  tfChild, Button, btnSave,  \
                     x, 180, y, 2,                     \
                     width, 64, height, 21,            \
                     Align, waLeft,                     \
                     Caption, 'Save',                   \
                     TextAlign, dtfAlignCenter or dtfAlignMiddle,       \
                     OnClick, OnSaveFile,         \
                     Visible, TRUE

        ObjTemplate  tfChild, Button, btnNumbers,  \
                     x, 180, y, 2,                     \
                     width, 21, height, 21,            \
                     Align, waLeft,                     \
                     Caption, '#',                  \
                     TextAlign, dtfAlignCenter or dtfAlignMiddle,       \
                     OnClick, OnNumbers,         \
                     Visible, TRUE

        ObjTemplate  tfChild, Button, btnZebra,  \
                     x, 180, y, 2,                     \
                     width, 21, height, 21,            \
                     Align, waLeft,                     \
                     Caption, 'Z',                  \
                     TextAlign, dtfAlignCenter or dtfAlignMiddle,       \
                     OnClick, OnZebra,         \
                     Visible, TRUE

        ObjTemplate  tfChild, Button, btnTheme,  \
                     x, 180, y, 2,                     \
                     width, 21, height, 21,            \
                     Align, waLeft,                     \
                     Caption, 'T',                  \
                     TextAlign, dtfAlignCenter or dtfAlignMiddle,       \
                     OnClick, OnTheme,         \
                     Visible, TRUE

        ObjTemplate  tfEnd, Edit, FilenameEdit,         \
                     x, 2, y, 2,                        \
                     width, 100, height, 21,            \
                     Align, waClient,                     \
                     Visible, TRUE

        ObjTemplate tfEnd, FreshEdit, Editor,   \
                    x, 8, y, 8,                 \
                    width, 624, height, 464,    \
                    Align, waClient,            \
                    Visible, TRUE


  SampleText file 'unicode_test.txt'
             dd   0

__TestDataSize = $ - __TestData
endg


uglobal
  Timer1 dd ?
endg

var FreshEditSetTheme = TFETheme.SetDefaultThemeWindows


proc OnTheme, .self, .mousebtn
begin
        xor     [FreshEditSetTheme], TFETheme.SetDefaultThemeWindows xor TFETheme.SetDefaultThemeClassic
        stdcall [FreshEditSetTheme], FreshEditTheme
        xor     [SynTheme], fasm_colors_classic xor fasm_colors_windows
        execute [Editor], TFreshEdit.Refresh
        return
endp


proc OnZebra, .self, .mousebtn
begin
        xor     [FreshEditTheme.Options], eoStripedBackground
        execute [Editor], TFreshEdit.Refresh
        return
endp


proc OnNumbers, .self, .mousebtn
begin
        xor     [FreshEditTheme.Options], eoLineNumbers
        execute [Editor], TFreshEdit.Refresh
        return
endp


cErrorTitleOpen text "Error open file."
cErrorTitleSave text "Error save file."

proc OnSaveFile, .self, .mousebtn
begin
        pushad

        stdcall Get, [FilenameEdit], TEdit.Text
        push    eax
        stdcall StrPtr, eax
        mov     edi, eax

        stdcall Get, [Editor], TFreshEdit.Text
        jc      .finish

        push    eax
        stdcall StrPtr, eax

        stdcall SaveBinaryFile, edi, eax, [eax+string.len]
        jnc     .end_save

        stdcall GetErrorString, eax
        mov     esi, eax
        stdcall ShowMessage, [frmMain], smiError, cErrorTitleSave, esi, smbOK
        stdcall FreeErrorString, esi

.end_save:
        stdcall StrDel ; from the stack
.finish:
        stdcall StrDel ; from the stack
        popad
        return
endp


proc OnOpenFile, .self, .mousebtn
begin
        pushad
; Load test file
        stdcall Get, [FilenameEdit], TEdit.Text
        push    eax

        stdcall StrPtr, eax
        stdcall LoadBinaryFile, eax
        jnc     .loaded

        stdcall GetErrorString, eax
        mov     esi, eax
        stdcall ShowMessage, [frmMain], smiError, cErrorTitleOpen, esi, smbOK
        stdcall FreeErrorString, esi
        jmp     .exit

.loaded:
        push    eax
        stdcall Set, [Editor], TFreshEdit.Text, eax
        stdcall FreeMem ; from the stack

.exit:
        stdcall StrDel ; from the stack

        mov     eax, [Editor]
        mov     [eax+TFreshEdit._xCaret], 0
        mov     [eax+TFreshEdit._yCaret], 0
        mov     [eax+TFreshEdit._xSelection], 0
        mov     [eax+TFreshEdit._ySelection], 0

;        stdcall ParseFolding, [eax+TFreshEdit._pLines]

        execute [Editor], TFreshEdit.Refresh
        execute [Editor], TFreshEdit.Focus
        popad
        return
endp



proc PrepareDemo
begin
        stdcall CreateFromTemplate, frmMainForm, 0
        mov     ecx, [pApplication]
        mov     [ecx+TApplication.MainWindow], frmMain

        stdcall Set, [Editor], TFreshEdit._procSyntax, SyntaxFASM
        stdcall Set, [Editor], TFreshEdit.OnControlKey, procKeyPress
        stdcall Set, [Editor], TFreshEdit.Text, SampleText

        mov     esi, [Editor]
; test - set some flags on line 33
        mov     eax, [esi+TFreshEdit._pLines]
        or      [eax+TArray.array+sizeof.TEditorLine*26+TEditorLine.flags], lfBreakpoint

; test - set some flags on line 34
        mov     eax, [esi+TFreshEdit._pLines]
        or      [eax+TArray.array+sizeof.TEditorLine*27+TEditorLine.flags], lfBreakpoint
        mov     [eax+TArray.array+sizeof.TEditorLine*27+TEditorLine.debugdata], $12345
        mov     [eax+TArray.array+sizeof.TEditorLine*28+TEditorLine.debugdata], $12345
        mov     [eax+TArray.array+sizeof.TEditorLine*29+TEditorLine.debugdata], $12345

        stdcall ParseFolding, eax
.exit:
        return
endp



proc procKeyPress, .self, .keyevent
begin
        mov     ebx, [.keyevent]

        mov     eax, [ebx+TKeyboardEvent.key]

        cmp     eax, $03        ; ctrl+C
        je      .copy
        cmp     eax, $16        ; ctrl+V
        je      .paste
        cmp     eax, 12 ; ctrl+L
        je      .length_list
        cmp     eax, 18 ; ctrl+R
        je      .clipright
        cmp     eax, 19 ; ctrl+S == save
        je      .save
        cmp     eax, 20 ; ctrl+T
        je      .test_something

        cmp     [ebx+TKeyboardEvent.scancode], keyF2
        je      .toggle_breakpoint

.finish:
        mov     eax, chgfNoClearSelection
.exit:
        return

.copy:
        stdcall Get, [.self], TFreshEdit.Selection
        test    eax, eax
        jz      .end_copy
        stdcall ClipboardWrite, eax
        stdcall StrDel, eax
.end_copy:
        mov     eax, chgfNoClearSelection
        return

.paste:
        stdcall ClipboardRead
        test    eax, eax
        jz      .end_paste

        stdcall Set, [.self], TFreshEdit.Selection, eax
        stdcall StrDel, eax

        mov     eax, chgfNeedRefresh
.end_paste:
        return


.save:
        stdcall OnSaveFile, [.self], 0
        xor     eax, eax
        return

.length_list:
        xor     eax, eax
        return

.clipright:
        stdcall Get, esi, TFreshEdit.CurrentLine
        jc      .finish
        stdcall StrClipSpacesR, [eax+TEditorLine.Data]
        mov     eax, chgfNeedRefresh
        return

.test_something:
        mov     eax, chgfNeedRefresh
        return


.toggle_breakpoint:
        cmp     [esi+TFreshEdit._fReadOnly], froReadWrite
        jne     .finish

        stdcall Get, esi, TFreshEdit.CurrentLine
        jc      .finish

        xor     [eax+TEditorLine.flags], lfBreakpoint
        mov     eax, chgfNeedRefresh or chgfNoClearSelection
        return


;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

endp




; very primitive! To be rewrited from scratch to allow custom keywords.
proc ParseFolding, .pLines
begin
        pushad

        xor     ebx, ebx
        mov     esi, [.pLines]
        mov     ecx, [esi+TArray.count]
        lea     esi, [esi+TArray.array]

.loop:
        jecxz   .endparse

        stdcall StrPtr, [esi+TEditorLine.Data]
        jc      .forward

        cmp     [eax+string.len], 4
        jb      .forward

        cmp     dword [eax], 'proc'
        je      .up

        cmp     [eax+string.len], 6
        jb      .forward

        cmp     dword [eax], 'loca'
        jne     .forward
        cmp     word [eax+4], 'ls'
        jne     .forward

.up:
        inc     ebx
        or      [esi+TEditorLine.flags], lfFoldHeader

.forward:
        mov     [esi+TEditorLine.fold_level], ebx

        stdcall StrPtr, [esi+TEditorLine.Data]
        jc      .forward2

        cmp     [eax+string.len], 4
        jb      .forward2

        cmp     dword [eax], 'endp'
        je      .down
        cmp     dword [eax], 'endl'
        jne     .forward2

.down:
        test    ebx, ebx
        jz      .forward2
        dec     ebx

.forward2:
        add     esi, sizeof.TEditorLine
        dec     ecx
        jmp     .loop

.endparse:
        popad
        return
endp








DispSize 'Test ground dummy code:', ($-__TestGround)+__TestDataSize

; without this, the application crashes in Linux with untraceable seg fault. Why???
; It seems it crashes during the load, before even one instruction executed.
; Maybe it is some kind of bug in the elf formater...
; IT CRASHES ONLY SOMETIMES?????
;rb 64

include '%lib%/FreshEdit/fasm_syntax.asm'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/test_code0/TestGroundKeyboard.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;   Description: This test source provides some testing of the keyboard facilities
;                of FreshLib
;
;   Target OS: All/Linux/Win32 - depending on current test needs.
;
;   Dependencies:
;
;   Notes: The main test program calls "PrepareDemo" procedure.
;_________________________________________________________________________________________

__TestGround:

; Global data...
iglobal

__TestData:

frmMainForm:
        ObjTemplate  tfEnd, Form, frmMain, \
                     x, 100,        \
                     y, 50,         \
                     width, 120,    \
                     height, 80,   \
                     Visible, TRUE, \
                     OnKeyPress, MainKeyPressed,        \
                     Caption, 'FreshLib minimal application test.'

__TestDataSize = $ - __TestData
endg






cKeyMessage text 'Key pressed:'
cCRLF       db   13, 10, 0
cSpace      db   '  ', 0



proc MainKeyPressed, .self, .keyevent
begin
        mov     esi, [.self]
        mov     edi, [.keyevent]

        stdcall Output, cKeyMessage
        stdcall OutputNumber, [edi+TKeyboardEvent.key], 16, 8
        stdcall Output, cSpace
        stdcall OutputNumber, [edi+TKeyboardEvent.scancode], 16, 8
        stdcall Output, cSpace
        stdcall OutputNumber, [edi+TKeyboardEvent.kbdStatus], 16, 8
        stdcall Output, cCRLF
        return
endp








proc PrepareDemo
begin
        stdcall CreateFromTemplate, frmMainForm, 0
        mov     ecx, [pApplication]
        mov     [ecx+TApplication.MainWindow], frmMain

        return
endp












DispSize 'Test ground dummy code', ($-__TestGround)+__TestDataSize
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































Deleted freshlib/test_code0/TestLib.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;
;  Description: The main file of FreshLib test application. Main file.
;
;  Target OS: Any
;
;  Dependencies: FreshLib - see includes in the source.
;
;  Notes: This is the main file of the project. It forms the common frame of the GUI
;         program. The real test code is separated in several different files,
;         named TestGround(xxxx).asm where (xxxx) is some suffix.
;         Include only one of these files.
;_________________________________________________________________________________________


include '%lib%/freshlib.inc'
@BinaryType GUI

options.FastEnter         = 0           ; enter/leave or push ebp/pop ebp approach to the procedures.
options.ShowSkipped       = 0           ; shows the procedures skiped because of no use.
options.ShowSizes         = 1           ; enable/disable work of DispSize macro.
options.DebugMode         = 0           ; enable/disable macroses of simpledebug library.


include '%lib%/freshlib.asm'



; use one and only one of the following files.
;
include  'TestGround.asm'
;include 'TestGroundComplex.asm'
;include 'TestGroundKeyboard.asm'
;include 'TestGroundFreshEdit.asm'
;include 'TestGroundConfig.asm'
;include 'TestGroundDirFunctions.asm'

;if TargetOS eq Linux
;  rb 604       ; this bytes simply make ELF file to be loadable.
;              ; there is a bug somewhere in the ELF generator (FASM or possibly ELF macros)
;              ; that makes some sizes of the ELF executable not loadable. (the Linux loader crashes with SEGFAULT)
;end if

iglobal
  time_test  dq -5

  date_time TDateTime
endg

; Main Program
start:

DebugMsg 'Before initializing.'

        InitializeAll

DebugMsg 'After initializing.'

        stdcall Create, CApplication
        jc      .start_error
        mov     [pApplication], ebx

        stdcall PrepareDemo

DebugMsg 'Just before run.'

        stdcall Run

.terminate:
        push    eax
        FinalizeAll

        DebugMsg 'Just before the end.'
        stdcall Terminate       ; from the stack

.start_error:
        mov     eax, 1
        DebugMsg "Can't create application object."
        jmp      .terminate

; end of main program


@AllImportSection
@AllDataSection


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































Deleted freshlib/test_code0/UTF8_examples.asm.

1
2
3
4
5
  utf8_string db $49, $C3, $B1, $74, $C3, $AB, $72, $6E, $C3, $A2, $74, $69, $C3, $B4, $6E, $C3, $A0, $6C, $69, $7A, $C3, $A6, $74, $69, $C3, $B8, $6E, $00 ; the word "Internationalization" written with different languages chars

; greek, cyrillic and latin in one text.
  utf8_long   file 'UnicodeSample.txt':3
              dd 0
<
<
<
<
<










Deleted freshlib/test_code0/UnicodeSample.txt.

1
2
3
4
5
6
Russian: Я могу еÑть Ñтекло, оно мне не вредит. 
Yoruba: Mo lè je̩ dígí, kò ní pa mí lára.
Chinese: 我能åžä¸‹çŽ»ç’ƒè€Œä¸ä¼¤èº«ä½“。 
Greek: ΜποÏÏŽ να φάω σπασμένα γυαλιά χωÏίς να πάθω τίποτα.
Québécois: J'peux manger d'la vitre, ça m'fa pas mal. 
Ukrainian: Я можу Ñ—Ñти Ñкло, Ñ– воно мені не зашкодить. 
<
<
<
<
<
<












Deleted freshlib/test_code0/UnicodeSampleEng.txt.

1
The main goal of Fresh is to make programming in assembly as fast and efficient as in other visual languages, without sacrificing the small application size and the raw power of assembly language. Because Fresh is the logical continuation of the FASM project in the area of visual programming, it is perfectly compatible with FASM and you can use all your knowledge about FASM to program in Fresh.
<


Deleted freshlib/test_code0/_test_images/icon.gif.

cannot compute difference between binary files

Deleted freshlib/test_code0/_test_images/test.gif.

cannot compute difference between binary files

Deleted freshlib/test_code0/test.forth.

1
2
3
4
5
6
7
8
9
10
: TestWord
  1 2 3 4 5 6 7 8 9 10 * * * * * * * * *
  "
  Test multiline text
  Line1
  Line2
  Another line!
  This is forthScript.
  " .
;
<
<
<
<
<
<
<
<
<
<




















Deleted freshlib/test_code0/test_config.udb.

cannot compute difference between binary files

Deleted freshlib/test_code0/test_utf8.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
test00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111111111111
00000000011111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222222222233333333334
12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "Fresh artistic license."         |
;|_______________________________________________________________________________________|
;  Notes:
;    This is a test file. It is based on strlib.asm but has been modified and
;    should not be used as a library.
;    Това е теÑтов файл. Базиран е на strlib.asm но е модифициран и не бива да Ñе използва като библиотека. Ð’ този теÑтов файл Ñе използват форматиращи команди, които Ñа ÑъвмеÑтими Ñ FASM и могат да Ñе компилират без проблеми.
;    използва като библиотека.
;    Αυτό είναι ένα δοκιμαστικό αÏχείο. Βασίζεται σε strlib.asm αλλά έχει
;    Ï„Ïοποποιηθεί και δεν Ï€Ïέπει να χÏησιμοποιείται ως βιβλιοθήκη.
;    ეს áƒáƒ áƒ˜áƒ¡ გáƒáƒ›áƒáƒªáƒ“რფáƒáƒ˜áƒšáƒ˜. ის ეფუძნებრstrlib.asm მáƒáƒ’რáƒáƒ› შეიცვáƒáƒšáƒ დრáƒáƒ  უნდáƒ
;    იქნáƒáƒ¡ გáƒáƒ›áƒáƒ§áƒ”ნებული ბიბლიáƒáƒ—ეკáƒáƒ¨áƒ˜.
;_________________________________________________________________________________________

            mov  eax, '1234'
            mov  ecx, 1234

__StringLibrary:

STR_MINSTRLEN = 15      ; must be N*8-1


struc string {
  .capacity dd ?
  .len      dd ?
  label .data byte
}

virtual at -(sizeof.string)
  string string
  sizeof.string = $-string
end virtual


; NumToStr flags
ntsSigned       = $00000
ntsUnsigned     = $10000
ntsFixedWidth   = $20000


ntsBin  = $0200
ntsQuad = $0400
ntsOct  = $0800
ntsDec  = $0a00
ntsHex  = $1000


; Global variable, storing parameters of dynamic strings list.
uglobal
  if used InitStrings
  ptrStrTable       dd  ?      ; StrLib strings arrray. Contains pointers to the memory allocated for strings.

  flagStringFastAdd dd  ?      ; Flag: when TRUE, enables "Fast addition mode" where new strings are allocated
                               ; without searching the ptrStrTable array for empty slots.
                               ; This can increase allocation speed, but at the expense of more memory allocated
                               ; in the array and not using possibly free handles. This mode should to be used
                               ; carefully and set to FALSE after the end of mass allocations.
  end if
endg



; < OS independent library functions >

;************************************************************************************
; Allocates memory for string table and allocates memory for strings.
; Start it before any work with strings. (Or better use InitializeAll macro)
; Returns 0 if failed to allocate needed memory.
;************************************************************************************
if used ptrStrTable
initialize InitStrings
begin
        StrLib = 1

        stdcall CreateArray, 4
        jc      .finish

        mov     [ptrStrTable], eax
        or      [eax+TArray.lparam], -1     ; lParam is the last allocated handle number

.finish:
        return
endp
end if

;**************************************************************************************
; Frees all memory used for strings library
; Call it before exit of the program or use FinalizeAll macro.
;**************************************************************************************
if used InitStrings
finalize FreeStrings
begin
        mov     esi, [ptrStrTable]
        mov     ecx, [esi+TArray.count]
        xor     ebx,ebx

.freeloop:
        dec     ecx
        js      .endloop

        cmp     [esi+TArray.array+4*ecx], ebx
        je      .freeloop

        stdcall FreeMem, [esi+TArray.array+4*ecx]
        jmp     .freeloop

.endloop:
        stdcall FreeMem, esi
        mov     [ptrStrTable], ebx

        return
endp
end if



;**************************************************************************************
;  Returns:
;    CF=0 no error; eax = pointer in memory of the hString
;    CF=1 on error - hString is handle, but is not in the table.*
;**************************************************************************************
proc StrPtr, .hString
begin
        mov     eax, [.hString]

        xor     eax, $c0000000
        test    eax, $c0000000
        jnz     .pointer

        push    ebx

        mov     ebx, [ptrStrTable]
        cmp     eax, [ebx+TArray.count]
        jae     .notfound

        mov     eax, [ebx+TArray.array+4*eax]
        test    eax, eax
        jz      .notfound

        add     eax, sizeof.string
        pop     ebx
        clc
        return

.pointer:
        xor     eax, $c0000000
        clc
        return

.notfound:
        stc
        pop     ebx
        return
endp

;**************************************************************************************
;  Creates new empty string and returns handle
;  Return: handle of the new created string.
;**************************************************************************************
proc StrNew
begin
        push    ecx edx esi

; Search for first empty place.
        mov     edx, [ptrStrTable]
        mov     ecx, [edx+TArray.count]

        cmp     [flagStringFastAdd], 0
        jne     .notfound

        mov     esi,[edx+TArray.lparam]
        xor     eax,eax

.search:
        dec     ecx
        js      .notfound

        inc     esi
        cmp     esi, [edx+TArray.count]
        jne     @f
        xor     esi,esi
@@:
        cmp     [edx+TArray.array+4*esi],eax
        je      .found
        jmp     .search

.notfound:
        mov     esi, [edx+TArray.count]
        stdcall AddArrayItem, edx
        mov     [ptrStrTable], edx

.found:
        mov     [edx+TArray.lparam], esi
        stdcall GetMem, STR_MINSTRLEN + sizeof.string + 1
        mov     [edx+TArray.array+4*esi], eax
        mov     [eax+sizeof.string+string.capacity], STR_MINSTRLEN

        mov     eax, esi
        or      eax, $c0000000

        pop     esi edx ecx
        return
endp


;**************************************************************************
; Deletes the string if it is possible.
;**************************************************************************
proc StrDel, .hString
begin
        push    eax ecx esi

        mov     esi, [ptrStrTable]
        mov     ecx, [.hString]
        jecxz   .finish

        xor     ecx, $c0000000
        test    ecx, $c0000000
        jnz     .pointer

        cmp     ecx, [esi+TArray.count]
        jae     .finish

.free:
        stdcall FreeMem, [esi+TArray.array+4*ecx]
        mov     [esi+TArray.array+4*ecx], 0

.finish:
        pop     esi ecx eax
        return

.pointer:
        xor     ecx, $c0000000

; search the pointer in the table.
        lea     eax, [ecx-sizeof.string]
        mov     ecx, [esi+TArray.count]

.search:
        dec     ecx
        js      .finish
        cmp     [esi+TArray.array+4*ecx], eax
        jne     .search
        jmp     .free
endp


;**************************************************************************
; Duplicates given string, and returns a handle to new one
;**************************************************************************
proc StrDup, .hSource
begin
        stdcall StrNew
        stdcall StrCopy, eax, [.hSource]
        return
endp


;**************************************************************************
; Arguments:
;  hString - handle or pointer to the string (static or dynamic)
; Returns:
;   CF=0; eax = length of the string in bytes.
;   CF=1; eax = 0 in case, the handle of the string can't be found in the
;               string table or the pointer is NULL.
;
; If pointer is passed the the procedure, it should be dword aligned and
; all bytes of the string including zero terminator to be accessed on
; qword boundary. Although, the zero terminator can be single byte zero.
;
; The performance of the procedure is high for pointers and
; instant for handles (the StrLib created string doesn't need any
; search, because the length is precomputed)
;**************************************************************************

proc StrLen, .hString    ; proc StrLen [hString]
begin
        push    esi

        mov     esi, [ptrStrTable]
        mov     eax, [.hString]

        xor     eax, $c0000000
        test    eax, $c0000000
        jnz     .pointer

        cmp     eax, [esi+TArray.count]
        jae     .error

        mov     eax, [esi+TArray.array+4*eax]
        test    eax, eax
        jz      .error

        mov     eax, [eax+sizeof.string+string.len]
        clc
        pop     esi
        return

.error:
        xor     eax, eax
        stc
        pop     esi
        return

.pointer:
        push    ecx edx edi

        xor     eax, $c0000000

; align on dword
.byte1:
        test    eax, 3
        jz      .scan

        cmp     byte [eax], 0
        je      .found

        inc     eax
        jmp     .byte1

.scan:
        mov     ecx, [eax]
        mov     edx, [eax+4]

        lea     eax, [eax+8]

        lea     esi, [ecx-$01010101]
        lea     edi, [edx-$01010101]

        not     ecx
        not     edx

        and     esi, ecx
        and     edi, edx

        and     esi, $80808080
        and     edi, $80808080

        or      esi, edi
        jz      .scan

        sub     eax, 9

; byte 0 was found: so search by bytes.
.byteloop:
        lea     eax, [eax+1]
        cmp     byte [eax], 0
        jne     .byteloop

.found:
        sub     eax, [.hString]
        clc
        pop     edi edx ecx esi
        return
endp





; This procedure calculates the length of zero terminated string and "fixes" [string.len] field.
; StrFixLen should be call when the content of the string is created by call to external to StrLib
; procedures - for example Win32 API functions.
;
proc StrFixLen, .hstring
begin
        push    eax ecx
        stdcall StrPtr, [.hstring]
        mov     ecx, eax
        stdcall StrLen, eax
        mov     [ecx+string.len], eax
        pop     ecx eax
        return
endp




;***************************************************************************
; If the hString is larger than length - do nothing
; If the hString is smaller than length -> set the length of string to length
; returns pointer to the new (old) string
;
; Arguments:
;   hString - string handle. /not pointer!/
;   length - new string length.
; Returns:
;   eax: pointer to the string.
;   CF: error flag. If 1 the pointer to the string is returned, but
;       the capacity is not changed.
;***************************************************************************
proc StrSetCapacity, .hString, .capacity
begin
        push    ebx ecx esi

        mov     eax, [.hString]

        xor     eax, $c0000000
        test    eax, $c0000000
        jnz     .pointer

        mov     esi, eax

        mov     ebx, [ptrStrTable]
        cmp     esi, [ebx+TArray.count]
        jae     .pointer

        mov     eax, [ebx+TArray.array+4*esi]   ; pointer to the string.
        mov     ecx, [.capacity]

        cmp     [eax+sizeof.string+string.capacity], ecx
        jae     .sizeok

        add     ecx, sizeof.string+8
        and     cl,  $f8                ; align the size to 8 bytes

        stdcall ResizeMem, eax, ecx
        jc      .error

        lea     ecx, [ecx-(sizeof.string+1)]
        mov     [ebx+TArray.array+4*esi], eax
        mov     [eax+sizeof.string+string.capacity], ecx

.sizeok:
        add     eax, sizeof.string
        pop     esi ecx ebx
        return

.error:
        add     eax, sizeof.string
        stc
        pop     esi ecx ebx
        return

.pointer:
        xor     eax, $c0000000
        stc
        pop     esi ecx ebx
        return
endp


;***************************************************************************************
;  Copies source to destination string.
;  Arguments:
;     dest - destination string (handle only)
;     source -  source string (handle or pointer)
;  Returns: nothing
;***************************************************************************************
proc StrCopy, .dest, .source
begin
        push    esi edi eax ecx

        stdcall StrLen, [.source]
        mov     ecx, eax
        stdcall StrSetCapacity, [.dest], ecx
        mov     edi, eax
        stdcall StrPtr, [.source]
        mov     esi, eax

        mov     [edi+string.len], ecx

        inc     ecx
        mov     eax, ecx
        shr     ecx, 2
        rep movsd
        mov     ecx, eax
        and     ecx, 3
        rep movsb

        pop     ecx eax edi esi
        return
endp



;***************************************************************************************
; Compares two strings - case sensitive.
; Returns CARRY = 1 if the strings are equal.
; Returns CARRY = 0 if the strings are different.
;
; As long as this function uses StrLen, it will be very fast on handles and relatively
; slow on pointers.
;***************************************************************************************
proc StrCompCase, .str1, .str2
begin
        push    eax ecx esi edi

        mov     eax, [.str1]
        mov     ecx, [.str2]

        cmp     eax, ecx
        je      .equal

        test    eax, eax
        jz      .noteq

        test    ecx, ecx
        jz      .noteq

        stdcall StrLen, eax
        push    eax
        stdcall StrLen, ecx

        pop     ecx
        cmp     eax, ecx
        jne     .noteq

        stdcall StrPtr, [.str1]
        mov     esi,eax
        stdcall StrPtr, [.str2]
        mov     edi,eax

        mov     eax, ecx
        and     cl, $fc
        repe cmpsd
        jne     .noteq
        mov     ecx, eax
        and     ecx, 3
        repe cmpsb
        jne     .noteq

.equal:
        stc
        pop     edi esi ecx eax
        return

.noteq:
        clc
        pop     edi esi ecx eax
        return
endp


;***************************************************************************************
; Compares two strings - case NOT sensitive.
; Returns CARRY = 1 if the strings are equal.
; Returns CARRY = 0 if the strings are different.
;
; relatively slow, especially on equal strings, passed as pointers - this is the worst
; case. The nontrivial best case is "strings with different lengths passed as handles."
;***************************************************************************************
proc StrCompNoCase, .str1, .str2
begin
        push    eax ebx ecx edx esi edi

        mov     eax, [.str1]
        mov     ecx, [.str2]

        cmp     eax, ecx
        je      .equal

        test    eax, eax
        jz      .noteq

        test    ecx, ecx
        jz      .noteq

        stdcall StrLen, eax
        push    eax
        stdcall StrLen, ecx

        pop     ecx
        cmp     eax, ecx
        jne     .noteq

        stdcall StrPtr, [.str1]
        mov     esi,eax
        stdcall StrPtr, [.str2]
        mov     edi,eax


        mov     ebx, ecx
        shr     ecx, 2
        and     ebx, 3

.dword:
        dec     ecx
        js      .byte

        mov     eax, [esi]
        mov     edx, [edi]

        and     eax, $40404040
        and     edx, $40404040
        shr     eax, 1
        shr     edx, 1
        or      eax, [esi]
        or      edx, [edi]

        lea     esi, [esi+4]
        lea     edi, [edi+4]

        cmp     eax, edx
        jne     .noteq
        jmp     .dword

.byte:
        dec     ebx
        js      .equal

        mov     al, [esi]
        mov     ah, [edi]

        and     eax, $ffff
        mov     edx, eax
        and     eax, $4040
        shr     eax, 1
        or      eax, edx

        inc     esi
        inc     edi

        cmp     al, ah
        je      .byte

.noteq:
        clc
        pop     edi esi edx ecx ebx eax
        return

.equal:
        stc
        pop     edi esi edx ecx ebx eax
        return

endp



;**********************************************************
;  Creates string and assigns it to variable. If variable
;  already contains string handle, the old string will be
;  used.
;  Arguments:
;    [ptrHString] - variable containing string handle.
;    ptrSource - pointer to the source for string.
;**********************************************************
proc SetString, .ptrHString, .ptrSource
begin
        push    eax esi
        mov     esi, [.ptrHString]

        mov     eax, [esi]
        test    eax, eax
        jnz     @f
        stdcall StrNew
@@:
        mov     [esi], eax
        stdcall StrCopy, eax, [.ptrSource]
        pop     esi eax
        return
endp


;**********************************************************************************
; StrCat appends one string to another
; Arguments:
;   dest - destination string (handle only)
;   source - source string
;**********************************************************************************
proc StrCat, .dest, .source
begin
        push    eax ebx ecx esi edi

        stdcall StrLen, [.dest]
        mov     ebx,eax                 ; store dest length in ebx

        stdcall StrLen, [.source]
        mov     esi, eax
        lea     ecx, [eax+ebx]

        stdcall StrSetCapacity, [.dest], ecx

        mov     [eax+string.len], ecx
        lea     edi, [eax+ebx]

        stdcall StrPtr, [.source]
        lea     ecx, [esi+1]
        mov     esi, eax

        mov     ebx, ecx
        shr     ecx, 2
        rep movsd
        mov     ecx, ebx
        and     ecx, 3
        rep movsb

        pop     edi esi ecx ebx eax
        return
endp


;**********************************************************************************
; StrCharPos returns a pointer to the first occurence of a given char
;   in specified string
; Arguments:
;   Char - char to look for
;   hString -  string to search
; Returns: a pointer to the char in source, or NULL if char doesn't occur
;   in given string
;**********************************************************************************
proc StrCharPos, .hString, .char
begin
        push    esi

        stdcall StrPtr, [.hString]
        mov     esi,eax

        mov     eax, [.char]
        xchg    al,ah

.search:
        mov     al,[esi]
        inc     esi
        or      al,al
        je      .not_found
        cmp     al,ah
        jne     .search

        mov     eax, esi
        dec     eax
        pop     esi
        return

.not_found:
        xor     eax,eax
        pop     esi
        return
endp


;**********************************************************************************
; StrPos returns a pointer to the first occurence of a pattern string
;   in another string
; Arguments:
;   hPattern - 'pattern' string
;   hString -  string to search
; Returns: a pointer to the pattern string in source , or NULL if pattern string
; doesn't occur in the string to search
;**********************************************************************************
proc StrPos, .hString, .hPattern
begin
        push    ebx ecx edx esi edi     ; esp = esp -20
        mov     esi,[.hPattern]         ; mov esi,[hPattern]
        mov     edi,[.hString]          ; mov edi,[hString]
        stdcall StrLen, edi
        mov     ebx,eax                 ; now ebx holds lenght of the string to search
        stdcall StrLen, esi
        mov     edx,eax                 ; now edx holds length of the pattern string

        cmp     edx, ebx
        ja      .not_found              ; if the pattern is longer than the string

        stdcall StrPtr, esi
        mov     esi,eax                 ; put pointer to the pattern str in esi
        stdcall StrPtr,edi
        mov     edi,eax                 ; put pointer to the search str in edi
        lodsb                           ; load first character of the pattern
        mov     ecx,ebx                 ;
        mov     ebx,edx                 ; put str_len(pattern)-1 in ebx
        dec     ebx                     ;
        sub     ecx, ebx                ; there is no need to search to the end, but only to len(string)-len(pattern)-1

.search:
        repne   scasb
        jne     .not_found
        cmp     ecx,ebx
        jb      .not_found
        push    edi esi ecx
        or      ebx,ebx                 ; ebx==0 means that we were searching for one
        jz      .got_it                 ; character. We found it, so we stop.
        mov     ecx,ebx
        repe    cmpsb
        jne     .not_match

.got_it:
        pop     ecx esi edi
        dec     edi
        mov     eax,edi

.ret:
        pop     edi esi edx ecx ebx
        return

.not_match:
        pop     ecx esi edi
        jmp     .search

.not_found:
        xor     eax,eax
        jmp     .ret
endp





proc StrCopyPart, .dest, .source, .pos, .len
begin
        push    eax ecx esi edi

        stdcall StrPtr, [.source]
        mov     esi, eax
        stdcall StrLen, [.source]
        mov     ecx, eax

        mov     eax, [.pos]
        cmp     eax, ecx
        jae     .cleardest      ;

        sub     ecx, [.pos]
        mov     eax, [.len]

; ecx = min(ecx, eax)
        sub     eax, ecx
        sbb     edi, edi
        and     edi, eax
        add     ecx, edi

        add     esi, [.pos]

        stdcall StrSetCapacity, [.dest], ecx
        jc      .finish

        mov     edi, eax
        mov     [edi+string.len], ecx

        push    ecx
        shr     ecx, 2
        rep movsd
        pop     ecx
        and     ecx, 3
        rep movsb

        lea     ecx, [edi+3]
        and     cl, $fc
        sub     ecx, edi
        xor     eax, eax
        rep stosb

.finish:
        pop     edi esi ecx eax
        return

.cleardest:
        stdcall StrSetCapacity, [.dest], STR_MINSTRLEN
        mov     [eax+string.len], 0
        mov     dword [eax], 0
        jmp     .finish
endp




;**********************************************************************************
; StrExtract copies the part of [string] from [index] with lenght in [len]
; Returns handle to new created string.
;**********************************************************************************
proc StrExtract, .string, .pos, .len
begin
        stdcall StrNew
        stdcall StrCopyPart, eax, [.string], [.pos], [.len]
        return
endp




;__________________________________________________________________________________
; Splits the string on two strings, at position [.pos]
; Arguments:
;   .pString - pointer to string to be splitted.
;   .pos     - position where to split the string.
; Returns:
;   eax - handle to the new created string with second part of the string.
;         the original string does not reallocate memory and it's capacity
;         and the pointer will remains the same.
;__________________________________________________________________________________

proc StrSplit, .hString, .pos
begin
        push    ecx edi

        stdcall StrExtract, [.hString], [.pos], -1
        push    eax

        stdcall StrLen, eax
        mov     ecx, eax
        stdcall StrPtr, [.hString]

        sub     [eax+string.len], ecx   ; new length of the source string.
        add     eax, [eax+string.len]
        mov     edi, eax

        lea     ecx, [eax+3]
        and     cl, $fc
        sub     ecx, eax
        xor     eax, eax
        rep stosb

        pop     eax
        pop     edi ecx
        return
endp





;__________________________________________________________________________________
; StrInsert inserts one string into another at specified pos
; Arguments:
;   dest - destination where the source will be inserted.
;   source -  string to insert
;   pos    - where to insert.
; Returns:
;   nothing.
;__________________________________________________________________________________
proc StrInsert, .dest, .source, .pos
begin
        push    eax
        stdcall StrSplit, [.dest], [.pos]
        push    eax eax
        stdcall StrCat, [.dest], [.source]
        stdcall StrCat, [.dest] ; source from the stack.
        stdcall StrDel; from the stack.
        pop     eax
        return
endp


; TODO:
; String case functions are giving weird results in linux, so
; here are two functons I wrote some time ago.
; I have tested the following functions in win32 and worked well
; Perhaps it is time to fully support UTF encoded strings.
; These functions here are faster (20-25%), but the results are
; exactly the same as the strlib ones.
;                                    pelaillo

; -----------------------------------------------
; str_ucase:
;         Author: pelaillo
;           Date: Jan. 16, 2002
;    Converts also accented characters: ÑÚ <--> ñú
; -----------------------------------------------

proc StrUCase2, .hString
begin
        push    eax edx edi

        stdcall StrPtr, [.hString]
        mov     edi, eax
.str_ucase:
                mov     eax, [edi]
                mov     edx, eax
                and     edx, 40404040h
                ror     edx, 1
                xor     edx, -1
                and     eax, edx
                mov     [edi], eax
                add     edi, 4
                lea     edx, [eax-01010101h]
                xor     eax, edx
                and     eax, 80808080h
                jz      .str_ucase
                and     eax, edx
                jz      .str_ucase

        pop     edi edx eax
        return
endp

; -----------------------------------------------
; str_lcase:
;         Author: pelaillo
;           Date: Jan. 16, 2002
;    Converts also accented characters: ÑÚ <--> ñú
; -----------------------------------------------

proc StrLCase2, .hString
begin
        push    eax edx edi

        stdcall StrPtr, [.hString]
        mov     edi, eax
.str_lcase:
        mov     eax, [edi]
        mov     edx, eax
        and     edx, 40404040h
        ror     edx, 1
        or      eax, edx
        mov     [edi], eax
        add     edi, 4
        lea     edx, [eax-01010101h]
        xor     eax, edx
        and     eax, 80808080h
        jz      .str_lcase
        and     eax, edx
        jz      .str_lcase

        pop     edi edx eax
        return
endp


;**********************************************************************************
; Converts strings to Lower Case
;**********************************************************************************
proc StrLCase, .hString
begin
        push    eax ebx ecx edx edi

        stdcall StrPtr, [.hString]
        mov     edi, eax

        stdcall StrLen, [.hString]
        mov     ecx, eax
        mov     ebx, edi

        and     ebx, 3
        sub     ecx, ebx
        jbe     .byte2          ; the string is small enough, so process it by bytes.

.byte1:
        test    edi, 3
        jz      .ddword

        mov     al, [edi]
        and     al, $40
        shr     al, 1
        or      byte [edi], al

        inc     edi
        jmp     .byte1

.ddword:
        mov     ebx, ecx
        and     ebx, 3
        shr     ecx, 2
        jecxz   .byte

.qword:
        mov     eax, [edi]
        mov     edx, [edi+4]

        and     eax, $40404040
        and     edx, $40404040

        shr     eax, 1
        shr     edx, 1

        or      [edi], eax
        or      [edi+4], edx

        add     edi, 8
        dec     ecx
        jnz     .qword

.byte:
        dec     ebx
        js      .finish

        mov     al, [edi]
        and     al, $40
        shr     al, 1
        or      byte [edi], al

        inc     edi
        jmp     .byte

.byte2:
        mov     ebx, ecx
        jmp     .byte

.finish:
        pop     edi edx ecx ebx eax
        return
endp


;**********************************************************************************
; Converts strings to Upper Case
; First parameter = String to Convert to upper case
;**********************************************************************************
proc StrUCase, .hString
begin
        push    eax ebx ecx edx edi

        stdcall StrPtr, [.hString]
        mov     edi, eax

        stdcall StrLen, [.hString]
        mov     ecx, eax
        mov     ebx, edi

        and     ebx, 3
        sub     ecx, ebx
        jbe     .byte2          ; the string is small enough, so process it by bytes.

.byte1:
        test    edi, 3
        jz      .ddword

        mov     al, [edi]
        and     al, $40
        shr     al, 1
        not     al
        and     byte [edi], al

        inc     edi
        jmp     .byte1

.ddword:
        mov     ebx, ecx
        and     ebx, 3
        shr     ecx, 2
        jecxz   .byte

.qword:
        mov     eax, [edi]
        mov     edx, [edi+4]

        and     eax, $40404040
        and     edx, $40404040

        shr     eax, 1
        shr     edx, 1

        not     eax
        not     edx

        and     [edi], eax
        and     [edi+4], edx

        add     edi, 8
        dec     ecx
        jnz     .qword

.byte:
        dec     ebx
        js      .finish

        mov     al, [edi]
        and     al, $40
        shr     al, 1
        not     al
        and     byte [edi], al

        inc     edi
        jmp     .byte

.byte2:
        mov     ebx, ecx
        jmp     .byte

.finish:
        pop     edi edx ecx ebx eax
        return
endp




;**********************************************************************************
; _NumToStr converts the number in eax to the string in any radix approx. [2..26]
; Arguments:
;   [edi] - pointer to the string buffer
;   ecx - radix
;   eax - number to convert.
; There is no parameter check, so be careful.
; returns: edi points to the end of a converted number
;**********************************************************************************
proc _NumToStr
begin
    test  eax,eax
    jns   _NumToStrU
    neg   eax
    mov   byte [edi],"-"
    inc   edi
endp

proc _NumToStrU
begin
    cmp   eax,ecx
    jb    .lessA
    xor   edx,edx
    div   ecx
    push  edx
    call  _NumToStrU
    pop   eax
.lessA:
    cmp   al, 10
    sbb   al, 69h
    das
    stosb
    return
endp



;*****************************************************
; NumToStrF:
;   Converts signed integer value to string.
; NumToStrUF:
;   Converts unsigned integer value to string.
;
; edi - pointer to string buffer
; eax - Number to convert
; ecx - radix from 2 to $ff
; esi - length of the number in chars
;
; returns: edi - pointer to the end of converted num
;
; Note: Don't use 1 as radix.
;*****************************************************
proc _NumToStrF
begin
        test    eax,eax
        jns     _NumToStrUF
        neg     eax
        mov     byte [edi],'-'
        push    esi
        dec     esi
        add     edi, esi
        push    edi
        jmp     _NumToStrUF.loopc
endp

proc _NumToStrUF
begin
        push    esi
        add     edi, esi
        push    edi
        dec     edi
.loopc:
        xor     edx,edx
        div     ecx
        xchg    al,dl
        cmp     al,$0a
        sbb     al,$69
        das
        mov     [edi],al
        dec     edi
        xchg    al,dl
        dec     esi
        jnz     .loopc
        pop     edi
        pop     esi
        return
endp


;***********************************************************
; NumToStr - converts number to any radix.
; num - number to convert
; str - handle of the string. If NULL - creates new string.
; index - Offset in string where to put converted number.
; flags:
;   byte 0 - number of digits if ntsFixedWidth is set.
;   byte 1 - contains radix for the convertion.
;   byte 2,3 - flags.
; Returns:
;   eax - handle of the string.
;***********************************************************
proc NumToStr, .num, .flags
begin
        push    ebx ecx edx esi edi

        stdcall StrNew
        push    eax

        stdcall StrSetCapacity, eax, 40
        mov     edi, eax
        push    eax             ; pointer for the length.

; determine which conversion func to use
        movzx   eax, byte [.flags+2]    ; signed/fixed
        and     eax, (ntsUnsigned or ntsFixedWidth) shr 16
        mov     ebx, [.NumToStrFunc+4*eax]

        movzx   ecx, byte [.flags+1]       ; load radix into ecx
        movzx   esi, byte [.flags]
        mov     eax, [.num]
        call    ebx                     ; call low-level convertion routine
        mov     dword [edi], 0

        pop     eax
        sub     edi, eax
        mov     [eax+string.len], edi

        pop     eax
        pop     edi esi edx ecx ebx
        return

.NumToStrFunc dd _NumToStr, _NumToStrU, _NumToStrF, _NumToStrUF

endp




;-------------------------------------------------------
; function StrToNum
;   Converts specified string into a number
;
; Arguments:
;   hString - handle/pointer of the string containing
;     number to convert. It doesn't have to be ended by
;     NULL, any other character will stop conversion.
;     Number to convert must be decimal.
;
; Return:
;   eax - converted number
;
; Note: in case of failture (first char of given pointer
;   isn't a number) function returns -1.
;-------------------------------------------------------
proc StrToNum, .hString
begin
        push    ebx edx esi
        xor     ebx,ebx         ; ebx will store our number

        stdcall StrPtr, [.hString]
        mov     esi,eax
        xor     eax,eax
        mov     al,[esi]
        cmp     al,'0'
        jb      .error
        cmp     al,'9'
        jbe     .digit
        jmp     .error
     .digit:
        sub     al,'0'
        add     ebx,eax
        inc     esi
        mov     al,[esi]
        cmp     al,'0'
        jb      .finish
        cmp     al,'9'
        ja      .finish
        mov     edx,ebx         ; multiply ebx by 10
        shl     ebx,3
        add     ebx,edx
        add     ebx,edx
        jmp     .digit
     .finish:
        mov     eax,ebx
        pop     esi edx ebx
        return

     .error:
        xor     eax,eax
        dec     eax
        pop     esi edx ebx
        return
endp

;-------------------------------------------------------
; function StrCharCat
;   Appends up to 4 chard at the end of the string.
;
; Arguments:
;   hString - string to append
;   char - char(s) to add
; Returns:
;   nothing
;-------------------------------------------------------
proc StrCharCat, .hString, .char
begin
        push    eax ecx

        stdcall StrLen, [.hString]
        mov     ecx, eax
        add     eax, 8

        stdcall StrSetCapacity, [.hString], eax

        pushd   [.char]
        popd    [eax+ecx]
        mov     dword [eax+ecx+4], 0
        dec     ecx
.goend:
        inc     ecx
        cmp     byte [eax+ecx], 0
        jne     .goend

        mov     [eax+string.len], ecx

        pop     ecx eax
        return
endp


;------------------------------------------------------------
; function StrInsertChar
;   Inserts up to 4 chars into the given position of the string
;
; Arguments:
;   hString - string to append
;   char    - char to add
;   pos     - position where to add the char
;-------------------------------------------------------------
proc StrCharInsert, .hString, .char, .pos
.str rd 2
begin
        push    eax
        push    [.char]
        pop     [.str]
        mov     [.str+4], 0

        lea     eax, [.str]
        stdcall StrInsert, [.hString], eax, [.pos]
        pop     eax
        return
endp






;_______________________________________________________________________
;
; proc StrHash
;   Computes 32 bit hash value from the string.
;   This procedure implements the hash algoritm: FNV-1b
;
; Arguments:
;   ptrString - pointer to PASCAL string with dword length at [ptr-4]
;
; Return:
;   eax - 32bit hash value.
;
; Changes:
;   eax
;_______________________________________________________________________
proc StrHash, .hString
begin
        push    edx ecx esi

        stdcall StrPtr, [.hString]
        mov     esi, eax
        stdcall StrLen, [.hString]
        mov     ecx, eax
        mov     eax, $811C9DC5                  ; 2166136261              ; FNV offset basis

        jecxz   .exit

.hashloop:
        movzx   edx, byte [esi]
        xor     eax, edx
        inc     esi
        imul    eax, $01000193                  ;   16777619              ; FNV prime
        dec     ecx
        jnz     .hashloop

.exit:
        pop     esi ecx edx
        return
endp



proc StrURLEncode, .hstr
.res dd ?
begin
        push    ebx ecx edx esi edi
        stdcall StrPtr, [.hstr]
        mov     esi, eax

        stdcall StrLen, esi
        mov     ecx, eax
        lea     edx, [2*eax+eax]        ; the encoded string can be max 3x long as original string.

        stdcall StrNew
        mov     [.res], eax
        jecxz   .finish

        stdcall StrSetCapacity, eax, edx
        mov     edi, eax
        xor     edx, edx
        xor     ebx, ebx

        push    eax
.encode:
        lodsb
        cmp     al, $80
        jae     .store          ; it is a hack, but I hope save enough.

        mov     dl, al
        mov     bl, al
        shr     edx, 5
        and     ebx, $1f
        bt      dword [.URLCharTable+4*edx], ebx
        jnc     .store

        mov     ah, al
        mov     al, '%'
        stosb
        mov     al, ah
        shr     al, 4
        cmp     al, $0a
        sbb     al, $69
        das
        stosb
        mov     al, ah
        and     al, $0f
        cmp     al, $0a
        sbb     al, $69
        das

.store:
        stosb
        loop    .encode

        xor     al, al
        mov     [edi], al

        pop     eax
        sub     edi, eax
        mov     [eax+string.len], edi

.finish:
        mov     eax, [.res]
        pop     edi esi edx ecx ebx
        return

; Contains 1 where the character must be % encoded and 0 where it is save to pass it directly
.URLCharTable db 11111111b       ;
             db 11111111b       ;
             db 11111111b       ;
             db 11111111b       ; 0..31 -control chars | encoded
             db 11111111b       ; $27 - $20: '&%$#"!   | encoded
             db 11111111b       ; $2f - $28: /.-,+*)(  | encoded
             db 00000000b       ; $37 - $30: 76543210  | not encoded
             db 11111100b       ; $3f - $38: ?>=<;:98  | partially
             db 00000001b       ; $47 - $40: GFEDCBA@  | partially
             db 00000000b       ; $4f - $48: ONMLKJIH  | not encoded
             db 00000000b       ; $57 - $50: WVUTSRQP  | not encoded
             db 11111000b       ; $5f - $58: _^]\[ZYX  | partially
             db 00000001b       ; $67 - $60: gfedcba`  | partially
             db 00000000b       ; $6f - $68: onmlkjih  | not encoded
             db 00000000b       ; $77 - $70: wvutsrqp  | not encoded
             db 11111000b       ; $7f - $78:  ~}|{zyx  | partially

endp




; UTF-8 support functions.
; Some of the above functions also need some revision in order to support
; utf-8 strings properly.



proc StrLenUtf8, .hString, .len
.maxptr dd ?
begin
        push    esi ecx edx

        stdcall StrPtr, [.hString]
        mov     esi, eax
        mov     eax, [.len]
        cmp     eax, -1
        je      @f
        add     eax, esi
@@:
        mov     [.maxptr], eax
        xor     ecx, ecx

.loop:
        cmp     esi, [.maxptr]
        jae     .endofstring

        stdcall DecodeUtf8, [esi]
        jc      .error

        test    eax, eax
        jz      .endofstring

        add     esi, edx
        inc     ecx
        jmp     .loop

.endofstring:
        mov     eax, ecx
        pop     edx ecx esi
        clc
        return

.error:
        pop     edx ecx esi
        return
endp



proc StrOffsUtf8, .hString, .pos
begin
        push    edx esi

        stdcall StrPtr, [.hString]
        mov     esi, eax

.loop:
        dec     [.pos]
        js      .finish

        stdcall DecodeUtf8, [esi]
        jc      .error

        test    eax, eax
        jz      .finish

        add     esi, edx
        jmp     .loop

.finish:
        clc
        mov     eax, esi
        pop     esi edx
        return

.error:
        xor     eax, eax
        pop     esi edx
        return
endp



; decodes 4 bytes in [.chars] to UNICODE dword value.
; returns:
;   CF=0 - no error
;     eax - unicode value.
;     edx - byte count of the char. [1..4]
;   CF=1 - invalid utf-8 char;
;     eax = edx = 0  the character can not be decoded.
;     edx <> 0 -> eax = the overlong encoded character. edx = byte count of the char.
;
;  Note: When CF=1 and [.chars] are overlong encoded char.
;        eax contains the proper value and edx contains the proper length.
;        But it is still invalid character, according to the standards.
proc DecodeUtf8, .chars
begin
        push    ebx ecx

        xor     ecx, ecx

.loop1:
        shl     byte [.chars], 1
        jnc     .countok
        inc     ecx
        jmp     .loop1

.countok:
        jecxz   .ascii

        cmp     ecx, 1
        je      .error          ; internal byte
        cmp     ecx, 4
        ja      .error          ; more than 4 bytes

        mov     edx, 1
        xor     ebx, ebx
        movzx   eax, byte [.chars]
        shr     eax, cl
        shr     eax, 1

.loop2:
        mov     bl, byte [.chars+edx]
        and     bl, $c0
        cmp     bl, $80
        jne     .error
        mov     bl, byte [.chars+edx]
        and     bl, $3f
        shl     eax, 6
        or      eax, ebx
        inc     edx
        cmp     edx, ecx
        jne     .loop2

        and     eax, $1fffff
        cmp     eax, $10ffff
        ja      .error

        cmp     eax, [._minimal+4*edx-8]
        jb      .overlong   ; overlong coding.

        clc
        pop     ecx ebx
        return

.ascii:
        movzx   eax, byte [.chars]
        shr     eax, 1
        mov     edx, 1
        pop     ecx ebx
        clc
        return

.error:
        xor     eax, eax
        xor     edx, edx
.overlong:
        stc
        pop     ecx ebx
        return

._minimal dd $80, $800, $10000

endp



proc ScanForwardUtf8
begin
        push    eax

        mov     al, [esi]
        test    al, al
        jns     .finish

        and     al, 11000000b
        cmp     al, 11000000b
        je      .finish

; inc forward
.loopf:
        inc     esi
        mov     al, [esi]
        and     al, 11000000b
        cmp     al, 10000000b
        je      .loopf

.finish:
        pop     eax
        return
endp



proc ScanBackUtf8
begin
        push    eax

        mov     al, [esi]
        test    al, al
        jns     .finish

        and     al, 11000000b
        cmp     al, 11000000b
        je      .finish

; inc back
.loopf:
        dec     esi
        mov     al, [esi]
        and     al, 11000000b
        cmp     al, 10000000b
        je      .loopf

.finish:
        pop     eax
        return
endp


include '%TargetOS%/utf8.asm'



DispSize "String library", $ - __StringLibrary
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted freshlib/test_code0/unicode_test.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
;#F:w
;This is example text, aimed simply to show the features of the FreshEdit control.

;#F:w
;1. Word-wrap feature. It works only for the lines formated with word-wrap format. You can set/remove word-wrap format by Ctrl+W key.

;#F:w
;2. FreshEdit can save the format into the source file. The formating is transparent for FASM compiler, so you can compile the files without removing formating.

;3. FreshEdit uses UTF-8 encoding - see following samples:

;Russian: Я могу еÑть Ñтекло, оно мне не вредит.
;Yoruba: Mo lè je̩ dígí, kò ní pa mí lára.
;Greek: ΜποÏÏŽ να φάω σπασμένα γυαλιά χωÏίς να πάθω τίποτα.
;Québécois: J'peux manger d'la vitre, ça m'fa pas mal.
;Ukrainian: Я можу Ñ—Ñти Ñкло, Ñ– воно мені не зашкодить.
;English: I can eat glass and it doesn't hurt me.

;#F:bw
;5. The bookmarks are saved with the text as well. Use Ctrl+B to set/remove a bookmark.

;6. Also FreshEdit, has code folding feature.
proc SomeTestProcedure
begin
        nop
        mov     eax, 1234
        return
endp

;#F:w
;7. also, there are line numbers and breakpoint icons on the left margin of the editor. You can set/remove breakpoint with F2 key.

        nop
        nop
        int3

;#F:w
; 8. Color themes: Click on "T" button to switch the color theme for the editor.

;#F:w
; 9. Zebra background - if you like such eye-candy things. Click on "Z" button in order to switch it on/off.

proc AnotherTestProcedure
begin
        xor     eax, eax

locals  ; We have of course several folding levels.
  .x  dd  ?
  .y  dd  ?
  .rect TBounds
endl

        mov     ecx, 'ABCD'
        return
endp

; 10. Click "#" to turn on/off the line numbers.
; 11. Ctrl-T will switch ON/OFF the whole left margin field.
;#F:w
; 12. Alt+Ins will switch the type of selection - line, char and block are supported for now.

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































Deleted include/finc.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
This directory is out of date. 
It is here only for compatibility reasons with some old sources and examples.
The new standart library include files are in "freshlib" directory.
The files inside "include/win32" directory are wrappers for the new include files.
The files inside "include/libs" directory are libraries that are still not converted
to the new portable format. They will be revised and moved to "freshlib" subsequently.

-------------------------------------------------------------------------------------

This directory will contain all
"Fresh standard library" files and
include files with Windows equates.

The path of this directory should be set as "finc" environment
variable or as "finc" key in Fresh.ini file, section [Environment]

/libs - standard Fresh libraries
/components - Installed visual components
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































Deleted include/libs/TDataGrid.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
;-----------------------------------------------------------
; DataGrid control.
; This is conrol, that displays data in the form of Grid.
; The control does not handle the data itself, but calls
; callback functions in order to get the data and other
; properties.
; It is intended to be a base for handling of complex data
; sets, such as database tables, memory dump tables, etc.
;
; This control is part of "Fresh standard library".
; This source is distributed under "Fresh artistic license".
; Check for details at: http://fresh.flatassembler.net
;
;
;
; (c)2004 John Found (Fresh developement team)
;-----------------------------------------------------------

initialize RegisterDataGrid
.wc WNDCLASS
begin
        xor     eax, eax
        lea     edi, [.wc]
        mov     esi, edi
        mov     ecx, sizeof.WNDCLASS shr 2
        rep stosd

        mov     [.wc.style], CS_OWNDC
        mov     [.wc.lpfnWndProc], TDataGrid.DataGridWinProc
        mov     eax, [hInstance]
        mov     [.wc.hInstance], eax
        invoke  LoadCursorA, 0, IDC_ARROW
        mov     [.wc.hCursor], eax
        mov     [.wc.hbrBackground], NULL;COLOR_WINDOW+1
        mov     [.wc.lpszClassName], cDataGridClassName

        invoke  RegisterClassA, esi
        return
endp


iglobal
  cDataGridClassName text 'TDataGrid'
  property propCtrlData, 'CtrlData'
endg


;--------------------------------------------
; This procedure executes very common task,
; extracting control data assigned to the
; window property.
; Maybe it have to resides somewhere else and
; to be used in more common way for all controls.
;--------------------------------------------
proc GetCtrlData, .hwnd, .datasize
begin
        invoke  GetPropA, [.hwnd], [propCtrlData]
        push    eax
        test    eax, eax
        jz      .finish

        invoke  IsBadReadPtr, eax, [.datasize]
        test    eax, eax
        jz      .finish

        and     dword [esp], 0

.finish:
        pop     eax
        return
endp


;----------------------------------------------------
; Window procedure of the TDataGrid control.
;----------------------------------------------------
winproc TDataGrid.DataGridWinProc
begin
        push    esi edi ebx

        invoke  GetPropA, [.hwnd], [propCtrlData]
        mov     edi, eax

        mov     ebx, [.wmsg]

ondefault
       invoke   DefWindowProcA, [.hwnd], [.wmsg], [.wparam], [.lparam]

.finish:
       pop      ebx edi esi
       return


onmessage WM_SETFONT
        invoke  SelectObject, [edi+TDataGrid.hShadowDC], [.wparam]
        jmp     .finish


onmessage WM_CREATE
; TDataGrid structure.
        mov     eax, [.lparam]
        mov     esi, [eax+CREATESTRUCT.lpCreateParams]
        invoke  IsBadWritePtr, esi, sizeof.TDataGrid
        test    eax, eax
        jz      .pointerOK

        or      eax, -1
        jmp     .finish

.pointerOK:
        invoke  SetPropA, [.hwnd], [propCtrlData], esi

        invoke  CreateCompatibleDC, NULL
        mov     [esi+TDataGrid.hShadowDC], eax

        stdcall GetMem, 4
        mov     [esi+TDataGrid.ptrColX], eax
        stdcall GetMem, 4
        mov     [esi+TDataGrid.ptrRowY], eax

        mov     eax, [.hwnd]
        mov     [esi+TDataGrid.hwnd], eax

; Default values for sizes.
        mov     [esi+TDataGrid.ColWidth], 64
        mov     [esi+TDataGrid.RowHeight], 16
        mov     [esi+TDataGrid.FixedCols], 1
        mov     [esi+TDataGrid.FixedRows], 1
        mov     [esi+TDataGrid.Flags], dgfGridLinesFixed or dgfGridlines
        mov     [esi+TDataGrid.focused.x], 2
        mov     [esi+TDataGrid.focused.y], 2
        mov     [esi+TDataGrid.selflags], -1

        invoke  GetSysColor, COLOR_BTNFACE
        mov     [esi+TDataGrid.clFixed], eax
        invoke  GetSysColor, COLOR_WINDOW
        mov     [esi+TDataGrid.clCell], eax
        invoke  GetSysColor, COLOR_HIGHLIGHT
        mov     [esi+TDataGrid.clSelected], eax
        invoke  GetSysColor, COLOR_WINDOWTEXT
        mov     [esi+TDataGrid.clTextCell], eax
        invoke  GetSysColor, COLOR_BTNTEXT
        mov     [esi+TDataGrid.clTextFixed], eax
        invoke  GetSysColor, COLOR_HIGHLIGHTTEXT
        mov     [esi+TDataGrid.clTextSelected], eax
        invoke  GetSysColor, COLOR_HOTLIGHT
        mov     [esi+TDataGrid.clMarked], eax

        stdcall TDataGrid.SetCounts, esi, 0, 0

        xor     eax, eax
        jmp     .finish

onmessage WM_SIZE
; creates new bitmap
        movsx   eax, word [.lparam+2] ; height
        movsx   ecx, word [.lparam]   ; width

        push    eax
        push    ecx

        invoke  GetDC, [.hwnd]
        mov     ebx, eax
        invoke  CreateCompatibleBitmap, ebx ; size from the stack
        mov     [edi+TDataGrid.hShadow], eax
        invoke  SelectObject, [edi+TDataGrid.hShadowDC], eax
        invoke  DeleteObject, eax
        invoke  ReleaseDC, [.hwnd], ebx

; invalidate shadow buffer.
        mov     [edi+TDataGrid.fShadowReady], 0

        stdcall TDataGrid.__AdjustScrollbars, edi
        xor     eax, eax
        jmp     .finish

onmessage WM_DESTROY
        invoke  DeleteDC, [edi+TDataGrid.hShadowDC]
        invoke  DeleteObject, [edi+TDataGrid.hSelected]

        stdcall FreeMem, [edi+TDataGrid.ptrColX]
        stdcall FreeMem, [edi+TDataGrid.ptrRowY]
        mov     [edi+TDataGrid.hwnd], 0

        xor     eax, eax
        jmp     .finish

onmessage WM_MOUSEWHEEL
        movsx   eax, word [.wparam+2]
        cdq
        mov     ecx, 120
        idiv    ecx
        imul    eax, [edi+TDataGrid.RowHeight]
        mov     ebx, eax
        invoke  GetScrollPos, [.hwnd], SB_VERT
        sub     eax, ebx
        invoke  SetScrollPos, [.hwnd], SB_VERT, eax, TRUE
        mov     [edi+TDataGrid.fShadowReady], 0
        invoke  InvalidateRect, [.hwnd], NULL, FALSE
        xor     eax, eax
        jmp     .finish


onmessage WM_PAINT
locals
  .ps PAINTSTRUCT
endl
        lea     esi, [.ps]
        invoke  BeginPaint, [.hwnd], esi
        test    eax, eax
        jz      .finish

        cmp     [edi+TDataGrid.fShadowReady], 0
        jne     .shadowok

        lea     eax, [esi+PAINTSTRUCT.rcPaint]
        stdcall TDataGrid.RedrawShadow, eax
        inc     [edi+TDataGrid.fShadowReady]

.shadowok:

        mov     ecx, [esi+PAINTSTRUCT.rcPaint.right]
        mov     edx, [esi+PAINTSTRUCT.rcPaint.bottom]
        sub     ecx, [esi+PAINTSTRUCT.rcPaint.left]
        sub     edx, [esi+PAINTSTRUCT.rcPaint.top]

        invoke  BitBlt, [esi+PAINTSTRUCT.hdc],                  \
                        [esi+PAINTSTRUCT.rcPaint.left],         \
                        [esi+PAINTSTRUCT.rcPaint.top],          \
                        ecx, edx,                               \
                        [edi+TDataGrid.hShadowDC],              \
                        [esi+PAINTSTRUCT.rcPaint.left],         \
                        [esi+PAINTSTRUCT.rcPaint.top],          \
                        SRCCOPY

        invoke  EndPaint, [.hwnd], esi
        xor     eax, eax
        jmp     .finish


onmessage DGM_SETPARAM
        cmp     [.wparam], sizeof.TDataGrid - 4
        jg      .finish

        mov     eax, [.wparam]
        pushd    [.lparam]
        popd     [edi+eax]

        stdcall  TDataGrid.__AdjustScrollbars, edi
        mov     [edi+TDataGrid.fShadowReady], 0
        invoke   InvalidateRect, [.hwnd], NULL, FALSE
        jmp      .finish

onmessage DGM_GETPARAM
        cmp     [.wparam], sizeof.TDataGrid - 4
        jg      .finish

        mov     eax, [.wparam]
        mov     eax, [edi+eax]
        jmp      .finish

onmessage WM_HSCROLL
        mov      eax, [edi+TDataGrid.ColWidth]
        jmp      .oncommonscroll
onmessage WM_VSCROLL
        mov      eax, [edi+TDataGrid.RowHeight]

.oncommonscroll:
        stdcall  ScrollBarMessage, [.hwnd], [.wmsg], [.wparam], NULL, eax
        mov     [edi+TDataGrid.fShadowReady], 0
        invoke   InvalidateRect, [.hwnd], NULL, FALSE
        jmp      .finish



onmessage WM_GETDLGCODE
        mov     eax, DLGC_WANTARROWS or DLGC_WANTCHARS
        jmp     .finish


onmessage WM_KEYDOWN
        mov     eax, [.wparam]
        cmp     eax, VK_DOWN
        je      .down
        cmp     eax, VK_UP
        je      .up
        cmp     eax, VK_LEFT
        je      .left
        cmp     eax, VK_RIGHT
        je      .right
        cmp     eax, VK_PGUP
        je      .pgup
        cmp     eax, VK_PGDN
        je      .pgdn
        cmp     eax, VK_HOME
        je      .home
        cmp     eax, VK_END
        je      .end
        jmp     .ondefault


.up:
        mov     eax, [edi+TDataGrid.focused.y]
        dec     eax
        cmp     eax, [edi+TDataGrid.FixedRows]
        jb      .endkeydown
        mov     [edi+TDataGrid.focused.y], eax
        jmp     .ensurevisible

.down:
        mov     eax, [edi+TDataGrid.focused.y]
        inc     eax
        cmp     eax, [edi+TDataGrid.RowCount]
        jae     .endkeydown
        mov     [edi+TDataGrid.focused.y], eax
        jmp     .ensurevisible

.left:
        mov     eax, [edi+TDataGrid.focused.x]
        dec     eax
        cmp     eax, [edi+TDataGrid.FixedCols]
        jl      .endkeydown
        mov     [edi+TDataGrid.focused.x], eax
        jmp     .ensurevisible

.right:
        mov     eax, [edi+TDataGrid.focused.x]
        inc     eax
        cmp     eax, [edi+TDataGrid.ColCount]
        jae     .endkeydown
        mov     [edi+TDataGrid.focused.x], eax
        jmp     .ensurevisible

.pgup:
        mov     ebx, -1
        jmp     .pgupdn

.pgdn:
        mov     ebx, 1

.pgupdn:
locals
  .si SCROLLINFO
endl
        mov     [.si.cbSize], sizeof.SCROLLINFO
        mov     [.si.fMask], SIF_PAGE or SIF_POS or SIF_RANGE
        lea     eax, [.si]
        invoke  GetScrollInfo, [.hwnd], SB_VERT, eax
        mov     eax, [.si.nPage]
        xor     edx, edx
        div     [edi+TDataGrid.RowHeight]
        imul    eax, ebx
        add     eax, [edi+TDataGrid.focused.y]

        cmp     eax, [edi+TDataGrid.FixedRows]
        jge     @f
        mov     eax, [edi+TDataGrid.FixedRows]
@@:
        cmp     eax, [edi+TDataGrid.RowCount]
        jl      @f
        mov     eax, [edi+TDataGrid.RowCount]
        dec     eax
@@:
        mov     [edi+TDataGrid.focused.y], eax
        jmp     .ensurevisible

.home:
        mov     eax, [edi+TDataGrid.FixedCols]
        mov     ecx, [edi+TDataGrid.FixedRows]
        jmp     .setfocused

.end:
        mov     eax, [edi+TDataGrid.ColCount]
        mov     ecx, [edi+TDataGrid.RowCount]
        dec     eax
        dec     ecx

.setfocused:
        mov     [edi+TDataGrid.focused.x], eax
        mov     [edi+TDataGrid.focused.y], ecx
        jmp     .ensurevisible


.ensurevisible:
; Clear existing selection
        invoke  DeleteObject, [edi+TDataGrid.hSelected]
        mov     [edi+TDataGrid.hSelected], 0

        stdcall TDataGrid.EnsureVisible, edi, [edi+TDataGrid.focused.x], [edi+TDataGrid.focused.y]
        mov     [edi+TDataGrid.fShadowReady], 0
        invoke  InvalidateRect, [.hwnd], 0, FALSE

.endkeydown:
        xor     eax, eax
        jmp     .finish


onmessage WM_LBUTTONDOWN
        invoke  SetFocus, [.hwnd]
        invoke  SetCapture, [.hwnd]

        movsx   eax, word [.lparam]
        movsx   ecx, word [.lparam+2]
        stdcall TDataGrid.HitTest3, edi, eax, ecx, htwXBoth, htwYBoth

        mov     [edi+TDataGrid.selflags], 0
        mov     [edi+TDataGrid.selection.left], eax
        mov     [edi+TDataGrid.selection.top], edx
        mov     [edi+TDataGrid.selection.right], eax
        mov     [edi+TDataGrid.selection.bottom], edx

        cmp     eax, [edi+TDataGrid.FixedCols]
        jge     .notleft

; if the cursor is on the left fixed cells
        or      [edi+TDataGrid.selflags], 1
        mov     ebx, [edi+TDataGrid.FixedCols]  ; xbeg
        mov     ecx, [edi+TDataGrid.ColCount]   ; xend
        mov     [edi+TDataGrid.selection.left], ebx
        mov     [edi+TDataGrid.selection.right], ecx

.notleft:
        cmp     edx, [edi+TDataGrid.FixedRows]
        jge     .nottop

; if the cursor is on the top fixed cells
        or      [edi+TDataGrid.selflags], 2
        mov     ebx, [edi+TDataGrid.FixedRows]  ; ybeg
        mov     ecx, [edi+TDataGrid.RowCount]   ; yend
        mov     [edi+TDataGrid.selection.top], ebx
        mov     [edi+TDataGrid.selection.bottom], ecx

.nottop:
        cmp     [edi+TDataGrid.selflags], 0
        jne     .clearcurrent

        mov     [edi+TDataGrid.focused.x], eax
        mov     [edi+TDataGrid.focused.y], edx

.clearcurrent:
        test    [.wparam], MK_CONTROL
        jnz     .invalidate

        invoke  DeleteObject, [edi+TDataGrid.hSelected]
        mov     [edi+TDataGrid.hSelected], 0

.invalidate:
        mov     [edi+TDataGrid.fShadowReady], 0
        invoke  InvalidateRect, [.hwnd], 0, FALSE
        xor     eax, eax
        jmp     .finish


onmessage WM_MOUSEMOVE
        invoke  GetCapture
        cmp     eax, [.hwnd]
        jne     .ondefault       ; temporary...

        mov     esi, [edi+TDataGrid.selflags]
        cmp     esi, 3
        je      .ondefault    ; nothing to select.

        mov     eax, htwXData
        mov     ebx, htwYData

        cmp     esi, 1
        jne     @f
        mov     eax, htwXFixed
@@:
        cmp     esi, 2
        jne     @f
        mov     ebx, htwYFixed
@@:
        movsx   ecx, word [.lparam]
        movsx   edx, word [.lparam+2]
        stdcall TDataGrid.HitTest3, edi, ecx, edx, eax, ebx

        cmp     esi, 1
        jne     .maybecol

        mov     [edi+TDataGrid.selection.bottom], edx
        mov     eax, [edi+TDataGrid.selection.left]
        jmp     .endmove

.maybecol:
        cmp     esi, 2
        jne     .cellselect

        mov     [edi+TDataGrid.selection.right], eax
        mov     edx, [edi+TDataGrid.selection.top]
        jmp     .endmove

; select normal cells
.cellselect:
        mov     [edi+TDataGrid.selection.right], eax
        mov     [edi+TDataGrid.selection.bottom], edx

.endmove:
        stdcall TDataGrid.EnsureVisible, edi, eax, edx
        mov     [edi+TDataGrid.fShadowReady], 0
        invoke  InvalidateRect, [.hwnd], 0, FALSE

        xor     eax, eax
        jmp     .finish


onmessage WM_LBUTTONUP
        invoke  GetCapture
        cmp     eax, [.hwnd]
        jne     .ondefault

        invoke  SetCapture, NULL

        mov     [edi+TDataGrid.selflags], -1

        lea     esi, [edi+TDataGrid.selection]
        call    TDataGrid.SortRect

        stdcall TDataGrid.SelectRect, edi, [edi+TDataGrid.selection.left],   \
                                           [edi+TDataGrid.selection.top],    \
                                           [edi+TDataGrid.selection.right],  \
                                           [edi+TDataGrid.selection.bottom], \
                                           soMerge

        mov     [edi+TDataGrid.fShadowReady], 0
        invoke  InvalidateRect, [.hwnd], 0, FALSE

        xor     eax, eax
        jmp     .finish
endwp



proc TDataGrid.SortRect
begin
        mov     eax, [esi+RECT.left]
        mov     ecx, [esi+RECT.right]
        cmp     ecx, eax
        jge     @f
        xchg    eax,ecx
@@:
        mov     [esi+RECT.left],eax
        mov     [esi+RECT.right], ecx

        mov     eax, [esi+RECT.top]
        mov     ecx, [esi+RECT.bottom]
        cmp     ecx, eax
        jge     @f
        xchg    eax,ecx
@@:
        mov     [esi+RECT.top],eax
        mov     [esi+RECT.bottom], ecx
        return
endp


;-----------------------------------------------------------------------
; TDataGrid public functions.
;
;-----------------------------------------------------------------------
proc TDataGrid.RedrawShadow, .ptrRect
.rcFixedTL RECT
.rcFixedT  RECT
.rcFixedL  RECT
.rcFloat   RECT
.rcClient  RECT
begin
        lea     eax, [.rcClient]
        invoke  GetClientRect, [edi+TDataGrid.hwnd], eax

        mov     eax, [.rcClient.right]
        mov     ecx, [.rcClient.bottom]
        xor     edx, edx

        mov     [.rcFixedT.right], eax
        mov     [.rcFixedL.bottom], ecx
        mov     [.rcFloat.right], eax
        mov     [.rcFloat.bottom], ecx

        mov     [.rcFixedTL.left], edx
        mov     [.rcFixedTL.top], edx
        mov     [.rcFixedT.top], edx
        mov     [.rcFixedL.left], edx

        mov     ecx, [edi+TDataGrid.FixedCols]
        mov     eax, [edi+TDataGrid.ptrColX]
        test    eax, eax
        jnz     .colsizeok

        imul    ecx, [edi+TDataGrid.ColWidth]   ; default width if there is no size array
        jmp     .x1ok

.colsizeok:
        mov     ecx, [eax+4*ecx]
.x1ok:
        mov     edx, [edi+TDataGrid.FixedRows]
        mov     eax, [edi+TDataGrid.ptrRowY]
        test    eax, eax
        jnz     .rowsizeok

        imul    edx, [edi+TDataGrid.ColWidth]   ; default width if there is no size array
        jmp     .y1ok

.rowsizeok:
        mov     edx, [eax+4*edx]
.y1ok:
        mov     [.rcFixedTL.right], ecx
        mov     [.rcFixedTL.bottom], edx
        mov     [.rcFixedT.left], ecx
        mov     [.rcFixedT.bottom], edx
        mov     [.rcFixedL.right], ecx
        mov     [.rcFixedL.top], edx
        mov     [.rcFloat.left], ecx
        mov     [.rcFloat.top], edx

; Here all 4 rectangles are ready. Some of them can be empty of course.
; Lets make intersections with the invalidated rectangle.

.drawFixedTL:
        lea     eax, [.rcFixedTL]
        invoke  IntersectRect, eax, eax, [.ptrRect]
        test    eax, eax
        jz      .drawFixedT

        lea     eax, [.rcFixedTL]
        stdcall TDataGrid.__DrawCellArea, eax, ffHorizontal or ffVertical

.drawFixedT:
        lea     eax, [.rcFixedT]
        invoke  IntersectRect, eax, eax, [.ptrRect]
        test    eax, eax
        jz      .drawFixedL

        lea     eax, [.rcFixedT]
        stdcall TDataGrid.__DrawCellArea, eax, ffVertical

.drawFixedL:
        lea     eax, [.rcFixedL]
        invoke  IntersectRect, eax, eax, [.ptrRect]
        test    eax, eax
        jz      .drawFloat

        lea     eax, [.rcFixedL]
        stdcall TDataGrid.__DrawCellArea, eax, ffHorizontal

.drawFloat:
        lea     eax, [.rcFloat]
        invoke  IntersectRect, eax, eax, [.ptrRect]
        test    eax, eax
        jz      .finish

        lea     eax, [.rcFloat]
        stdcall TDataGrid.__DrawCellArea, eax, 0

.finish:
        return
endp


; .fFixed contains flags:
ffHorizontal = 1
ffVertical   = 2

proc TDataGrid.__DrawCellArea, .ptrClipRect, .fFixed
.Cell  RECT
.si    SCROLLINFO
.xofs  dd ?
.yofs  dd ?
.clip  RECT
.brush dd ?
.brushsel dd ?
.flags dd ?
.sel   RECT
begin
        push    ebx esi

        lea     esi, [.sel]
        lea     eax, [edi+TDataGrid.selection]
        invoke  CopyRect, esi, eax
        call    TDataGrid.SortRect
        inc     [esi+RECT.right]
        inc     [esi+RECT.bottom]

        mov     eax, [edi+TDataGrid.FixedRows]
        mov     ecx, [edi+TDataGrid.FixedCols]

; [esi+RECT.top] := max([esi+RECT.top], [edi+TDataGrid.FixedRows])
        sub     eax, [esi+RECT.top]
        sbb     edx, edx
        not     edx
        and     edx, eax
        add     [esi+RECT.top], edx

; [esi+RECT.left] := max([esi+RECT.left], [edi+TDataGrid.FixedCols])
        sub    ecx, [esi+RECT.left]
        sbb    edx, edx
        not    edx
        and    edx, ecx
        add    [esi+RECT.left], edx

        mov     esi, [.ptrClipRect]

; Create the brush for selected cells background.
        invoke  CreateSolidBrush, [edi+TDataGrid.clSelected]
        mov     [.brush], eax
        invoke  CreateSolidBrush, [edi+TDataGrid.clMarked]
        mov     [.brushsel], eax

; Set the cliping region for the shadow DC.
        invoke  CreateRectRgnIndirect, [.ptrClipRect]
        push    eax
        invoke  SelectClipRgn, [edi+TDataGrid.hShadowDC], eax
        invoke  DeleteObject ; from the stack

; erase the background
        mov     eax, [edi+TDataGrid.clCell]
        cmp     [.fFixed], 0
        je      .bgok
        mov     eax, [edi+TDataGrid.clFixed]

.bgok:
        invoke  CreateSolidBrush, eax
        push    eax
        invoke  FillRect, [edi+TDataGrid.hShadowDC], [.ptrClipRect], eax
        invoke  DeleteObject ; from the stack

        invoke  SetBkMode, [edi+TDataGrid.hShadowDC], TRANSPARENT

; If the cells are not fixed, compute the real coordinates of the rectangle.
        mov    [.si.cbSize], sizeof.SCROLLINFO
        mov    [.si.fMask], SIF_POS or SIF_RANGE
        lea    ebx, [.si]

        xor     eax, eax
        mov     [.xofs], eax
        mov     [.yofs], eax

        test    [.fFixed], ffHorizontal
        jnz     .horizOK

        invoke  GetScrollInfo, [edi+TDataGrid.hwnd], SB_HORZ, ebx
        mov     eax, [ebx+SCROLLINFO.nPos]
        sub     eax, [ebx+SCROLLINFO.nMin]
        mov     [.xofs], eax
        add     [esi+RECT.left], eax
        add     [esi+RECT.right], eax

.horizOK:
        test    [.fFixed], ffVertical
        jnz     .vertOK

        invoke  GetScrollInfo, [edi+TDataGrid.hwnd], SB_VERT, ebx
        mov     eax, [ebx+SCROLLINFO.nPos]
        sub     eax, [ebx+SCROLLINFO.nMin]
        mov     [.yofs], eax
        add     [esi+RECT.top], eax
        add     [esi+RECT.bottom], eax

; Determine the cell range for the given clip rectangle.
.vertOK:
        stdcall TDataGrid.__SearchCellRange, [esi+RECT.left], [esi+RECT.right], [edi+TDataGrid.ptrColX], [edi+TDataGrid.ColCount]
        mov     [.Cell.left], eax
        mov     [.Cell.right], edx

        stdcall TDataGrid.__SearchCellRange, [esi+RECT.top], [esi+RECT.bottom], [edi+TDataGrid.ptrRowY], [edi+TDataGrid.RowCount]
        mov     [.Cell.top], eax
        mov     [.Cell.bottom], edx

        mov     ebx, [.Cell.top]

.yloop:
        cmp     ebx, [.Cell.bottom]
        jge     .endyloop

        mov     eax, [edi+TDataGrid.ptrRowY]
        mov     ecx, [4*ebx+eax+4]              ; bottom
        mov     eax, [4*ebx+eax]                ; top
        sub     ecx, [.yofs]
        sub     eax, [.yofs]

        mov     [.clip.bottom], ecx
        mov     [.clip.top], eax

        mov     esi, [.Cell.left]

.xloop:
        cmp     esi, [.Cell.right]
        jge     .endxloop

        mov     eax, [edi+TDataGrid.ptrColX]
        mov     ecx, [4*esi+eax+4]
        mov     eax, [4*esi+eax]
        sub     ecx, [.xofs]
        sub     eax, [.xofs]

        mov     [.clip.right], ecx
        mov     [.clip.left], eax

; draw the background if the cell is selected
        mov     eax, [edi+TDataGrid.hSelected]
        test    eax, eax
        jz      .bkgroundok

        invoke  PtInRegion, eax, esi, ebx
        test    eax, eax
        jz      .bkgroundok

        lea     eax, [.clip]
        invoke  FillRect, [edi+TDataGrid.hShadowDC], eax, [.brush]

.bkgroundok:
        mov     [.flags], eax   ; true is the cell is selected

        cmp     [edi+TDataGrid.selflags], -1
        je      .notselection

        lea     eax, [.sel]
        invoke  PtInRect, eax, esi, ebx
        test    eax, eax
        jz      .notselection

        lea     eax, [.clip]
        invoke  FillRect, [edi+TDataGrid.hShadowDC], eax, [.brushsel]
        inc     [.flags]

.notselection:
        cmp     [edi+TDataGrid.OnDrawItem], 0
        je      .drawgridlines

        lea     eax, [.clip]
        stdcall [edi+TDataGrid.OnDrawItem], [edi+TDataGrid.hShadowDC], eax, esi, ebx, [edi+TDataGrid.ptrGridData], [.flags], [.fFixed]

; draw the gridlines:
.drawgridlines:
        cmp     [.fFixed], FALSE
        je      .datagridline

        test    [edi+TDataGrid.Flags], dgfGridLinesFixed
        jz      .gridok

        lea     eax, [.clip]
        invoke  DrawEdge, [edi+TDataGrid.hShadowDC], eax, BDR_RAISEDINNER, BF_RECT
        jmp     .gridok

.datagridline:
        test    [edi+TDataGrid.Flags], dgfGridlines
        jz      .gridok

        mov     eax, [.clip.bottom]
        mov     edx, [.clip.top]
        mov     ecx, [.clip.right]
        dec     eax
        dec     edx
        dec     ecx

        push    edx ecx
        push    eax ecx
        push    0 eax [.clip.left]

        invoke  MoveToEx, [edi+TDataGrid.hShadowDC]
        invoke  LineTo, [edi+TDataGrid.hShadowDC]
        invoke  LineTo, [edi+TDataGrid.hShadowDC]

.gridok:
        cmp     esi, [edi+TDataGrid.focused.x]
        jne     .endcell
        cmp     ebx, [edi+TDataGrid.focused.y]
        jne     .endcell

        lea     eax, [.clip]
        dec     [.clip.right]
        dec     [.clip.bottom]
        invoke  DrawFocusRect, [edi+TDataGrid.hShadowDC], eax
        inc     [.clip.right]
        inc     [.clip.bottom]

.endcell:
        inc     esi
        jmp     .xloop

.endxloop:
        inc     ebx
        jmp     .yloop

.endyloop:
        invoke  DeleteObject, [.brush]
        invoke  DeleteObject, [.brushsel]

        pop     esi ebx
        return
endp



;------------------------------------------------------------------
; If .Col, .Row is inside the visible client area, does nothing.
; , if .Col, .Row is outside this area, provides scrolling to
; make it visible to the center of the client area.
;------------------------------------------------------------------
proc TDataGrid.EnsureVisible, .ptrGrid, .Col, .Row
.si  SCROLLINFO
.client RECT
begin
        push    ebx edi
        mov     edi, [.ptrGrid]

        lea     eax, [.client]
        invoke  GetClientRect, [edi+TDataGrid.hwnd], eax

        mov     [.si.cbSize], sizeof.SCROLLINFO
        mov     [.si.fMask], SIF_RANGE or SIF_POS

        mov     eax, [.Col]
        cmp     eax, [edi+TDataGrid.FixedCols]
        jb      .posvertical                    ; fixed columns are always inside the screen

        lea     eax, [.si]
        invoke  GetScrollInfo, [edi+TDataGrid.hwnd], SB_HORZ, eax

        mov     eax, [.client.right]
        mov     ecx, [.si.nPos]
        sub     eax, [.si.nMin]
        add     eax, ecx
        mov     [.client.left], ecx
        mov     [.client.right], eax

        mov     edx, [edi+TDataGrid.ptrColX]
        mov     ecx, [.Col]
        mov     ebx, [edx+4*ecx]
        mov     ecx, [edx+4*ecx+4]

        cmp     ecx, [.client.right]
        jle     .rightok

        sub     ecx, [.client.right]
        add     ecx, [.client.left]
        mov     [.si.nPos], ecx
        lea     ecx, [.si]
        invoke  SetScrollInfo, [edi+TDataGrid.hwnd], SB_HORZ, ecx, TRUE
        jmp     .posvertical

.rightok:
        cmp     ebx, [.client.left]
        jge     .posvertical

        mov     [.si.nPos], ebx
        lea     ecx, [.si]
        invoke  SetScrollInfo, [edi+TDataGrid.hwnd], SB_HORZ, ecx, TRUE

.posvertical:
        mov     eax, [.Row]
        cmp     eax, [edi+TDataGrid.FixedRows]
        jb      .endpos

        lea     eax, [.si]
        invoke  GetScrollInfo, [edi+TDataGrid.hwnd], SB_VERT, eax

        mov     eax, [.client.bottom]
        mov     ecx, [.si.nPos]
        sub     eax, [.si.nMin]
        add     eax, ecx
        mov     [.client.top], ecx
        mov     [.client.bottom], eax

        mov     edx, [edi+TDataGrid.ptrRowY]
        mov     ecx, [.Row]
        mov     ebx, [edx+4*ecx]
        mov     ecx, [edx+4*ecx+4]

        cmp     ecx, [.client.bottom]
        jle     .bottomok

        sub     ecx, [.client.bottom]
        add     ecx, [.client.top]
        mov     [.si.nPos], ecx
        lea     ecx, [.si]
        invoke  SetScrollInfo, [edi+TDataGrid.hwnd], SB_VERT, ecx, TRUE
        jmp     .endpos

.bottomok:
        cmp     ebx, [.client.top]
        jge     .endpos

        mov     [.si.nPos], ebx
        lea     ecx, [.si]
        invoke  SetScrollInfo, [edi+TDataGrid.hwnd], SB_VERT, ecx, TRUE

.endpos:
        pop     edi ebx
        return
endp



;-----------------------------------------------------------------------
; Returns the cell coordinates of the cell, where pixel [.x,.y] is located.
; eax : Column
; edx ; Row
;--------------------------------------------------------------------------
proc TDataGrid.HitTest3, .ptrGrid, .x, .y, .fWhereX, .fWhereY
.si SCROLLINFO
begin
        push    edi esi ebx

        mov     edi, [.ptrGrid]

        mov     [.si.cbSize], sizeof.SCROLLINFO
        mov     [.si.fMask], SIF_POS or SIF_RANGE

        lea     eax, [.si]
        invoke  GetScrollInfo, [edi+TDataGrid.hwnd], SB_HORZ, eax
        mov     eax, [.si.nMin]
        mov     ecx, [.si.nPos]

        cmp     [.fWhereX], htwXFixed
        je      .xfixed
        cmp     [.fWhereX], htwXData
        je      .fixx

        cmp     [.x], eax
        jl      .xfixed

.fixx:
        sub     [.x], eax
        add     [.x], ecx

.xfixed:
        mov     [.si.fMask], SIF_POS or SIF_RANGE
        lea     eax, [.si]
        invoke  GetScrollInfo, [edi+TDataGrid.hwnd], SB_VERT, eax
        mov     eax, [.si.nMin]
        mov     ecx, [.si.nPos]

        cmp     [.fWhereY], htwYFixed
        je      .yfixed
        cmp     [.fWhereY], htwYData
        je      .fixy

        cmp     [.y], eax
        jl      .yfixed

.fixy:
        sub     [.y], eax
        add     [.y], ecx

.yfixed:
        stdcall TDataGrid.__SearchCellRange, [.x], [.x], [edi+TDataGrid.ptrColX], [edi+TDataGrid.ColCount]
        push    eax
        stdcall TDataGrid.__SearchCellRange, [.y], [.y], [edi+TDataGrid.ptrRowY], [edi+TDataGrid.RowCount]

        mov     edx, eax
        pop     eax

        pop     ebx esi edi
        return
endp




;--------------------------------------------
; possible operations: all RGN_ operations.
;
  soMerge = RGN_OR
  soClearPrev = RGN_COPY
  soInvert    = RGN_XOR

proc TDataGrid.SelectRect, .ptrGrid, .BegCol, .BegRow, .EndCol, .EndRow, .operation
begin
        push    edi ebx

        mov     edi, [.ptrGrid]

        mov     eax, [edi+TDataGrid.FixedRows]
        mov     ecx, [edi+TDataGrid.FixedCols]

; [.BegRow] := max([.BegRow], [edi+TDataGrid.FixedRows])
        sub     eax, [.BegRow]
        sbb     edx, edx
        not     edx
        and     edx, eax
        add     [.BegRow], edx

; [.BegCol] := max([.BegCol], [edi+TDataGrid.FixedCols])
        sub    ecx, [.BegCol]
        sbb    edx, edx
        not    edx
        and    edx, ecx
        add    [.BegCol], edx

        mov     eax, [edi+TDataGrid.RowCount]
        mov     ecx, [edi+TDataGrid.ColCount]
        cmp     [.BegRow], eax
        jae     .finish
        cmp     [.BegCol], ecx
        jae     .finish

        dec     eax
        dec     ecx

; [.EndRow] := min([.EndRow], [edi+TDataGrid.RowCount])
        sub     eax, [.EndRow]
        sbb     edx, edx
        and     edx, eax
        add     [.EndRow], edx

; [.EndCol] := min([.EndCol], [edi+TDataGrid.ColCount])
        sub    ecx, [.EndCol]
        sbb    edx, edx
        and    edx, ecx
        add    [.EndCol], edx

        inc     [.EndCol]
        inc     [.EndRow]

        invoke  CreateRectRgn, [.BegCol], [.BegRow], [.EndCol], [.EndRow]
        mov     ebx, eax

        cmp     [edi+TDataGrid.hSelected], 0
        je      .newselection

        invoke  CombineRgn, [edi+TDataGrid.hSelected],  \
                            ebx,                        \
                            [edi+TDataGrid.hSelected],  \
                            [.operation]

        cmp     eax, NULLREGION
        jne     .free

        invoke  DeleteObject, [edi+TDataGrid.hSelected]
        mov     [edi+TDataGrid.hSelected], 0

.free:
        invoke  DeleteObject, ebx
.finish:
        pop     ebx edi
        return

.newselection:
        mov     [edi+TDataGrid.hSelected], ebx
        pop     ebx edi
        return
endp



proc TDataGrid.GetCellXY, .ptrGrid, .Col, .Row
begin
        push    esi

        mov     esi, [.ptrGrid]
        mov     eax, [.Col]
        mov     edx, [.Row]
        shl     eax, 2
        shl     edx, 2
        add     eax, [esi+TDataGrid.ptrColX]
        add     edx, [esi+TDataGrid.ptrRowY]
        mov     eax, [eax]
        mov     edx, [edx]

        pop     esi
        return
endp



proc TDataGrid.SetCounts, .ptrGrid, .ColCount, .RowCount
.ycount dd ?
.ptrNewColX  dd ?
.ptrNewRowY  dd ?
begin
        push    esi ebx edi

        mov     [.ptrNewColX], 0
        mov     [.ptrNewRowY], 0
        mov     ebx, [.ptrGrid]

; resize column coordinates array...
        mov     eax, [ebx+TDataGrid.ptrColX]
        mov     [.ptrNewColX], eax

        mov     eax, [.ColCount]
        cmp     eax, [ebx+TDataGrid.ColCount]
        je      .resizey

        mov     eax, [.ColCount]
        lea     eax, [4*eax+4]          ; byte size of the array.
        test    eax, eax
        jg      @f
        mov     eax, 4
@@:
        stdcall ResizeMem, [ebx+TDataGrid.ptrColX], eax
        mov     [.ptrNewColX], eax
        test    eax, eax
        jz      .finish

        mov     edi, eax

        mov     ecx, [ebx+TDataGrid.ColCount]
        cmp     ecx, [.ColCount]
        jge     .resizey

        mov     eax, [edi+4*ecx]

.newsizesx:
        inc     ecx
        cmp     ecx, [.ColCount]
        jg      .resizey

        add     eax, [ebx+TDataGrid.ColWidth]
        mov     [edi+4*ecx], eax
        jmp     .newsizesx

.resizey:
; resize row coordinates array...
        mov     eax, [ebx+TDataGrid.ptrRowY]
        mov     [.ptrNewRowY], eax

        mov     eax, [.RowCount]
        cmp     eax, [ebx+TDataGrid.RowCount]
        je      .finish

        mov     eax, [.RowCount]
        lea     eax, [4*eax+4]          ; byte size of the array.
        test    eax, eax
        jg      @f
        mov     eax, 4
@@:
        stdcall ResizeMem,[ebx+TDataGrid.ptrRowY], eax
        mov     [.ptrNewRowY], eax
        test    eax, eax
        jz      .finish

        mov     edi, eax

        mov     ecx, [ebx+TDataGrid.RowCount]
        cmp     ecx, [.RowCount]
        jg      .finish

        mov     eax, [edi+4*ecx]

.newsizesy:
        inc     ecx
        cmp     ecx, [.RowCount]
        jg      .finish

        add     eax, [ebx+TDataGrid.RowHeight]
        mov     [edi+4*ecx], eax
        jmp     .newsizesy

.finish:
        xor     eax, eax
        cmp     eax, [.ptrNewColX]
        je      .error1
        cmp     eax, [.ptrNewRowY]
        je      .error2

        mov     ecx, [.RowCount]
        mov     edx, [.ColCount]
        mov     [ebx+TDataGrid.RowCount], ecx
        mov     [ebx+TDataGrid.ColCount], edx

        mov     ecx, [.ptrNewColX]
        mov     edx, [.ptrNewRowY]
        mov     [ebx+TDataGrid.ptrColX], ecx
        mov     [ebx+TDataGrid.ptrRowY], edx

        xor     eax, eax
        pop     edi ebx esi
        return

.error2:
        stdcall FreeMem, [.ptrNewColX]

.error1:
        xor     eax, eax
        inc     eax
        pop     edi ebx esi
        return
endp


proc TDataGrid.SetColWidth, .ptrGrid, .Col, .Width
begin
        mov     eax, [.ptrGrid]
        stdcall TDataGrid.__SetRowColSize, eax, [eax+TDataGrid.ptrColX], [eax+TDataGrid.ColCount], [.Col], [.Width]
        return
endp


proc TDataGrid.SetColumnsWidth, .ptrGrid, .BegCol, .EndCol, .Width
begin
        push    ebx edi

        mov     edi, [.ptrGrid]
        mov     ebx, [.BegCol]
        cmp     ebx, [edi+TDataGrid.ColCount]
        jae     .endloop

        mov     eax, [edi+TDataGrid.ColCount]
        cmp     [.EndCol], eax
        jl      .loop

        dec     eax
        mov     [.EndCol], eax

.loop:
        cmp     ebx, [.EndCol]
        ja      .endloop
        cmp     ebx, [edi+TDataGrid.ColCount]
        jae     .endloop

        stdcall TDataGrid.__SetRowColSize, edi, [edi+TDataGrid.ptrColX], [edi+TDataGrid.ColCount], ebx, [.Width]
        inc     ebx
        jmp     .loop
.endloop:
        pop     edi ebx
        return
endp



proc TDataGrid.SetRowHeight, .ptrGrid, .Row, .Height
begin
        mov     eax, [.ptrGrid]
        stdcall TDataGrid.__SetRowColSize, eax, [eax+TDataGrid.ptrRowY], [eax+TDataGrid.RowCount], [.Row], [.Height]
        return
endp


proc TDataGrid.SetRowsHeight, .ptrGrid, .BegRow, .EndRow, .Height
begin
        push    ebx edi

        mov     edi, [.ptrGrid]
        mov     ebx, [.BegRow]
        cmp     ebx, [edi+TDataGrid.RowCount]
        jae     .endloop

        mov     eax, [edi+TDataGrid.RowCount]
        cmp     [.EndRow], eax
        jl      .loop

        dec     eax
        mov     [.EndRow], eax

.loop:
        cmp     ebx, [.EndRow]
        ja      .endloop

        stdcall TDataGrid.__SetRowColSize, edi, [edi+TDataGrid.ptrRowY], [edi+TDataGrid.RowCount], ebx, [.Height]
        inc     ebx
        jmp     .loop

.endloop:
        pop     edi ebx
        return
endp



;-----------------------------------------------------------------------
; TDataGrid example event handlers.
;
;-----------------------------------------------------------------------

;-----------------------------------------------------------------------
; Simple example handler for TDataGrid.OnDrawCell
; It uses TDataGrid.OnGetString to obtain a string handler.
; After printing, the string will be deleted.
;-----------------------------------------------------------------------
proc OnDrawStringCell, .hdc, .ptrRect, .Col, .Row, .ptrData, .fSelected, .fFixed
begin
        push    esi ebx

; Choose text color
        mov     eax, [edi+TDataGrid.clTextFixed]
        cmp     [.fFixed], 0
        jne     .colorok

        mov     eax, [edi+TDataGrid.clTextSelected]
        cmp     [.fSelected], FALSE
        jne     .colorok

        mov     eax, [edi+TDataGrid.clTextCell]

.colorok:
        invoke  SetTextColor, [.hdc], eax

        stdcall [edi+TDataGrid.OnGetString], [.Col], [.Row], [.ptrData], [.fSelected], [.fFixed]
        test    eax, eax
        jz      .drawok

        mov     ebx, eax
        stdcall StrPtr, ebx
        invoke  DrawTextA, [.hdc], eax, -1, [.ptrRect], DT_CENTER or DT_VCENTER or DT_SINGLELINE or DT_NOPREFIX
        stdcall StrDel, ebx

.drawok:
        pop     ebx esi
        return
endp



;------------------------------------------------------------------------
; TDataGrid private functions.
; These functions are for internal use. Don't call them outside TDataGrid
; control.
;------------------------------------------------------------------------


; Returns eax - BegCell, edx - EndCell of the range that fits in the xMin..xMax coordinates.
; Returns ecx containinig the left coordinate of the BegCell.
; Binary search - note that the array is always sorted...
proc TDataGrid.__SearchCellRange, .xMin, .xMax, .ptrXArray, .Count
begin
        push    esi ebx
        mov     esi, [.ptrXArray]

        xor     eax, eax
        mov     edx, [.Count]
.minloop:
        mov     ecx, eax
        add     ecx, edx
        sar     ecx, 1
        cmp     ecx, eax
        je      .endminloop

        mov     ebx, [esi+4*ecx]
        cmp     [.xMin], ebx
        jl      .rightmin

        mov     eax, ecx
        jmp     .minloop

.rightmin:
        mov     edx, ecx
        jmp     .minloop

.endminloop:
        push    eax     ; left cell.

        xor     eax, eax
        mov     edx, [.Count]
.maxloop:
        mov     ecx, eax
        add     ecx, edx
        sar     ecx, 1
        cmp     ecx, eax
        je      .endmaxloop

        mov     ebx, [esi+4*ecx]
        cmp     [.xMax], ebx
        jl      .rightmax

        mov     eax, ecx
        jmp     .maxloop

.rightmax:
        mov     edx, ecx
        jmp     .maxloop

.endmaxloop:
        pop     eax     ; edx contains eax+1 -> right value.
        mov     ecx, [esi+4*eax]  ; absolute coordinate of the left cell.

        pop     ebx esi
        return
endp



;---------------------------------------------------------
; Auto adjusts the scrollbars
;---------------------------------------------------------
proc TDataGrid.__AdjustScrollbars, .ptrGrid
.client RECT
begin
        push    ebx

        mov     ebx, [.ptrGrid]

        lea     eax, [.client]
        invoke  GetClientRect, [ebx+TDataGrid.hwnd], eax

        stdcall TDataGrid.__AdjustOneScroller, [ebx+TDataGrid.hwnd], SB_VERT, [ebx+TDataGrid.ptrRowY], [ebx+TDataGrid.RowCount], [ebx+TDataGrid.FixedRows], [.client.bottom], [ebx+TDataGrid.RowHeight]
        stdcall TDataGrid.__AdjustOneScroller, [ebx+TDataGrid.hwnd], SB_HORZ, [ebx+TDataGrid.ptrColX], [ebx+TDataGrid.ColCount], [ebx+TDataGrid.FixedCols], [.client.right], [ebx+TDataGrid.ColWidth]

        invoke  InvalidateRect, [ebx+TDataGrid.hwnd], NULL, FALSE

.finish:
        pop     ebx
        return
endp


proc TDataGrid.__AdjustOneScroller, .hwnd, .kind, .ptrArray, .Count, .Fixed, .client, .meansize
.si    SCROLLINFO
begin
        push    esi

        invoke  GetScrollPos, [.hwnd], [.kind]
        mov     [.si.nPos], eax
        mov     [.si.nPage], -1

        mov     esi, [.ptrArray]
        test    esi, esi
        jz      .finish

        mov     [.si.cbSize], sizeof.SCROLLINFO
        mov     [.si.fMask], SIF_RANGE or SIF_PAGE or SIF_POS or SIF_TRACKPOS

        mov     ecx, [.Count]
        mov     edx, [.Fixed]
        mov     ecx, [esi+4*ecx]
        mov     edx, [esi+4*edx]
        mov     [.si.nMax], ecx
        mov     [.si.nMin], edx

        cmp     [.meansize], 0
        je      .skippg

        mov     eax, [.client]
        xor     edx, edx
        sub     eax, [.si.nMin]        ;remaining client area.
        jns     @f
        xor     eax, eax
@@:
        mov     [.si.nPage], eax

.skippg:
        lea     eax, [.si]
        invoke  SetScrollInfo, [.hwnd], [.kind], eax, TRUE

.finish:
        pop     esi
        return
endp



proc TDataGrid.__SetRowColSize, .ptrGrid, .ptrSizes, .Count, .x, .NewSize
begin
        push    edi
        mov     edi, [.ptrGrid]
        mov     eax, [.ptrSizes]
        mov     ecx, [.x]

        lea     eax, [eax+4*ecx+4]

        mov     edx, [.NewSize]
        sub     ecx, [.Count]
        jge     .finish         ; error, the index is greater than count.

        sub     edx, [eax]
        neg     ecx
        add     edx, [eax-4]

.loop:
        add     [eax], edx
        lea     eax, [eax+4]
        loop    .loop

        stdcall TDataGrid.__AdjustScrollbars, edi

.finish:
        pop     edi
        return
endp









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted include/libs/TDataGrid.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
struct TDataGrid
  .hwnd      dd  ?      ; handle to the instance window.

; properties
  .ColCount  dd ?
  .RowCount  dd ?
  .ColWidth  dd ?       ; default column width - every column can have different width though.
  .RowHeight dd ?       ; default row height - every row can have diferent height.

  .FixedCols dd ?       ; count of the fixed columns [0..FixedCols-1]
  .FixedRows dd ?       ; count of the fixed rows [0..FixedRows-1]
  .Flags     dd ?       ; grid flags ( dgf* flags)

  .ptrGridData dd ?     ; one pointer for the user.

; Color of the grid elements.
  .clCell         dd ?          ; normal data cell background
  .clFixed        dd ?          ; fixed cell background
  .clSelected     dd ?          ; selected cell background
  .clMarked       dd ?          ; background for the cells that are selected in the moment.
  .clTextCell     dd ?          ; normal cell text color
  .clTextFixed    dd ?          ; fixed cell text color
  .clTextSelected dd ?          ; selected cell text color

  .focused   POINT      ; coordinates of the focused cell.
  .hSelected dd ?       ; handle to region containing selected cells.

; These 2 arrays contains respectively ColCount+1 and RowCount+1 elements.
  .ptrColX dd ?     ; pointer to array of dwords with X coordinates of the columns.
  .ptrRowY dd ?     ; pointer to array of dwords with Y coordinates of the rows.

; back buffer data - allows flicker free drawing of the grid.
  .hShadowDC dd ?
  .hShadow   dd ?
  .fShadowReady dd ?    ; flag that shows whether the shadow need repaint.

  .selection RECT       ; rectangle with current selection.
  .selflags  dd ?       ; 1 - column selection

; Callback functions
  .OnGetPopupMenu dd ? ; proc GetPopupMenu, .ptrGrid, .Col, .Row
  .OnDrawItem dd ?     ; proc DrawItem, .hdc, .ptrRect, .Col, .Row, .ptrData, .fSelected, .fFixed
  .OnGetString  dd ?   ; proc GetData, .Col, .Row, .ptrData, .flags, .fFixed
ends

dgfGridlines = 1
dgfGridLinesFixed = 2


winmessage DGM_SETPARAM     ; (offset, value):nothing
winmessage DGM_GETPARAM     ; (offset, nothing):value

htwXFixed = 1
htwXData  = 2
htwXBoth  = 3

htwYFixed = 1
htwYData  = 2
htwYBoth  = 3
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































Deleted include/libs/application.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
uglobal
  hApplication dd 0     ; Only one application window can exists.
endg

iglobal
  cApplicationClassName text 'TApplication'
  property propMainForm,'MainForm'
  property propOnIdle, 'OnIdle'
  property propAccelerators, 'Accelerators'
endg

;initialize CreateAppPropertyes
;begin
;        stdcall CreateProperty, propMainForm
;        stdcall CreateProperty, propOnIdle
;        stdcall CreateProperty, propAccelerators
;        return
;endp
;
;
;finalize DeleteAppProperties
;begin
;        stdcall DestroyProperty, propMainForm
;        stdcall DestroyProperty, propOnIdle
;        stdcall DestroyProperty, propAccelerators
;        return
;endp
;

initialize RegisterApplicationClass
.wc WNDCLASS
begin
        xor     eax, eax
        lea     edi, [.wc]
        mov     ecx, sizeof.WNDCLASS / 4
        rep stosd

        mov     [.wc.style], CS_OWNDC
        mov     [.wc.lpfnWndProc], ApplicationWinProc
        mov     eax,[hInstance]
        mov     [.wc.hInstance],eax
        mov     [.wc.lpszClassName], cApplicationClassName

        sub     edi, sizeof.WNDCLASS
        invoke  RegisterClassA, edi
        return
endp


proc InitApplication, .idIcon, .ptrCaption
begin
        xor     eax, eax
        invoke  CreateWindowExA, 0, cApplicationClassName, [.ptrCaption],               \
                                WS_SYSMENU or WS_CAPTION or WS_POPUPWINDOW or         \
                                WS_VISIBLE or WS_CLIPSIBLINGS or WS_MINIMIZEBOX,      \
                                eax, eax, eax, eax,                                   \
                                eax, eax, [hInstance], eax
        mov     [hApplication], eax

        cmp     [.idIcon], 0
        je      .finish

        invoke  LoadImageA, [hInstance], [.idIcon], IMAGE_ICON, 16, 16, 0
        invoke  SendMessageA, [hApplication], WM_SETICON, ICON_SMALL, eax
        invoke  LoadImageA, [hInstance], [.idIcon], IMAGE_ICON, 32, 32, 0
        invoke  SendMessageA, [hApplication], WM_SETICON, ICON_BIG, eax

.finish:
        return
endp



winproc ApplicationWinProc
.rect   RECT
.str    rb 1024
begin
        push    esi edi ebx
        mov     ebx, [.wmsg]

ondefault
        invoke  DefWindowProcA, [.hwnd], [.wmsg], [.wparam], [.lparam]
        jmp     .finish

;-------------------------------------------------------------------------
onmessage WM_ENABLE
        stdcall EnableAllOwnedWindows, [.hwnd], [.wparam]
        jmp     .ondefault

;;-------------------------------------------------
;.setfocus:
;        invoke  SetFocus, [hLastActive]
;        xor     eax, eax
;        jmp     .finish

;-------------------------------------------------------------------------
onmessage WM_CREATE
; hide window.
        invoke  GetSystemMetrics, SM_CXSCREEN
        mov     ebx, eax
        invoke  GetSystemMetrics, SM_CYSCREEN
        shr     ebx, 3
        shr     eax, 3

        xor     ecx,ecx
        invoke  SetWindowPos, [.hwnd], ecx, ebx, eax, ecx, ecx, SWP_NOZORDER or SWP_SHOWWINDOW
        jmp     .qfalse

;-------------------------------------------------------------------------
onmessage WM_NCDESTROY
        invoke  GetPropA, [.hwnd], [propAccelerators]
        test    eax, eax
        jz      .accelok

        invoke  DestroyAcceleratorTable, eax

.accelok:
        invoke  SendMessageA, [.hwnd], WM_GETICON, ICON_SMALL, 0
        invoke  DestroyIcon, eax
        invoke  SendMessageA, [.hwnd], WM_GETICON, ICON_BIG, 0
        invoke  DestroyIcon, eax

        invoke  PostQuitMessage, 0
        jmp     .ondefault

;-------------------------------------------------------------------------
onmessage AM_TRANSACCEL
        invoke  GetPropA, [.hwnd], [propAccelerators]
        test    eax, eax
        jz      .qfalse ; false - no accelerators table.
        mov     ebx, eax

        invoke  GetPropA, [.hwnd], [propMainForm]
        test    eax, eax
        jz      .qfalse ; false - no main form.
        mov     esi, eax

        invoke  IsWindowEnabled, esi
        test    eax, eax
        jz      .qfalse  ; false - the main form is disabled

        invoke  TranslateAccelerator, esi, ebx, [.wparam]    ; Accelerators handling.
        jmp     .finish

;-------------------------------------------------------------------------
onmessage AM_ONIDLE
        invoke  GetPropA, [.hwnd], [propOnIdle]
        test    eax, eax
        jz      .qfalse

        call    dword eax

;------------------------------------------

.qtrue:
        xor     eax, eax
        inc     eax
        jmp     .finish

.qfalse:
        xor     eax,eax

.finish:
        pop     ebx edi esi
        return

endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































Deleted include/libs/application.inc.

1
2
3
4
5
AppLib = 1

AM_FIRST = WM_USER + $1500
AM_TRANSACCEL = AM_FIRST + 1    ; wparam - ptr to MSG structure.
AM_ONIDLE     = AM_FIRST + 2    ; no parameters.
<
<
<
<
<










Deleted include/libs/asmedit/asmedit.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
;-------------------------------------------
; Assembly Editor for Win32
; Copyright (c) 2001-2002, Tomasz Grysztar.
; All rights reserved.
;-------------------------------------------

iglobal
  cAsmEditClassName   text  'ASMEDIT'
  wheel_scroll_lines      dd  3             ; this is the number of lines to scroll with mouse wheel.
endg


uglobal
  case_table   rb 100h
endg

;-------------------------------------------
; Registers AsmEdit control class.
; Call only once in application.
;-------------------------------------------
initialize RegisterAsmEditClass

.ae WNDCLASS

begin
        mov     [.ae.style], CS_GLOBALCLASS + CS_DBLCLKS
        mov     [.ae.lpfnWndProc], AsmEdit
        mov     eax,[hInstance]
        mov     [.ae.hInstance],eax
        mov     [.ae.hbrBackground],0
        xor     eax,eax
        mov     [.ae.cbClsExtra],eax
        mov     [.ae.cbWndExtra], $10
        mov     [.ae.lpszMenuName],eax
        mov     [.ae.lpszClassName], cAsmEditClassName
        mov     [.ae.hIcon], eax
        mov     [.ae.hCursor],0         ; If Window procedure handles WM_SETCURSOR, this should be NULL
        lea     eax, [.ae]
        invoke  RegisterClassA, eax
        or      eax,eax
        jz      .failed

        push    ebx esi edi

        mov     edi,case_table
        xor     ebx,ebx
        mov     esi,100h

    .make_case_table:
        invoke  CharLowerA,ebx
        stosb
        inc     bl
        dec     esi
        jnz     .make_case_table

        pop     edi esi ebx

        xor     eax,eax
        jmp     .finish

.failed:
        mov     eax,1
.finish:
        return
endp


;----------------------------------------------
; AsmEdit window proc
;----------------------------------------------
proc AsmEdit, .hwnd, .wmsg, .wparam, .lparam

  .editor_memory dd ?
  .editor_style dd ?

  .editor_data:

  .first_line dd ?
  .lines_count dd ?
  .caret_line dd ?
  .caret_position dd ?
  .caret_line_number dd ?
  .window_line dd ?
  .window_position dd ?
  .window_line_number dd ?
  .sel_line dd ?
  .sel_position dd ?
  .sel_line_number dd ?
  .editor_mode dd ?
  .line_to_draw dd ?
  .Modified  dd ?

  .editor_status_size = $ - .editor_data

  .editor_font dd ?
  .font_width dd ?
  .font_height dd ?
  .page_size dd ?
  .editor_screen dd ?
  .screen_width dd ?
  .screen_height dd ?
  .background_color dd ?
  .text_color dd ?
  .selection_background dd ?
  .selection_text dd ?
  .margin_background dd ?
  .margin_border dd ?
  .margin_width dd ?
  .margin_gap dd ?
  .focus_fg dd ?
  .focus_bg dd ?
  .syntax_proc dd ?
  .syntax_colors dd ?
  .unallocated_lines dd ?
  .unallocated_lines_end dd ?
  .memory_search_block dd ?
  .memory_search_line dd ?
  .undo_data dd ?
  .search_text dd ?
  .caret_x dd ?
  .caret_y dd ?
  .PopupMenu dd ?
  .read_only dd ?
  .focus_line dd ?

  .bookmark_count = 10
  .bookmarks rd .bookmark_count
  .bookmark_icon dd ?

  .current_operation db ?
  .last_operation db ?
  .mouse_select db ?
  .focus db ?

  .editor_data_size = $ - .editor_data

  .current_line dd ?
  .return_value dd ?
  .background_brush dd ?
  .selection_brush dd ?
  .margin_brush dd ?
  .marginb_brush dd ?
  .bookmark_brush dd ?
  .was_selection db ?
  .line_selection db ?
  .redraw_now db ?
  .notification db ?

; moved from global to local - 12.08.2003 johnfound
  .sc   SCROLLINFO
  .ps   PAINTSTRUCT
  .tm   TEXTMETRIC
  .rect RECT
  .rc   RECT
  .pt   POINT

  .char         rb 4
  .kbstate      rb 100h

  .line_colors  rb 100h
  .line_buffer  rb 100h
  .text_buffer  rb 100h
  .param_buffer rd 10h


begin
        push    ebx esi edi

        invoke  GetWindowLongA, [.hwnd], GWL_STYLE
        mov     [.editor_style],eax
        cmp     [.wmsg], WM_CREATE
        je      .wmcreate
        cmp     [.wmsg], WM_GETDLGCODE
        je      .wmgetdlgcode
        invoke  GetWindowLongA, [.hwnd], ofsAsmEditMemory
        or      eax,eax
        jz      .defwndproc
        mov     [.editor_memory],eax
        lea     esi,[eax+8]
        lea     edi,[.editor_data]
        mov     ecx,.editor_data_size shr 2
        rep     movsd
        mov     [.return_value],0
        mov     [.notification],0
        mov     [.redraw_now],0
        cmp     [.wmsg],WM_DESTROY
        je      .wmdestroy
        cmp     [.wmsg],WM_PAINT
        je      .wmpaint
        invoke  HideCaret,[.hwnd]
        cmp     [.wmsg],WM_HSCROLL
        je      .wmhscroll
        cmp     [.wmsg],WM_VSCROLL
        je      .wmvscroll
        cmp     [.wmsg],WM_SIZE
        je      .wmsize
        cmp     [.sel_line],0
        setnz   al
        mov     [.was_selection],al
        xor     al,al
        xchg    [.current_operation],al
        mov     [.last_operation],al
        mov     eax,[.wmsg]
        cmp     eax,WM_SETFOCUS
        je      .wmsetfocus
        cmp     eax,WM_KILLFOCUS
        je      .wmkillfocus
        cmp     eax,WM_LBUTTONDOWN
        je      .wmlbuttondown
        cmp     eax,WM_LBUTTONUP
        je      .wmlbuttonup
        cmp     eax,WM_RBUTTONDOWN
        je      .wmrbuttondown
        cmp     eax,WM_RBUTTONUP
        je      .wmrbuttonup
        cmp     eax,WM_MOUSEMOVE
        je      .wmmousemove
        cmp     eax,WM_LBUTTONDBLCLK
        je      .wmlbuttondblclk
        cmp     eax,WM_MOUSEWHEEL
        je      .wmmousewheel
        cmp     eax,WM_COPY
        je      .wmcopy

        cmp     eax,WM_SYSKEYDOWN
        je      .wmsyskeydown
        cmp     eax,WM_KEYDOWN
        je      .wmkeydown
        cmp     [.read_only],0
        jne     .dont_process               ; Added Tommy Lillehagen 31.01.2004
        cmp     eax,WM_CHAR
        je      .wmchar
        cmp     eax,WM_CUT
        je      .wmcut
        cmp     eax,WM_PASTE
        je      .wmpaste
        cmp     eax,WM_CLEAR
        je      .wmclear
        cmp     eax,WM_SETTEXT
        je      .wmsettext
        cmp     eax,WM_UNDO
        je      .wmundo
        cmp     eax,EM_UNDO
        je      .wmundo
        cmp     eax,EM_REPLACESEL
        je      .emreplacesel
        cmp     eax,AEM_COMMENT
        je      .aemcomment
        cmp     eax,AEM_INDENT
        je      .aemindent
    .dont_process:

        cmp     eax,WM_GETTEXTLENGTH
        je      .wmgettextlength
        cmp     eax,WM_GETTEXT
        je      .wmgettext
        cmp     eax,WM_SETFONT
        je      .wmsetfont
        cmp     eax,WM_GETFONT
        je      .wmgetfont
        cmp     eax,WM_CONTEXTMENU
        je      .wmrbuttonup
        cmp     eax,EM_CANUNDO
        je      .emcanundo
        cmp     eax,EM_EMPTYUNDOBUFFER
        je      .ememptyundobuffer
        cmp     eax,AEM_SETMODE
        je      .aemsetmode
        cmp     eax,AEM_GETMODE
        je      .aemgetmode
        cmp     eax, AEM_GETMODIFIED            ; John Found 25.11.2003
        je      .aemgetmodified
        cmp     eax, AEM_SETMODIFIED
        je      .aemsetmodified
        cmp     eax,AEM_SETSYNTAXHIGHLIGHT
        je      .aemsetsyntaxhighlight
        cmp     eax, AEM_GETLINEPTR
        je      .aemgetlineptr
        cmp     eax,AEM_GETLINEDATA
        je      .aemgetlinedata
        cmp     eax, AEM_SETLINEDATA
        je      .aemsetlinedata
        cmp     eax,AEM_SETPOS
        je      .aemsetpos
        cmp     eax,AEM_GETPOS
        je      .aemgetpos
        cmp     eax, AEM_GETCARETXY     ; Added john found 06.01.2004
        je      .amgetcaretxy
        cmp     eax,AEM_FINDFIRST
        je      .aemfindfirst
        cmp     eax,AEM_FINDNEXT
        je      .aemfindnext
        cmp     eax,AEM_CANFINDNEXT
        je      .aemcanfindnext
        cmp     eax,AEM_GETWORDATCARET
        je      .aemgetwordatcaret
        cmp     eax,AEM_SETTEXTCOLOR
        je      .aemsettextcolor
        cmp     eax,AEM_SETSELCOLOR
        je      .aemsetselcolor
        cmp     eax,AEM_SETPOPUPMENU
        je      .aemsetpopupmenu
        cmp     eax,AEM_SETMARGINCOLOR
        je      .aemsetmargincolor
        cmp     eax,AEM_SETMARGINWIDTH
        je      .aemsetmarginwidth
        cmp     eax,AEM_SETTHEME
        je      .aemsettheme
        cmp     eax,AEM_TOGGLEBOOKMARK
        je      .aemtogglebookmark
        cmp     eax,AEM_GOTOBOOKMARK
        je      .aemgotobookmark
        cmp     eax,AEM_CLEARBOOKMARKS
        je      .aemclearbookmarks
        cmp     eax,AEM_SETBOOKMARKICON
        je      .aemsetbookmarkicon
        cmp     eax,AEM_READONLY                ; Added Tommy Lillehagen 30.01.2004
        je      .aemreadonly
        cmp     eax,AEM_SETFOCUSLINE            ; Added Tommy Lillehagen 30.01.2004
        je      .aemsetfocusline

        invoke  ShowCaret,[.hwnd]

.defwndproc:
        invoke  DefWindowProcA,[.hwnd],[.wmsg],[.wparam],[.lparam]
        jmp     .finish

.wmcreate:
        call    .init_editor_memory
        jc      .create_failed
        call    .init_editor_data
        invoke  SetWindowLongA, [.hwnd], ofsAsmEditMemory, [.editor_memory]
        invoke  GetSysColor,COLOR_WINDOW
        mov     [.background_color],eax
        mov     [.margin_background],eax
        mov     [.margin_border],eax
        invoke  GetSysColor,COLOR_WINDOWTEXT
        mov     [.text_color],eax
        invoke  GetSysColor,COLOR_HIGHLIGHT
        mov     [.selection_background],eax
        mov     [.focus_bg],eax
        invoke  GetSysColor,COLOR_HIGHLIGHTTEXT
        mov     [.selection_text],eax
        mov     [.focus_fg],eax

        invoke  GetStockObject, SYSTEM_FIXED_FONT
        mov     [.editor_font], eax

        invoke  GetDC,[.hwnd]
        mov     ebx,eax
        invoke  SelectObject,ebx,[.editor_font]

        lea     eax, [.tm]
        invoke  GetTextMetricsA,ebx,eax

        mov     eax,[.tm.tmHeight]
        test    eax, eax
        jnz     @f
        inc     eax
@@:
        mov     [.font_height],eax
        mov     eax,[.tm.tmAveCharWidth]
        test    eax, eax
        jnz     @f
        inc     eax
@@:
        mov     [.font_width],eax
        invoke  ReleaseDC,[.hwnd],ebx
        call    .update_positions
        call    .update_screen

        mov     [.PopupMenu], NULL
        mov     [.Modified], FALSE
        mov     [.bookmark_icon], NULL

        call    .clear_marks

        mov     [.margin_width],1
        mov     [.margin_gap],0
        mov     [.return_value],0
        mov     [.read_only],0
        mov     [.focus_line],0
        jmp     .done

    .create_failed:
        or      eax,-1
        jmp     .finish


;----------- WM_DESTROY --------------------

.wmdestroy:
        invoke  GlobalFree,[.editor_screen]
        call    .release_editor_memory
        invoke  SetWindowLongA,[.hwnd], ofsAsmEditMemory, 0
        xor     eax,eax
        jmp     .finish

.wmgetdlgcode:
        mov     eax, DLGC_WANTCHARS or DLGC_WANTARROWS or DLGC_WANTTAB
        mov     ecx, [.lparam]
        test    ecx, ecx
        jz      .finish

        cmp     [ecx+MSG.message], WM_KEYDOWN
        jne     .finish

        cmp     [ecx+MSG.wParam], VK_RETURN
        jne     .finish

        or      eax, DLGC_WANTMESSAGE
        jmp     .finish

.wmpaint:
        lea     eax,[.rect]
        invoke  GetUpdateRect,[.hwnd],eax,FALSE
        or      eax,eax
        jz      .finish
        cmp     [.editor_screen],0
        je      .finish
        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
        call    .paint_marks
        invoke  SelectObject,ebx,[.editor_font]
        mov     esi,[.editor_screen]
        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]
        mov     eax,[.window_line_number]
        dec     eax
        mov     [.line_to_draw],eax
    .paint_screen:
        push    ecx
        inc     [.line_to_draw]
        mov     eax,[.margin_width]
        mov     [.rect.left],eax
        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
        mov     eax,[.focus_line]
        cmp     [.line_to_draw],eax
        je      .focusline_color
        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]
        jmp     .color_ok
    .focusline_color:
        invoke  SetBkColor,ebx,[.focus_bg]
        invoke  SetTextColor,ebx,[.focus_fg]
    .color_ok:
        mov     ecx,[esp]
        mov     eax,[.font_width]
        mul     ecx
        add     eax,[.rect.left]
        mov     [.rect.right],eax
        lea     eax, [.rect]
        invoke  DrawTextA,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

    .paint_bookmarks:
        pushad
        invoke  GetDC,[.hwnd]
        mov     ebx,eax
        invoke  CreateSolidBrush,[.background_color]
        mov     [.background_brush],eax
        lea     eax,[.rect]
        invoke  GetClientRect,[.hwnd],eax
        call    .paint_marks
        invoke  DeleteObject,[.background_brush]
        invoke  ReleaseDC,[.hwnd],ebx
        popad
        ret
    .paint_marks:
        push    [.rect.left] [.rect.right]
        cmp     [.margin_gap],0
        je      .fill_margin
        mov     eax,[.margin_width]
        sub     eax,[.margin_gap]
        mov     [.rect.right],eax
        invoke  CreateSolidBrush,[.margin_background]
        mov     [.margin_brush],eax
        lea     eax,[.rect]
        invoke  FillRect,ebx,eax,[.margin_brush]
        mov     eax,[.rect.right]
        mov     [.rect.left],eax
        invoke  DeleteObject,[.margin_brush]
        add     [.rect.right],1
        invoke  CreateSolidBrush,[.margin_border]
        mov     [.marginb_brush],eax
        lea     eax,[.rect]
        invoke  FillRect,ebx,eax,[.marginb_brush]
        mov     eax,[.rect.right]
        mov     [.rect.left],eax
        invoke  DeleteObject,[.marginb_brush]
        mov     eax,[.margin_gap]
        dec     eax
        add     [.rect.right],eax
      .fill_margin:
        lea     eax,[.rect]
        invoke  FillRect,ebx,eax,[.background_brush]
        pop     [.rect.right] [.rect.left]
        xor     eax,eax
        mov     [.rc.left],eax
        mov     eax,[.margin_width]
        sub     eax,[.margin_gap]
        mov     [.rc.right],eax
        cmp     [.margin_width],1
        jle     .no_marks
        mov     ecx,.bookmark_count
      .paint_next_mark:
        push    ecx
        mov     eax,4
        mul     ecx
        lea     edx,[.bookmarks-4]
        add     eax,edx
        cmp     dword [eax],0
        je      .paint_next_item
        mov     edx,dword [eax]
        mov     eax,edx
        sub     eax,[.window_line_number]
        inc     eax
        call    .mark_line
      .paint_next_item:
        pop     ecx
        loop    .paint_next_mark
      .no_marks:
        ret
      .mark_line:
        mov     ecx,[.font_height]
        mul     ecx
        sub     eax,[.font_height]
        mov     [.rc.top],eax
        mov     [.rc.left],1
        cmp     [.bookmark_icon],0
        je      .no_marks
        invoke  DrawIconEx,ebx,[.rc.left],[.rc.top],[.bookmark_icon],14,14,0,0,DI_NORMAL
        ret
.wmsetfocus:
        or      [.focus],-1
        call    .create_caret
        mov     [.notification],AEN_SETFOCUS
        cmp     [.was_selection],0
        je      .done
        jmp     .moved_window
.wmkillfocus:
        mov     [.focus],0
        invoke  DestroyCaret
        mov     [.notification],AEN_KILLFOCUS
        cmp     [.was_selection],0
        je      .done
        jmp     .moved_window
.wmhscroll:
        mov     [.sc.cbSize],sizeof.SCROLLINFO
        mov     [.sc.fMask],SIF_PAGE
        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,100h
        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,100h
        sub     ecx,eax
        add     [.window_position],eax
        cmp     [.window_position],ecx
        jbe     .moved_window
        mov     [.window_position],ecx
        jmp     .moved_window
.wmvscroll:
        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]
        mov     esi,[esi]
        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]
    .scroll_up:
        mov     eax,[esi+4]
        or      eax,eax
        jz      .scroll_ok
        dec     [.window_line_number]
        mov     esi,eax
        loop    .scroll_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     .scroll_down
        mov     ecx,[.sc.nPage]
    .scroll_down:
        mov     eax,[esi]
        or      eax,eax
        jz      .scroll_ok
        inc     [.window_line_number]
        mov     esi,eax
        loop    .scroll_down
    .scroll_ok:
        mov     [.window_line],esi
        jmp     .moved_window

.wmmousewheel:
        mov     esi,[.window_line]
        mov     eax,[.wparam]
        sar     eax,16
        cdq
        mov     ecx,120
        idiv    ecx
        imul    eax,[wheel_scroll_lines]
        mov     ecx,eax
        cmp     ecx,0
        jg      .scroll_up
        neg     ecx
        jnz     .scroll_down
        jmp     .done


;---------- WM_SIZE -------------------------------

.wmsize:
        cmp     [.editor_screen], 0
        je      @f
        invoke  GlobalFree,[.editor_screen]     ; sometimes [.editor_screen] is NULL here.
@@:
        call    .update_positions
        call    .update_screen
        lea     esi, [.rect]
        invoke  GetClientRect,[.hwnd],esi
        invoke  InvalidateRect,[.hwnd],esi,FALSE
        jmp     .done

;----------- WM_KEYDOWN ---------------------------

.wmkeydown:
        lea     eax, [.kbstate]
        invoke  GetKeyboardState, eax
        cmp     [.was_selection],0
        jne     .process_key

        mov     eax,[.caret_line]
        mov     [.sel_line],eax
        mov     eax,[.caret_position]
        mov     [.sel_position],eax
        mov     eax,[.caret_line_number]
        mov     [.sel_line_number],eax

    .process_key:
        mov     eax,[.wparam]
        cmp     eax,VK_LEFT
        je      .left
        cmp     eax,VK_RIGHT
        je      .right
        cmp     eax,VK_UP
        je      .up
        cmp     eax,VK_DOWN
        je      .down
        cmp     eax,VK_HOME
        je      .line_home
        cmp     eax,VK_END
        je      .line_end
        cmp     eax,VK_PGUP
        je      .pgup
        cmp     eax,VK_PGDN
        je      .pgdn

        cmp     [.read_only],0       ; read only => only navigation keys
        jne     .ignore

        cmp     eax,VK_BACK
        je      .back
        cmp     eax,VK_DELETE
        je      .del
        cmp     eax,VK_INSERT
        je      .insert
        cmp     eax,VK_F6
        je      .duplicate_line
        test    [.kbstate+VK_CONTROL],80h
        jz      .convert_to_ascii
        cmp     eax,'Y'
        je      .remove_line


    .convert_to_ascii:
        mov     ax,word [.lparam+2]
        and     eax,7Fh

        lea     ecx, [.kbstate]
        lea     edx, [.char]
        invoke  ToAscii, [.wparam], eax, ecx, edx, FALSE

        or      eax,eax
        jz      .ignore
        mov     al,[.char]
        cmp     al,20h
        jae     .put_char
        cmp     al,0Dh
        je      .put_char
        cmp     al,9
        je      .put_char
        jmp     .ignore
  .left:
        test    [.kbstate+VK_CONTROL],80h
        jnz     .word_left
        cmp     [.caret_position],0
        je      .ignore
        dec     [.caret_position]
        jmp     .moved_caret
  .right:
        test    [.kbstate+VK_CONTROL],80h
        jnz     .word_right
        cmp     [.caret_position],100h
        je      .ignore
        inc     [.caret_position]
        jmp     .moved_caret
  .up:
        mov     esi,[.caret_line]
        mov     eax,[esi+4]
        or      eax,eax
        jz      .ignore
        mov     [.caret_line],eax
        dec     [.caret_line_number]
        jmp     .moved_caret
  .down:
        mov     esi,[.caret_line]
        mov     eax,[esi]
        or      eax,eax
        jz      .ignore
        mov     [.caret_line],eax
        inc     [.caret_line_number]
        jmp     .moved_caret
  .line_home:
        test    [.kbstate+VK_CONTROL],80h
        jnz     .screen_home
        mov     [.caret_position],0
        jmp     .moved_caret
  .line_end:
        test    [.kbstate+VK_CONTROL],80h
        jnz     .screen_end
    .find_line_end:
        mov     edi,[.caret_line]
        add     edi,108h-1
        mov     al,20h
        mov     ecx,100h
        std
        repe    scasb
        setne   al
        movzx   eax,al
        add     ecx,eax
        cld
        mov     [.caret_position],ecx
        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,[.page_size]
        dec     eax
        call    .find_line
        mov     [.caret_line],esi
        mov     [.caret_line_number],ecx
        jmp     .moved_caret
  .pgup:
        test    [.kbstate+VK_CONTROL],80h
        jnz     .text_home
        mov     eax,[.caret_line_number]
        mov     eax,[.caret_line_number]
        sub     eax,[.page_size]
        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,[.page_size]
        ja      .pgup_window_ok
        mov     eax,1
        cmp     [.window_line_number],eax
        je      .moved_caret
    .pgup_window_ok:
        call    .find_line
        mov     [.window_line],esi
        mov     [.window_line_number],ecx
        jmp     .moved_caret
  .pgdn:
        test    [.kbstate+VK_CONTROL],80h
        jnz     .text_end
        mov     eax,[.caret_line_number]
        mov     eax,[.caret_line_number]
        add     eax,[.page_size]
        call    .find_line
        mov     [.caret_line],esi
        mov     [.caret_line_number],ecx
        mov     eax,[.window_line_number]
        mov     ecx,[.page_size]
        add     eax,ecx
        mov     ebx,[.lines_count]
        sub     ebx,ecx
        jbe     .moved_caret
        inc     ebx
        cmp     eax,ebx
        jb      .pgdn_window_ok
        mov     eax,ebx
        cmp     [.window_line_number],eax
        je      .moved_caret
    .pgdn_window_ok:
        call    .find_line
        mov     [.window_line],esi
        mov     [.window_line_number],ecx
        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:
        mov     ecx,[.caret_position]
        mov     esi,[.caret_line]
        add     esi,8
    .find_left_word:
        sub     ecx,1
        jc      .word_line_up
        mov     al,[esi+ecx]
        call    .recognize_character
        jnc     .find_word_start
        jmp     .find_left_word
    .word_line_up:
        sub     esi,8
        mov     eax,[esi+4]
        or      eax,eax
        jz      .word_left_ok
        mov     [.caret_line],eax
        dec     [.caret_line_number]
        lea     esi,[eax+8]
        mov     ecx,100h
        jmp     .find_left_word
    .find_word_start:
        sub     ecx,1
        jc      .word_left_ok
        mov     al,[esi+ecx]
        call    .recognize_character
        jc      .word_left_ok
        jmp     .find_word_start
    .word_left_ok:
        inc     ecx
        mov     [.caret_position],ecx
        jmp     .moved_caret
  .word_right:
        mov     ecx,[.caret_position]
        mov     esi,[.caret_line]
        add     esi,8
        cmp     ecx,100h
        je      .word_line_down
    .find_word_end:
        add     ecx,1
        jc      .word_line_down
        mov     al,[esi+ecx]
        call    .recognize_character
        jc      .find_right_word
        jmp     .find_word_end
    .find_right_word:
        add     cl,1
        jc      .word_line_down
    .check_right_word:
        mov     al,[esi+ecx]
        call    .recognize_character
        jnc     .word_right_ok
        jmp     .find_right_word
    .word_line_down:
        mov     eax,[esi-8]
        or      eax,eax
        jz      .find_line_end
        mov     [.caret_line],eax
        inc     [.caret_line_number]
        lea     esi,[eax+8]
        xor     ecx,ecx
        jmp     .check_right_word
    .word_right_ok:
        mov     [.caret_position],ecx
        jmp     .moved_caret
  .insert:
        test    [.kbstate+VK_MENU],80h
        jnz     .switch_blocks
        test    [.kbstate+VK_CONTROL],80h
        jnz     .wmcopy
        test    [.kbstate+VK_SHIFT],80h
        jnz     .wmpaste
        xor     [.editor_mode],AEMODE_OVERWRITE
        mov     [.notification],AEN_MODECHANGE
        call    .create_caret
        cmp     [.was_selection],1
        je      .done
        mov     [.sel_line],0
        jmp     .done
  .del:
        test    [.kbstate+VK_CONTROL],80h
        jnz     .wmclear
        test    [.kbstate+VK_SHIFT],80h
        jnz     .wmcut
        cmp     [.was_selection],0
        je      .no_selection
        test    [.editor_style],AES_SECURESEL
        jz      .wmclear
    .no_selection:
        mov     edi,[.caret_line]
        mov     [.current_line],edi
        test    [.editor_mode],AEMODE_OVERWRITE
        jnz     .delete_char
        add     edi,108h-1
        mov     al,20h
        mov     ecx,100h
        std
        repe    scasb
        setne   al
        movzx   eax,al
        add     ecx,eax
        cld
        mov     edx,[.caret_position]
        cmp     edx,ecx
        jb      .delete_char
        mov     ecx,100h
        sub     ecx,edx
        mov     edi,[.caret_line]
        mov     esi,[edi]
        or      esi,esi
        jz      .ignore
        call    .store_status_for_undo
        call    .store_line_for_undo
        mov     [.current_line],esi
        call    .store_line_for_undo
        mov     ebx,[esi]
        mov     [edi],ebx
        or      ebx,ebx
        jz      .append_line
        mov     [.current_line],ebx
        call    .store_line_for_undo
        mov     [ebx+4],edi
    .append_line:
        or      dword [esi],-1
        dec     [.lines_count]
        lea     edi,[edi+8+edx]
        add     esi,8
        rep     movsb
        mov     [.sel_line],0
        jmp     .text_modified
    .delete_char:
        mov     [.current_operation],VK_DELETE
        cmp     [.last_operation],VK_DELETE
        je      .undo_delete_ok
        call    .store_status_for_undo
        call    .store_line_for_undo
    .undo_delete_ok:
        call    .delete_character
        mov     [.sel_line],0
        jmp     .text_modified
  .back:
        cmp     [.was_selection],0
        je      .no_selection_to_clear
        test    [.editor_style],AES_SECURESEL
        jz      .wmclear
    .no_selection_to_clear:
        mov     eax,[.caret_line]
        mov     [.current_line],eax
        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
        je      .undo_back_ok
        call    .store_status_for_undo
        call    .store_line_for_undo
    .undo_back_ok:
        dec     [.caret_position]
        call    .delete_character
        mov     [.sel_line],0
        jmp     .text_modified
    .word_back:
        call    .store_status_for_undo
        call    .store_line_for_undo
        mov     ecx,[.caret_position]
        mov     esi,[.caret_line]
        add     esi,8
    .skip_spaces:
        sub     ecx,1
        jc      .delete_word
        mov     al,[esi+ecx]
        cmp     al,20h
        je      .skip_spaces
        call    .recognize_character
        jnc     .find_word_to_delete_start
    .find_word_to_delete_end:
        sub     ecx,1
        jc      .delete_word
        mov     al,[esi+ecx]
        call    .recognize_character
        jnc     .delete_word
        jmp     .find_word_to_delete_end
    .find_word_to_delete_start:
        sub     ecx,1
        jc      .delete_word
        mov     al,[esi+ecx]
        call    .recognize_character
        jc      .delete_word
        jmp     .find_word_to_delete_start
    .delete_word:
        inc     ecx
        mov     eax,ecx
        lea     edi,[esi+eax]
        xchg    eax,[.caret_position]
        lea     esi,[esi+eax]
        mov     ecx,100h
        sub     ecx,eax
        rep     movsb
        mov     ecx,[.caret_line]
        add     ecx,108h
        sub     ecx,edi
        mov     al,20h
        rep     stosb
        jmp     .text_modified
    .line_back:
        test    [.editor_mode],AEMODE_OVERWRITE
        jnz     .ignore
        mov     esi,[.caret_line]
        mov     edi,[esi+4]
        or      edi,edi
        jz      .ignore
        call    .store_status_for_undo
        call    .store_line_for_undo
        mov     [.caret_line],edi
        dec     [.caret_line_number]
        mov     [.current_line],edi
        call    .store_line_for_undo
        mov     eax,[esi]
        mov     [edi],eax
        or      dword [esi],-1
        dec     [.lines_count]
        or      eax,eax
        jz      .line_removed
        mov     [.current_line],eax
        call    .store_line_for_undo
        mov     [eax+4],edi
    .line_removed:
        add     edi,108h-1
        mov     al,20h
        mov     ecx,100h
        std
        repe    scasb
        setne   al
        movzx   eax,al
        add     ecx,eax
        add     edi,eax
        cld
        inc     edi
        mov     [.caret_position],ecx
        sub     ecx,100h
        neg     ecx
        add     esi,8
        rep     movsb
        mov     [.sel_line],0
        jmp     .text_modified
  .put_char:
        mov     ebx,[.caret_line]
        mov     [.current_line],ebx
        cmp     al,0Dh
        je      .new_line
        cmp     al,9
        je      .tab
        cmp     [.was_selection],0
        je      .no_selection_to_replace
        call    .store_status_for_undo
        test    [.editor_style],AES_SECURESEL
        jnz     .put_new_char
        push    eax
        call    .delete_block
        pop     eax
        call    .insert_character
        jmp     .text_modified
    .no_selection_to_replace:
        mov     [.current_operation],VK_SPACE
        cmp     [.last_operation],VK_SPACE
        je      .undo_put_ok
        call    .store_status_for_undo
    .put_new_char:
        call    .store_line_for_undo
    .undo_put_ok:
        call    .insert_character
        mov     [.sel_line],0
        jmp     .text_modified
  .tab:
        call    .store_status_for_undo
        cmp     [.was_selection],0
        je      .tab_securesel
        test    [.editor_style],AES_SECURESEL
        jnz     .tab_securesel
        test    [.editor_style],AES_INDENTSEL
        jnz     .indent_text
        call    .delete_block
        call    .make_tab
        jmp     .text_modified
    .tab_securesel:
        call    .store_line_for_undo
        call    .make_tab
        mov     [.sel_line],0
        jmp     .text_modified
    .make_tab:
        test    [.editor_style],AES_SMARTTABS
        jz      .standard_tab
        mov     esi,[.current_line]
        mov     esi,[esi+4]
        or      esi,esi
        jz      .standard_tab
        mov     edx,[.caret_position]
        lea     edi,[esi+8+edx]
        mov     ecx,100h
        sub     ecx,edx
        jecxz   .standard_tab
        mov     al,20h
        repne   scasb
        jne     .standard_tab
        repe    scasb
        je      .standard_tab
        add     ecx,edx
        sub     ecx,100h-1
        neg     ecx
        jmp     .tab_spaces
    .standard_tab:
        mov     ecx,[.caret_position]
        and     ecx,not 111b
        sub     ecx,[.caret_position]
        add     ecx,8
    .tab_spaces:
        push    ecx
        mov     al,20h
        call    .insert_character
        pop     ecx
        loop    .tab_spaces
        ret

    .indent_text:
        pushad

        cmp     [.was_selection], 0
        je      .done

        mov     ecx,[.sel_line_number]
        sub     ecx,[.caret_line_number]
        cmp     ecx,0
        jge     .count_lines_ok
        neg     ecx
        push    ecx

  .goto_first_line:
        mov     esi,[.caret_line]
        test    esi, esi
        jz      @f
        mov     edi,[esi+4]
        mov     [.caret_line],edi
        loop    .goto_first_line
@@:
        mov     ebx,[.caret_position]
        mov     eax,[.sel_position]
        mov     [.sel_position],ebx
        mov     [.caret_position],eax

        mov     ebx,[.caret_line_number]
        mov     eax,[.sel_line_number]
        mov     [.caret_line_number],eax
        mov     [.sel_line_number],ebx

        pop     ecx

   .count_lines_ok:
        cmp     [.sel_position], 0
        jne     @f
        mov     eax, [.sel_line]
        test    eax, eax
        jz      @f
        mov     eax, [eax+4]
        mov     [.sel_line], eax
        dec     [.sel_line_number]
        dec     ecx
@@:
        inc     ecx

        mov     [.caret_position],0
        mov     [.sel_position],100h

        push    [.caret_line_number] [.caret_line] [.caret_position]

   .indent_loop:
        push    ecx
        xor     eax,eax
        mov     [.caret_position],0
        test    [.kbstate+VK_SHIFT],80h
        jz      .do_indent
        mov     esi,[.caret_line]
        add     esi,8
        cmp     byte [esi],20h
        jne     .ok_next
        inc     esi
        cmp     byte [esi],20h
        jne     .ok_next
        call    .delete_character
        call    .delete_character
        jmp     .ok_next
      .do_indent:
        mov     al,' '
        call    .insert_character
        mov     al,' '
        call    .insert_character
      .ok_next:
        inc     [.caret_line_number]
        mov     esi,[.caret_line]
        mov     edi,[esi]
        mov     [.caret_line],edi
        pop     ecx
        loop    .indent_loop
        pop     [.caret_position] [.caret_line] [.caret_line_number]
        popad
        jmp     .text_modified
  .new_line:
        call    .store_status_for_undo
        cmp     [.was_selection],0
        je      .new_line_securesel
        test    [.editor_style],AES_SECURESEL
        jnz     .new_line_securesel
        call    .delete_block
    .new_line_securesel:
        test    [.editor_mode],AEMODE_OVERWRITE
        jnz     .next_line
        call    .store_line_for_undo
        call    .allocate_line
        jc      .out_of_memory
        mov     edi,eax
        mov     [.current_line],eax
        call    .store_line_for_undo
        mov     esi,[.caret_line]
        mov     ebx,[esi]
        mov     [.current_line],ebx
        call    .store_line_for_undo
        mov     [edi],ebx
        mov     [edi+4],esi
        mov     [esi],edi
        or      ebx,ebx
        jz      .line_prepared
        mov     [ebx+4],edi
    .line_prepared:
        mov     [.caret_line],edi
        inc     [.caret_line_number]
        add     edi,8
        add     esi,8
        mov     edx,[.caret_position]
        mov     [.caret_position],0
        test    [.editor_style],AES_AUTOINDENT
        jz      .indent_ok
        push    edi
        mov     al,20h
        lea     edi,[esi+edx]
        mov     ecx,100h
        sub     ecx,edx
        repe    scasb
        je      .line_ok
        mov     edx,100h-1
        sub     edx,ecx
    .line_ok:
        mov     edi,esi
        mov     ecx,100h
        repe    scasb
        setne   al
        neg     ecx
        add     ecx,100h-1
        movzx   eax,al
        imul    ecx,eax
        pop     edi
        cmp     ecx,edx
        ja      .indent_ok
        mov     [.caret_position],ecx
    .indent_ok:
        mov     eax,20202020h
        mov     ecx,100h shr 2
        rep     stosd
        inc     [.lines_count]
        cmp     edx,100h
        je      .new_line_ok
        sub     edi,100h
        add     edi,[.caret_position]
        add     esi,edx
        cmp     edx,[.caret_position]
        jae     .position_ok
        mov     edx,[.caret_position]
    .position_ok:
        mov     ecx,100h
        sub     ecx,edx
    .move_data:
        movsb
        mov     byte [esi-1],20h
        loop    .move_data
        jmp     .new_line_ok
    .next_line:
        mov     esi,[.caret_line]
        mov     ebx,[esi]
        or      ebx,ebx
        jnz     .next_line_ok
        call    .store_line_for_undo
        call    .allocate_line
        jc      .out_of_memory
        mov     esi,[.caret_line]
        mov     ebx,eax
        mov     [.current_line],eax
        call    .store_line_for_undo
        mov     [esi],ebx
        mov     [ebx],dword 0
        mov     [ebx+4],esi
        lea     edi,[ebx+8]
        mov     eax,20202020h
        mov     ecx,100h shr 2
        rep     stosd
        inc     [.lines_count]
    .next_line_ok:
        mov     [.caret_line],ebx
        inc     [.caret_line_number]
        mov     [.caret_position],0
    .new_line_ok:
        mov     eax,[.caret_line]
        mov     [.current_line],eax
        call    .store_line_for_undo
        mov     [.sel_line],0
        jmp     .text_modified
  .remove_line:
        mov     esi,[.caret_line]
        mov     [.current_line],esi
        mov     ebx,[esi]
        or      ebx,ebx
        jz      .clear_line
        mov     [.caret_position],0
        call    .store_status_for_undo
        call    .store_line_for_undo
        cmp     esi,[.window_line]
        jne     .window_ok
        mov     [.window_line],ebx
    .window_ok:
        mov     edi,[esi+4]
        mov     [.caret_line],ebx
        mov     [.current_line],ebx
        call    .store_line_for_undo
        mov     [ebx+4],edi
        or      dword [esi],-1
        dec     [.lines_count]
        or      edi,edi
        jz      .removed_first
        mov     [.current_line],edi
        call    .store_line_for_undo
        mov     [edi],ebx
        mov     [.sel_line],0
        jmp     .text_modified
    .removed_first:
        mov     [.first_line],ebx
        mov     [.sel_line],0
        jmp     .text_modified
    .clear_line:
        lea     edi,[esi+8]
        mov     ecx,100h
        mov     al,20h
        repe    scasb
        je      .ignore
        mov     [.caret_position],0
        call    .store_status_for_undo
        call    .store_line_for_undo
        lea     edi,[esi+8]
        mov     eax,20202020h
        mov     ecx,100h shr 2
        rep     stosd
        mov     [.sel_line],0
        jmp     .text_modified
  .duplicate_line:
        mov     esi,[.caret_line]
        mov     [.current_line],esi
        call    .store_status_for_undo
        call    .store_line_for_undo
        call    .allocate_line
        jc      .out_of_memory
        mov     edi,eax
        mov     [.current_line],eax
        call    .store_line_for_undo
        mov     esi,[.caret_line]
        mov     ebx,[esi]
        mov     [.current_line],ebx
        call    .store_line_for_undo
        mov     [edi],ebx
        mov     [edi+4],esi
        mov     [esi],edi
        or      ebx,ebx
        jz      .line_ready
        mov     [ebx+4],edi
    .line_ready:
        add     esi,8
        add     edi,8
        mov     ecx,100h shr 2
        rep     movsd
        inc     [.lines_count]
        jmp     .text_modified
.wmsyskeydown:
        mov     eax,[.wparam]
        cmp     eax,VK_INSERT
        je      .switch_blocks
        cmp     [.read_only],0
        jne     .ignore
        cmp     eax,VK_BACK
        je      .wmundo
        mov     al,[.last_operation]
        mov     [.current_operation],al
        invoke  ShowCaret,[.hwnd]
        jmp     .defwndproc
  .switch_blocks:
        xor     [.editor_mode],AEMODE_VERTICALSEL
        mov     [.notification],AEN_MODECHANGE
        cmp     [.was_selection],0
        je      .ignore
        jmp     .moved_window

.wmchar:
        test    [.lparam],1 shl 31
        jz      .ignore

        mov     eax,[.wparam]
        jmp     .put_char


;-------- WM_LBUTTONDOWN -------------------

.wmlbuttondown:
        call    .update_mouse_cursor
        cmp     [.focus],0
        jne     .focus_ok
        invoke  SetFocus,[.hwnd]
        mov     esi,[.editor_memory]
        add     esi,8
        lea     edi,[.editor_data]
        mov     ecx,.editor_data_size shr 2
        rep     movsd
    .focus_ok:
        lea     eax,[.kbstate]
        invoke  GetKeyboardState,eax

        cmp     [.was_selection],0
        jne     .sel_ok

        mov     eax,[.caret_line]
        mov     [.sel_line],eax
        mov     eax,[.caret_position]
        mov     [.sel_position],eax
        mov     eax,[.caret_line_number]
        mov     [.sel_line_number],eax

    .sel_ok:
        call    .get_mouse_position
        invoke  SetCapture,[.hwnd]
        or      [.mouse_select],-1
        jmp     .moved_caret

    .get_mouse_position:
        mov     ax,word [.lparam]
        cwde
        sub     eax,[.margin_width]
        cdq
        idiv    [.font_width]
        add     eax,[.window_position]
        cmp     eax,0
        jl      .lowest_position
        cmp     eax,100h
        jg      .highest_position
        jmp     .click_position_ok

    .lowest_position:
        xor     eax,eax
        jmp     .click_position_ok

    .highest_position:
        mov     eax,100h

    .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
        ret

.wmlbuttonup:
        mov     [.mouse_select],0
        invoke  ReleaseCapture
        test    [.kbstate+VK_CONTROL],80h
        jz      .done
        mov     eax,[.lparam]
        and     eax,0FFFFh
        cmp     eax,[.margin_width]
        jge     .done
        mov     [.sel_position],100h
        mov     [.caret_position],0
        mov     eax,[.caret_line]
        mov     ebx,[.caret_line_number]
        mov     [.sel_line],eax
        mov     [.sel_line_number],ebx
        jmp     .moved_selection

.wmrbuttondown:
        cmp     [.was_selection],0
        jne     .ignore

        call    .get_mouse_position
        jmp    .moved_selection

.wmrbuttonup:
        cmp     [.PopupMenu],0
        je      .wmlbuttonup
        lea     eax,[.pt]
        invoke  GetCursorPos,eax
        invoke  GetParent,[.hwnd]
        invoke  TrackPopupMenu,[.PopupMenu],TPM_LEFTALIGN or TPM_RIGHTBUTTON ,[.pt.x],[.pt.y],0,eax,0
        jmp     .wmlbuttonup

.wmmousemove:
        call    .update_mouse_cursor
        cmp     [.mouse_select],0
        je      .ignore
        cmp     [.was_selection],0
        jne     .select
        mov     eax,[.caret_line]
        mov     ebx,[.caret_line_number]
        mov     [.sel_line],eax
        mov     [.sel_line_number],ebx
        mov     eax,[.caret_position]
        mov     [.sel_position],eax
    .select:
        call    .get_mouse_position
        jmp     .moved_selection

.update_mouse_cursor:
        mov     eax,[.lparam]
        and     eax,0FFFFh
        cmp     eax,[.margin_width]
        jge     .cursor_normal
        invoke  LoadCursorA,0,IDC_ARROW
        invoke  SetCursor,eax
        jmp     .cursor_ok
      .cursor_normal:
        invoke  LoadCursorA,0,IDC_IBEAM
        invoke  SetCursor,eax
      .cursor_ok:
        ret

.wmlbuttondblclk:
        mov     [.mouse_select],0
        call    .get_mouse_position
        call    .get_word_edges
        mov     [.sel_position],edx
        mov     [.caret_position],ecx
        mov     eax,[.caret_line]
        mov     ebx,[.caret_line_number]
        mov     [.sel_line],eax
        mov     [.sel_line_number],ebx
        jmp     .moved_selection
.wmcopy:
        cmp     [.was_selection],0
        je      .ignore
        call    .copy_to_clipboard
        jmp     .ignore
    .copy_to_clipboard:
        call    .get_block_size
        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
        ret
    .copy_failed:
        invoke  GlobalFree,ebx
        ret
.wmcut:
        cmp     [.was_selection],0
        je      .ignore
        call    .copy_to_clipboard
.wmclear:
        cmp     [.was_selection],0
        je      .ignore
        call    .store_status_for_undo
        call    .delete_block
        mov     [.sel_line],0
        jmp     .text_modified

;------- WM_PASTE -------------------------

.wmpaste:
        invoke  OpenClipboard,NULL
        invoke  GetClipboardData,CF_TEXT
        or      eax,eax
        jz      .close_clipboard
        mov     ebx,eax
        invoke  GlobalLock,ebx
        mov     esi,eax
        push    ebx
        call    .store_status_for_undo
        call    .get_selection_start_position
        cmp     [.was_selection],0
        je      .do_paste
        test    [.editor_style],AES_SECURESEL
        jnz     .do_paste
        push    esi
        call    .delete_block
        pop     esi
    .do_paste:
        call    .insert_block
        pop     ebx
        jc      .close_clipboard
        invoke  GlobalUnlock,ebx
        invoke  CloseClipboard
        test    [.editor_style],AES_SECURESEL
        jnz     .text_modified
        mov     eax,[.sel_line]
        mov     ebx,[.sel_position]
        mov     ecx,[.sel_line_number]
        mov     [.caret_line],eax
        mov     [.caret_position],ebx
        mov     [.caret_line_number],ecx
        mov     [.sel_line],0
        jmp     .text_modified
    .close_clipboard:
        invoke  CloseClipboard
        jmp     .ignore
    .get_selection_start_position:
        mov     eax,[.sel_line_number]
        mov     ebx,[.sel_position]
        cmp     [.was_selection],0
        je      .new_position_ok
        cmp     eax,[.caret_line_number]
        ja      .new_position_ok
        jb      .update_position
        cmp     ebx,[.caret_position]
        ja      .new_position_ok
    .update_position:
        xchg    eax,[.caret_line_number]
        xchg    ebx,[.caret_position]
        push    eax ebx
        call    .update_positions
        pop     [.caret_position] [.caret_line_number]
    .new_position_ok:
        ret

;------- WM_SETTEXT -----------------------

.wmsettext:
        call    .reset_editor_memory
        call    .allocate_line
        mov     [.first_line],eax
        mov     [.lines_count],1
        mov     [.caret_line],eax
        mov     [.caret_line_number],1
        mov     [.window_line],eax
        mov     [.window_line_number],1
        mov     edi,eax
        xor     eax,eax
        stosd
        stosd
        mov     eax,20202020h
        mov     ecx,100h shr 2
        rep     stosd
        mov     [.caret_position],0
        mov     [.window_position],0
        mov     [.sel_line],0
        mov     esi,[.lparam]
        or      esi,esi
        jz      .text_modified
        mov     ebx,[.first_line]
        lea     edi,[ebx+8]
        mov     ecx,100h
    .copy_line:
        lodsb
        or      al,al
        jz      .text_modified
        cmp     al,0Ah
        je      .copy_lf
        cmp     al,0Dh
        je      .copy_cr
        cmp     al,9
        je      .copy_tab
        stosb
        loop    .copy_line
    .skip_overlap:
        lodsb
        or      al,al
        jz      .text_modified
        cmp     al,0Ah
        je      .copy_lf
        cmp     al,0Dh
        je      .copy_cr
        jmp     .skip_overlap
    .copy_tab:
        mov     edx,ecx
        and     ecx,111b
        setz    al
        shl     al,3
        or      cl,al
        sub     edx,ecx
        jc      .skip_overlap
        mov     al,20h
        rep     stosb
        mov     ecx,edx
        jmp     .copy_line
    .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:
        push    ebx esi
        call    .allocate_line
        jc      .out_of_memory
        pop     esi ebx
        mov     edi,eax
        mov     edx,[ebx]
        mov     [edi],edx
        mov     [edi+4],ebx
        mov     [ebx],edi
        mov     ebx,edi
        add     edi,8
        mov     eax,20202020h
        mov     ecx,100h shr 2
        rep     stosd
        inc     [.lines_count]
        or      edx,edx
        jz      .do_copy
        mov     [edx+4],ebx
    .do_copy:
        mov     ecx,100h
        lea     edi,[ebx+8]
        jmp     .copy_line


.wmgettextlength:
        mov     esi,[.first_line]
        xor     edx,edx
    .get_line_length:
        lea     edi,[esi+8+100h-1]
        mov     ecx,100h
        mov     al,20h
        std
        repe    scasb
        cld
        setne   al
        movzx   eax,al
        add     edx,ecx
        add     edx,eax
        add     edx,2
        mov     esi,[esi]
        or      esi,esi
        jnz     .get_line_length
        sub     edx,2
        mov     [.return_value],edx
        jmp     .ignore


;---------- WM_GETTEXT ------------------------

.wmgettext:
        mov     edi,[.lparam]
        mov     ebx,[.first_line]
        mov     edx,[.wparam]
        sub     edx,1
        jc      .ignore
    .get_line:
        push    edi
        lea     edi,[ebx+8+100h-1]
        mov     ecx,100h
        mov     al,20h
        std
        repe    scasb
        cld
        setne   al
        movzx   eax,al
        add     ecx,eax
        pop     edi
        lea     esi,[ebx+8]
        test    [.editor_style],AES_OPTIMALFILL
        jz      .copy_data

        push    ecx edx edi
        lea     edi,[.line_colors]
        mov     ecx,100h shr 2
        xor     eax,eax
        rep     stosd
        lea     edi, [.line_colors]
        invoke  .syntax_proc, esi, edi
        pop     edi edx ecx

    .optimal_fill:
        cmp     ecx,8
        jbe     .copy_data
        push    ecx edi
        lea     edi,[esi+7]
        lea     eax,[.line_colors+edi-8]
        sub     eax,ebx
        mov     ecx,8

    .count_spaces:
        cmp     byte [edi],20h
        jne     .spaces_counted
        cmp     byte [eax],0
        jne     .spaces_counted
        dec     edi
        dec     eax
        loop    .count_spaces
    .spaces_counted:
        pop     edi eax
        cmp     ecx,7
        jb      .put_tab
        mov     ecx,8
        sub     edx,ecx
        jc      .cut_overlap
        rep     movsb
        mov     ecx,eax
        sub     ecx,8
        jmp     .optimal_fill
    .put_tab:
        sub     edx,ecx
        jc      .cut_overlap
        push    esi
        rep     movsb
        pop     esi
        add     esi,8
        or      edx,edx
        jz      .end_text
        dec     edx
        mov     ecx,eax
        sub     ecx,8
        mov     al,9
        stosb
        jmp     .optimal_fill
    .copy_data:
        sub     edx,ecx
        jc      .cut_overlap
        rep     movsb
        mov     ebx,[ebx]
        or      ebx,ebx
        jz      .end_text
        sub     edx,2
        jc      .end_text
        mov     ax,0A0Dh
        stosw
        jmp     .get_line
    .cut_overlap:
        neg     edx
        sub     ecx,edx
        rep     movsb
    .end_text:
        xor     al,al
        stosb
        mov     eax,edi
        dec     eax
        sub     eax,[.lparam]
        mov     [.return_value],eax
        jmp     .ignore

;--------- WM_SETFONT ---------------------

.wmsetfont:
        mov     esi,[.wparam]
        or      esi,esi
        jnz     .get_metrics

        invoke  GetStockObject, SYSTEM_FIXED_FONT
        mov     esi, eax

    .get_metrics:
        invoke  GetDC,[.hwnd]
        mov     ebx,eax
        invoke  SelectObject,ebx,esi

        lea     eax, [.tm]
        invoke  GetTextMetricsA,ebx,eax

        invoke  ReleaseDC,[.hwnd],ebx

        test    [.tm.tmPitchAndFamily],TMPF_FIXED_PITCH
        jnz     .ignore

        mov     [.return_value],esi
        mov     [.editor_font],esi
        mov     eax,[.tm.tmHeight]
        test    eax, eax
        jnz     @f
        inc     eax
@@:
        mov     [.font_height],eax

        mov     eax,[.tm.tmAveCharWidth]
        test    eax, eax
        jnz     @f
        inc     eax
@@:
        mov     [.font_width],eax
        call    .create_caret
        mov     eax,[.lparam]
        mov     [.redraw_now],al
        jmp     .wmsize


;----------- WM_GETFONT ----------------------

.wmgetfont:
        mov     eax,[.editor_font]
        mov     [.return_value],eax
        jmp     .ignore


;------------ WM_UNDO ------------------------
.wmundo:
        cmp     [.undo_data],0
        je      .ignore
        call    .undo
        mov     [.last_operation],0
        call    .create_caret
        jmp     .text_modified

.emcanundo:
        mov     eax,[.undo_data]
        or      eax,eax
        jz      .ignore
        mov     [.return_value],TRUE
        jmp     .ignore

.ememptyundobuffer:
        call    .clear_undo_data
        jmp     .ignore

.emreplacesel:
        test    [.editor_mode],AEMODE_VERTICALSEL
        jnz     .ignore
        push    [.editor_mode]
        and     [.editor_mode],not AEMODE_OVERWRITE
        push    [.caret_line] [.caret_position]
        cmp     [.wparam],0
        je      .status_ok
        call    .store_status_for_undo

    .status_ok:
        call    .get_selection_start_position
        cmp     [.was_selection],0
        je      .ready_for_replace
        call    .delete_block
        mov     [.sel_line],0

    .ready_for_replace:
        mov     esi,[.lparam]
        call    .insert_block
        mov     [.notification],AEN_TEXTCHANGE
        pop     eax esi
        pop     [.editor_mode]
        sub     esi,[.caret_line]
        sub     eax,[.caret_position]
        or      eax,esi
        jz      .text_modified
        mov     eax,[.sel_line]
        xchg    eax,[.caret_line]
        mov     [.sel_line],eax
        mov     eax,[.sel_line_number]
        xchg    eax,[.caret_line_number]
        mov     [.sel_line_number],eax
        mov     eax,[.sel_position]
        xchg    eax,[.caret_position]
        mov     [.sel_position],eax
        jmp     .text_modified

.aemsetmode:
        mov     eax,[.wparam]
        xchg    [.editor_mode],eax
        cmp     eax,[.editor_mode]
        je      .ignore
        mov     [.notification],AEN_MODECHANGE
        call    .create_caret
        cmp     [.was_selection],0
        jne     .moved_window
        jmp     .done

.aemgetmode:
        mov     eax,[.editor_mode]
        mov     [.return_value],eax
        jmp     .ignore

; John Found - 25.11.2003
.aemgetmodified:
        mov     eax, [.Modified]
        mov     [.return_value], eax
        jmp     .ignore

.aemsetmodified:
        mov     eax, [.wparam]
        xchg    eax, [.Modified]
        mov     [.return_value], eax
        mov     [.notification],AEN_TEXTCHANGE
        jmp     .ignore

.aemsetsyntaxhighlight:
        mov     eax,[.wparam]
        mov     ebx,[.lparam]
        cmp     eax,0
        je      .no_new_colors
        mov     [.syntax_colors],eax
      .no_new_colors:
        mov     [.syntax_proc],ebx
      .syntax_proc_ok:
        or      ebx,ebx
        jnz     .wmsize
        mov     [.syntax_proc],SyntaxProc
        jmp     .wmsize


.aemsettextcolor:
        mov     eax,[.wparam]
        mov     ebx,[.lparam]
        mov     [.text_color],eax
        mov     [.background_color],ebx
        jmp     .wmsize


.aemsetselcolor:
        mov     eax,[.wparam]
        mov     ebx,[.lparam]
        mov     [.selection_text],eax
        mov     [.selection_background],ebx
        jmp     .wmsize


.aemsetmargincolor:
        mov     eax,[.wparam]
        mov     ebx,[.lparam]
        mov     [.margin_background],eax
        mov     [.margin_border],ebx
        jmp     .wmsize


.aemsetmarginwidth:
        mov     eax,[.wparam]
        mov     ebx,[.lparam]
        mov     [.margin_gap],eax
        mov     [.margin_width],ebx
        jmp     .wmsize


.aemsetpopupmenu:
        mov     eax, [.lparam]
        mov     [.PopupMenu],eax
        jmp     .ignore


.aemsettheme:
        mov     ebx,[.lparam]
        mov     eax,[ebx]
        mov     [.text_color],eax
        add     ebx,4
        mov     eax,[ebx]
        mov     [.background_color],eax
        add     ebx,4
        mov     eax,[ebx]
        mov     [.selection_text],eax
        add     ebx,4
        mov     eax,[ebx]
        mov     [.selection_background],eax
        add     ebx,4
        mov     eax,[ebx]
        mov     [.margin_background],eax
        add     ebx,4
        mov     eax,[ebx]
        mov     [.margin_border],eax
        add     ebx,4
        mov     eax,[ebx]
        mov     [.margin_width],eax
        add     ebx,4
        mov     eax,[ebx]
        mov     [.margin_gap],eax
        add     ebx,4
        mov     eax,[ebx]
        mov     [.focus_fg],eax
        add     ebx,4
        mov     eax,[ebx]
        mov     [.focus_bg],eax
        add     ebx,4
        mov     eax,[ebx]
        mov     [.syntax_proc],eax
        or      eax,eax
        jnz     .syn_colors
        mov     [.syntax_proc],SyntaxProc
      .syn_colors:
        add     ebx,4
        mov     [.syntax_colors],ebx
        jmp     .wmsize


;----------------------------------------------------

.aemtogglebookmark:
       mov     ecx, .bookmark_count
       mov     edx,[.caret_line_number]
       xor     eax,eax

  .loop_exists:
       cmp     [.bookmarks + 4*ecx - 4],edx
       je      .done_toggle
       loop    .loop_exists

       mov     ecx,.bookmark_count
       xchg    edx,eax

  .check_next_mark:
        cmp     dword [.bookmarks + 4*ecx - 4], edx
        je      .done_toggle
        loop    .check_next_mark

        jmp     .wmsize

  .done_toggle:
        mov     dword [.bookmarks + 4*ecx - 4], eax
        mov     [.return_value],ecx
        jmp     .wmsize


;--------------------------------------------------

.aemgotobookmark:
        mov     eax,[.lparam]
        cmp     eax,AEBM_NEXT
        je      .aemnextbookmark
        cmp     eax,AEBM_PREV
        je      .aemprevbookmark
        mov     eax,[.wparam]
        mov     ecx,4
        mul     ecx
        lea     edx,[.bookmarks-4]
        add     eax,edx
        mov     ecx,dword [eax]
        mov     [.return_value],ecx
        jmp     .ignore
.aemnextbookmark:
        mov     ecx,.bookmark_count
      .loop_next:
        push    ecx
        mov     eax,4
        mul     ecx
        lea     edx,[.bookmarks-4]
        add     eax,edx
        mov     ecx,[.caret_line_number]
        cmp     dword [eax],ecx
        jle     .loop_check_next
        mov     ecx,[.return_value]
        cmp     ecx,0
        je      .set_next_value
        cmp     ecx,dword [eax]
        jl      .loop_check_next
      .set_next_value:
        mov     ecx,dword [eax]
        mov     [.return_value],ecx
      .loop_check_next:
        pop     ecx
        loop    .loop_next
        jmp     .ignore
.aemprevbookmark:
        mov     ecx,.bookmark_count
      .loop_prev:
        push    ecx
        mov     eax,4
        mul     ecx
        lea     edx,[.bookmarks-4]
        add     eax,edx
        mov     ecx,[.caret_line_number]
        cmp     dword [eax],ecx
        jge     .loop_check_prev
        mov     ecx,[.return_value]
        cmp     ecx,0
        je      .set_prev_value
        cmp     ecx,dword [eax]
        jg      .loop_check_prev
      .set_prev_value:
        mov     ecx,dword [eax]
        mov     [.return_value],ecx
      .loop_check_prev:
        pop     ecx
        loop    .loop_prev
        jmp     .ignore
.aemclearbookmarks:
        call    .clear_marks
        jmp     .wmsize
      .clear_marks:
        mov     ecx,.bookmark_count
      .clear_next_mark:
        push    ecx
        mov     eax,4
        mul     ecx
        lea     edx, [.bookmarks-4]
        add     eax, edx
        mov     dword [eax],0
        pop     ecx
        loop    .clear_next_mark
        ret
.aemsetbookmarkicon:
        mov     eax,[.wparam]
        mov     [.bookmark_icon],eax
        jmp     .wmsize

.aemcomment:
        cmp     [.was_selection], 0
        je      .done

        mov     ecx,[.sel_line_number]
        sub     ecx,[.caret_line_number]
        cmp     ecx,0
        jge     .count_lines

        neg     ecx
        push    ecx

   .goto_first:
        mov     esi,[.caret_line]
        mov     edi,[esi+4]
        mov     [.caret_line],edi
        loop    .goto_first

        mov     ebx,[.caret_position]
        mov     eax,[.sel_position]
        mov     [.sel_position],ebx
        mov     [.caret_position],eax

        mov     ebx,[.caret_line_number]
        mov     eax,[.sel_line_number]
        mov     [.sel_line_number],ebx
        mov     [.caret_line_number],eax

        pop     ecx

   .count_lines:
        cmp     [.sel_position], 0
        jne     @f
        mov     eax, [.sel_line]
        test    eax, eax
        jz      @f
        mov     eax, [eax+4]
        mov     [.sel_line], eax
        dec     [.sel_line_number]
        dec     ecx
@@:
        inc     ecx
        mov     [.caret_position],0
        mov     [.sel_position],100h

        push    [.caret_line_number] [.caret_line] [.caret_position]

      .comment_loop:
        push    ecx
        xor     eax,eax
        mov     [.caret_position],0
        cmp     [.lparam],1
        je      .do_comment
        mov     esi,[.caret_line]
        add     esi,8
      .check_for_blank:
        cmp     byte [esi],' '
        je      .inc_pos
        cmp     byte [esi],';'
        jne     .next_line_comment
        call    .delete_character
        jmp     .next_line_comment
      .inc_pos:
        inc     esi
        inc     [.caret_position]
        jmp     .check_for_blank
      .do_comment:
        mov     al,';'
        call    .insert_character
      .next_line_comment:
        inc     [.caret_line_number]
        mov     esi,[.caret_line]
        mov     edi,[esi]
        mov     [.caret_line],edi
        pop     ecx
        loop    .comment_loop
        pop     [.caret_position] [.caret_line] [.caret_line_number]
        jmp     .text_modified

.aemindent:
        cmp     [.lparam],1
        je      .not_outdent
        mov     [.kbstate+VK_SHIFT],80h
        jmp     .do_aemindent
      .not_outdent:
        mov     [.kbstate+VK_SHIFT],0
      .do_aemindent:
        jmp     .indent_text

.aemreadonly: ; Added Tommy Lillehagen 30.01.2004
        mov     eax,[.wparam]
        mov     [.read_only],eax
        mov     [.return_value],eax
        jmp     .ignore

.aemsetfocusline: ; Added Tommy Lillehagen 30.01.2004
        mov     eax,[.wparam]
        mov     [.focus_line],eax
        test    eax,eax
        jz      .wmsize
        sub     eax,[.window_line_number]
        inc     eax
        jz      .setfocusline_updatepos
        js      .setfocusline_updatepos
        cmp     eax,[.screen_height]
        jl      .refresh

    .setfocusline_updatepos:
        mov     eax,[.wparam]
        mov     ecx,[.screen_height]
        shr     ecx,1
        sub     eax,ecx
        jz      .setfocusline_notok
        jns     .setfocusline_ok

    .setfocusline_notok:
        xor     eax,eax
        inc     eax

    .setfocusline_ok:
        call    .find_line
        mov     [.window_line],esi
        mov     [.window_line_number],ecx
        jmp     .moved_window

.aemgetlineptr:
        mov     esi,[.caret_line]
        mov     eax,[.wparam]
        or      eax,eax
        jz      .line_ptr_ok
        call    .find_line
        cmp     ecx,[.wparam]
        jne     .ignore
    .line_ptr_ok:
        mov     [.return_value],esi
        jmp     .ignore


.aemgetlinedata:
        mov     esi,[.caret_line]
        mov     eax,[.wparam]
        or      eax,eax
        jz      .line_data_ok
        call    .find_line
        cmp     ecx,[.wparam]
        jne     .ignore
    .line_data_ok:
        add     esi,8
        mov     edi,[.lparam]
        mov     ecx,100h shr 2
        rep     movsd
        mov     [.return_value],100h
        jmp     .ignore

.aemsetlinedata:        ; Sets only the text of the line, not the pointers.
        mov     esi,[.caret_line]
        mov     eax,[.wparam]
        or      eax,eax
        jz      .setline_data_ok
        call    .find_line
        cmp     ecx,[.wparam]
        jne     .ignore
    .setline_data_ok:
        add     esi,8
        mov     edi,[.lparam]
        xchg    esi, edi
        mov     ecx,100h shr 2
        rep     movsd
        mov     [.return_value],100h
        jmp     .ignore

.aemsetpos:
        mov     edi,[.wparam]
        virtual at edi
        .aepos  AEPOS
        end     virtual
        cmp     [.sel_line],0
        jne     .sel_start_ok
        mov     eax,[.caret_line]
        mov     [.sel_line],eax
        mov     eax,[.caret_line_number]
        mov     [.sel_line_number],eax
        mov     eax,[.caret_position]
        mov     [.sel_position],eax
    .sel_start_ok:
        mov     eax,[.aepos.selectionLine]
        or      eax,eax
        jz      .sel_line_ok
        call    .find_line
        mov     [.sel_line],esi
        mov     [.sel_line_number],ecx
    .sel_line_ok:
        mov     eax,[.aepos.selectionPosition]
        or      eax,eax
        jz      .sel_position_ok
        dec     eax
        mov     [.sel_position],eax
        cmp     eax,100h
        jbe     .sel_position_ok
        mov     [.sel_position],100h
    .sel_position_ok:
        mov     eax,[.aepos.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,[.aepos.caretPosition]
        or      eax,eax
        jz      .caret_position_ok
        dec     eax
        cmp     eax,100h
        jbe     .caret_position_ok
        mov     eax,100h
    .caret_position_ok:
        mov     [.caret_position],eax
        cmp     esi,[.sel_line]
        jne     .moved_selection
        cmp     eax,[.sel_position]
        jne     .moved_selection
        mov     [.sel_line],0
        jmp     .moved_selection

.aemgetpos:
        mov     edi,[.wparam]
        mov     eax,[.caret_line_number]
        mov     [.aepos.selectionLine],eax
        mov     [.aepos.caretLine],eax
        mov     eax,[.caret_position]
        inc     eax
        mov     [.aepos.selectionPosition],eax
        mov     [.aepos.caretPosition],eax
        cmp     [.sel_line],0
        je      .ignore
        mov     eax,[.sel_line_number]
        mov     [.aepos.selectionLine],eax
        mov     eax,[.sel_position]
        inc     eax
        mov     [.aepos.selectionPosition],eax
        jmp     .ignore

.amgetcaretxy:
        mov     ecx, [.wparam]

        mov     eax,[.caret_y]
        mov     ebx,[.caret_x]
        add     ebx,[.margin_width]

        mov     [ecx+AECARETXY.x0], ebx
        mov     [ecx+AECARETXY.x1], ebx
        mov     [ecx+AECARETXY.y0], eax

        add     eax, [.font_height]
        mov     [ecx+AECARETXY.y1], eax
        jmp     .ignore

.aemfindfirst:
        mov     eax,[.search_text]
        or      eax,eax
        jnz     .buffer_ok
        call    .allocate_line
        jc      .out_of_memory
    .buffer_ok:
        mov     esi,[.lparam]
        mov     edi,eax
        mov     eax,[.wparam]
        push    edi
        stosd
        stosd
        mov     edx,eax
        mov     ebx,case_table
        mov     ecx,100h
        lodsb
    .copy_text:
        test    edx,AEFIND_CASESENSITIVE
        jnz     .text_case_ok
        xlatb
    .text_case_ok:
        stosb
        lodsb
        or      al,al
        loopnz  .copy_text
        pop     edi
        jnz     .ignore
        neg     ecx
        add     ecx,100h
        mov     [edi+4],ecx
        mov     [.search_text],edi
.aemfindnext:
        mov     esi,[.search_text]
        or      esi,esi
        jz      .ignore
        cmp     dword [esi+4],0
        je      .ignore
        mov     edi,[.caret_line]
        mov     ecx,[.caret_line_number]
        mov     edx,[.caret_position]
        test    byte [esi],AEFIND_BACKWARD
        jnz     .search_backward
    .do_search:
        push    ecx
        call    .find_text
        pop     ecx
        jnc     .text_found
        inc     ecx
        xor     edx,edx
        mov     edi,[edi]
        or      edi,edi
        jnz     .do_search
        jmp     .search_done
    .text_found:
        mov     [.caret_line],edi
        mov     [.sel_line],edi
        mov     [.caret_line_number],ecx
        mov     [.sel_line_number],ecx
        mov     [.caret_position],eax
        mov     esi,[.search_text]
        add     eax,[esi+4]
        mov     [.sel_position],eax
        call    .update_positions
        call    .let_caret_appear
        mov     eax,[.caret_position]
        xchg    eax,[.sel_position]
        mov     [.caret_position],eax
        mov     [.return_value],TRUE
        jmp     .moved_selection
    .backward_found:
        mov     [.caret_line],edi
        mov     [.sel_line],edi
        mov     [.caret_line_number],ecx
        mov     [.sel_line_number],ecx
        mov     [.sel_position],eax
        mov     esi,[.search_text]
        add     eax,[esi+4]
        mov     [.caret_position],eax
        call    .update_positions
        call    .let_caret_appear
        mov     eax,[.caret_position]
        xchg    eax,[.sel_position]
        mov     [.caret_position],eax
        mov     [.return_value],TRUE
        jmp     .moved_selection
    .search_backward:
        push    ecx
        call    .find_text
        pop     ecx
        jnc     .backward_found
        dec     ecx
        mov     edx,100h
        mov     edi,[edi+4]
        or      edi,edi
        jnz     .search_backward
    .search_done:
        xor     eax,eax
        mov     esi,[.search_text]
        mov     [esi],eax
        mov     [.search_text],eax
        jmp     .done
.aemcanfindnext:
        cmp     [.search_text],0
        je      .ignore
        mov     [.return_value],TRUE
        jmp     .ignore
.aemgetwordatcaret:
        call    .get_word_edges

        mov     word [.return_value], dx
        mov     word [.return_value+2], cx

        mov     edi,[.lparam]
        lea     esi,[esi+8+edx]
        sub     ecx,edx
        inc     ecx
        cmp     cx, word [.wparam]
        jbe     .size_ok
        movzx   ecx, word [.wparam]
    .size_ok:
        dec     ecx
        rep     movsb
        xor     al,al
        stosb

        jmp     .ignore

    .get_word_edges:
        mov     esi,[.caret_line]
        mov     edx,[.caret_position]
    .find_left_edge:
        or      edx,edx
        jz      .left_edge_ok
        mov     al,[esi+8+edx-1]
        cmp     byte [.wparam+2], 0
        jne     .pointok

        cmp     al, '.'
        je      .inword

.pointok:
        call    .recognize_character
        jc      .left_edge_ok

.inword:
        dec     edx
        jmp     .find_left_edge
    .left_edge_ok:
        mov     ecx,[.caret_position]
    .find_right_edge:
        cmp     ecx,100h
        je      .right_edge_ok
        mov     al,[esi+8+ecx]
        call    .recognize_character
        jc      .right_edge_ok
        inc     ecx
        jmp     .find_right_edge
    .right_edge_ok:
        ret
.moved_caret:
        test    [.kbstate+VK_SHIFT],80h
        jnz     .moved_selection
        mov     [.sel_line],0
.moved_selection:
        mov     [.notification],AEN_POSCHANGE
        jmp     .update
.moved_window:
        call    .update_positions
        jmp     .refresh
.text_modified:
        mov     [.notification],AEN_TEXTCHANGE
    .update:
        call    .update_positions
        call    .let_caret_appear
    .refresh:
        call    .paint_bookmarks
        cmp     [.focus_line],0
        jne     .wmsize
        mov     eax,[.editor_screen]
        or      eax,eax
        jz      .wmsize
        push    eax
        call    .update_screen
        mov     esi,[esp]
        mov     edi,[.editor_screen]
        or      edi,edi
        jz      .refresh_failed
        mov     [.rect.top],0
        mov     edx,[.font_height]
        mov     [.rect.bottom],edx
        mov     ecx,[.screen_height]
    .refresh_screen:
        push    ecx
        mov     ecx,[.screen_width]
        mov     ebx,[.screen_height]
        imul    ebx,ecx
        mov     edx,[.font_width]
        xor     eax,eax
        mov     [.rect.left],eax
        mov     [.rect.right],eax
    .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
        mov     eax,[.margin_width]
        add     [.rect.left],eax
        add     [.rect.right],eax
        lea     eax, [.rect]
        invoke  InvalidateRect,[.hwnd],eax,FALSE
        pop     edx ecx
        mov     eax,[.margin_width]
        sub     [.rect.right],eax
        mov     eax,[.rect.right]
        mov     [.rect.left],eax
        jecxz   .refresh_next_line
        dec     ecx
        jnz     .refresh_line
    .refresh_next_line:
        mov     eax,[.font_height]
        add     [.rect.top],eax
        add     [.rect.bottom],eax
        pop      ecx
        dec     ecx
        jnz     .refresh_screen
        invoke      GlobalFree
        jmp     .done
    .refresh_failed:
        pop     [.editor_screen]
        jmp     .wmsize


.ignore:
        mov     dl,[.last_operation]
        mov     [.current_operation],dl
        cmp     [.was_selection],0
        jne     .done
        mov     [.sel_line],0
.done:
        cmp     [.focus],0
        je      .caret_ok
        call    .update_caret_position
        invoke  ShowCaret,[.hwnd]

    .caret_ok:

        lea     esi,[.editor_data]
        mov     edi,[.editor_memory]
        add     edi,8
        mov     ecx,.editor_data_size shr 2
        rep     movsd                           ; updates editor memory.

        cmp     [.notification],0
        je      .notification_ok
        invoke  GetWindowLongA, [.hwnd], GWL_HWNDPARENT
        mov     edi,eax
        invoke  GetWindowLongA, [.hwnd], GWL_ID
        movzx   ebx,[.notification]
        shl     ebx,16
        or      eax,ebx
        invoke  SendMessageA, edi, WM_COMMAND, eax, [.hwnd]

    .notification_ok:
        cmp     [.redraw_now],0
        je      .redraw_ok
        invoke  UpdateWindow,[.hwnd]

    .redraw_ok:
        mov     eax,[.return_value]

.finish:
        pop     edi esi ebx
        return

.out_of_memory:
        call    .undo

.not_enough_memory:
        lea     esp,[.editor_memory-10h]
        mov     [.notification],AEN_OUTOFMEMORY
        or      [.return_value],-1
        jmp     .ignore

.update_positions:
        lea     eax, [.rect]
        invoke  GetClientRect,[.hwnd],eax
        mov     eax,[.rect.left]
        add     eax,[.margin_width]
        mov     [.rect.left],eax
        cmp     eax,[.rect.right]
        jbe     .margin_ok
        mov     [.rect.right],eax
    .margin_ok:
        mov     eax,[.rect.right]
        sub     eax,[.rect.left]
        cdq
        div     [.font_width]
        add     edx,-1
        adc     eax,0
        mov     [.screen_width],eax
        mov     eax,[.rect.bottom]
        sub     eax,[.rect.top]
        cdq
        div     [.font_height]
        add     edx,-1
        adc     eax,0
        mov     [.screen_height],eax

    .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,[.rect.bottom]
        sub     eax,[.rect.top]
        xor     edx,edx
        div     [.font_height]
        mov     [.page_size],eax
        mov     [.sc.nPage],eax
        mov     edx,[.window_line_number]
        mov     [.sc.nPos],edx
        cmp     edx,1
        je      .vscroll_ok
        add     edx,eax
        dec     edx
        cmp     edx,ecx
        jle     .vscroll_ok
        sub     edx,ecx

    .vscroll_correction:
        mov     esi,[.window_line]
        mov     esi,[esi+4]
        or      esi,esi
        jz      .setup_vscroll
        mov     [.window_line],esi
        dec     [.window_line_number]
        dec     edx
        jnz     .vscroll_correction
        jmp     .setup_vscroll

    .vscroll_ok:
        test    [.editor_style],WS_VSCROLL
        jz      .setup_hscroll
        lea     eax, [.sc]
        invoke  SetScrollInfo,[.hwnd],SB_VERT,eax,TRUE

    .setup_hscroll:
        mov     [.sc.nMin],0
        mov     [.sc.nMax],100h
        mov     eax,[.rect.right]
        sub     eax,[.rect.left]
        xor     edx,edx
        div     [.font_width]
        mov     [.sc.nPage],eax
        mov     edx,[.window_position]
        mov     [.sc.nPos],edx
        or      edx,edx
        jz      .hscroll_ok
        add     edx,eax
        cmp     edx,101h
        jbe     .hscroll_ok
        sub     edx,101h
        sub     [.window_position],edx
        jnc     .setup_hscroll
        mov     [.window_position],0
        jmp     .setup_hscroll

    .hscroll_ok:
        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
        ret

.let_caret_appear:
        mov     eax,[.caret_position]
        cmp     eax,[.window_position]
        jl      .horizontal_correction
        mov     eax,[.rect.right]
        sub     eax,[.rect.left]
        xor     edx,edx
        div     [.font_width]
        or      eax,eax
        jz      .horizontal_check
        dec     eax

    .horizontal_check:
        neg     eax
        add     eax,[.caret_position]
        cmp     [.window_position],eax
        jge     .horizontal_ok

    .horizontal_correction:
        mov     [.window_position],eax
        call    .update_positions

    .horizontal_ok:
        mov     esi,[.caret_line]
        mov     ecx,[.caret_line_number]
        cmp     ecx,[.window_line_number]
        jl      .vertical_correction
        mov     eax,[.rect.bottom]
        sub     eax,[.rect.top]
        xor     edx,edx
        div     [.font_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]
        inc     ecx
        cmp     ecx,eax
        jl      .vertical_find

    .vertical_correction:
        mov     [.window_line],esi
        mov     [.window_line_number],ecx
        call    .update_positions

    .vertical_ok:
        ret


.create_caret:
        xor     eax,eax
        test    [.editor_mode],AEMODE_OVERWRITE
        jnz     .block_caret
        test    [.editor_style],AES_CONSOLECARET
        jnz     .console_caret
        invoke  CreateCaret,[.hwnd],NULL,0,[.font_height]
        jmp     .update_caret_position

    .block_caret:
        invoke  CreateCaret,[.hwnd],NULL,[.font_width],[.font_height]
        jmp     .update_caret_position

    .console_caret:
        invoke  CreateCaret,[.hwnd],NULL,[.font_width],2

.update_caret_position:
        mov     eax,[.caret_y]
        mov     ebx,[.caret_x]
        add     ebx,[.margin_width]
        test    [.editor_mode],AEMODE_OVERWRITE
        jnz     .set_position
        test    [.editor_style],AES_CONSOLECARET
        jz      .set_position
        add     eax,[.font_height]
        sub     eax,2

      .set_position:
        cmp     ebx,[.margin_width]
        jge     @F
        xor     ebx,ebx
        sub     ebx,[.font_width]
        @@:
        invoke  SetCaretPos,ebx,eax
        ret




.update_screen:
        mov     eax,[.screen_width]
        mul     [.screen_height]
        mov     ebx,eax
        shl     eax,1
        or      eax,eax
        jz      .screen_allocated
        invoke  GlobalAlloc,GMEM_FIXED,eax
    .screen_allocated:
        mov     [.editor_screen],eax
        or      eax,eax
        jz      .screen_prepared
        mov     edi,eax
        add     ebx,edi
        push    ebx
        mov     ecx,[.screen_height]
        mov     esi,[.window_line]

    .prepare_screen:
        push    ecx
        push    edi

        lea     edi,[.line_colors]
        mov     ecx,100h shr 2
        xor     eax,eax
        rep     stosd
        lea     eax,[esi+8]

        lea     edi, [.line_colors]
        invoke  .syntax_proc, eax, edi

        pop     edi
        push    esi

        mov     edx,[.window_position]
        lea     esi,[esi+8+edx]
        mov     eax,100h
        sub     eax,edx
        cmp     eax,[.screen_width]
        jbe     .prepare_line
        mov     eax,[.screen_width]
    .prepare_line:
        mov     ecx,eax
        rep     movsb
        lea     esi,[.line_colors+edx]
        mov     ecx,eax
        xchg    edi,ebx
        rep     movsb
        xchg    edi,ebx
        pop     esi
        cmp     eax,[.screen_width]
        je      .prepare_next_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
    .prepare_next_line:
        pop     ecx
        mov     esi,[esi]
        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     .hidesel_ok
        cmp     [.focus],0
        je      .screen_prepared
    .hidesel_ok:
        cmp     [.sel_line],0
        je      .screen_prepared
        mov     eax,[.window_line_number]
        mov     esi,[.sel_line_number]
        mov     edi,[.caret_line_number]
        sub     esi,eax
        sub     edi,eax
        mov     ecx,[.window_position]
        mov     eax,[.sel_position]
        mov     edx,[.caret_position]
        sub     eax,ecx
        sub     edx,ecx
        cmp     esi,edi
        jle     .sel_boundaries_ok
        xchg    esi,edi
        xchg    eax,edx
    .sel_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],AEMODE_VERTICALSEL
        jz      .prepare_hsel
    .prepare_vsel:
        cmp     eax,edx
        jle     .vsel_boundaries_ok
        xchg    eax,edx
    .vsel_boundaries_ok:
        cmp     esi,0
        jge     .vsel_start_ok
        xor     esi,esi
    .vsel_start_ok:
        inc     edi
        cmp     edi,ecx
        jle     .vsel_end_ok
        mov     edi,ecx
    .vsel_end_ok:
        mov     ecx,[.screen_width]
        cmp     edx,0
        jl      .screen_prepared
        cmp     eax,ecx
        jge     .screen_prepared
        cmp     eax,0
        jge     .vsel_line_start_ok
        xor     eax,eax
    .vsel_line_start_ok:
        cmp     edx,ecx
        jle     .vsel_line_end_ok
        mov     edx,ecx
    .vsel_line_end_ok:
        mov     ecx,edi
        sub     ecx,esi
        imul    esi,[.screen_width]
        add     ebx,esi
    .prepare_vsel_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_vsel_line
        jmp     .screen_prepared
    .prepare_hsel:
        cmp     esi,0
        jge     .hsel_start_ok
        xor     esi,esi
        xor     eax,eax
    .hsel_start_ok:
        cmp     edi,ecx
        jl      .hsel_end_ok
        mov     edi,ecx
        xor     edx,edx
    .hsel_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     .hsel_start_line_ok
        sub     edi,eax
        add     ecx,eax
        sub     eax,[.screen_width]
        jle     .hsel_start_line_ok
        add     edi,eax
        sub     ecx,eax
    .hsel_start_line_ok:
        cmp     edx,0
        jle     .hsel_end_line_ok
        add     ecx,edx
        sub     edx,[.screen_width]
        jle     .hsel_end_line_ok
        sub     ecx,edx
    .hsel_end_line_ok:
        mov     al,80h
        rep     stosb
    .screen_prepared:
        ret




.init_editor_memory:

        invoke  VirtualAlloc,0,10800h,MEM_COMMIT,PAGE_READWRITE
        or      eax,eax
        jz      .memory_error
        mov     [.editor_memory],eax
        mov     dword [eax],0
        mov     dword [eax+4],0
        lea     ebx,[eax+108h]
        mov     [.unallocated_lines],ebx
        mov     [.memory_search_line],ebx
        add     eax,10800h
        mov     [.unallocated_lines_end],eax
        mov     [.memory_search_block],eax
        clc
        ret
    .memory_error:
        stc
        ret

.reset_editor_memory:
        mov     esi,[.editor_memory]
        lea     eax,[esi+108h]
        mov     [.unallocated_lines],eax
        mov     [.memory_search_line],eax
        lea     eax,[esi+10800h]
        mov     [.unallocated_lines_end],eax
        mov     [.memory_search_block],eax
        pushd   [esi]
    .decommit:
        pop     ebx
        test    ebx, ebx
        jz      .decommit_done
        pushd   [ebx]
        invoke  VirtualFree, ebx, 0, MEM_RELEASE
        jmp     .decommit

    .decommit_done:
        mov     eax,[.editor_memory]
        mov     [eax],dword 0
        mov     [.undo_data],0
        mov     [.search_text],0
        mov     [.current_operation],0
        ret

.release_editor_memory:
        mov     esi,[.editor_memory]
    .release:
        mov     ebx,[esi]
        invoke  VirtualFree,esi,0,MEM_RELEASE
        mov     esi,ebx
        or      esi,esi
        jnz     .release
        mov     [.editor_memory],0
        ret
.allocate_line:
        mov     eax,[.unallocated_lines]
        mov     ebx,[.memory_search_block]
        mov     esi,[.memory_search_line]
        cmp     eax,[.unallocated_lines_end]
        je      .find_free_line
        add     [.unallocated_lines],108h
        clc
        ret
    .find_free_line:
        cmp     esi,ebx
        je      .find_in_next_block
        cmp     dword [esi],-1
        je      .reuse_line
        add     esi,108h
        cmp     esi,[.memory_search_line]
        jne     .find_free_line
        sub     ebx,10800h
    .find_last_memory_block:
        cmp     dword [ebx],0
        je      .allocate_more_memory
        mov     ebx,[ebx]
        jmp     .find_last_memory_block
    .allocate_more_memory:
        invoke  VirtualAlloc,0,10800h,MEM_COMMIT,PAGE_READWRITE
        or      eax,eax
        jz      .failed
        mov     [ebx],eax
        mov     [eax],dword 0
        mov     [eax+4],ebx
        lea     ebx,[eax+10800h]
        mov     [.unallocated_lines_end],ebx
        add     eax,108h
        lea     ebx,[eax+108h]
        mov     [.unallocated_lines],ebx
        clc
        ret
    .failed:
        stc
        ret
    .reuse_line:
        mov     eax,esi
        mov     [.memory_search_block],ebx
        add     esi,108h
        mov     [.memory_search_line],esi
        clc
        ret
    .find_in_next_block:
        sub     ebx,10800h
        mov     esi,[ebx]
        lea     ebx,[esi+10800h]
        or      esi,esi
        jnz     .find_free_line
        mov     ebx,[.editor_memory]
        mov     esi,ebx
        add     ebx,10800h
        jmp     .find_free_line
.init_editor_data:
        call    .allocate_line
        mov     [.first_line],eax
        mov     [.lines_count],1
        mov     [.caret_line],eax
        mov     [.caret_line_number],1
        mov     [.window_line],eax
        mov     [.window_line_number],1
        mov     edi,eax
        xor     eax,eax
        stosd
        stosd
        mov     eax,20202020h
        mov     ecx,100h shr 2
        rep     stosd
        mov     [.caret_position],0
        mov     [.sel_position], 0
        mov     [.window_position],0
        mov     [.sel_line],0
        mov     [.sel_line_number], 1   ; 11.12.2003 John Found Added, bug fix for
                                        ; some functions immediately after creation
                                        ; of AsmEdit.
        mov     [.undo_data],0
        mov     [.search_text],0
        mov     [.current_operation],0
        mov     [.editor_mode],0
        mov     [.syntax_proc], SyntaxProc
        mov     [.syntax_colors],0
        mov     [.focus],0
        mov     [.mouse_select],0
        ret
.insert_character:
        mov     edx,[.caret_position]
        cmp     edx,100h
        je      .insert_done
        mov     esi,[.caret_line]
        lea     esi,[esi+8+edx]
        test    [.editor_mode],AEMODE_OVERWRITE
        jnz     .overwrite
        mov     ecx,100h
        sub     ecx,edx
        inc     edx
        mov     [.caret_position],edx
        mov     ah,al
        mov     ebx,esi
        mov     edx,ecx
    .shift_data_right:
        xchg    al,[esi]
        inc     esi
        loop    .shift_data_right
        test    [.editor_style],AES_AUTOBRACKETS
        jz      .insert_done
        cmp     ah,'('
        je      .round
        cmp     ah,'['
        je      .square
        cmp     ah,'{'
        je      .brace
    .insert_done:
        ret
    .round:
        mov     al,')'
        jmp     .auto_bracket
    .square:
        mov     al,']'
        jmp     .auto_bracket
    .brace:
        mov     al,'}'
    .auto_bracket:
        xor     ah,ah
        mov     ecx,edx
        dec     ecx
        jz      .insert_done
        lea     esi,[ebx+1]
        xchg    al,[esi]
        call    .recognize_character
        jnc     .cancel_bracket
        inc     esi
        dec     ecx
        jnz     .shift_data_right
        ret
    .cancel_bracket:
        mov     [esi],al
        ret
    .overwrite:
        mov     [esi],al
        inc     [.caret_position]
        ret
.delete_character:
        mov     edx,[.caret_position]
        cmp     edx,100h
        je      .delete_done
        mov     esi,[.caret_line]
        mov     al,20h
        test    [.editor_mode],AEMODE_OVERWRITE
        jnz     .delete
        add     esi,108h
        mov     ecx,100h
        sub     ecx,[.caret_position]
    .shift_data_left:
        dec     esi
        xchg    al,[esi]
        loop    .shift_data_left
    .delete_done:
        ret
    .delete:
        mov     [esi+8+edx],al
        ret

.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
        ret
    .separator_character:
        stc
        ret
.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     [esi],dword 0
        je      .line_found
        inc     ecx
        mov     esi,[esi]
        jmp     .find_forward
    .backward_from_window:
        mov     esi,[.window_line]
        mov     ecx,[.window_line_number]
    .find_backward:
        cmp     ecx,eax
        je      .line_found
        cmp     [esi+4],dword 0
        je      .line_found
        dec     ecx
        mov     esi,[esi+4]
        jmp     .find_backward
    .line_found:
        ret

.insert_block:
        test    [.editor_mode],AEMODE_VERTICALSEL
        jz      .do_insert_block
        push    esi
        or      edx,-1
        xor     ecx,ecx
    .count:
        lodsb
        cmp     al,9
        je      .cannot_insert
        cmp     al,0Dh
        je      .count_next_line
        or      al,al
        jz      .check_count
        inc     ecx
        jmp     .count
    .count_next_line:
        lodsb
    .check_count:
        cmp     edx,0
        jl      .line_to_insert_ok
        je      .cannot_insert
        cmp     edx,ecx
        je      .line_to_insert_ok
        jmp     .cannot_insert
    .line_to_insert_ok:
        mov     edx,ecx
        xor     ecx,ecx
        or      al,al
        jz      .cannot_insert
        cmp     byte [esi],0
        jne     .count
        pop     esi
    .do_insert_block:
        mov     eax,[.caret_line]
        mov     [.current_line],eax
        call    .store_line_for_undo
        mov     edx,[eax]
        mov     [.current_line],edx
        call    .store_line_for_undo
        mov     ebx,eax
        mov     [.sel_line],ebx
        mov     edx,[.caret_position]
        mov     eax,[.caret_line_number]
        mov     [.sel_line_number],eax
        lea     edi,[ebx+8+edx]
        test    [.editor_mode],AEMODE_OVERWRITE
        jnz     .begin_insert
        test    [.editor_mode],AEMODE_VERTICALSEL
        jnz     .begin_insert

        push    esi edi
        mov     esi,edi

        lea     edi,[.line_buffer]
        mov     ecx,100h
        sub     ecx,[.caret_position]
        rep     movsb

        mov     ecx,[.caret_position]
        mov     al,20h
        rep     stosb
        mov     edi,[esp]
        mov     ecx,100h
        sub     ecx,[.caret_position]
        mov     al,20h
        rep     stosb
        pop     edi esi
    .begin_insert:
        mov     edx,esi
        xor     ecx,ecx
    .count_characters:
        lodsb
        cmp     al,0Dh
        je      .put_string
        cmp     al,9
        je      .convert_string
        or      al,al
        jz      .put_string
        inc     ecx
        jmp     .count_characters

    .convert_string:
        mov     esi,edx
        push    edi
        lea     edi,[.text_buffer]
        xor     ecx,ecx

    .convert_tabs:
        lodsb
        cmp     al,0Dh
        je      .convert_done
        cmp     al,9
        je      .insert_tab
        or      al,al
        jz      .convert_done
        cmp     ecx,100h
        jae     .convert_tabs
        inc     ecx
        stosb
        jmp     .convert_tabs
    .insert_tab:
        mov     edx,ecx
        and     ecx,not 111b
        sub     ecx,edx
        add     ecx,8
        add     edx,ecx
        mov     al,20h
        rep     stosb
        mov     ecx,edx
        jmp     .convert_tabs

    .convert_done:
        lea     edx,[.text_buffer]
        pop     edi

    .put_string:
        xchg    esi,edx
        lea     eax,[ebx+108h]
        sub     eax,edi
        cmp     eax,ecx
        jbe     .larger_string
        test    [.editor_mode],AEMODE_VERTICALSEL
        jz      .simple_put
        test    [.editor_mode],AEMODE_OVERWRITE
        jnz     .simple_put
        sub     eax,ecx
        xchg    eax,ecx
        push    esi edi
        lea     esi,[edi+ecx-1]
        lea     edi,[ebx+108h-1]
        std
        rep     movsb
        cld
        pop     edi esi
        xchg    eax,ecx
    .simple_put:
        rep     movsb
        jmp     .put_ok
    .larger_string:
        xchg    ecx,eax
        sub     eax,ecx
        rep     movsb
    .put_ok:
        mov     esi,edx
        cmp     byte [esi-1],0
        je      .last_line
        lodsb
        or      al,al
        jz      .last_line
        cmp     byte [esi],0
        je      .last_line
        test    [.editor_mode],AEMODE_VERTICALSEL
        jnz     .insert_next_line
        test    [.editor_mode],AEMODE_OVERWRITE
        jnz     .overwrite_line
    .insert_new_line:
        push    ebx esi
        call    .allocate_line
        jc      .out_of_memory
        pop     esi ebx
        mov     [.sel_line],eax
        inc     [.sel_line_number]
        mov     [.current_line],eax
        call    .store_line_for_undo
        mov     edi,eax
        mov     edx,[ebx]
        mov     [edi],edx
        mov     [edi+4],ebx
        mov     [ebx],edi
        mov     ebx,edi
        add     edi,8
        mov     eax,20202020h
        mov     ecx,100h shr 2
        rep     stosd
        inc     [.lines_count]
        or      edx,edx
        jz      .insert_into_line
        mov     [edx+4],ebx
        jmp     .insert_into_line
    .overwrite_line:
        lea     ecx,[ebx+8+100h]
        sub     ecx,edi
        mov     al,20h
        rep     stosb
    .insert_next_line:
        mov     eax,[ebx]
        or      eax,eax
        jz      .insert_new_line
        mov     ebx,eax
        mov     [.sel_line],ebx
        inc     [.sel_line_number]
        mov     [.current_line],eax
        call    .store_line_for_undo
    .insert_into_line:
        mov     edx,esi
        xor     ecx,ecx
        lea     edi,[ebx+8]
        test    [.editor_mode],AEMODE_VERTICALSEL
        jz      .count_characters
        add     edi,[.caret_position]
        jmp     .count_characters
    .last_line:
        test    [.editor_mode],AEMODE_OVERWRITE
        jnz     .block_inserted
        test    [.editor_mode],AEMODE_VERTICALSEL
        jnz     .block_inserted
        lea     eax,[ebx+108h]
        cmp     edi,eax
        jae     .block_inserted
        push    edi
        mov     ecx,eax
        sub     ecx,edi
        lea     esi,[.line_buffer]
        rep     movsb
        pop     edi
    .block_inserted:
        lea     ebx,[ebx+8]
        mov     eax,edi
        sub     eax,ebx
        mov     [.sel_position],eax
        clc
        ret
    .cannot_insert:
        pop     esi
        stc
        ret
.delete_block:
        mov     eax,[.sel_line]
        mov     ebx,[.sel_position]
        mov     ecx,[.caret_line]
        mov     edx,[.caret_position]
        mov     esi,[.sel_line_number]
        test    [.editor_mode],AEMODE_VERTICALSEL
        jnz     .delete_vertical
        cmp     esi,[.caret_line_number]
        jb      .boundaries_for_delete_ok
        ja      .exchange_boundaries_for_delete
        cmp     ebx,edx
        jb      .boundaries_for_delete_ok
    .exchange_boundaries_for_delete:
        xchg    eax,ecx
        xchg    ebx,edx
        mov     esi,[.caret_line_number]
    .boundaries_for_delete_ok:
        mov     [.caret_line],eax
        mov     [.caret_line_number],esi
        mov     esi,eax
        mov     [.sel_line],0
        test    [.editor_mode],AEMODE_OVERWRITE
        jnz     .overwrite_delete
        mov     [.caret_position],ebx
        mov     [.current_line],eax
        call    .store_line_for_undo
        mov     edi,eax
        cmp     eax,ecx
        je      .delete_from_line
        mov     eax,[eax]
    .delete_line:
        mov     [.current_line],eax
        call    .store_line_for_undo
        mov     esi,eax
        cmp     eax,[.window_line]
        jne     .release_line
        mov     eax,[.caret_line]
        mov     [.window_line],eax
        mov     eax,[.caret_line_number]
        mov     [.window_line_number],eax
    .release_line:
        cmp     esi,ecx
        je      .lines_deleted
        or      eax,-1
        xchg    [esi],eax
        dec     [.lines_count]
        jmp     .delete_line
    .lines_deleted:
        mov     eax,[esi]
        mov     [edi],eax
        or      eax,eax
        jz      .delete_last_line
        mov     [.current_line],eax
        call    .store_line_for_undo
        mov     eax,[.current_line]
        mov     [eax+4],edi
    .delete_last_line:
        or      dword [esi],-1
    .delete_from_line:
        lea     edi,[edi+8+ebx]
        lea     esi,[esi+8+edx]
        mov     ecx,100h
        sub     ecx,ebx
        xor     eax,eax
        cmp     ebx,edx
        jae     .move_remaining_data
        mov     ecx,100h
        sub     ecx,edx
        mov     eax,edx
        sub     eax,ebx
    .move_remaining_data:
        rep     movsb
        mov     ecx,eax
        mov     al,20h
        rep     stosb
    .block_deleted:
        ret
    .overwrite_delete:
        push    ecx
        mov     ecx,100h
        sub     ecx,ebx
        lea     edi,[esi+ebx+8]
        pop     ebx
    .fill_with_spaces:
        cmp     esi,ebx
        jne     .end_fill_ok
        sub     ecx,100h
        add     ecx,edx
    .end_fill_ok:
        mov     al,20h
        rep     stosb
        cmp     esi,ebx
        je      .block_deleted
        mov     esi,[esi]
        mov     [.current_line],esi
        call    .store_line_for_undo
        mov     ecx,100h
        lea     edi,[esi+8]
        jmp     .fill_with_spaces
    .delete_vertical:
        cmp     esi,[.caret_line_number]
        jbe     .vboundaries_for_delete_ok
        xchg    eax,ecx
    .vboundaries_for_delete_ok:
        cmp     ebx,edx
        jbe     .hboundaries_for_delete_ok
        xchg    ebx,edx
    .hboundaries_for_delete_ok:
        mov     [.sel_line],0
        mov     esi,eax
        mov     edi,ecx
        mov     [.current_line],esi
        call    .store_line_for_undo
        test    [.editor_mode],AEMODE_OVERWRITE
        jnz     .vertical_fill
        mov     [.caret_position],ebx
    .cut_from_line:
        push    esi edi
        lea     edi,[esi+8+ebx]
        lea     esi,[esi+8+edx]
        mov     ecx,100h
        sub     ecx,edx
        rep     movsb
        mov     ecx,edx
        sub     ecx,ebx
        mov     al,20h
        rep     stosb
        pop     edi esi
        cmp     esi,edi
        je      .block_deleted
        mov     esi,[esi]
        mov     [.current_line],esi
        call    .store_line_for_undo
        jmp     .cut_from_line
    .vertical_fill:
        push    edi
        lea     edi,[esi+8+ebx]
        mov     ecx,edx
        sub     ecx,ebx
        mov     al,20h
        rep     stosb
        pop     edi
        cmp     esi,edi
        je      .block_deleted
        mov     esi,[esi]
        mov     [.current_line],esi
        call    .store_line_for_undo
        jmp     .vertical_fill
.copy_block:
        mov     esi,[.sel_line]
        mov     eax,[.caret_line]
        mov     ebx,[.sel_position]
        mov     edx,[.caret_position]
        mov     ecx,[.sel_line_number]
        test    [.editor_mode],AEMODE_VERTICALSEL
        jnz     .copy_vertical_block
        cmp     ecx,[.caret_line_number]
        jb      .boundaries_for_copy_ok
        ja      .exchange_boundaries_for_copy
        cmp     ebx,edx
        jb      .boundaries_for_copy_ok
    .exchange_boundaries_for_copy:
        xchg    esi,eax
        xchg    ebx,edx
    .boundaries_for_copy_ok:
        cmp     esi,eax
        je      .hboundaries_for_copy_ok
        push    esi edi
        lea     edi,[esi+108h-1]
        lea     esi,[esi+8+ebx]
        mov     ecx,100h
        sub     ecx,ebx
        mov     ebx,eax
        jmp     .get_line_size
    .copy_whole_line:
        mov     esi,[esi]
        cmp     esi,ebx
        je      .copy_last_line
        push    esi edi
        add     esi,8
        lea     edi,[esi+100h-1]
        mov     ecx,100h
    .get_line_size:
        mov     al,20h
        std
        repe    scasb
        setne   al
        movzx   eax,al
        add     ecx,eax
        cld
        pop     edi
        rep     movsb
        mov     word [edi],0A0Dh
        add     edi,2
        pop     esi
        jmp     .copy_whole_line
    .copy_last_line:
        add     esi,8
        mov     ecx,edx
        rep     movsb
        mov     ax,0A0Dh
        stosw
        xor     al,al
        stosb
        ret
    .copy_vertical_block:
        cmp     ecx,[.caret_line_number]
        jb      .vboundaries_for_copy_ok
        xchg    esi,eax
    .vboundaries_for_copy_ok:
        cmp     ebx,edx
        jb      .hboundaries_for_copy_ok
        xchg    ebx,edx
    .hboundaries_for_copy_ok:
        push    esi
        lea     esi,[esi+8+ebx]
        mov     ecx,edx
        sub     ecx,ebx
        rep     movsb
        mov     word [edi],0A0Dh
        add     edi,2
        pop     esi
        cmp     esi,eax
        je      .block_copied
        mov     esi,[esi]
        jmp     .hboundaries_for_copy_ok
    .block_copied:
        xor     al,al
        stosb
        ret
.get_block_size:
        xor     ecx,ecx
        mov     esi,[.sel_line]
        mov     eax,[.caret_line]
        mov     ebx,[.sel_position]
        mov     edx,[.caret_position]
        mov     edi,[.sel_line_number]
        test    [.editor_mode],AEMODE_VERTICALSEL
        jnz     .vertical_block
        cmp     edi,[.caret_line_number]
        jb      .boundaries_ok
        ja      .exchange_boundaries
        cmp     ebx,edx
        jb      .boundaries_ok
    .exchange_boundaries:
        xchg    esi,eax
        xchg    ebx,edx
    .boundaries_ok:
        xor     ecx,ecx
        cmp     esi,eax
        je      .hboundaries_ok
        add     edx,ecx
        mov     ecx,100h
        sub     ecx,ebx
        mov     ebx,eax
        lea     edi,[esi+8+100h-1]
        jmp     .count_line_bytes
    .whole_line:
        mov     esi,[esi]
        cmp     esi,ebx
        je      .block_size_ok
        lea     edi,[esi+8+100h-1]
        mov     ecx,100h
    .count_line_bytes:
        mov     al,20h
        std
        repe    scasb
        setne   al
        movzx   eax,al
        add     ecx,eax
        cld
        add     edx,ecx
        add     edx,2
        jmp     .whole_line
    .block_size_ok:
        mov     ecx,edx
        add     ecx,3
        ret
    .vertical_block:
        cmp     edi,[.caret_line_number]
        jb      .vboundaries_ok
        xchg    esi,eax
    .vboundaries_ok:
        cmp     ebx,edx
        jb      .hboundaries_ok
        xchg    ebx,edx
    .hboundaries_ok:
        add     ecx,edx
        sub     ecx,ebx
        add     ecx,2
        cmp     esi,eax
        je      .vertical_block_size_ok
        mov     esi,[esi]
        jmp     .hboundaries_ok
    .vertical_block_size_ok:
        inc     ecx
        ret
.find_text:
        push    edi edx
        add     edi,8
        mov     esi,[.search_text]
        test    byte [esi],AEFIND_BACKWARD
        jnz     .backward
        mov     ecx,100h
        sub     ecx,edx
        jz      .not_found
        add     edi,edx
        test    byte [esi],AEFIND_CASESENSITIVE
        jnz     .case_ok
        mov     esi,edi
        lea     edi,[.text_buffer]
        push    ecx
        mov     ebx,case_table
    .convert_case:
        lodsb
        xlatb
        stosb
        loop    .convert_case
        pop     ecx
        lea     edi,[.text_buffer]
        mov     esi,[.search_text]
    .case_ok:
        mov     edx,ecx
        cmp     ecx,[esi+4]
        jb      .not_found
    .search:
        mov     al,[esi+8]
        repne   scasb
        jne     .not_found
        mov     eax,[esi+4]
        dec     eax
        jz      .found
        cmp     ecx,eax
        jb      .not_found
        push    ecx esi edi
        mov     ecx,eax
        lea     esi,[esi+8+1]
        repe    cmpsb
        pop     edi esi ecx
        jne     .search
    .found:
        mov     eax,edx
        sub     eax,ecx
        dec     eax
        add     eax,[esp]
        test    byte [esi],AEFIND_WHOLEWORDS
        jz      .found_ok
        or      eax,eax
        jz      .left_bound_ok
        mov     ebx,[esp+4]
        push    eax
        mov     al,[ebx+8+eax-1]
        call    .recognize_character
        pop     eax
        jnc     .search
    .left_bound_ok:
        mov     ebx,[esi+4]
        add     ebx,eax
        cmp     ebx,100h
        je      .found_ok
        add     ebx,[esp+4]
        push    eax
        mov     al,[ebx+8]
        call    .recognize_character
        pop     eax
        jnc     .search
    .found_ok:
        pop     edx edi
        cld
        clc
        ret
    .backward:
        std
        or      edx,edx
        jz      .not_found
        mov     ecx,edx
        lea     edi,[edi+edx-1]
        mov     esi,[.search_text]
        test    byte [esi],AEFIND_CASESENSITIVE
        jnz     .backward_case_ok
        mov     esi,edi
        lea     edi,[.text_buffer+ecx-1]
        push    ecx
        mov     ebx,case_table
    .convert_case_backward:
        lodsb
        xlatb
        stosb
        loop    .convert_case_backward
        pop     ecx
        lea     edi,[.text_buffer+ecx-1]
        mov     esi,[.search_text]
    .backward_case_ok:
        cmp     ecx,[esi+4]
        jb      .not_found
    .backward_search:
        mov     eax,[esi+4]
        mov     al,[esi+8+eax-1]
        repne   scasb
        jne     .not_found
        mov     eax,[esi+4]
        dec     eax
        jz      .found_in_backward
        cmp     ecx,eax
        jb      .not_found
        push    ecx esi edi
        mov     ecx,eax
        lea     esi,[esi+8+eax-1]
        repe    cmpsb
        pop     edi esi ecx
        jne     .backward_search
    .found_in_backward:
        mov     eax,ecx
        inc     eax
        mov     ebx,eax
        sub     eax,[esi+4]
        test    byte [esi],AEFIND_WHOLEWORDS
        jz      .found_ok
        cmp     ebx,100h
        je      .right_bound_ok
        add     ebx,[esp+4]
        push    eax
        mov     al,[ebx+8]
        call    .recognize_character
        pop     eax
        jnc     .backward_search
    .right_bound_ok:
        or      eax,eax
        jz      .found_ok
        mov     ebx,[esp+4]
        push    eax
        mov     al,[ebx+8+eax-1]
        call    .recognize_character
        pop     eax
        jnc     .backward_search
        jmp     .found_ok
    .not_found:
        pop     edx edi
        cld
        stc
        ret

.store_status_for_undo:
        pusha
        cmp     [.was_selection],0
        jne     .selection_ok
        mov     [.sel_line],0

    .selection_ok:
        call    .allocate_line
        jc      .not_enough_memory
        mov     [eax],dword 0
        mov     edi,eax
        xchg    eax,[.undo_data]
        push    eax
        call    .allocate_line
        jnc     .store_editor_status
        or      eax,-1
        stosd
        jmp     .not_enough_memory

    .store_editor_status:
        mov     [eax],dword 0
        mov     [eax+4],dword 0
        stosd
        pop     eax
        stosd
        lea     esi,[.editor_data]
        mov     ecx,.editor_status_size shr 2
        rep     movsd
        popa
        clc
        ret

.store_line_for_undo:
        pusha
        cmp     [.current_line],0
        je      .line_for_undo_ok

        mov     [.Modified], TRUE       ; John Found 25.11.2003

        mov     esi,[.undo_data]
        or      esi,esi
        jz      .line_for_undo_ok
        mov     esi,[esi]
        mov     ecx,[esi+4]
        lea     edi,[esi+8+ecx*8]
        inc     ecx
        cmp     ecx,20h
        jbe     .slot_ok
        push    esi
        call    .allocate_line
        jc      .out_of_memory
        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
        mov     esi,[.current_line]
        mov     eax,[esi]
        cmp     eax,-1
        jne     .store_line
        stosd
        mov     eax,esi
        stosd
        jmp     .line_for_undo_ok
    .store_line:
        call    .allocate_line
        jc      .out_of_memory
        mov     ebx,eax
        stosd
        mov     eax,[.current_line]
        stosd
        mov     esi,eax
        mov     edi,ebx
        mov     ecx,108h shr 2
        rep     movsd
    .line_for_undo_ok:
        popa
        ret


.undo:
        mov     esi,[.undo_data]
        or      esi,esi
        jz      .undo_ok
        or      ebx,-1
        xchg    ebx,[esi]
        add     esi,4
        lodsd
        mov     [.undo_data],eax
        lea     edi,[.editor_data]
        mov     ecx,.editor_status_size shr 2
        rep     movsd
    .lines_block:
        or      ebx,ebx
        jz      .undo_ok
        mov     esi,ebx
        or      ebx,-1
        xchg    ebx,[esi]
        add     esi,4
        lodsd
        mov     ecx,eax
        jecxz   .undo_ok
        lea     esi,[esi+ecx*8]
    .restore_lines:
        sub     esi,8
        push    esi ecx
        mov     edi,[esi+4]
        mov     esi,[esi]
        or      esi,esi
        jz      .restore_next
        cmp     esi,-1
        jne     .restore_data
        mov     eax,esi
        stosd
        jmp     .restore_next
    .restore_data:
        mov     ecx,108h shr 2
        rep     movsd
        or      dword [esi-108h],-1
    .restore_next:
        pop     ecx esi
        loop    .restore_lines
        jmp     .lines_block
    .undo_ok:
        ret


.clear_undo_data:
        mov     esi,[.undo_data]
        or      esi,esi
        jz      .undo_data_ok
        or      ebx,-1
        xchg    ebx,[esi]
        add     esi,4
        lodsd
        mov     [.undo_data],eax
    .release_lines_block:
        or      ebx,ebx
        jz      .clear_undo_data
        mov     esi,ebx
        or      ebx,-1
        xchg    ebx,[esi]
        add     esi,4
        lodsd
        mov     ecx,eax
        jecxz   .clear_undo_data
        lea     esi,[esi+ecx*8]
    .release_lines:
        sub     esi,8
        mov     eax,[esi]
        cmp     eax,-1
        je      .release_next
        or      dword [eax],-1
    .release_next:
        loop    .release_lines
        jmp     .release_lines_block
    .undo_data_ok:
        mov     [.last_operation],0
        ret

endp

proc SyntaxProc, .lpLine, .lpColors
begin
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted include/libs/asmedit/asmedit.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

; AsmEdit styles

AES_AUTOINDENT   = 0001h
AES_SMARTTABS    = 0002h
AES_OPTIMALFILL  = 0004h
AES_SECURESEL    = 0008h
AES_AUTOBRACKETS = 0010h
AES_CONSOLECARET = 0020h
AES_INDENTSEL    = 0040h  ; indent/outdent selection by pressing tab/shift+tab

; AsmEdit messages

AEM_SETMODE            = WM_USER + 0   ; (modevalue, null)
AEM_GETMODE            = WM_USER + 1   ; (null, null): modevalue
AEM_SETSYNTAXHIGHLIGHT = WM_USER + 2   ; (syntaxcolors or 0, syntaxproc)
AEM_GETLINEDATA        = WM_USER + 3   ; (linenum, *buffer)
AEM_SETPOS             = WM_USER + 4   ; (*aepos, null)
AEM_GETPOS             = WM_USER + 5   ; (*aepos, null)
AEM_FINDFIRST          = WM_USER + 6   ; (flags, *string): found?
AEM_FINDNEXT           = WM_USER + 7   ; (null, null): found?
AEM_CANFINDNEXT        = WM_USER + 8   ; (null, null): found?
AEM_GETWORDATCARET     = WM_USER + 9   ; (sizeof, *buffer)
AEM_SETTEXTCOLOR       = WM_USER + 10  ; (fg, bg)
AEM_SETSELCOLOR        = WM_USER + 11  ; (fg, bg)
AEM_SETPOPUPMENU       = WM_USER + 12  ; (null, handle)
AEM_SETMARGINCOLOR     = WM_USER + 13  ; (bg, border)
AEM_SETMARGINWIDTH     = WM_USER + 14  ; (gap, width)
AEM_SETTHEME           = WM_USER + 15  ; (null, *aetheme)
AEM_TOGGLEBOOKMARK     = WM_USER + 16  ; (null, null): id
AEM_GOTOBOOKMARK       = WM_USER + 17  ; (id/null, aebm_?): linenum
AEM_CLEARBOOKMARKS     = WM_USER + 18  ; (null, null)
AEM_COMMENT            = WM_USER + 19  ; (null, true/false)
AEM_INDENT             = WM_USER + 20  ; (null, true/false)
AEM_SETLINEDATA        = WM_USER + 21  ; (linenum, *buffer)
AEM_GETLINEPTR         = WM_USER + 22  ; (linenum, 0):lineptr
AEM_GETMODIFIED        = WM_USER + 23  ; (null, null):modified
AEM_SETMODIFIED        = WM_USER + 24  ; (modified, null): old_modified
AEM_SETBOOKMARKICON    = WM_USER + 25  ; (handle, null)
AEM_GETCARETXY         = WM_USER + 26  ; (ptr AECARETXY, 0)
AEM_READONLY           = WM_USER + 27  ; (true/false, null): true/false
AEM_SETFOCUSLINE       = WM_USER + 28  ; (line, null)

; AsmEdit mode flags

AEMODE_OVERWRITE   = 1
AEMODE_VERTICALSEL = 2

; AsmEdit search flags

AEFIND_CASESENSITIVE = 1
AEFIND_WHOLEWORDS    = 2
AEFIND_BACKWARD      = 4

; AsmEdit bookmark constants

AEBM_NUM  = 0
AEBM_NEXT = 1
AEBM_PREV = 2

; AsmEdit notifications

AEN_SETFOCUS     = 01h
AEN_KILLFOCUS    = 02h
AEN_TEXTCHANGE   = 03h
AEN_POSCHANGE    = 04h
AEN_MODECHANGE   = 05h
AEN_OUTOFMEMORY  = 0Fh

; AsmEdit position structure

struct AEPOS
   .selectionPosition dd ?
   .selectionLine     dd ?
   .caretPosition     dd ?
   .caretLine         dd ?
ends

struct AECARETXY
  .x0 dd ?
  .y0 dd ?
  .x1 dd ?
  .y1 dd ?
ends

; AsmEdit theme structure
struc AETHEME tfg,tbg,sfg,sbg,mbg,mfg,mw,gw,focusfg,focusbg,synproc,[syn]
{
   common
     .text_color        dd tfg
     .text_background   dd tbg
     .sel_text          dd sfg
     .sel_background    dd sbg
     .margin_background dd mbg
     .margin_border     dd mfg
     .margin_width      dd mw
     .margin_gap        dd gw
     .focus_color       dd focusfg
     .focus_background  dd focusbg
     .syntax_proc       dd synproc
     .syntax_colors:
   forward
     if ~ syn eq
       dd syn
     end if
   common
     .syntax_colors_count = ($ - .syntax_colors) / 4
 }


macro Theme fontName, fontSize, fontCharset, asmeditStyle,      \
            tfg,tbg,sfg,sbg,mbg,mfg,mw,gw,focusfg,focusbg,[syn]
{
  common
    local ..fontN, ..theme, ..beg, ..size
  ..beg:
    dd ..fontN
    dd fontSize
    dd fontCharset
    dd asmeditStyle
    dd ..theme
    dd ..size
  common
    ..fontN db fontName, 0
            rb 256 - ($-..fontN)
    ..theme AETHEME tfg, tbg, sfg, sbg, mbg, mfg, mw, gw, focusfg, focusbg, 0, syn
  ..size = $ - ..beg
}



struct AELINE
  .next dd ?
  .prev dd ?
  .text rb 256
ends

; AsmEdit offsets in window extra memory.
ofsAsmEditMemory     = 0
ofsOpenFileStruct    = $c
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































Deleted include/libs/asmedit/syntax.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
ttText = 0
ttStr = 1
ttRem = 2
ttNum = 3
ttChar = 4

clDefaultText   = 0
clSymbol        = 1
clNumber        = 2
clString        = 3
clComment       = 4
clRegister      = 5
clInstruction   = 6
clDirective     = 7
clPreprocessor  = 8

SyntaxColorCount = 8

macro dps [txt] {
    forward
      if txt eq 0
        db 0
      else
        db txt
        db 0
        dw 0
      end if
  }


  struc synList minLen, maxLen, ptrlist {
    .MinLen  dd minLen
    .MaxLen  dd maxLen
    .ptrList dd ptrlist
  }

  virtual at 0
    synList synList 0, 0, 0
  end virtual


proc fasm_syntax, .ptrLine, .ptrColors
.status      dd ?
.wlen        dd ?
.w           rb 256
.lastword    dd ?
.Quo         db ?

; Sometimes, AsmEdit calls this procedure with wrong ptrLine.
; In these cases GPF appear.

begin
        pushad
        mov     [.status],ttText
        xor     ah,ah
        mov     [.wlen], 0
        mov     esi, [.ptrLine]
        mov     edi, [.ptrColors]
        mov     [.lastword], edi
        mov     ecx,256

.loop:
        lodsb
        cmp     [.status], ttRem
        je      .endif
        cmp     [.status], ttStr
        jne     .ifnotstr
        cmp     al,[.Quo]
        jne     .endif
        mov     [.status], ttText
        jmp     .endif

.ifnotstr:
        cmp     al, ';'
        jne     .notrem
        mov     [.status], ttRem
        mov     ah, clComment
        jmp     .endif

.notrem:
        cmp     al, '"'
        je      .str
        cmp     al, "'"
        jne     .notstr

.str:
        mov     [.status], ttStr
        mov     [.Quo], al
        mov     ah, clString
        jmp     .endif

.notstr:
        call    .CharInSymbols
        jnc     .notsym
        mov     [.status], ttChar
        mov     ah, clSymbol
        call    .MakeWord
        jmp     .endif

.notsym:
        lea     edx,[esi-1]
        cmp     edx, [.ptrLine]
        je      .maybenum

        cmp     [.status], ttChar
        jne     .notnumbeg

.maybenum:
        call    .CharInNum
        jnc     .notnum
        mov      [.status], ttNum
        mov      ah, clNumber
        jmp      .endif

.notnum:
        mov     [.status], ttText
        xor     ah,ah
        mov     [.wlen], 1
        mov     [.w], al
        mov     [.lastword], edi
        jmp     .endif

.notnumbeg:
        cmp     [.status], ttText
        jne     .endif
        xor     ah,ah
        lea     ebx, [.w]
        add     ebx, [.wlen]
        mov     [ebx], al
        inc     [.wlen]

.endif:
        mov     [edi], ah
        inc     edi
        dec     ecx
        jnz     .loop

.endwhile:
        popad
        return
endp



.MakeWord:
        push    edi esi eax ecx
        cmp     [.wlen],0
        je      .end
        lea     esi, [.w]
        push    esi edi
        lea     edi, [.w]
 .new_char:
        lodsb
        cmp     al,0
        je      .ok
        cmp     al,"A"
        jl      @F
        cmp     al,"Z"
        jg      @F
        add     al,20h
@@:
        stosb
        jmp     .new_char
.ok:
        pop     edi esi

        mov     ah, clRegister
        stdcall FindInstr, sSymbols, esi, [.wlen], 2, 0
        jnc     .maybeinstr

        cmp     dl, 10h
        je      .found

        mov     ah, clDirective
        jmp     .found

.maybeinstr:
        mov     ah, clInstruction
        stdcall FindInstr, sInstructions, esi, [.wlen], 3, 1
        jnc     .maybeoperator

        cmp     edx, fasm_instructions - instruction_handler
        jae     .found

        mov     ah, clDirective
        jmp     .found

.maybeoperator:
        mov     ah, clDirective
        stdcall SearchSimple, directive_operators, esi, [.wlen], 1
        jc      .found

        stdcall FindInstr, sDataDirectives, esi, [.wlen], 3, -1
        jc      .found

        mov     ah, clPreprocessor
        stdcall SearchSimple, preprocessor_directives, esi, [.wlen], 2
        jc      .found
        stdcall SearchSimple, macro_directives, esi, [.wlen], 2
        jnc     .notfound

.found:
        mov     ebx, [.wlen]
        mov     edi, [.lastword]

.chgcolor:
        mov     [edi], ah
        inc     edi
        dec     ebx
        jnz     .chgcolor

.notfound:
        and     [.wlen], 0

.end:
        pop     ecx eax esi edi
        retn


.CharInSymbols:
        push    edi ecx

        mov     edi, symbol_characters+1
        movzx   ecx, byte [edi-1]

        repne scasb
        jne   @f
        stc
        pop     ecx edi
        ret
@@:
        clc
        pop     ecx edi
        retn


.CharInNum:
        cmp     al, '$'
        jne     @f
        stc
        retn

@@:
        cmp     al, '0'
        jb      @f
        cmp     al, '9'
        ja      @f
        stc
        retn
@@:
        clc
        retn




proc FindInstr, .ptrArray, .ptrWord, .len, .addbytes, .return
.count dd ?
begin

        push    eax ebx ecx esi edi

        mov     ecx, [.ptrArray]
        mov     edi, [.ptrWord]
        mov     edx, [.len]

        cmp     edx, [ecx+synList.MinLen]
        jb      .notfound

        cmp     edx, [ecx+synList.MaxLen]
        ja      .notfound

        mov     esi, [ecx+synList.ptrList]

        sub     edx, [ecx+synList.MinLen]
        movzx   eax, word [esi+4*edx+2]       ; items count
        mov     [.count], eax
        movzx   ebx, word [esi+4*edx]         ; offset to esi
        add     esi, ebx
        mov     edx,[.len]
        add     edx, [.addbytes]

.loopmain:
        dec     [.count]
        js      .notfound

        xor     ebx, ebx

.loopword:
        mov     al,[esi+ebx]
        cmp     [edi+ebx], al
        ja      .next
        jb      .notfound
        inc     ebx
        cmp     ebx, [.len]
        jne     .loopword

        cmp     [.return], 0
        jl      .found

        lea     eax, [esi+ebx]
        add     eax, [.return]

        movsx   edx, word [eax]

.found:
        stc
        jmp     .end

.next:
        add     esi, edx
        jmp     .loopmain

.notfound:
        clc

.end:
        pop     edi esi ecx ebx eax
        return
endp



proc SearchSimple, .ptrList, .ptrWord, .len, .addbytes
.count dd ?
begin
        push    eax ecx edx esi edi

        mov     esi, [.ptrList]
        mov     edx, [.len]

.loopmain:
        lodsb
        test    al, al
        jz      .notfound

        cmp     al, dl
        jne     .next

        mov     edi, [.ptrWord]
        movzx   ecx, al
        repe    cmpsb
        je      .found

        add     esi, ecx
        add     esi, [.addbytes]
        jmp     .loopmain

.next:
        movzx   eax, al
        lea     esi, [esi+eax]
        add     esi, [.addbytes]
        jmp     .loopmain

.found:
        stc
        jmp     .end

.notfound:
        clc
.end:
        pop     edi esi edx ecx eax
        return
endp





iglobal
  sInstructions   synList 2, 16, instructions
  sSymbols        synList 2, 11, symbols
  sDataDirectives synList 2, 4, data_directives
endg
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































Deleted include/libs/buttonedit.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
cBtnEditPrecursor text 'EDIT'
cBtnEditPrecursor2 text 'BUTTON'


initialize RegisterButtoneditClass
.wc WNDCLASS
begin
        lea     eax, [.wc]
        invoke  GetClassInfoA, [hInstance], cBtnEditPrecursor, eax

        mov     [.wc.lpszClassName], cButtonEditClassName
        mov     eax, [.wc.cbWndExtra]
        mov     [ihButton], eax
        add     eax, 4
        mov     [.wc.cbWndExtra], eax

        mov     eax, [.wc.lpfnWndProc]
        mov     [ptrEditWindowProc], eax
        mov     [.wc.lpfnWndProc], ButtonEditProc

        invoke  GetModuleHandleA, 0
        mov     [.wc.hInstance], eax

        lea     eax,[.wc]
        invoke  RegisterClassA,eax
        return
endp

iglobal
  cButtonEditClassName text 'TButtonEdit'
endg

uglobal
  ptrEditWindowProc dd ?
  ihButton          dd ?
endg



proc ButtonEditProc, .hwnd, .wmsg, .wparam, .lparam
.rect RECT
begin
        push    ebx esi edi

        mov     ebx, [.wmsg]
        Messages                        \
        WM_CREATE, .wmcreate,           \
        WM_DESTROY, .wmdestroy,         \
        WM_SIZE,    .wmsize,            \
        WM_SETFONT, .wmsetfont,         \
        WM_COMMAND, .wmcommand,         \
\
        BEM_SETBUTTONTEXT, .bemsetbuttontext   ; (0, ptrText)

.default:
;        mov     esi, [ptrEditWindowProc]
        invoke  CallWindowProcA, [ptrEditWindowProc], [.hwnd], [.wmsg], [.wparam], [.lparam]

.finish:
        pop     edi esi ebx
        return

.bemsetbuttontext:
        invoke  GetWindowLongA, [.hwnd], [ihButton]
        invoke  SendMessageA, eax, WM_SETTEXT, 0, [.lparam]
        jmp     .finish

.wmcommand:
        mov     eax, [.wparam]
        cmp     ax, 1
        jne     .default

        shr     eax, 16
        cmp     eax, BN_CLICKED
        jne     .default


.click:
        invoke  GetParent, [.hwnd]
        mov     ebx, eax
        invoke  GetWindowLongA, [.hwnd], GWL_ID
        invoke  SendMessageA, ebx, BEM_BUTTONCLICK, eax, [.hwnd]
        xor     eax, eax
        jmp     .finish

.wmsetfont:
        invoke  GetWindowLongA, [.hwnd], [ihButton]
        invoke  SendMessageA, eax, WM_SETFONT, [.wparam], [.lparam]
        jmp     .default

.wmdestroy:
        invoke  GetWindowLongA, [.hwnd], [ihButton]
        invoke  DestroyWindow, eax
        jmp     .default

.wmcreate:
        invoke  CreateWindowExA, 0, cBtnEditPrecursor2, NULL, \
                                WS_VISIBLE or WS_CHILD or BS_TEXT or BS_VCENTER or BS_NOTIFY,                  \
                                0, 0, 16, 16, [.hwnd], 1, [hInstance], NULL
        mov     ebx, eax
        invoke  SetWindowLongA, [.hwnd], [ihButton], ebx

        invoke  SendMessageA, [.hwnd], WM_GETFONT, 0, 0
        invoke  SendMessageA, ebx, WM_SETFONT, 0, FALSE

        mov     eax, $00100000
        invoke  PostMessageA, [.hwnd], EM_SETMARGINS, EC_RIGHTMARGIN, eax
        jmp     .default


.wmsize:
        invoke  GetWindowLongA, [.hwnd], [ihButton]
        test    eax, eax
        jz      .default

        mov     ebx, eax
        lea     eax, [.rect]
        invoke  GetClientRect, [.hwnd], eax

        mov     esi, [.rect.right]
        sub     esi, [.rect.bottom]

        xor     edi, edi

        invoke  GetWindowLongA, ebx, GWL_STYLE
        test    eax, WS_BORDER
        jnz     @f

        inc     edi
        inc     esi
        sub     [.rect.bottom], 2

@@:
        invoke  SetWindowPos, ebx, 0, esi, edi, [.rect.bottom], [.rect.bottom], SWP_NOZORDER

        mov     eax, [.rect.bottom]
        and     eax, $ffff
        shl     eax, 16

        invoke  SendMessageA, [.hwnd], EM_SETMARGINS, EC_RIGHTMARGIN, eax
        jmp     .default
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































Deleted include/libs/buttonedit.inc.

1
2
3
4
; Button edit messages
;
BEM_SETBUTTONTEXT = WM_USER + $1000
BEM_BUTTONCLICK = WM_USER + $1001       ; (buttonedit ID, buttonedit HWND)
<
<
<
<








Deleted include/libs/giflib.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
GifLib:

;===============================================================================
;       FreshGif v1.2 - (C) Copyright by Exagone
;===============================================================================
; The included Fresh artistic license (see license.txt) applies to this source
; code. By using this code, you agree to the terms of the license.
;
; Original source code by Exagone
; http://exagone.cjb.net | http://www.exagone.org
; _thomas_@mailroom.com
;===============================================================================
; (c)2004 John Found - Port for FASM/Fresh cleanup and improvements.
; http://flatassembler.net
; http://fresh.flatassembler.net
;===============================================================================


struct TGifInfo
;--- Header ---
  .GIFVersion       rb      3    ; 3 byte string (not 0-terminated) that identifies
                                 ; the GIF Version (like 97a or 98a)
; --- Logical screen descriptor ---
  .dwLSWidth        dd      ?    ; Logical screen width
  .dwLSHeight       dd      ?    ; Logical screen height
                                 ; NOTE: Use ImageWidth/Height to find the dimensions,
                                 ; This one can be different from the logical screen
                                 ; width and height.
; --- Color info ---
  .lpColorTable     dd      ?    ; Pointer to the color table
  .ColorCount       dd      ?    ; Number of colors in image (and color table)
  .fTransparent     dd      ?    ; if TRUE - the image have transparent color.
  .iTrasparentColor dd      ?    ; index of transparent color in the color table.

; --- Image info ---
  .dwImageWidth     dd      ?    ; Width of image
  .dwImageHeight    dd      ?    ; Height of image

; --- Image data ---
  .lpImageData      dd      ?    ; Pointer to the actual image data

; --- Input data ---
  .lpGIFData        dd      ?    ; Pointer to the GIF File data
  .dwGIFDataSize    dd      ?    ; Size of GIF Data

; --- Internal data ---
; Don't touch this data below, it is used internally by GIFLIB
  .lpLZWTable       dd      ?    ; Pointer to LZW Table
  .dwLZWTableSize   dd      ?    ; Current maximum size of table
                                 ; This size is dynamic and changes
                                 ; if the codesize exceeds 9 bits

  .dwLZWTableCount  dd      ?    ; Current nr of entries in the LZW table
  .fGlobalCTable    db      ?    ; If set, the GIF file has a global color table
  .dbGCTableSize    db      ?    ; Size of the global color table, if available
  .fLocalCTable     db      ?    ; If set, the first image has a local color table
  .dbLCTableSize    db      ?    ; Size of the local color table, if available
  .lpGIFImage       dd      ?    ; Pointer to the first real image data(Table based image data)
  .lpCurrentByte    dd      ?    ; Pointer to the current byte (used with decompression)
                                 ; note: if this value is -1, end of the file is reached and
                                 ; the code-supplier returns 0 as padding

  .dbBitsAvailable  db      ?    ; Nr of codebits currently available
  .dbCurBitSize     db      ?    ; Current LZW code size
  .dbInitBitSize    db      ?    ; Initial LZW code size
  .lpLastEOSB       dd      ?    ; Pointer to end of current subblock (used with decompression)
  .dwLZWClear       dd      ?    ; Value of LZW Clear code (CC)
  .CurrentBits      dd      ?    ; Holds the current bits loaded
  .IsFirstCode      db      ?    ; Indicates if the first code is being read now
  .PixelCounter     dd      ?    ; Counts nr of PIXELS outputted
ends

EXTENSIONBLOCK           =  021h
IMAGEDESCRIPTOR          =  02Ch
GRAPHICCONTROLEXTENSTION =  0F9h
COMMENTEXTENSION         =  0FEh
PLAINTEXTEXTENSION       =  001h
APPLICATIONEXTENSION     =  0FFh



proc LoadGif, .hInst, .ptrName
.gifinfo TGifInfo
begin
        lea     eax, [.gifinfo]
        stdcall DoLoadGif, [.hInst], [.ptrName], eax
        return
endp


;--------------------------------------------------------------
; You should use gui.asm if you want to call this function
;--------------------------------------------------------------
proc ImageList_LoadGif, .hInst, .ptrName, .width, .fDisabled
.gifinfo TGifInfo
.result     dd ?
.colorback  dd ?
begin
        push    esi edi ebx
        mov     [.result], 0

        invoke  GetSysColor, COLOR_BTNFACE
        mov     [.colorback], eax

        lea     edi, [.gifinfo]

        stdcall DoLoadGif, [.hInst], [.ptrName], edi
        test    eax, eax
        jz      .quit
        mov     ebx, eax

        mov     eax, [edi+TGifInfo.dwImageWidth]
        cmp     [.width], -1
        jne     @f
        mov     [.width], eax
@@:
        invoke  ImageList_Create, [.width], [edi+TGifInfo.dwImageHeight],  ILC_COLOR32 or ILC_MASK, 0, 1
        test    eax, eax
        jz      .quitclean

        mov     [.result], eax

        mov     ecx, $ff010101
        cmp     [edi+TGifInfo.fTransparent], 0
        je      @f
        mov     ecx, [edi+TGifInfo.iTrasparentColor]
        lea     ecx, [ecx+2*ecx]
        add     ecx, [edi+TGifInfo.lpColorTable]
        mov     ecx, [ecx]
        and ecx, $00ffffff
@@:
        push    ecx

        cmp     [.fDisabled], 0
        je      @f

        stdcall DisableBitmap, ebx, [.width], ecx, [.colorback], ecx
        xchg    eax, ebx
        invoke  DeleteObject, eax

@@:
        invoke  ImageList_AddMasked, [.result], ebx     ; , ecx from the stack

.quitclean:
        invoke  DeleteObject, ebx
.quit:
        mov     eax, [.result]
        pop     ebx edi esi
        return
endp



proc DoLoadGif, .hInst, .ptrName, .ptrGifInfo
.bitmapinfo BITMAPINFOHEADER
.result     dd ?
begin
        push    esi edi
        mov     [.result], 0

        mov     edi, [.ptrGifInfo]
        lea     esi, [.bitmapinfo]

        stdcall GIFLoadResource, edi, [.hInst], [.ptrName]
        jz      .quit

        stdcall GIFLoadHeader, edi
        jz      .quit

        stdcall GIFInitalizeDecoder, edi
        jz       .quit

        stdcall GIFFillBitmapInfoStruct, edi, esi

        lea     eax, [edi+TGifInfo.lpImageData]
        invoke  CreateDIBSection, NULL, esi, DIB_RGB_COLORS, eax, NULL, NULL
        test    eax, eax
        jz      .quit

        mov     [.result], eax

        stdcall GIFDecompress, edi
        jz      .quit

        stdcall GIFCleanup, edi

.quit:
        mov     eax, [.result]
        pop     edi esi
        return
endp



proc GIFCreateBitmap, .ptrGIFFile, .szGIFFile
.bitmapinfo BITMAPINFOHEADER
.result     dd ?
.GifInfo  TGifInfo
begin
        push    esi edi
        mov     [.result], 0

        lea     edi, [.GifInfo]
        lea     esi, [.bitmapinfo]


        mov     eax, [.ptrGIFFile]
        mov     ecx, [.szGIFFile]
        mov     [edi+TGifInfo.lpGIFData], eax
        mov     [edi+TGifInfo.dwGIFDataSize], ecx

        stdcall GIFLoadHeader, edi
        jz      .quit

        stdcall GIFInitalizeDecoder, edi
        jz       .quit

        stdcall GIFFillBitmapInfoStruct, edi, esi

        lea     eax, [edi+TGifInfo.lpImageData]
        invoke  CreateDIBSection, NULL, esi, DIB_RGB_COLORS, eax, NULL, NULL
        test    eax, eax
        jz      .quit

        mov     [.result], eax

        stdcall GIFDecompress, edi
        jz      .quit

        stdcall GIFCleanup, edi

.quit:
        mov     eax, [.result]
        pop     edi esi
        return
endp


;===============================================================================
;       GIFLoadResource
;===============================================================================
; Loads gif data from a resource (of type RT_RCDATA)
; lpName:pointer to a resource name OR resource ID
proc GIFLoadResource, .lpGifInfo, .hInst, .lpName
begin
        push    esi edi ebx
        mov     esi, [.lpGifInfo]

        invoke  FindResourceA, [.hInst], [.lpName], RT_RCDATA
        test    eax,eax
        jz      .exit

        mov     ebx, eax

        invoke  LoadResource, [.hInst], eax
        test    eax, eax
        jz      .exit

        mov     [esi+TGifInfo.lpGIFData], eax

        invoke  SizeofResource, [.hInst], ebx
        test    eax, eax
        jz      .exit

        mov     [esi+TGifInfo.dwGIFDataSize], eax
        xor     eax, eax
        inc     eax

.exit:
        pop     ebx edi esi
        return
endp

;===============================================================================
;       GIFLoadFile
;===============================================================================
; Loads gif data from a file
; SHOULD CLEANUP POINTER AFTERWARDS (globalalloc)
proc GIFLoadFile, .lpGifInfo, .lpFile
.hFile  dd  ?
.bRead  dd  ?
begin
        mov     esi, [.lpGifInfo]

        stdcall FileOpen, [.lpFile]
        jc      .false

        mov     [.hFile], eax
        stdcall FileSeek, eax, 0, fsFromEnd
        jc      .closefalse

        mov     [esi+TGifInfo.dwGIFDataSize], eax

        stdcall GetMem, [esi+TGifInfo.dwGIFDataSize]
        jc      .closefalse

        mov     [esi+TGifInfo.lpGIFData], eax

        stdcall FileSeek, [.hFile], 0, fsFromBegin
        stdcall FileRead, [.hFile], [esi+TGifInfo.lpGIFData], [esi+TGifInfo.dwGIFDataSize]

.closefalse:
        pushf
        stdcall FileClose, [.hFile]
        xor             eax, eax
        popf
        cmc
        adc     eax, 0
        return

.false:
        xor     eax, eax
        return
endp



;===============================================================================
;       GIFCleanup
;===============================================================================
; Cleanup
;
proc GIFCleanup, .lpGifInfo
begin
        push    esi
        mov     esi, [.lpGifInfo]
        stdcall FreeMem, [esi+TGifInfo.lpLZWTable]
        pop     esi
        return
endp



;===============================================================================
;       GIFFillBitmapInfoStruct
;===============================================================================
;  Fills a bitmap info structure width the given properties or automatically
proc GIFFillBitmapInfoStruct, .lpGifInfo, .lpBIH
begin
        push    esi edi
        mov     esi, [.lpGifInfo]
        mov     edi, [.lpBIH]

        mov     [edi+ BITMAPINFOHEADER.biSize], sizeof.BITMAPINFOHEADER
        mov     eax, [esi+TGifInfo.dwImageHeight]
        mov     ecx, [esi+TGifInfo.dwImageWidth]
        neg     eax                                     ;negative because it outputs a top-down bitmap
        mov     [edi+BITMAPINFOHEADER.biWidth], ecx
        mov     [edi+BITMAPINFOHEADER.biHeight], eax

        mov     [edi+BITMAPINFOHEADER.biPlanes], 1
        mov     [edi+BITMAPINFOHEADER.biBitCount], 32
        xor     eax, eax
        mov     [edi+BITMAPINFOHEADER.biCompression], BI_RGB
        mov     [edi+BITMAPINFOHEADER.biSizeImage], eax
        mov     [edi+BITMAPINFOHEADER.biXPelsPerMeter], eax
        mov     [edi+BITMAPINFOHEADER.biYPelsPerMeter], eax
        mov     [edi+BITMAPINFOHEADER.biClrUsed], eax
        mov     [edi+BITMAPINFOHEADER.biClrImportant], eax

        pop     edi esi
        return
endp




;===============================================================================
;       GIFDecompress
;===============================================================================
; Decompresses the gif and outputs
; returns:
; 0  - color format not allowed
; 1  - success
; -1 - failed
proc GIFDecompress, .lpGifInfo
begin
        push    esi edi ebx

        mov     esi, [.lpGifInfo]
        mov     edi, [esi+TGifInfo.lpImageData]

        ; --- Initially, load 4 bytes ---
        mov     [esi+TGifInfo.CurrentBits], 0
        mov     [esi+TGifInfo.dbBitsAvailable], 0

        mov     ebx, 4
.while:
        stdcall LoadNextByte, esi
        dec     ebx
        jne     .while

        stdcall DECInitialize, esi
        stdcall DECDecodeGIF, [.lpGifInfo]

        xor     eax, eax
        inc     eax
        pop     ebx edi esi
        return

.qfalse:
        xor     eax, eax
        pop     ebx edi esi
        return
endp

;===============================================================================
;       DECDecodeGIF
;===============================================================================
; The actual decoder
;
proc DECDecodeGIF, .lpGifInfo
 .OldCode            dd ?
 .FirstCharOfOldCode db ?
 .FirstCharOfCode    db ?
 .dummyalign         dw ?
 .NrCodesToOutput    dd ?
begin
        push    esi edi ebx

        mov     esi, [.lpGifInfo]

        ; --- set counters ---
        mov     [esi+TGifInfo.PixelCounter], 0   ;0 codes outputted
        mov     eax, [esi+TGifInfo.dwImageWidth]
        mul     [esi+TGifInfo.dwImageHeight]
        mov     [.NrCodesToOutput], eax    ;this is an OUTPUT CODE counter, not nr of compressed codes

; LZW Decompression
;     [1] Initialize string table;
;     [2] get first code: <code>;
;     [3] output the string for <code> to the charstream;
;     [4] <old> = <code>;
;     [5] <code> <- next code in codestream;
;     [6] does <code> exist in the string table?
;      (yes: output the string for <code> to the charstream;            (A)
;            [...] <- translation for <old>;                            (B)
;            K <- first character of translation for <code>;            (C)
;            add [...]K to the string table;                            (D)
;                        <old> <- <code>;  )                            (E)
;      (no: [...] <- translation for <old>;                             (F)
;           K <- first character of [...];                              (G)
;           output [...]K to charstream and add it to string table;     (H)
;           <old> <- <code>                                             (I)
;      )
;     [7] go to [5];

.mainloop:
        mov     eax, [.NrCodesToOutput]
        cmp     eax, [esi+TGifInfo.PixelCounter]
        je      .endloop

        stdcall GetNextCode, esi                        ; [1] and [5]
        mov     ebx, eax
        cmp     ebx, [esi+TGifInfo.dwLZWClear]          ; Check for clearcode
        jne     .noclear

        stdcall DECResetLZW, esi                ; Reset LZW
        jmp     .mainloop

.noclear:
       cmp      [esi+TGifInfo.IsFirstCode], 1   ; Checks if steps [1]-[4] have to be done
       jne      .notfirst

       dec      [esi+TGifInfo.IsFirstCode]      ;[2]
       stdcall  DECOutputString, esi, ebx       ;[3]
       mov      [.FirstCharOfOldCode], al       ; saved for (G)
       mov      [.OldCode], ebx                 ;[4]
       jmp      .mainloop

.notfirst:
       cmp     [esi+TGifInfo.dwLZWTableCount], ebx  ; [6]   ; DECIsCodeInTable replacement
       jbe     .notintable

       stdcall  DECOutputString, esi, ebx           ;(B)
       mov      [.FirstCharOfCode], al              ;(C)
       mov      [.FirstCharOfOldCode], al           ; saved for (G)
       stdcall  DECAddToTable, esi, [.OldCode], eax ;(D)
       mov      [.OldCode], ebx
       jmp      .mainloop

.notintable:                                        ;(F)-(I)
       mov      al, [.FirstCharOfOldCode]           ; (G)
       stdcall  DECAddToTable, esi, [.OldCode], eax ;(H)
       stdcall  DECOutputString, esi, ebx           ;(H)
       mov      [.FirstCharOfOldCode], al           ; saved for (G)
       mov      [.OldCode], ebx
       jmp      .mainloop

.endloop:
       xor     eax, eax
       inc     eax
       pop     ebx edi esi
       return
endp


;===============================================================================
; DECAddToTable
;===============================================================================
; Adds an entry to the LZW Table
; The enry consists of a prefix and a suffix (size is calculated automatically)
; returns the code for the new entry
proc DECAddToTable, .lpGifInfo, .dwPrefix, .dbSuffix
begin
        push    esi edi ebx

        mov     esi, [.lpGifInfo]

        ; --- Check if enough space in the table left
        mov     ecx, [esi+TGifInfo.dwLZWTableSize]
        mov     ebx, [esi+TGifInfo.dwLZWTableCount]

        push    ebx
        shl     ebx, 2

        ; --- If no space left, make the table bigger:
        cmp     ebx, ecx
        jne     .sizeok

        shl     ecx, 1          ;Table size doubles
        mov     [esi+TGifInfo.dwLZWTableSize], ecx

        ; --- Reallocate memory ---
        stdcall ResizeMem, [esi+TGifInfo.lpLZWTable], ecx
        mov     [esi+TGifInfo.lpLZWTable], eax

.sizeok:
        ; --- Create pointer to first free entry ---
        add     ebx, [esi+TGifInfo.lpLZWTable]

        ; --- Find out the size of the string ---
        mov     eax, [.dwPrefix]
        shl     eax, 2
        add     eax, [esi+TGifInfo.lpLZWTable]
        mov     eax, [eax]
        shr     eax, 8
        and     eax, 0FFFh      ;eax now holds the size of the prefix string
        inc     eax

        ; --- Create the entry DWORD ---
        ; (see DECResetLZW for the format)
        mov     ecx, [.dwPrefix]
        shl     ecx, 20
        shl     eax, 8
        or      ecx, eax
        mov     eax, [.dbSuffix]
        and     eax, 0ffh
        or      ecx, eax

        ; --- Store entry ---
        mov     [ebx], ecx

        inc     [esi+TGifInfo.dwLZWTableCount]

        pop     ebx     ;get saved code of new entry

        mov     cl, [esi+TGifInfo.dbCurBitSize]
        xor     eax, eax
        inc     eax
        shl     eax, cl
        dec     eax
        cmp     eax, ebx
        jne     @f

        ;bitsize should be increased
        inc     [esi+TGifInfo.dbCurBitSize]   ;increase bitsize

@@:
        mov     eax, ebx
        pop     ebx edi esi
        return
endp


;===============================================================================
; DECOutputString
;===============================================================================
; Writes the string of dwCode to the output stream
; returns the first character of the string in al
;
proc DECOutputString, .lpGifInfo, .dwCode
.LastChar     db ?
begin
        push    esi edi ebx

        mov     esi, [.lpGifInfo]
        mov     edi, [esi+TGifInfo.lpLZWTable]  ; --- Set basepointer ---

        mov     eax, [.dwCode]                   ; --- Get entry ---

        mov     ebx, [edi+4*eax]                ; --- Get size of string ---
        shr     ebx, 8                          ; See the description of LZW table below.
        and     ebx, $0fff

; --- Output all codes backwards ---
        mov     edx, [esi+TGifInfo.PixelCounter]
        shl     edx, 2
        add     edx, [esi+TGifInfo.lpImageData]         ; edx is base pointer in the image data.

        add     [esi+TGifInfo.PixelCounter], ebx        ; update the pixel counter.
        dec     ebx                                     ; ebx is the counter and index in image data.

        mov     esi, [esi+TGifInfo.lpColorTable]        ; We don't need TGifInfo anymore.

.outloop:
        mov     eax, [edi+4*eax]
        mov     [.LastChar], al

; Get the color from the color table - esi points to 3 byte  palette array.
        movzx   ecx, al
        lea     ecx, [ecx+2*ecx]  ; = 3*ecx
        mov     ecx, [esi+ecx]
        bswap   ecx
        shr     ecx, 8

; Draw the pixel.
        mov     [edx+4*ebx], ecx

        shr     eax, 20         ; Get the prefix index in the LZW table.
        and     eax, $0fff

        dec     ebx
        jns     .outloop

        mov     al, [.LastChar]
        pop     ebx edi esi
        return
endp



;===============================================================================
; GetNextCode
;===============================================================================
; retrieves the next code from the compressed data stream and loads new bits
; if needed.
proc GetNextCode, .lpGifInfo
begin
        push    esi edi ebx

        mov     esi, [.lpGifInfo]
        mov     ebx, [esi+TGifInfo.CurrentBits]

        ; --- Create bitmask for current nr of bits ---
        mov     cl, [esi+TGifInfo.dbCurBitSize]
        xor     eax, eax
        inc     eax
        shl     eax, cl
        dec     eax

        ; --- AND ebx with bitmask ---
        and     ebx, eax

        ; --- Shift used bits ---
        mov     cl, [esi+TGifInfo.dbCurBitSize]
        shr     [esi+TGifInfo.CurrentBits], cl

        ; --- Decrease # of bits available ---
        sub     [esi+TGifInfo.dbBitsAvailable], cl

        ; --- Load as many bits as possible ---
.while:
        cmp     [esi+TGifInfo.dbBitsAvailable], 24
        ja      .endwhile
        stdcall LoadNextByte, esi
        jmp     .while

.endwhile:
        ; --- Return bits ---
        mov     eax, ebx
        pop     ebx edi esi
        return
endp


;===============================================================================
; LoadNextByte
;===============================================================================
; Loads the currentbits entry with new bits
;
proc LoadNextByte, .lpGifInfo
begin
        push    esi edi ebx
        mov     esi, [.lpGifInfo]

        ; --- Get next byte from datastream ---
        mov     edi, [esi+TGifInfo.lpCurrentByte]
        cmp     edi, -1
        jne     .notend

;end of data already reached
        xor     al, al  ;return 0 as padding
        jmp     .gotbyte

;End of subblock reached?
.notend:
        cmp      edi, [esi+TGifInfo.lpLastEOSB]
        jne      .noteosb

        xor      eax, eax
        mov      al, [edi]       ; new subblock size
        test     al,al
        jnz      .sizeok

        ; if size=0, end of data
        mov      [esi+TGifInfo.lpCurrentByte], -1 ;EOF indicator
        jmp      .gotbyte

.sizeok:
        inc      edi             ; new subblock with size al
        add      eax, edi
        mov      [esi+TGifInfo.lpLastEOSB], eax  ;set new end of subblock
        add      [esi+TGifInfo.lpCurrentByte], 2
        mov      al, [edi]
        jmp      .gotbyte

.noteosb:
        mov      al, [edi]                       ;get next byte
        inc      [esi+TGifInfo.lpCurrentByte]    ;increase for next read

        ; --- Got the new byte from the datasteam ---
.gotbyte:
        mov      cl, [esi+TGifInfo.dbBitsAvailable] ;Get nr of bits available
        mov      edx, [esi+TGifInfo.CurrentBits]    ;Get current bits
        and      eax, 0ffh                          ;eax = al
        shl      eax, cl                            ;Shift bits to right position
        or       edx, eax                           ;OR new bits with current bits
        mov      [esi+TGifInfo.CurrentBits], edx    ;Save bits
        add      [esi+TGifInfo.dbBitsAvailable], 8  ;Set new bits avaialble

        pop     ebx edi esi
        return
endp


;===============================================================================
;       DECInitialize
;===============================================================================
; Initializes the decoder (table for LZW etc)
;
proc DECInitialize, .lpGifInfo
begin
        push    esi edi

        mov     esi, [.lpGifInfo]
        mov     edi, [esi+TGifInfo.lpGIFImage]

        ; --- Get initial LZW code size ---
        mov     cl, [edi]
        inc     cl
        mov     [esi+TGifInfo.dbInitBitSize], cl

        ; --- Set current bit size to initial bitsize ---
        mov     [esi+TGifInfo.dbCurBitSize], cl

        ; --- Set size of LZW table ---

        cmp     cl, 8
        jae     @f    ;if initial code size is less than 8-bits,
        mov     cl, 8 ;set to 8-bits, if higher, don't change it
@@:
        ; Calculate size of codetable:
        xor     eax, eax
        inc     eax
        add     cl, 2           ; bitsize + 2
        shl     eax, cl         ; eax = 2 ^ (bitsize + 2) = 4 * (2^bitsize)
        mov     [esi+TGifInfo.dwLZWTableSize], eax

        ; --- Allocate memory for LZW Table and store pointer ---
        stdcall GetMem, eax
        mov     [esi+TGifInfo.lpLZWTable], eax

        ; --- Reset LZW ---
        stdcall DECResetLZW, esi

        xor     eax, eax
        inc     eax
        pop     edi esi
        return
endp



;===============================================================================
; DECResetLZW
;===============================================================================
; Resets the LZW Table and variables (this is the proper action for a clear
; code (CC) in data
proc DECResetLZW, .lpGifInfo
begin
        push    esi edi ebx
        mov     esi, [.lpGifInfo]

; The LZW table has the following format:
; An array of DWORDS represents an array of string entries
; One entry consists of a prefix code (which is an index to
; another entry that should prefix the entry), a string length,
; and the suffix byte (this byte should be added to the prefix
; to get the full string).
; DWORD:
; | AAAA AAAA | AAAA BBBB | BBBB BBBB | CCCC CCCC |
; ^                                               ^
; MSB                                           LSB
; AAAAAAAAAAAA:  12-bit index in the LZW Table that indicates the prefix
; BBBBBBBBBBBB:  12-bit length of the string
; CCCCCCCC    :   8-bit suffix byte

        ; --- reset LZW Table ---
        ; Reset bit size:

        mov     cl, [esi+TGifInfo.dbInitBitSize]
        mov     [esi+TGifInfo.dbCurBitSize], cl

        ; Get initial nr of entries
        ;mov            eax, [esi].ColorCount
        ;NOTE: THE LINE ABOVE WAS PREVIOUSLY USED TO GET THE NR OF ROOT ENTRIES
        ; THIS DIDN'T WORK BECAUSE 1-BIT GIF'S ARE FOR AN UNKNOWN REASON CODED
        ; AS 2-BIT GIFS, SO THE NR OF ROOT ENTRIES HAS TO BE DETERMINED FROM THE
        ; INITIAL BITSIZE
        dec     cl
        xor     eax, eax
        inc     eax
        shl     eax, cl         ; 2**codesize
        add     eax, 2
        mov     [esi+TGifInfo.dwLZWTableCount], eax
        mov     edx, [esi+TGifInfo.lpLZWTable]
        ; Fill first {2**codcesize+2} entries
        shl     eax, 2
        add     eax, edx
        xor     ecx, ecx
        inc     ch                      ;size of sting is set to 1

.fill:
        mov     [edx], ecx
        inc     cl
        add     edx, 4
        cmp     edx, eax
        jb      .fill

        ; --- set clear code ---
        mov     eax, [esi+TGifInfo.dwLZWTableCount]
        sub     eax, 2
        mov     [esi+TGifInfo.dwLZWClear], eax
        mov     [esi+TGifInfo.IsFirstCode], 1

        ;lpLZWTable             dd      ?   ; Pointer to LZW Table
        ;dwLZWTableSize         dd      ?   ; Current maximum size of table
        ;dwLZWTableCount        dd      ?   ; Current nr of entries in the LZW table
        ;dbCurBitSize           db      ?   ; Current LZW code size
        ;dbInitBitSize          db      ?   ; Initial LZW code size
        ;dwLZWClear             dd      ?   ; Value of LZW Clear code (CC)

        xor     eax, eax
        inc     eax
        pop     ebx edi esi
        return
endp



;===============================================================================
;       GIFLoadHeader
;===============================================================================
; Loads header and logical screen descriptor
;
proc GIFLoadHeader, .lpGifInfo
begin
        push    esi edi ebx
        mov     esi, [.lpGifInfo]

        ; --- EDI points to GIF Data, EBX is size of data ---
        mov     edi, [esi+TGifInfo.lpGIFData]
        mov     ebx, [esi+TGifInfo.dwGIFDataSize]

        cmp     ebx, 11
        jb      .failed ; ebx smaller than header & Logical screen descr. -> invalid GIF

        ; --- Check first 3 bytes ("GIF" signature) ---
        mov     eax, [edi]
        and     eax, $00ffffff
        cmp     eax, 'GIF'
        jne     .failed

        ; --- Copy version number ---
        lea     ecx, [esi+TGifInfo.GIFVersion]
        mov     ax, [edi+3]
        mov     [ecx], ax
        mov     al, [edi+5]
        mov     [ecx+2], al

        ; --- Copy logical screen sizes ---
        xor     eax, eax
        mov     ax, [edi+6]                     ;Get Logical screen width
        mov     [esi+TGifInfo.dwLSWidth], eax
        mov     ax, [edi+8]                     ;Get Logical screen width
        mov     [esi+TGifInfo.dwLSHeight], eax

        ; --- Set global color table flag and size ---
        mov     cl, [edi+10]
        mov     al, cl
        rol     al, 1
        and     al, 1
        mov     [esi+TGifInfo.fGlobalCTable], al
        and     cl, 111b
        mov     [esi+TGifInfo.dbGCTableSize], cl

        xor     eax, eax
        inc     eax
        pop     ebx edi esi
        return

.failed:
        xor     eax, eax
        pop     ebx edi esi
        return
endp



;===============================================================================
;       GIFInitalizeDecoder
;===============================================================================
; Initializes decoder
;
proc GIFInitalizeDecoder, .lpGifInfo
begin
        push    esi edi ebx
        mov     esi, [.lpGifInfo]

        ; --- EDI points to GIF Data, EBX to end of data ---
        mov     edi, [esi+TGifInfo.lpGIFData]
        mov     ebx, [esi+TGifInfo.dwGIFDataSize]
        add     ebx, edi

        add     edi, 13         ; skip header and local screen descriptor

        ; --- Get global color tablesize in bytes ---
        mov     cl, [esi+TGifInfo.dbGCTableSize]
        inc     cl
        xor     eax, eax
        inc     eax
        shl     eax, cl
        mov     ecx, eax
        shl     ecx, 1          ;--+--> ecx * 3
        add     ecx, eax        ;--+

        ; --- Skip global color table if available ---
        cmp     [esi+TGifInfo.fGlobalCTable], 0
        je      @f
        add     edi, ecx
@@:
        cmp     edi, ebx
        jae     .failed

        ; --- Search through the GIF blocks for the first graphic block ---
.scanloop:
        cmp     edi, ebx
        jae     .failed

        mov     al, [edi]
        cmp     al, EXTENSIONBLOCK
        jne     .maybe

        stdcall SkipExtension, edi, ebx
        mov     edi, eax
        jmp     .scanloop

.maybe:
        cmp     al, IMAGEDESCRIPTOR
        jne     .scanloop               ; BUG: loop forever on some circumstances...

        stdcall ProcessImageDescriptor, [.lpGifInfo], edi, ebx
        add     edi, 11
        stdcall SkipSubBlocks, edi

        xor     eax, eax
        inc     eax
.quit:
        pop     ebx edi esi
        return

.failed:
        xor     eax, eax
        jmp     .quit
endp



;===============================================================================
; ProcessImageDescriptor
;===============================================================================
; Processes an image desriptor block
proc ProcessImageDescriptor, .lpGifInfo, .lpStart, .lpEOF
begin
        push    esi edi
        mov     esi, [.lpGifInfo]

        mov     edx, [.lpStart]
        xor     eax, eax

        ; --- copy image width & height ---
        mov     ax, [edx+5]
        mov     [esi+TGifInfo.dwImageWidth], eax
        mov     ax, [edx+7]
        mov     [esi+TGifInfo.dwImageHeight], eax

        ; --- look for local color table ---
        mov     cl, [edx+9]
        mov     al, cl
        rol     cl, 1
        and     cl, 1
        mov     [esi+TGifInfo.fLocalCTable], cl
        and     al, 111b
        mov     [esi+TGifInfo.dbLCTableSize], al

        ; --- Find out which color table to use ---
        cmp     cl, 1
        jne     .setglobal

        ;local color table available
        ; --- Set color count ---
        mov     cl, [esi+TGifInfo.dbLCTableSize]
        inc     cl
        xor     eax, eax
        inc     eax
        shl     eax, cl
        mov     [esi+TGifInfo.ColorCount], eax
        ; --- Set color table pointer ---
        mov     eax, edx
        add     eax, 10 ;move to the local color table
        mov     [esi+TGifInfo.lpColorTable], eax
        jmp     .ctableok

.setglobal:
        ;no local color table, use global color table
        ; --- Set color count ---
        mov     cl, [esi+TGifInfo.dbGCTableSize]
        inc     cl
        xor     eax, eax
        inc     eax
        shl     eax, cl
        mov     [esi+TGifInfo.ColorCount], eax
        ; --- Set color table pointer ---
        mov     eax, [esi+TGifInfo.lpGIFData]
        add     eax, 13 ;move to the global color table (at offset 13 in file)
        mov     [esi+TGifInfo.lpColorTable], eax

.ctableok:
        ; --- Set pointer to real image data (table based image data)
        mov     eax, edx
        add     eax, 10                                 ;Skip image descriptor

        cmp     [esi+TGifInfo.fLocalCTable], 0
        je      .setptr

        mov     ecx, [esi+TGifInfo.ColorCount]   ;-+
        add     eax, ecx                         ; + add size of colortable
        shl     ecx, 1                           ; + (colorcount * 3)
        add     eax, ecx                         ;-+

.setptr:
        mov     [esi+TGifInfo.lpGIFImage], eax

        ; --- Set some pointers to initialize the decompressor
        inc     eax
        mov     [esi+TGifInfo.lpLastEOSB], eax
        mov     [esi+TGifInfo.lpCurrentByte], eax

        xor     eax, eax
        inc     eax
        pop     edi esi
        return
endp



;=====================================================================
; Skips an extension block that starts at lpStart. EOF is at lpEnd.
; returns pointer to the end of block + 1
; or 0 if failed
; esi points at TGifInfo structure.
proc SkipExtension, .lpStart, .lpEnd
begin
        ; --- Get type of extension ---
        mov     edx, [.lpStart]
        mov     al, [edx+1]

        ; --- Skip each type seperately ---
        cmp     al, GRAPHICCONTROLEXTENSTION
        jne     @f

        ; Get transparent color and flag.
        movzx   eax, byte [edx+3]
        and     eax, 1
        mov     [esi+TGifInfo.fTransparent], eax
        mov     al, [edx+6]
        mov     [esi+TGifInfo.iTrasparentColor], eax

        ; Graphic control extension, has a fixed size of 8 bytes
        add     edx, 8
        mov     eax, edx
        jmp     .endext

@@:
        cmp     al, COMMENTEXTENSION
        jne     @f

        ; Comment extension, consists of subblocks of text
        add     edx, 2  ;move to first subblock
        stdcall SkipSubBlocks, edx
        jmp     .endext

@@:
        cmp     al, PLAINTEXTEXTENSION
        jne     @f

        ; Plain text extension, 15 header bytes and subblocks follow
        add     edx, 15
        stdcall SkipSubBlocks, edx
        jmp     .endext

@@:
        cmp     al, APPLICATIONEXTENSION
        jne     .endext

        ; Application extension, 14 header bytes and subblocks follow
        add     edx, 14
        stdcall SkipSubBlocks, edx
.endext:
        return
endp


;===============================================================================
;       SkipSubBlocks
;===============================================================================
; Skips a sequence of subblocks until a block-terminator is found.
; returns a pointer to the end of the block + 1.
; lpStart points to the start of the subblocks
;
proc SkipSubBlocks, .lpStart
begin
        mov     eax, [.lpStart]
        xor     ecx, ecx
.skiploop:
        mov     cl, [eax]       ; get size of subblock
        test    cl, cl
        jz      .endloop   ; size=0 means terminator
        inc     eax
        add     eax, ecx        ; add size to pointer
        jmp     .skiploop

.endloop:
        inc     eax
        return
endp


DispSize 'GifLib', $ - GifLib
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted include/libs/gui.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
;*************************************************************
;* coolmenu.asm
;*
;* This file contains coolmenu/toolbars/accelerators engine code.
;* You must include in executable section of the program.
;*
;* You can use this work for any purpos, only don't forget to
;* write somewhere in docs: "Based on work of John Found" or
;* something similar. :)
;*
;* '2003 John Found
;*************************************************************

iglobal
  cToolbarClassName   text  TOOLBAR_CLASS
endg


CoolCode:

;************************************************************
; Function DrawMenuIcon
; Parameters:
;       DC - device context
;       x,y - coordinates of upper left corner of the item
;       height - height of the menu item
;       State - state of the menu item
;************************************************************
proc DrawMenuIcon, .DC, .x, .y, .height, .Image, .State

.v      dd      0
.Brush1 LOGBRUSH
.Brush2 LOGBRUSH

begin

        mov     [.Brush1.lbStyle], BS_SOLID
        mov     [.Brush2.lbStyle], BS_SOLID

        invoke  GetSysColor, COLOR_BTNHIGHLIGHT
        test    [.State], ODS_CHECKED
        jnz     @f
        invoke  GetSysColor, COLOR_MENU
@@:
        invoke  ImageList_SetBkColor, [hIml], eax

; Compute coordinates
        mov     eax,[.y]
        shl     eax,1
        add     eax,[.height]
        sub     eax,18          ; the height of the image. THE IMAGE MUST BE 16x16 pixels.
        sar     eax,1
        mov     [.v],eax
        mov     ecx,[.x]

        inc     eax
        inc     ecx

; Select image list
        mov     ebx,[hIml]
        test    [.State],ODS_GRAYED
        jz      @f
        mov     ebx,[hImlGray]
@@:
        cmp     [.Image],-1
        jne     @f

        test    [.State],ODS_CHECKED
        jz      .qfalse               ; if the item is not checked and there is no Image (Image = -1) then return false

        mov     [.Image], ImageChecked
@@:
        invoke  ImageList_Draw, ebx, [.Image], [.DC], ecx, eax, ILD_NORMAL
        invoke  GetSysColor, COLOR_MENU
        invoke  ImageList_SetBkColor, ebx, eax

; Draw border
        mov     [.Brush1.lbColor],$ffffff
        mov     [.Brush2.lbColor],$808080

        test    [.State], ODS_GRAYED
        jz      @f

        invoke  GetSysColor,COLOR_GRAYTEXT
        mov     [.Brush1.lbColor],eax
        mov     [.Brush2.lbColor],eax

@@:
        test    [.State],ODS_SELECTED or ODS_CHECKED
        jnz     @f

        invoke  GetSysColor,COLOR_MENU
        mov     [.Brush1.lbColor],eax
        mov     [.Brush2.lbColor],eax

@@:
        test    [.State],ODS_CHECKED
        jz      @f

        mov     [.Brush1.lbColor], $808080
        mov     [.Brush2.lbColor], $ffffff

@@:
        lea     eax, [.Brush1]
        invoke  ExtCreatePen,PS_COSMETIC,1,eax,0,NULL
        invoke  SelectObject,[.DC],eax
        push    eax

        mov     esi,[.v]
        mov     ebx,[.x]
        add     esi,18
        add     ebx,18

        invoke  MoveToEx,[.DC],[.x],esi,NULL
        invoke  LineTo,[.DC],[.x],[.v]
        invoke  LineTo,[.DC],ebx,[.v]

;        pop     eax
        invoke  SelectObject,[.DC]       ;,eax   The eax is in stack, don't pop/push again
        invoke  DeleteObject,eax

        lea     eax, [.Brush2]
        invoke  ExtCreatePen, PS_COSMETIC, 1, eax, 0, NULL
        invoke  SelectObject,[.DC],eax
        push    eax

        dec     [.x]
        invoke  LineTo,[.DC],ebx,esi
        invoke  LineTo,[.DC],[.x],esi

;        pop     eax
        invoke  SelectObject,[.DC]       ;,eax
        invoke  DeleteObject,eax

        xor     eax,eax
        dec     eax
        jmp     .finish

.qfalse:
        xor     eax,eax

.finish:
        return
endp


;************************************************************
; Function DrawMenuText                                     *
; Parameters:                                               *
;       DC          - device context                        *
;       x1,y1,x2,y2 - rectangle to draw text                *
;       xOfs        - offset of text in rectangle           *
;       Caption     - pointer to the caption string         *
;       CapLen      - length of the caption string          *
;       State       - state of the menu item                *
;       ID          - ID of the menu function.              *
;************************************************************
proc DrawMenuText, .DC, .x1, .y1, .x2, .y2, .xOfs, .Caption, .CapLen, .State, .ID, .ptrAccel

.str    rb      64

        begin

; Draw background rectangle
        mov     esi,COLOR_HIGHLIGHT
        mov     edi,COLOR_HIGHLIGHTTEXT

        test    [.State],ODS_SELECTED
        jnz     @f

        mov     esi,COLOR_MENU
        mov     edi,COLOR_MENUTEXT
@@:
        test    [.State],ODS_GRAYED
        jz      @f

        mov     edi,COLOR_GRAYTEXT

@@:
        invoke  GetSysColor,esi
        invoke  SetBkColor,[.DC],eax
        invoke  GetSysColor,edi
        invoke  SetTextColor,[.DC],eax

        inc     esi

        lea     ebx,[.x1]
        invoke  FillRect,[.DC],ebx,esi
        sub     [.x2],12

; Draw text
        mov     ecx,[.xOfs]
        add     [.x1],ecx

        invoke  DrawTextA, [.DC], [.Caption], [.CapLen], ebx,    \
                          DT_LEFT or DT_SINGLELINE or DT_VCENTER

        lea     esi,[.str]
        stdcall AccelToStr, [.ptrAccel], esi
        invoke  DrawTextA, [.DC], esi, eax, ebx,                 \
                          DT_RIGHT or DT_SINGLELINE or DT_VCENTER

        pop     eax
        invoke  SelectObject, [.DC], eax
        return
endp

;*************************************************************
;  Draws the entire menu item (icon and text)
;*************************************************************
proc DoDrawItem, .DC, .x1, .y1, .x2, .y2, .Caption, .CapLen, .State, .Image, .ID, .ptrAccel
begin
        mov     eax, [.y2]
        sub     eax, [.y1]
        stdcall DrawMenuIcon, [.DC], [.x1], [.y1], eax, [.Image], [.State]
        mov     ebx, 20
        test    eax, eax
        jz      @f              ; if no image, don't move the left side of the rectangle.
        add     [.x1], ebx
        xor     ebx, ebx
@@:
        inc     ebx
; Print the text.
        stdcall DrawMenuText, [.DC], [.x1], [.y1], [.x2], [.y2], ebx,           \
                              [.Caption], [.CapLen], [.State], [.ID], [.ptrAccel]
        return
endp


;************************************************************
;  On draw item.
;************************************************************
proc OnDrawItem, .lparam
begin
        mov     esi, [.lparam]    ; address of TDrawItemStruct
        cmp     [esi+DRAWITEMSTRUCT.CtlType], ODT_MENU
        jne     .qfalse

        mov     edi,[esi+DRAWITEMSTRUCT.itemData]
        test    edi,edi
        jz      .qfalse

        movzx   eax, [edi+TAction.TextLen]
        movsx   ecx, [edi+TAction.Image]
        stdcall DoDrawItem, [esi+DRAWITEMSTRUCT.hDC],             \
                            [esi+DRAWITEMSTRUCT.rcItem.left],   \
                            [esi+DRAWITEMSTRUCT.rcItem.top],    \
                            [esi+DRAWITEMSTRUCT.rcItem.right],  \
                            [esi+DRAWITEMSTRUCT.rcItem.bottom], \
                            [edi+TAction.ptrText],                 \
                            eax,                                   \
                            [esi+DRAWITEMSTRUCT.itemState],       \
                            ecx,                                   \
                            [esi+DRAWITEMSTRUCT.CtlID],           \
                            [edi+TAction.ptrAccel]

        xor     eax,eax
        inc     eax
        jmp     .finish
.qfalse:
        xor     eax,eax
.finish:
        return
endp


;************************************************************
;  On measure item.
;************************************************************
proc OnMeasureItem, .hwnd, .lparam
.ARect  RECT
.DC     dd      ?
.str    rb      64
.sz     SIZE

begin
        mov     esi,[.lparam]     ; address of MEASUREITEMSTRUCT
        cmp     [esi+MEASUREITEMSTRUCT.CtlType], ODT_MENU
        jne     .qfalse

        mov     edi,[esi+MEASUREITEMSTRUCT.itemData]
        test    edi,edi
        jz      .qfalse

        invoke  GetStockObject, DEFAULT_GUI_FONT
        push    eax

        invoke  GetDC,[.hwnd]           ; try with current window DC
        mov     [.DC],eax

;        pop     ecx              ; don't uncomment, this is only illustration.
        invoke  SelectObject, eax ;,ecx   -> the parameter is already in stack, why to push it again?
        push    eax

        xor     eax,eax
        mov     [.ARect.left],eax
        mov     [.ARect.right],eax
        mov     [.ARect.top],eax
        mov     [.ARect.bottom],eax
        lea     ebx,[.ARect]

        movzx   eax, [edi+TAction.TextLen]
        lea     ebx, [esi+MEASUREITEMSTRUCT.itemWidth]
        invoke  GetTextExtentPoint32A, [.DC], [edi+TAction.ptrText], eax, ebx

        cmp     [esi+MEASUREITEMSTRUCT.itemHeight],19          ; this is height of the icon image
        jae     @f
        mov     [esi+MEASUREITEMSTRUCT.itemHeight],19
@@:

        lea     ebx,[.str]
        stdcall AccelToStr, [edi+TAction.ptrAccel], ebx
        test    eax, eax
        jz      .NoAccel

        lea     ecx,[.sz]
        invoke  GetTextExtentPoint32A, [.DC], ebx, eax, ecx

        mov     ebx,[.sz.cx]      ; height is in eax
        add     [esi+MEASUREITEMSTRUCT.itemWidth],ebx

        cmp     [edi+TAction.Image], -1
        jne     .NoAccel

        add     [esi+MEASUREITEMSTRUCT.itemWidth],12

.NoAccel:
        add     [esi+MEASUREITEMSTRUCT.itemWidth],16   ; 24.06.2003 John Found this is solution for bug with items with no accelerators
                                                        ; I know this is not clear, but it works for now.

        invoke  SelectObject,[.DC]      ; the last arg is in stack.
        invoke  ReleaseDC, [.hwnd], [.DC]

        xor     eax, eax
        inc     eax
        return

.qfalse:
        xor     eax,eax
        return
endp

uglobal
  buffMenuitem   MENUITEMINFO
endg


;*********************************************************
; On Menu char  WM_MENUCHAR message
;*********************************************************
proc OnMenuChar, .wparam, .hmenu
.count  dd ?
begin
        test     word [.wparam+2], MF_SYSMENU
        jnz      .default

        invoke  GetMenuItemCount, [.hmenu]
        cmp     eax,0
        jle     .default
        mov     [.count],eax

        xor     ebx,ebx
        mov     [buffMenuitem.cbSize],sizeof.MENUITEMINFO
        mov     [buffMenuitem.fMask], MIIM_DATA or MIIM_TYPE or MIIM_SUBMENU

.searchloop:
        invoke  GetMenuItemInfoA, [.hmenu], ebx, TRUE, buffMenuitem
        test    eax, eax
        jz      .notthis

        cmp     [buffMenuitem.hSubMenu], 0
        jne     .notthis ; windows will handle this

        test   [buffMenuitem.fType], MFT_OWNERDRAW
        jz     .nod

        mov     edi, [buffMenuitem.dwItemData]
        movzx   ecx, [edi+TAction.TextLen]
        mov     edi, [edi+TAction.ptrText]
        jmp     .OK

.nod:
        cmp     [buffMenuitem.fType], MFT_STRING
        jne     .notthis

        mov     edi, [buffMenuitem.dwTypeData]
        mov     ecx, [buffMenuitem.cch]
        test    edi, edi
      ;  jz      .notthis
.OK:
        jecxz  .notthis

        mov     dl, byte [.wparam]
        cmp     dl, $61
        jb      .search
        cmp     dl, $7a
        ja      .search
        sub     dl, 20h

.search:
        mov     ax, [edi]
        cmp     al, '&'
        jne     .next

        cmp     ah, $61
        jb      @f
        cmp     ah, $7a
        ja      @f
        sub     ah, 20h
@@:
        cmp     ah, dl
        je      .this

.next:
        inc     edi
        loop   .search

.notthis:
        inc     ebx
        cmp     ebx, [.count]
        jne     .searchloop

;not found
.default:
        stc
        return

.this:
        mov     ax, 2
        shl     eax, 16
        mov     ax, bx

.finish:
        clc
        return
endp


;****************************************************************
;  Creates menu from CoolMenu structure (See CoolMenu macro).
;  Returns handle to the menu.
;
;  ptrMenuItems: pointer to the CoolMenu array
;  fPopup:       if <>0, creates popup menu instead of main menu
;****************************************************************
proc CreateCoolMenu, .ptrMenuItems, .fPopup
.item   MENUITEMINFO
.level  dd ?
begin
        push    esi edi ebx

        mov     esi, [.ptrMenuItems]
        mov     [.level], 0

        mov     eax, [.fPopup]
        test    eax, eax
        jnz     .popup

        invoke  CreateMenu
        jmp     .cont

.popup:
        invoke  CreatePopupMenu

.cont:
        mov     ebx,eax

        mov     [.item.cbSize],sizeof.MENUITEMINFO
        mov     [.item.fMask], MIIM_ID or MIIM_STATE or MIIM_SUBMENU or MIIM_TYPE or MIIM_DATA
        mov     [.item.fState],MFS_ENABLED
        mov     [.item.hbmpChecked],0
        mov     [.item.hbmpUnchecked],0

.loopitems:
        xor     eax,eax
        mov     [.item.hSubMenu],eax
        mov     [.item.wID],eax
        mov     [.item.dwItemData],eax

        test    [esi+TCoolMenuItem.Flags],mfEnd
        jnz     .leveldn

        test    [esi+TCoolMenuItem.Flags],mfSeparator
        jnz     .separator

        test    [esi+TCoolMenuItem.Flags],mfSubmenu
        jnz     .submenu

        mov     [.item.fState],MFS_ENABLED
        test    [esi+TCoolMenuItem.Flags], mfChecked
        jz      @f
        or      [.item.fState], MFS_CHECKED
@@:
        mov     [.item.fType],MFT_OWNERDRAW

        movzx   edi, [esi+TCoolMenuItem.Action]
        imul    edi, sizeof.TAction
        add     edi, MainActionList

        movzx   eax,[edi+TAction.ID]
        mov     [.item.wID],eax

        mov     [.item.dwItemData],edi
        jmp     .ready

.separator:
        mov     [.item.fType],MFT_SEPARATOR
        jmp     .ready

.submenu:
        invoke  CreatePopupMenu

        mov     [.item.hSubMenu],eax
        mov     [.item.fType],MFT_STRING
        movzx   edi,[esi+TCoolMenuItem.Action]  ; Action is the offset to the string
        add     edi,esi
        mov     [.item.dwTypeData],edi
        lea     eax,[.item]
        invoke  InsertMenuItemA,ebx,-1,TRUE,eax

        inc     [.level]
        push    ebx
        mov     ebx,[.item.hSubMenu]
        jmp     .next

.leveldn:
        cmp     [.level],0
        je      .next

        pop     ebx
        dec     [.level]
        jmp     .next

.ready:
        lea     eax, [.item]
        invoke  InsertMenuItemA, ebx, -1, TRUE, eax

.next:
        add     esi,sizeof.TCoolMenuItem
        cmp     word [esi],-2                   ; end of structure
        jne     .loopitems

        mov     eax,ebx
        pop     ebx edi esi
        return
endp



proc GetHintText, .ActList, .action
begin
        mov     eax, [.action]
        imul    eax, sizeof.TAction
        add     eax, [.ActList]

        mov     eax, [eax+TAction.ptrHint]
        return
endp


;***********************************************************************
;  Creates toolbar from CoolToolbar structure (See CoolToolbar macro).
;  Returns handle to the toolbar.
;***********************************************************************
proc CreateCoolToolbar, .ptrActionList, .ptrToolbarItems, .ParentWindow, .ToolbarID, .ImagesNormal, .ImagesDisabled
.item   TToolbarButton
.win WINDOWPOS
begin
; Create toolbar
        xor     esi,esi
        invoke  GetModuleHandleA,esi
        mov     edi, eax
        invoke  CreateWindowExA, esi, cToolbarClassName, NULL,    \
                                WS_CHILD or                      \
                                WS_VISIBLE or                    \
                                WS_CLIPSIBLINGS or               \
                                WS_CLIPCHILDREN or               \
                                TBSTYLE_TRANSPARENT or           \
                                TBSTYLE_FLAT or                  \
                                TBSTYLE_TOOLTIPS or              \
                                TBSTYLE_WRAPABLE,                \
                                esi, esi, esi, esi,              \
                                [.ParentWindow], [.ToolbarID],   \
                                edi, NULL
        mov     ebx,eax
        stdcall SubclassWindow, ebx, CoolToolbarProc
        invoke  SetPropA, ebx, [propAutoSize], TRUE

        invoke  SendMessageA, ebx, TB_BUTTONSTRUCTSIZE, TToolbarButton.size, esi

; make arrows for dropdown buttons
        invoke  SendMessageA, ebx, TB_GETEXTENDEDSTYLE, esi, esi
        or      eax,TBSTYLE_EX_DRAWDDARROWS
        invoke  SendMessageA, ebx, TB_SETEXTENDEDSTYLE, esi, eax

; Set image lists
        invoke  SendMessageA, ebx, TB_SETIMAGELIST, esi, [.ImagesNormal]
        invoke  SendMessageA, ebx, TB_SETDISABLEDIMAGELIST, esi, [.ImagesDisabled]

; make tooltip to appear on not active main window.
        invoke  SendMessageA, ebx, TB_GETTOOLTIPS, 0, 0
        mov     esi, eax
        invoke  GetWindowLongA, esi, GWL_STYLE
        or      eax, TTS_ALWAYSTIP or TTS_NOPREFIX
        invoke  SetWindowLongA, esi, GWL_STYLE, eax
; Set tooltip delay time.
        invoke  SendMessageA, esi, TTM_SETDELAYTIME, TTDT_AUTOMATIC, 600

; Create buttons
        mov     esi, [.ptrToolbarItems]
        xor     eax, eax
        mov     [.item.dwData], eax
        mov     [.item.iString], -1

.itemloop:
        cmp     [esi+TCoolButton.Action],-2        ; end of structure
        je      .finish

        test    [esi+TCoolButton.Flags],bfSeparator
        jnz     .separator

        movzx   edi,[esi+TCoolButton.Action]
        imul    edi,sizeof.TAction
        add     edi,[.ptrActionList]

        movsx   eax,[edi+TAction.Image]
        movzx   ecx,[edi+TAction.ID]
        mov     [.item.iBitmap],eax
        mov     [.item.idCommand],ecx

        mov     al,[esi+TCoolButton.Flags]
        mov     [.item.fsStyle],al
        and     [.item.fsStyle], $1f

        mov     [.item.fsState],TBSTATE_ENABLED
        test    al, bfDisabled
        jz      @f
        mov     [.item.fsState],0
@@:
        test    al, bfChecked
        jz      @f
        or      [.item.fsState], TBSTATE_CHECKED
@@:
        test    al, bfWrap
        jz      .ready
        or      [.item.fsState], TBSTATE_WRAP or TBSTATE_ENABLED
        jmp     .ready

.separator:
        xor     eax,eax
        mov     [.item.iBitmap],eax
        mov     [.item.idCommand],eax
        mov     [.item.fsState],al
        mov     [.item.fsStyle],TBSTYLE_SEP

.ready:
        lea     edi,[.item]
        invoke  SendMessageA, ebx, TB_ADDBUTTONS, 1, edi

        add     esi, sizeof.TCoolButton
        jmp     .itemloop

.finish:
;        stdcall AutoSizeToolbar, ebx
        mov     eax,ebx
        return
endp


proc AutoSizeToolbar, .htb
begin
        invoke  GetPropA, [.htb], [propAutoSize]
        test    eax, eax
        jz      .exit

        xor     eax, eax
        invoke  SetWindowPos, [.htb], eax, eax, eax, eax, eax, SWP_NOZORDER
.exit:
        return
endp


winproc CoolToolbarProc
begin

ondefault
        stc
        return

onmessage WM_WINDOWPOSCHANGING
locals
  .winbounds TBounds
  .winrect   RECT
endl
        invoke  GetPropA, [.hwnd], [propAutoSize]
        test    eax, eax
        jz      .finish

        invoke  GetPropA, [.hwnd], [propAlign]
        mov     edi, eax

        mov     [.winbounds.width],$4
        mov     [.winbounds.height],$4

        xor     esi,esi
        lea     ebx,[.winrect]

.whiletoolbar:
        invoke  SendMessageA,[.hwnd],TB_GETITEMRECT, esi, ebx
        test    eax,eax
        jz      .endauto

; [.winbounds.width] = max ([.winbounds.width], [.winrect.right])
        mov     eax,[.winrect.right]
        sub     eax,[.winbounds.width]
        sbb     ecx,ecx
        not     ecx
        and     ecx,eax
        add     [.winbounds.width],ecx

; [.winbounds.height] = max ([.winbounds.height], [.winrect.bottom])
        mov     eax,[.winrect.bottom]
        sub     eax,[.winbounds.height]
        sbb     ecx,ecx
        not     ecx
        and     ecx,eax
        add     [.winbounds.height],ecx

        inc     esi
        jmp     .whiletoolbar

.endauto:
        mov     esi,[.lparam]
        stdcall GetNCSize, [.hwnd]

        cmp     edi,waLeft
        je      .setautowidth
        cmp     edi,waRight
        je      .setautowidth

        cmp     edi,waTop
        je      .setautoheight
        cmp     edi,waBottom
        je      .setautoheight

        jmp     .finish

.setautowidth:
        add     [.winbounds.width],edx
        push    [.winbounds.width]
        pop     [esi+WINDOWPOS.cx]
        jmp     .resize

.setautoheight:
        add     [.winbounds.height],eax
        push    [.winbounds.height]
        pop     [esi+WINDOWPOS.cy]

.resize:
        and     [esi+WINDOWPOS.flags], not SWP_NOSIZE

.finish:
        xor     eax, eax
        clc
        return
endwp




proc GetNCSize, .hwnd
.winrect RECT
.client  RECT
begin
        lea     eax, [.winrect]
        invoke  GetWindowRect, [.hwnd], eax
        lea     eax, [.client]
        invoke  GetClientRect, [.hwnd], eax

        mov     eax, [.winrect.bottom]
        mov     edx, [.winrect.right]
        sub     eax, [.winrect.top]
        sub     edx, [.winrect.left]
        sub     eax, [.client.bottom]
        sub     edx, [.client.right]
        return
endp





struct TKeyName
  .VirtKey  dw ?
  .NextOfs  db ?
  .Text     db ?
ends


struc dk [code,txt] {
  forward
    local .TheEnd
      dw code
      db .TheEnd-$+2
      db txt,0
    .TheEnd = $
  common
    dw -1
}

iglobal
  VKeyArray dk                              \
          VK_BACK,      'BkSp',             \
          VK_TAB,       'Tab',              \
          VK_CLEAR,     'Clear',            \
          VK_RETURN,    'Enter',            \
          VK_SHIFT,     'Shift',            \
          VK_CONTROL,   'Ctrl',             \
          VK_MENU,      'Alt',              \
          VK_PAUSE,     'Pause',            \
          VK_CAPITAL,   'CapsLock',         \
          VK_ESCAPE,    'Esc',              \
          VK_SPACE,     'Space',            \
          VK_PGUP,      'PgUp',             \
          VK_PGDN,      'PgDn',             \
          VK_END,       'End',              \
          VK_HOME,      'Home',             \
          VK_LEFT,      'Left',             \
          VK_UP,        'Up',               \
          VK_RIGHT,     'Right',            \
          VK_DOWN,      'Down',             \
          VK_SELECT,    'Select',           \
          VK_EXECUTE,   'Execute',          \
          VK_SNAPSHOT,  'PrtScr',           \
          VK_INSERT,    'Ins',              \
          VK_DELETE,    'Del',              \
          VK_HELP,      'Help',             \
          VK_LWIN,      'LeftWin',          \
          VK_RWIN,      'RightWin',         \
          VK_APPS,      'Apps',             \
          VK_NUMPAD0,   'Num0',             \
          VK_NUMPAD1,   'Num1',             \
          VK_NUMPAD2,   'Num2',             \
          VK_NUMPAD3,   'Num3',             \
          VK_NUMPAD4,   'Num4',             \
          VK_NUMPAD5,   'Num5',             \
          VK_NUMPAD6,   'Num6',             \
          VK_NUMPAD7,   'Num7',             \
          VK_NUMPAD8,   'Num8',             \
          VK_NUMPAD9,   'Num9',             \
          VK_MULTIPLY,  'Num*',             \
          VK_ADD,       'Num+',             \
          VK_SUBTRACT,  'Num-',                \
          VK_DECIMAL,   'Num.',                \
          VK_DIVIDE,    'Num/',                \
          VK_F1,        'F1',               \
          VK_F2,        'F2',               \
          VK_F3,        'F3',               \
          VK_F4,        'F4',               \
          VK_F5,        'F5',               \
          VK_F6,        'F6',               \
          VK_F7,        'F7',               \
          VK_F8,        'F8',               \
          VK_F9,        'F9',               \
          VK_F10,       'F10',              \
          VK_F11,       'F11',              \
          VK_F12,       'F12',              \
          VK_F13,       'F13',              \
          VK_F14,       'F14',              \
          VK_F15,       'F15',              \
          VK_F16,       'F16',              \
          VK_F17,       'F17',              \
          VK_F18,       'F18',              \
          VK_F19,       'F19',              \
          VK_F20,       'F20',              \
          VK_F21,       'F21',              \
          VK_F22,       'F22',              \
          VK_F23,       'F23',              \
          VK_F24,       'F24',              \
          VK_NUMLOCK,   'NumLock',          \
          VK_SCROLL,    'ScrLock',          \
          VK_LSHIFT,    'LShift',           \
          VK_RSHIFT,    'RShift'
endg



;************************************************************************
; Returns string with text name of the virtual key in
; given accelerator.
;
; ptrAccel: Pointer to the ACCEL structure of the accelerator.
; ptrStr:   Pointer to the buffer for the string.
;
; Returns: eax - length of the string (only ASCII chars)
;
; Note: IMHO this is not the best method to convert virtual
;       key to string, but windows don't provide any other way.
;       using MapVirtualKey and then GetKeyNameText don't works
;       good, because of bad convertion VK -> scancode
; WARNING:
;       NO ERROR CHECK.
;       If you set some strange accelerator key /VK_LBUTTON for example/
;       the result string will be strange.
;************************************************************************

proc AccelToStr, .ptrAccel, .ptrStr

.Prefix rb 32
.str    rb 32

        begin
        push    esi edi ebx

        mov     edx, [.ptrAccel]
        test    edx, edx
        jz      .noaccel

        movzx   eax, [edx+TAccel.Key]
        mov     esi, VKeyArray

.search:
        cmp     [esi+TKeyName.VirtKey],-1
        je      .notfound
        cmp     [esi+TKeyName.VirtKey], ax
        je      .found
        movzx   ebx, [esi+TKeyName.NextOfs]
        add     esi, ebx
        jmp     .search

.notfound:
        and     ax, $00ff
        mov     word [.str], ax
        jmp     .prefix

.found:
        add     esi, 3
        lea     edi, [.str]
.copy:
        mov     al, [esi]
        inc     esi
        mov     [edi], al
        inc     edi
        test    al, al
        jnz     .copy

.prefix:
        lea     esi, [.str]

        test    [edx+TAccel.Flags], Alt
        jz      @f
        sub     esi, 4
        mov     dword [esi], 'Alt+'
@@:
        test    [edx+TAccel.Flags], Ctrl
        jz      @f
        sub     esi, 5
        mov     dword [esi], 'Ctrl'
        mov     byte  [esi+4], '+'
@@:
        test    [edx+TAccel.Flags], Shift
        jz      @f
        sub     esi, 6
        mov     dword [esi], 'Shif'
        mov     word  [esi+4],'t+'
@@:
        mov     edi, [.ptrStr]
        xor     eax, eax
        dec     eax
.copy2:
        mov     bl, [esi]
        inc     esi
        mov     [edi], bl
        inc     edi
        inc     eax             ; eax is counter of string length
        test    bl, bl
        jnz     .copy2
        jz      .exit

.noaccel:
        mov     edi,[.ptrStr]
        xor     eax,eax
        mov     [edi],eax

.exit:
        pop     ebx edi esi
        return
endp



proc DisableBitmap, .hBmp, .IconWidth, .clrTransparent, .clrGrayBlend, .clrBack
  .bmp   BITMAPINFOHEADER
  .b     BITMAP
  .ptrBits dd ?
  .hBmpRes dd ?
  .dc      dd ?
  .dc2     dd ?
  .clr     dd ?
begin
        push    esi edi ebx

        mov     eax, [.clrGrayBlend]
        bswap   eax
        shr     eax, 8
        mov     [.clrGrayBlend], eax

        mov     al, byte [.clrBack]
        xchg    al, byte [.clrBack+2]
        mov     byte [.clrBack], al

        xor     ebx, ebx
        dec     [.IconWidth]

        invoke  CreateCompatibleDC, ebx
        mov     [.dc], eax
        invoke  CreateCompatibleDC, ebx
        mov     [.dc2], eax

        lea     esi, [.b]
        invoke  GetObjectA, [.hBmp], sizeof.BITMAP, esi

        mov     [.bmp.biSize], sizeof.BITMAPINFOHEADER
        mov     ecx, [.b.bmWidth]
        mov     edx, [.b.bmHeight]
        mov     [.bmp.biWidth], ecx
        mov     [.bmp.biHeight], edx
        mov     [.bmp.biPlanes], 1
        mov     [.bmp.biBitCount], 32
        mov     [.bmp.biCompression], BI_RGB
        mov     [.bmp.biSizeImage], ebx
        mov     [.bmp.biClrUsed],ebx
        mov     [.bmp.biClrImportant], ebx

        lea     ecx, [.ptrBits]
        lea     esi, [.bmp]
        invoke  CreateDIBSection, ebx, esi, ebx, ecx, ebx, ebx
        mov     [.hBmpRes], eax

        invoke  SelectObject, [.dc2], [.hBmpRes]
        push    eax

        invoke  SelectObject, [.dc], [.hBmp]
        push    eax

        lea     eax, [.bmp]
        invoke  GetDIBits, [.dc], [.hBmp], ebx, [.bmp.biHeight], [.ptrBits], eax, ebx

        invoke  SelectObject, [.dc]
        invoke  SelectObject, [.dc2]
        invoke  DeleteDC, [.dc]
        invoke  DeleteDC, [.dc2]

        mov     edi, [.ptrBits]
        mov     ecx, [.bmp.biHeight]
        shl     ecx, 16

.outloop:
        xor     esi, esi        ; Counter from 0 to IconWidth-1
        mov     cx,  word [.bmp.biWidth]
.inloop:
        xor     ebx, ebx
        xor     eax, eax
        xor     ebx, ebx
        and     dword [edi], $ffffff
        mov     edx, [edi]
        cmp     edx, [.clrTransparent]
        jne     .gray
        mov     eax, [.clrBack]
        jmp     .next

.gray:
        movzx   eax, dl
        movzx   ebx, dh

        add     eax, eax        ; 2* Blue
        add     eax, ebx        ; + Green

        shr     edx, 16
        movzx   ebx, dl
        add     eax, ebx        ; + Red

        shr     eax, 2          ; div 4 -> Grayscale pixel.
                                ; This formula gives more realistic view.

        push    eax eax

; -----byte 0
        movzx   ebx, byte [.clrGrayBlend]
        imul    ebx, esi          ; clrBlend * xi

        mov     edx, eax
        imul    edx, esi          ; clrGray * xi

        imul    eax, [.IconWidth]  ; clrGray * xmax

        add     eax, ebx          ;
        sub     eax, edx          ; eax := clrBlend * xi + clrGray * xmax - clrGray * xi

        xor     edx, edx
        div     [.IconWidth]

        mov     byte [.clr], al

; -----byte 1
        pop     eax

        movzx   ebx, byte [.clrGrayBlend+1]
        imul    ebx, esi          ; clrBlend * xi

        mov     edx, eax
        imul    edx, esi          ; clrGray * xi

        imul    eax, [.IconWidth]  ; clrGray * xmax

        add     eax, ebx          ;
        sub     eax, edx          ; eax := clrBlend * xi + clrGray * xmax - clrGray * xi

        xor     edx, edx
        div     [.IconWidth]

        mov     byte [.clr+1], al

; -----byte 2
        pop     eax

        movzx   ebx, byte [.clrGrayBlend+2]
        imul    ebx, esi          ; clrBlend * xi

        mov     edx, eax
        imul    edx, esi          ; clrGray * xi

        imul    eax, [.IconWidth]  ; clrGray * xmax

        add     eax, ebx          ;
        sub     eax, edx          ; eax := clrBlend * xi + clrGray * xmax - clrGray * xi

        xor     edx, edx
        div     [.IconWidth]

        mov     byte [.clr+2], al

; combine it all
        mov     eax, [.clr]
        and     eax, $ffffff

.next:
        mov     [edi], eax
        lea     edi, [edi+4]

        inc     esi
        cmp     esi, [.IconWidth]
        jbe     .doloop
        xor     esi, esi

.doloop:
        dec     cx
        jnz     .inloop
        sub     ecx, $10000
        jnz     .outloop

.finish:
        mov     eax, [.hBmpRes]
        pop     ebx edi esi
        return
endp



proc ExecAction, .actionlist, .number, .wparam, .lparam
begin
        mov     ebx, [.actionlist]
        movzx   esi, word [.wparam]
        cmp     esi, FirstID
        jl      .ondefault

        sub     esi, FirstID
        cmp     esi, [.number]
        jge     .ondefault

        imul    esi,sizeof.TAction
        add     esi, [.actionlist]

        cmp     [esi+TAction.OnExecute], 0
        je      @f

        stdcall [esi+TAction.OnExecute], [.wparam], [.lparam]

@@:
        xor     eax, eax
        clc
        return

.ondefault:
        stc
        return
endp



DispSize 'actions engine', ($ - CoolCode)

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted include/libs/gui.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
;*************************************************************
;* gui.inc
;*
;* This file contains coolmenu/toolbars/accelerators data
;* structures and constants. It not contains any data or
;* code.
;*************************************************************
GUILib = 1

Ctrl = FCONTROL
Alt = FALT
Shift = FSHIFT

FirstMRU = $2000        ; This is the first ID for MRU menu items.
FirstID = $7000         ; This is the first number for command IDs

;**********************************************************************
; This is ACCEL windows structure.                                    *
; WARNING, SDK help file have error in description of this structure. *
; Flags field must be word, not byte.                                 *
;**********************************************************************
struc TAccel AFlags,AKey,aID {
  .Flags dw  AFlags
  .Key   dw  AKey
  .ID    dw  aID

  .size = $ - .Flags
}

virtual at 0
  TAccel TAccel ?,?,?
end virtual


; This is TBBUTTON structure, but with parameters.
struc TToolbarButton {
  .iBitmap   dd ?
  .idCommand dd ?
  .fsState   db ?
  .fsStyle   db ?
  .resword   dw ?
  .dwData    dd ?
  .iString   dd ?
  .size      =  $ - .iBitmap
}

virtual at 0
  TToolbarButton TToolbarButton
end virtual



;***************************************************************
;*  Action/Menu/Buttons structures                             *
;*  This structure describes "Action" with common properties   *
;*  for menu items and toolbar buttons.                        *
;***************************************************************

struct TAction
  .ID           dw      ?
  .Image        dw      ?
  .ptrText      dd      ?
  .TextLen      dw      ?
  .ptrHint      dd      ?
  .ptrAccel     dd      ?
  .OnExecute    dd      ?
ends


; Possible menuitem flags.
mfNormal        = $00
mfSubmenu       = $01
mfSeparator     = $02
mfChecked       = $08
mfGrayed        = MF_GRAYED
mfEnd           = $80
;MF_GRAYED


struct TCoolMenuItem
  .Action       dw      ?       ; index of action in the action array
  .Flags        db      ?
ends


; Possible button flags
bfButton        = $00
bfSeparator     = $01
bfCheck         = $02
bfGroup         = $04
bfDropDown      = $08
bfCheckGroup    = bfGroup or bfCheck
bfAutosize      = $10

bfChecked       = $80                   ; it's not standard. See "gui.asm"
bfDisabled      = $40
bfWrap          = $20


struct TCoolButton
  .Action       dw      ?
  .Flags        db      ?
ends

macro ActionList lblActions, lblAccel, [Name, Image, Text, Accel, strHint, OnExecute ] {
  common
    local Number
    Number = 0
    label lblActions

  forward
    local Caption, CapLen, HotKey, Hint, HintLen

    if defined options.ShowActions and options.ShowActions
      disp 1, 'Defined action:', `Name, '= $', <Name, $10>, $0d
    end if
    Name = Number + FirstID

    dw  Name
    dw  Image
    dd  Caption
    dw  CapLen

    if ~strHint eq NONE
      dd  Hint
    else
      dd  0
    end if

    if ~Accel eq NONE
      dd  HotKey
    else
      dd  0
    end if

    if defined OnExecute
      dd OnExecute
    else
      dd 0
    end if

    Number = Number + 1

  forward
    Caption db Text
    CapLen  = $ - Caption
            db 0

  forward
    if ~strHint eq NONE

      Hint    db strHint,0

    end if

  common
    lblActions#.Number dd Number

    label lblAccel
    Number = 0

  forward
    if ~ Accel eq NONE
      HotKey TAccel FVIRTKEY+FNOINVERT+Accel,Name
      Number = Number + 1
    end if
  common
    lblAccel#.Count dd Number

}



macro CoolMenu lblMenu, [Flags, Action]  {
  common
    local ..menusize

    dw  ..menusize

    label lblMenu word

  forward
    if Action eqtype ''
      local .Text
      dw  rva .Text - rva $           ; if the item is submenu.
    else
      if Flags and (mfSeparator or mfEnd) = 0
        dw  Action - FirstID            ; if the item is action, this is index in action list.
      else
        dw  -1                          ; if the item is separator.
      end if
  end if

    db  Flags

  common
    dw  -2      ; End of CoolMenu structure.

  forward
    if Action eqtype ''
      .Text db Action,0
    end if

  common
    ..menusize = $ - lblMenu
}


macro CoolToolbar lblToolbar, [Flags, Action]       {
  common
    label lblToolbar
  forward
    if (Flags and bfSeparator) = 0
      dw  Action - FirstID            ; if the item is action, this is index in action list.
    else
      dw  -1                          ; if the item is separator.
    end if

    db  Flags
  common
    dw  -2      ; End of CoolToolbar structure.
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































Deleted include/libs/mainloop.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
;----------------------------------------------
; Main message loop
;----------------------------------------------
Run:
        call    ProcessMessages
        jc      .terminate

if defined AppLib
        invoke  SendMessageA, [hApplication], AM_ONIDLE, 0, 0
end if
        invoke  WaitMessage
        jmp     Run

.terminate:
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























Deleted include/libs/msgutils.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
;------------------------------------------------------
; proc JumpTo
; Searches for the message in the message table.
; Arguments:
;   ebx - message number to search in the table.
; Returns:
;   This procedure doesn't returns. It simply
;   jumps to the address from table or imediately
;   after the table if the message is not found.
;   in both cases esi = eip
; Uses:
;   eax, esi
;------------------------------------------------------
proc JumpTo
begin
        pop     esi     ; get table address and remove return
                        ; address from the stack.
.loop:
        lodsd
        test    eax,eax
        jz      .exit

        cmp     bx, ax
        jne     .loop

        sar     eax, 16
        add     esi, eax
.exit:
        jmp     esi
endp



;-------------------------------------------------
; Process all messages in the queue
; then exits. if WM_QUIT is accepted, exits
; directly from application.
;
; This procedure should be called during any
; long process to avoid hanging of application.
;
; Returns CF = 0 if message queue is empty
; Returns CF = 1 is WM_QUIT message was detected.
;         in this case, ProcessMessages also returns
;         the exit code in register eax.
;-------------------------------------------------
proc ProcessMessages
.msg MSG
begin
        push    esi ebx

        lea     esi, [.msg]

.msg_loop:
        xor     eax, eax
        invoke  PeekMessageA, esi, eax, eax, eax, PM_REMOVE     ; peek message from queue if any.
        test    eax,eax
        jz      .finish                                 ; exit.

        cmp     [.msg.message], WM_QUIT ; if message is WM_QUIT then quit.
        je      .terminate

; Process keyboard acceleration table if any...
.accel:
if defined AppLib
        invoke  SendMessageA, [hApplication], AM_TRANSACCEL, esi, 0
        test    eax,eax
        jnz     .msg_loop
else
  if (defined hAccelerators) & (defined hMainForm)
          invoke  IsWindowEnabled, [hMainForm]
          test    eax, eax
          jz      .dialog

          invoke  TranslateAccelerator, [hMainForm], [hAccelerators], esi
          test    eax,eax
          jnz     .msg_loop
  end if
end if

; Processing of standard dialog messages (standard navigation: Tab, shift Tab etc.)
.dialog:
if defined AppLib
        invoke  GetLastActivePopup, [hApplication]
        invoke  IsDialogMessage, eax, esi
        test    eax, eax
        jnz     .msg_loop
else
  if defined hMainForm
        invoke  GetLastActivePopup, [hMainForm]
        invoke  IsDialogMessage, eax, esi
        test    eax, eax
        jnz     .msg_loop
  end if
end if

.translate:
        invoke  TranslateMessage, esi                           ; So, standard processing.
        invoke  DispatchMessageA, esi
        jmp     .msg_loop

.terminate:
        mov     eax, [.msg.wParam]
        stc
        pop     ebx esi
        return

.finish:
        clc
        pop     ebx esi
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































Deleted include/libs/msgutils.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
macro MessageList [message, msghandler] {
  forward
        dw message,msghandler - $ - 2
  common
        dd 0
}

macro Messages [msg, handler] {
if ~ msg eq
      call JumpTo
      MessageList msg, handler
end if
}

..CurrentMessage = WM_USER + $3000

macro winmessage [name] {
  forward
    name = ..CurrentMessage
    ..CurrentMessage = ..CurrentMessage + 1
    if defined options.ShowUserMessages & options.ShowUserMessages
      disp iconInfo, 'User message: ', `name, ' = $', <name, 16>, $0d
    end if
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































Deleted include/libs/parents.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
proc AlignChildren, .hwnd
.InternalData TInternalAlign
.bounds       TBounds
.class        rd 16
begin
        push    esi

        lea     esi, [.InternalData]
        invoke  GetClientRect, [.hwnd], esi

        lea      eax, [.class]
        invoke   GetClassNameA, [.hwnd], eax, 16*4
        cmp      dword [.class+2], 'sTab'           ; is it TabControl?
        jne      @f

        invoke  SendMessageA, [.hwnd], TCM_ADJUSTRECT, FALSE, esi
@@:
        and     [.InternalData.hClientWindow], 0

        invoke  BeginDeferWindowPos, 10
        mov     [.InternalData.hDefer], eax

        invoke  GetWindow, [.hwnd], GW_CHILD

.childrenloop:
        test    eax, eax
        jz      .endchildren

        push    GW_HWNDNEXT
        push    eax
        stdcall DoAlignOne, eax
        invoke  GetWindow ; from the stack
        jmp     .childrenloop

.endchildren:
        cmp     [.InternalData.hClientWindow], 0
        je      .enddefer

        lea     eax, [.bounds]
        stdcall AlignWindow, [esi+TInternalAlign.hClientWindow], esi, eax, waClient
        test    eax, eax
        jz      .enddefer

        invoke  DeferWindowPos, [.InternalData.hDefer],         \
                                [.InternalData.hClientWindow],  \
                                eax,                            \
                                [.bounds.x], [.bounds.y],       \
                                [.bounds.width], [.bounds.height], \
                                SWP_NOZORDER or SWP_DRAWFRAME
.enddefer:
        invoke  EndDeferWindowPos, [.InternalData.hDefer]
        pop     esi
        return
endp



proc DoAlignOne, .hwnd
.bounds TBounds
begin
        push    ebx

        invoke  GetPropA, [.hwnd], [propAlign]
        test    eax, eax
        jz      .exit
        mov     ebx, eax

        invoke  GetWindowLongA, [.hwnd], GWL_STYLE
        test    eax,WS_VISIBLE
        jz      .exit

        cmp     ebx, waClient
        jne     .doalign

; only one window with waClient may exists.
        cmp     [esi+TInternalAlign.hClientWindow], 0
        jne     .exit

        mov     eax, [.hwnd]
        mov     [esi+TInternalAlign.hClientWindow], eax
        jmp     .exit


.doalign:
        lea     eax, [.bounds]
        stdcall AlignWindow, [.hwnd], esi, eax, ebx
        test    eax, eax
        jz      .exit

        invoke  DeferWindowPos, [esi+TInternalAlign.hDefer],       \
                                [.hwnd],                           \
                                eax,                               \
                                [.bounds.x], [.bounds.y],          \
                                [.bounds.width], [.bounds.height], \
                                SWP_NOZORDER

.exit:
        mov     eax, 1
        pop     ebx
        return
endp




;************************************************************
;  Alignes some window in the bounds of ptrClientRect
;  rectangle. Excludes the result window from the
;  rectangle.
;  Returns the result x,y,w and h of the window in
;  ptrWinBounds
;
;  Returns: TRUE if the window is resized and FALSE if not.
;************************************************************
proc AlignWindow, .hwnd, .ptrClientRect, .ptrWinBounds, .winalign

.winrect RECT
.oldrect RECT

begin

        push    esi edi ecx ebx edx

        invoke  GetWindowLongA, [.hwnd], GWL_STYLE
        test    eax,WS_VISIBLE
        jz      .exit

        lea     esi,[.oldrect]
        invoke  GetWindowRect, [.hwnd], esi
        invoke  GetParent, [.hwnd]
        push    esi eax
        add     esi, 8
        invoke  ScreenToClient, eax, esi
        invoke  ScreenToClient ; from the stack.

        mov     esi, [.ptrClientRect]             ; Parent client rect pointer
        lea     edi, [.winrect]
        mov     ecx, 4
        rep movsd       ; copy client rect to window rect.

        mov     edx,[.oldrect.right]
        mov     ecx,[.oldrect.bottom]
        sub     edx,[.oldrect.left]             ; width of window
        sub     ecx,[.oldrect.top]              ; height of window
        mov     esi, [.ptrClientRect]             ; Parent client rect pointer

        mov     ebx,[.winalign]
        cmp     ebx, waClient
        jg      .exit
        cmp     ebx, waNone
        jle     .exit

        mov     eax, [.tableAlignProc+4*ebx-4]
        call    eax  ; make adjustment of the size and client rect.

; is rectangle changed?
        mov     eax,[.oldrect.top]
        mov     ebx,[.oldrect.left]
        mov     ecx,[.oldrect.right]
        mov     edx,[.oldrect.bottom]

        sub     eax,[.winrect.top]
        sub     ebx,[.winrect.left]
        sub     ecx,[.winrect.right]
        sub     edx,[.winrect.bottom]

        or      eax,ebx
        or      ecx,edx
        or      eax,ecx                 ; eax is NULL an ZF = 1 if .winrect = .oldrect
        jz      .end

        mov     eax,[.winrect.right]
        mov     ebx,[.winrect.bottom]
        sub     eax,[.winrect.left]
        jns     @f
        xor     eax,eax
@@:
        sub     ebx,[.winrect.top]
        jns     @f
        xor     ebx,ebx
@@:
        mov     esi,[.ptrWinBounds]

        mov     [esi+TBounds.width],eax
        mov     [esi+TBounds.height],ebx

        push    [.winrect.left]
        push    [.winrect.top]
        pop     [esi+TBounds.y]
        pop     [esi+TBounds.x]

        xor     eax,eax
        dec     eax
        jmp     .end

.exit:
        xor     eax, eax
.end:
        pop     edx ebx ecx edi esi
        return


.tableAlignProc dd .left, .right, .top, .bottom, .client

; align left
.left:
        mov     eax, [.winrect.left]
        add     eax, edx
        mov     [.winrect.right], eax
        add     [esi+RECT.left],edx            ; move the client rect
        ret

; align right
.right:
        mov     eax, [.winrect.right]
        sub     eax ,edx
        mov     [.winrect.left],eax
        sub     [esi+RECT.right],edx            ; move the client rect
        ret

; align top
.top:
        mov     eax, [.winrect.top]
        add     eax, ecx
        mov     [.winrect.bottom],eax
        add     [esi+RECT.top],ecx            ; move the client rect
        ret

; align bottom
.bottom:
        mov     eax, [.winrect.bottom]
        sub     eax, ecx
        mov     [.winrect.top], eax
        sub     [esi+RECT.bottom],ecx            ; move the client rect
        ret

; align client
.client:
        xor     eax,eax
        mov     [esi+RECT.left],eax
        mov     [esi+RECT.right],eax
        mov     [esi+RECT.top],eax
        mov     [esi+RECT.bottom],eax          ; make client rect missing
        ret
endp


proc AlignSiblings, .hwnd
begin
        invoke  GetParent, [.hwnd]
        test    eax, eax
        jz      .exit
        stdcall AlignChildren, eax
.exit:
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































Deleted include/libs/parents.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct TInternalAlign
  .client        RECT
  .hClientWindow dd ?
  .hDefer        dd ?
ends

;-----------------------------
; Window alignment constants.
;-----------------------------
waNone   = 0
waLeft   = 1
waRight  = 2
waTop    = 3
waBottom = 4
waClient = 5

struct TBounds
  .x       dd ?
  .y       dd ?
  .width   dd ?
  .height  dd ?
ends
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































Deleted include/libs/scrollbars.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
ScrollbarsLib:
;---------------------------------------------------------
; Scrollbar lib is small library that provides
; windows with client area bigger than its actual size.
;---------------------------------------------------------

;----------------------------------------------------------------------
; This procedure is handler for WM_HSCROLL and WM_VSCROLL
; messages. Call it from window message procedure passing
; the message parameters.
;----------------------------------------------------------------------
proc ScrollBarMessage, .hwnd, .wmsg, .wparam, .updateproc, .linesize
.sbi SCROLLINFO
.kind dd ?
begin
        push    edi esi ebx
        mov     eax, [.wmsg]
        sub     eax, WM_HSCROLL
        mov     [.kind], eax

        lea     edi, [.sbi]

        mov     [.sbi.cbSize], sizeof.SCROLLINFO
        mov     [.sbi.fMask], SIF_RANGE or SIF_PAGE or SIF_POS or SIF_TRACKPOS
        invoke  GetScrollInfo, [.hwnd], [.kind], edi

        movzx   ebx, word [.wparam]
        cmp     ebx, SB_THUMBTRACK
        je      .track
        cmp     ebx, SB_THUMBPOSITION
        je      .track

        cmp     ebx, SB_TOP
        je      .top
        cmp     ebx, SB_BOTTOM
        je      .bottom

        mov     edx, 1  ; multiplier down

        cmp     ebx, SB_PAGEDOWN
        je      .pageupdn
        cmp     ebx, SB_LINEDOWN
        je      .lineupdn

        mov     edx, -1  ; multiplier UP

        cmp     ebx, SB_PAGEUP
        je      .pageupdn
        cmp     ebx, SB_LINEUP
        je      .lineupdn
; Undefined command...
        return

;-----------------------------------------------------
; Handling of different actions...
;-----------------------------------------------------
.track:
        mov     eax, [.sbi.nTrackPos]
;        movsx   eax, word [.wparam+2]
        jmp     .setpos

.top:
        mov     eax, [.sbi.nMin]
        jmp     .setpos

.bottom:
        mov     eax, [.sbi.nMax]
        sub     eax, [.sbi.nPage]
        jmp     .setpos

.pageupdn:
        mov     eax, [.sbi.nPos]
        mov     ecx, [.sbi.nPage]
        imul    ecx, edx
        add     eax, ecx
        jmp     .setpos

.lineupdn:
        mov     eax, [.sbi.nPos]
        mov     ecx, [.linesize]
        imul    ecx, edx
        add     eax, ecx

.setpos:
        mov     esi, [.sbi.nPos] ; Old scroll position.

        mov     [.sbi.nPos], eax ; New scroll position.
        mov     [.sbi.fMask], SIF_POS
        invoke  SetScrollInfo, [.hwnd], [.kind], edi, TRUE

; Update children windows positions
        mov     [.sbi.fMask], SIF_POS
        invoke  GetScrollInfo, [.hwnd], [.kind], edi ; get the position corrected by Windows

        cmp       [.updateproc], 0
        je        .finish

        sub     esi, [.sbi.nPos] ; correction value
        stdcall [.updateproc], [.hwnd], [.kind], esi

.finish:
        mov     eax, [.sbi.nPos]
        pop     ebx esi edi
        return
endp



;--------------------------------------------------------------------
; Call this procedure when the window size have been changed, to
; adjust scrollbars thumbs size acordingly.
;--------------------------------------------------------------------
proc UpdateThumbs, .hwnd
.rect RECT
begin
        lea     eax, [.rect]
        invoke  GetClientRect, [.hwnd], eax
        stdcall _DoUpdateOneThumb, [.hwnd], SB_HORZ, [.rect.right]
        stdcall _DoUpdateOneThumb, [.hwnd], SB_VERT, [.rect.bottom]
        return
endp



proc _DoUpdateOneThumb, .hwnd, .kind, .size
.sbi SCROLLINFO
begin
; Get the current possition of the scrollbar.
        mov     [.sbi.cbSize], sizeof.SCROLLINFO
        mov     [.sbi.fMask], SIF_POS
        lea     eax, [.sbi]
        invoke  GetScrollInfo, [.hwnd], [.kind], eax
        mov     esi, [.sbi.nPos] ; Old position of the scrollbar

; Set the new page size of the scrollbar.
        mov     eax, [.size]
        mov     [.sbi.nPage], eax
        mov     [.sbi.fMask], SIF_PAGE
        lea     eax, [.sbi]
        invoke  SetScrollInfo, [.hwnd], [.kind], eax, TRUE

; Get again the new position, because possibly Windows changed it.
        mov     [.sbi.fMask], SIF_POS
        lea     eax, [.sbi]
        invoke  GetScrollInfo, [.hwnd], [.kind], eax

; Move the first level children acording to the new scroll position.
        sub     esi, [.sbi.nPos]  ; correction value
        jz      .finish
;        stdcall DoCorrectChildren, [.hwnd], [.kind], esi
.finish:
        return
endp


proc DoCorrectChildren, .hwnd, .kind, .correct
.defer dd ?
.rect  RECT
begin
        mov     edi, [.kind]
        shl     edi, 2          ; eax = 0 if .kind = SB_HORZ (0) and eax = 4 if .kind = SB_VERT (1)
        mov     esi, [.correct]

        invoke  BeginDeferWindowPos, 10
        mov     [.defer], eax

        invoke  GetWindow, [.hwnd], GW_CHILD
.loop:
        test    eax, eax
        je      .enddefer

        mov     ebx, eax

        lea     eax, [.rect]
        invoke  GetWindowRect, ebx, eax

        lea     eax, [.rect]
        invoke  ScreenToClient, [.hwnd], eax

        add     [.rect+edi], esi
        invoke  DeferWindowPos, [.defer], ebx, 0, [.rect.left], [.rect.top], 0, 0, SWP_NOSIZE or SWP_NOZORDER
        mov     [.defer], eax

        invoke  GetWindow, ebx, GW_HWNDNEXT
        jmp     .loop

.enddefer:
        invoke  EndDeferWindowPos, [.defer]
        return
endp




proc AutoSizeScrollers, .hwnd
.sbi SCROLLINFO
.rect RECT
.maxrect RECT
begin
        mov     eax, $7fffffff
        mov     [.maxrect.left], eax
        mov     [.maxrect.top], eax
        inc     eax
        mov     [.maxrect.right], eax
        mov     [.maxrect.bottom], eax

        invoke  GetWindow, [.hwnd], GW_CHILD

.loop:
        test    eax, eax
        jz      .endloop
        mov     ebx, eax

        lea     esi, [.rect]
        invoke  GetWindowRect, ebx, esi
        invoke  ScreenToClient, [.hwnd], esi
        lea     eax, [esi+8]
        invoke  ScreenToClient, [.hwnd], eax

        mov     eax, [.rect.left]
        cmp     eax, [.maxrect.left]
        jge     @f
        mov     [.maxrect.left], eax
@@:
        mov     eax, [.rect.top]
        cmp     eax, [.maxrect.top]
        jge     @f
        mov     [.maxrect.top], eax
@@:
        mov     eax, [.rect.right]
        cmp     eax, [.maxrect.right]
        jle     @f
        mov     [.maxrect.right], eax
@@:
        mov     eax, [.rect.bottom]
        cmp     eax, [.maxrect.bottom]
        jle     @f
        mov     [.maxrect.bottom], eax
@@:
        invoke  GetWindow, ebx, GW_HWNDNEXT
        jmp     .loop

.endloop:
        mov     eax, [.maxrect.left]
        mov     ecx, [.maxrect.right]

        mov     [.sbi.nMin], 0
        mov     [.sbi.nMax], ecx
        mov     [.sbi.fMask], SIF_RANGE
        mov     [.sbi.cbSize], sizeof.SCROLLINFO
        lea     eax, [.sbi]
        invoke  SetScrollInfo, [.hwnd], SB_HORZ, eax, TRUE

        mov     eax, [.maxrect.top]
        mov     ecx, [.maxrect.bottom]

        mov     [.sbi.nMin], 0
        mov     [.sbi.nMax], ecx
        lea     eax, [.sbi]
        invoke  SetScrollInfo, [.hwnd], SB_VERT, eax, TRUE

        return
endp


DispSize 'Scrollbars library:', $-ScrollbarsLib
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































Deleted include/libs/splitter.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
;*********************************************
; This is code for universal splitter control
; (C)2003 John Found
; It MUST be fixed in order to be added to the
; Fresh visual controls.
;*********************************************

iglobal
  cSplitterClassName text 'TSplitter',0
endg

;*************************************************************************
; Registers class TSplitter
;*************************************************************************
initialize RegisterSplitterClass
.wc WNDCLASS
begin
        xor     eax,eax
        mov     [.wc.style], CS_DBLCLKS or CS_PARENTDC or CS_VREDRAW or CS_HREDRAW
        mov     [.wc.lpfnWndProc], SplitterProc
        mov     [.wc.cbClsExtra], eax
        mov     [.wc.cbWndExtra], 4

        mov     [.wc.hIcon],eax
        mov     [.wc.hCursor],eax
        mov     [.wc.hbrBackground], eax
        mov     [.wc.lpszMenuName], eax
        mov     [.wc.lpszClassName], cSplitterClassName

        invoke  GetModuleHandleA,eax
        mov     [.wc.hInstance],eax

        lea     eax,[.wc]
        invoke  RegisterClassA,eax

        return
endp


proc CreateSplitter, .hControl, .flagVisible, .CursorV, .CursorH
begin
        push    ebx esi
        xor     ebx, ebx

        invoke  GetModuleHandleA, ebx
        mov     esi, eax

        invoke  GetParent, [.hControl]
        test    eax, eax
        jz      .finish

        mov     ecx, WS_CHILD or WS_CLIPSIBLINGS
        cmp     [.flagVisible], FALSE
        je      @f
        or      ecx, WS_VISIBLE
@@:
        invoke  CreateWindowExA, ebx, cSplitterClassName, ebx,       \
                                ecx,                                \
                                ebx, ebx, 20, 20,                 \
                                eax, ebx, esi, [.hControl]
        push    eax
        invoke  SendMessageA, eax, SPM_SETCURSORS, [.CursorV], [.CursorH]
        pop     eax
.finish:
        pop     esi ebx
        return
endp

;*************************************************************************
; The window proc for TSplitter control.
;*************************************************************************
proc SplitterProc, .hwnd, .wmsg, .wparam, .lparam

.ctrl   dd      ?
.rect   RECT
.pnt    POINT
.pntstr PAINTSTRUCT

begin
        push    esi edi ebx

        mov     ebx,[.wmsg]
        call    JumpTo
        MessageList                             \
          WM_CREATE,            .create,        \
          WM_DESTROY,           .destroy,       \
          WM_WINDOWPOSCHANGING, .poschanging,   \
          AM_ALIGNCHANGED,      .alignchanged,  \
          WM_MOUSEMOVE,         .mousemove,     \
          WM_LBUTTONDOWN,       .buttondown,    \
          WM_LBUTTONUP,         .buttonup,      \
          WM_SETCURSOR,         .setcursor,     \
          WM_ERASEBKGND,        .eraseback,     \
          SPM_SETCONTROL,       .setcontrol,    \
          SPM_SETCURSORS,       .setcursors,    \
          SPM_SETMAXMIN,        .setmaxmin

.default:
        invoke  DefWindowProcA, [.hwnd], [.wmsg], [.wparam], [.lparam]
        jmp     .finish

;***************************************************************************
.setmaxmin:
        invoke  GetWindowLongA, [.hwnd], 0
        mov     ecx, [.wparam]
        mov     edx, [.lparam]
        mov     [eax+TSplitter.MinSize], ecx
        mov     [eax+TSplitter.MaxSize], edx
        jmp     .finishdone

;***************************************************************************
.setcontrol:
        cmp     [.wparam],0
        jz      .finishdone

        invoke  GetParent, [.wparam]
        invoke  SetParent, [.hwnd], eax

        invoke  GetWindowLongA, [.hwnd], 0
        push    [.wparam]
        pop     [eax+TSplitter.Control]

        invoke  GetPropA, [.wparam], [propAlign]
        stdcall SetAlign, [.hwnd], eax

        xor     ebx, ebx
        invoke  SetWindowPos, [.hwnd], [.wparam], ebx, ebx, ebx, ebx, SWP_NOMOVE or SWP_SHOWWINDOW
        stdcall AlignSiblings, [.hwnd]

        invoke  IsWindowVisible, [.wparam]
        invoke  ShowWindow, [.hwnd], eax

        jmp     .finishdone

;***************************************************************************
.setcursors:
        invoke  GetWindowLongA, [.hwnd], 0
        push    [.wparam]
        push    [.lparam]
        pop     [eax+TSplitter.crHorizontal]
        pop     [eax+TSplitter.crVertical]
        jmp     .finishdone

;***************************************************************************
.mousemove:
        invoke  GetCapture
        cmp     eax,[.hwnd]
        jne     .finishdone

        invoke  GetWindowLongA,[.hwnd],0
        push    [eax+TSplitter.Control]
        pop     [.ctrl]
        movsx   esi,word [.lparam]
        movsx   edi,word [.lparam+2]

        cmp     [eax+TSplitter.Orientation],soVertical
        je      .movex
        cmp     [eax+TSplitter.Orientation],soHorizontal
        je      .movey

        xor     esi,esi
        xor     edi,edi
        jz      .domove

.movex:
        sub     esi,[eax+TSplitter.Hold.x]
        xor     edi,edi
        jmp     .domove

.movey:
        sub     edi,[eax+TSplitter.Hold.y]
        xor     esi,esi

.domove:
        mov     [.pnt.x],esi
        mov     [.pnt.y],edi
        lea     ebx,[.pnt]
        mov     edi,eax         ; Address of TSplitter structure

        invoke  ClientToScreen,[.hwnd],ebx
        invoke  GetParent, [.hwnd]
        invoke  ScreenToClient,eax,ebx

; there is no need to move the splitter itself. The align system will move it automaticaly.
;       invoke  SetWindowPos,[.hwnd],NULL,[.pnt.x],[.pnt.y],0,0,SWP_NOSIZE or SWP_NOZORDER
; resize the control

        lea     esi,[.rect]
        invoke  GetWindowRect,[.ctrl], esi
        invoke  GetParent,[.ctrl]
        mov     ebx,eax

        invoke  ScreenToClient,ebx, esi
        add     esi,8
        invoke  ScreenToClient,ebx,esi

        invoke  GetPropA, [.ctrl], [propAlign]
        mov     ecx,eax

        mov     edx,[edi+TSplitter.MinSize]
        mov     ebx,[edi+TSplitter.MaxSize]

        loop    @f

;.sizeLeft:
        add     edx, [.rect.left]
        add     ebx, [.rect.left]

        mov     eax,[.pnt.x]
        cmp     eax,edx
        jge     .cmx1
        mov     eax,edx
.cmx1:
        cmp     eax,ebx
        jle     .cmx2
        mov     eax,ebx
.cmx2:
        mov     [.rect.right], eax
        jmp     .dosize

@@:     loop    @f
;.sizeRight:
        sub     edx,[.rect.right]
        sub     ebx,[.rect.right]
        neg     edx                     ; Max coordinate
        neg     ebx                     ; Min coordinate

        mov     eax,[.pnt.x]
        add     eax,[edi+TSplitter.Width]

        cmp     eax,ebx
        jge     .cmx3
        mov     eax,ebx
.cmx3:
        cmp     eax,edx
        jle     .cmx4
        mov     eax,edx
.cmx4:
        mov     [.rect.left],eax
        jmp     .dosize

@@:     loop    @f
;.sizeTop:
        add     edx,[.rect.top]
        add     ebx,[.rect.top]

        mov     eax,[.pnt.y]

        cmp     eax,edx
        jge     .cmy1
        mov     eax,edx
.cmy1:
        cmp     eax,ebx
        jle     .cmy2
        mov     eax,ebx
.cmy2:
        mov     [.rect.bottom],eax
        jmp     .dosize

@@:     loop    @f
;.sizeBottom:
        sub     edx,[.rect.bottom]
        sub     ebx,[.rect.bottom]
        neg     edx                     ; Max coordinate
        neg     ebx                     ; Min coordinate

        mov     eax,[.pnt.y]
        add     eax,[edi+TSplitter.Width]

        cmp     eax,ebx
        jge     .cmy3
        mov     eax,ebx
.cmy3:
        cmp     eax,edx
        jle     .cmy4
        mov     eax,edx
.cmy4:
        mov     [.rect.top],eax

.dosize:
        mov     eax,[.rect.right]
        mov     ebx,[.rect.bottom]
        sub     eax,[.rect.left]
        sub     ebx,[.rect.top]

        invoke  SetWindowPos, [.ctrl], NULL, [.rect.left], [.rect.top], eax, ebx, SWP_NOZORDER or SWP_NOCOPYBITS
        stdcall AlignSiblings, [.ctrl]
@@:
        jmp     .finishdone

;**************************************************************************

.buttondown:
        invoke  SetCapture, [.hwnd]
        invoke  GetWindowLongA,  [.hwnd], GWL_HWNDPARENT

        mov     edi,eax
        lea     esi,[.rect]

        invoke  GetClientRect, edi, esi
        invoke  ClientToScreen, edi, esi
        add     esi,8
        invoke  ClientToScreen, edi, esi
        sub     esi,8
        invoke  ClipCursor, esi

        invoke  GetWindowLongA, [.hwnd], 0
        movzx   esi, word [.lparam]
        movzx   edi, word [.lparam+2]
        mov     [eax+TSplitter.Hold.x],esi
        mov     [eax+TSplitter.Hold.y],edi
        jmp     .finishdone

;**************************************************************************

.buttonup:

        invoke  ReleaseCapture
        invoke  ClipCursor,NULL
        jmp     .finishdone

;**************************************************************************

.create:
        stdcall GetMem, sizeof.TSplitter
        mov     esi,eax

        invoke  SetWindowLongA, [.hwnd], 0, esi

        mov     [esi+TSplitter.Width],4
        mov     [esi+TSplitter.Orientation],soNone
        mov     [esi+TSplitter.MinSize],$10
        mov     [esi+TSplitter.MaxSize],$120
        mov     [esi+TSplitter.crVertical], IDC_SIZEWE or $ffff0000
        mov     [esi+TSplitter.crHorizontal], IDC_SIZENS or $ffff0000

        mov     eax, [.lparam]
        mov     eax, [eax+CREATESTRUCT.lpCreateParams]
        test    eax, eax
        jz      .finishdone

        invoke  SendMessageA, [.hwnd], SPM_SETCONTROL, eax, eax
        jmp     .finishdone

;**************************************************************************

.destroy:
        invoke  GetWindowLongA,[.hwnd],0
        mov     esi,eax
        stdcall FreeMem, esi
        jmp     .finishdone

;**************************************************************************
.poschanging:
        invoke  GetWindowLongA,[.hwnd],0
        mov     esi,eax                         ; Pointer of TSplitter
        mov     edi,[.lparam]

        mov     ecx, [esi+TSplitter.Orientation]
        loop    @f
; soVertical
        push    [esi+TSplitter.Width]
        pop     [edi+WINDOWPOS.cx]
        jmp     .finishdone

@@:     loop    @f
; soHorizontal
        push    [esi+TSplitter.Width]
        pop     [edi+WINDOWPOS.cy]
@@:
; soNone
        jmp     .finishdone
;**************************************************************************

.alignchanged:
        invoke  GetWindowLongA,[.hwnd],0
        cmp     [.wparam],waLeft
        je      .setvert
        cmp     [.wparam],waRight
        je      .setvert
        cmp     [.wparam],waTop
        je      .sethorz
        cmp     [.wparam],waBottom
        je      .sethorz

        mov     [eax+TSplitter.Orientation],soNone
        jmp     .finishdone

.setvert:
        mov     [eax+TSplitter.Orientation],soVertical
        jmp     .finishdone

.sethorz:
        mov     [eax+TSplitter.Orientation],soHorizontal
        jmp     .finishdone

;**************************************************************************

.setcursor:
        invoke  GetWindowLongA,[.hwnd],0
        mov     ecx,[eax+TSplitter.Orientation]
        xor     edx,edx
        jecxz   @f
        mov     edx, [eax+TSplitter.crVertical + 4*ecx -4]
@@:
        push    edx
        and     dword [esp], $ffff
        xor     eax, eax
        test    edx, edx
        js      .loadit

        invoke  GetModuleHandleA, eax

.loadit:
        push    eax
        invoke  LoadCursorA      ; arguments are in the stack.
        invoke  SetCursor,eax

        jmp     .finishdone

;**************************************************************************

.eraseback:
        lea     edi, [.rect]
        invoke  GetClientRect, [.hwnd], edi
        invoke  DrawEdge, [.wparam], edi, EDGE_ETCHED, BF_RECT or BF_MIDDLE
        xor     eax,eax
        inc     eax
        pop     ebx edi esi
        return

;**************************************************************************
.finishdone:
        xor     eax,eax
.finish:
        pop     ebx edi esi
        return
endp


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted include/libs/splitter.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
;************************************************
; splitter control structures and constants.
;
; (c)2003 John Found
;************************************************

soNone       = 0
soVertical   = 1
soHorizontal = 2

winmessage SPM_SETCONTROL          ; wparam - handle of the control that will be resized.
winmessage SPM_SETCURSORS          ; wparam - vertical cursor resource, lparam - horizontal cursor resource
winmessage SPM_SETMAXMIN           ; (min, max)

struct TSplitter
  .Width        dd ?        ; width if HSIZE / height if VSIZE
  .Control      dd ?        ; handle of resized control.
  .Hold         POINT
  .Orientation  dd ?      ; Don't set manually this field

  .MinSize      dd ?
  .MaxSize      dd ?

  .crVertical   dd ?      ; Vertical cursor.
  .crHorizontal dd ?      ; Horizontal cursor.
ends

;********************************************

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































Deleted include/libs/templates.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
; Common properties names.
iglobal
  property propAlign, 'Align'
  property propAutoSize, 'AutoSize'
  property propOwnFont, 'OwnFont'
  property propOldWinProc, 'OldWinProc'
  property propUserWinProc, 'UserWinProc'
endg

;initialize CreateCommonProperties
;begin
;        stdcall CreateProperty, propAlign
;        stdcall CreateProperty, propAutoSize
;        stdcall CreateProperty, propOwnFont
;        stdcall CreateProperty, propOldWinProc
;        stdcall CreateProperty, propUserWinProc
;        return
;endp
;
;finalize DeleteCommonProperties
;begin
;        stdcall DestroyProperty, propAlign
;        stdcall DestroyProperty, propAutoSize
;        stdcall DestroyProperty, propOwnFont
;        stdcall DestroyProperty, propOldWinProc
;        stdcall DestroyProperty, propUserWinProc
;        return
;endp
;

;*********************************************************************************************
; CreateForm
; Creates form window with all children from template.
; Arguments:
;   ptrTemplate - pointer to the form template. See TWinTemplate structure and
;                 WinTemplate macro in 'form.inc' for details.
; Returns:
;   EBX - handle of the created form. It's more useful to use ebx for this purpose to
;         allow using of folowing sequence without eax preserving:
;
;         stdcall CreateForm, xxxx
;         stdcall ShowModal, ebx
;         ... some API calls ...
;         invoke DestroyWindow, ebx
;
;*********************************************************************************************
proc CreateForm, .ptrTemplate, .hOwner
begin
        push    esi edi

        mov     esi, [.ptrTemplate]
        stdcall _DoCreateForm, [.hOwner]
        invoke  SendMessageA, ebx, FM_AFTERCREATE, 0, 0

        pop     edi esi
        return
endp

;----- internal called from create form ------------------------------------

proc _DoCreateForm, .hParent

.hwnd   dd      ?
.style  dd      ?

begin
        push    edi

.loop:
        push    [esi+TWinTemplate.WinProc]      ; ???
        push    [hInstance]
        movzx   eax, [esi+TWinTemplate.ID]
        movsx   edx, [esi+TWinTemplate.height]
        movsx   ecx, [esi+TWinTemplate.width]
        push    eax
        push    [.hParent]
        push    edx
        push    ecx

        movsx   edx, [esi+TWinTemplate.top]
        movsx   eax, [esi+TWinTemplate.left]
        push    edx
        push    eax

        mov     eax, [esi+TWinTemplate.style]
        mov     [.style], eax
        test    eax, WS_CHILD
        jnz     .styleok
        and     eax, not WS_VISIBLE
.styleok:
        push    eax

        push    [esi+TWinTemplate.ptrText]
        push    [esi+TWinTemplate.ptrClass]
        push    [esi+TWinTemplate.styleEx]
        invoke  CreateWindowExA

        mov     [.hwnd], eax
        cmp     [esi+TWinTemplate.WinProc], 0
        je      .subclassok

        stdcall SubclassWindow, eax, [esi+TWinTemplate.WinProc]

.subclassok:
        movzx   eax, [esi+TWinTemplate.Align]
        stdcall SetAlign, [.hwnd], eax

        invoke  SendMessageA, [.hParent], WM_GETFONT, 0, 0
        stdcall ControlSetFont, [.hwnd], eax

        movzx   edi, [esi+TWinTemplate.flags]
        add     esi, sizeof.TWinTemplate

        test    edi, wtParent
        jz      @f

        stdcall _DoCreateForm, [.hwnd]

@@:
        test    [.style], WS_CHILD
        jnz     @f

        test    [.style], WS_VISIBLE
        jz      @f

        invoke  ShowWindow, [.hwnd], SW_SHOWNORMAL
@@:
        test    edi, wtEnd
        jz      .loop

        mov     ebx, [.hwnd]
        pop     edi
        return
endp



proc SubclassWindow, .hwnd, .ptrUserProc
begin
        invoke  GetWindowLongA, [.hwnd], GWL_WNDPROC
        invoke  SetPropA, [.hwnd], [propOldWinProc], eax
        invoke  SetPropA, [.hwnd], [propUserWinProc], [.ptrUserProc]
        invoke  SetWindowLongA, [.hwnd], GWL_WNDPROC, UniversalWinProc
        invoke  SendMessageA, [.hwnd], AM_INITWINDOW, 0, 0
        return
endp


proc UnSubclassWindow, .hwnd
begin
        invoke  GetPropA, [.hwnd], [propOldWinProc]
        test    eax, eax
        jz      .exit

        invoke  SetWindowLongA, [.hwnd], GWL_WNDPROC, eax
        invoke  RemovePropA, [.hwnd], propOldWinProc
        invoke  RemovePropA, [.hwnd], propUserWinProc
.exit:
        return
endp


proc UniversalWinProc, .hwnd, .wmsg, .wparam, .lparam
begin
        invoke  GetPropA, [.hwnd], [propUserWinProc]
        test    eax, eax
        jz      .oldproc

        push    ebx esi edi
        mov     ebx, [.wmsg]
        stdcall eax, [.hwnd], ebx, [.wparam], [.lparam]
        pop     edi esi ebx
        jnc     .finish

.oldproc:
        invoke  GetPropA, [.hwnd], [propOldWinProc]
        invoke  CallWindowProcA, eax ,[.hwnd],[.wmsg],[.wparam],[.lparam]

.finish:
        return
endp


;------------------------------------------------------------
; Set new Align for the window.
; Notifies the window about changing with AM_ALIGNCHANGED
; Realigns the parent childrens.
; Returns old align
;------------------------------------------------------------
proc SetAlign, .hwnd, .align
begin
        invoke  GetPropA, [.hwnd], [propAlign]
        cmp     eax, [.align]
        je      .exit

        push    eax

        invoke  SetPropA, [.hwnd], [propAlign], [.align]
        invoke  SendMessageA, [.hwnd], AM_ALIGNCHANGED, [.align], 0

        stdcall AlignSiblings, [.hwnd]
        pop     eax
.exit:
        return
endp



;----------------------------------------------------------------------
; Set the font of some window if propOwnFont = FALSE
;----------------------------------------------------------------------
proc ControlSetFont, .hwnd, .hFont
begin
        invoke  GetPropA, [.hwnd], [propOwnFont]
        test    eax, eax
        jnz     .exit

        invoke  SendMessageA, [.hwnd], WM_SETFONT, [.hFont], TRUE
        mov     eax, TRUE

.exit:
        return
endp


; Various property related string procedures
proc CreateProperty, .ptrProp
begin
        push    ebx
        mov     ebx, [.ptrProp]
        invoke  IsBadReadPtr, ebx, 4
        test    eax, eax
        jnz     .exit

        invoke  IsBadStringPtr, [ebx], 256
        test    eax, eax
        jnz     .exit

        invoke  AddAtom, [ebx]
        movzx   eax, ax
        mov     [ebx], eax
.exit:
        pop     ebx
        return
endp


proc DestroyProperty, .ptrProp
begin
        push    ebx
        mov     ebx, [.ptrProp]
        invoke  IsBadReadPtr, ebx, 4
        test    eax, eax
        jnz     .exit

        invoke  DeleteAtom, [ebx]
.exit:
        pop     ebx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































Deleted include/libs/templates.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
;***************************************************************
; Template engine related constants and structures
;***************************************************************

winmessage AM_INITWINDOW
winmessage AM_ALIGNCHANGED


wtChild  = 0
wtParent = 1    ; The current window is the parent for next windows until the window with wtEnd flag.
wtEnd    = 2    ; The current window is the last child of the current parent window. The next
                ; window becomes child of the previous parent.


;-------------------------------------------------------------------------
; This is structure describing the windows parent child structure.
;-------------------------------------------------------------------------
struct TWinTemplate
  .flags      db  ?   ;
  .Align      db  ?
  .ptrClass   dd  ?   ; pointer to the classname.
  .ptrText    dd  ?
  .style      dd  ?
  .styleEx    dd  ?
  .ID         dw  ?
  .left       dw  ?
  .top        dw  ?
  .width      dw  ?
  .height     dw  ?
  .WinProc    dd  ?
ends


macro Window  name, flags, walign, class, txt, style, styleEx, ID, left, top, width, height, winproc {
common
  if ~(name eq NONE)
    label name
  end if
  local ..class, ..text

  db   flags
  db   walign
  dd   ..class ; pointer to the classname.
  if txt eqtype ''
    dd   ..text  ; pointer to the text.
  else
    dd  txt
  end if
  dd   style
  dd   styleEx
  dw   ID
  dw   left
  dw   top
  dw   width
  dw   height
  dd   winproc

  ..class text class
  ..text  text txt
}

ComDlgStyle = WS_CAPTION or WS_SYSMENU or WS_DLGFRAME or WS_TABSTOP
ComCtrlStyle = WS_CHILD or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_VISIBLE


;------------------------------------------------------------------------
; Macro for defining names for window properties (SetProp/GetProp)
; that to be used with and without AddAtom function.
; When the name is not added to the atom table, the first
; dword of the structure contains pointer to the string.
; If the macro is added to the application atom table
; (via CreateProperty procedure), the first dword contains
; atom handle. In both cases GetProp and SetProp uses [propname] as
; pointer to the property name.
;------------------------------------------------------------------------
macro property [name, string] {
  forward
    align 4
    local ..txt
    name  dd ..txt
    ..txt db string
    dw   0
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































Deleted include/libs/tform.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
TFormLib:

;************************************************************
;*   Form class library                                     *
;*                                                          *
;*   This file is part of Fresh base library                *
;*   This is base window class for "Fresh" created project  *
;*                                                          *
;*   (C)2003, 2004 John Found                               *
;************************************************************

;*********************************************************************************************
; Registers form window class
; Call only once
;*********************************************************************************************
initialize RegisterFormClass

.wc WNDCLASS

begin
        xor     eax, eax
        lea     edi, [.wc]
        mov     ecx, sizeof.WNDCLASS / 4
        rep stosd

        invoke  LoadCursorA, eax, IDC_ARROW
        mov     [.wc.hCursor],eax
        mov     [.wc.style], CS_OWNDC
        mov     [.wc.lpfnWndProc],FormWinProc
        mov     [.wc.cbWndExtra], 32
        mov     eax,[hInstance]
        mov     [.wc.hInstance],eax
        mov     [.wc.lpszClassName], cFormClassName

        lea     eax, [.wc]
        invoke  RegisterClassA, eax

        return
endp


iglobal
  cFormClassName text 'TForm'
  property propLastFocused, 'LastFocused'
  property propColor, 'Color'
  property propModalResult, 'ModalResult'
  property propFont, 'Font'
endg

uglobal
  hLastBeforeMenu dd ?

  LastMessage dd ? ; debug only
endg


;initialize CreateFormProperties
;begin
;        stdcall CreateProperty, propLastFocused
;        stdcall CreateProperty, propColor
;        stdcall CreateProperty, propModalResult
;        stdcall CreateProperty, propFont
;        return
;endp


;finalize DeleteFormProperties
;begin
;        stdcall DestroyProperty, propLastFocused
;        stdcall DestroyProperty, propColor
;        stdcall DestroyProperty, propModalResult
;        stdcall DestroyProperty, propFont
;        return
;endp


;*********************************************************************************************
; Main window procedure for 'TForm' window class.
;*********************************************************************************************
winproc FormWinProc
begin
        push    ebx edi esi
        mov     ebx, [.wmsg]

ondefault
        push    [.wmsg]
        pop     [LastMessage]
        invoke  DefWindowProcA, [.hwnd],[.wmsg],[.wparam],[.lparam]
        pop     esi edi ebx
        return

;------------------------------------------------------------------------
onmessage FM_SETCOLOR
        mov      eax, [.wparam]
        cmp      eax, $ff000000
        jne      .setcolor

        invoke  RemovePropA, [.hwnd], [propColor]
        pop     esi edi ebx
        return

.setcolor:
        or       eax, $ff000000
        invoke   SetPropA, [.hwnd], [propColor], eax
        invoke   InvalidateRect, [.hwnd], NULL, TRUE
        pop     esi edi ebx
        return

;------------------------------------------------------------------------
onmessage WM_SYSCOMMAND
        mov     eax, [.wparam]
        and     eax, $fff0

        cmp     eax, SC_MINIMIZE
        je      .savestate

        cmp     eax, SC_KEYMENU
        jne     .ondefault

        invoke  GetParent, [.hwnd]
        mov     ebx, eax
        test    eax, eax
        jnz     .resendmessage

; Get the main application window.
if defined AppLib
        invoke  GetPropA, [hApplication], [propMainForm]
        test    eax, eax
        jz      .ondefault

        cmp     eax, [.hwnd]
        je      .ondefault

        mov     ebx, eax
else
  if defined hMainForm
        mov ebx, [hMainForm]
        cmp ebx, [.hwnd]
        je  .ondefault
  end if
        jmp     .ondefault
end if

        invoke  GetMenu, [.hwnd]
        test    eax, eax
        jnz     .ondefault

        invoke  GetFocus
        mov     [hLastBeforeMenu], eax

        invoke  SetFocus, ebx

.resendmessage:
        invoke  SendMessageA, ebx, [.wmsg], [.wparam], [.lparam]

        xor     eax, eax
        pop     esi edi ebx
        return

;-------------------------------------------------
onmessage WM_ACTIVATE
        cmp     word [.wparam], WA_INACTIVE
        jne     .ondefault

; Save the last focused window
.savestate:
        stdcall GetFocusedControl, [.hwnd]
        test    eax, eax
        jz      .ondefault

        invoke  SetPropA, [.hwnd], [propLastFocused], eax
        jmp     .ondefault

;----------------------------------------------------------------
onmessage WM_SETFOCUS
; Restore the last focused window
        invoke  GetPropA, [.hwnd], [propLastFocused]
        test    eax, eax
        jnz     .focusit

        invoke  GetNextDlgTabItem, [.hwnd], NULL, FALSE
        test    eax, eax
        jz      .endsetfocus

        push    eax
        invoke  SetPropA, [.hwnd], [propLastFocused], eax
        pop     eax

.focusit:
        invoke  SetFocus, eax

.endsetfocus:
        xor     eax, eax
        pop     esi edi ebx
        return

;-------------------------------------------------------------------------
;onmessage WM_NEXTDLGCTL
;;          int3
;        cmp     [.lparam], FALSE
;        je      .nextprev
;
;        invoke  SetFocus, [.wparam]
;        xor     eax, eax
;        pop     esi edi ebx
;        return
;
;.nextprev:
;        stdcall GetFocusedControl, [.hwnd]
;        test    eax, eax
;        jz      .focusok
;
;        invoke  GetNextDlgTabItem, [.hwnd], eax, [.wparam]
;        invoke  SetFocus, eax
;
;.focusok:
;        pop     esi edi ebx
;        return

;------------------------------------------------------------------------
onmessage WM_ERASEBKGND
locals
  .rect    RECT
endl
        lea     eax, [.rect]
        invoke  GetClientRect, [.hwnd], eax

        invoke  GetPropA, [.hwnd], [propColor]
        test    eax, eax
        jnz     .colorok

        invoke  GetSysColor, COLOR_BTNFACE

.colorok:
        and     eax, $ffffff
        invoke  CreateSolidBrush, eax
        push    eax
        lea     ecx, [.rect]
        invoke  FillRect, [.wparam], ecx, eax
        invoke  DeleteObject ; from the stack.
        xor     eax, eax
        inc     eax
        pop     esi edi ebx
        return

;------------------------------------------------------------------------
onmessage WM_COMMAND

        invoke  GetWindowLongA, [.hwnd], GWL_STYLE
        test    eax, WS_CHILD
        jz      .process

        invoke  GetParent, [.hwnd]
        test    eax, eax
        jz      .process

        invoke  SendMessageA, eax, [.wmsg], [.wparam], [.lparam]
        xor     eax, eax
        pop     esi edi ebx
        return

.process:
        movzx   eax, word [.wparam]
        cmp     eax, MODAL_MIN
        jb      .ondefault
        cmp     eax, MODAL_MAX
        ja      .ondefault

        invoke  SetPropA, [.hwnd], [propModalResult], eax

        xor     eax, eax
        pop     esi edi ebx
        return

;------------------------------------------------------------------------
onmessage WM_CLOSE
if defined AppLib

        invoke  GetPropA, [hApplication], [propMainForm]
        cmp     eax, [.hwnd]
        jne     .ondefault

        invoke  SendMessageA,  [hApplication], WM_CLOSE, 0, 0
        xor     eax, eax
        pop     esi edi ebx
        return
else
  if defined hMainForm
        mov     eax, [.hwnd]
        cmp     eax, [hMainForm]
        jne     .ondefault

        invoke  PostQuitMessage, 0
        jmp     .ondefault
  end if
end if


;------------------------------------------------------------------------
onmessage WM_EXITMENULOOP
        cmp     [hLastBeforeMenu], 0
        je      @f

        invoke  SetFocus, [hLastBeforeMenu]
@@:
        xor     eax, eax
        mov     [hLastBeforeMenu], eax
        pop     esi edi ebx
        return

;------------------------------------------------------------------------
onmessage WM_WINDOWPOSCHANGED
        mov     eax, [.lparam]
        mov     ecx, [eax+WINDOWPOS.flags]
        test    ecx, SWP_SHOWWINDOW
        jnz     .realign

        test    ecx, SWP_HIDEWINDOW
        jnz     .savestate

        test    ecx, SWP_NOSIZE
        jnz     .ondefault

.realign:
        stdcall AlignChildren, [.hwnd]
        jmp     .ondefault

;------------------------------------------------------------------------


if defined GUILib
;------------------------------------------------------------------------
onmessage WM_MEASUREITEM
        stdcall OnMeasureItem,[.hwnd],[.lparam]
        mov     eax, TRUE
        pop     esi edi ebx
        return

;------------------------------------------------------------------------
onmessage WM_DRAWITEM
        stdcall OnDrawItem, [.lparam]
        mov     eax, TRUE
        pop     esi edi ebx
        return

;------------------------------------------------------------------------
onmessage WM_MENUCHAR
        stdcall OnMenuChar, [.wparam], [.lparam]
        jc      .ondefault
        pop     esi edi ebx
        return

end if

;------------------------------------------------------------------------
onmessage WM_GETFONT
        invoke  GetPropA, [.hwnd], [propFont]
        test    eax, eax
        jnz     @f

        invoke  GetStockObject, DEFAULT_GUI_FONT
@@:
        pop     esi edi ebx
        return

;------------------------------------------------------------------------
onmessage WM_PARENTNOTIFY
        cmp     word [.wparam], WM_CREATE
        jne     @f

        invoke  GetPropA, [.lparam], [propOwnFont]
        test    eax, eax
        jnz     @f

        invoke  SendMessageA, [.hwnd], WM_GETFONT, 0, 0
        invoke  SendMessageA, [.lparam], WM_SETFONT, eax, TRUE

@@:
        xor     eax, eax
        pop     esi edi ebx
        return
endwp



proc GetFocusedControl, .hwnd
begin
        push    esi ebx
        invoke  GetFocus
        mov     esi, eax

.parentloop:
        mov     ebx, eax
        invoke  GetParent, eax
        test    eax, eax
        jnz     .parentloop

;        xor     eax, eax     ; eax is zero here...
        cmp     ebx, [.hwnd]
        jne     .endfocused
        mov     eax, esi
.endfocused:
        pop     ebx esi
        return
endp


;*********************************************************************************************
; Shows given form in modal form.
; Returns modal result
; This is first version so behaviour is not very proper.
;*********************************************************************************************

proc ShowModal, .hwnd, .flags

.rect RECT

        begin
        push    esi edi ebx

        invoke  GetFocus
        push    eax      ; the parameter for SetFocus at the end of the procedure.

        lea     eax, [.rect]
        invoke  GetWindowRect, [.hwnd], eax

        mov     esi, [.rect.left]
        mov     edi, [.rect.top]

        test    [.flags], MSF_HCENTER
        jz      @f

        invoke  GetSystemMetrics, SM_CXSCREEN
        sub     eax, [.rect.right]
        add     eax, [.rect.left]
        sar     eax,1
        mov     esi, eax
@@:
        test    [.flags], MSF_VCENTER
        jz      @f

        invoke  GetSystemMetrics, SM_CYSCREEN
        sub     eax, [.rect.bottom]
        add     eax, [.rect.top]
        sar     eax,1
        mov     edi, eax

@@:
        invoke  SendMessageA, [.hwnd], WM_INITDIALOG, 0, 0
        invoke  SetWindowPos, [.hwnd], HWND_TOP, esi, edi, 0, 0, SWP_NOSIZE
        invoke  ShowWindow, [.hwnd], SW_SHOW
;        invoke  SendMessageA, [.hwnd], AM_CHILDRESIZED, 0, 0

        invoke  GetWindow, [.hwnd], GW_OWNER
        mov     ebx, eax

; Disables window owner and all other windows owned by window owner.

        invoke  EnableWindow, ebx, FALSE
        stdcall EnableAllOwnedWindows, ebx, FALSE       ; This is useless if all top level windows
                                                        ; are TForm, but it is important if not...

        invoke  EnableWindow, [.hwnd], TRUE              ; IMPORTANT: re-enable modal window.

        invoke  GetNextDlgTabItem, [.hwnd], NULL, FALSE
        test    eax, eax
        jz      @f
        invoke  SetFocus, eax
@@:
        invoke  SetPropA, [.hwnd], [propModalResult], MR_NONE

; Special message loop for modal window. It not finish until window becomes invisible.
.modalloop:
        call    ProcessMessages

        invoke  IsWindowVisible, [.hwnd]
        test    eax,eax
        jz      .endloop

        invoke  GetPropA, [.hwnd], [propModalResult]
        test    eax,eax              ; mrNone = 0
        jnz     .endloop

        invoke  SendMessageA, [.hwnd], FM_ONIDLE, 0, 0

        invoke  WaitMessage
        jmp     .modalloop

.endloop:
        stdcall EnableAllOwnedWindows, ebx, TRUE
        invoke  EnableWindow, ebx, TRUE
        invoke  ShowWindow, [.hwnd], SW_HIDE

        invoke  SetFocus                       ; the parameter is in stack

        invoke  GetPropA, [.hwnd], [propModalResult]
        pop     ebx edi esi
        return
endp


;-------------------------------------------------------------
; Enables or disables all windows owned by specifyed window.
;
; fEnable - TRUE = enable
;           FALSE = disable
;-------------------------------------------------------------
proc EnableAllOwnedWindows, .hwnd, .fEnable
        begin

        mov     eax, _EnableOwnedProc
        cmp     [.fEnable], FALSE
        jne     @f
        mov     eax, _DisableOwnedProc
@@:
        invoke  EnumWindows, eax, [.hwnd]
        return
endp


; callback procedure used in EnableAllOwnedWindows
proc _EnableOwnedProc, .hwnd, .owner
begin

        invoke  GetWindow, [.hwnd], GW_OWNER
        cmp     eax, [.owner]
        jne     .ready
        invoke  EnableWindow, [.hwnd], TRUE

.ready:
        mov     eax, 1
        return
endp


; callback procedure used in EnableAllOwnedWindows
proc _DisableOwnedProc, .hwnd, .owner
begin
        invoke  GetWindow, [.hwnd], GW_OWNER

        cmp     eax, [.owner]
        jne     .ready
        invoke  EnableWindow, [.hwnd], FALSE
.ready:
        mov     eax, 1
        return
endp




DispSize 'TForm class library', $ - TFormLib
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted include/libs/tform.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
;-------------------------------
; Form messages
;-------------------------------
FM_FIRST = WM_USER + $5000

FM_AFTERCREATE = FM_FIRST+1     ;(0, 0) - message that is send to the main form window, after creation.
FM_SETCOLOR    = FM_FIRST+2     ;(color, 0)

if defined AM_ONIDLE
  FM_ONIDLE = AM_ONIDLE
else
  FM_ONIDLE = FM_FIRST+3
end if

struct TForm
  .hFont        dd  ?        ; handle of the form font.
  .ModalResult  dd  ?        ; Modal result for modal forms.
  .hPopupMenu   dd  ?        ; popup menu handler
  .clBackground dd  ?        ; Background color.
ends



;***************************************************************
; ShowModal related constants and structures
;***************************************************************
;-------------------------------
;    Modal show flags
;-------------------------------
MSF_HCENTER  =  1  ; On show, center form horizontaly on screen.
MSF_VCENTER  =  2  ; On show, center form verticaly on screen.
MSF_CENTER   =  3  ; On show, center form horizontaly and verticaly on screen.


;-------------------------------
; Modal result ID's
; Some button must have some of
; these values for ID to set
; automatically ModalResult
; Use it as: MODAL_ID + MR_OK
;-------------------------------
;------------------------------------------------
;   Modal result predefined constants
;------------------------------------------------
MODAL_MIN       =  MR_NONE
MR_NONE         =       0
MR_OK           =       IDOK
MR_CANCEL       =       IDCANCEL
MR_ABORT        =       IDABORT
MR_RETRY        =       IDRETRY
MR_IGNORE       =       IDIGNORE
MR_YES          =       IDYES
MR_NO           =       IDNO
MR_CLOSE        =       IDCLOSE
MR_HELP         =       IDHELP
MODAL_MAX       =  MR_HELP

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































Deleted include/win32/allimports.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 library kernel32,'KERNEL32.DLL',\
          user32,'USER32.DLL',    \
          gdi32,'gdi32.dll',      \
          comctl32,'comctl32.dll',\
          comdlg32,'comdlg32.dll',\
          shell32, 'shell32.dll', \
          ole32,   'ole32.dll',   \
          advapi32,'advapi32.dll',\
          sqlite3, 'sqlite3.dll'


  include '%lib%/imports/Win32/kernel32.inc'
  include '%lib%/imports/Win32/user32.inc'
  include '%lib%/imports/Win32/gdi32.inc'
  include '%lib%/imports/Win32/ComCtl32.inc'
  include '%lib%/imports/Win32/ComDlg32.inc'
  include '%lib%/imports/Win32/Shell32.inc'
  include '%lib%/imports/Win32/ole32.inc'
  include '%lib%/imports/Win32/advapi32.inc'
  include '%lib%/imports/Win32/sqlite3.inc'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































Deleted include/win32/win32a.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
; Win32 programming headers (ASCII)

macro module [arg] {}
macro endmodule {}
macro uses [arg] {}

include '%lib%/macros/_struct.inc'
include '%lib%/macros/Win32/_exceptions.inc'
include '%lib%/macros/_stdcall.inc'
include '%lib%/macros/Win32/_winproc.inc'
include '%lib%/macros/Win32/_import.inc'
include '%lib%/macros/Win32/_export.inc'
include '%lib%/macros/_display.inc'
include '%lib%/macros/_globals.inc'

struc CHAR count { rb count }

macro TEXT lbl,[txt] {
  lbl  db  txt
}

include '%lib%/equates/Win32/_exceptions.inc'
include '%lib%/equates/Win32/_kernel32.inc'
include '%lib%/equates/Win32/_user32.inc'
include '%lib%/equates/Win32/_gdi32.inc'
include '%lib%/equates/Win32/_comctl32.inc'
include '%lib%/equates/Win32/_comdlg32.inc'
include '%lib%/equates/Win32/_shell32.inc'
include '%lib%/equates/Win32/_wsock32.inc'
include "%lib%/equates/_sqlite3.inc"

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































Deleted include/win32/win32w.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
; Win32 programming headers (Unicode)

include '%lib%/macros/_struct.inc'
include '%lib%/macros/Win32/_exceptions.inc'
include '%lib%/macros/_stdcall.inc'
include '%lib%/macros/Win32/_winproc.inc'
include '%lib%/macros/Win32/_import.inc'
include '%lib%/macros/Win32/_export.inc'
include '%lib%/macros/_display.inc'
include '%lib%/macros/_globals.inc'

struc CHAR count { rw count }
macro TEXT lbl, [txt] { lbl  du  txt }

include '%lib%/equates/Win32/_kernel32.inc'
include '%lib%/equates/Win32/_user32.inc'
include '%lib%/equates/Win32/_gdi32.inc'
include '%lib%/equates/Win32/_comctl32.inc'
include '%lib%/equates/Win32/_comdlg32.inc'
include '%lib%/equates/Win32/_shell32.inc'
include '%lib%/equates/Win32/_wsock32.inc'
include "%lib%/equates/Win32/_sqlite3.inc"

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































Deleted installer/Fresh2_0.iss.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
[Setup]
AppName=Fresh
AppVersion=2.0.9
;AppVerName=Fresh 2.0.9
AppPublisher=Fresh development team
AppPublisherURL=http://fresh.flatassembler.net
AppSupportURL=http://fresh.flatassembler.net
AppUpdatesURL=http://fresh.flatassembler.net
DefaultDirName={pf}\Fresh
DefaultGroupName=Fresh
AllowNoIcons=yes
LicenseFile=..\License.txt
OutputDir=..\installer
OutputBaseFilename=FreshSetup2_0_9
SetupIconFile=..\source\images\Fresh.ico
Compression=lzma/ultra64
SolidCompression=yes
Uninstallable = no

[Types]
Name: "all"; Description: "Custom type."; Flags: iscustom


[Components]
Name: "FreshIDE"; Description: "Fresh IDE essential files - binaries, includes and help."; Types: all; Flags: fixed;
Name: "SourceCode"; Description: "Full source code of Fresh IDE."; Types: all;
Name: "Examples"; Description: "Example Fresh projects."; Types: all;


[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Files]
; Fresh IDE
Source: "..\*";         Excludes: "*.ini,*.fossil,_FOSSIL_"; DestDir: "{app}";         Components: FreshIDE;   Flags: ignoreversion
Source: "..\include\*"; Excludes: "*.exe,*.dll";             DestDir: "{app}\include"; Components: FreshIDE;   Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\IDE\*"; Excludes: "Current.theme,*.exe,*.dll";   DestDir: "{app}\IDE";     Components: FreshIDE;   Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\doc\*.*";                                        DestDir: "{app}\doc";     Components: FreshIDE;   Flags: ignoreversion

; FreshLib  
Source: "..\freshlib\*"; Excludes: "*.exe,*.dll,\_*,_*\*,test_code\*,test_code0\*,\test_code,\test_code0,\ForthScript,TestFreshLib.fpr";  DestDir: "{app}\freshlib"; Components: FreshIDE;   Flags: ignoreversion recursesubdirs createallsubdirs

; Source code
;  Fresh
Source: "..\source\Fresh.fpr";                    DestDir: "{app}\source";    Components: SourceCode; Flags: ignoreversion
Source: "..\source\*.asm";                        DestDir: "{app}\source";    Components: SourceCode; Flags: ignoreversion
Source: "..\source\*.inc";                        DestDir: "{app}\source";    Components: SourceCode; Flags: ignoreversion
Source: "..\source\*.frm";                        DestDir: "{app}\source";    Components: SourceCode; Flags: ignoreversion
; FASM compiler
Source: "..\source\fasm\*.*";                     DestDir: "{app}\source\fasm";       Components: SourceCode; Flags: ignoreversion
; Images
Source: "..\source\images\*.*";                   DestDir: "{app}\source\images";     Components: SourceCode; Flags: ignoreversion

; Examples
Source: "..\examples\*"; Excludes: "*.exe,*.bin,*.tga";  DestDir: "{app}\examples";  Components: Examples; Flags: ignoreversion recursesubdirs createallsubdirs

[Run]
Filename: "{app}\Fresh.exe"; Description: "{cm:LaunchProgram,Fresh}"; Flags: nowait postinstall skipifsilent
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































Deleted source/ActionEvents.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
iglobal
  include 'actions.inc'   ; menus, action, etc

  cAddFileTitle text 'Add file to the project'
  cSetMainTitle text 'Select main file'
endg


ActionEvents:

;----------------------------------------------------------------
; This is OnIdle handler of the application.
; When message queue is empty, this subroutine is called once.
; The idea is to provide updating of the status of the controls
; without performance decreasing.
;----------------------------------------------------------------

proc OnIdle

.changed dd ?
.buffer  rb 256

begin
        push    esi edi ebx

        mov     [.changed], 0

        invoke  SendMessageA, [hMainToolbar], TB_ISBUTTONENABLED, actCut, 0
        test    eax,eax
        setnz   bh

        stdcall CanAction, [ptrCurrentFile], WM_CUT
        test    eax, eax
        setnz   bl

        cmp     bh, bl
        je      .cut_action_ok

        movzx   eax, bl
        movzx   ebx, bh         ; MF_BYCOMMAND + ( MF_GRAYED | MF_ENABLED )
        inc     [.changed]

        invoke  SendMessageA, [hMainToolbar], TB_ENABLEBUTTON, actCut, eax
        invoke  EnableMenuItem, [hMainMenu], actCut, ebx
        invoke  EnableMenuItem, [hEditorMenu], actCut, ebx

.cut_action_ok:

        invoke  SendMessageA, [hMainToolbar], TB_ISBUTTONENABLED, actCopy, 0
        test    eax,eax
        setnz   bh

        stdcall CanAction, [ptrCurrentFile], WM_COPY
        test    eax, eax
        setnz   bl

        cmp     bh, bl
        je      .copy_action_ok

        movzx   eax, bl
        movzx   ebx, bh         ; MF_BYCOMMAND + ( MF_GRAYED | MF_ENABLED )
        inc     [.changed]

        invoke  SendMessageA, [hMainToolbar], TB_ENABLEBUTTON, actCopy, eax
        invoke  EnableMenuItem, [hMainMenu], actCopy, ebx
        invoke  EnableMenuItem, [hEditorMenu], actCopy, ebx

.copy_action_ok:


;----------------------------------------------------------------------
; Set actPaste state enable/disable. Only for text data in clipboard.
;----------------------------------------------------------------------
        invoke  SendMessageA, [hMainToolbar], TB_ISBUTTONENABLED, actPaste, 0
        test    eax,eax
        setnz   bh

        stdcall CanAction, [ptrCurrentFile], WM_PASTE
        test    eax, eax
        setnz   bl

        cmp     bh, bl
        je      .paste_action_ok

        movzx   eax, bl
        movzx   ebx, bh         ; MF_BYCOMMAND + ( MF_GRAYED | MF_ENABLED )
        inc     [.changed]

        invoke  SendMessageA, [hMainToolbar], TB_ENABLEBUTTON, actPaste, eax
        invoke  EnableMenuItem, [hMainMenu], actPaste, ebx
        invoke  EnableMenuItem, [hEditorMenu], actPaste, ebx

.paste_action_ok:


;----------------------------------------------------------------------
; Set actUndo state enable/disable.
;----------------------------------------------------------------------
        invoke  SendMessageA, [hMainToolbar], TB_ISBUTTONENABLED, actUndo, 0
        xor     esi, esi
        test    eax, eax
        setnz   bh

        stdcall CanAction, [ptrCurrentFile], WM_UNDO
        test    eax, eax
        setnz   bl

        cmp     bh, bl
        je      .undo_action_ok

        movzx   eax, bl
        movzx   ebx, bh
        inc     [.changed]

        invoke  SendMessageA, [hMainToolbar], TB_ENABLEBUTTON, actUndo, eax
        invoke  EnableMenuItem, [hMainMenu], actUndo, ebx
        invoke  EnableMenuItem, [hEditorMenu], actUndo, ebx

.undo_action_ok:

;----------------------------------------------------------------------
; Set actSave state enable/disable.
;----------------------------------------------------------------------
        invoke  SendMessageA, [hMainToolbar], TB_ISBUTTONENABLED, actSave, 0
        test    eax, eax
        setnz   bh

        stdcall GetModified, [ptrCurrentFile]
        test    eax,eax
        setnz   bl

        cmp     bh,bl
        jz      .save_action_ok

        movzx   eax, bl
        movzx   ebx, bh
        inc     [.changed]

        invoke  SendMessageA, [hMainToolbar], TB_ENABLEBUTTON, actSave, eax
        invoke  EnableMenuItem,[hMainMenu], actSave, ebx
        invoke  EnableMenuItem,[hTabMenu], actSave, ebx

.save_action_ok:

;----------------------------------------------------------------------
; Set actSaveAll state enable/disable.
;----------------------------------------------------------------------

        invoke  SendMessageA, [hMainToolbar], TB_ISBUTTONENABLED, actSaveAll, 0
        test    eax, eax
        setnz   bh

        stdcall EnumOpenFiles, _checkfirstforsave, NULL
        test    eax, eax
        setnz   bl

        cmp     bh, bl
        je      .saveall_action_ok

        movzx   eax, bl
        movzx   ebx, bh
        inc     [.changed]

        invoke  SendMessageA, [hMainToolbar], TB_ENABLEBUTTON, actSaveAll, eax
        invoke  EnableMenuItem, [hMainMenu], actSaveAll, ebx

.saveall_action_ok:

;----------------------------------------------------------------------
; Set actCompile state enable/disable.
;----------------------------------------------------------------------

        invoke  SendMessageA, [hMainToolbar], TB_ISBUTTONENABLED, actCompile, 0
        test    eax, eax
        setnz   bh

        invoke  SendMessageA, [hProjManager], PMM_GETMAINFILE, 0, 0
        test    eax, eax
        setnz   bl

        mov     eax, [ptrCurrentFile]
        test    eax, eax
        jz      .checkcomp

        cmp     [eax+TOpenFile.ptrType], ftCommonSource
        sete    al
        or      bl, al

.checkcomp:
        cmp     bh, bl
        je      .compile_action_ok

        movzx   edi, bl
        movzx   ebx, bh
        inc     [.changed]

        invoke  SendMessageA, [hMainToolbar], TB_ENABLEBUTTON, actCompile, edi
        invoke  SendMessageA, [hMainToolbar], TB_ENABLEBUTTON, actRun, edi
        invoke  SendMessageA, [hMainToolbar], TB_ENABLEBUTTON, actDebug, edi

        invoke  EnableMenuItem,[hMainMenu], actCompile, ebx
        invoke  EnableMenuItem,[hMainMenu], actRun, ebx
        invoke  EnableMenuItem,[hMainMenu], actDebug, ebx
        invoke  EnableMenuItem,[hMainMenu], actRunDirect, ebx

.compile_action_ok:

        cmp     [.changed], 0
        je      .quit
        invoke  InvalidateRect, [hMainToolbar], NULL, FALSE
.quit:
        pop     ebx edi esi
        return
endp


proc _checkfirstforsave, .ptrFile, .dummy
begin
        stdcall GetModified, [.ptrFile]
        bt      eax, 0
        return
endp















;---------------------------------------------------
; Opens file(s) in the Fresh
;
;---------------------------------------------------
proc OnOpen, .wparam, .lparam
begin
        stdcall OpenFilesDialog, cOpenFileTitle, TRUE, AllFilter, OpenFileByNameEdit, NULL
        return
endp




proc OnOpenFileAtCursor, .wparam, .lparam
.line rb 256
.pos  AEPOS
.directory rb 1024
.name      dd ?
begin
        mov     esi, [ptrCurrentFile]
        mov     eax, [esi+TOpenFile.ptrType]
        cmp     [eax+TFileType.CreateProc], CreateSourceEditor
        jne     .finish

        mov     ebx, [esi+TOpenFile.hEditor]
        test    ebx, ebx
        je      .finish

        lea     eax, [.pos]
        invoke  SendMessageA, ebx, AEM_GETPOS, eax, 0

        lea     esi, [.line]
        invoke  SendMessageA, ebx, AEM_GETLINEDATA, 0, esi

        mov     ebx, [.pos.caretPosition]
        dec     ebx
        mov     ax, $2227    ; " or '
; Search to left
.toleft:
        dec     ebx
        js      .finish

        cmp     [esi+ebx], al
        je      .found
        cmp     [esi+ebx], ah
        jne     .toleft
        mov     al,ah
.found:
        lea     edi, [esi+ebx+1]
; search to right
.toright:
        inc     ebx
        cmp     ebx, $100
        jae     .finish

        cmp     [esi+ebx], al
        jne     .toright
.foundName:
        mov     byte [esi+ebx], 0

        mov     eax, [ptrCurrentFile]
        mov     eax, [eax+TOpenFile.hFileName]
        stdcall StrPtr, eax
        lea     ebx, [.directory]
        lea     ecx, [.name]
        invoke  GetFullPathNameA, eax, 1024, ebx, ecx
        mov     eax, [.name]
        mov     byte [eax], 0

        invoke  SetCurrentDirectoryA, ebx


        stdcall ConvertPath, edi
        push    eax
        stdcall OpenFileByName, eax, NULL, TRUE
        stdcall StrDel ; from stack.

.finish:
        return
endp





;----------------------------------------------------
; Save the current project and all open files to disk.
;----------------------------------------------------
proc OnSaveAll, .wparam, .lparam
begin
        stdcall EnumOpenFiles, _dosaveonefile, 0
        stdcall EnumOpenFiles, _dosaveonefile, 0
        return
endp


proc  _dosaveonefile, .ptrFile, .dummy
begin
        stdcall SaveFile, [.ptrFile]
        clc
        return
endp



;----------------------------------------------------
; Save the current editor file to the disk.
;----------------------------------------------------
proc OnSave, .wparam, .lparam
begin
        stdcall SaveFile, [ptrCurrentFile]
        return
endp


;----------------------------------------------------------
; Save the current editor file to the disk with new name.
;----------------------------------------------------------
proc OnSaveAs, .wparam, .lparam
begin
        mov     esi, [ptrCurrentFile]
        test    esi, esi
        jz      .finish
        xor     ebx, ebx
        inc     ebx
        xchg    [esi+TOpenFile.fNeverSaved], ebx

        stdcall SaveFile, esi
        test    eax, eax
        jnz     .finish

        xchg    [esi+TOpenFile.fNeverSaved], ebx

.finish:
        return
endp



;------------------------------------------
; actExit action handler
;------------------------------------------
proc OnExit, .wparam, .lparam
begin
        invoke  PostMessageA, [hApplication], WM_CLOSE, 0, 0
        return
endp




;------------------------------------------
; actClose action handler.
; Closes the current file.
;------------------------------------------
proc OnFileClose, .wparam, .lparam
begin
        xor     eax, eax
        xchg    eax, [ptrCurrentFile]
        stdcall CloseFile, eax
        return
endp


;------------------------------------------
; actCloseAll action handler.
;------------------------------------------
proc OnCloseAll, .wparam, .lparam
begin
        mov     [ptrCurrentFile], 0
        invoke  SendMessageA, [hProjManager], WM_CLOSE, 0, 0
        stdcall EnumOpenFiles, _docloseone, NULL
        return
endp



proc _docloseone, .ptrFile, .dummy
begin
        stdcall CloseFile, [.ptrFile]
        cmp     eax, cfrCanceled
        je      .stop
        clc
        return

.stop:
        stc
        return
endp



proc OnCleanupMRU, .wparam, .lparam
begin
        stdcall  ValidateMRUList, [ptrMRUFiles], _MRUCheckCallback
        stdcall  ValidateMRUList, [ptrMRUProj], _MRUCheckCallback
        return
endp


proc _MRUCheckCallback, .hMRUItem
begin
        stdcall StrPtr, [.hMRUItem]
        stdcall FileExists, eax
        return
endp



;------------------------------------------
; aux procedure. make simultaneous switch
; of menu item and toolbutton with the same
; action.
;------------------------------------------
proc ActionSetCheck, .ID, .check
        begin
        push    esi ebx
        movzx   ebx, word [.ID]
        mov     eax, MF_UNCHECKED
        xor     esi,esi
        cmp     [.check], FALSE
        je      @f
        mov     eax, MF_CHECKED
        inc     esi
@@:
        or      eax, MF_BYCOMMAND
        invoke  CheckMenuItem, [hMainMenu], ebx, eax
        invoke  SendMessageA, [hMainToolbar], TB_CHECKBUTTON, ebx, esi
        pop     ebx esi
        return
endp

;------------------------------------------
; actGridView action handler
;------------------------------------------
proc OnGridView, .wparam, .lparam
begin
        xor     [fGridVisible],1
        stdcall ActionSetCheck, [.wparam], [fGridVisible]
;        invoke  SendMessageA, [hProjManager], PMM_REFRESHFORMS, 0, 0

        stdcall EnumOpenFiles, DoRefreshForms, 0
        return
endp


proc DoRefreshForms, .ptrFile, .dummy
begin
        mov     eax, [.ptrFile]
        cmp     [eax+TOpenFile.ptrType], ftFormSource
        jne     .finish

        cmp     [eax+TOpenFile.hEditor], 0
        je      .finish

        invoke  GetPropA, [eax+TOpenFile.hEditor], [propWinTemplate]
        test    eax, eax
        jz      .finish

        invoke  InvalidateRect, [eax+TWinTemplateDT.hwnd], NULL, TRUE

.finish:
        clc
        return
endp


;------------------------------------------
; actSnap action handler
;------------------------------------------
proc OnSnap, .wparam, .lparam
        begin
        xor     [fSnapToGrid],1
        stdcall ActionSetCheck, [.wparam], [fSnapToGrid]
        return
endp

;------------------------------------------
; actSnap action handler
;------------------------------------------
proc OnPartialSelect, .wparam, .lparam
        begin
        xor     [fPartialSelect],1
        stdcall ActionSetCheck, [.wparam], [fPartialSelect]
        return
endp


proc OnViewProjMan, .wparam, .lparam
        begin
        invoke  IsWindowVisible, [hProjManager]
        mov     ebx, SW_SHOWNORMAL
        xor     eax, TRUE
        jnz     @f
        mov     ebx, SW_HIDE
@@:
        stdcall ActionSetCheck, [.wparam], eax
        invoke  ShowWindow, [hProjManager], ebx
        return
endp


proc OnViewPropEditor, .wparam, .lparam
        begin
        invoke  IsWindowVisible, [hPropEditor]
        mov     ebx, SW_SHOWNORMAL
        xor     eax, TRUE
        jnz     @f
        mov     ebx, SW_HIDE
@@:
        stdcall ActionSetCheck, [.wparam], eax
        invoke  ShowWindow, [hPropEditor], ebx
        return
endp


proc OnViewSourceEditor, .wparam, .lparam
        begin
        invoke  IsWindowVisible, [hEditorsHost]
        test    eax, eax
        jnz     .setfocus

        mov     ebx, SW_SHOWNORMAL
        mov     eax, TRUE
        stdcall ActionSetCheck, [.wparam], eax
        invoke  ShowWindow, [hEditorsHost], ebx
        return

.setfocus:
        invoke  SetActiveWindow, [hEditorsHost]
        return
endp



proc OnShowForm, .wparam, .lparam
begin
        mov     eax, [ptrCurrentFile]
        test    eax, eax
        jz      .exit

        cmp     [eax+TOpenFile.ptrType], ftFormSource
        jne      .exit

        invoke  SendMessageA, [eax+TOpenFile.hEditor], FEM_SWITCHMODE, 0, 0

.exit:
        return
endp



proc OnUndo, .wparam, .lparam
begin
        stdcall CommonAction2, WM_UNDO
        return
endp


proc OnPaste, .wparam, .lparam
begin
        stdcall CommonAction2, WM_PASTE
        return
endp

proc OnDelete, .wparam, .lparam
begin
        stdcall CommonAction2, WM_CLEAR
        return
endp


proc OnCut, .wparam, .lparam
begin
        stdcall CommonAction2, WM_CUT
        return
endp


proc OnCopy, .wparam, .lparam
begin
        stdcall CommonAction2, WM_COPY
        return
endp


proc CommonAction2, .cmd
begin
        invoke  GetFocus
        mov     esi, eax

        invoke  GetPropA, esi, [propOpenFileStructure]
        test    eax, eax
        jnz     .toeditor

        mov     eax, esi

.loop:
        mov     ebx, eax
        invoke  GetPropA, ebx, [propTemplateDT]
        test    eax, eax
        jnz     .toformeditor

        invoke  GetParent, ebx
        test    eax, eax
        jnz     .loop

.control:
        invoke  SendMessageA, esi, [.cmd], 0, 0
        return

.toeditor:
        stdcall CommonAction, eax, [.cmd]
        return

.toformeditor:
        cmp     [eax+TWinTemplateDT.ptrFile], 0
        je      .next

        mov     eax, [eax+TWinTemplateDT.ptrFile]
        jmp     .toeditor

.next:
        mov     eax, [eax+TWinTemplateDT.parent]
        test    eax, eax
        jnz     .toformeditor
        return
endp

;------------------------------------------------
; Temporary action handler for functions
; not implemented on this stage.
;------------------------------------------------
proc OnNotImplemented, .wparam, .lparam
begin
        invoke  MessageBoxA, [hApplication], cNotImplText, cNotImplTitle, MB_OK or MB_ICONINFORMATION
        return
endp


cNotImplText text 'Sorry, but this feature is not implemented yet. :)'
cNotImplTitle text 'Information'


;------------------------------------------
; actAbout action handler
; using of message box is only temporary.
; this must be more fancy :)
;------------------------------------------
proc OnAbout, .wparam, .lparam
begin
        stdcall CreateForm, AboutForm, [hApplication]

        stdcall LoadGif, [hInstance], resBmpAbout
        push    eax
        invoke  SendDlgItemMessageA, ebx, 101, STM_SETIMAGE, IMAGE_BITMAP, eax

        invoke  CreateFontA, about_font_size, 0, 0, 0, FW_NORMAL,                                \
                            0, 0, 0, about_font_charset,                                        \
                            OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,           \
                            FIXED_PITCH or FF_DONTCARE, about_font_name
        push    eax
        invoke  SendDlgItemMessageA, ebx, 102, WM_SETFONT, eax, TRUE
        invoke  SendDlgItemMessageA, ebx, 102, WM_SETTEXT, 0, cAboutText

        stdcall ShowModal, ebx, MSF_CENTER

        invoke  DestroyWindow, ebx
        invoke  DeleteObject
        invoke  DeleteObject

        return
endp



iglobal
  ; About box form definition.
  Window AboutForm, wtParent or wtEnd, waNone, 'TForm', 'About "Fresh"...', WS_CAPTION or WS_CLIPCHILDREN or WS_SYSMENU or WS_DLGFRAME, 0, NULL, 0, 0, 480, 300, NULL
  Window NONE, wtChild, waBottom, 'Button', 'Close', WS_VISIBLE or WS_CHILD or WS_BORDER, 0, MR_OK, 10, 50, 64, 25, NULL
  Window NONE, wtChild, waLeft, 'Static', '', WS_VISIBLE or WS_CHILD or SS_BITMAP or SS_CENTERIMAGE or WS_BORDER, 0, 101, 0, 10, 178, 19, NULL
  Window NONE, wtChild or wtEnd, waClient, 'Static', '', WS_VISIBLE or WS_CHILD or SS_LEFT or WS_BORDER, WS_EX_CLIENTEDGE, 102, 0, 10, 180, 19, NULL


  cAboutText db $0d, ' Fresh IDE', $0d, $0d
             db ' IDE: ', FRESH_VERSION, $0d
             db ' build: '
             create_build_time DAY, MONTH, YEAR
             db $0d
             db '    © John Found', $0d
             db '    © Fredrik Klasson (aka scientica)', $0d
             db '    © Tommy Lillehagen',$0d
             db '    © Mateusz Tymek (aka decard)', $0d
             db '    © Victor Loh (aka roticv)', $0d
             db '    © Yunus Sina Gulsen (aka VeSCeRa)', $0d, $0d
             db '  Compiler: FASM ',VERSION_STRING, $0d
             db '    © Tomasz Grysztar (aka Privalov)', 0

  create_build_time DAY, MONTH, YEAR

  about_font_size = -12
  about_font_charset = ANSI_CHARSET
  about_font_name text 'Arial', 0
endg




;*****************************************************************************
; Bookmarks actions and some edit actions by Tommy Lillehagen.
;*****************************************************************************

proc OnToggleBM, .wparam, .lparam
begin
        xor     eax, eax
        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, eax, eax
        test    eax, eax
        jz      .finish
        invoke  SendMessageA, eax, AEM_TOGGLEBOOKMARK, 0, 0
.finish:
        return
endp



proc OnNextBM, .wparam, .lparam
.pos AEPOS
        begin
        xor     eax, eax
        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, eax, eax
        test    eax, eax
        jz      .finish
        mov     ebx,eax
        invoke  SendMessageA,ebx, AEM_GOTOBOOKMARK, 0, AEBM_NEXT

        mov     [.pos.caretLine],eax
        mov     [.pos.selectionLine],eax
        mov     [.pos.caretPosition],1
        mov     [.pos.selectionPosition],1
        lea     eax, [.pos]
        invoke  SendMessageA, ebx, AEM_SETPOS, eax, 0
.finish:
        return
endp



proc OnPrevBM, .wparam, .lparam
.pos AEPOS
begin
        xor     eax, eax
        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, eax, eax
        test    eax, eax
        jz      .finish

        mov     ebx,eax
        invoke  SendMessageA, ebx, AEM_GOTOBOOKMARK, 0, AEBM_PREV
        mov     [.pos.caretLine], eax
        mov     [.pos.selectionLine], eax
        mov     [.pos.caretPosition],1
        mov     [.pos.selectionPosition],1
        lea     eax, [.pos]
        invoke  SendMessageA, ebx, AEM_SETPOS, eax, 0
.finish:
        return
endp


proc OnClearBM, .wparam, .lparam
        begin
        xor     eax, eax
        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, eax, eax
        test    eax, eax
        jz      .finish
        invoke  SendMessageA, eax, AEM_CLEARBOOKMARKS, 0, 0
.finish:
        return
endp


proc OnComment, .wparam, .lparam
begin
        xor     eax, eax
        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, eax, eax
        test    eax, eax
        jz      .finish
        mov     ebx, eax
        invoke  SendMessageA, ebx, AEM_COMMENT, 0, 1
        invoke  SendMessageA, ebx, AEM_SETMODIFIED, TRUE, 0

.finish:
        return
endp



proc OnUncomment, .wparam, .lparam
begin
        xor     eax, eax
        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, eax, eax
        test    eax, eax
        jz      .finish
        mov     ebx, eax
        invoke  SendMessageA, ebx, AEM_COMMENT, 0, 0
        invoke  SendMessageA, ebx, AEM_SETMODIFIED, TRUE, 0
.finish:
        return
endp



proc OnIndent, .wparam, .lparam
begin
        xor     eax, eax
        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, eax, eax
        test    eax, eax
        jz      .finish
        mov     ebx, eax
        invoke  SendMessageA, ebx, AEM_INDENT, 0, 1
        invoke  SendMessageA, ebx, AEM_SETMODIFIED, TRUE, 0
.finish:
        return
endp


proc OnOutdent, .wparam, .lparam
begin
        xor     eax, eax
        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, eax, eax
        test    eax, eax
        jz      .finish
        mov     ebx, eax
        invoke  SendMessageA, ebx, AEM_INDENT, 0, 0
        invoke  SendMessageA, ebx, AEM_SETMODIFIED, TRUE, 0
.finish:
        return
endp



;************************************************************************
; Returns modal result from progress window.
;************************************************************************
proc OnCompile, .wparam, .lparam
.exit dd ?
.compiled_file dd ?
begin
        invoke  LoadCursorA, 0, IDC_WAIT
        invoke  SetCursor, eax

        cmp     [comp_handle], 0
        je      @f
        invoke  TerminateThread, [comp_handle], 0
        invoke  CloseHandle, [comp_handle]
        mov     [comp_handle], 0
@@:

        invoke  SendMessageA, [frmMsg], MWM_CLEARMESSAGES, 0, 0

        invoke  LoadCursorA, 0, IDC_APPSTARTING
        invoke  SetCursor, eax

; Save compiler options

; Set compiler properties...
        mov     eax, [poMemory]
        cmp     eax, 8192               ; 8MEG is smallest possible memory
        jge     @f
        mov     eax, 8192
@@:
        mov     [compiler_memory], eax

; Set output filename...

        xor     eax, eax
        cmp     [poBinNameAuto], FALSE
        jne     .setoutputname

        stdcall StrLen, [poBinName]
        test    eax, eax
        jz      .setoutputname

uglobal
  out_filename_buffer rb 256
endg
        lea     ecx, [eax+1]
        stdcall StrPtr, [poBinName]
        mov     esi, eax
        mov     edi, out_filename_buffer
        rep movsb

        mov     eax, out_filename_buffer

.setoutputname:
        mov     [output_file], eax
        mov     eax, cDumpFilename
        mov     [symbols_file], eax

        stdcall ProgressWndCreate, 4, 1, cProgressCaption, 0

        invoke  SendMessageA, [hProjManager], PMM_GETMAINFILE, 0, 0
        test    eax, eax
        jnz     .docompile

        mov     eax, [ptrCurrentFile]
        test    eax, eax
        jz      .finish

        cmp     [eax+TOpenFile.ptrType], ftCommonSource
        jne     .finish

.docompile:
        mov     [.compiled_file], eax
        stdcall PrepareForCompilation, [eax+TOpenFile.hFileName]
        test    eax, eax
        jz      .outofmemory

        mov     [flagFakeCompile], 0
        stdcall ThreadCreate, flat_assembler, NULL
        mov     [comp_handle], eax

        stdcall ShowModal, [hProgressWnd], MSF_CENTER
        mov     [.exit], eax

        cmp     [.exit], MR_CANCEL
        jne     .compended

;user canceled the compilation
        invoke  TerminateThread, [comp_handle], -1
        invoke  CloseHandle, [comp_handle]
        mov     [comp_handle], 0

.compended:
        cmp     [.exit], MR_OK
        je      .compile_ok

; try to compile with flagFakeCompile = 1 -> this should remove errors.
        stdcall CleanupAfterCompilation
        mov     eax, [.compiled_file]
        stdcall PrepareForCompilation, [eax+TOpenFile.hFileName]

        cmp     [comp_handle], 0
        je      @f
        invoke  WaitForSingleObject, [comp_handle], -1
@@:
        mov     [flagFakeCompile], 1
        stdcall ThreadCreate, flat_assembler, 0
        mov     [comp_handle], eax

        stdcall ShowModal, [hProgressWnd], MSF_CENTER
        cmp     [output_file], 0
        je      .compile_ok
        stdcall FileDelete, [output_file]

.compile_ok:
        cmp     [.exit], MR_OK
        je      .finalize

; find the error message.
        invoke  SendMessageA, [frmMsg], MWM_FIRSTERROR, 0, 0

.finalize:
        stdcall AddCompilationStatistics

        stdcall CleanupAfterCompilation
        mov     [flagFakeCompile], 0

        push    [.exit]
        jmp     .return

.outofmemory:
        invoke  MessageBoxA, [hApplication], cOutOfMemory, NULL, MB_ICONERROR or MB_OK
.finish:
        push    MR_ABORT

.return:
        stdcall ProgressWndDestroy

        invoke  LoadCursorA, 0, IDC_ARROW
        invoke  SetCursor, eax

        pop     eax
        return
endp

uglobal
  comp_handle dd ?
endg

cDumpFilename text 'dump.fas'
cProgressCaption text 'Compiling...'
cOutOfMemory text "Can't allocate memory for compiler. Check settings of Fresh."


proc OnDebug, .wparam, .lparam
.sinfo  STARTUPINFO
.pinfo  PROCESSINFO
begin
        stdcall OnCompile, 0, 0
        cmp     eax, MR_OK
        jne     .finish         ; There are errors during compilation.

        cmp     [output_format], 5
        jne     .windebuger

        stdcall RunInLinux, TRUE
        jmp     .finish

.windebuger:
        mov     ecx, sizeof.STARTUPINFO / 4
        lea     edi,[.sinfo]
        xor     eax, eax
        rep stosd
        mov     [.sinfo.cb], sizeof.STARTUPINFO
        mov     [.sinfo.dwFlags],0

        stdcall GetParamFromINI, cDebugerKey
        jnc     .debugerok

        stdcall StrNew
        push    eax
        jmp     .nodebuger

.debugerok:
        push    eax
        stdcall StrCharCat, eax, ' '

.nodebuger:
        stdcall StrCharCat, eax, '"'
        stdcall StrCat, eax, [CompiledFileName]
        stdcall StrCharCat, eax, '"'
        stdcall StrPtr, eax

        lea     edx,[.sinfo]
        lea     ecx,[.pinfo]
        invoke  CreateProcessA, NULL, eax, NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,edx,ecx
        stdcall StrDel ; from the stack
        test    eax,eax
        jnz     .ok

        stdcall LastError
.ok:
        invoke  CloseHandle,[.pinfo.hThread]
        invoke  CloseHandle,[.pinfo.hProcess]
.finish:
        return
endp



proc OnShowMessages, .wparam, .lparam
begin

        invoke  IsWindowVisible, [frmMsg]
        xor     eax, 1
        invoke  SendMessageA, [frmMsg], MWM_SHOWMESSAGES, eax, 0
        return
endp



iglobal
  Window  dlgCategorySelect,  wtParent or wtEnd, waNone, 'TForm', 'Add category:', $06080000, WS_EX_DLGMODALFRAME, 0, 0, 0, 252, 208, CategorySelectProc
  Window  NONE,  wtChild, waNone, 'Static', 'Category &Name:', ComCtrlStyle, 0, 0, 4, 4, 200, 16, NULL
  Window  NONE,  wtChild, waNone, 'Edit', '', ComCtrlStyle or WS_TABSTOP or ES_AUTOHSCROLL,  WS_EX_CLIENTEDGE, 101, 4, 20, 236, 19, NULL
  Window  NONE,  wtChild, waNone, 'Static', 'Category &Icon:', ComCtrlStyle, 0, 0, 4, 42, 200, 16, NULL
  Window  NONE,  wtChild, waNone, LISTVIEW_CLASS, '', ComCtrlStyle or WS_TABSTOP or LVS_ICON or LVS_SINGLESEL or LVS_SHAREIMAGELISTS or LVS_NOLABELWRAP or LVS_AUTOARRANGE or LVS_NOSCROLL or LVS_SHOWSELALWAYS, WS_EX_CLIENTEDGE, 102, 4, 58, 236, 92, NULL
  Window  NONE,  wtChild, waNone, 'Button', 'OK', ComCtrlStyle or WS_TABSTOP or BS_DEFPUSHBUTTON, 0, MR_OK, 48, 156, 64, 24, NULL
  Window  NONE,  wtChild or wtEnd, waNone, 'Button', 'Cancel', ComCtrlStyle or WS_TABSTOP, 0, MR_CANCEL, 128, 156, 64, 24, NULL
endg


proc CategorySelectProc, .hwnd, .wmsg, .wparam, .lparam
.lvi LVITEM
.tvi TVITEM
.str rb 256
begin
        cmp     [.wmsg], FM_AFTERCREATE
        je      .aftercreate

        stc
        return

.aftercreate:
        invoke  SendDlgItemMessageA, [.hwnd], 102, LVM_SETIMAGELIST, LVSIL_NORMAL, [imlCategories]
        invoke  SendDlgItemMessageA, [.hwnd], 102, LVM_SETICONSPACING, 0, $00240018
        invoke  SendDlgItemMessageA, [.hwnd], 102, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_BORDERSELECT

        invoke  ImageList_GetImageCount, [imlCategories]
        mov     ebx, eax
        xor     esi, esi

.imageadd:
        lea     ecx, [esi+1]
        stdcall NumToStr, ecx, ntsUnsigned or ntsDec
        push    eax
        stdcall StrPtr, eax

        mov     [.lvi.pszText], eax
        mov     [.lvi.mask], LVIF_IMAGE or LVIF_TEXT
        mov     [.lvi.iItem], esi
        mov     [.lvi.iSubItem], 0
        mov     [.lvi.iImage], esi
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], 102, LVM_INSERTITEM, 0, eax
        stdcall StrDel ; from the stack.

        inc     esi
        dec     ebx
        jnz     .imageadd

        mov     [.lvi.stateMask], LVIS_FOCUSED or LVIS_SELECTED
        mov     [.lvi.state], LVIS_FOCUSED or LVIS_SELECTED
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], 102, LVM_SETITEMSTATE, 0, eax

        invoke  GetDlgItem, [hProjManager], ProjTreeCtrlID
        mov     ebx, eax

        invoke  SendMessageA, ebx, TVM_GETNEXTITEM, TVGN_CARET, 0


        stdcall GetFullItemName, ebx, eax
        push    ecx
        push    eax

        stdcall StrPtr, eax
        invoke  SendDlgItemMessageA, [.hwnd], 101, WM_SETTEXT, 0, eax
        invoke  SendDlgItemMessageA, [.hwnd], 101, EM_SETSEL, 0, -1
        stdcall StrDel ; from the stack.

        pop     ecx
        lea     eax, [.lvi]
        mov     [eax+LVITEM.stateMask], LVIS_FOCUSED or LVIS_SELECTED
        mov     [eax+LVITEM.state], LVIS_FOCUSED or LVIS_SELECTED

        invoke  SendDlgItemMessageA, [.hwnd], 102, LVM_SETITEMSTATE, ecx, eax

        invoke  SendMessageA, [hProjManager], _CEM_SETMODIFIED, TRUE, 0

        clc
        return
endp


proc OnAddCategory, .wparam, .lparam
.res  dd ?
begin
        mov     [.res], FALSE

        stdcall CreateForm, dlgCategorySelect, [hApplication]

        stdcall ShowModal, ebx, MSF_CENTER
        cmp     eax, MR_OK
        jne     .finishadd

        invoke  SendDlgItemMessageA, ebx, 102, LVM_GETNEXTITEM, -1, LVNI_FOCUSED
        cmp     eax, -1
        jne     @f

        mov     eax, 4
@@:
        mov     edi, eax

        invoke   GetDlgItem, ebx, 101
        stdcall  GetControlText, eax, NULL
        push     eax ; for delete

        stdcall StrCharCat, eax, '\'
        stdcall GetCategoryTree, eax, TVI_ROOT, edi

        invoke  SendDlgItemMessageA, [hProjManager], ProjTreeCtrlID, TVM_SELECTITEM, TVGN_CARET, eax

        stdcall StrDel ; From the stack.
        mov     [.res], TRUE

        invoke  SendMessageA, [hProjManager], _CEM_SETMODIFIED, TRUE, 0

.finishadd:
        invoke  DestroyWindow, ebx
        mov     eax, [.res]
        return
endp



proc OnEditCategory, .wparam, .lparam
.tvi TVITEM
begin
        stdcall CreateForm, dlgCategorySelect, [hApplication]
        invoke  SendDlgItemMessageA, ebx, 101, EM_SETREADONLY, TRUE, 0

        stdcall ShowModal, ebx, MSF_CENTER
        cmp     eax, MR_OK
        jne     .finish

        invoke  SendDlgItemMessageA, ebx, 102, LVM_GETNEXTITEM, -1, LVNI_FOCUSED
        cmp     eax, -1
        jne     @f

        mov     eax, 4
@@:
        mov     edi, eax

        invoke   GetDlgItem, ebx, 101
        stdcall  GetControlText, eax, NULL
        push     eax ; for delete

        stdcall GetCategoryTree, eax, TVI_ROOT, edi

        lea     ecx, [.tvi]
        mov     [ecx+TVITEM.hItem], eax
        mov     [ecx+TVITEM.mask], TVIF_IMAGE or TVIF_SELECTEDIMAGE
        mov     [ecx+TVITEM.iImage], edi
        mov     [ecx+TVITEM.iSelectedImage], edi

        invoke  SendDlgItemMessageA, [hProjManager], ProjTreeCtrlID, TVM_SETITEM, 0, ecx
        invoke  SendDlgItemMessageA, [hProjManager], ProjTreeCtrlID, TVM_SELECTITEM, TVGN_CARET, eax

        stdcall StrDel ; From the stack.

.finish:
        invoke  DestroyWindow, ebx
        return
endp



proc OnAddFile, .wparam, .lparam
begin
        stdcall OpenFilesDialog, cAddFileTitle, TRUE, AllFilter, _AddFileCallback, FALSE, NULL
        return
endp

proc _AddFileCallback, .hFileName, .lParam
begin
        stdcall OpenFileByName, [.hFileName], NULL, FALSE
        test    eax, eax
        jz      .finish
        invoke  SendMessageA, [hProjManager], PMM_ADDFILE, eax, -1
.finish:
        return
endp


proc OnSetMainFile, .wparam, .lparam
begin
        stdcall OpenFilesDialog, cSetMainTitle, FALSE, FileFilter, _SetMainCallback, NULL
        return
endp


proc _SetMainCallback, .hFileName, .dummy
begin
        stdcall OpenFileByName, [.hFileName], NULL, FALSE
        test    eax, eax
        jz      .finish
        invoke  SendMessageA, [hProjManager], PMM_ADDFILE, eax, 0
.finish:
        return
endp




proc OnShowNotUsed, .wparam, .lparam
begin
        invoke  SendMessageA, [frmMsg], MWM_CLEARMESSAGES, 0, 0
        stdcall ShowNotUsed
        return
endp


proc OnAutoArrange, .wparam, .lparam
begin
        stdcall AutoArrangeWindows
        return
endp

proc OnNextWindow, .wparam, .lparam
begin
        invoke  SendMessageA, [hEditorsHost], _EHM_SETACTIVETAB, 1, TRUE
        return
endp



proc OnPrevWindow, .wparam, .lparam
begin
        invoke  SendMessageA, [hEditorsHost], _EHM_SETACTIVETAB, -1, TRUE
        return
endp


iglobal
  cIncludeFilesTitle text 'Filenames as "include" statement', 0
  cIncludeRoot       db 0
endg

proc OnIncludeFile, .wparam, .lparam
.aepos AEPOS
.hwnd  dd ?
.IncludeGroup dd ?
begin
        xor     eax, eax
        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, eax, eax
        test    eax, eax
        jz      .finish

        mov     [.hwnd], eax

        stdcall StrNew
        mov     [.IncludeGroup], eax

        stdcall ConvertPath, cIncludeRoot
        push    eax
        stdcall OpenFilesDialog, cIncludeFilesTitle, TRUE, AllFilter, _DoInsertOneFile, eax, [.IncludeGroup]
        stdcall StrDel ; from the stack

        lea     esi, [.aepos]
        invoke  SendMessageA, [.hwnd], AEM_GETPOS, esi, 0
        mov     [esi+AEPOS.caretPosition], 1
        mov     [esi+AEPOS.selectionPosition], 1
        mov     eax, [esi+AEPOS.caretLine]
        mov     [esi+AEPOS.selectionLine], eax
        invoke  SendMessageA, [.hwnd], AEM_SETPOS, esi, 0

        invoke  SendMessageA, [.hwnd], AEM_GETMODE, 0, 0
        push    eax
        invoke  SendMessageA, [.hwnd], AEM_SETMODE, 0, 0

        stdcall StrCat, [.IncludeGroup], cIncludeEnd2
        stdcall StrPtr, [.IncludeGroup]
        invoke  SendMessageA, [.hwnd], EM_REPLACESEL, TRUE, eax

        stdcall StrDel, [.IncludeGroup]

        pop     eax
        invoke  SendMessageA, [.hwnd], AEM_SETMODE, eax, 0

        lea     esi, [.aepos]
        invoke  SendMessageA, [.hwnd], AEM_GETPOS, esi, 0
        mov     eax, [esi+AEPOS.selectionPosition]
        mov     ecx, [esi+AEPOS.selectionLine]
        mov     [esi+AEPOS.caretPosition], eax
        mov     [esi+AEPOS.caretLine], ecx
        invoke  SendMessageA, [.hwnd], AEM_SETPOS, esi, 0

.finish:
        return
endp


proc _DoInsertOneFile, .hFileName, .hGroup
begin
        stdcall _RelativeToFinc, [.hFileName]
        stdcall StrCat, [.hGroup], cIncludeCommand

        stdcall StrCat, [.hGroup], eax
        stdcall StrDel, eax

        stdcall StrCat, [.hGroup], cIncludeEnd
        return
endp


proc _RelativeToFinc, .hFileName
.olddir rb 1024
begin
        lea     eax, [.olddir]
        invoke  GetCurrentDirectoryA, 1024, eax

        stdcall ConvertPath, cIncludeRoot
        push    eax

        stdcall StrPtr, eax
        invoke  SetCurrentDirectoryA, eax
        stdcall StrDel ; from the stack

        stdcall GetRelativePath, [.hFileName]
        stdcall StrInsert, eax, cIncludeRoot, 0
        push    eax

        lea     eax, [.olddir]
        invoke  SetCurrentDirectoryA, eax

        pop     eax
        return
endp

;************************************************************************
; ReplaceVarString - replaces some variable (actually string) in hEdit with
; the value of hString.
; hEdit - handle of AsmEdit control
; ptrVar - pointer to varname string.
; hString - handle of the string that will replace the var name.
;************************************************************************
proc ReplaceVarString, .hEdit, .ptrVar, .hString

.oldpos AEPOS
.aepos  AEPOS

        begin
        push    ebx esi

        lea     eax, [.oldpos]
        invoke  SendMessageA, [.hEdit], AEM_GETPOS, eax, 0

        stdcall StrPtr, [.hString]
        mov     esi, eax
        test    esi, esi
        jz      .endofsearch

        mov     ebx, [.hEdit]

        mov     [.aepos.selectionPosition], 1
        mov     [.aepos.selectionLine], 1
        mov     [.aepos.caretPosition], 1
        mov     [.aepos.caretLine], 1
        lea     eax, [.aepos]
        invoke  SendMessageA, ebx, AEM_SETPOS, eax, 0
        invoke  SendMessageA, ebx, AEM_FINDFIRST, AEFIND_CASESENSITIVE, [.ptrVar]
        test    eax, eax
        jz      .endofsearch

        invoke  SendMessageA, ebx, EM_REPLACESEL, FALSE, esi

.loop:
        invoke  SendMessageA, ebx, AEM_FINDNEXT, 0, 0
        test    eax, eax
        jz      .endofsearch

        invoke  SendMessageA, ebx, EM_REPLACESEL, FALSE, esi
        jmp     .loop

.endofsearch:
        lea     eax, [.oldpos]
        invoke  SendMessageA, [.hEdit], AEM_SETPOS, eax, 0

        pop     esi ebx
        return
endp


        DispSize  'action events', ($ - ActionEvents)
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/ActionsEditor.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
;<ff
Window FormLabel, 3, 0, 'TForm', 'ActionList editor', $16080000, $80, 0, 209, 216, 442, 277, FormWinProc;
Window NONE, 0, 0, 'EDIT', '&Open', $50000080, $200, 0, 176, 24, 161, 19, 0;
Window NONE, 0, 0, 'EDIT', '1', $50000080, $200, 0, 176, 64, 161, 19, 0;
Window NONE, 0, 0, 'STATIC', '&Caption:', $50000000, $0, 0, 176, 8, 40, 13, 0;
Window NONE, 0, 0, 'STATIC', '&Image index:', $50000000, $0, 0, 176, 48, 64, 13, 0;
Window NONE, 0, 0, 'EDIT', 'Ctrl+O', $50000080, $200, 0, 176, 104, 161, 19, 0;
Window NONE, 0, 0, 'STATIC', '&Accelerator:', $50000000, $0, 0, 176, 88, 64, 13, 0;
Window NONE, 0, 0, 'EDIT', 'Open file from disk', $500000C4, $200, 0, 176, 144, 160, 56, 0;
Window NONE, 0, 0, 'STATIC', '&Hint text:', $50000000, $0, 0, 176, 128, 48, 13, 0;
Window NONE, 0, 0, 'EDIT', 'OnOpen', $50000080, $200, 0, 176, 224, 161, 19, 0;
Window NONE, 0, 0, 'STATIC', '&Procedure:', $50000000, $0, 0, 176, 208, 64, 16, 0;
Window NONE, 0, 0, 'BUTTON', 'Add', $50000000, $0, 0, 352, 8, 64, 20, 0;
Window NONE, 0, 0, 'BUTTON', 'Remove', $50000000, $0, 0, 352, 32, 64, 20, 0;
Window NONE, 0, 0, 'BUTTON', 'Move Up', $50000000, $0, 0, 352, 64, 64, 20, 0;
Window NONE, 0, 0, 'BUTTON', 'Move Dn', $50000000, $0, 0, 352, 88, 64, 20, 0;
Window NONE, 2, 1, 'SysListView32', 'ListView', $50000201, $200, 0, 0, 0, 168, 253, 0;
;ff>

;-----------------------------------------------------------------------
; Window procedure for the form.
; Arguments:
;   .hwnd - handle of the window
;   .wmsg - code of the message
;   .wparam \ Parameters of the message
;   .lparam /
;-----------------------------------------------------------------------
winproc FormWinProc
begin
;-----------------------------------------------------------------------
; Write here the code that have to be executed before
; message dispathing.
;-----------------------------------------------------------------------


ondefault
;-----------------------------------------------------------------------
; Write here the code that have to be executed if message
; was not processed by this procedure.
;-----------------------------------------------------------------------
        stc
        return
endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































Deleted source/CCList.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
uglobal
  hCCList         dd 0
endg

idCCList = 763


proc CreateCCList, .parent
begin
        push    ebx

        invoke  CreateWindowExA, 0, cFormClassName, 0, WS_POPUP or WS_SIZEBOX or WS_CLIPSIBLINGS or WS_CLIPCHILDREN,   \
                                0, 0, 300, 120, 0, 0, [hInstance], 0
        mov     [hCCList], eax
        invoke  SetWindowLongA, [hCCList], GWL_HWNDPARENT, [.parent]
        stdcall SubclassWindow, [hCCList], CCParentProc

        invoke  CreateWindowExA, 0,  cListboxClassName,  0,              \
                WS_CHILD or WS_VISIBLE or WS_VSCROLL or LBS_NOINTEGRALHEIGHT or LBS_OWNERDRAWFIXED or LBS_NODATA, \
                0, 0, 300, 120, [hCCList], idCCList, [hInstance], 0
        mov     ebx, eax
        stdcall SubclassWindow, ebx, CCListProc
        stdcall SetAlign, ebx, waClient

        invoke  GetStockObject, DEFAULT_GUI_FONT
        invoke  SendMessageA, ebx, WM_SETFONT, eax, TRUE

        pop     ebx
        return
endp



proc AddCCListItem, .hStr, .ptrLabel
begin
        push    eax ecx edx

        invoke  GetWindowLongA, [hCCList], GWL_USERDATA
        stdcall AddArrayItems, eax, 1
        pushd    [.ptrLabel]
        popd     [eax]
        invoke   SetWindowLongA, [hCCList], GWL_USERDATA, edx

        pop     edx ecx eax
        return
endp


; returns pointer to the string in ebx
proc GetCCListSelected
begin
        push    eax ecx edx

        invoke  SendMessageA, [hCCList], LB_GETCURSEL, 0, 0
        add     eax, 1
        jc      .err

        mov     ebx, eax

        invoke  GetWindowLongA, [hCCList], GWL_USERDATA
        cmp     [eax+TArray.count], ebx
        jb      .err

        mov     ebx, [eax+TArray.array+4*ebx-4]
        mov     ebx, [ebx+TLabel.iName]
        add     ebx, [ptrNames]

        clc
.err:
        pop     edx ecx eax
        return
endp



proc ClearCCList
begin
        invoke  SendMessageA, [hCCList], LB_SETCOUNT, 0, 0
        invoke  GetWindowLongA, [hCCList], GWL_USERDATA

        stdcall FreeMem, eax
        stdcall CreateArray, 4  ; dword array.

        invoke  SetWindowLongA, [hCCList], GWL_USERDATA, eax
        return
endp




proc SelectCCList, .hStr
begin
        push    ebx esi edi

        stdcall StrPtr, [.hStr]
        mov     edi, eax

        invoke  GetWindowLongA, [hCCList], GWL_USERDATA
        mov     ebx, [eax+TArray.count]
        lea     esi, [eax+TArray.array]
        or      eax, -1

.matchloop:
        inc     eax
        cmp     eax, ebx
        je      .notfound

        mov     ecx, [esi]
        lea     esi, [esi+4]

        mov     ecx, [ecx+TLabel.iName]
        add     ecx, [ptrNames]
        stdcall StringMatch, ecx, edi

        jnc     .matchloop

        invoke  SendMessageA, [hCCList], LB_SETCURSEL, eax, 0
        clc
        return

.notfound:
        invoke  SendMessageA, [hCCList], LB_SETCURSEL, 0, 0
        stc
        return
endp






winproc CCParentProc
begin
        cmp     ebx, WM_KEYDOWN
        je      .relay

        cmp     ebx, LB_ADDSTRING
        jl      .process
        cmp     ebx, LB_ITEMFROMPOINT
        ja      .process

.relay:
        invoke  SendDlgItemMessageA, [.hwnd], idCCList, [.wmsg], [.wparam], [.lparam]
        clc
        return

.process:

ondefault
        stc
        return


onmessage AM_INITWINDOW
        stdcall CreateArray, 4  ; dword array.
        invoke  SetWindowLongA, [.hwnd], GWL_USERDATA, eax
        clc
        return


onmessage WM_SIZE
        invoke  GetDlgItem, [.hwnd], idCCList
        invoke  InvalidateRect, eax, 0, 0
        xor     eax, eax
        clc
        return


onmessage WM_CLOSE
        invoke  GetWindowLongA, [.hwnd], GWL_HWNDPARENT
        invoke  SetFocus, eax

        invoke  DestroyWindow, [.hwnd]
        xor     eax, eax
        mov     [hCCList], 0
        clc
        return


onmessage WM_DESTROY
        invoke  GetWindowLongA, [.hwnd], GWL_USERDATA
        stdcall FreeMem, eax
        stc
        return



onmessage WM_MEASUREITEM
locals
  .ccrect RECT
endl
        mov     esi, [.lparam]
        cmp     [esi+MEASUREITEMSTRUCT.CtlType], ODT_LISTBOX
        jne     .ondefault

        cmp     [esi+MEASUREITEMSTRUCT.CtlID], idCCList
        jne     .ondefault

        invoke  GetDlgItem, [.hwnd], idCCList
        mov     ebx, eax

        lea     ecx, [.ccrect]
        invoke  GetClientRect, ebx, ecx
        push    [.ccrect.right]
        pop     [esi+MEASUREITEMSTRUCT.itemWidth]

        or      eax, -1
        clc
        return


onmessage WM_DRAWITEM
locals
  .rectL RECT
  .rectR RECT
  .bkbrush dd ?
  .buffer rb 32
endl
        cmp     [.wparam], idCCList
        jne      .ondefault

        mov     esi, [.lparam]
        mov     eax, [esi+DRAWITEMSTRUCT.hwndItem]

        mov     eax, COLOR_HIGHLIGHT
        mov     ebx, COLOR_HIGHLIGHTTEXT
        test    [esi+DRAWITEMSTRUCT.itemState], ODS_SELECTED or ODS_FOCUS
        jnz     @f
        mov     eax, COLOR_WINDOW
        mov     ebx, COLOR_WINDOWTEXT
@@:
        invoke  GetSysColor, eax

        invoke  CreateSolidBrush, eax
        mov     [.bkbrush], eax

        invoke  GetSysColor, ebx
        invoke  SetTextColor, [esi+DRAWITEMSTRUCT.hDC], eax
        invoke  SetBkMode, [esi+DRAWITEMSTRUCT.hDC], TRANSPARENT

; First fill the background
        lea     eax, [esi+DRAWITEMSTRUCT.rcItem]
        invoke  FillRect, [esi+DRAWITEMSTRUCT.hDC], eax, [.bkbrush]

; then compute the rectangles
        mov     eax, [esi+DRAWITEMSTRUCT.rcItem.left]
        mov     ecx, [esi+DRAWITEMSTRUCT.rcItem.right]
        mov     [.rectL.left], eax
        mov     [.rectL.right], ecx
        mov     [.rectR.left], ecx
        mov     [.rectR.right], ecx

        sub     ecx, eax
        shr     ecx, 2          ; 1/4 of the field for the value.
        sub     [.rectL.right], ecx
        sub     [.rectR.left], ecx

        mov     eax, [esi+DRAWITEMSTRUCT.rcItem.top]
        mov     ecx, [esi+DRAWITEMSTRUCT.rcItem.bottom]
        mov     [.rectL.top], eax
        mov     [.rectL.bottom], ecx
        mov     [.rectR.top], eax
        mov     [.rectR.bottom], ecx

        add     [.rectL.left], 4
        add     [.rectR.left], 4

        invoke  GetSysColor, COLOR_BTNFACE
        invoke  CreatePen, PS_SOLID, 0, eax
        invoke  SelectObject, [esi+DRAWITEMSTRUCT.hDC], eax
        push    eax

        invoke  MoveToEx, [esi+DRAWITEMSTRUCT.hDC], [.rectL.right], [.rectL.top], NULL
        invoke  LineTo, [esi+DRAWITEMSTRUCT.hDC], [.rectL.right], [.rectL.bottom]

        mov     edi, [.rectL.bottom]
        dec     edi
        invoke  MoveToEx, [esi+DRAWITEMSTRUCT.hDC], [esi+DRAWITEMSTRUCT.rcItem.left], edi, NULL
        invoke  LineTo, [esi+DRAWITEMSTRUCT.hDC],   [.rectR.right], edi

        invoke  SelectObject, [esi+DRAWITEMSTRUCT.hDC]  ; from the stack
        invoke  DeleteObject, eax

; then write the text
        mov     edi, [esi+DRAWITEMSTRUCT.itemID]
        cmp     edi, -1
        je      .cleanup

        invoke  GetWindowLongA, [.hwnd], GWL_USERDATA
        cmp     edi, [eax+TArray.count]
        jae     .cleanup

        mov     edi, [eax+TArray.array + 4*edi]

        mov     eax, [edi+TLabel.iName]
        add     eax, [ptrNames]
        lea     ecx, [.rectL]
        invoke  DrawTextA, [esi+DRAWITEMSTRUCT.hDC], eax, -1, ecx, DT_SINGLELINE or DT_LEFT or DT_VCENTER or DT_END_ELLIPSIS

  cNotDefined text 'undefined'
  cVirtual    text 'virtual'

; then write the value

        test    [edi+TLabel.flags], lfDefined
        jz      .notdefined

        cmp     [edi+TLabel.SIBEx], 0
        jne     .virtual

        stdcall NumToStr, [edi+TLabel.ValueLo], ntsHex or ntsSigned
        jmp     .printvalue

.notdefined:
        stdcall StrDup, cNotDefined
        jmp     .printvalue

.virtual:
        stdcall StrDup, cVirtual

.printvalue:
        push    eax
        stdcall StrPtr, eax
        lea     ecx, [.rectR]
        invoke  DrawTextA, [esi+DRAWITEMSTRUCT.hDC], eax, -1, ecx, DT_SINGLELINE or DT_LEFT or DT_VCENTER
        stdcall StrDel ; from the stack.

.cleanup:
        invoke  DeleteObject, [.bkbrush]
        or      eax, -1
        clc
        return

endwp







winproc CCListProc
begin

ondefault
        stc
        return

; This makes CCList to never get the focus.
;onmessage WM_SETFOCUS
;        invoke GetParent, [.hwnd]
;        invoke SetFocus, eax
;        xor    eax, eax
;        clc
;        return

;-----------------------------------------------------------------------
onmessage WM_LBUTTONDBLCLK

        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, 0, 0
        invoke  PostMessageA, eax, WM_KEYDOWN, VK_RETURN, 0
        clc
        return

;-----------------------------------------------------------------------
onmessage WM_KEYDOWN

        mov     ebx, [.wparam]
        call    JumpTo
        MessageList                                     \
          VK_DOWN,   .ondefault,                        \
          VK_UP,     .ondefault,                        \
          VK_PRIOR,  .ondefault,                        \
          VK_NEXT,   .ondefault,                        \
          VK_HOME,   .ondefault,                        \
          VK_END,    .ondefault

        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, 0, 0
        invoke  PostMessageA, eax, [.wmsg], [.wparam], [.lparam]
        clc
        return

endwp




proc UpdateCCPosition
.aepos AEPOS
.caret AECARETXY
.rect  RECT
.workrect RECT
.word rb $100
.aedit dd ?
begin
        cmp     [hCCList], 0
        je      .finish

        invoke  GetWindowLongA, [hCCList], GWL_HWNDPARENT
        mov     [.aedit], eax

        lea     ebx, [.caret]
        invoke  SendMessageA, [.aedit], AEM_GETCARETXY, ebx, 0

        invoke  ClientToScreen, [.aedit], ebx
        add     ebx, 8
        invoke  ClientToScreen, [.aedit], ebx
        sub     ebx, 8

        lea     eax, [.rect]
        invoke  GetWindowRect, [hCCList], eax
        mov     eax, [.rect.right]
        mov     ecx, [.rect.bottom]
        sub     eax, [.rect.left]
        sub     ecx, [.rect.top]
        mov     [.rect.right], eax
        mov     [.rect.bottom], ecx

        lea     ebx, [.workrect]
        invoke  SystemParametersInfoA, SPI_GETWORKAREA,0,ebx,0

        mov     eax, [.workrect.right]
        sub     eax, [.rect.right]
        mov     ecx, [.caret.x0]
        cmp     eax, ecx
        jle     @f
        mov     eax, ecx
@@:
        mov     edx, [.workrect.bottom]
        sub     edx, [.rect.bottom]
        mov     ecx, [.caret.y1]
        add     ecx, 1

        cmp     edx, ecx
        jg      @f

        mov     ecx, [.caret.y0]
        sub     ecx, [.rect.bottom]
        sub     ecx, 2
@@:
        invoke  SetWindowPos, [hCCList], NULL, eax, ecx, 0, 0, SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_NOCOPYBITS

        lea     ebx, [.word]
        invoke  SendMessageA, [.aedit], AEM_GETWORDATCARET, $100, ebx

        stdcall ClearCCList

        stdcall SearchTree, ebx, ptrLabels
        test    eax, eax
        jz      .destroycc

        mov     esi, [eax]
        test    esi, esi
        jz      .destroycc

        mov     ebx, [esi+TArray.count]
        lea     esi, [esi+TArray.array]

        test    ebx, ebx
        jz      .destroycc

        mov     edi, edx        ; The last word
        xor     ecx, ecx

.fillloop:
        mov     eax, [ptrNames]
        add     eax, [esi+TLabel.iName]
        stdcall StringMatch, eax, edi
        jnc     .next

        stdcall AddCCListItem, eax, esi
        inc     ecx

.next:
        add     esi, sizeof.TLabel
        dec     ebx
        jnz     .fillloop

        test    ecx, ecx
        jz      .destroycc

        invoke  SendMessageA, [hCCList], LB_SETCOUNT, ecx

        stdcall SelectCCList, edi
        stdcall StrDel, edi

        invoke  SetWindowPos, [hCCList], NULL, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE or SWP_NOZORDER or SWP_SHOWWINDOW or SWP_NOACTIVATE

.finish:
        return

.destroycc:
        invoke  PostMessageA, [hCCList], WM_CLOSE, 0, 0
        return
endp


proc StringMatch, .str1, .str2
begin
        push    esi edi eax
        stdcall StrPtr, [.str1]
        mov     esi, eax

        stdcall StrPtr, [.str2]
        mov     edi, eax
.loop:
        mov     al, [esi]
        inc     esi
        mov     ah, [edi]
        inc     edi

        test    ah,ah
        jz      .match

        test    al,al
        jz      .notmatch

        or      eax, $2020
        cmp     al,ah
        je      .loop

.notmatch:
        clc
        pop     eax edi esi
        return

.match:
        stc
        pop     eax edi esi
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/Controls.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
iglobal
  xGrid           dd 8
  yGrid           dd 8
  fGridVisible    dd TRUE
  fSnapToGrid     dd TRUE
  fPartialSelect  dd TRUE
endg


;-----------------------------------------------------------------------
; Window procedure of the subclassed designtime window.
; It make window to behave properly in visual editor - selecting, moving
; resize etc.
; Also, it inhibits the main functionality of the controls.
;------------------------------------------------------------------------
winproc procDesignControl
.rect RECT
.rect0 RECT
.pnt    POINT
.pnt0   POINT
begin
        invoke  GetPropA, [.hwnd], [propTemplateDT]
        mov     edi, eax
        test    eax, eax
        jz      .ondefault

ondefault
        stc
        return

;-----------------------------------------------------------------
onmessage WM_NCHITTEST

        invoke  GetPropA, [.hwnd], [propOldWinProc]
        test    eax, eax
        jz      @f

        invoke  CallWindowProcA, eax, [.hwnd], [.wmsg], [.wparam], [.lparam]
        cmp     eax, -1

        jne     @f
        mov     eax, HTCLIENT
@@:
        clc
        return

;-----------------------------------------------------------------
onmessage WM_MOUSEACTIVATE
        mov     eax, MA_NOACTIVATE
        clc
        return

;-----------------------------------------------------------------
onmessage WM_ACTIVATE
        mov     ebx, [edi+TWinTemplateDT.ptrFile]
        test    ebx, ebx
        jz      .endactivate
        stdcall SetCurrentFile, ebx

        mov     ebx, [ebx+TOpenFile.hEditor]
        test    ebx, ebx
        jz      .endactivate

        invoke  SetPropA, ebx, [propVisualMode], 1

.endactivate:
        mov     eax, edi
        stdcall GetSizer
        invoke  SetFocus, eax
        xor     eax, eax
        clc
        return

;------------------------------------------------------------------
onmessage WM_SETFOCUS
        mov     eax, edi
        stdcall GetSizer
        invoke  SetFocus, eax
        xor     eax,eax
        clc
        return

;-------------------------------------------------------------------
onmessage WM_ERASEBKGND
        lea     ebx, [.rect]
        invoke  GetClientRect, [.hwnd], ebx

        invoke  GetClassLongA, [.hwnd], GCL_HBRBACKGROUND
        test    eax,eax
        jnz     .brushok

        invoke  GetSysColorBrush, COLOR_BTNFACE

.brushok:
        invoke  FillRect, [.wparam], ebx, eax

        invoke  GetWindowLongA, [.hwnd], GWL_STYLE
        test    eax,WS_CHILD
        jnz     .ondefault

        cmp     [fGridVisible], FALSE
        je      .enderase

        invoke  CreatePen, PS_SOLID, 0, $00a0a0a0
        invoke  SelectObject, [.wparam], eax
        push    eax

        xor     edi, edi
.loopx:
        invoke  MoveToEx, [.wparam], edi, 0, NULL
        invoke  LineTo,   [.wparam], edi, [.rect.bottom]

        add     edi, [xGrid]
        cmp     edi, [.rect.right]
        jbe     .loopx

        xor     edi, edi
.loopy:
        invoke  MoveToEx, [.wparam], 0, edi, NULL
        invoke  LineTo,   [.wparam], [.rect.right], edi

        add     edi, [yGrid]
        cmp     edi, [.rect.bottom]
        jbe     .loopy

        invoke  SelectObject, [.wparam]
        invoke  DeleteObject, eax

.enderase:
        xor     eax,eax
        clc
        return


;-------------------------------------------------------------------
onmessage WM_SETCURSOR

        invoke  GetWindowLongA, [.hwnd], GWL_HWNDPARENT
        cmp     eax, [hApplication]                         ; ????
        je      .ondefault

        invoke  LoadCursorA,NULL,IDC_ARROW
        invoke  SetCursor,eax
        xor     eax,eax
        clc
        return

;---------------------------------------------------------------------------
onmessage WM_WINDOWPOSCHANGED

        mov     ebx, [.lparam]
        mov     eax, [ebx+WINDOWPOS.flags]
        and     eax, SWP_NOSIZE or SWP_NOMOVE
        cmp     eax, SWP_NOSIZE or SWP_NOMOVE
        je      .endposchanged

        xor     ecx, ecx
        test    eax, SWP_NOSIZE
        jnz     .sizeok

        mov     eax, [ebx+WINDOWPOS.cx]
        mov     edx, [ebx+WINDOWPOS.cy]
        mov     [edi+TWinTemplateDT.width], ax
        mov     [edi+TWinTemplateDT.height], dx
        or      ecx, upSize

.sizeok:
        test    eax, SWP_NOMOVE
        jnz     .posok

        mov     eax, [ebx+WINDOWPOS.x]
        mov     edx, [ebx+WINDOWPOS.y]
        mov     [edi+TWinTemplateDT.left], ax
        mov     [edi+TWinTemplateDT.top], dx
        or      ecx, upPosition

.posok:
        invoke  PostMessageA, [hPropEditor], PRM_UPDATEPROP, edi, ecx

        cmp     [edi+TWinTemplateDT.parent], 0
        je      .updatesizer

        cmp     [edi+TWinTemplateDT.Align], waNone
        je      .updatesizerok

.updatesizer:
        mov     eax, edi
        stdcall GetSizer
        invoke  SendMessageA, eax, SZM_UPDATESIZE, 0, 0

.updatesizerok:
; Mark control as modified...
        mov    eax, edi
.search:
        cmp     [eax+TWinTemplateDT.parent], 0
        je      .found
        mov     eax, [eax+TWinTemplateDT.parent]
        jmp     .search

.found:
        mov     eax, [eax+TWinTemplateDT.ptrFile]
        invoke  SendMessageA, [eax+TOpenFile.hEditor], _CEM_SETMODIFIED, TRUE, 0

.endposchanged:
        stdcall AlignChildren, [.hwnd]
        xor     eax, eax
        clc
        return

        cmp     [edi+TWinTemplateDT.Align], waNone
        jne     .quitsize

        cmp     [edi+TWinTemplateDT.parent], 0
        jne     .quitsize

        stc
        return

.quitsize:
        xor     eax, eax
        clc
        return

;-------------------------------------------------------------------
onmessage WM_CLOSE
        invoke  SetFocus, [hEditorsHost]
        invoke  ShowWindow, [.hwnd], SW_HIDE

        xor     eax, eax
        clc
        return

;-------------------------------------------------------------------
onmessage WM_LBUTTONDOWN
  locals
    .cursorpos POINT
    .tool      dd ?
  endl
        stdcall GetCurrentTool
        mov     [.tool], eax
        test    eax, eax
        jnz     .selectrect

        test    [.wparam], MK_SHIFT
        jnz     .selectrect

        mov     esi, [edi+TWinTemplateDT.parent]
        test    esi, esi
        jz      .topselectrect

        mov     ecx, 1
        test    [.wparam], MK_CONTROL
        jnz     @f
        dec     ecx
@@:
; select one control
        mov     eax, esi
        stdcall GetSizer
        mov     esi, eax
        invoke  SendMessageA, esi, SZM_SELECTCONTROL, edi, ecx

        test    [.wparam], MK_CONTROL
        jnz     .endsingleselect

        lea     ebx, [.cursorpos]
        invoke  GetCursorPos, ebx
        invoke  ScreenToClient, esi, ebx
        mov     ax, word [.cursorpos.y]
        shl     eax, 16
        mov     ax, word [.cursorpos.x]

        invoke  SendMessageA, esi, WM_LBUTTONDOWN, [.wparam], eax

.endsingleselect:
        xor     eax, eax
        clc
        return

.topselectrect:
        invoke  SendDlgItemMessageA, [hPropEditor], 101, PEM_SETCONTROL, edi, 0

.selectrect:
        test    [.wparam], MK_CONTROL
        jnz     @f
        mov     eax, edi
        stdcall GetSizer
        invoke  SendMessageA, eax, SZM_UNSELECTALL, 0, 0
@@:
; search window to get capture...
.parentloop:
        test    [edi+TWinTemplateDT.styleEx], WS_EX_CONTROLPARENT
        jnz     .parentok

        cmp     [edi+TWinTemplateDT.parent], 0
        je      .parentok

        mov     edi, [edi+TWinTemplateDT.parent]
        jmp     .parentloop

.parentok:
        mov     eax, [edi+TWinTemplateDT.hwnd]
        mov     [.hwnd], eax
        invoke  SetCapture, [.hwnd]

        lea     esi,[.rect]
        invoke  GetClientRect, [.hwnd], esi
        invoke  ClientToScreen, [.hwnd], esi
        add     esi,8
        invoke  ClientToScreen, [.hwnd], esi
        sub     esi,8
        invoke  ClipCursor, esi

        invoke  GetCursorPos, esi
        invoke  ScreenToClient, [.hwnd], esi

        mov     ebx, [esi+POINT.x]
        mov     ecx, [esi+POINT.y]

        cmp     [.tool], 0
        je      .snapok

        stdcall RoundToGrid, ebx, [xGrid]
        mov     ebx, eax
        stdcall RoundToGrid, ecx, [yGrid]
        mov     ecx, eax

.snapok:
        mov     [edi+TWinTemplateDT.DragRect.left],ebx
        mov     [edi+TWinTemplateDT.DragRect.top],ecx
        inc     ebx
        inc     ecx
        mov     [edi+TWinTemplateDT.DragRect.right],ebx
        mov     [edi+TWinTemplateDT.DragRect.bottom],ecx

        xor     eax, eax
        clc
        return


;-------------------------------------------------------------------
onmessage WM_MOUSEMOVE

        invoke  GetCapture
        cmp     eax,[.hwnd]
        jne     .endmove

; Draw select rect
        invoke  GetDCEx, [.hwnd], NULL, DCX_PARENTCLIP
        mov     ebx, eax

        lea     esi, [edi+TWinTemplateDT.DragRect]
        stdcall DrawSortedFocusRect, ebx, esi

        stdcall GetCurrentTool

        movsx   ecx, word [.lparam]
        movsx   edx, word [.lparam+2]

        test    eax, eax
        jz      .movesnapok

        stdcall RoundToGrid, ecx, [xGrid]
        mov     ecx, eax
        stdcall RoundToGrid, edx, [yGrid]
        mov     edx, eax

.movesnapok:
        mov     [edi+TWinTemplateDT.DragRect.right], ecx
        mov     [edi+TWinTemplateDT.DragRect.bottom], edx
        stdcall DrawSortedFocusRect, ebx, esi

        invoke  ReleaseDC, [.hwnd], ebx

.endmove:
        xor     eax, eax
        clc
        return

;-------------------------------------------------------------------
onmessage WM_LBUTTONUP

        invoke  GetCapture
        cmp     eax,[.hwnd]
        jne     .endbuttonup

        invoke  ReleaseCapture
        invoke  ClipCursor,NULL

; select rect or create rectangle.
        invoke  GetDCEx, [.hwnd], NULL, DCX_PARENTCLIP
        push    eax
        lea     ebx, [edi+TWinTemplateDT.DragRect]
        stdcall DrawSortedFocusRect, eax, ebx                           ; remove the last select rect.
        invoke  ReleaseDC, [.hwnd] ;, from the stack.

        stdcall GetCurrentTool
        test    eax, eax
        jz      .select

        mov     esi, eax

        invoke  SendMessageA, edx, TB_CHECKBUTTON, 0, TRUE

        stdcall CreateControlFromTool, esi, edi, ebx          ;CreateControlFromTool, Tool, Parent, ptrRect
        test    eax,eax
        jnz     .endbuttonup

.select:
        xor     ecx, ecx
        test    [.wparam], MK_CONTROL
        jz      @f
        inc     ecx
@@:
        stdcall SelectInDragRect, edi, ecx

.endbuttonup:
        xor     eax,eax
        clc
        return
endwp



;***************************************************
proc SelectInDragRect, .ptrParent, .fDontClear

.select RECT
.rect   RECT
.inter  RECT
.hSizer  dd ?

begin
        push    edi ebx esi

        mov     edi, [.ptrParent]
        test    edi, edi
        jz      .endchildren

        mov     eax, edi
        stdcall GetSizer
        mov     [.hSizer], eax

        lea     ecx, [edi+TWinTemplateDT.DragRect]
        lea     esi, [.select]
        invoke  CopyRect, esi, ecx
        stdcall SortRect

        mov     ebx, [edi+TWinTemplateDT.children]
        lea     esi, [ebx+TArray.array]
        mov     ebx, [ebx+TArray.count]

.searchchildren:
        dec     ebx
        js      .endchildren

        mov     edi, [esi+4*ebx]
        movsx   ecx, [edi+TWinTemplateDT.left]
        movsx   edx, [edi+TWinTemplateDT.top]
        mov     [.rect.left], ecx
        mov     [.rect.top], edx
        movsx   ecx, [edi+TWinTemplateDT.width]
        movsx   edx, [edi+TWinTemplateDT.height]
        add     ecx, [.rect.left]
        add     edx, [.rect.top]
        mov     [.rect.right], ecx
        mov     [.rect.bottom], edx

        lea     ecx, [.rect]
        lea     edx, [.inter]
        lea     eax, [.select]
        invoke  IntersectRect, edx, ecx, eax

        cmp     [fPartialSelect], FALSE
        jne     .partial

        lea     edx, [.inter]
        lea     ecx, [.rect]
        invoke  EqualRect, ecx, edx
        test    eax,eax
        jnz     .selectit
        jz      .searchchildren

.partial:
        lea     edx, [.inter]
        invoke  IsRectEmpty, edx
        test    eax,eax
        jnz     .searchchildren

.selectit:
        invoke  SendMessageA, [.hSizer], SZM_SELECTCONTROL, edi, [.fDontClear]
        mov     [.fDontClear], 1

        jmp     .searchchildren

.endchildren:
        pop     esi ebx edi
        return
endp


;***************************************************
; Draws focus rectangle on the given DC
; even if the rectangle is not sorted.
;***************************************************
proc DrawSortedFocusRect, .hDC, .ptrRect

.rect   RECT

        begin
        push    esi

        lea     esi, [.rect]
        invoke  CopyRect, esi, [.ptrRect]
        call    SortRect
        invoke  DrawFocusRect, [.hDC], esi

        pop     esi
        return
endp


;***************************************************
; Creates new control depending of the current
; selected tool.
;***************************************************
proc CreateControlFromTool, .Tool, .Parent, .ptrRect
begin
        push    esi edi ebx

; Creates empty TWinTemplate and attaches it to the parents window tree.
        stdcall GetMem, sizeof.TWinTemplateDT
        mov     edi, eax

        stdcall CreateArray, 4
        mov     [edi+TWinTemplateDT.children], eax

        mov     ecx, [.Parent]
        mov     [edi+TWinTemplateDT.parent], ecx

        stdcall AddArrayItems, [ecx+TWinTemplateDT.children], 1
        mov     [ecx+TWinTemplateDT.children], edx
        mov     [eax], edi

        mov     ebx, [.Tool]
        mov     esi, [.ptrRect]
        call    SortRect

        mov     eax, [esi+RECT.right]
        mov     ecx, [esi+RECT.bottom]
        sub     eax, [esi+RECT.left]
        sub     ecx, [esi+RECT.top]

        cmp     eax, 8
        jge     @f
        mov     eax, [ebx+TDesignTimeInfo.DefaultWidth]
@@:
        cmp     ecx, 8
        jge     @f
        mov     ecx, [ebx+TDesignTimeInfo.DefaultHeight]
@@:
        mov     [edi+TWinTemplateDT.width], ax
        mov     [edi+TWinTemplateDT.height], cx

        mov     eax, [esi+RECT.left]
        mov     ecx, [esi+RECT.top]
        mov     [edi+TWinTemplateDT.left], ax
        mov     [edi+TWinTemplateDT.top], cx

        mov     eax, [ebx+TDesignTimeInfo.DefaultStyle]
        mov     ecx, [ebx+TDesignTimeInfo.DefaultStyleEx]
        or      eax, WS_VISIBLE
        mov     [edi+TWinTemplateDT.style], eax
        mov     [edi+TWinTemplateDT.styleEx], ecx

        stdcall StrDup, [ebx+TDesignTimeInfo.ClassName]
        mov     [edi+TWinTemplateDT.ptrClass], eax

        stdcall StrDup, [ebx+TDesignTimeInfo.DefaultText]
        mov     [edi+TWinTemplateDT.ptrText], eax

        stdcall StrDup, cFormNameNone
        mov     [edi+TWinTemplateDT.hName], eax

        stdcall StrNew
        mov     [edi+TWinTemplateDT.WinProc], eax

        stdcall CreateDesignWindow, edi

.qtrue:
        xor     eax,eax
        dec     eax
.finish:
        pop     ebx edi esi
        return
endp


cDefaultFormStyleEx = 0
cDefaultFormStyle = WS_VISIBLE or WS_SYSMENU or WS_CLIPSIBLINGS or WS_CLIPCHILDREN
cDefaultX         = 220
cDefaultY         = 220
cDefaultWidth     = 320
cDefaultHeight    = 240
cDefaultFontSize  = 8
cDefaultFontWeight  = FW_NORMAL
cDefaultFontItalic  = FALSE
cFormDefaultFont text 'MS Sans Serif'



;---------------------------------------------------------------------
; Fully destroys control and frees all allocated
; memory.
; Arguments:
;   ptrWinTemplateDT - pointer to the TWinTemplateDT structure of the
; control.
;---------------------------------------------------------------------
proc DestroyDesignWindow, .ptrWinTemplateDT, .detach
begin
        push    esi edi ebx

        mov     esi, [.ptrWinTemplateDT]
        test    esi, esi
        jz      .finish

        mov     edi, [esi+TWinTemplateDT.children]
        mov     ebx, [edi+TArray.count]

; Loop to destroy all children.
.delchildren:
        dec     ebx
        js      .endchildren

        stdcall DestroyDesignWindow, [edi+4*ebx+TArray.array], FALSE
        jmp     .delchildren

.endchildren:
        stdcall FreeMem, edi

        cmp     [.detach], FALSE
        je      .parentok

; detach from parent window
        mov     edi, [esi+TWinTemplateDT.parent]
        test    edi, edi
        jz      .parentok

        stdcall ListIndexOf, [edi+TWinTemplateDT.children], esi
        jc      .parentok

        stdcall DeleteArrayItems, [edi+TWinTemplateDT.children], eax, 1
        mov     [edi+TWinTemplateDT.children], edx

.parentok:
; Remove the control from property editor.
        invoke  SendDlgItemMessageA, [hPropEditor], 101, PEM_GETCONTROL, 0, 0
        cmp     eax, esi
        jne     .propeditok

        invoke  SendDlgItemMessageA, [hPropEditor], 101, PEM_SETCONTROL, [esi+TWinTemplateDT.parent], 0

.propeditok:
; Destroy strings used in design time.

        stdcall StrDel, [esi+TWinTemplateDT.hName]
        stdcall StrDel, [esi+TWinTemplateDT.ptrClass]
        stdcall StrDel, [esi+TWinTemplateDT.ptrText]
        stdcall StrDel, [esi+TWinTemplateDT.WinProc]

; Destroy windows instances.
        invoke  DestroyWindow, [esi+TWinTemplateDT.hSizer]
        invoke  DestroyWindow, [esi+TWinTemplateDT.hwnd]

; Destroy TWinTemplateDT structure.
        stdcall FreeMem, esi

.finish:
        pop     ebx edi esi
        return
endp


proc SortRect
        begin
        mov     eax, [esi+RECT.left]
        mov     ecx, [esi+RECT.right]
        cmp     ecx, eax
        jge     @f
        xchg    eax,ecx
@@:
        mov     [esi+RECT.left],eax
        mov     [esi+RECT.right], ecx

        mov     eax, [esi+RECT.top]
        mov     ecx, [esi+RECT.bottom]
        cmp     ecx, eax
        jge     @f
        xchg    eax,ecx
@@:
        mov     [esi+RECT.top],eax
        mov     [esi+RECT.bottom], ecx
        return
endp



proc RoundToGrid, .coordinate, .step
begin
        push    ecx edx

        mov     eax, [.coordinate]

        cmp     [fSnapToGrid], FALSE
        je      .quit

        cdq
        mov     ecx, [.step]
        idiv    ecx

        sar     ecx,1
        cmp     edx, ecx
        jl      @f
        inc     eax
@@:
        imul    eax, [.step]

.quit:
        pop     edx ecx
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/Controls.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
;************************************************************************
; Design time template structure.
;************************************************************************
struct TWinTemplateDT
  . TWinTemplate
  .parent     dd   ?
  .children   dd   ?   ; pointer to TArray with children.

  .ptrFile    dd   ?   ; pointer to TOpenFile structure. Only top-level window
                       ; have this field set.

  .hName      dd   ?   ; Design name of the control - in CT this is the label name of the control.

  .DesignInfo dd   ?   ; pointer to designtime info of the class
  .hwnd       dd   ?   ; handle of the created instance of the window.

  .hSizer     dd   ?   ; handle of TSizer control that handles operations on selected controls.
  .DragRect   RECT
ends
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































Deleted source/Doc/1_TODO.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
1.To be fixed behaviour of comment block/uncomment block.
2. CCList cant insert text when vertical mode in editor is set.
3. Several crashes reported, but without any additional information.



Ïðåäè ïóáëèêàöèÿ:

DONE: 1. Äà ñå íàïðàâè ôàëøèâàòà êîìïèëàöèÿ äà íå çàâèñè îò ðåäîâå â ñîðñà... EndSource å ãëóïàâî.
DONE: 3. 2/3 îò ïðîñòðàíñòâîòî çà ïðîäæåêò ìåíàæåðà, 1/3 çà ïðîïúðòèñ.
DONE: 2. Äà ñå ïðåìàõíàò àâòîìàòè÷íèòå íàñòðîéêè çà âúíøíè ïðîäóêòè.
DONE: 4. Èêîíèòå çà áóêìàðêè...
DONE: 5. Âðåìå å äà ñå îïðàâè ">" äà íå îòâàðÿ àóòîêîìïëèòà.
DONE: 6. "." íà åäèíè÷íà òî÷êà äà íå îòâàðÿ àóòîêîìïëèòà.

7. - íèñúê ïðèîðèòåò - asmedit2

8. îùå âåäíúæ äà ñå ïðîâåðÿò ðåäîâåòå âúâ ôîðìèòå. Èëè âúîáùå äà ñå èçõâúðëÿò îò ôàéëà.
   äà ñå ñëîæàò íà êðàÿ è äð.ïîä. Àêî ñå ñëîæàò íàêðàÿ, ìîæå íàïðàâî äà ñå îñòàâÿò â ñîðñà.

*******************************************************************************************

0. Äà ñå îáðàáîòâà WM_CONTEXTMENU â project manager.

Êîãàòî êîìïèëàöèÿòà çàâúðøâà ñ write failed íå ñå ñúçäàâà fas ôàéë. ?????

DONE: 1. Îïöèèòå äà ñå ìàõíàò îò ïðîåêòà - îñòàâàò â ñîðñà, çàùîòî ñà ñîðñ-çàâèñèìè.
DONE: 3. Ïðè ãðåøíà êîìïèëàöèÿ äà íå ñå îïèòâà äà ïðàâè "goto definition"

   3.1 Ìîæå åäíîêðàòíî äà ñå îïèòà äà ñå ïðåñêà÷à ðåäà, êîéòî äàâà ãðåøêàòà.
        òîçè ñëó÷àé, ìîæå äà ñå ïîëó÷àò è êîðåêòíè ñòîéíîñòè çà åòèêåòèòå.
       Àêî òîçè íîìåð íå ìèíàâà è ïàê âúçíèêâà ãðåøêà, òî öåëèÿò ñîðñ ñå çàãðàæäà
       ñúñ "if 0" "end if" è ñå êîìïèëèðà íàíîâî - ïîíå äúðâîòî ñ åòèêåòèòå ùå ñå èçãðàäè.
       Àêî ãðåøêàòà å ïî âðåìå íà ïðåïðîöåñèíãà - íå ñå ñåùàì êàêâî ìîæå äà ñå
       íàïðàâè...

DONE: 4. Äà ñå ñúçäàâàò ñòðóêòóðèòå íà àñåìáëèðàíèÿ êîä - çà äåáúãåðà.
DONE: 5. Ôóíêöèÿòà "goto address"
DONE: 6. Äà ñå ïîìèñëè êàê ùå ñå äåáúãâà ïîä Ëèíóêñ.

   6.1. Äà ñå âèäè ïðîåêòà AsmBug çàùî íå ìîæå äà ðàáîòè âúâ andLinux

   7. Âñå îùå íå ìè õàðåñâà àâòîìàòè÷íîòî ñêðèâàíå íà ñúîáùåíèÿòà.
      Çíàì ñè àç, ÷å ïî âðåìå íå ñòàâà íèêîãà äîáðå!
      Ìîæå áè òðÿáâà äà èç÷åçâà, êîãàòî çàïî÷íå ðàáîòà â ðåäàêòîðà - ïèñàíå,
      ìåñòåíå ñúñ ñòðåëêèòå - òàêèâà ðàáîòè - òîåñò, êîãàòî ïðå÷è. Èíà÷å äà ñè
      ñòîè.

DONE: 8. Âñå îùå çàáèâà ïðè íÿêîè êëàâèøè - ÿâíî ñâúðçàíè ñ ìåíþòàòà.


9. Ôóíêöèÿ êàëêóëàòîð, íî äà ñå ïîëçâà èçêëþ÷èòåëíî ëåñíî - ïðèìåðíî
   ïèøåø â ðåäàêòîðà èçðàç, íàòèñêàø êëàâèø è èçðàçà ñå èç÷èñëÿâà.

10. Êëàñè÷åñêè cross-reference - è èíñòðóìåíò êàòî "goto location" íà ñèìåíñ
    (åäíà îò ìàëêîòî èì äîáðè èäåè...)
    ñàìî íå å ÿñíî, äàëè îò äîñòúïíàòà èíôîðìàöèÿ ìîæå äà ñå ñúçäàäå êðîñ ðåôåðåíñ?
    Ñòðóâà ìè ñå, ÷å íå. Ìîæå äà ñå ïðåòúðñâà ïðåïðîöåñèðàíèÿ êîä.

DONE: 11. íîâ ôîðìàò çà ïðîåêòèòå.

12. Ìåíàæåðà íà ïðîåêòèòå òðÿáâà äà ñå íàïðàâè ïî-óäîáåí.
    Îñîáåííî çà ìàëêè ðåçîëþöèè. Íàïðèìåð ìîæå äà ñå êðèå èçâúí åêðàíà è äà ñå ïîêàçâà
    êàòî òàñê áàðà íà Óèíäîóñ. Ïðè òîâà êàòî ÷å ëè îòäÿñíî å ïî-óäîáíî, çàùîòî
    äÿñíàòà ñòðàíà íà ðåäàêòîðà å ïî-íåíàòîâàðåíà. Ñúùîòî âàæè è çà äÿñíàòà ñòðàíà íà
    ãëàâíèÿ ïðîçîðåö. Òîåñò ìåíàæåðà íà ïðîåêòè ìîæå äà çàåìà öÿëàòà äÿñíà ñòðàíà íà
    åêðàíà. Ëîøîòî íà òàêîâà ðåøåíèå å, ÷å ùå ñè ïðå÷àò ñúñ ñêðîëáàðà íà ðåäàêòîðà, à
    òîâà å íåäîïóñòèìî...







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































Deleted source/Doc/Common properties.txt.

1
2
3
4
5
6
7
8
9
10
11
12
The properties that have to be defined as atoms:

; Window size control properties.
propAlign db 'Align', 0
propAutoSize db 'AutoSize', 0

; Window subclassing properties.
propOldProc  db 'OldProc', 0
propUserProc db 'UserProc', 0

; TForm properties
propLastFocused db 'LastFocused'
<
<
<
<
<
<
<
<
<
<
<
<
























Deleted source/Doc/DesignTimeRunTime.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
Now:

The format of the one window description (visual edited windows) is:

TWinTemplate structure of data, describes one simple Window without
specific for particular class data - for example tree items for Tree-view
control.

WindowName:             (optional label)
        db  flags     ; flags wtChild, wtParent and wtEnd
        db  WinAlign  ; Win align value: waNone, waLeft, waRight, waTop, waBottom or waClient
        dd  ptrClass  ; pointer to the classname, defined as string (for now not unique)
        dd  ptrText   ; pointer to the text string. That is not neccessary for all controls.
        dd  style
        dd  styleEx
        dw  ID        ; or hMenu for top level windows.
        dw  left
        dw  top
        dw  width
        dw  Hight
        dd  LabelToWinProc

It is simple, but not very powerfull, because it is not able to auto initialize
controls (only text) in the time when this is easy - when the control is created.
Later, the initialization needs more efforts: GetDlgItem for example and also, it
needs writing code, that can reside in one common place and to be used when needed.
Diferent controls needs as a rule different code to be initialized:

1. Edit controls - CreateWindow
2. ListBox - Series of LB_ADDSTRING messages, pointing to the strings from item list.
3. Combo box - Series of CB_ADDSTRING messages, to the combobox control.
4. Scrollbar - SBM_SETSCROLLINFO with structure SCROLLINFO
5.

So, visibly every visual control needs some special procedure to allow it to be
properly initialized and also it need to have some data (different size and content)
in order to be initialized properly.

Initializing can be separated to two types:
1. Run-time init
2. Design-time init

The second one is important, because in design-time there is only the
source code of the control - this code can be parsed, but the code Fresh
needs to call doesn't exists (it is part of the source too.) and can't be
called.

One possible solution is to make design-time library for every control, that
to contains the function, designed to init the control in design time.
The same function will exists in the source of the project and will
be called by CreateForm procedure after window creation.

OK, let's see the properties every Window has without exception:

1. flags - this concerns not the window, but the Windows tree structure.
2. Class name - we have to make something for all these equal names (strings)
3. Style      - every window has style
4. StyleEx    - every window has styleEx

5. WinAlign - every window can be auto-aligned in Fresh architecture.
 5.1. - if the WinAlign = waNone, then Window needs sizes:
   X, Y, Width and Height - 4 words = 2 dwords


The next are invisible components - menues, action-lists etc.
They have relations with other components, but they are not visible and
they are not windows at all, but simply some data-structures, possibly
with handles (they needs some creating and possibly destruction)
but they doesn't stay in the Windows tree, they simply have some
relation to the windows and possibly other invisible components - for example
the menues uses actions from the action lists, and also the forms may have
menues attached to them during creation (but they may not as well).

Finally: Whole data needed to be created one component (visible or invisible)
might be represented as a stream - different pieces of this stream will be
processed by several (various) procedures called during CreateForm procedure.

The list of the procedures should be incorporated in the different list for
every component and in the stream will be only a pointer to this data.
btw, this list might contains classname for window components as well.

This approach at first glance looks like overbloat, but if the application
contains at least several windows that need static initialization, this
approach will lead to smaller code, than classic approach.
I suppose, the needed init procedures can be made small enough to not cause
code overbloat at all.

IT IS GOOD TO MAKE POSSIBLE, THE DATA INSIDE CONTROL TO BE OPTIONAL - like
flag fDataOnlyInDesignTime - this will ensure that the design time forms
that MUST be filled dynamically (for example from files) will have appropriate
look and feel during design process - it is matter of comfort.

Another topic:
~~~~~~~~~~~~~~
We need some common system for design-time handling of symbolic constants,
that will become numeric constants on run-time:
I mean: resource and window ID's - on design time we need to use only
symbolic names and later in compilation, create the source of type:
someID = 1
otherID = 101
etc.


BTW: All these thoughts means relatively big restructuring of the visual
editors structure and most possibly another breaking of the back compatibility.
But better now, until Fresh is in pre-alpha stage. After the official
alpha-beta-release will be too late to make such big changes.


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































Deleted source/Doc/EditorInterface.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
Common editor interface.
[ Preliminary, not finished, not useful ;) ]

1. Subject
   This document describes requirements for every editor for Fresh IDE.

2. Common requirements

  As a rule, every editor is window class that can show and/or edit
one file of given type. Editor can interacts with other editor windows
only by calling procedures from FMAPI (file manager API) of Fresh.
File manager controls editor via several user defined messages, all with
prefix: 'CEM_' or '_CEM_'. Also, file manager creates one data structure of
type TOpenFile for every file processed in Fresh.


3. Creation of editor window.

   Every editor should provide function of the type:

proc CreateSomeEditor, ptrOpenFile

ptrOpenFile arguments is pointer to the structure of type TOpenFile, that
contains information about edited file. The procedure should provide following
operations:
  1. Create editor window
  2. Store ptrOpenFile to it for future using
  3. Proper attaching the editor to the Fresh IDE, for example
     adding it to the Editors host window
  4. Loading the disk file to the editor or (if the file does not
     exists) creating new empty file of given type.

  Procedure returns handle to the editor window or NULL if there are some
errors.


4. Message processing

   Every editor window should provide processing of so called, _CEM messages

;-----------------------------------------------------------------------

CEM_LOADFILE
Arguments: (0, 0)
Returns: NULL if OK
         ErrorCode, if error.

  Loads (or reloads) the file from assigned TOpenFile structure
in the editor. If the file is already loaded, it should be reloaded
from the last saved disk file.

;-----------------------------------------------------------------------

_CEM_SAVEFILE   ; (0, 0): ErrorCode

ErrorCode - NULL if the opeation is done, or error code if there are
errors.

Save the edited file to disk.

;-----------------------------------------------------------------------


message _CEM_CHANGENOTIFY ; (0, 0) - notifies the editor
                          ; that content of the structure was changed
                          ; - name, the status of the file, etc.
                          ; Editor should provide updating of the file view.
                          ; Of course it can discard this message if it
                          ; not need such notifications. Also, the editor
                          ; can send _CEN_FILECHANGED to it's parent window

message _CEM_FOCUSFILE    ; (0, 0) - Activates the editor window
                          ; and focuses the file.

message _CEM_CANACTION    ; (0, action) - returns TRUE if the
                          ; content of the editor allows given action in
                          ; this moment.
                          ;  [action] can be one of:
                          ;    WM_UNDO
                          ;    WM_COPY
                          ;    WM_CUT
                          ;    WM_PASTE
                          ;    WM_CLEAR

message _CEM_EDITACTION   ; (0, action) - Execute common edit
                          ; action in given file.
                          ;  [action] can be one of:
                          ;    WM_UNDO
                          ;    WM_COPY
                          ;    WM_CUT
                          ;    WM_PASTE
                          ;    WM_CLEAR

message _CEM_GETMODIFIED  ; (0, 0) - returns TRUE if the given
                          ; file is modified and FALSE if the file is not
                          ; modified after the last save - it is probably
                          ; save to always return TRUE.

message _CEM_GETTITLE     ; (0, 0) - returns string with title of the file.
                          ; caller have to StrDel after using of the string.

message _CEM_GETICONINDEX ; (0, 0) - returns the image index of the
                          ; icon that represents current file type.

message _CEM_GETFILE      ; (0, 0) - returns pointer to TOpenFile structure
                          ; of the given file.

message _CEM_GETASMEDIT   ; (0, 0) - returns handle of possibly internal for editor
                          ; ASMEDIT window, if any. NULL otherwize.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































Deleted source/Doc/FASM internals.txt.

cannot compute difference between binary files

Deleted source/Doc/FreshEditors.txt.

cannot compute difference between binary files

Deleted source/Doc/History.txt.

cannot compute difference between binary files

Deleted source/Doc/NewEditorFeatures.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
Ñïåöèôèêàöèÿ íà òåêñòîâèÿ ðåäàêòîð íà Fresh:

1. Editor have to keep some data associated to every line of text:

  1.1. Bookmark flag

  1.2. Read-only flag - the lines marked with this flag are auto generated
       by the visual editors and can't be manually edited. This will allow
       this kind of lines to stay even inside files and to be not removed
       from the editor.

  1.3. dword value with current address - after compilation, the compiler
       fills this data in order to allow proper recognition of the labels
       for code completition and debugging functions.

  1.4.

2. Global functions:

  2.1. Global "read-only" flag for whole file. This flag will not
       have effect on syntax highligher.

  2.2. Maybe we don't need search functions (AEM_FINDFIRST etc.)
       WM_GETTEXT and external search functions will allow more
       flexible search of multiply files, than opening every file
       in editor and then closing it.

  2.3.  Syntax highlight interface have to be improved in order to
        be simplyfied when ASMEDIT2 is used in Fresh. For example
        Syntax procedure can fill directly colors to the buffer not
        indexes. That will make possible to have only one color table
        common for all instances of AsmEdit2.

  2.4. If it is possible (not very difficult) we need word wrap function
       for editor because in Fresh the editor edits text files
       together with assembly source files.

  2.5. Highlighting of group of lines with different color depending of
       the current context - for example "red" to mark compilation error
       line and "aqua" to mark curent executted line in debugger.
       (AEM_SETFOCUSLINE)

  2.6. If it is not very hard for implementation, it is good to make
       custom set of keys. The approach of Pe2 looks very flexible.

  2.7. It is good idea to make the editor portable because this will
       make easy porting Fresh to other platforms later.


Supported messages:

1. Standard windows messages:

  WM_COPY
  WM_CUT
  WM_PASTE
  WM_CLEAR
  WM_SETTEXT
  WM_GETTEXTLENGTH
  WM_GETTEXT
  WM_SETFONT
  WM_GETFONT
  WM_UNDO / EM_UNDO
  EM_CANUNDO
  EM_EMPTYUNDOBUFFER
  EM_REPLACESEL

2. AEM_ messages

  AEM_SETMODE

  Parameters:
    wparam = new mode value
    lparam = ignored

  Return:  nothing

  Remarks:
    Mode value can be zero or any combination of the following constants:
      AEMODE_OVERWRITE   - overwrite mode
      AEMODE_VERTICALSEL - vertical selection mode

-----------------------------------------------------------------------------
  AEM_GETMODE

  Parameters:
    wparam = ignored
    lparam = ignored

  Return:  Current mode value - any compination of AEMODE_OVERWRITE and
           AEMODE_VERTICALSEL.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































Deleted source/Doc/NewFormEngine.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
RT = run-time
DT = design-time
CT = compile time
CEI = common editor interface

This is base window template needed to create every window in
DT and RT:

struc TWinTemplate  {
  .flags      db ?    ; one or more of 0, wtParent, wtEnd
  .Align      db ?    ; one of waNone, waLeft, waRight, waTop, waBottom, waClient
  .ptrClass   dd ?    ; pointer to the classname. In DT handle to the classname
  .ptrText    dd ?    ; pointer to the text (through WM_SETTEXT) in DT - handle
  .style      dd ?    ;
  .styleEx    dd ?    ;
  .ID         dw ?    ; What to do with top level windows? - this should be MENU handle.
  .left       dw ?
  .top        dw ?
  .width      dw ?
  .height     dw ?
  .WinProc    dd ?  ; pointer to the user window procedure of the window.
                    ; In design-time - handle to the string with the name
                    ; of the window procedure.
}

struc TWinTemplateDT {
  . TWinTemplate

  .DesignInfo dd ?   ; pointer to designtime info of the class
                     ; the problem is on reload of the controls.

  .hName      dd ?   ; Design name of the control - in CT this
                     ; is the label name of the control.

  .selected  dd ?    ; boolean TRUE if the window is selected.

  .hSizer    dd ?    ; handle of TSizer window.
  .DragMode  dd ?    ;  Handling of rectangle selection inside the control.
  .DragRect  RECT    ;

  .hwnd      dd   ?             ; handle of the created instance of the window.
}


Clipboard handling:
~~~~~~~~~~~~~~~~~~~
CT_TEXT format of descriptions. Actually copying through the clipboard
is the same as loading the window from .frm file and saveing to the .frm
file, with the difference that only some of the windows can be copied/pasted.
Have to be used the same procedures as on Load/Save to .frm format.

There is a problems with text stored as argument to macro, because FASM can't handle
multiline text in quotes. We have to find workaround or to convince Privalov to
change string handling of FASM to support escapes.


Memory structure of the visual forms:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I tend to use the native RT format for DT too, but using TWinTemplateDT
instead of TWinTemplate arrays. The advantage is that the parent/child
structure is described explicitly and there is no need to use Windows
structures to recreate the structure. The tree of windows depends of the
.flags field of the TWinTemplate. For example:

W0      wtParent or wtEnd
W1        0
W2        wtParent
W3          0
W4          0
W5          wtEnd
W6        0
W7        wtEnd

btw: Using this format is possible to be created more than one top-level
window in one .frm file. Only IDE should be made able to create them.
Also another feature is to make possible creation of top level windows
that are not TForm class.

Refreshing windows after changing properties in property editor:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

All TWinTemplateDC structures have to be created in TList dynamic list.
The pointer of the structure have to be written in the windows instances
using SetWindowLong.

On inserting new window it will be added as first immediately after its
parent window.

On deleting window it will be deleted from the list and if it have wtParent
flag set - all following windows to the one with wtEnd flag set.

On recreating window with new properties: Two variants

    1. New window is created, then all children are to be moved with SetParent
to the new parent and at the end old parent is to be deleted.

    2. The window is deleted with all children and then whole tree is to be
recreated.


Common behaviour and handling of the Form editor
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1. IMPORTANT - the positioning in the source editor of the form editor have
an offset depending of the count of the windows defined inside it.
It is important on the error positioning after compilation.
On the other hand, search/replace functions work OK, because they works
directly in the asmedit window.

2. The form editor must have a flag: fMode [femVisual, femText] and to
show/hide form depending on this flag.

fMode := femVisual when the user shows the form with F12, of some of controls
         in this form is selected in property editor.

fMode := femText when
  1. the form editor or one of its children get focus back.
  2. the form is closed (hidden), or loosed focus - this will make F12 to
     focus the form again, even after editing in the property editor.




File structure in the project
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RT modules:
tform.asm / tform.inc - TForm window class itself.
forms.asm / forms.inc - Form handling procedures - CreateForm, ShowModal, etc.
winalign.asm / winalign.inc - Main window subclass library. All visual created
                              windows have to be subclassed through this
                              library (at least in DT) - I have to think
                              about RT - maybe if the control have waNone
                              and User procedure = NULL.

DT modules:
formsDT.asm / formsDT.inc - creates windows from TWinTemplateDT structures
instead of TWinTemplate. Also, creates the TWinTemplateDT structures from
text representation and back to text representation for load/save and
clipboard operations.

controls.asm / controls.inc - Provides DT message procedure, common
for all controls, that provides the editing features in visual editor,
instead of normal control behaviour.

FormEditor.asm/FormEditor.inc - Standard Fresh CEI file editor for
.frm file types. It provides editing and navigation in .frm files and
all functionality in CEI specification.



Data links in DT
~~~~~~~~~~~~~~~~~

Control|GWL_USERDATA        = ptr  to TAlignData structure.
  TAlignData.UserProc       = ptr  to CustomControlProc of the controls.asm
  TAlignData.UserData       = ptr  to TWinTemplateDT structure of the control.
  TWinTemplateDT.hwnd       = hwnd of window instance.
  TWinTemplateDT.DesignInfo = ptr  to TDesignTimeInfo structure.

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































Deleted source/Doc/ProjectFileFormat.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
The project file format must be flexible enough to provide
free developement of new features and compatibility with the
previous projects.
Also, it is good to keep it in binary format, as more assembly like. :)

Project must contain following data:

1. Project options - actually I think that all IDE options - directories, environment variables
                     even help files must be project based, not IDE based.
                     Of course, present options should be maintained as well.

2. Project tree - here should be possible to set files as links and as a text inside the project.
3. Main file / main files....
4. project encapsulated source files.


Project file format:

0. Header: 

offset len       content         description
------+-----+----------------+----------------------------------
  0   |  4  |    'FNPr'      | "(F)resh (N)ew (Pr)oject format"
  4   |  2  |   $0d, $0a     |  CR+LF
  6   |  1  |   $1a          |  EOF
  7   |  1  |   $0a          |  LF      (pad to 8
------+-----+----------------+----------------------------------



1. Chunk header:

offset  len      content         description
------+-----+----------------+--------------------------------------------------
  0   |  4  |   dword Name   |   Readable name of the chunk.
  4   |  4  |   dword L      |   Length of data field of the chunk in bytes.
  8   |  L  |   data bytes   |   Data bytes of the chunk.
  L+8 |  4  |   Hash         |   FNV-1a hash of the chunk data.
------+-----+----------------+--------------------------------------------------

3. Common chunks:

PRTR - project tree element. Contains one category and list of containing files.
       Files that are inside the project directory (the directory of the
       project file) will have relative names. The files that are outside the project
       directory should have absolute filenames.
       Files have no custom icons - they have icons depending on file type.

ICPL - icons pool - contains the icons used in the project tree.

ESRC - embeded source file - identified with unique index in the chunk. Every index
       have respective item in EMDR chunk. The files can be text or binary (images for example)

EDIR - embeded sources directory. Contains tree of directories where embeded files resides.
       also, contains list of all embeded files in the project.

VARS - local environment variables defined for the project. If the names of the local and global
       variables conflicts - the local take precedence.

MAIN - main source file of the project.

CTNM - Target filename of the project (executable to be created)

CMEM - compiler options - memory size.


At first time following chunks should be implemented:

MAIN - main filename of the project.
PRTR - it contains the structure of the project.
VARS - good feature.
CTNM - name and auto flag of the project.
CMEM - compiler memory size.



PRTR data format:

[dword icon], [dword FLAGS], 'full category name', 0
'filename 1', 0
.......
'filename N', 0



VARS data format:

'name', 0, 'value', 0, ..., 0 - double NULL ends the list.

CTNM data format:

[byte flag], 'name', 0
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































Deleted source/Doc/RDBMS.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
SQL and Fresh:

A small RDBMS (like SQLite) can be used to keep whole project in one
only file, thus ensure project consistency. Then virtual files will make
the compiler to produce the binary code.

Using database tables we can reach some different structure of the source
that may have (I think) big advantages compared with hierarchical database
that is in fact the file system used for Fresh now.

Using RDBMS for example will allow keeping of bookmarks, debug information,
formating info (for example read-only rows of some file) in one consistent
place, without bothering with hard checks about data consistency, missing
files, etc., etc.

There might be no directories, paths, etc, but some more clear structure of
the libraries - possibly in other database(s), or even (optional) as copy
in the project database - this will allow adjusting of every library for
the needs of the project.

BTW, SQLite is not the best choice as a native Fresh database, but it is
the only choice we have in this moment. There is total lack of other so
small and so powerfull RDBMS and using other multi-megabytes monster is
not an option for assembly programming.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































Deleted source/Doc/TODO.TXT.

1
2
1.

<
<




Deleted source/Doc/WineDetectTrick.txt.

1
Трика е ÑледниÑÑ‚ - функциÑта kernel32.wine_get_unix_file_name() ÑъщеÑтвува Ñамо в WINE.
<


Deleted source/Doc/asmedit.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%
%                                                                           %
%  AsmEdit control - Documentation                                          %
%  Copyright © Tomasz Grysztar                                              %
%  Modifications by Tommy Lillehagen                                        %
%                                                                           %
%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%

%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%
%  History                                                                  %
%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%

-----------------------------------------------------------------------------
  Version 1.4.5 [31.01.2004] Tommy Lillehagen
  [+] Added message AEM_READONLY and AEM_SETFOCUSLINE.
  [-] Setting focus line will now scoll and place the focus line in middle
      of the window (only if not the line is in the window).
  [-] Changed the parameters of AEM_READONLY.
  [-] Added focus line colors to the AETHEME structure.
  [-] Some minor fixes.

-----------------------------------------------------------------------------
  Version 1.4.4 [10.01.2004] John Found
  [-] Changed behaviour of the message AEM_GETWORDATCARET.
       byte [wparam+2] - if =0 the "." will be included in the word
                            <>0 the "." will be not included in the word
       Returns: lo word of eax - position of the left edge of the word
                hi word of eax - position of the right edge of the word

-----------------------------------------------------------------------------
  Version 1.4.3 [06.01.2004] John Found
  [+] Added message AEM_GETCARETXY and AECARETXY structure.

-----------------------------------------------------------------------------
  Version 1.4.2 fixes [14.12.2003] Tommy Lillehagen
  [-] Using DrawIconEx to draw the marks instead of a imagelist
  [+] Added AEM_SETBOOKMARKICON to set the icon for bookmarks.

-----------------------------------------------------------------------------
  Version 1.4.2 [14.12.2003] Tommy Lillehagen
  [-] The bookmarks is now cleared during the creation of the control
  [-] Using bitmap to mark bookmarks

-----------------------------------------------------------------------------
  Version 1.4.1 [24.11.2003] John Found
  [+] Added message: AEM_SETLINEDATA - opposite to AEM_GETLINEDATA with same
      parameters.
  [+] Added message: AEM_GETLINEPTR - returns the pointer to the given line
-----------------------------------------------------------------------------
  Version 1.4 fixes [15.11.2003] John Found
  [+] Changes in behaviour of right mouse button. Now it moves the cursor
      on the position on WM_RBUTTONDOWN
-----------------------------------------------------------------------------
  Version 1.4 [10.09.03 - 09:07]
-----------------------------------------------------------------------------
  [+] Support for comment/uncomment/indent/outdent lines
  [+] Added dymamic bookmark system (see messages reference for more info)
  [-] Minor bug fixes

  Version 1.3 [11.08.03 - 16:15]
-----------------------------------------------------------------------------
  [-] AEM_LOAD and AEM_SAVE are not a part of the library anymore
  [-] Minor bug fixes

  Version 1.2 [11.08.03 - 14:10]
-----------------------------------------------------------------------------
  [+] Different cursor in margin
  [+] AsmEdit in source, not via DLL
  [-] Changes in the AEM_SETTHEME (new name) message (see the messages
      reference)
  [-] Changes in the AEM_SETSYNTAXHIGHLIGHT message (see the messages
      reference)
  [-] Removed an unnecessary API call in AEM_LOAD
  [-] Removed the fasm_syntax procedure from the library

  Version 1.1 [10.08.03 - 20:08]
-----------------------------------------------------------------------------
  [+] Now you select the whole line by double-click in the left-margin
  [-] Fixed "caret-in-margin" bug
  [-] Fixed default font

  Version 1.0 [10.08.03 - 12:12]
-----------------------------------------------------------------------------
  [+] Added messages for file handling (AEM_LOAD, AEM_SAVE)
  [+] Added support for left-margin (AEM_SETMARGINWIDTH, AEM_SETMARGINCOLOR)
  [+] Popup-menu is now supported (AEM_SETPOPUPMENU)


%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%
%  Todo /bugs                                                               %
%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%

  * Highlight of lines (breakpoint/error etc.)


%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%
%  Available styles and notifications                                       %
%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%

  Styles:
    AES_AUTOINDENT, AES_SMARTTABS, AES_OPTIMALFILL, AES_SECURESEL,
    AES_AUTOBRACKETS, AES_CONSOLECARET, AES_INDENTSEL, AES_LINESELECT

  Notifications:
    AEN_SETFOCUS, AEN_KILLFOCUS, AEN_TEXTCHANGE, AEN_POSCHANGE,
    AEN_MODECHANGE, AEN_OUTOFMEMORY, AEN_MARGINDBLCLK


%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%
%  Messages reference                                                       %
%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%&%

  WM_COPY
  WM_CUT
  WM_PASTE
  WM_CLEAR
  WM_SETTEXT
  WM_GETTEXTLENGTH
  WM_GETTEXT
  WM_SETFONT
  WM_GETFONT
  WM_UNDO / EM_UNDO
  EM_CANUNDO
  EM_EMPTYUNDOBUFFER
  EM_REPLACESEL

  Parameters:
    As for standard messages of those names.

  Return:
    As for standard messages of those names.

-----------------------------------------------------------------------------

  AEM_SETMODE

  Parameters:
    wparam = new mode value
    lparam = ignored, should be zero

  Return:
    Always returns zero.

  Remarks:
    Mode value can be zero or any combination of the following constants:
      AEMODE_OVERWRITE   - overwrite mode
      AEMODE_VERTICALSEL - vertical selection mode

-----------------------------------------------------------------------------

  AEM_GETMODE

  Parameters:
    wparam = ignored, should be zero
    lparam = ignored, should be zero

  Return:
    Current mode value.

-----------------------------------------------------------------------------

  AEM_SETSYNTAXHIGHLIGHT

  Parameters:
    wparam = pointer to table of syntax colors
    lparam = pointer to syntax highlight procedure or 0

  Return:
    Always returns zero.

  Remarks:
    Syntax procedure is SyntaxProc(lpLine,lpColors), both parameters are
    pointers to buffer of length 256. First is the pointer to the data of
    line that has to be syntax highlighted (it is padded with spaces to the
    maximum length), second is the pointer to colors for the each character
    in line, initially filled with zeros. Each color value occupies one byte
    and is index to the table of syntax colors (each field in that table is
    the standard 32-bit color value, table is indexed from 1) or zero for
    the unhighlighed color.
    If wparam equals to zero, the table of syntax colors will be as it is.

-----------------------------------------------------------------------------

  AEM_GETLINEDATA

  Parameters:
    wparam = line number
    lparam = pointer to buffer for the line data

  Return:
    Always returns zero.

  Remarks:
    If line number is zero, current line is selected, if it's -1, the last
    line is selected. Buffer should have length of 256 bytes.

-----------------------------------------------------------------------------

  AEM_SETPOS

  Parameters:
    wparam = pointer to AEPOS structure
    lparam = ignored, should be zero

  Return:
    Always returns zero.

  Remarks:
    Fields of AEPOS should be set to the following values:
      caretLine         = number of line in which caret has to be placed,
                          zero means current line, -1 means last line
      caretPosition     = position in line where caret has to be placed,
                          zero means current position, 257 is the maximum
      selectionLine     = number of line where the selection has to begin,
                          zero means current line, -1 means last line
                          the end of selection is marked by caret position
      selectionPosition = position in line where selection has to begin,
                          zero means current position, 257 is the maximum

-----------------------------------------------------------------------------

  AEM_GETPOS

  Parameters:
    wparam = pointer to AEPOS structure
    lparam = ignored, should be zero

  Return:
    Always returns zero.

  Remarks:
    Fields of AEPOS are filled with the following information:
      caretLine         = number of line in which caret is placed
      caretPosition     = position in line where caret is placed
      selectionLine     = number of line where the selection begins
      selectionPosition = position in line where selection begins

-----------------------------------------------------------------------------

  AEM_FINDFIRST

  Parameters:
    wparam = search flags
    lparam = pointer to string to search for

  Return:
    TRUE if string was found, FALSE otherwise.

  Remarks:
    Flags can be zero or any combination of the following values:
      AEFIND_CASESENSITIVE - case sensitive search
      AEFIND_WHOLEWORDS    - accept whole words only
      AEFIND_BACKWARD      - search backward from current position

-----------------------------------------------------------------------------

  AEM_FINDNEXT

  Parameters:
    wparam = ignored, should be zero
    lparam = ignored, should be zero

  Return:
    TRUE if string was found, FALSE otherwise.

  Remarks:
    AEM_FINDFIRST has to be called first.

-----------------------------------------------------------------------------

  AEM_CANFINDNEXT

  Parameters:
    wparam = ignored, should be zero
    lparam = ignored, should be zero

  Return:
    TRUE if there is some search to be completed, FALSE otherwise.

-----------------------------------------------------------------------------

  AEM_GETWORDATCARET

  Parameters:
    word [wparam] = size of buffer
    word [wparam+2] = flag -> TRUE -> point is not in word.
                              FALSE ->point is in the word.
    lparam = pointer to buffer

  Return:
    Always returns zero.

  Remarks:
    The buffer is filled with the string containing word in which the caret
    is placed.

-----------------------------------------------------------------------------

  AEM_SETTEXTCOLOR

  Parameters:
    wparam = color for text
    lparam = color for text background

  Return:
    Always returns zero.

-----------------------------------------------------------------------------

  AEM_SETSELCOLOR

  Parameters:
    wparam = color for selected text
    lparam = color for selected background

  Return:
    Always returns zero.

-----------------------------------------------------------------------------

  AEM_SETPOPUPMENU

  Parameters:
    wparam = ignored, should be zero
    lparam = handle of popup menu

  Return:
    Always returns zero.

-----------------------------------------------------------------------------

  AEM_SETMARGINCOLOR

  Parameters:
    wparam = color for margin background
    lparam = color for margin border

  Return:
    Always returns zero.

-----------------------------------------------------------------------------

  AEM_SETMARGINWIDTH

  Parameters:
    wparam = gap between border and text
    lparam = width of margin

  Return:
    Always returns zero.

-----------------------------------------------------------------------------

  AEM_SETTHEME

  Parameters:
    wparam = ignored, should be zero
    lparam = pointer to AETHEME structure

  Return:
    Always returns zero.

  Remarks:
    Fields of AETHEME should be set to the following values:
      .text_color          = window text
      .text_background     = window background
      .sel_text            = selected text
      .sel_background      = background of the selected text
      .margin_background   = background of the margin
      .margin_border       = border of the margin
      .margin_width        = width of margin
      .margin_gap          = width of gap between margin border and text
      .bookmark            = bookmark color
      .syntax_proc         = pointer to syntax highlight procedure or 0
      .syntax_colors       = colors used in the syntax procedure
                             (can be zero or more dword values)

-----------------------------------------------------------------------------
  AEM_SETBOOKMARKICON

  Parameters:
    wparam = handle of icon
    lparam = ignored

-----------------------------------------------------------------------------

  AEM_TOGGLEBOOKMARK

  Parameters:
    wparam = ignored, should be zero
    lparam = ignored, should be zero

  Return:
    Returns the id of the newly created bookmark.

-----------------------------------------------------------------------------

  AEM_GOTOBOOKMARK

  Parameters:
    wparam = zero (or id of bookmark if lparam = AEBM_NUM)
    lparam = bookmark constant: AEBM_NEXT, AEBM_PREV or AEBM_NUM

  Return:
    Returns the line number of the target bookmark.

-----------------------------------------------------------------------------

  AEM_CLEARBOOKMARKS

  Parameters:
    wparam = ignored, should be zero
    lparam = ignored, should be zero

  Return:
    Always returns zero.

-----------------------------------------------------------------------------

  AEM_COMMENT

  Parameters:
    wparam = ignored, should be zero
    lparam = comment (= true) or uncomment (= false)

  Return:
    Always returns zero.

-----------------------------------------------------------------------------

  AEM_INDENT

  Parameters:
    wparam = ignored, should be zero
    lparam = indent (= true) or outdent (= false)

  Return:
    Always returns zero.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/Doc/fas.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405

                                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 (in current versions always 56).    |
  |--------|---------|------------------------------------------------------|
  |   +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.                       |
  \-------------------------------------------------------------------------/

  Notes:

    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.


   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 symbol (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.                              |
  \-----------------------------------------------------------------/

  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 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.


   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      |
  |-------|----------|
  | 0F4h  | EIP      |
  |-------|----------|
  | 0F8h  | 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.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/Doc/fasmguide.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601

	     The official guide to flat assembler internals


Table of contents
-----------------


Chapter 1  Introduction

	1.1  Source structure
	1.2  Memory organization
	1.3  Core modules

Chapter 2  Interface

	2.1  Interface files
	2.2  Memory allocation
	2.3  Program parameters
	2.4  File operations
	2.5  Environment variables
	2.6  Timestamp
	2.7  Error handling
	2.8  Displaying messages

Chapter 3  Preprocessor

	3.1  Initial state of preprocessor
	3.2  Main preprocessor routine
	3.3  Preprocessing file
	3.4  Tables used by preprocessor
        3.5  Preprocessing line
        3.6  Preprocessing directive handlers



Chapter 1  Introduction
-----------------------

This guide is intended mainly to help all the people that want to make some
modifications into flat assembler source, port it to another operating system,
or add some features. But it may also become helpful for the people who want
to write their own assembler or compiler and want to see how was it done in
this case. The reader is expected to know assembly language enough to read
some small piece of assembly code and understand what it does.
  Altough there are almost no comments inside the source of flat assembler,
the detailed labels are usually enough to navigate through this source,
because in most cases they explain what exactly does the piece of code that is
following them. These names will be our navigational points in the source, so
it's better not to change them if you want to use this guide.


1.1  Source structure

In the SOURCE directory you can find many files with .INC extension an a few
subdirectories. Files in the root of SOURCE directory form the "core" of FASM
and are OS-independent, so they are common for all versions of the program.
Core is written in the way which allows to compile it in both 16-bit or 32-bit
mode, but it always uses the 32-bit addressing and therefore it needs a flat
memory space to be provided.
  Each subdirectory contains the files dedicated to one operating system.
This is the "interface" of FASM. It mediates between the core and the OS,
prepares the memory and files for the core and displays the messages during
and after the assembly.


1.2  Memory organization

FASM uses two continuous block of memory for all its operations, we will call
them the main and additional memory block. The first version of FASM was
designed for DOS and it was allocating the free extended memory as a main
memory block and the free conventional memory as a additional memory block.
  Other versions allocate one big memory block and divide it into two parts,
with main memory block seven times bigger than additional memory block.
This proportion could be changed, but the additional block doesn't need to be
as large as the main block.
  Core uses both those block from the bottom and from the top. When the
highest used address from the bottom meets the lowest used address from the
top in the same block, core calls the error handler in the interface with
the "out of memory" message. The data structures that are contained inside
those blocks will be described in later chapters.


1.3  Core modules

The core of FASM consists of four modules: preprocessor, parser, assembler,
and formatter. They should be called by interface exactly in this order after
the memory blocks are allocated and the names of source and output files are
prepared. When an error occurs during the execution of one of these modules,
the OS-dependent error handler in the interface is called to display the
appropriate message and terminate the program. If everything is successful,
interface displays the summary message and exits.
  The first module in order is preprocessor. It loads all the source files
into main memory block, interpretes its sets of directives and processes the
macroinstructions and symbolic constants. It also separates the words and
special characters in the lines and removes the spaces that were between them.
When it's finished with all the loaded files, the source is ready to be
processed by parser.
  The parser module converts the source into FASM's internal code, all
assembly language keywords are replaced with short codes, also each labels
is replaced with it's unique identificator.
  The assembler module intepretes the code generated by parser to generate
the output code. It may take many passes the correctly resolve all the values,
but these passes are quite fast, because all the most time consuming tasks
related to string comparisions are already done by parser. When the assembler
finishes its job, the formatter creates the output file in the selected format
and fills it with the generated code.


Chapter 2  Interface
--------------------

This chapter describes all the functionality OS-dependent interface needs to
provide and should be the most helpful for the ones wanting to port FASM to
some operating system other than those for which interfaces already exist.
The following information applies to each version of the interface, unless it
is said otherwise.


2.1  Interface files

Each interface subdirectory contains FASM.ASM file, which is the main file
that has to be assembled into the final executable. All other source files
are referred by this one using the INCLUDE directive.
  The main file should contain all the structures needed to create valid
executable for the appropriate operating system. The main routine of program
should allocate needed memory blocks, interprete the program arguments and
then call the core modules. After finishing the assembly process it usually
also displays some message about generated code before exiting. The files
containing core are included right after this code.
  The main file should also contain declarations for all the uninitialized
data variables that core is using. These declarations should be copied
exactly in the form they occur in the main file of each interface. They
should be put into executable structure in such way that they won't take any
space in the executable file.
  Other files in the interface subdirectories (usually it's the SYSTEM.INC
file) contain the OS-specific procedures that can be used both by the
interface or core. The procedures that have to be called by core should
stricly follow the rules that will be described later, because the core will
expect them to behave in the same way no matter on what OS it is running.
Other procedures can be specific to interface as they will be called only by
files designed for the chosen operating system.


2.2  Memory allocation

As it was said in previous chapter, FASM needs two continuous blocks of
memory. Interface usually contains the "init_memory" routine, which is called
just after the start of program. This routine allocates the needed memory and
fills the [memory_start] and [memory_end] variables with pointers to the first
byte of main memory block and to the first byte after the main memory block.
In the same way it fills the [additional_memory] and [additional_memory_end]
variables with the pointer for start and end of the additional memory block.
  If program needs to free the allocated memory before exiting, it should do
it in the "exit_program" routine which is called by interface after displaying
the final messages. This routine restores all the system resources that need
to be restored and exits the program. It has one argument, provided in AL
register, which is the exit code that should be passed to OS. If OS accepts
exit code larger than the byte, the value of AL should be zero-extended to fit
the needed size. When this routine is called after the successful assembly,
the exit code is set to 0.


2.3  Program parameters

At the beginning interface calls also its own routine called "get_params".
This procedure converts the command line arguments into separated zero-ended
string. If OS already does it for program, no such routine is needed. When
parameters are ready, interface checks whether there are valid parameters
and fills the [input_file] and [output_file] variables with the pointers to
first and second parameter. If there is no second parameter specified,
[output_file] variable should be set to zero. If there is no parameters or
there are too many of them, interface jumps to "information" routine, which
displays the information about program usage and exits by jumping to the
"exit_program" routine with the exit code set to 1.


2.4  File operations

The most important group of routines that is used by core are the file
operations. "open" and "create" routines need a pointer to zero-ended file
name to be provided in EDX (both slashed and backslashed should be interpreted
as a path separators; if system does not support some of them, the conversion
of path must be done first). The first one opens the file for reading, the
second one creates the file for writing. Both set the CF to 0 and return the
file handle in EBX when the operation is succesful, otherwise CF is set 1.
These functions should not modify the ESI, EDI and EBP registers.
  "read" routine reads the bytes of count given in ECX from the file handle
given in EBX into the buffer pointed by EDX. "write" writes the bytes of count
given in ECX from the memory pointed by EDX into handle given in EBX. Both
these functions clear CF if operation is succesful or set it otherwise. These
functions should leave the EBX, ECX, EDX, ESI, EDI and EBP unmodified.
  "close" closes the handle given in EBX, it should keep the ESI, EDI and EBP
unchanged.
  "lseek" moves the current position in file of handle given in EBX, EDX
contains the amount of bytes by which the position should be moved and AL
contains the identifier of the origin for the move (0 means the beginning of
file, 1 means current position, 2 means the end of file). It should return the
new position from the beginning of file in EAX and leave the EBX, ESI, EDI and
EBP unchanged.


2.5  Environment variables

The "get_environment_variable" function should search the system environment
for the variable of zero-ended name pointer by ESI and store its value in
the buffer pointer to by EDI. The buffer is limited only by the top of the
main memory block, that is by [memory_end] variable. The function should
return the EDI pointing to the first byte after the last one filled with
value of environment variable, if no variable of given name was found, the
empty value should be used, that is EDI should be left unchanged.


2.6  Timestamp

The "make_timestamp" routine should return the valid timestamp in the EAX.
This value should contain current system time converted to the number of
seconds since the 1-1-1970 00:00:00 (some operating systems already use the
timestamp format for the system time, so the conversion is not needed there).
This procedure is used by formatter.


2.7  Error handling

There are two procedures in the interface that are called in case of the error
during the compilation. They should display the appropriate message and then
exit by calling the "exit_program" with appropriate exit code. The pointer to
the zero-ended string describing the error that occured is stored on the stack
(pointed by ESP), because each such string follows the CALL instruction which
executes the error handler in interface. So the address stored on stack will
be the word value if executable uses 16-bit code or double word value if
executable uses 32-bit code.
  The "fatal_error" routine is called when some error occurs that is not
related to any particular line of source. This handler should just display
the message of address stored on the stack and then call the "exit_program"
with the exit code 255. All the error messages are provided as the zero-ended
byte strings.
  The "assembler_error" routine is called when error that occured is related
to the line of source that was currently processed. This handler not only
displays the message from address on the stack, but also displays detailed
information about the line in which an error occured. To understand how it
works, the knowledge about the preprocessed source format is needed, and it
will be described in next chapter. But usually it should be enough to copy
the standard handler that is used in the same form by Win32 and Linux version
and should be OS-independent if only executable uses 32-bit code and all
needed interface routines are provided. It uses some of the routines for the
file operations that were already described, and also some displaying routines
that are described below. After displaying all messages this handler jumps
to the "exit_program" routine with the exit code 2.


2.8  Displaying messages

Interface contains a few routines for displaying messages, but only one is
needed and used by core, it's "display_block" procedure, which is called by
assembler to display the user messages from source. The address of data
that should be displayed is provided in ESI, ECX contains the amount of bytes
to display. Core doesn't need any register to be preserved by this routine,
but because it is also used by standard error handler, it should leave EBX
register unmodified for it.
  All other display routines are used by the standard error handler and should
preserve the EBX register. "display_string" displays the zero-ended string
pointed by ESI, "display_character" displays the single character from DL,
"display_number" displays the value of EAX as a decimal number.


Chapter 3  Preprocessor
-----------------------

This chapter describes the first of core modules, which is called just after
the interface have completed all its initial tasks. The purpose of this module
is to load the source into memory, separate and enumerate all source lines
and process the special set of directives which we will call the preprocessor
directives. Some of these directive define the symbolic contants and
macroinstruction, and the task of replacing them with appropriate values in
source is also performed by preprocessor. Only one pass is applied to the
whole source at this stage, each line is scanned for directives, symbolic
constants and macroinstructions right after it is separated from the source
file, and all tasks are done on it before reading the next line.


3.1  Initial state of preprocessor

When interface calls the preprocessor module, it is expected to have already
allocated the needed memory blocks, the [memory_start] and [memory_end]
variables should contain the addresses of the beginning and the end of main
memory block, the [additional_memory] and [additional_memory_end] variables
should contain such addresses for the additional memory block. [input_file]
variable should contain the pointer to zero-ended name of source file.


3.2  Main preprocessor routine

All the preprocessing job is done by the routine called "preprocessor".
At startup, it first generates a table of characters that will be used for
both case conversion and detecting special characters in source. The table
consists of the 256 bytes, and each corresponds to the character of value the
same as the index of byte in table. The zero byte in table marks that the
corresponding character is one of the special characters (also called
symbol characters), for the other characters the bytes in table are the
values for them after converting to lower case - this will be used for
case insensitive comparisions.
  Then the value of the INCLUDE environment variable is received through the 
interface and stored it in the beginning of main memory block, and the 
[memory_start] variable is updated to point to the first free byte after
this value. This new starting point of main memory block is then used as an
origin of buffer where the preprocessed code will be stored. During the
preprocessing the pointer to the place in this buffer where the data of
preprocessed line will be stored is kept in EDI register, initially it is
equal to the [memory_start] variable. To do the actual preprocessing,
"preprocess_file" routine is called, it needs an EDI to point to the current
position in main memory block where the lines have to be stored, ESI to point
to the name of source file and EBX to contain handle of this file already
opened for reading. It returns control to main routine after preprocessing all
lines from that file, the EDI register is updated to point to the first free
byte after the last preprocessed line.This value is later used by parser module
as a pointer to the place where the parsed source will be stored, for this
purpose it is stored in [source_start] variable.


3.3  Preprocessing file

The "preprocess_file" routine uses the file handle stored in EBX register to
load the contents of at the end of main memory block and then it closes the
handle. The [memory_end] variable is updated to point to the first byte of
loaded source, because during the preprocessing it should be always a valid
pointer to the end of free memory - after the preprocessing of file is done,
the [memory_end] is restored to the previous value. The data loaded from file
is followed by one additional byte, which is the ASCII end of file marker
(value 1Ah). This byte is recognized by preprocessor as the place where it
should end preprocessing the file, if such byte is encountered before the
actual end of file, the rest of file will not be preprocessed at all.
  After reading the source comes the "preprocess_source" loop. While in this
loop, the ESI register points to the source that has yet to be preprocessed,
EDI points to the place where the next preprocessed line will be stored,
ECX contains line counter, EBX points to the beginning of loaded file that
is currently preprocessed (when entering the loop, it is the same as ESI) and
EDX points to the name of this file. The values of EBX, ECX and EDX are
needed only for the purpose of building the header of each preprocessed line.
This header is 16 bytes long and consists of four double word values, in the
table 3.1 you can see its layout.


   Table 3.1  Header of preprocessed line loaded from source
  /-------------------------------------------------------------------------\
  | Offset | Value							    |
  |========|================================================================|
  |   +0   | pointer to the name of file, from which the line was loaded    |
  |--------|----------------------------------------------------------------|
  |   +4   | line number in bits 0-30, the highest bit zeroed		    |
  |--------|----------------------------------------------------------------|
  |   +8   | offset of line inside the file				    |
  |--------|----------------------------------------------------------------|
  |  +12   | reserved, set to zero					    |
  \-------------------------------------------------------------------------/


  After making the header for line, the "convert_line" routine is called,
which processes one line from source (all bytes from where the ESI points up
to the line break or EOF character) and converts it into data portions that
follow the line header. They are line elements of different types, followed
by single zero byte, which marks the end of preprocessed line (the header of
next line will follow this byte immediately).
  Any chain of characters that have no special meaning, separated from other
similar chains with spaces or some other special characters, is converted
into symbol element. 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 line elements. These
characters are defined by the "symbol_characters" list, first byte of this
data structure is the count of characters that follow. Some of those
characters do not become a line element, but have some special meaning for
preprocessor: spaces and tabs are stripped, line breaks are converted into
zero byte that ends the chain of line elements, semicolon is stripped with all
the bytes that follow it up to the end of line and backslash causes the
following line break to be ignored. All other characters from that list
are converted into symbol characters, which are line elements consisting of
only one byte each, with the value the same as original character.
For example, if source contains this line of text:

    mov ax,4

preprocessor will convert 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 last type of element 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'

will be 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 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 should
be ignored by later modules. Such symbol cannot occur in the data created by
"convert_line" routine, but after "convert_line" has done it's job inside the
"preprocess_source" loop, the "preprocess_line" routine is called, and the
purpose of this routine is to recognize some special directives and
macroinstructions, and - if they occur in line - interprete them and update
the line data accordingly.
  The "convert_line" routine can modify the ECX register used by
"preprocess_source" loop - this happens in case of lines concatenated with
backslash character, "convert_line" makes one line out of them, but updates the
ECX register accordingly.


3.4  Tables used by preprocessor

There are few data structures that are used by "preprocess_line" procedure when
scanning the already converted line for directives or some user-defined symbols
like symbolic constants or macros. First one is the static table
"preprocessor_directives", followed by the list of symbols that are recognized
as directives. Each entry in this list begins with byte containing the length
of symbol in characters, then this amount of bytes that define the symbol, and
then 16-bit value, which defines and offset relative to the "preprocessor"
label, which points to the routine that handles this directive.
  The second structure is build during the preprocessing and contains the list
of all macroinstructions defined in source. This structure is placed at the
bottom of additional memory block and ends at address stored in the
[free_additional_memory] variable, which points to the first free byte after
the table of macroinstruction. Each entry in this table is 8 bytes long, the
first double word contains the hash of macroinstruction name, the second
double word contains an address to the first character of the name of
macroinstruction. The hash value is made by the "hash_macro" procedure, which
needs ESI to point to the name, CL to contain the length of name and CH to be
zero, except for the lowest bit, which is the flag set in case of the structure
macroinstruction (the one defined with "struc" directive). The "hash_macro"
procedure returns in EAX the value that is then stored as the first double word
of the entry in table of macroinstructions - it contains the length of name in
bits 0 to 7, structure flag in bit 8 and the 22-bit hash created with FNV-1a
algorithm in the bits 10 to 31 (bit 9 is reserved, possibly for another flag).
This information is enough to recognize and apply the macroinstruction, because
the name pointed by the second doulbe word of entry in the table is the one
inside the line which defined that macroinstruction, so it is followed by the
next elements of line, in particular by the whole definition (possibly spanning
multiple lines).
  The third structure is stored at the top of additional memory blocks and
is the table of symbolic constants. Each entry in this table is 16 bytes long,
first double word contains the hash of constant name, second the address of
constant name, third the length of the value of constant in bytes, and fourth
is the pointer to the value of constant (as this value is inside the already
preprocessed line, it is composed of line elements). The hash value is made
by the "hash_constant" routine, called with EBX pointing to the name of
constant, CL containing the length of name and CH zeroed except for the lowest
bit, which is the flag set in the case of prioritized constant (the one defined
with "fix" directive). It returns in EAX value to be stored as the first double
word of the entry in table, the structure of this value is very similar to the
one used for macroinstructions - it contains the length of name in the lowest
8 bits, the FNV-1a hash in the highest 22 bits and the priority flag in bit 8.
  The table of symbolic constants is pointed to by the [labels_list] variable,
and this address is moved down while the new entries are added to the table.
To summarize: at the beginning of additional memory block (the address stored
in [additional_memory] variable) starts the table of macroinstructions and
ends at the [free_additional_memory] address, free memory follows and ends at
the [labels_list] address, the table of symbolic constants follows and ends at
the [additional_memory_end] address.


3.5  Preprocessing line

The "preprocess_line" procedure is called after the source line has been
already completely converted into format described earlier. It has to preserve
the ECX and ESI registers for the "preprocess_source" loop, and it should
keep the EDI register pointing to the first byte after the data of preprocessed
line. When entering "preprocess_line", the EDI register already points to the
first byte after the end of line data created by "convert_line" and if no more
preprocessing is done on this line, the EDI should be left unchanged. However
"preprocess_line" might alter some of the data portions inside the line and
the length of data might change - in such case EDI needs to be updated.
  The pointer to the line that needs to be preprocessed is stored in the
[current_line] variable, the "preprocess_line" checks whether this line
contains some data that needs to be further preprocessed, and in such case
performs the appropriate tasks and updates the line with the changed data.
These tasks include interpretation of preprocessor directives and expanding the
macroinstructions and symbolic constants. If some directive is detected,
preprocessor jumps to the handler of such directive. Each directive handler
ends with the jump to the "line_preprocessed" label and the EDI should contain
a valid pointer to the first byte after the preprocessed line when performing
this jump.
  The first check that is done by "preprocess_line" is the check for definition
of prioritized constants - to detect such definition preprocessor checks
whether the first two data portions are symbols, and whether the second symbol
is the word "fix". If such situation is detected, preprocessor jumps to the
"define_fix_constant" handler. Otherwise it calls the "process_fix_constants"
routine, which checks the line for occurences of prioritized symbolic constants
and if any are found, it replaces them with their values.
  In case when the line that is preprocessed is not line converted directly
from source, but the line generated by macroinstruction, the prioritized 
constants and their definitions are not detected and processed in such line
(since they were already processed in the original source line that generated
this new one). Instead, it calls the "process_macro_operators" routine, which
does some processing specific to lines generated by macroinstruction - it will
be explained in details later.
  After this initial processing is finished, the main check for directives and 
macroinstructions comes. If the first element of line is the symbol, preprocessor
checks whether is it a directive with the "get_symbol" routine. This procedure 
needs ESI to point to the data of symbol, ECX to contain the length of symbol 
and EDI to point to the table of symbols that have to be recognized. Each entry 
in that table begins with one byte containing the length of symbol, then this 
amount of bytes containing the symbol itself and then one 16-bit word containing 
identifier of the symbol. In case of directives the identifier is the address of
directive handler relative to the beginning of preprocessor module. If symbol
is found in the table, the "get_symbol" clears the carry flag and returns the
found identifier in AX. Also it leaves the ESI pointing to the first byte after
the symbol data (in this case - to the next element of line). Otherwise it sets
the carry flag and leaves the ESI and ECX unchanged.
  When the symbol is recognized as directive, its first byte is replaced with
the value 3Bh, what causes the rest of given line to be ignored by the parser.
Then preprocessor jumps to the directive handler with ESI pointing to the first
line element after the directive symbol.
  When symbol is not a directive, the further checking is done - this time to
detect, whether this symbol has been defined as macroinstruction. This one is
performed by calling the "get_macro" procedure. It needs CL to contain the
length of symbol, ESI to point to the symbol data and CH to contain the
structure flag - when CH is set to 1, it searches for the structure macro of
given name, otherwise it searches for the standard macro of such name. In this
case the CH is zeroed, since the first symbol in line can only be a standard
macroinstruction. The "get_macro" sets the carry flag when no macroinstruction
of given name exists, otherwise it clears the carry and returns in EBX the
pointer to found entry in table of macroinstructions. If the symbol is
recognized as macroinstruction, preprocessor replaces its first byte with the
value 3Bh and jumps to the "use_macro" handler.
  If the given symbol is not a macroinstruction, the next element of line is
checked. If it is the colon character, the symbol is treated as label (which
will be processed later by the parser module). In such case both the label
symbol and the colon character are skipped and the checking described above is
done again, this time starting from the line element following the colon.
Preprocessor treats it as a new starting point of the line and will not return
to the skipped part, therefore when skipping the label symbol, it checks it
for the event of being a symbolic constant, and in such case replaces the
label symbol with the value of constant, shifting the rest of line (and the
new starting point for line preprocessing) if necessary - the whole task of
skipping the label symbol is done by the subroutine starting at
"preprocess_label" label.
  If the first element of line is a symbol, but is not recognized by any of the
checks mentioned above, preprocessor goes to the second element. When it is
also a symbol, it is first checked to be the symbolic constant definition
directive. In such case it jumps to the "define_equ_constant" handler,
otherwise it uses the "get_macro" procedure again, this time with CH set to 1
in order to find out whether the structure macroinstruction of given name
exists. If none is found, it jumps to the "not_preprocessor_symbol" label -
what means that the line contains instructions that will go through the parsing
process - and finally calls the "process_equ_constants" procedure. This routine
needs ESI to point to the first element of line which has to be processed and
EDI to the first byte after the end of line, it replaces all the symbolic
constans in the line with their values and updates the EDI accordingly if the
length of line has changed because of this operation.
  In case, when the structure macroinstruction is encountered, preprocessor
changes the line data to make the first element of line be parsed as a label
and the rest of line to be ignored by parser. When the first element is not
a symbolic constant, it's enough to put the colon character in the place of
first byte of the second symbol and then the 3Bh byte and the length of
second symbol shortened by one. The symbol containing name of structure
macroinstruction is destroyed this way, but it doesn't matter, since it had
been recognized by preprocessor already, and parser will not do anything more
than skip it, which will work correctly even in case of zero-length symbol
(what can happen when the macroinstruction name was one character long).
In case, when the first symbol is a symbolic constant, there is no need to
modify the second symbol, since the rest of line data has to be shifted
anyway. So the preprocessor shifts all the line elements starting from the
second symbol by the appropriate amount, so the value of symbolic constant,
the colon character and the zero-length symbol starting with 3Bh byte all will
fit just before the rest of line data. When the line is ready, preprocessor
jumps to the "use_macro" handler, with the [struc_name] variable containing
the pointer to the structure label (the first element of line).


3.6  Preprocessing directive handlers

  As it was stated in previous section, when preprocessor recognizes the first
element of line to be the directive, it marks such symbol by replacing the
initial byte with value 3Bh and then jumps to the handler of recognized
directive. The ESI points to the first element of line following the directive
symbol, the EDI points to the first byte after the line data, what also means
the first byte after the already prepared source. The directive handler may
add even the whole new lines there and update the EDI. After peforming all
its task, the handler should jump to the "line_preprocessed" label, with the
correct pointer in EDI register.
  The "include_file" handler performs the inclusion of additional source
files. After finding the file specified by the directive parameters, it
calls the "preprocess_file" routine (since handler itself is executed by the
subroutine called from the "preprocess_file" procedure, this is a recursion
process, limited in depth only by the available stack space) to make the
source lines out of it and place them in the area pointed to by EDI register.

[...]
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/Doc/namespace.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
;--------------------------------------------------------------------
; This file describe a possible syntax changes to the FASM compiler
; allowing using of more levels of labels.
;--------------------------------------------------------------------

GlobalName:

.level11:          ; Defines "GlobalName.level11" label.

>> .localname:     ; adds the label name to the current global label.
                   ; i.e. if the current global label becomes:
                   ; "GlobalName.localname". Also defines this label.

   .level21:       ; Defines: "GlobalName.localname.level21"
   .level22:       ; Defines: "GlobalName.localname.level22"

<<                 ; removes one level from the current global label
                   ; if possible. If not possible - error??? or ignore???
                   ; In present case, global label becomes: "GlobalName".

.level12:          ; Defines "GlobalName.level12" label.

@global            ; Returns the current global name.

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































Deleted source/Doc/tables.txt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

A few tables for the chapters that don't exist yet:


   Table 3.2  Header of preprocessed line generated by macroinstruction
  /-------------------------------------------------------------------------\
  | Offset | Value							    |
  |========|================================================================|
  |   +0   | pointer to the name symbol of macro which generated this line  |
  |--------|----------------------------------------------------------------|
  |   +4   | line number in bits 0-30, the highest bit set		    |
  |--------|----------------------------------------------------------------|
  |   +8   | pointer to the line which invoked the macro		    |
  |--------|----------------------------------------------------------------|
  |  +12   | pointer to the line in macro from which this one was generated |
  \-------------------------------------------------------------------------/


   Table 5.1  Symbol structure
  /-------------------------------------------------------------------------\
  | Offset | Size  | Description					    |
  |========|=======|========================================================|
  |   +0   | qword | value of symbol 					    |
  |--------|-------|--------------------------------------------------------|
  |   +8   | word  | flags (table 5.2)					    |
  |--------|-------|--------------------------------------------------------|
  |  +10   | byte  | size of data labelled by this symbol		    |
  |--------|-------|--------------------------------------------------------|
  |  +11   | byte  | type of symbol (table 5.3)				    |
  |--------|-------|--------------------------------------------------------|
  |  +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 | address of object section or external symbol to which  |
  |	   |	   | this symbol is relative (only for relocatable symbols) |
  \-------------------------------------------------------------------------/


   Table 5.2  Symbol flags
  /----------------------------------------------------------------\
  | Bit | Value | Description					   |
  |=====|=======|==================================================|
  |  0  |     1 | symbol was defined				   |
  |-----|-------|--------------------------------------------------|
  |  1  |     2 | symbol can be redefined			   |
  |-----|-------|--------------------------------------------------|
  |  2  |     4 | symbol was redefined				   |
  |-----|-------|--------------------------------------------------|
  |  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			   |
  \----------------------------------------------------------------/


   Table 5.3  Symbol 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 section where it was calculated,  |
  |	  | it should not occur in the symbol structure)	      |
  |-------|-----------------------------------------------------------|
  |   4   | relocatable 64-bit address                                |
  \-------------------------------------------------------------------/
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































Deleted source/EDITOptions.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
;<ff
Window frmEditorOptions, 3, 0, 'TForm', 'Editor options', $6480000, $10001, 0, 212, 183, 480, 320, EditorOptionsProc;
Window NONE, 0, 1, 'SysListView32', 'ListView', $5081208C, $0, 1000, 0, 0, 100, 293, 0;
Window NONE, 1, 3, 'TForm', 'Form', $50810000, $10100, 1001, 100, 0, 372, 40, ThemesPanelWinProc;
Window NONE, 0, 0, 'STATIC', 'T&hemes:', $50000202, $0, 0, 4, 8, 40, 21, 0;
Window NONE, 0, 0, 'BUTTON', '&Save', $50018000, $0, 103, 278, 8, 40, 21, 0;
Window NONE, 0, 0, 'BUTTON', '&Load', $50018000, $0, 102, 322, 8, 40, 21, 0;
Window NONE, 2, 0, 'COMBOBOX', '', $50010002, $10000, 101, 48, 8, 224, 150, 0;
Window NONE, 3, 4, 'TForm', 'Form', $50810000, $10100, 0, 100, 253, 372, 40, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50010001, $0, 1, 224, 8, 64, 25, 0;
Window NONE, 2, 0, 'BUTTON', 'Cancel', $50010000, $0, 2, 296, 8, 64, 25, 0;
;ff>

winmessage OM_UPDATEDIALOG
winmessage OM_THEMECHANGED


struct TEditorSettings
  .ptrFontName  dd  ?
  .FontSize     dd  ?
  .FontCharset  dd  ?
  .AsmEditStyle dd  ?
  .ptrTheme     dd  ?
  .size         dd  ?
ends

virtual at 0
  aeTheme AETHEME 0,0,0,0,0,0,1,0,0,0,0
  sizeof.aeTheme = $
end virtual

iglobal
  property propTempSettings, 'TempSettings'
  cDefaultThemesDirectory text '%Fresh%/IDE/themes/'
endg

cThemeSize = sizeof.TEditorSettings + sizeof.aeTheme + SyntaxColorCount*4 + $100


proc OnEditorOptions, .wparam, .lparam
begin
        stdcall CreateForm, frmEditorOptions, [hApplication]
        test    ebx, ebx
        jz      .finish

        stdcall ShowModal, ebx, MSF_CENTER
        invoke  DestroyWindow, ebx

.finish:
        return
endp



;---------------------------------------------------------

winproc EditorOptionsProc

.lvi LVITEM

begin

ondefault
        stc
        return

onmessage OM_THEMECHANGED
        invoke  GetDlgItem, [.hwnd], 1000
        mov     ebx, eax
        lea     edi, [.lvi]

        invoke  SendMessageA, ebx, LVM_GETITEMCOUNT, 0, 0
        dec     eax
        mov     [edi+LVITEM.iItem], eax

        mov     [edi+LVITEM.mask], LVIF_PARAM
        mov     [edi+LVITEM.iSubItem], 0

.itemsave:
        invoke  SendMessageA, ebx, LVM_GETITEM, 0, edi
        invoke  SendMessageA, [edi+LVITEM.lParam], OM_UPDATEDIALOG, 0, 0
        dec     [edi+LVITEM.iItem]
        jns     .itemsave
        clc
        return


onmessage WM_NOTIFY
        cmp     [.wparam], 1000
        jne     .ondefault

        mov     esi, [.lparam]
        cmp     [esi+NMHDR.code], LVN_ITEMCHANGED
        jne     .ondefault

        test    [esi+NMLISTVIEW.uChanged], LVIF_STATE
        jz      .ondefault

        mov     eax, [esi+NMLISTVIEW.uNewState]
        xor     eax, [esi+NMLISTVIEW.uOldState]
        test    eax, LVIS_FOCUSED
        jz      .ondefault

        mov     ecx, SW_SHOWNORMAL
        test    [esi+NMLISTVIEW.uNewState], LVIS_FOCUSED
        jnz     @f
        mov     ecx, SW_HIDE
@@:

; show window
        invoke  ShowWindow, [esi+NMLISTVIEW.lParam], ecx
        stdcall AlignChildren, [.hwnd]

        clc
        return



onmessage WM_COMMAND

        cmp     word [.wparam], MR_OK
        jne     .ondefault

        invoke  GetPropA, [.hwnd], [propTempSettings]
        stdcall ThemeDuplicate, eax

        xchg    [CurrentSettings], eax
        stdcall DestroySettings, eax

        stdcall EnumOpenFiles, ApplyCurrentTheme, NULL

        stc
        return


onmessage WM_DESTROY
        invoke  GetPropA, [.hwnd], [propTempSettings]
        stdcall DestroySettings, eax
        invoke  RemovePropA, [.hwnd], [propTempSettings]
        stc
        return

onmessage FM_AFTERCREATE
        stdcall ThemeDuplicate, [CurrentSettings]
        invoke  SetPropA, [.hwnd], [propTempSettings], eax
        invoke  SendDlgItemMessageA, [.hwnd], 1001, FM_AFTERCREATE, 0, 0

locals
  .hlv dd ?
endl
        invoke  GetDlgItem, [.hwnd], 1000
        mov     [.hlv], eax

        stdcall ImageList_LoadGif, [hInstance], 283, 32, FALSE
        invoke  SendMessageA, [.hlv], LVM_SETIMAGELIST, LVSIL_NORMAL, eax

        xor     esi, esi
        lea     edi, [.lvi]

        mov     [edi+LVITEM.mask], LVIF_TEXT or LVIF_PARAM or LVIF_IMAGE
        mov     [edi+LVITEM.iSubItem], 0

iglobal
  cEditOptionsApplets dd frmEditorColors, frmEditorBehaviour, 0
endg

.addloop:
        mov     ecx, [4*esi+cEditOptionsApplets]
        jecxz   .endadd

        stdcall CreateForm, ecx, [.hwnd]
        stdcall SetAlign, ebx, waClient

        mov     [edi+LVITEM.lParam], ebx
        stdcall GetControlText, ebx, 0
        push    eax

        stdcall StrPtr, eax
        mov     [edi+LVITEM.pszText], eax
        mov     [edi+LVITEM.iImage], esi

        invoke  SendMessageA, [.hlv], LVM_INSERTITEM, 0, edi

        stdcall StrDel ; from the stack.
        inc     esi
        jmp     .addloop

.endadd:
        invoke  SendMessageA, [.hlv], LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_BORDERSELECT

        stdcall ListViewCenterIcons, [.hlv], 64

        mov     [.lvi.stateMask], TVIS_FOCUSED or TVIS_SELECTED
        mov     [.lvi.state], TVIS_FOCUSED or TVIS_SELECTED
        lea     eax, [.lvi]
        invoke  SendMessageA, [.hlv], LVM_SETITEMSTATE, 0, eax

        clc
        return
endwp




winproc ThemesPanelWinProc
.theme_name dd ?
begin

ondefault
        stc
        return

onmessage WM_COMMAND
        movzx   eax, word [.wparam]

        cmp     eax, 102                  ; Load profile button ID
        je      .loadprofile

        cmp     eax, 103                  ; save profile button ID
        je      .saveprofile

        jmp     .ondefault


.saveprofile:
        invoke  GetParent, [.hwnd]
        invoke  GetPropA, eax, [propTempSettings]
        mov     edi, eax

        invoke  GetDlgItem, [.hwnd], 101  ; profiles combo box
        stdcall GetControlText, eax, NULL
        mov     [.theme_name], eax
        stdcall StrPtr, eax

        stdcall SaveEditorSettings, eax, edi, FALSE
        stdcall StrDel, [.theme_name]
        clc
        return

.loadprofile:
        invoke  GetParent, [.hwnd]
        mov     ebx, eax
        invoke  GetPropA, ebx, [propTempSettings]
        mov     edi, eax

        invoke  GetDlgItem, [.hwnd], 101  ; profiles combo box
        stdcall GetControlText, eax, NULL
        mov     [.theme_name], eax
        stdcall StrPtr, eax
        stdcall LoadEditorSettings, eax
        jc      .errorload

        invoke  SetPropA, ebx, [propTempSettings], eax
        stdcall DestroySettings, edi

        stdcall StrDel, [.theme_name]
        invoke  SendMessageA, ebx, OM_THEMECHANGED, 0, 0
        clc
        return

.errorload:
        stdcall StrDel, [.theme_name]
        test    eax, eax
        jnz     @f
        invoke  GetLastError
@@:
        stdcall ErrorMessage, eax
        clc
        return


onmessage FM_AFTERCREATE

locals
  .fd FINDDATA
endl

cThemesFilter text '%Fresh%/IDE/themes/*.*'

; Fill combobox with saved themes
        invoke  GetDlgItem, [.hwnd], 101
        mov     ebx, eax

        stdcall ConvertPath, cThemesFilter
        push    eax

        stdcall StrPtr, eax
        lea     ecx, [.fd]

        invoke  FindFirstFileA, eax, ecx
        cmp     eax, INVALID_HANDLE_VALUE
        je      .endofsearch

        mov     esi, eax
        stdcall StrDel ; from the stack

.themeloop:
        test    [.fd.dwFileAttributes], FILE_ATTRIBUTE_DIRECTORY
        jnz     .nextfile

        lea     eax, [.fd.cFileName]
        invoke  SendMessageA, ebx, CB_ADDSTRING, 0, eax

.nextfile:
        lea     eax, [.fd]
        invoke  FindNextFileA, esi, eax
        test    eax, eax
        jnz     .themeloop

        invoke  FindClose, esi

.endofsearch:
; select current theme if there is one
        invoke  SendMessageA, ebx, CB_SELECTSTRING, -1, cCurrentEditorSettings

        clc
        return

endwp



;---------------------------------------------------------


; EnumOpenFiles callback...
proc ApplyCurrentTheme, .ptrFile, .dummy
begin
        mov     esi, [.ptrFile]
        cmp     [esi+TOpenFile.hEditor], 0
        je      .exit

        stdcall GetAsmEdit, [esi+TOpenFile.hEditor]
        test    eax, eax
        jz      .exit

        mov     edi, eax
        mov     eax, [esi+TOpenFile.ptrType]

        stdcall ApplySettingsToAsmEdit, edi, [CurrentSettings], [eax+TFileType.lParam]

.exit:
        clc
        return
endp



;------------------------------------------------------------------
; THIS PROCEDURE CAN AND MUST BE USED FOR SETTING PROPERTIES FOR
; ALL ASMEDIT WINDOWS
;------------------------------------------------------------------
proc ApplySettingsToAsmEdit, .hAsmEdit, .ptrSettings, .ptrSyntaxProc
begin
        push    esi ebx

        mov     esi, [.ptrSettings]

; Apply style
        invoke  GetWindowLongA, [.hAsmEdit], GWL_STYLE
        and     eax, $ffffff00
        or      eax, [esi+TEditorSettings.AsmEditStyle]
        invoke  SetWindowLongA, [.hAsmEdit], GWL_STYLE, eax

; Apply font
        invoke  SendMessageA, [.hAsmEdit], WM_GETFONT, 0, 0
        mov     ebx, eax

        invoke  CreateFontA, [esi+TEditorSettings.FontSize], 0, 0, 0, FW_NORMAL,                 \
                            0, 0, 0, [esi+TEditorSettings.FontCharset],                         \
                            OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,           \
                            FIXED_PITCH or FF_DONTCARE, [esi+TEditorSettings.ptrFontName]
        invoke  SendMessageA, [.hAsmEdit], WM_SETFONT, eax, 0
        invoke  DeleteObject, ebx

; Apply colors and syntax highlighter
        invoke  SendMessageA, [.hAsmEdit], AEM_SETTHEME, 0, [esi+TEditorSettings.ptrTheme]
        invoke  SendMessageA, [.hAsmEdit], AEM_SETSYNTAXHIGHLIGHT, 0, [.ptrSyntaxProc]

        pop     ebx esi
        return
endp




;------------------------------------------
; Loads the file with editor settings and
; Returns pointer to its header.
;------------------------------------------
proc LoadEditorSettings, .hThemeName
begin
        stdcall StrDup, cDefaultThemesDirectory
        push    eax ; save for strdel

        stdcall StrCat, eax, [.hThemeName]
        stdcall ConvertPath, eax
        push    eax ; save for strdel

        stdcall StrPtr, eax

        stdcall LoadBinaryFile, eax
        jc      .error

        stdcall ResizeMem, eax, cThemeSize
        test    eax, eax
        jnz     .relocate

.error:
        stdcall StrDel    ; from stack
        stdcall StrDel    ; from stack
        stc
        return

; relocate pointers
.relocate:
        add     [eax+TEditorSettings.ptrFontName], eax
        mov     ecx, [eax+TEditorSettings.ptrTheme]
        add     ecx, eax
        mov     [eax+TEditorSettings.ptrTheme], ecx
        mov     [ecx+aeTheme.syntax_proc], fasm_syntax
        mov     [eax+TEditorSettings.size], cThemeSize
        stdcall StrDel    ; from stack
        stdcall StrDel    ; from stack
        clc
        return
endp


proc SaveEditorSettings, .hThemeName, .ptrTheme, .fOverWrite
begin
        push    ebx esi

        mov     esi, [.ptrTheme]

        stdcall StrDup, cDefaultThemesDirectory
        push    eax ; save for strdel
        stdcall StrCat, eax, [.hThemeName]
        stdcall ConvertPath, eax
        mov     ebx, eax        ; filename
        stdcall StrDel    ; from stack

        stdcall StrPtr, ebx
        stdcall FileExists, eax
        jc      .saveit

        cmp     [.fOverWrite], FALSE
        jne     .saveit

cThemeExists      text   'The theme "'
cThemeExistsEnd   text   '" already exists. Do you want to overwrite it?'
cThemeExistsTitle text   'This theme already exist.'

        stdcall StrDup, cThemeExists
        push    eax
        stdcall StrCat, eax, [.hThemeName]
        stdcall StrCat, eax, cThemeExistsEnd
        stdcall StrPtr, eax
        invoke  MessageBoxA, [hApplication], eax, cThemeExistsTitle, MB_YESNO or MB_ICONQUESTION
        stdcall StrDel ; from stack
        cmp     eax, IDYES
        jne     .finish

.saveit:
        push    [esi+TEditorSettings.ptrFontName]
        push    [esi+TEditorSettings.ptrTheme]

        sub     [esi+TEditorSettings.ptrFontName], esi
        sub     [esi+TEditorSettings.ptrTheme], esi

        stdcall StrPtr, ebx
        stdcall SaveBinaryFile, eax, esi, [esi+TEditorSettings.size]

        pop     [esi+TEditorSettings.ptrTheme]
        pop     [esi+TEditorSettings.ptrFontName]

.finish:
        stdcall StrDel, ebx
        xor     eax, eax
        pop     esi ebx
        return
endp


proc ThemeDuplicate, .ptrTheme
begin
        push    esi edi
        mov     esi, [.ptrTheme]

        push    [esi+TEditorSettings.ptrFontName]
        push    [esi+TEditorSettings.ptrTheme]

        sub     [esi+TEditorSettings.ptrFontName], esi
        sub     [esi+TEditorSettings.ptrTheme], esi

        stdcall GetMem, [esi+TEditorSettings.size]
        mov     edi, eax
        push    eax
        push    esi

        mov     ecx, [esi+TEditorSettings.size]
        shr     ecx, 2

        rep movsd

        pop     esi
        pop     eax

        pop     [esi+TEditorSettings.ptrTheme]
        pop     [esi+TEditorSettings.ptrFontName]

        add     [eax+TEditorSettings.ptrFontName], eax
        add     [eax+TEditorSettings.ptrTheme], eax

        pop     edi esi
        return
endp



proc DestroySettings, .ptrSettings
begin
        stdcall FreeMem, [.ptrSettings]
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/EditPath.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
;<ff
Window frmEditPath, 3, 0, 'TForm', 'Input name and path', $4C80000, $110001, 0, 271, 210, 320, 114, frmEditPathProc;
Window NONE, 0, 0, 'STATIC', '&Alias:', $50000000, $0, 0, 8, 8, 32, 13, 0;
Window NONE, 0, 0, 'EDIT', '', $50010180, $200, 100, 8, 24, 72, 21, 0;
Window NONE, 0, 0, 'STATIC', '&Value:', $50000000, $0, 0, 88, 8, 32, 13, 0;
Window NONE, 0, 0, 'TButtonEdit', '', $50010180, $200, 101, 88, 24, 216, 21, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50000001, $0, 1, 88, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50000000, $0, 2, 160, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50000001, $0, 1, 88, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50000000, $0, 2, 160, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50000001, $0, 1, 88, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50000000, $0, 2, 160, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50000001, $0, 1, 88, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50000000, $0, 2, 160, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50000001, $0, 1, 88, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50000000, $0, 2, 160, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50000001, $0, 1, 88, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50000000, $0, 2, 160, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50000001, $0, 1, 88, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50000000, $0, 2, 160, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50000001, $0, 1, 88, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50000000, $0, 2, 160, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50000001, $0, 1, 88, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50000000, $0, 2, 160, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50000001, $0, 1, 88, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50000000, $0, 2, 160, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50000001, $0, 1, 88, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50000000, $0, 2, 160, 216, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50010001, $0, 1, 80, 56, 64, 25, 0;
Window NONE, 2, 0, 'BUTTON', 'Cancel', $50010000, $0, 2, 152, 56, 64, 25, 0;
;ff>
cIncludeTitle text 'Select include directory:',0

idAliasName = 100
idPathEdit  = 101

proc InputAliasName, .hName, .hValue
begin
        push    esi ebx
        stdcall CreateForm, frmEditPath, [hApplication]

        stdcall StrPtr, [.hName]
        invoke  SendDlgItemMessageA, ebx, idAliasName, WM_SETTEXT, 0, eax
        stdcall StrPtr, [.hValue]
        invoke  SendDlgItemMessageA, ebx, idPathEdit, WM_SETTEXT, 0, eax

        stdcall ShowModal, ebx, MSF_CENTER
        push    eax
        cmp     eax, MR_OK
        jne     .exit

        invoke  SendDlgItemMessageA, ebx, idAliasName, WM_GETTEXTLENGTH, 0, 0
        lea     esi, [eax+1]
        stdcall StrSetCapacity, [.hName], esi
        invoke  SendDlgItemMessageA, ebx, idAliasName, WM_GETTEXT, esi, eax
        stdcall StrFixLen, [.hName]

        invoke  SendDlgItemMessageA, ebx, idPathEdit, WM_GETTEXTLENGTH, 0, 0
        lea     esi, [eax+1]
        stdcall StrSetCapacity, [.hValue], esi
        invoke  SendDlgItemMessageA, ebx, idPathEdit, WM_GETTEXT, esi, eax
        stdcall StrFixLen, [.hValue]

        stdcall RemoveEndSlash, [.hValue]

.exit:
        invoke  DestroyWindow, ebx
        pop     eax
        pop     ebx esi
        return
endp



proc RemoveEndSlash, .hPath
begin
        push    edi ebx
        stdcall StrPtr, [.hPath]
        mov     edi, eax
        stdcall StrLen, [.hPath]
        mov     ebx, eax

        cmp     byte [edi+ebx-1], '\'
        je      .killslash
        cmp     byte [edi+eax-1], '/'
        jne     .pathok                 ; well more checks need, but later...

.killslash:
        mov     byte [edi+eax-1], 0

.pathok:
        pop     ebx edi
        return
endp



winproc frmEditPathProc
.str rb 1024
begin

ondefault
        stc
        return

onmessage BEM_BUTTONCLICK

        lea     edi, [.str]
        invoke  SendDlgItemMessageA, [.hwnd], idPathEdit, WM_GETTEXT, 1024, edi
        stdcall SelectPathDialog, [hApplication], cIncludeTitle, edi
        test    eax,eax
        jz      .quit

        push    eax
        stdcall StrPtr, eax
        invoke  SendDlgItemMessageA, [.hwnd], idPathEdit, WM_SETTEXT, 0, eax
        stdcall StrDel ; From stack

.quit:
        invoke  SetActiveWindow, [.hwnd]
        clc
        return
endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































Deleted source/EditPathsOptions.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
;<ff
Window frmIDEOptions, 3, 0, 'TForm', 'Aliases', $56000000, $10000, 0, 234, 184, 320, 275, IDEOptionsProc;
Window NONE, 0, 5, 'SysListView32', 'ListView', $5001800D, $0, 103, 0, 32, 312, 216, 0;
Window NONE, 3, 3, 'TForm', 'Form', $50800000, $10000, 0, 0, 0, 312, 32, 0;
Window NONE, 0, 0, 'STATIC', 'A&liases:', $50000200, $0, 0, 8, 12, 64, 19, 0;
Window NONE, 0, 0, 'BUTTON', '&Add', $50018000, $0, 100, 96, 8, 64, 19, 0;
Window NONE, 0, 0, 'BUTTON', '&Remove', $50018000, $0, 101, 168, 8, 64, 19, 0;
Window NONE, 2, 0, 'BUTTON', '&Edit', $50018000, $0, 102, 240, 8, 64, 19, 0;
;ff>

winproc IDEOptionsProc
  .lvi LVITEM
begin

.idButtonAdd  = 100
.idButtonDel  = 101
.idButtonEdit = 102
.idListView    = 103


ondefault
        stc
        return

;--------------------------------
; Init columns of the listview
;--------------------------------
onmessage FM_AFTERCREATE
locals
  .lvc LVCOLUMN
endl

cTitleKey text 'Name'
cTitleVal text 'Value'

        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_GRIDLINES or LVS_EX_FULLROWSELECT

        lea     ebx, [.lvc]

        mov     [.lvc.mask], LVCF_FMT or LVCF_TEXT or LVCF_SUBITEM
        mov     [.lvc.fmt], LVCFMT_RIGHT
        mov     [.lvc.pszText], cTitleKey
        mov     [.lvc.iSubItem], 0
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_INSERTCOLUMN, 0, ebx

        mov     [.lvc.mask], LVCF_FMT or LVCF_TEXT or LVCF_SUBITEM
        mov     [.lvc.fmt], LVCFMT_LEFT
        mov     [.lvc.pszText], cTitleVal
        mov     [.lvc.iSubItem], 1
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_INSERTCOLUMN, 1, ebx

        clc
        return


;----------------------------------------------------------
; Loads the path aliases ("environment variables") from
; the .ini file.
;-----------------------------------------------------------
onmessage OM_LOADOPTIONS
        cmp     [.lparam], 0
        je      .readfromini

; read the aliases from array of type TEnvVarType (.lparam is pointer to pointer to TArray)

        mov     esi, [.lparam]
        mov     esi, [esi]
        test    esi, esi
        jz      .sizecols

        mov     ebx, [esi+TArray.count]
        lea     esi, [esi+TArray.array]

.insertloop:
        cmp     ebx, 0
        je      .sizecols

        stdcall StrPtr, [esi+TEnvVarType.pName]
        mov     [.lvi.mask], LVIF_TEXT
        mov     [.lvi.iItem], 10000
        mov     [.lvi.iSubItem], 0
        mov     [.lvi.pszText], eax
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_INSERTITEM, 0, eax

        mov     [.lvi.iItem], eax
        stdcall StrPtr, [esi+TEnvVarType.pValue]
        mov     [.lvi.pszText], eax
        mov     [.lvi.mask], LVIF_TEXT
        mov     [.lvi.iSubItem], 1
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETITEM, 0, eax

        add     esi, sizeof.TEnvVarType
        dec     ebx
        jmp     .insertloop


; read the aliases from ini file.
.readfromini:
        stdcall GetMem, 32768          ; get maximum buffer for INI section.
        mov     edi, eax

        stdcall StrPtr, [hIniFileName]
        invoke  GetPrivateProfileSectionA, _section_environment, edi, 32767, eax

; fill "evironment" variables to the listview.
        push    edi

.fillloop:
        mov     esi, edi
        cmp     byte [edi], 0
        je      .endoflist

.scaneq:
        cmp     byte [edi], 0
        je      .endofstring

        cmp     byte [edi], '='
        je      .eqfound

        inc     edi
        jmp     .scaneq

.endofstring:
        inc     edi
        jmp     .fillloop

.eqfound:
        mov     byte [edi],0
        inc     edi

        mov     [.lvi.mask], LVIF_TEXT
        mov     [.lvi.iItem], 10000
        mov     [.lvi.iSubItem], 0
        mov     [.lvi.pszText], esi
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_INSERTITEM, 0, eax

        mov     [.lvi.mask], LVIF_TEXT
        mov     [.lvi.iItem], eax
        mov     [.lvi.iSubItem], 1
        mov     [.lvi.pszText], edi
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETITEM, 0, eax

        xor     al,al
        mov     ecx, 32768
        repne scasb
        jmp     .fillloop

.endoflist:
        stdcall FreeMem ; from the stack.

.sizecols:
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETCOLUMNWIDTH, 0, LVSCW_AUTOSIZE_USEHEADER
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETCOLUMNWIDTH, 1, LVSCW_AUTOSIZE_USEHEADER

        clc
        return

;--------------------------------------------------------------------
; Saves the paths to the .ini file on exit of the dialog with MR_OK
;--------------------------------------------------------------------
onmessage OM_SAVEOPTIONS

locals
  .buffer rb 1024
endl
        cmp     [.lparam], 0
        je      .savetoini

; save to project poVarArray
        mov     esi, [.lparam]

        stdcall EmptyVarList, [.lparam]

        stdcall FreeMem, [esi]
        stdcall CreateArray, sizeof.TEnvVarType
        mov     [esi], eax

        xor     ebx, ebx

.getloop2:
        lea     eax, [.buffer]
        mov     [.lvi.iSubItem], 0
        mov     [.lvi.pszText], eax
        mov     [.lvi.cchTextMax], 1024
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETITEMTEXT, ebx, eax
        test    eax,eax
        jz      .endofitems2

        stdcall AddArrayItems, [esi], 1
        mov     [esi], edx
        mov     edi, eax

        lea     eax, [.buffer]
        stdcall StrDup, eax
        mov     [edi+TEnvVarType.pName], eax

        lea     eax, [.buffer]
        mov     [.lvi.iSubItem], 1
        mov     [.lvi.pszText], eax
        mov     [.lvi.cchTextMax], 1024
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETITEMTEXT, ebx, eax

        lea     eax, [.buffer]
        stdcall StrDup, eax
        mov     [edi+TEnvVarType.pValue], eax

        inc     ebx
        jmp     .getloop2

.endofitems2:
        clc
        return


.savetoini:
        stdcall GetMem, 32768
        mov     edi, eax

        xor     esi, esi

        push    edi

.getloop:
        mov     [.lvi.iSubItem], 0
        mov     [.lvi.pszText], edi
        mov     [.lvi.cchTextMax], 1024
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETITEMTEXT, esi, eax
        test    eax,eax
        jz      .endofitems

        add     edi, eax
        mov     byte [edi], '='
        inc     edi

        mov     [.lvi.iSubItem], 1
        mov     [.lvi.pszText], edi
        mov     [.lvi.cchTextMax], 1024
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETITEMTEXT, esi, eax

        add     edi, eax
        inc     edi
        inc     esi

        jmp     .getloop

.endofitems:
        mov     byte [edi], 0

        pop     edi

        stdcall StrPtr, [hIniFileName]
        invoke  WritePrivateProfileSectionA, _section_environment, edi, eax

        stdcall FreeMem, edi

        clc
        return

;-------------------------------------------------------------
; Well, executes the functions when
; one clicks on buttons "Add", "Edit", etc.
; Uses dialog box from the file "EditPath.frm"
;-------------------------------------------------------------
onmessage WM_COMMAND

        movzx   esi, word [.wparam]

        cmp     esi, .idButtonAdd ; button near include path edit
        je      .addpath

        cmp     esi, .idButtonDel
        je      .delpath

        cmp     esi, .idButtonEdit
        jne     .ondefault

.editpath:
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETNEXTITEM, -1, LVNI_SELECTED
        cmp     eax, -1
        jne     .getselected

        clc
        return

.getselected:
        mov     ebx, eax

        stdcall StrNew
        mov     esi, eax
        stdcall StrSetCapacity, esi, 1024
        mov     [.lvi.iSubItem], 0
        mov     [.lvi.pszText], eax
        mov     [.lvi.cchTextMax], 1024
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETITEMTEXT, ebx, eax
        stdcall StrFixLen, esi

        stdcall StrNew
        mov     edi, eax
        stdcall StrSetCapacity, edi, 1024
        mov     [.lvi.iSubItem], 1
        mov     [.lvi.pszText], eax
        mov     [.lvi.cchTextMax], 1024
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETITEMTEXT, ebx, eax
        stdcall StrFixLen, edi

        stdcall InputAliasName, esi, edi
        cmp     eax, MR_OK
        jne     .exitdelstrings

        stdcall StrPtr, esi
        mov     [.lvi.iSubItem], 0
        mov     [.lvi.pszText], eax
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETITEMTEXT, ebx, eax

        stdcall StrPtr, edi
        mov     [.lvi.iSubItem], 1
        mov     [.lvi.pszText], eax
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETITEMTEXT, ebx, eax

.exitdelstrings:
        stdcall StrDel, esi
        stdcall StrDel, edi

        clc
        return

.addpath:
        stdcall StrNew
        mov     esi, eax
        stdcall StrNew
        mov     edi, eax

        stdcall InputAliasName, esi, edi
        cmp     eax, MR_OK
        jne     .exitdelstrings

        stdcall StrPtr, esi
        mov     [.lvi.pszText], eax
        mov     [.lvi.mask], LVIF_TEXT
        mov     [.lvi.iItem], 10000
        mov     [.lvi.iSubItem], 0
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_INSERTITEM, 0, eax

        lea     ecx, [.lvi]
        push    ecx
        push    eax
        stdcall StrPtr, edi
        mov     [.lvi.pszText], eax
        mov     [.lvi.iSubItem], 1
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETITEMTEXT
        jmp     .exitdelstrings


.delpath:
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETNEXTITEM, -1, LVNI_SELECTED
        cmp     eax, -1
        jne     .delselected

        clc
        return

.delselected:
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_DELETEITEM, eax, 0
        clc
        return
endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































Deleted source/EditorBehaviour.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
;<ff
Window frmEditorBehaviour, 3, 0, 'TForm', 'Editor behaviour', $46000000, $10000, 0, 201, 191, 374, 246, EditorBehaviourWinProc;
Window NONE, 0, 0, 'BUTTON', 'Auto &brackets', $5001C003, $0, 216, 224, 8, 104, 16, 0;
Window NONE, 0, 0, 'BUTTON', 'Tab indents selection', $5001C003, $0, 264, 224, 128, 120, 16, 0;
Window NONE, 0, 0, 'BUTTON', '&Console caret', $5001C003, $0, 232, 224, 108, 88, 16, 0;
Window NONE, 0, 0, 'BUTTON', '&Secure selection', $5001C003, $0, 208, 224, 68, 104, 16, 0;
Window NONE, 0, 0, 'BUTTON', '&Optimal fill on saving', $5001C003, $0, 204, 224, 88, 120, 16, 0;
Window NONE, 0, 0, 'BUTTON', 'Smart &tabulations', $5001C003, $0, 202, 224, 48, 104, 16, 0;
Window NONE, 0, 0, 'BUTTON', 'Auto &Indents', $5001C003, $0, 201, 224, 28, 104, 16, 0;
Window NONE, 0, 1, 'STATIC', '', $50000000, $0, 0, 0, 0, 4, 219, 0;
Window NONE, 0, 1, 'ASMEDIT', 'AsmEdit', $50810127, $0, 400, 4, 0, 212, 219, 0;
Window NONE, 2, 0, 'STATIC', '<- Type here to test', $50000000, $0, 0, 224, 160, 120, 16, 0;
;ff>

winproc EditorBehaviourWinProc
begin

ondefault
        stc
        return

onmessage FM_AFTERCREATE

        invoke  SendDlgItemMessageA, [.hwnd], 400, WM_SETTEXT, 0, cPreviewSource


onmessage OM_UPDATEDIALOG
; Set properties for preview window.
        invoke  GetDlgItem, [.hwnd], 400
        mov     esi, eax

        invoke  GetParent, [.hwnd]
        invoke  GetPropA, eax, [propTempSettings]
        mov     ebx, eax

        stdcall ApplySettingsToAsmEdit, esi, ebx, fasm_syntax

        invoke  GetWindow, [.hwnd], GW_CHILD
        mov     edi, [ebx+TEditorSettings.AsmEditStyle]

.stylesloop:
        mov     esi, eax
        invoke  GetWindowLongA, esi, GWL_ID
        cmp     eax, 200
        jl      .nextcheckbox
        cmp     eax, 400
        jge     .nextcheckbox

        sub     eax, 200
        test    edi, eax
        setnz   al
        movzx   eax, al
        invoke  SendMessageA, esi, BM_SETCHECK, eax, 0

.nextcheckbox:
        invoke  GetWindow, esi, GW_HWNDNEXT
        test    eax, eax
        jnz     .stylesloop

        clc
        return


onmessage WM_COMMAND
; Recreate AsmEdit styles
        movsx   eax, word [.wparam]
        cmp     eax, 200
        jl      .ondefault
        cmp     eax, 400
        jge     .ondefault

        xor     edi, edi
        invoke  GetWindow, [.hwnd], GW_CHILD

.loop:
        mov     esi, eax

        invoke  GetWindowLongA, esi, GWL_ID
        cmp     eax, 200
        jl      .next
        cmp     eax, 400
        jge     .next

        invoke  SendMessageA, esi, BM_GETCHECK, 0, 0
        cmp     eax, BST_CHECKED
        jne     .next

        invoke  GetWindowLongA, esi, GWL_ID
        sub     eax, 200
        or      edi, eax

.next:
        invoke  GetWindow, esi, GW_HWNDNEXT
        test    eax, eax
        jnz     .loop

        invoke  GetParent, [.hwnd]
        invoke  GetPropA, eax, [propTempSettings]
        mov     esi, eax

        mov     [esi+TEditorSettings.AsmEditStyle], edi

        invoke  GetDlgItem, [.hwnd], 400
        stdcall ApplySettingsToAsmEdit, eax, esi, fasm_syntax

.exit:
        clc
        return
endwp



;--------------------------------------------------------------

winproc FlagsGroupProc
begin

ondefault
        stc
        return

endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































Deleted source/EditorColors.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
;<ff
Window frmEditorColors, 3, 0, 'TForm', 'Syntax colors', $46000000, $10000, 0, 363, 158, 374, 237, CustomWinProc;
Window NONE, 0, 0, 'BUTTON', '&Color', $50010000, $0, 104, 312, 176, 40, 24, 0;
Window NONE, 0, 0, 'TForm', '', $50800000, $0, 109, 200, 176, 104, 24, 0;
Window NONE, 0, 0, 'ASMEDIT', '', $58810167, $0, 200, 4, 24, 188, 176, 0;
Window NONE, 0, 0, 'LISTBOX', '', $50B10141, $0, 106, 200, 24, 152, 144, 0;
Window NONE, 0, 0, 'STATIC', '&Font:', $50000200, $0, 0, 4, 2, 24, 19, 0;
Window NONE, 0, 0, 'STATIC', '&Syntax elements:', $50000200, $0, 0, 200, 4, 88, 19, 0;
Window NONE, 2, 0, 'TButtonEdit', '', $50810880, $0, 111, 32, 4, 161, 17, 0;
;ff>
iglobal

  cPreviewSource file 'PreviewSource.inc'
                 db   0

  cSynListboxColors:
          IndexedStrings                                          \
            aeTheme.text_color,      'Default text',              \
            aeTheme.text_background, 'Default background',        \
            aeTheme.sel_text,        'Selected text',             \
            aeTheme.sel_background,  'Selected background',       \
            aeTheme.focus_color,     'Focused line text',         \
            aeTheme.focus_background,'Focused line background',   \
            aeTheme.margin_background,'Left margin background',   \
            aeTheme.margin_border,    'Left margin border',       \
            aeTheme.syntax_colors+4*(clDirective-1),   'Assembler directive',     \
            aeTheme.syntax_colors+4*(clPreprocessor-1), 'Preprocessor directive', \
            aeTheme.syntax_colors+4*(clInstruction-1), 'Instruction',   \
            aeTheme.syntax_colors+4*(clRegister-1),    'Register',      \
            aeTheme.syntax_colors+4*(clSymbol-1),      'Symbol',        \
            aeTheme.syntax_colors+4*(clNumber-1),      'Number',        \
            aeTheme.syntax_colors+4*(clString-1),      'String',        \
            aeTheme.syntax_colors+4*(clComment-1),     'Comment'

  cFontCharsets:
          IndexedStrings                          \
            ANSI_CHARSET          , 'Western',    \
            DEFAULT_CHARSET       , 'Default',    \
            SYMBOL_CHARSET        , 'Symbol',     \
            SHIFTJIS_CHARSET      , 'Shiftjis',   \
            HANGEUL_CHARSET       , 'Hangeul',    \
            GB2312_CHARSET        , 'GB2312',     \
            CHINESEBIG5_CHARSET   , 'Chinese Big5',\
            OEM_CHARSET           , 'OEM',        \
            JOHAB_CHARSET         , 'Johab',      \
            HEBREW_CHARSET        , 'Hebrew',     \
            ARABIC_CHARSET        , 'Arabic',     \
            GREEK_CHARSET         , 'Greek',      \
            TURKISH_CHARSET       , 'Turkish',    \
            VIETNAMESE_CHARSET    , 'Vietnamese', \
            THAI_CHARSET          , 'Thai',       \
            EASTEUROPE_CHARSET    , 'Central European', \
            RUSSIAN_CHARSET       , 'Cyrillic',         \
            MAC_CHARSET           , 'Mac',              \
            BALTIC_CHARSET        , 'Baltic'
endg



winproc CustomWinProc
begin

ondefault
        stc
        return

onmessage FM_AFTERCREATE
locals
  .aep AEPOS
endl
; Fill listbox with color names.
        mov    esi, cSynListboxColors

        invoke  GetDlgItem, [.hwnd], 111
        invoke  GetDlgItem, eax, 1
        mov     ebx, eax
        invoke  GetWindowLongA, ebx, GWL_STYLE
        or      eax, BS_FLAT
        invoke  SetWindowLongA, ebx, GWL_STYLE, eax

.addloop:
        lodsd
        test    eax,eax
        jz      .OM_UPDATEDIALOG

        mov     ebx, [esi]
        add     esi, 4

        invoke  SendDlgItemMessageA, [.hwnd], 106, LB_ADDSTRING, 0, eax
        cmp     eax, LB_ERR
        je      .addloop

        invoke  SendDlgItemMessageA, [.hwnd], 106, LB_SETITEMDATA, eax, ebx
        jmp     .addloop

onmessage OM_UPDATEDIALOG
; Set properties for preview window.
        invoke  GetDlgItem, [.hwnd], 200
        mov     esi, eax

        invoke  GetParent, [.hwnd]
        invoke  GetPropA, eax, [propTempSettings]
        mov     ebx, eax

        stdcall ApplySettingsToAsmEdit, esi, ebx, fasm_syntax

        invoke  SendMessageA, esi, WM_SETTEXT, 0, cPreviewSource
        invoke  SendMessageA, esi, AEM_READONLY, TRUE, 0
        invoke  SendMessageA, esi, AEM_SETFOCUSLINE, 2, 0

        mov     [.aep.caretLine], 10
        mov     [.aep.caretPosition], 0
        mov     [.aep.selectionLine], 10
        mov     [.aep.selectionPosition], 255
        lea     eax, [.aep]
        invoke  SendMessageA, esi, AEM_SETPOS, eax, 0

; Set font name size and charset

; Name
iglobal
  cComma db ', ',0
endg
        stdcall StrDup, [ebx+TEditorSettings.ptrFontName]
        mov     edi, eax
        stdcall StrCat, edi, cComma
; Size
        stdcall NumToStr, [ebx+TEditorSettings.FontSize], ntsDec
        stdcall StrCat, edi, eax
        stdcall StrDel, eax
        stdcall StrCat, edi, cComma

; Charset
        mov     ecx, [ebx+TEditorSettings.FontCharset]
        mov     esi, cFontCharsets
.setloop:
        lodsd
        test    eax, eax
        jz      .notfound

        mov     edx, eax
        lodsd
        cmp     eax, ecx
        jne     .setloop

        stdcall StrCat, edi, edx

.setfonttext:
        stdcall StrPtr, edi
        invoke  SendDlgItemMessageA, [.hwnd], 111, WM_SETTEXT, 0, eax
        stdcall StrDel, edi

; Set current selected color...
        invoke  SendDlgItemMessageA, [.hwnd], 106, LB_GETCURSEL, 0, 0
        cmp     eax, LB_ERR
        jne     .validselection

        invoke  GetDlgItem, [.hwnd], 104
        invoke  EnableWindow, eax, FALSE
        invoke  GetPropA, [.hwnd], [propColor]
        invoke  SendDlgItemMessageA, [.hwnd], 109, FM_SETCOLOR, eax, 0
        clc
        return

.validselection:
        invoke  SendDlgItemMessageA, [.hwnd], 106, LB_GETITEMDATA, eax, 0

        mov     edi, [ebx+TEditorSettings.ptrTheme]
        mov     eax, [edi+eax]
        invoke  SendDlgItemMessageA, [.hwnd], 109, FM_SETCOLOR, eax, 0

        invoke  GetDlgItem, [.hwnd], 104
        invoke  EnableWindow, eax, TRUE

        clc
        return

.notfound:
        stdcall NumToStr, ecx, ntsSigned or ntsDec
        stdcall StrCat, edi, eax
        stdcall StrDel, eax
        jmp     .setfonttext


        clc
        return


onmessage WM_COMMAND
locals
  .cc CHOOSECOLOR
endl
        cmp     word [.wparam+2], LBN_SELCHANGE
        je      .colorlistbox

        cmp     word [.wparam], 104                  ; ID of the "Color" button
        je      .changecolor

        jmp     .ondefault

iglobal
  arrayCustomColors:
        times 16 dd $00ffffff
endg

.changecolor:
        invoke  GetParent, [.hwnd]
        invoke  GetPropA, eax, [propTempSettings]
        mov     edi, eax

        invoke  SendDlgItemMessageA, [.hwnd], 106, LB_GETCURSEL, 0, 0
        cmp     eax, LB_ERR
        je      .endcolorset

        invoke  SendDlgItemMessageA, [.hwnd], 106, LB_GETITEMDATA, eax, 0

        mov     edi, [edi+TEditorSettings.ptrTheme]
        lea     edi, [edi+eax]
        mov     eax, [edi]

        lea     esi, [.cc]
        mov     [esi+CHOOSECOLOR.lStructSize], sizeof.CHOOSECOLOR
        mov     [esi+CHOOSECOLOR.hwndOwner], 0
        mov     [esi+CHOOSECOLOR.rgbResult], eax
        mov     [esi+CHOOSECOLOR.lpCustColors], arrayCustomColors
        mov     [esi+CHOOSECOLOR.Flags], CC_RGBINIT or CC_ENABLEHOOK
        mov     [esi+CHOOSECOLOR.lpfnHook], CommonDialogHook

        invoke  ChooseColorA, esi
        test    eax, eax
        jz      .endcolorset

        mov     eax, [esi+CHOOSECOLOR.rgbResult]
        mov     [edi], eax
        invoke  SendDlgItemMessageA, [.hwnd], 109, FM_SETCOLOR, eax, 0
        jmp     .OM_UPDATEDIALOG


.endcolorset:
        clc
        return



.colorlistbox:
        movzx   eax, word [.wparam]
        cmp     eax, 106   ; id of the list box.
        jne     .ondefault

        invoke  GetParent, [.hwnd]
        invoke  GetPropA, eax, [propTempSettings]
        mov     esi, [eax+TEditorSettings.ptrTheme]

        invoke  SendMessageA, [.lparam], LB_GETCURSEL, 0, 0
        cmp     eax, LB_ERR
        je      .endcommand

        invoke  SendMessageA, [.lparam], LB_GETITEMDATA, eax, 0
        lea     esi, [esi+eax]

        invoke  SendDlgItemMessageA, [.hwnd], 109, FM_SETCOLOR, [esi], 0
        invoke  GetDlgItem, [.hwnd], 104
        invoke  EnableWindow, eax, TRUE

.endcommand:
        xor     eax, eax
        clc
        return


onmessage BEM_BUTTONCLICK
locals
  .cf CHOOSEFONT
  .lf LOGFONT
endl
        lea     esi, [.cf]
        mov     [esi+CHOOSEFONT.lStructSize], sizeof.CHOOSEFONT

        mov     [esi+CHOOSEFONT.hwndOwner], 0
        mov     [esi+CHOOSEFONT.Flags], CF_FIXEDPITCHONLY or CF_FORCEFONTEXIST or CF_NOVECTORFONTS or CF_SCREENFONTS or CF_INITTOLOGFONTSTRUCT or CF_ENABLEHOOK
        lea     eax, [.lf]
        mov     [esi+CHOOSEFONT.lpLogFont], eax
        mov     [esi+CHOOSEFONT.lpfnHook], CommonDialogHook

        invoke  GetParent, [.hwnd]
        invoke  GetPropA, eax, [propTempSettings]
        mov     esi, eax

        mov     eax, [esi+TEditorSettings.FontSize]
        mov     ecx, [esi+TEditorSettings.FontCharset]
        mov     [.lf.lfHeight], eax
        mov     [.lf.lfCharSet], cl

        mov     esi, [esi+TEditorSettings.ptrFontName]
        mov     ecx, 32
        lea     edi, [.lf.lfFaceName]
        rep movsb

        lea     esi, [.cf]
        invoke  ChooseFontA, esi
        test    eax, eax
        jz      .endfont

        invoke  GetParent, [.hwnd]
        invoke  GetPropA, eax, [propTempSettings]
        mov     edi, eax

        mov     eax, [.lf.lfHeight]
        movzx   ecx, [.lf.lfCharSet]
        mov     [edi+TEditorSettings.FontSize], eax
        mov     [edi+TEditorSettings.FontCharset], ecx

        mov     edi, [edi+TEditorSettings.ptrFontName]
        mov     ecx, 32
        lea     esi, [.lf.lfFaceName]
        rep movsb

        jmp     .OM_UPDATEDIALOG

.endfont:
        clc
        return

endwp


winproc CommonDialogHook
.rect RECT
begin
        push    esi edi ebx
        mov     ebx, [.wmsg]

ondefault
        xor     eax, eax
        pop     ebx edi esi
        return

onmessage WM_INITDIALOG

        lea     eax, [.rect]
        invoke  GetWindowRect, [.hwnd], eax

        invoke  GetSystemMetrics, SM_CXSCREEN
        sub     eax, [.rect.right]
        add     eax, [.rect.left]
        sar     eax,1
        mov     esi, eax

        invoke  GetSystemMetrics, SM_CYSCREEN
        sub     eax, [.rect.bottom]
        add     eax, [.rect.top]
        sar     eax,1
        mov     edi, eax

        invoke  SetWindowPos, [.hwnd], 0, esi, edi, 0, 0, SWP_NOSIZE or SWP_NOZORDER

        mov     eax, 1
        pop     ebx edi esi
        return
endwp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































Deleted source/EmbededHelp.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
uglobal
  hEHelp dd ?
  hEHFont dd ?
endg

cEHelpFont text 'Courier New'

initialize InitEHelp
begin
        xor     ebx, ebx
        invoke  CreateFontA, -11, ebx, ebx, ebx, FW_DONTCARE,                                 \
                            ebx, ebx, ebx,                                                   \
                            1, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,     \
                            FIXED_PITCH or FF_DONTCARE, cEHelpFont
        mov     [hEHFont], eax
        return
endp


finalize FreeEHelp
begin
        invoke  DeleteObject, [hEHFont]
        return
endp




proc CreateEHWindow, .parent
begin
        cmp     [hEHelp], 0
        jne     .exit

        invoke  CreateWindowExA, 0, cStaticClassName, 0,                   \
                WS_POPUP or WS_BORDER or SS_OWNERDRAW or SS_LEFT,         \
                10, 10, 564, 300, [.parent], 0, [hInstance], 0
        mov     [hEHelp], eax
        stdcall SubclassWindow, eax, procEHelp

.exit:
        invoke  SetWindowLongA, [hEHelp], GWL_HWNDPARENT, [.parent]
        call    UpdateEHelp
        return
endp



proc UpdateEHelp
.edit dd ?
.help dd ?
.rect1 RECT
.height dd ?
.caret AECARETXY
begin
        cmp     [hEHelp], 0
        je      .exit


        invoke  GetWindowLongA, [hEHelp], GWL_HWNDPARENT
        mov     [.edit], eax

; create the text content of the window

        stdcall GetDefinition
        jc      .notfound

        push    eax
        stdcall ExtractEmbededHelp, eax, edx
        stdcall StrDel ; from the stack
        test    eax, eax
        jz      .notfound

        mov     [.help], eax

; then set the possition
  ; first, compute the size of the window.
        stdcall StrPtr, [.help]
        invoke  SendMessageA, [hEHelp], WM_SETTEXT, 0, eax

        invoke  GetDC, [hEHelp]
        push    eax
        invoke  CreateCompatibleDC, eax
        push    eax
        stdcall PaintEHelp, [hEHelp], eax
        mov     [.height], eax
        invoke  DeleteDC ; from the stack
        invoke  ReleaseDC, [hEHelp] ; from the stack

  ; then compute the place

        lea     ebx, [.caret]
        invoke  SendMessageA, [.edit], AEM_GETCARETXY, ebx, 0
        invoke  ClientToScreen, [.edit], ebx
        add     ebx, 8
        invoke  ClientToScreen, [.edit], ebx
        sub     ebx, 8

        lea     eax, [.rect1]
        invoke  SystemParametersInfoA, SPI_GETWORKAREA, 0, eax, 0

        mov     eax, 564
        mov     edx, [.height]

        mov     ecx, [ebx+AECARETXY.x0]
        add     eax, ecx
        sub     [.rect1.right], eax
        jns     @f
        add     ecx, [.rect1.right]
@@:
        mov     [.rect1.right], ecx

        mov     ecx, [ebx+AECARETXY.y1]
        sub     [.rect1.bottom], edx
        cmp     ecx, [.rect1.bottom]
        jbe     @f
        mov     ecx, [ebx+AECARETXY.y0]
        sub     ecx, edx
@@:
        mov     [.rect1.top], ecx

        invoke  SetWindowPos, [hEHelp], 0, [.rect1.right], ecx, 564, [.height], SWP_NOZORDER or SWP_NOACTIVATE or SWP_SHOWWINDOW
        invoke  InvalidateRect, [hEHelp], 0, TRUE

.finish:
        stdcall StrDel, [.help]

.exit:
        return

.notfound:
        invoke  PostMessageA, [hEHelp], WM_CLOSE, 0, 0
        jmp     .finish
endp



winproc procEHelp
begin

ondefault
        stc
        return

;___________________________________________________________________________
;
onmessage WM_ERASEBKGND
cEHBackground = $ffffd0
locals
  .bkrect RECT
endl
        lea     ebx, [.bkrect]
        invoke  GetClientRect, [.hwnd], ebx
        invoke  CreateSolidBrush, cEHBackground
        push    eax
        invoke  FillRect, [.wparam], ebx, eax
        invoke  DeleteObject ; from the stack
        xor     eax, eax
        dec     eax
        clc
        return

;___________________________________________________________________________
;
onmessage WM_PAINT
locals
  .update RECT
  .ps     PAINTSTRUCT
endl

        lea     eax, [.update]
        invoke  GetUpdateRect, [.hwnd], eax, TRUE
        test    eax, eax
        jz      .finishpaint

        lea     esi, [.ps]
        invoke  BeginPaint, [.hwnd], esi
        test    eax, eax
        jz      .endpaint

        stdcall PaintEHelp, [.hwnd], [esi+PAINTSTRUCT.hdc]

.endpaint:
        invoke  EndPaint, [.hwnd], esi

.finishpaint:
        xor     eax, eax
        clc
        return


;___________________________________________________________________________
;
onmessage WM_CLOSE
        invoke  DestroyWindow, [.hwnd]
        mov     [hEHelp], 0
        clc
        return
endwp




; paints the embeded help window and returns the size needed.
; eax: height of the window needed.
proc PaintEHelp, .hwnd, .hdc
.str dd ?
.deffont dd ?
.point POINT
.metrics TEXTMETRIC
.rect RECT
begin
        push    ebx edi

        stdcall GetControlText, [.hwnd], NULL
        mov     [.str], eax

        stdcall StrPtr, [.str]
        mov     edi, eax

        invoke  SetTextColor, [.hdc], $000000
        invoke  SetBkMode, [.hdc], TRANSPARENT
        invoke  SelectObject, [.hdc], [hEHFont]
        mov     [.deffont], eax

        lea     ebx, [.rect]
        invoke  GetClientRect, [.hwnd], ebx
        add     [ebx+RECT.left], 2
        add     [ebx+RECT.top], 2
        sub     [ebx+RECT.right], 2
        mov     [ebx+RECT.bottom], 10000
        invoke  DrawTextA, [.hdc], edi, -1, ebx, DT_LEFT or DT_EXTERNALLEADING
        stdcall StrDel, [.str]

        add     eax, 8
        pop     edi ebx
        return
endp




proc ExtractEmbededHelp, .hFilename, .LineNumber
begin
        pushad

        dec     [.LineNumber]
        stdcall CreateArray, 4
        mov     edx, eax

        stdcall FileOpen, [.hFilename]
        jc      .error
        mov     ebx, eax

.read_loop:
        stdcall FileReadLine, ebx
        test    eax, eax
        jz      .end_of_file

        push    eax
        stdcall AddArrayItems, edx, 1
        popd    [eax]
        jmp     .read_loop

.end_of_file:
        stdcall FileClose, ebx

        mov     ecx, [.LineNumber]
        cmp     ecx, [edx+TArray.count]
        jae     .error

.search_start:
        dec     ecx
        js      .end_found

        mov     ebx, [edx+TArray.array+4*ecx]

        stdcall StrClipSpacesR, ebx
        stdcall StrClipSpacesL, ebx
        stdcall StrLen, ebx
        test    eax, eax
        jz      .search_start

        inc     ecx

.search_loop:
        dec     ecx
        js      .end_found

        mov     ebx, [edx+TArray.array+4*ecx]

        stdcall StrClipSpacesR, ebx
        stdcall StrClipSpacesL, ebx
        stdcall StrPtr, ebx

        cmp     byte [eax], ';'
        je      .search_loop

.end_found:
        stdcall StrNew
        mov     ebx, eax

.skip_leading_empty_lines:
        inc     ecx
        cmp     ecx, [.LineNumber]
        jae     .end_compose

        stdcall StrLen, [edx+TArray.array+4*ecx]
        test    eax, eax
        jz      .skip_leading_empty_lines

        dec     ecx

.compose_loop:
        inc     ecx
        cmp     ecx, [.LineNumber]
        jae     .end_compose

        stdcall StrCat, ebx, [edx+TArray.array+4*ecx]
        stdcall StrCharCat, ebx, $0a0d
        jmp     .compose_loop

.end_compose:
        stdcall StrClipSpacesL, ebx
        mov     [esp+4*regEAX], ebx

        stdcall StrPtr, ebx
        mov     ecx, [eax+string.len]

.skip_trailing:
        dec     ecx
        js      .end_trailing

        cmp     byte [eax+ecx], ' '
        je      .skip_trailing
        cmp     byte [eax+ecx], $0d
        je      .skip_trailing
        cmp     byte [eax+ecx], $0a
        je      .skip_trailing

.end_trailing:
        inc     ecx
        jecxz   .error

        mov     dword [eax+ecx], 0
        mov     [eax+string.len], ecx

.finish:
        stdcall ListFree, edx, StrDel
        popad
        return

.error:
        stdcall StrDel, [esp+4*regEAX]
        mov     dword [esp+4*regEAX], 0
        jmp     .finish
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































Deleted source/ExternalOptions.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
;<ff
Window frmExternalOptions, 3, 0, 'TForm', 'Debugers and emulators', $46000000, $10000, 0, 243, 191, 337, 256, frmExternalOptionsProc;
Window NONE, 0, 0, 'STATIC', 'Hint: In order to run Linux applications in Windows,  you have to install "andLinux".', $50000000, $0, 0, 8, 8, 320, 32, 0;
Window NONE, 0, 0, 'STATIC', 'andLinux &shared directory:', $50000000, $0, 0, 168, 48, 144, 16, 0;
Window NONE, 0, 0, 'STATIC', 'Win32 E&xternal debugger:', $50000000, $0, 0, 8, 176, 144, 16, 0;
Window NONE, 0, 0, 'TButtonEdit', '', $50810080, $0, 105, 8, 192, 312, 19, 0;
Window NONE, 0, 0, 'TButtonEdit', '', $50810080, $0, 106, 8, 64, 152, 19, 0;
Window NONE, 0, 0, 'TButtonEdit', '', $50810080, $0, 107, 168, 64, 152, 19, 0;
Window NONE, 0, 0, 'STATIC', 'Linux terminal:', $50000000, $0, 0, 168, 96, 96, 16, 0;
Window NONE, 0, 0, 'STATIC', 'and&Linux directory:', $50000000, $0, 0, 8, 48, 96, 16, 0;
Window NONE, 0, 0, 'EDIT', '', $50810080, $0, 109, 168, 112, 152, 19, 0;
Window NONE, 0, 0, 'STATIC', 'Linux debugger:', $50000000, $0, 0, 8, 96, 96, 16, 0;
Window NONE, 2, 0, 'EDIT', '', $50810080, $0, 108, 8, 112, 152, 19, 0;
;ff>

  cAndLinuxKey        text 'andLinux'
  cAndLinuxSharedKey  text 'LinuxSharedDir'
  cLinuxDbgKey        text 'LinuxDebugger'
  cLinuxTerminalKey   text 'LinuxTerminal'

  cAndTitle    text 'Select andLinux directory:'
  cSharedTitle text 'Select andLinux shared directory:'
  cDbgTitle    text 'Select external debuger:'

iglobal
  cExecutablesFilter db 'Executables (*.exe)',0,'*.exe',0
                     db 0
endg


idDebuggerEdit     = 105
idAndLinuxDirEdit  = 106
idSharedDirEdit    = 107
idLinuxDebugEdit   = 108
idLinuxTerminalEdit = 109

winproc frmExternalOptionsProc
  .str rb 1024
begin

ondefault
        stc
        return

onmessage WM_CLOSE
          clc
          return

onmessage FM_AFTERCREATE
        invoke  SendDlgItemMessageA, [.hwnd], idDebuggerEdit, BEM_SETBUTTONTEXT, 0, cTitleBtnEdit
        invoke  SendDlgItemMessageA, [.hwnd], idAndLinuxDirEdit, BEM_SETBUTTONTEXT, 0, cTitleBtnEdit
        invoke  SendDlgItemMessageA, [.hwnd], idSharedDirEdit, BEM_SETBUTTONTEXT, 0, cTitleBtnEdit
        clc
        return

onmessage OM_LOADOPTIONS

        stdcall GetParamFromINI, cAndLinuxKey
        jc      @f
        push    eax
        stdcall StrPtr, eax
        invoke  SendDlgItemMessageA, [.hwnd], idAndLinuxDirEdit, WM_SETTEXT, 0, eax
        stdcall StrDel ; from the stack
@@:
        stdcall GetParamFromINI, cAndLinuxSharedKey
        jc      @f
        push    eax
        stdcall StrPtr, eax
        invoke  SendDlgItemMessageA, [.hwnd], idSharedDirEdit, WM_SETTEXT, 0, eax
        stdcall StrDel ; from the stack
@@:
        stdcall GetParamFromINI, cLinuxDbgKey
        jc      @f
        push    eax
        stdcall StrPtr, eax
        invoke  SendDlgItemMessageA, [.hwnd], idLinuxDebugEdit, WM_SETTEXT, 0, eax
        stdcall StrDel ; from the stack
@@:
        stdcall GetParamFromINI, cDebugerKey
        jc      @f
        push    eax
        stdcall StrPtr, eax
        invoke  SendDlgItemMessageA, [.hwnd], idDebuggerEdit, WM_SETTEXT, 0, eax
        stdcall StrDel ; from the stack
@@:
        stdcall GetParamFromINI, cLinuxTerminalKey
        jc      @f
        push    eax
        stdcall StrPtr, eax
        invoke  SendDlgItemMessageA, [.hwnd], idLinuxTerminalEdit, WM_SETTEXT, 0, eax
        stdcall StrDel ; from the stack
@@:

        clc
        return


onmessage OM_SAVEOPTIONS

        stdcall StrPtr, [hIniFileName]
        mov     esi, eax
        lea     edi,[.str]

        invoke  SendDlgItemMessageA, [.hwnd], idAndLinuxDirEdit, WM_GETTEXT, 1024, edi
        invoke  WritePrivateProfileStringA, cParamSection, cAndLinuxKey, edi, esi

        invoke  SendDlgItemMessageA, [.hwnd], idSharedDirEdit, WM_GETTEXT, 1024, edi
        invoke  WritePrivateProfileStringA, cParamSection, cAndLinuxSharedKey, edi, esi

        invoke  SendDlgItemMessageA, [.hwnd], idLinuxDebugEdit, WM_GETTEXT, 1024, edi
        invoke  WritePrivateProfileStringA, cParamSection, cLinuxDbgKey, edi, esi

        invoke  SendDlgItemMessageA, [.hwnd], idDebuggerEdit, WM_GETTEXT, 1024, edi
        invoke  WritePrivateProfileStringA, cParamSection, cDebugerKey, edi, esi

        invoke  SendDlgItemMessageA, [.hwnd], idLinuxTerminalEdit, WM_GETTEXT, 1024, edi
        invoke  WritePrivateProfileStringA, cParamSection, cLinuxTerminalKey, edi, esi

        clc
        return


onmessage BEM_BUTTONCLICK

        lea     edi, [.str]

        cmp     [.wparam], idAndLinuxDirEdit
        je      .linuxdir

        cmp     [.wparam], idSharedDirEdit
        je      .shareddir

        cmp     [.wparam], idDebuggerEdit
        je      .debugfile

        clc
        return

.linuxdir:
        invoke  GetDlgItem, [.hwnd], idAndLinuxDirEdit
        mov     esi, cAndTitle
        jmp     .commondirButtonEdit

.shareddir:
        invoke  GetDlgItem, [.hwnd], idSharedDirEdit
        mov     esi, cSharedTitle

.commondirButtonEdit:
        mov     ebx, eax
        invoke  SendMessageA, ebx, WM_GETTEXT, 1024, edi
        stdcall SelectPathDialog, [hApplication], esi, edi
        test    eax,eax
        jz      .nodir

        push    eax
        stdcall StrPtr, eax
        invoke  SendMessageA, ebx, WM_SETTEXT, 0, eax
        stdcall StrDel ; From stack

.nodir:
        clc
        return

.debugfile:
        invoke  GetDlgItem, [.hwnd], idDebuggerEdit
        mov     esi, cDbgTitle
        mov     ebx, eax

        invoke  SendMessageA, ebx, WM_GETTEXT, 1024, edi
        stdcall OpenFilesDialog, esi, FALSE, cExecutablesFilter, ButtonEditFileSelect, edi, ebx
        clc
        return

endwp



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































Deleted source/Fasm.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
;-----------------------------------------------------------------------------------------------
;
; flat assembler interface for Fresh RAD IDE
;
; Copyright (c) 1999-2003, Tomasz Grysztar.
; Copyright (c) 2003, John Found
; All rights reserved.
;
;   This file is modified version of the fasm.inc file from
; FASMW package.
;
;-----------------------------------------------------------------------------------------------

iglobal
  _section_environment db 'Environment',0
endg


uglobal
  bytes_count           dd ?
  systime               SYSTEMTIME

  start_time            dd ?
  preprocess_time       dd ?
  parsing_time          dd ?
  capturing_time        dd ?
  assembling_time       dd ?
  formating_time        dd ?
  collect_time          dd ?

  total_time            dd ?

  exit_code             dd ?
  buffer                rb 1000h
endg

;
; Fresh internal variables not related to FASM compiler
uglobal
  CompiledFileName      dd ?

  param_buffer          rd 10h
  path_buffer           rb 1000h

  hfile                 dd ?

  error_data_size       dd ?
  compiler_memory       dd ?

  ptrMemoryAllocated    dd ?

  save_stack_pointer    dd ?
endg



align 16

include 'fasm\version.inc'

include 'fasm\errors.inc'
include 'fasm\symbdump.inc'
include 'fasm\preproce.inc'
include 'fasm\parser.inc'
include 'fasm\exprpars.inc'

include 'fasm\assemble.inc'
fasm_instructions:
include 'fasm\x86_64.inc'
include 'fasm\avx.inc'

include 'fasm\exprcalc.inc'
include 'fasm\formats.inc'


iglobal
  include 'fasm\messages.inc'
  include 'fasm\tables.inc'
endg

uglobal
  include 'fasm\variable.inc'
endg


uglobal
 fmsg TFreshMsg
 hStrFileName   dd ?
endg


;----------------------------------------------------------
; Prepares the compiler for compilation, allocating needed
; memory, preparing filename, path, etc.
; It is good to call from main thread.
;
; Returns:
;   eax - TRUE if compiler is ready.
;         FALSE if there is no free memory.
;----------------------------------------------------------
proc PrepareForCompilation, .hFileName
begin
; Init virtual cash with current files in the editor.
        stdcall InitVCash

; Init display strings.
        stdcall StrNew
        mov     [strDisplay], eax
        mov     [iLastIcon], -1
        mov     [hLastMsg], TVI_ROOT

; Init filename string
        cmp     [hStrFileName], 0
        je      .strnameok

        stdcall StrDel, [hStrFileName]

.strnameok:
        stdcall ConvertPath, [.hFileName]
        mov     [hStrFileName], eax

        stdcall StrPtr, eax
        mov     [input_file], eax

        invoke  GetFullPathNameA, eax, 1000h, path_buffer, param_buffer
        mov     edi,[param_buffer]
        xor     al,al
        stosb
        invoke  SetCurrentDirectoryA, path_buffer

        mov     [hfile], 0

        mov     [error_data_size],0
        mov     [memory_start],0

        mov     eax, [compiler_memory]
        shl     eax,10
        jz      .out_of_memory

.allocate_memory:
        mov     edx,eax
        shr     edx,3
        mov     ecx,eax
        sub     ecx,edx
        mov     [memory_end],ecx
        mov     [additional_memory_end],edx

        stdcall GetMem, eax
        jnc     .memory_allocated

        mov     eax, [additional_memory_end]
        shl     eax, 2
        cmp     eax, 4000h
        jb      .out_of_memory
        jmp     .allocate_memory

.memory_allocated:
        mov     [ptrMemoryAllocated], eax       ; independent pointer to allocated block.
        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

        xor     eax, eax
        inc     eax
        return

.out_of_memory:
        stdcall StrDel, [strDisplay]
        mov     [strDisplay], 0

        xor     eax, eax
        return
endp


;----------------------------------------------------------
; Free compiling resources.
; Frees all memory used by compiler, dynamic strings, etc.
; It is good to be called from main thread. (also in case of
; canceling compilation.
;----------------------------------------------------------
proc CleanupAfterCompilation
begin
        mov     eax,[ptrMemoryAllocated]
        or      eax,eax
        jz      .memory_ok

        stdcall FreeMem, eax
        mov     [memory_start],0
        mov     [ptrMemoryAllocated], 0

.memory_ok:
        mov     ebx,[hfile]
        or      ebx,ebx
        jz      .handle_ok

        call    close

.handle_ok:
        stdcall StrDel, [strDisplay]
        stdcall DestroyVCash

        return
endp



;---------------------------------------------
; Compiles the file with filename in lParam
; You can use this procedure with stdcall
; or with CreateThread.
;---------------------------------------------
align 16
proc flat_assembler, .dummy
begin
        pushad
        mov     [save_stack_pointer], esp

;        invoke  SetThreadPriority,[hthread],[compiler_priority]

        invoke  GetTickCount
        mov     [start_time], eax

; Preprocessing
        stdcall DisplayBlock, cMsgPreprocess
  call preprocessor
        stdcall ProgressWndStepIt
        invoke  GetTickCount
        mov     [preprocess_time], eax

; Parsing
        stdcall DisplayBlock, cMsgParsing
  call parser
        stdcall ProgressWndStepIt
        invoke  GetTickCount
        mov     [parsing_time], eax

; Assembling
        stdcall DisplayBlock, cMsgAssembling
  call assembler
        stdcall ProgressWndStepIt
        invoke  GetTickCount
        mov     [assembling_time], eax

; Format output file.
        stdcall DisplayBlock, cMsgFormating
  call    formatter
        stdcall ProgressWndStepIt
        invoke  GetTickCount
        mov     [formating_time], eax


; finalize the compilation.
        cmp     [CompiledFileName], 0
        je      @f
        stdcall StrDel, [CompiledFileName]
        mov     [CompiledFileName], 0
@@:
        cmp     [output_file], 0
        je      @f
        stdcall StrDup, [output_file]
        mov     [CompiledFileName], eax
@@:
        call    show_display_buffer

        invoke  GetTickCount
        mov     [total_time], eax

; Capture debug information
        stdcall DisplayBlock, cMsgDebugInfo

; close the modal progress window
        invoke  SendMessageA,[hProgressWnd], WM_COMMAND, MR_OK, 0

    cmp     [output_file], 0
    je      .fasok

    stdcall LoadBinaryFile, cDumpFilename
    pushf
    stdcall FileDelete, cDumpFilename
    popf
    jc      .fasok

    stdcall CopyPreprocessedSource, eax
    stdcall CreateLabelsTree, eax
    stdcall CaptureDebugInfo, eax

    stdcall FreeMem, eax

    stdcall UpdateStatusbarCompiler

.fasok:
        xor     al,al

.exit_program:
        movzx   eax, al
        mov     [exit_code], eax

        test    eax, eax
        jz      @f
        invoke  SendMessageA,[hProgressWnd], WM_COMMAND, MR_ABORT, 0
@@:
        mov     esp, [save_stack_pointer]
        popad
        mov     eax, [exit_code]

        invoke  CloseHandle, [comp_handle]
        mov     [comp_handle], 0
        return
endp

iglobal
;  cTotalLines    db  'Total lines: ', 0
;  cAsmLines      db  'Binary code lines: ', 0

  cCompileTime db 'Total time: ',0
  cPreprocessTime db 'Preprocessing: ', 0
  cParsingTime    db 'Parsing:', 0
  cAssemblingTime db 'Assembling: ', 0
  cFormatTime     db 'Formating: ',0

  cTimeUnits   db ' seconds',0
  cCompilePasses db 'Passes: ', 0
  cCompileSize   db 'Compiled: ', 0
  cSizeUnits     db ' bytes',0
  cSummary       db 'Compilation summary:', 0
endg




proc AddCompilationStatistics
begin
        pushad

        invoke  LockWindowUpdate, [tvMessagesWin]

; Compilation summary display message:
        mov     [fmsg.link.hFileName], 0
        mov     [fmsg.type], mtInfo
        mov     [fmsg.hMessage], cSummary
        invoke  SendMessageA, [frmMsg], MWM_ADDMESSAGE, fmsg, TVI_ROOT
        mov     ebx, eax

; display times
        mov     eax, [total_time]
        sub     eax, [start_time]
        stdcall FormatTime, eax, cCompileTime
        mov     [fmsg.hMessage], eax
        invoke  SendMessageA, [frmMsg], MWM_ADDMESSAGE, fmsg, ebx
        stdcall StrDel, [fmsg.hMessage]

        push    ebx
        mov     ebx, eax

        mov     eax, [preprocess_time]
        sub     eax, [start_time]
        stdcall FormatTime, eax, cPreprocessTime
        mov     [fmsg.hMessage], eax
        invoke  SendMessageA, [frmMsg], MWM_ADDMESSAGE, fmsg, ebx
        stdcall StrDel, [fmsg.hMessage]

        mov     eax, [parsing_time]
        sub     eax, [preprocess_time]
        stdcall FormatTime, eax, cParsingTime
        mov     [fmsg.hMessage], eax
        invoke  SendMessageA, [frmMsg], MWM_ADDMESSAGE, fmsg, ebx
        stdcall StrDel, [fmsg.hMessage]

        mov     eax, [assembling_time]
        sub     eax, [parsing_time]
        stdcall FormatTime, eax, cAssemblingTime
        mov     [fmsg.hMessage], eax
        invoke  SendMessageA, [frmMsg], MWM_ADDMESSAGE, fmsg, ebx
        stdcall StrDel, [fmsg.hMessage]

        mov     eax, [formating_time]
        sub     eax, [assembling_time]
        stdcall FormatTime, eax, cFormatTime
        mov     [fmsg.hMessage], eax
        invoke  SendMessageA, [frmMsg], MWM_ADDMESSAGE, fmsg, ebx
        stdcall StrDel, [fmsg.hMessage]

        invoke  SendMessageA, [tvMessagesWin], TVM_EXPAND, TVE_COLLAPSE, ebx

        pop     ebx

        movzx   eax, [current_pass]
        inc     eax
        stdcall NumToStr, eax, ntsUnsigned or ntsDec
        mov     esi, eax
        mov     [fmsg.hMessage], eax
        stdcall StrInsert, esi, cCompilePasses, 0
        invoke  SendMessageA, [frmMsg], MWM_ADDMESSAGE, fmsg, ebx
        stdcall StrDel,esi

        stdcall NumToStr, [written_size], ntsUnsigned or ntsDec
        mov     esi, eax
        mov     [fmsg.hMessage], eax
        stdcall StrInsert, esi, cCompileSize, 0
        stdcall StrCat, esi, cSizeUnits
        invoke  SendMessageA, [frmMsg], MWM_ADDMESSAGE, fmsg, ebx
        stdcall StrDel, esi

        invoke  LockWindowUpdate, NULL

        popad
        return
endp








proc FormatTime, .time, .header
begin
        push    esi
        stdcall NumToStr, [.time], ntsUnsigned or ntsDec
        mov     esi, eax

.addzero:
        stdcall StrLen, esi
        cmp     eax, 4
        jae     .insertdot

        stdcall StrCharInsert, esi, '0', 0
        jmp     .addzero

.insertdot:
        sub     eax, 3
        stdcall StrCharInsert, esi, '.', eax
        stdcall StrInsert, esi, [.header], 0
        stdcall StrCat, esi, cTimeUnits

        mov     eax, esi
        pop     esi
        return
endp


;---------------------------------------------------------------------
; This is part of interface subroutines since FASM1.52
;---------------------------------------------------------------------
get_environment_variable:
        stdcall SearchForProjectVariable, esi, edi
        jc      .copyok
        stdcall StrPtr, [hIniFileName]
        invoke  GetPrivateProfileStringA, _section_environment, esi, path_buffer, edi, $1000, eax
.copyok:
        add     edi,eax
        retn


;**********************************************************
; Convert path wrapper for common use outside compiler.
; Returns string handle to converted name.
; returns in edx pointer to the end of the name.
;**********************************************************
proc ConvertPath, .hFileName
.res dd ?
.env rb 512
.ini rb 512
.strend dd ?
begin
        push    ebx edi esi

        stdcall StrNew
        mov     [.res], eax

        stdcall StrSetCapacity, [.res], 512
        mov     edi, eax
        add     eax, 512
        mov     [.strend], eax

        stdcall StrPtr, [.hFileName]
        mov     esi, eax

.copy_path:
        lods    byte [esi]
        cmp     al,'%'
        je      .envvariable
        stos    byte [edi]
        test    al,al
        jnz     .copy_path

        stdcall StrFixLen, [.res]

        mov     edx,edi
        mov     eax, [.res]
        pop     esi edi ebx
        return

.envvariable:
        mov     ebx,esi

.find_var_end:
        lods    byte [esi]
        or      al,al
        jz      .not_env_var
        cmp     al,'%'
        jne     .find_var_end

        mov     byte [esi-1],0

        stdcall SearchForProjectVariable, ebx, edi
        jc      .found

        stdcall StrPtr, [hIniFileName]
        push    eax     ; INI filename pointer

        lea     ecx, [.env]
        invoke  GetEnvironmentVariableA, ebx, ecx, 512
        mov     byte [.env+eax], 0
        mov     eax, [.strend]
        sub     eax,edi

        lea     ecx, [.env]
        invoke  GetPrivateProfileStringA, _section_environment, ebx, ecx, edi, eax ; the last parameter is already in the stack

.found:
        add     edi,eax
        mov     byte [esi-1],'%'
        jmp     .copy_path

.not_env_var:
        mov     al,'%'
        stos    byte [edi]
        mov     esi,ebx
        jmp     .copy_path
endp


;------------------------------------------------------------------------------------------------
; Interface routines needed by FASM code
;------------------------------------------------------------------------------------------------
;-----------------------------------------------------------------------------------------------
; Opens "virtual file" and returns pointer to the structure TVFile
; If the file is in the editor - load the virtual file from editor.
; if the file is on the disk, reads the entire file in the virtual file.
; Arguments:
;   EDX - pointer to the filename.
; Returns:
;   EBX - pointer to TVFile structure or handle of open file.
;-----------------------------------------------------------------------------------------------

open:
        cmp     [flagFakeCompile], 0
        je      .opennormal

        stdcall StrCompCase, edx, [input_file]
        jc      .openmain

.opennormal:
        stdcall CheckCash, edx
        test    eax, eax
        jnz     .openfromcash

        stdcall FileOpen, edx
        jc      .file_error

        mov     [hfile],eax
        mov     ebx, eax
        clc
        ret

.openfromcash:
        mov     ebx, eax
        stdcall VSetFilePointer, ebx, 0, FILE_BEGIN
        clc
        ret

.file_error:
        stc
        ret

.openmain:
        push    esi edi ebp

        mov     ebp, edx
        stdcall GetMem, sizeof.TVFile
        jc      .erroropenmain

        mov     [ptrMainFile], eax
        mov     edx, ebp
        mov     [eax+TVFile.hFileName], edx

        mov     ebx, eax

        stdcall CheckCash, edx
        test    eax, eax
        jnz     .copyfromcash

        stdcall LoadBinaryFile, edx
        jc      .erroropenmain

        mov     esi, eax
        mov     ebp, eax
        jmp     .copyit

.copyfromcash:
        mov     esi, [eax+TVFile.buffer]
        mov     ecx, [eax+TVFile.size]
        xor     ebp, ebp

.copyit:
        mov     [ebx+TVFile.size], ecx
        push    esi

        add     ecx, cFakeProlog.size + cFakeEpilog.size
        stdcall GetMem, ecx
        mov     [ebx+TVFile.buffer], eax
        mov     edi, eax

        mov     ecx, cFakeProlog.size
        mov     esi, cFakeProlog
        rep movsb

        pop     esi
        mov     ecx, [ebx+TVFile.size]
        rep movsb

        mov     ecx, cFakeEpilog.size
        mov     esi, cFakeEpilog
        rep movsb

        add     [ebx+TVFile.size],  cFakeProlog.size + cFakeEpilog.size
        stdcall VSetFilePointer, ebx, 0, FILE_BEGIN

        test    ebp, ebp
        jz      .endopenmain

        stdcall FreeMem, ebp

.endopenmain:
        pop     ebp edi esi
        clc
        retn

.erroropenmain:
        pop     ebp edi esi
        stc
        retn

uglobal
  flagFakeCompile dd 0
  ptrMainFile dd 0
endg


iglobal
  cFakeProlog db 'if 0', 13, 10
  .size = $ - cFakeProlog

  cFakeEpilog db 13, 10, 'end if', 13, 10
  .size = $-cFakeEpilog
endg


;________________________________________________________________________
;
; Creates file on disk and returns handle to the file.
; Arguments:
;   edx - pointer to the filename.
; Returns:
;   CF=0; ebx=file_handle -> in case the file is created.
;   CF=1 in case there is an error.
;________________________________________________________________________


create:
        stdcall FileCreate, edx
        jc      open.file_error
        mov     ebx, eax
        retn

;________________________________________________________________________________________________
;
;  Arguments:
;    ebx - handle to the file.
;    edx - pointer to a buffer with data.
;    ecx - byte count to write.
; Returns:
;   CF=0 - no error.
;   CF=1 - error.
;________________________________________________________________________________________________

write:
        stdcall FileWrite, ebx, edx, ecx
        jc      open.file_error
        retn

;________________________________________________________________________________________________
; Reads data from file or virtual file.
; Arguments:
;   ebx - file handle or pointer to TVFile strructure.
;   edx - buffer to put data.
;   ecx - bytes read count.
;________________________________________________________________________________________________

read:
        test    ebx, $ffff0000
        jnz     .readfromcash

        mov     ebp, ecx
        stdcall FileRead, ebx, edx, ecx
        jc      open.file_error

        cmp     ebp, eax
        jne     open.file_error

        clc
        retn

.readfromcash:
        mov     ebp, ecx
        stdcall VReadFile, ebx, edx, ecx
        cmp     ebp, eax
        jne     open.file_error
        clc
        retn

;------------------------------------------------------------------------------------------------

close:
        cmp     ebx, [hfile]
        jne     .close_handle
        mov     [hfile], 0

.close_handle:
        test    ebx, $ffff0000
        jnz     .closevirtual

        stdcall FileClose, ebx
        retn

.closevirtual:
        cmp     [ptrMainFile], ebx
        jne     .endclose

        mov     [ptrMainFile], 0
        stdcall FreeMem, [ebx+TVFile.buffer]
        stdcall FreeMem, ebx

.endclose:
        retn


;------------------------------------------------------------------------------------------------

lseek:
        test    ebx, $ffff0000
        jnz     .seekcash

        movzx   eax,al
        stdcall FileSeek, ebx, edx, eax
        jc      open.file_error
        retn

.seekcash:
        movzx   eax, al
        stdcall VSetFilePointer, ebx, edx, eax
        clc
        retn

;------------------------------------------------------------------------------------------------

uglobal
  strDisplay dd ?
  iLastIcon  dd ?
  hLastMsg   dd ?
endg


proc display_block
.fmsg TFreshMsg
begin
        push    ebx
        mov     byte [esi+ecx], 0

.loopskip:
        mov     edx, esi

.lineloop:
; Check for eol.
        lodsb
        test    al,al
        jz      .eol
        cmp     al,$0d
        je      .eol
        cmp     al,$0a
        je      .eol
        cmp     al,$09
        je      .eol
        cmp     al,$08
        je      .eol

        cmp     al, 5
        ja      .lineloop

.eol:
        mov     bl,al
        mov     byte [esi-1], 0

        stdcall StrCat, [strDisplay], edx

        test    bl, bl
        jz      .finish
        cmp     bl, $0d
        je      .eol2
        cmp     bl, $0a
        je      .eol2
        cmp     bl, $09
        je      .eol2
        cmp     bl, $08
        je      .eol2

        movzx   ebx, bl
        dec     ebx
        mov     [iLastIcon], ebx
        jmp     .loopskip

.eol2:
        stdcall StrPtr, [strDisplay]
        cmp     byte [eax], 0
        je      .loopskip               ; Don't append empty messages.

        push    [iLastIcon] [strDisplay]
        pop     [.fmsg.hMessage] [.fmsg.type]
        and     [.fmsg.link.hFileName], 0
        lea     eax, [.fmsg]
        invoke  SendMessageA, [frmMsg], MWM_ADDMESSAGE, eax, [hLastMsg]

        cmp     bl, $0d
        je      .cr
        cmp     bl, $0a
        je      .end
        cmp     bl, $09
        je      .set

.back:
        invoke  SendMessageA, [tvMessagesWin], TVM_GETNEXTITEM, TVGN_PARENT, [hLastMsg]
        jmp     .set
.cr:
        mov     eax, TVI_ROOT
.set:
        mov     [hLastMsg], eax
.end:
        stdcall StrPtr, [strDisplay]
        mov     byte [eax], 0
        mov     [eax+string.len], 0
        mov     [iLastIcon], -1
        jmp     .loopskip

.finish:
        pop     ebx
        return
endp




proc DisplayBlock, .hString
begin
        pushad

        stdcall StrDup, [.hString]
        push    eax

        stdcall StrPtr, eax
        mov     esi, eax

        stdcall StrLen, [.hString]
        mov     ecx, eax

        call    display_block

        stdcall StrDel  ; arg is in the stack.
        popad
        return
endp



proc AppendErrorMessage, .filename, .linenum, .parent, .emsg
.FMsg TFreshMsg
.name rb 512
.ptr  dd ?
begin
        pushad

        mov     [.FMsg.type], mtError
        push    [.linenum]
        push    [.linenum]
        pop     [.FMsg.link.pos.caretLine]
        pop     [.FMsg.link.pos.selectionLine]
        mov     [.FMsg.link.hFileName], 0
        mov     [.FMsg.link.pos.caretPosition], 1
        mov     [.FMsg.link.pos.selectionPosition], 257

        stdcall StrNew
        mov     [.FMsg.hMessage], eax
        mov     esi, eax

        cmp     [.emsg], NULL
        je      .nomessage

        stdcall StrCopy, esi, cErrorPrefix
        stdcall StrCat, esi, [.emsg]

.nomessage:
        cmp     [.filename], NULL
        je      .messageready

        stdcall StrPtr, [.filename]
        lea     edi, [.name]
        lea     ecx, [.ptr]
        invoke  GetFullPathNameA, eax, 512, edi, ecx

        mov     [.FMsg.link.hFileName], edi

        stdcall StrCat, esi, [.ptr]
        stdcall StrCat, esi, cLMiddleBracket
        stdcall NumToStr, [.linenum], ntsUnsigned or ntsDec
        stdcall StrCat, esi, eax
        stdcall StrDel, eax
        stdcall StrCat, esi, cRMiddleBracket

.messageready:
        lea     eax, [.FMsg]
        invoke  SendMessageA, [frmMsg], MWM_ADDMESSAGE, eax, [.parent]
        mov     [.ptr], eax
        stdcall StrDel, esi
        popad
        mov     eax, [.ptr]
        return
endp


iglobal
  cMsgPreprocess db 3, 'Preprocessing...',13,0
  cMsgParsing    db 3, 'Parsing...',13,0
  cMsgAssembling db 3, 'Assembling...',13,0
  cMsgFormating  db 3, 'Formating...',13,0
  cMsgDebugInfo  db 3, 'Collect debug info...',13,0

  cLMiddleBracket db ' [',0
  cRMiddleBracket db ']',0

  cErrorPrefix   db 'Error: ', 0
endg


;------------------------------------------------------------------------------------------------

fatal_error:
        call    show_display_buffer

        stdcall AppendErrorMessage, NULL, -1, TVI_ROOT    ; the error message address is in the stack.
        mov     al,0FFh
        jmp     flat_assembler.exit_program

assembler_error:
        call    show_display_buffer

        pop     esi
        mov     edi, buffer

.copymessage:
        lodsb
        stosb
        test    al,al
        jnz     .copymessage

        dec     edi
        mov     eax, ' << '
        stosd

        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      copy_symbol     ;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:

        dec     edi
        mov     eax, ' >> '
        stosd
        mov     byte [edi], 0

        mov     edi, buffer

        push    dword 0
        mov     ebx,[current_line]

        mov     ecx, TVI_ROOT

  get_error_lines:
        push    ebx
        test    byte [ebx+TIntLine.LineNumber+3], 80h       ; First if not set ???
        jz      display_error_line

        mov     edx, [ebx+TIntLine.ofsGenerator]
        cmp     word [edx+1], '__'      ; is it internal macro definition?
        jne     .notinternal

        pop     ebx

.searchdown:
        mov     ebx, [ebx+TIntLine.ofsMacroLine]
        test    byte [ebx+TIntLine.LineNumber+3], $80
        jnz     .searchdown
        push    ebx
        jmp     display_error_line

.notinternal:
        pop     ebx
        mov     edx,ebx

  find_definition_origin:
  ; check the macro name
        mov     edx,[edx+TIntLine.ofsMacroLine]
        test    byte [edx+TIntLine.LineNumber+3],80h
        jnz     find_definition_origin

        push    edx
        mov     ebx,[ebx+TIntLine.ofsSourceLine]
        jmp     get_error_lines

 display_error_line:
        pop     ebx
        test    ebx, ebx
        jz      finish_error
        mov     esi,[ebx]
        mov     eax,[ebx+4]
        stdcall AppendErrorMessage, [ebx], [ebx+4], ecx, edi
; uncomment if you want only one level of nesting error messages.
; Maybe it's interesting if the style of the message treeview
; includes TVS_SINGLEEXPAND style.
;        cmp     ecx, TVI_ROOT
;        jne     display_error_line

        xor     edi, edi
        mov     ecx, eax
        jmp     display_error_line

  finish_error:
        mov     al,2
        jmp     flat_assembler.exit_program

;------------------------------------------------------------------------------------------------

make_timestamp:
        stdcall GetTime
        retn

;------------------------------------------------------------------------------------------------

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/FormEditor.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
proc CreateFormEditor, .ptrOpenFile, .hTemplate
begin
        push    esi edi ebx

        mov     esi, [CurrentSettings]

        xor     ebx, ebx
        mov     ecx, WS_CHILD or WS_HSCROLL or WS_VSCROLL or ES_NOHIDESEL or ES_WANTRETURN
        or      ecx, [esi+TEditorSettings.AsmEditStyle]

        invoke  CreateWindowExA, WS_EX_CLIENTEDGE or WS_EX_ACCEPTFILES, cAsmEditClassName, ebx,       \
                ecx, ebx, ebx, ebx, ebx,                                                             \
                [hEditorsHost], ebx, [hInstance], ebx
        test    eax, eax
        jz      .errorcreate

        mov     edi, eax

        mov     eax, [.ptrOpenFile]
        mov     [eax+TOpenFile.hEditor], edi
        invoke  SetPropA, edi, [propOpenFileStructure], eax

; adjust the look and feel for the editor window.
        invoke  CreateFontA, [esi+TEditorSettings.FontSize], 0, 0, 0, FW_NORMAL,                 \
                            0, 0, 0, [esi+TEditorSettings.FontCharset],                         \
                            OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,           \
                            FIXED_PITCH or FF_DONTCARE, [esi+TEditorSettings.ptrFontName]
        invoke  SendMessageA, edi, WM_SETFONT, eax, ebx
        invoke  SendMessageA, edi, AEM_SETTHEME, ebx, [esi+TEditorSettings.ptrTheme]
        invoke  SendMessageA, edi, AEM_SETSYNTAXHIGHLIGHT, ebx, fasm_syntax
        invoke  SendMessageA, edi, AEM_SETPOPUPMENU, ebx, [hEditorMenu]
        invoke  SendMessageA, edi, AEM_SETBOOKMARKICON, [hBookmarkIcon], ebx

        stdcall SubclassWindow, edi, FormEditorProc

        invoke  SendMessageA, edi, CEM_LOADFILE, [.hTemplate], ebx
        test    eax, eax
        jnz     .errorload

        invoke  SendMessageA, [hEditorsHost], EHM_DOCKWINDOW, edi, dfClient

        xor     eax, eax
        pop     ebx edi esi
        return

.errorcreate:
        invoke  GetLastError
        pop     ebx edi esi
        return

.errorload:
        push    eax
        invoke  DestroyWindow, edi
        mov     [esi+TOpenFile.hEditor], ebx
        pop     eax
        pop     ebx edi esi
        return
endp


iglobal
; properties for internal use...
  property propOpenFileStructure, 'OpenFileStructure' ; This is pointer to TOpenFile structure of the edited file.
  property propWinTemplate, 'WinTemplate'
  property propVisualMode, 'VisualMode'  ; 0 - view source, 1 - view form, 2 - pure text mode.
endg


winproc FormEditorProc
begin

; prolog executed before message dispatcher
        invoke  GetPropA, [.hwnd], [propOpenFileStructure]
        mov     edi, eax

; message dispatcher
ondefault
        stc
        return

; Message handlers
;-----------------------------------------------------------------------
; Message handlers inherited from Source editor
onmessage WM_DROPFILES
onmessage WM_KEYDOWN
onmessage WM_LBUTTONDOWN
onmessage WM_RBUTTONDOWN
onmessage WM_KILLFOCUS

onmessage CCM_UPDATECCPOS
onmessage CCM_UPDATEPAPOS

onmessage WM_MEASUREITEM
onmessage WM_DRAWITEM

onmessage WM_VSCROLL
onmessage WM_HSCROLL
        stdcall SourceEditProc, [.hwnd], [.wmsg], [.wparam], [.lparam]
        return


onmessage FEM_SWITCHMODE
        invoke  GetPropA, [.hwnd], [propVisualMode]
        mov     ebx, eax
        xor     ebx, 1

; show source
        invoke  SetPropA, [.hwnd], [propVisualMode], ebx

        test    ebx, ebx
        jz      .showsource

        invoke  GetPropA, [.hwnd], [propWinTemplate]
        invoke  SetWindowPos, [eax+TWinTemplateDT.hwnd], HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE or SWP_SHOWWINDOW
        clc
        return

.showsource:
        invoke  SetFocus, [.hwnd]
        clc
        return

;-----------------------------------------------------------------------
onmessage WM_SETFOCUS
        invoke  SetPropA, [.hwnd], [propVisualMode], 0
        stc
        return

;-----------------------------------------------------------------------
onmessage WM_COMMAND
        invoke  GetParent, [.hwnd]
        invoke  SendMessageA, eax, [.wmsg], [.wparam], [.lparam]
        clc
        return

;-----------------------------------------------------------------------
onmessage CEM_LOADFILE
locals
  .formname dd ?
  .forfree  dd ?
endl
        mov     [.formname], 0  ; the name is from the loaded source.

        cmp     [.wparam], 0
        jne     .loadfile

        cmp     [edi+TOpenFile.fNeverSaved], 0
        je      .loadfile

        mov     [.formname], cFormNameNone

        stdcall ConvertPath, cBaseTemplateFile
        mov     ebx, eax
        stdcall StrPtr, ebx
        stdcall LoadBinaryFile, eax
        pushf
        stdcall StrDel, ebx
        popf
        jmp     .formloaded

cBaseTemplateFile text '%fresh%/IDE/templates/complex.asm'

; load from file
.loadfile:
        mov     eax, [.wparam]
        test    eax, eax
        jnz     @f
        mov     eax, [edi+TOpenFile.hFileName]
@@:
        stdcall StrPtr, eax
        stdcall LoadBinaryFile, eax

.formloaded:
        jnc    .loadok

; error code is in eax already
        clc
        return

.loadok:
        mov     [.forfree], eax
        mov     esi, eax

        cmp     dword [esi], ';<ff'
        jne     .errorformat

        stdcall SkipToNextLine

; Creates TWinTemplateDT for the form
        stdcall CompileSourceTemplate, esi
        mov     esi, edx
        mov     ebx, eax
        test    ebx, ebx
        jnz     .compiled

        mov     esi, [.forfree]
        jmp     .errorformat

.compiled:
        mov     [ebx+TWinTemplateDT.ptrFile], edi
        invoke  SetPropA, [.hwnd], [propWinTemplate], ebx
        stdcall CreateDesignWindow, ebx

        cmp     dword [esi], ';ff>'
        jne     .errorformat

        stdcall SkipToNextLine

.errorformat:
        invoke  SendMessageA, [.hwnd], WM_SETTEXT, 0, esi

        invoke  SendDlgItemMessageA, [hPropEditor], 101, PEM_SETCONTROL, ebx, 0
        invoke  SendDlgItemMessageA, [hPropEditor], 101, PEM_SETUPDATEPROC, 0, CreateDesignWindow
        invoke  PostMessageA, [.hwnd], FEM_SWITCHMODE, 0, 0

        cmp     [edi+TOpenFile.fNeverSaved], 0
        jne     .MRUOK
        stdcall AddToMRUList, [ptrMRUFiles], [edi+TOpenFile.hFileName]
.MRUOK:

        stdcall FreeMem, [.forfree]
        xor     eax, eax
        clc
        return



;-----------------------------------------------------------------------
onmessage _CEM_GETTEXT
        mov     ebx, [.lparam]
        test    ebx, ebx
        jz      .errortext

        mov     [ebx+TInMemoryFile.fAscii], TRUE

        invoke  GetPropA, [.hwnd], [propWinTemplate]
        test    eax, eax
        jz      .errortext

        stdcall CreateSourceTemplate, eax
        mov     esi, eax                ; string with source header.

        invoke  SendMessageA, [.hwnd], WM_GETTEXTLENGTH, 0, 0
        mov     edx, eax

        stdcall StrLen, esi
        add     edx, eax
        push    eax
        add     edx, 12

        mov     [ebx+TInMemoryFile.fileSize], edx

        add     edx, 32 ; some reserve...
        stdcall GetMem, edx
        mov     [ebx+TInMemoryFile.ptrBuffer], eax

        pop     ecx             ; length of the string
        mov     edi, eax
        mov     eax, [ebx+TInMemoryFile.fileSize]
        sub     eax, ecx
        push    eax             ; length of buffer remaining
        push    esi             ; handle of the string

        mov     eax, ';<ff'
        stosd
        mov     ax, $0a0d
        stosw

        stdcall StrPtr, esi
        mov     esi, eax

        rep movsb

        mov     eax, ';ff>'
        stosd
        mov     ax, $0a0d
        stosw

        pop     esi
        pop     ecx
        add     ecx, 2  ; reserve for terminating NULL

        invoke  SendMessageA, [.hwnd], WM_GETTEXT, ecx, edi

        stdcall StrDel, esi     ; delete temporary string.

        xor     eax, eax
        clc
        return

.errortext:
        xor     eax, eax
        inc     eax
        clc
        return


;-----------------------------------------------------------------------
onmessage _CEM_CHANGENOTIFY
        invoke  GetParent, [.hwnd]
        invoke  SendMessageA, eax, EHM_FILECHANGED, edi, 0
        clc
        return


;-----------------------------------------------------------------------
onmessage _CEM_FOCUSFILE

        invoke  GetParent, [.hwnd]
        invoke  SendMessageA, eax, EHM_FOCUSWINDOW, [.hwnd], 0
        clc
        return


;-----------------------------------------------------------------------
onmessage _CEM_CANACTION
  locals
    .aepos AEPOS
  endl
        mov     eax, [.lparam]
        cmp     eax, WM_CUT
        je      .checkcopycut
        cmp     eax, WM_COPY
        je      .checkcopycut
        cmp     eax, WM_CLEAR
        je      .checkcopycut
        cmp     eax, WM_UNDO
        je      .checkundo
        cmp     eax, EM_UNDO
        je      .checkundo
        cmp     eax, WM_PASTE
        je      .checkpaste
        xor     eax, eax
        clc
        return

.checkcopycut:

        invoke  GetPropA, [.hwnd], [propVisualMode]
        test    eax, eax
        jz      .checksource

        invoke  GetPropA, [.hwnd], [propWinTemplate]
        stdcall GetSelectionList, eax
        test    eax, eax
        jz      .exitcopycheck

        mov     eax, [eax+TArray.count]

.exitcopycheck:
        clc
        return

.checksource:
        lea     esi, [.aepos]
        invoke  SendMessageA, [.hwnd], AEM_GETPOS, esi, 0
        mov     eax, [esi+AEPOS.caretPosition]
        mov     ecx, [esi+AEPOS.caretLine]
        cmp     [esi+AEPOS.selectionPosition], eax
        jne     .can_copy
        cmp     [esi+AEPOS.selectionLine], ecx
        jne     .can_copy

        xor     eax, eax
        clc
        return

.can_copy:
        xor     eax, eax
        inc     eax
        clc
        return

.checkundo:
        invoke  SendMessageA, [.hwnd], EM_CANUNDO, 0, 0
        clc
        return

.checkpaste:
        invoke  IsClipboardFormatAvailable, CF_TEXT
        clc
        return


;-----------------------------------------------------------------------
onmessage _CEM_EDITACTION

        invoke  GetPropA, [.hwnd], [propVisualMode]
        test    eax, eax
        jnz     .formmode

.sourcemode:
        invoke  SendMessageA, [.hwnd], [.lparam], 0, 0
        clc
        return

;-------------------------------------
; Common actions for form edit mode
;-------------------------------------
.formmode:
        cmp     [.lparam], WM_COPY
        je      .copycontrol

        cmp     [.lparam], WM_CUT
        je      .cutcontrol

        cmp     [.lparam], WM_CLEAR
        je      .delcontrol

        cmp     [.lparam], WM_PASTE
        je      .pastecontrol

        clc
        return

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.pastecontrol:
  locals
    .hmem dd ?
    .ptrTarget dd ?
  endl
        invoke  IsClipboardFormatAvailable, CF_TEXT
        test    eax, eax
        jz      .endpaste

        invoke  OpenClipboard, NULL

        invoke  GetClipboardData, CF_TEXT
        test    eax, eax
        jz      .closepastecb

        mov     [.hmem], eax
        invoke  GlobalLock, eax
        mov     esi, eax

        invoke  GetPropA, [.hwnd], [propWinTemplate]
        mov     edi, eax

; search for paste target
        stdcall GetSelectionList, edi
        mov     ecx, [eax+TArray.count]
        jecxz   .compileloop

        mov     edi, [eax+TArray.array]

; Compile windows from clipboard...
.compileloop:
        stdcall CompileSourceTemplate, esi
        test    eax, eax
        jz      .endcompileloop

        mov     esi, edx
        mov     ebx, eax

        lea     ecx, [edi+TWinTemplateDT.children]
        stdcall AddArrayItems, [edi+TWinTemplateDT.children], 1
        mov     [edi+TWinTemplateDT.children], edx
        mov     [eax], ebx
        mov     [ebx+TWinTemplateDT.parent], edi

; Check for coordinates to be inside client area of the target
        mov     cx, [ebx+TWinTemplateDT.left]
        mov     dx, [ebx+TWinTemplateDT.top]

.adjustx:
        cmp     cx, [edi+TWinTemplateDT.width]
        jb      .adjusty
        sub     cx, [edi+TWinTemplateDT.width]
        jmp     .adjustx

.adjusty:
        cmp     dx, [edi+TWinTemplateDT.height]
        jb      .xyok
        sub     dx, [edi+TWinTemplateDT.height]
        jmp     .adjusty

; Creates windows instances...
.xyok:
        mov     [ebx+TWinTemplateDT.left], cx
        mov     [ebx+TWinTemplateDT.top], dx
        stdcall CreateDesignWindow, ebx
        invoke  SendMessageA, [.hwnd], AEM_SETMODIFIED, TRUE, 0
        jmp     .compileloop

.endcompileloop:
        invoke  GlobalUnlock, [.hmem]

.closepastecb:
        invoke  CloseClipboard

.endpaste:
        clc
        return

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.cutcontrol:
        invoke  SendMessageA, [.hwnd], _CEM_EDITACTION, 0, WM_COPY

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.delcontrol:
        invoke  GetPropA, [.hwnd], [propWinTemplate]
        push    eax
        stdcall GetSelectionList, eax

        mov     ebx, [eax+TArray.count]
        lea     esi, [eax+TArray.array]

.delloop:
        dec     ebx
        js      .enddel

        stdcall DestroyDesignWindow, [esi+4*ebx], TRUE
        jmp     .delloop

.enddel:
        pop     eax
        stdcall GetSizer
        invoke  SendMessageA, eax, SZM_UNSELECTALL, 0, 0
        invoke  SendMessageA, [.hwnd], AEM_SETMODIFIED, TRUE, 0
        clc
        return

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.copycontrol:
        stdcall StrNew
        mov     ebx, eax

        invoke  GetPropA, [.hwnd], [propWinTemplate]
        stdcall GetSelectionList, eax

        mov     edi, [eax+TArray.count]
        lea     esi, [eax+TArray.array]

.copyselected:
        dec     edi
        js      .endcopyloop

        stdcall CreateSourceTemplate, [esi]
        stdcall StrCat, ebx, eax
        stdcall StrDel, eax

        add     esi, 4
        jmp     .copyselected

.endcopyloop:
        stdcall StrLen, ebx
        test    eax, eax
        jz      .endcopy

        lea     esi, [eax+1]

        invoke  OpenClipboard, NULL
        test    eax, eax
        jz      .endcopy

        invoke  EmptyClipboard

        invoke  GlobalAlloc, GHND or GMEM_DDESHARE, esi
        test    eax, eax
        jz      .closecb

        mov     [.hmem], eax

        invoke  GlobalLock, eax
        mov     edi, eax

        mov     ecx, esi
        stdcall StrPtr, ebx
        mov     esi, eax
        rep movsb
        invoke  GlobalUnlock, [.hmem]

        invoke  SetClipboardData, CF_TEXT, [.hmem]

.closecb:
        invoke  CloseClipboard

.endcopy:
        stdcall StrDel, ebx
        clc
        return


;-----------------------------------------------------------------------
onmessage _CEM_GETMODIFIED
        invoke   SendMessageA, [.hwnd], AEM_GETMODIFIED, 0, 0
        clc
        return

;-----------------------------------------------------------------------
onmessage _CEM_SETMODIFIED
        invoke  SendMessageA, [.hwnd], AEM_SETMODIFIED, [.wparam], [.lparam]
        clc
        return


;-----------------------------------------------------------------------
onmessage _CEM_GETFILE
        mov     eax, edi
        clc
        return


;-----------------------------------------------------------------------
onmessage _CEM_GETASMEDIT
        mov     eax, [.hwnd]
        clc
        return

;-----------------------------------------------------------------------
onmessage WM_DESTROY
        invoke  GetPropA, [.hwnd], [propWinTemplate]
        stdcall DestroyDesignWindow, eax, TRUE
        stdcall SourceEditProc, [.hwnd], [.wmsg], [.wparam], [.lparam]
        return
endwp




;------------------------------------------------------------------------
; Several callback procedures for EnumSelections procedure "formsDT.asm"
;------------------------------------------------------------------------
proc CopySelectedVisual, .dummy, .ptrList, .hString
begin
        push    esi edi ebx

        mov     esi, [.ptrList]
        mov     ebx, [esi+TList.Count]
        mov     esi, [esi+TList.ptrItems]

.loop:
        dec     ebx
        js      .endloop

        stdcall CreateSourceTemplate, [esi]
        stdcall StrCat, [.hString], eax
        stdcall StrDel, eax

        add     esi, 4
        jmp     .loop

.endloop:
        pop     ebx edi esi
        return
endp



proc UnselectAll, .ptrWinTemplateDT
begin
        mov     eax, [.ptrWinTemplateDT]
        stdcall GetSizer
        invoke  SendMessageA, eax, SZM_UNSELECTALL, 0, 0
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/FormEditor.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
winmessage FEM_SWITCHMODE

;-------------------------------------------------
; This structure will be atached to tree item
; for message handling procedure of the window
;-------------------------------------------------
;struct TWindowProc
;  .Text       dd ?   ; Handle of the string with Window procedure.
;  .ptrBaseWin dd ?   ; pointer to TBaseWin of the window.
;ends
;
;
;struct TMessageHandle
;  .Message dd ?  ; message of the handle
;ends
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























Deleted source/Fresh.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
; _____________________________________________________________________________________________
;|                                                                                             |
;| Fresh.asm                                                                                   |
;|                                                                                             |
;| This file is the main file of:                                                              |
;|                                                                                             |
;| ..::Fresh::.. - assembler RAD IDE with built-in FASM assembler.                             |
;|                                                                                             |
;| Credits:                                                                                    |
;|   Tomasz Grysztar (aka Privalov) - for exelent work with FASM - the base for Fresh.         |
;|                                                                                             |
;| The people that contributed to the project:                                                 |
;|                                                                                             |
;|    John Found                                                                               |
;|    Fredrik Klasson (aka scientica)                                                          |
;|    Tommy Lillehagen                                                                         |
;|    Mateusz Tymek (aka decard)                                                               |
;|    Victor Loh (aka roticv)                                                                  |
;|    Yunus Sina Gulsen (aka VeSCeRa)                                                          |
;|                                                                                             |
;|    Tomasz Grysztar - FASM compiler and AsmEdit control.                                     |
;|                                                                                             |
;| Contact the authors: http:/board.flatassembler.net/                                         |
;| FASM main site:      http://www.flatassembler.net/                                          |
;|                                                                                             |
;|_____________________________________________________________________________________________|
;

include '%lib%/freshlib.inc'

@BinaryType GUI

uses kernel32, user32, gdi32, comctl32, comdlg32, ole32

LIB_MODE  equ OLD

if TargetOS eq Win32
  stack 0x10020           ; 64K stack for HtmlHelp :/
end if

options.ShowUserMessages = 0
options.ShowSkipped = 0
options.FastEnter = 0
options.CheckArguments = 0
options.ShowSizes = 1
options.DebugMode = 0


include 'version.inc'

include '../include/libs/msgutils.inc'
include '../include/libs/gui.inc'
include '../include/libs/parents.inc'
include '../include/libs/tform.inc'
include '../include/libs/templates.inc'
include '../include/libs/application.inc'
include '../include/libs/TDataGrid.inc'
include '../include/libs/buttonedit.inc'

include '../include/libs/asmedit/asmedit.inc'
include 'lister.inc'
include 'dumper.inc'
include 'designtime.inc'
include 'virtfiles.inc'
include 'resourceid.inc'
include 'projmanager.inc'
include 'Controls.inc'
include 'editorhost.inc'
include 'msgwindow.inc'
include '../include/libs/splitter.inc'
include 'propgrid.inc'
include 'MainWindow.inc'
include 'fasm/Version.inc'
include 'xref.inc'
include 'LabelsList.inc'
include 'debug.inc'
include 'debugger.inc'
include 'dbgserver.inc'
include 'propeditor.inc'
include 'filemanager.inc'
include 'FormEditor.inc'
include 'SizerClass.inc'


;;<OS INDEPENDENT SOURCES> all included files should resides here
include "%lib%/freshlib.asm"

;<OS DEPENDENT SOURCES> - at the end this list should be empty.

  include '%lib%/data/ToBeRemoved/strlibos.asm'

  include '../include/libs/asmedit/asmedit.asm'
  include '../include/libs/asmedit/syntax.asm'

  include 'errors.asm'

  include 'LabelsList.asm'
  include 'fasm.asm'

  include 'virtfiles.asm'

  include 'LabelProperties.frm.asm'
  include 'LabelsExplorer.frm.asm'
  include 'LabelInfo.frm'

  include '../include/libs/parents.asm'
  include '../include/libs/tform.asm'
  include '../include/libs/templates.asm'
  include '../include/libs/application.asm'

  include '../include/libs/giflib.asm'  ; this is the old version of giflib.

  include 'Controls.asm'
  include 'SizerClass.asm'

  include '../include/libs/TDataGrid.asm'

  include 'MainWindow.asm'

  include 'ActionEvents.asm'
  include 'actNewFile.asm'
  include 'formutils.asm'
  include 'opendialog.asm'

  include 'propeditor.asm'

  include 'projmanager.asm'

  include 'msgwindow.asm'

  include 'palette.asm'

  include '../include/libs/splitter.asm'
  include '../include/libs/buttonedit.asm'
  include 'propgrid.asm'

  include 'progresswnd.frm'

  include 'findreplace.asm'
  include 'editorhost.asm'
  include 'sourceeditor.asm'
  include 'CCList.asm'
  include 'PAHint.asm'
  include 'EmbededHelp.asm'

  include 'fileutils.asm'
  include 'mrulist.asm'

  include 'IDEparams.asm'

  include 'HelpFilesOptions.asm'

  include 'EditPath.frm'
  include 'EditPathsOptions.frm'
  include 'IDEBehaviourOptions.frm'
  include 'IDEOptions.frm'

  include 'formsDT.asm'
  include 'help.asm'

  include 'lister.asm'
  include 'dumper.asm'

  include 'dbgserver.asm'
  include 'debugger.asm'
  include 'debug.asm'

  include 'dialogs.asm'
  include 'FormEditor.asm'

  include 'filemanager.asm'
  include 'watcheditor.frm'


  include '../include/libs/msgutils.asm'
  include '../include/libs/gui.asm'

  include '../include/libs/scrollbars.asm'

  include 'EDITOptions.frm'
  include 'EditorBehaviour.frm'
  include 'EditorColors.frm'

  include 'frmStyleEditor.frm'
  include 'ProjectOptions.frm'
  include 'GraphicEditor.frm'
  include 'templates.frm'
  include 'ExternalOptions.frm'

  include 'HelpFileList.frm'

; Common initialized globals

; Standard class names
  cEditClassName          text  'EDIT'
  cStaticClassName        text  'STATIC'
  cButtonClassName        text  'BUTTON'
  cComboClassName         text  'COMBOBOX'
  cScrollClassName        text  'SCROLLBAR'
  cListboxClassName       text  'LISTBOX'

; some CommCtrl class names
  cTabClassName           text  TABCONTROL_CLASS
  cTreeViewClassName      text  TREEVIEW_CLASS
  cStatusBarClassName     text  STATUS_CLASS
  cProgressbarClassName   text  PROGRESS_CLASS
  cListviewClassName      text  LISTVIEW_CLASS


uglobal
  hInstance       dd 0  ; Instance handle for common use.
  hFreshDirectory dd 0  ; string containing Fresh directory.
  ComCtrlsFlags   INITCOMMONCONTROLSEX
endg



start:
; Main init sequence
        invoke  GetModuleHandleA,0
        mov     [hInstance],eax

; Init ALL common controls
        mov     [ComCtrlsFlags.dwSize], sizeof.INITCOMMONCONTROLSEX
        mov     [ComCtrlsFlags.dwICC], $1fff
        invoke  InitCommonControlsEx, ComCtrlsFlags

; call all "initialize" procedures in the included modules...
        InitializeAll

; Startup windows creation
        stdcall InitApplication, resAppIcon, cMainTitle

; Accelerator table creating
        invoke  CreateAcceleratorTableA, Accelerators, [Accelerators.Count]

        invoke  SetPropA, [hApplication], [propAccelerators], eax
        invoke  SetPropA, [hApplication], [propOnIdle], OnIdle

        stdcall InitMainWindow, [hApplication]  ; Create main window.
        stdcall AutoArrangeWindows

; Create the tool palette
        stdcall  OnReloadVCL, 0, [hMainWindow]

; Command line parameters.
        stdcall  ParseCommandLine

        stdcall StrNew
        mov     ebx,eax
        mov     [hFreshDirectory],eax
        stdcall StrSetCapacity, eax, MAX_PATH
        stdcall StrPtr, ebx
        invoke  GetCurrentDirectoryA, MAX_PATH, eax
        stdcall StrFixLen, ebx

; Main message loop
Run:
        call    ProcessMessages
        jc      .terminate

if defined AppLib
        invoke  SendMessageA, [hApplication], AM_ONIDLE, 0, 0
end if
        invoke  WaitMessage
        jmp     Run

.terminate:
        push    eax
        FinalizeAll
        stdcall Terminate  ; exit code from the stack.


@AllDataSection
@AllImportSection

section '.res' resource from 'images\freshnew.res' data readable

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































Deleted source/Fresh.fpr.

cannot compute difference between binary files

Deleted source/GraphicEditor.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
;<ff
Window frmGraphicEditor, 3, 0, 'TForm', '', $46000000, $200, 0, 215, 213, 328, 217, GraphEditorProc;
Window NONE, 2, 5, 'STATIC', 'Image', $5031000A, $0, 100, 0, 0, 316, 186, PaintBoxProc;
;ff>
clBackground = $808080
clOutOfImage = $808080
clBackgroundLines = $ffffff
clGridLines       = $606060


struct TGraphic
; edited image data
  .ImageDC   dd ?
  .Image     BITMAPINFOHEADER
  .ptrImage  dd ?
  .hImage    dd ?

; back buffer data
  .ScreenDC  dd ?
  .Shadow    BITMAPINFOHEADER
  .ptrShadow dd ?
  .hShadow   dd ?

; editor data
  .Zoom      dd ? ; zoom factor.
  .xBeg      dd ? ;
  .yBeg      dd ? ;
  .hBackground dd ? ; brush for the background.
ends


iglobal
  property propGraphic, 'Graphic'

  CoolToolbar GraphicToolbar,           \
    bfCheckGroup or bfWrap, actSelectTool,             \
    bfCheckGroup or bfWrap, actWandTool,               \
    bfCheckGroup or bfWrap, actPenTool,                \
    bfCheckGroup or bfWrap, actFillTool
endg



proc CreateGraphicEditor, .ptrOpenFile, .hTemplate
begin
        push    ebx esi edi

        mov     esi, [.ptrOpenFile]

        stdcall CreateForm, frmGraphicEditor, [hEditorsHost]
        test    ebx, ebx
        jz      .errorcreate

        mov     [esi+TOpenFile.hEditor], ebx
        invoke  SetPropA, ebx, [propOpenFileStructure], esi

        invoke  SendMessageA, ebx, CEM_LOADFILE, [.hTemplate], 0
        test    eax, eax
        jnz     .errorload

        invoke  SendMessageA, [hEditorsHost], EHM_DOCKWINDOW, ebx, dfClient
        xor     eax, eax
        pop     edi esi ebx
        return

.errorcreate:
        invoke  GetLastError
        pop     edi esi ebx
        return

.errorload:
        push    eax
        invoke  DestroyWindow, ebx
        pop     eax
        pop     edi esi ebx
        return
endp



;*********************************************************************
; This is window procedure for paint box for image editing.
;*********************************************************************
winproc PaintBoxProc
begin
        invoke  GetPropA, [.hwnd], [propGraphic]
        mov     edi, eax

ondefault
; never passes the messages to the static class procedure.
; uses DefWindowProc instead.
        invoke  DefWindowProcA, [.hwnd], [.wmsg], [.wparam], [.lparam]
        clc
        return


onmessage WM_SIZE
; creates new bitmap
        movsx   eax, word [.lparam+2] ; height
        movsx   ecx, word [.lparam]   ; width
        neg     eax
        mov     [edi+TGraphic.Shadow.biWidth], ecx
        mov     [edi+TGraphic.Shadow.biHeight], eax
        mov     [edi+TGraphic.Shadow.biSize], sizeof.BITMAPINFOHEADER
        mov     [edi+TGraphic.Shadow.biPlanes], 1
        mov     [edi+TGraphic.Shadow.biBitCount], 32
        mov     [edi+TGraphic.Shadow.biCompression], BI_RGB
        mov     [edi+TGraphic.Shadow.biSizeImage], 0
        mov     [edi+TGraphic.Shadow.biClrUsed], 0
        mov     [edi+TGraphic.Shadow.biClrImportant], 0
        lea     eax, [edi+TGraphic.Shadow]
        lea     ecx, [edi+TGraphic.ptrShadow]
        invoke  CreateDIBSection, [edi+TGraphic.ScreenDC], eax, DIB_RGB_COLORS, ecx, NULL, NULL
        mov     [edi+TGraphic.hShadow], eax
        invoke  SelectObject, [edi+TGraphic.ScreenDC], [edi+TGraphic.hShadow]

; delete old bitmap
        invoke  DeleteObject, eax

; Draw shadow image (back buffer)
        stdcall DrawShadow, edi

; Set scrollbar
  locals
    .sbi  SCROLLINFO
  endl
        lea     esi, [.sbi]

        mov     eax, [edi+TGraphic.Shadow.biWidth]
        xor     edx, edx
        div     [edi+TGraphic.Zoom]
        test    edx, edx
        jz      @f
        inc     eax
@@:
        mov     [esi+SCROLLINFO.nPage], eax

        mov     eax, [edi+TGraphic.Image.biWidth]
        mov     [esi+SCROLLINFO.nMax], eax

        mov     [esi+SCROLLINFO.nMin], 0
        mov     [esi+SCROLLINFO.cbSize], sizeof.SCROLLINFO
        mov     [esi+SCROLLINFO.fMask], SIF_RANGE or SIF_PAGE

        invoke  SetScrollInfo, [.hwnd], SB_HORZ, esi, TRUE

        mov     eax, [edi+TGraphic.Shadow.biHeight]
        neg     eax
        xor     edx, edx
        div     [edi+TGraphic.Zoom]
        test    edx, edx
        jz      @f
        inc     eax
@@:
        mov     [esi+SCROLLINFO.nPage], eax

        mov     eax, [edi+TGraphic.Image.biHeight]
        neg     eax
        mov     [esi+SCROLLINFO.nMax], eax

        invoke  SetScrollInfo, [.hwnd], SB_VERT, esi, TRUE

        xor     eax, eax
        clc
        return

onmessage WM_ERASEBKGND

        xor     eax, eax
        inc     eax
        clc
        return


onmessage WM_PAINT
  locals
    .ps PAINTSTRUCT
  endl

        lea     esi, [.ps]
        invoke  BeginPaint, [.hwnd], esi

        mov     eax, [edi+TGraphic.Shadow.biHeight]
        neg     eax
        invoke  BitBlt, [esi+PAINTSTRUCT.hdc], 0, 0,            \
                        [edi+TGraphic.Shadow.biWidth], eax,     \
                        [edi+TGraphic.ScreenDC], 0, 0, SRCCOPY

        invoke  EndPaint, [.hwnd], esi
        xor     eax, eax
        clc
        return


onmessage AM_INITWINDOW
; Initialization of the editor.
        stdcall GetMem, sizeof.TGraphic
        mov     edi, eax
        invoke  SetPropA, [.hwnd], [propGraphic], edi

        invoke  CreateCompatibleDC, NULL
        mov     [edi+TGraphic.ScreenDC], eax

        mov     [edi+TGraphic.Zoom], 12  ; begin zoom factor.

        clc
        return


onmessage WM_DESTROY

        invoke  DeleteDC, [edi+TGraphic.ScreenDC]
        invoke  DeleteObject, [edi+TGraphic.hShadow]
        invoke  DeleteDC, [edi+TGraphic.ImageDC]
        invoke  DeleteObject, [edi+TGraphic.hImage]

        stdcall FreeMem, edi
        clc
        return

onmessage WM_GETDLGCODE
        mov     eax, DLGC_WANTARROWS
        clc
        return

onmessage WM_HSCROLL
onmessage WM_VSCROLL
        stdcall ScrollBarMessage, [.hwnd], [.wmsg], [.wparam], NULL

        lea     ecx, [edi+TGraphic.xBeg]
        cmp     [.wmsg], WM_HSCROLL
        je      .kindok
        lea     ecx, [edi+TGraphic.yBeg]
.kindok:
        mov     [ecx], eax

        stdcall DrawShadow, edi
        invoke  RedrawWindow, [.hwnd], NULL, NULL, RDW_INVALIDATE or RDW_UPDATENOW

        xor     eax, eax
        clc
        return

endwp


uglobal
  imgTools     dd ?
  imgToolsGray dd ?
endg


;-----------------------------------------------------------------------
; Window procedure for the GraphicEditor window.
; Arguments:
;   .hwnd - handle of the window
;   .wmsg - code of the message
;   .wparam \ Parameters of the message
;   .lparam /
;-----------------------------------------------------------------------
winproc GraphEditorProc
begin

ondefault
        stc
        return


onmessage FM_AFTERCREATE
; init toolboxes and menues...
        stdcall  ImageList_LoadGif, [hInstance], resBmpGraphicTools, 16, FALSE
        mov      [imgTools], eax
        stdcall  ImageList_LoadGif, [hInstance], resBmpGraphicTools, 16, TRUE
        mov      [imgToolsGray], eax

        stdcall  CreateCoolToolbar, MainActionList, GraphicToolbar, [.hwnd], 101, [imgTools], [imgToolsGray]
        mov      ebx, eax
        stdcall  SetAlign, ebx, waTop

        clc
        return


onmessage WM_DESTROY
        invoke  ImageList_Destroy, [imgTools]
        invoke  ImageList_Destroy, [imgToolsGray]
        jmp     .ondefault


onmessage CEM_LOADFILE
  locals
    .bitmap BITMAP
    .newbitmap dd ?
  endl

        invoke  GetDlgItem, [.hwnd], 100
        invoke  GetPropA, eax, [propGraphic]
        mov     edi, eax

        invoke  CreateCompatibleDC, NULL
        mov     [edi+TGraphic.ImageDC], eax

        invoke  GetPropA, [.hwnd], [propOpenFileStructure]
        mov     ebx, eax

        mov     eax, [ebx+TOpenFile.fNeverSaved]
        mov     [.newbitmap], eax

        test    eax, eax
        jz      .trytoload

        mov     [edi+TGraphic.Image.biWidth], 640
        mov     [edi+TGraphic.Image.biHeight], -480
        jmp     .createnew

.trytoload:
        mov     eax, [.wparam]
        test    eax, eax
        jnz     .nameok

        mov     eax, [ebx+TOpenFile.hFileName]

.nameok:
        stdcall StrPtr, eax
        invoke  LoadImageA, [hInstance], eax, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION or LR_LOADFROMFILE
        test    eax, eax
        jnz     .fileloaded

        mov     eax, errLoadBmp
        clc
        return

.fileloaded:
        mov     esi, eax
        lea     eax, [.bitmap]
        invoke  GetObjectA, esi, sizeof.BITMAP, eax
        test    eax, eax
        jz      .errorload

        mov     eax, [.bitmap.bmWidth]
        mov     ecx, [.bitmap.bmHeight]
        test    ecx, ecx
        js      @f
        neg     ecx
@@:
        mov     [edi+TGraphic.Image.biWidth], eax
        mov     [edi+TGraphic.Image.biHeight], ecx

.createnew:
        mov     [edi+TGraphic.Image.biSize], sizeof.BITMAPINFOHEADER
        mov     [edi+TGraphic.Image.biPlanes], 1
        mov     [edi+TGraphic.Image.biCompression], BI_RGB
        mov     [edi+TGraphic.Image.biBitCount], 32
        mov     [edi+TGraphic.Image.biSizeImage], 0
        mov     [edi+TGraphic.Image.biClrUsed], 0
        mov     [edi+TGraphic.Image.biClrImportant], 0
        lea     eax, [edi+TGraphic.Image]
        lea     ecx, [edi+TGraphic.ptrImage]
        invoke  CreateDIBSection, [edi+TGraphic.ImageDC], eax, DIB_RGB_COLORS, ecx, NULL, NULL
        mov     [edi+TGraphic.hImage], eax
        test    eax, eax
        jnz     @f

.errorload:
        invoke  GetLastError
        clc
        return

@@:
        invoke  SelectObject, [edi+TGraphic.ImageDC], eax

; copy loaded image to the DIB section
        cmp     [.newbitmap], 0
        jne     .endload

        invoke  CreateCompatibleDC, NULL
        mov     ebx, eax
        invoke  SelectObject, ebx, esi

        mov     ecx, [edi+TGraphic.Image.biHeight]
        neg     ecx
        invoke  BitBlt, [edi+TGraphic.ImageDC], 0, 0,           \
                        [edi+TGraphic.Image.biWidth], ecx,      \
                        ebx, 0, 0, SRCCOPY

        invoke  DeleteDC, ebx
        invoke  DeleteObject, esi

        cmp     [.bitmap.bmBitsPixel], 32
        je      .endload

        mov     ecx, [edi+TGraphic.Image.biWidth]
        imul    ecx, [edi+TGraphic.Image.biHeight]
        neg     ecx

        mov     esi, [edi+TGraphic.ptrImage]

.clralpha:
        mov     eax, [esi]
        or      eax, $ff000000
        mov     [esi], eax
        add     esi, 4
        loop    .clralpha

.endload:
        xor     eax, eax
        clc
        return

onmessage _CEM_GETFILE
        invoke  GetPropA, [.hwnd], [propOpenFileStructure]
        clc
        return
endwp





proc DrawShadow, .ptrGraphic
.time dd ?
begin
        push    edi esi

        invoke  GetTickCount
        mov     [.time], eax

        mov     esi, [.ptrGraphic]

; Draw the background
        invoke  SetBkColor, [esi+TGraphic.ScreenDC], $00c0c0c0
        invoke  CreateHatchBrush, HS_FDIAGONAL, $00808080
        invoke  SelectObject, [esi+TGraphic.ScreenDC], eax
        push    eax

        mov     ecx, [esi+TGraphic.Shadow.biWidth]
        mov     edx, [esi+TGraphic.Shadow.biHeight]
        neg     edx

        invoke  PatBlt, [esi+TGraphic.ScreenDC], 0, 0, ecx, edx, PATCOPY
        invoke  SelectObject, [esi+TGraphic.ScreenDC] ; from the stack
        invoke  DeleteObject, eax

; Draw the image above the background.

; 1. Compute the width and height of the image that to be displayed on
;    the visible surface.
locals
  .srcwidth  dd ?
  .srcheight dd ?
  .dstwidth  dd ?
  .dstheight dd ?
  .zoomx     dd ?
  .zoomy     dd ?
  .ydst      dd ?
endl

        mov     eax, [esi+TGraphic.Shadow.biWidth]
        xor     edx, edx
        div     [esi+TGraphic.Zoom]
        test    edx, edx
        jz      @f
        inc     eax
@@:
        mov     ecx, eax
        add     ecx, [esi+TGraphic.xBeg]
        sub     ecx, [esi+TGraphic.Image.biWidth]
        jle     @f
        sub     eax, ecx
@@:
        mov     [.srcwidth], eax
        imul    eax, [esi+TGraphic.Zoom]
        mov     [.dstwidth], eax

        mov     eax, [esi+TGraphic.Shadow.biHeight]
        xor     edx, edx
        neg     eax
        div     [esi+TGraphic.Zoom]
        test    edx,edx
        jz      @f
        inc     eax
@@:
        mov     ecx, eax
        add     ecx, [esi+TGraphic.yBeg]
        add     ecx, [esi+TGraphic.Image.biHeight]
        jle     @f
        sub     eax, ecx
@@:
        mov     [.srcheight], eax
        imul    eax, [esi+TGraphic.Zoom]
        mov     [.dstheight], eax

        mov     edi, [esi+TGraphic.ptrShadow]  ; pointer to the row in the dest bitmap

        mov     ebx, [esi+TGraphic.ptrImage]
        mov     eax, [esi+TGraphic.yBeg]
        dec     eax
        mov     edx, [esi+TGraphic.Image.biWidth]
        shl     edx, 2
        imul    eax, edx
        add     ebx, eax        ; pointer to the row in the source bitmap

        mov     [.zoomy], 1
        mov     [.ydst], 0

; load MMX constants
        pcmpeqd   mm3, mm3        ; 1's in mm3
        pxor      mm5, mm5        ; 0's in mm5
        punpcklbw mm3, mm5        ; 00ff00ff00ff00ff

.outer:
        inc       [.ydst]
        mov       eax, [.ydst]
        cmp       eax, [.dstheight]
        jg        .endouter
        neg       eax
        cmp       eax, [esi+TGraphic.Shadow.biHeight]
        jl        .endouter

        dec       [.zoomy]
        jnz       .srcrowok

        mov       ecx, [esi+TGraphic.Zoom]
        mov       eax, [esi+TGraphic.Image.biWidth]
        mov       [.zoomy], ecx
        lea       ebx, [ebx+4*eax]

.srcrowok:
        mov       ecx, [.dstwidth]
        mov       edx, [.srcwidth]
        add       edx, [esi+TGraphic.xBeg]
        mov       [.zoomx], 1

.inner:
        dec       ecx
        js        .nextrow

        dec       [.zoomx]
        jnz       .srcok

        dec       edx

; Get the source pixel, put it to mm7 for future use.
; Get the alpha from this pixel and put it in mm2 for future use also.
        movd      mm7, [ebx+4*edx]    ; src pixel
        punpcklbw mm7, mm5            ; pixel from the source image
        mov       al, [ebx+4*edx+3]
        mov       ah, al
        shl       eax, 8
        mov       al, ah
        movd      mm2, eax

        movq      mm4, mm3        ; 00ff00ff00ff00ff
        punpcklbw mm2, mm5        ; alpha value
        psubw     mm4, mm2        ; 255 - alpha

        mov       eax, [esi+TGraphic.Zoom]
        mov       [.zoomx], eax

.srcok:
        cmp       ecx, [esi+TGraphic.Shadow.biWidth]
        jge       .inner

        movd      mm1, [edi+4*ecx] ; background pixel
        movq      mm0, mm7         ; image pixel

        punpcklbw mm1, mm5       ; from byte to word in mm1

        pmullw    mm0, mm2      ; image * alpha
        pmullw    mm1, mm4      ; background * (255-alpha)
        paddw     mm0, mm1      ; mm0 = a*i + (255-a)*b
        psrlw     mm0, 8        ; div 256 -> wrong, must be 255, but very fast... ;)
        packuswb  mm0, mm5

        movd      [edi+4*ecx], mm0

        jmp       .inner

.nextrow:
        mov       eax, [esi+TGraphic.Shadow.biWidth]
        lea       edi, [edi+4*eax]
        jmp       .outer

.endouter:
        emms

; Draw gridlines if any
        cmp      [esi+TGraphic.Zoom], 4
        jle      .finish

        mov     edi, [esi+TGraphic.ScreenDC]
        invoke  CreatePen, PS_SOLID, 0, clGridLines
        invoke  SelectObject, edi, eax
        push    eax

        xor     ebx, ebx  ; xcoor

.xloop:
        invoke  MoveToEx, edi, ebx, 0, 0
        invoke  LineTo, edi, ebx, [.dstheight]
        add     ebx, [esi+TGraphic.Zoom]
        cmp     ebx, [.dstwidth]
        jle     .xloop

        xor     ebx, ebx
.yloop:
        invoke  MoveToEx, edi, 0, ebx, 0
        invoke  LineTo, edi, [.dstwidth], ebx
        add     ebx, [esi+TGraphic.Zoom]
        cmp     ebx, [.dstheight]
        jle     .yloop

        invoke  SelectObject, edi ; from the stack
        invoke  DeleteObject, eax

.finish:
        invoke  GetTickCount
        sub     eax, [.time]

        stdcall NumToStr, eax, ntsDec or ntsUnsigned
        stdcall SetControlText, [hEditorsHost], eax
        stdcall StrDel, eax

        pop     esi edi
        return
endp



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/HelpFileList.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
;<ff
Window frmHelpList, 3, 0, 'TForm', 'Help files list', $4C80000, $110001, 0, 270, 206, 320, 210, HelpFileWinProc;
Window NONE, 0, 3, 'LISTBOX', 'Listbox', $50810541, $200, 100, 0, 0, 312, 144, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50010001, $0, 1, 90, 152, 64, 25, 0;
Window NONE, 2, 0, 'BUTTON', 'Cancel', $50010000, $0, 2, 158, 152, 64, 25, 0;
;ff>
idHelpList = 100

proc OnOpenHelpFile, .wparam, .lparam
begin
        pushad

        stdcall CreateForm, frmHelpList, [hApplication]

        mov     esi, [ptrHelpFiles]
        test    esi, esi
        jz      .finish

        cmp    [esi+TArray.count], 0
        je     .finish

        xor     edi, edi
.loop:
        stdcall StrPtr, [esi+TArray.array+4*edi]
        mov     ecx, [eax+string.len]

.loop2:
        dec     ecx
        js      .found

        cmp     byte [eax+ecx], '/'
        je      .found
        cmp     byte [eax+ecx], '\'
        jne     .loop2

.found:
        inc     ecx
        lea     eax, [eax+ecx]
        invoke  SendDlgItemMessageA, ebx, idHelpList, LB_ADDSTRING, 0, eax
        test    eax, eax
        js      .next

        invoke  SendDlgItemMessageA, ebx, idHelpList, LB_SETITEMDATA, eax, [esi+TArray.array+4*ecx]

.next:
        inc     edi
        cmp     edi, [esi+TArray.count]
        jne     .loop

        stdcall ShowModal, ebx, MSF_CENTER
        cmp     eax, MR_OK
        jne     .finish

        invoke  SendDlgItemMessageA, ebx, idHelpList, LB_GETCURSEL, 0, 0
        test    eax, eax
        js      .finish

        invoke  SendDlgItemMessageA, ebx, idHelpList, LB_GETITEMDATA, eax, 0

        stdcall SearchOneHelp, eax, 0, TRUE

.finish:
        invoke  DestroyWindow, ebx
        popad
        return
endp





winproc HelpFileWinProc
begin

ondefault
        stc
        return

onmessage WM_COMMAND
        cmp     word [.wparam+2], LBN_DBLCLK
        jne     .ondefault

        invoke  SetPropA, [.hwnd], [propModalResult], MR_OK
        xor     eax, eax
        clc
        return
endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































Deleted source/HelpFilesOptions.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
;<ff
Window frmHelpFiles, 3, 0, 'TForm', 'Helps and manuals', $46000000, $10000, 0, 307, 194, 320, 240, HelpFilesOptionsProc;
Window NONE, 0, 5, 'SysListView32', 'ListView', $50000209, $200, 200, 0, 36, 312, 177, 0;
Window NONE, 3, 3, 'TForm', 'Form', $50800000, $10000, 0, 0, 0, 312, 36, 0;
Window NONE, 0, 0, 'STATIC', '&Help files:', $50000200, $0, 0, 8, 12, 64, 19, 0;
Window NONE, 0, 0, 'BUTTON', '&Add', $50018000, $0, 100, 88, 8, 56, 19, 0;
Window NONE, 0, 0, 'BUTTON', '&Remove', $50018000, $0, 101, 152, 8, 56, 19, 0;
Window NONE, 0, 0, 'BUTTON', '&Down', $50018000, $0, 103, 264, 8, 40, 19, 0;
Window NONE, 2, 0, 'BUTTON', '&Up', $50018000, $0, 102, 216, 8, 40, 19, 0;
;ff>
; this is options dialog for the help files creation.

iglobal
  cHelpTitle  db 'Select help file:',0
  cHelpFilter db 'Help files (*.hlp; *.chm)',0,'*.hlp;*.chm',0
              db 0
endg

;-----------------------------------------------------------------------
; Window procedure for the form.
; Arguments:
;   .hwnd - handle of the window
;   .wmsg - code of the message
;   .wparam \ Parameters of the message
;   .lparam /
;-----------------------------------------------------------------------
winproc HelpFilesOptionsProc
  .str rb 1024

  .idButtonAdd  = 100
  .idButtonDel  = 101
  .idButtonUp   = 102
  .idButtonDn   = 103
  .idListView   = 200

  .lvitem LVITEM

begin

ondefault
        stc
        return

onmessage WM_COMMAND
        mov     eax, [.wparam]
        cmp     eax, .idButtonAdd
        je      .addfiles

        cmp     eax, .idButtonDel
        je      .delfile

        cmp     eax, .idButtonUp
        je      .moveup

        cmp     eax, .idButtonDn
        je      .movedn

        stc
        return

.delfile:
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETNEXTITEM, -1, LVNI_ALL or LVNI_SELECTED
        cmp     eax, -1
        je      .enddel

        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_DELETEITEM, eax, 0
        jmp     .delfile

.enddel:
        clc
        return


.addfiles:
        stdcall OpenFilesDialog, cHelpTitle, TRUE, cHelpFilter, _OnAddHelpCallback, 0, [.hwnd]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETCOLUMNWIDTH, 0, LVSCW_AUTOSIZE_USEHEADER
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETCOLUMNWIDTH, 1, LVSCW_AUTOSIZE_USEHEADER
        clc
        return

.moveup:
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETNEXTITEM, -1, LVNI_FOCUSED
        cmp     eax, -1
        je      .endmove

        test    eax, eax
        jz      .endmove

        lea     ebx, [.lvitem]
        mov     [ebx+LVITEM.iItem], eax
        mov     [ebx+LVITEM.mask], LVIF_TEXT or LVIF_STATE
        mov     [ebx+LVITEM.state], LVIS_FOCUSED or LVIS_SELECTED
        mov     [ebx+LVITEM.stateMask], LVIS_FOCUSED or LVIS_SELECTED
        mov     [ebx+LVITEM.iSubItem], 0
        lea     eax, [.str]
        mov     [ebx+LVITEM.pszText], eax
        mov     [ebx+LVITEM.cchTextMax], 1024
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETITEM, 0, ebx
        sub     [ebx+LVITEM.iItem], 1
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_INSERTITEM, 0, ebx

        add     [ebx+LVITEM.iItem], 2
        mov     [ebx+LVITEM.iSubItem], 1
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETITEM, 0, ebx
        sub     [ebx+LVITEM.iItem], 2
        mov     [ebx+LVITEM.mask], LVIF_TEXT
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETITEM, 0, ebx

        add     [ebx+LVITEM.iItem], 2
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_DELETEITEM, [ebx+LVITEM.iItem], 0
        jmp      .endmove


.movedn:
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETNEXTITEM, -1, LVNI_FOCUSED
        cmp     eax, -1
        je      .endmove

        lea     ebx, [.lvitem]
        mov     [ebx+LVITEM.iItem], eax

        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETITEMCOUNT, 0, 0
        dec     eax
        cmp     eax, [ebx+LVITEM.iItem]
        jbe     .endmove

        mov     [ebx+LVITEM.mask], LVIF_TEXT or LVIF_STATE
        mov     [ebx+LVITEM.state], LVIS_FOCUSED or LVIS_SELECTED
        mov     [ebx+LVITEM.stateMask], LVIS_FOCUSED or LVIS_SELECTED
        mov     [ebx+LVITEM.iSubItem], 0
        lea     eax, [.str]
        mov     [ebx+LVITEM.pszText], eax
        mov     [ebx+LVITEM.cchTextMax], 1024
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETITEM, 0, ebx
        add     [ebx+LVITEM.iItem], 2
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_INSERTITEM, 0, ebx

        sub     [ebx+LVITEM.iItem], 2
        mov     [ebx+LVITEM.iSubItem], 1
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETITEM, 0, ebx
        add     [ebx+LVITEM.iItem], 2
        mov     [ebx+LVITEM.mask], LVIF_TEXT
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETITEM, 0, ebx
        sub     [ebx+LVITEM.iItem], 2
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_DELETEITEM, [ebx+LVITEM.iItem], 0

.endmove:
        clc
        return

;----------------------------------------------------------------------

onmessage FM_AFTERCREATE
locals
  .lvc LVCOLUMN
endl

cTitle1 text 'Help file'
cTitle2 text 'Full path'

        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_GRIDLINES or LVS_EX_FULLROWSELECT

        lea     ebx, [.lvc]

        mov     [.lvc.mask], LVCF_FMT or LVCF_TEXT or LVCF_SUBITEM
        mov     [.lvc.fmt], LVCFMT_RIGHT
        mov     [.lvc.pszText], cTitle1
        mov     [.lvc.iSubItem], 0
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_INSERTCOLUMN, 0, ebx

        mov     [.lvc.mask], LVCF_FMT or LVCF_TEXT or LVCF_SUBITEM
        mov     [.lvc.fmt], LVCFMT_LEFT
        mov     [.lvc.pszText], cTitle2
        mov     [.lvc.iSubItem], 1

        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_INSERTCOLUMN, 1, ebx

        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETCOLUMNWIDTH, 0, LVSCW_AUTOSIZE_USEHEADER
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETCOLUMNWIDTH, 1, LVSCW_AUTOSIZE_USEHEADER

        clc
        return

onmessage OM_LOADOPTIONS
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_DELETEALLITEMS, 0, 0
        stdcall ReadSectionFromIni, [hIniFileName], cHelpSection, _OnAddHelpCallback, [.hwnd]
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETCOLUMNWIDTH, 0, LVSCW_AUTOSIZE_USEHEADER
        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_SETCOLUMNWIDTH, 1, LVSCW_AUTOSIZE_USEHEADER
        clc
        return


onmessage OM_SAVEOPTIONS
locals
  .keys   rb 4
endl
        mov     dword [.keys], 'aaa='

        stdcall GetMem, 65536   ; should be enough
        mov     edi, eax
        push    eax

        mov     [.lvitem.mask], LVIF_TEXT
        mov     [.lvitem.iSubItem], 1
        mov     [.lvitem.cchTextMax], 1024

        invoke  SendDlgItemMessageA, [.hwnd], .idListView, LVM_GETITEMCOUNT, 0, 0
        mov     esi, eax
        xor     ebx, ebx

.createloop:
        cmp     ebx, esi
        je      .endcreate

        call    .insertkey

        mov     [.lvitem.iItem], ebx
        mov     [.lvitem.pszText], edi
        lea     eax, [.lvitem]
        invoke  SendDlgItemMessageA, [.hwnd], HelpFilesOptionsProc.idListView, LVM_GETITEM, 0, eax
        stdcall StrLen, edi
        lea     edi, [edi+eax+1]
        inc     ebx
        jmp     .createloop

.endcreate:
        xor     eax, eax
        stosd

        pop     edi

        stdcall StrPtr, [hIniFileName]
        invoke  WritePrivateProfileSectionA, cHelpSection, edi, eax

        stdcall FreeMem, edi
        clc
        return

.insertkey:
        push    dword [.keys]
        pop     dword [edi]
        add     edi,4
        inc     byte [.keys+2]
        cmp     [.keys+2], 'z'
        jbe     @f
        mov     [.keys+2], 'a'
        inc     [.keys+1]
        cmp     [.keys+1], 'z'
        jbe     @f
        mov     [.keys+1], 'a'
        inc     [.keys]
        cmp     [.keys], 'z'
        jbe     @f
        mov     [.keys], 'a'
@@:
        retn
endwp


proc _OnAddHelpCallback, .hFileName, .hApplet
.lvitem LVITEM
begin
        push    ebx
        stdcall ExtractFileName, [.hFileName]
        stdcall StrExtract, [.hFileName], eax, -1
        push    eax
        stdcall StrPtr, eax

        lea     ebx, [.lvitem]
        mov     [ebx+LVITEM.mask], LVIF_TEXT
        mov     [ebx+LVITEM.iItem], 10000
        mov     [ebx+LVITEM.iSubItem], 0
        mov     [ebx+LVITEM.pszText], eax
        invoke  SendDlgItemMessageA, [.hApplet], HelpFilesOptionsProc.idListView, LVM_INSERTITEM, 0, ebx
        stdcall StrDel ; from the stack.

        mov     [ebx+LVITEM.iItem], eax
        stdcall StrPtr, [.hFileName]
        mov     [ebx+LVITEM.pszText], eax
        mov     [ebx+LVITEM.iSubItem], 1
        invoke  SendDlgItemMessageA, [.hApplet], HelpFilesOptionsProc.idListView, LVM_SETITEM, 0, ebx

        clc
        pop     ebx
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































































































































Deleted source/IDEBehaviourOptions.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
;<ff
Window frmIDEBehaviour, 3, 0, 'TForm', 'IDE options', $46000000, $10000, 0, 262, 194, 365, 240, IDEBehaviourProc;
Window NONE, 0, 0, 'BUTTON', 'Auto hide message window', $50010002, $0, 100, 16, 16, 160, 21, 0;
Window NONE, 0, 0, 'STATIC', 'Hide interval:', $50000000, $0, 0, 16, 44, 64, 16, 0;
Window NONE, 0, 0, 'EDIT', '5000', $50012082, $200, 101, 80, 40, 49, 21, 0;
Window NONE, 2, 0, 'STATIC', 'ms', $50000000, $0, 0, 132, 44, 32, 13, 0;
;ff>
idAutoHideCheck = 100
idAutoHideTime  = 101




;-----------------------------------------------------------------------
; Window procedure for the form.
; Arguments:
;   .hwnd - handle of the window
;   .wmsg - code of the message
;   .wparam \ Parameters of the message
;   .lparam /
;-----------------------------------------------------------------------
winproc IDEBehaviourProc
.buff dd ?
begin

ondefault
        stc
        return


onmessage WM_COMMAND
        cmp     word [.wparam], idAutoHideCheck
        jne     .ondefault

        cmp     word [.wparam+2], BN_CLICKED
        jne     .ondefault

        invoke  SendDlgItemMessageA, [.hwnd], idAutoHideCheck, BM_GETCHECK, 0, 0
        mov     ebx, eax
        xor     ebx, 1
        invoke  SendDlgItemMessageA, [.hwnd], idAutoHideCheck, BM_SETCHECK, ebx, 0

        invoke  GetDlgItem, [.hwnd], idAutoHideTime
        invoke  EnableWindow, eax, ebx

        clc
        return

onmessage OM_LOADOPTIONS
        mov     eax, [flagAutoHide]
        invoke  SendDlgItemMessageA, [.hwnd], idAutoHideCheck, BM_SETCHECK, eax, 0

        invoke  SetDlgItemInt, [.hwnd], idAutoHideTime, [timeAutoHide], 0
        invoke  GetDlgItem, [.hwnd], idAutoHideTime
        invoke  EnableWindow, eax, [flagAutoHide]

        clc
        return


onmessage OM_SAVEOPTIONS
        invoke  GetDlgItem, [.hwnd], idAutoHideCheck
        invoke  SendDlgItemMessageA, [.hwnd], idAutoHideCheck, BM_GETSTATE, 0, 0
        and     eax, 1
        mov     [flagAutoHide], eax
        add     eax, $30
        mov     [.buff], eax

        stdcall StrPtr, [hIniFileName]
        lea     ecx, [.buff]
        invoke  WritePrivateProfileStringA, cParamSection, cAutoHideKey, ecx, eax

        stdcall StrPtr, [hIniFileName]
        push    eax
        invoke  GetDlgItemInt, [.hwnd], idAutoHideTime, 0, 0
        mov     [timeAutoHide], eax
        stdcall NumToStr, eax, ntsUnsigned or ntsDec
        mov     ebx, eax
        stdcall StrPtr, ebx
        invoke  WritePrivateProfileStringA, cParamSection, cAutoHideTime, eax ; filename pointer from the stack
        stdcall StrDel, ebx

        clc
        return

endwp


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































Deleted source/IDEOptions.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
;<ff
Window frmMainOptions, 3, 0, 'TForm', 'IDE options', $6480000, $10001, 0, 170, 222, 460, 320, IDEOptionsWinProc;
Window NONE, 0, 1, 'SysListView32', 'ListView', $5081200C, $0, 1000, 0, 0, 128, 293, 0;
Window NONE, 3, 4, 'TForm', 'Form', $50800000, $10000, 1001, 128, 253, 324, 40, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50010001, $0, 1, 176, 8, 64, 25, 0;
Window NONE, 2, 0, 'BUTTON', 'Cancel', $50010000, $0, 2, 248, 8, 64, 25, 0;
;ff>
;***********************************************************
; This file contains routines for reading/writing/handling
; parameters of Fresh IDE
;***********************************************************

; Special OM_ messages for options applet windows.
winmessage OM_SAVEOPTIONS
winmessage OM_LOADOPTIONS

cTitleBtnEdit text '...'      ; common button text for TButtonEdit

iglobal
  cOptionsApplets dd frmIDEOptions, frmExternalOptions, frmHelpFiles, frmIDEBehaviour, 0
endg

;---------------------------------------------------
; Opens IDE options dialog.
;---------------------------------------------------
proc OnIDEOptions, .wparam, .lparam
.str rb 1024
.lvi LVITEM
.ptr dd ?
begin
        stdcall CreateForm, frmMainOptions, [hApplication]
        stdcall ShowModal, ebx, MSF_CENTER
        invoke  DestroyWindow, ebx

        stdcall CheckParams
        invoke  PostMessageA, [hMainWindow], WM_COMMAND, actReloadVCL, 0
        return
endp



;-----------------------------------------------------------------------
; Window procedure for the Options form.
; Arguments:
;   .hwnd - handle of the window
;   .wmsg - code of the message
;   .wparam \ Parameters of the message
;   .lparam /
;-----------------------------------------------------------------------
winproc IDEOptionsWinProc

  .lvi LVITEM

begin

ondefault
        stc
        return

onmessage WM_COMMAND
        cmp     word [.wparam], MR_OK
        jne     .ondefault

        invoke  GetDlgItem, [.hwnd], 1000
        mov     ebx, eax
        lea     edi, [.lvi]

        invoke  SendMessageA, ebx, LVM_GETITEMCOUNT, 0, 0
        dec     eax
        mov     [edi+LVITEM.iItem], eax

        mov     [edi+LVITEM.mask], LVIF_PARAM
        mov     [edi+LVITEM.iSubItem], 0

.itemsave:
        invoke  SendMessageA, ebx, LVM_GETITEM, 0, edi
        invoke  SendMessageA, [edi+LVITEM.lParam], OM_SAVEOPTIONS, 0, 0
        dec     [edi+LVITEM.iItem]
        jns     .itemsave

        jmp     .ondefault


onmessage WM_NOTIFY

        cmp     [.wparam], 1000
        jne     .ondefault

        mov     esi, [.lparam]
        cmp     [esi+NMHDR.code], LVN_ITEMCHANGED
        jne     .ondefault

        test    [esi+NMLISTVIEW.uChanged], LVIF_STATE
        jz      .ondefault

        mov     eax, [esi+NMLISTVIEW.uNewState]
        xor     eax, [esi+NMLISTVIEW.uOldState]
        test    eax, LVIS_FOCUSED
        jz      .ondefault

        mov     ecx, SW_SHOWNORMAL
        test    [esi+NMLISTVIEW.uNewState], LVIS_FOCUSED
        jnz     @f
        mov     ecx, SW_HIDE
@@:

; show window
        invoke  ShowWindow, [esi+NMLISTVIEW.lParam], ecx
        stdcall AlignChildren, [.hwnd]

        clc
        return


onmessage FM_AFTERCREATE
locals
  .hlv dd ?
  .rect RECT
endl
        invoke  GetDlgItem, [.hwnd], 1000
        mov     ebx, eax

        lea     eax, [.rect]
        invoke  GetClientRect, ebx, eax
        mov     eax, 64 shl 16
        mov     ax, word [.rect.right]

        invoke  SendDlgItemMessageA, [.hwnd], 1000, LVM_SETICONSPACING, 0, eax

        invoke  GetDlgItem, [.hwnd], 1000
        mov     [.hlv], eax

        stdcall ImageList_LoadGif, [hInstance], 282, 32, FALSE
        invoke  SendMessageA, [.hlv], LVM_SETIMAGELIST, LVSIL_NORMAL, eax

        xor     esi, esi
        lea     edi, [.lvi]

        mov     [edi+LVITEM.mask], LVIF_TEXT or LVIF_PARAM or LVIF_IMAGE
        mov     [edi+LVITEM.iSubItem], 0


.addloop:
        mov     ecx, [4*esi+cOptionsApplets]
        jecxz   .endadd

        stdcall CreateForm, ecx, [.hwnd]
        stdcall SetAlign, ebx, waClient

        mov     [edi+LVITEM.lParam], ebx
        stdcall GetControlText, ebx, 0
        push    eax

        stdcall StrPtr, eax
        mov     [edi+LVITEM.pszText], eax
        mov     [edi+LVITEM.iImage], esi

        invoke  SendMessageA, [.hlv], LVM_INSERTITEM, 0, edi

        stdcall StrDel ; from the stack.

        invoke  SendMessageA, ebx, OM_LOADOPTIONS, 0, 0

        inc     esi
        jmp     .addloop

.endadd:
        invoke  SendMessageA, [.hlv], LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_BORDERSELECT

        stdcall ListViewCenterIcons, [.hlv], 64

        mov     [.lvi.stateMask], TVIS_FOCUSED or TVIS_SELECTED
        mov     [.lvi.state], TVIS_FOCUSED or TVIS_SELECTED
        lea     eax, [.lvi]
        invoke  SendMessageA, [.hlv], LVM_SETITEMSTATE, 0, eax

        clc
        return

endwp




proc ButtonEditFileSelect, .hFileName, .hButtonEdit
begin
        stdcall StrPtr, [.hFileName]
        invoke  SendMessageA, [.hButtonEdit], WM_SETTEXT, 0, eax
        return
endp



proc ListViewCenterIcons, .hListView, .ystep
.lvi LVITEM
.rect RECT
.point POINT
begin
        lea     eax, [.rect]
        invoke  GetClientRect, [.hListView], eax

        invoke  SendMessageA, [.hListView], LVM_GETITEMCOUNT, 0, 0
        mov     ebx, eax

        mov     edi, [.ystep]

        imul    eax, edi
        add     eax, 16
        mov     [.point.y], eax

        mov     eax, [.rect.right]
        sar     eax, 1
        sub     eax, 16         ; for 32x32 icons
        mov     [.point.x], eax

        lea     esi, [.point]

.itemloop:
        dec     ebx
        js      .endloop

        sub     [esi+POINT.y], edi

        invoke  SendMessageA, [.hListView], LVM_SETITEMPOSITION32, ebx, esi
        jmp     .itemloop

.endloop:
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































Deleted source/LabelInfo.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
;<ff
Window frmLabelInfo, 2, 0, 'TForm', 'Cross reference', $60C0000, $10080, 0, 579, 147, 400, 240, LabelInfoWinProc;
;ff>

winproc LabelInfoWinProc
begin


ondefault
        stc
        return


onmessage FM_AFTERCREATE

        stdcall CreateForm, frmLabelProp, [.hwnd]
        stdcall SetAlign, ebx, waClient
        invoke  SetWindowLongA, ebx, GWL_ID, idLabelProp

        clc
        return


onmessage WM_CLOSE

        invoke  DestroyWindow, [.hwnd]
        clc
        return


endwp







;-----------------------------------------------------------------------

uglobal
  hLabelInfo dd ?
endg


proc OnShowXRef, .wparam, .lparam
.str rb 512
.rect RECT
begin
        stdcall WaitForCompiler

        mov     edi, [ptrPreprocessed]
        test    edi, edi
        jz      .missing_info

        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, 0, 0
        test    eax, eax
        jz      .finish

        lea     esi, [.str]
        invoke  SendMessageA, eax, AEM_GETWORDATCARET, 512, esi

        cmp     byte [esi], 0
        je      .finish

        stdcall SearchTreeExact, esi, ptrLabels
        test    eax, eax
        jz      .finish

;        test    [eax+TLabel.flags], lfDefined
;        jz      .finish

        mov     esi, eax

        cmp     [hLabelInfo], 0
        je      .prevok

        invoke  DestroyWindow, [hLabelInfo]

.prevok:

        lea     eax, [.rect]
        invoke  GetWindowRect, [hEditorsHost], eax

        sub     [.rect.right], 440
        add     [.rect.top], 32

        stdcall CreateForm, frmLabelInfo, [hEditorsHost]
        mov     [hLabelInfo], ebx
        invoke  GetDlgItem, ebx, idLabelProp
        push    eax
        invoke  GetDlgItem, eax, 1
        invoke  ShowWindow, eax, SW_HIDE
        stdcall AlignChildren ; from the stack

        invoke  SetWindowPos, ebx, 0, [.rect.right], [.rect.top], 0, 0, SWP_NOSIZE or SWP_NOZORDER or SWP_SHOWWINDOW or SWP_NOACTIVATE
        invoke  SendDlgItemMessageA, ebx, idLabelProp, LPR_DISPLAY, 0, esi

.finish:
        return

.missing_info:
        invoke  MessageBoxA, [hEditorsHost], cErrorNotCompiled, 0, MB_OK or MB_ICONINFORMATION
        jmp     .finish
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































Deleted source/LabelProperties.frm.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
;<ff
Window frmLabelProp, 3, 0, 'TForm', 'TForm window', $56000000, $10000, 0, 597, 232, 377, 318, frmLabelPropWinProc;
Window NONE, 0, 5, 'SysListView32', 'ListView', $5000800D, $200, 201, 0, 104, 369, 187, 0;
Window NONE, 3, 3, 'TForm', 'Form', $50000000, $0, 1, 0, 0, 369, 104, 0;
Window NONE, 0, 0, 'STATIC', 'Value:', $5000000B, $0, 0, 8, 4, 64, 16, 0;
Window NONE, 0, 0, 'EDIT', '', $50800884, $0, 10, 8, 20, 180, 17, 0;
Window NONE, 0, 0, 'STATIC', 'Size | Flags | type', $5000000B, $0, 0, 8, 44, 88, 16, 0;
Window NONE, 0, 0, 'EDIT', '', $50800884, $0, 11, 8, 60, 180, 17, 0;
Window NONE, 2, 0, 'STATIC', 'Reference list:', $50000000, $0, 0, 8, 88, 80, 16, 0;
;ff>


idLabelProp = 33
idXRefList = 201


winmessage LPR_DISPLAY     ; wparam = hparent - handle of string with the name of the parent label; lparam = pointer to the TLabel;


uglobal
  hXRefFont dd ?
endg


iglobal
  cXRefFont text 'Courier New'
endg


initialize InitLabelProperties
begin
        invoke  CreateFontA, -12, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN, cXRefFont
        mov     [hXRefFont], eax
        return
endp


finalize FinalizeLabelProperties
begin
        invoke  DeleteObject, [hXRefFont]
        return
endp




winproc frmLabelPropWinProc
begin

ondefault
        stc
        return


onmessage WM_NOTIFY
locals
  .dblitem LVITEM
  .line    dd ?
endl

        cmp     [.wparam], idXRefList
        jne     .ondefault

        mov     esi, [.lparam]
        cmp     [esi+NMLISTVIEW.hdr.code], LVN_ITEMACTIVATE
        jne     .ondefault

        stdcall GetMem, 2048    ; buffer for the filename
        mov     edi, eax

        lea     ebx, [.dblitem]

        mov     [ebx+LVITEM.mask], LVIF_PARAM or LVIF_TEXT
        mov     eax, [esi+NMLISTVIEW.iItem]     ; list item double clicked
        mov     [ebx+LVITEM.iItem], eax
        mov     [ebx+LVITEM.iSubItem], 2        ; file name pointer
        mov     [ebx+LVITEM.pszText], edi
        mov     [ebx+LVITEM.cchTextMax], 2000

        invoke  SendMessageA, [esi+NMLISTVIEW.hdr.hwndFrom], LVM_GETITEM, 0, ebx

        stdcall PosEditor, edi, [ebx+LVITEM.lParam]

        stdcall FreeMem, edi
        clc
        return



onmessage FM_AFTERCREATE

locals
  .col LVCOLUMN
endl
        invoke  GetDlgItem, [.hwnd], idXRefList
        mov     ebx, eax

        lea     ecx, [.col]

        mov     [ecx+LVCOLUMN.mask], LVCF_FMT or LVCF_TEXT or LVCF_WIDTH or LVCF_SUBITEM
        mov     [ecx+LVCOLUMN.fmt], LVCFMT_LEFT
        mov     [ecx+LVCOLUMN.cx], 100
        mov     [ecx+LVCOLUMN.pszText], cColumnSymbolName
        mov     [ecx+LVCOLUMN.iSubItem], 0

        invoke  SendMessageA, ebx, LVM_INSERTCOLUMN, 0, ecx

        lea     ecx, [.col]
        mov     [ecx+LVCOLUMN.mask], LVCF_FMT or LVCF_TEXT or LVCF_WIDTH or LVCF_SUBITEM
        mov     [ecx+LVCOLUMN.fmt], LVCFMT_LEFT
        mov     [ecx+LVCOLUMN.cx], 100
        mov     [ecx+LVCOLUMN.pszText], cColumnSource
        mov     [ecx+LVCOLUMN.iSubItem], 1

        invoke  SendMessageA, ebx, LVM_INSERTCOLUMN, 1, ecx

        lea     ecx, [.col]
        mov     [ecx+LVCOLUMN.mask], LVCF_FMT or LVCF_TEXT or LVCF_WIDTH or LVCF_SUBITEM
        mov     [ecx+LVCOLUMN.fmt], LVCFMT_LEFT
        mov     [ecx+LVCOLUMN.cx], 100
        mov     [ecx+LVCOLUMN.pszText], cColumnFilename
        mov     [ecx+LVCOLUMN.iSubItem], 2

        invoke  SendMessageA, ebx, LVM_INSERTCOLUMN, 2, ecx

        lea     ecx, [.col]
        mov     [ecx+LVCOLUMN.mask], LVCF_FMT or LVCF_TEXT or LVCF_WIDTH or LVCF_SUBITEM
        mov     [ecx+LVCOLUMN.fmt], LVCFMT_LEFT
        mov     [ecx+LVCOLUMN.cx], 100
        mov     [ecx+LVCOLUMN.pszText], cColumnLineNum
        mov     [ecx+LVCOLUMN.iSubItem], 3

        invoke  SendMessageA, ebx, LVM_INSERTCOLUMN, 3, ecx
        invoke  SendMessageA, ebx, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_GRIDLINES or LVS_EX_FULLROWSELECT or LVS_EX_INFOTIP
        invoke  SendMessageA, ebx, WM_SETFONT, [hXRefFont], FALSE
        clc
        return

iglobal
  cColumnSymbolName text 'Symbol'
  cColumnSource     text 'Source line'
  cColumnFilename text 'File'
  cColumnLineNum  text 'Line'
endg



onmessage LPR_DISPLAY

        invoke  GetDlgItem, [.hwnd], 1
        mov     ebx, eax

; Pointer to TLabel structure of given label.
        mov     edi, [.lparam]
        test    edi, edi
        jz      .finish

        stdcall NumToStr, [edi+TLabel.ValueLo], ntsUnsigned or ntsHex
        push    eax
        push    eax

        stdcall NumToStr, [edi+TLabel.ValueHi], ntsUnsigned or ntsHex
        stdcall StrCharInsert, eax, '$', 0
        stdcall StrCharCat, eax, ':'

        stdcall StrCat, eax     ; second from the stack
        stdcall StrDel
        push    eax

        stdcall StrPtr, eax
        invoke  SendDlgItemMessageA, ebx, 10, WM_SETTEXT, 0, eax
        stdcall StrDel ; from the stack

        movzx   eax, [edi+TLabel.DataSize]
        stdcall NumToStr, eax, ntsHex or ntsFixedWidth + 2
        mov     edx, eax
        stdcall StrCat, edx, cStrDelimiter
        movzx   eax, [edi+TLabel.flags]
        stdcall NumToStr, eax, ntsHex or ntsFixedWidth + 4
        push    eax
        stdcall StrCat, edx, eax
        stdcall StrDel ; from the stack
        stdcall StrCat, edx, cStrDelimiter
        movzx   eax, [edi+TLabel.type]
        stdcall NumToStr, eax, ntsHex or ntsFixedWidth + 2
        push    eax
        stdcall StrCat, edx, eax
        stdcall StrDel ; from the stack

        stdcall StrPtr, edx
        push    edx
        invoke  SetDlgItemTextA, ebx, 11, eax
        stdcall StrDel ; from the stack

; cross reference
        invoke  GetDlgItem, [.hwnd], idXRefList
        mov     ebx, eax

        cmp     [.wparam], 0
        jne     @f

        invoke  SendMessageA, ebx, LVM_DELETEALLITEMS, 0, 0

@@:
        mov     esi, [edi+TLabel.pXRefArray]
        test    esi, esi
        jz      .finish

        mov     ecx, [esi+TArray.count]
        test    ecx, ecx
        jz      .finish

        mov     [.count], ecx
        lea     esi, [esi+TArray.array]

locals
  .count dd ?
  .line_num dd ?
  .lvitem LVITEM
endl

.loop_xref:
        mov     ecx, [esi+TXRefInfo.ofsSource]
        add     ecx, [ptrPreprocessed]

.search_filename:
        mov     eax, [ecx+TIntLine.LineNumber]
        test    eax, eax
        jns     .direct

; the name of the macro
        mov    eax, [ecx+TIntLine.ofsGenerator]
        add    eax, [ptrPreprocessed]
        cmp    word [eax+1], '__'          ; internal macro definition... for example __UGlobalBlock or __IGlobalBlock
        je    .searchdown

        mov    ecx, [ecx+TIntLine.ofsSourceLine]
        add    ecx, [ptrPreprocessed]
        jmp   .search_filename

.searchdown:
        mov     ecx, [ecx+TIntLine.ofsMacroLine]
        add     ecx, [ptrPreprocessed]
        jmp     .search_filename

.direct:
        mov     [.line_num], eax

        mov     eax, [ecx+TIntLine.ofsGenerator]
        add     eax, [ptrPreprocessed]
        cmp     eax, [ptrPreprocessed]
        jne     .found

        stdcall StrPtr, [hStrFileName]

.found:
        push    eax     ; pointer to the filename

        mov     eax, [edi+TLabel.iName]
        add     eax, [ptrNames]

        lea     ecx, [.lvitem]
        mov     [ecx+LVITEM.mask], LVIF_PARAM or LVIF_TEXT
        mov     [ecx+LVITEM.iItem], $7fffffff
        mov     [ecx+LVITEM.iSubItem], 0
        mov     [ecx+LVITEM.pszText], eax
        mov     eax, [.line_num]
        mov     [ecx+LVITEM.lParam], eax

        invoke  SendMessageA, ebx, LVM_INSERTITEM, 0, ecx

        lea     ecx, [.lvitem]
        mov     [ecx+LVITEM.iItem], eax


        mov     eax, [esi+TXRefInfo.ofsSource]
        add     eax, [ptrPreprocessed]
        stdcall RestoreSourceLine, eax
        push    eax

        stdcall StrPtr, eax
        mov     [ecx+LVITEM.mask], LVIF_TEXT
        mov     [ecx+LVITEM.iSubItem], 1
        mov     [ecx+LVITEM.pszText], eax

        invoke  SendMessageA, ebx, LVM_SETITEMTEXT, [ecx+LVITEM.iItem], ecx

        lea     ecx, [.lvitem]

        stdcall StrDel ; from the stack

        pop     eax

        mov     [ecx+LVITEM.mask], LVIF_TEXT
        mov     [ecx+LVITEM.iSubItem], 2
        mov     [ecx+LVITEM.pszText], eax

        invoke  SendMessageA, ebx, LVM_SETITEMTEXT, [ecx+LVITEM.iItem], ecx

        lea     ecx, [.lvitem]

        stdcall NumToStr, [.line_num], ntsUnsigned or ntsDec
        push    eax
        stdcall StrPtr, eax

        mov     [ecx+LVITEM.mask], LVIF_TEXT
        mov     [ecx+LVITEM.iSubItem], 3
        mov     [ecx+LVITEM.pszText], eax

        invoke  SendMessageA, ebx, LVM_SETITEMTEXT, [ecx+LVITEM.iItem], ecx

        stdcall StrDel ; from the stack

        add     esi, sizeof.TXRefInfo
        dec     [.count]
        jnz     .loop_xref

        invoke  SendMessageA, ebx, LVM_SETCOLUMNWIDTH, 0, LVSCW_AUTOSIZE_USEHEADER
        invoke  SendMessageA, ebx, LVM_SETCOLUMNWIDTH, 1, LVSCW_AUTOSIZE_USEHEADER
        invoke  SendMessageA, ebx, LVM_SETCOLUMNWIDTH, 2, 100
        invoke  SendMessageA, ebx, LVM_SETCOLUMNWIDTH, 3, LVSCW_AUTOSIZE_USEHEADER

; add the children labels to the cross reference list
        mov    edi, [edi+TLabel.Children]
        test   edi, edi
        jz     .finish

        mov     ebx, [edi+TArray.count]
        lea     edi, [edi+TArray.array]

.children_loop:
        dec     ebx
        js      .finish

        invoke  SendMessageA, [.hwnd], LPR_DISPLAY, 1, edi
        add     edi, sizeof.TLabel
        jmp     .children_loop


.finish:
        clc
        return



endwp



iglobal
  cSizeConst    text 'const',0
  cSizeByte     text 'byte', 0
  cSizeWord     text 'word', 0
  cSizeDword    text 'dword', 0
  cSizeQword    text 'qword', 0
  cStrDelimiter text ' | ', 0
endg




; there is another similar procedure "CreateLineString" in debug.asm file.
; TODO: these two procedures should be replaced by only one with common interface.

proc RestoreSourceLine, .ptrPreprocessedLine
.char dd ?
begin
        push    esi edi ebx

        stdcall StrNew
        mov     edi, eax

        mov     esi, [.ptrPreprocessedLine]
        lea     esi, [esi+TIntLine.PreprocessedLine]

        mov     [.char], $20202020

.getloop:
        xor     eax, eax
        lodsb
        test    al, al
        jz      .eol
        cmp     al, $3b
        je      .ignore
        cmp     al, $1a         ; prefix of token
        je      .token
        cmp     al, $22         ; quoted text.
        je      .quoted

        stdcall StrCharCat, edi, eax

        cmp     al,','
        jne     .getloop

        mov     al,$20
        stdcall StrCharCat, edi, eax
        jmp     .getloop

.quoted:
        stdcall StrCharCat, edi, "'"

        lodsd                   ; length
        xor     edx, edx
        xchg    [esi+eax], edx
        stdcall StrCat, edi, esi
        xchg    [esi+eax], edx
        add     esi, eax

        stdcall StrCharCat, edi, "'"
        jmp     .getloop

.token:
        lodsb                   ; length
        xor     edx, edx
        xchg    [esi+eax], edx
        stdcall StrCat, edi, esi
        xchg    [esi+eax], edx
        add     esi, eax

        cmp     byte [esi], '['
        je      .tab
        cmp     byte [esi], $1a
        jne     .getloop

.tab:
        stdcall StrCharCat, edi, [.char]
        mov     byte [.char], $20
        jmp     .getloop

.ignore:
.eol:
        mov     eax, edi        ; string handle
        pop     ebx edi esi
        return
endp





<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/LabelsExplorer.frm.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
;<ff
Window frmBrowser, 3, 0, 'TForm', 'Labels explorer', $60D0000, $10080, 0, 158, 34, 640, 480, frmBrowserWinProc;
Window NONE, 0, 5, 'SysTreeView32', 'TreeView', $50000037, $200, 2, 0, 42, 801, 421, 0;
Window NONE, 3, 3, 'BUTTON', 'Filter', $54002007, $20, 3, 0, 0, 801, 42, GroupboxProc;
Window NONE, 0, 0, 'BUTTON', 'Structures', $50000009, $20, 101, 64, 16, 72, 17, 0;
Window NONE, 0, 0, 'BUTTON', 'Data', $50000009, $20, 102, 136, 16, 48, 17, 0;
Window NONE, 0, 0, 'BUTTON', 'Show all', $50000009, $20, 104, 256, 16, 64, 17, 0;
Window NONE, 0, 0, 'BUTTON', 'Labels', $50000009, $20, 100, 8, 16, 56, 17, 0;
Window NONE, 2, 0, 'BUTTON', 'Constants', $50000009, $20, 103, 184, 16, 72, 17, 0;
;ff>
cExplorerRoot text 'Root'

uglobal
  hLabelExplorer dd ?
endg


proc OnExplorer, .wparam, .lparam
.rect RECT
begin
        cmp     [hLabelExplorer], 0
        je      .oldwin_ok

        invoke  SendMessageA, [hLabelExplorer], WM_CLOSE, 0, 0
        mov     [hLabelExplorer], 0

.oldwin_ok:
        cmp     [ptrLabels], 0
        je      .missing_info

        lea     eax, [.rect]
        invoke  GetWindowRect, [hEditorsHost], eax

        sub     [.rect.right], 680
        add     [.rect.top], 32

        stdcall CreateForm, frmBrowser, [hEditorsHost]
        mov     [hLabelExplorer], ebx

        invoke  SetWindowPos, ebx, 0, [.rect.right], [.rect.top], 0, 0, SWP_NOSIZE or SWP_NOZORDER or SWP_SHOWWINDOW

.finish:
        return

.missing_info:
        invoke  MessageBoxA, [hEditorsHost], cErrorNotCompiled, 0, MB_OK or MB_ICONINFORMATION
        jmp     .finish
endp

iglobal
  cErrorNotCompiled text 'You must compile the source in order to use cross reference functions.'
  cErrorNotDefined  text 'This symbol is not defined. Try to compile without errors.'
endg



proc AddLabelsToTree, .tree, .parent, .ptrVarArray, .filterProc
.tvi  TVINSERTSTRUCT
begin
        push    esi ebx

        mov     eax, [.ptrVarArray]
        mov     esi, [eax]              ; pointer to TArray
        test    esi, esi
        jz      .finish

        mov     ebx, [esi+TArray.count]
        lea     esi, [esi+TArray.array]

.iteratelist:
;        cmp     [esi+TLabel.Children], 0        ; because some of the childrens
;        jne     .addit

        cmp     [.filterProc], 0
        je      .addit

        call    [.filterProc]
        jnc     .next

.addit:
        mov     eax, [.parent]
        mov     [.tvi.hParent], eax
        mov     ecx, TVI_LAST
        cmp     eax, TVI_ROOT
        jne     @f
        mov     ecx, TVI_SORT
@@:
        mov     [.tvi.hInsertAfter], ecx
        mov     [.tvi.item.mask], TVIF_TEXT or TVIF_PARAM

        mov     eax, [esi+TLabel.iName]
        add     eax, [ptrNames]
        mov     [.tvi.item.pszText], eax
        mov     [.tvi.item.lParam], esi

        lea     eax, [.tvi]
        invoke  SendMessageA, [.tree], TVM_INSERTITEM, 0, eax

        cmp     dword [esi], 0
        je      .next
        stdcall AddLabelsToTree, [.tree], eax, esi, 0

.next:
        add     esi, sizeof.TLabel
        dec     ebx
        jnz     .iteratelist

.finish:
        pop     ebx esi
        return
endp




;**************************************************************************
; frmBrowser message handling procedure.
;
;   hwnd - handle of the form window
;   wmsg     - message code
;   wparam, lparam - parameters of the message
;**************************************************************************
proc frmBrowserWinProc, .hwnd, .wmsg, .wparam, .lparam
begin
        mov     ebx, [.wmsg]
        call    JumpTo
        MessageList                                             \
        FM_AFTERCREATE, .fmaftercreate,                         \
        WM_NOTIFY,      .wmnotify,                              \
        WM_CLOSE,       .wmclose

.default:
        stc
        return

.wmclose:
        invoke  DestroyWindow, [.hwnd]
        clc
        return

.fmaftercreate:
        stdcall CreateForm, frmLabelProp, [.hwnd]
        stdcall SetAlign, ebx, waRight
        invoke  SetWindowLongA, ebx, GWL_ID, idLabelProp

        invoke  CreateWindowExA, 0, cSplitterClassName, NULL,            \
                WS_CLIPSIBLINGS or WS_CHILD,              \
                0, 0, 0, 0, [.hwnd], NULL, [hInstance], ebx
        push    eax
        invoke  SendMessageA, eax, SPM_SETCURSORS, resVSplit, resHSplit
        pop     eax
        invoke  SendMessageA, eax, SPM_SETMAXMIN, 20, 10000

        invoke  GetDlgItem, [.hwnd], 1   ; static panel
        invoke  GetDlgItem, eax, 3      ; group box
        mov     ebx, eax
        invoke  SendDlgItemMessageA, ebx, 100, BM_SETCHECK, 1, 0
        invoke  SendMessageA, ebx, WM_COMMAND, 100, 0

        invoke  SetFocus, ebx

        clc
        return

.wmnotify:
        mov     esi, [.lparam]
        cmp     [esi+NMHDR.code], TVN_SELCHANGED
        je      .selchanged

        jmp     .default

; selection of the treeview changed.
.selchanged:
; Pointer to TLabel structure of given label.
        invoke  GetDlgItem, [.hwnd], 1
        mov     ebx, eax

        mov     edi, [esi+NMTREEVIEW.itemNew.lParam]
        test    edi, edi
        jz      .finish

        invoke  SendDlgItemMessageA, [.hwnd], idLabelProp, LPR_DISPLAY, 0, edi

.finish:
        clc
        return
endp






proc GroupboxProc, .hwnd, .wmsg, .wparam, .lparam
begin
        cmp     [.wmsg], WM_COMMAND
        je      .wmcommand
.default:
        stc
        return

.wmcommand:
        movzx   eax, word [.wparam]
        cmp     eax, 100
        jl      .default
        cmp     eax, 104
        jg      .default

.update:
; Update tree-view control
        push    eax

        invoke  GetParent, [.hwnd]
        invoke  GetDlgItem, eax, 2
        mov     edi, eax
        invoke  LockWindowUpdate, edi
        invoke  SendMessageA, edi, TVM_DELETEITEM, 0, TVI_ROOT

        pop     eax

        mov     edx, procCheckForLabel
        cmp     eax, 100
        je      .filterok

        mov     edx, procCheckForStruct
        cmp     eax, 101
        je      .filterok

        mov     edx, procCheckForData
        cmp     eax, 102
        je      .filterok

        mov     edx, procCheckForConst
        cmp     eax, 103
        je      .filterok

        xor     edx, edx

.filterok:
        stdcall AddLabelsToTree, edi, TVI_ROOT, ptrLabels, edx
        invoke  LockWindowUpdate, NULL
        clc
        return
endp





;------------------------------------------------
; FILTER PROCEDURES
;------------------------------------------------

proc procCheckForLabel
begin
        test    [esi+TLabel.flags], lfCanRedefine
        jnz     .no

        test    [esi+TLabel.flags], lfOptimized
        jz      .no

        cmp     [esi+TLabel.DataSize], 0
        jne     .no

        stc
        return
.no:    clc
        return
endp


proc procCheckForStruct
begin
        cmp     [esi+TLabel.ValueLo], 0
        jne     .no
        cmp     [esi+TLabel.ValueHi], 0
        jne     .no

        test    [esi+TLabel.flags], lfOptimized
        jnz      .no

        test    [esi+TLabel.flags], lfDefined
        jz      .no

        test    [esi+TLabel.flags], lfCanRedefine
        jnz     .no

        cmp     [esi+TLabel.DataSize], 0
        jne     .no

        stc
        return
.no:    clc
        return
endp



proc procCheckForData
begin
        cmp     [esi+TLabel.DataSize], 0
        je      .no
        stc
        return

.no:    clc
        return
endp



proc procCheckForConst
begin
        test    [esi+TLabel.flags], lfCanRedefine
        jz      .no
        stc
        return
.no:    clc
        return
endp



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































Deleted source/LabelsList.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
cNamesInitialSize = 65536

uglobal
  ptrLabels dd ?        ; ptr to Root items TArray structure.
  ptrNames  dd ?        ; pointer to memory buffer with name strings

  ptrPreprocessed dd ?  ; pointer to memory with preprocessed source.
endg


proc WaitForCompiler
begin
        cmp     [comp_handle], 0
        je      .end_wait

        invoke  LoadCursorA, 0, IDC_WAIT
        invoke  SetCursor, eax
        push    eax

.wait:
        cmp     [comp_handle], 0
        je      .end_thread

        invoke  WaitForSingleObject, [comp_handle], 100
        cmp     eax, WAIT_OBJECT_0
        je      .end_thread

        stdcall ProcessMessages
        jmp     .wait

.end_thread:
        invoke  SetCursor ; from the stack

.end_wait:
        return
endp


proc FreePreprocessed
begin
        cmp     [ptrPreprocessed], 0
        je      .exit

        stdcall FreeMem, [ptrPreprocessed]
        mov     [ptrPreprocessed], 0
.exit:
        return
endp


proc CopyPreprocessedSource, .ptrFAS
begin
        pushad

        stdcall FreePreprocessed

        mov     ebx, [.ptrFAS]
        test    ebx, ebx
        jz      .exiterror

        mov     esi, [ebx+TDumpHeader.ofsPreprocessed]
        test    esi, esi
        jz      .exiterror

        add     esi, ebx
        stdcall GetMem, [ebx+TDumpHeader.lenPreprocessed]
        mov     edi, eax
        mov     [ptrPreprocessed], eax

        test    eax, eax
        jz      .exiterror

        cld

        mov     ecx, [ebx+TDumpHeader.lenPreprocessed]
        shr     ecx, 2
        rep movsd
        mov     ecx, [ebx+TDumpHeader.lenPreprocessed]
        and     ecx, 3
        rep movsb

.exitok:
        clc
        popad
        return

.exiterror:
        stc
        popad
        return
endp








proc CreateLabelsTree, .ptrFAS
.symend dd ?
.strend dd ?
.buffer rb 1024
begin
        pushad

        cmp     [ptrLabels], 0
        je      @f

        stdcall DestroyLabelsTree, [ptrLabels]
        mov     [ptrLabels], 0

@@:

; Allocate memory for label names.
        stdcall CreateMemoryStream, ptrNames, cNamesInitialSize

        mov     esi, [.ptrFAS]
        cmp     esi, 0
        je      .endofsymbols   ; there is no FAS file loaded.

        mov     edi, [esi+TDumpHeader.ofsSymbolTable]
        cmp     edi, 0
        je      .endofsymbols   ; there is no symbols table in the fas file.

        mov     ebx, [esi+TDumpHeader.lenSymbolTable]
        add     edi, esi    ; pointer to the symbol table
        add     ebx, edi    ; pointer to the end of symbol table

.symbol_loop:
        cmp     edi, ebx
        jae     .endofsymbols

; get name
        mov     edx, [edi+TIntLabel.ofsName]
        test    edx, edx
        js      .instrings

; in preprocessed source; pascal string copy
        add     edx, [esi+TDumpHeader.ofsPreprocessed]
        add     edx, esi

        movzx   ecx, byte [edx]
        mov     [.buffer+ecx], 0

.copypas:
        dec     ecx
        js      .nameok

        mov     al, [edx+ecx+1]
        cmp     al, '?'
        je      .nextlabel              ; this is internal generated label.
        mov     [.buffer+ecx], al
        jmp     .copypas


; in strings table; asciiz string;
.instrings:
        and     edx, $7fffffff
        add     edx, [esi+TDumpHeader.ofsStringTable]
        add     edx, esi
        xor     ecx, ecx

.copy:
        mov     al, byte [edx+ecx]
        mov     [.buffer+ecx], al
        inc     ecx

        cmp     al, '?'
        je      .nextlabel

        cmp     al, 0
        jne     .copy

.nameok:
        lea     eax, [.buffer]
        stdcall AddToTree, eax, ptrLabels       ; returns pointer to TLabel structure

        mov     ecx, eax

        stdcall CreateArray, sizeof.TXRefInfo
        mov     [ecx+TLabel.pXRefArray], eax

        mov     dx, [edi+TIntLabel.Flags]
        mov     [ecx+TLabel.flags], dx

        mov     dl, [edi+TIntLabel.DataSize]
        mov     [ecx+TLabel.DataSize], dl
        mov     dl, [edi+TIntLabel.type]
        mov     [ecx+TLabel.type], dl

        mov     edx, [edi+TIntLabel.SIBEx]
        mov     [ecx+TLabel.SIBEx], edx

        mov     edx, dword [edi+TIntLabel.Value]
        mov     [ecx+TLabel.ValueLo], edx

        mov     edx, dword [edi+TIntLabel.Value+4]
        mov     [ecx+TLabel.ValueHi], edx

        stdcall AddArrayItems, [ecx+TLabel.pXRefArray], 1
        mov     [ecx+TLabel.pXRefArray], edx

        mov     edx, [edi+TIntLabel.ofsDefinition]
        mov     [eax+TXRefInfo.ofsSource], edx
        mov     [eax+TXRefInfo.flags], fxrefDefinition

        mov     eax, edi
        sub     eax, esi
        sub     eax, [esi+TDumpHeader.ofsSymbolTable]
        stdcall AppendXrefList, [.ptrFAS], ecx, eax

.nextlabel:
        add     edi, sizeof.TIntLabel
        jmp     .symbol_loop

.endofsymbols:
        popad
        return
endp




proc AppendXrefList, .ptrFAS, .ptrLabel, .ofsSymbol
begin
        pushad

        mov     esi, [.ptrFAS]
        test    esi, esi
        jz      .finish

        mov     edi, [.ptrLabel]

        mov     ecx, [esi+TDumpHeader.lenXRef]
        add     esi, [esi+TDumpHeader.ofsXRef]
        add     ecx, esi

.search_loop:
        mov     eax, [esi+TIntXRef.ofsSymbol]
        cmp     eax, [.ofsSymbol]
        jne     .next_xref

; add the source line to the xref array
        stdcall AddArrayItems, [edi+TLabel.pXRefArray], 1
        mov     [edi+TLabel.pXRefArray], edx
        mov     ebx, eax

        mov     eax, [esi+TIntXRef.ofsAssembly]
        mov     edx, [.ptrFAS]
        add     eax, [edx+TDumpHeader.ofsAsmDump]
        add     eax, edx

        mov     eax, [eax+TAsmDumpElement.ofsPreprocessed]
        mov     [ebx+TXRefInfo.ofsSource], eax
        mov     [ebx+TXRefInfo.flags], 0

.next_xref:
        add     esi, sizeof.TIntXRef
        cmp     esi, ecx
        jb      .search_loop

.finish:
        popad
        return
endp




proc AddToNames, .ptrString
begin
        push    esi edi ebx

        stdcall StrLen, [.ptrString]
        lea     eax, [eax+5]
        and     al, $fc
        stdcall GetStreamRoom, ptrNames, eax

        mov     esi, [.ptrString]

        push    edi
        lea     edi, [ebx+edi]

.copyloop:
        lodsb
        stosb
        test    al, al
        jnz     .copyloop

        pop     eax
        pop     ebx edi esi
        return
endp



;---------------------------------------------------------------
; Returns:
;    eax - The name of the label without the first parent name.
;    edx - First parent.
;---------------------------------------------------------------
proc GetLabelParent, .ptrLabel
begin
        push    esi ebx

        mov     esi, [.ptrLabel]
        push    esi

        cmp     word [esi], '..'        ; Begins with ".."
        jne     .search

        add     esi, 2

.search:
        mov     al, [esi]
        test    al,al
        jz      .notfound
        cmp     al, '.'
        je      .found

        inc     esi
        jmp     .search

.found:
        mov     byte [esi], 0

        lea     eax, [esi+1]
        pop     edx

        pop     ebx esi
        return

.notfound:
        pop     eax
        xor     edx, edx

        pop     ebx esi
        return
endp


proc SearchCreateLabel, .ptrVarArray, .ptrLabel
.hash dd ?
begin
        push    esi edi ebx edx

        stdcall StrHash, [.ptrLabel]
        mov     [.hash], eax

        mov     edx, [.ptrVarArray]
        mov     esi, [edx]
        test    esi, esi
        jnz     .arrayok

        stdcall CreateArray, sizeof.TLabel
        mov     edx, [.ptrVarArray]
        mov     [edx],eax
        mov     esi, eax        ; pointer to TArray structure

        stdcall CreateArray, 8               ; Array for search tree.
        stdcall AddArrayItems, eax, 1        ; First empty element of the tree.
        mov     [esi+TArray.lparam], edx
        mov     dword [eax], 0
        mov     dword [eax+4], 0

.arrayok:
        mov     edi, [esi+TArray.lparam]         ; the parent array.
        mov     ecx, 32         ; the depth of the tree
        mov     ebx, TArray.array

.treeseek:
        xor     eax, eax
        ror     [.hash], 1
        adc     eax, 0
        lea     edx, [ebx+4*eax]

        mov     edx, [edi + edx]        ; eax is offset from the begining of the array.
        test    edx, edx
        jz      .notfound

        mov     ebx, edx
        loop    .treeseek

.found:                         ; the offset of the item is in the ebx register
        lea     eax, [edx+4*eax]  ; the last bit is in eax
        mov     eax, [edi+eax]
        lea     eax, [esi+eax]
        pop     edx ebx edi esi
        return


.addloop:
        xor     eax, eax
        ror     [.hash],1
        adc     eax, 0

.notfound:      ; edi - pointer to the tree array,  ebx - offset of the last found element.
                ; eax - 0 or 1 depending of the last bit checked. ecx - remaining bits count.
                ; edx = 0

        push    ecx eax

        stdcall AddArrayItems, [esi+TArray.lparam], 1
        mov     [esi+TArray.lparam], edx
        mov     dword [eax], 0
        mov     dword [eax+4], 0

        mov     edi, edx                ; new base for the array.
        sub     eax, edx                ; offset of the new element

        xchg    eax, [esp]              ; this is the old eax
        lea     edx, [ebx+ 4*eax]

        pop     ebx
        mov     [edi+edx], ebx          ; the new offset is properly set.

        pop     ecx
        loop    .addloop

        push    eax
        mov     edx, [edi+edx]
        lea     ebx, [edi+edx]  ; address of the last element.

        mov     ecx, [.ptrVarArray]
        stdcall AddArrayItems, [ecx], 1
        mov     [ecx], edx

        mov     esi, eax
        sub     eax, edx        ; offset of the TLabel item.

        pop     ecx
        mov     [ebx+4*ecx], eax  ; stored.

        xor     eax, eax
        mov     [esi+TLabel.Children], eax
        mov     [esi+TLabel.type], al
        mov     [esi+TLabel.flags], ax
        mov     [esi+TLabel.ValueLo], eax
        mov     [esi+TLabel.ValueHi], eax
;        mov     [esi+TLabel.ptrIntLabel], eax

; This should be the only place where the .iName and .hashName of TLabel is set.
        stdcall AddToNames, [.ptrLabel]
        mov     [esi+TLabel.iName], eax
        push    [.hash]
        pop     [esi+TLabel.hashName]

        mov     eax, esi
        pop     edx ebx edi esi
        return

endp

;------------------------------------------------------
; Returns: eax - pointer to new created TLabel
;          [hLabelName] content of the string will be
;          destroyed.
;------------------------------------------------------
proc AddToTree, .ptrLabelName, .ptrVarTree
begin
        push    esi edi ebx ecx

        mov     edi, [.ptrVarTree]
        mov     ebx, [.ptrLabelName]

;        int3
.addloop:
        stdcall GetLabelParent, ebx
        test    edx, edx
        jz      .addhere

        mov     ebx, eax
        stdcall SearchCreateLabel, edi, edx

        lea     edi, [eax+TLabel.Children]
        jmp     .addloop

.addhere:
        stdcall SearchCreateLabel, edi, eax

        pop     ecx ebx edi esi
        return
endp




proc SearchLabel, .ptrVarArray, .hLabel
.hash dd ?
begin
        push    esi edi ebx edx

        mov     edx, [.ptrVarArray]
        mov     esi, [edx]
        test    esi, esi
        jz      .notfound

        stdcall StrHash, [.hLabel]
        mov     [.hash], eax

        mov     edi, [esi+TArray.lparam]
        mov     ecx, 32         ; the depth of the tree
        mov     ebx, TArray.array

.treeseek:
        xor     eax, eax
        ror     [.hash], 1
        adc     eax, 0
        lea     edx, [ebx+4*eax]

        mov     edx, [edi + edx]        ; eax is offset from the begining of the array.
        test    edx, edx
        jz      .notfound

        mov     ebx, edx
        loop    .treeseek

.found:                         ; the offset of the item is in the ebx register
        lea     eax, [edx+4*eax]  ; the last bit of the hash in eax
        mov     eax, [edi+eax]
        lea     eax, [esi + eax]

        pop     edx ebx edi esi
        return

.notfound:
        xor     eax, eax
        pop     edx ebx edi esi
        return
endp



proc SearchTree, .hLabelName, .ptrVarTree
begin
        push    edi ebx ecx

        mov     edi, [.ptrVarTree]
        mov     ebx, [.hLabelName]

.searchloop:
        stdcall GetLabelParent, ebx
        test    edx, edx
        jz      .here

        mov     ebx, eax
        stdcall SearchLabel, edi, edx
        test    eax, eax
        jz      .finish

        lea     edi, [eax+TLabel.Children]
        jmp     .searchloop

.here:
        mov     edx, eax
        mov     eax, edi

.finish:
        pop     ecx ebx edi
        return
endp

; returns pointer to TLabel or NULL
proc SearchTreeExact, .hLabelName, .ptrVarTree
begin
        push    edi ebx ecx

        mov     edi, [.ptrVarTree]
        mov     ebx, [.hLabelName]

.searchloop:
        stdcall GetLabelParent, ebx
        test    edx, edx
        jz      .here

        mov     ebx, eax
        stdcall SearchLabel, edi, edx
        test    eax, eax
        jz      .finish

        lea     edi, [eax+TLabel.Children]
        jmp     .searchloop

.here:
        stdcall SearchLabel, edi, eax

.finish:
        pop     ecx ebx edi
        return
endp





proc DestroyLabelsTree, .ptrArray
begin
        push    esi ebx

        cmp     [hLabelExplorer], 0
        je      .oldwin_ok

        invoke  SendMessageA, [hLabelExplorer], WM_CLOSE, 0, 0
        mov     [hLabelExplorer], 0

.oldwin_ok:
        cmp     [hLabelInfo], 0
        je      .oldwin_ok2

        invoke  SendMessageA, [hLabelInfo], WM_CLOSE, 0, 0
        mov     [hLabelInfo], 0

.oldwin_ok2:

        mov     esi, [.ptrArray]
        test    esi, esi
        jz      .finish

        mov     ebx, [esi+TArray.count]
        lea     esi, [esi+TArray.array]

.clearlist:
        dec     ebx
        js      .endoflist

        cmp     dword [esi+TLabel.Children], 0
        je      .next
        stdcall DestroyLabelsTree, [esi+TLabel.Children]      ; for .Children field of the TLabel
.next:
        add     esi, sizeof.TLabel
        jmp     .clearlist

.endoflist:
        mov     ebx, [.ptrArray]
        stdcall FreeMem, [ebx+TArray.lparam]
        stdcall FreeMem, ebx

.finish:
        cmp     [ptrNames], 0
        je      .quit

        stdcall FreeMem, [ptrNames]
        mov     [ptrNames], 0

.quit:
        pop     ebx esi
        return
endp






; Doesn't work properly!
; to be fixed.
;********************************
proc ShowNotUsed
.frm TFreshMsg
begin
        push    esi edi ebx

        mov     esi, [ptrLabels]
        test    esi, esi
        jz      .finish

        mov     ebx, [esi+TArray.count]
        test    ebx, ebx
        jz      .finish

        lea     esi, [esi+TArray.array]

.valuesloop:
        test    [esi+TLabel.flags], lfCanRedefine
        jnz     .next

        test    [esi+TLabel.flags], lfDefined
        jz      .next

        test    [esi+TLabel.flags], lfUsed
        jnz     .next

        cmp     [esi+TLabel.iName], 0
        je      .next

        stdcall StrNew
        push    eax

        stdcall StrCopy, eax, cHintPrefix
        mov     ecx, [esi+TLabel.iName]
        add     ecx, [ptrNames]
        stdcall StrCat, eax, ecx
        stdcall StrCat, eax, cHintSuffix

        mov     [.frm.type], mtInfo
        mov     [.frm.link.hFileName], 0
        mov     [.frm.hMessage], eax

        lea     eax, [.frm]
        invoke  SendMessageA, [frmMsg], MWM_ADDMESSAGE, eax, 0
        stdcall StrDel ; from the stack.

.next:
        add     esi, sizeof.TLabel
        dec     ebx
        jnz     .valuesloop

.finish:
        pop     ebx edi esi
        return
endp

iglobal
  cHintPrefix db 'The label "',0
  cHintSuffix db '" is defined but not used.',0
endg

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/LabelsList.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
lfDefined               = $01
lfCanRedefine           = $02
lfIsRedefined           = $04
lfUsed                  = $08
lfPredictionUsed        = $10
lfLastUsedPrediction    = $20
lfPredictionDefined     = $40
lfLastDefinedPrediction = $80
lfOptimized             = $100

ltAbsolute = 0
ltRelocSegment = 1
ltRelocAbsolute = 2
ltRelocRelative = 3
ltReloc64       = 4
ltELF_GOT_relative = 5
ltELF_PLT_entry_address  = 6
ltELF_PLT_entry__relative = 7

struct TDumpHeader
  .signature       db 'fas',$1a
  .fasm_ver_hi     db ?
  .fasm_ver_lo     db ?
  .header_size     dw ?

  .ofsSourceName   dd ?

  .ofsCompiledName dd ?

  .ofsStringTable  dd ?
  .lenStringTable  dd ?

  .ofsSymbolTable  dd ?
  .lenSymbolTable  dd ?

  .ofsPreprocessed dd ?
  .lenPreprocessed dd ?

  .ofsAsmDump      dd ?
  .lenAsmDump      dd ?

  .ofsSections     dd ?
  .lenSections     dd ?

  .ofsXRef         dd ?
  .lenXRef         dd ?
ends



struct TIntLine
  .ofsGenerator      dd ?   ; ASCIIZ of filename (if generated from file) or PASCAL string with the name of the macros that generated this line.
  .LineNumber        dd ?   ;
  .ofsSourceLine     dd ?   ;
  .ofsMacroLine      dd ?   ; if the line was generated by macro.
  .PreprocessedLine:
ends



struct TIntLabel
  .Value         dq ?     ; Value of the label
  .Flags         dw ?     ; lf**** flags.
  .DataSize      db ?
  .type          db ?     ; lt**** values.
  .SIBEx         dd ?     ; ???
  .PassDefined   dw ?
  .PassUsed      dw ?
  .RelAddress    dd ?     ; Address of object section or external symbol to which this label is relative.
  .ofsName       dd ?     ; offset of the name in the preprocessed source or (if bit 31 is set) in string table.
  .ofsDefinition dd ?     ;
ends



struct TLabel
  .Children    dd ?    ; Pointer to TArray of TLabel structures.

  .iName       dd ?
  .hashName    dd ?
  .flags       dw ?
  .DataSize    db ?
  .type        db ?
  .SIBEx       dd ?
  .ValueLo     dd ?
  .ValueHi     dd ?
  .pXRefArray  dd ?     ; pointer to TArray of TXrefInfo

               rb 32-$+.Children
ends

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































Deleted source/Listing.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
struct TListingLine
  .ptrLine  dd ?        ; pointer to the formated line text.
  .Nesting  dd ?        ; nesting level. The color of the background of listing browser.
                        ; will depend on this in order to indicate different files.
  .ptrFile  dd ?        ; filename where generated or NULL if generated by macro.
  .LineNum  dd ?        ; line number inside the file or pointer to TListingLine if generated by macro.
ends



; Creates listing from the given FAS file.
; Puts the listing in the memory stream. ptrVarStream is a pointer to the variable containing pointer to the stream.
; Pointer to every line is placed in the array. ptrVarArray is pointer to the variable that points to the array of dwords.


proc CreateListing, .ptrVarStream, .ptrVarArray, .ptrFAS, .ptrPreprocessed
.asmlen dd ?
begin
        pushad

        stdcall CreateMemoryStream, [.ptrVarStream], $1000
        stdcall CreateArray, 4
        mov     ecx, [.ptrVarArray]
        mov     [ecx], eax

        mov     ebx, [.ptrFAS]
        mov     esi, [ebx+TDumpHeader.ofsAsmDump]
        add     esi, ebx                                ; esi - pointer to the assembler dump section of FAS file.

        mov     eax, [ebx+TDumpHeader.lenAsmDump]
        mov     [.asmlen], eax

.linesloop:
        cmp     [.asmlen], 4
        jbe     .endofdump

.notlast:
        cmp     [esi+TAsmDumpElement.extSIB+sizeof.TAsmDumpElement], 0
        jne     .nextline

        cmp     [esi+TAsmDumpElement.flagVirtual+sizeof.TAsmDumpElement], 0
        jne     .nextline

        mov     eax, dword [esi+TAsmDumpElement.ofsBinary]
        cmp     eax, dword [esi+TAsmDumpElement.ofsBinary+sizeof.TAsmDumpElement]
        je      .nextline

.thisline:
        inc     [AsmLines]

        mov     ebx, [esi+TAsmDumpElement.ofsPreprocessed]
        add     ebx, [ptrPreprocessed]

; process one line, pointed by ebx
        stdcall CreateLineString, ebx
        push    eax

.findbaseline:
        test    byte [ebx+TIntLine.LineNumber+3], $80
        jz      .lineok

        mov     eax, [ebx+TIntLine.ofsGenerator]
        add     eax, [ptrPreprocessed]
        cmp     word [eax+1], '__'      ; is it internal macro definition?
        je      .searchdown

        mov     ebx, [ebx+TIntLine.ofsSourceLine] ; get the line where the macro was invoked.
        add     ebx, [ptrPreprocessed]
        jmp     .findbaseline

.searchdown:
        mov     ebx, [ebx+TIntLine.ofsMacroLine]
        add     ebx, [ptrPreprocessed]
        test    byte [ebx+TIntLine.LineNumber+3], $80
        jnz     .searchdown

.lineok:
        mov     edi, eax

        pop     [edi+TDebugLine.strLine]

        mov     eax, dword [esi+TAsmDumpElement.Address]
        mov     edx, dword [esi+TAsmDumpElement.Address+4]
        mov     dword [edi+TDebugLine.Address], eax
        mov     dword [edi+TDebugLine.Address+4], edx

        mov     ecx, dword [ebx+TIntLine.LineNumber] ; line number.
        mov     [edi+TDebugLine.LineNum], ecx

        mov     eax, [iLastFilename]
        mov     ecx, [ebx+TIntLine.ofsGenerator]

        test    ecx, ecx
        jnz     .notmain

        mov     ecx, [input_file]
        sub     ecx, [ptrPreprocessed]

.notmain:
        add     ecx, [ptrPreprocessed]
        cmp     [ptrLastFilename], ecx
        je      .filenameok

        mov     [ptrLastFilename], ecx
        stdcall FileNameSearchAdd, ecx       ; filename, returns index in the filename array.
        mov     [iLastFilename], eax

.filenameok:
        mov     [edi+TDebugLine.iFile], eax

.nextline:
        add     esi, sizeof.TAsmDumpElement
        sub     [.asmlen], sizeof.TAsmDumpElement
        jmp     .linesloop

.endofdump:
        popad
        return
endp



proc FormatListingLine, .ptrVarStream, .ptrLine

.x    dd ?
.char dd ?

begin
        push    esi edi ebx

        stdcall GetStreamRoom, [.ptrVarStream], $1000
        push    edi                             ; this will be returned.
        add     edi, ebx

        mov     esi, [.ptrLine]
        lea     esi, [esi+TIntLine.PreprocessedLine]

        mov     [.char], $09

.getloop:
        lodsb
        test    al, al
        jz      .eol
        cmp     al, $3b
        je      .ignore
        cmp     al, $1a         ; prefix of token
        je      .token
        cmp     al, $22         ; quoted text.
        je      .quoted

        stosb
        cmp     al,','
        jne     .getloop
        mov     al,$20
        stosb
        jmp     .getloop

.quoted:
        mov     al, "'"
        stosb

        lodsd   ; length
        mov     ecx, eax
        rep movsb

        mov     al, "'"
        stosb
        jmp     .getloop

.token:
        movzx   ecx, byte [esi]
        inc     esi
        rep movsb               ; copy the token to the output string.

        cmp     byte [esi], '['
        je      .tab
        cmp     byte [esi], $1a
        jne     .getloop
.tab:
        mov     al, byte [.char]
        mov     byte [.char], $20
        stosb
        jmp     .getloop

.ignore:
        mov     al, 0

.eol:
        stosb

        sub     edi, ebx
        mov     [ebx+TMemoryStream.offset], edi

        pop     eax
        pop     ebx edi esi
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































Deleted source/MainWindow.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
        ; Global variables used from this module.
uglobal
  hMainWindow     dd 0  ; MainWindow handle.
  hMainMenu       dd 0  ; handle of main menu.
  hReopenMenu     dd 0  ; handle of the reopen submenu.
  hMainToolbar    dd 0  ; handle of main toolbar
  hIml            dd 0  ; handle of image list for the toolbar/menu
  hImlGray        dd 0  ; handle of image list for disabled buttons/menu
  hDefImageBitmap dd 0

  hIniFileName    dd 0  ; handle of the string with INI file name
endg


iglobal
  cMainTitle      text  'Fresh ', FRESH_VERSION
  cMainSeparator  text ' : '
  cHintSelectTool text 'Select tool'

  Window MainForm, wtEnd, waNone, 'TForm', cMainTitle, WS_CAPTION or WS_VISIBLE or WS_SIZEBOX or WS_SYSMENU or WS_MINIMIZEBOX or WS_CLIPCHILDREN or WS_CLIPSIBLINGS, 0, NULL, 0, 0, 0, 100, MainWindowProc
endg


;**************************************************
; Creates form for main window.
;**************************************************

proc InitMainWindow, .hOwner
begin
        xor     ebx,ebx
        stdcall CreateForm, MainForm, [.hOwner]
        mov     [hMainWindow], ebx
        return
endp

iglobal
  property propLastActivePopup, 'LastActivePopup'
endg

;**************************************************************************
; Main window message callback procedure
;**************************************************************************
proc MainWindowProc, .hwnd, .wmsg, .wparam, .lparam

.rect   RECT
.tci    TCITEM
.tbb    TToolbarButton
.ti     TOOLINFO
.mii    MENUITEMINFO
.msg    TFreshMsg
.str    rb 512

begin
        call    JumpTo
        MessageList                             \
            DM_STATUSCHANGED, .statuschanged,   \
            DM_EVENTRAISED,   .eventraised,     \
            WM_DESTROY,       .wmdestroy,       \
            AM_INITWINDOW,    .aminitwindow,    \       ; instead of WM_CREATE
            WM_COMMAND,       .command,         \
            WM_SETTINGCHANGE, .settingchange,   \
            WM_NOTIFY,        .notify,          \
            WM_SYSCOMMAND,    .syscom,          \
            WM_CLOSE,         .toapp,           \
            WM_SETTEXT,       .settitle,        \
            WM_INITMENUPOPUP, .initmenupopup,   \
            WM_SETFOCUS,      .setfocus
.default:
        stc
        return


;-----WM_SETFOCUS-------------------------------------
.setfocus:
        invoke  SetPropA, [.hwnd], [propLastActivePopup], [.wparam]
        stc
        return

;-----WM_INITMENUPOPUP--------------------------------
.initmenupopup:
        mov     eax, [.wparam]
        cmp     eax, [hReopenMenu]
        jne     .qtrue

        stdcall FillMRUMenu, [.wparam], [ptrMRUProj], FirstMRU, 1
        stdcall FillMRUMenu, [.wparam], [ptrMRUFiles], FirstMRU, 2
        jmp     .qfalse

;---- WM_SETTEXT -------------------------------------
.settitle:
        stdcall StrNew
        mov     ebx, eax
        stdcall StrCopy, ebx, cMainTitle
        cmp     [.lparam], 0
        je      .setit

        stdcall StrCat, ebx, cMainSeparator
        stdcall StrCat, ebx, [.lparam]

.setit:
        stdcall StrPtr, ebx
        invoke  DefWindowProcA, [.hwnd], WM_SETTEXT, 0, eax
        stdcall StrDel, ebx
        clc
        return

;---- WM_SYSCOMMAND ----------------------------------
.syscom:
        mov     eax, [.wparam]
        and     eax, $fff0

        cmp     eax, SC_MAXIMIZE
        jz      .toapp
        cmp     eax, SC_MINIMIZE
        jz      .toapp

        cmp     eax, SC_RESTORE
        jnz     .default

.toapp:
        invoke  GetWindow, [.hwnd], GW_OWNER
        invoke  SendMessageA, eax, [.wmsg], [.wparam], [.lparam]
        clc
        return

;--- WM_NOTIFY ------------------------------------------------

.notify:
        mov     edi, [.lparam]
        mov     ebx, [edi+NMHDR.code]
        call    JumpTo
        MessageList                             \
            TTN_NEEDTEXT,    .tooltipneedtext,  \
            TCN_SELCHANGE,   .plt_selchange,    \
            TCN_SELCHANGING, .plt_selchanging,  \
            TBN_DROPDOWN,    .dropdown
        jmp     .default

; Opens drop-down menu for reopen files.
.dropdown:
        lea     ebx, [.rect]
        invoke  SendMessageA, [edi+NMHDR.hwndFrom], TB_COMMANDTOINDEX, [edi+NMTOOLBAR.iItem], 0
        invoke  SendMessageA, [edi+NMHDR.hwndFrom], TB_GETITEMRECT, eax, ebx
        invoke  ClientToScreen, [edi+NMHDR.hwndFrom], ebx
        add     ebx, 8
        invoke  ClientToScreen, [edi+NMHDR.hwndFrom], ebx
        invoke  TrackPopupMenu, [hReopenMenu], TPM_LEFTALIGN, [.rect.left], [.rect.bottom], 0, [.hwnd], NULL
        jmp     .qfalse

.tooltipneedtext:
; Force main window at the top.
        invoke  SetWindowPos, [.hwnd], HWND_TOP, eax, eax, eax, eax, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE

; Get hint text for toolbars.
        lea     eax, [.ti]
        mov     [.ti.cbSize], sizeof.TOOLINFO
        invoke  SendMessageA, [edi+NMHDR.hwndFrom], TTM_GETCURRENTTOOL, 0, eax

        mov     eax, [.ti.hwnd]
        cmp     eax, [hMainToolbar]
        je      .maintoolbar

        lea     eax, [.tbb]
        mov     ecx, [edi+NMHDR.idFrom]
        inc     ecx                             ; index of the button is ID+1, because of the separator.

        invoke  SendMessageA, [.ti.hwnd], TB_GETBUTTON, ecx, eax

        mov     ecx, cHintSelectTool
        mov     eax, [.tbb.dwData]
        and     eax, $7fffffff
        test    eax, eax
        jz      @f

        mov     ecx, [eax+TDesignTimeInfo.ControlHint]
@@:
        mov     [edi+TOOLTIPTEXT.lpszText], ecx
        mov     [edi+TOOLTIPTEXT.hinst], 0
        jmp     .qfalse


.maintoolbar:
        mov     eax, [edi+NMHDR.idFrom]
        sub     eax, FirstID
        stdcall GetHintText, MainActionList, eax
        mov     [edi+TOOLTIPTEXT.lpszText], eax
        mov     [edi+TOOLTIPTEXT.hinst], 0
        jmp     .qfalse

; Tool palette tab control, selection changed.
.plt_selchange:
        invoke  SendMessageA, [edi+NMHDR.hwndFrom], TCM_GETCURSEL, 0, 0
        mov     [.tci.mask], TCIF_PARAM
        lea     ebx, [.tci]
        invoke  SendMessageA, [edi+NMHDR.hwndFrom], TCM_GETITEM, eax, ebx

        invoke  ShowWindow, [.tci.lParam], SW_SHOWNORMAL
        invoke  SendMessageA, [.tci.lParam], TB_CHECKBUTTON, 0, TRUE

        stdcall AlignChildren, [edi+NMHDR.hwndFrom]
        jmp     .qfalse

.plt_selchanging:
        invoke  SendMessageA, [edi+NMHDR.hwndFrom], TCM_GETCURSEL, 0, 0
        lea     ebx, [.tci]
        mov     [.tci.mask], TCIF_PARAM
        invoke  SendMessageA, [edi+NMHDR.hwndFrom], TCM_GETITEM, eax, ebx
        invoke  ShowWindow, [.tci.lParam], SW_HIDE
        jmp     .qfalse


;-- WM_DISPLAYCHANGE ------------------------------------------
.settingchange:
        stdcall AutoArrangeWindows
        xor     eax,eax
        clc
        return

;--------- AM_INITWINDOW -------------------------------------------
.aminitwindow:
; Crete string with the filename of the INI file.

        lea     ebx, [.str]
        invoke  GetModuleFileNameA, NULL, ebx, 512
        mov     ecx, eax

.findloop:
        dec     eax
        js      .notfound

        cmp     byte [ebx+eax], '.'
        je      .found
        jmp     .findloop

.notfound:
        mov     eax, ecx
.found:
        mov     dword [ebx+eax], '.ini'
        mov     byte [ebx+eax+4], 0

        lea     esi, [eax+16]

        stdcall StrDup, ebx
        mov     [hIniFileName], eax

; Create image lists for toolbar and menus
        stdcall ImageList_LoadGif, [hInstance], resBmpAll, 16, FALSE
        mov     [hIml], eax

        stdcall ImageList_LoadGif, [hInstance], resBmpAll, 16, TRUE
        mov     [hImlGray],eax

; Create main menu
        stdcall CreateCoolMenu, MainMenu, FALSE
        mov     [hMainMenu], eax
        invoke  SetMenu, [.hwnd], [hMainMenu]

        invoke  GetSubMenu, [hMainMenu], 0      ; Get file menu
        invoke  GetSubMenu, eax, 3              ; Get reopen menu
        mov     [hReopenMenu], eax

; Create the main toolbar
        stdcall CreateCoolToolbar, MainActionList, MainToolbar, [.hwnd], $2000, [hIml], [hImlGray]
        mov     [hMainToolbar],eax
        stdcall SetAlign, eax, waTop

; Set Main window icon.
        invoke  LoadImageA, [hInstance], resMainIcon, IMAGE_ICON, 0, 0, 0
        invoke  SendMessageA, [.hwnd], WM_SETICON, ICON_SMALL, eax

; Set this window as main form for the application.
        invoke  SetPropA, [hApplication], [propMainForm], [.hwnd]

; Init of the windows and systems in the application...
        mov     [passes_limit], $80

        stdcall InitEditorHost, [hApplication]
        stdcall InitMessageWindow
        stdcall CheckParams

        stdcall InitSourceEditor  ; Create source editor.
        stdcall InitDumperWindow, [frmMsg]
        stdcall InitListerWindow, [hEditorsHost]

        stdcall InitPropEditor, [hApplication]  ; Create property editor
        stdcall InitProjectManager              ; Create project manager

        stdcall InitFileManager

        stdcall InitFindOptions
        stdcall InitHelp

        jmp     .qfalse



;---------- WM_DESTROY ------------------------------------
.wmdestroy:
        cmp     [comp_handle], 0
        je      @f

        invoke  TerminateThread, [comp_handle], 0
        invoke  CloseHandle, [comp_handle]
        mov     [comp_handle], 0
@@:
        invoke  DestroyWindow, [hEditorsHost]
        stdcall FinalizeSourceEditor
        stdcall FinalizeProjectManager
        stdcall CloseFileManager

        stdcall DestroyToolPalette

        stdcall DestroyLabelsTree, [ptrLabels]
        mov     [ptrLabels], 0

        stdcall ClearDebugInfo
        stdcall FreePreprocessed

        invoke  DestroyWindow, [hFindHistory]

        invoke  ImageList_Destroy,[hIml]
        invoke  ImageList_Destroy,[hImlGray]

        invoke  SendMessageA, [.hwnd], WM_GETICON, TRUE, 0
        invoke  DestroyIcon, eax
        invoke  SendMessageA, [.hwnd], WM_GETICON, FALSE, 0
        invoke  DestroyIcon, eax

        invoke  DeleteObject, [hDefImageBitmap]
        invoke  DestroyMenu, [hMainMenu]

        stdcall StrDel, [hIniFileName]

        jmp     .qfalse

;---------- WM_COMMAND -----------------------
.command:
; Return the control to the last window if the command is invoked from
; main window toolbar.

        invoke  GetFocus

.search:
        mov     ebx, eax
        invoke  GetParent, ebx
        test    eax, eax
        jnz     .search

        cmp     ebx, [.hwnd]
        jne     @f

        invoke  GetPropA, [.hwnd], [propLastActivePopup]
        test    eax, eax
        jz      @f

        invoke  SetFocus, eax

@@:
        movzx   esi,word [.wparam]
        cmp     esi, FirstID
        jl      .maybeMRU

        sub     esi,FirstID
        cmp     esi,[MainActionList.Number]
        jge     .default

        imul    esi,sizeof.TAction
        add     esi,MainActionList

        xor     eax,eax
        cmp     [esi+TAction.OnExecute],eax
        je      .qfalse

        stdcall [esi+TAction.OnExecute], [.wparam], [.lparam]

        jmp     .qtrue

.maybeMRU:
        sub     esi, FirstMRU
        js      .default

        invoke  GetMenuItemCount, [hReopenMenu]
        cmp     esi, eax
        jge     .default

        mov     [.mii.cbSize], sizeof.MENUITEMINFO
        mov     [.mii.fMask], MIIM_TYPE
        mov     [.mii.fType], MFT_STRING
        lea     ebx, [.str]
        mov     [.mii.dwTypeData], ebx
        mov     [.mii.cch], 256

        lea     eax, [.mii]
        invoke  GetMenuItemInfoA, [hReopenMenu], esi, TRUE, eax
        test    eax, eax
        jz      .default

        stdcall OpenFileByName, ebx, NULL, TRUE       ; inteligent open project/file.
        jmp     .qtrue

.qfalse:
        xor     eax,eax
        clc
        return

.qtrue:
        xor     eax,eax
        inc     eax
        clc
        return

;----------------------------------------------------------------------------------------------------
;      DEBUGGER MESSAGES.
;----------------------------------------------------------------------------------------------------
.statuschanged:
        mov     ecx, cStatusRunning
        cmp     [dbgStatus], dsRunning
        je      .statusok
        mov     ecx, cStatusPaused
        cmp     [dbgStatus], dsPaused
        je      .statusok
        mov     ecx, cStatusTerminated
        cmp     [dbgStatus], dsFinished
        je      .statusok
        mov     ecx, cStatusUnknown

.statusok:
        invoke  SendMessageA, [hStatus], SB_SETTEXT, 5, ecx
        clc
        return

iglobal
  cStatusRunning    text  ' Running...'
  cStatusPaused     text  ' Paused'
  cStatusTerminated text  ' Finished'
  cStatusUnknown    text  ' Unknown'
endg


.eventraised:
        cmp     [.wparam], 0
        jne     .exception

        mov     esi, [dbgEvent.dwDebugEventCode]
        cmp     esi, 9
        jbe     @f
        xor     esi, esi
@@:
        stdcall [TblDebugEvents+4*esi]
        test    eax, eax
        jz      .loggingOK

        lea     edi, [.msg]
        mov     [edi+TFreshMsg.type], mtDebug
        mov     [edi+TFreshMsg.hMessage], eax
        mov     [edi+TFreshMsg.link.hFileName], 0

        invoke  SendMessageA, [frmMsg], MWM_ADDMESSAGE, edi, TVI_ROOT
        stdcall StrDel, [edi+TFreshMsg.hMessage]

.loggingOK:
        cmp     esi, EXCEPTION_DEBUG_EVENT
        je      .exception

        cmp     esi, CREATE_PROCESS_DEBUG_EVENT
        je      .createprocess

        cmp     esi, EXIT_PROCESS_DEBUG_EVENT
        je      .exitprocess

.continue:
        mov     eax, dbgcContinue
        clc
        return


;--------- Exception debug event ------------------------
.exception:
        mov     [dbgContext.ContextFlags], CONTEXT_FULL
        invoke  GetThreadContext, [dbgPInfo.hThread], dbgContext

        invoke  SendMessageA, [hPropEditor], PRM_UPDATEPROP, 0, 0

        stdcall FindAddressPosition, [dbgContext.regEip]
        test    eax,eax
        jz      .unknownposition

        mov     [LastKnownLine], eax
        stdcall PosEditor, [eax+TDebugLine.ptrFile], [eax+TDebugLine.LineNum]
        invoke  SendMessageA, [hLister], LM_SHOWLIST, eax, 0

        invoke  GetDlgItem, [hPropEditor], 101
        invoke  ShowWindow, eax, SW_SHOW

        xor      eax, eax
        clc
        return

.unknownposition:
        invoke  GetDlgItem, [hPropEditor], 101
        invoke  ShowWindow, eax, SW_HIDE

        mov     eax, dbgcContinue
        cmp     [dbgEvent.Exception.ExceptionRecord.ExceptionCode], EXCEPTION_BREAKPOINT
        je      @f
        mov     eax, dbgcContinueNotHandled   ; Pass these kind of exceptions to the code.
@@:
        clc
        return


.createprocess:
        invoke  SendDlgItemMessageA, [hPropEditor], 101, PEM_SETCONTROL, dbgContext, DebuggerProperties
        invoke  SendDlgItemMessageA, [hPropEditor], 101, PEM_SETUPDATEPROC, 0, UpdateThreadContext
        invoke  SendMessageA, [hLister], LM_SHOW, SW_SHOWNORMAL, 0
        invoke  SendMessageA, [Dumper.hwnd], DMM_SHOW, SW_SHOWNORMAL, 0

        mov     eax, [dbgEvent.CreateProcessInfo.hFile]
        mov     [hDebugFileImage], eax
        mov     eax, dbgcContinue
        clc
        return

.exitprocess:
        invoke  CloseHandle, [hDebugThread]
        mov     [hDebugThread], 0

        invoke  CloseHandle, [hDebugFileImage]
        mov     [hDebugFileImage], 0

        invoke  SendDlgItemMessageA, [hPropEditor], 101, PEM_SETCONTROL, 0, 0

        invoke  GetDlgItem, [hPropEditor], 101
        invoke  ShowWindow, eax, SW_SHOW

        invoke  SendMessageA, [hLister], WM_SETTEXT, 0, 0
        invoke  SendMessageA, [hLister], LM_SHOW, SW_HIDE, 0
        invoke  SendMessageA, [Dumper.hwnd], DMM_SHOW, SW_HIDE, 0

        stdcall AlignChildren, [hEditorsHost]

        mov     eax, dbgcFinish
        clc
        return

endp


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/MainWindow.inc.

1
2
winmessage DM_EVENTRAISED             ;(0,0)
winmessage DM_STATUSCHANGED           ;(0,0)
<
<




Deleted source/MenuEditor.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
;<ff
Window FormLabel, 2, 0, 'TForm', 'Menu editor', $16080000, $0, 0, 199, 196, 367, 279, FormWinProc;
;ff>

;-----------------------------------------------------------------------
; Window procedure for the form.
; Arguments:
;   .hwnd - handle of the window
;   .wmsg - code of the message
;   .wparam \ Parameters of the message
;   .lparam /
;-----------------------------------------------------------------------
winproc FormWinProc
begin
;-----------------------------------------------------------------------
; Write here the code that have to be executed before
; message dispathing.
;-----------------------------------------------------------------------


ondefault
;-----------------------------------------------------------------------
; Write here the code that have to be executed if message
; was not processed by this procedure.
;-----------------------------------------------------------------------
        stc
        return
endwp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































Deleted source/PAHint.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
; checks for procedure call on current line of text and then shows a hint window with
; procedure definition line (if available)

cCallStdCall text 'stdcall'
cCallCCall   text 'ccall'
cCallInvoke  text 'invoke'
cCallCInvoke text 'cinvoke'
cProcName    text 'proc '

cPAFontName  text 'Trebuchet MS'


uglobal
  hPAHint dd ?
  hPAFontNormal dd ?
  hPAFontBold   dd ?
endg

initialize InitPAHint
begin
        invoke  CreateFontA, -11, 0, 0, 0, FW_NORMAL,                 \
                            0, 0, 0, 0,                              \
                            OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,           \
                            FF_DONTCARE, cPAFontName
        mov     [hPAFontNormal], eax

        invoke  CreateFontA, -11, 0, 0, 0, FW_BOLD,                                                \
                            0, 0, 0, 0,                         \
                            OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,           \
                            FF_DONTCARE, cPAFontName
        mov     [hPAFontBold], eax
        return
endp


finalize FreePAHint
begin
        invoke  DeleteObject, [hPAFontNormal]
        invoke  DeleteObject, [hPAFontBold]
        return
endp




proc CreatePAHint, .parent
begin
        cmp     [hPAHint], 0
        jne     .exit

        invoke  CreateWindowExA, 0, cStaticClassName, 0,                   \
                WS_POPUP or WS_BORDER or SS_OWNERDRAW or SS_LEFT,         \
                10, 10, 350, 300, [.parent], 0, [hInstance], 0
        mov     [hPAHint], eax
        stdcall SubclassWindow, eax, procPAHint

.exit:
        invoke  SetWindowLongA, [hPAHint], GWL_HWNDPARENT, [.parent]
        call    UpdatePAHint
        return
endp



; Returns pointer to the string with current line from the editor.
; If the current line is continuation of some of the previous lines, they are included as well to the line.
;
; returns:
; eax pointer to the line buffer.
; ecx contains offset in the string of the cursor.
proc GetCurrentLine, .asmedit
.aepos AEPOS

.ptrbuffer   dd ?
.buffersize  dd ?
.bufferlimit dd ?

.caret  dd ?

begin
        push    ebx esi edi

        mov     [.buffersize], $400
        mov     [.bufferlimit], $400- $104
        stdcall GetMem, [.buffersize]
        mov     edi, eax
        mov     [.ptrbuffer], eax

        lea     eax, [.aepos]
        invoke  SendMessageA, [.asmedit], AEM_GETPOS, eax, 0

        mov     ebx, [.aepos.caretLine]

.begloop:
        dec     ebx
        jz      .lineloop
        call    .IsLineMerged
        jc      .begloop

.lineloop:
        inc     ebx
        cmp     ebx, [.aepos.caretLine]
        ja      .endprocessing
        jne     .caretok

        mov     eax, edi
        sub     eax, [.ptrbuffer]
        mov     [.caret], eax

.caretok:
        mov     eax, edi
        sub     eax, [.ptrbuffer]
        cmp     eax, [.bufferlimit]
        jb      .bufferok

        sub     edi, [.ptrbuffer]
        shl     [.buffersize], 1


        stdcall ResizeMem, [.ptrbuffer], [.buffersize]
        mov     [.ptrbuffer], eax
        add     edi, eax

        push    [.buffersize]
        pop     [.bufferlimit]
        sub     [.bufferlimit], $104

.bufferok:
        invoke  SendMessageA, [.asmedit], AEM_GETLINEDATA, ebx, edi

        xor     ecx, ecx
        dec     ecx
        xor     esi, esi
.endloop:
        inc     ecx
        cmp     ecx, $100
        je      .endline1

        cmp     byte [edi+ecx], ';'
        je      .endline
        cmp     byte [edi+ecx], '\'
        je      .endline
        cmp     byte [edi+ecx], ' '
        je      .endloop
        lea     esi, [ecx+1]
        jmp     .endloop

.endline1:
        mov     ecx, esi

.endline:
        lea     edi, [edi+ecx+1]
        mov     byte [edi-1], ' '
        jmp     .lineloop

.endprocessing:
        mov     dword [edi-1], 0

        mov     eax, [.ptrbuffer]
        mov     ecx, [.caret]
        add     ecx, [.aepos.caretPosition]
        dec     ecx

        pop     edi esi ebx
        return

.IsLineMerged:
        invoke  SendMessageA, [.asmedit], AEM_GETLINEPTR, ebx, 0
        xor     ecx, ecx

.mergloop:
        cmp     byte [eax+ecx+8], ';'
        je      .notmerged

        cmp     byte [eax+ecx+8], '\'
        je      .merged

        inc     ecx
        cmp     ecx, $100
        jne     .mergloop

.notmerged:
        clc
        retn

.merged:
        stc
        retn
endp




proc UpdatePAHint
  .aepos  AEPOS
  .caret  AECARETXY
  .ptrBuffer dd ?
  .arg    dd ?
  .save   dd ?
  .edit   dd ?
  .begarg dd ?
begin
        cmp     [hPAHint], 0
        je      .exit


        invoke  GetWindowLongA, [hPAHint], GWL_HWNDPARENT
        mov     [.edit], eax

        stdcall StrDup, cProcName
        mov     [.arg], eax

        lea     eax, [.aepos]
        invoke  SendMessageA, [.edit], AEM_GETPOS, eax, 0

        stdcall GetCurrentLine, [.edit]
        mov     [.ptrBuffer], eax
        mov     esi, eax
        mov     [.aepos.caretPosition], ecx

        mov     ebx, 5
        stdcall StrPos, esi, cCallCCall
        test    eax, eax
        jnz     .found

        inc     ebx
        stdcall StrPos, esi, cCallInvoke
        test    eax, eax
        jnz     .found

        inc     ebx
        stdcall StrPos, esi, cCallCInvoke
        test    eax, eax
        jnz     .found

        stdcall StrPos, esi, cCallStdCall
        test    eax, eax
        jz      .notfound

; search the name of the procedure
.found:
        lea     esi, [eax+ebx]

.loop:
        inc     esi
        cmp     byte [esi], 0
        je      .notfound

        cmp     byte [esi], ' '
        je      .loop

        mov     ebx, esi        ; begin of the name.

.endloop:
        inc     esi
        mov     al, [esi]
        cmp     al, 0
        je      .endfound

        cmp     al, ','
        je      .endfound

        cmp     al, ' '
        jne     .endloop

.endfound:
        mov     [.begarg], esi
        pushd   [esi]
        popd    [.save]
        mov     byte [esi], 0

        mov     edi, [ptrPreprocessed]
        test    edi, edi
        jz      .notfound

        stdcall SearchTreeExact, ebx, ptrLabels
        test    eax, eax
        jz      .notfound

        push    eax
        stdcall StrCat, [.arg], ebx

        mov     eax, [.save]
        mov     [esi], eax
        pop     esi             ; esi - pointer to TLabel with the procedure label.

        mov     esi, [esi+TLabel.Children]
        test    esi, esi
        jz      .endsearch

        mov     edi, [esi+TArray.count]
        lea     esi, [esi+TArray.array]

        cmp     edi, 0
        jle     .endsearch

.loopchild:
        cmp     [esi+TLabel.ValueLo], 4
        jl      .nextchild

        cmp     [esi+TLabel.SIBEx], $00010045
        je      @f
        cmp     [esi+TLabel.SIBEx], $00010025
        jne     .nextchild

@@:
        mov     eax, [esi+TLabel.iName]
        add     eax, [ptrNames]
        stdcall StrCat, [.arg], cComma
        stdcall StrCharCat, [.arg], '.'
        stdcall StrCat, [.arg], eax

.nextchild:
        add     esi, sizeof.TLabel
        dec     edi
        jnz     .loopchild

.endsearch:

; what argument is now?
        mov     esi, [.begarg]
        mov     ebx, [.aepos.caretPosition]
        add     ebx, [.ptrBuffer]
        xor     ecx, ecx

.commaloop:
        cmp     esi, ebx
        jae     .endcount
        lodsb

        cmp     al, "'"
        je      .skip_quoted
        cmp     al, '"'
        je      .skip_quoted

        cmp     al, ','
        jne     .commaloop
        inc     ecx
        jmp     .commaloop

.skip_quoted:
        mov     ah, al
.quoteloop:
        lodsb
        cmp     al, ah
        je      .commaloop
        cmp     esi, ebx
        jb      .quoteloop

.endcount:
        invoke  SetWindowLongA, [hPAHint], GWL_USERDATA, ecx

locals
  .rect1 RECT
  .height dd ?
endl
; then set the possition
  ; first, compute the size of the window.
        stdcall StrPtr, [.arg]
        invoke  SendMessageA, [hPAHint], WM_SETTEXT, 0, eax

        invoke  GetDC, [hPAHint]
        push    eax
        invoke  CreateCompatibleDC, eax
        push    eax
        stdcall PaintPAHint, [hPAHint], eax
        mov     [.height], eax
        invoke  DeleteDC ; from the stack
        invoke  ReleaseDC, [hPAHint] ; from the stack

  ; then compute the place

        lea     ebx, [.caret]
        invoke  SendMessageA, [.edit], AEM_GETCARETXY, ebx, 0
        invoke  ClientToScreen, [.edit], ebx
        add     ebx, 8
        invoke  ClientToScreen, [.edit], ebx
        sub     ebx, 8

        lea     eax, [.rect1]
        invoke  SystemParametersInfoA, SPI_GETWORKAREA, 0, eax, 0

        mov     eax, 350
        mov     edx, [.height]

        mov     ecx, [ebx+AECARETXY.x0]
        add     eax, ecx
        sub     [.rect1.right], eax
        jns     @f
        add     ecx, [.rect1.right]
@@:
        mov     [.rect1.right], ecx

        mov     ecx, [ebx+AECARETXY.y1]
        sub     [.rect1.bottom], edx
        cmp     ecx, [.rect1.bottom]
        jbe     @f
        mov     ecx, [ebx+AECARETXY.y0]
        sub     ecx, edx
@@:
        mov     [.rect1.top], ecx

        invoke  SetWindowPos, [hPAHint], 0, [.rect1.right], ecx, 350, [.height], SWP_NOZORDER or SWP_NOACTIVATE or SWP_SHOWWINDOW
        invoke  InvalidateRect, [hPAHint], 0, TRUE

.finish:
        stdcall StrDel, [.arg]
        stdcall FreeMem, [.ptrBuffer]
.exit:
        return

.notfound:
        invoke  PostMessageA, [hPAHint], WM_CLOSE, 0, 0
        jmp     .finish
endp








winproc procPAHint
begin

ondefault
        stc
        return

;___________________________________________________________________________
;
onmessage WM_ERASEBKGND
cPABackground = $e0ffff
locals
  .bkrect RECT
endl
        lea     ebx, [.bkrect]
        invoke  GetClientRect, [.hwnd], ebx
        invoke  CreateSolidBrush, cPABackground
        push    eax
        invoke  FillRect, [.wparam], ebx, eax
        invoke  DeleteObject ; from the stack
        xor     eax, eax
        dec     eax
        clc
        return

;___________________________________________________________________________
;
onmessage WM_PAINT
locals
  .update RECT
  .ps     PAINTSTRUCT
endl

cPAColorGray  = $000000
cPAColorLight = $ff0000

        lea     eax, [.update]
        invoke  GetUpdateRect, [.hwnd], eax, TRUE
        test    eax, eax
        jz      .finishpaint

        lea     esi, [.ps]
        invoke  BeginPaint, [.hwnd], esi
        test    eax, eax
        jz      .endpaint

        stdcall PaintPAHint, [.hwnd], [esi+PAINTSTRUCT.hdc]

.endpaint:
        invoke  EndPaint, [.hwnd], esi

.finishpaint:
        xor     eax, eax
        clc
        return


;___________________________________________________________________________
;
onmessage WM_CLOSE
        invoke  DestroyWindow, [.hwnd]
        mov     [hPAHint], 0
        clc
        return
endwp




; paints the hint window and returns the size needed.
; eax: height of the window needed.
proc PaintPAHint, .hwnd, .hdc
.str dd ?
.deffont dd ?
.point POINT
.metrics TEXTMETRIC
begin
        push    ebx edi

        stdcall GetControlText, [.hwnd], NULL
        mov     [.str], eax

        stdcall StrPtr, eax
        mov     edi, eax

        stdcall StrLen, edi
        mov     ebx, eax

        invoke  GetWindowLongA, [.hwnd], GWL_USERDATA
        test    eax, eax
        je      .textready

        xor     ebx, ebx
        dec     ebx

.commaloop:
        inc     ebx
        cmp     byte [edi+ebx], 0
        je      .textready

        cmp     byte [edi+ebx], ','
        jne     .commaloop
        dec     eax
        jnz     .commaloop

.here:
        inc     ebx

.textready:
        invoke  SetTextAlign, [.hdc], TA_LEFT or TA_TOP or TA_UPDATECP
        invoke  SetTextColor, [.hdc], cPAColorGray
        invoke  SetBkMode, [.hdc], TRANSPARENT
        invoke  SelectObject, [.hdc], [hPAFontNormal]
        mov     [.deffont], eax

        lea     eax, [.metrics]
        invoke  GetTextMetricsA, [.hdc], eax

        mov     eax, 4
        sub     eax, [.metrics.tmInternalLeading]

        invoke  MoveToEx, [.hdc], 2, eax, 0
        stdcall TextOutWithWrap, [.hdc], 350, edi, ebx

        cmp     byte [edi+ebx], 0
        je      .enddraw

        lea     edi, [edi+ebx]
        xor     ebx, ebx
        dec     ebx

.comma2:
        inc     ebx
        cmp     byte [edi+ebx], 0
        je      .drawbold
        cmp     byte [edi+ebx], ','
        jne     .comma2

.drawbold:
        invoke  SelectObject, [.hdc], [hPAFontBold]
        invoke  SetTextColor, [.hdc], cPAColorLight

        stdcall TextOutWithWrap, [.hdc], 350, edi, ebx

        cmp     byte [edi+ebx], 0
        je      .enddraw

        lea     edi, [edi+ebx]
        invoke  SelectObject, [.hdc], [hPAFontNormal]
        invoke  SetTextColor, [.hdc], cPAColorGray
        stdcall StrLen, edi

        stdcall TextOutWithWrap, [.hdc], 350, edi, eax

.enddraw:
        invoke  SelectObject, [.hdc], [.deffont]
        stdcall StrDel, [.str]

        lea     eax, [.point]
        invoke  MoveToEx, [.hdc], 0, 0, eax

        mov     eax, [.metrics.tmHeight]
        add     eax, [.point.y]
        add     eax, 2
        pop     edi ebx
        return
endp




proc TextOutWithWrap, .hdc, .width, .ptrstring, .count
.size SIZE
.point POINT
begin
        push    ebx esi

        mov     esi, [.ptrstring]
.wordloop:
        xor     ebx, ebx

.loopstring:
        cmp     ebx, [.count]
        jae     .word2

        cmp     byte [esi+ebx], ' '
        je      .word
        cmp     byte [esi+ebx], ','
        je      .word

        inc     ebx
        jmp     .loopstring

.word:
        inc     ebx
.word2:
        lea     eax, [.size]
        invoke  GetTextExtentPoint32A, [.hdc], esi, ebx, eax
        lea     eax, [.point]
        invoke  MoveToEx, [.hdc], 0, 0, eax
        invoke  MoveToEx, [.hdc], [.point.x], [.point.y], 0

        mov     eax, [.size.cx]
        add     eax, [.point.x]
        cmp     eax, [.width]
        jbe     .outputit

        cmp     [.point.x], 2   ; left most point.
        je      .wrapit

; next line
        mov     eax, [.point.y]
        add     eax, [.size.cy]
        add     eax, 2
        invoke  MoveToEx, [.hdc], 2, eax, 0
        jmp     .word2

.wrapit:
        dec     ebx
        jnz     .word2
; can't be fitted - then exit

.finish:
        mov     eax, [.size.cy]
        pop     esi ebx
        return

.outputit:
        invoke  TextOutA, [.hdc], 0, 0, esi, ebx

        sub     [.count], ebx
        jle     .finish

        lea     esi, [esi+ebx]
        jmp     .wordloop
endp


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/PreviewSource.inc.

1
2
3
4
5
6
7
8
9
10
; just a comment
;--focused line-----
.lbl db  'a string'
     dd  (1234)
if DoIt
     sbb ecx, ecx
else
     add eax, ecx
end if
;--Selected line----
<
<
<
<
<
<
<
<
<
<




















Deleted source/ProgressWnd.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
;<ff
Window dlgProgress, 3, 0, 'TForm', '', $6000000, $10080, 0, 233, 236, 216, 96, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50010001, $0, 2, 76, 43, 64, 20, 0;
Window NONE, 2, 0, 'msctls_progress32', '', $50000001, $0, 100, 8, 12, 192, 19, 0;
;ff>
uglobal
  hProgressWnd dd ?
endg


; creates progress window and returns its handle in ebx (also hProgressWnd variable is set)
; hwnd_progress variable is set to progressbar's handle
; arguments:
;  p_max  - maximum value of progressbar
;  p_step - on each step progressbar will be increased by this value
;  caption - pointer or handle to string containing progress window's caption
;  no_cancel_btn - if set to 1, "cancel" button won't appear in the window
proc ProgressWndCreate, .p_max, .p_step, .caption, .no_cancel_btn
.rect RECT
begin
        push    esi edi

        stdcall CreateForm, dlgProgress, [hApplication]
        mov     [hProgressWnd], ebx

        stdcall StrPtr, [.caption]
        invoke  SendMessageA, ebx,WM_SETTEXT,0,eax
        mov     eax,[.p_max]
        shl     eax,16

        invoke  SendDlgItemMessageA, [hProgressWnd], 100, PBM_SETRANGE, 0, eax
        xor     eax,eax
        invoke  SendDlgItemMessageA, [hProgressWnd], 100, PBM_SETPOS, eax, eax
        invoke  SendDlgItemMessageA, [hProgressWnd], 100, PBM_SETSTEP, 1, eax

        lea     eax, [.rect]
        invoke  GetWindowRect, [hProgressWnd], eax
        invoke  GetSystemMetrics, SM_CXSCREEN
        sub     eax, [.rect.right]
        add     eax, [.rect.left]
        sar     eax,1
        mov     esi, eax
        invoke  GetSystemMetrics, SM_CYSCREEN
        sub     eax, [.rect.right]
        add     eax, [.rect.left]
        sar     eax,1
        mov     edi, eax
        mov     eax,96
        cmp     [.no_cancel_btn],1
        jne     @f
        mov     eax,64
    @@:
        invoke  SetWindowPos, [hProgressWnd],HWND_TOP,esi,edi,216,eax,0
        pop     edi esi
        return
endp


; destroys progress window
proc ProgressWndDestroy
begin
        invoke  DestroyWindow, [hProgressWnd]
        mov     [hProgressWnd], 0
        return
endp


; increases value of progressbar in progress window
proc ProgressWndStepIt
begin
        pushad
        invoke  SendDlgItemMessageA,[hProgressWnd], 100, PBM_STEPIT, 0, 0
        popad
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































Deleted source/ProjectOptions.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
;<ff
Window frmProjectOptions, 3, 0, 'TForm', 'Project options', $4C80000, $110001, 0, 447, 88, 336, 357, winprocProjectOptions;
Window NONE, 0, 0, 'COMBOBOX', 'Combobox', $54010002, $0, 701, 8, 80, 144, 180, 0;
Window NONE, 0, 0, 'STATIC', '&Binary filename:', $50000000, $0, 0, 8, 24, 88, 13, 0;
Window NONE, 0, 0, 'EDIT', '', $50010180, $200, 703, 8, 40, 304, 21, 0;
Window NONE, 0, 0, 'BUTTON', '&Automatic name creation.', $50010003, $0, 702, 8, 8, 160, 16, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50010001, $0, 1, 96, 296, 64, 25, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50010000, $0, 2, 168, 296, 64, 25, 0;
Window NONE, 0, 0, 'STATIC', 'kbytes', $50000200, $0, 0, 156, 80, 40, 21, 0;
Window NONE, 0, 0, 'STATIC', 'Compiler &memory:', $50000200, $0, 0, 8, 64, 80, 16, 0;
Window NONE, 2, 0, 'TForm', 'Form', $50800000, $10000, 704, 8, 112, 315, 176, 0;
;ff>
idComboMemory  = 701
idCheckboxAuto = 702
idEditFilename = 703
idAliasesPanel = 704

idAliasList = 1234


proc OnProjectOptions, .wparam, .lparam
begin
        push    ebx

        stdcall CreateForm, frmProjectOptions, [hApplication]
        stdcall ShowModal, ebx, MSF_CENTER
        cmp     eax, MR_OK
        jne     .exit

; Get parameters back...

; Aliases:
        invoke  GetDlgItem, ebx, idAliasesPanel
        invoke  GetWindow, eax, GW_CHILD
        invoke  SendMessageA, eax, OM_SAVEOPTIONS, 0, poVarArray

        stdcall CreateParametersMenu

; Memory size
        invoke  GetDlgItem, ebx, idComboMemory
        stdcall GetControlText, eax, NULL
        push    eax

        stdcall StrToFasmNum, eax
        mov     [poMemory], eax
        stdcall StrDel ; from the stack.

; Binary name
        invoke  GetDlgItem, ebx, idEditFilename
        stdcall GetControlText, eax, NULL
        stdcall StrDel, [poBinName]
        mov     [poBinName], eax

; Binary name auto flag
        invoke  SendDlgItemMessageA, ebx, idCheckboxAuto, BM_GETCHECK, 0, 0
        mov     [poBinNameAuto], eax

; mark the project as modified...
        invoke  SendMessageA, [hProjManager], _CEM_SETMODIFIED, TRUE, 0

.exit:
        invoke  DestroyWindow, ebx

        pop     ebx
        return
endp


;-----------------------------------------------------------------------
; Window procedure for the form.
; Arguments:
;   .hwnd - handle of the window
;   .wmsg - code of the message
;   .wparam \ Parameters of the message
;   .lparam /
;-----------------------------------------------------------------------
winproc winprocProjectOptions
begin


ondefault
        stc
        return


onmessage FM_AFTERCREATE

        invoke  GetDlgItem, [.hwnd], idAliasesPanel

        stdcall CreateForm, frmIDEOptions, eax
        stdcall SetAlign, ebx, waClient
        invoke  SetWindowLongA, ebx, GWL_ID, idAliasList


        invoke  SendMessageA, ebx, OM_LOADOPTIONS, 0, poVarArray

        invoke  GetDlgItem, [.hwnd], idComboMemory
        mov     ebx, eax

        mov     esi, cMemorySizes

.sizesloop:
        cmp     byte [esi], 0
        je      .endoflist

        invoke  SendMessageA, ebx, CB_ADDSTRING, 0, esi
        stdcall StrLen, esi
        stc
        adc     esi, eax
        jmp     .sizesloop

.endoflist:
        stdcall NumToStr, [poMemory], ntsUnsigned or ntsDec
        stdcall SetControlText, ebx, eax
        stdcall StrDel, eax

; Set the binary filename.
        invoke   GetDlgItem, [.hwnd], idEditFilename
        stdcall  SetControlText, eax, [poBinName]

; Set the check in checkbox.
        mov     esi, [poBinNameAuto]
        invoke  SendDlgItemMessageA, [.hwnd], idCheckboxAuto, BM_SETCHECK, esi, 0

        test    esi, esi
        jz      .endcreate

        xor     esi, 1
        invoke  GetDlgItem, [.hwnd], idEditFilename
        invoke  EnableWindow, eax, esi

.endcreate:
        clc
        return


onmessage WM_COMMAND
        cmp     word [.wparam], idCheckboxAuto
        je      .checkautoname

        stc
        return

.checkautoname:
        invoke  SendMessageA, [.lparam], BM_GETCHECK, 0, 0
        mov     ebx, eax

        xor     eax, 1
        push    eax
        invoke  GetDlgItem, [.hwnd], idEditFilename
        invoke  EnableWindow, eax

        clc
        return

endwp


iglobal
  cMemorySizes  db      '16384', 0
                db      '32768', 0
                db      '65536', 0
                db      '131072', 0
                db      '262144', 0
                db      '524288', 0
                db      '1048576', 0
                db      0
endg
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































Deleted source/SizerClass.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
initialize RegisterSizerClass
.wc WNDCLASS
begin
        xor     ebx, ebx

        mov     [.wc.hIcon],ebx
        mov     [.wc.hCursor],ebx
        mov     [.wc.style], CS_PARENTDC
        mov     [.wc.lpfnWndProc], SizerWinProc
        mov     [.wc.cbClsExtra],ebx
        mov     [.wc.cbWndExtra], 16
        mov     eax, [hInstance]
        mov     [.wc.hInstance],eax
        mov     [.wc.hbrBackground], ebx
        mov     [.wc.lpszMenuName], ebx
        mov     [.wc.lpszClassName], cSizerClassName

        lea     eax, [.wc]
        invoke  RegisterClassA, eax
        return
endp

cSizerClassName text 'SzBx'


iglobal
  SizerGripSize dd 8
  clSizerSize   dd $d8ffd8
  clSizerMove   dd $a0c0ff
endg


winproc SizerWinProc
  .cursorpos POINT
begin
        push    esi edi ebx

        invoke  GetWindowLongA, [.hwnd], 0
        mov     edi, eax
        mov  ebx, [.wmsg]

ondefault
        invoke  DefWindowProcA, [.hwnd], [.wmsg], [.wparam], [.lparam]
        pop     ebx edi esi
        return

;-----------------------------------------------------------------------
onmessage WM_NCHITTEST
        stdcall GetCurrentTool
        test    eax, eax
        jnz     .transp

        movsx   ecx, word [.lparam]
        movsx   edx, word [.lparam+2]
        mov     [.cursorpos.x], ecx
        mov     [.cursorpos.y], edx
        lea     ecx, [.cursorpos]
        invoke  ScreenToClient, [.hwnd], ecx
        invoke  PtInRegion, [edi+TSizer.region], [.cursorpos.x], [.cursorpos.y]
        test    eax, eax
        jnz     .ondefault

.transp:
        mov     eax, HTTRANSPARENT
        pop     ebx edi esi
        return

;-----------------------------------------------------------------------
onmessage WM_MOUSEACTIVATE
        invoke  SetFocus, [.hwnd]
        mov     eax, MA_ACTIVATE
        pop     ebx edi esi
        return

;-----------------------------------------------------------------------
onmessage WM_GETDLGCODE

        mov     eax, DLGC_WANTALLKEYS
        clc
        return


;-----------------------------------------------------------------
onmessage WM_KEYDOWN

        cmp     [.wparam], VK_ESCAPE
        jne     .ondefault

        mov     eax, [edi+TSizer.selected]
        cmp     [eax+TArray.count], 0
        je      .ondefault

        mov     esi, [eax+TArray.array]

        mov     edi, [esi+TWinTemplateDT.parent]
        test    edi, edi
        jz      .endselparent

        mov     esi, [edi+TWinTemplateDT.parent]
        test    esi, esi
        jz      .onlyprop

        invoke  SendMessageA, [.hwnd], SZM_SELECTCONTROL, edi, 0

.endselparent:
        xor     eax, eax
        pop     ebx edi esi
        return

.onlyprop:
        invoke  SendMessageA, [.hwnd], SZM_UNSELECTALL, 0, 0
        invoke  SendDlgItemMessageA, [hPropEditor], 101, PEM_SETCONTROL, edi, 0
        xor     eax, eax
        pop     ebx edi esi
        return

;-----------------------------------------------------------------------
onmessage WM_CREATE
        stdcall GetMem, sizeof.TSizer
        mov     edi, eax
        invoke  SetWindowLongA, [.hwnd], 0, edi

        stdcall CreateArray, 4
        mov     [edi+TSizer.selected], eax

        xor     eax, eax
        pop     ebx edi esi
        return

;-----------------------------------------------------------------------
onmessage WM_DESTROY
        stdcall FreeMem, [edi+TSizer.selected]
        cmp     [edi+TSizer.region], 0
        je      @f
        invoke  DeleteObject, [edi+TSizer.region]
@@:
        stdcall FreeMem, edi
        xor     eax, eax
        pop     ebx edi esi
        return

;-----------------------------------------------------------------------
onmessage SZM_UPDATESIZE
        stdcall UpdateSizerSize, [.hwnd], edi
        pop     ebx edi esi
        return

;-----------------------------------------------------------------------
onmessage SZM_UNSELECTALL
        stdcall FreeMem, [edi+TSizer.selected]
        stdcall CreateArray, 4
        mov     [edi+TSizer.selected], eax

        stdcall UpdateSizerSize, [.hwnd], edi
        pop     ebx edi esi
        return

;-----------------------------------------------------------------------
onmessage SZM_SELECTCONTROL     ; .wparam - pointer to TWinTemplateDT

        mov     eax, [.wparam]
        mov     esi, [eax+TWinTemplateDT.parent]
        test    esi, esi
        jz      .topropedit     ; the top-level window can't be selected.

        invoke  GetParent, [.hwnd]
        cmp     [esi+TWinTemplateDT.hwnd], eax
        je      .parentOK

; Move the sizer to the new parent...
; First clear the selection.
        stdcall  FreeMem, [edi+TSizer.selected]
        stdcall  CreateArray, 4
        mov      [edi+TSizer.selected], eax

; Second move the sizer to the new parent.
        invoke    SetParent, [.hwnd], [esi+TWinTemplateDT.hwnd]
        mov       esi, [.wparam]
        jmp       .selectit

.parentOK:
        cmp     [.lparam], sfDontClearOld
        je      .clearok

; Clear the old selection...
        stdcall  FreeMem, [edi+TSizer.selected]
        stdcall  CreateArray, 4
        mov      [edi+TSizer.selected], eax

.clearok:
        mov     esi, [.wparam]
        stdcall ListIndexOf, [edi+TSizer.selected], esi
        jnc     .topropedit

; so, add it to selection list...
.selectit:
        stdcall AddArrayItems, [edi+TSizer.selected], 1
        mov     [edi+TSizer.selected], edx
        mov     [eax], esi

.topropedit:
        invoke  SendDlgItemMessageA, [hPropEditor], 101, PEM_SETCONTROL, esi, 0

.endselect:
        stdcall UpdateSizerSize, [.hwnd], edi
        invoke  SetFocus, [.hwnd]
        pop     ebx edi esi
        return


;-----------------------------------------------------------------------
onmessage SZM_UNSELECTCONTROL

        stdcall ListIndexOf, [edi+TSizer.selected], [.wparam]
        jc      .endselect

        stdcall DeleteArrayItems, [edi+TSizer.selected], eax, 1
        mov     [edi+TSizer.selected], edx
        jmp     .endselect

;-----------------------------------------------------------------------
onmessage WM_SETCURSOR
        mov     ecx, IDC_ARROW
        mov     eax, [edi+TSizer.selected]
        cmp     [eax+TArray.count], 1
        jg      .setit

        stdcall ComputeDragKind, [.hwnd], [SizerGripSize]

        movsx   ecx, ah
        shl     ecx, 2
        movsx   eax, al
        add     ecx, eax

        mov     ecx, [SizerCursors+4*ecx]

.setit:
        invoke  LoadCursorA, NULL, ecx
        invoke  SetCursor,eax
        pop     ebx edi esi
        return

;-----------------------------------------------------------------------
onmessage WM_LBUTTONDOWN
  locals
    .parentrect RECT
  endl
        test    [.wparam], MK_CONTROL
        jnz     .unselect             ; unselect control under the cursor

;        test    [.wparam], MK_SHIFT
;        je      .cancelsend          ; clears all selections and resend the message to the control under the mouse.

        mov     [edi+TSizer.moveX], 3
        mov     [edi+TSizer.moveY], 3

        mov     eax, [edi+TSizer.selected]
        cmp     [eax+TArray.count], 1
        jg     .capturethemouse

; single selected - resize enabled.
        stdcall ComputeDragKind, [.hwnd], [SizerGripSize]
        movsx   ecx, ah  ; X
        movsx   edx, al  ; Y

        shl     ecx, 2
        shl     edx, 2

        movsx   ebx, al
        add     ecx, ebx
        movsx   ebx, ah
        add     edx, ebx

        movsx   ecx, [SizerXYInc+ecx]
        mov     [edi+TSizer.moveX], ecx

        movsx   edx, [SizerXYInc+edx]
        mov     [edi+TSizer.moveY], edx

.capturethemouse:
        lea     eax, [.cursorpos]
        invoke  GetCursorPos, eax

        cmp     [edi+TSizer.moveY], 3
        jne     .cursorok

        invoke  LoadCursorA, NULL, IDC_SIZEALL
        invoke  SetCursor, eax

.cursorok:
        invoke  DragDetect, [.hwnd], [.cursorpos.x], [.cursorpos.y]
        test    eax, eax
        jz      .captureOK

; store mouse coordinates in drag point.
        movsx   eax, word [.lparam]
        movsx   ecx, word [.lparam+2]
        mov     [edi+TSizer.dragXY.x], eax
        mov     [edi+TSizer.dragXY.y], ecx

        invoke  SetCapture, [.hwnd]
        invoke  GetParent, [.hwnd]
        mov     ebx, eax

        lea     esi, [.parentrect]
        invoke  GetClientRect, ebx, esi
        invoke  ClientToScreen, ebx, esi
        lea     eax, [.parentrect.right]
        invoke  ClientToScreen, ebx, eax

        invoke  ClipCursor, esi

.captureOK:
        xor     eax, eax
        pop     ebx edi esi
        return

.unselect:
        lea     ebx, [.cursorpos]
        invoke  GetCursorPos, ebx
        invoke  GetParent, [.hwnd]
        invoke  ScreenToClient, eax, ebx

        mov     esi, [edi+TSizer.selected]
        mov     ebx, [esi+TArray.count]

.unselectloop:
  locals
    .winrect RECT
  endl
        dec     ebx
        js      .endunselect

        mov     eax, [esi+4*ebx+TArray.array]
        movsx   ecx, [eax+TWinTemplateDT.left]
        movsx   edx, [eax+TWinTemplateDT.top]
        mov     [.winrect.left], ecx
        mov     [.winrect.top], edx
        movzx   ecx, [eax+TWinTemplateDT.width]
        movzx   edx, [eax+TWinTemplateDT.height]
        add     ecx, [.winrect.left]
        add     edx, [.winrect.top]
        mov     [.winrect.right], ecx
        mov     [.winrect.bottom], edx

        lea     ecx, [.winrect]
        invoke  PtInRect, ecx, [.cursorpos.x], [.cursorpos.y]
        test    eax, eax
        jz      .unselectloop

        invoke  SendMessageA, [.hwnd], SZM_UNSELECTCONTROL, [esi+4*ebx+TArray.array], 0
        stdcall UpdateSizerSize, [.hwnd], edi

.endunselect:
        xor     eax, eax
        pop     ebx edi esi
        return


;-----------------------------------------------------------------------
onmessage WM_LBUTTONUP
        invoke  SetCapture, NULL
        invoke  ClipCursor, NULL

        stdcall AlignSiblings, [.hwnd]
        test    eax, eax
        jz      .endmouseup

        stdcall UpdateSizerSize, [.hwnd], edi

.endmouseup:
        xor     eax, eax
        pop     ebx edi esi
        return


;-----------------------------------------------------------------------
onmessage WM_MOUSEMOVE
locals
  .point  POINT
  .delta POINT
  .delta2 POINT
  .hDefer dd ?
endl
        invoke  GetCapture
        cmp     eax, [.hwnd]
        jne     .endmousemove

; compute deltas
        movsx   eax, word [.lparam]
        movsx   ecx, word [.lparam+2]
        sub     eax, [edi+TSizer.dragXY.x]
        sub     ecx, [edi+TSizer.dragXY.y]
        mov     [.delta.x], eax
        mov     [.delta.y], ecx

        stdcall RoundToGrid, eax, [xGrid]
        mov     [.delta2.x], eax
        stdcall RoundToGrid, ecx, [yGrid]
        mov     [.delta2.y], eax
        or      eax, [.delta2.x]
        jz      .endmousemove

        mov     esi, [edi+TSizer.selected]
        mov     ebx, [esi+TArray.count]
        lea     esi, [esi+TArray.array]

        invoke  BeginDeferWindowPos, ebx
        mov     [.hDefer], eax

.selectedloop:
        dec     ebx
        js      .endselloop

        mov     eax, [esi]
        movsx   ecx, [eax+TWinTemplateDT.left]
        movsx   edx, [eax+TWinTemplateDT.top]
        mov     [.point.x], ecx
        mov     [.point.y], edx
        movsx   ecx, [eax+TWinTemplateDT.width]
        movsx   edx, [eax+TWinTemplateDT.height]
        add     ecx, [.point.x]
        add     edx, [.point.y]

        mov     eax, [.delta2.x]

        test    [edi+TSizer.moveX], 1
        jz      @f
        add     [.point.x], eax
@@:
        test    [edi+TSizer.moveX], 2
        jz      @f
        add     ecx, eax
@@:

        mov     eax, [.delta2.y]

        test    [edi+TSizer.moveY], 1
        jz      @f
        add     [.point.y], eax
@@:
        test    [edi+TSizer.moveY], 2
        jz      @f
        add     edx, eax
@@:
        sub     ecx, [.point.x]
        sub     edx, [.point.y]

        cmp     [edi+TSizer.moveX], 3
        je      .heightok

        cmp     ecx, 16
        jge     .widthok

        test    [edi+TSizer.moveX], 2
        jz      @f
        sub     ecx, 16
        add     [.point.x], ecx
@@:
        mov     ecx, 16

.widthok:
        cmp     edx, 16
        jge     .heightok

        test    [edi+TSizer.moveY], 2
        jz      @f
        sub     edx, 16
        add     [.point.y], edx
@@:
        mov     edx, 16

.heightok:
        push    SWP_NOZORDER or SWP_NOREDRAW
        push    edx
        push    ecx

        mov     eax, [esi]

        mov     [eax+TWinTemplateDT.width], cx
        mov     [eax+TWinTemplateDT.height], dx
        mov     ecx, [.point.x]
        mov     edx, [.point.y]
        push    edx
        push    ecx
        mov     [eax+TWinTemplateDT.left], cx
        mov     [eax+TWinTemplateDT.top], dx
        invoke  DeferWindowPos, [.hDefer], [eax+TWinTemplateDT.hwnd], 0

        add     esi, 4
        jmp     .selectedloop

.endselloop:
        invoke  EndDeferWindowPos, [.hDefer]
        stdcall UpdateSizerSize, [.hwnd], edi

.endmousemove:
; update the TSizer.dragXY
        lea     esi, [edi+TSizer.dragXY]
        invoke  GetCursorPos, esi
        invoke  ScreenToClient, [.hwnd], esi

        mov     ecx, [.delta.x]
        mov     edx, [.delta.y]
        sub     ecx, [.delta2.x]
        sub     edx, [.delta2.y]
        sub     [edi+TSizer.dragXY.x], ecx
        sub     [edi+TSizer.dragXY.y], edx

        xor     eax, eax
        pop     ebx edi esi
        return

;-----------------------------------------------------------------------
onmessage WM_PAINT
  locals
    .paintstr PAINTSTRUCT
    .client   RECT
    .middle   RECT
    .half     dd ?
  endl
        lea     esi, [.paintstr]
        invoke  BeginPaint, [.hwnd], esi

        lea     eax, [.client]
        lea     ecx, [.middle]
        stdcall ComputeInternalRect, [.hwnd], eax, ecx, [SizerGripSize]

        mov     eax, [edi+TSizer.selected]
        cmp     [eax+TArray.count], 1
        jle     .regionok

; Draw frame around all selected objects in rectangle.
        invoke  CreateSolidBrush, [clSizerSize]
        push    eax
        invoke  FrameRgn, [esi+PAINTSTRUCT.hdc], [edi+TSizer.region], eax, 2, 2
        invoke  DeleteObject ; brush from the stack

; Draw dotted rectangle around the sizer.
        invoke  CreatePen, PS_DOT, 0, 0
        invoke  SelectObject, [esi+PAINTSTRUCT.hdc], eax
        push    eax

        invoke  GetStockObject, NULL_BRUSH
        invoke  SelectObject, [esi+PAINTSTRUCT.hdc], eax
        push    eax
        invoke  SetBkMode, [esi+PAINTSTRUCT.hdc], TRANSPARENT

        mov     eax, [SizerGripSize]
        sar     eax,1
        mov     [.half], eax

        mov     eax, [.client.right]
        mov     ecx, [.client.bottom]
        sub     eax, [.half]
        sub     ecx, [.half]

        invoke  Rectangle, [esi+PAINTSTRUCT.hdc], [.half], [.half], eax, ecx

        invoke  SelectObject, [esi+PAINTSTRUCT.hdc] ; old brush from the stack
        invoke  SelectObject, [esi+PAINTSTRUCT.hdc] ; old pen from the stack
        invoke  DeleteObject, eax


.regionok:
; Draw drag rectangles in the corners.
        mov     eax, [edi+TSizer.selected]
        cmp     [eax+TArray.count], 1
        jg      .dragok

        invoke  GetStockObject, BLACK_PEN
        invoke  SelectObject, [esi+PAINTSTRUCT.hdc], eax
        push    eax

        invoke  CreateSolidBrush, [clSizerSize]
        invoke  SelectObject, [esi+PAINTSTRUCT.hdc], eax
        push    eax

        invoke  Rectangle, [esi+PAINTSTRUCT.hdc], 0, 0, [SizerGripSize], [SizerGripSize]
        invoke  Rectangle, [esi+PAINTSTRUCT.hdc], 0, [.client.top], [SizerGripSize], [.client.bottom]
        invoke  Rectangle, [esi+PAINTSTRUCT.hdc], [.client.left], 0, [.client.right], [SizerGripSize]
        invoke  Rectangle, [esi+PAINTSTRUCT.hdc], [.client.left], [.client.top], [.client.right], [.client.bottom]

        invoke  Rectangle, [esi+PAINTSTRUCT.hdc], [.middle.left], 0, [.middle.right], [SizerGripSize]
        invoke  Rectangle, [esi+PAINTSTRUCT.hdc], 0, [.middle.top], [SizerGripSize], [.middle.bottom]
        invoke  Rectangle, [esi+PAINTSTRUCT.hdc], [.middle.left], [.client.top], [.middle.right], [.client.bottom]
        invoke  Rectangle, [esi+PAINTSTRUCT.hdc], [.client.left], [.middle.top], [.client.right], [.middle.bottom]

;        invoke  CreateSolidBrush, [clSizerMove]
;        invoke  SelectObject, [esi+PAINTSTRUCT.hdc], eax
;        invoke  DeleteObject, eax
;
;        invoke  Rectangle, [esi+PAINTSTRUCT.hdc], [.middle.left], [.middle.top], [.middle.right], [.middle.bottom]

        invoke  SelectObject, [esi+PAINTSTRUCT.hdc] ; old brush from the stack
        invoke  DeleteObject, eax

        invoke  SelectObject, [esi+PAINTSTRUCT.hdc] ; old pen from the stack

.dragok:
        invoke  EndPaint, [.hwnd], esi
        xor     eax, eax
        pop     ebx edi esi
        return
endwp


iglobal
label SizerCursors dword
      dd IDC_ARROW, IDC_ARROW,    IDC_ARROW,  IDC_ARROW
      dd IDC_ARROW, IDC_SIZENWSE, IDC_SIZENS, IDC_SIZENESW
      dd IDC_ARROW, IDC_SIZEWE,   IDC_ARROW,  IDC_SIZEWE
      dd IDC_ARROW, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE

label SizerXYInc byte
      db 3, 3, 3, 3
      db 3, 1, 0, 2
      db 3, 1, 3, 2
      db 3, 1, 0, 2
endg




proc ComputeDragKind, .hwnd, .width
.point POINT
.client RECT
.middle RECT
begin
        push    ebx

        lea     ecx, [.middle]
        lea     eax, [.client]
        stdcall ComputeInternalRect, [.hwnd], eax, ecx, [.width]

        lea     ebx, [.point]
        invoke  GetCursorPos, ebx
        invoke  ScreenToClient, [.hwnd], ebx

        xor     ebx, ebx
        mov     eax, [.point.x]
        mov     ecx, [.point.y]

        cmp     eax, [.width]
        jg      @f
        test    eax, eax
        js      .indexy
        mov     bl, 1
        jmp     .indexy

@@:
        cmp     eax, [.middle.right]
        jg      @f
        cmp     eax, [.middle.left]
        jl      .indexy
        mov     bl, 2
        jmp     .indexy

@@:
        cmp     eax, [.client.left]
        jl      .indexy
        cmp     eax, [.client.right]
        jg      .indexy

        mov     bl, 3

.indexy:
        cmp     ecx, [.width]
        jg      @f
        test    ecx, ecx
        js      .indexok
        mov     bh, 1
        jmp     .indexok

@@:
        cmp     ecx, [.middle.bottom]
        jg      @f
        cmp     ecx, [.middle.top]
        jl      .indexok
        mov     bh, 2
        jmp     .indexok

@@:
        cmp     ecx, [.client.top]
        jl      .indexok
        cmp     ecx, [.client.bottom]
        jg      .indexok

        mov     bh, 3

.indexok:
        mov     eax, ebx
        pop     ebx
        return
endp



proc ComputeInternalRect, .hwnd, .ptrClient, .ptrMiddle, .width
begin
        push    esi edi
        mov     esi, [.ptrClient]
        mov     edi, [.ptrMiddle]

        invoke  GetClientRect, [.hwnd], esi

        mov     eax, [esi+RECT.right]
        mov     ecx, [esi+RECT.bottom]
        sub     eax, [.width]
        sub     ecx, [.width]
        mov     [esi+RECT.left], eax
        mov     [esi+RECT.top], ecx

        mov     eax, [esi+RECT.right]
        mov     ecx, [esi+RECT.bottom]
        sub     eax, [.width]
        sub     ecx, [.width]
        sar     eax, 1
        sar     ecx, 1
        mov     [edi+RECT.left], eax
        mov     [edi+RECT.top], ecx
        add     eax, [.width]
        add     ecx, [.width]
        mov     [edi+RECT.right], eax
        mov     [edi+RECT.bottom], ecx

        pop     edi esi
        return
endp



proc UpdateSizerSize, .hWnd, .ptrSizer
.rectmax   RECT
.point1    POINT
.point2    POINT
.update    dd ?
.region    dd ?
.parent    dd ?

begin
        push    esi edi ebx

        invoke  GetParent, [.hWnd]
        mov     [.parent], eax

        mov     esi, [.ptrSizer]
        invoke  DeleteObject, [esi+TSizer.region]
        mov     eax, [.region]
        mov     [esi+TSizer.region], eax

        xor     eax, eax
        lea     edi, [.rectmax]
        mov     [edi+RECT.right], eax
        mov     [edi+RECT.bottom], eax
        mov     eax, $7fffffff
        mov     [edi+RECT.left], eax
        mov     [edi+RECT.top], eax

        xor     eax, eax
        invoke  CreateRectRgn, eax, eax, eax, eax
        mov     [.region], eax
        mov     [esi+TSizer.region], eax

; Old rectangle, that have to be erased.
        lea     ecx, [.point1]
        invoke  GetWindowRect, [.hWnd], ecx
        lea     ecx, [.point1]
        invoke  ScreenToClient, [.parent], ecx
        lea     ecx, [.point2]
        invoke  ScreenToClient, [.parent], ecx
        lea     ecx, [.point1]
        invoke  CreateRectRgnIndirect, ecx
        mov     [.update], eax

        mov     esi, [esi+TSizer.selected]
        mov     ebx, [esi+TArray.count]

.adjloop:
        dec     ebx
        js      .endloop

        mov     eax, [esi+4*ebx+TArray.array]
        movsx   ecx, [eax+TWinTemplateDT.left]
        movsx   edx, [eax+TWinTemplateDT.top]
        mov     [.point1.x], ecx
        mov     [.point1.y], edx

;[result.left] = MIN [result.left] [.rect.left]
        cmp     ecx, [edi+RECT.left]
        jge     @f
        mov     [edi+RECT.left], ecx
@@:
;[result.top] = MIN [result.top] [.rect.top]
        cmp     edx, [edi+RECT.top]
        jge     @f
        mov     [edi+RECT.top], edx
@@:
        movsx   ecx, [eax+TWinTemplateDT.width]
        movsx   edx, [eax+TWinTemplateDT.height]
        add     ecx, [.point1.x]
        add     edx, [.point1.y]

;[result.right] = MAX [result.right] [.rect.right]
        cmp     ecx, [edi+RECT.right]
        jle     @f
        mov     [edi+RECT.right], ecx
@@:
;[result.bottom] = MAX [result.bottom] [.rect.bottom]
        cmp     edx, [edi+RECT.bottom]
        jle     @f
        mov     [edi+RECT.bottom], edx
@@:
; Add rectangle to the selected region.
        invoke  CreateRectRgn, [.point1.x], [.point1.y], ecx, edx
        push    eax
        invoke  CombineRgn, [.region], [.region], eax, RGN_OR
        invoke  DeleteObject ; from the stack

; exclude children rectangles...
        push    esi ebx
        mov     eax, [esi+4*ebx+TArray.array]

        mov     esi, [eax+TWinTemplateDT.children]
        mov     ebx, [esi+TArray.count]

.childrenloop:
        dec     ebx
        js      .endchildren

        mov     eax, [esi+4*ebx+TArray.array]

        movsx   ecx, [eax+TWinTemplateDT.left]
        movsx   edx, [eax+TWinTemplateDT.top]
        add     ecx, [.point1.x]
        add     edx, [.point1.y]
        mov     [.point2.x], ecx
        mov     [.point2.y], edx
        movsx   ecx, [eax+TWinTemplateDT.width]
        movsx   edx, [eax+TWinTemplateDT.height]
        add     ecx, [.point2.x]
        add     edx, [.point2.y]

        invoke  CreateRectRgn, [.point2.x], [.point2.y], ecx, edx
        push    eax
        invoke   CombineRgn, [.region], [.region], eax, RGN_DIFF
        invoke  DeleteObject ; from the stack
        jmp     .childrenloop

.endchildren:
        pop     ebx esi
        jmp     .adjloop

.endloop:

; offset of the region
        mov     edx, [SizerGripSize]
        mov     eax, [edi+RECT.left]
        mov     ecx, [edi+RECT.top]
        neg     eax
        sar     edx, 1
        neg     ecx
        add     eax, edx
        add     ecx, edx

        invoke  OffsetRgn, [.region], eax, ecx
        cmp     eax, NULLREGION
        je      .hide

; Compute width, height, left and top
        mov     eax, [SizerGripSize]
        sar     eax, 1
        sub     [edi+RECT.left], eax
        sub     [edi+RECT.top], eax
        add     [edi+RECT.right], eax
        add     [edi+RECT.bottom], eax

        invoke  CreateRectRgnIndirect, edi
        push    eax
        invoke  CombineRgn, [.update], [.update], eax, RGN_OR
        invoke  DeleteObject ; from the stack

        mov     eax, [edi+RECT.left]
        mov     ecx, [edi+RECT.top]
        sub     [edi+RECT.right], eax
        sub     [edi+RECT.bottom], ecx

        mov     eax, [.ptrSizer]
        mov     eax, [eax+TSizer.selected]
        cmp     [eax+TArray.count], 1
        jne     @f

        lea     eax, [.point1]
        push    eax
        invoke  GetRgnBox, [.region], eax
        invoke  CreateRectRgnIndirect ; from the stack
        mov     ebx, eax
        invoke  CreateRectRgn, 0, 0, [edi+RECT.right], [edi+RECT.bottom]
        push    eax
        invoke  CombineRgn, ebx, eax, ebx, RGN_DIFF
        invoke  DeleteObject ; from the stack
        invoke  CombineRgn, [.region], [.region], ebx, RGN_OR
        invoke  DeleteObject, ebx

@@:
        invoke  SetWindowPos, [.hWnd], HWND_TOP, [edi+RECT.left], [edi+RECT.top], [edi+RECT.right], [edi+RECT.bottom], SWP_SHOWWINDOW or SWP_NOREDRAW or SWP_NOSENDCHANGING

        invoke  RedrawWindow, [.parent], NULL, [.update], RDW_ERASE or RDW_INVALIDATE or RDW_ERASENOW or RDW_UPDATENOW or RDW_ALLCHILDREN
        invoke  RedrawWindow, [.hWnd], NULL, NULL, RDW_ERASE or RDW_INVALIDATE or RDW_ERASENOW or RDW_UPDATENOW

        invoke  DeleteObject, [.update]
        pop     ebx edi esi
        return

.hide:
        invoke  ShowWindow, [.hWnd], SW_HIDE
        invoke  DeleteObject, [.update]
        pop     ebx edi esi
        return
endp



;-----------------------------------------------------------------
; Arguments:
;   eax = pointer to the TWinTemplateDT structure.
; Returns:
;   eax = handle of the TSizer control for given set of windows.
;-----------------------------------------------------------------
proc GetSizer
begin
.backloop:
        cmp     [eax+TWinTemplateDT.parent], 0
        je      .found
        mov     eax, [eax+TWinTemplateDT.parent]
        jmp     .backloop

.found:
        mov     eax, [eax+TWinTemplateDT.hSizer]
        return
endp



proc GetSelectionList, .ptrWinTemplate
begin
        mov     eax, [.ptrWinTemplate]
        stdcall GetSizer
        invoke  GetWindowLongA, eax, 0
        mov     eax, [eax+TSizer.selected]
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/SizerClass.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct TSizer
  .moveX    dd ?      ; 1 - move left border, 2 - move right border 3 - both
  .moveY    dd ?      ; 1 - move top border, 2 - move bottom border 3 - both
  .region   dd ?      ; region that contains all controls selected in the sizer.
  .dragXY   POINT     ; point where the window is draged.
  .selected dd ?      ; pointer to TArray with pointers to selected components.
ends

sfDontClearOld = 1

winmessage SZM_SELECTCONTROL          ; (ptrWinTemplate, flags) - selects control inside the sizer.
winmessage SZM_UNSELECTCONTROL        ; (ptrWinTemplate, 0) - unselects control
winmessage SZM_UNSELECTALL            ; (0, 0) - unseelcts all controls and hides the sizer
winmessage SZM_UPDATESIZE             ; (0, 0)

struct TMouseEvent
  .mousePos POINT
  .msg      dd ?
  .wparam   dd ?
  .sender   dd ?
ends
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































Deleted source/actNewFile.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
iglobal
  Window  frmNewFile, $3, $0, 'TForm', 'New...', $06080000 or WS_TABSTOP, WS_EX_DLGMODALFRAME, 0, 201, 182, 320, 257, frmNewProc
  Window  NONE, $0, $0, LISTVIEW_CLASS, '', WS_VISIBLE or WS_CHILD or WS_TABSTOP or LVS_ICON or LVS_SINGLESEL or LVS_SHOWSELALWAYS, $200, 100, 0, 0, 312, 192, NULL
  Window  NONE, $0, $0, 'Button', 'OK', $50000001 or WS_TABSTOP, $0, MR_OK, 88, 200, 64, 25, NULL
  Window  NONE, $2, $0, 'Button', 'Cancel', $50000000 or WS_TABSTOP, $0, MR_CANCEL, 160, 200, 64, 25, NULL

  NewFilePrefix text 'Noname'
endg

uglobal
  hNewIml       dd ?
endg


;------------------------------------------
; actNewApplication action handler
;------------------------------------------
proc OnNew, .wparam, .lparam
.lvi LVITEM
.suf rb 8
begin
        stdcall CreateForm, frmNewFile, [hApplication]
        stdcall ShowModal, ebx, MSF_CENTER
        cmp     eax, MR_OK
        jne     .finish

        invoke  SendDlgItemMessageA, ebx, 100, LVM_GETNEXTITEM, -1, LVNI_FOCUSED
        cmp     eax, -1
        je      .finish

        mov     [.lvi.iItem], eax
        mov     [.lvi.iSubItem], 0
        mov     [.lvi.mask], LVIF_PARAM
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, ebx, 100, LVM_GETITEM, 0, eax
        test    eax, eax
        jz      .finish

        mov     eax, [.lvi.iItem]
        mov     eax, [FileTypeExt + 4*eax]
        mov     dword [.suf], eax
        mov     [.suf+4], 0
        lea     eax, [.suf]
        stdcall CreateUniqueName, NewFilePrefix, eax
        push    eax

        stdcall CreateFStruct, eax, [.lvi.lParam]
        mov     esi, eax

        cmp     [esi+TOpenFile.ptrType], ftProject
        je      .added
        invoke  SendMessageA, [hProjManager], PMM_ADDFILE, esi, -1
.added:
        stdcall LoadFile, esi, NULL

        stdcall StrDel ; from the stack.

.finish:
        invoke  DestroyWindow, ebx
        return
endp





proc frmNewProc, .hwnd, .wmsg, .wparam, .lparam
.lvi LVITEM
.count dd ?
begin
        cmp     [.wmsg], FM_AFTERCREATE
        je      .fmaftercreate

        cmp     [.wmsg], WM_NOTIFY
        je      .notify

.default:
        stc
        return

.fmaftercreate:
        stdcall ImageList_LoadGif, [hInstance], resBmpNewDlg, 32, FALSE
        invoke  SendDlgItemMessageA, [.hwnd], 100, LVM_SETIMAGELIST, LVSIL_NORMAL, eax

        mov     esi, FileTypeNames
        mov     edi, FileTypes
        mov     ebx, [esi]
        mov     [.count], ebx
        xor     ebx, ebx
        add     esi, 4

        invoke  SendDlgItemMessageA, [.hwnd], 100, LVM_SETITEMCOUNT, [.count], 0
.typeloop:
        mov     [.lvi.mask], LVIF_TEXT or LVIF_IMAGE or LVIF_PARAM
        lodsd   ; pointer to the string.
        mov     [.lvi.pszText], eax
        mov     eax, [edi+TFileType.iFileIcon]
        test    eax, eax
        jns     @f
        mov     eax, 8
@@:
        mov     [.lvi.iImage], eax
        mov     [.lvi.lParam], edi
        mov     [.lvi.iItem], ebx
        mov     [.lvi.iSubItem], 0
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], 100, LVM_INSERTITEM, 0, eax
        add     edi, sizeof.TFileType
        inc     ebx
        dec     [.count]
        jnz     .typeloop

        invoke  SendDlgItemMessageA, [.hwnd], 100, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_BORDERSELECT

        mov     [.lvi.stateMask], TVIS_FOCUSED or TVIS_SELECTED
        mov     [.lvi.state], TVIS_FOCUSED or TVIS_SELECTED
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], 100, LVM_SETITEMSTATE, 1, eax

        clc
        return

.notify:
        cmp     [.wparam], 100
        jne     .default

        mov     esi, [.lparam]
        cmp     [esi+NMHDR.code], NM_DBLCLK
        jne     .default

        invoke  SetPropA, [.hwnd], [propModalResult], MR_OK

        clc
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































Deleted source/actions.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
;*************************************************************
;* actions.inc
;*
;* This file contains Actions data.
;*
;* You must include it somewhere in data section of the program.
;*
;* You can use this work for any purpose, only don't forget to
;* write somewhere in docs: "Based on work of John Found" or
;* something similar. :)
;*
;* '2003 John Found
;*************************************************************


ImageChecked    = 11   ; index of the Image used for checked menu items, when there is no icon.


CoolData:

ActionList MainActionList, Accelerators,                                                                        \
  actNew,         0, '&New...',         <Ctrl, 'N'>,         'Opens new file dialog.',     OnNew,               \
  actNewApplication, -1, 'New &Application', <Ctrl+Shift, 'N'>, 'Creates new application project from template.', NewFromTemplate, \
  actOpen,        1, '&Open',           <Ctrl, 'O'>,         'Open file',                  OnOpen,              \
  actSave,        2, '&Save',           <Ctrl, 'S'>,         'Save file',                  OnSave,              \
  actSaveAs,     22, 'Save &As',        <NONE>,              'Save file with new name',    OnSaveAs,            \
  actSaveAll,    23, '&Save all',       <Ctrl + Shift, 'S'>, 'Save all',                   OnSaveAll,           \
  actFileClose,  -1, 'Close current page', <Ctrl, VK_F4>,    'Closes current file from source editor.', OnFileClose,    \
  actCloseAll,   -1, 'Close whole project', <NONE>,          'Closes all current open files and project', OnCloseAll,  \
  actExit,       -1, '&Exit',           <Alt,  'X'>,         'Exit program',               OnExit,              \
  actCleanupMRU, -1, '&Cleanup list',   <NONE>,              'Cleans the reopen list',     OnCleanupMRU,        \
\
  actUndo,       31, '&Undo',           <Ctrl, 'Z'>,         'Undo last change',           OnUndo,              \
  actCut ,        3, 'Cu&t',            <Ctrl, 'X'>,         'Cut to clipboard',           OnCut,               \
  actCopy,        4, '&Copy',           <Ctrl, 'C'>,         'Copy to clipboard',          OnCopy,              \
  actPaste,       5, '&Paste',          <Ctrl, 'V'>,         'Paste from clipboard',       OnPaste,             \
  actDelete,     -1, '&Delete',         <Ctrl, VK_DELETE>,   'Delete selection',           OnDelete,            \
  actInclude,    -1, '&Include',        <Ctrl + Alt, 'I'>,   'Insert "include" statement.', OnIncludeFile,      \
\
  actIndent,     16, '&Indent',         <Ctrl + Shift, 'I'>, 'Moves selected block to right.', OnIndent,         \
  actOutdent,    17, '&Outdent',        <Ctrl + Shift, 'U'>, 'Moves selected block to left.',  OnOutdent,        \
  actComment,    18, '&Comment',        <Ctrl + Shift, 'R'>, 'Comments selected text.',         OnComment,           \
  actUncomment,  19, '&Uncomment',      <Ctrl + Shift, 'E'>, 'Uncomments selected text.',      OnUncomment,         \
\
  actFindFirst,  28, '&Find...',        <Ctrl, 'F'>,         'Search in sources for specified string',  OnFindFirst,\
  actFindNext,   -1, 'Find &next',      <0, VK_F3>,          'Search in sources for next occurence of specified string',  OnFindNext,\
  actReplace,    29, '&Replace...',     <Ctrl, 'H'>,         'Replaces specified string by another',  OnReplace,\
  actOpenFileAtCursor, -1, '&Open file at cursor', <Ctrl, VK_RETURN>, 'Opens the file with name under cursor', OnOpenFileAtCursor,       \
\
  actToggleBM,   12, '&Toggle bookmark',<Ctrl, 'B'>,         'Toggle bookmark',            OnToggleBM,          \
  actNextBM,     14, '&Next bookmark',  <Ctrl, VK_DOWN>,     'Next bookmark',              OnNextBM,            \
  actPrevBM,     13, '&Previous bookmark',<Ctrl, VK_UP>,     'Previous bookmark',          OnPrevBM,            \
  actClearBM,    15, '&Clear bookmarks',<NONE>,              'Clear bookmarks',            OnClearBM,           \
\
  actShowForm,   -1, 'Switch &form/source', <0, VK_F12>,     'Switch between form and source', OnShowForm,      \
  actViewGrid,    7, '&Grid visible',   <NONE>,              'Show/Hide form grid lines.', OnGridView,          \
  actSnapToGrid,  8, '&Snap to grid',   <NONE>,              'On/Off snap to grid',        OnSnap,              \
  actPartSelect, 10, '&Partial select', <NONE>,              'On/Off partial select',      OnPartialSelect,     \
  actViewProjMan,-1, 'View p&roject manager', <Ctrl, 'P'>,   'Project manager is visible when checked', OnViewProjMan,          \
  actViewPropEditor,-1, 'View properties', <NONE>,           'Property editor is visible when checked', OnViewPropEditor,      \
  actViewSourceEditor,-1, 'View &editor', <Ctrl, 'E'>,       'Source editor is visible when checked',   OnViewSourceEditor,     \
\
  actSetMainFile, 27, '&Set main file', <NONE>,              'Set the main file of the project', OnSetMainFile,                 \
  actAddCategory, 26, 'Add ca&tegory', <NONE>,               'Add new category in the project.', OnAddCategory,                 \
  actAddFile,    25, '&Add file(s)',   <NONE>,               'Add a file(s) to the project',  OnAddFile,                        \
  actEditCategory,  -1, 'Category &properties', <NONE>, 'Edit category properties', OnEditCategory,                       \
  actAddToProject, 25, '&Add to project', <NONE>,              'Add current editor file to the project.', OnAddToProject,         \
  actSetCurrentMain, 27, '&Set as main', <NONE>,               'Set current editor file as main file.',  OnSetCurrentAsMain,      \
  actCompile,     9, '&Compile',       <Ctrl, VK_F9>,        'Compiles the project.',      OnCompile,                           \
  actShowMessages, -1, 'Show/Hide &messages', <Ctrl, 'M'>,   'Show/Hide message window.', OnShowMessages, \
  actExplorer,   -1, 'Labels &explorer', <NONE>,              'Shows all labels defined in the project.',  OnExplorer,      \
  actShowNotUsed, -1, 'Show not &used', <NONE>,       'Show not used labels.', OnShowNotUsed,                                   \
  actGotoAddr,    -1, '&Goto address',         <Ctrl, 'G'>,       'Find what row in the source is on given address.', OnGotoAddr,  \
  actGotoDefinition, -1, 'Goto &definition',   <Ctrl, 'D'>,   'Find definition of synbol under caret.', OnGotoDefinition,       \
  actCrossReference, -1, 'Cross &Reference',   <Ctrl, 'R'>,   'Display information and cross reference for the symbol under caret.', OnShowXRef, \
  actProjectOptions, -1, 'Project &options',   <Ctrl, VK_F12>, 'Edit project options.', OnProjectOptions,                       \
\
  actMoveCategoryUp, -1, 'Move &Up', <NONE>, <NONE>, OnMoveCategory,    \
  actMoveCategoryDn, -1, 'Move &Down', <NONE>, <NONE>, OnMoveCategory,  \
\
  actRun,        30, '&Run',           <0, VK_F9>,           'Compiles and runs the project', OnRun,                             \
  actRunDirect,  -1, 'Run &direct',    <Shift, VK_F9>,       'Compiles and runs the project without debuging feature.', OnRunDirect, \
  actPause,      32, '&Pause',         <0, VK_PAUSE>,        'Pause debugged process.', OnPause,                                  \
  actStepOver,   33, 'Step &over',      <0, VK_F8>,       'Step over calls.', OnStepOver,                                         \
  actStepInto,   34, 'Step &into',      <0, VK_F7>,       'Step into calls.', OnStepInto,                                         \
  actStop,       35, '&Stop',            <Alt, VK_PAUSE>, 'Terminate debuged process.', OnStop,                                  \
  actShowListing,-1, 'Sho&w listing',    <Ctrl+Shift, 'L'>, 'Show listing file.', OnShowListing,                                 \
\
  actDebug,      -1, '&External debugger',         <Shift, VK_F8>,           'Runs the project in debuger.', OnDebug,            \
\
  actIDEOptions,  -1, '&IDE options',   <NONE>,              <NONE>,                       OnIDEOptions,                \
  actEditOptions, -1, '&Editor options', <NONE>,             <NONE>,                       OnEditorOptions,             \
  actReloadVCL,  -1, '&Reload visual components', <NONE>,    <NONE>,                       OnReloadVCL,                 \
\
  actAutoArrange,-1, '&Auto arrange windows', <NONE>,         'Arranges the Fresh windows.', OnAutoArrange,             \
  actNextWindow, -1, '&Next file',     <Ctrl, VK_TAB>,        'Move to the next editor window', OnNextWindow,           \
  actPrevWindow, -1, '&Previous file', <Ctrl+Shift, VK_TAB>,  'Move to the previous editor window', OnPrevWindow,       \
\
  actHelp,       -1, '&Help',          <0, VK_F1>,              'Show context help for the word under the editor cursor',  OnHelp,        \
  actHelpFile,   -1, '&Help file',     <Ctrl, VK_F1>,           'Opens one of the configured help files.', OnOpenHelpFile,                \
  actAbout,      -1, '&About Fresh...', <NONE>,              <NONE>,                       OnAbout,                                       \
\ ; Graphic tools
  actSelectTool, 0, '&Select', <NONE>, <NONE>, OnNotImplemented,       \
  actWandTool, 1, '&Magic wand', <NONE>, <NONE>, OnNotImplemented,         \
  actPenTool, 2, '&Pen', <NONE>, <NONE>, OnNotImplemented,       \
  actFillTool, 4, '&Fill', <NONE>, <NONE>, OnNotImplemented,     \
\ ; Debuger actions
  actDumpAddress, -1, '&Dump memory', <0, VK_F5>, 'Dumps the memory of debugged process.', OnDumpAddress


CoolMenu MainMenu,                      \
  mfSubmenu, '&File',                   \
    mfNormal,    actNewApplication,     \
    mfNormal,    actNew,                \
    mfNormal,    actOpen,               \
    mfSubmenu, '&Reopen',               \
      mfNormal, actCleanupMRU,          \
      mfSeparator, NONE,                \
    mfEnd, END,                         \
    mfSeparator, NONE,                  \
    mfNormal,    actSave,               \
    mfNormal,    actSaveAs,             \
    mfNormal,    actSaveAll,            \
    mfSeparator, NONE,                  \
    mfNormal, actFileClose,             \
    mfNormal, actCloseAll,              \
    mfSeparator, NONE,                  \
    mfNormal,    actExit,               \
  mfEnd, END,                           \
  mfSubmenu, '&Edit',                   \
    mfNormal,    actUndo,               \
    mfSeparator, NONE,                  \
    mfNormal,    actCut,                \
    mfNormal,    actCopy,               \
    mfNormal,    actPaste,              \
    mfSeparator, NONE,                  \
    mfNormal,    actFindFirst,          \
    mfNormal,    actFindNext,           \
    mfNormal,    actReplace,            \
    mfSeparator, NONE,                  \
    mfNormal,    actIndent,             \
    mfNormal,    actOutdent,            \
    mfSeparator, NONE,                  \
    mfNormal,    actComment,            \
    mfNormal,    actUncomment,          \
    mfSeparator, NONE,                  \
    mfNormal,    actInclude,            \
    mfNormal,    actDelete,             \
  mfEnd, END,                           \
  mfSubmenu, '&View',                   \
    mfNormal,     actShowForm,          \
    mfSeparator,  NONE,                 \
    mfChecked,    actViewGrid,          \
    mfChecked,    actSnapToGrid,        \
    mfChecked,    actPartSelect,        \
    mfSeparator,  NONE,                 \
    mfChecked,    actViewProjMan,       \
    mfChecked,    actViewPropEditor,    \
    mfChecked,    actViewSourceEditor,  \
    mfNormal,     actShowMessages,      \
  mfEnd, END,                           \
  mfSubmenu, '&Bookmarks',              \
    mfNormal,    actToggleBM,           \
    mfSeparator, NONE,                  \
    mfNormal,    actNextBM,             \
    mfNormal,    actPrevBM,             \
    mfSeparator, NONE,                  \
    mfNormal,    actClearBM,            \
  mfEnd, END,                           \
  mfSubmenu, '&Project',                \
    mfNormal, actSetMainFile,           \
    mfNormal, actAddFile,               \
    mfNormal, actAddCategory,           \
    mfNormal, actEditCategory,          \
    mfSeparator, NONE,                  \
    mfNormal, actCompile,               \
    mfSeparator, NONE,                  \
    mfNormal, actShowNotUsed,           \
    mfNormal, actExplorer,              \
    mfSeparator, NONE,                  \
    mfNormal, actProjectOptions,        \
  mfEnd, END,                           \
  mfSubmenu, '&Debug',                  \
    mfNormal, actRun,                   \
    mfNormal, actRunDirect,             \
    mfSeparator, NONE,                  \
    mfNormal, actPause,                 \
    mfNormal, actStop,                  \
    mfSeparator, NONE,                  \
    mfNormal, actStepInto,              \
    mfNormal, actStepOver,              \
    mfSeparator, NONE,                  \
    mfNormal, actGotoAddr,              \
    mfNormal, actDebug,                 \
    mfSeparator, NONE,                  \
    mfNormal, actShowListing,           \
  mfEnd, END,                           \
  mfSubmenu, '&Options',                \
    mfNormal, actIDEOptions,             \
    mfNormal, actEditOptions,            \
    mfSeparator, NONE,                  \
    mfNormal, actReloadVCL,             \
  mfEnd, END,                           \
  mfSubmenu, '&Window',                \
    mfNormal, actFileClose,             \
    mfNormal, actCloseAll,              \
    mfNormal, actAutoArrange,           \
    mfSeparator,  NONE,                 \
    mfNormal, actNextWindow,            \
    mfNormal, actPrevWindow,            \
  mfEnd, END,                           \
  mfSubmenu, '&Help',                   \
    mfNormal, actHelp,                  \
    mfNormal, actHelpFile,              \
    mfSeparator, NONE,                  \
    mfNormal, actAbout,                 \
  mfEnd, END




CoolToolbar MainToolbar,                \
    bfButton,    actNew,                \
    bfDropDown,  actOpen,               \
    bfButton,    actSave,               \
    bfButton,    actSaveAll,            \
    bfSeparator, NONE,                  \
    bfButton,    actUndo,               \
    bfSeparator, NONE,                  \
    bfButton,    actCut,                \
    bfButton,    actCopy,               \
    bfButton,    actPaste,              \
    bfSeparator, NONE,                  \
    bfButton,    actCompile,            \
    bfSeparator, NONE,                  \
    bfButton,    actRun,                \
    bfButton,    actStop,               \
    bfButton,    actPause,              \
    bfButton,    actStepInto,           \
    bfButton,    actStepOver,           \
    bfSeparator, NONE,                  \
    bfCheck or bfChecked, actViewGrid,  \
    bfCheck or bfChecked, actSnapToGrid,\
    bfCheck or bfChecked, actPartSelect,\
    bfSeparator, NONE,                  \
    bfButton,    actIndent,             \
    bfButton,    actOutdent,            \
    bfSeparator, NONE,                  \
    bfButton,    actComment,            \
    bfButton,    actUncomment,          \
    bfSeparator, NONE,                  \
    bfButton,    actToggleBM,           \
    bfButton,    actPrevBM,             \
    bfButton,    actNextBM,             \
    bfButton,    actClearBM


    DispSize 'actions data', ($-CoolData)
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































Deleted source/breakpoints.asm.

1
2
3
4
5
6
7
8
9
10
11
struct TBreakpoint
  .Address dq ?
  .OldByte rb 4
  .Flags   dd ?
ends


brfStepOver = 1         ; breakpoint set by step-over function. Should be restored as soon as possible.
btfUser     = 2         ; breakpoint set by the user. Can be editted etc.
btfHardCoded = 3        ; breakpoint hardcoded in the source as int3. What we should do with it???

<
<
<
<
<
<
<
<
<
<
<






















Deleted source/dbgserver.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
;-------------------------------------------------------------------------------
; The idea is to make everything concerning debugger in  one separate thread
; and to command it through some commands.
;-------------------------------------------------------------------------------

;-----------------------------------------------------------
; Global variables for synchronization between Fresh and
; debugger.
;-----------------------------------------------------------
uglobal
  dbgStatus  dd ?

  align 16
  dbgEvent   TDebugEvent

  align 4
  dbgContext CONTEXT
  align 4
  dbgSInfo   STARTUPINFO
  align 4
  dbgPInfo   PROCESSINFO

  dbgCommand  dd ?

  intBreakAddr dd ?         ; internal breakpoint.
  intBreakOrig dd ?

  instrBuffer rb 256

  LastKnownLine dd ?

endg


byteInt3 = $cc



;-----------------------------------------------------------
; Thread procedure for debug server.
;-----------------------------------------------------------
;
; TODO: The debug server have to be implemented to get
;       commands from the message queue of the thread
;       not to poll the command variable.
;       this will ensure low resource consumpsion and
;       will not need wait states while server is busy.
;

proc DebuggerThread, .hFileName
begin
; Run the debugged program.
        mov     ecx, sizeof.STARTUPINFO shr 2
        mov     edi, dbgSInfo
        xor     eax, eax
        rep stosd

        mov     [dbgSInfo.cb], sizeof.STARTUPINFO

        stdcall StrPtr, [CompiledFileName]
        invoke  CreateProcessA, eax, NULL, NULL, NULL, FALSE,                            \
                               NORMAL_PRIORITY_CLASS or DEBUG_PROCESS or DEBUG_ONLY_THIS_PROCESS, \
                               NULL, NULL, dbgSInfo, dbgPInfo
        test    eax,eax
        jz      .StartError

        stdcall SetDbgStatus, dsRunning
        mov     [dbgCommand], 0

        stdcall TDumper.DumpAddress, $4013fd, [dbgPInfo.hProcess]

.debuggerloop:
        invoke  WaitForDebugEvent, dbgEvent, 100
        test    eax, eax
        jnz     .event_raised

.commandloop:
        cmp     [dbgCommand], 0
        je      .debuggerloop

        call    ExecuteCommand
        jc      .event_raised

        cmp     [dbgStatus], dsPaused
        je      .commandloop

        cmp     [dbgStatus], dsRunning
        je      .debuggerloop

        xor     eax, eax
        return

;------------- On debugger event raised --------------------------
.event_raised:
        mov     [dbgCommand], 0
        stdcall SetDbgStatus, dsPaused

        invoke  SendMessageA, [hMainWindow], DM_EVENTRAISED, 0, 0        ; Notify main window

        mov     [dbgCommand], eax
        call    ExecuteCommand
        jc      .event_raised

        cmp     [dbgStatus], dsFinished
        jne     .debuggerloop

        xor     eax, eax
        return

.StartError:
        mov     eax, 1
        return
endp


ExecuteCommand:
        cmp     [dbgCommand], 0
        je      .exit

        mov     ebx, [dbgCommand]

.docommand:
        cmp     ebx, dbgcContinue
        je      .continue

        cmp     ebx, dbgcContinueNotHandled
        je      .continuenh

        cmp     ebx, dbgcKillProcess
        je      .killprocess

        cmp     ebx, dbgcFinish
        je      .finish

        cmp     ebx, dbgcPause
        je      .pause

        cmp     ebx, dbgcStepInto
        je      .stepinto

        cmp     ebx, dbgcStepOver
        je      .stepover

.endcommand:
        mov     [dbgCommand], 0
.exit:
        clc
        ret

.endcommand_with_event:
        mov     [dbgCommand], 0
        stc
        ret


.stepover:
; find the next assembled line.
        mov     ecx, [ptrDebugInfo]
        mov     ecx, [ecx+TArray.count]
        imul    ecx, sizeof.TDebugLine
        lea     ecx, [ecx+TArray.array]
        add     ecx, [ptrDebugInfo]

        mov     eax, [LastKnownLine]
        mov     edx, [eax+TDebugLine.ptrFile]
        mov     ebx, [eax+TDebugLine.LineNum]

.nextsearch:
        add     eax, sizeof.TDebugLine

        cmp     eax, ecx
        jae     .endcommand

        cmp     edx, [eax+TDebugLine.ptrFile]
        jne     .foundnext
        cmp     ebx, [eax+TDebugLine.LineNum]
        je      .nextsearch

.foundnext:
        mov     ecx, dword [eax+TDebugLine.Address]
        mov     [intBreakAddr], ecx

; put int3 at it.
        invoke  ReadProcessMemory, [dbgPInfo.hProcess], [intBreakAddr], intBreakOrig, 1, NULL
        mov     [instrBuffer], byteInt3
        invoke  WriteProcessMemory, [dbgPInfo.hProcess], [intBreakAddr], instrBuffer, 1, NULL

; then continue the program.
        invoke  ContinueDebugEvent, [dbgEvent.dwProcessId], [dbgEvent.dwThreadId], DBG_CONTINUE

; wait for event to become.
        invoke  WaitForDebugEvent, dbgEvent, 1000   ; wait to stop again.
        push    eax

; restore original instruction.
        invoke  WriteProcessMemory, [dbgPInfo.hProcess], [intBreakAddr], intBreakOrig, 1, NULL

; check for timeout.
        pop     eax
        test    eax, eax
        jnz     .have_event

        stdcall SetDbgStatus, dsRunning    ; if timeout then go pause the process. something goes wrong.
        jmp     .endcommand

; check for EXCEPTION_BREAKPOINT. If another event, go pause.
.have_event:
        cmp     [dbgEvent.dwDebugEventCode], EXCEPTION_DEBUG_EVENT
        jne     .endcommand_with_event

        cmp     [dbgEvent.Exception.ExceptionRecord.ExceptionCode], EXCEPTION_BREAKPOINT
        jne     .endcommand_with_event

        mov     [dbgContext.ContextFlags], CONTEXT_FULL
        invoke  GetThreadContext, [dbgPInfo.hThread], dbgContext

; it is breakpoint, but is it the right breakpoint?
        mov     eax, [dbgContext.regEip]
        dec     eax
        cmp     eax, [intBreakAddr]
        jne     .eipok
        mov     [dbgContext.regEip], eax
        invoke  SetThreadContext, [dbgPInfo.hThread], dbgContext

.eipok:
; update editors and display
        stdcall FindAddressPosition, [dbgContext.regEip]
        test    eax,eax
        jz      .unknownposition

        mov     [LastKnownLine], eax
        stdcall PosEditor, [eax+TDebugLine.ptrFile], [eax+TDebugLine.LineNum]
        invoke  SendMessageA, [hLister], LM_SHOWLIST, eax, 0

        invoke  GetDlgItem, [hPropEditor], 101
        invoke  ShowWindow, eax, SW_SHOW
        jmp     .endcommand

.unknownposition:
        invoke  GetDlgItem, [hPropEditor], 101
        invoke  ShowWindow, eax, SW_HIDE
        jmp     .continue


.stepinto:
        mov     [dbgContext.ContextFlags], CONTEXT_CONTROL
        invoke  GetThreadContext, [dbgPInfo.hThread], dbgContext
        or      [dbgContext.regFlag], $100
        invoke  SetThreadContext, [dbgPInfo.hThread], dbgContext
        invoke  ContinueDebugEvent, [dbgEvent.dwProcessId], [dbgEvent.dwThreadId], DBG_CONTINUE
        jmp     .endcommand


.continue:
        invoke  ContinueDebugEvent, [dbgEvent.dwProcessId], [dbgEvent.dwThreadId], DBG_CONTINUE
        stdcall SetDbgStatus, dsRunning
        jmp     .endcommand

.continuenh:
        invoke  ContinueDebugEvent, [dbgEvent.dwProcessId], [dbgEvent.dwThreadId], DBG_EXCEPTION_NOT_HANDLED
        stdcall SetDbgStatus, dsRunning
        jmp     .endcommand

.getcontext:
        invoke  GetThreadContext, [dbgPInfo.hThread], dbgContext
        jmp     .endcommand

.pause:
        invoke  SuspendThread, [dbgPInfo.hThread]
        mov     [dbgContext.ContextFlags], CONTEXT_CONTROL
        invoke  GetThreadContext, [dbgPInfo.hThread], dbgContext
        or      [dbgContext.regFlag], $100
        invoke  SetThreadContext, [dbgPInfo.hThread], dbgContext
        invoke  ResumeThread, [dbgPInfo.hThread]
        jmp     .endcommand


.killprocess:
        invoke  TerminateProcess, [dbgPInfo.hProcess], -1
        mov     [dbgEvent.dwDebugEventCode], EXIT_PROCESS_DEBUG_EVENT
        mov     [dbgEvent.ExitProcess.dwExitCode], -1
        invoke  SendMessageA, [hMainWindow], DM_EVENTRAISED, 0, 0

.finish:
        invoke  ContinueDebugEvent, [dbgEvent.dwProcessId], [dbgEvent.dwThreadId], DBG_CONTINUE
        stdcall SetDbgStatus, dsFinished

        invoke  CloseHandle, [dbgPInfo.hThread]
        invoke  CloseHandle, [dbgPInfo.hProcess]

        ret



proc SetDbgStatus, .status
begin
        mov     eax, [.status]
        cmp     [dbgStatus], eax
        je      .finish

        mov     [dbgStatus], eax
        invoke  PostMessageA, [hMainWindow], DM_STATUSCHANGED, 0, 0

.finish:
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































Deleted source/dbgserver.inc.

1
2
3
4
5
6
7
8
9
10
11
dsRunning = 1
dsPaused  = 2
dsFinished = 3

dbgcContinue = 1
dbgcContinueNotHandled = 2
dbgcKillProcess = 3
dbgcFinish = 4
dbgcPause = 5
dbgcStepInto = 6
dbgcStepOver = 7
<
<
<
<
<
<
<
<
<
<
<






















Deleted source/debug.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
uglobal
align 4
  LastAddr      dd ?
  LastPtrLine   dd ?
  LastVirt      db ?

align 4
  ptrMainFilename dd ?  ; pointer to a copy of the main filename.

  ptrDebugInfo  dd ?   ; Dynamic array with TLineInfo elements.
  ptrListing    dd ?   ; Pointer to TMemoryStream structures with the listing.

  AsmLines      dd ?   ; count of the lines assembled to code
  TotalLines    dd ?   ; count of all compiled lines
endg

cInitListingSize = 65536

proc InitDebugInfo
begin
        stdcall ClearDebugInfo

        stdcall StrLen, [input_file]
        add     eax, 1
        push    eax

        stdcall GetMem, eax
        mov     [ptrMainFilename], eax
        mov     edi, eax
        mov     esi, [input_file]
        pop     ecx
        rep movsb

        stdcall CreateArray, sizeof.TDebugLine
        mov     [ptrDebugInfo], eax

        stdcall CreateMemoryStream, ptrListing, cInitListingSize
        return
endp



proc  ClearDebugInfo
begin
        stdcall DestroyDebugInfo, ptrDebugInfo

        cmp     [ptrMainFilename], 0
        je      .clearok

        stdcall FreeMem, [ptrMainFilename]
        mov     [ptrMainFilename], 0

.clearok:
        return
endp


proc DestroyDebugInfo, .ptrVarArray
begin
        push    esi ebx

        mov     esi, [.ptrVarArray]
        cmp     dword [esi], 0
        je      .finish

        xor     ebx, ebx
        xchg    ebx, [esi]

        test    ebx, ebx
        jz      .debugok

        stdcall FreeMem, ebx

.debugok:
        stdcall FreeMem, [ptrListing]
        mov     [ptrListing], 0

.finish:
        pop     ebx esi
        return
endp





proc CaptureDebugInfo, .ptrFAS
.asmlen dd ?
begin
        pushad

        stdcall InitDebugInfo

        mov     ebx, [.ptrFAS]
        mov     esi, [ebx+TDumpHeader.ofsAsmDump]
        add     esi, ebx

        mov     eax, [ebx+TDumpHeader.lenAsmDump]
        mov     [.asmlen], eax

        mov     [TotalLines], 0
        mov     [AsmLines], 0

.linesloop:
        cmp     [.asmlen], 4
        jbe     .endofdump

        inc     [TotalLines]

        cmp     [esi+TAsmDumpElement.flagVirtual], 0
        jne     .nextline

        cmp     [esi+TAsmDumpElement.extSIB],0
        jne     .nextline

        cmp     [.asmlen], 4+sizeof.TAsmDumpElement       ; last line of the code...???
        ja      .notlast

        mov     eax, dword [esi+TAsmDumpElement.ofsBinary]
        cmp     eax, dword [esi+sizeof.TAsmDumpElement]
        je      .nextline
        jmp     .thisline

.notlast:
        cmp     [esi+TAsmDumpElement.extSIB+sizeof.TAsmDumpElement], 0
        jne     .nextline

        cmp     [esi+TAsmDumpElement.flagVirtual+sizeof.TAsmDumpElement], 0
        jne     .nextline

        mov     eax, dword [esi+TAsmDumpElement.ofsBinary]
        cmp     eax, dword [esi+TAsmDumpElement.ofsBinary+sizeof.TAsmDumpElement]
        je      .nextline

.thisline:
        inc     [AsmLines]

        mov     ebx, [esi+TAsmDumpElement.ofsPreprocessed]
        add     ebx, [ptrPreprocessed]

; process one line, pointed by ebx
        stdcall CreateLineString, ebx
        push    eax

.findbaseline:
        test    byte [ebx+TIntLine.LineNumber+3], $80
        jz      .lineok

        mov     eax, [ebx+TIntLine.ofsGenerator]
        add     eax, [ptrPreprocessed]
        cmp     word [eax+1], '__'      ; is it internal macro definition?
        je      .searchdown

        mov     ebx, [ebx+TIntLine.ofsSourceLine] ; get the line where the macro was invoked.
        add     ebx, [ptrPreprocessed]
        jmp     .findbaseline

.searchdown:
        mov     ebx, [ebx+TIntLine.ofsMacroLine]
        add     ebx, [ptrPreprocessed]
        test    byte [ebx+TIntLine.LineNumber+3], $80
        jnz     .searchdown

.lineok:
        stdcall AddArrayItems, [ptrDebugInfo], 1
        mov     [ptrDebugInfo], edx
        mov     edi, eax

        pop     [edi+TDebugLine.strLine]

        mov     eax, dword [esi+TAsmDumpElement.Address]
        mov     edx, dword [esi+TAsmDumpElement.Address+4]
        mov     dword [edi+TDebugLine.Address], eax
        mov     dword [edi+TDebugLine.Address+4], edx

        mov     ecx, dword [ebx+TIntLine.LineNumber] ; line number.
        mov     [edi+TDebugLine.LineNum], ecx

        mov     ecx, [ebx+TIntLine.ofsGenerator]
        test    ecx, ecx
        jnz     .fileok

        mov     ecx, [ptrMainFilename]
        sub     ecx, [ptrPreprocessed]

.fileok:
        add     ecx, [ptrPreprocessed]
        mov     [edi+TDebugLine.ptrFile], ecx

.nextline:
        add     esi, sizeof.TAsmDumpElement
        sub     [.asmlen], sizeof.TAsmDumpElement
        jmp     .linesloop

.endofdump:
        stdcall VacuumArray, [ptrDebugInfo]

        popad
        return
endp








proc CreateLineString, .ptrLine
.char dd ?
begin
        push    esi edi ebx

        stdcall GetStreamRoom, ptrListing, $1000
        push    edi                             ; this will be returned.
        add     edi, ebx

        mov     esi, [.ptrLine]
        lea     esi, [esi+TIntLine.PreprocessedLine]

        mov     [.char], $09

.getloop:
        lodsb
        test    al, al
        jz      .eol
        cmp     al, $3b
        je      .ignore
        cmp     al, $1a         ; prefix of token
        je      .token
        cmp     al, $22         ; quoted text.
        je      .quoted

        stosb
        cmp     al,','
        jne     .getloop
        mov     al,$20
        stosb
        jmp     .getloop

.quoted:
        mov     al, "'"
        stosb

        lodsd   ; length
        mov     ecx, eax
        rep movsb

        mov     al, "'"
        stosb
        jmp     .getloop

.token:
        movzx   ecx, byte [esi]
        inc     esi
        rep movsb               ; copy the token to the output string.

        cmp     byte [esi], '['
        je      .tab
        cmp     byte [esi], $1a
        jne     .getloop
.tab:
        mov     al, byte [.char]
        mov     byte [.char], $20
        stosb
        jmp     .getloop

.ignore:
        mov     al, 0

.eol:
        stosb

        sub     edi, ebx
        mov     [ebx+TMemoryStream.offset], edi

        pop     eax
        pop     ebx edi esi
        return
endp




;--------------------------------------------------------------
; Find the file and line of the source, where some address
; is generate.
; Returns:
;   eax: pointer to the TDebugLine record - 0 means not found
;--------------------------------------------------------
proc FindAddressPosition, .addr
begin
        push    ecx edx

        mov     eax, [ptrDebugInfo]
        test    eax, eax
        jz      .notfound

        mov     ecx, [eax+TArray.count]
        lea     eax, [eax+TArray.array]
        mov     edx, [.addr]

.search:
        jecxz   .notfound
        cmp     edx, dword [eax+TDebugLine.Address]
        jbe     .finish
        add     eax, sizeof.TDebugLine
        dec     ecx
        jmp     .search

.notfound:
        xor     eax, eax

.finish:
        pop     edx ecx
        return
endp







;--------------------------------------------------
; Positions the editor to the file/line
;--------------------------------------------------
uglobal
  fSetCurrent dd ?
endg


proc PosEditor, .hFileName, .LineNum
.aepos AEPOS
begin
        push    eax ebx ecx edx
        stdcall ConvertPath, [.hFileName]
        push    eax

        stdcall OpenFileByName, eax, NULL, TRUE
        stdcall StrDel ; from the stack.
        test    eax, eax
        jz      .finish

        mov     ebx, [eax+TOpenFile.hEditor]
        mov     [fSetCurrent], ebx

        invoke  SendMessageA, ebx, AEM_SETFOCUSLINE, [.LineNum], 0
        invoke  RedrawWindow, ebx, NULL, NULL, RDW_UPDATENOW

        invoke  SetForegroundWindow, ebx

; workaround, because AEM_SETFOCUSLINE do not move the caret.
        mov     [.aepos.selectionPosition], 1
        mov     [.aepos.caretPosition], 1
        mov     eax, [.LineNum]
        mov     [.aepos.selectionLine], eax
        mov     [.aepos.caretLine], eax
        lea     eax, [.aepos]
        invoke  SendMessageA, ebx, AEM_SETPOS, eax, 0

; Work around, because of some bug in AsmEdit, that make caret to dissapear, even when
; the control have an input focus.
        invoke  SetFocus, 0
        invoke  SetFocus, ebx

        mov     [fSetCurrent], 0
.finish:
        pop     edx ecx ebx eax
        return
endp



;----------------------------------------------------------
; Returns the address in binary of some line from file
;----------------------------------------------------------
proc FindAddress, .hFilename, .linenum
begin

endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































Deleted source/debug.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
;----------------------------------------------------
; This structure describes one element of the array
; with debug information.
;----------------------------------------------------
struct TDebugLine
  .Address        dq ?          ;
  .strLine        dd ?          ; pointer to string with real line after macroses executed.
  .ptrFile        dd ?          ; pointer to the filename.
  .LineNum        dd ?          ; line number in the file.
ends


struct TAsmDumpElement
  .ofsBinary       dd ?       ; offset of the line in the output binary file.
  .ofsPreprocessed dd ?       ; offset of the line in preprocessed file.
  .Address         dq ?       ; value of $ for this line.
  .extSIB          dd ?       ; Extended SIB for the $ address, the first two bytes
                              ; are register codes and the second two bytes are corresponding scales.
  .RelocatibleTo   dd ?
  .AddrType        db ?
  .codeType        db ?       ; 16, 32 or 64
  .flagVirtual     db ?       ; <>0 means .ofsBinary is meaningless because the line is not included.; 1 = virtual block; 2 = missing from the binary, because of other reason.
  .reserved        db ?
ends
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































Deleted source/debugger.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
uglobal
  hDebugThread dd ?
  hDebugFileImage dd ?
endg



; helper routine for running applications with
; programs such debuggers/emulators
proc RunIndirect, .pszApplication
.sinfo  STARTUPINFO
.pinfo  PROCESSINFO
begin
;        stdcall FileExists, [.pszApplication]
;        test    eax,eax
;        jz      .finish

        mov     ecx, sizeof.STARTUPINFO/4
        lea     edi,[.sinfo]
        xor     eax, eax
        rep     stosd
        mov     [.sinfo.cb], sizeof.STARTUPINFO
        mov     [.sinfo.dwFlags], STARTF_USESHOWWINDOW
        mov     [.sinfo.wShowWindow], SW_HIDE
        lea     ecx,[.pinfo]
        lea     eax,[.sinfo]
        push    ecx eax
        stdcall StrDup, [.pszApplication]
        mov     ebx,eax
        stdcall StrCharCat, ebx,' '
        stdcall StrCat, ebx, [CompiledFileName]
        stdcall StrPtr,ebx
        invoke  CreateProcessA, NULL, eax, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS , NULL, NULL
        test    eax,eax
        jnz     .ok
        stdcall LastError
   .ok:
        invoke  CloseHandle,[.pinfo.hThread]
        invoke  CloseHandle,[.pinfo.hProcess]
   .finish:
        return
endp


proc Execute, .hLine
.process PROCESS_INFORMATION
.startup STARTUPINFO
.exit_code dd ?
begin
        push    edi ecx edx

        lea     edi, [.startup]
        xor     eax, eax
        mov     ecx, sizeof.STARTUPINFO / 4
        rep stosd
        mov     [.startup.cb], sizeof.STARTUPINFO

        lea     edi, [.process]
        xor     eax, eax
        mov     ecx, sizeof.PROCESS_INFORMATION / 4
        rep stosd

        stdcall StrPtr, [.hLine]
        lea     ecx, [.process]
        lea     edx, [.startup]
        invoke  CreateProcessA, NULL, eax, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS , NULL, NULL, edx, ecx
        test    eax, eax
        jz      .failed
        invoke  WaitForSingleObject, [.process.hProcess], 1000
        cmp     eax, WAIT_TIMEOUT
        je      .timeout

        lea     ecx, [.exit_code]
        invoke  GetExitCodeProcess, [.process.hProcess], ecx
.ok:
        clc
        pop     edx ecx edi
        return


.timeout:
        invoke  TerminateProcess, [.process.hProcess], -1
        xor     eax, eax
        dec     eax

.failed:
        stc
        pop     edx ecx edi
        return
endp




iglobal
  LinuxFull      db ' ./FreshProgram', 0
  LinuxProg      db '\FreshProgram', 0
  AndCmd         db '\Launcher\andCmd.exe" ', 0
  LinuxScript666 db 'chmod 666 windows/FreshProgram', 0
  LinuxScriptRM  db 'rm windows/FreshProgram', 0
  LinuxScript777 db 'chmod 777 windows/FreshProgram', 0
  LinuxScriptCD  db ' cd windows; ', 0
endg



proc RunInLinux, .fDebug

.htarget dd ?
.sinfo  STARTUPINFO
.pinfo  PROCESSINFO
.hexec dd ?
.filename dd ?
.wine_get_unix_file_name dd ?

begin
        pushad

; check for wine
        invoke  LoadLibraryA, 'kernel32.dll'
        test    eax, eax
        jz      .finish         ; Strange error???

        invoke  GetProcAddress, eax, 'wine_get_unix_file_name'
        test    eax, eax
        jz      .andLinux

; run it directly
        mov     [.wine_get_unix_file_name], eax

; get the Linux filename of the executable.
        stdcall utf8ToWideChar, [CompiledFileName]

        push    eax
        call   [.wine_get_unix_file_name]
        ; it is ccall so, the argument is still in the stack.

        stdcall FreeMem ; from the stack.

        push    eax
        stdcall StrDup, eax
        mov     [.filename], eax
        stdcall FreeMem ; the address returned by wine_get_unix_file_name must be freed by
                        ; HeapFree(GetProcessHeap(), ...) - As long as FreeMem for Win32 uses
                        ; the process heap, everything is OK.

; set execute permissions to the file:
        stdcall StrPtr, eax
        mov     ebx, eax

        mov     eax, $0f  ; sys_chmod
        mov     ecx, 755o ; 755 permissions.
        int     80h       ; Linux system call.

        mov     eax, cLinuxTerminalKey
        cmp     [.fDebug], FALSE
        je      @f
        mov     eax, cLinuxDbgKey
@@:
        stdcall GetParamFromINI, eax
        jnc     .terminal_ok

        stdcall StrDup, [.filename]
        jmp     .exec_ok

.terminal_ok:
        stdcall StrCharCat, eax, ' '
        stdcall StrCat, eax, [.filename]

.exec_ok:
        mov     [.hexec], eax

        mov     ecx, sizeof.STARTUPINFO
        shr     ecx, 2
        lea     edi,[.sinfo]
        xor     eax, eax
        rep stosd
        mov     [.sinfo.cb], sizeof.STARTUPINFO
        mov     [.sinfo.dwFlags],0
        lea     ecx,[.pinfo]
        lea     eax,[.sinfo]
        push    ecx eax
        stdcall StrPtr, [.hexec]

        invoke  CreateProcessA, NULL, eax, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL
        test    eax,eax
        jnz     .ok

        stdcall LastError
.ok:
        invoke  CloseHandle,[.pinfo.hThread]
        invoke  CloseHandle,[.pinfo.hProcess]
        stdcall StrDel, [.hexec]
        stdcall StrDel, [.filename]

        clc
        popad
        return

.err_runelf:
        stdcall StrDel, [.filename]
        stc
        popad
        return

; run it using andLinux
.andLinux:
        stdcall GetParamFromINI, cAndLinuxSharedKey
        jc      .finish

        mov     [.htarget], eax
        stdcall StrCat, eax, LinuxProg

        stdcall GetParamFromINI, cAndLinuxKey
        jc      .finish2

        mov     ebx, eax
        stdcall StrCat, ebx, AndCmd
        stdcall StrCharInsert, ebx, '"', 0

; change mode
        stdcall StrDup, ebx
        mov     esi, eax

; change permisions to 666
        stdcall StrCat, esi, LinuxScript666
        stdcall Execute, esi
        jc      .failed

; remove the file
        stdcall StrCopy, esi, ebx
        stdcall StrCat, esi, LinuxScriptRM
        stdcall Execute, esi
        jc      .failed

; copy the file
        stdcall StrPtr, [CompiledFileName]
        stdcall LoadBinaryFile, eax
        jc      .failed

        push    eax

        push    ecx
        push    eax

        stdcall StrPtr, [.htarget]
        stdcall SaveBinaryFile, eax  ; remaining, arguments from stack
        pop     ecx
        pushf
        stdcall FreeMem, ecx
        popf
        jc      .failed

; change permisions to 777
        stdcall StrCopy, esi, ebx
        stdcall StrCat, esi, LinuxScript777

        stdcall Execute, esi
        jc      .failed

; so what to do?
        mov     eax, cLinuxTerminalKey
        cmp     [.fDebug], 0
        je      .keyok

        mov     eax, cLinuxDbgKey

.keyok:
; execute the program.
        stdcall StrCopy, esi, ebx
        stdcall StrCat, esi, LinuxScriptCD

        stdcall GetParamFromINI, eax
        jc      .failed

        push    eax
        stdcall StrCat, esi, eax
        stdcall StrDel ; from the stack
        stdcall StrCat, esi, LinuxFull
        stdcall Execute, esi
        jc      .failed

        stdcall StrDel, esi
        stdcall StrDel, [.htarget]
        clc
        popad
        return

.failed:
        stdcall StrDel, esi

.finish2:
        stdcall StrDel, [.htarget]

.finish:
        stc
        popad
        return
endp



proc OnRun, .wparam, .lparam
begin
        cmp     [hDebugThread], 0
        jne     .rundebugged

        stdcall OnCompile, 0, 0

        cmp     eax, MR_OK
        jne     .finish         ; There are errors during compilation.

        stdcall WaitForCompiler

        cmp     [output_format],5
        je      .runELF

        cmp     [output_format],4
        jae     .runObject

        cmp     [output_format], 3
        jne     .dos

        invoke  SendMessageA, [frmMsg], MWM_CLEARMESSAGES, 0, 0

        stdcall ThreadCreate, DebuggerThread, [output_file]
        mov     [hDebugThread], eax
        test    eax, eax
        jz      .errorthread
        return

.errorthread:
        call    LastError
.finish:
        return

.runObject:
        invoke  MessageBoxA, [hApplication], cRunObjectError, NULL, MB_ICONERROR+MB_OK
        return

.runELF:
        stdcall RunInLinux, FALSE
        jnc     .elfok
        invoke  MessageBoxA, [hApplication], cRunLinuxError, NULL, MB_ICONERROR+MB_OK
.elfok:
        return

iglobal
  cRunLinuxError db "Linux application can't be started.",0
endg

.dos:
        stdcall OnRunDirect, 3, 0
        return

.rundebugged:
        cmp     [dbgStatus], dsPaused
        jne     .finish

        call    ResetSingleStep
        return
endp

iglobal
  cRunObjectError db "Can't execute object file.",0
endg


; --------------------------------------------------------------
; if wparam = 3 then the source is compiled, so simply run it.
; --------------------------------------------------------------
proc OnRunDirect, .wparam, .lparam
.sinfo  STARTUPINFO
.pinfo  PROCESSINFO
begin
        cmp     [.wparam], 3
        je      .compileok

        stdcall OnCompile, 0, 0
        cmp     eax, MR_OK
        jne     .finish         ; There are errors during compilation.

.compileok:
        cmp     [output_format],5
        je      OnRun.runELF

        cmp     [output_format],4
        jae     OnRun.runObject

        mov     ecx, sizeof.STARTUPINFO
        shr     ecx, 2
        lea     edi,[.sinfo]
        xor     eax, eax
        rep stosd
        mov     [.sinfo.cb], sizeof.STARTUPINFO
        mov     [.sinfo.dwFlags],0
        lea     ecx,[.pinfo]
        lea     eax,[.sinfo]
        push    ecx eax
        stdcall StrPtr, [CompiledFileName]
        invoke  CreateProcessA,eax,NULL,NULL,NULL,FALSE, NORMAL_PRIORITY_CLASS,NULL,NULL
        test    eax,eax
        jnz     .ok

        stdcall LastError
.ok:
        invoke  CloseHandle,[.pinfo.hThread]
        invoke  CloseHandle,[.pinfo.hProcess]

.finish:
        return
endp





proc OnStepInto, .wparam, .lparam
begin
        cmp     [dbgStatus], dsPaused
        jne     .finish

        call    WaitForCommandOrTimeout
        jc      .finish

        mov     [dbgCommand], dbgcStepInto

.finish:
        return
endp


proc OnStepOver, .wparam, .lparam
begin
        cmp     [dbgStatus], dsPaused
        jne     .finish

        call    WaitForCommandOrTimeout
        jc      .finish

        mov     [dbgCommand], dbgcStepOver

.finish:
        return
endp


proc OnPause, .wparam, .lparam
begin
        call    WaitForCommandOrTimeout
        jc      @f
        mov     [dbgCommand], dbgcPause
@@:
        return
endp


proc OnStop, .wparam, .lparam
begin
        call     WaitForCommandOrTimeout
        jc       @f
        mov      [dbgCommand], dbgcKillProcess
@@:
        return
endp




proc ResetSingleStep
begin
        mov     [dbgContext.ContextFlags], CONTEXT_CONTROL
        invoke  GetThreadContext, [dbgPInfo.hThread], dbgContext
        and     [dbgContext.regFlag], $fffffeff
        invoke  SetThreadContext, [dbgPInfo.hThread], dbgContext
        call    WaitForCommandOrTimeout
        jc      @f
        mov     [dbgCommand], dbgcContinue
@@:
        return
endp



iglobal
cDebugNumberHex = ntsHex or ntsUnsigned or ntsFixedWidth or 8
DebuggerProperties:
      PropInfo                                                                      \
        'EAX', ptDword, CONTEXT.regEax, IntPropEditor,    cDebugNumberHex, 0,       \
        'EBX', ptDword, CONTEXT.regEbx, IntPropEditor,    cDebugNumberHex, 0,       \
        'ECX', ptDword, CONTEXT.regEcx, IntPropEditor,    cDebugNumberHex, 0,       \
        'EDX', ptDword, CONTEXT.regEdx, IntPropEditor,    cDebugNumberHex, 0,       \
        'ESI', ptDword, CONTEXT.regEsi, IntPropEditor,    cDebugNumberHex, 0,       \
        'EDI', ptDword, CONTEXT.regEdi, IntPropEditor,    cDebugNumberHex, 0,       \
        'EBP', ptDword, CONTEXT.regEbp, IntPropEditor,    cDebugNumberHex, 0,       \
        'ESP', ptDword, CONTEXT.regEsp, IntPropEditor,    cDebugNumberHex, 0,       \
        'EIP', ptDword, CONTEXT.regEip, IntPropEditor,    cDebugNumberHex, 0,       \
        'flags', ptDword, CONTEXT.regFlag, IntPropEditor, cDebugNumberHex, 0
;        'CS:', ptDword, CONTEXT.regCs, IntPropEditor,    cDebugNumberHex, 0,       \
;        'SS:', ptDword, CONTEXT.regSs, IntPropEditor,    cDebugNumberHex, 0,       \
;        'DS:', ptDword, CONTEXT.regDs, IntPropEditor,    cDebugNumberHex, 0,       \
;        'ES:', ptDword, CONTEXT.regEs, IntPropEditor,    cDebugNumberHex, 0,       \
;        'FS:', ptDword, CONTEXT.regFs, IntPropEditor,    cDebugNumberHex, 0,       \
;        'GS:', ptDword, CONTEXT.regGs, IntPropEditor,    cDebugNumberHex, 0
endg



proc WaitForCommandOrTimeout
begin

.wait:
        cmp     [dbgCommand], 0
        je      .finish

        invoke  GetCurrentThread
        invoke  WaitForSingleObject, eax, 100
        cmp     [dbgCommand], 0
        jne     .timeout

.finish:
        clc
        return
.timeout:
        stc
        return
endp



proc UpdateThreadContext, .ptrContext
begin
        cmp     [dbgStatus], dsPaused
        jne     @f

        mov     [dbgContext.ContextFlags], CONTEXT_FULL
        invoke  SetThreadContext, [dbgPInfo.hThread], [.ptrContext]
@@:
        return
endp




iglobal
  TblDebugEvents dd  DbgEventUnknown
                 dd  DbgEventException
                 dd  DbgEventCreateThread
                 dd  DbgEventCreateProcess
                 dd  DbgEventExitThread
                 dd  DbgEventExitProcess
                 dd  DbgEventLoadDll
                 dd  DbgEventUnloadDll
                 dd  DbgEventOutputString
                 dd  DbgEventRIP

  cDbgEventUnknown        db      'Unknown debug event.', 0
  cDbgEventException      db      'Exception:',0
  cDbgEventCreateThread   db      'New thread created',0
  cDbgEventCreateProcess  db      'New process created',0
  cDbgEventExitThread     db      'Thread terminated',0
  cDbgEventExitProcess    db      'Process terminated',0
  cDbgEventLoadDll        db      'DLL loaded: ',0
  cDbgEventUnloadDll      db      'DLL unloaded: ',0
  cDbgEventOutputString   db      'String output: ',0
  cDbgEventRIP            db      'Internal debuger error.',0
endg


proc DbgEventUnknown
begin
        stdcall StrNew
        stdcall StrCopy, eax, cDbgEventUnknown
        return
endp


proc DbgEventException
begin
        mov     ecx, [dbgEvent.Exception.ExceptionRecord.ExceptionCode]
        cmp     ecx, EXCEPTION_SINGLE_STEP
        jne     .logexception
        xor     eax, eax
        return

.logexception:
        stdcall StrDup, cDbgEventException
        mov     edx, eax

        stdcall GetExceptionText, ecx
        stdcall StrCat, edx, ecx
        stdcall StrDel, ecx
        stdcall StrCharCat, edx, ' at '
        stdcall NumToStr, [dbgEvent.Exception.ExceptionRecord.ExceptionAddress], ntsHex or ntsFixedWidth or ntsUnsigned or 8
        stdcall StrCat, edx, eax
        stdcall StrDel, eax
        mov     eax, edx
        return
endp


proc GetExceptionText, .number
begin
        push    eax edx esi

        mov     esi, tblExceptions
.loop:
        mov     eax, dword [esi]
        test    eax, eax
        jz      .notfound

        cmp     eax, [.number]
        je      .found

        add     esi, 4
        jmp     .loop

.found:
        stdcall StrDup, [esi+4]
        jmp     .finish

.notfound:
        stdcall NumToStr, [.number], ntsHex or ntsUnsigned or ntsFixedWidth or 8
        stdcall StrCharInsert, eax, '$', 0

.finish:
        mov     ecx, eax
        pop     esi edx eax
        return
endp


macro KeyString [key, string] {
  forward
    local  ptrstr
    dd     key, ptrstr
  common
    dd  0
  forward
ptrstr db  string, 0
}


iglobal

tblExceptions:
     KeyString                                                            \
          EXCEPTION_ACCESS_VIOLATION,           'Access violation',       \
          EXCEPTION_DATATYPE_MISALIGNMENT,      'Datatype misalignment',  \
          EXCEPTION_BREAKPOINT,                 'Breakpoint',             \
          EXCEPTION_SINGLE_STEP,                'Single step',            \
          EXCEPTION_ARRAY_BOUNDS_EXCEEDED,      'Array bounds exceeded',  \
          EXCEPTION_FLT_DENORMAL_OPERAND,       'FPU Denormal operand',   \
          EXCEPTION_FLT_DIVIDE_BY_ZERO,         'FPU Divide by zero',     \
          EXCEPTION_FLT_INEXACT_RESULT,         'FPU Inexact result',     \
          EXCEPTION_FLT_INVALID_OPERATION,      'FPU Invalid operation',  \
          EXCEPTION_FLT_OVERFLOW,               'FPU Overflow',           \
          EXCEPTION_FLT_STACK_CHECK,            'FPU Stack check',        \
          EXCEPTION_FLT_UNDERFLOW,              'FPU Underflow',          \
          EXCEPTION_INT_DIVIDE_BY_ZERO,         'Divide by zero',         \
          EXCEPTION_INT_OVERFLOW,               'Overflow',               \
          EXCEPTION_ILLEGAL_INSTRUCTION,        'Illegal instruction',    \
          EXCEPTION_PRIV_INSTRUCTION,           'Privileged instruction', \
          EXCEPTION_IN_PAGE_ERROR,              'Page error'
endg





proc DbgEventCreateThread
begin
        stdcall StrNew
        stdcall StrCopy, eax, cDbgEventCreateThread
        return
endp

proc DbgEventCreateProcess
begin
        stdcall StrNew
        stdcall StrCopy, eax, cDbgEventCreateProcess
        return
endp

proc DbgEventExitThread
begin
        stdcall StrNew
        stdcall StrCopy, eax, cDbgEventExitThread
        return
endp

proc DbgEventExitProcess
begin
        stdcall StrNew
        stdcall StrCopy, eax, cDbgEventExitProcess
        return
endp


proc DbgEventLoadDll
.name rb 512
.buffer rd 128
begin
        stdcall StrNew
        mov     edi, eax
        stdcall StrCopy, edi, cDbgEventLoadDll

        lea     ecx, [.buffer]
        invoke  ReadProcessMemory, [dbgPInfo.hProcess], [dbgEvent.LoadDll.lpImageName], ecx, 4, NULL
        test    eax, eax
        jz      .finish

        mov     esi, [.buffer]
        test    esi, esi
        jz      .finish

        lea     ecx, [.buffer]
        invoke  ReadProcessMemory, [dbgPInfo.hProcess], esi, ecx, 512, NULL
        test    eax, eax
        jz      .finish

        push    edi

        lea     esi, [.buffer]
        lea     edi, [.name]
        xor     ecx, ecx
        cmp     [dbgEvent.LoadDll.fUnicode], 0
        jz      @f
        inc     ecx
@@:
        lodsb
        stosb
        add     esi, ecx
        test    al,al
        jnz     @b

        pop    edi

        lea     eax, [.name]
        stdcall StrCat, edi, eax

.finish:
        mov     eax, edi
        return
endp

proc DbgEventUnloadDll
begin
        stdcall StrNew
        stdcall StrCopy, eax, cDbgEventUnloadDll
        return
endp

proc DbgEventOutputString
begin
        stdcall StrNew
        stdcall StrCopy, eax, cDbgEventOutputString
        stdcall StrCat, eax, [dbgEvent.DebugString.lpDebugStringData]
        return
endp

proc DbgEventRIP
begin
        stdcall StrNew
        stdcall StrCopy, eax, cDbgEventRIP
        return
endp



;---------------------------------------------------------------------
; Goto address dialog form.
;---------------------------------------------------------------------
iglobal
  Window dlgGotoAddr, $3, $0, 'TForm', 'Goto address', $6C80000, $10001, 0, 373, 322, 159, 113, NULL
  Window NONE, $0, $0, 'Static', 'Input the address:', $50000000, $0, 0, 16, 8, 88, 13, NULL
  Window NONE, $0, $0, 'Edit', 'h', $50800080 or WS_TABSTOP, $0, 100, 16, 24, 121, 18, NULL
  Window NONE, $2, $0, 'Button', 'Go', $50000001 or WS_TABSTOP, $0, MR_OK, 40, 56, 64, 24, NULL
endg

;---------------------------------------------------------------------
; Goto address function action procedure.
;---------------------------------------------------------------------
proc OnGotoAddr, .wparam, .lparam
.pos AEPOS
.buff rb 256
begin
        stdcall CreateForm, dlgGotoAddr, [hApplication]

        stdcall ShowModal, ebx, MSF_CENTER
        cmp     eax, MR_OK
        jne     .finish

        lea     esi, [.buff]
        invoke  SendDlgItemMessageA, ebx, 100, WM_GETTEXT, 256, esi

        invoke  DestroyWindow, ebx

        stdcall StrToFasmNum, esi
        stdcall FindAddressPosition, eax
        test    eax, eax
        jz      .notfound

        stdcall PosEditor, [eax+TDebugLine.ptrFile], [eax+TDebugLine.LineNum]

.finish:
        return

.notfound:
        invoke  MessageBoxA, [hApplication], cAddressNotFound, NULL, MB_OK or MB_ICONERROR
        return
endp

cAddressNotFound text 'Address not found. Check the value.'




proc OnShowListing, .wparam, .lparam
begin
        invoke  IsWindowVisible, [hLister]
        test    eax, eax
        jz      .show

        invoke  SendMessageA, [hLister], WM_SETTEXT, 0, 0
        invoke  SendMessageA, [hLister], LM_SHOW, FALSE, 0
        return

.show:
        cmp     [ptrListing], 0
        je      .exit

        invoke  SendMessageA, [hLister], LM_SHOW, TRUE, 0

        invoke  SendMessageA, [hLister], WM_SETTEXT, 0, 0
        mov     esi, [ptrListing]
        mov     edi, [esi+TMemoryStream.offset]
        add     edi, esi
        lea     esi, [esi+TMemoryStream.data]

        stdcall StrNew
        mov     ebx, eax

.loop:
        stdcall StrCat, ebx, esi
        stdcall StrCharCat, ebx, 10
        stdcall StrLen, esi
        lea     esi, [esi+eax+1]
        cmp     esi, edi
        jb      .loop

        stdcall StrPtr, ebx
        invoke  SendMessageA, [hLister], WM_SETTEXT, 0, eax
        stdcall StrDel, ebx

        stdcall AlignChildren, [hEditorsHost]
;        invoke  RedrawWindow, [hLister], NULL, NULL, RDW_ERASE or RDW_INVALIDATE or RDW_ERASENOW or RDW_UPDATENOW
.exit:
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/debugger.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
struct TDebugEvent
  .dwDebugEventCode dd ?
  .dwProcessId      dd ?
  .dwThreadId       dd ?
  .u                rd sizeof.EXCEPTION_DEBUG_INFO
  virtual at .u
    .Exception EXCEPTION_DEBUG_INFO
  end virtual
  virtual at .u
    .CreateThread CREATE_THREAD_DEBUG_INFO
  end virtual
  virtual at .u
    .CreateProcessInfo CREATE_PROCESS_DEBUG_INFO
  end virtual
  virtual at .u
    .ExitThread EXIT_THREAD_DEBUG_INFO
  end virtual
  virtual at .u
    .ExitProcess EXIT_PROCESS_DEBUG_INFO
  end virtual
  virtual at .u
    .LoadDll LOAD_DLL_DEBUG_INFO
  end virtual
  virtual at .u
    .UnloadDll UNLOAD_DLL_DEBUG_INFO
  end virtual
  virtual at .u
    .DebugString OUTPUT_DEBUG_STRING_INFO
  end virtual
  virtual at .u
    .RipInfo RIP_INFO
  end virtual
ends

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































Deleted source/designtime.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225

; Design-time information is information that Fresh uses in the process
; of visual design of the windows.
; This info describes what styles are allowed for this control,
; what is his classname, what are the names of styles, what files
; contains executable code for the control (if any) what will be the
; icon on the control panel, etc. (Look at TDesignTimeInfo for full
; description.)
;
; Every control used in the visual form designer must have this
; description, even Windows standard controls like BUTTON.
;
; Design-time info is binary data that is created using FASM compiler.
; For the example look at 'BUTTON.asm' file. It must be compiled
; to get exact binary design-time data file.
;
; Of course it is possible to make Fresh to compile this files on every
; run and to get directly binary info in memory, but I think that first
; version will be with pre-compiled files. ( The reason is simply
; that FASM compiler still doesn't work in Fresh :) )
;
; On running, Fresh will read these files from 'controls' subdir of 'include' dir
; and will add controls to the control palette. Then Fresh will use
; this information in design process to ensure proper handling for different
; controls.

; This is first version of the structure, so, there WILL be changes.
; More, here is not specifyed how Fresh will handle executable code for
; user defined controls. I have some ideas, but still not clear, so, This
; will be specifyed later.

; This is data structure, describing some information about
; Fresh visual components.

struc TDesignTimeInfo {

  .ClassName       dd ?    ; offset to class name string.
  .ControlHint     dd ?    ; offset to hint string.
  .Palette         dd ?    ; offset to palette name string.
  .DefaultText     dd ?    ; offset to default control text.
  .DefaultStyle    dd ?    ; Default window style.
  .DefaultStyleEx  dd ?    ; Default window styleEx.

; Default window width and height on the creation in the form designer when
; the user simply click on the form or the size he specify is too small.
  .DefaultWidth    dd ?
  .DefaultHeight   dd ?

  .StyleNames      dd ?    ; offset to private style names list for this component.
  .StyleExNames    dd ?    ; offset to private styleEx names list for this component.

  .StyleMaskAnd    dd ?    ; Styles that must be 0 for this component.
  .StyleMaskOr     dd ?    ; Styles that must be 1 for this component.

  .StyleExMaskAnd  dd ?    ; The Ex styles that must be 0 for this component.
  .StyleExMaskOr   dd ?    ; Ex Styles that must be 1 for this component.

  .SubtypeMask     dd ?    ; this is the mask for separating subtype part from style word.
                           ; For example for BUTTON class this is $0000000f, because low 4
                           ; bits from Style are not bit flags, but number of button subtype.

  .SubtypeRange    dd ?    ; offset to the list like WinStyles with allowed subtypes numbers,
                           ; names and descriptions.

  .LibFile         dd ?    ; if the component is not standard component, this is
                           ; the name of the file containing the source code for the
                           ; component. NULL for standard windows components.
  .ImageFile       dd ?    ; offset to the image filename 16x16 pixels bitmap for toolbar icon.
}

; NOTE: Don't use "struct" macro here. This file is used sometimes as standalone,
; without "struct" support.
virtual at 0
  TDesignTimeInfo TDesignTimeInfo
  sizeof.TDesignTimeInfo = $
end virtual


macro  WinStyles [_value, _dsc] {

  common
    local index

    index = 0
  forward

    index = index + 1

  common

   dd index             ; The first dword is count of the items in the list.

  forward

    local name, namelen, hint, hintlen

; Style value
            dd  _value

; Style name - Pascal string - the first byte is length of the string.
            db  namelen
    name    db  `_value, 0
    namelen =   $ - name

; Style description - Pascal string.
            db  hintlen
    hint    db  _dsc, 0
    hintlen =   $ - hint
}



macro DesignTimeInfo [ classname,       \; Control class name
                       hint,            \; Short description for the button on the tool palette.
                       palette,         \; The name of the palette, where control will reside.
                       deftext,         \; Default text for the control when it is created.
                       defstyle,        \; Default style for the control.
                       defstyleex,      \; Default StyleEx for the control.
                       defwidth,        \; Default width of the control.
                       defheight,       \; Default height
                       StyleNames,      \; List with names and numbers for styles private for the control.
                       StyleExNames,    \; List with names and numbers for styleEx.
                       StyleMaskAnd,    \; Mask for bits forced to 0 in Style
                       StyleMaskOr,     \; Mask for bits forced to 1 in Style
                       StyleExMaskAnd,  \; Mask for bits forced to 0 in StyleEx
                       StyleExMaskOr,   \; Mask for bits forced to 1 in StyleEx
                       SubtypeMask,     \; Mask for lower x bits, that are subtype number.
                       SubtypeRange,    \; List with names and numbers for subtypes.
                       LibFile,         \; string with library file with design time procedures.
                       ImageFile        \; string with file name for icon in the tool palette. Must be 24x24 icon file.
                     ] {

forward ; Array of TDesignTimeInfo structures.

  local base, namestr, deftxt, subtype, stylenm, styleexnm, filename, image, hintstr, pal

        label base dword
        dd      namestr - base
        dd      hintstr - base
        dd      pal - base
        dd      deftxt - base
        dd      defstyle
        dd      defstyleex
        dd      defwidth
        dd      defheight
        dd      stylenm - base
        dd      styleexnm - base
        dd      StyleMaskAnd xor $ffffffff
        dd      StyleMaskOr
        dd      StyleExMaskAnd xor $ffffffff
        dd      StyleExMaskOr
        dd      SubtypeMask
        dd      subtype - base

  if LibFile eq NONE
        dd      base
  else
        dd      filename - base
  end if

  if ImageFile eq NONE
        dd      base
  else
        dd      image - base
  end if

common

        dd 0    ; End of the array of TDesignTypeInfo.

forward ; Array of classname strings.

namestr db      classname, 0

forward ; Array of hint strings.

hintstr db      hint,0

forward ; Array of Palette names

pal     db      palette,0

forward ; Array of subtype ranges

if ~ (SubtypeRange eq NONE)
  label subtype
          WinStyles SubtypeRange
else
  subtype = base
end if

forward ; List with stylenames.

if ~ (StyleNames eq NONE)
  label stylenm
          WinStyles StyleNames
else
  stylenm = base
end if

forward ; List with styleEx names.

if ~ (StyleExNames eq NONE)
  label styleexnm
          WinStyles StyleExNames
else
  styleexnm = base
end if

forward ; library filenames.

  if ~(LibFile eq NONE)
    filename db LibFile, 0
  end if

forward

  if ~ (ImageFile eq NONE)
    image db ImageFile, 0
  end if

forward ; Array of default text strings.
  deftxt db deftext, 0
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































Deleted source/dialogs.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
proc LastError
begin
        pushad
        invoke  GetLastError
        stdcall ErrorMessage, eax
        popad
        return
endp

;-------------------------------------------------------------------------
; Shows message box with error message.
; Arguments:
;  errorcode - code of the error. This is code returned by GetLastError.
;
;  Because of missing information about "Message table" resources, this
;  procedure uses specific processing for application defined messages
;-------------------------------------------------------------------------
proc ErrorMessage, .errorcode
.errstr dd ?
begin
        pushad

        test    [.errorcode], errFresh
        jnz     .freshmsg

        lea     esi, [.errstr]
        invoke  FormatMessageA, FORMAT_MESSAGE_ALLOCATE_BUFFER or                \
                               FORMAT_MESSAGE_FROM_SYSTEM,                      \
                               NULL, [.errorcode], NULL, esi, 256, NULL
        invoke  MessageBoxA, [hApplication], [.errstr], NULL, MB_OK or MB_ICONERROR
        invoke  LocalFree, [.errstr]
.finish:
        popad
        return

.freshmsg:
        cmp     [.errorcode], errCanceled
        je      .finish

        mov     esi, FreshErrorMessages-8

; search for message
.loop:
        add     esi, 8
        mov     ecx, [esi]
        mov     eax, [esi+4]
        jecxz   .notfound

        cmp     eax, [.errorcode]
        jne     .loop

;found:
.msg:
        invoke  MessageBoxA, [hApplication], ecx, NULL, MB_OK or MB_ICONERROR
        popad
        return

.notfound:
        mov     ecx, errmsgUnknownError
        jmp     .msg

endp



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































Deleted source/dumper.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
uglobal
  hSplitterDumper dd ?
  Dumper  TDumper
  hDumperPopupMenu dd ?
endg

cDefaultDumperFontWidth = 6
cDefaultDumperFontHeight = 8

iglobal
  cDefaultDumperFont db 'Terminal', 0

  CoolMenu  DumperPopupMenu,    \
    mfNormal, actDumpAddress
endg

proc InitDumperWindow, .hParent
.DumperFont dd ?
begin
        xor     ebx, ebx

        invoke  CreateFontA, cDefaultDumperFontHeight, cDefaultDumperFontWidth, ebx, ebx, FW_DONTCARE,                \
                            ebx, ebx, ebx,                                                   \
                            1, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,     \
                            FIXED_PITCH or FF_DONTCARE, cDefaultDumperFont
        mov     esi, eax

        invoke   CreateWindowExA, ebx, cDataGridClassName, NULL,                  \
                 WS_CHILD or WS_HSCROLL or WS_VSCROLL,                           \
                 ebx, ebx , 400, ebx,                                            \
                 [.hParent],                                                     \
                 ebx, [hInstance],                                               \
                 Dumper

        mov     ebx, eax

        invoke  SendMessageA, ebx, WM_SETFONT, esi, FALSE
        stdcall SetAlign, ebx, waLeft
        stdcall SubclassWindow, ebx, DumperWinProc

        mov     [Dumper.Flags], dgfGridLinesFixed
        mov     [Dumper.OnDrawItem], TDumper.DrawCell

        stdcall TDataGrid.SetCounts, Dumper, 18, 100
        stdcall TDataGrid.SetColumnsWidth, Dumper, 1, 16, 16
        stdcall TDataGrid.SetColumnsWidth, Dumper, 17, 17, 100

        invoke  CreateWindowExA, 0, cSplitterClassName, NULL,            \
                WS_CLIPSIBLINGS or WS_CHILD,                            \
                0, 0, 0, 0, [.hParent], NULL, [hInstance], [Dumper.hwnd]
        mov     [hSplitterDumper], eax
        invoke  SendMessageA, eax, SPM_SETCURSORS, resVSplit, resHSplit
        invoke  SendMessageA, [hSplitterDumper], SPM_SETMAXMIN, 16, 9999

        stdcall CreateCoolMenu, DumperPopupMenu, TRUE
        mov     [hDumperPopupMenu], eax

        return
endp



winproc DumperWinProc
begin

ondefault
        stc
        return

onmessage WM_DESTROY
        invoke  DestroyMenu, [hDumperPopupMenu]

        cmp     [Dumper.ptrData], 0
        je      .ondefault

        stdcall FreeMem, [Dumper.ptrData]
        stc
        return

onmessage WM_RBUTTONDOWN
locals
  .pnt POINT
endl
        lea     eax, [.pnt]
        invoke  GetCursorPos, eax

        invoke  TrackPopupMenu, [hDumperPopupMenu], TPM_LEFTBUTTON or TPM_LEFTBUTTON,   \
                [.pnt.x],[.pnt.y], 0, [hEditorsHost], NULL
        xor     eax, eax
        clc
        return


onmessage DMM_SHOW
        invoke  ShowWindow, [hSplitterDumper], [.wparam]
        invoke  ShowWindow, [.hwnd], [.wparam]
        invoke  GetParent, [.hwnd]
        stdcall AlignChildren, eax
        clc
        return
endwp



proc OnDumpAddress, .wparam, .lparam
.buff rb $100
begin
  iglobal
    cDumpTitle db 'Memory dump', 0
  endg

        stdcall CreateForm, dlgGotoAddr, [hApplication]

        invoke  SendMessageA, ebx, WM_SETTEXT, 0, cDumpTitle

        stdcall ShowModal, ebx, MSF_CENTER
        cmp     eax, MR_OK
        jne     .finish

        lea     esi, [.buff]
        invoke  SendDlgItemMessageA, ebx, 100, WM_GETTEXT, 256, esi

        invoke  DestroyWindow, ebx

        stdcall StrToFasmNum, esi
        stdcall TDumper.DumpAddress, eax, [dbgPInfo.hProcess]

        invoke  InvalidateRect, [Dumper.hwnd], 0, 0
        mov     [Dumper.fShadowReady], 0

.finish:
        return
endp





; todo: Check if the [.addr] is inside existing buffer and to not allocate
; new buffer.

proc TDumper.DumpAddress, .addr, .hProcess
.buffer dd ?
begin
        push    esi edi ebx

        mov     esi, [.addr]
        and     esi, $fffff000  ; address of the begining of the page.
        mov     [Dumper.pointer], esi

; determine the size of the memory block.
        lea     edi, [.buffer]
        lea     ebx, [esi-4096]
.getsz:
        add     ebx, 4096
        invoke  ReadProcessMemory, [.hProcess], ebx, edi, 1, NULL
        test    eax, eax
        jnz     .getsz

; set grid size.
        sub     ebx, esi

        mov     ecx, ebx
        sar     ecx, 4
        inc     ecx
        stdcall TDataGrid.SetCounts, Dumper, [Dumper.ColCount], ecx

        cmp     [Dumper.ptrData], 0
        je      .bufferok

        stdcall FreeMem, [Dumper.ptrData]
        mov     [Dumper.ptrData], 0

.bufferok:
; allocate memory buffer
        stdcall GetMem, ebx
        jc      .dataok

        mov     edi, eax

; read memory from the debugged process.
        invoke  ReadProcessMemory, [.hProcess], esi, edi, ebx, NULL
        test    eax, eax
        jz      .dataok

        mov     [Dumper.ptrData], edi
        mov     [Dumper.DataSize], ebx

.dataok:
; Set focused cell.
        mov     eax, [.addr]
        mov     ecx, eax
        sub     eax, [Dumper.pointer]
        and     ecx, $0f
        sar     eax, 4
        inc     ecx
        inc     eax

        mov     [Dumper.focused.x], ecx
        mov     [Dumper.focused.y], eax

        stdcall TDataGrid.GetCellXY, Dumper, ecx, eax
        push    edx

        invoke  SetScrollPos, [Dumper.hwnd], SB_HORZ, eax, TRUE
        pop     edx
        invoke  SetScrollPos, [Dumper.hwnd], SB_VERT, edx, TRUE

        invoke  InvalidateRect, [Dumper.hwnd], NULL, FALSE
        pop     ebx edi esi
        return
endp


uglobal
  DumperBuffer rb 32
endg




proc TDumper.DrawCell, .hdc, .ptrRect, .Col, .Row, .dummy, .fSelected, .fFixed
begin
        push    esi ebx

; Choose text color
        mov     eax, [edi+TDataGrid.clTextFixed]
        cmp     [.fFixed], 0
        jne     .colorok

        mov     eax, [edi+TDataGrid.clTextSelected]
        cmp     [.fSelected], FALSE
        jne     .colorok

        mov     eax, [edi+TDataGrid.clTextCell]

.colorok:
        invoke  SetTextColor, [.hdc], eax

        cmp     [.fFixed], 0
        jne     .fixed

; Data..maybe
        cmp     [Dumper.ptrData], 0
        je      .drawok

        cmp     [.Col], 17      ; ASCII field
        je      .ascii

; yes it is data cell
        mov     eax, [.Row]
        mov     ecx, [.Col]
        dec     eax
        dec     ecx
        shl     eax, 4
        add     ecx, [Dumper.ptrData]

        movzx   eax, byte [eax+ecx]


        stdcall NumToStr, eax, ntsHex or ntsFixedWidth or 2
        jmp     .drawit

.ascii:
        push    edi

        mov     esi, [.Row]
        dec     esi
        shl     esi, 4
        add     esi, [Dumper.ptrData]
        mov     edi, DumperBuffer
        mov     ecx, $10

.copy:  lodsb
        cmp     al, ' '
        jae     @f
        mov     al, '.'
@@:     stosb
        loop    .copy

        pop     edi

        invoke  DrawTextA, [.hdc], DumperBuffer, 16, [.ptrRect], DT_VCENTER or DT_CENTER or DT_SINGLELINE or DT_NOPREFIX
        jmp     .drawok

.fixed:
        cmp     [.Row], 0
        je      .offset

; address...
        mov     eax, [.Row]
        dec     eax
        shl     eax, 4  ; *16 bytes on row
        add     eax, [edi+TDumper.pointer]
        stdcall NumToStr, eax, ntsHex or ntsUnsigned or ntsFixedWidth or 8
        jmp     .drawit

.offset:
        mov     eax, [.Col]
        test    eax, eax
        jz      .drawok

        lea     eax, [DumperOffsets+4*eax]
        stdcall StrDup, eax

.drawit:
        push    eax
        stdcall StrPtr, eax
        invoke  DrawTextA, [.hdc], eax, -1, [.ptrRect], DT_VCENTER or DT_CENTER or DT_SINGLELINE
        stdcall StrDel ; from the stack

.drawok:
        pop     ebx esi
        return
endp



iglobal
  DumperOffsets  dd      0, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'ASCI', 'I'
endg
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































































































































Deleted source/dumper.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
winmessage DMM_SHOW

struct TDumper
  . TDataGrid
  .pointer dd ?         ; address of the data in the debugged process.
  .ptrData dd ?         ; pointer to the buffer with data copyed from the debugged process.
  .DataSize dd ?        ; size of the buffer.
  .format  dd ?
ends

struct TWatch
  .LblName dd ?    ; handle of the string with name of the label. Can be 0
  .addr    dd ?    ; dword address of the variable.
  .format  dd ?    ; display format flags.
  .Count   dd ?    ; count of elements in the watch.

  .ptrGrid dd ? ; pointer to the TDataGrid displaying the watch.
ends
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































Deleted source/editorhost.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773

uglobal
  hEditorsHost    dd 0                        ; handle of editors host window
  hStatus         dd 0                        ; handle of the Statusbar of the editor host.
                                              ; This statusbar is for common use from all
                                              ; hosted windows.

  ptrMRUFiles     dd 0

  hEditorTab      dd 0
  hTabMenu        dd 0                        ; popup menu for the tab control.
  hTabIml         dd 0
endg

  cEmptyEditorTitle text 'Fresh editor:'
iglobal
  cStatusBarParts dd    64, 128, 192, 208, 264, 320, -1

CoolMenu TabPopup,                      \
    mfNormal, actFileClose,             \
    mfSeparator, NONE,                  \
    mfNormal, actNew,                   \
    mfNormal, actOpen,                  \
    mfNormal, actSave,                  \
    mfSeparator, NONE,                  \
    mfNormal, actSetCurrentMain,        \
    mfNormal, actAddToProject
endg



;----------------------------------------
; Creates editorhost window.
; Call this only once.
;----------------------------------------
proc InitEditorHost, .owner
begin

        stdcall CreateCoolMenu, TabPopup, TRUE
        mov     [hTabMenu], eax

        invoke   CreateWindowExA, 0, cFormClassName, cEmptyEditorTitle,               \
                 WS_VISIBLE or WS_CAPTION or WS_CLIPCHILDREN or WS_SIZEBOX or        \
                 WS_MINIMIZEBOX or WS_MAXIMIZEBOX or WS_SYSMENU,                     \
                 100, 100 , 200, 200,                                                \
                 [.owner],                                                            \
                 NULL, [hInstance],                                                  \
                 NULL

        mov     [hEditorsHost], eax

        stdcall SubclassWindow, eax, EditorHostProc

        invoke  LoadImageA, [hInstance], resSourceIcon, IMAGE_ICON, 0, 0, 0
        invoke  SendMessageA, [hEditorsHost], WM_SETICON, ICON_SMALL, eax

        return
endp



;-----------------------------------------------------
; Dialog proc for Source editor
;-----------------------------------------------------
proc EditorHostProc, .hwnd, .wmsg, .wparam, .lparam
.nmh    NMHDR
.ptr dd ?
.tci    TEditorTab
.str    rb      1024
.tchi    TCHITTESTINFO
.pnt     POINT
.textlen dd ?
.written dd ?
.iItem   dd ?

begin
        call    JumpTo
        MessageList                              \
            AM_INITWINDOW,      .aminitwindow,   \
            WM_DESTROY,         .destroy,        \
            WM_NOTIFY,          .notify,         \
            WM_DROPFILES,       .wmdropfiles,    \
\
            _EHM_SETACTIVETAB,   .setactivetab,   \
\ ; EHM_ messages this window is not an editor but a host for all editors.
            EHM_DOCKWINDOW,      .dockwindow,    \
            EHM_UNDOCKWINDOW,    .undockwindow,  \
            EHM_GETCURRENTASMEDIT, .getcurrentasmedit, \
            EHM_FILECHANGED,       .filechanged,       \
            EHM_FOCUSWINDOW,       .focuswindow,       \
\
            WM_CLOSE,           .close,          \
            WM_ACTIVATE,        .activate,       \
            WM_COMMAND,         .command,        \
            WM_PARENTNOTIFY,    .wmparentnotify, \
            WM_SETFOCUS,        .wmsetfocus

.default:
        stc
        return

;------------ EHM_FOCUSWINDOW ----------------------
.focuswindow:
        stdcall IndexByWindow, [.wparam]
        cmp     eax, -1
        je      .endfocus

        invoke  SendMessageA, [.hwnd], _EHM_SETACTIVETAB, eax, FALSE

.endfocus:
        clc
        return

;------------ EHM_FILECHANGED ----------------------
.filechanged:
        mov     eax, [.wparam]
        stdcall IndexByWindow, [eax+TOpenFile.hEditor]
        cmp     eax, -1
        je      .endchanged

        mov     edi, eax

        mov     [.tci.mask], TCIF_TEXT or TCIF_IMAGE

        stdcall GetScreenProperties, [.wparam]
        push    eax

        mov     [.tci.iImage], edx

        stdcall StrPtr, eax
        mov     [.tci.pszText], eax
        lea     ecx, [.tci]
        invoke  SendMessageA, [hEditorTab], TCM_SETITEM, edi, ecx

        stdcall StrDel ; from the stack...

        mov     eax, [.wparam]
        stdcall StrPtr, [eax+TOpenFile.hFileName]
        invoke  SendMessageA, [.hwnd], WM_SETTEXT, 0, eax

.endchanged:
        clc
        return

;----------- EHM_DOCKWINDOW ------------------------
.dockwindow:
        invoke  ShowWindow, [.wparam], SW_HIDE
        invoke  SetParent, [.wparam], [.hwnd]
        stdcall SetAlign, [.wparam], [.lparam]

        cmp     [.lparam], dfClient
        je      .addtotabs

        stdcall CreateSplitter, [.wparam], FALSE, resVSplit, resHSplit
        mov     ebx, eax

; Show window and splitter.
        invoke  ShowWindow, [.wparam], SW_SHOWNORMAL
        invoke  ShowWindow, ebx, SW_SHOWNORMAL
        mov     eax, ebx
        clc
        return

.addtotabs:
        mov     [.tci.mask], TCIF_TEXT or TCIF_IMAGE or TCIF_PARAM

        stdcall GetEditorFile, [.wparam]
        stdcall GetScreenProperties, eax
        mov     [.tci.iImage], edx

        push    eax
        stdcall StrPtr, eax
        mov     [.tci.pszText], eax

        invoke  SendMessageA, [hEditorTab], TCM_GETCURSEL, ebx, ebx
        lea     edi, [eax+1]

        mov     eax, [.wparam]
        mov     [.tci.hEditor], eax

        lea     ecx, [.tci]
        invoke  SendMessageA, [hEditorTab], TCM_INSERTITEM, edi, ecx
        mov     edi, eax

        stdcall StrDel ; from the stack.

        invoke  ShowWindow, [hEditorTab], SW_SHOWNORMAL
        invoke  ShowWindow, [hStatus], SW_SHOWNORMAL

        invoke  SendMessageA, [.hwnd], _EHM_SETACTIVETAB, edi, ebx
        return

;----------- EHM_UNDOCKWINDOW ----------------------
.undockwindow:

        return

;----------- EHM_GETCURRENTASMEDIT -----------------
.getcurrentasmedit:
        call    .loadtcitem
        xor     eax, eax
        stdcall GetAsmEdit, [.tci.hEditor]
        clc
        return

;----------- WM_DROPFILES -------------------------
.wmdropfiles:
        lea     esi, [.str]

        invoke  DragQueryFile, [.wparam], -1, esi, 1024
        mov     ebx, eax
        xor     edi, edi

.opendroploop:
        invoke  DragQueryFile, [.wparam], edi, esi, 1024
        stdcall OpenFileByName, esi, NULL, TRUE
        inc     edi
        dec     ebx
        jnz     .opendroploop

        invoke  DragFinish, [.wparam]
        xor     eax, eax
        clc
        return

;-----------WM_COMMAND-----------------------------

.command:
        movzx   esi,word [.wparam]
        cmp     esi, MR_CANCEL
        je      .close_something

        cmp     esi, MR_OK
        je      .jmp_link

        sub     esi,FirstID

        cmp     esi, [MainActionList.Number]
        jae     .maybeasmedit

        imul    esi, sizeof.TAction
        add     esi,MainActionList

        xor     eax,eax
        cmp     [esi+TAction.OnExecute],eax
        je      .qfalse

        stdcall [esi+TAction.OnExecute], [.wparam], [.lparam]
        jmp     .default

.jmp_link:
        invoke  GetFocus
        cmp     eax, [tvMessagesWin]
        jne     .qfalse

        invoke  PostMessageA, [frmMsg], WM_COMMAND, MR_OK, 0
        jmp     .qfalse

.close_something:
        invoke  GetFocus
        cmp     eax, [tvMessagesWin]
        je      .closemessages

        cmp     [hCCList], 0
        je      .ccok

        invoke  PostMessageA, [hCCList], WM_CLOSE, 0, 0
        jmp     .qfalse

.ccok:
        cmp     [hPAHint], 0
        je      .phok

        invoke  PostMessageA, [hPAHint], WM_CLOSE, 0, 0
        jmp     .qfalse

.phok:
        cmp     [hEHelp], 0
        je      .ehok

        invoke  PostMessageA, [hEHelp], WM_CLOSE, 0, 0
        jmp     .qfalse

.ehok:
        cmp     [hLabelInfo], 0
        je      .qfalse

        invoke  PostMessageA, [hLabelInfo], WM_CLOSE, 0, 0
        jmp     .qfalse

.closemessages:
        invoke  PostMessageA, [frmMsg], MWM_SHOWMESSAGES, 0, 0
        jmp     .qfalse

.maybeasmedit:
        movzx   eax, word [.wparam+2]
        cmp     eax, AEN_POSCHANGE
        je      .updatestatusbar
        cmp     eax, AEN_TEXTCHANGE
        je      .updatestatusbar
        cmp     eax, AEN_SETFOCUS
        je      .updatestatusbar
        cmp     eax, AEN_MODECHANGE
        jne     .default

.updatestatusbar:
        stdcall UpdateStatusbar, [.lparam]
        stdcall UpdatePAHint
        stdcall UpdateEHelp
        jmp     .default

;------- WM_ACTIVATE -------------------------
.activate:
        cmp     [.wparam], WA_ACTIVE
        je      .wmsetfocus
        cmp     [.wparam], WA_CLICKACTIVE
        jne     .qfalse

;----------- WM_SETFOCUS ---------------------------
.wmsetfocus:
        invoke  SendMessageA, [hEditorTab], TCM_GETCURSEL, 0, 0
        cmp     eax, -1
        je      .focussomething

; focus active asmedit
        lea     ecx, [.tci]
        mov     [.tci.mask], TCIF_PARAM
        invoke  SendMessageA, [hEditorTab], TCM_GETITEM, eax, ecx

        stdcall GetEditorFile, [.tci.hEditor]
        stdcall FocusFile, eax
        jmp     .qfalse

.focussomething:
        invoke  SetFocus, [frmMsg]
        test    eax, eax
        jnz     .qfalse

.activatemain:
        invoke  SetActiveWindow, [hMainWindow]
        jmp     .qfalse



;----------- WM_CLOSE ---------------------------
.close:
        stdcall ActionSetCheck, actViewSourceEditor, FALSE
        invoke  ShowWindow, [.hwnd], SW_HIDE
        jmp     .qfalse

;----------- _EHM_SETACTIVETAB -----------------------
.setactivetab:
        lea     ebx, [.nmh]

        cmp     [.lparam], FALSE
        je      .doset

        invoke  SendMessageA, [hEditorTab], TCM_GETITEMCOUNT
        mov     esi, eax
        dec     esi
        js      .qfalse

        invoke  SendMessageA, [hEditorTab], TCM_GETCURSEL, 0, 0
        test    eax, eax
        js      .qfalse

        add     eax, [.wparam]
        jns     @f
        mov     eax, esi        ; Set Max
@@:
        cmp     eax, esi
        jle     @f
        xor     eax, eax
@@:
        mov     [.wparam], eax

.doset:
        mov     [.nmh.code], TCN_SELCHANGING
        invoke  SendMessageA, [hEditorTab], WM_NOTIFY, 0, ebx

        invoke  SendMessageA, [hEditorTab], TCM_SETCURSEL, [.wparam], 0

        mov     [.nmh.code], TCN_SELCHANGE
        invoke  SendMessageA, [hEditorTab], WM_NOTIFY, 0, ebx
        jmp     .qfalse

;------------------ WM_PARENTNOTIFY --------------------
.wmparentnotify:
        movzx   eax, word [.wparam]
        cmp     eax, WM_DESTROY
        jne     .default

        stdcall IndexByWindow, [.lparam]
        cmp     eax, -1
        je      .default

        mov     ebx, eax
        invoke  SendMessageA, [hEditorTab], TCM_DELETEITEM, eax, 0
        invoke  SendMessageA, [hEditorTab], TCM_GETITEMCOUNT, 0, 0
        test    eax, eax
        jz      .hidetabs

        test    ebx, ebx
        jz      .setactive
        dec     ebx

.setactive:
        invoke  SendMessageA, [.hwnd], _EHM_SETACTIVETAB, ebx, FALSE
        jmp     .qfalse

.hidetabs:
        invoke  ShowWindow, [hEditorTab], SW_HIDE
        invoke  ShowWindow, [hStatus], SW_HIDE
; check project

        cmp     [ptrProjectFile], 0
        je      .qfalse

        stdcall FocusFile, [ptrProjectFile]
        jmp     .qfalse

;----------- WM_NOTIFY --------------------------
.notify:
        mov     esi, [.lparam]

        cmp     [esi+NMHDR.code], TCN_SELCHANGE
        je      .change

        cmp     [esi+NMHDR.code], TCN_SELCHANGING
        je      .changing

        cmp     [esi+NMHDR.code], NM_RCLICK
        jne     .qfalse

.rclick:
        mov     eax, [hEditorTab]
        cmp     [esi+NMHDR.hwndFrom], eax
        jne     .qfalse

        lea     ebx, [.pnt]
        invoke  GetCursorPos, ebx

        mov     ecx, [.pnt.x]
        mov     edx, [.pnt.y]
        mov     [.tchi.pt.x], ecx
        mov     [.tchi.pt.y], edx

        lea     ebx, [.tchi]
        invoke  ScreenToClient, [esi+NMHDR.hwndFrom], ebx
        invoke  SendMessageA, [esi+NMHDR.hwndFrom], TCM_HITTEST, 0, ebx
        cmp     eax, -1
        je      .qfalse

        invoke  SendMessageA, [.hwnd], _EHM_SETACTIVETAB, eax, 0
        invoke  TrackPopupMenu, [hTabMenu], TPM_LEFTALIGN or TPM_RIGHTBUTTON, [.pnt.x], [.pnt.y] , 0, [.hwnd], NULL
        jmp     .qfalse

.changing:
        invoke  SendMessageA, [hEditorTab], TCM_GETCURSEL, 0, 0
        cmp     eax, -1
        je      .qfalse

        lea     ebx, [.tci]
        mov     [.tci.mask], TCIF_PARAM
        invoke  SendMessageA, [hEditorTab], TCM_GETITEM, eax, ebx

        push    [.tci.hEditor]
        pop     [hLastEditorForHide]
;        invoke  ShowWindow, [.tci.hEditor], SW_HIDE
        jmp     .qfalse

uglobal
  hLastEditorForHide dd ?
endg

.change:
        invoke  SendMessageA, [hEditorTab], TCM_GETCURSEL, 0, 0
        cmp     eax, -1
        je      .qfalse

        mov     ebx, eax
        lea     ecx, [.tci]
        mov     [.tci.mask], TCIF_PARAM
        invoke  SendMessageA, [hEditorTab], TCM_GETITEM, ebx, ecx

        invoke  LockWindowUpdate, [.hwnd]
        invoke  ShowWindow, [hLastEditorForHide], SW_HIDE
        invoke  ShowWindow, [.tci.hEditor], SW_SHOW

        invoke  SetFocus, 0                             ; work around for ASMEDIT bug (highly obscure)
        invoke  SetFocus, [.tci.hEditor]
        stdcall GetEditorFile, [.tci.hEditor]
        mov     ebx, eax
        stdcall SetCurrentFile, ebx
        stdcall AlignChildren, [.hwnd]
        invoke  LockWindowUpdate, NULL

        stdcall StrPtr, [ebx+TOpenFile.hFileName]
        invoke  SendMessageA, [.hwnd], WM_SETTEXT, 0, eax
        jmp     .qfalse

;----------- WM_DESTROY -------------------------
.destroy:
        invoke  SendMessageA, [hEditorTab], TCM_GETITEMCOUNT, 0, 0
        test    eax, eax
        mov     ebx, eax

.emptyloop:
        dec     ebx
        js      .emptyok

        mov     [.tci.mask], TCIF_PARAM
        lea     eax, [.tci]
        invoke  SendMessageA, [hEditorTab], TCM_GETITEM, ebx, eax
        stdcall GetEditorFile, [.tci.hEditor]
        stdcall CloseFile, eax
        jmp     .emptyloop

.emptyok:
        stdcall SaveMRUToIni, [ptrMRUFiles], [hIniFileName], cMRUFilesSection
        stdcall DestroyMRUList, [ptrMRUFiles]

        invoke  SendMessageA, [.hwnd], WM_GETICON, FALSE, 0
        invoke  DestroyIcon, eax

        invoke DestroyMenu, [hTabMenu]

        invoke  ImageList_Destroy, [hTabIml]
        jmp     .qfalse

cMRUFilesSection text 'MRU files'

;-----------AM_INITWINDOW----------------------------
.aminitwindow:
        xor     ebx,ebx

        invoke  CreateWindowExA, 0, cTabClassName, NULL,                                         \
                WS_CHILD or WS_CLIPCHILDREN or TCS_FOCUSNEVER or TCS_TABS or TCS_TOOLTIPS,                         \
                ebx, ebx, ebx, 23,                                                              \
                [.hwnd], NULL, [hInstance], NULL
        mov     [hEditorTab], eax
        invoke  SendMessageA, eax, TCM_SETITEMEXTRA, sizeof.TEditorTab - sizeof.TCITEMHEADER
        stdcall SetAlign, [hEditorTab], waTop

; Set image list.
        stdcall ImageList_LoadGif, [hInstance], resBmpTab, 16, FALSE
        mov     [hTabIml], eax
        invoke  SendMessageA, [hEditorTab], TCM_SETIMAGELIST, 0, [hTabIml]

; Create status bar
        invoke  CreateWindowExA, 0, cStatusBarClassName, NULL,                                   \
                WS_CHILD or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or SBARS_SIZEGRIP,               \
                ebx,ebx, ebx, ebx,                                                              \
                [.hwnd], NULL, [hInstance], NULL

        mov     [hStatus], eax
        stdcall SetAlign, eax, waBottom

        invoke  SendMessageA, [hStatus], SB_SETPARTS, 7, cStatusBarParts

        stdcall LoadMRUFromIni, 16, [hIniFileName], cMRUFilesSection
        mov     [ptrMRUFiles], eax

        invoke  DragAcceptFiles, [.hwnd], TRUE

.qfalse:
        xor     eax,eax
        clc
        return

.qtrue:
        xor     eax, eax
        inc     eax
        clc
        return

; Loads the [.tci] structure with tab info depending of
; TCommonFile structure pointed by esi.
.loadtcitem:
        invoke  SendMessageA, [hEditorTab], TCM_GETCURSEL, 0, 0

        mov     [.tci.mask], TCIF_PARAM or TCIF_TEXT or TCIF_IMAGE
        lea     ecx, [.str]
        mov     [.tci.pszText], ecx
        mov     [.tci.cchTextMax], 1024

        lea     ecx, [.tci]
        invoke  SendMessageA, [hEditorTab], TCM_GETITEM, eax, ecx
        retn
endp



  cStatusLine text 'Line:'
  cStatusPos  text 'Pos:'
  cStatusOverwrite text 'Overwrite'
  cStatusInsert    text 'Insert'
  cStatusVertical  text '||'
  cStatusHorizontal text '='
  cStatusModified text 'Modified'

  cStatusCompiled      text 'Total: '
  cStatusCompiledBin   text '  Binary: '
  cStatusCompiledLines text ' lines.'

proc UpdateStatusbar, .hEditor
.pos  AEPOS
begin
        push    esi edi ebx
        mov     ebx, [.hEditor]   ; handle of the AsmEdit window

        lea     eax, [.pos]
        invoke  SendMessageA, ebx, AEM_GETPOS, eax, 0

        stdcall NumToStr, [.pos.caretLine], ntsDec or ntsUnsigned
        push    eax
        stdcall StrInsert, eax, cStatusLine, 0
        stdcall StrPtr, eax
        invoke  SendMessageA, [hStatus], SB_SETTEXT, 0, eax
        stdcall StrDel ; from the stack

        stdcall NumToStr, [.pos.caretPosition], ntsDec or ntsUnsigned
        push    eax
        stdcall StrInsert, eax, cStatusPos, 0
        stdcall StrPtr, eax
        invoke  SendMessageA, [hStatus], SB_SETTEXT, 1, eax
        stdcall StrDel ; from the stack

        invoke  SendMessageA, ebx, AEM_GETMODE, 0, 0
        push    eax
        mov     ecx, cStatusOverwrite
        test    eax, AEMODE_OVERWRITE
        jnz     @f
        mov     ecx, cStatusInsert
@@:
        invoke  SendMessageA, [hStatus], SB_SETTEXT, 2, ecx
        pop     eax  ; mode again
        mov     ecx, cStatusVertical
        test    eax, AEMODE_VERTICALSEL
        jnz     @f
        mov     ecx, cStatusHorizontal
@@:
        invoke  SendMessageA, [hStatus], SB_SETTEXT, 3, ecx

        invoke  SendMessageA, ebx, AEM_GETMODIFIED, 0, 0
        mov     ecx, cStatusModified
        test    eax, eax
        jnz     @f
        xor     ecx, ecx
@@:
        invoke  SendMessageA, [hStatus], SB_SETTEXT, 4, ecx

        cmp     [hDebugThread], 0
        jne     @f

        invoke  SendMessageA, [hStatus], SB_SETTEXT, 5, NULL

        cmp     [fSetCurrent], 0
        jne     @f

        invoke  SendMessageA, ebx, AEM_SETFOCUSLINE, 0, 0
@@:

;        invoke  SendMessageA, [hStatus], SB_SETTEXT, 6, NULL

        pop     ebx edi esi
        return
endp




proc UpdateStatusbarCompiler
begin
        push    esi

; update source lines display.
        xor     esi, esi
        mov     eax, [TotalLines]
        or      eax, [AsmLines]
        jz      .disp_lines

        stdcall StrDup, cStatusCompiled
        mov     esi, eax

        stdcall NumToStr, [TotalLines], ntsUnsigned or ntsDec
        stdcall StrCat, esi, eax
        stdcall StrDel, eax
        stdcall StrCat, esi, cStatusCompiledLines
        stdcall StrCat, esi, cStatusCompiledBin

        stdcall NumToStr, [AsmLines], ntsUnsigned or ntsDec
        stdcall StrCat, esi, eax
        stdcall StrDel, eax
        stdcall StrCat, esi, cStatusCompiledLines

        stdcall StrPtr, esi

.disp_lines:
        invoke  SendMessageA, [hStatus], SB_SETTEXT, 6, eax

        stdcall StrDel, esi

        pop     esi
        return
endp


;-------------------------------------------------------------
; Returns index of the tab containing handle of given window
; or -1 if such tab item is not found.
;-------------------------------------------------------------
proc IndexByWindow, .hChildWindow
.tci TEditorTab
begin
        push    ebx

        invoke  SendMessageA, [hEditorTab], TCM_GETITEMCOUNT, 0, 0
        mov     ebx, eax

.while:
        dec     ebx
        js      .notfound

        mov     [.tci.mask], TCIF_PARAM
        lea     eax, [.tci]
        invoke  SendMessageA, [hEditorTab], TCM_GETITEM, ebx, eax
        test    eax, eax
        jz      .while

        mov     eax, [.hChildWindow]
        cmp     [.tci.hEditor], eax
        jne     .while

.notfound:
        mov     eax, ebx
        pop     ebx
        return
endp



;-----------------------------------------------------------
; Adds current active in editor file to current category in
; the project.
; If the file belongs to the project, remove it from the
; project and then adds it in the current category.
;-----------------------------------------------------------
proc OnAddToProject, .wparam, .lparam
begin
        mov     esi, [ptrCurrentFile]
        test    esi, esi
        jz      .finish

        invoke  SendMessageA, [hProjManager], PMM_ADDFILE, esi, -1

.finish:
        return
endp


proc OnSetCurrentAsMain, .wparam, .lparam
begin
        mov     esi, [ptrCurrentFile]
        test    esi, esi
        jz      .finish

        invoke  SendMessageA, [hProjManager], PMM_ADDFILE, esi, 0

.finish:
        return
endp

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/editorhost.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

dfLeft = waLeft
dfRight = waRight
dfTop = waTop
dfBottom = waBottom
dfClient = waClient              ; In this case, the docked window will be added to the tab control.
winmessage EHM_DOCKWINDOW           ; (hWnd, flags) - docks the specified window in the client area.

winmessage EHM_UNDOCKWINDOW         ; (hWnd, 0) - undocks the specified window from the dock area.

winmessage EHM_FILECHANGED          ; (hWnd, 0) - the file properties are changed.
                                 ; titles, icons, etc, should be updated.

winmessage EHM_FOCUSWINDOW          ; (hWnd, 0) - try to focus given window.

winmessage EHM_GETCURRENTASMEDIT    ; (0, 0) - returns handle of currently active
                                 ; ASMEDIT window if any, NULL otherwise.

winmessage _EHM_SETACTIVETAB         ; (iTab, fRelative)



MASK_SetRelative = $00FF0000

struct TEditorTab
  .               TCITEMHEADER  ; inherit the TCITEMHEADER
  .hEditor        dd ?          ; handle to the ASMEDIT child window.
ends

etUndefined = 0
etFromFile = 1
etFromProj = 2
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































Deleted source/errors.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
; This file contains application level error codes for using with
; GetLastError/SetLastError functions inside Fresh IDE
; LastError and ErrorMessage functions uses these error codes
; together with system error codes to create error messagebox.
;----------------------------------------------------------------

errFresh = $20000000   ; 29-th bit set for application defined error codes.

; This error does not generate messagebox window. Fresh simply does nothing.
errCanceled = 1 + errFresh ; The operation was canceled. No error should be generated.
errLoadBmp  = 2 + errFresh ; LoadImage API can't load specified bitmap.


iglobal
  label FreshErrorMessages dword
  IndexedStrings       \
    errCanceled, 'Canceled operation.', \
    errLoadBmp,  "LoadImage API can't load specified bitmap image."

  errmsgUnknownError text 'Unknown Fresh error reported. Probably bug...'
endg
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































Deleted source/fasm/ASSEMBLE.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056

; flat assembler core
; Copyright (c) 1999-2012, 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     [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],20h
        sub     ebx,8+20h
        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
        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     line_assembled
      new_line:
        lods    dword [esi]
        mov     [current_line],eax
        mov     [prefixed_instruction],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
        mov     edx,[eax+8]
        push    edx
        cmp     [current_pass],0
        je      get_constant_value
        test    dl,4
        jnz     get_constant_value
        mov     cx,[current_pass]
        cmp     cx,[eax+16]
        je      get_constant_value
        and     dl,not 1
        mov     [eax+8],dl
      get_constant_value:
        push    eax
        mov     al,byte [esi-1]
        push    eax
        or      [size_override],-1
        call    get_value
        pop     ebx
        mov     ch,bl
        pop     ebx
        pop     dword [ebx+8]
        cmp     ebx,0Fh
        jb      invalid_use_of_symbol
        je      reserved_word_used_as_symbol
        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     [size_override],0
;        mov     [operand_prefix],0
;        mov     [opcode_prefix],0
        and     dword [operand_size],0
;        mov     [rex_prefix],0
;        mov     [vex_required],0
;        mov     [vex_register],0
;        mov     [immediate_size],0
        and     dword [rex_prefix],0
        call    instruction_handler
      instruction_handler:
        movzx   ebx,word [esi]
        mov     al,[esi+2]
        add     esi,3
        add     [esp],ebx
        ret
      instruction_assembled:
        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],0
        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    dword [ebx+8]
        push    ebx ecx
        and     byte [ebx+8],not 1
        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
        pop     dword [ebx+8]
        mov     ch,[value_type]
        or      ch,ch
        jz      make_free_label
        cmp     ch,4
        je      make_free_label
        cmp     ch,2
        jne     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:
        mov     ebx,[addressing_space]
        mov     ecx,edi
        sub     ecx,[ebx+18h]
        mov     [ebx+1Ch],ecx
        lods    byte [esi]
        cmp     al,'('
        jne     invalid_argument
        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
        cmp     [symbols_file],0
        je      get_addressing_space
        cmp     [next_pass_needed],0
        jne     get_addressing_space
        call    store_label_reference
      get_addressing_space:
        mov     ebx,[ebx]
      get_data_address:
        push    ebx
        cmp     byte [esi],'.'
        je      invalid_value
        or      [size_override],-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     ecx,edx
        jnz     bad_data_address
        mov     eax,ebx
        sub     eax,[ds:ebp+18h]
        jc      bad_data_address
        movzx   ecx,[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
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      [size_override],-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     ebp,[addressing_space]
        jne     instruction_assembled
        cmp     edi,[undefined_data_end]
        jne     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
        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

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,100h
        jc      stack_overflow
        cmp     eax,[stack_limit]
        jb      stack_overflow
        push    esi
        or      [prefixed_instruction],-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,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
        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
        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
        call    init_addressing_space
        or      byte [ebx+0Ah],1
        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
      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
        test    byte [ebx+0Ah],2
        jz      addressing_space_closed
        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
        cmp     eax,[ebx+8]
        jbe     out_of_memory
        mov     [tagged_blocks],eax
        lea     edi,[eax+ecx-1]
        xchg    eax,[ebx+18h]
        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
        cdq
        add     [ebx],eax
        adc     dword [ebx+4],edx
        adc     byte [ebx+8],dl
        pop     edx ecx edi esi
      addressing_space_closed:
        ret
repeat_directive:
        cmp     [prefixed_instruction],0
        jne     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:
        cmp     [prefixed_instruction],0
        jne     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:
        cmp     [prefixed_instruction],0
        jne     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:
        cmp     [prefixed_instruction],0
        jne     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:
        cmp     [prefixed_instruction],0
        jne     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:
        cmp     [prefixed_instruction],0
        jne     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:
        cmp     [prefixed_instruction],0
        jne     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

data_bytes:
        call    define_data
        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
      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],'{'
        jne     duplicate_single_data_value
        inc     esi
      duplicate_data:
        push    eax esi
      duplicated_values:
        cmp     edi,[tagged_blocks]
        jae     out_of_memory
        call    near dword [esp+8]
        lods    byte [esi]
        cmp     al,','
        je      duplicated_values
        cmp     al,'}'
        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
        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],'{'
        jne     skip_single_data_value
        inc     esi
      skip_data_value:
        call    skip_symbol
        jc      invalid_argument
        cmp     byte [esi],'}'
        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
        call    near dword [esp]
      data_defined:
        lods    byte [esi]
        cmp     al,','
        je      define_data
        dec     esi
        add     esp,4
        jmp     instruction_assembled
data_unicode:
        or      [base_code],-1
        jmp     define_words
data_words:
        mov     [base_code],0
      define_words:
        call    define_data
        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
        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
        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
        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
        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
        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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/fasm/AVX.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787

; flat assembler core
; Copyright (c) 1999-2012, Tomasz Grysztar.
; All rights reserved.

avx_single_source_pd_instruction:
        or      [vex_required],2
        jmp     avx_pd_instruction
avx_pd_instruction_imm8:
        mov     [immediate_size],1
avx_pd_instruction:
        mov     [opcode_prefix],66h
        mov     [mmx_size],0
        jmp     avx_instruction
avx_single_source_ps_instruction:
        or      [vex_required],2
        jmp     avx_ps_instruction
avx_ps_instruction_imm8:
        mov     [immediate_size],1
avx_ps_instruction:
        mov     [mmx_size],0
        jmp     avx_instruction
avx_sd_instruction_imm8:
        mov     [immediate_size],1
avx_sd_instruction:
        mov     [opcode_prefix],0F2h
        mov     [mmx_size],8
        jmp     avx_instruction
avx_ss_instruction_imm8:
        mov     [immediate_size],1
avx_ss_instruction:
        mov     [opcode_prefix],0F3h
        mov     [mmx_size],4
        jmp     avx_instruction
avx_cmp_pd_instruction:
        mov     [opcode_prefix],66h
avx_cmp_ps_instruction:
        mov     [mmx_size],0
        mov     byte [value],al
        mov     al,0C2h
        jmp     avx_instruction
avx_cmp_sd_instruction:
        mov     [opcode_prefix],0F2h
        mov     [mmx_size],8
        mov     byte [value],al
        mov     al,0C2h
        jmp     avx_instruction
avx_cmp_ss_instruction:
        mov     [opcode_prefix],0F3h
        mov     [mmx_size],4
        mov     byte [value],al
        mov     al,0C2h
        jmp     avx_instruction
avx_comiss_instruction:
        or      [vex_required],2
        mov     [mmx_size],4
        jmp     avx_instruction
avx_comisd_instruction:
        or      [vex_required],2
        mov     [opcode_prefix],66h
        mov     [mmx_size],8
        jmp     avx_instruction
avx_haddps_instruction:
        mov     [opcode_prefix],0F2h
        mov     [mmx_size],0
        jmp     avx_instruction
avx_movshdup_instruction:
        or      [vex_required],2
        mov     [opcode_prefix],0F3h
        mov     [mmx_size],0
        jmp     avx_instruction
avx_128bit_instruction:
        mov     [mmx_size],16
        mov     [opcode_prefix],66h
avx_instruction:
        mov     [base_code],0Fh
        mov     [extended_code],al
      avx_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
      avx_vex_reg:
        test    [vex_required],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:
        cmp     [mmx_size],0
        je      avx_regs_size_ok
        cmp     ah,16
        jne     invalid_operand
      avx_regs_size_ok:
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        call    take_avx_rm
        jc      avx_regs_reg
        mov     al,[extended_code]
        mov     ah,[supplemental_code]
        cmp     al,0C2h
        je      sse_cmp_mem_ok
        cmp     ax,443Ah
        je      sse_cmp_mem_ok
        mov     al,[base_code]
        and     al,11011100b
        cmp     al,11001100b
        je      sse_cmp_mem_ok
        cmp     [immediate_size],1
        je      mmx_imm8
        cmp     [immediate_size],0
        jge     instruction_ready
        cmp     byte [esi],','
        jne     invalid_operand
        inc     esi
        call    take_avx_register
        shl     al,4
        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
        mov     al,[extended_code]
        mov     ah,[supplemental_code]
        cmp     al,0C2h
        je      sse_cmp_nomem_ok
        cmp     ax,443Ah
        je      sse_cmp_nomem_ok
        mov     al,[base_code]
        and     al,11011100b
        cmp     al,11001100b
        je      sse_cmp_nomem_ok
        cmp     [immediate_size],1
        je      mmx_nomem_imm8
        cmp     [immediate_size],0
        jge     nomem_instruction_ready
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        mov     al,bl
        shl     al,4
        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
        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
        mov     [operand_size],cl
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_avx_register
        cmp     [mmx_size],0
        je      avx_reg_ok
        cmp     ah,16
        jne     invalid_operand
      avx_reg_ok:
        stc
        ret
      take_avx_mem:
        push    ecx
        call    get_address
        pop     eax
        cmp     [mmx_size],0
        jne     avx_smem
        xchg    al,[operand_size]
        or      al,al
        jz      avx_mem_ok
        cmp     al,[operand_size]
        jne     operand_sizes_do_not_match
      avx_mem_ok:
        clc
        ret
      avx_smem:
        xchg    al,[operand_size]
        or      al,al
        jz      avx_smem_ok
        cmp     al,[mmx_size]
        jne     invalid_operand_size
      avx_smem_ok:
        clc
        ret
      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

avx_single_source_128bit_instruction_38:
        or      [vex_required],2
avx_128bit_instruction_38:
        mov     [mmx_size],16
        jmp     avx_instruction_38_setup
avx_single_source_instruction_38:
        or      [vex_required],2
avx_instruction_38:
        mov     [mmx_size],0
      avx_instruction_38_setup:
        mov     [opcode_prefix],66h
        mov     [supplemental_code],al
        mov     al,38h
        jmp     avx_instruction
avx_instruction_38_w1:
        or      [rex_prefix],8
        jmp     avx_instruction_38

avx_ss_instruction_3a_imm8:
        mov     [mmx_size],4
        jmp     avx_instruction_3a_imm8_setup
avx_sd_instruction_3a_imm8:
        mov     [mmx_size],8
        jmp     avx_instruction_3a_imm8_setup
avx_single_source_128bit_instruction_3a_imm8:
        or      [vex_required],2
avx_128bit_instruction_3a_imm8:
        mov     [mmx_size],16
        jmp     avx_instruction_3a_imm8_setup
avx_triple_source_instruction_3a:
        mov     [mmx_size],0
        mov     [immediate_size],-1
        mov     byte [value],0
        jmp     avx_instruction_3a_setup
avx_single_source_instruction_3a_imm8:
        or      [vex_required],2
avx_instruction_3a_imm8:
        mov     [mmx_size],0
      avx_instruction_3a_imm8_setup:
        mov     [immediate_size],1
      avx_instruction_3a_setup:
        mov     [opcode_prefix],66h
        mov     [supplemental_code],al
        mov     al,3Ah
        jmp     avx_instruction
avx_pclmulqdq_instruction:
        mov     byte [value],al
        mov     [mmx_size],16
        mov     al,44h
        jmp     avx_instruction_3a_setup

avx_permq_instruction:
        or      [vex_required],2
        or      [rex_prefix],8
avx_perm2f128_instruction:
        mov     [immediate_size],1
        mov     ah,3Ah
        jmp     avx_perm_instruction
avx_permd_instruction:
        mov     ah,38h
      avx_perm_instruction:
        mov     [opcode_prefix],66h
        mov     [base_code],0Fh
        mov     [extended_code],ah
        mov     [supplemental_code],al
        mov     [mmx_size],0
        or      [vex_required],1
        call    take_avx_register
        cmp     ah,32
        jne     invalid_operand_size
        mov     [postbyte_register],al
        jmp     avx_vex_reg

avx_movdqu_instruction:
        mov     [opcode_prefix],0F3h
        jmp     avx_movps_instruction
avx_movpd_instruction:
        mov     [opcode_prefix],66h
avx_movps_instruction:
        mov     [mmx_size],0
        or      [vex_required],2
        mov     [base_code],0Fh
        mov     [extended_code],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
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        call    take_avx_register
        mov     [postbyte_register],al
        jmp     instruction_ready
avx_movntpd_instruction:
        mov     [opcode_prefix],66h
avx_movntps_instruction:
        or      [vex_required],1
        mov     [base_code],0Fh
        mov     [extended_code],al
        lods    byte [esi]
        call    get_size_operator
        jmp     avx_mem
avx_lddqu_instruction:
        mov     [opcode_prefix],0F2h
        mov     [mmx_size],0
        xor     cx,cx
      avx_load_instruction:
        mov     [base_code],0Fh
        mov     [extended_code],al
        or      [vex_required],1
        call    take_avx_register
        or      cl,cl
        jz      avx_load_reg_ok
        cmp     ah,cl
        jne     invalid_operand
      avx_load_reg_ok:
        cmp     [mmx_size],0
        je      avx_load_reg_
        xor     ah,ah
      avx_load_reg_:
        xchg    ah,[operand_size]
        push    eax
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        je      avx_load_reg_reg
        cmp     al,'['
        jne     invalid_operand
        call    get_address
        pop     eax
        xchg    ah,[operand_size]
        mov     [postbyte_register],al
        mov     al,[mmx_size]
        or      al,al
        jz      instruction_ready
        or      ah,ah
        jz      instruction_ready
        cmp     al,ah
        jne     invalid_operand_size
        jmp     instruction_ready
      avx_load_reg_reg:
        lods    byte [esi]
        call    convert_avx_register
        cmp     ch,ah
        jne     invalid_operand
        mov     bl,al
        pop     eax
        xchg    ah,[operand_size]
        mov     [postbyte_register],al
        jmp     nomem_instruction_ready

avx_movntdqa_instruction:
        mov     [mmx_size],0
        xor     cx,cx
        jmp     avx_load_instruction_38
avx_broadcastss_instruction:
        mov     [mmx_size],4
        xor     cl,cl
        mov     ch,16
        jmp     avx_load_instruction_38
avx_broadcastsd_instruction:
        mov     [mmx_size],8
        mov     cl,32
        mov     ch,16
        jmp     avx_load_instruction_38
avx_pbroadcastb_instruction:
        mov     [mmx_size],1
        jmp     avx_pbroadcast_instruction
avx_pbroadcastw_instruction:
        mov     [mmx_size],2
        jmp     avx_pbroadcast_instruction
avx_pbroadcastd_instruction:
        mov     [mmx_size],4
        jmp     avx_pbroadcast_instruction
avx_pbroadcastq_instruction:
        mov     [mmx_size],8
      avx_pbroadcast_instruction:
        xor     cl,cl
        mov     ch,16
        jmp     avx_load_instruction_38
avx_broadcastf128_instruction:
        mov     [mmx_size],16
        mov     cl,32
        xor     ch,ch
      avx_load_instruction_38:
        mov     [opcode_prefix],66h
        mov     [supplemental_code],al
        mov     al,38h
        jmp     avx_load_instruction
avx_movlpd_instruction:
        mov     [opcode_prefix],66h
avx_movlps_instruction:
        mov     [base_code],0Fh
        mov     [extended_code],al
        mov     [mmx_size],8
        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
        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_maskmov_w1_instruction:
        or      [rex_prefix],8
avx_maskmov_instruction:
        call    setup_66_0f_38
        mov     [mmx_size],0
        or      [vex_required],1
        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
        call    take_avx_rm
        jc      invalid_operand
        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
      setup_66_0f_38:
        mov     [extended_code],38h
        mov     [supplemental_code],al
        mov     [base_code],0Fh
        mov     [opcode_prefix],66h
        ret
avx_movd_instruction:
        or      [vex_required],1
        jmp     movd_instruction
avx_movq_instruction:
        or      [vex_required],1
        jmp     movq_instruction
avx_movddup_instruction:
        or      [vex_required],1
        mov     [opcode_prefix],0F2h
        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_avx_register
        mov     [postbyte_register],al
        mov     [mmx_size],0
        cmp     ah,32
        je      avx_regs_size_ok
        mov     [mmx_size],8
        jmp     avx_regs_size_ok
avx_movmskpd_instruction:
        mov     [opcode_prefix],66h
avx_movmskps_instruction:
        mov     [base_code],0Fh
        mov     [extended_code],50h
        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
        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_movsd_instruction:
        mov     [opcode_prefix],0F2h
        mov     [mmx_size],8
        jmp     avx_movs_instruction
avx_movss_instruction:
        mov     [opcode_prefix],0F3h
        mov     [mmx_size],4
      avx_movs_instruction:
        or      [vex_required],1
        mov     [base_code],0Fh
        mov     [extended_code],10h
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     avx_movlps_mem
        lods    byte [esi]
        call    convert_xmm_register
        mov     [postbyte_register],al
        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_cvtdq2pd_instruction:
        mov     [opcode_prefix],0F3h
avx_cvtps2pd_instruction:
        mov     [base_code],0Fh
        mov     [extended_code],al
        or      [vex_required],1
        call    take_avx_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
        jne     avx_cvtdq2pd_reg_mem
        lods    byte [esi]
        call    convert_xmm_register
        mov     bl,al
        mov     [operand_size],cl
        jmp     nomem_instruction_ready
      avx_cvtdq2pd_reg_mem:
        cmp     al,'['
        jne     invalid_operand
        mov     [mmx_size],cl
        call    get_address
        mov     al,[mmx_size]
        mov     ah,al
        xchg    al,[operand_size]
        or      al,al
        jz      instruction_ready
        shl     al,1
        cmp     al,ah
        jne     invalid_operand_size
        jmp     instruction_ready
avx_cvtpd2dq_instruction:
        mov     [opcode_prefix],0F2h
        jmp     avx_cvtpd_instruction
avx_cvtpd2ps_instruction:
        mov     [opcode_prefix],66h
      avx_cvtpd_instruction:
        mov     [base_code],0Fh
        mov     [extended_code],al
        or      [vex_required],1
        call    take_avx_register
        mov     [postbyte_register],al
        cmp     ah,16
        jne     invalid_operand
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        mov     [operand_size],0
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     avx_cvtpd2dq_reg_mem
        lods    byte [esi]
        call    convert_avx_register
        mov     bl,al
        jmp     nomem_instruction_ready
      avx_cvtpd2dq_reg_mem:
        cmp     al,'['
        jne     invalid_operand
        call    get_address
        mov     al,[operand_size]
        or      al,al
        jz      operand_size_not_specified
        cmp     al,16
        je      instruction_ready
        cmp     al,32
        jne     invalid_operand_size
        jmp     instruction_ready
avx_cvttps2dq_instruction:
        or      [vex_required],2
        mov     [opcode_prefix],0F3h
        mov     [mmx_size],0
        jmp     avx_instruction
avx_cvtsd2si_instruction:
        or      [vex_required],1
        jmp     cvtsd2si_instruction
avx_cvtss2si_instruction:
        or      [vex_required],1
        jmp     cvtss2si_instruction
avx_cvtsi2ss_instruction:
        mov     [opcode_prefix],0F3h
        jmp     avx_cvtsi_instruction
avx_cvtsi2sd_instruction:
        mov     [opcode_prefix],0F2h
      avx_cvtsi_instruction:
        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
        jmp     cvtsi_xmmreg

avx_extractf128_instruction:
        or      [vex_required],1
        call    setup_66_0f_3a
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        je      avx_extractf128_reg
        cmp     al,'['
        jne     invalid_operand
        call    get_address
        xor     al,al
        xchg    al,[operand_size]
        or      al,al
        jz      avx_extractf128_mem_size_ok
        cmp     al,16
        jne     invalid_operand_size
      avx_extractf128_mem_size_ok:
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        call    take_avx_register
        cmp     ah,32
        jne     invalid_operand_size
        mov     [postbyte_register],al
        jmp     mmx_imm8
      avx_extractf128_reg:
        lods    byte [esi]
        call    convert_xmm_register
        mov     [operand_size],0
        push    eax
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        call    take_avx_register
        cmp     ah,32
        jne     invalid_operand_size
        mov     [postbyte_register],al
        pop     ebx
        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
avx_insertf128_instruction:
        or      [vex_required],1
        call    setup_66_0f_3a
        call    take_avx_register
        cmp     ah,32
        jne     invalid_operand
        mov     [postbyte_register],al
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        call    take_avx_register
        mov     [vex_register],al
        mov     [operand_size],0
        mov     [mmx_size],16
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        call    take_avx_rm
        mov     [operand_size],32
        jnc     mmx_imm8
        mov     bl,al
        jmp     mmx_nomem_imm8
avx_extractps_instruction:
        or      [vex_required],1
        jmp     extractps_instruction
avx_insertps_instruction:
        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     insertps_xmmreg
avx_pextrb_instruction:
        or      [vex_required],1
        jmp     pextrb_instruction
avx_pextrw_instruction:
        or      [vex_required],1
        jmp     pextrw_instruction
avx_pextrd_instruction:
        or      [vex_required],1
        jmp     pextrd_instruction
avx_pextrq_instruction:
        or      [vex_required],1
        jmp     pextrq_instruction
avx_pinsrb_instruction:
        mov     [mmx_size],1
        or      [vex_required],1
        jmp     avx_pinsr_instruction_3a
avx_pinsrw_instruction:
        mov     [mmx_size],2
        or      [vex_required],1
        jmp     avx_pinsr_instruction
avx_pinsrd_instruction:
        mov     [mmx_size],4
        or      [vex_required],1
        jmp     avx_pinsr_instruction_3a
avx_pinsrq_instruction:
        mov     [mmx_size],8
        or      [vex_required],1
        call    operand_64bit
      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
        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_maskmovdqu_instruction:
        or      [vex_required],1
        jmp     maskmovdqu_instruction
avx_pmovmskb_instruction:
        or      [vex_required],1
        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
avx_pshufd_instruction:
        or      [vex_required],1
        mov     [mmx_size],0
        mov     [opcode_prefix],al
        mov     [base_code],0Fh
        mov     [extended_code],70h
        call    take_avx_register
        mov     [postbyte_register],al
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        call    take_avx_rm
        jnc     mmx_imm8
        mov     bl,al
        jmp     mmx_nomem_imm8

avx_pmovsxbw_instruction:
        mov     [mmx_size],8
        jmp     avx_pmovsx_instruction
avx_pmovsxbd_instruction:
        mov     [mmx_size],4
        jmp     avx_pmovsx_instruction
avx_pmovsxbq_instruction:
        mov     [mmx_size],2
        jmp     avx_pmovsx_instruction
avx_pmovsxwd_instruction:
        mov     [mmx_size],8
        jmp     avx_pmovsx_instruction
avx_pmovsxwq_instruction:
        mov     [mmx_size],4
        jmp     avx_pmovsx_instruction
avx_pmovsxdq_instruction:
        mov     [mmx_size],8
      avx_pmovsx_instruction:
        or      [vex_required],1
        call    setup_66_0f_38
        call    take_avx_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,10h
        je      avx_pmovsx_xmmreg_reg
        cmp     al,'['
        jne     invalid_operand
        call    get_address
        pop     eax
        cmp     al,32
        jb      avx_pmovsx_size_check
        shl     [mmx_size],1
      avx_pmovsx_size_check:
        xchg    al,[operand_size]
        test    al,al
        jz      instruction_ready
        cmp     al,[mmx_size]
        jne     invalid_operand_size
        jmp     instruction_ready
      avx_pmovsx_xmmreg_reg:
        lods    byte [esi]
        call    convert_xmm_register
        mov     bl,al
        pop     eax
        mov     [operand_size],al
        jmp     nomem_instruction_ready
avx_permil_instruction:
        call    setup_66_0f_3a
        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,'['
        je      avx_permil_reg_mem
        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
        xchg    cl,[operand_size]
        pop     esi
        cmp     al,'['
        je      avx_permil_reg_reg_mem
        cmp     al,10h
        jne     avx_permil_reg_reg_imm8
        call    take_avx_register
        mov     bl,al
        mov     [extended_code],38h
        add     [supplemental_code],8
        jmp     nomem_instruction_ready
      avx_permil_reg_reg_mem:
        lods    byte [esi]
        call    get_size_operator
        call    get_address
        mov     [extended_code],38h
        add     [supplemental_code],8
        jmp     instruction_ready
      avx_permil_reg_reg_imm8:
        dec     esi
        xor     bl,bl
        xchg    bl,[vex_register]
        jmp     mmx_nomem_imm8
      avx_permil_reg_mem:
        call    get_address
        jmp     mmx_imm8
avx_bit_shift_instruction:
        mov     [opcode_prefix],66h
        mov     [base_code],0Fh
        mov     [extended_code],al
        or      [vex_required],1
        call    take_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
        push    esi
        xor     cl,cl
        xchg    cl,[operand_size]
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        je      avx_bit_shift_regs_reg
        pop     esi
        cmp     al,'['
        je      avx_bit_shift_regs_mem
        xchg    cl,[operand_size]
        dec     esi
        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]
        xchg    bl,[vex_register]
        jmp     mmx_nomem_imm8
      avx_bit_shift_regs_reg:
        pop     eax
        lods    byte [esi]
        call    convert_xmm_register
        xchg    cl,[operand_size]
        mov     bl,al
        jmp     nomem_instruction_ready
      avx_bit_shift_regs_mem:
        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_pslldq_instruction:
        mov     [postbyte_register],al
        mov     [opcode_prefix],66h
        mov     [base_code],0Fh
        mov     [extended_code],73h
        or      [vex_required],1
        call    take_avx_register
        mov     [vex_register],al
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        call    take_avx_register
        mov     bl,al
        jmp     mmx_nomem_imm8

vzeroall_instruction:
        mov     [operand_size],32
vzeroupper_instruction:
        mov     [base_code],0Fh
        mov     [extended_code],al
        or      [vex_required],1
        call    store_instruction_code
        jmp     instruction_assembled
vldmxcsr_instruction:
        or      [vex_required],1
        jmp     fxsave_instruction
vcvtph2ps_instruction:
        mov     [opcode_prefix],66h
        mov     [supplemental_code],al
        mov     al,38h
        jmp     avx_cvtps2pd_instruction
vcvtps2ph_instruction:
        call    setup_66_0f_3a
        or      [vex_required],1
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        je      vcvtps2ph_reg
        cmp     al,'['
        jne     invalid_operand
        call    get_address
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        shl     [operand_size],1
        call    take_avx_register
        mov     [postbyte_register],al
        jmp     mmx_imm8
      vcvtps2ph_reg:
        lods    byte [esi]
        call    convert_xmm_register
        mov     bl,al
        mov     [operand_size],0
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        call    take_avx_register
        mov     [postbyte_register],al
        jmp     mmx_nomem_imm8

bmi_instruction:
        mov     [base_code],0Fh
        mov     [extended_code],38h
        mov     [supplemental_code],0F3h
        mov     [postbyte_register],al
      bmi_reg:
        or      [vex_required],1
        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],1
        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],1
        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],1
        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],1
        call    get_reg_mem
        jc      rorx_reg_reg
        call    operand_32or64
        jmp     mmx_imm8
      rorx_reg_reg:
        call    operand_32or64
        jmp     mmx_nomem_imm8

fma_instruction_pd:
        or      [rex_prefix],8
fma_instruction_ps:
        mov     [mmx_size],0
        jmp     avx_instruction_38_setup
fma_instruction_sd:
        or      [rex_prefix],8
        mov     [mmx_size],8
        jmp     avx_instruction_38_setup
fma_instruction_ss:
        mov     [mmx_size],4
        jmp     avx_instruction_38_setup

fma4_instruction_p:
        mov     [mmx_size],0
        jmp     fma4_instruction_setup
fma4_instruction_sd:
        mov     [mmx_size],8
        jmp     fma4_instruction_setup
fma4_instruction_ss:
        mov     [mmx_size],4
      fma4_instruction_setup:
        mov     [immediate_size],-2
        mov     byte [value],0
        jmp     avx_instruction_3a_setup

xop_single_source_sd_instruction:
        or      [vex_required],2
        mov     [mmx_size],8
        jmp     xop_instruction_9
xop_single_source_ss_instruction:
        or      [vex_required],2
        mov     [mmx_size],4
        jmp     xop_instruction_9
xop_single_source_instruction:
        or      [vex_required],2
        mov     [mmx_size],0
      xop_instruction_9:
        mov     [base_code],al
        mov     [xop_opcode_map],9
        jmp     avx_common
xop_single_source_128bit_instruction:
        or      [vex_required],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_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     [mmx_size],16
        mov     [base_code],ah
        mov     [xop_opcode_map],8
        jmp     avx_common
vpcmov_instruction:
        or      [vex_required],1
        mov     [immediate_size],-2
        mov     byte [value],0
        mov     [mmx_size],0
        mov     [base_code],al
        mov     [xop_opcode_map],8
        jmp     avx_common
xop_shift_instruction:
        mov     [base_code],al
        or      [vex_required],1
        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

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:
        mov     [base_code],0Fh
        mov     [supplemental_code],al
        mov     al,3Ah
        mov     [mmx_size],0
        jmp     avx_instruction

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],1
        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],1
        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

gather_instruction_pd:
        or      [rex_prefix],8
gather_instruction_ps:
        call    setup_66_0f_38
        or      [vex_required],4
        call    take_avx_register
        mov     [postbyte_register],al
        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]
        test    al,al
        jz      gather_elements_size_ok
        test    [rex_prefix],8
        jnz     gather_elements_64bit
        cmp     al,4
        jne     invalid_operand_size
        jmp     gather_elements_size_ok
      gather_elements_64bit:
        cmp     al,8
        jne     invalid_operand_size
      gather_elements_size_ok:
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        call    take_avx_register
        mov     [vex_register],al
        cmp     al,[postbyte_register]
        je      disallowed_combination_of_registers
        mov     al,bl
        and     al,1111b
        cmp     al,[postbyte_register]
        je      disallowed_combination_of_registers
        cmp     al,[vex_register]
        je      disallowed_combination_of_registers
        mov     al,bl
        shr     al,4
        cmp     al,0Ch
        je      gather_vr_128bit
        mov     al,[rex_prefix]
        shr     al,3
        xor     al,[supplemental_code]
        test    al,1
        jz      gather_256bit
        test    [supplemental_code],1
        jz      invalid_operand_size
        mov     al,32
        xchg    al,[operand_size]
        cmp     al,16
        jne     invalid_operand_size
        jmp     instruction_ready
      gather_256bit:
        cmp     ah,32
        jne     invalid_operand_size
        jmp     instruction_ready
      gather_vr_128bit:
        cmp     ah,16
        je      instruction_ready
        test    [supplemental_code],1
        jnz     invalid_operand_size
        test    [rex_prefix],8
        jz      invalid_operand_size
        jmp     instruction_ready

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,0Fh
        and     ah,0F0h
        sub     ah,0B0h
        jbe     invalid_operand
        cmp     ah,32
        ja      invalid_operand
        cmp     al,8
        jb      match_register_size
        cmp     [code_type],64
        jne     invalid_operand
        jmp     match_register_size
store_vex_instruction_code:
        mov     al,[base_code]
        cmp     al,0Fh
        jne     store_xop_instruction_code
        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     vex_l_bit_ok
        or      al,100b
      vex_l_bit_ok:
        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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/fasm/ERRORS.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

; flat assembler core
; Copyright (c) 1999-2012, 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

unexpected_end_of_file:
        push    _unexpected_end_of_file
        jmp     general_error
code_cannot_be_generated:
        push    _code_cannot_be_generated
        jmp     general_error
format_limitations_exceeded:
        push    _format_limitations_exceeded
    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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































Deleted source/fasm/EXPRCALC.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327

; flat assembler core
; Copyright (c) 1999-2012, 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:
        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,0E0h
        je      calculate_rva
        cmp     al,0E1h
        je      calculate_plt
        cmp     al,0D0h
        je      calculate_not
        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
        cmp     [symbols_file],0
        je      label_reference_ok
        cmp     [next_pass_needed],0
        jne     label_reference_ok
        call    store_label_reference
      label_reference_ok:
        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
        cmp     [size_override],-1
        je      calculation_loop
        cmp     [size_override],0
        je      check_size
        cmp     [operand_size],0
        jne     calculation_loop
        mov     [operand_size],al
        jmp     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
      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
        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
        jz      calculation_loop
        or      cl,cl
        jz      xor_size_check
        xor     eax,[ebx]
        xor     edx,[ebx+4]
      xor_size_check:
        mov     cl,[value_size]
        cmp     cl,1
        je      xor_byte_result
        cmp     cl,2
        je      xor_word_result
        cmp     cl,4
        je      xor_dword_result
        cmp     cl,6
        je      xor_pword_result
        cmp     cl,8
        jne     calculation_loop
        xor     edx,[ebx+4]
        js      xor_result_truncated
        jmp     calculation_loop
      xor_pword_result:
        test    edx,0FFFF0000h
        jnz     calculation_loop
        cmp     word [ebx+6],-1
        jne     calculation_loop
        xor     dx,[ebx+4]
        jns     calculation_loop
        not     word [ebx+6]
        jmp     xor_result_truncated
      xor_dword_result:
        test    edx,edx
        jnz     calculation_loop
        cmp     dword [ebx+4],-1
        jne     calculation_loop
        xor     eax,[ebx]
        jns     calculation_loop
        not     dword [ebx+4]
        jmp     xor_result_truncated
      xor_word_result:
        test    edx,edx
        jnz     calculation_loop
        test    eax,0FFFF0000h
        jnz     calculation_loop
        cmp     dword [ebx+4],-1
        jne     calculation_loop
        cmp     word [ebx+2],-1
        jne     calculation_loop
        xor     ax,[ebx]
        jns     calculation_loop
        not     dword [ebx+4]
        not     word [ebx+2]
        jmp     xor_result_truncated
      xor_byte_result:
        test    edx,edx
        jnz     calculation_loop
        test    eax,0FFFFFF00h
        jnz     calculation_loop
        cmp     dword [ebx+4],-1
        jne     calculation_loop
        cmp     word [ebx+2],-1
        jne     calculation_loop
        cmp     byte [ebx+1],-1
        jne     calculation_loop
        xor     al,[ebx]
        jns     calculation_loop
        not     dword [ebx+4]
        not     word [ebx+2]
        not     byte [ebx+1]
      xor_result_truncated:
        mov     byte [ebx+13],0
        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
        cmp     byte [ebx+13],0
        je      do_shr
        mov     al,[value_size]
        cmp     al,1
        je      shr_negative_byte
        cmp     al,2
        je      shr_negative_word
        cmp     al,4
        je      shr_negative_dword
        cmp     al,6
        je      shr_negative_pword
        cmp     al,8
        jne     do_shr
      shr_negative_qword:
        test    byte [ebx+7],80h
        jz      do_shr
      shr_truncated:
        mov     byte [ebx+13],0
      do_shr:
        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
      shr_negative_byte:
        cmp     dword [ebx+4],-1
        jne     do_shr
        cmp     word [ebx+2],-1
        jne     do_shr
        cmp     byte [ebx+1],-1
        jne     do_shr
        test    byte [ebx],80h
        jz      do_shr
        not     dword [ebx+4]
        not     word [ebx+2]
        not     byte [ebx+1]
        jmp     shr_truncated
      shr_negative_word:
        cmp     dword [ebx+4],-1
        jne     do_shr
        cmp     word [ebx+2],-1
        jne     do_shr
        test    byte [ebx+1],80h
        jz      do_shr
        not     dword [ebx+4]
        not     word [ebx+2]
        jmp     shr_truncated
      shr_negative_dword:
        cmp     dword [ebx+4],-1
        jne     do_shr
        test    byte [ebx+3],80h
        jz      do_shr
        not     dword [ebx+4]
        jmp     shr_truncated
      shr_negative_pword:
        cmp     word [ebx+6],-1
        jne     do_shr
        test    byte [ebx+5],80h
        jz      do_shr
        not     word [ebx+6]
        jmp     shr_truncated
      calculate_not:
        cmp     word [edi+8],0
        jne     invalid_expression
        cmp     byte [edi+12],0
        je      not_ok
        call    recoverable_misuse
      not_ok:
        mov     al,[value_size]
        cmp     al,1
        je      not_byte
        cmp     al,2
        je      not_word
        cmp     al,4
        je      not_dword
        cmp     al,6
        je      not_pword
        cmp     al,8
        je      not_qword
        not     dword [edi]
        not     dword [edi+4]
        not     byte [edi+13]
        add     edi,14h
        jmp     calculation_loop
      not_qword:
        not     dword [edi]
        not     dword [edi+4]
      finish_not:
        mov     byte [edi+13],0
        add     edi,14h
        jmp     calculation_loop
      not_byte:
        cmp     dword [edi+4],0
        jne     not_qword
        cmp     word [edi+2],0
        jne     not_qword
        cmp     byte [edi+1],0
        jne     not_qword
        not     byte [edi]
        jmp     finish_not
      not_word:
        cmp     dword [edi+4],0
        jne     not_qword
        cmp     word [edi+2],0
        jne     not_qword
        not     word [edi]
        jmp     finish_not
      not_dword:
        cmp     dword [edi+4],0
        jne     not_qword
        not     dword [edi]
        jmp     finish_not
      not_pword:
        cmp     word [edi+6],0
        jne     not_qword
        not     word [edi+4]
        not     dword [edi]
        jmp     finish_not
      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],8+1
        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_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:
        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
        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
        jnz     invalid_value
      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
        ja      value_out_of_range
        cmp     cx,32
        jbe     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
      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
        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
      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
        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
      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
        mov     [size_override],-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,-80h
        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
        mov     [size_override],-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,-8000h
        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
        mov     [size_override],-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
        shr     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
        bt      eax,31
        jnc     range_exceeded
        ret
      dword_positive:
        test    edx,edx
        jne     range_exceeded
        ret
get_pword_value:
        mov     [value_size],6
        mov     [size_override],-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,-8000h
        jb      range_exceeded
        ret
      pword_positive:
        cmp     edx,10000h
        jae     range_exceeded
        ret
get_qword_value:
        mov     [value_size],8
        mov     [size_override],-1
        call    calculate_value
      check_qword_value:
        mov     eax,[edi]
        mov     edx,[edi+4]
        cmp     byte [edi+13],0
        je      qword_positive
        cmp     edx,-80000000h
        jb      range_exceeded
      qword_positive:
        ret
get_count_value:
        mov     [value_size],8
        mov     [size_override],-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
        jmp     calculate_address
get_address_dword_value:
        mov     [address_size],4
        mov     [value_size],4
        jmp     calculate_address
get_address_qword_value:
        mov     [address_size],8
        mov     [value_size],8
        jmp     calculate_address
get_address_value:
        mov     [address_size],0
        mov     [value_size],8
      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,6
        je      special_address_type_32bit
        cmp     al,5
        je      special_address_type_32bit
        ja      invalid_use_of_symbol
        test    al,1
        jnz     invalid_use_of_symbol
        or      al,al
        jz      address_size_ok
        shl     al,5
        jmp     address_symbol_ok
      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:
        mov     [value_type],2
        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
        cmp     ah,0Ch
        je      check_vsib_address
        cmp     ah,0Dh
        je      check_vsib_address
        cmp     al,0Ch
        je      check_vsib_address
        cmp     al,0Dh
        je      check_vsib_address
        or      bh,bh
        jz      check_address_registers
        or      bl,bl
        jz      check_address_registers
        cmp     al,ah
        jne     invalid_address
      check_address_registers:
        or      al,ah
        mov     ah,[address_size]
        and     ah,0Fh
        jz      address_registers_sizes_ok
        cmp     al,ah
        jne     address_sizes_do_not_match
      address_registers_sizes_ok:
        cmp     al,4
        je      sib_allowed
        cmp     al,8
        je      sib_allowed
        cmp     al,0Fh
        je      check_ip_relative_address
        or      cl,cl
        jz      check_word_value
        cmp     cl,1
        je      check_word_value
        jmp     invalid_address
      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,0F4h
        je      check_dword_value
        cmp     bh,0F8h
        jne     invalid_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:
        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_address:
        cmp     ah,0Ch
        je      swap_vsib_registers
        cmp     ah,0Dh
        jne     check_vsib_base
      swap_vsib_registers:
        cmp     cl,1
        ja      invalid_address
        xchg    bl,bh
        mov     cl,1
      check_vsib_base:
        test    bh,bh
        jz      vsib_base_ok
        mov     al,bh
        shr     al,4
        cmp     al,4
        je      vsib_base_ok
        cmp     [code_type],64
        jne     invalid_address
        cmp     al,8
        jne     invalid_address
      vsib_base_ok:
        mov     al,bl
        shr     al,4
        cmp     al,0Ch
        je      check_index_scale
        cmp     al,0Dh
        je      check_index_scale
        jmp     invalid_address

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
        mov     [size_override],-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,'{'
        je      logical_expression
        cmp     al,0FFh
        je      invalid_expression
        cmp     al,88h
        je      check_for_defined
        cmp     al,89h
        je      check_for_used
        cmp     al,'0'
        je      given_false
        cmp     al,'1'
        je      given_true
        call    get_value_for_comparison
        mov     bh,[value_sign]
        push    eax edx [symbol_identifier] ebx ecx
        mov     al,[esi]
        or      al,al
        jz      logical_number
        cmp     al,0Fh
        je      logical_number
        cmp     al,'}'
        je      logical_number
        cmp     al,'&'
        je      logical_number
        cmp     al,'|'
        je      logical_number
        inc     esi
        mov     [compare_type],al
        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_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
        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    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,'}'
        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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/fasm/EXPRPARS.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266

; flat assembler core
; Copyright (c) 1999-2012, 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-10h]
        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,100h
        jc      stack_overflow
        cmp     eax,[stack_limit]
        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,')'
        jne     invalid_expression
        ret
      symbol_value:
        cmp     [source_start],0
        je      preprocessor_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
        cmp     ah,8
        je      register_value
        cmp     ah,0Ch
        je      register_value
        cmp     ah,0Dh
        je      register_value
        cmp     ah,0Fh
        je      register_value
        cmp     ah,2
        jne     no_address_register
        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
        cmp     [hash_tree],0
        je      invalid_value
        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
        push    esi
        mov     esi,[edx+8]
        push    [current_offset]
        call    convert_expression
        pop     [current_offset]
        pop     esi
        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,'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
        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
        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
        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
        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,'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
        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
        lods    byte [esi]
        cmp     al,1Ah
        je      fp_value_start
        cmp     al,'-'
        je      fp_sign_ok
        cmp     al,'+'
        jne     not_fp_value
      fp_sign_ok:
        lods    byte [esi]
        cmp     al,1Ah
        jne     not_fp_value
      fp_value_start:
        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
        lods    byte [esi]
        mov     [fp_sign],0
        cmp     al,1Ah
        je      fp_get
        inc     esi
        cmp     al,'+'
        je      fp_get
        mov     [fp_sign],1
      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,'}'
        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,'{'
        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,'}'
        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,'{'
        je      skip_logical_value_internal_parenthesis
        cmp     al,'}'
        jne     skip_logical_value_symbol
        sub     [logical_value_parentheses],1
        jnc     skip_logical_value_symbol
        cmp     [logical_value_wrapping],'{'
        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],'{'
        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],'}'
        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,'{'
        je      logical_value_internal_parentheses
        cmp     al,'}'
        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],'{'
        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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/fasm/FORMATS.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108

; flat assembler core
; Copyright (c) 1999-2012, 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]
      copy_output_path:
        lods    byte [esi]
        cmp     edi,[structures_buffer]
        jae     out_of_memory
        stos    byte [edi]
        or      al,al
        jnz     copy_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
        cmp     [symbols_file],0
        je      public_reference_ok
        cmp     [next_pass_needed],0
        jne     public_reference_ok
        mov     ebx,eax
        call    store_label_reference
        mov     eax,ebx
      public_reference_ok:
        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     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     [number_of_relocations]
        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     [label_size],0
        xor     edx,edx
        xor     ebp,ebp
        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
        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,[edx+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     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
        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
      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
        jmp     read_resource_headers
      resource_headers_ok:
        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
        cmp     word [esi],1D19h
        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
        cmp     word [esi],1D19h
        jne     elf_header_ok
        jmp     format_elf64_exe
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:
        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:
        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]
        test    [format_flags],8
        jnz     finish_elf64_header
        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:
        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
        mov     ecx,10
        rep     stos dword [edi]
        test    [format_flags],8
        jz      elf_null_section_ok
        mov     ecx,6
        rep     stos dword [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
        stos    dword [edi]
        stos    dword [edi]
      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+10h],2
        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     eax,edi
        xor     ebp,ebp
        xor     cl,cl
        sub     eax,[code_start]
        sbb     ebp,0
        sbb     cl,0
        mov     [ebx+4],eax
        add     eax,[image_base]
        adc     ebp,0
        adc     cl,0
        mov     [ebx+8],eax
        mov     [ebx+0Ch],eax
        mov     [edx+18h],eax
        not     eax
        not     ebp
        not     cl
        add     eax,1
        adc     ebp,0
        adc     cl,0
        add     eax,edi
        adc     ebp,0
        adc     cl,0
      elf_exe_addressing_setup:
        push    eax
        call    init_addressing_space
        pop     eax
        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+10h],2
        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
        push    edx
        mov     eax,edi
        sub     eax,[code_start]
        mov     [ebx+8],eax
        xor     edx,edx
        xor     cl,cl
        add     eax,[image_base]
        adc     edx,[image_base_high]
        adc     cl,0
        mov     [ebx+10h],eax
        mov     [ebx+10h+4],edx
        mov     [ebx+18h],eax
        mov     [ebx+18h+4],edx
        pop     ebx
        mov     [ebx+18h],eax
        mov     [ebx+18h+4],edx
        not     eax
        not     edx
        not     cl
        add     eax,1
        adc     edx,0
        adc     cl,0
        add     eax,edi
        adc     edx,0
        adc     cl,0
        jmp     elf_exe_addressing_setup
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
        cmp     [value_type],0
        jne     invalid_use_of_symbol
        mov     edx,[code_start]
        mov     [edx+18h],eax
        jmp     instruction_assembled
      elf64_entry:
        call    get_qword_value
        cmp     [value_type],0
        jne     invalid_use_of_symbol
        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
        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
        push    edi
        mov     edi,ebx
        mov     ecx,20h shr 2
        xor     eax,eax
        rep     stos dword [edi]
        pop     edi
        or      [next_pass_needed],-1
      new_elf_segment:
        mov     byte [ebx],1
        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
        jmp     elf_segment_flags
      elf_segment_flags_ok:
        mov     eax,edi
        sub     eax,[code_start]
        mov     [ebx+4],eax
        pop     edx
        and     eax,0FFFh
        add     edx,eax
        mov     [ebx+8],edx
        mov     [ebx+0Ch],edx
        mov     eax,edx
        xor     edx,edx
        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
      elf_segment_addressing_setup:
        mov     [ds:ebp],eax
        mov     [ds:ebp+4],edx
        mov     [ds:ebp+8],cl
        inc     [number_of_sections]
        jmp     instruction_assembled
      close_elf_segment:
        cmp     [number_of_sections],0
        jne     finish_elf_segment
        cmp     edi,[symbols_stream]
        jne     first_elf_segment_ok
        push    edi
        mov     edi,[code_start]
        add     edi,34h
        mov     ecx,20h shr 2
        xor     eax,eax
        rep     stos dword [edi]
        pop     edi
        mov     eax,[image_base]
        ret
      first_elf_segment_ok:
        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
        mov     edi,[undefined_data_start]
      elf_segment_size_ok:
        mov     [ebx+14h],eax
        add     eax,edi
        sub     eax,edx
        mov     [ebx+10h],eax
        mov     eax,[ebx+8]
        cmp     byte [ebx],1
        jne     elf_segment_position_ok
        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
        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
        mov     ebx,[symbols_stream]
        sub     ebx,38h
        push    edi
        mov     edi,ebx
        mov     ecx,38h shr 2
        xor     eax,eax
        rep     stos dword [edi]
        pop     edi
        or      [next_pass_needed],-1
      new_elf64_segment:
        mov     byte [ebx],1
        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
        jmp     elf64_segment_flags
      elf64_segment_flags_ok:
        mov     ecx,edi
        sub     ecx,[code_start]
        mov     [ebx+8],ecx
        pop     edx eax
        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
        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
        jmp     elf_segment_addressing_setup
      close_elf64_segment:
        cmp     [number_of_sections],0
        jne     finish_elf64_segment
        cmp     edi,[symbols_stream]
        jne     first_elf64_segment_ok
        push    edi
        mov     edi,[code_start]
        add     edi,40h
        mov     ecx,38h shr 2
        xor     eax,eax
        rep     stos dword [edi]
        pop     edi
        mov     eax,[image_base]
        mov     edx,[image_base_high]
        ret
      first_elf64_segment_ok:
        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
        mov     edi,[undefined_data_start]
      elf64_segment_size_ok:
        mov     [ebx+28h],eax
        add     eax,edi
        sub     eax,edx
        mov     [ebx+20h],eax
        mov     eax,[ebx+10h]
        mov     edx,[ebx+10h+4]
        cmp     byte [ebx],1
        jne     elf64_segment_position_ok
        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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/fasm/LICENSE.TXT.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

flat assembler  version 1.70
Copyright (c) 1999-2012, 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).
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































Deleted source/fasm/MESSAGES.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

; flat assembler core
; Copyright (c) 1999-2012, 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
_unexpected_end_of_file db 'unexpected end of file',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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































Deleted source/fasm/PARSER.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422

; flat assembler core
; Copyright (c) 1999-2012, 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
        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
        cmp     al,3Bh
        je      skip_rest_of_line
        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,100h
        jc      stack_overflow
        cmp     eax,[stack_limit]
        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,100h
        jc      stack_overflow
        cmp     eax,[stack_limit]
        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      unallowed_character
        cmp     al,'}'
        je      unallowed_character
        cmp     al,'#'
        je      unallowed_character
        cmp     al,'`'
        je      unallowed_character
        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
      symbol_argument:
        pop     edi
        stos    word [edi]
        jmp     argument_parsed
      operator_argument:
        pop     edi
        cmp     al,85h
        je      ptr_argument
        stos    byte [edi]
        cmp     al,80h
        je      forced_multipart_expression
        cmp     al,8Ch
        je      forced_expression
        cmp     al,81h
        je      forced_parenthesis
        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
        jne     forced_multipart_expression
        jmp     argument_parsed
      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,100h
        jc      stack_overflow
        cmp     eax,[stack_limit]
        jb      stack_overflow
        push    esi edi
        inc     esi
        mov     al,'{'
        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
        dec     esi
        mov     al,')'
        stos    byte [edi]
        jmp     argument_parsed
      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,60h
        jne     unknown_segment_prefix
        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,'{'
        jmp     separator
      unallowed_character:
        mov     al,0FFh
        jmp     separator
      close_parenthesis:
        mov     al,'}'
      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,2
        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     [formatter_symbols_allowed],0
        je      no_symbol
      symbol_ok:
        pop     esi
        add     esi,ebp
        clc
        ret
      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,16
        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,2
        ja      find_label
        inc     esi
        jb      get_current_offset_id
        inc     esi
        cmp     byte [esi-1],'$'
        je      get_org_origin_id
        sub     esi,ecx
        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_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     invalid_name
      name_first_char_ok:
        cmp     al,'$'
        jne     check_for_reserved_word
        cmp     ecx,1
        jne     invalid_name
      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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/fasm/PREPROCE.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567

; flat assembler core
; Copyright (c) 1999-2012, 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     esi,[input_file]
        mov     edx,esi
        call    open
        jc      main_file_not_found
        mov     edi,[memory_start]
        call    preprocess_file
        mov     eax,[error_line]
        mov     [current_line],eax
        cmp     [macro_status],0
        jne     incomplete_macro
        mov     [source_start],edi
        ret

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      missing_end_quote
        cmp     al,0Dh
        je      missing_end_quote
        or      al,al
        jz      missing_end_quote
        cmp     al,1Ah
        je      missing_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      unexpected_end_of_file
        or      al,al
        jz      unexpected_end_of_file
        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]
        jmp     group_backslashes
      backslashed_symbol:
        cmp     al,1Ah
        je      unexpected_end_of_file
        or      al,al
        jz      unexpected_end_of_file
        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      unexpected_end_of_file
        or      al,al
        jz      unexpected_end_of_file
        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     unexpected_end_of_file
      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_ok
      next_directive:
        mov     edi,ebx
        add     edi,2
        jmp     scan_directives
      no_directive:
        mov     esi,edx
        mov     ecx,ebp
        stc
        ret
      directive_ok:
        lea     esi,[edx+ebp]
        call    directive_handler
      directive_handler:
        pop     ecx
        movzx   eax,word [ebx]
        add     eax,ecx
        clc
        ret

preprocess_line:
        mov     eax,esp
        sub     eax,100h
        jc      stack_overflow
        cmp     eax,[stack_limit]
        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
        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:
        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:
        push    line_preprocessed
        jmp     replace_symbolic_constant
      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
        movzx   ecx,cl
        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
        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
        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,'*'
        jne     macro_argument_end
        lods    byte [esi]
      macro_argument_end:
        cmp     al,','
        je      skip_macro_arguments
        cmp     al,']'
        jne     end_macro_arguments
        lods    byte [esi]
        not     ebp
      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      [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     [default_argument_value],0
        je      invalid_macro_arguments
        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     [default_argument_value],0
        je      simple_argument
        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
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
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
        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:
        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
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
        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
        xchg    esi,ebx
        mov     [edx+12],esi
        mov     [default_argument_value],0
        call    skip_macro_argument_value
        call    finish_macro_argument
        xchg    esi,ebx
        cmp     byte [esi],'='
        je      argument_with_default_value
        cmp     byte [esi],'*'
        jne     macro_argument_ok
        cmp     dword [edx+8],0
        je      invalid_macro_arguments
        inc     esi
      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
      argument_with_default_value:
        inc     esi
        push    esi
        or      [default_argument_value],-1
        call    skip_macro_argument_value
        pop     eax
        cmp     dword [edx+8],0
        jne     macro_argument_ok
        mov     [edx+12],eax
        call    finish_macro_argument
        jmp     macro_argument_ok
      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 [current_line] 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,'*'
        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      [default_argument_value],-1
        call    skip_macro_argument_value
        inc     esi
      irps_name_ok:
        cmp     al,','
        jne     invalid_macro_arguments
        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
        mov     ebx,esi
        cmp     [base_code],1
        ja      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
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,[macro_line]
        add     eax,16+1
        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     [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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/fasm/SYMBDUMP.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450

; flat assembler core
; Copyright (c) 1999-2012, 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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/fasm/TABLES.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412

; flat assembler core
; Copyright (c) 1999-2012, 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 5,'macro'
 dw define_macro-directive_handler
 db 5,'match'
 dw match_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

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,'not',0D0h
 db 3,'plt',0E1h
 db 3,'rva',0E0h
 db 0

directive_operators:
 db 5,'align',8Ch
 db 2,'as',86h
 db 2,'at',80h
 db 7,'defined',88h
 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_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_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,62h
 db 'cx',10h,21h
 db 'dh',10h,06h
 db 'di',10h,27h
 db 'dl',10h,12h
 db 'ds',10h,64h
 db 'dx',10h,22h
 db 'es',10h,61h
 db 'fs',10h,65h
 db 'gs',10h,66h
 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 'si',10h,26h
 db 'sp',10h,24h
 db 'ss',10h,63h
 db 'st',10h,0A0h
symbols_3:
 db 'bpl',10h,15h
 db 'cr0',10h,50h
 db 'cr1',10h,51h
 db 'cr2',10h,52h
 db 'cr3',10h,53h
 db 'cr4',10h,54h
 db 'cr5',10h,55h
 db 'cr6',10h,56h
 db 'cr7',10h,57h
 db 'cr8',10h,58h
 db 'cr9',10h,59h
 db 'dil',10h,17h
 db 'dll',1Bh,80h
 db 'dr0',10h,70h
 db 'dr1',10h,71h
 db 'dr2',10h,72h
 db 'dr3',10h,73h
 db 'dr4',10h,74h
 db 'dr5',10h,75h
 db 'dr6',10h,76h
 db 'dr7',10h,77h
 db 'dr8',10h,78h
 db 'dr9',10h,79h
 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,0F4h
 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,0F8h
 db 'rsi',10h,86h
 db 'rsp',10h,84h
 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',10h,90h
 db 'tr1',10h,91h
 db 'tr2',10h,92h
 db 'tr3',10h,93h
 db 'tr4',10h,94h
 db 'tr5',10h,95h
 db 'tr6',10h,96h
 db 'tr7',10h,97h
 db 'wdm',1Bh,81h
symbols_4:
 db 'byte',11h,1
 db 'code',19h,5
 db 'coff',18h,40h
 db 'cr10',10h,5Ah
 db 'cr11',10h,5Bh
 db 'cr12',10h,5Ch
 db 'cr13',10h,5Dh
 db 'cr14',10h,5Eh
 db 'cr15',10h,5Fh
 db 'data',19h,6
 db 'dr10',10h,7Ah
 db 'dr11',10h,7Bh
 db 'dr12',10h,7Ch
 db 'dr13',10h,7Dh
 db 'dr14',10h,7Eh
 db 'dr15',10h,7Fh
 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,0D0h
 db 'ymm1',10h,0D1h
 db 'ymm2',10h,0D2h
 db 'ymm3',10h,0D3h
 db 'ymm4',10h,0D4h
 db 'ymm5',10h,0D5h
 db 'ymm6',10h,0D6h
 db 'ymm7',10h,0D7h
 db 'ymm8',10h,0D8h
 db 'ymm9',10h,0D9h
symbols_5:
 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 'xword',11h,16
 db 'ymm10',10h,0DAh
 db 'ymm11',10h,0DBh
 db 'ymm12',10h,0DCh
 db 'ymm13',10h,0DDh
 db 'ymm14',10h,0DEh
 db 'ymm15',10h,0DFh
 db 'yword',11h,32
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 'dynamic',1Eh,2
 db 'efiboot',1Bh,11
symbols_8:
 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 '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_end-instructions_16)/(16+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 '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 '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_vmx_instruction-instruction_handler
 db 'clgi',0DDh
 dw simple_vmx_instruction-instruction_handler
 db 'clts',6
 dw simple_extended_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_3a_imm8-instruction_handler
 db 'dpps',40h
 dw sse4_instruction_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 '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_vmx_instruction-instruction_handler
 db 'stgi',0DCh
 dw simple_vmx_instruction-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-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_vmx_instruction-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 '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 '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_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 'rdpmc',33h
 dw simple_extended_instruction-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 ret_instruction_32bit-instruction_handler
 db 'retfq',0CAh
 dw ret_instruction_64bit-instruction_handler
 db 'retfw',0CAh
 dw ret_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-instruction_handler
 db 'vdpps',40h
 dw avx_instruction_3a_imm8-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-instruction_handler
 db 'vpxor',0EFh
 dw avx_pd_instruction-instruction_handler
 db 'while',0
 dw while_directive-instruction_handler
 db 'wrmsr',30h
 dw simple_extended_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_vmx_instruction-instruction_handler
instructions_6:
 db 'aesdec',0DEh
 dw sse4_instruction_38-instruction_handler
 db 'aesenc',0DCh
 dw sse4_instruction_38-instruction_handler
 db 'aesimc',0DBh
 dw sse4_instruction_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 '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 '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 '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_38-instruction_handler
 db 'pmaxsd',3Dh
 dw sse4_instruction_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_38-instruction_handler
 db 'pmaxuw',3Eh
 dw sse4_instruction_38-instruction_handler
 db 'pminsb',38h
 dw sse4_instruction_38-instruction_handler
 db 'pminsd',39h
 dw sse4_instruction_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_38-instruction_handler
 db 'pminuw',3Ah
 dw sse4_instruction_38-instruction_handler
 db 'pmuldq',28h
 dw sse4_instruction_38-instruction_handler
 db 'pmulhw',0E5h
 dw basic_mmx_instruction-instruction_handler
 db 'pmulld',40h
 dw sse4_instruction_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 '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 'rdrand',110b
 dw rdrand_instruction-instruction_handler
 db 'rdseed',111b
 dw rdrand_instruction-instruction_handler
 db 'rdtscp',1
 dw rdtscp_instruction-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',0
 dw swapgs_instruction-instruction_handler
 db 'sysret',07h
 dw simple_extended_instruction-instruction_handler
 db 't1mskc',17h
 dw tbm_instruction-instruction_handler
 db 'vaddpd',58h
 dw avx_pd_instruction-instruction_handler
 db 'vaddps',58h
 dw avx_ps_instruction-instruction_handler
 db 'vaddsd',58h
 dw avx_sd_instruction-instruction_handler
 db 'vaddss',58h
 dw avx_ss_instruction-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-instruction_handler
 db 'vdivps',5Eh
 dw avx_ps_instruction-instruction_handler
 db 'vdivsd',5Eh
 dw avx_sd_instruction-instruction_handler
 db 'vdivss',5Eh
 dw avx_ss_instruction-instruction_handler
 db 'vlddqu',0F0h
 dw avx_lddqu_instruction-instruction_handler
 db 'vmaxpd',5Fh
 dw avx_pd_instruction-instruction_handler
 db 'vmaxps',5Fh
 dw avx_ps_instruction-instruction_handler
 db 'vmaxsd',5Fh
 dw avx_sd_instruction-instruction_handler
 db 'vmaxss',5Fh
 dw avx_ss_instruction-instruction_handler
 db 'vmcall',0C1h
 dw simple_vmx_instruction-instruction_handler
 db 'vminpd',5Dh
 dw avx_pd_instruction-instruction_handler
 db 'vminps',5Dh
 dw avx_ps_instruction-instruction_handler
 db 'vminsd',5Dh
 dw avx_sd_instruction-instruction_handler
 db 'vminss',5Dh
 dw avx_ss_instruction-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-instruction_handler
 db 'vmulps',59h
 dw avx_ps_instruction-instruction_handler
 db 'vmulsd',59h
 dw avx_sd_instruction-instruction_handler
 db 'vmulss',59h
 dw avx_ss_instruction-instruction_handler
 db 'vmxoff',0C4h
 dw simple_vmx_instruction-instruction_handler
 db 'vpabsb',1Ch
 dw avx_single_source_instruction_38-instruction_handler
 db 'vpabsd',1Eh
 dw avx_single_source_instruction_38-instruction_handler
 db 'vpabsw',1Dh
 dw avx_single_source_instruction_38-instruction_handler
 db 'vpaddb',0FCh
 dw avx_pd_instruction-instruction_handler
 db 'vpaddd',0FEh
 dw avx_pd_instruction-instruction_handler
 db 'vpaddq',0D4h
 dw avx_pd_instruction-instruction_handler
 db 'vpaddw',0FDh
 dw avx_pd_instruction-instruction_handler
 db 'vpandn',0DFh
 dw avx_pd_instruction-instruction_handler
 db 'vpavgb',0E0h
 dw avx_pd_instruction-instruction_handler
 db 'vpavgw',0E3h
 dw avx_pd_instruction-instruction_handler
 db 'vpcmov',0A2h
 dw vpcmov_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 'vpermd',36h
 dw avx_permd_instruction-instruction_handler
 db 'vpermq',0
 dw avx_permq_instruction-instruction_handler
 db 'vpperm',0A3h
 dw xop_128bit_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_bit_shift_instruction-instruction_handler
 db 'vpsllq',0F3h
 dw avx_bit_shift_instruction-instruction_handler
 db 'vpsllw',0F1h
 dw avx_bit_shift_instruction-instruction_handler
 db 'vpsrad',0E2h
 dw avx_bit_shift_instruction-instruction_handler
 db 'vpsraw',0E1h
 dw avx_bit_shift_instruction-instruction_handler
 db 'vpsrld',0D2h
 dw avx_bit_shift_instruction-instruction_handler
 db 'vpsrlq',0D3h
 dw avx_bit_shift_instruction-instruction_handler
 db 'vpsrlw',0D1h
 dw avx_bit_shift_instruction-instruction_handler
 db 'vpsubb',0F8h
 dw avx_pd_instruction-instruction_handler
 db 'vpsubd',0FAh
 dw avx_pd_instruction-instruction_handler
 db 'vpsubq',0FBh
 dw avx_pd_instruction-instruction_handler
 db 'vpsubw',0F9h
 dw avx_pd_instruction-instruction_handler
 db 'vptest',17h
 dw avx_single_source_instruction_38-instruction_handler
 db 'vrcpps',53h
 dw avx_single_source_ps_instruction-instruction_handler
 db 'vrcpss',53h
 dw avx_ss_instruction-instruction_handler
 db 'vsubpd',5Ch
 dw avx_pd_instruction-instruction_handler
 db 'vsubps',5Ch
 dw avx_ps_instruction-instruction_handler
 db 'vsubsd',5Ch
 dw avx_sd_instruction-instruction_handler
 db 'vsubss',5Ch
 dw avx_ss_instruction-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 'xabort',0
 dw xabort_instruction-instruction_handler
 db 'xbegin',0
 dw xbegin_instruction-instruction_handler
 db 'xgetbv',0D0h
 dw simple_vmx_instruction-instruction_handler
 db 'xrstor',101b
 dw fxsave_instruction-instruction_handler
 db 'xsetbv',0D1h
 dw simple_vmx_instruction-instruction_handler
instructions_7:
 db 'blcfill',11h
 dw tbm_instruction-instruction_handler
 db 'blendpd',0Dh
 dw sse4_instruction_3a_imm8-instruction_handler
 db 'blendps',0Ch
 dw sse4_instruction_3a_imm8-instruction_handler
 db 'blsfill',12h
 dw tbm_instruction-instruction_handler
 db 'clflush',111b
 dw fxsave_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 '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 'insertq',0
 dw insertq_instruction-instruction_handler
 db 'invlpga',0DFh
 dw invlpga_instruction-instruction_handler
 db 'invpcid',82h
 dw vmx_inv_instruction-instruction_handler
 db 'invvpid',81h
 dw vmx_inv_instruction-instruction_handler
 db 'ldmxcsr',10b
 dw fxsave_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 'monitor',0C8h
 dw monitor_instruction-instruction_handler
 db 'movddup',12h
 dw sse_sd_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_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_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_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_38-instruction_handler
 db 'pcmpgtw',65h
 dw basic_mmx_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 'roundpd',9
 dw sse4_instruction_3a_imm8-instruction_handler
 db 'roundps',8
 dw sse4_instruction_3a_imm8-instruction_handler
 db 'roundsd',0Bh
 dw sse4_sd_instruction_3a_imm8-instruction_handler
 db 'roundss',0Ah
 dw sse4_ss_instruction_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 fxsave_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 'ucomisd',2Eh
 dw comisd_instruction-instruction_handler
 db 'ucomiss',2Eh
 dw comiss_instruction-instruction_handler
 db 'vaesdec',0DEh
 dw avx_128bit_instruction_38-instruction_handler
 db 'vaesenc',0DCh
 dw avx_128bit_instruction_38-instruction_handler
 db 'vaesimc',0DBh
 dw avx_single_source_128bit_instruction_38-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 '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-instruction_handler
 db 'vhaddps',07Ch
 dw avx_haddps_instruction-instruction_handler
 db 'vhsubpd',07Dh
 dw avx_pd_instruction-instruction_handler
 db 'vhsubps',07Dh
 dw avx_haddps_instruction-instruction_handler
 db 'virtual',0
 dw virtual_directive-instruction_handler
 db 'vmclear',6
 dw vmclear_instruction-instruction_handler
 db 'vmmcall',0D9h
 dw simple_vmx_instruction-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_movpd_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_pd_instruction-instruction_handler
 db 'vpaddsw',0EDh
 dw avx_pd_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_pextrb_instruction-instruction_handler
 db 'vpextrd',16h
 dw avx_pextrd_instruction-instruction_handler
 db 'vpextrq',16h
 dw avx_pextrq_instruction-instruction_handler
 db 'vpextrw',15h
 dw avx_pextrw_instruction-instruction_handler
 db 'vphaddd',2
 dw avx_instruction_38-instruction_handler
 db 'vphaddw',1
 dw avx_instruction_38-instruction_handler
 db 'vphsubd',6
 dw avx_instruction_38-instruction_handler
 db 'vphsubw',5
 dw avx_instruction_38-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_instruction_38-instruction_handler
 db 'vpmaxsd',3Dh
 dw avx_instruction_38-instruction_handler
 db 'vpmaxsw',0EEh
 dw avx_pd_instruction-instruction_handler
 db 'vpmaxub',0DEh
 dw avx_pd_instruction-instruction_handler
 db 'vpmaxud',3Fh
 dw avx_instruction_38-instruction_handler
 db 'vpmaxuw',3Eh
 dw avx_instruction_38-instruction_handler
 db 'vpminsb',38h
 dw avx_instruction_38-instruction_handler
 db 'vpminsd',39h
 dw avx_instruction_38-instruction_handler
 db 'vpminsw',0EAh
 dw avx_pd_instruction-instruction_handler
 db 'vpminub',0DAh
 dw avx_pd_instruction-instruction_handler
 db 'vpminud',3Bh
 dw avx_instruction_38-instruction_handler
 db 'vpminuw',3Ah
 dw avx_instruction_38-instruction_handler
 db 'vpmuldq',28h
 dw avx_instruction_38-instruction_handler
 db 'vpmulhw',0E5h
 dw avx_pd_instruction-instruction_handler
 db 'vpmulld',40h
 dw avx_instruction_38-instruction_handler
 db 'vpmullw',0D5h
 dw avx_pd_instruction-instruction_handler
 db 'vpsadbw',0F6h
 dw avx_pd_instruction-instruction_handler
 db 'vpshufb',0
 dw avx_instruction_38-instruction_handler
 db 'vpshufd',66h
 dw avx_pshufd_instruction-instruction_handler
 db 'vpsignb',8
 dw avx_instruction_38-instruction_handler
 db 'vpsignd',0Ah
 dw avx_instruction_38-instruction_handler
 db 'vpsignw',9
 dw avx_instruction_38-instruction_handler
 db 'vpslldq',111b
 dw avx_pslldq_instruction-instruction_handler
 db 'vpsllvd',47h
 dw avx_instruction_38-instruction_handler
 db 'vpsllvq',47h
 dw avx_instruction_38_w1-instruction_handler
 db 'vpsravd',46h
 dw avx_instruction_38-instruction_handler
 db 'vpsrldq',011b
 dw avx_pslldq_instruction-instruction_handler
 db 'vpsrlvd',45h
 dw avx_instruction_38-instruction_handler
 db 'vpsrlvq',45h
 dw avx_instruction_38_w1-instruction_handler
 db 'vpsubsb',0E8h
 dw avx_pd_instruction-instruction_handler
 db 'vpsubsw',0E9h
 dw avx_pd_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-instruction_handler
 db 'vsqrtps',51h
 dw avx_single_source_ps_instruction-instruction_handler
 db 'vsqrtsd',51h
 dw avx_sd_instruction-instruction_handler
 db 'vsqrtss',51h
 dw avx_ss_instruction-instruction_handler
 db 'vtestpd',0Fh
 dw avx_single_source_instruction_38-instruction_handler
 db 'vtestps',0Eh
 dw avx_single_source_instruction_38-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_38_xmm0-instruction_handler
 db 'blendvps',14h
 dw sse4_instruction_38_xmm0-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',0
 dw insertps_instruction-instruction_handler
 db 'maskmovq',0
 dw maskmovq_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_38-instruction_handler
 db 'packuswb',67h
 dw basic_mmx_instruction-instruction_handler
 db 'pblendvb',10h
 dw sse4_instruction_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 'sysenter',34h
 dw simple_extended_instruction-instruction_handler
 db 'sysexitq',35h
 dw simple_extended_instruction_64bit-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_instruction_3a_imm8-instruction_handler
 db 'vblendps',0Ch
 dw avx_instruction_3a_imm8-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 vldmxcsr_instruction-instruction_handler
 db 'vmlaunch',0C2h
 dw simple_vmx_instruction-instruction_handler
 db 'vmovddup',12h
 dw avx_movddup_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_movntpd_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_instruction_3a_imm8-instruction_handler
 db 'vmresume',0C3h
 dw simple_vmx_instruction-instruction_handler
 db 'vpaddusb',0DCh
 dw avx_pd_instruction-instruction_handler
 db 'vpaddusw',0DDh
 dw avx_pd_instruction-instruction_handler
 db 'vpalignr',0Fh
 dw avx_instruction_3a_imm8-instruction_handler
 db 'vpblendd',2
 dw avx_instruction_3a_imm8-instruction_handler
 db 'vpblendw',0Eh
 dw avx_instruction_3a_imm8-instruction_handler
 db 'vpcmpeqb',74h
 dw avx_pd_instruction-instruction_handler
 db 'vpcmpeqd',76h
 dw avx_pd_instruction-instruction_handler
 db 'vpcmpeqq',29h
 dw avx_instruction_38-instruction_handler
 db 'vpcmpeqw',75h
 dw avx_pd_instruction-instruction_handler
 db 'vpcmpgtb',64h
 dw avx_pd_instruction-instruction_handler
 db 'vpcmpgtd',66h
 dw avx_pd_instruction-instruction_handler
 db 'vpcmpgtq',37h
 dw avx_instruction_38-instruction_handler
 db 'vpcmpgtw',65h
 dw avx_pd_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 '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_instruction_38-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_instruction_38-instruction_handler
 db 'vphsubwd',0E2h
 dw xop_single_source_128bit_instruction-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_pd_instruction-instruction_handler
 db 'vpmulhuw',0E4h
 dw avx_pd_instruction-instruction_handler
 db 'vpmuludq',0F4h
 dw avx_pd_instruction-instruction_handler
 db 'vpshufhw',0F3h
 dw avx_pshufd_instruction-instruction_handler
 db 'vpshuflw',0F2h
 dw avx_pshufd_instruction-instruction_handler
 db 'vpsubusb',0D8h
 dw avx_pd_instruction-instruction_handler
 db 'vpsubusw',0D9h
 dw avx_pd_instruction-instruction_handler
 db 'vroundpd',9
 dw avx_single_source_instruction_3a_imm8-instruction_handler
 db 'vroundps',8
 dw avx_single_source_instruction_3a_imm8-instruction_handler
 db 'vroundsd',0Bh
 dw avx_sd_instruction_3a_imm8-instruction_handler
 db 'vroundss',0Ah
 dw avx_ss_instruction_3a_imm8-instruction_handler
 db 'vrsqrtps',52h
 dw avx_single_source_ps_instruction-instruction_handler
 db 'vrsqrtss',52h
 dw avx_ss_instruction-instruction_handler
 db 'vstmxcsr',11b
 dw vldmxcsr_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 '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 'xsaveopt',110b
 dw fxsave_instruction-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',0
 dw extractps_instruction-instruction_handler
 db 'fxrstor64',1
 dw fxsave_instruction_64bit-instruction_handler
 db 'pclmulqdq',-1
 dw pclmulqdq_instruction-instruction_handler
 db 'pcmpestri',61h
 dw sse4_instruction_3a_imm8-instruction_handler
 db 'pcmpestrm',60h
 dw sse4_instruction_3a_imm8-instruction_handler
 db 'pcmpistri',63h
 dw sse4_instruction_3a_imm8-instruction_handler
 db 'pcmpistrm',62h
 dw sse4_instruction_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 'vaddsubpd',0D0h
 dw avx_pd_instruction-instruction_handler
 db 'vaddsubps',0D0h
 dw avx_haddps_instruction-instruction_handler
 db 'vblendvpd',4Bh
 dw avx_triple_source_instruction_3a-instruction_handler
 db 'vblendvps',4Ah
 dw avx_triple_source_instruction_3a-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-instruction_handler
 db 'vcvtpd2dq',0E6h
 dw avx_cvtpd2dq_instruction-instruction_handler
 db 'vcvtpd2ps',5Ah
 dw avx_cvtpd2ps_instruction-instruction_handler
 db 'vcvtph2ps',13h
 dw vcvtph2ps_instruction-instruction_handler
 db 'vcvtps2dq',5Bh
 dw avx_single_source_pd_instruction-instruction_handler
 db 'vcvtps2pd',5Ah
 dw avx_cvtps2pd_instruction-instruction_handler
 db 'vcvtps2ph',1Dh
 dw vcvtps2ph_instruction-instruction_handler
 db 'vcvtsd2si',2Dh
 dw avx_cvtsd2si_instruction-instruction_handler
 db 'vcvtsd2ss',5Ah
 dw avx_sd_instruction-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-instruction_handler
 db 'vcvtss2si',2Dh
 dw avx_cvtss2si_instruction-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 'vinsertps',0
 dw avx_insertps_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 'vpackssdw',6Bh
 dw avx_pd_instruction-instruction_handler
 db 'vpacksswb',63h
 dw avx_pd_instruction-instruction_handler
 db 'vpackusdw',2Bh
 dw avx_instruction_38-instruction_handler
 db 'vpackuswb',67h
 dw avx_pd_instruction-instruction_handler
 db 'vpblendvb',4Ch
 dw avx_triple_source_instruction_3a-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 'vpermilpd',5
 dw avx_permil_instruction-instruction_handler
 db 'vpermilps',4
 dw avx_permil_instruction-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_pmovsxdq_instruction-instruction_handler
 db 'vpmovsxwd',23h
 dw avx_pmovsxwd_instruction-instruction_handler
 db 'vpmovsxwq',24h
 dw avx_pmovsxwq_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_pmovsxdq_instruction-instruction_handler
 db 'vpmovzxwd',33h
 dw avx_pmovsxwd_instruction-instruction_handler
 db 'vpmovzxwq',34h
 dw avx_pmovsxwq_instruction-instruction_handler
 db 'vpmulhrsw',0Bh
 dw avx_instruction_38-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
instructions_10:
 db 'aesdeclast',0DFh
 dw sse4_instruction_38-instruction_handler
 db 'aesenclast',0DDh
 dw sse4_instruction_38-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_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 '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 'vcvttpd2dq',0E6h
 dw avx_cvtpd2ps_instruction-instruction_handler
 db 'vcvttps2dq',5Bh
 dw avx_cvttps2dq_instruction-instruction_handler
 db 'vcvttsd2si',2Ch
 dw avx_cvtsd2si_instruction-instruction_handler
 db 'vcvttss2si',2Ch
 dw avx_cvtss2si_instruction-instruction_handler
 db 'vextractps',0
 dw avx_extractps_instruction-instruction_handler
 db 'vgatherdpd',92h
 dw gather_instruction_pd-instruction_handler
 db 'vgatherdps',92h
 dw gather_instruction_ps-instruction_handler
 db 'vgatherqpd',93h
 dw gather_instruction_pd-instruction_handler
 db 'vgatherqps',93h
 dw gather_instruction_ps-instruction_handler
 db 'vmaskmovpd',2Dh
 dw avx_maskmov_instruction-instruction_handler
 db 'vmaskmovps',2Ch
 dw avx_maskmov_instruction-instruction_handler
 db 'vpclmulqdq',-1
 dw avx_pclmulqdq_instruction-instruction_handler
 db 'vpcmpestri',61h
 dw avx_single_source_128bit_instruction_3a_imm8-instruction_handler
 db 'vpcmpestrm',60h
 dw avx_single_source_128bit_instruction_3a_imm8-instruction_handler
 db 'vpcmpistri',63h
 dw avx_single_source_128bit_instruction_3a_imm8-instruction_handler
 db 'vpcmpistrm',62h
 dw avx_single_source_128bit_instruction_3a_imm8-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_instruction_ps-instruction_handler
 db 'vpgatherdq',90h
 dw gather_instruction_pd-instruction_handler
 db 'vpgatherqd',91h
 dw gather_instruction_ps-instruction_handler
 db 'vpgatherqq',91h
 dw gather_instruction_pd-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_instruction_38-instruction_handler
 db 'vpmaskmovd',8Ch
 dw avx_maskmov_instruction-instruction_handler
 db 'vpmaskmovq',8Ch
 dw avx_maskmov_w1_instruction-instruction_handler
 db 'vpunpckhbw',68h
 dw avx_pd_instruction-instruction_handler
 db 'vpunpckhdq',6Ah
 dw avx_pd_instruction-instruction_handler
 db 'vpunpckhwd',69h
 dw avx_pd_instruction-instruction_handler
 db 'vpunpcklbw',60h
 dw avx_pd_instruction-instruction_handler
 db 'vpunpckldq',62h
 dw avx_pd_instruction-instruction_handler
 db 'vpunpcklwd',61h
 dw avx_pd_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 'vaesdeclast',0DFh
 dw avx_128bit_instruction_38-instruction_handler
 db 'vaesenclast',0DDh
 dw avx_128bit_instruction_38-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 '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 '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 'vphminposuw',41h
 dw avx_single_source_instruction_38-instruction_handler
 db 'vpunpckhqdq',6Dh
 dw avx_pd_instruction-instruction_handler
 db 'vpunpcklqdq',6Ch
 dw avx_pd_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 '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
instructions_13:
 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 'vpclmulhqlqdq',1
 dw avx_pclmulqdq_instruction-instruction_handler
 db 'vpclmullqlqdq',0
 dw avx_pclmulqdq_instruction-instruction_handler
instructions_14:
 db 'vbroadcastf128',1Ah
 dw avx_broadcastf128_instruction-instruction_handler
 db 'vbroadcasti128',5Ah
 dw avx_broadcastf128_instruction-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
instructions_15:
 db 'aeskeygenassist',0DFh
 dw sse4_instruction_3a_imm8-instruction_handler
instructions_16:
 db 'vaeskeygenassist',0DFh
 dw avx_single_source_128bit_instruction_3a_imm8-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:
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/fasm/VARIABLE.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

; flat assembler core variables
; Copyright (c) 1999-2012, 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 ?

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 ?
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 ?
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 ?
resource_data dd ?
resource_size dd ?
actual_fixups_size dd ?
reserved_fixups dd ?
reserved_fixups_size dd ?
last_fixup_base dd ?
parenthesis_stack dd ?
blocks_stack dd ?
parsed_lines dd ?
logical_value_parentheses dd ?
file_extension dd ?

operand_size db ?
size_override db ?
operand_prefix db ?
opcode_prefix db ?
rex_prefix db ?
vex_required db ?
vex_register db ?
immediate_size 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 ?

value_undefined db ?
value_constant db ?
value_type db ?
value_sign db ?
fp_sign db ?
fp_format db ?
address_sign db ?
compare_type db ?
logical_value_wrapping db ?
next_pass_needed db ?
output_format db ?
code_type db ?
adjustment_sign db ?

macro_status db ?
default_argument_value db ?
prefixed_instruction db ?
formatter_symbols_allowed db ?

characters rb 100h
converted rb 100h
message rb 200h
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































Deleted source/fasm/VERSION.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

; flat assembler  version 1.71
; Copyright (c) 1999-2012, 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.71.03"

VERSION_MAJOR = 1
VERSION_MINOR = 71
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































Deleted source/fasm/WHATSNEW.TXT.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312

Visit http://flatassembler.net/ for more information.


version 1.71.03 (Sep 27, 2012)

[-] Fixed a bug in "org" directive introduced by recent changes, which
    was manifesting with bases larger than 31-bit.


version 1.71.02 (Sep 26, 2012)

[-] Expression calculator now allows to calculate the difference of
    relocatable addresses in a reverse order (first substracting/negating
    and then adding the other one).


version 1.71.01 (Sep 23, 2012)

[+] Added support for ADX, RDSEED and SMAP instruction sets.

[-] Fixed the bugs related to creating a new addressing space inside the
    virtual block with "org" directive.


version 1.71.00 (Sep 21, 2012)

[+] 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.


version 1.70.03 (Jun 29, 2012)

[-] Allowed to freely upgrade or downgrade the relocatable addresses in
    object format between the 32-bit or 64-bit size.


version 1.70.02 (May 22, 2012)

[-] Corrected the optimization of segment prefixes when the extended syntax
    of some string instructions ("cmps", "lods", "movs" and "outs") is
    used in long mode. Now it is consistent with optimizations done with
    all the other instructions.


version 1.70.01 (Apr 30, 2012)

[-] Corrected a recently introduced bug that caused some illegal
    address expressions to cause an error prematurely during the
    parsing stage.


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.
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































































































































































































































































































































































































































































































































































































































Deleted source/fasm/X86_64.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059

; flat assembler core
; Copyright (c) 1999-2012, 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
prefix_instruction:
        stos    byte [edi]
        or      [prefixed_instruction],-1
        jmp     continue_line
segment_prefix:
        mov     ah,al
        shr     ah,4
        cmp     ah,6
        jne     illegal_instruction
        and     al,1111b
        mov     [segment_register],al
        call    store_segment_prefix
        or      [prefixed_instruction],-1
        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
        jne     value_out_of_range
        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_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_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,'['
        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,60h
        jb      mov_mem_general_reg
        cmp     al,70h
        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
        mov     al,ah
        call    operand_autodetect
        mov     al,[postbyte_register]
        or      al,bl
        or      al,bh
        jz      mov_mem_ax
        inc     [base_code]
        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,88h
        jnz     mov_mem_address64_al
        or      ch,ch
        jnz     invalid_address_size
        cmp     [code_type],64
        je      mov_mem_address64_al
        cmp     [code_type],32
        je      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_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_instruction_code
        mov     eax,edx
        stos    word [edi]
        cmp     edx,10000h
        jge     value_out_of_range
        jmp     instruction_assembled
      mov_mem_address64_al:
        call    store_segment_prefix_if_necessary
        mov     [base_code],0A2h
      store_mov_address64:
        call    store_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,88h
        jnz     mov_mem_address64_ax
        or      ch,ch
        jnz     invalid_address_size
        cmp     [code_type],64
        je      mov_mem_address64_ax
        cmp     [code_type],32
        je      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,61h
        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_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_nosize:
        call    recoverable_unknown_size
      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,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,5
        je      mov_reg_creg
        cmp     ah,7
        je      mov_reg_dreg
        ja      mov_reg_treg
        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_treg:
        cmp     ah,9
        jne     invalid_operand
        mov     [extended_code],24h
        jmp     mov_reg_xrx
      mov_reg_dreg:
        mov     [extended_code],21h
        jmp     mov_reg_xrx
      mov_reg_creg:
        mov     [extended_code],20h
      mov_reg_xrx:
        mov     [base_code],0Fh
        cmp     [code_type],64
        je      mov_reg_xrx_64bit
        cmp     [operand_size],4
        jne     invalid_operand_size
        cmp     [postbyte_register],8
        jne     mov_reg_xrx_store
        cmp     [extended_code],20h
        jne     mov_reg_xrx_store
        mov     al,0F0h
        stos    byte [edi]
        mov     [postbyte_register],0
      mov_reg_xrx_store:
        jmp     nomem_instruction_ready
      mov_reg_xrx_64bit:
        cmp     [operand_size],8
        jne     invalid_operand_size
        jmp     nomem_instruction_ready
      mov_reg_mem:
        call    get_address
        mov     al,[operand_size]
        cmp     al,1
        je      mov_reg_mem_8bit
        call    operand_autodetect
        mov     al,[postbyte_register]
        or      al,bl
        or      al,bh
        jz      mov_ax_mem
        add     [base_code],3
        jmp     instruction_ready
      mov_reg_mem_8bit:
        mov     al,[postbyte_register]
        or      al,bl
        or      al,bh
        jz      mov_al_mem
        add     [base_code],2
        jmp     instruction_ready
      mov_al_mem:
        test    ch,22h
        jnz     mov_al_mem_address16
        test    ch,44h
        jnz     mov_al_mem_address32
        test    ch,88h
        jnz     mov_al_mem_address64
        or      ch,ch
        jnz     invalid_address_size
        cmp     [code_type],64
        je      mov_al_mem_address64
        cmp     [code_type],32
        je      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,88h
        jnz     mov_ax_mem_address64
        or      ch,ch
        jnz     invalid_address_size
        cmp     [code_type],64
        je      mov_ax_mem_address64
        cmp     [code_type],32
        je      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_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,5
        je      mov_creg
        cmp     ah,7
        je      mov_dreg
        ja      mov_treg
        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_treg:
        cmp     ah,9
        jne     invalid_operand
        mov     [extended_code],26h
        jmp     mov_xrx
      mov_dreg:
        mov     [extended_code],23h
        jmp     mov_xrx
      mov_creg:
        mov     [extended_code],22h
      mov_xrx:
        mov     [base_code],0Fh
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        lods    byte [esi]
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_register
        mov     bl,al
        cmp     [code_type],64
        je      mov_xrx_64bit
        cmp     ah,4
        jne     invalid_operand_size
        cmp     [postbyte_register],8
        jne     mov_xrx_store
        cmp     [extended_code],22h
        jne     mov_xrx_store
        mov     al,0F0h
        stos    byte [edi]
        mov     [postbyte_register],0
      mov_xrx_store:
        jmp     nomem_instruction_ready
      mov_xrx_64bit:
        cmp     ah,8
        je      mov_xrx_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_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_nosize:
        call    recoverable_unknown_size
      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_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_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_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_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_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,70h
        jae     invalid_operand
        sub     al,61h
        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_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_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_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     [size_override],0
        mov     [operand_prefix],0
        mov     [rex_prefix],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_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     [size_override],0
        mov     [operand_prefix],0
        mov     [rex_prefix],0
        jmp     pop_next
      pop_sreg:
        mov     dl,[operand_size]
        mov     dh,[push_size]
        cmp     al,62h
        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,70h
        jae     invalid_operand
        sub     al,61h
        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_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
        lods    byte [esi]
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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
        lods    byte [esi]
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_register
        mov     [postbyte_register],al
        jmp     nomem_instruction_ready
bound_instruction:
        cmp     [code_type],64
        je      illegal_instruction
        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
        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
retf_instruction:
        cmp     [code_type],64
        jne     ret_instruction
ret_instruction_64bit:
        call    operand_64bit
ret_instruction:
        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_instruction_code
        mov     ax,dx
        stos    word [edi]
        jmp     instruction_assembled
      simple_ret:
        inc     [base_code]
        call    store_instruction_code
        jmp     instruction_assembled
lea_instruction:
        mov     [base_code],8Dh
        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     al,al
        xchg    al,[operand_size]
        push    eax
        lods    byte [esi]
        call    get_size_operator
        cmp     al,'['
        jne     invalid_operand
        mov     [size_override],-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:
        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
        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
        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
        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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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:
        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
        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,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:
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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:
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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:
        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
        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

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:
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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_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_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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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_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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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_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
        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      relative_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     relative_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 [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_instruction_code
        mov     ax,bx
        call    mark_relocation
        stos    word [edi]
      jmp_far_segment:
        pop     [symbol_identifier] 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_instruction_code
        mov     eax,ebx
        call    mark_relocation
        stos    dword [edi]
        jmp     jmp_far_segment
conditional_jump:
        mov     [base_code],al
        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      relative_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     relative_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     relative_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
        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     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
swapgs_instruction:
        cmp     [code_type],64
        jne     illegal_instruction
rdtscp_instruction:
        mov     [base_code],0Fh
        mov     [extended_code],1
        mov     [postbyte_register],7
        mov     bl,al
        jmp     nomem_instruction_ready

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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_register
        mov     bl,[postbyte_register]
        mov     [postbyte_register],al
        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:
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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_instruction_code
        jmp     instruction_assembled
      bswap_reg64:
        call    operand_64bit
        call    store_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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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
        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
        call    make_mmx_prefix
        mov     [postbyte_register],al
        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     [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_mmx_register
        mov     [postbyte_register],al
        call    make_mmx_prefix
        jmp     nomem_instruction_ready
      movd_mmreg:
        mov     [extended_code],6Eh
        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      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
      make_mmx_prefix:
        cmp     [vex_required],0
        jne     mmx_prefix_for_vex
        cmp     [operand_size],16
        jne     no_mmx_prefix
        mov     [operand_prefix],66h
      no_mmx_prefix:
        ret
      mmx_prefix_for_vex:
        cmp     [operand_size],16
        jne     invalid_operand
        mov     [opcode_prefix],66h
        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
        mov     [operand_size],0
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        lods    byte [esi]
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_mmx_register
        mov     [postbyte_register],al
        cmp     ah,16
        je      movq_mem_xmmreg
        mov     [extended_code],7Fh
        jmp     instruction_ready
     movq_mem_xmmreg:
        mov     [extended_code],0D6h
        mov     [opcode_prefix],66h
        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
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        mov     [operand_size],0
        lods    byte [esi]
        call    convert_mmx_register
        mov     [postbyte_register],al
        call    make_mmx_prefix
        mov     [extended_code],7Eh
        call    operand_64bit
        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
        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
        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      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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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
sse4_instruction_38:
        mov     [mmx_size],16
        mov     [opcode_prefix],66h
        mov     [supplemental_code],al
        mov     al,38h
        jmp     sse_instruction
sse4_ss_instruction_3a_imm8:
        mov     [immediate_size],1
        mov     [mmx_size],4
        jmp     sse4_instruction_3a_setup
sse4_sd_instruction_3a_imm8:
        mov     [immediate_size],1
        mov     [mmx_size],8
        jmp     sse4_instruction_3a_setup
sse4_instruction_3a_imm8:
        mov     [immediate_size],1
        mov     [mmx_size],16
      sse4_instruction_3a_setup:
        mov     [opcode_prefix],66h
        mov     [supplemental_code],al
        mov     al,3Ah
        jmp     sse_instruction
pclmulqdq_instruction:
        mov     byte [value],al
        mov     [mmx_size],16
        mov     al,44h
        jmp     sse4_instruction_3a_setup
extractps_instruction:
        mov     [opcode_prefix],66h
        mov     [base_code],0Fh
        mov     [extended_code],3Ah
        mov     [supplemental_code],17h
        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
        call    operand_64bit
        jmp     mmx_nomem_imm8
insertps_instruction:
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_xmm_register
        mov     [postbyte_register],al
      insertps_xmmreg:
        mov     [opcode_prefix],66h
        mov     [base_code],0Fh
        mov     [extended_code],3Ah
        mov     [supplemental_code],21h
        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:
        mov     [opcode_prefix],66h
        mov     [base_code],0Fh
        mov     [extended_code],3Ah
        mov     [supplemental_code],al
        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]
        call    operand_autodetect
        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:
        mov     [opcode_prefix],66h
        mov     [base_code],0Fh
        mov     [extended_code],3Ah
        mov     [supplemental_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
      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:
        mov     [opcode_prefix],66h
        mov     [base_code],0Fh
        mov     [extended_code],38h
        mov     [supplemental_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
        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

fxsave_instruction_64bit:
        call    operand_64bit
fxsave_instruction:
        mov     [extended_code],0AEh
        mov     [base_code],0Fh
        mov     [postbyte_register],al
        lods    byte [esi]
        call    get_size_operator
        cmp     al,'['
        jne     invalid_operand
        call    get_address
        mov     ah,[operand_size]
        or      ah,ah
        jz      fxsave_size_ok
        mov     al,[postbyte_register]
        cmp     al,111b
        je      clflush_size_check
        cmp     al,10b
        jb      invalid_operand_size
        cmp     al,11b
        ja      invalid_operand_size
        cmp     ah,4
        jne     invalid_operand_size
        jmp     fxsave_size_ok
      clflush_size_check:
        cmp     ah,1
        jne     invalid_operand_size
      fxsave_size_ok:
        jmp     instruction_ready
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
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

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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_register
        cmp     ax,0400h
        jne     invalid_operand
        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_register
        cmp     ax,0401h
        jne     invalid_operand
        cmp     [postbyte_register],0C8h
        jne     monitor_instruction_store
        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_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
movntdqa_instruction:
        mov     [opcode_prefix],66h
        mov     [base_code],0Fh
        mov     [extended_code],38h
        mov     [supplemental_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
        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
        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,8
        je      crc32_reg64
        cmp     ah,4
        jne     invalid_operand
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        mov     [operand_size],0
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        je      crc32_reg32_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_reg32_mem_store
        cmp     al,4
        ja      invalid_operand_size
        inc     [supplemental_code]
        call    operand_autodetect
      crc32_reg32_mem_store:
        jmp     instruction_ready
      crc32_unknown_size:
        call    recoverable_unknown_size
        jmp     crc32_reg32_mem_store
      crc32_reg32_reg:
        lods    byte [esi]
        call    convert_register
        mov     bl,al
        mov     al,ah
        cmp     al,1
        je      crc32_reg32_reg_store
        cmp     al,4
        ja      invalid_operand_size
        inc     [supplemental_code]
        call    operand_autodetect
      crc32_reg32_reg_store:
        jmp     nomem_instruction_ready
      crc32_reg64:
        lods    byte [esi]
        cmp     al,','
        jne     invalid_operand
        mov     [operand_size],0
        call    operand_64bit
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        je      crc32_reg64_reg
        cmp     al,'['
        jne     invalid_operand
        call    get_address
        mov     ah,[operand_size]
        mov     al,8
        test    ah,ah
        jz      crc32_unknown_size
        cmp     ah,1
        je      crc32_reg32_mem_store
        cmp     ah,al
        jne     invalid_operand_size
        inc     [supplemental_code]
        jmp     crc32_reg32_mem_store
      crc32_reg64_reg:
        lods    byte [esi]
        call    convert_register
        mov     bl,al
        mov     al,8
        cmp     ah,1
        je      crc32_reg32_reg_store
        cmp     ah,al
        jne     invalid_operand_size
        inc     [supplemental_code]
        jmp     crc32_reg32_reg_store
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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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

simple_vmx_instruction:
        mov     ah,al
        mov     al,0Fh
        stos    byte [edi]
        mov     al,1
        stos    word [edi]
        jmp     instruction_assembled
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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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
        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
        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:
        mov     [opcode_prefix],66h
        mov     [extended_code],38h
        mov     [supplemental_code],al
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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_instruction_code
        pop     eax
        stos    byte [edi]
        jmp     instruction_assembled
skinit_instruction:
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_register
        cmp     ax,0400h
        jne     invalid_operand
        mov     al,0DEh
        jmp     simple_vmx_instruction
invlpga_instruction:
        push    eax
        mov     [base_code],0Fh
        mov     [extended_code],1
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_register
        or      al,al
        jnz     invalid_operand
        mov     bl,ah
        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_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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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
        lods    byte [esi]
        call    get_size_operator
        cmp     al,10h
        jne     invalid_operand
        lods    byte [esi]
        call    convert_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      relative_jump_out_of_range
      xbegin_rel32_ok:
        mov     ax,0F8C7h
        stos    word [edi]
        mov     eax,edx
        stos    dword [edi]
        jmp     instruction_assembled

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],80h
        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
        cmp     [vex_required],0
        jne     invalid_operand
        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
        mov     [size_override],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
        mov     [size_override],0
        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:
        mov     [segment_register],0
        mov     [address_size],0
        mov     al,[code_type]
        shr     al,3
        mov     [value_size],al
        mov     al,[esi]
        and     al,11110000b
        cmp     al,60h
        jne     get_size_prefix
        lods    byte [esi]
        sub     al,60h
        mov     [segment_register],al
        mov     al,[esi]
        and     al,11110000b
      get_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     [address_size],al
        mov     [value_size],al
      address_size_prefix_ok:
        call    calculate_address
        cmp     byte [esi-1],']'
        jne     invalid_address
        mov     [address_high],edx
        mov     edx,eax
        cmp     [code_type],64
        jne     address_ok
        or      bx,bx
        jnz     address_ok
        test    ch,0Fh
        jnz     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,0FF00h
      address_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
        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],1000b
        jz      nomem_reg_code_ok
        or      [rex_prefix],44h
        and     [postbyte_register],111b
      nomem_reg_code_ok:
        test    bl,1000b
        jz      nomem_rm_code_ok
        or      [rex_prefix],41h
        and     bl,111b
      nomem_rm_code_ok:
        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
        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,0F800h
        je      address_rip_based
        cmp     bx,0F400h
        je      address_eip_based
        cmp     bx,0FF00h
        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
        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     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]
        cmp     dx,80h
        jge     value_out_of_range
        cmp     dx,-80h
        jl      value_out_of_range
        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
        cmp     al,0Ch
        je      vector_index_ok
        cmp     al,0Dh
        jne     invalid_address
      vector_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:
        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
        jnz     sib_address_32bit_value
        test    ch,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     edx,80h
        jb      sib_address_8bit_value
        cmp     edx,-80h
        jae     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]
        cmp     edx,80h
        jge     value_out_of_range
        cmp     edx,-80h
        jl      value_out_of_range
        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
        jnz     store_address_32bit_value
        test    ch,88h
        jnz     store_address_32bit_value
        or      ch,ch
        jnz     invalid_address_size
        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
        jnz     simple_address_32bit_value
        test    ch,88h
        jnz     simple_address_32bit_value
        or      ch,ch
        jnz     address_sizes_do_not_agree
        or      edx,edx
        jz      simple_address
        cmp     edx,80h
        jb      simple_address_8bit_value
        cmp     edx,-80h
        jae     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]
        cmp     edx,80h
        jge     value_out_of_range
        cmp     edx,-80h
        jl      value_out_of_range
        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
        jnz     address_immediate_32bit
        test    ch,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
      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
        jo      value_out_of_range
        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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/fasm/native/FASM.ASM.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

; flat assembler interface for Win32
; Copyright (c) 1999-2012, 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

	call	preprocessor
	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	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,'m'
	je	memory_option
	cmp	al,'M'
	je	memory_option
	cmp	al,'p'
	je	passes_option
	cmp	al,'P'
	je	passes_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
    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:
	xor	al,al
	stosb
	jmp	find_param
    all_params:
	cmp	[input_file],0
	je	bad_params
	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-2012, Tomasz Grysztar',0Dh,0Ah,0

_logo db 'flat assembler  version ',VERSION_STRING,0
_usage db 0Dh,0Ah
       db 'usage: fasm <source> [output]',0Dh,0Ah
       db 'optional settings:',0Dh,0Ah
       db ' -m <limit>    set the limit in kilobytes for the available memory',0Dh,0Ah
       db ' -p <limit>    set the maximum allowed number of passes',0Dh,0Ah
       db ' -s <file>     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 ?
bytes_count dd ?
displayed_count dd ?
character db ?
last_displayed rb 2

params rb 1000h
options 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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































































































































































































































































































































































































































Deleted source/fasm/native/NotForUseWithFresh.txt.

1
2
These files are here only for reference. 
They are not needed for Fresh.
<
<




Deleted source/fasm/native/SYSTEM.INC.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493

; flat assembler interface for Win32
; Copyright (c) 1999-2012, 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]
	shr	eax,2
	add	eax,dword [buffer+12]
    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]
	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
	push	dword 0
	mov	ebx,[current_line]
      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
	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
	mov	esi,cr_lf
	call	display_string
	pop	ebx
	or	ebx,ebx
	jnz	display_error_line
	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
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/filemanager.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
;***************************************************
; The file manager is a part of Fresh IDE
; that control all files Fresh working with.
; It supersedes most of the functionality
; of project manager and source editor that is
; related to managing any type of files.
;***************************************************

iglobal

FileTypes:
  ; Project file type.
  ftProject         TFileType CreateProjectManager,     \
                              ProjFilter,               \
                              -1,                       \
                              NULL

  ; Usual text source file.
  ftCommonSource    TFileType CreateSourceEditor,       \
                              FileFilter,               \
                              0,                        \
                              fasm_syntax

  ; Main source file.
  ftMainSource      TFileType CreateSourceEditor,       \
                              FileFilter,               \
                              1,                        \
                              fasm_syntax

  ; File containing Form template and form handling source file.
  ftFormSource      TFileType CreateFormEditor,         \
                              FormFilter,               \
                              3,                        \
                              fasm_syntax

  ; Text document without syntax highlighter.
  ftTextDocument    TFileType CreateSourceEditor,       \
                              FileFilter,               \
                              2,                        \
                              NULL

  ; graphic file
  ftGraphic         TFileType CreateGraphicEditor,      \
                              GraphicFilter,            \
                              4,                        \
                              NULL

;  ftWatch           TFileType CreateMemWatch,           \
;                              WatchFilter,              \
;                              5,                        \
;                              NULL

  FileTypeNames:
        StrList                               \
          'Project',                          \
          'Source file',                      \
          'Main file',                        \
          'Form',                             \
          'Text document',                    \
          'Image';,                            \
;          'Memory watch table'

  FileTypeExt  dd '.fpr', '.asm', '.asm', '.frm', '.txt', '.bmp';, '.mwt'

endg


uglobal
  ptrCurrentFile dd ?   ; TOpenFile descendent that have the focus in that moment.
  listFiles      dd ?   ; TArray with all open files.
endg


;-------------------------------------------------
; Prepares file manager for work.
; Call this procedure only once at the begining.
;-------------------------------------------------
proc InitFileManager
begin
        stdcall CreateArray, 4
        mov     [listFiles], eax
        return
endp


;-------------------------------------------------
; Closes all still open files and finalizes the
; file manager. Call it once on close of Fresh
;-------------------------------------------------
proc CloseFileManager
begin
; Close and free all open files.
        stdcall ListFree, [listFiles], _FreeFileProc
        mov     [listFiles], 0
        return
endp


    proc _FreeFileProc, .ptrOpenFile
    begin
            push    esi
            mov     esi, [.ptrOpenFile]
            mov     [esi+TOpenFile.projectID], 0
            stdcall CloseFile, esi
            pop     esi
            return
    endp


proc OpenFileByNameEdit, .hFileName, .dummy
begin
        stdcall OpenFileByName, [.hFileName], NULL, TRUE
        return
endp


proc OpenFileByName, .hFileName, .hTemplate, .fLoadInEditor
begin
        push    ebx

        stdcall IsFileOpen, [.hFileName]
        mov     ebx, eax
        test    eax, eax
        jnz     .focus

        stdcall DetectFileType, [.hFileName]
        mov     ebx, eax
        test    eax, eax
        jz      .unknowntype

.doopen:
        stdcall CreateFStruct, [.hFileName], ebx
        mov     ebx, eax

.focus:
        cmp     [ebx+TOpenFile.hEditor], 0
        jne     .dofocus

        cmp     [.fLoadInEditor], FALSE
        je      .finish

        stdcall LoadFile, ebx, [.hTemplate]
        test    eax, eax
        jz      .error

.dofocus:
        stdcall FocusFile, ebx

.finish:
        mov     eax, ebx
        pop     ebx
        return

.unknowntype:
        mov     ebx, ftTextDocument
        invoke  MessageBoxA, [hApplication], cWarningUnknownType, NULL, MB_YESNO or MB_ICONQUESTION
        cmp     eax, IDYES
        je      .doopen

        xor     eax, eax
        pop     ebx
        return

.error:
        stdcall FreeFStruct, ebx
        xor     eax, eax
        pop     ebx
        return
endp

iglobal
  cWarningUnknownType text 'Unknown file type.', 13, 10,      \
                             'Do you want to open it as text?'
endg



;--------------------------------------------------------------------
; Check whether the file is already open in the coresponding editor.
; Returns:
; eax:
;   NULL - the file is not open.
;   ptrOpenFile - the file is open.
;--------------------------------------------------------------------
proc IsFileOpen, .hFileName
.str rb 512
.ptr dd ?
begin
        push    esi ebx

        stdcall StrPtr, [.hFileName]
        lea     ebx, [.str]
        lea     edx, [.ptr]
        invoke  GetFullPathNameA, eax, 512, ebx, edx

        stdcall HashFilename, ebx
        mov     edx, eax

        mov     esi, [listFiles]
        mov     ecx, [esi+TArray.count]
        lea     esi, [esi+TArray.array]

.while:
        dec     ecx
        js      .notfound
        lodsd
        cmp     edx, [eax+TOpenFile.hashFileName]
        jne     .while

        stdcall StrCompNoCase, [eax+TOpenFile.hFileName], ebx
        jnc     .while

; Found:
        pop     ebx esi
        return

.notfound:
        xor     eax, eax
        pop     ebx esi
        return
endp



;----------------------------------------------------------------------
; Detects the proper type of the file from it's extension.
; Returns valid pointer to TFileType structure or NULL for error.
;----------------------------------------------------------------------
proc DetectFileType, .hFileName
begin
        stdcall StrLen, [.hFileName]
        mov     ecx, eax
        stdcall StrPtr, [.hFileName]

.extloop:
        dec     ecx
        js      .error

        cmp     byte [eax+ecx], '.'
        jne     .extloop

        mov     ecx, dword [eax+ecx]    ; get the extension
        or      ecx, $20202000          ; case insensitive

        mov     eax, ftCommonSource
        cmp     ecx, '.asm'
        je      .typeok

        cmp     ecx, '.inc'
        je      .typeok

        mov     eax, ftFormSource
        cmp     ecx, '.frm'
        je      .typeok

        mov     eax, ftProject
        cmp     ecx, '.fpr'
        je      .typeok

        mov     eax, ftTextDocument
        cmp     ecx, '.txt'
        je      .typeok

        mov     eax, ftGraphic
        cmp     ecx, '.bmp'
        je      .typeok

.error:
        xor     eax, eax
.typeok:
        return
endp




;----------------------------------------------------------------------
; Creates the file structure for given file type.
; If in some of the editors, the file with the same name is
; already open, returns the pointer to the existing file.
;
; In the case if new file is created:
; Set the values for following fields:
;   .type         = needed type value.
;   .hFileName    = full filename of the file.
;   .hashFileName = hash value of the filename.
;   .fNeverSaved  = FALSE if the file with given name exists
;                   TRUE otherwize.
;
;  Returns the pointer to the TOpenFile in the eax register.
;----------------------------------------------------------------------
proc CreateFStruct, .hFileName, .type
.str  rb  512
.ptr  dd  ?
begin
        push    ebx esi

        mov     ebx, [.type]
        test    ebx, ebx
        jnz     .typeok

        mov     ebx, ftTextDocument

.typeok:
        stdcall IsFileOpen, [.hFileName]
        test    eax, eax
        jnz     .finish

        stdcall GetMem, sizeof.TOpenFile
        mov     esi, eax

        stdcall AddArrayItems, [listFiles], 1
        mov     [listFiles], edx
        mov     [eax], esi

        mov     [esi+TOpenFile.ptrType], ebx

        stdcall StrPtr, [.hFileName]
        lea     ecx, [.str]
        push    ecx             ; for future use
        lea     edx, [.ptr]

        invoke  GetFullPathNameA, eax, 512, ecx, edx
        stdcall StrDup  ; .str from the stack

        mov     [esi+TOpenFile.hFileName], eax

        stdcall HashFilename, eax
        mov     [esi+TOpenFile.hashFileName], eax


        stdcall StrPtr, [esi+TOpenFile.hFileName]
        stdcall FileExists, eax
        rcl     [esi+TOpenFile.fNeverSaved], 1

        mov     eax, esi

.finish:
        pop     esi ebx
        return
endp


;--------------------------------------------------
; Frees the TOpenFile descendent structure.
;--------------------------------------------------
proc FreeFStruct, .ptrFile
begin
        push    esi
        mov     esi, [.ptrFile]

        cmp     [esi+TOpenFile.hEditor], 0
        je      .editorclosed
        invoke  DestroyWindow, [esi+TOpenFile.hEditor]
        mov     [esi+TOpenFile.hEditor], 0

.editorclosed:
        cmp     [esi+TOpenFile.projectID], 0
        je      .notinproject

        invoke  SendMessageA, [hProjManager], PMM_REMOVEFILE, esi, 0

.notinproject:
        stdcall ListIndexOf, [listFiles], esi
        jc      .removedfromlist

        stdcall DeleteArrayItems, [listFiles], eax, 1
        mov     [listFiles], edx

.removedfromlist:
        stdcall StrDel, [esi+TOpenFile.hFileName]
        stdcall FreeMem, esi

        pop     esi
        return
endp


;------------------------------------------------------------------------
; Loads the given file in the apropriate editor window.
; If the file is loaded - do nothing.
; Returns NULL if error or eax = [ptrFile] if OK.
;------------------------------------------------------------------------
proc LoadFile, .ptrFile, .hTemplate
begin
        push    esi

        mov     esi, [.ptrFile]
        cmp     [esi+TOpenFile.hEditor], 0
        jne     .fileisloaded

        mov     eax, [esi+TOpenFile.ptrType]

        stdcall [eax+TFileType.CreateProc], esi, [.hTemplate]
        test    eax, eax
        jnz     .error

.fileisloaded:
        stdcall FocusFile, esi
        mov     eax, esi
        pop     esi
        return

.error:
        stdcall ErrorMessage, eax
        xor     eax, eax
        pop     esi
        return
endp


;-------------------------------------------------
; Renames given file and notifies the editor that
; the file was renamed.
;-------------------------------------------------
proc RenameFile, .ptrFile, .hNewName
begin
        push    esi
        mov     esi, [.ptrFile]

        stdcall StrCopy, [esi+TOpenFile.hFileName], [.hNewName]
        stdcall HashFilename, [esi+TOpenFile.hFileName]
        mov     [esi+TOpenFile.hashFileName], eax

        cmp     [esi+TOpenFile.hEditor], 0
        je      .checkproject

        ; notify the editor.
        invoke  SendMessageA, [esi+TOpenFile.hEditor], _CEM_CHANGENOTIFY, 0, 0

.checkproject:
        cmp     [esi+TOpenFile.projectID], 0
        je      .finish

        ; notify project manager.
        invoke  SendMessageA, [hProjManager], PMM_FILECHANGED, esi, 0

.finish:
        pop     esi
        return
endp




;------------------------------------------------
; Saves the file to the disk.
; Also checks if the flag .fNeverSaved is TRUE
; and opens the SaveAs dialog.
; The easy way to make function SaveAs is to
; set .fNeverSaved and to call this function.
; Return: TRUE if the file is saved
;         FALSE if the user canceled operation or error ocures.
;---------------------------------------------------------------
proc SaveFile, .ptrFile
.inmem TInMemoryFile
.res   dd ?
begin
        push    esi

        mov     [.res], TRUE
        mov     [.inmem.ptrBuffer], 0

        mov     esi, [.ptrFile]
        test    esi, esi
        jz      .finish

        cmp     [esi+TOpenFile.hEditor], 0
        je      .finish                         ; the file is not loaded in editor.

; Is the file need SaveAs?
        cmp     [esi+TOpenFile.fNeverSaved], FALSE
        je      .dosave

        mov     eax, [esi+TOpenFile.ptrType]
        stdcall SaveFileDialog, cSaveFileTitle, [eax+TFileType.ptrFilter], [esi+TOpenFile.hFileName]
        test    eax, eax
        jnz     .rename

        mov     [.res], eax
        jmp     .finish

.rename:
        push    eax
        stdcall RenameFile, esi, eax
        stdcall StrDel ; from the stack.

.dosave:
        lea     eax, [.inmem]
        invoke  SendMessageA, [esi+TOpenFile.hEditor], _CEM_GETTEXT, 0, eax
        test    eax, eax
        jnz     .errorsave

        stdcall StrPtr, [esi+TOpenFile.hFileName]
        stdcall SaveBinaryFile, eax, [.inmem.ptrBuffer], [.inmem.fileSize]
        jc      .errorsave

        mov     [esi+TOpenFile.fNeverSaved], 0   ; Mark it as saved at least once.

        xor     eax, eax
        push    eax eax eax eax
        invoke  SendMessageA, [esi+TOpenFile.hEditor], EM_EMPTYUNDOBUFFER  ; remaining arguments are in stack.
        invoke  SendMessageA, [esi+TOpenFile.hEditor], _CEM_SETMODIFIED
        jmp     .free

.errorsave:
        mov     [.res], 0
        stdcall ErrorMessage, eax

.free:
        cmp     [.inmem.ptrBuffer], 0
        je      .finish

        stdcall FreeMem, [.inmem.ptrBuffer]

.finish:
        mov     eax, [.res]
        pop     esi
        return
endp









;--------------------------------------------------
; Close the file and removes it from its editor.
; Returns:
;   0: file is closed successfully
;   1: file is closed and TOpenFile structure was destroyed.
;   2: some error
;   3: CANCEL button was pressed on the save dialog.
;--------------------------------------------------
proc CloseFile, .ptrFile
begin
        push    esi

        mov     esi, [.ptrFile]
        test    esi, esi
        jz      .fault

        cmp     [esi+TOpenFile.hEditor], 0
        je      .checkproj

        stdcall GetModified, esi
        test    eax, eax
        je      .saveok

        stdcall StrDup, cNotSaved1
        push    eax
        stdcall StrCat, eax, [esi+TOpenFile.hFileName]
        stdcall StrCat, eax, cNotSaved2
        stdcall StrPtr, eax

        invoke  MessageBoxA, [hApplication], eax, cTitleWarning, MB_YESNOCANCEL or MB_ICONQUESTION
        stdcall StrDel ; from the stack
        cmp     eax, IDNO
        je      .saveok

        cmp     eax, IDCANCEL
        je      .cancel

        stdcall SaveFile, esi

.saveok:
        invoke  DestroyWindow, [esi+TOpenFile.hEditor]
        mov     [esi+TOpenFile.hEditor], 0

.checkproj:
        cmp     [esi+TOpenFile.projectID], 0
        jne     .finishok

        stdcall FreeFStruct, esi
        mov     eax, cfrDestroyed
        pop     esi
        return

.finishok:
        xor     eax, eax
        mov     al, cfrClosed
        pop     esi
        return

.fault:
        xor     eax, eax
        mov     al, cfrFault
        pop     esi
        return

.cancel:
        xor     eax, eax
        mov     al, cfrCanceled
        pop     esi
        return
endp

iglobal
  cTitleWarning text 'Warning!'
  cNotSaved1  text 'The file "'
  cNotSaved2  text '" is not saved.', 13, 10,         \
                     'Do you want to save it now?'
endg



proc FocusFile, .ptrFile
begin
        push    esi

        mov     esi, [.ptrFile]
        test    esi, esi
        jz      .focusok

        cmp     [esi+TOpenFile.hEditor], 0
        jz      .finish

        invoke  SendMessageA, [esi+TOpenFile.hEditor], _CEM_FOCUSFILE, 0, 0

.focusok:
        stdcall SetCurrentFile, esi
.finish:
        pop     esi
        return
endp


proc SetCurrentFile, .ptrFile
begin
        push    [.ptrFile]
        pop     [ptrCurrentFile]
        return
endp




;----------------------------------------------------------
; Returns TRUE if the file allows some edit action,
; FALSE otherwise.
;----------------------------------------------------------
proc CanAction, .ptrFile, .action
begin
        push    esi

        mov     esi, [.ptrFile]
        test    esi, esi
        jz      .qfalse
        cmp     [esi+TOpenFile.hEditor], 0
        je      .qfalse

        invoke  SendMessageA, [esi+TOpenFile.hEditor], _CEM_CANACTION, 0, [.action]

        pop     esi
        return

.qfalse:
        xor     eax, eax
        pop     esi
        return
endp



proc CommonAction, .ptrFile, .action
begin
        push    esi

        mov     esi, [.ptrFile]
        test    esi, esi
        jz      .finish
        cmp     [esi+TOpenFile.hEditor], 0
        je      .finish

        invoke  SendMessageA, [esi+TOpenFile.hEditor],   \
                             _CEM_EDITACTION, 0, [.action]

.finish:
        pop     esi
        return
endp

;*******************************************************
; Returns TRUE if the file is modified after loading
;*******************************************************
proc GetModified, .ptrFile
begin
        mov     eax, [.ptrFile]
        test    eax, eax
        jz      .exit

        cmp     [eax+TOpenFile.fNeverSaved], 0  ; if the file is never saved.
        jne     .finish

        mov     eax, [eax+TOpenFile.hEditor]
        test    eax, eax
        jz      .exit

        invoke  SendMessageA, eax, _CEM_GETMODIFIED, 0, 0
        return

.finish:
        xor     eax, eax
        inc     eax
.exit:
        return
endp



;*****************************************
; Returns visual properties of the file.
; eax - string handle with screen title
; edx - index of the icon in the files
;       image list.
;*****************************************
proc GetScreenProperties, .ptrFile
begin
        push    edi
        mov     edi, [.ptrFile]
        test    edi,edi
        jz      .error

        stdcall ExtractFileName, [edi+TOpenFile.hFileName]
        stdcall StrExtract, [edi+TOpenFile.hFileName], eax, -1

        mov     edx, [edi+TOpenFile.ptrType]
        mov     edx, [edx+TFileType.iFileIcon]
        cmp     [edi+TOpenFile.projectID], 0
        jne     @f
        add     edx, 8
@@:
        pop     edi
        return

.error:
        mov     eax, edi
        pop     edi
        return
endp



;-------------------------------------
; Returns ptr to TOpenFile of given
; editor. IF there is no such editor
; registered, returns NULL
;-------------------------------------
proc GetEditorFile, .hEditor
begin
        invoke  SendMessageA, [.hEditor], _CEM_GETFILE, 0, 0
        return
endp


;-----------------------------------
; Returns handle of AsmEdit window
; of the some editor. (if any)
; If editor does not contains
; AsmEdit control, returns NULL
;-----------------------------------
proc GetAsmEdit, .hEditor
begin
        invoke  SendMessageA, [.hEditor], _CEM_GETASMEDIT, 0, 0
        return
endp



proc GetFileAsmEdit, .ptrOpenFile
begin
        mov     eax, [.ptrOpenFile]
        test    eax, eax
        jz      .finish
        mov     eax, [eax+TOpenFile.hEditor]
        test    eax, eax
        jz      .finish

        invoke  SendMessageA, eax, _CEM_GETASMEDIT, 0, 0
.finish:
        return
endp




;-------------------------------------------------------
; Notifies editor, that file properties were changed
; ptrFile - TOpenFile structute of the file.
; fWho - fcEditor, fcProject, fcAll
;-------------------------------------------------------
proc FileChanged, .ptrFile, .fWho
begin
        push    ebx
        mov     ebx, [.ptrFile]
        test    ebx, ebx
        jz      .finish

        stdcall CheckFileForFree, ebx
        test    eax, eax
        jnz     .finish

        test    [.fWho], fcEditor
        jz      .notifyproject

        cmp     [ebx+TOpenFile.hEditor], 0
        je      .notifyproject

        invoke  SendMessageA, [ebx+TOpenFile.hEditor], _CEM_CHANGENOTIFY, 0, 0

.notifyproject:
        test    [.fWho], fcProject
        jz      .finish

        cmp     [eax+TOpenFile.projectID], NULL
        je      .finish

        invoke  SendMessageA, [hProjManager], PMM_FILECHANGED, eax, 0

.finish:
        pop     ebx
        return
endp

;--------------------------------------------
; Returns TRUE if the file was destroyed.
;--------------------------------------------
proc CheckFileForFree, .ptrFile
begin
        xor     eax, eax

        mov     ecx, [.ptrFile]
        jecxz   .finish

        mov     edx, [ecx+TOpenFile.hEditor]
        add     edx, [ecx+TOpenFile.projectID]
        jnz     .finish

        stdcall FreeFStruct, ecx
        xor     eax, eax
        inc     eax

.finish:
        return
endp



;---------------------------------------------------
; Enumerates all open files and calls [ptrCallBack]
; Format for callback is:
; proc MyCallBack, ptrFile, lParam
; if callback returns C=1, the enumeration stops
; and the functions returns value in eax.
;---------------------------------------------------
proc EnumOpenFiles, .ptrCallBack, .lParam
begin
        push    esi ecx

        mov     esi, [listFiles]
        mov     ecx, [esi+TArray.count]
        xor     eax, eax
        jecxz   .finish

        lea     esi, [esi+4*ecx-4+TArray.array]

.filesloop:
        push    esi ecx
        stdcall [.ptrCallBack], [esi], [.lParam]
        pop     ecx esi
        jc      .finish

        lea     esi, [esi-4]
        loop    .filesloop

.finish:
        pop     ecx esi
        return
endp

;------------------------------------------
; Returns the number of the files that are
; members of the currently open project.
;------------------------------------------
proc GetProjectFilesCount
begin
        xor     edx, edx
        stdcall EnumOpenFiles, _docountproject, 0
        mov     eax, edx
        return
endp

proc _docountproject, .ptrFile, .lParam
begin
        mov     eax, [.ptrFile]
        cmp     [eax+TOpenFile.projectID], NULL
        je      @f
        inc     edx
@@:
        clc
        return
endp



;------------------------------------------
; Returns the number of the files that are
; currently open for editing.
;------------------------------------------
proc GetEditFilesCount
begin
        xor     edx, edx
        stdcall EnumOpenFiles, _docountedit, 0
        mov     eax, edx
        return
endp


proc _docountedit, .ptrFile, .lParam
begin
        mov     eax, [.ptrFile]
        cmp     [eax+TOpenFile.hEditor], NULL
        je      @f
        inc     edx
@@:
        clc
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/filemanager.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
; Common editor messages
; They should be very simply and easy to be implemented. The most checks and error
; detection should be made by common functions in the file manager. This will make
; writing of the additional editors more easy.
;
;
;Description of CEI (common editor interface).
;
; Preface:
;   CEI is intended to provide easy interface for different files
; editor integrated to Fresh IDE. In the future, it is possible to
; make this interface open for editors added as DLL plugins.
;
; All interaction between "CEI compatible editor" (CCE) and Fresh file
; manager is only trough windows user defined messages (_CEM) and data
; structures. On the other hand, Fresh should interacts with CCE only
; through file manager API (FMA). The main goal of this approach is to
; make requirements for _CEM message handlers more simple and easy to
; implement. As a rule, _CEM message handlers should not provide error
; checking and only basic parameters checking.
;
; 1. Data structures:
;
; For every file that should be edited in some CCE, there should be
; defined data structure of type TFileType that describes the file
; format, editor and points to procedures that to make specific for
; this file type processing. This structure is defined following way:


struc TFileType createproc, ptrfilter, imageindex, lparam {
  .CreateProc dd  createproc   ; procedure that creates editor window for given file type.

  .ptrFilter  dd  ptrfilter    ; pointer (or handle) to the string that
                               ; contains the filter for Open/Save
                               ; dialogs for given file type.

  .iFileIcon  dd imageindex    ; Index of the icon for the file itself (in the project manager).

  .lParam    dd lparam       ; SyntaxProc for text source files. For another file types,
                             ; this may serve another functions.
}

virtual at 0
  TFileType TFileType 0,0,0,0
  sizeof.TFileType = $
end virtual

; The structure for the file that is created by File manager.
; This is description of the file and it's state in Fresh.
; It is not necessary the file to be loaded in the editor window.
; For example this structure is created for every file in the
; current open project, but only when the file is open for editing,
; editor will be created.
struct TOpenFile
  .ptrType      dd      ?       ; pointer to TFileType structure.
  .hFileName    dd      ?       ; handle of a string with full filename.
  .hashFileName dd      ?       ; precompiled hash value of the filename.

  .hEditor      dd      ?       ; Handle of the editor window. Every editor window
                                ; edits only one file.

  .projectID    dd      ?       ; Identifier that is back link to the project.
                                ; probably it should be handle of the treeview
                                ; item. The exact meaning of this value depends
                                ; only from project manager.

  .fNeverSaved  dd      ?       ; if TRUE, the file is created but never saved,
                                ; i.e. there is no file with this name on the disk.
                                ; File manager provides SaveAs dialogs for such
                                ; files on Save action. Also, such files MUST be
                                ; always loaded in the editor.

  .wParam       dd      ?       ; Last two dwords can have different meaning
  .lParam       dd      ?       ; depending of the particular type of the file.
ends

struct TInMemoryFile
  .fAscii    dd ?
  .fileSize  dd ?
  .ptrBuffer dd ?
ends


; 2. _CEM messages:
;
winmessage _CEM_GETTEXT      ; (0, ptrMemoryFile) - returns filled up structure [ptrMemoryFile]
                             ;                    the buffer is filled with content of the file
                             ;                    eax = FALSE if there is no error.
                             ;                    Returns TRUE if the error occurs.

winmessage CEM_LOADFILE      ; (hFilename, 0) - NULL if OK,
                             ; ErrorCode if error.
                             ; Loads (or reloads) the file in the editor.

winmessage _CEM_SETMODIFIED  ; (fModified, 0) - sets the "modified" status of the editor.

winmessage _CEM_CHANGENOTIFY  ; (0, 0) - notifies the editor
                              ; that content of the structure was changed
                              ; - name, the status of the file, etc.
                              ; Editor should provide updating of the file view.
                              ; Of course it can discard this message if it
                              ; not need such notifications. Also, the editor
                              ; can send _CEN_FILECHANGED to it's parent window

winmessage _CEM_FOCUSFILE    ; (0, 0) - Activates the editor window
                             ; and focuses the file.

winmessage _CEM_CANACTION    ; (0, action) - returns TRUE if the
                             ; content of the editor allows given action in
                             ; this moment.
                             ;  [action] can be one of:
                             ;    WM_UNDO
                             ;    WM_COPY
                             ;    WM_CUT
                             ;    WM_PASTE
                             ;    WM_CLEAR

winmessage _CEM_EDITACTION   ; (0, action) - Execute common edit
                             ; action in given file.
                             ;  [action] can be one of:
                             ;    WM_UNDO
                             ;    WM_COPY
                             ;    WM_CUT
                             ;    WM_PASTE
                             ;    WM_CLEAR

winmessage _CEM_GETMODIFIED  ; (0, 0) - returns TRUE if the given
                             ; file is modified and FALSE if the file is not
                             ; modified after the last save - it is probably
                             ; safe to always return TRUE.

winmessage _CEM_GETFILE      ; (0, 0) - returns pointer to TOpenFile structure
                             ; of the given file.

winmessage _CEM_GETASMEDIT   ; (0, 0) - returns handle of possibly internal for editor
                             ; ASMEDIT window, if any. NULL otherwize.

macro StrList [string] {
common
  local ..cnt
  ..cnt = 0
forward
  ..cnt = ..cnt + 1
common
         dd  ..cnt
forward
  local ..str
         dd  ..str
forward
  ..str  db  string,0
}


fcEditor = 1
fcProject = 2
fcAll     = 3

; Results from CloseFile function

cfrClosed = 0
cfrDestroyed = 1
cfrFault = 2
cfrCanceled = 3
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































Deleted source/fileutils.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
;---------------------------------------------------------------------
; Converts some filename's path (full or relative) in relative
; form, related to current directory.
; Arg:
;   hFileName - handle/ptr of the filename.
; Returns:
;   eax - Handle to new string containing the relative path/filename
;---------------------------------------------------------------------

proc GetRelativePath, .hFileName
.root rb 512
.name rb 512
.res  rb 512
.ptr  dd ?
begin
        push    esi edi ebx

        lea     esi, [.root]
        invoke  GetCurrentDirectoryA, 512, esi
        cmp     byte [esi+eax-1], '\'
        je      @f
        mov     word [esi+eax], '\'
@@:
        stdcall StrPtr, [.hFileName]
        lea     edi, [.name]
        lea     ecx, [.ptr]
        invoke  GetFullPathNameA, eax, 512, edi, ecx
        test    eax, eax
        jz      .returnempty    ; there is invalid or missing filename.

        lea     edx, [.res]

; find first subdir
        mov     cl, ':'
        call    _CmpSubFolder
        jc      .copy                   ; Copy full path, because they are in different drives.

        mov     cl, '\'

        inc     esi
        inc     edi

.subloop:
        call    _CmpSubFolder
        jnc     .subloop

        dec     esi

; count of remaining subfolders.
.count:
        inc     esi
        mov     al, [esi]
        test    al,al
        je      .copy
        cmp     al,cl
        jne     .count
.found:
        mov     dword [edx], '..\'
        add     edx, 3
        test    al,al
        jnz     .count

.copy:
        mov     al, [edi]
        inc     edi
        mov     [edx], al
        inc     edx
        test    al,al
        jnz     .copy

        stdcall StrNew
        lea     edx, [.res]
        stdcall StrCopy, eax, edx

        pop     ebx edi esi
        return

.returnempty:
        stdcall StrNew
        pop     ebx edi esi
        return
endp




proc _CmpSubFolder       ; esi - first, edi - second, cl - end char
begin
        xor     ebx, ebx

.scanloop:
        mov     al, [esi+ebx]
        test    al,al
        jz      .endofpath

        mov     ch, al
        mov     ah, [edi+ebx]
        or      ax, $2020
        cmp     al, ah
        jne     .notequal

        cmp     ch,cl
        je      .eosubdir

        inc     ebx
        jmp     .scanloop

.endofpath:
        cmp     byte [edi+ebx], cl
        jne     .notequal
        inc     edi
        add     edi, ebx
        add     esi, ebx
        xor     ebx, ebx
        stc
        return

.eosubdir:
        add     esi, ebx
        add     edi, ebx
        inc     esi
        inc     edi
        xor     ebx, ebx
        clc
        return

.notequal:
        stc
        return
endp

;----------------------------------------
; Returns an index to the filename
; separated from full path name.
; The original string remains unchanged
;----------------------------------------
proc ExtractFileName, .hPath
begin
        push    ebx ecx edx
        stdcall StrPtr, [.hPath]
        mov     ebx, eax
        mov     edx, eax
        xor     ecx, ecx
.loop:
        mov     cl, [edx]
        inc     edx
        jecxz   .end

        cmp     cl, '\'
        je      .dir
        cmp     cl, '/'
        jne     .loop
.dir:
        mov     eax, edx
        jmp     .loop

.end:
        sub     eax, ebx
        pop     edx ecx ebx
        return
endp





;----------------------------------------------------------
; Create an unique for the project filename of shape:
; <hPrefix>NNN<hSuffix> - where NNN is the mimimal number
; that makes the filename unique.
; Returns:
;   eax - handle to the new created filename.
;   edx - the NNN number.
;----------------------------------------------------------

proc CreateUniqueName, .hPrefix, .hSuffix
.str rb 1024
.num dd ?
.nm  dd ?
.ptr dd ?
begin
        push    esi edi ebx
        mov     [.num], 1
        stdcall StrNew
        mov     [.nm], eax
        lea     ebx, [.str]

; Create name
.findloop:
        stdcall StrCopy, [.nm], [.hPrefix]

        stdcall NumToStr, [.num], ntsUnsigned or ntsDec
        stdcall StrCat, [.nm], eax
        stdcall StrDel, eax
        stdcall StrCat, [.nm], [.hSuffix]

        stdcall StrPtr, [.nm]
        lea     esi, [.ptr]
        invoke  GetFullPathNameA, eax, 1024, ebx, esi

        stdcall IsFileOpen, ebx
        test    eax, eax
        jz      .found

.nextloop:
        inc     [.num]
        jmp     .findloop

.found:
        stdcall StrCopy, [.nm], ebx
        mov     eax, [.nm]
        mov     edx, [.num]

        pop     ebx edi esi
        return
endp



proc HashFilename, .hFileName
.str rb 1024
.ptr dd ?
begin
        push    esi edi ebx
        lea     esi, [.str]

        stdcall StrPtr, [.hFileName]
        lea     ecx, [.ptr]
        invoke  GetFullPathNameA, eax, 1024, esi, ecx
        stdcall StrLCase, esi
        stdcall StrHash, esi
        pop     ebx edi esi
        return
endp




proc ChangeDir, .hFileName
.ptrname dd ?
.str rb 1024
begin
        push    esi
        stdcall StrPtr, [.hFileName]

        lea     ecx, [.ptrname]
        lea     esi, [.str]
        invoke  GetFullPathNameA, eax, 1024, esi, ecx
        test    eax, eax
        jz      .finish_error

        mov     eax, [.ptrname]
        test    eax, eax
        jz      @f
        mov     byte [eax], 0
@@:
        invoke  SetCurrentDirectoryA, esi
        pop     esi
        return

.finish_error:
        stc
        pop     esi
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































Deleted source/findreplace.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
; find/replace routines (Mateusz Tymek)

include "findreplace.inc"

; actFindFirst action handler
proc OnFindFirst, .wparam, .lparam
begin
        push    ebx
        stdcall CreateForm, FindDialog, [hApplication]
        or      ebx,ebx
        jz      .finish
        stdcall SetFindOptions, ebx
        invoke  SendMessageA, ebx,WM_INITDIALOG,0,0
        stdcall ShowModal, ebx,MSF_CENTER
        cmp     eax,MR_OK
        jne     .finish
        stdcall GetFindOptions, ebx
        invoke  DestroyWindow, ebx
        mov     [FindOptions.search_type],1
        stdcall AddStringToHistory, FindOptions.search_str
        call    FindReplace
  .finish:
        pop     ebx
        return
endp

; actReplace action handler
proc OnReplace, .wparam, .lparam
        begin
        push    ebx
        stdcall CreateForm, ReplaceDialog, [hApplication]
        or      ebx,ebx
        jz      .finish
        stdcall SetFindOptions, ebx
        invoke  SendMessageA, ebx,WM_INITDIALOG,0,0
        stdcall ShowModal, ebx,MSF_CENTER
        cmp     eax,MR_OK
        jne     .finish
        stdcall GetFindOptions, ebx
        invoke  DestroyWindow, ebx
        mov     [FindOptions.search_type],2
        stdcall AddStringToHistory, FindOptions.search_str
        call    FindReplace
  .finish:
        pop     ebx
        return
endp

; actFindNext action handler
proc OnFindNext, .wparam, .lparam
        begin
        push    eax
        cmp     [FindOptions.search_type],0
        je      .finish
        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, 0, 0
        or      eax,eax
        jz      .clear_search
        stdcall FindNext, eax
        or      eax,eax
        jz      .not_found
  .finish:
        pop     eax
        return
  .not_found:
        invoke  MessageBoxA,[hEditorsHost], cTextNotFound, cSearchTitle, MB_ICONINFORMATION
  .clear_search:
        mov     [FindOptions.search_type],0
        pop     eax
        return
endp

;--------------------------------------------------------------------------------------------------

; Window proc for find and replace dialogs
proc FindDialogProc, .hwnd, .wmsg, .wparam, .lparam
begin
        cmp     [.wmsg], AM_ONIDLE
        je      .onidle

        stc
        return

.onidle:
        invoke  SendDlgItemMessageA, [.hwnd], fdlgTextEditID, WM_GETTEXTLENGTH, 0, 0
        test    eax, eax
        setnz   al
        movzx   eax, al
        push    eax

        invoke  GetDlgItem, [.hwnd],fdlgFindButtonID
        invoke  EnableWindow, eax ; flag from the stack
        clc
        return
endp

;--------------------------------------------------------------------------------------------------

; loads strings from string history to specified combobox
; modified version from FASMW by Tomasz Grysztar
proc GetStringsFromHistory, .hwnd_combobox
        begin
        push    ebx esi
        invoke  SendMessageA,[hFindHistory],LB_GETCOUNT,0,0
        mov     esi,eax
        xor     ebx,ebx
  .get_string:
        cmp     ebx,esi
        je      .finish
        invoke  SendMessageA,[hFindHistory],LB_GETTEXT,ebx,string_buffer
        invoke  SendMessageA,[.hwnd_combobox],CB_ADDSTRING,0,string_buffer
        inc     ebx
        jmp     .get_string
  .finish:
        pop     esi ebx
        return
endp

; add string to find history.
; modified version from FASMW by Tomasz Grysztar
proc AddStringToHistory, .lpstr
        begin
        mov     eax,[.lpstr]
        cmp     byte [eax],0
        je      .finish
        invoke  SendMessageA,[hFindHistory],LB_FINDSTRINGEXACT,-1,[.lpstr]
        cmp     eax,LB_ERR
        je      .insert
        invoke  SendMessageA,[hFindHistory],LB_DELETESTRING,eax,0
  .insert:
        invoke  SendMessageA,[hFindHistory],LB_INSERTSTRING,0,[.lpstr]
        cmp     eax,LB_ERRSPACE
        jne     .finish
        invoke  SendMessageA,[hFindHistory],LB_GETCOUNT,0,0
        sub     eax,1
        jc      .finish
        invoke  SendMessageA,[hFindHistory],LB_DELETESTRING,eax,0
        jmp     .insert
  .finish:
        return
endp

;--------------------------------------------------------------------------------------------------

; initializes find/replace routines
proc InitFindOptions
        begin
        xor     eax,eax
        mov     [FindOptions.case_sensitive],eax
        mov     [FindOptions.whole_words],eax
        mov     [FindOptions.prompt_on_replace],eax
        mov     [FindOptions.direction],eax
        mov     [FindOptions.range],eax
        mov     [FindOptions.search_type],eax
        invoke  CreateWindowExA, 0,cListboxClassName,NULL, WS_CHILD or LBS_HASSTRINGS,0,0,0,0,[hApplication],NULL,[hInstance],NULL
        mov     [hFindHistory],eax
        return
endp

iglobal
  hFindInstance dd ?
endg

proc FindReplace
begin

        mov     eax,[FindOptions.range]
        cmp     eax,2
        jb      .simple_search
        cmp     eax,2
        je      .search_all_open

        stdcall GetProjectFilesCount
        jmp     .number_ok

  .search_all_open:
        stdcall GetEditFilesCount

  .number_ok:
        stdcall ProgressWndCreate, eax,1,cPerformingSearch,0

        stdcall ThreadCreate, FindReplaceThread, 0
        mov     [hFindInstance],eax

        mov     [find_cancel_flag], 0
        stdcall ShowModal, [hProgressWnd], MSF_CENTER
        cmp     eax,MR_OK
        je      .search_done            ; if the search was cancelled, we set
                                        ; [find_cancel_flag] to 1, and then we wait
                                        ; for the search routine to cleanup.

        mov     [find_cancel_flag],1

.search_done:
        invoke  SendMessageA, [hEditorsHost],WM_SETREDRAW,TRUE,0
        invoke  InvalidateRect, [hEditorsHost],NULL,0
        invoke  RedrawWindow, [hEditorsHost], NULL, NULL, RDW_INVALIDATE or RDW_ERASE or RDW_ALLCHILDREN
        invoke  SetActiveWindow, [hApplication]
        return

  .simple_search:
        stdcall FindReplaceThread, 0
        return
endp



; peforms find or replace operation
proc FindReplaceThread, .dummy
.msg       TFreshMsg
.tvi       TVITEM
.count     dd ?
.parentmsg dd ?
.closeflag dd ?
.rect      RECT
begin
        push    ebx ecx esi edi
        mov     eax,[FindOptions.range]
        or      eax,eax
        jz      .find_first_only
        dec     eax
        jz      .find_whole_current
        dec     eax
        jz      .find_all_open_files
        dec     eax
        jz      .find_whole_project
        jmp     .ret

  .find_first_only:
        stdcall GetFileAsmEdit, [ptrCurrentFile]
        or      eax,eax
        jz      .finish
        stdcall FindFirst,eax
        or      eax,eax
        jz      .not_found
        jmp     .ret

;----------------------------------------------------------------------

  .find_whole_current:
        stdcall GetFileAsmEdit, [ptrCurrentFile]        ; johnfound
        or      eax,eax
        jz      .finish
        mov     ebx,eax
        invoke  SendMessageA, [frmMsg],MWM_CLEARMESSAGES,0,0

        mov     [blockAutoHide], 1

        mov     eax, [ptrCurrentFile]
        mov     eax, [eax+TOpenFile.hFileName]
        stdcall FindAll, ebx, eax, TVI_ROOT
        or      eax,eax
        jz      .not_found
        jmp     .finish


;-----------------------------------------------------------------------

  .find_all_open_files:
        invoke  SendMessageA, [frmMsg],MWM_CLEARMESSAGES,0,0

        mov     [blockAutoHide], 1

        ; prepare message in msg window
        stdcall StrDup, cSearchOneFile1
        mov     edi,eax
        mov     [.msg.hMessage],eax
        stdcall StrCat, edi,FindOptions.search_str
        stdcall StrCharCat, edi,'"'
        mov     [.msg.type], mtFind
        mov     [.msg.link.hFileName],0
        lea     eax,[.msg]
        invoke  SendMessageA, [frmMsg],MWM_ADDMESSAGE,eax,TVI_ROOT
        mov     [.parentmsg],eax

        xor     ebx, ebx
        stdcall EnumOpenFiles, _dosearchonefile, [.parentmsg]
        test    ebx, ebx
        jz      .not_found

        ; add number of results to message window
        stdcall StrDup, cSearchResults1
        mov     edx, eax
        stdcall NumToStr, ebx, ntsDec or ntsUnsigned
        stdcall StrCat, edx, eax
        stdcall StrDel, eax
        stdcall StrCat, edi, edx
        stdcall StrDel, edx
        stdcall StrCat, edi, cSearchResults2
        mov     [.tvi.mask], TVIF_TEXT+TVIF_HANDLE
        mov     eax,[.parentmsg]
        mov     [.tvi.hItem],eax
        stdcall StrPtr, edi
        mov     [.tvi.pszText],eax
        lea     eax,[.tvi]
        invoke  SendMessageA, [tvMessagesWin],TVM_SETITEM,0,eax
        stdcall StrDel, edi

        invoke  SendMessageA, [hProgressWnd], WM_COMMAND, MR_OK, 0
        jmp     .finish

;---------------------------------------------------------------------------

  .find_whole_project:
        invoke  SendMessageA, [frmMsg],MWM_CLEARMESSAGES,0,0

        mov     [blockAutoHide], 1

        ; prepare message in msg window
        stdcall StrDup, cSearchOneFile1
        mov     edi,eax
        mov     [.msg.hMessage],eax
        stdcall StrCat, edi,FindOptions.search_str
        stdcall StrCharCat, edi,'"'
        mov     [.msg.type], mtFind
        mov     [.msg.link.hFileName],0
        lea     eax,[.msg]
        invoke  SendMessageA, [frmMsg],MWM_ADDMESSAGE,eax,TVI_ROOT
        mov     [.parentmsg],eax

     ; search the project
        xor     ebx, ebx
        stdcall EnumOpenFiles, _dosearchoneprojfile, [.parentmsg]
        test    ebx, ebx
        jz      .not_found

        ; add number of results to message window
        stdcall StrDup, cSearchResults1
        mov     edx, eax
        stdcall NumToStr, ebx, ntsDec or ntsUnsigned
        stdcall StrCat, edx, eax
        stdcall StrDel, eax
        stdcall StrCat, edi, edx
        stdcall StrDel, edx
        stdcall StrCat, edi, cSearchResults2
        mov     [.tvi.mask], TVIF_TEXT+TVIF_HANDLE
        mov     eax,[.parentmsg]
        mov     [.tvi.hItem],eax
        stdcall StrPtr, edi
        mov     [.tvi.pszText],eax
        lea     eax,[.tvi]
        invoke  SendMessageA, [tvMessagesWin], TVM_SETITEM, 0, eax
        stdcall StrDel, edi
        invoke  SendMessageA, [hProgressWnd], WM_COMMAND, MR_OK, 0
        jmp     .finish

;---------------------------------------------------------------------------------

.not_found:
        mov     [FindOptions.search_type],0
        invoke  MessageBoxA,[hEditorsHost],cTextNotFound,cSearchTitle,MB_ICONINFORMATION
        invoke  SendMessageA, [hProgressWnd], WM_COMMAND, MR_OK, 0

.finish:
        xor     eax,eax
        mov     [FindOptions.search_type],eax

.ret:
        pop     edi esi ecx ebx
        return
endp



;----------------------------------------------------------------------
; callback functions for EnumOpenFiles used in search thread function
;----------------------------------------------------------------------

proc _dosearchonefile, .ptrFile, .lParam
begin
        mov     esi, [.ptrFile]
        cmp     [esi+TOpenFile.hEditor], NULL
        je      .finish

        stdcall GetAsmEdit, [esi+TOpenFile.hEditor]
        test    eax, eax
        jz      .step

        stdcall FindAll, eax, [esi+TOpenFile.hFileName], [.lParam]
        add     ebx, eax

.step:
        stdcall ProgressWndStepIt
.finish:
        xor     eax, eax
        cmp     [find_cancel_flag], 0
        jne     .cancel

        clc
        return

.cancel:
        inc     eax
        stc
        return
endp


proc _dosearchoneprojfile, .ptrFile, .parentMsg
.flag dd ?
begin
        push    edi
        mov     esi, [.ptrFile]
        cmp     [esi+TOpenFile.projectID], NULL
        je      .finish                    ; not in the project.

        mov     [.flag], 0
        cmp     [esi+TOpenFile.hEditor], NULL
        jne     .editorok

        stdcall LoadFile, esi, NULL
        cmp     [esi+TOpenFile.hEditor], NULL
        je      .step

        inc     [.flag]

.editorok:
        stdcall GetAsmEdit, [esi+TOpenFile.hEditor]
        test    eax, eax
        jz      .searchok

        stdcall FindAll, eax, [esi+TOpenFile.hFileName], [.parentMsg]
        add     ebx, eax

.searchok:
        cmp     [.flag], 0
        je      .step

        stdcall GetModified, esi
        test    eax, eax
        jz      .saveok

        stdcall SaveFile, esi

.saveok:
        stdcall CloseFile, esi

.step:
        stdcall ProgressWndStepIt

.finish:
        xor     eax, eax
        cmp     [find_cancel_flag], 0
        jne     .cancel

        pop     edi
        clc
        return

.cancel:
        inc     eax
        pop     edi
        stc
        return
endp


; sets members of FindOptions structure corresponding to given find (replace) dialog
proc GetFindOptions, .hwnd
        begin
        push    eax ebx
        invoke  IsDlgButtonChecked, [.hwnd],fdlgCaseSensitiveCheckID
        mov     [FindOptions.case_sensitive],eax
        invoke  IsDlgButtonChecked, [.hwnd],fdlgWholeWordsCheckID
        mov     [FindOptions.whole_words],eax
        invoke  GetDlgItem, [.hwnd],fdlgPromptOnReplaceCheckID
        or      eax,eax
        jz      @f
        invoke  IsDlgButtonChecked, [.hwnd],fdlgPromptOnReplaceCheckID
        mov     [FindOptions.prompt_on_replace],eax
    @@: invoke  IsDlgButtonChecked, [.hwnd],fdlgDirectionRadioID   ; forward direction ?
        or      eax,eax
        jz      @f                                                ; no, jump
        xor     eax,eax                                           ; yes, set proper FindOption
        jmp     .direction_ok
    @@: inc     eax
    .direction_ok:
        mov     [FindOptions.direction],eax
        xor     ebx,ebx
        invoke  IsDlgButtonChecked, [.hwnd],fdlgSearchInRadioID    ; search in current source file?
        or      eax,eax
        jz      @f
        jmp     .range_ok
    @@: inc     ebx
        invoke  IsDlgButtonChecked, [.hwnd],fdlgSearchInRadioID+1  ; search in whole current file?
        or      eax,eax
        jz      @f
        jmp     .range_ok
    @@: inc     ebx
        invoke  IsDlgButtonChecked, [.hwnd],fdlgSearchInRadioID+2  ; search in all opened files?
        or      eax,eax
        jz      @f
        jmp     .range_ok
    @@: inc     ebx
    .range_ok:
        mov     [FindOptions.range],ebx
        invoke  GetDlgItemTextA, [.hwnd],fdlgTextEditID,FindOptions.search_str,fdlgMaxFindStrLen
        invoke  GetDlgItemTextA, [.hwnd],fdlgReplaceTextEditID,FindOptions.replace_str,fdlgMaxFindStrLen
        pop     edx eax
        return
endp

; setup given find (replace) dialog corresponding to FindOptions structure
proc SetFindOptions, .hwnd
.str rb 0x100
        begin
        push    eax esi
        invoke  CheckDlgButton, [.hwnd],fdlgCaseSensitiveCheckID,[FindOptions.case_sensitive]
        invoke  CheckDlgButton, [.hwnd],fdlgWholeWordsCheckID,[FindOptions.whole_words]
        invoke  CheckDlgButton, [.hwnd],fdlgPromptOnReplaceCheckID,[FindOptions.prompt_on_replace]
        mov     eax,fdlgDirectionRadioID
        add     eax,[FindOptions.direction]
        invoke  CheckDlgButton, [.hwnd],eax,BST_CHECKED
        mov     eax,fdlgSearchInRadioID
        add     eax,[FindOptions.range]
        invoke  CheckDlgButton, [.hwnd],eax,BST_CHECKED
        invoke  GetDlgItem, [.hwnd],fdlgTextEditID
        push    eax
        stdcall GetStringsFromHistory, eax

        stdcall GetFileAsmEdit, [ptrCurrentFile]
        or      eax,eax
        jz      .finish

        lea     esi, [.str]
        invoke  SendMessageA, eax, AEM_GETWORDATCARET, 256, esi

        pop     eax
        invoke  SendMessageA, eax, WM_SETTEXT, 0, esi
  .finish:
        pop     esi eax
        return
endp


; searches for the first occurrence of specified string in specified AsmEdit control
; (and replaces it if necessary. Returns 1 on success and 0 on fail
proc FindFirst, .hAsmEdit
        begin
        push    edx
        xor     edx,edx
        xor     eax,eax
        cmp     [FindOptions.whole_words],eax
        jz      @f
        or      edx,AEFIND_WHOLEWORDS
    @@: cmp     [FindOptions.case_sensitive],eax
        jz      @f
        or      edx,AEFIND_CASESENSITIVE
    @@: cmp     [FindOptions.direction],eax
        jz      @f
        or      edx,AEFIND_BACKWARD
    @@: lea     eax,[FindOptions.search_str]
        ; find
        invoke  SendMessageA, [.hAsmEdit],AEM_FINDFIRST,edx,eax
        push    eax
        cmp     [FindOptions.search_type],2   ; replace?
        jne     .finish
        or      eax,eax
        jz      .finish
        cmp     [FindOptions.prompt_on_replace],0   ; prompt on replace?
        je      .dont_prompt
        invoke  MessageBoxA, HWND_DESKTOP,cReplacePrompt,cTtlReplaceQuery, MB_ICONQUESTION+MB_YESNO
        cmp     eax,IDNO
        je      .finish
  .dont_prompt:
        ; replace
        invoke  SendMessageA,[.hAsmEdit],EM_REPLACESEL,TRUE,FindOptions.replace_str
  .finish:
        pop     eax
        pop     edx
        return
endp

; finds (replaces) next occurrence of a string in specified AsmEdit control
proc FindNext, .hAsmEdit
        begin
        ; find
        invoke  SendMessageA, [.hAsmEdit],AEM_FINDNEXT,0,0
        push    eax
        cmp     [FindOptions.search_type],2   ; replace?
        jne     .finish
        or      eax,eax
        jz      .finish
        cmp     [FindOptions.prompt_on_replace],0   ; prompt on replace?
        je      .dont_prompt
        invoke  MessageBoxA, HWND_DESKTOP,cReplacePrompt,cTtlReplaceQuery, MB_ICONQUESTION+MB_YESNO
        cmp     eax,IDNO
        je      .finish
  .dont_prompt:
        ; replace
        invoke  SendMessageA,[.hAsmEdit],EM_REPLACESEL,TRUE,FindOptions.replace_str
  .finish:
        pop     eax
        return
endp

; searches specified AsmEdit for all occurrences and returns their number
proc FindAll, .hAsmEdit, .hFileName, .hParentMsg
.old_pos AEPOS
.msg     TFreshMsg
.line    rb 0x100
.tvi     TVITEM
.count   dd ?

begin
        push    ebx esi edi

        mov     [.count],0
        mov     ebx,[.hAsmEdit]

        mov     [.msg.type], mtFind
        mov     eax,[.hFileName]
        mov     [.msg.link.hFileName], eax

        lea     eax, [.old_pos]
        invoke  SendMessageA, ebx,AEM_GETPOS,eax,0
        ; prepare search message
        stdcall StrDup, cSearchOneFile1
        mov     esi,eax
        stdcall StrCat, eax,FindOptions.search_str
        stdcall StrCat, esi,cSearchOneFile2
        mov     [.msg.type], mtFind
        mov     [.msg.hMessage], esi
        mov     eax,[.hFileName]
        mov     [.msg.link.hFileName],eax
        stdcall StrCat, esi,eax
        ; store cursor old position and set it to (1,1)
        mov     [.msg.link.pos.caretLine], 1
        mov     [.msg.link.pos.caretPosition], 1
        mov     [.msg.link.pos.selectionLine], 1
        mov     [.msg.link.pos.selectionPosition], 1
        lea     eax,[.msg.link.pos]
        invoke  SendMessageA, ebx,AEM_SETPOS,eax,0
        mov     [FindOptions.direction],0       ; force forward direction
        stdcall FindFirst, [.hAsmEdit]           ; search for the first occurrence
        or      eax,eax
        jz      .finish
        lea     eax, [.msg]
        invoke  SendMessageA, [frmMsg],MWM_ADDMESSAGE,eax,[.hParentMsg]
        mov     [.hParentMsg],eax
  .find_next:
        inc     [.count]
        lea     eax,[.msg.link.pos]
        invoke  SendMessageA, ebx,AEM_GETPOS,eax,0
        stdcall StrDup, cSearchLine1
        mov     edi,eax
        stdcall NumToStr, [.msg.link.pos.caretLine], ntsUnsigned or ntsDec
        stdcall StrCat, edi, eax
        stdcall StrDel, eax
        stdcall StrCat, edi, cSearchLine2
        lea     eax,[.line]
        invoke  SendMessageA, ebx, AEM_GETLINEDATA, [.msg.link.pos.caretLine], eax
        mov     eax, 0x100
    .findeol:
        dec     eax
        js      .stop
        cmp     [.line+eax], 0x20
        je      .findeol
    .stop:
        mov     [.line+eax+1], 0
        lea     eax, [.line]
        stdcall StrCat, edi, eax
        stdcall StrCat, edi, cSearchLine3
        mov     [.msg.hMessage], edi
        lea     eax, [.msg]
        invoke  SendMessageA, [frmMsg],MWM_ADDMESSAGE,eax,[.hParentMsg]
        stdcall StrDel, edi
        stdcall FindNext,[.hAsmEdit]
        or      eax,eax
        jnz     .find_next
        ; display number of results
        stdcall StrDup, cSearchResults1
        mov     edx, eax
        stdcall NumToStr, [.count], ntsDec or ntsUnsigned
        stdcall StrCat, edx, eax
        stdcall StrDel, eax
        stdcall StrCat, esi, edx
        stdcall StrDel, edx
        stdcall StrCat, esi,cSearchResults2
        mov     [.tvi.mask],TVIF_TEXT+TVIF_HANDLE
        mov     eax,[.hParentMsg]
        mov     [.tvi.hItem],eax
        stdcall StrPtr, esi
        mov     [.tvi.pszText],eax
        lea     eax,[.tvi]
        invoke  SendMessageA, [tvMessagesWin],TVM_SETITEM,0,eax
        stdcall StrDel, esi
  .finish:
        ; restore old cursor position
        lea     eax,[.old_pos]
        invoke  SendMessageA, ebx,AEM_SETPOS,eax,0
        mov     eax,[.count]
        pop     edi esi ebx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/findreplace.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
; Constants;

fdlgFindButtonID           = MR_OK
fdlgReplaceButtonID        = MR_OK
fdlgTextEditID             = 10
fdlgReplaceTextEditID      = 11
fdlgCaseSensitiveCheckID   = 20
fdlgWholeWordsCheckID      = 21
fdlgPromptOnReplaceCheckID = 22
fdlgDirectionRadioID       = 30
fdlgSearchInRadioID        = 40

fdlgMaxFindStrLen = 0x50

struct TFindOptions
  .search_type       dd ?
  .search_str        rb fdlgMaxFindStrLen
  .replace_str       rb fdlgMaxFindStrLen
  .range             dd ?
  .case_sensitive    dd ?
  .direction         dd ?
  .whole_words       dd ?
  .prompt_on_replace dd ?
ends

; Initialized data.

iglobal
; Search dialog.
  Window  FindDialog, wtParent or wtEnd, waNone, 'TForm', 'Find', ComDlgStyle, 0, NULL, 0, 0, 296, 310, FindDialogProc
  Window  NONE, wtChild, 0, 'Static', "Text to find:", WS_VISIBLE or WS_CHILD, 0, 0, 10, 8, 60, 13, NULL
  Window  NONE, wtChild, 0, 'Combobox', '', WS_VISIBLE or WS_CHILD or CBS_DROPDOWN or CBS_AUTOHSCROLL or WS_VSCROLL or WS_TABSTOP, 0, fdlgTextEditID, 10, 24, 270, 120, NULL
  Window  NONE, wtChild, 0, 'Button', "Options", WS_VISIBLE or WS_CHILD or BS_GROUPBOX, 0, 0, 150, 50, 130, 70, NULL
  Window  NONE, wtChild, 0, 'Button', "Case sensitive", WS_VISIBLE or WS_CHILD or BS_AUTOCHECKBOX or WS_TABSTOP , 0, fdlgCaseSensitiveCheckID, 160, 72, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "Whole words only", WS_VISIBLE or WS_CHILD or BS_AUTOCHECKBOX or WS_TABSTOP, 0, fdlgWholeWordsCheckID, 160, 95, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "Direction", WS_VISIBLE or WS_CHILD or BS_GROUPBOX, 0, 0, 10, 50, 130, 70, NULL
  Window  NONE, wtChild, 0, 'Button', "Forward", WS_VISIBLE or WS_CHILD or BS_AUTORADIOBUTTON or WS_GROUP or WS_TABSTOP, 0, fdlgDirectionRadioID, 20, 72, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "Backward", WS_VISIBLE or WS_CHILD or BS_AUTORADIOBUTTON or WS_TABSTOP, 0, fdlgDirectionRadioID or 1, 20, 95, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "Search in:", WS_VISIBLE or WS_CHILD or BS_GROUPBOX, 0, 0, 10, 130, 130, 110, NULL
  Window  NONE, wtChild, 0, 'Button', "C&urrent file", WS_VISIBLE or WS_CHILD or BS_AUTORADIOBUTTON or WS_GROUP or WS_TABSTOP, 0, fdlgSearchInRadioID, 20, 152, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "&Whole current file", WS_VISIBLE or WS_CHILD or BS_AUTORADIOBUTTON or WS_TABSTOP, 0, fdlgSearchInRadioID+1, 20, 174, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "&All open files", WS_VISIBLE or WS_CHILD or BS_AUTORADIOBUTTON or WS_TABSTOP, 0, fdlgSearchInRadioID+2, 20, 196, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "Whole &project", WS_VISIBLE or WS_CHILD or BS_AUTORADIOBUTTON or WS_TABSTOP, 0, fdlgSearchInRadioID+3, 20, 218, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "&Find first", WS_VISIBLE or WS_CHILD or BS_DEFPUSHBUTTON or WS_TABSTOP, 0, fdlgFindButtonID, 10, 250, 80, 24, NULL
  Window  NONE, wtEnd, 0, 'Button', 'Cancel', WS_VISIBLE or WS_CHILD or WS_TABSTOP, 0, MR_CANCEL, 100, 250, 80, 24, NULL

; Replace dialog
  Window  ReplaceDialog, wtParent or wtEnd, waNone, 'TForm', "Replace", ComDlgStyle, 0, NULL, 0, 0, 296, 350, FindDialogProc
  Window  NONE, wtChild, 0, 'Static', "Text to find:", WS_VISIBLE or WS_CHILD, 0, 0, 10, 8, 60, 13, NULL
  Window  NONE, wtChild, 0, 'Combobox', '', WS_VISIBLE or WS_CHILD or CBS_DROPDOWN or CBS_AUTOHSCROLL or WS_VSCROLL or WS_TABSTOP, 0, fdlgTextEditID, 10, 24, 270, 120, NULL
  Window  NONE, wtChild, 0, 'Static', "New text:", WS_VISIBLE or WS_CHILD, 0, 0, 10, 50, 60, 13, NULL
  Window  NONE, wtChild, 0, 'Combobox', '', WS_VISIBLE or WS_CHILD or CBS_DROPDOWN or CBS_AUTOHSCROLL or WS_VSCROLL or WS_TABSTOP, 0, fdlgReplaceTextEditID, 10, 65, 270, 120, NULL
  Window  NONE, wtChild, 0, 'Button', "Options", WS_VISIBLE or WS_CHILD or BS_GROUPBOX, 0, 0, 150, 90, 130, 190, NULL
  Window  NONE, wtChild, 0, 'Button', "Case sensitive", WS_VISIBLE or WS_CHILD or BS_AUTOCHECKBOX or WS_TABSTOP, 0, fdlgCaseSensitiveCheckID, 160, 112, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "Whole words only", WS_VISIBLE or WS_CHILD or BS_AUTOCHECKBOX or WS_TABSTOP, 0, fdlgWholeWordsCheckID, 160, 135, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "Prompt on replace", WS_VISIBLE or WS_CHILD or BS_AUTOCHECKBOX or WS_TABSTOP, 0, fdlgPromptOnReplaceCheckID, 160, 157, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "Direction", WS_VISIBLE or WS_CHILD or BS_GROUPBOX, 0, 0, 10, 90, 130, 70, NULL
  Window  NONE, wtChild, 0, 'Button', "Forward", WS_VISIBLE or WS_CHILD or BS_AUTORADIOBUTTON or WS_GROUP or WS_TABSTOP, 0, fdlgDirectionRadioID, 20, 112, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "Backward", WS_VISIBLE or WS_CHILD or BS_AUTORADIOBUTTON or WS_TABSTOP, 0, fdlgDirectionRadioID+1, 20, 135, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "Search in:", WS_VISIBLE or WS_CHILD or BS_GROUPBOX, 0, 0, 10, 170, 130, 110, NULL
  Window  NONE, wtChild, 0, 'Button', "C&urrent file", WS_VISIBLE or WS_CHILD or BS_AUTORADIOBUTTON or WS_GROUP or WS_TABSTOP, 0, fdlgSearchInRadioID, 20, 192, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "&Whole current file", WS_VISIBLE or WS_CHILD or BS_AUTORADIOBUTTON or WS_TABSTOP, 0, fdlgSearchInRadioID+1, 20, 214, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "&All open files", WS_VISIBLE or WS_CHILD or BS_AUTORADIOBUTTON or WS_TABSTOP, 0, fdlgSearchInRadioID+2, 20, 236, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', "Whole &project", WS_VISIBLE or WS_CHILD or BS_AUTORADIOBUTTON or WS_TABSTOP, 0, fdlgSearchInRadioID+3, 20, 258, 105, 13, NULL
  Window  NONE, wtChild, 0, 'Button', 'Replace', WS_VISIBLE or WS_CHILD or BS_DEFPUSHBUTTON or WS_TABSTOP, 0, fdlgReplaceButtonID, 10, 290, 80, 24, NULL
  Window  NONE, wtEnd, 0, 'Button', 'Cancel', WS_VISIBLE or WS_CHILD or WS_TABSTOP, 0, MR_CANCEL, 100, 290, 80, 24, NULL
endg

cSearchTitle      text  "Search"
cTextNotFound     text  "Text not found"
cReplacePrompt    text  "Replace this occurrence?"
cPerformingSearch text  "Performing search..."

cSearchOneFile1 text "Search for """
cSearchOneFile2 text """ in file "
cSearchResults1 text " (total "
cSearchResults2 text " results)"
cSearchLine1    text "line: "
cSearchLine2    text " ["
cSearchLine3    text "]"
cTtlReplaceQuery text 'Replace?'


uglobal
  FindOptions   TFindOptions
  hFindHistory  dd ?
  string_buffer rb 0x100
  hwnd_find_progress dd ?
  find_cancel_flag dd ?
endg
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































Deleted source/formsDT.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
;**********************************************************************
; Returns string with source code for given window Template and all its
; children.
; Arguments:
;       ptrWinTemplateDT - pointer to TWinTemplateDT structure.
;
; Returns:
;       eax - handle to the string with source code.
;**********************************************************************
proc CreateSourceTemplate, .ptrWinTemplateDT
begin
        stdcall StrNew
        push    eax
        stdcall _DoCreateSourceTemplate, [.ptrWinTemplateDT], eax, FALSE
        pop     eax
        return
endp


iglobal
  cFormMacro  db 'Window ',0
  cFormNULL   db '0',0
  cFormNameNone db 'NONE',0
endg



proc _DoCreateSourceTemplate, .ptrWinTemplateDT, .res, .fNotLast
begin
        push    esi edi ebx
        mov     esi, [.ptrWinTemplateDT]

; create the line for parent window
;-------------------------------------------------------
        stdcall StrCat, [.res], cFormMacro

        mov     eax, [esi+TWinTemplateDT.hName] ; Or maybe empty string?
        test    eax, eax
        jnz     @f
        mov     eax, cFormNameNone
@@:
        stdcall StrCat, [.res], eax
        stdcall StrCharCat, [.res], ', '

; Add wtXXX flags
        xor     eax, eax
        mov     ecx, [esi+TWinTemplateDT.children]
        cmp     [ecx+TArray.count], 0
        je      @f
        or      eax, wtParent
@@:
        cmp     [.fNotLast], 0
        jne     @f
        or      eax, wtEnd
@@:
        stdcall NumToStr, eax, ntsDec or ntsUnsigned
        stdcall StrCat, [.res], eax
        stdcall StrDel, eax
        stdcall StrCharCat, [.res], ', '

; Add Align:
        movzx   eax, [esi+TWinTemplateDT.Align]
        stdcall NumToStr, eax, ntsDec or ntsUnsigned
        stdcall StrCat, [.res], eax
        stdcall StrDel, eax
        stdcall StrCharCat, [.res], ', '
;
; Add Class name
        stdcall StrCharCat, [.res], "'"
        stdcall StrCat, [.res], [esi+TWinTemplateDT.ptrClass]
        stdcall StrCharCat, [.res], "'"
        stdcall StrCharCat, [.res], ', '

; Add window text
        stdcall StrCharCat, [.res], "'"
        stdcall StrCat, [.res], [esi+TWinTemplateDT.ptrText]
        stdcall StrCharCat, [.res], "'"
        stdcall StrCharCat, [.res], ', '

; Add Style and StyleEx
        stdcall NumToStr, [esi+TWinTemplateDT.style], ntsHex or ntsUnsigned
        stdcall StrCharCat, [.res], '$'
        stdcall StrCat, [.res], eax
        stdcall StrDel, eax
        stdcall StrCharCat, [.res], ', '

        stdcall NumToStr, [esi+TWinTemplateDT.styleEx], ntsHex or ntsUnsigned
        stdcall StrCharCat, [.res], '$'
        stdcall StrCat, [.res], eax
        stdcall StrDel, eax
        stdcall StrCharCat, [.res], ', '

; Add ID
        movzx   eax, [esi+TWinTemplateDT.ID]
        stdcall NumToStr, eax, ntsDec or ntsUnsigned
        stdcall StrCat, [.res], eax
        stdcall StrDel, eax
        stdcall StrCharCat, [.res], ', '

; Add coordinates/size
        movsx   eax, [esi+TWinTemplateDT.left]
        stdcall NumToStr, eax, ntsDec
        stdcall StrCat, [.res], eax
        stdcall StrDel, eax
        stdcall StrCharCat, [.res], ', '

        movsx   eax, [esi+TWinTemplateDT.top]
        stdcall NumToStr, eax, ntsDec
        stdcall StrCat, [.res], eax
        stdcall StrDel, eax
        stdcall StrCharCat, [.res], ', '

        movsx   eax, [esi+TWinTemplateDT.width]
        stdcall NumToStr, eax, ntsDec
        stdcall StrCat, [.res], eax
        stdcall StrDel, eax
        stdcall StrCharCat, [.res], ', '

        movsx   eax, [esi+TWinTemplateDT.height]
        stdcall NumToStr, eax, ntsDec
        stdcall StrCat, [.res], eax
        stdcall StrDel, eax
        stdcall StrCharCat, [.res], ', '

; Add user WinProc
        mov     ecx, [esi+TWinTemplateDT.WinProc]
        stdcall StrLen, ecx
        test    eax, eax
        jnz     @f
        mov     ecx, cFormNULL
@@:
        stdcall StrCat, [.res], ecx
        stdcall StrCharCat, [.res], ';'+13*$100+10*$10000

; recursive creation of children
        mov     esi, [esi+TWinTemplateDT.children]
        mov     ebx, [esi+TArray.count]

.loop:
        dec     ebx
        js      .endloop
        stdcall _DoCreateSourceTemplate, [esi+TArray.array], [.res], ebx
        add     esi, 4
        jmp     .loop

.endloop:
        pop     ebx edi esi
        return
endp




;------------------------------------
; Retrives the TBaseWin structure
; pointer from the given window.
; Returns NULL if the window have no
; atached such structure.
;------------------------------------
;proc GetBasePointer, hwnd
;begin
;        push    esi
;        invoke  GetWindowLongA, [.hwnd], GWL_USERDATA
;        test    eax, eax
;        jz      .exit
;        mov     esi, eax
;        invoke  IsBadReadPtr, esi, sizeof.TAlignData
;        test    eax, eax
;        jnz     .false
;
;        mov     esi, [esi+TAlignData.UserData]
;        invoke  IsBadReadPtr, esi, sizeof.TBaseWin
;        test    eax, eax
;        jnz     .false
;
;        mov     eax, esi
;        pop     esi
;        return
;
;.false:
;        xor     eax, eax
;.exit:
;        pop     esi
;        return
;endp
;




;------------------------------------------------------------------------
; Create binary structure TWinTemplateDT structure from
; source text in FASM syntax.
;
; Arguments:
;   ptrSource: pointer to the source text.
;
; Returns:
;   eax: TWinTemplateDT structure containing all children etc.
;   edx: pointer to the next source line after the last processed.
;------------------------------------------------------------------------
proc CompileSourceTemplate, .ptrSource
begin
        push    esi edi ebx
        mov     esi, [.ptrSource]
        invoke  IsBadStringPtrA, esi, -1
        test    eax, eax
        jnz     .errorformat

.compileloop:
        stdcall GetMem, sizeof.TWinTemplateDT
        mov     edi, eax

        stdcall CreateArray, 4
        mov     [edi+TWinTemplateDT.children], eax

        cmp     dword [esi], 'Wind'
        jne     .errorformat

        cmp     word [esi+4], 'ow'
        jne     .errorformat

        cmp     byte [esi+6], ' '
        jne     .errorformat

        add     esi, 7
        mov     ebx, esi        ; begin of the label

.search:
        call    SearchComma
        jc      .errorformat

.getname:
        mov     byte [esi-1], 0

        stdcall StrDup, ebx     ; creates string with name of the window.
        mov     [edi+TWinTemplateDT.hName], eax

; get TWinTemplateDT.flags value
        call    SearchNonSpace
        jc      .errorformat
        mov     ebx, esi
        call    SearchComma
        jc      .errorformat
        mov     byte [esi-1], 0

        stdcall StrToFasmNum, ebx
        jc      .errorformat

        mov     [edi+TWinTemplateDT.flags], al

; get TWinTemplateDT.Align value
        call    SearchNonSpace
        jc      .errorformat
        mov     ebx, esi
        call    SearchComma
        jc      .errorformat
        mov     byte [esi-1], 0

        stdcall StrToFasmNum, ebx
        jc      .errorformat

        mov     [edi+TWinTemplateDT.Align], al

; get TWinTemplateDT.ptrClass
        call    SearchNonSpace
        jc      .errorformat
        cmp     byte [esi], "'"
        jne     .errorformat

        inc     esi
        mov     ebx, esi
        call    SearchQuote
        jc      .errorformat

        mov     byte [esi-1], 0

        stdcall StrDup, ebx
        mov     [edi+TWinTemplateDT.ptrClass], eax

; get TWinTemplateDT.ptrText
        call    SearchQuote
        jc      .errorformat

        mov     ebx, esi
        call    SearchQuote
        jc      .errorformat

        mov     byte [esi-1], 0
        stdcall StrDup, ebx
        mov     [edi+TWinTemplateDT.ptrText], eax

; get TWinTemplateDT.style
        add     esi, 2
        call    SearchNonSpace
        jc      .errorformat

        mov     ebx, esi
        call    SearchComma
        jc      .errorformat

        mov     byte [esi-1], 0
        stdcall StrToFasmNum, ebx
        jc      .errorformat

        mov     [edi+TWinTemplateDT.style], eax

; get TWinTemplateDT.styleEx

        call    SearchNonSpace
        jc      .errorformat
        mov     ebx, esi

        call    SearchComma
        jc      .errorformat

        mov     byte [esi-1], 0
        stdcall StrToFasmNum, ebx
        jc      .errorformat

        mov     [edi+TWinTemplateDT.styleEx], eax

; get  TWinTemplateDT.ID

        call    SearchNonSpace
        jc      .errorformat
        mov     ebx, esi

        call    SearchComma
        jc      .errorformat

        mov     byte [esi-1], 0
        stdcall StrToFasmNum, ebx
        jc      .errorformat

        mov     [edi+TWinTemplateDT.ID], ax

; get  TWinTemplateDT.left
        call    SearchNonSpace
        jc      .errorformat
        mov     ebx, esi

        call    SearchComma
        jc      .errorformat

        mov     byte [esi-1], 0
        stdcall StrToFasmNum, ebx
        jc      .errorformat

        mov     [edi+TWinTemplateDT.left], ax

; get  TWinTemplateDT.top

        call    SearchNonSpace
        jc      .errorformat
        mov     ebx, esi

        call    SearchComma
        jc      .errorformat

        mov     byte [esi-1], 0
        stdcall StrToFasmNum, ebx
        jc      .errorformat

        mov     [edi+TWinTemplateDT.top], ax

; get  TWinTemplateDT.width

        call    SearchNonSpace
        jc      .errorformat
        mov     ebx, esi

        call    SearchComma
        jc      .errorformat

        mov     byte [esi-1], 0
        stdcall StrToFasmNum, ebx
        jc      .errorformat

        mov     [edi+TWinTemplateDT.width], ax

; get  TWinTemplateDT.height

        call    SearchNonSpace
        jc      .errorformat
        mov     ebx, esi

        call    SearchComma
        jc      .errorformat

        mov     byte [esi-1], 0
        stdcall StrToFasmNum, ebx
        jc      .errorformat

        mov     [edi+TWinTemplateDT.height], ax

; get TWinTemplateDT.WinProc, i.e. the label to the user procedure.
        stdcall StrNew
        mov     [edi+TWinTemplateDT.WinProc], eax

        call    SearchNonSpace
        jc      .errorformat
        cmp     byte [esi], '0'
        je      .nowinproc

        mov     ebx, esi
        call    SearchComment
        jc      .errorformat

        mov     byte [esi-1], 0
        stdcall StrCopy, [edi+TWinTemplateDT.WinProc], ebx

.nowinproc:
        call    SkipToNextLine  ; go to the next line to get next window.

; the window template is created, so what to do?
        test    [edi+TWinTemplateDT.flags], wtParent
        jz      .childrenok

.childrenloop:
        stdcall CompileSourceTemplate, esi
        mov     esi, edx                     ; next line of source
        mov     ebx, eax                     ; TWinTemplateDT of child.

        test    ebx, ebx
        jz      .errorformat

        stdcall AddArrayItems, [edi+TWinTemplateDT.children], 1
        mov     [edi+TWinTemplateDT.children], edx
        mov     [eax], ebx

        test    [ebx+TWinTemplateDT.flags], wtEnd
        jz      .childrenloop

.childrenok:
        stdcall VacuumArray, [edi+TWinTemplateDT.children]
        mov     [edi+TWinTemplateDT.children], edx

        mov     eax, edi
        mov     edx, esi

        pop     ebx edi esi
        return

.errorformat:
        xor     eax, eax
        pop     ebx edi esi
        return
endp


proc SearchComma
begin
.search:
        lodsb
        cmp     al, ','
        je      .found

        cmp     al, $0d
        je      .error
        cmp     al, $0a
        je      .error
        cmp     al, ' '
        je      .error
        cmp     al, $09
        jne     .search

.error:
        stc
        return

.found:
        clc
        return
endp


proc SkipToNextLine
begin
.searchloop:
        lodsb
        test    al,al
        jz      .error
        cmp     al, $0d         ; 0000 1101
        je      .found
        xor     al, $0a         ; 0000 1010
        jne     .searchloop
.found:
        xor     al, $07         ; CR <-> LF
        cmp     [esi], al
        jne     .exit
        inc     esi
.exit:
        clc
        return

.error:
        stc
        dec     esi
        return
endp


proc SearchNonSpace
begin
.loop:
        lodsb
        test    al,al
        jz      .error
        cmp     al, $0d
        je      .error
        cmp     al, $0a
        je      .error

        cmp     al, ' '
        je      .loop
        cmp     al, $09
        je      .loop

        dec     esi
        clc
        return

.error:
        dec     esi
        stc
        return
endp


proc SearchQuote
begin
.search:
        lodsb
        cmp     al, "'"
        je      .found

        cmp     al, $0d
        je      .error
        cmp     al, $0a
        jne     .search

.error:
        stc
        return

.found:
        clc
        return
endp

proc SearchComment
begin
.search:
        lodsb
        cmp     al, ";"
        je      .found

        cmp     al, $0d
        je      .error
        cmp     al, $0a
        je      .error
        cmp     al, ' '
        je      .error
        cmp     al, $09
        jne     .search

.error:
        stc
        return

.found:
        clc
        return
endp






;--------------------------------------------------
; Creates the form from design window template
;--------------------------------------------------
proc CreateDesignWindow, .ptrTemplate
begin
        push    esi

        mov     esi, [.ptrTemplate]
        cmp     [esi+TWinTemplateDT.hwnd], 0
        je      @f
        invoke  DestroyWindow, [esi+TWinTemplateDT.hwnd]
@@:
        cmp     [esi+TWinTemplateDT.hSizer], 0
        je      @f

; deal with sizer window


@@:
        mov     edx, [hApplication]
        mov     eax, [.ptrTemplate]
        mov     esi, [esi+TWinTemplateDT.parent]
        test    esi, esi
        jz      @f
        mov     edx, [esi+TWinTemplateDT.hwnd]
@@:
        stdcall _DoCreateDesignWindow, edx, [.ptrTemplate]
        push    eax

        mov     eax, [.ptrTemplate]
        stdcall GetSizer
        invoke  SendMessageA, eax, SZM_UPDATESIZE, 0, 0

        mov     eax, [.ptrTemplate]
        stdcall ReorderChildren, [eax+TWinTemplateDT.parent]

        pop     eax
        pop     esi
        return
endp


proc ReorderChildren, .ptrTemplate
begin
        push    esi edi ebx
        cmp     [.ptrTemplate], 0
        je      .finish

        mov     esi, [.ptrTemplate]
        mov     esi, [esi+TWinTemplateDT.children]
        mov     ebx, [esi+TArray.count]

        mov     edi, HWND_BOTTOM

.loop:
        dec     ebx
        js      .endloop

        mov     eax, dword [esi+TArray.array]
        push    SWP_NOSIZE or SWP_NOMOVE
        push    0 0 0 0
        push    edi
        push    [eax+TWinTemplateDT.hwnd]
        mov     edi, [eax+TWinTemplateDT.hwnd]
        invoke  SetWindowPos
        add     esi, 4
        jmp     .loop

.endloop:
        mov     eax, [.ptrTemplate]
        stdcall AlignChildren, [eax+TWinTemplateDT.hwnd]

.finish:
        pop     ebx edi esi
        return
endp



;----- internally called from CreateDesignWindow -----
proc _DoCreateDesignWindow, .hParent, .ptrTemplate
begin
        push    esi edi ebx

        mov     esi, [.ptrTemplate]

        movsx   eax, [esi+TWinTemplateDT.left]
        movsx   ebx, [esi+TWinTemplateDT.top]
        movsx   ecx, [esi+TWinTemplateDT.width]
        movsx   edx, [esi+TWinTemplateDT.height]
        movzx   edi, [esi+TWinTemplateDT.ID]

        push    NULL
        push    [hInstance]
        push    edi
        push    [.hParent]
        push    edx ecx ebx eax
        mov     eax, [esi+TWinTemplateDT.style]
        or      eax, WS_VISIBLE
        mov     ecx, [.hParent]
        cmp     ecx, [hApplication]
        jne     @f
        or      eax, WS_SIZEBOX
        and     eax, not WS_CHILD
@@:
        push    eax

        stdcall StrPtr, [esi+TWinTemplateDT.ptrText]
        push    eax
        stdcall StrPtr, [esi+TWinTemplateDT.ptrClass]
        push    eax
        push    [esi+TWinTemplateDT.styleEx]
        invoke  CreateWindowExA
        test    eax, eax
        jz      .errorcreate

        mov     [esi+TWinTemplateDT.hwnd], eax

; disable all internal windows
        invoke  EnumChildWindows, [esi+TWinTemplateDT.hwnd], procDisableCallback, 0

        cmp     [esi+TWinTemplateDT.parent], 0
        jne     .sizerok

; This is not proper way of handling sizer window in all cases.
; for example when there is already a sizer in the window and it
; have some windows selected.
        invoke  CreateWindowExA, WS_EX_TRANSPARENT, cSizerClassName, NULL,        \
                                WS_CHILD, 0, 0, 0, 0, [esi+TWinTemplateDT.hwnd], \
                                0, [hInstance], 0
        mov     [esi+TWinTemplateDT.hSizer], eax

.sizerok:
        stdcall SubclassWindow, [esi+TWinTemplateDT.hwnd], procDesignControl
        invoke  SetPropA, [esi+TWinTemplateDT.hwnd], [propTemplateDT], esi
        movzx   eax, [esi+TWinTemplateDT.Align]
        stdcall SetAlign, [esi+TWinTemplateDT.hwnd], eax

        invoke  SendMessageA, [.hParent], WM_GETFONT, 0, 0
        stdcall ControlSetFont, [esi+TWinTemplateDT.hwnd], eax

        mov     eax, [esi+TWinTemplateDT.children]
        cmp     [eax+TArray.count], 0
        je      .childrenOK

        mov     edi, [esi+TWinTemplateDT.children]
        mov     ebx, [edi+TArray.count]

.childrenloop:
        dec     ebx
        js      .childrenOK

        mov     eax, [edi+TArray.array]
        mov     [eax+TWinTemplateDT.parent], esi

        stdcall _DoCreateDesignWindow, [esi+TWinTemplateDT.hwnd], eax
        add     edi, 4
        jmp     .childrenloop

.childrenOK:
        stdcall SearchForDesignTimeInfo, [esi+TWinTemplateDT.ptrClass], [esi+TWinTemplateDT.style]
        mov     [esi+TWinTemplateDT.DesignInfo], eax

        mov     eax, esi
        pop     ebx edi esi
        return

.errorcreate:
        stdcall LastError
        jmp     .childrenOK
endp


proc procDisableCallback, .hwnd, .dummy
begin
        invoke  EnableWindow, [.hwnd], FALSE
        mov     eax, 1
        return
endp


proc CountDesignWindows, .ptrWinTemplateDT
begin
        push    esi edi ebx
        mov     eax, [.ptrWinTemplateDT]
        mov     esi, [eax+TWinTemplateDT.children]
        mov     ebx, [esi+TArray.count]
        xor     edi, edi

.childrenloop:
        dec     ebx
        js      .endchildren
        stdcall CountDesignWindows, [esi+4*ebx+TArray.array]
        add     edi, eax
        jmp     .childrenloop

.endchildren:
        lea     eax, [edi+1]
        pop     ebx edi esi
        return
endp


iglobal
  property propTemplateDT, 'TemplateDT'
endg
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/formutils.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
proc PseudoAlign, .hwnd, .ptrRect, .winalign
.bounds TBounds
begin
        lea     eax, [.bounds]
        stdcall AlignWindow, [.hwnd], [.ptrRect], eax, [.winalign]
        test    eax, eax
        jz      .finish
        invoke  SetWindowPos, [.hwnd], NULL,                                                     \
                              [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height],      \
                              SWP_NOZORDER or SWP_NOCOPYBITS
.finish:
        return
endp



proc AutoArrangeWindows
.workrect RECT
.rect1    RECT
.rect2    RECT
begin
        push    ebx

        lea     ebx, [.workrect]
        invoke  GetClientRect, [hMainWindow], ebx
        mov     [.workrect.bottom], 80        ; set it to 24 in order to hide component palette.
        invoke  AdjustWindowRectEx, ebx, [MainForm+TWinTemplate.style], TRUE, [MainForm+TWinTemplate.styleEx]

        mov     eax, [.workrect.bottom]
        mov     ecx, [.workrect.right]
        sub     eax, [.workrect.top]
        sub     ecx, [.workrect.left]

        invoke  SetWindowPos, [hMainWindow], 0, 0, 0, ecx, eax, SWP_NOMOVE or SWP_NOZORDER

        lea     ebx, [.workrect]
        invoke  SystemParametersInfoA, SPI_GETWORKAREA,0,ebx,0
        stdcall PseudoAlign, [hMainWindow], ebx, waTop


        invoke  IsWindowVisible, [hProjManager]
        mov     esi, eax
        invoke  IsWindowVisible, [hPropEditor]
        test    esi, eax
        jnz     .both

        mov     ecx, [hProjManager]
        test    esi, esi
        jnz     .leftpane
        mov     ecx, [hPropEditor]
        test    eax, eax
        jz      .client

.leftpane:
        stdcall PseudoAlign, ecx, ebx, waLeft
        jmp     .client

.both:
        stdcall PseudoAlign, [hPropEditor], ebx, waLeft

        lea     eax, [.rect1]
        invoke  GetWindowRect, [hPropEditor], eax

        mov     eax, [.rect1.left]
        mov     ecx, [.rect1.right]
        sub     ecx, eax
        mov     [.rect2.left], eax
        mov     [.rect2.right], ecx
        mov     [.rect1.right], ecx

        mov     ecx, [.rect1.top]
        mov     eax, [.rect1.bottom]
        sub     eax, ecx

        push    eax

        xor     edx, edx
        mov     ecx, 3
        div     ecx          ; eax = height /3

        pop     ecx
        sub     ecx, eax

        mov     [.rect1.bottom], eax
        mov     [.rect2.bottom], ecx
        add     eax, [.rect1.top]
        mov     [.rect2.top], eax


        invoke  SetWindowPos, [hPropEditor], NULL, [.rect1.left], [.rect1.top], [.rect1.right], [.rect1.bottom], SWP_NOZORDER or SWP_NOACTIVATE
        invoke  SetWindowPos, [hProjManager], NULL, [.rect2.left], [.rect2.top], [.rect2.right], [.rect2.bottom], SWP_NOZORDER or SWP_NOACTIVATE

.client:
        stdcall PseudoAlign, [hEditorsHost], ebx, waClient

        invoke  SetFocus, [hEditorsHost]

        pop     ebx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































Deleted source/frmStyleEditor.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
;<ff
Window frmStyleEditor, 3, 0, 'TForm', 'Select styles', $6800000, $10080, 0, 225, 202, 360, 247, StyleEditorWinProc;
Window NONE, 0, 0, 'EDIT', '', $50810084, $0, 1000, 0, 200, 208, 20, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50010000, $0, 2, 288, 200, 64, 20, 0;
Window NONE, 0, 3, 'COMBOBOX', 'Combobox', $50010003, $0, 102, 0, 0, 352, 150, 0;
Window NONE, 0, 3, 'SysListView32', 'ListView', $50814005, $0, 101, 0, 21, 352, 171, 0;
Window NONE, 2, 0, 'BUTTON', 'OK', $50010001, $0, 1, 216, 200, 64, 20, 0;
;ff>
winproc StyleEditorWinProc

.lvc LVCOLUMN
.lvi LVITEM
.ctrl dd ?
.style dd ?
.subtype dd ?
.cursub  dd ?
.index   dd ?

begin

ondefault
        stc
        return

onmessage WM_COMMAND
        cmp     word [.wparam+2], CBN_SELCHANGE
        jne     .ondefault
        jmp     .itemchanged

onmessage WM_NOTIFY

        mov     esi,[.lparam]
        mov     eax,[esi+NMHDR.code]
        cmp     eax, LVN_ITEMCHANGED
        je      .itemchanged
        cmp     eax, LVN_ITEMACTIVATE
        jne     .ondefault

        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_GETITEMSTATE, [esi+NMLISTVIEW.iItem], LVIS_STATEIMAGEMASK

        xor     eax, $3000
        mov     [.lvi.state], eax
        mov     [.lvi.stateMask], LVIS_STATEIMAGEMASK
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_SETITEMSTATE, [esi+NMLISTVIEW.iItem], eax

        clc
        return

.itemchanged:
        stdcall CreateBitValue, [.hwnd]
        mov     ebx, eax

        invoke  SetWindowLongA, [.hwnd], 8, ebx

        stdcall NumToStr, ebx, ntsHex or ntsUnsigned
        push    eax
        stdcall StrCharInsert, eax, '$', 0

        stdcall StrPtr, eax
        invoke  SendDlgItemMessageA, [.hwnd], 1000, WM_SETTEXT, 0, eax
        stdcall StrDel ; from the stack.

        clc
        return

onmessage FM_AFTERCREATE
        invoke  SendDlgItemMessageA, [.hwnd], 101,               \
                LVM_SETEXTENDEDLISTVIEWSTYLE, 0,                \
                LVS_EX_CHECKBOXES or LVS_EX_INFOTIP

        lea     eax, [.lvc]
        mov     [eax+LVCOLUMN.mask], LVCF_WIDTH or LVCF_FMT or LVCF_SUBITEM
        mov     [eax+LVCOLUMN.cx], 100
        mov     [eax+LVCOLUMN.fmt], LVCFMT_LEFT
        mov     [eax+LVCOLUMN.iSubItem], 0
        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_INSERTCOLUMN, 0, eax

        lea     eax, [.lvc]
        mov     [eax+LVCOLUMN.iSubItem], 1
        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_INSERTCOLUMN, 1, eax

        lea     eax, [.lvc]
        mov     [eax+LVCOLUMN.iSubItem], 2
        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_INSERTCOLUMN, 2, eax

        clc
        return

onmessage WM_INITDIALOG
        invoke  GetWindowLongA, [.hwnd], 4
        mov     [.ctrl], eax

        mov     ecx, [eax+TWinTemplateDT.style]
        mov     edi, [eax+TWinTemplateDT.DesignInfo]

        mov     [.style], ecx
        and     ecx, [edi+TDesignTimeInfo.SubtypeMask]
        mov     [.subtype], ecx

        invoke  SetWindowLongA, [.hwnd], 8, [eax+TWinTemplateDT.style]

; pointer to the subtype list of styles.
        mov     esi, [edi+TDesignTimeInfo.SubtypeRange]
        cmp     esi, edi
        jne     .wehavesubtypes

        invoke  SendDlgItemMessageA, [.hwnd], 102, CB_ADDSTRING, 0, cDefaultSubtype
        invoke  SendDlgItemMessageA, [.hwnd], 102, CB_SETITEMDATA, 0, 0
        invoke  SendDlgItemMessageA, [.hwnd], 102, CB_SETCURSEL, 0, 0
        jmp     .checksubtypescount

.wehavesubtypes:
        lodsd
        mov     ebx, eax        ; count of subtypes

.addsubtypes:
        dec     ebx
        js      .checksubtypescount

        lodsd   ; value
        mov     [.cursub], eax

        lodsb
        push    esi
        movzx   eax, al
        add     esi, eax

        invoke  SendDlgItemMessageA, [.hwnd], 102, CB_ADDSTRING, 0     ; lparam is already in the stack
        mov     [.index], eax

        invoke  SendDlgItemMessageA, [.hwnd], 102, CB_SETITEMDATA, [.index], [.cursub]

        mov     eax, [.cursub]
        cmp     eax, [.subtype]
        jne     .skiphint

        invoke  SendDlgItemMessageA, [.hwnd], 102, CB_SETCURSEL, [.index], 0

.skiphint:
        lodsb
        movzx   eax, al
        add     esi, eax
        jmp     .addsubtypes

.checksubtypescount:
        invoke  SendDlgItemMessageA, [.hwnd], 102, CB_GETCOUNT, 0, 0
        cmp     eax, 1
        ja      .addstyles

        invoke  GetDlgItem, [.hwnd], 102
        invoke  EnableWindow, eax, FALSE

.addstyles:
        mov     esi, [edi+TDesignTimeInfo.StyleNames]
        cmp     esi, edi
        je      @f
        call    .AddWinStylesArray
@@:
        mov     esi, CommonStyles
        call    .AddWinStylesArray

; set the width of the list view columns
        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_SETCOLUMNWIDTH, 0, LVSCW_AUTOSIZE
        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_SETCOLUMNWIDTH, 1, LVSCW_AUTOSIZE
        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_SETCOLUMNWIDTH, 2, LVSCW_AUTOSIZE

        clc
        return


.AddWinStylesArray:
        lodsd
        mov     ebx, eax        ; count of items.

.addloop:
        dec     ebx
        jns     .doloop
        retn

.doloop:
        lodsd   ; the value
        mov     [.lvi.lParam], eax

        lodsb
        movzx   eax, al
        mov     [.lvi.pszText], esi
        add     esi, eax              ; string with help text.

        mov     [.lvi.mask], LVIF_TEXT or LVIF_PARAM
        mov     [.lvi.iItem], 0
        mov     [.lvi.iSubItem], 0

        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_INSERTITEM, 0, eax

        mov     [.lvi.iItem], eax

        mov     [.lvi.stateMask], LVIS_STATEIMAGEMASK
        mov     [.lvi.state], $1000

        mov     eax, [.style]
        and     eax, [.lvi.lParam]
        cmp     eax, [.lvi.lParam]
        jne     .setcheckmark

        add     [.lvi.state], $1000

.setcheckmark:
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_SETITEMSTATE, [.lvi.iItem], eax

        mov     [.lvi.iSubItem], 1
        stdcall NumToStr, [.lvi.lParam], ntsHex or ntsUnsigned
        push    eax
        stdcall StrCharInsert, eax, '$', 0
        stdcall StrPtr, eax
        mov     [.lvi.pszText], eax
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_SETITEMTEXT, [.lvi.iItem], eax
        stdcall StrDel ; from the stack.

        mov     [.lvi.iSubItem], 2
        lodsb
        movzx   eax, al
        mov     [.lvi.pszText], esi
        add     esi, eax                ; next style.

        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_SETITEMTEXT, [.lvi.iItem], eax

        jmp     .addloop


onmessage WM_SHOWWINDOW
        cmp     [.wparam], FALSE
        jne     .ondefault

        invoke  GetWindowLongA, [.hwnd], GWL_HWNDPARENT
        invoke  GetDlgItem, eax, 101
        mov     ebx, eax

        invoke  GetDlgItem, [.hwnd], 1000
        stdcall GetControlText, eax, 0
        push    eax

        stdcall StrPtr, eax
        invoke  SendMessageA, ebx, PEM_SETEDITORTEXT, 0, eax
        stdcall StrDel
        jmp     .ondefault
endwp





proc CreateBitValue, .hwnd
.lvi LVITEM
begin
        push    esi edi ebx
        xor     edi, edi
        xor     ebx, ebx

        invoke  SendDlgItemMessageA, [.hwnd], 102, CB_GETCURSEL, ebx, ebx
        cmp     eax, CB_ERR
        je      .getchecked

        invoke  SendDlgItemMessageA, [.hwnd], 102, CB_GETITEMDATA, eax, ebx
        or      edi, eax

.getchecked:
        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_GETITEMCOUNT, ebx, ebx
        mov     esi, eax

.itemloop:
        dec     esi
        js      .endloop

        mov     [.lvi.iItem], esi
        mov     [.lvi.iSubItem], ebx
        mov     [.lvi.mask], LVIF_PARAM or LVIF_STATE
        mov     [.lvi.stateMask], LVIS_STATEIMAGEMASK
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], 101, LVM_GETITEM, ebx, eax

        cmp     [.lvi.state], $1000
        je      .itemloop

        or      edi, [.lvi.lParam]
        jmp     .itemloop

.endloop:
        invoke  GetWindowLongA, [.hwnd], 4
        mov     eax, [eax+TWinTemplateDT.DesignInfo]

        and     edi, [eax+TDesignTimeInfo.StyleMaskAnd]
        or      edi, [eax+TDesignTimeInfo.StyleMaskOr]

        mov     eax, edi
        pop     ebx edi esi
        return
endp




iglobal
  cDefaultSubtype db 'Default',0

  CommonStyles:
    WinStyles                                                                               \
      WS_ICONICPOPUP, '..',                                               \
      WS_POPUP,       'Creates a pop-up window. This style cannot be used with the WS_CHILD style.',                                               \
      WS_CHILD,       'Creates a child window. This style cannot be used with the WS_POPUP style.',                                               \
      WS_MINIMIZE,    'Create window that is initially minimized.',       \
      WS_VISIBLE,     'The window is visible.',                           \
      WS_DISABLED,    'The window is disabled.',                          \
      WS_CLIPSIBLINGS,'Clip siblings.', \
      WS_CLIPCHILDREN,'Excludes the area occupied by child windows when drawing occurs within the parent window. This style is used when creating the parent window.',                                    \
      WS_MAXIMIZE,    'Creates a window that is initially maximized.',    \
      WS_CAPTION,     'Creates a window that has a title bar (includes the WS_BORDER style).', \
      WS_BORDER,      'Creates a window that has a thin-line border.',     \
      WS_DLGFRAME,    'Creates a window that has a border of a style typically used with dialog boxes. A window with this style cannot have a title bar.',    \
      WS_VSCROLL,     'Creates a window that has a vertical scroll bar.',  \
      WS_HSCROLL,     'Creates a window that has a horizontal scroll bar.',   \
      WS_SYSMENU,     'Creates a window that has a window-menu on its title bar. The WS_CAPTION style must also be specified.',       \
      WS_SIZEBOX,     'Creates a window that has a sizing border. Same as the WS_THICKFRAME style.',       \
      WS_TABSTOP,     'Specifies a control that can receive the keyboard focus when the user presses the TAB key.',   \
      WS_GROUP,       'Specifies the first control of a group of controls.', \
      WS_MAXIMIZEBOX, 'Creates a window that has a Maximize button. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified. ',\
      WS_MINIMIZEBOX, 'Creates a window that has a Minimize button. Cannot be combined with the WS_EX_CONTEXTHELP style. The WS_SYSMENU style must also be specified. '
endg






;----------------
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































Deleted source/help.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
cHHCtrlLib  text "HHCTRL.OCX"
cHtmlHelpA  text "HtmlHelpA"
;  cFreshHelp    db "%fresh%\"
;  cFreshDefHelp db "doc\freshguide.chm", 0
;  .size = $ - cFreshDefHelp


uglobal
  HtmlHelp     dd ?
  hHHCtrl      dd ?
  ptrHelpFiles dd ?     ; points to array of dwords with handles of strings with help filenames.
endg

proc InitHelp
begin
        invoke  LoadLibraryA, cHHCtrlLib
        mov     [hHHCtrl],eax
        or      eax,eax
        jz      .finish

        invoke  GetProcAddress, eax, cHtmlHelpA

.finish:
        mov     [HtmlHelp],eax
        return
endp



finalize FreeHelpList
begin
        push    esi ebx

        mov     esi, [ptrHelpFiles]
        test    esi, esi
        jz      .endfree

        mov     ebx, [esi+TArray.count]
.cleanloop:
        dec     ebx
        js      .endclean

        stdcall StrDel, [esi+TArray.array+4*ebx]
        jmp     .cleanloop

.endclean:
        stdcall FreeMem, esi
        mov     [ptrHelpFiles], 0

.endfree:
        pop     ebx esi
        return
endp



proc RebuildHelpFilesList
begin
        stdcall FreeHelpList
        stdcall CreateArray, 4
        mov     [ptrHelpFiles], eax

        stdcall ReadSectionFromIni, [hIniFileName], cHelpSection, _AddOneHelpFile, 0
        return
endp



proc _AddOneHelpFile, .ptrName, .dummy
begin
        stdcall StrDup, [.ptrName]
        push    eax
        stdcall AddArrayItems, [ptrHelpFiles], 1
        mov     [ptrHelpFiles], edx
        popd    [eax]
        clc
        return
endp



proc OnHelp, .wparam, .lparam
.filecount dd ?
.str       rb 256
begin
        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, 0, 0
        test    eax, eax
        jz      .finish
        lea     ebx, [.str]
        invoke  SendMessageA, eax, AEM_GETWORDATCARET, 256, ebx

        mov     esi, [ptrHelpFiles]
        test    esi, esi
        jz      .finish

        push    [esi+TArray.count]
        pop     [.filecount]

        cmp     [.filecount], 0
        je      .finish

        xor     edi, edi
.searchloop:
        stdcall SearchOneHelp, [esi+TArray.array+4*edi], ebx, FALSE
        jc     .finish
        inc    edi
        cmp    edi, [.filecount]
        jne    .searchloop

        stdcall SearchOneHelp, [esi+TArray.array+4*edi-4], ebx, TRUE

.finish:
        return
endp



proc SearchOneHelp, .hFileName, .ptrWord, .flagIndex
  .aklink    HH_AKLINK
begin
        push    ebx esi edi

        stdcall StrLen, [.hFileName]
        mov     ecx, eax
        stdcall StrPtr, [.hFileName]

.extloop:
        dec     ecx
        js      .notfound

        cmp     byte [eax+ecx], '.'
        jne     .extloop

        mov     ecx, dword [eax+ecx]    ; get the extension
        or      ecx, $20202000          ; case insensitive

        cmp     ecx, '.hlp'
        je      .winhelp

        cmp     ecx, '.chm'
        je      .htmlhelp

.notfound:
        clc
        pop     edi esi ebx
        return

.htmlhelp:
        cmp     [HtmlHelp], NULL
        je      .notfound

        xor     eax, eax
        mov     [.aklink.cbStruct], sizeof.HH_AKLINK
        mov     [.aklink.fReserved], eax
        mov     [.aklink.pszUrl], eax
        mov     [.aklink.pszMsgText], eax
        mov     [.aklink.pszMsgTitle], eax
        mov     [.aklink.pszWindow], eax

        push    [.ptrWord]
        pop     [.aklink.pszKeywords]

        push    [.flagIndex]
        pop     [.aklink.fIndexOnFail]

        stdcall StrPtr, [.hFileName]
        mov     ebx,eax
        lea     eax, [.aklink]

        mov     ecx, HH_KEYWORD_LOOKUP
        cmp     [eax+HH_AKLINK.pszKeywords], 0
        jne     @f
        mov     ecx, HH_DISPLAY_TOC
@@:
        invoke  HtmlHelp, NULL, ebx, ecx, eax
        test    eax,eax   ; if eax==0 then given word doesn't exist in the help
        jz      .notfound   ;  file - so we search in user defined help file

.found:
        stc
        pop     edi esi ebx
        return


.winhelp:
        stdcall StrPtr, [.hFileName]

        cmp     [.ptrWord], 0
        jne     @f

        invoke  WinHelpA, [hEditorsHost], eax, HELP_FINDER, 0
        jmp     .found

@@:
        invoke  WinHelpA, [hEditorsHost], eax, HELP_PARTIALKEY, [.ptrWord]

        cmp     [.flagIndex], 0
        jne     .found

        invoke  FindWindowA, cWinHelpName, 0
        mov     ebx, eax

        invoke  SendMessageA, ebx, WM_GETTEXTLENGTH, 0, 0
        invoke  IsWindowVisible, ebx
        test    eax, eax
        jnz     .found

        stdcall StrPtr, [.hFileName]
        invoke  WinHelpA, [hEditorsHost], eax, HELP_QUIT, 0

.waitforclose:
        invoke  FindWindowA, cWinHelpName, 0
        test    eax, eax
        jnz     .waitforclose

        jmp     .notfound
endp


cWinHelpName text 'MS_WINHELP'
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































Deleted source/ideparams.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
; This module is responsible for creating/reading/saving of common for
; the whole IDE parameters from the main .ini file.
;

cParamSection text 'IDE settings'
cDebugerKey   text 'Debugger'
cHelpSection  text 'HelpFiles'

cAutoHideKey  text 'AutoHideEnable'
cAutoHideTime text 'AutoHideTime'

cErrStr2      text 'ERR!'


uglobal
  flagAutoHide dd ?
  timeAutoHide dd ?
  blockAutoHide dd ?
endg



proc CheckParams
begin
        invoke  SendMessageA, [frmMsg], MWM_CLEARMESSAGES, 0, 0

; Check ini file consistency...
        stdcall StrPtr, [hIniFileName]
        mov     esi, eax

        stdcall FileExists, esi
        jnc     .doCheckParams  ; if the file exists, go check params.

        stdcall FirstTimeInstall       ; try to create .ini file automatically

.doCheckParams:
        stdcall CheckFilesSection, cHelpSection, cHelpFileNotSet, cHelpFileNotExists
        stdcall CheckFileParam, cDebugerKey, cDebuggerNotSet, cDebuggerNotExists

; Load IDE options from the .ini file
        invoke  GetPrivateProfileIntA, cParamSection, cAutoHideKey, 0, esi
        mov     [flagAutoHide], eax
        invoke  GetPrivateProfileIntA, cParamSection, cAutoHideTime, 5000, esi
        mov     [timeAutoHide], eax

        stdcall RebuildHelpFilesList

        call SetAutoHideTimer
        return

  cHelpFileNotExists text  "Some of configured help files doesn't exists."
  cHelpFileNotSet    text  "Not any help file is set in IDE options.",0

  cDebuggerNotExists text  "Specified external debugger doesn't exists."
  cDebuggerNotSet    text  "No external debugger is set in IDE options."
endp



proc CheckFileParam, .ptrKeyName, .msgNotSet, .msgNotExists
begin
        stdcall GetParamFromINI, [.ptrKeyName]
        jc      .filenotset

        push    eax
        stdcall StrPtr, eax
        stdcall FileExists, eax
        jc      .notexists

        stdcall StrDel ; from the stack
        return

.notexists:
        stdcall StrDel ; from the stack
        stdcall AddCheckMessage, [.msgNotExists], mtError
        return

.filenotset:
        stdcall AddCheckMessage, [.msgNotSet], mtWarning
        return
endp


proc CheckFilesSection, .ptrSectionName, .msgNotSet, .msgNotExists
.count dd ?
.bad   dd ?
begin
        mov     [.count], 0
        mov     [.bad], 0
        lea     eax, [.count]
        stdcall ReadSectionFromIni, [hIniFileName], [.ptrSectionName], _OnCheckOneFile, eax

        cmp     [.count], 0
        je      .filenotset

        cmp     [.bad], 0
        jne     .notexists

.finish:
        return

.notexists:
        stdcall AddCheckMessage, [.msgNotExists], mtError
        return

.filenotset:
        stdcall AddCheckMessage, [.msgNotSet], mtWarning
        return
endp


proc _OnCheckOneFile, .ptrFileName, .ptrCounts
begin
        mov     esi, [.ptrCounts]
        inc     dword [esi]

        stdcall FileExists, [.ptrFileName]
        jnc     .finish

        inc     dword [esi+4]

.finish:
        clc
        return
endp



;-------------------------------------
; It tries to create proper ini file
; in the case that ini file does not
; exists.
;-------------------------------------
proc FirstTimeInstall
.str rb 1024
.filename dd ?
begin
        stdcall SearchTablePath, cPathsTableInc, _section_environment, cIncludeKey, 1, cNotFoundMsg1, esi
        stdcall SearchTablePath, cPathsTableMain, _section_environment, cFreshKey, 1, cNotFoundMsg2, esi
        stdcall SearchTablePath, cPathsTableLib, _section_environment, cLibKey, 1, cNotFoundMsg3, esi

        stdcall SearchTablePath, cFreshGuideTable, cHelpSection, help_first_key, 0, cErrorFreshGuide, esi
        return
endp

iglobal
  cFreshGuideTable dd  .guide1, .guide2, 0
  .guide1 db '../'
  .guide2 db 'doc/FreshGuide.chm', 0

  help_first_key db 'aaa', 0

  cErrorFreshGuide db 'FreshGuide.chm not found.'
endg





proc SearchTablePath, .ptrTable, .ptrSection, .ptrKey, .fPathOnly, .ptrErrorMsg, .ptrIniFile
  .str rb 1024
  .ptr dd ?
begin
        pushad

        mov     ebx, [.ptrTable]

.findloop:
        mov     ecx, [ebx]
        test    ecx, ecx
        jz      .notfound

        lea     edi, [.str]
        lea     eax, [.ptr]
        invoke  GetFullPathNameA, ecx, 1024, edi, eax
        stdcall FileExists, edi
        lea     ebx, [ebx+4]
        jc      .findloop

        cmp     [.fPathOnly], 0
        je      @f
        mov     eax, [.ptr]
        mov     byte [eax-1], 0

@@:
        invoke  WritePrivateProfileStringA, [.ptrSection], [.ptrKey], edi, [.ptrIniFile]

        clc
        popad
        return

.notfound:
        invoke  MessageBoxA, [hApplication], [.ptrErrorMsg], cNotFoundTtl, MB_ICONWARNING or MB_OK
        stc
        popad
        return
endp


iglobal
  cPathsTableInc dd cAutoPath1, cAutoPath2, 0
  cAutoPath2  db '..\'
  cAutoPath1  db 'include'
  cFincTestFile db '\finc.txt',0

  cPathsTableMain dd cAutoPath4, cAutoPath3, 0
  cAutoPath3  db '..\'
  cAutoPath4  db 'Fresh.exe',0

  cPathsTableLib dd cAutoPath6, cAutoPath5, 0
  cAutoPath5  db '..\'
  cAutoPath6  db 'freshlib'
  cLibTestFile db '\freshlib.inc',0
endg

cIncludeKey   text 'finc'
cFreshKey     text 'Fresh'
cLibKey       text 'lib'

cNotFoundMsg1 text "First time run procedure can't find include path automanically. Try to set it manualy in 'options|IDE params' menu.",     \
                     "You have to use 'finc' name for this path."
cNotFoundMsg2 text "First time run procedure can't find main program directory. Try to set it manually in 'options|IDE params' menu.",        \
                     "You have to use 'Fresh' name for this path.",0
cNotFoundMsg3 text "First time run procedure can't find FreshLib directory. Try to set it manually in 'options|IDE params' menu.",        \
                     "You have to use 'Lib' name for this path.",0
cNotFoundTtl  text 'Auto setup error'


proc AddCheckMessage, .ptrMessage, .msgType
.msg TFreshMsg
begin
        mov     eax, [.msgType]
        mov     ecx, [.ptrMessage]
        mov     [.msg.type], eax
        mov     [.msg.hMessage], ecx
        mov     [.msg.link.hFileName], 0

        lea     eax, [.msg]
        invoke  SendMessageA, [frmMsg], MWM_ADDMESSAGE, eax, TVI_ROOT
        return
endp




;------------------------------------------------
; Parces command line and opens the files.
;------------------------------------------------
proc ParseCommandLine
.num dd ?
begin
        pushad

        stdcall GetCmdArguments
        mov     esi, eax

        cmp     [esi+TArray.count], 2
        jb      .finish

        xor     ebx, ebx
        inc     ebx

.open_loop:
        stdcall OpenFileByName, [esi+TArray.array+4*ebx], NULL, TRUE
        inc     ebx
        cmp     ebx, [esi+TArray.count]
        jne     .open_loop

.finish:
        stdcall ListFree, esi, StrDel
        popad
        return
endp



proc GetParamFromINI, .ptrKeyName
.buff rb 1024
begin
        stdcall StrPtr, [hIniFileName]

        lea     ecx, [.buff]
        invoke  GetPrivateProfileStringA, cParamSection, [.ptrKeyName], cErrStr2, ecx, 1024, eax
        cmp     dword [.buff], 'ERR!'
        je      .error

        lea     eax, [.buff]
        stdcall StrDup, eax
        clc
        return

.error:
        xor     eax, eax
        stc
        return
endp





proc ReadSectionFromIni, .hIniFile, .hSectionName, .procCallback, .lparam
.ptrmem dd ?
begin
        push    ebx esi edi

        stdcall GetMem, 65536     ; should be enough
        mov     esi, eax
        mov     [.ptrmem], eax

        stdcall StrPtr, [.hIniFile]
        push    eax
        push    65536
        push    esi
        stdcall StrPtr, [.hSectionName]
        push    eax
        invoke  GetPrivateProfileSectionA ; parameters from the stack.

.addloop:
        cmp     byte [esi], 0
        je      .endofread

        pushad
        add     esi, 4  ; skip the key name
        stdcall [.procCallback], esi, [.lparam]
        popad
        jc      .endofread

        stdcall StrLen, esi
        lea     esi, [esi+eax+1]
        jmp     .addloop

.endofread:
        pushf
        stdcall FreeMem, [.ptrmem]
        popf
        pop     edi esi ebx
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






































































































































































































































































































































































































































































































































































































































































































Deleted source/images/About.gif.

cannot compute difference between binary files

Deleted source/images/Arrow.ico.

cannot compute difference between binary files

Deleted source/images/Bookmark.ico.

cannot compute difference between binary files

Deleted source/images/Categories.gif.

cannot compute difference between binary files

Deleted source/images/EditorApplets.gif.

cannot compute difference between binary files

Deleted source/images/Fresh.ico.

cannot compute difference between binary files

Deleted source/images/FreshBtnSmall.ico.

cannot compute difference between binary files

Deleted source/images/FreshNew.res.

cannot compute difference between binary files

Deleted source/images/IDEapplets.gif.

cannot compute difference between binary files

Deleted source/images/Messages.gif.

cannot compute difference between binary files

Deleted source/images/NewDlg.gif.

cannot compute difference between binary files

Deleted source/images/ToolBoxImg.gif.

cannot compute difference between binary files

Deleted source/images/files.gif.

cannot compute difference between binary files

Deleted source/images/form.ico.

cannot compute difference between binary files

Deleted source/images/hsplit.cur.

cannot compute difference between binary files

Deleted source/images/select.cur.

cannot compute difference between binary files

Deleted source/images/source.ico.

cannot compute difference between binary files

Deleted source/images/tbFresh.gif.

cannot compute difference between binary files

Deleted source/images/vsplit.cur.

cannot compute difference between binary files

Deleted source/images/work/About.gif.

cannot compute difference between binary files

Deleted source/images/work/About2.gif.

cannot compute difference between binary files

Deleted source/images/work/Arrow.ico.

cannot compute difference between binary files

Deleted source/images/work/Categories.gif.

cannot compute difference between binary files

Deleted source/images/work/EditorApplets.gif.

cannot compute difference between binary files

Deleted source/images/work/Fresh.ico.

cannot compute difference between binary files

Deleted source/images/work/FreshBtn.ico.

cannot compute difference between binary files

Deleted source/images/work/FreshBtnSmall.ico.

cannot compute difference between binary files

Deleted source/images/work/FreshMore.ico.

cannot compute difference between binary files

Deleted source/images/work/IDEapplets.gif.

cannot compute difference between binary files

Deleted source/images/work/Messages.gif.

cannot compute difference between binary files

Deleted source/images/work/NewDlg.bmp.

cannot compute difference between binary files

Deleted source/images/work/NewDlg.gif.

cannot compute difference between binary files

Deleted source/images/work/NewIcon.bmp.

cannot compute difference between binary files

Deleted source/images/work/Noname1.bmp.

cannot compute difference between binary files

Deleted source/images/work/PaintRoller.bmp.

cannot compute difference between binary files

Deleted source/images/work/SmallBug.bmp.

cannot compute difference between binary files

Deleted source/images/work/SmallBug2.bmp.

cannot compute difference between binary files

Deleted source/images/work/StilizedTurtle.gif.

cannot compute difference between binary files

Deleted source/images/work/ToolBoxImg.gif.

cannot compute difference between binary files

Deleted source/images/work/bug.bmp.

cannot compute difference between binary files

Deleted source/images/work/files.gif.

cannot compute difference between binary files

Deleted source/images/work/form.ico.

cannot compute difference between binary files

Deleted source/images/work/hsplit.cur.

cannot compute difference between binary files

Deleted source/images/work/select.cur.

cannot compute difference between binary files

Deleted source/images/work/source.ico.

cannot compute difference between binary files

Deleted source/images/work/tbFreshMini.gif.

cannot compute difference between binary files

Deleted source/images/work/tbFreshMiniBlack.gif.

cannot compute difference between binary files

Deleted source/images/work/tbFreshMiniBold.gif.

cannot compute difference between binary files

Deleted source/images/work/tux.bmp.

cannot compute difference between binary files

Deleted source/images/work/tux2.bmp.

cannot compute difference between binary files

Deleted source/images/work/vsplit.cur.

cannot compute difference between binary files

Deleted source/lister.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
uglobal
  hLister dd ?
  hSplitterLister dd ?
endg


proc InitListerWindow, .hParent
begin
        xor     ebx, ebx
        invoke   CreateWindowExA, ebx, cAsmEditClassName, NULL,          \
                 WS_CHILD or WS_CLIPCHILDREN or WS_HSCROLL or WS_VSCROLL or   \
                 ES_NOHIDESEL or AES_AUTOINDENT or AES_SMARTTABS or AES_CONSOLECARET ,      \
                 ebx, ebx , 200, ebx,                                 \
                 [.hParent],                                           \
                 ebx, [hInstance],                                    \
                 NULL

        mov     [hLister], eax
        mov     ebx, eax

        mov     edi, [CurrentSettings]
        invoke  CreateFontA, [edi+TEditorSettings.FontSize], 0, 0, 0, FW_NORMAL,                 \
                            0, 0, 0, [edi+TEditorSettings.FontCharset],                         \
                            OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,           \
                            FIXED_PITCH or FF_DONTCARE, [edi+TEditorSettings.ptrFontName]

        invoke  SendMessageA, ebx, WM_SETFONT, eax, TRUE
        invoke  SendMessageA, ebx, AEM_SETTHEME, 0, [edi+TEditorSettings.ptrTheme]
        invoke  SendMessageA, ebx, AEM_SETMARGINWIDTH, 0, 0
        invoke  SendMessageA, ebx, AEM_SETBOOKMARKICON, [hBookmarkIcon], 0

        stdcall SetAlign, ebx, waRight
        stdcall SubclassWindow, ebx, ListerWinProc

        invoke  CreateWindowExA, 0, cSplitterClassName, NULL,            \
                WS_CLIPSIBLINGS or WS_CHILD,              \
                0, 0, 0, 0, [.hParent], NULL, [hInstance], [hLister]
        mov     [hSplitterLister], eax
        invoke  SendMessageA, eax, SPM_SETCURSORS, resVSplit, resHSplit
        return
endp




proc ListerWinProc, .hwnd, .wmsg, .wparam, .lparam
.minaddr dd ?
.maxaddr dd ?
.line    dd ?
.beg     dd ?
.end     dd ?
begin
        cmp     [.wmsg], LM_SHOWLIST
        je      .lmshowlist

        cmp     [.wmsg], LM_SHOW
        je      .lmshow

        stc
        return

;-------- LM_SHOW ----------------------
.lmshow:
        invoke  ShowWindow, [hSplitterLister], [.wparam]
        invoke  ShowWindow, [.hwnd], [.wparam]
        clc
        return

;-------- LM_SHOWLIST ------------------

.lmshowlist:
        mov     esi, [.wparam]
        mov     edi, [ptrDebugInfo]
        test    edi, edi
        jnz     .doprocess
        clc
        return

.doprocess:
        lea     eax, [edi+TArray.array]
        mov     ecx, [edi+TArray.count]

        dec     ecx
        mov     [.minaddr], eax
        imul    ecx, [edi+TArray.itemsize]
        add     eax, ecx
        mov     [.maxaddr], eax

        mov     [.line], 1

        mov     ecx, [esi+TDebugLine.ptrFile]
        mov     edx, [esi+TDebugLine.LineNum]

        stdcall StrNew
        mov     ebx, eax

.searchbegin:
        cmp     esi, [.minaddr]
        je      .begfound

        cmp     [esi+TDebugLine.ptrFile-sizeof.TDebugLine], ecx   ; check prev
        jne     .begfound

        cmp     [esi+TDebugLine.LineNum-sizeof.TDebugLine], edx
        jne     .begfound

        sub     esi, sizeof.TDebugLine
        inc     [.line]
        jmp     .searchbegin

.begfound:
        mov     [.beg], esi
        mov     esi, [.wparam]

.searchend:
        cmp     esi, [.maxaddr]
        je      .endfound
        cmp     dword [esi+TDebugLine.ptrFile+sizeof.TDebugLine], ecx   ; check next
        jne     .endfound
        cmp     [esi+TDebugLine.LineNum+sizeof.TDebugLine], edx
        jne     .endfound

        add     esi, sizeof.TDebugLine
        jmp     .searchend

.endfound:
        mov     [.end], esi
        mov     esi, [.beg]

.getloop:
        mov     eax, [esi+TDebugLine.strLine]
        add     eax, [ptrListing]

        stdcall StrCat, ebx, eax
        stdcall StrCharCat, ebx, $0d
        add     esi, sizeof.TDebugLine
        cmp     esi, [.end]
        jbe     .getloop

        stdcall StrPtr, ebx
        invoke  SendMessageA, [hLister], WM_SETTEXT, 0, eax
        stdcall StrDel, ebx

        invoke  SendMessageA, [hLister], AEM_SETFOCUSLINE, [.line], 0

        clc
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































Deleted source/lister.inc.

1
2
winmessage LM_SHOWLIST     ; (ptrDebugLine, 0)
winmessage LM_SHOW         ; (fShow, 0)
<
<




Deleted source/mrulist.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
;****************************************
; Creates and manages MRU lists.
; This file was written very quick, so
; it will be commented later. Maybe...
;****************************************

proc CreateNewMRUList, .count
begin
        mov     eax, [.count]
        add     eax, 2          ; Two additional cells for capacity and count.
        shl     eax, 2          ;

        stdcall GetMem, eax
        pushd   [.count]
        popd    [eax]      ; capacity of the MRU list.
        return
endp


proc AddToMRUList, .ptrList, .hString
begin
        push    esi ebx

        mov     esi, [.ptrList]
        mov     ebx, [esi+4]    ; the count of MRU items.

.search:
        dec     ebx
        js      .notfound
        stdcall StrCompNoCase, [esi+4*ebx+8], [.hString]
        jnc     .search

; Found
        pushd   [esi+4*ebx+8]   ; The found one.
.move:
        inc     ebx
        cmp     ebx, [esi+4]
        je      .save

        pushd   [esi+4*ebx+8]
        popd    [esi+4*ebx+4]
        jmp     .move

.save:
        popd    [esi+4*ebx+4]   ; Move to the top.
        pop     ebx esi
        return

.notfound:
        mov     ebx, [esi+4]    ; Count
        cmp     ebx, [esi]      ; Capacity
        jl      .insertlast

        stdcall RemoveFromMRUList, [.ptrList], 0
        dec     ebx

.insertlast:
        stdcall StrNew
        mov     [esi+4*ebx+8], eax      ; On the last free place
        stdcall StrCopy, eax, [.hString]
        inc     dword [esi+4]

        pop     ebx esi
        return
endp


proc RemoveFromMRUList, .ptrList, .iItem
begin
        push    esi ebx

        mov     esi, [.ptrList]
        mov     ebx, [.iItem]
        cmp     ebx, [esi+4]      ; Count
        jae     .finish

        dec     dword [esi+4]
        stdcall StrDel, [esi+4*ebx+8]

.shift:
        cmp     ebx, [esi+4]
        je      .zero

        pushd   [esi+4*ebx+12]
        popd    [esi+4*ebx+8]
        inc     ebx
        jmp     .shift
.zero:
        mov     dword [esi+4*ebx+8], 0        ; Zero the last element.

.finish:
        pop     ebx esi
        return
endp


proc ValidateMRUList, .ptrList, .ptrCallback
begin
        push    esi ebx
        mov     esi, [.ptrList]
        mov     ebx, [esi+4]    ; count;

.checkloop:
        dec     ebx
        js      .endcheck
        invoke  .ptrCallback, [esi+4*ebx+8]      ; Check from the end to the begin
        jnc     .checkloop
        stdcall RemoveFromMRUList, [.ptrList], ebx
        jmp     .checkloop

.endcheck:
        pop     ebx esi
        return
endp


proc DestroyMRUList, .ptrList
begin
        push    esi ebx
        mov     esi, [.ptrList]
        mov     ebx, [esi+4]      ; Count

.freestrings:
        dec     ebx
        js      .freelist
        stdcall StrDel, [esi+4*ebx+8]
        jmp     .freestrings

.freelist:
        stdcall FreeMem, esi
        pop     ebx esi
        return
endp


proc SaveMRUToIni, .ptrList, .hIniName, .hSection
.ptrini dd ?
begin
        push    ebx esi edi
        mov     esi, [.ptrList]

        stdcall StrPtr, [.hIniName]
        mov     [.ptrini], eax

        stdcall StrPtr, [.hSection]
        mov     edi, eax

        stdcall NumToStr, [esi+4], ntsUnsigned or ntsDec
        push    eax
        stdcall StrPtr, eax
        ; Write the count key
        invoke  WritePrivateProfileStringA, edi, cMRUCountKey, eax, [.ptrini]
        stdcall StrDel ; from the stack.

        xor     ebx, ebx
.itemsloop:
        cmp     ebx, [esi+4]
        jae     .endsave

        stdcall StrDup, cMRUKey
        mov     edx, eax
        stdcall NumToStr, ebx, ntsUnsigned or ntsDec
        stdcall StrCat, edx, eax
        stdcall StrDel, eax
        stdcall StrPtr, [esi+4*ebx+8]
        push    [.ptrini]
        push    eax
        stdcall StrPtr, edx
        push    eax
        push    edi
        invoke  WritePrivateProfileStringA
        stdcall StrDel, edx
        inc     ebx
        jmp     .itemsloop
.endsave:
        pop     edi esi ebx
        return
endp

cMRUCountKey  text 'MRUCount'    ; max 9999 items.
cMRUKey       text 'Item'        ;
cMRUErr       text 'ERR#'


proc LoadMRUFromIni, .capacity, .hIniName, .hSection
.ptrini dd ?
.str    rb 1024
.count  dd ?
begin
        push    esi edi ebx

        stdcall CreateNewMRUList, [.capacity]
        mov     esi, eax

        stdcall StrPtr, [.hIniName]
        mov     [.ptrini], eax

        stdcall StrPtr, [.hSection]
        mov     edi, eax

        invoke  GetPrivateProfileIntA, edi, cMRUCountKey, 0, [.ptrini]
        test    eax, eax
        jz      .finish

        mov     [.count], eax
        xor     ebx, ebx

.loadloop:
        cmp     ebx, [.count]
        jae     .finish

        stdcall StrDup, cMRUKey
        mov     edx, eax
        push    eax
        stdcall NumToStr, ebx, ntsUnsigned or ntsDec
        stdcall StrCat, edx, eax
        stdcall StrDel, eax

        stdcall StrPtr, edx
        lea     ecx, [.str]
        invoke  GetPrivateProfileStringA, edi, eax, cMRUErr, ecx, 1024, [.ptrini]
        stdcall StrDel ; from the stack

        cmp     dword [.str], 'ERR#'
        je      .next

        lea     eax, [.str]
        stdcall AddToMRUList, esi, eax
.next:
        inc     ebx
        jmp     .loadloop

.finish:
        mov     eax, esi
        pop     ebx edi esi
        return
endp



proc FillMRUMenu, .hMenu, .ptrList, .ItemID, .fromSeparator
.mii  MENUITEMINFO
begin
        push    esi edi ebx

        mov     [.mii.cbSize], sizeof.MENUITEMINFO
        mov     [.mii.fMask], MIIM_TYPE or MIIM_ID

        xor     edi, edi

        invoke  GetMenuItemCount, [.hMenu]
        mov     ebx, eax
        test    ebx, ebx
        jz      .endscan

.scanloop:
        lea     ecx, [.mii]
        invoke  GetMenuItemInfoA, [.hMenu], edi, TRUE, ecx
        cmp     [.mii.fType], MF_SEPARATOR
        jne     .next
        dec     [.fromSeparator]
        jz      .delloop
.next:
        inc     edi
        cmp     edi, ebx
        jae     .endscan
        jmp     .scanloop

; found needed separator, delete to the next separator.
.delloop:
        invoke  DeleteMenu, [.hMenu], edi, MF_BYPOSITION
        dec     ebx
        cmp     edi, ebx
        jae     .endscan

        lea     ecx, [.mii]
        invoke  GetMenuItemInfoA, [.hMenu], edi, TRUE, ecx
        cmp     [.mii.fType], MF_SEPARATOR
        jne     .delloop

.endscan:
        mov     [.mii.fType], MFT_STRING

        mov     esi, [.ptrList]
        xor     ebx, ebx
        mov     eax, [esi+4]
        add     [.ItemID], eax
        stc                     ; One for the separator.
        adc     [.ItemID], edi
.loop:
        cmp     ebx, [esi+4]
        jae     .endinsert

        stdcall StrPtr, [esi+4*ebx+8]
        mov     [.mii.dwTypeData], eax

        dec     [.ItemID]
        push    [.ItemID]
        pop     [.mii.wID]

        lea     eax, [.mii]
        invoke  InsertMenuItemA, [.hMenu], edi, TRUE, eax
        inc     ebx
        jmp     .loop

.endinsert:
; Put separator at the begin.
        mov     [.mii.fMask], MIIM_TYPE
        mov     [.mii.fType], MFT_SEPARATOR
        mov     [.mii.wID], NULL
        lea     eax, [.mii]
        invoke  InsertMenuItemA, [.hMenu], edi, TRUE, eax

.finish:
        pop     ebx edi esi
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































Deleted source/msgwindow.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
uglobal
  frmMsg        dd 0                        ; Messages window.
  hSplitterMsg  dd 0
  tvMessagesWin dd 0
  fDisableLinks dd 0
endg


iglobal
  cMessagesTitle  db 'Fresh messages.',0
endg



proc InitMessageWindow
begin
        xor     ebx, ebx
        invoke   CreateWindowExA, ebx, cFormClassName, cMessagesTitle, \
                 WS_CHILD or WS_CLIPCHILDREN ,                        \
                 ebx, ebx , ebx, 100,                                 \
                 [hEditorsHost],                                      \
                 ebx, [hInstance],                                    \
                 NULL

        mov     [frmMsg], eax
        stdcall SetAlign, eax, waBottom
        stdcall SubclassWindow, [frmMsg], MsgWindowProc

        invoke  SendMessageA, [hEditorsHost], EHM_DOCKWINDOW, [frmMsg], dfBottom
        mov     [hSplitterMsg], eax

        invoke  SendMessageA, [frmMsg], MWM_CLEARMESSAGES, 0, 0
        return
endp





proc MsgWindowProc, .hwnd, .wmsg, .wparam, .lparam
.tvi    TVINSERTSTRUCT
begin

        call    JumpTo
        MessageList                             \
            AM_INITWINDOW,      .aminitwindow,  \
            WM_NOTIFY,          .notify,        \
            MWM_CLEARMESSAGES,  .clearmessages, \
            MWM_SHOWMESSAGES,   .showmessages,  \
            MWM_ADDMESSAGE,     .addmessage,    \
            MWM_FIRSTERROR,     .openfirsterror,\
            WM_SETFOCUS,        .setfocus,      \
            WM_COMMAND,         .command
.qtrue:
        stc
        return

.command:
        cmp     [.wparam], MR_OK
        jne     .qtrue
        jmp     .gotolink_fromuser


; ---------- WM_SETFOCUS ------------------------------
.setfocus:
        invoke  SetFocus, [tvMessagesWin]
        stc
        return

;----------- AM_INITWINDOW ----------------------------
.aminitwindow:
        xor     ebx,ebx

        invoke  CreateWindowExA, WS_EX_CLIENTEDGE, cTreeViewClassName, ebx,                      \
                WS_VISIBLE or WS_CHILD or WS_CLIPSIBLINGS or WS_VSCROLL or                      \
                TVS_DISABLEDRAGDROP or TVS_SHOWSELALWAYS or TVS_HASBUTTONS or                   \
                TVS_LINESATROOT or TVS_HASLINES,                                                \
                ebx,ebx, ebx, ebx,                                                              \
                [.hwnd], ebx, [hInstance], ebx

        mov     esi, eax
        mov     [tvMessagesWin], eax
        stdcall SetAlign, esi, waClient
        stdcall SubclassWindow, esi, MsgTreeWinProc

        stdcall ImageList_LoadGif, [hInstance], resBmpMessage, 14, FALSE
        invoke  SendMessageA, esi, TVM_SETIMAGELIST, TVSIL_NORMAL, eax
        clc
        return

;----------- WM_NOTIFY --------------------------
.notify:
        mov     esi, [.lparam]

        cmp     [esi+NMHDR.code], TVN_DELETEITEM
        je      .delitem

        cmp     [esi+NMHDR.code], TVN_SELCHANGED
        je      .selchanged

        cmp     [esi+NMHDR.code], TVN_KEYDOWN
        jne     .qfalse

; TVN_KEYDOWN
        cmp     [esi+TVKEYDOWN.wVKey], $20
        jne     .qfalse

        mov     eax, [esi+NMHDR.hwndFrom]
        cmp     eax, [tvMessagesWin]
        jne     .qfalse

.gotolink_fromuser:
        invoke  SendMessageA, [tvMessagesWin], TVM_GETNEXTITEM, TVGN_CARET, NULL
        mov     [.tvi.item.hItem], eax
        mov     [.tvi.item.mask], TVIF_PARAM
        lea     eax, [.tvi.item]
        invoke  SendMessageA, [tvMessagesWin], TVM_GETITEM, 0, eax
        mov     edi, [.tvi.item.lParam]

        invoke  SetFocus, [hEditorsHost]
        jmp     .gotolink

.selchanged:
        cmp     [fDisableLinks], 0
        jne     .qfalse

        test    [esi+NMTREEVIEW.itemNew.state], TVIS_SELECTED
        jz      .qfalse

        mov     edi, [esi+NMTREEVIEW.itemNew.lParam]

.gotolink:
        test    edi, edi
        jz      .qfalse

        invoke  GetFocus
        mov     [.lastfocus], eax

; this will change the focus to the asmedit window
        stdcall OpenFileByName, [edi+TFileLine.hFileName], NULL, TRUE
        test    eax, eax
        jz      .qfalse
        mov     ebx, eax

; take the focus back
        mov     eax, [.lastfocus]
        cmp     eax, [tvMessagesWin]
        jne     .focusok

        invoke  SetFocus, [tvMessagesWin]
.focusok:

        mov     esi, [edi+TFileLine.pos.selectionLine]

        cmp     [ebx+TOpenFile.ptrType], ftFormSource
        jne     .setthepos

        invoke  GetPropA, [ebx+TOpenFile.hEditor], [propWinTemplate]
        stdcall CountDesignWindows, eax

        sub     esi, eax
        sub     esi, 2

.setthepos:
        stdcall GetFileAsmEdit, ebx
        test    eax, eax
        jz      .qfalse

        mov     ebx, eax

locals
  .aepos AEPOS
  .lastfocus dd ?
endl

; workaround, because AEM_SETFOCUSLINE do not move the caret.
        mov     [.aepos.selectionPosition], 1
        mov     [.aepos.caretPosition], 1
        mov     [.aepos.selectionLine], esi
        mov     [.aepos.caretLine], esi
        lea     eax, [.aepos]
        invoke  SendMessageA, ebx, AEM_SETPOS, eax, 0

        invoke  SendMessageA, ebx, AEM_SETFOCUSLINE, esi, 0
        jmp     .qfalse

.delitem:
        mov     edi, [esi+NMTREEVIEW.itemOld.lParam]
        test    edi, edi
        jz      .checkvisible

        stdcall StrDel, [edi+TFileLine.hFileName]
        stdcall FreeMem, edi

.checkvisible:
        invoke  SendMessageA, [tvMessagesWin], TVM_GETCOUNT, 0, 0
        cmp     eax, 1
        ja      .qfalse

.hidemsgwnd:
        mov     ebx, SW_HIDE
        jmp     .doshow

;---------- MWM_SHOWMESSAGES --------------------------------
.showmessages:
        mov     ebx, SW_HIDE

        cmp     [.wparam], 0
        je      .doshow

        mov     ebx, SW_SHOWNORMAL

.doshow:
        invoke  SetWindowPos, [hStatus], HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE
        invoke  ShowWindow, [.hwnd], ebx
        invoke  ShowWindow, [hSplitterMsg], ebx
        stdcall AlignSiblings, [.hwnd]

        stdcall SetAutoHideTimer

        jmp     .qfalse


;---------- MWM_ADDMESSAGE ----------------------------------
.addmessage:
        cmp     [flagFakeCompile], 0
        jne     .qfalse

        mov     esi, [.wparam]
        test    esi, esi
        jz      .qfalse

        lea     edi, [.tvi]
        mov     ecx, sizeof.TVINSERTSTRUCT / 4
        xor     eax, eax
        rep stosd

        mov     eax, [.lparam]
        mov     [.tvi.hParent], eax
        mov     [.tvi.hInsertAfter], TVI_LAST
        mov     [.tvi.item.mask], TVIF_IMAGE or TVIF_PARAM or TVIF_SELECTEDIMAGE or TVIF_TEXT

        mov     eax, [esi+TFreshMsg.type]
        mov     [.tvi.item.iImage], eax
        mov     [.tvi.item.iSelectedImage], eax

        stdcall StrPtr, [esi+TFreshMsg.hMessage]
        mov     [.tvi.item.pszText], eax

        mov     edi, [esi+TFreshMsg.link.hFileName]
        test    edi, edi
        jz      .skiplink

        stdcall GetMem, sizeof.TFileLine
        mov     edi, eax

        stdcall StrNew
        mov     [edi+TFileLine.hFileName], eax
        stdcall StrCopy, eax, [esi+TFreshMsg.link.hFileName]
        mov     eax, [esi+TFreshMsg.link.pos.caretLine]
        mov     ecx, [esi+TFreshMsg.link.pos.caretPosition]
        mov     [edi+TFileLine.pos.caretLine], eax
        mov     [edi+TFileLine.pos.caretPosition], ecx
        mov     eax, [esi+TFreshMsg.link.pos.selectionLine]
        mov     ecx, [esi+TFreshMsg.link.pos.selectionPosition]
        mov     [edi+TFileLine.pos.selectionLine], eax
        mov     [edi+TFileLine.pos.selectionPosition], ecx

.skiplink:
        mov     [.tvi.item.lParam], edi

        lea     eax, [.tvi]
        invoke  SendMessageA, [tvMessagesWin], TVM_INSERTITEM, 0, eax
        push    eax

        invoke  SendMessageA, [tvMessagesWin], TVM_ENSUREVISIBLE, 0, eax
        invoke  SendMessageA, [tvMessagesWin], TVM_EXPAND, TVE_EXPAND, [.tvi.hParent]

        invoke  GetWindowLongA, [.hwnd], GWL_STYLE
        test    eax, WS_VISIBLE
        jnz     .endadd

        invoke  PostMessageA, [.hwnd], MWM_SHOWMESSAGES, 1, 0

.endadd:
        call SetAutoHideTimer

        pop     eax
        clc
        return

;----------- MWM_FIRSTERROR --------------------------
.openfirsterror:
        mov     ebx, TVI_ROOT

.loopchild:
        invoke  SendMessageA, [tvMessagesWin], TVM_GETNEXTITEM, TVGN_CHILD, ebx
        test    eax, eax
        jz      .notfound

        lea     esi, [.tvi.item]
        mov     [.tvi.item.mask], TVIF_IMAGE or TVIF_PARAM

.itemsloop:
        mov     ebx, eax
        mov     [.tvi.item.hItem], ebx

        invoke  SendMessageA, [tvMessagesWin], TVM_GETITEM, 0, esi
        cmp     [.tvi.item.iImage], mtError
        je      .found

.next:
        invoke  SendMessageA, [tvMessagesWin], TVM_GETNEXTITEM, TVGN_NEXT, ebx
        test    eax, eax
        jnz     .itemsloop

.notfound:
        mov     eax, TRUE
        clc
        return

.found:
        mov     edi, [.tvi.item.lParam]
        test    edi, edi
        jz      .next

        invoke  SendMessageA, [tvMessagesWin], TVM_SELECTITEM, TVGN_CARET, ebx
        jmp     .qfalse


;----------- MWM_CLEARMESSAGES ----------------------
.clearmessages:
        mov     [blockAutoHide], 0

        invoke  SendMessageA, [tvMessagesWin], TVM_GETCOUNT, 0, 0
        test    eax, eax
        jz      .hidemsgwnd

        mov     [fDisableLinks], TRUE
        invoke  SendMessageA, [tvMessagesWin], TVM_DELETEITEM, 0, TVI_ROOT
        mov     [fDisableLinks], FALSE
.qfalse:
        xor     eax, eax
        clc
        return

endp



iglobal
  idCloseTimer dd 0
endg


winproc MsgTreeWinProc
begin

ondefault
        stc
        return

onmessage WM_SETFOCUS
        call    KillAutoHideTimer
        stc
        return

onmessage WM_KILLFOCUS
        call    SetAutoHideTimer
        stc
        return

onmessage WM_TIMER
        mov     eax, [.wparam]
        cmp     eax, 101
        jne     .ondefault

        call    KillAutoHideTimer
        invoke  PostMessageA, [frmMsg], MWM_SHOWMESSAGES, 0, 0
        clc
        return
endwp


proc KillAutoHideTimer
begin
        cmp     [idCloseTimer],0
        je      .exit
        invoke  KillTimer, [tvMessagesWin], 101
        mov     [idCloseTimer], 0
.exit:
        return
endp

proc SetAutoHideTimer
begin
        call    KillAutoHideTimer
        cmp     [flagAutoHide], 0
        je      .exit
        cmp     [blockAutoHide], 0
        jne     .exit

        invoke  IsWindowVisible, [frmMsg]
        test    eax, eax
        jz      .exit

        invoke  SetTimer, [tvMessagesWin], 101, [timeAutoHide], 0
        mov     [idCloseTimer], eax

.exit:
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/msgwindow.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
winmessage MWM_CLEARMESSAGES       ; Clears all messages in the message window
winmessage MWM_SHOWMESSAGES        ; .wparam=1 show the window; .wparam=0 hide the windowss

winmessage MWM_ADDMESSAGE          ; wparam - pointer to TMsg structure describing the message.
                                ; lparam - handle of the parent item.
                                ; returns the handle of the new message line.

winmessage MWM_FIRSTERROR          ; searches for the last root error message and opens the file.

struct TFileLine
  .hFileName dd ?       ; handle to the filename string.
  .pos       AEPOS      ; Position of cursor and selection in ASMEDIT control.
ends

struct TFreshMsg
  .type        dd ?      ; 0..4
  .hMessage    dd ?      ; ptr/handle of the message
  .link        TFileLine ; File link information.
ends

mtWarning = 0
mtError = 1
mtInfo = 2
mtFind = 3
mtNone = 4
mtDebug = 5

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































Deleted source/opendialog.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
iglobal
  cOpenFileTitle text 'Open file:'
  cOpenProjectTitle text 'Open project:'
  cSaveProjectTitle text 'Save project as:'
  cSaveFileTitle text 'Save file as:'
  cBackSlash text '\'
  ProjFilter:
        db 'Fresh project (*.fpr)', 0, '*.fpr',0
        db 'All files (*.*)', 0, '*.*',0
        db 0
  AllFilter:
        db 'All Fresh files (*.fpr, *.asm, *.inc, *.frm, *.bmp)', 0, '*.fpr;*.asm;*.inc;*.frm;*.bmp',0
        db 'Fresh project (*.fpr)', 0, '*.fpr',0
        db 'Form (*.frm)', 0, '*.frm',0
        db 'Assembler files (*.asm, *.inc)', 0, '*.asm;*.inc', 0
        db 'Bitmaps (*.bmp)', 0, '*.bmp',0
        db 'All files (*.*)', 0, '*.*',0
        db 0
  FileFilter:
        db 'Assembler files (*.asm, *.inc)', 0, '*.asm;*.inc', 0
        db 'All files (*.*)', 0, '*.*',0
        db 0
  FormFilter:
        db 'Form (*.frm)', 0, '*.frm',0
        db 'All files (*.*)', 0, '*.*', 0
        db 0
  GraphicFilter:
        db 'Bitmap (*.bmp)', 0, '*.bmp',0
        db 'All files (*.*)', 0, '*.*', 0
        db 0
  WatchFilter:
        db 'Memory watch table (*.mwt)', 0, '*.mwt',0
        db 'All files (*.*)', 0, '*.*', 0
        db 0
  cOpenDialogError text 'Error show open dialog.'
endg


cFilenameBufferSize = 4096


proc OpenFilesDialog, .ptrTitle, .MultiSelect, .ptrFilter, .ptrCallBack, .hFileName, .lParam
.opn OPENFILENAME
.str rb 1024
.ptr dd ?
.errcnt dd ?
.oldwin dd ?
begin
        mov     [.errcnt], 0

        invoke  GetActiveWindow
        mov     [.oldwin], eax

; Allocate memory for filename buffer.
        stdcall GetMem, cFilenameBufferSize
        mov     edi, eax

        mov     [.opn.lpstrInitialDir], 0

        cmp     [.hFileName], 0
        je      .setstructure

        stdcall StrPtr, [.hFileName]
        lea     ecx, [.str]
        mov     [.opn.lpstrInitialDir], ecx
        lea     edx, [.ptr]
        invoke  GetFullPathNameA, eax, 1024, ecx, edx
        test    eax, eax
        jz      .setstructure

        mov     esi, [.ptr]
        test    esi, esi
        jz      .setstructure

        mov     byte [esi-1], 0

        push    edi

.copyname:
        lodsb
        stosb
        test    al,al
        jnz     .copyname

        pop     edi

.setstructure:
        xor     edx, edx
        mov     [.opn.lStructSize], sizeof.OPENFILENAME
        mov     eax, [hApplication]
        mov     [.opn.hwndOwner], eax
        mov     [.opn.hInstance], edx
        mov     eax, [.ptrFilter]
        mov     [.opn.lpstrFilter], eax
        mov     [.opn.lpstrCustomFilter], edx
        mov     [.opn.nFilterIndex], 1
        mov     [.opn.lpstrFile], edi
        mov     [.opn.nMaxFile], cFilenameBufferSize
        mov     [.opn.lpstrFileTitle], edx
        mov     [.opn.nMaxFileTitle], edx
        mov     eax, [.ptrTitle]
        mov     [.opn.lpstrTitle], eax
        mov     [.opn.Flags], OFN_EXPLORER or           \
                              OFN_HIDEREADONLY or       \
                              OFN_NOCHANGEDIR or        \
                              OFN_FILEMUSTEXIST

        cmp     [.MultiSelect], FALSE
        je      @f
        or      [.opn.Flags], OFN_ALLOWMULTISELECT
@@:
        mov     [.opn.lpstrDefExt], edx
        mov     [.opn.lCustData], edx
        mov     [.opn.lpfnHook], edx

.retry:
        lea     eax, [.opn]
        invoke  GetOpenFileNameA, eax
        push    eax
        invoke  SetActiveWindow, [.oldwin]      ; restore the old active window.

        pop     eax
        test    eax, eax
        jnz     @f

; Error open dialog or simply cancel...
        invoke  CommDlgExtendedError
        test    eax, eax
        jz      .finish

        cmp     eax, $3002
        jne     .errbox

        cmp     [.errcnt], 0
        jne     .errbox

        mov     [.opn.lpstrInitialDir], 0
        inc     [.errcnt]
        jmp     .retry

.errbox:
        invoke  MessageBoxA, [hApplication], cOpenDialogError, NULL, MB_ICONERROR or MB_OK
        jmp     .finish

@@:
; Get file(s) path.

        movzx   esi, [.opn.nFileOffset]
        add     esi, edi
        cmp     byte [esi-1], 0                 ; if 0 then more than one file is selected.
        je      .multyfile                      ; The ebx string contains the filename.

; only one file to read:
        stdcall [.ptrCallBack], edi, [.lParam]
        jmp     .finish

.multyfile:
        stdcall StrNew
        mov     ebx, eax

.fileloop:
        cmp     byte [esi], 0
        je      .endfiles

        stdcall StrCopy, ebx, edi               ; path
        stdcall StrCat, ebx, cBackSlash         ; '\'
        stdcall StrCat, ebx, esi                ; path + name

        stdcall [.ptrCallBack], ebx, [.lParam]

.findend:
        lodsb
        test    al,al
        jnz     .findend
        jmp     .fileloop

.endfiles:
        stdcall StrDel, ebx

.finish:
;Free filename buffer
        stdcall FreeMem, edi
        return
endp



proc SaveFileDialog, .ptrTitle, .ptrFilter, .hFileName
.opn OPENFILENAME
begin
; Allocate memory for filename buffer.
        push      esi edi ebx
        stdcall   StrNew
        mov       ebx, eax
        stdcall   StrSetCapacity, ebx, 1024
        test      eax, eax
        jz        .finish

        mov       edi, eax
        stdcall   StrCopy, ebx, [.hFileName]

        xor     edx, edx
        mov     [.opn.lStructSize], sizeof.OPENFILENAME
        mov     eax, [hApplication]
        mov     [.opn.hwndOwner], eax
        mov     [.opn.hInstance], edx
        mov     eax, [.ptrFilter]
        mov     [.opn.lpstrFilter], eax
        mov     [.opn.lpstrCustomFilter], edx
        mov     [.opn.nFilterIndex], 1
        mov     [.opn.lpstrFile], edi
        mov     [.opn.nMaxFile], 1024
        mov     [.opn.lpstrFileTitle], edx
        mov     [.opn.nMaxFileTitle], edx
        mov     [.opn.lpstrInitialDir], edx
        mov     eax, [.ptrTitle]
        mov     [.opn.lpstrTitle], eax
        mov     [.opn.Flags], OFN_EXPLORER or           \
                              OFN_HIDEREADONLY or       \
                              OFN_NOREADONLYRETURN or   \
                              OFN_NOCHANGEDIR
        mov     [.opn.lpstrDefExt], edx
        mov     [.opn.lCustData], edx
        mov     [.opn.lpfnHook], edx

        lea     eax, [.opn]
        invoke  GetSaveFileNameA, eax
        test    eax, eax
        jz      .finish

        stdcall StrFixLen, ebx
        mov     eax, ebx
.finish:
        pop     ebx edi esi
        return
endp



proc SelectPathDialog, .hOwner, .hTitle, .hPath
.bi BROWSEINFO
.str rb 256
.path rb 1024
.IMalloc dd ?
begin
        push    esi edi
        mov     eax, [.hOwner]
        lea     esi, [.str]
        mov     [.bi.hwndOwner], eax
        mov     [.bi.pidlRoot], 0

        mov     [.bi.pszDisplayName], esi
        stdcall StrPtr, [.hTitle]
        mov     [.bi.lpszTitle], eax
        mov     [.bi.ulFlags], BIF_RETURNONLYFSDIRS
        mov     [.bi.lpfn], _BrowseFolderProc
        lea     eax, [.hOwner]
        mov     [.bi.lParam], eax

        lea     eax, [.bi]
        invoke  SHBrowseForFolder, eax
        test    eax, eax
        jz      .finish

        push    eax

        lea     edi, [.path]
        xor     esi, esi
        invoke  SHGetPathFromIDList, eax, edi
        test    eax, eax
        jz      .memfree

        stdcall StrDup, edi
        mov     esi, eax

.memfree:
        invoke  CoTaskMemFree ; From the stack
        mov     eax, esi

.finish:
        pop     edi esi
        return
endp


proc _BrowseFolderProc, .hwnd, .wmsg, .lparam, .lpData
begin
        cmp     [.wmsg], BFFM_INITIALIZED
        jne     .finish

        mov     esi, [.lpData] ; This is pointer to arguments of SelectPathDialog
        stdcall StrPtr, [esi+4]
        invoke  SendMessageA, [.hwnd], WM_SETTEXT, 0, eax
        stdcall StrPtr, [esi+8]
        invoke  SendMessageA, [.hwnd], BFFM_SETSELECTION, TRUE, eax

.finish:
        xor     eax, eax
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
























































































































































































































































































































































































































































































































































































































Deleted source/palette.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
uglobal
  hToolPalette dd ?
endg

iglobal
  cControlsMask text '*.vcl'
  cControlsPath text '%Fresh%\IDE\components\'
endg


;***************************************************************
; Reloads visual components from standard component directory.
;***************************************************************
proc OnReloadVCL, .wparam, .lparam
begin
        push    ebx
        mov     ebx, [hMainWindow]
        test    ebx, ebx
        jnz     @f
        mov     ebx, [.lparam]
@@:
        stdcall CreateToolPalette, ebx
        stdcall ConvertPath, cControlsPath
        push    eax
        stdcall ScanForComponents, eax
        stdcall StrDel
        pop     ebx
        return
endp




;----------------------------------------------
; Creates tool palette and returns handle to
; the tab-control.
;----------------------------------------------
proc CreateToolPalette, .hParent
begin
        cmp     [hToolPalette], 0
        je      @f
        stdcall DestroyToolPalette
@@:
        xor     ebx,ebx
        invoke  CreateWindowExA, 0, cTabClassName, NULL,                         \
                WS_CHILD or WS_VISIBLE or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or \
                TCS_FOCUSNEVER or TCS_SINGLELINE or TCS_TABS,                   \
                ebx, 20, 200,  56,                                             \
                [.hParent], NULL, [hInstance], NULL

        mov     [hToolPalette], eax
        stdcall SetAlign, eax, waClient
        return
endp

;--------------------------------------------
; Clears all content of the tool palette.
; Frees all alocated memory.
;--------------------------------------------
proc ClearToolPalette
.tci TCITEM
.tbb TBBUTTON
begin
        invoke  SendMessageA, [hToolPalette], TCM_GETITEMCOUNT, 0, 0
        mov     ebx, eax

.tabloop:
        dec     ebx
        js      .finish

        lea     eax, [.tci]
        mov     [.tci.mask], TCIF_PARAM
        invoke  SendMessageA, [hToolPalette], TCM_GETITEM, ebx, eax

        mov     esi, [.tci.lParam]      ; handle of the toolbar.
        invoke  SendMessageA, esi, TB_BUTTONCOUNT, 0, 0
        mov     edi, eax

.btnloop:
        dec     edi
        js      .destroytoolbar

        lea     eax, [.tbb]
        invoke  SendMessageA, esi, TB_GETBUTTON, edi, eax

        mov     ecx, [.tbb.dwData]
        jecxz   .btnloop

        test    ecx, $80000000
        jz      .btnloop

        and     ecx, $7fffffff  ; Reset the marker for the block that need to be free-ed.

        stdcall FreeMem, ecx
        jmp     .btnloop

.destroytoolbar:
        invoke  DestroyWindow, esi
        jmp     .tabloop

.finish:
        return
endp

;-----------------------------------------------
; Free all memory allocated for TDesignTimeInfo
; structures and all toolbars and tab control of
; the tool palette.
;-----------------------------------------------
proc DestroyToolPalette
begin
        cmp     [hToolPalette], 0
        je      .finish
        stdcall ClearToolPalette
        invoke  DestroyWindow, [hToolPalette]
        mov     [hToolPalette], 0
.finish:
        return
endp



;-----------------------------------------------
; Scans given directory for components and add
; it to the tool palette.
;-----------------------------------------------
proc ScanForComponents, .hPath
.nmh    NMHDR
.olddir rb 1024
.find FINDDATA
begin
        lea     eax, [.olddir]
        invoke  GetCurrentDirectoryA, 1024, eax

        mov     [.find.dwFileAttributes], FILE_ATTRIBUTE_NORMAL

        stdcall StrNew
        mov     edi, eax
        stdcall StrCopy, edi, [.hPath]
        stdcall StrDup, edi                     ; edi - path.
        stdcall StrCat, eax, cControlsMask      ; eax - search mask
        push    eax

        stdcall StrPtr, eax

        lea     esi, [.find]

        invoke  FindFirstFileA, eax, esi

        stdcall StrDel  ; eax is in the stack.

        cmp     eax, INVALID_HANDLE_VALUE
        je      .finish
        mov     ebx, eax

.addloop:
        stdcall StrDup, edi
        push    eax

        lea     ecx, [.find.cFileName]
        stdcall StrCat, eax, ecx

        stdcall AddToPalette, eax

        stdcall StrDel  ; eax is in the stack

        invoke  FindNextFileA, ebx, esi
        test    eax,eax
        jnz     .addloop

        stdcall StrDel, edi

        invoke  FindClose, ebx

; Select first tab.
        mov     [.nmh.code], TCN_SELCHANGING
        push    [hToolPalette]
        pop     [.nmh.hwndFrom]
        lea     edi, [.nmh]

        invoke  SendMessageA, [hToolPalette], WM_NOTIFY, 0, edi
        invoke  SendMessageA, [hToolPalette], TCM_SETCURSEL, 0, 0

        mov     [.nmh.code], TCN_SELCHANGE
        invoke  SendMessageA, [hToolPalette], WM_NOTIFY, 0, edi

.finish:
        lea     eax, [.olddir]
        invoke  SetCurrentDirectoryA, eax

        return
endp







;--------------------------------------
;  if palette with this name exists,
;  returns the handle of the toolber.
;  If such palette does not exists,
;  creates one and returns handle of
;  the new created toolbar.
;--------------------------------------
proc GetPaletteToolbar, .hPaletteName
.nmh   NMHDR
.tci   TCITEM
.tbb   TBBUTTON
.index dd ?
.name  rb 256

begin
        push    ebx esi edi

; Check for palette.
        invoke  SendMessageA, [hToolPalette], TCM_GETITEMCOUNT, 0, 0
        dec     eax
        js      .createnew
        mov     [.index], eax

        mov     [.tci.mask], TCIF_TEXT or TCIF_PARAM
        lea     ebx, [.name]
        mov     [.tci.pszText], ebx
        mov     [.tci.cchTextMax], 256
        lea     esi, [.tci]

.find:
        invoke  SendMessageA, [hToolPalette], TCM_GETITEM, [.index], esi

        stdcall StrCompNoCase, [.tci.pszText], [.hPaletteName]
        mov     eax, [.tci.lParam]
        jc      .finish
        dec     [.index]
        jns     .find

.createnew:
        xor     esi, esi
        invoke  CreateWindowExA, esi, cToolbarClassName, NULL,    \
                                WS_CHILD or                      \
                                WS_CLIPSIBLINGS or               \
                                WS_CLIPCHILDREN or               \
                                TBSTYLE_TRANSPARENT or           \
                                TBSTYLE_FLAT or                  \
                                TBSTYLE_TOOLTIPS or              \
                                CCS_NODIVIDER or                 \
                                CCS_NORESIZE,                    \
                                esi, esi, 10000, esi,            \
                                [hToolPalette], esi, [hInstance],\
                                esi
        mov     ebx, eax
        invoke  SendMessageA, ebx, TB_BUTTONSTRUCTSIZE, TToolbarButton.size, esi

        invoke  ImageList_Create, 24, 24, ILC_COLOR24 or ILC_MASK, 0, 1
        mov     esi, eax

        invoke  LoadImageA, [hInstance], resArrowIcon, IMAGE_ICON, 24, 24, LR_DEFAULTCOLOR
        push    eax

        invoke  ImageList_AddIcon, esi, eax

        invoke  DestroyIcon     ; eax is in the stack

        invoke  SendMessageA, ebx, TB_SETIMAGELIST, 0, esi
        invoke  SendMessageA, ebx, TB_SETBITMAPSIZE, 0, $00180018

        stdcall SetAlign, ebx, waClient
        invoke  SetPropA, ebx, [propAutoSize], TRUE

; make tooltip to appear on not active main window.
        invoke  SendMessageA, ebx, TB_GETTOOLTIPS, 0, 0
        mov     esi, eax
        invoke  GetWindowLongA, esi, GWL_STYLE
        or      eax, TTS_ALWAYSTIP or TTS_NOPREFIX
        invoke  SetWindowLongA, esi, GWL_STYLE, eax

; Set tooltip delay time.
        invoke  SendMessageA, esi, TTM_SETDELAYTIME, TTDT_AUTOMATIC, 600

; Add arrow button to the palette toolbar.
        mov     [.tbb.iBitmap], 0
        mov     [.tbb.idCommand], 0
        mov     [.tbb.fsState], TBSTATE_CHECKED or TBSTATE_ENABLED
        mov     [.tbb.fsStyle], TBSTYLE_CHECKGROUP
        mov     [.tbb.dwData], 0
        mov     [.tbb.iString], -1
        lea     eax, [.tbb]
        invoke  SendMessageA, ebx, TB_ADDBUTTONS, 1, eax

        mov     [.tbb.fsState], 0
        mov     [.tbb.fsStyle], TBSTYLE_GROUP or TBSTYLE_SEP
;        mov     [.tbb.dwData], 0
        lea     eax, [.tbb]
        invoke  SendMessageA, ebx, TB_ADDBUTTONS, 1, eax


; Insert the new palette
        mov     [.nmh.code], TCN_SELCHANGING
        push    [hToolPalette]
        pop     [.nmh.hwndFrom]
        lea     edi, [.nmh]

        invoke  SendMessageA, [hToolPalette], WM_NOTIFY, 0, edi

        mov     [.tci.mask], TCIF_TEXT or TCIF_PARAM
        stdcall StrPtr, [.hPaletteName]
        mov     [.tci.pszText], eax
        mov     [.tci.lParam], ebx

        lea     esi, [.tci]
        invoke  SendMessageA, [hToolPalette], TCM_INSERTITEM, 10000, esi
        invoke  SendMessageA, [hToolPalette], TCM_SETCURSEL, eax, 0

        mov     [.nmh.code], TCN_SELCHANGE
        invoke  SendMessageA, [hToolPalette], WM_NOTIFY, 0, edi

        mov     eax, ebx
.finish:
        pop     edi esi ebx
        return
endp

;--------------------------------------------
; Adds the file with design-time description
; of controls in the tool palette.
; Returns:
;   0 - operation OK
;   1 - file open error
;   2 - file read error
;   3 - image read error
;--------------------------------------------
proc AddToPalette, .hFileName
.tbb    TBBUTTON
.ptrName dd ?
.path   rb 1024
.ffirst dd ?
begin
        push    ebx esi edi

        lea     edx, [.path]
        lea     ecx, [.ptrName]

        stdcall StrPtr, [.hFileName]

        invoke  GetFullPathNameA, eax, 1024, edx, ecx
        mov     eax, [.ptrName]
        mov     byte [eax-1], 0
        lea     eax, [.path]
        invoke  SetCurrentDirectoryA, eax

        stdcall LoadBinaryFile, [.ptrName]
        jc      .error_open

        mov     edi, eax

; So, here, edi points to buffer with read data. It is array of TDesignTimeInfo
; make relocation of the array pointers.
        push    edi
.reloc:
        cmp     dword [edi], 0
        je      .endloop

        add     [edi+TDesignTimeInfo.ClassName], edi
        add     [edi+TDesignTimeInfo.ControlHint], edi
        add     [edi+TDesignTimeInfo.Palette], edi
        add     [edi+TDesignTimeInfo.DefaultText], edi
        add     [edi+TDesignTimeInfo.StyleNames], edi
        add     [edi+TDesignTimeInfo.StyleExNames], edi
        add     [edi+TDesignTimeInfo.SubtypeRange], edi
        cmp     [edi+TDesignTimeInfo.LibFile], 0
        je      @f
        add     [edi+TDesignTimeInfo.LibFile], edi
@@:
        cmp     [edi+TDesignTimeInfo.ImageFile], 0
        je      @f
        add     [edi+TDesignTimeInfo.ImageFile], edi
@@:
        add     edi, sizeof.TDesignTimeInfo
        jmp     .reloc

.endloop:
        pop     edi

        mov     [.ffirst], $80000000
; Creates buttons from the structure.
.createbuttons:
        cmp     dword [edi], 0
        je      .endcreate

        stdcall GetPaletteToolbar, [edi+TDesignTimeInfo.Palette]
        mov     ebx, eax        ; handle for toolbar.

        invoke  LoadImageA, [hInstance], [edi+TDesignTimeInfo.ImageFile], IMAGE_ICON, 24, 24, LR_LOADFROMFILE ;  or LR_LOADTRANSPARENT
        test    eax, eax
        jz      .error_image

        mov     esi, eax

        invoke  SendMessageA, ebx, TB_GETIMAGELIST, 0, 0
        invoke  ImageList_ReplaceIcon, eax, -1, esi
        mov     [.tbb.iBitmap], eax
        mov     [.tbb.idCommand], eax
        invoke  DestroyIcon, esi

        mov     [.tbb.fsState], TBSTATE_ENABLED
        mov     [.tbb.fsStyle], TBSTYLE_CHECKGROUP

        mov     [.tbb.dwData], edi
        cmp     [.ffirst], 0
        je      @f
        or      [.tbb.dwData], $80000000
        and     [.ffirst], 0
@@:
        mov     [.tbb.iString], -1

        lea     eax, [.tbb]
        invoke  SendMessageA, ebx, TB_INSERTBUTTON, -1, eax

        add     edi, sizeof.TDesignTimeInfo
        jmp     .createbuttons

.endcreate:
        xor     eax,eax
        jmp     .finish

.error_open:
        mov     eax, 1
        jmp     .finish

.error_read:
        invoke  CloseHandle, esi
        mov     eax, 2
        jmp     .finish

.error_image:
        mov     eax, 3

.finish:
        pop     edi esi ebx
        return
endp



;--------------------------------------
; Returns pointer to TDesignTimeInfo
; structure for current selected
; tool.
; Returns NULL if there is no tool
; selected.
; Returns toolbar handle in the edx
;--------------------------------------
proc GetCurrentTool

.tci TCITEM
.tbb TBBUTTON

begin
        push    esi edi ebx
        invoke  SendMessageA, [hToolPalette], TCM_GETCURSEL, 0, 0
        cmp     eax, -1
        je      .finish

        lea     ecx, [.tci]
        mov     [.tci.mask], TCIF_PARAM
        invoke  SendMessageA, [hToolPalette], TCM_GETITEM, eax, ecx
        test    eax,eax
        jz      .finish

        invoke  SendMessageA, [.tci.lParam], TB_BUTTONCOUNT, 0, 0
        test    eax, eax
        jz      .finish

        mov     ebx, eax
        xor     esi, esi
        lea     edi, [.tbb]

.find:
        invoke  SendMessageA, [.tci.lParam], TB_GETBUTTON, esi, edi
        test    [.tbb.fsState], TBSTATE_CHECKED
        jnz     .found

        inc     esi
        cmp     esi, ebx
        jne     .find

        xor     eax, eax
        jz      .finish

.found:
        mov     eax, [.tbb.dwData]
        and     eax, $7fffffff
        mov     edx, [.tci.lParam]

.finish:
        pop     ebx edi esi
        return
endp


;---------------------------------------------------------
; Returns pointer to TDesignTimeInfo structure, if
; there is match. Returns NULL if there is no component
; with this parameters.
;---------------------------------------------------------
proc SearchForDesignTimeInfo, .hClassName, .Style
.tci TCITEM
.tbb TToolbarButton
.tb  dd ?
begin
        push    esi edi ebx

        invoke  SendMessageA, [hToolPalette], TCM_GETITEMCOUNT, 0, 0
        mov     ebx, eax

.tabloop:
        dec     ebx
        js      .finish

        lea     eax, [.tci]
        mov     [.tci.mask], TCIF_PARAM
        invoke  SendMessageA, [hToolPalette], TCM_GETITEM, ebx, eax

        mov     eax, [.tci.lParam]      ; handle of the toolbar.
        mov     [.tb], eax
        invoke  SendMessageA, [.tb], TB_BUTTONCOUNT, 0, 0
        mov     edi, eax

.btnloop:
        dec     edi
        js      .tabloop

        lea     eax, [.tbb]
        invoke  SendMessageA, [.tb], TB_GETBUTTON, edi, eax
        mov     esi, [.tbb.dwData]
        test    esi, esi
        jz      .btnloop

        and     esi, $7fffffff  ; address of TDesignTimeInfo
        stdcall StrCompNoCase, [.hClassName], [esi+TDesignTimeInfo.ClassName]
        jnc     .btnloop

        mov     eax, [esi+TDesignTimeInfo.SubtypeMask]
        and     eax, [.Style]

        mov     edx, [esi+TDesignTimeInfo.SubtypeRange]
        cmp     edx, esi
        je      .nosubstyle

        mov     ecx, [edx]      ; count of the items in the list
        add     edx, 4

.substyle:
        dec     ecx
        js      .btnloop

        cmp     eax, [edx]
        je      .found

        add     edx, 4
        push    ecx
        movzx   ecx, byte [edx]
        lea     edx, [edx+ecx+1]   ; skip the text
        movzx   ecx, byte [edx]
        lea     edx, [edx+ecx+1]   ; skip the comment
        pop     ecx
        jmp     .substyle

.nosubstyle:
        mov     eax, [esi+TDesignTimeInfo.StyleMaskAnd]
        not     eax
        and     eax, [.Style]
        jnz     .btnloop
        mov     eax, [esi+TDesignTimeInfo.StyleMaskOr]
        and     eax, [.Style]
        cmp     eax, [esi+TDesignTimeInfo.StyleMaskOr]
        jne     .btnloop

.found:
        mov     eax, esi
        pop     ebx edi esi
        return

.finish:
        xor     eax, eax
        pop     ebx edi esi
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/projmanager.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
uglobal
  hProjManager    dd 0  ; handle of project manager
  ptrProjectFile  dd 0  ; pointer to TOpenFile with ftProject, currently open in the project manager.
  fProjModified   dd 0  ; flag "modified" for current open project.

  poMemory       dd 0  ; The memory for the compiler
  poBinNameAuto  dd 0  ; The flag whether the binary name will be auto created of fixed
  poBinName      dd 0  ; Handle to the binary name.
  poVarArray     dd 0  ; points to the array with environment variables for the project.

  imlCategories   dd 0  ; Image list for tree-view control

  ptrMRUProj      dd 0  ; pointer to MRU list for projects.

  hTreePopup      dd 0
  hListPopup      dd 0
  hSettingsPopup  dd 0
  hSettingsString dd 0
endg


cProjTitle       text 'Project manager'
cSettingsCaption text 'Settings: '


iglobal
  CoolMenu mnuProjTree,           \
    mfNormal, actAddCategory,     \
    mfNormal, actEditCategory,    \
    mfSeparator, NONE,            \
    mfNormal, actMoveCategoryUp,  \
    mfNormal, actMoveCategoryDn

  CoolMenu mnuProjList,         \
    mfNormal, actAddFile

  CoolMenu mnuSettings,         \
    mfSeparator, NONE,          \
    mfNormal, actProjectOptions

endg




;----------------------------------------
; Creates project manager common objects.
; Call this only once.
;----------------------------------------
proc InitProjectManager
begin
; Read project MRU list
        stdcall LoadMRUFromIni, 16, [hIniFileName], cMRUProjSection
        mov     [ptrMRUProj], eax

        stdcall ImageList_LoadGif, [hInstance], resBmpProjMan, 16, FALSE
        mov     [imlCategories], eax

        stdcall CreateCoolMenu, mnuProjTree, TRUE
        mov     [hTreePopup], eax

        stdcall CreateCoolMenu, mnuProjList, TRUE
        mov     [hListPopup], eax

        stdcall CreateCoolMenu, mnuSettings, TRUE
        mov     [hSettingsPopup], eax

        mov     [poBinNameAuto], TRUE
        mov     [poMemory], 65536

        stdcall StrNew
        mov     [poBinName], eax

        return
endp


proc FinalizeProjectManager
begin
        cmp     [ptrProjectFile], NULL
        je      .closeproj

        stdcall CloseFile, [ptrProjectFile]

.closeproj:
        stdcall SaveMRUToIni, [ptrMRUProj], [hIniFileName], cMRUProjSection
        stdcall DestroyMRUList, [ptrMRUProj]
        invoke  ImageList_Destroy, [imlCategories]

        invoke  DestroyMenu, [hTreePopup]
        invoke  DestroyMenu, [hListPopup]
        invoke  DestroyMenu, [hSettingsPopup]
        return
endp


proc CreateProjectManager, .ptrOpenFile, .hTemplate
begin
        push    ebx esi
        xor     ebx, ebx

        mov     esi, [.ptrOpenFile]

        cmp     [ptrProjectFile], ebx
        je      .onlyone

        stdcall CloseFile, [ptrProjectFile]
        cmp     eax, cfrDestroyed
        jne     .fault

.onlyone:
        mov     [ptrProjectFile], esi

; Initial project options... they could be changed after CEM_LOADFILE
        mov     [poMemory], 65536
        mov     [poBinNameAuto], TRUE

        cmp     [poBinName], 0
        je      @f
        stdcall StrDel, [poBinName]
@@:
        stdcall StrNew
        mov     [poBinName], eax

        invoke   CreateWindowExA, WS_EX_TOOLWINDOW, cFormClassName, cProjTitle,  \
                                 WS_VISIBLE or WS_CAPTION or WS_CLIPCHILDREN or \
                                 WS_SIZEBOX or WS_SYSMENU,                      \
                                 ebx, ebx , 160, 400,                           \
                                 [hApplication], ebx, [hInstance], ebx

        mov     [hProjManager], eax
        mov     [esi+TOpenFile.hEditor], eax
        mov     [esi+TOpenFile.projectID], ebx
        stdcall SubclassWindow, eax, ProjManProc

        invoke  SendMessageA, [hProjManager], CEM_LOADFILE, [.hTemplate], ebx
        push    eax
        stdcall AutoArrangeWindows
        pop     eax

.finish:
        pop     esi ebx
        return

.fault:
        mov     eax, errCanceled
        pop     esi ebx
        return
endp



VarMenuBaseID = 20

proc CreateParametersMenu
.mii MENUITEMINFO
.pos dd ?
.pos_in_list dd ?
.buffer rb 256
begin
        push    ebx ecx esi

        xor     eax, eax
        cmp     [hSettingsString], eax
        jne     @f
        stdcall StrDel, [hSettingsString]
@@:
        stdcall StrDup, cSettingsCaption
        mov     [hSettingsString], eax

; first clear to the first separator.
.deleteloop:
        lea     ebx, [.mii]
        mov     [ebx+MENUITEMINFO.cbSize], sizeof.MENUITEMINFO
        mov     [ebx+MENUITEMINFO.fMask], MIIM_TYPE
        mov     [ebx+MENUITEMINFO.hSubMenu], 0
        lea     eax, [.buffer]
        mov     [ebx+MENUITEMINFO.dwTypeData], eax
        mov     [ebx+MENUITEMINFO.cch], 256
        invoke  GetMenuItemInfoA, [hSettingsPopup], 0, TRUE, ebx
        test    [ebx+MENUITEMINFO.fType], MFT_SEPARATOR
        jnz     .insertvalues

        invoke  DeleteMenu, [hSettingsPopup], 0, MF_BYPOSITION
        jmp     .deleteloop

; then check for multivalue elements in poVarArray
.insertvalues:
        mov     [.pos], 0
        mov     [.pos_in_list], VarMenuBaseID

        mov     esi, [poVarArray]
        test    esi, esi
        jz      .finish

        mov     ecx, [esi+TArray.count]
        lea     esi, [esi+TArray.array]

        cmp     ecx, 0
        je      .finish

.arrayloop:
        stdcall StrCharPos, [esi+TEnvVarType.pValue], '|'       ; check for separator.
        test    eax, eax
        jz      .next_item

        push    ecx
        mov     ecx, eax

        stdcall CreatePopupFromString, [esi+TEnvVarType.pValue], [.pos_in_list]
        mov     [ebx+MENUITEMINFO.hSubMenu], eax

; create menu string.
        mov     byte [ecx], 0
        stdcall StrDup, [esi+TEnvVarType.pName]
        push    eax

        stdcall StrCharCat, eax, 09
        stdcall StrCat, eax, [esi+TEnvVarType.pValue]
        stdcall StrCat, [hSettingsString], [esi+TEnvVarType.pValue]
        stdcall StrCharCat, [hSettingsString], ','
        stdcall StrCharCat, [hSettingsString], ' '
        mov     byte [ecx], '|'

; insert menu item

        mov     [ebx+MENUITEMINFO.cbSize], sizeof.MENUITEMINFO
        mov     [ebx+MENUITEMINFO.fMask], MIIM_TYPE or MIIM_SUBMENU
        mov     [ebx+MENUITEMINFO.fType], MFT_STRING
        stdcall StrPtr, eax
        mov     [ebx+MENUITEMINFO.dwTypeData], eax
        mov     [ebx+MENUITEMINFO.cch], 0
        invoke  InsertMenuItemA, [hSettingsPopup], [.pos], TRUE, ebx
        inc     [.pos]

        stdcall StrDel ; from the stack.

        pop     ecx

.next_item:
        add     esi, sizeof.TEnvVarType
        inc     [.pos_in_list]
        dec     ecx
        jnz     .arrayloop

.finish:
        invoke  GetDlgItem, [hProjManager], ProjSettingsID
        invoke  RedrawWindow, eax, 0, 0, RDW_INVALIDATE

        pop     esi ecx ebx
        return
endp



proc CreatePopupFromString, .hString, .baseid
.mii MENUITEMINFO
.pos dd ?
begin
        push    ebx ecx esi edi

        invoke  CreatePopupMenu
        mov     edi, eax

        stdcall StrPtr, [.hString]
        mov     esi, eax
        lea     ebx, [.mii]

        mov     [.pos], 0

.stringsplit:
        mov     eax, [.baseid]
        shl     eax, 8
        add     eax, [.pos]

        mov     [ebx+MENUITEMINFO.wID], eax
        mov     [ebx+MENUITEMINFO.cbSize], sizeof.MENUITEMINFO
        mov     [ebx+MENUITEMINFO.fMask], MIIM_TYPE or MIIM_ID
        mov     [ebx+MENUITEMINFO.fType], MFT_STRING
        mov     [ebx+MENUITEMINFO.dwTypeData], esi
        mov     [ebx+MENUITEMINFO.cch], 0
        mov     [ebx+MENUITEMINFO.hSubMenu], 0

        xor     eax, eax
.searchloop:
        lodsb
        cmp     al, '|'
        je      .splithere
        cmp     al, 0
        jne      .searchloop

.splithere:
        push    eax
        mov     byte [esi-1], 0

        invoke  InsertMenuItemA, edi, 0, TRUE, ebx
        inc     [.pos]

        pop     eax
        mov     [esi-1], al
        cmp     eax, 0
        jne     .stringsplit

        mov     eax, edi
        pop     edi esi ecx ebx
        return
endp





msgPUC1 text 'The file: "'
msgPUC2 text '" is part of saved project, but it doesn''t exists on the disk.', 13, 10, \
               'Do you want to add it to the project anyway?'
msgPUCtitle text  'Error adding file to the project.'


proc ProjectInconsistent, .ptrOpenFile
begin
        push    ebx
        mov     ebx, [.ptrOpenFile]

        stdcall StrDup, msgPUC1
        stdcall StrCat, eax, [ebx+TOpenFile.hFileName]
        stdcall StrCat, eax, msgPUC2
        push    eax
        stdcall StrPtr, eax

        invoke  MessageBoxA, [hApplication], eax, msgPUCtitle, MB_YESNO or MB_ICONWARNING
        stdcall StrDel ; from the stack
        pop     ebx
        return
endp




;-----------------------------------------------------
; Dialog proc for Project manager.
;-----------------------------------------------------
winproc ProjManProc

.tvi    TVINSERTSTRUCT
.lvi    LVITEM
.col    LVCOLUMN
.count  dd ?
.str    rb 1024
.str2   rb 256
.ptr    dd ?
.pnt    POINT

begin

ondefault
        stc
        return


onmessage PMM_FILECHANGED

        stdcall SearchForFile, [.hwnd], [.wparam]
        cmp     eax, -1
        je      .endchanged

        push    eax

        invoke  SendMessageA, [.hwnd], PMM_REMOVEFILE, [.wparam], 0
        invoke  SendMessageA, [.hwnd], PMM_ADDFILE, [.wparam] ; lparam from the stack

.endchanged:
        clc
        return

onmessage PMM_ADDFILE

        mov     [fProjModified], TRUE
        mov     eax, [.wparam]
        cmp     [eax+TOpenFile.projectID], FALSE
        je      .projok

        invoke  SendMessageA, [.hwnd], PMM_REMOVEFILE, eax, 0

.projok:
        cmp     [.lparam], 0
        jne     .addtocategory

; Add as main file.
        mov     eax, [.wparam]
        cmp     [eax+TOpenFile.ptrType], ftMainSource
        je      .typeok
        cmp     [eax+TOpenFile.ptrType], ftCommonSource
        jne     .erroradd
        mov     [eax+TOpenFile.ptrType], ftMainSource   ; change file type.
.typeok:
        mov     [eax+TOpenFile.projectID], TRUE

        stdcall AddToListView, [.hwnd], ProjMainCtrlID, [.wparam]
        invoke  SendDlgItemMessageA, [.hwnd], ProjMainCtrlID, LVM_SETCOLUMNWIDTH, 0, LVSCW_AUTOSIZE

        stdcall FileChanged, [.wparam], fcEditor
        jmp     .endadd

.addtocategory:
        mov     eax, [.wparam]
        cmp     [eax+TOpenFile.ptrType], ftMainSource
        jne     .typeok2

        mov     [eax+TOpenFile.ptrType], ftCommonSource

.typeok2:
        cmp     [eax+TOpenFile.projectID], FALSE
        jne     .erroradd

        mov     eax, [.lparam]
        cmp     eax, -1
        jne     .addit

.getcurrent:
        invoke  SendDlgItemMessageA, [.hwnd], ProjTreeCtrlID, TVM_GETNEXTITEM, TVGN_CARET, 0
        test    eax, eax
        jnz     .additfocused

        invoke  SendDlgItemMessageA, [.hwnd], ProjTreeCtrlID, TVM_GETNEXTITEM, TVGN_ROOT, 0
        test    eax, eax
        jnz     .additfocused

        stdcall OnAddCategory, eax, eax
        test    eax, eax
        jz      .erroradd
        jmp     .getcurrent

.additfocused:
        mov     [.lparam], eax

.addit:
        mov     esi, eax
        stdcall GetTVItemPtr, [.hwnd], esi
        stdcall AddArrayItems, eax, 1
        jc      .erroradd

        stdcall SetTVItemPtr, [.hwnd], esi, edx

        mov     ecx, [.wparam]
        mov     dword [eax], ecx
        mov     [ecx+TOpenFile.projectID], TRUE

        stdcall FileChanged, ecx, fcEditor

        invoke  SendDlgItemMessageA, [.hwnd], ProjTreeCtrlID, TVM_GETNEXTITEM, TVGN_CARET, 0
        cmp     eax, [.lparam]
        jne     .endadd

        stdcall ReloadListView, [.hwnd], [.lparam]

.endadd:
        xor     eax, eax
        clc
        return

.erroradd:
        xor     eax, eax
        inc     eax
        clc
        return

onmessage PMM_REMOVEFILE

        mov     [fProjModified], TRUE

        mov     esi, [.wparam]
        mov     [esi+TOpenFile.projectID], FALSE
        stdcall FileChanged, esi, fcEditor

        stdcall SearchForFile, [.hwnd], esi
        test    eax, eax
        jz      .mainfile
        js      .errdel

        mov     edi, eax
        mov     ebx, edx

        stdcall GetTVItemPtr, [.hwnd], edi
        stdcall DeleteArrayItems, eax, ebx, 1

        invoke  SendDlgItemMessageA, [.hwnd], ProjTreeCtrlID, TVM_GETNEXTITEM, TVGN_CARET, 0
        cmp     eax, edi
        jne     .enddel

        stdcall ReloadListView, [.hwnd], edi

.enddel:
        xor     eax, eax
        clc
        return

.mainfile:
        invoke  SendDlgItemMessageA, [.hwnd], ProjMainCtrlID, LVM_DELETEITEM, 0, 0
        jmp     .enddel

.errdel:
        xor     eax, eax
        inc     eax
        clc
        return

onmessage CEM_LOADFILE
locals
  .chunkname dd ?
endl
        mov     ebx, [ptrProjectFile]

        cmp     [.wparam], 0
        jne     .loadit

        cmp     [ebx+TOpenFile.fNeverSaved], FALSE
        je      .loadit

        mov     [fProjModified], FALSE
        xor     eax, eax
        clc
        return

.loadit:
        mov     [fProjModified], FALSE
        stdcall ChangeDir, [ebx+TOpenFile.hFileName]

; first set default options.
        stdcall EmptyVarList, poVarArray

; then load it...
        mov     eax, [.wparam]
        test    eax, eax
        jnz     @f
        mov     eax, [ebx+TOpenFile.hFileName]
@@:
        stdcall StrPtr, eax
        stdcall LoadBinaryFile, eax

        mov     [.ptr], eax
        mov     esi, eax

        cmp     ecx, 8
        jl      .invalidfile

; Project file header.
; Check the file singature
        lea     ecx, [ecx-8]

        lodsd
        cmp     eax, 'FNPr'   ; Fresh new project?
        jne     .invalidfile

        lodsd
        cmp     eax, $0a1a0a0d  ;) magic number. 'CR, LF, EOF, LF'
        je      .readchunks

.invalidfile:
        invoke  MessageBoxA, [hApplication], cErrorNotProject, NULL, MB_ICONERROR or MB_OK
        jmp     .endoffile

.readchunks:
        cmp     ecx, 8
        jl      .endoffile

        sub     ecx, 4
        lodsd
        mov     [.chunkname], eax

        call    .get_chunk_len
        jl      .invalidfile

        call    .check_chunk_hash
        jne     .invalidfile

; now esi points to the begin of the chunk data. edx contains the length of the chunk.
        push    ecx
        push    esi
        push    edx

        cmp     [.chunkname], 'PRTR'
        je      .read_project_tree

        cmp     [.chunkname], 'VARS'
        je      .read_vars

        cmp     [.chunkname], 'MAIN'
        je      .read_main_source_name

        cmp     [.chunkname], 'CMEM'
        je      .read_compiler_memory

        cmp     [.chunkname], 'CTNM'
        je      .read_output_filename

; unknown chunk. simply skip it.
.nextchunk:
        pop      edx
        pop      esi
        pop      ecx

        lea     esi, [esi+edx+4]  ; skip hash, it is already checked.
; adjust file length
        sub     ecx, edx
        sub     ecx, 4          ; 4 more bytes for the hash
        jmp     .readchunks


.endoffile:
        stdcall FreeMem, [.ptr]
        stdcall SetMainTitle

        stdcall CreateParametersMenu

        mov     ebx, [ptrProjectFile]
        stdcall AddToMRUList, [ptrMRUProj], [ebx+TOpenFile.hFileName]

        invoke  SendDlgItemMessageA, [.hwnd], ProjMainCtrlID, LVM_SETCOLUMNWIDTH, 0, LVSCW_AUTOSIZE

        xor     eax, eax
        clc
        return

  cErrorNotProject text 'Error: this file is not a project file in Fresh project format.',13, \
                          'New project created.'

;*****************************************************************************
;
; Chunk helper procedures.
;*****************************************************************************


;returns data length in EDX and datalen+4 in eax
.get_chunk_len:
        sub     ecx, 4
        lodsd   ; length of the chunk data
        mov     edx, eax
        add     eax, 4
        cmp     ecx, eax
        retn

; esi points to data.
; edx contains data len.
;
; returns computed hash in eax
.check_chunk_hash:
        push    esi edx ecx

        mov     eax, $811C9DC5                  ; 2166136261              ; FNV offset basis
        test    edx, edx
        jz      .endhash

.hashloop:
        movzx   ecx, byte [esi]
        inc     esi
        xor     eax, ecx
        imul    eax, $01000193                  ;   16777619              ; FNV prime
        dec     edx
        jnz     .hashloop

.endhash:
        mov     ecx, [esi]       ; hash from the chunk end
        cmp     eax, ecx
        pop     ecx edx esi
        retn

; esi points to the begin of the data.
; edi points just after the data.

.finalize_chunk:
        push    edx

        mov     edx, edi
        sub     edx, esi
        mov     [esi-4], edx      ; size of the chunk.
        stdcall .check_chunk_hash
        stosd                     ; save chunk hash at the end of the chunk.

        pop     edx
        retn


;--------------------------------------
; edi - pointer to the stream buffer
; eax - handle/pointer to the string
;--------------------------------------
.StrToStream:
        push    ecx
        stdcall StrPtr, eax
        xor     ecx, ecx

.copyname:
        mov     cl, [eax]
        inc     eax
        jecxz   .endofname
        mov     [edi], cl
        inc     edi
        jmp     .copyname

.endofname:
        pop     ecx
        retn






;***************************************************************************
;
; chunk 'PRTR' - contains one project category and its files.
;
;
.read_project_tree:
        lodsd                   ; icon number
        add     esi, 4          ; reserved dword for future use.

        stdcall GetCategoryTree, esi, TVI_ROOT, eax
        mov     ebx, eax        ; Current category tree item.

.filesloop:
        stdcall StrLen, esi
        lea     esi, [esi+eax+1]        ; goto to next file

        cmp     byte [esi], 0
        je      .nextchunk

        stdcall DetectFileType, esi
        stdcall CreateFStruct, esi, eax
        mov     edi, eax

        cmp     [.wparam], 0
        jne     .addtoproject    ; loaded from template.

        stdcall GetModified, edi
        test    eax, eax
        jz      .addtoproject

        stdcall ProjectInconsistent, edi
        cmp     eax, IDNO
        je      .adderror

.addtoproject:
        push    [fProjModified]
        invoke  SendMessageA, [.hwnd], PMM_ADDFILE, edi, ebx
        pop    [fProjModified]
;        mov     [fProjModified], FALSE

        test    eax, eax
        jz      .filesloop

.adderror:
        mov     [fProjModified], TRUE
        stdcall FreeFStruct, edi   ; error add file...
        jmp     .filesloop


;******************************************************************
.read_vars:
        stdcall StrLen, esi
        test    eax, eax
        jz      .nextchunk

        push    esi
        lea     esi, [esi+eax+1]
        stdcall StrDup ; from the stack.
        push    eax             ; key name

        stdcall StrLen, esi

        push    esi
        lea     esi, [esi+eax+1]
        stdcall StrDup ; from the stack.
        push    eax     ; key value.

        stdcall _AddKeyValueToArray, poVarArray ; two more arguments already in stack.
        jmp     .read_vars


;******************************************************************
; reads main source file name.

.read_main_source_name:

        stdcall StrLen, esi
        mov     ebx, eax

        test    ebx, ebx
        jz      .nextchunk

        stdcall CreateFStruct, esi, ftMainSource
        mov     edi, eax

        cmp     [.wparam], 0
        jne     .addmain        ; loaded from template so someone else have to bother for consistency

        stdcall GetModified, edi
        test    eax, eax
        jz      .addmain

        stdcall ProjectInconsistent, edi
        cmp     eax, IDNO
        jne     .addmain

        stdcall FreeFStruct, edi
        mov     [fProjModified], TRUE
        jmp     .nextchunk

.addmain:
        push   [fProjModified]
        invoke  SendMessageA, [.hwnd], PMM_ADDFILE, edi, NULL
        pop    [fProjModified]

        jmp     .nextchunk


;******************************************************************

.read_compiler_memory:
        lodsd
        mov     [poMemory], eax
        jmp     .nextchunk

;******************************************************************

.read_output_filename:
        xor     eax, eax
        lodsb
        mov     [poBinNameAuto], eax

        stdcall StrCopy, [poBinName], esi
        jmp     .nextchunk

;******************************************************************
onmessage _CEM_GETTEXT
        mov     eax, [ptrProjectFile]
        stdcall ChangeDir, [eax+TOpenFile.hFileName]

        mov     esi, [.lparam]  ; pointer to TInMemoryFile

        stdcall GetMem, 65536       ; Maximal size of the project file.
        jc      .errorgettext

        mov     [esi+TInMemoryFile.ptrBuffer], eax
        mov     edi, eax

; magic header.
        mov     eax, 'FNPr'
        stosd
        mov     eax, $0a1a0a0d  ;) magic number. 'CR, LF, EOF, LF'
        stosd

;_________________________
;
; write chunk MAIN
;_________________________

        invoke  SendMessageA, [.hwnd], PMM_GETMAINFILE, 0, 0
        test    eax, eax
        jz      .main_chunk_ok

        mov     ecx, eax
        mov     eax, 'MAIN'
        stosd

        add     edi, 4
        mov     esi, edi

        stdcall GetRelativePath, [ecx+TOpenFile.hFileName]
        push    eax
        call    .StrToStream
        stdcall StrDel ; from the stack
        xor     al,al
        stosb   ; end of string.

        call    .finalize_chunk
.main_chunk_ok:

;_________________________
;
; write chunks CTNM
;_________________________
        mov     eax, 'CTNM'     ; compiler target name.
        stosd

        add     edi, 4
        mov     esi, edi

        mov     al, byte [poBinNameAuto]
        stosb

        mov     eax, [poBinName]
        stdcall .StrToStream

        mov     al, 0
        stosb

        call    .finalize_chunk

;_________________________
;
; write chunks CMEM
;_________________________

        mov     eax, 'CMEM'
        stosd

        add     edi, 4
        mov     esi, edi

        mov     eax, [poMemory]
        stosd

        call    .finalize_chunk

;_________________________
;
; write chunks VARS
;_________________________

        mov     ebx, [poVarArray]
        test    ebx, ebx
        jz      .vars_ok

        mov     ecx, [ebx+TArray.count]
        lea     ebx, [ebx+TArray.array]
        jecxz   .vars_ok

        mov     eax, 'VARS'
        stosd

        add     edi, 4
        mov     esi, edi

.varsloop:
        mov     eax, [ebx+TEnvVarType.pName]
        call    .StrToStream
        mov     al, 0
        stosb
        mov     eax, [ebx+TEnvVarType.pValue]
        call    .StrToStream
        mov     al, 0
        stosb

        add     ebx, sizeof.TEnvVarType
        dec     ecx
        jnz     .varsloop

        stosb   ; final zero.

        call    .finalize_chunk

.vars_ok:

;_________________________
;
; write chunks PRTR
;_________________________

; Save categories...
        invoke  GetDlgItem, [.hwnd], ProjTreeCtrlID

        ;  proc CategoriesScan, hTree, tvRoot, lparam, ptrCallback
        stdcall CategoriesScan, eax, TVI_ROOT, eax, SaveOneCategory


; all is ok, so finish this work.
        mov     esi, [.lparam]
        sub     edi, [esi+TInMemoryFile.ptrBuffer]
        mov     [esi+TInMemoryFile.fileSize], edi
        xor     eax, eax
        mov     [esi+TInMemoryFile.fAscii], eax
        clc
        return

.errorgettext:
        mov     eax, 1
        stc
        return

;******************************************************************************************


onmessage  _CEM_CHANGENOTIFY
; change directory to the new name...
        mov     ebx, [ptrProjectFile]
        stdcall ChangeDir, [ebx+TOpenFile.hFileName]
        stdcall SetMainTitle
        stdcall AddToMRUList, [ptrMRUProj], [ebx+TOpenFile.hFileName]
        clc
        return


onmessage _CEM_FOCUSFILE
        invoke  SetFocus, [.hwnd]
        clc
        return


onmessage _CEM_CANACTION
        xor     eax, eax
        clc
        return

onmessage _CEM_EDITACTION
        clc
        return


onmessage _CEM_GETFILE
        mov     eax, [ptrProjectFile]
        clc
        return


onmessage _CEM_GETMODIFIED
        mov     eax, [fProjModified]
        clc
        return


onmessage _CEM_SETMODIFIED
        push    [.wparam]
        pop     [fProjModified]
        clc
        return


onmessage WM_ACTIVATE
        stdcall FocusFile, [ptrProjectFile]
        stc
        return

onmessage WM_DROPFILES
        lea     esi, [.str]
        invoke  DragQueryFile, [.wparam], -1, esi, 1024
        mov     ebx, eax
        xor     edi, edi

.opendroploop:
        invoke  DragQueryFile, [.wparam], edi, esi, 1024
        stdcall OpenFileByName, esi, NULL, FALSE
        test    eax, eax
        jz      .next
        invoke  SendMessageA, [.hwnd], PMM_ADDFILE, eax, -1
.next:
        inc     edi
        dec     ebx
        jnz     .opendroploop

        invoke  DragFinish, [.wparam]

        xor     eax, eax
        clc
        return

onmessage WM_COMMAND
        mov     eax, [.wparam]

        cmp     eax, ProjSettingsID
        je      .projsettings

        cmp     eax, IDOK
        je      .enter_key

        cmp     eax, FirstID
        jb      .from_menu

.tomain:
        invoke  PostMessageA, [hMainWindow], WM_COMMAND, [.wparam], [.lparam]

        clc
        xor     eax, eax
        return


.projsettings:
locals
  .btnrect RECT
endl
        invoke  GetDlgItem, [.hwnd], ProjSettingsID
        lea     ebx, [.btnrect]
        invoke  GetWindowRect, eax, ebx
        invoke  TrackPopupMenu, [hSettingsPopup], TPM_LEFTALIGN or TPM_LEFTBUTTON, \
                [.btnrect.left], [.btnrect.top], 0, [.hwnd], 0

        clc
        return


.enter_key:
        invoke  GetFocus
        invoke  GetDlgCtrlID, eax

        cmp     eax, ProjListCtrlID
        je      .listviewenter
        cmp     eax, ProjMainCtrlID
        jne     .ondefault

.listviewenter:
        mov     [.wparam], eax
        jmp     .itemactivate


.from_menu:
; this is actually fast settings menu.
        movzx   eax, word [.wparam]

        shr     eax, 8
        sub     eax, VarMenuBaseID
        mov     esi, [poVarArray]
        cmp     eax, [esi+TArray.count]
        jae     .endmenu

        lea     esi, [esi+eax*sizeof.TEnvVarType + TArray.array]
; so process the value.
        movzx   ecx, word [.wparam]
        and     ecx, $ff

        stdcall StrPtr, [esi+TEnvVarType.pValue]
        mov     edi, eax
        mov     edx, eax
.loop1:
        cmp     byte [edi], 0
        je      .endmenu

        cmp     byte [edi], '|'
        lea     edi, [edi+1]
        jne     .loop1

        loop    .loop1

        push    edi     ; first separator + 1
.loop2:
        mov     al, [edi]
        lea     edi, [edi+1]
        cmp     al, 0
        je      .endfound
        cmp     al, '|'
        jne     .loop2

.endfound:
        movzx   ecx, al
        mov     byte [edi-1], 0

        pop     esi
        stdcall StrDup, esi
        mov     ebx, eax

        mov     [edi], cl       ; restore the separator.
        sub     edi, 2
        sub     esi, 2

.shift:
        cmp     esi, edx
        jb      .endshift

        mov     al, [esi]
        lea     esi, [esi-1]
        mov     [edi], al
        lea     edi, [edi-1]
        jmp     .shift

.endshift:
        mov     byte [edi], '|'
        mov     edi, edx

        stdcall StrPtr, ebx
        mov     esi, eax

.copyloop:
        mov     al, [esi]
        lea     esi, [esi+1]

        test    al, al
        jz      .endcopy

        mov     [edi], al
        lea     edi, [edi+1]
        jmp     .copyloop

.endcopy:
        stdcall StrDel, ebx
        stdcall CreateParametersMenu
        invoke  SendMessageA, [.hwnd], _CEM_SETMODIFIED, TRUE, 0

.endmenu:
        clc
        return



;**********************************************************************************************

onmessage PMM_GETMAINFILE

        mov     [.lvi.mask], LVIF_PARAM
        mov     [.lvi.iItem], 0
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], ProjMainCtrlID, LVM_GETITEM, 0, eax
        test    eax, eax
        jz      .endgetmain
        mov     eax, [.lvi.lParam]
.endgetmain:
        clc
        return

;**********************************************************************************************

onmessage WM_NOTIFY
        mov     ecx, [.wparam]
        mov     esi, [.lparam]
        cmp     ecx, ProjTreeCtrlID
        je      .treenotify
        cmp     ecx, ProjMainCtrlID
        je      .listnotify
        cmp     ecx, ProjListCtrlID
        je      .listnotify

        stc
        return

;-----------ListView notification messages-----------------

.listnotify:
        cmp     [esi+NMHDR.code], LVN_ITEMACTIVATE
        je      .itemactivate
        cmp     [esi+NMHDR.code], LVN_KEYDOWN
        je      .listkey
        cmp     [esi+NMHDR.code], NM_RCLICK
        je      .lvrightclick

        stc
        return

;        je      .lvrightclick
;        cmp     [esi+NMHDR.code], LVN_ITEMCHANGED
;        jmp     .qfalse

.lvrightclick:
        push    [hListPopup]

        lea     eax, [.pnt]
        invoke  GetCursorPos, eax
        pop     eax

        invoke  TrackPopupMenu, eax, TPM_LEFTALIGN or TPM_RIGHTBUTTON, [.pnt.x], [.pnt.y], 0, [.hwnd], NULL
        jmp     .qfalse

.itemactivate:
        xor     ebx, ebx
        dec     ebx

.openloop:
        invoke  SendDlgItemMessageA, [.hwnd], [.wparam], LVM_GETNEXTITEM, ebx, LVNI_SELECTED
        cmp     eax, -1
        je      .qfalse

        mov     ebx, eax

        mov     [.lvi.mask], LVIF_PARAM
        mov     [.lvi.iItem], eax
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], [.wparam], LVM_GETITEM, 0, eax
        stdcall LoadFile, [.lvi.lParam], NULL
        jmp     .openloop


;---------- Del key is pressed in the list view -------------------
.listkey:
        cmp     [esi+LVKEYDOWN.wVKey], VK_DELETE
        jne     .qfalse

.delitems:
        xor     ebx, ebx
        push    ebx             ; marker for the end of the list
        dec     ebx
.delloop:
        invoke  SendDlgItemMessageA, [.hwnd], [.wparam], LVM_GETNEXTITEM, ebx, LVNI_SELECTED
        cmp     eax, -1
        je      .delit

        mov     ebx, eax

        mov     [.lvi.mask], LVIF_PARAM
        mov     [.lvi.iItem], eax
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hwnd], [.wparam], LVM_GETITEM, 0, eax
        push    [.lvi.lParam]
        jmp     .delloop

.delit:
        cmp     dword [esp], 0
        je      .delitloop

        invoke  MessageBoxA, [hApplication], cDelFileQuery, cDelFileTitle, MB_ICONQUESTION or MB_YESNO
        cmp     eax, IDYES
        je      .delitloop

.clearstack:
        pop     ecx
        jecxz   .endfiledel
        jmp     .clearstack

.delitloop:
        pop     ecx
        jecxz   .endfiledel
        invoke  SendMessageA, [.hwnd], PMM_REMOVEFILE, ecx, 0
        jmp     .delitloop

.endfiledel:
        xor     eax, eax
        clc
        return

  cDelFileQuery text 'Do you really want to remove selected file(s) from the project?'
  cDelFileTitle text 'Remove file from project.'

;--- Category tree notification messages ---------
.treenotify:
        cmp     [esi+NMHDR.code], TVN_SELCHANGED
        je      .selchanged

        cmp     [esi+NMHDR.code], TVN_KEYDOWN
        je      .keydown

        cmp     [esi+NMHDR.code], NM_RCLICK
        je      .tvrightclick

        cmp     [esi+NMHDR.code], TVN_ENDLABELEDIT
        je      .endlabeledit

        cmp     [esi+NMHDR.code], TVN_DELETEITEM
        jne     .qfalse

.deleteitem:
        mov     edi, [esi+NMTREEVIEW.itemOld.lParam]
        test    edi, edi
        jz      .qfalse

        test    [esi+NMTREEVIEW.itemOld.state], TVIS_FOCUSED
        jz      .freelist

        invoke  SendDlgItemMessageA, [.hwnd], ProjListCtrlID, LVM_DELETEALLITEMS, 0, 0

.freelist:
        stdcall ListFree, edi, FileListFreeCallback
        jmp     .qfalse

;----------- end of label editing ------------------------
.endlabeledit:
        mov     esi, [.lparam]
        cmp     [esi+TVDISPINFO.item.pszText], 0
        je      .endedit

        mov     [fProjModified], TRUE
        mov     [esi+TVDISPINFO.item.mask], TVIF_TEXT
        lea     esi, [esi+TVDISPINFO.item]
        invoke  SendDlgItemMessageA, [.hwnd], ProjTreeCtrlID, TVM_SETITEM, 0, esi

.endedit:
       clc
       return

;---------- right click on treeview control --------------
.tvrightclick:
        lea     eax, [.pnt]
        invoke  GetCursorPos, eax
        invoke  TrackPopupMenu, [hTreePopup], TPM_LEFTALIGN or TPM_RIGHTBUTTON, [.pnt.x], [.pnt.y], 0, [.hwnd], NULL
        jmp     .qfalse


;---------- selection changed notification ---------------
.selchanged:
; load the new selected category in the listview...
        stdcall ReloadListView, [.hwnd], [esi+NMTREEVIEW.itemNew.hItem]
        xor     eax, eax
        clc
        return

;------------- key down notification -----------------
.keydown:
        cmp     [esi+TVKEYDOWN.wVKey], VK_DELETE
        jne     .qfalse

; delete key on category...
        invoke  MessageBoxA, [hApplication], cDelProjQuery, cDelProjTitle, MB_ICONQUESTION or MB_YESNO
        cmp     eax, IDYES
        jne     .qfalse

        invoke  SendDlgItemMessageA, [.hwnd], ProjTreeCtrlID, TVM_GETNEXTITEM, TVGN_CARET, 0
        invoke  SendDlgItemMessageA, [.hwnd], ProjTreeCtrlID, TVM_DELETEITEM, 0, eax
        jmp     .qfalse

cDelProjQuery text 'Do you really want to remove this category and all category files from the project?'
cDelProjTitle text 'Remove category.'

onmessage WM_CLOSE
        stdcall CloseFile, [ptrProjectFile]
        cmp     eax, cfrDestroyed
        jne     .qfalse
        mov     [ptrProjectFile], 0
        jmp     .qfalse

onmessage WM_DESTROY
        mov     [ptrProjectFile], 0

        invoke  SendMessageA, [.hwnd], PMM_GETMAINFILE, 0, 0
        test    eax, eax
        jz      .mainfree

        stdcall FileListFreeCallback, eax

.mainfree:
        stdcall DeleteAllTVItems, [hProjManager] ; clear all items in the project and frees the memory.
        mov     [hProjManager], 0

        stdcall StrDel, [poBinName]
        mov     [poBinName], 0
        mov     [poBinNameAuto], TRUE

        cmp     [poVarArray], 0
        je      .qfalse

        stdcall FreeMem, [poVarArray]
        mov     [poVarArray], 0

        jmp     .qfalse


cMRUProjSection text 'MRU projects'

onmessage AM_INITWINDOW

        xor     ebx, ebx

        invoke  CreateWindowExA, 0, cButtonClassName, ebx,                   \
                                WS_CHILD or WS_VISIBLE or BS_OWNERDRAW or   \
                                BS_VCENTER or WS_TABSTOP,                   \
                                ebx, ebx, ebx, 16,                          \
                                [.hwnd], ProjSettingsID, [hInstance], ebx

        push    0 BST_CHECKED BM_SETCHECK eax
        stdcall SetAlign, eax, waTop
        invoke  SendMessageA ; from the stack

        invoke  CreateWindowExA, WS_EX_CLIENTEDGE, cListviewClassName, ebx,      \
                                WS_CHILD or WS_VISIBLE or LVS_REPORT or         \
                                LVS_SHAREIMAGELISTS or LVS_SORTASCENDING or     \
                                LVS_NOSCROLL or LVS_NOCOLUMNHEADER or           \
                                LVS_NOSORTHEADER or WS_TABSTOP,                 \
                                ebx, ebx, ebx, 20,                              \
                                [.hwnd], ProjMainCtrlID, [hInstance], ebx

        mov     edi, eax
        stdcall SetAlign, eax, waTop

        mov     [.col.mask], LVCF_FMT or LVCF_WIDTH
        mov     [.col.fmt], LVCFMT_LEFT
        mov     [.col.cx], 1024
        lea     eax, [.col]
        invoke  SendMessageA, edi, LVM_INSERTCOLUMN, ebx, eax
        invoke  SendMessageA, edi, LVM_SETIMAGELIST, LVSIL_SMALL, [hTabIml]

        invoke  CreateWindowExA, ebx, cStaticClassName, ebx,              \
                                WS_CHILD or WS_VISIBLE or SS_LEFT,       \
                                ebx, ebx, ebx, 4,                        \
                                [.hwnd], ebx, [hInstance], ebx
        stdcall SetAlign, eax, waTop

        invoke  CreateWindowExA, WS_EX_CLIENTEDGE,                                                       \
                                cTreeViewClassName, ebx,                                                \
                                WS_CHILD or WS_VISIBLE or TVS_DISABLEDRAGDROP or TVS_HASBUTTONS or     \
                                TVS_SHOWSELALWAYS or TVS_HASLINES or TVS_LINESATROOT or TVS_EDITLABELS or WS_TABSTOP, \
                                ebx, ebx, ebx, 100,                                                     \
                                [.hwnd], ProjTreeCtrlID, [hInstance], ebx
        mov     edi, eax
        stdcall SetAlign, eax, waTop
        invoke  SendMessageA, edi, TVM_SETIMAGELIST, TVSIL_NORMAL, [imlCategories]

        stdcall CreateSplitter, edi, TRUE, resVSplit, resHSplit
        invoke  SendMessageA, eax, SPM_SETMAXMIN, 16, 1000


        invoke  CreateWindowExA, WS_EX_CLIENTEDGE, cListviewClassName, ebx,              \
                                WS_CHILD or WS_VISIBLE or LVS_REPORT or                 \
                                LVS_SHAREIMAGELISTS or LVS_SORTASCENDING or            \
                                LVS_NOCOLUMNHEADER or                                  \
                                LVS_SHOWSELALWAYS or WS_TABSTOP or LVS_NOSORTHEADER,  \
                                ebx, ebx, ebx, ebx,                                     \
                                [.hwnd], ProjListCtrlID, [hInstance], ebx

        mov     edi, eax
        stdcall SetAlign, eax, waClient

        invoke  SendMessageA, edi, LVM_SETIMAGELIST, LVSIL_SMALL, [hTabIml]
        invoke  SendMessageA, edi, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, \
                             LVS_EX_LABELTIP


        mov     [.col.mask], LVCF_FMT or LVCF_SUBITEM
        mov     [.col.fmt], LVCFMT_LEFT
        mov     [.col.iSubItem], 0
        lea     eax, [.col]
        invoke  SendMessageA, edi, LVM_INSERTCOLUMN, ebx, eax
        invoke  DragAcceptFiles, [.hwnd], TRUE

.qfalse:
        xor     eax,eax
        clc
        return


onmessage WM_DRAWITEM
        cmp     [.wparam], ProjSettingsID
        jne     .ondefault

        mov     esi, [.lparam]
        mov     edi, [esi+DRAWITEMSTRUCT.hDC]
        lea     ebx, [esi+DRAWITEMSTRUCT.rcItem]

        invoke  SetBkMode, edi, TRANSPARENT

        invoke  GetSysColor, COLOR_BTNFACE
        invoke  CreateSolidBrush, eax
        push    eax
        invoke  FillRect, edi, ebx, eax
        invoke  DeleteObject ; from the stack.

        invoke  DrawEdge, edi, ebx, EDGE_ETCHED,  BF_RECT; or BF_FLAT

        stdcall StrPtr, [hSettingsString]
        test    eax, eax
        je      .setshort
        cmp     eax, -1
        jne     .drawit

.setshort:
        mov     eax, cSettingsCaption

.drawit:
        add     [ebx+RECT.left],4
        invoke  DrawTextA, edi, eax, -1, ebx, DT_LEFT or DT_VCENTER or DT_SINGLELINE

        clc
        mov     eax, 1
        return

endwp




; it should return CF=1 if the result is still not found.
; arguments are [ptrList], [hTVItem] and [.lparam]
proc SaveOneCategory, .ptrList, .hItem, .hTree
.tvi TVITEM
.count dd ?
begin
        push    ebx esi

        mov     eax, 'PRTR'
        stosd

        add     edi, 4
        mov     esi, edi        ; pointer to the data.

        stdcall GetFullItemName, [.hTree], [.hItem]
        mov     ebx, eax

        mov     [.tvi.mask], TVIF_IMAGE or TVIF_PARAM
        mov     eax, [.hItem]
        mov     [.tvi.hItem], eax
        lea     eax, [.tvi]
        invoke  SendMessageA, [.hTree], TVM_GETITEM, 0, eax
        test    eax, eax
        jz      .finish

        mov     eax, [.tvi.iImage]         ; image index.
        stosd
        xor     eax, eax                   ; reserved.
        stosd

        mov     eax, ebx
        call    ProjManProc.StrToStream
        xor     al,al
        stosb

        stdcall StrDel, ebx     ; category name.

        mov     ebx, [.tvi.lParam]
        mov     edx, [ebx+TArray.count]
        mov     [.count], edx
        lea     ebx, [ebx+TArray.array]

.looplist:
        dec     [.count]
        js      .finish

        mov     eax, [ebx]      ; ptr to TOpenFile
        lea     ebx, [ebx+4]

        stdcall GetRelativePath, [eax+TOpenFile.hFileName]
        push    eax
        call    ProjManProc.StrToStream
        stdcall StrDel ; from the stack
        xor     al,al
        stosb
        jmp     .looplist

.finish:
        xor     eax, eax
        stosb

        call    ProjManProc.finalize_chunk

        stc
        pop     esi ebx
        return
endp



proc FileListFreeCallback, .ptrOpenFile
begin
        push    esi
        mov     esi, [.ptrOpenFile]

        mov     [esi+TOpenFile.projectID], FALSE
        stdcall FileChanged, esi, fcEditor
        pop     esi
        return
endp


;***********************************************************
; Set the filename of the project and updates the title of
; the main window.
;***********************************************************
proc SetMainTitle
begin
        push    esi

        xor     eax, eax
        mov     esi, [ptrProjectFile]
        test    esi, esi
        jz      @f

        stdcall StrPtr, [esi+TOpenFile.hFileName]

@@:
        invoke  SendMessageA, [hMainWindow], WM_SETTEXT, 0, eax
        pop     esi
        return
endp



;***********************************************************
; List view utils.
;***********************************************************
proc ReloadListView, .hProj, .hCategory
begin
        push    edi ebx

        invoke  SendDlgItemMessageA, [.hProj], ProjListCtrlID, LVM_DELETEALLITEMS, 0, 0
        stdcall GetTVItemPtr, [.hProj], [.hCategory]
        mov     edi, eax

        mov     eax, [edi+TArray.count]
        mov     ebx, eax
        invoke  SendDlgItemMessageA, [.hProj], ProjListCtrlID, LVM_SETITEMCOUNT, ebx, 0

        lea     edi, [edi+TArray.array]

.addnewlist:
        dec     ebx
        js      .finish

        stdcall AddToListView, [.hProj], ProjListCtrlID, [edi]
        lea     edi, [edi+4]
        jmp     .addnewlist

.finish:
        invoke  GetDlgItem, [.hProj], ProjListCtrlID
        invoke  PostMessageA, eax, LVM_SETCOLUMNWIDTH, 0, LVSCW_AUTOSIZE
        pop     ebx edi
        return
endp


proc AddToListView, .hProject, .ListID, .ptrOpenFile
.lvi LVITEM
begin
        push    esi
        mov     esi, [.ptrOpenFile]

        stdcall GetScreenProperties, esi
        test    eax, eax
        jz      .finish

        push    eax     ; for StrDel
        stdcall StrPtr, eax

        mov     [.lvi.mask], LVIF_IMAGE or LVIF_PARAM or LVIF_TEXT
        mov     [.lvi.iItem], 0
        mov     [.lvi.iSubItem], 0
        mov     [.lvi.iImage], edx
        mov     [.lvi.lParam], esi
        mov     [.lvi.pszText], eax

        lea     eax, [.lvi]
        invoke  SendDlgItemMessageA, [.hProject], [.ListID], LVM_INSERTITEM, 0, eax
        stdcall StrDel ; from the stack.
.finish:
        pop     esi
        return
endp


;------------------------------------------------------------;
; Searches the project for the file and returns:             ;
; eax - handle of the category that contain this file.       ;
;   eax = 0 if the file is main file.                        ;
;   eax = -1 if the file was not found.                      ;
; edx - index in TList containing the file pointer.          ;
;------------------------------------------------------------;
proc SearchForFile, .hProject, .ptrOpenFile
begin
        invoke  SendMessageA, [.hProject], PMM_GETMAINFILE, 0, 0
        test    eax, eax
        jz      .nomain

        cmp     eax, [.ptrOpenFile]
        je      .main

.nomain:
        invoke  GetDlgItem, [.hProject], ProjTreeCtrlID
        mov     ebx, eax
        stdcall CategoriesScan, ebx, TVI_ROOT, [.ptrOpenFile], _SearchCategory
        return

.main:
        mov     edx, eax
        xor     eax, eax
        return
endp


proc _SearchCategory, .ptrList, .hTVItem, .ptrOpenFile
begin
        stdcall ListIndexOf, [.ptrList], [.ptrOpenFile]
        jc      .finish

        mov     edx, [.hTVItem]
        xchg    eax, edx
        clc
.finish:
        return
endp


;---------------------------------------------------------------
; Recursively loops through all categories and calls callback
; procedure for every category.
;---------------------------------------------------------------
proc CategoriesScan, .hTree, .tvRoot, .lparam, .ptrCallback
.tvi TVITEM
begin
        push    esi ebx
        invoke  SendMessageA, [.hTree], TVM_GETNEXTITEM, TVGN_CHILD, [.tvRoot]

.loop:
        mov     ebx, eax
        test    ebx, ebx
        jz      .notfound

        mov     [.tvi.mask], TVIF_PARAM
        mov     [.tvi.hItem], ebx
        lea     eax, [.tvi]
        invoke  SendMessageA, [.hTree], TVM_GETITEM, 0, eax

        mov     esi, [.tvi.lParam]
        test    esi, esi
        jz      .listdone

; it should return CF=1 if the result is still not found.
; arguments are [ptrList] and [hTVItem] and [.lparam]
        stdcall [.ptrCallback], esi, ebx, [.lparam]
        jnc     .found

.listdone:
        stdcall CategoriesScan, [.hTree], ebx, [.lparam], [.ptrCallback]
        jnc     .found

        invoke  SendMessageA, [.hTree], TVM_GETNEXTITEM, TVGN_NEXT, ebx
        jmp     .loop

.notfound:
        stc
        pop     ebx esi
        return

.found:
        pop     ebx esi
        return
endp


;---------------------------------------------
; Returns handle to string contains full path
; name for given tree-view item.
; returns also, the image index of the item in ecx
;---------------------------------------------
proc GetFullItemName, .hTree, .hItem
.tvi TVITEM
.str rb 256
.img dd ?
begin
        push    esi ebx

        stdcall StrNew
        mov     esi, eax
        mov     eax, [.hItem]

.buildloop:
        mov     ebx, eax
        test    ebx, ebx
        jz      .rootoftree

        mov     [.tvi.mask], TVIF_TEXT or TVIF_IMAGE
        mov     [.tvi.hItem], ebx
        lea     eax, [.str]
        mov     [.tvi.pszText], eax
        mov     [.tvi.cchTextMax], 256
        lea     eax, [.tvi]
        invoke  SendMessageA, [.hTree], TVM_GETITEM, 0, eax

        cmp     ebx, [.hItem]
        jne     .dostring

        push    [.tvi.iImage]
        pop     [.img]

.dostring:
         stdcall StrCharInsert, esi, '\', 0
        stdcall StrInsert, esi, [.tvi.pszText], 0

        invoke  SendMessageA, [.hTree], TVM_GETNEXTITEM, TVGN_PARENT, ebx
        jmp     .buildloop

.rootoftree:
        mov     eax, esi
        mov     ecx, [.img]
        pop     ebx esi
        return
endp


;***********************************************************
; TreeView utils. This is small library for easy work with
; TreeView control.
;***********************************************************

;**************************************************************
; Returns lParam of the TreeView item.
;**************************************************************
proc GetTVItemPtr, .hProject, .hItem
.item   TVITEM
begin
        push    ecx edx

        push    [.hItem]
        pop     [.item.hItem]
        mov     [.item.mask], TVIF_PARAM
        lea     eax, [.item]
        invoke  SendDlgItemMessageA, [.hProject], ProjTreeCtrlID, TVM_GETITEM, 0, eax
        test    eax, eax
        jz      .error

        mov     eax, [.item.lParam]
        clc
        pop     edx ecx
        return

.error:
        stc
        pop     edx ecx
        return
endp



;**************************************************************
; Sets lParam of the TreeView item.
;**************************************************************
proc SetTVItemPtr, .hProject, .hItem, .lparam
.item   TVITEM
begin
        push    eax ecx edx
        push    [.hItem]
        pop     [.item.hItem]
        mov     [.item.mask], TVIF_PARAM
        push    [.lparam]
        pop     [.item.lParam]
        lea     eax, [.item]
        invoke  SendDlgItemMessageA, [.hProject], ProjTreeCtrlID, TVM_SETITEM, 0, eax
        pop     edx ecx eax
        return
endp





;***********************************************
; Handler of action actMoveCategory
;***********************************************
proc OnMoveCategory, .wparam, .lparam
begin
        xor     ebx, ebx
        cmp     [.wparam], actMoveCategoryUp
        je      @f
        inc     ebx
@@:
        invoke  GetDlgItem, [hProjManager], ProjTreeCtrlID
        mov     esi, eax

        invoke  SendMessageA, esi, TVM_GETNEXTITEM, TVGN_CARET, 0
        stdcall MoveTVItem, esi, eax, ebx
        mov     [fProjModified], TRUE
        return
endp


;****************************************************************
; Moves one hItem up or down in the treeview, depending of the
; fMoveDown:
;    FALSE - move up
;    TRUE  - move down
;****************************************************************
proc MoveTVItem, .hTreeView, .hItem, .fMoveDown
.ptr dd ?
.obj dd ?
.tvi TVITEM
.lparam dd ?
.tvs TVSORTCB
begin
        push    esi edi ebx

        invoke  SendMessageA, [.hTreeView], TVM_GETCOUNT, 0, 0
        shl     eax, 2
        stdcall GetMem, eax
        mov     [.ptr], eax
        mov     edi, eax

        mov     eax, [.hItem]
        mov     [.tvi.hItem], eax
        mov     [.tvi.mask], TVIF_PARAM
        lea     eax, [.tvi]
        invoke  SendMessageA, [.hTreeView], TVM_GETITEM, 0, eax
        mov     eax, [.tvi.lParam]
        mov     [.lparam], eax

        invoke  SendMessageA, [.hTreeView], TVM_GETNEXTITEM, TVGN_PARENT, [.hItem]
        mov     ebx, eax

        invoke  SendMessageA, [.hTreeView], TVM_GETNEXTITEM, TVGN_CHILD, ebx
.getloop:
        test    eax, eax
        jz      .endofchildren

        mov     [.tvi.hItem], eax
        mov     [.tvi.mask], TVIF_PARAM or TVIF_HANDLE
        lea     eax, [.tvi]
        invoke  SendMessageA, [.hTreeView], TVM_GETITEM, 0, eax
        mov     eax, [.tvi.lParam]
        cmp     eax, [.lparam]
        jne     .storeit
        mov     [.obj], edi
.storeit:
        stosd

        invoke  SendMessageA, [.hTreeView], TVM_GETNEXTITEM, TVGN_NEXT, [.tvi.hItem]
        jmp     .getloop

.endofchildren:
        stosd
        cmp     [.fMoveDown], FALSE
        je      .moveup

.movedown:
        mov     edi, [.obj]
        mov     eax, [edi+4]
        test    eax, eax
        jz      .cantmove       ; it is the last element.

        mov     ecx, [edi]
        mov     [edi], eax
        mov     [edi+4], ecx
        jmp     .sortit

.moveup:
        mov     edi, [.obj]
        cmp     edi, [.ptr]
        je      .cantmove               ; it is the first element

        mov     eax, [edi-4]
        mov     ecx, [edi]
        mov     [edi], eax
        mov     [edi-4], ecx

.sortit:
        mov     [.tvs.hParent], ebx
        mov     [.tvs.lpfnCompare], CompareTwoItems
        mov     eax, [.ptr]
        mov     [.tvs.lParam], eax
        lea     eax, [.tvs]
        invoke  SendMessageA, [.hTreeView], TVM_SORTCHILDRENCB, 0, eax

.cantmove:
        stdcall FreeMem, [.ptr]
        pop     ebx edi esi
        return
endp


proc CompareTwoItems, .lParam1, .lParam2, .ptrList
begin
        push    esi

        mov     esi, [.ptrList]
        mov     ecx, [.lParam1]
        mov     edx, [.lParam2]
.loop:
        lodsd
        test    eax, eax
        jz      .notfound

        cmp     eax, ecx
        je      .first

        cmp     eax, edx
        jne     .loop

.second:
        xor     eax, eax
        inc     eax
        pop     esi
        return

.first:
        xor     eax, eax
        dec     eax
        pop     esi
        return

.notfound:
        xor     eax, eax
        pop     esi
        return
endp


;****************************************************************
; Returns in ebx the handle of parent treeview item.
;****************************************************************
proc GetItemParent, .hItem
begin
        push    eax ecx edx

        invoke  SendDlgItemMessageA, [hProjManager], ProjTreeCtrlID, TVM_GETNEXTITEM, TVGN_PARENT, [.hItem]
        test    eax,eax
        jz      .error
        clc
        jmp     .finish

.error:
        stc
.finish:
        mov     ebx, eax
        pop     edx ecx eax
        return
endp


proc DeleteAllTVItems, .hProj
begin
.loop:
        invoke  SendDlgItemMessageA, [.hProj], ProjTreeCtrlID, TVM_GETNEXTITEM, TVGN_ROOT, 0
        test    eax, eax
        jz      .finish

        stdcall DeleteOneTVItem, [.hProj], eax
        jmp     .loop
.finish:
        return
endp


proc DeleteOneTVItem, .hProj, .hItem
begin
.clearloop:
        invoke  SendDlgItemMessageA, [.hProj], ProjTreeCtrlID, TVM_GETNEXTITEM, TVGN_CHILD, [.hItem]
        test    eax, eax
        jz      .childrendeleted

        stdcall DeleteOneTVItem, [.hProj], eax
        jmp     .clearloop

.childrendeleted:
        invoke  SendDlgItemMessageA, [.hProj], ProjTreeCtrlID, TVM_DELETEITEM, 0, [.hItem]
        return
endp


;-------------------------------------------------------------------------
; Returns the handle of treeview item that follow the tree of direcories
; of [hFileName]. If there is no some (or any) of the directories of the
; path, it will be created.
; The function checks for "/" and "\" as items separator.
; Arguments:
; hFileName - handle or pointer to the path.
; hRoot     - is root TVItem for category. For examples if category
;             have to be created in the root of the TreeView, hParent
;             should be TVI_ROOT
; Returns:
;   eax - Handle to treeview item that should be parent of the file.
;   edx - pointer to the name of the file without path.
;-------------------------------------------------------------------------
proc GetCategoryTree, .hFileName, .hRoot, .iImage
begin
        push    esi edi ebx



        stdcall StrPtr, [.hFileName]
        mov     esi, eax

        stdcall StrLen, [.hFileName]
        mov     ecx, eax

; find the filename:
.findloop:
        cmp     byte [esi+ecx], '/'
        je      .foundname
        cmp     byte [esi+ecx], '\'
        je      .foundname
        dec     ecx
        jns     .findloop

; Returns the [hRoot] if there is no directories names.
        mov     eax, [.hRoot]
        mov     edx, esi
        pop     ebx edi esi
        return

.foundname:
        lea     edi, [esi+ecx+1]
        pushd   [edi]
        and     dword [edi], 0
        stdcall _DoCategoryTree, esi, [.hRoot], [.iImage]    ; track/create path items.
        popd    [edi]
        mov     edx, edi
        pop     ebx edi esi
        return
endp


proc _DoCategoryTree, .ptrName, .hTVRoot, .iImage
begin
        push    esi edi ebx
        mov     esi, [.ptrName]
        mov     ebx, [.hTVRoot]

.outloop:
        cmp     byte [esi], 0   ; is it the end?
        je      .endloop
        mov     edi, esi
.loop:
        lodsb
        cmp     al,'\'
        je      .foundslash
        cmp     al,'/'
        jne     .loop

.foundslash:
        mov     byte [esi-1], 0
        stdcall _DoGetOneItem, edi, ebx, [.iImage]
        mov     ebx, eax
        mov     byte [esi-1], '/'
        jmp     .outloop

.endloop:
        mov     eax, ebx
        pop     ebx edi esi
        return
endp


proc _DoGetOneItem, .ptrItem, .hParent, .iImage
.tvi TVITEM
.tvins TVINSERTSTRUCT
.str rb 256
begin
        push    esi edi ebx

        invoke  SendDlgItemMessageA, [hProjManager], ProjTreeCtrlID, TVM_GETNEXTITEM, TVGN_CHILD, [.hParent]
        test    eax, eax
        jz      .notfound
.itemscan:
        mov     ebx, eax
        mov     [.tvi.hItem], eax
        lea     esi, [.str]
        mov     [.tvi.pszText], esi
        mov     [.tvi.cchTextMax], 256
        mov     [.tvi.mask], TVIF_HANDLE or TVIF_TEXT
        lea     ecx, [.tvi]
        invoke  SendDlgItemMessageA, [hProjManager], ProjTreeCtrlID, TVM_GETITEM, 0, ecx

        stdcall StrCompNoCase, esi, [.ptrItem]
        jc      .found

        invoke  SendDlgItemMessageA, [hProjManager], ProjTreeCtrlID, TVM_GETNEXTITEM, TVGN_NEXT, ebx
        test    eax, eax
        jnz     .itemscan

.notfound:
        mov     eax, [.hParent]
        mov     [.tvins.hParent], eax
        mov     [.tvins.hInsertAfter], TVI_LAST
        mov     [.tvins.item.mask], TVIF_TEXT or TVIF_IMAGE or TVIF_SELECTEDIMAGE or TVIF_PARAM
        mov     eax, [.iImage]
        mov     [.tvins.item.iImage], eax
        mov     [.tvins.item.iSelectedImage], eax

        mov     eax, [.ptrItem]
        mov     [.tvins.item.pszText], eax

        stdcall CreateArray, 4
        mov     [.tvins.item.lParam], eax

        lea     eax, [.tvins]
        invoke  SendDlgItemMessageA, [hProjManager], ProjTreeCtrlID, TVM_INSERTITEM, 0, eax
        pop     ebx edi esi
        return

.found:
        mov     eax, ebx
        pop     ebx edi esi
        return
endp



;--------------------------------------------------------------------
; Recursively scans given source file [hFileName] for "include"
; statements and creates treeview items with filenames.
;--------------------------------------------------------------------
proc ScanFileForIncludes, .hFileName, .hTVParent
.tvi TVINSERTSTRUCT
.hthis dd ?
.ptr   dd ?
.cnt   dd ?
begin
        push    esi edi ebx

; Scan the file for includes.
        stdcall LoadBinaryFile, [.hFileName]
        test    eax, eax
        jz      .quit

        mov     [.ptr], eax
        mov     [.cnt], ecx
        test    ecx, ecx
        jz      .finish

; Add the file to the project tree.
        mov     eax, [.hTVParent]
        mov     [.tvi.hParent], eax
        mov     [.tvi.hInsertAfter], TVI_SORT

        stdcall DetectFileType, [.hFileName]
        test    eax, eax
        jz      .finish

        mov     ecx, [eax+TFileType.iFileIcon]
        mov     [.tvi.item.iImage], ecx
        mov     [.tvi.item.iSelectedImage], ecx

        stdcall CreateFStruct, [.hFileName], eax
        mov     [.tvi.item.lParam], eax
        mov     [.tvi.item.mask], TVIF_TEXT or TVIF_IMAGE or TVIF_PARAM or TVIF_SELECTEDIMAGE

        stdcall GetRelativePath, [.hFileName]
        push    eax
        stdcall StrPtr, eax
        mov     [.tvi.item.pszText], eax

        lea     eax, [.tvi]
        invoke  SendDlgItemMessageA, [hProjManager], ProjTreeCtrlID, TVM_INSERTITEM, 0, eax
        mov     [.hthis], eax

        stdcall StrDel ; from the stack

        mov     ecx, [.tvi.item.lParam]
        mov     [ecx+TOpenFile.projectID], eax

        mov     esi, [.ptr]
        mov     ecx, [.cnt]

.scan:
        mov     eax, [esi]
        cmp     al, ';'
        je      .comment
        or      eax, $20202020
        cmp     eax, 'incl'
        je      .maybe
.nextscan:
        inc     esi
        loop    .scan
.finish:
        stdcall FreeMem, [.ptr]
.quit:
        pop     ebx edi esi
        return

.comment:
        cmp     byte [esi], $0d
        je      .scan
        cmp     byte [esi], $0a
        je      .scan
        inc     esi
        loop    .comment
        jmp     .finish

.maybe:
        add     esi, 4
        sub     ecx, 4
        jbe     .finish

        mov     eax, [esi]
        and     eax, $ffffff
        or      eax, $202020
        cmp     eax, 'ude'
        je      .found
        add     esi, 3
        sub     ecx, 3
        jbe     .finish
        jmp     .scan

; Include statement
.found:
        add     esi, 3
        sub     ecx, 3
        jbe     .finish

.foundloop:
        mov     al, [esi]
        cmp     al, '"'
        je      .begin
        cmp     al, "'"
        je      .begin

        cmp     al, ' '
        je      .next
        cmp     al, $9
        jne     .nextscan

.next:
        inc     esi
        loop    .foundloop
        jmp     .finish

.begin:
        inc     esi
        dec     ecx
        jz      .finish
        mov     edi, esi
.scanend:
        cmp     [esi], al
        je      .nameok
        inc     esi
        loop    .scanend
        jmp     .finish
.nameok:
        push    ecx
        mov     byte [esi], 0
;        stdcall ConvertPath, edi
;        push    eax
;        stdcall StrPtr, eax
        stdcall ScanFileForIncludes, edi, [.hthis]
;        stdcall StrDel ; from the stack
        pop     ecx
        inc     esi
        dec     ecx
        jnz     .scan
        jmp     .finish
endp




proc EmptyVarList, .ptrVarArray
begin
        push    esi ebx

        mov     esi, [.ptrVarArray]
        test    esi, esi
        jz      .exit

        cmp     dword [esi], 0
        je      .array_clear

; now delete all strings in the array.
        mov     ebx, [esi]
        mov     ecx, [ebx+TArray.count]
        lea     ebx, [ebx+TArray.array]
        jecxz   .delok

.delloop:
        stdcall StrDel, [ebx+TEnvVarType.pName]
        stdcall StrDel, [ebx+TEnvVarType.pValue]

        add     ebx, sizeof.TEnvVarType
        loop    .delloop
.delok:
; so free the array itself.

        stdcall FreeMem, [esi]

.array_clear:
        stdcall CreateArray, sizeof.TEnvVarType
        mov     [esi], eax

.exit:
        pop     ebx esi
        return
endp






proc _AddKeyValueToArray, .ptrVarArray, .hValue, .hKey
begin
        push    esi

        mov     esi, [.ptrVarArray]
        mov     esi, [esi]
        mov     ecx, [esi+TArray.count]
        lea     esi, [esi+TArray.array-sizeof.TEnvVarType]
        inc     ecx

.searchloop:
        lea     esi, [esi+sizeof.TEnvVarType]
        dec     ecx
        jz      .notfound

        stdcall StrCompNoCase, [esi+TEnvVarType.pName], [.hKey]
        jnc     .searchloop

; found - append it.
        stdcall StrCharCat, [esi+TEnvVarType.pValue], '|'
        stdcall StrCat, [esi+TEnvVarType.pValue], [.hValue]
        stdcall   StrDel, [.hValue]

        pop     esi
        return

.notfound:
        mov     ecx, [.ptrVarArray]
        stdcall AddArrayItems, [ecx], 1
        mov     [ecx], edx

        mov     ecx, [.hValue]
        mov     edx, [.hKey]
        mov     [eax+TEnvVarType.pValue], ecx
        mov     [eax+TEnvVarType.pName], edx

        pop     esi
        return
endp



;********************************************************************************************************
; searches the project variables for  given name and copies the value (active one) in the buffer [.dest]
; Returns:
;   eax - count of copied chars.
;   CF = 1 - found and copied.
;   CF = 0 - not found.
;********************************************************************************************************

proc SearchForProjectVariable, .hName, .dest
begin
        push    esi edi ecx

        mov     esi, [poVarArray]
        test    esi, esi
        jz      .notfound

        mov     ecx, [esi+TArray.count]
        lea     esi, [esi+TArray.array]

        jecxz   .notfound
.loop:
        stdcall StrCompNoCase, [esi+TEnvVarType.pName], [.hName]
        jc      .found
        lea     esi, [esi+sizeof.TEnvVarType]
        loop    .loop

.notfound:
        clc
        xor     eax, eax
        pop     ecx edi esi
        return

.found:
        mov     edi, [.dest]
        stdcall StrPtr, [esi+TEnvVarType.pValue]
        mov     esi, eax
        xor     eax, eax

.copy:
        mov     cl, [esi]
        lea     esi, [esi+1]

        cmp     cl, 0
        je      .endofcopy

        cmp     cl, '|'
        je      .endofcopy

        mov     [edi], cl
        inc     eax
        lea     edi, [edi+1]
        jmp     .copy

.endofcopy:
        stc
        pop     ecx edi esi
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/projmanager.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
winmessage PMM_ADDFILE         ; (ptrOpenFile, hCategory) adds the file to the
                            ; given category and make it the part of the
                            ; project.

winmessage PMM_REMOVEFILE      ; (ptrOpenFile, 0): returns NULL if OK or TRUE if failed.

winmessage PMM_GETMAINFILE     ; returns handle to main filename. You should not delete or
                            ; modify this string in any way.
winmessage PMM_FILECHANGED     ; (ptrFile, 0) - notifies the project manager, that some
                            ; file properties were changed.


ProjTreeCtrlID = 1000
ProjListCtrlID = 1001
ProjMainCtrlID = 1002
ProjTargetOS   = 1003
ProjSettingsID = 1004


; format of the project file:

; 0: dword 'FRPR'               string ID
; 4: X dword -1                   offset to the older project options. N = 7-X
;
; 8: compiler options if presented.
;
;
; N:

; X = -1 - sizeof.TCompilerOptions

;



struct TEnvVarType
  .pName dd ?
  .pValue dd ?
ends
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































Deleted source/propeditor.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
;<ff
Window  frmPropEditor, 3, 0, 'TForm', 'Properties', $12CC0000, $10080, 0, 0, 100, 200, 0, PropEditorProc;
Window  NONE,  2, 5, 'TPropertyGrid', 0, $56200000, $10200, 101, 0, 0, 100, 100, 0;
;ff>

iglobal
  cPropEditTitle db 'Properties',0
endg

uglobal
  hPropEditor     dd 0    ; handle of property editor
endg


;----------------------------------------
; Creates property editor.
; Call this only once.
;----------------------------------------

proc InitPropEditor, .owner
begin
        stdcall  CreateForm, frmPropEditor, [hApplication]
        mov      [hPropEditor], ebx
        return
endp


proc PropEditorProc, .hwnd, .wmsg, .wparam, .lparam

.buff   rb 256

begin
        call    JumpTo
        MessageList                     \
          WM_COMMAND,     .command,     \
          PRM_UPDATEPROP, .updateprop,  \
          WM_CLOSE,       .close,       \
          WM_ERASEBKGND,  .erasebkgnd,  \
          WM_SETFOCUS,    .wmsetfocus,  \
          WM_NEXTDLGCTL,  .wmnext

.qtrue:
        stc
        jmp     .finish

.wmnext:
        invoke  SendDlgItemMessageA, [.hwnd], 101, [.wmsg], [.wparam], [.lparam]
        clc
        return

;-------- WM_SETFOCUS ---------------------------------------
.wmsetfocus:

        invoke  GetDlgItem, [.hwnd], 101
        mov     ebx, eax

        invoke  SendMessageA, ebx, PEM_GETCONTROL, 0, 0
        test    eax, eax
        jz      .setfocus

        invoke  SetWindowPos, [eax+TWinTemplateDT.hwnd], HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE or SWP_SHOWWINDOW

.setfocus:
        invoke  SetFocus, ebx
        jmp     .qfalse

;-------- WM_ERASEBKGND -------------------------------------
.erasebkgnd:
        invoke  GetDlgItem, [.hwnd], 101
        invoke  IsWindowVisible, eax
        test    eax, eax
        jz      .qtrue

        xor     eax, eax
        inc     eax
        clc
        return

;-------- WM_CLOSE ------------------------------------------
.close:
        stdcall OnViewPropEditor, actViewPropEditor, 0
        jmp     .qfalse

;-------- PRM_UPDATEPROP ------------------------------------
.updateprop:
        invoke  GetDlgItem, [.hwnd], 101
        mov     ebx, eax
        invoke  InvalidateRect, ebx, NULL, FALSE
        jmp     .qfalse

;---------WM_COMMAND-----------------------------
.command:
        cmp     word [.wparam], MR_OK   ; enter pressed.
        jne     .tomain

        invoke  SendDlgItemMessageA, [.hwnd], 101, PEM_UPDATECONTROL, 0, 0
        jmp     .qfalse


.tomain:
        invoke  SendMessageA, [hMainWindow], [.wmsg], [.wparam], [.lparam]
        jmp     .qtrue

.qfalse:
        xor     eax,eax
        clc
.finish:
        return
endp


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































Deleted source/propeditor.inc.

cannot compute difference between binary files

Deleted source/propgrid.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
initialize RegisterPropGridClass
.wc WNDCLASS
begin
        xor     eax, eax
        lea     edi, [.wc]
        mov     esi, edi
        mov     ecx, sizeof.WNDCLASS shr 2
        rep stosd

        mov     [.wc.style], CS_PARENTDC
        mov     [.wc.lpfnWndProc], PropGridWinProc
        mov     [.wc.cbWndExtra], 4     ; pointer to the grid data.
        mov     eax, [hInstance]
        mov     [.wc.hInstance], eax
        invoke  LoadCursorA, 0, IDC_ARROW
        mov     [.wc.hCursor], eax
        mov     [.wc.hbrBackground], 0; COLOR_BTNFACE+1

        mov     [.wc.lpszClassName], cPropGridClassName

        invoke  RegisterClassA, esi
        return
endp

iglobal
  cPropGridClassName db 'TPropertyGrid',0
endg


iglobal
StandardProperties:
      PropInfo                                                                                 \
        'Align',   ptByte,   TWinTemplateDT.Align,   AlignPropEditor,  0,  frmAlign,       \
        'Style',   ptDword,   TWinTemplateDT.style,   StylePropEditor,  0,  frmStyleEditor, \
        'StyleEx', ptDword,   TWinTemplateDT.styleEx, IntPropEditor,    ntsHex, 0,          \
        'Left',    ptWord,   TWinTemplateDT.left,    IntPropEditor,    ntsDec, 0,       \
        'Top',     ptWord,   TWinTemplateDT.top,     IntPropEditor,    ntsDec, 0,        \
        'Width',   ptWord,   TWinTemplateDT.width,   IntPropEditor,    ntsDec, 0,          \
        'Height',  ptWord,   TWinTemplateDT.height,  IntPropEditor,    ntsDec, 0,          \
        'Name',    ptText,      TWinTemplateDT.hName,  StringPropEditor, 0, 0,                \
        'ID',      ptWord,   TWinTemplateDT.ID,      IntPropEditor,    ntsDec, 0,          \
        'Text',    ptText,      TWinTemplateDT.ptrText,   StringPropEditor, 0, frmTextEdit,   \
        'Class name', ptText,   TWinTemplateDT.ptrClass,  StringPropEditor, pfReadOnly, 0,    \
        'Msg handler', ptText,  TWinTemplateDT.WinProc,StringPropEditor, 0, 0
endg


proc PropGridWinProc, .hwnd, .wmsg, .wparam, .lparam
.rect RECT
.rectl RECT
.rectr RECT
.ps   PAINTSTRUCT
.hdc  dd ?
.si   SCROLLINFO
.maxaddr dd ?

begin
        push    esi edi ebx

        invoke  GetWindowLongA, [.hwnd], 0
        mov     edi, eax

        mov     ebx, [.wmsg]
        Messages                                \
        WM_PAINT,   .wmpaint,                   \
        WM_CREATE, .wmcreate,                   \
        WM_DESTROY, .wmdestroy,                 \
        WM_VSCROLL, .vscroll,                   \
        WM_SIZE,    .wmsize,                    \
        WM_GETFONT, .wmgetfont,                 \
        WM_LBUTTONDOWN, .wmlbuttondown,         \
        WM_COMMAND,     .wmcommand,             \
        WM_PARENTNOTIFY, .parentnotify,         \
        PEM_CLEARALL, .pemclear,           \
        PEM_ADDPROPERTY, .pemaddprop,      \
        PEM_SETCOUNT,    .pemsetcount,     \
        PEM_SETCONTROL,  .pemsetcontrol,   \
        PEM_GETCONTROL,  .pemgetcontrol,   \
        PEM_SETSELECTION, .pemsetselection,\
        PEM_UPDATECONTROL, .pemupdatecontrol,   \
        PEM_SETEDITORTEXT, .pemseteditortext,      \
        PEM_SETUPDATEPROC, .pemsetupdateproc,      \
\
        BEM_BUTTONCLICK,  .bembuttonclick,      \
        WM_SETFOCUS, .focus,                    \
        WM_NEXTDLGCTL, .nextdlgctrl
;        WM_KEYDOWN, .wmkeydown

.default:
        invoke  DefWindowProcA, [.hwnd], [.wmsg], [.wparam], [.lparam]
        jmp     .finish


;.wmkeydown:
;        cmp     [.wparam], VK_TAB
;        jne     .default

.nextdlgctrl:
        mov     eax, [edi+TPropGrid.iSelected]
        mov     ebx, [edi+TPropGrid.RowCount]
        dec     ebx
        cmp     [.wparam], FALSE
        je      .nextrow

        dec     eax
        jns     .updatetab
        mov     eax, ebx

.updatetab:
        invoke  SendMessageA, [.hwnd], PEM_SETSELECTION, eax, 0
        invoke  SendMessageA, [edi+TPropGrid.hEditor], EM_SETSEL, 0, -1
        invoke  SetFocus, [edi+TPropGrid.hEditor]
        jmp     .qfalse

.nextrow:
        inc      eax
        cmp     eax, ebx
        jle     .updatetab
        xor     eax,eax
        jmp     .updatetab


;.getdlgcode:
;        cmp     [.lparam], 0
;        jne     .msgcode
;
;        mov     eax, DLGC_WANTTAB
;        jmp     .finish
;
;.msgcode:
;        mov     eax, [.lparam]
;        cmp     [eax+MSG.message], WM_KEYDOWN
;        jne     .default
;
;        cmp     [eax+MSG.wParam], VK_TAB
;        jne     .default
;
;        mov     eax, DLGC_WANTMESSAGE
;        jmp     .finish
;

.focus:
        cmp     [edi+TPropGrid.hEditor], 0
        je      .default

        invoke  SetFocus, [edi+TPropGrid.hEditor]
        jmp     .qfalse




;--------- WM_PARENTNOTIFY ----------------
.parentnotify:
        cmp     word [.wparam], WM_CREATE
        jne     @f

        invoke  GetPropA, [.lparam], [propOwnFont]
        test    eax, eax
        jnz     @f

        invoke  SendMessageA, [.hwnd], WM_GETFONT, 0, 0
        invoke  SendMessageA, [.lparam], WM_SETFONT, eax, TRUE

@@:
        jmp     .qfalse

;--------- AM_ENTERPRESSED ----------------
.enter:
        invoke  SetFocus, [.hwnd]
        invoke  SetFocus, [edi+TPropGrid.hEditor]
        jmp     .qfalse

;--------- WM_COMMAND ---------------------
.wmcommand:
        movzx   eax, word [.wparam+2]
        cmp     eax, EN_KILLFOCUS
        je      .killfocus

        cmp     eax, EN_SETFOCUS
        jne     .qfalse

.setfocus:
        invoke  SendMessageA, [edi+TPropGrid.hEditor], EM_SETSEL, 0, -1
        jmp     .qfalse

.killfocus:
;        invoke  SendMessageA, [.hwnd], PEM_UPDATECONTROL, 0, 0
        jmp     .qfalse


;---------- WM_LBUTTONDOWN ------------------
.wmlbuttondown:
        movsx   ebx, word [.lparam+2]
        sar     ebx, 4

        invoke  GetScrollPos, [.hwnd], SB_VERT
        add     ebx, eax
        js      .qfalse

        cmp     ebx, [edi+TPropGrid.RowCount]
        jge     .qfalse

        invoke  SendMessageA, [.hwnd], PEM_SETSELECTION, ebx, 0
        jmp     .qfalse

;---------- WM_GETFONT ----------------------
.wmgetfont:
        invoke  GetStockObject, DEFAULT_GUI_FONT
        jmp     .finish

;----------- BEM_BUTTONCLICK ----------------
.bembuttonclick:
        cmp     [edi+TPropGrid.hEditor], 0
        je      .qfalse

        mov     ebx, [edi+TPropGrid.iSelected]
        imul    ebx, sizeof.TPropInfo
        add     ebx, [edi+TPropGrid.ptrArray]

        cmp     [ebx+TPropInfo.Form], 0
        je      .qfalse

        lea     eax, [.rect]
        invoke  GetWindowRect, [edi+TPropGrid.hEditor], eax

        stdcall CreateForm, [ebx+TPropInfo.Form], [.hwnd]
        invoke  SetWindowPos, ebx, 0, [.rect.left], [.rect.bottom], 0, 0, SWP_NOSIZE or SWP_NOZORDER

        invoke  SetWindowLongA, ebx, 4, [edi+TPropGrid.ptrCtrl]

        stdcall GetControlText, [edi+TPropGrid.hEditor], 0
        push    eax

        stdcall StrPtr, eax
        invoke  SendDlgItemMessageA, ebx, 1000, WM_SETTEXT, 0, eax
        stdcall StrDel ; from the stack

        stdcall ShowModal, ebx, 0
        push    eax
        invoke  DestroyWindow, ebx
        pop     eax

        cmp     eax, MR_OK
        jne     .qfalse

        invoke  SendMessageA, [.hwnd], PEM_UPDATECONTROL, 0, 0
        invoke  SetFocus, [edi+TPropGrid.hEditor]

        jmp     .qfalse

;----------PEM_SETEDITORTEXT-----------------
.pemseteditortext:
        cmp     [edi+TPropGrid.hEditor], 0
        je      .qfalse

        invoke  SendMessageA, [edi+TPropGrid.hEditor], WM_SETTEXT, 0, [.lparam]
        jmp     .qfalse

;---------- PEM_UPDATECONTROL ---------------
.pemupdatecontrol:
        cmp     [edi+TPropGrid.hEditor], 0
        je      .baseupdated

        mov     ebx, [edi+TPropGrid.iSelected]
        imul    ebx, sizeof.TPropInfo
        add     ebx, [edi+TPropGrid.ptrArray]

        cmp     [ebx+TPropInfo.procEditor], 0
        je      .qfalse

        stdcall [ebx+TPropInfo.procEditor], [edi+TPropGrid.ptrCtrl], ebx, pecUpdateWindow, NULL, [edi+TPropGrid.hEditor]
        test    eax, eax
        jnz     .baseupdated

.baseupdated:
        cmp     [edi+TPropGrid.ptrCtrl], 0
        je      .qfalse

        cmp     [edi+TPropGrid.ptrUpdateProc], 0
        je      .qfalse

        stdcall [edi+TPropGrid.ptrUpdateProc], [edi+TPropGrid.ptrCtrl]
        invoke  SetFocus, [.hwnd]

; Mark control as modified...
        mov     eax, [edi+TPropGrid.ptrCtrl]
.search:
        cmp     [eax+TWinTemplateDT.parent], 0
        je      .found
        mov     eax, [eax+TWinTemplateDT.parent]
        jmp     .search

.found:
        mov     eax, [eax+TWinTemplateDT.ptrFile]
        test    eax, eax
        jz      .qfalse

        invoke  SendMessageA, [eax+TOpenFile.hEditor], _CEM_SETMODIFIED, TRUE, 0
        jmp     .qfalse

;---------- PEM_SETSELECTION ----------------
.pemsetselection:
        cmp     [edi+TPropGrid.hEditor], 0
        je      .setnew

;        invoke  SendMessageA, [.hwnd], PEM_UPDATECONTROL, 0, 0
        invoke  DestroyWindow, [edi+TPropGrid.hEditor]
        mov     [edi+TPropGrid.hEditor], 0
        mov     [edi+TPropGrid.iSelected], -1

.setnew:
        mov     ebx, [.wparam]
        test    ebx, ebx
        js      .update

        cmp     ebx, [edi+TPropGrid.RowCount]
        jge     .update

        mov     [edi+TPropGrid.iSelected], ebx

        imul    ebx, sizeof.TPropInfo
        add     ebx, [edi+TPropGrid.ptrArray]

        cmp     [ebx+TPropInfo.procEditor], NULL
        je      .update

        xor     eax, eax
        stdcall [ebx+TPropInfo.procEditor], [edi+TPropGrid.ptrCtrl], ebx, pecGetEditor, eax, [.hwnd]
        mov     [edi+TPropGrid.hEditor], eax

        invoke  GetActiveWindow
        mov     ebx, eax
        invoke  GetParent, [.hwnd]
        cmp     eax, ebx
        jne     .update

        invoke  SetFocus, [edi+TPropGrid.hEditor]

.update:
        call    .updateeditor
        jmp     .qfalse

;---------- PEM_SETCONTROL ------------------
.pemsetcontrol:
        invoke  SendMessageA, [.hwnd], PEM_CLEARALL, 0, 0
        mov     eax, [.wparam]
        mov     [edi+TPropGrid.ptrCtrl], eax
        test    eax, eax
        jz      .qfalse

        mov     eax, [.lparam]
        test    eax, eax
        jnz     @f

        mov     eax, StandardProperties
@@:
        invoke  SendMessageA, [.hwnd], PEM_ADDPROPERTY, 0, eax
        jmp     .qfalse

;---------- PEM_GETCONTROL ------------------
.pemgetcontrol:
        mov     eax, [edi+TPropGrid.ptrCtrl]
        jmp     .finish

;---------- PEM_SETUPDATEPROC ---------------
.pemsetupdateproc:
        mov     eax, [.lparam]
        mov     [edi+TPropGrid.ptrUpdateProc], eax
        jmp     .qfalse

;---------- WM_SIZE -------------------------
.wmsize:
        invoke  SendMessageA, [.hwnd], PEM_SETCOUNT, [edi+TPropGrid.RowCount], 0
        call    .updateeditor
        jmp     .qfalse

;---------- WM_VSCROLL ----------------------
.vscroll:
        movzx   ebx, word [.wparam]
        movzx   esi, word [.wparam+2]

        cmp     ebx, SB_THUMBPOSITION
        je      .setit
        cmp     ebx, SB_THUMBTRACK
        je      .setit

        invoke  GetScrollPos, [.hwnd], SB_VERT
        mov     esi, eax

        inc     esi
        cmp     ebx, SB_LINEDOWN
        je      .setit
        cmp     ebx, SB_PAGEDOWN
        je      .setit
        sub     esi, 2
        cmp     ebx, SB_LINEUP
        je      .setit
        cmp     ebx, SB_PAGEUP
        je      .setit

        jmp     .qfalse


.setit:
        invoke  SetScrollPos, [.hwnd], SB_VERT, esi, TRUE
        call    .updateeditor
;        invoke  InvalidateRect, [.hwnd], NULL, TRUE
        jmp     .qfalse

;---------- PEM_SETCOUNT --------------------
.pemsetcount:
        mov     ebx, [.wparam]
        test    ebx, ebx
        js      .qfalse

        mov     [edi+TPropGrid.RowCount], ebx
        imul    ebx, sizeof.TPropInfo
        test    ebx, ebx
        jnz     @f
        mov     ebx, sizeof.TPropInfo
@@:
        stdcall ResizeMem, [edi+TPropGrid.ptrArray], ebx
        mov     [edi+TPropGrid.ptrArray], eax

        mov     [.si.cbSize], sizeof.SCROLLINFO
        mov     [.si.fMask], SIF_PAGE or SIF_RANGE; or SIF_DISABLENOSCROLL
        mov     [.si.nMin], 0
        push    [.wparam]
        pop     [.si.nMax]

        lea     eax, [.rect]
        invoke  GetClientRect, [.hwnd], eax
        mov     eax, [.rect.bottom]
        shr     eax, 4
        inc     eax
        mov     [.si.nPage], eax

        lea     ecx, [.si]
        invoke  SetScrollInfo, [.hwnd], SB_VERT, ecx, TRUE
        jmp     .qfalse

;---------- PEM_CLEARALL --------------------
.pemclear:
        cmp     [edi+TPropGrid.RowCount], 0
        je      .endfree

        mov     esi, [edi+TPropGrid.ptrArray]

.freeloop:
        stdcall StrDel, [esi+TPropInfo.hName]
        add     esi, sizeof.TPropInfo
        dec     [edi+TPropGrid.RowCount]
        jnz     .freeloop

.endfree:
        cmp     [edi+TPropGrid.hEditor], 0
        je      @f
        invoke  DestroyWindow, [edi+TPropGrid.hEditor]
        mov     [edi+TPropGrid.hEditor], 0
@@:
        invoke  SendMessageA, [.hwnd], PEM_SETCOUNT, 0, 0
        invoke  InvalidateRect, [.hwnd], NULL, TRUE
        jmp     .qfalse

;--------- PEM_ADDPROPERTY ---------------
.pemaddprop:
        mov     esi, [.lparam]
        test    esi, esi
        je      .qfalse

        mov     ebx, [edi+TPropGrid.RowCount]
        lodsd
        push    eax
        add     eax, ebx

        invoke  SendMessageA, [.hwnd], PEM_SETCOUNT, eax, 0

;        mov     [edi+TPropGrid.iSelected], ebx

        imul    ebx, sizeof.TPropInfo
        add     ebx, [edi+TPropGrid.ptrArray]
        pop     ecx

.addloop:
        stdcall StrNew
        mov     [ebx+TPropInfo.hName], eax
        stdcall StrCopy, eax, [esi+TPropInfo.hName]

        push    [esi+TPropInfo.type]
        pop     [ebx+TPropInfo.type]
        push    [esi+TPropInfo.procEditor]
        pop     [ebx+TPropInfo.procEditor]
        push    [esi+TPropInfo.ofsVal]
        pop     [ebx+TPropInfo.ofsVal]
        push    [esi+TPropInfo.Tag]
        pop     [ebx+TPropInfo.Tag]
        push    [esi+TPropInfo.Form]
        pop     [ebx+TPropInfo.Form]

        add     esi, sizeof.TPropInfo
        add     ebx, sizeof.TPropInfo
        loop    .addloop

;        invoke  SendMessageA, [.hwnd], PEM_SETSELECTION, [edi+TPropGrid.iSelected], 0
        jmp     .qfalse

;------------ WM_CREATE ------------------
.wmcreate:
        stdcall GetMem, sizeof.TPropGrid
        mov     edi, eax
        stdcall GetMem, sizeof.TPropInfo
        mov     [edi+TPropGrid.ptrArray], eax

        invoke  SetWindowLongA, [.hwnd], 0, edi
        invoke  SetScrollRange, [.hwnd], SB_VERT, 0, 0, FALSE

        ; LITTLE BIT TRICKY, but unfortunately I couldn't think it in more smart way.
        invoke  CreateWindowExA, 0, cEditClassName, NULL, WS_VISIBLE or WS_CHILD or WS_TABSTOP, 0, 0, 0, 0, [.hwnd], 100, [hInstance], NULL
        stdcall SubclassWindow, eax, NextEditorWinProc
        invoke  CreateWindowExA, 0, cEditClassName, NULL, WS_VISIBLE or WS_CHILD or WS_TABSTOP, 0, 0, 0, 0, [.hwnd], 101, [hInstance], NULL
        stdcall SubclassWindow, eax, NextEditorWinProc
        jmp     .qfalse

;----------- WM_DESTROY -------------------

.wmdestroy:
        invoke  SendMessageA, [.hwnd], PEM_CLEARALL, 0, 0

        stdcall FreeMem, [edi+TPropGrid.ptrArray]
        stdcall FreeMem, edi
        jmp     .qfalse


;-------- WM_PAINT -----------------------

.wmpaint:
        lea     eax, [.ps]
        invoke  BeginPaint, [.hwnd], eax
        test    eax, eax
        jz      .quitpaint

        mov     [.hdc], eax

        lea     ebx, [.rect]
        invoke  GetClientRect, [.hwnd], ebx
        xor     eax, eax
        mov     ecx, [.rect.right]
        mov     edx, [.rect.right]
        shr     ecx, 1
        mov     [.rectl.left], eax
        mov     [.rectl.right], ecx
        mov     [.rectl.top], eax
        mov     [.rectl.bottom], 15
        mov     [.rectr.left], ecx
        mov     [.rectr.right], edx
        mov     [.rectr.top], eax
        mov     [.rectr.bottom], 15

        invoke  CreatePen, PS_SOLID, 0, $a0a0a0
        invoke  SelectObject, [.hdc], eax
        push    eax
        invoke  GetStockObject, BLACK_BRUSH
        invoke  SelectObject, [.hdc], eax
        push    eax
        invoke  SetBkMode, [.hdc], TRANSPARENT
        invoke  GetStockObject, DEFAULT_GUI_FONT
        invoke  SelectObject, [.hdc], eax

; Draw properties
        invoke  GetScrollPos, [.hwnd], SB_VERT
        mov     ebx, eax
        imul    ebx, sizeof.TPropInfo

        add     ebx, [edi+TPropGrid.ptrArray]
        mov     esi, [edi+TPropGrid.RowCount]
        imul    esi, sizeof.TPropInfo
        add     esi, [edi+TPropGrid.ptrArray]
        mov     [.maxaddr], esi

        mov     esi, eax

.foundbeg:
        cmp     ebx, [.maxaddr]
        jge     .cleartoend

        lea     ecx, [.rectl]
        invoke  FillRect, [.hdc], ecx, COLOR_BTNFACE+1

        invoke  MoveToEx, [.hdc], [.rectl.left], [.rectl.bottom], NULL
        invoke  LineTo, [.hdc], [.rectl.right], [.rectl.bottom]

        stdcall StrPtr, [ebx+TPropInfo.hName]

        add     [.rectl.left], 2
        lea     ecx, [.rectl]
        invoke  DrawTextA, [.hdc], eax, -1, ecx, DT_TOP or DT_END_ELLIPSIS or DT_LEFT or DT_NOPREFIX or DT_SINGLELINE
        sub     [.rectl.left], 2

        lea     eax, [.rectr]
        invoke  FillRect, [.hdc], eax, COLOR_BTNFACE+1
        invoke  MoveToEx, [.hdc], [.rectr.left], [.rectr.bottom], NULL
        invoke  LineTo, [.hdc], [.rectr.right], [.rectr.bottom]

        cmp     esi, [edi+TPropGrid.iSelected]
        jne     @f

        lea     eax, [.rectl]
        invoke  DrawFocusRect, [.hdc], eax

        cmp     [edi+TPropGrid.hEditor], 0
        je      @f

        invoke  GetFocus
        cmp     eax, [edi+TPropGrid.hEditor]
        je      @f

        stdcall [ebx+TPropInfo.procEditor], [edi+TPropGrid.ptrCtrl], ebx, pecRefreshEditor, eax, [edi+TPropGrid.hEditor]

@@:
        cmp     [edi+TPropGrid.ptrCtrl], NULL
        je      .cleartoend

        cmp     [ebx+TPropInfo.procEditor], NULL
        je      .nextline

        add     [.rectr.left], 2
        lea     eax, [.rectr]
        stdcall [ebx+TPropInfo.procEditor], [edi+TPropGrid.ptrCtrl], ebx, pecDrawValue, eax, [.hdc]
        sub     [.rectr.left], 2

.nextline:
        add     [.rectl.top], 16
        add     [.rectl.bottom], 16
        add     [.rectr.top], 16
        add     [.rectr.bottom], 16
        add     [.rect.top], 16

        mov     eax, [.rectl.top]
        cmp     eax, [.rect.bottom]
        jge     .endpaint

        add     ebx, sizeof.TPropInfo
        inc     esi
        jmp     .foundbeg

.cleartoend:
        lea     eax, [.rect]
        invoke  FillRect, [.hdc], eax, COLOR_BTNFACE+1

.endpaint:
        xor     eax, eax
        xchg    eax, [.rectr.top]
        mov     [.rectr.bottom], eax
        lea     eax, [.rectr]
        invoke  DrawEdge, [.hdc], eax, EDGE_ETCHED, BF_LEFT

        invoke  SelectObject, [.hdc]
        invoke  SelectObject, [.hdc]
        invoke  DeleteObject, eax

.quitpaint:
        lea     eax, [.ps]
        invoke  EndPaint, [.hwnd], eax

;--------------------------------------------
.qfalse:
        xor     eax, eax
.finish:
        pop     ebx edi esi
        return



.updateeditor:
        cmp     [edi+TPropGrid.hEditor], NULL
        je      .updated

        lea     eax, [.rect]
        invoke  GetClientRect, [.hwnd], eax

        invoke  GetScrollPos, [.hwnd], SB_VERT
        mov     ebx, [edi+TPropGrid.iSelected]

        sub     ebx, eax
        js      .hideeditor

        shl     ebx, 4         ; Y Coordinate.
        cmp     ebx, [.rect.bottom]
        jge     .hideeditor

.showeditor:
        mov     eax, [.rect.right]
        shr     eax, 1
        add     eax, 2
        mov     ecx, [.rect.right]
        sub     ecx, eax
        invoke  SetWindowPos, [edi+TPropGrid.hEditor], 0, eax, ebx, ecx, 14, SWP_SHOWWINDOW or SWP_NOZORDER
        jmp     .updated

.hideeditor:
        invoke  ShowWindow, [edi+TPropGrid.hEditor], SW_HIDE
.updated:
        invoke  InvalidateRect, [.hwnd], NULL, TRUE
        ret
endp



winproc NextEditorWinProc
begin
ondefault
        stc
        return

onmessage WM_SETFOCUS
        invoke  GetWindowLongA, [.hwnd], GWL_ID
        lea     ebx, [eax-100]
        invoke  GetParent, [.hwnd]
        mov     esi, eax
        invoke  PostMessageA, esi, WM_NEXTDLGCTL, ebx, 0

        invoke  SendMessageA, esi, PEM_UPDATECONTROL, 0, 0

        xor     eax, eax
        clc
        return
endwp




proc IntPropEditor, .ptrCtrl, .ptrPropInfo, .cmd, .ptrRect, .lParam
.str rb 256
begin
        push    edi esi edx ecx ebx eax

        cmp     [.cmd], pecDrawValue
        je      .draw

        cmp     [.cmd], pecGetEditor
        je      .geteditor

        cmp     [.cmd], pecRefreshEditor
        je      .refresheditor

        cmp     [.cmd], pecUpdateWindow
        jne     .finish

.updatewindow:
        lea     ebx, [.str]
        invoke  SendMessageA, [.lParam], WM_GETTEXT, 256, ebx

        stdcall StrToFasmNum, ebx
        jc      .finish

        mov     esi, [.ptrPropInfo]
        mov     ecx, [esi+TPropInfo.ofsVal]
        add     ecx, [.ptrCtrl]

        movzx   edx, byte [ecx]
        mov     [ecx], al
        cmp     [esi+TPropInfo.type], ptByte
        je      .changed
        movzx   edx, word [ecx]
        mov     [ecx], ax
        cmp     [esi+TPropInfo.type], ptWord
        je      .changed
        mov     edx, [ecx]
        mov     [ecx], eax

.changed:
        xor     ecx, ecx
        cmp     edx, eax
        je      @f
        inc     ecx
@@:
        mov     [esp], ecx
        jmp     .finish


.refresheditor:
        call    .createstr
        push    eax
        stdcall StrPtr, eax
        invoke  SendMessageA, [.lParam], WM_SETTEXT, 0, eax
        stdcall StrDel ; From the stack
        jmp     .finish

.geteditor:
        invoke  CreateWindowExA, 0, cEditClassName, eax,                  \
                WS_CHILD or WS_CLIPSIBLINGS or                           \
                ES_AUTOHSCROLL,                                          \
                0, 0, 56, 16, [.lParam],                                  \
                NULL, [hInstance], NULL
        mov     [esp], eax
        mov     ebx, eax
        stdcall IntPropEditor, [.ptrCtrl], [.ptrPropInfo], pecRefreshEditor, NULL, ebx
        jmp     .finish

.draw:
        call    .createstr
        push    eax
        stdcall StrPtr, eax
        invoke  DrawTextA, [.lParam], eax, -1, [.ptrRect], DT_TOP or DT_END_ELLIPSIS or DT_LEFT or DT_NOPREFIX or DT_SINGLELINE
        stdcall StrDel ; From stack

.finish:
        pop     eax ebx ecx edx esi edi
        return

.createstr:
        mov     esi, [.ptrPropInfo]
        mov     eax, [esi+TPropInfo.ofsVal]
        add     eax, [.ptrCtrl]

        mov     ecx, [esi+TPropInfo.Tag]

        movsx   edx, byte [eax]
        cmp     [esi+TPropInfo.type], ptByte
        je      .sign

        movsx   edx, word [eax]
        cmp     [esi+TPropInfo.type], ptWord
        je      .sign

        mov     edx, [eax]
        jmp     .convert

.sign:
        test    ecx, ntsUnsigned
        jz      .convert

        and     edx, $ffff
        cmp     [esi+TPropInfo.type], ptWord
        je      .convert

        and     edx, $ff

.convert:
        stdcall NumToStr, edx, ecx
        mov     ecx, [esi+TPropInfo.Tag]
        and     ecx, $ff00

        cmp     ecx, ntsHex
        jne     @f
        stdcall StrCharInsert, eax, '$', 0
        jmp     .doit
@@:
        cmp     ecx, ntsBin
        jne     .doit
        stdcall StrCharCat, eax, 'b'
.doit:
        retn
endp




proc StringPropEditor, .ptrCtrl, .ptrPropInfo, .cmd, .ptrRect, .lParam
.str rb 256
begin
        push    edi esi edx ecx ebx eax

        cmp     [.cmd], pecDrawValue
        je      .draw

        cmp     [.cmd], pecGetEditor
        je      .geteditor

        cmp     [.cmd], pecRefreshEditor
        je      .refresheditor

        cmp     [.cmd], pecUpdateWindow
        jne     .finish

.updatewindow:
        lea     ebx, [.str]
        invoke  SendMessageA, [.lParam], WM_GETTEXT, 256, ebx

        mov     esi, [.ptrPropInfo]
        mov     eax, [esi+TPropInfo.ofsVal]
        add     eax, [.ptrCtrl]

        xor     ecx, ecx
        stdcall StrCompCase, [eax], ebx
        jnc     .copy

        mov     dword [esp], 0
        jmp     .finish

.copy:
        stdcall StrCopy, [eax], ebx
        mov     dword [esp], 1
        jmp     .finish

.refresheditor:
        mov     esi, [.ptrPropInfo]
        mov     eax, [esi+TPropInfo.ofsVal]
        add     eax, [.ptrCtrl]

        stdcall StrPtr, [eax]
        invoke  SendMessageA, [.lParam], WM_SETTEXT, 0, eax
        jmp     .finish

.geteditor:
        mov     eax, WS_CHILD or WS_CLIPSIBLINGS or ES_AUTOHSCROLL
        mov     ecx, [.ptrPropInfo]
        test    [ecx+TPropInfo.Tag], pfReadOnly
        jz      @f
        or      eax, ES_READONLY
@@:
        invoke  CreateWindowExA, 0, cButtonEditClassName, 0, eax,          \
                0, 0, 56, 16, [.lParam],                             \
                NULL, [hInstance], NULL
        mov     [esp], eax
        mov     ebx, eax
        invoke  SendMessageA, ebx, BEM_SETBUTTONTEXT, 0, cElipsis
        stdcall StringPropEditor, [.ptrCtrl], [.ptrPropInfo], pecRefreshEditor, NULL, ebx
        jmp     .finish

.draw:
        mov     esi, [.ptrPropInfo]
        mov     eax, [esi+TPropInfo.ofsVal]
        add     eax, [.ptrCtrl]
        mov     eax, [eax]
        test    eax, eax
        jz      .finish

        stdcall StrPtr, eax
        invoke  DrawTextA, [.lParam], eax, -1, [.ptrRect], DT_TOP or DT_END_ELLIPSIS or DT_LEFT or DT_NOPREFIX or DT_SINGLELINE

.finish:
        pop     eax ebx ecx edx esi edi
        return
endp


iglobal
  tblAlignProp  dd  cwaNone
                dd  cwaLeft
                dd  cwaRight
                dd  cwaTop
                dd  cwaBottom
                dd  cwaClient
  tblAlignEnd:
                dd  cwaError
  cwaNone   db 'waNone = 0',0
  cwaLeft   db 'waLeft = 1',0
  cwaRight  db 'waRight = 2',0
  cwaTop    db 'waTop = 3',0
  cwaBottom db 'waBottom = 4',0
  cwaClient db 'waClient = 5',0
  cwaError  db 'waError',0

  cElipsis db '...',0
endg


proc AlignPropEditor, .ptrCtrl, .ptrPropInfo, .cmd, .ptrRect, .lParam
.str rb 256
begin
        push    edi esi edx ecx ebx eax

        cmp     [.cmd], pecDrawValue
        je      .draw

        cmp     [.cmd], pecGetEditor
        je      .geteditor

        cmp     [.cmd], pecRefreshEditor
        je      .refresheditor

        cmp     [.cmd], pecUpdateWindow
        jne     .finish

.updatewindow:
        lea     ebx, [.str]
        invoke  SendMessageA, [.lParam], WM_GETTEXT, 256, ebx

        mov     esi, [.ptrPropInfo]
        mov     eax, [esi+TPropInfo.ofsVal]
        add     eax, [.ptrCtrl]

        movzx   ecx, word [.str]
        cmp     ecx, '0'
        jb      .finish
        cmp     ecx, '5'
        ja      .finish

        sub     cl, '0'
        xchg    byte [eax], cl

        xor     edx, edx
        cmp     [eax], cl
        je      @f
        inc     edx
@@:
        mov     [esp], edx
        jmp     .finish

.refresheditor:
        mov     esi, [.ptrPropInfo]
        mov     eax, [esi+TPropInfo.ofsVal]
        add     eax, [.ptrCtrl]

        movzx   eax, byte [eax]
        stdcall NumToStr, eax, ntsDec
        push    eax
        stdcall StrPtr, eax
        invoke  SendMessageA, [.lParam], WM_SETTEXT, 0, eax
        stdcall StrDel ; From the stack
        jmp     .finish

.geteditor:
        invoke  CreateWindowExA, 0, cButtonEditClassName, eax,                  \
                WS_CHILD or WS_CLIPSIBLINGS or                           \
                ES_NUMBER ,                                              \
                0, 0, 56, 16, [.lParam],                                  \
                NULL, [hInstance], NULL
        mov     [esp], eax
        mov     ebx, eax
        invoke  SendMessageA, ebx, BEM_SETBUTTONTEXT, 0, cElipsis
        stdcall AlignPropEditor, [.ptrCtrl], [.ptrPropInfo], pecRefreshEditor, NULL, ebx
        jmp     .finish

.draw:
        mov     esi, [.ptrPropInfo]
        mov     eax, [esi+TPropInfo.ofsVal]
        add     eax, [.ptrCtrl]
        movzx   eax, byte [eax]
        cmp     eax, waClient
        jbe     @f
        mov     eax, waClient+1
@@:
        mov     eax, [tblAlignProp+eax*4]
        invoke  DrawTextA, [.lParam], eax, -1, [.ptrRect], DT_TOP or DT_END_ELLIPSIS or DT_LEFT or DT_NOPREFIX or DT_SINGLELINE

.finish:
        pop     eax ebx ecx edx esi edi
        return
endp



proc StylePropEditor, .ptrCtrl, .ptrPropInfo, .cmd, .ptrRect, .lParam
.str rb 256
begin
        push    edi esi edx ecx ebx eax

        cmp     [.cmd], pecDrawValue
        je      .draw

        cmp     [.cmd], pecGetEditor
        je      .geteditor

        cmp     [.cmd], pecRefreshEditor
        je      .refresheditor

        cmp     [.cmd], pecUpdateWindow
        jne     .finish

.updatewindow:
        lea     ebx, [.str]
        invoke  SendMessageA, [.lParam], WM_GETTEXT, 256, ebx

        stdcall StrToFasmNum, ebx
        jc      .finish

        mov     esi, [.ptrPropInfo]
        mov     ecx, [esi+TPropInfo.ofsVal]
        add     ecx, [.ptrCtrl]
        xchg    [ecx], eax

        xor     edx, edx
        cmp     eax, [ecx]
        je      @f
        inc     edx
@@:
        mov     [esp], edx
        jmp     .finish


.refresheditor:
        mov     esi, [.ptrPropInfo]
        mov     eax, [esi+TPropInfo.ofsVal]
        add     eax, [.ptrCtrl]

        stdcall NumToStr, [eax], ntsHex
        push    eax
        stdcall StrCharInsert, eax, '$', 0
        stdcall StrPtr, eax
        invoke  SendMessageA, [.lParam], WM_SETTEXT, 0, eax
        stdcall StrDel ; From the stack
        jmp     .finish


.geteditor:
        invoke  CreateWindowExA, 0, cButtonEditClassName, eax,   \
                WS_CHILD or WS_CLIPSIBLINGS,                    \
                0, 0, 56, 16, [.lParam],                        \
                NULL, [hInstance], NULL

        mov     [esp], eax
        mov     ebx, eax
        invoke  SendMessageA, ebx, BEM_SETBUTTONTEXT, 0, cElipsis
        stdcall StylePropEditor, [.ptrCtrl], [.ptrPropInfo], pecRefreshEditor, NULL, ebx
        jmp     .finish

.draw:
        mov     esi, [.ptrPropInfo]
        mov     eax, [esi+TPropInfo.ofsVal]
        add     eax, [.ptrCtrl]

        stdcall NumToStr, [eax], ntsHex
        push    eax

        stdcall StrCharInsert, eax, '$', 0
        stdcall StrPtr, eax
        invoke  DrawTextA, [.lParam], eax, -1, [.ptrRect], DT_TOP or DT_END_ELLIPSIS or DT_LEFT or DT_NOPREFIX or DT_SINGLELINE
        stdcall StrDel ; From stack

.finish:
        pop     eax ebx ecx edx esi edi
        return
endp




;----------------------------------------
; Maybe slow but compatible in all cases.
;
; Convert the string in hString to number
; using FASM internal function get_number
;
; Returns: 64bit value in edx:eax
; Carry = 0 if the number is converted
; Carry = 1 if the number is invalid.
;----------------------------------------
proc StrToFasmNum, .hString
.str rb 256
.res rd 2
begin
        push    esi edi ebx

        xor     eax, eax
        mov     [.res], eax
        mov     [.res+4], eax

        stdcall StrLen, [.hString]
        cmp     eax, 255
        jge     .finish

        movzx   ecx, al
        mov     [.str], $1a
        mov     [.str+1], al
        lea     edi, [.str+2]

        stdcall StrPtr, [.hString]
        mov     esi, eax
        rep movsb

        lea     esi, [.str]
        lea     edi, [.res]
        push    ebp
        call    get_number
        pop     ebp

.finish:
        mov     eax, [.res]
        mov     edx, [.res+4]

        pop     ebx edi esi
        return
endp



iglobal
  Window  frmAlign, $3, $0, 'TForm', '', $96000000, $0, 0, 232, 217, 200, 128, ProcAlignEditor
  Window  NONE, $0, $4, 'Button', 'waBottom', $50008000, $0, 104, 0, 71, 194, 31, NULL
  Window  NONE, $0, $5, 'Button', 'waClient', $50008000, $0, 105, 64, 31, 66, 40, NULL
  Window  NONE, $0, $3, 'Button', 'waTop',    $50008000, $0, 103, 0, 0, 194, 31, NULL
  Window  NONE, $0, $1, 'Button', 'waLeft',   $50008000, $0, 101, 0, 31, 64, 40, NULL
  Window  NONE, $2, $2, 'Button', 'waRight',  $50008000, $0, 102, 130, 31, 64, 40, NULL

  Window  frmTextEdit, $3, $0, 'TForm', 'Control text', $96810000, $0, 0, 209, 195, 320, 216, frmTextEditWinProc
  Window  NONE, $0, $3, 'Edit', '', $503010C4, $200, 1000, 0, 0, 314, 176, NULL
  Window  NONE, $0, $0, 'Button', 'Cancel', $50000000, $0, MR_CANCEL, 168, 184, 64, 21, NULL
  Window  NONE, $2, $0, 'Button', 'OK', $50000001, $0, MR_OK, 80, 184, 64, 21, NULL
endg


proc ProcAlignEditor, .hwnd, .wmsg, .wparam, .lparam
begin
        cmp     [.wmsg], WM_COMMAND
        je      .command

.default:
        stc
        return

.command:
        cmp     word [.wparam+2], BN_CLICKED
        jne     .default

        movzx   esi, word [.wparam]
        sub     esi, 100

        invoke  GetWindowLongA, [.hwnd], GWL_HWNDPARENT
        invoke  GetDlgItem, eax, 101
        mov     ebx, eax

        stdcall NumToStr, esi, ntsDec
        push    eax
        stdcall StrPtr, eax
        invoke  SendMessageA, ebx, PEM_SETEDITORTEXT, 0, eax
        stdcall StrDel

        invoke  SetPropA, [.hwnd], [propModalResult], MR_OK
        clc
        return
endp



proc frmTextEditWinProc, .hwnd, .wmsg, .wparam, .lparam
begin
        cmp     [.wmsg], WM_SHOWWINDOW
        je      .show

.default:
        stc
        return

.show:
        cmp     [.wparam], FALSE
        jne     .default

        invoke  GetWindowLongA, [.hwnd], GWL_HWNDPARENT
        invoke  GetDlgItem, eax, 101
        mov     ebx, eax

        invoke  GetDlgItem, [.hwnd], 1000
        stdcall GetControlText, eax, 0
        push    eax

        stdcall StrPtr, eax
        invoke  SendMessageA, ebx, PEM_SETEDITORTEXT, 0, eax
        stdcall StrDel
        jmp     .default
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/propgrid.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
winmessage PEM_ADDPROPERTY   ;(0, ptrPropInfo)
winmessage PEM_CLEARALL      ;(0, 0)
winmessage PEM_SETCOUNT      ;(count, 0)

winmessage PEM_SETCONTROL    ; (ptrTBaseWin, ptrPropInfo)
winmessage PEM_GETCONTROL    ; (0, 0): ptrBaseWin

winmessage PEM_SETSELECTION  ; (iProp, 0)
winmessage PEM_UPDATECONTROL ; (0, 0)

winmessage PEM_SETEDITORTEXT ; (0, ptrString)
winmessage PEM_SETUPDATEPROC ; (0, ptrUpdateProc)

;message PEM_FOCUSNEXT   ; (directionFlag, 0)

; properties types

ptByte = 0
ptWord = 1
ptDword = 2
ptText = 3
ptUnsigned = $80000000

; property flags - as bit fields in Tag
pfReadOnly = 1

struct TPropInfo
  .hName      dd ?
  .type       dd ?
  .ofsVal     dd ?   ; The offset of the value in the control data structure (usually TBaseWin)
  .procEditor dd ?
  .Tag        dd ?   ; User defined value, that is used by property editors.
  .Form       dd ?   ; Modal form definition, that will be invoked when user press button on the editor.
ends

macro PropInfo [Name, type, ofsValue, Editor, lParam, form] {
common
  local ..propcount
  ..propcount = 0
forward
  ..propcount = ..propcount + 1
common
        dd      ..propcount
forward
  local ..ptrName, ..ptrValue
        dd      ..ptrName
        dd      type
        dd      ofsValue
        dd      Editor
        dd      lParam
        dd      form
forward
  ..ptrName db Name, 0
}


struct TPropGrid
  .RowCount dd ?
  .iSelected dd ?     ; Index to the selected property TPropInfo data.
  .ptrCtrl  dd ?        ; Pointer to the control data structure.
  .ptrUpdateProc dd ?   ; Pointer to the procedure that updates the control.
  .ptrArray dd ?        ; pointer to array of TPropInfo.
  .hEditor  dd ?        ; Current property editor loaded.
ends



; Commands for procEditor
; the procedure should have following params:
; proc procEditor, ptrCtrl, ptrPropInfo, cmd, hdc, ptrRect
; ptrPropInfo - pointer to TPropInfo structure.
; cmd         - command. see below.
; ptrRect     - pointer to RECT structure.
; lParam      - diferent meaning on different commands.
;
pecDrawValue = 0        ; Draws the given element value.        lParam is HDC
pecGetEditor = 1        ; Get given element editor window.      lParam is hParent
pecRefreshEditor = 2    ; Refresh the editor to the current value of the property. lParam is hEditor
pecUpdateWindow  = 3    ; Refreshes the TWinTemplateDT structure to the current value of editor.
                        ; returns TRUE if the value was changed
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































Deleted source/resourceid.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
;--------------------------------------------
; resource ID constants.
;--------------------------------------------
; Bitmaps
resBmpAll       =       $100
resBmpAbout     =       $0ff
resBmpMessage   =       $140
resDefBitmap    =       $102
resBmpProjMan   =       $116
resBmpTab       =       $117
resBmpNewDlg    =       $118
resBmpGraphicTools =    $119

; Icons
resAppIcon      =       $103
resMainIcon     =       $204
resSourceIcon   =       $12e
resArrowIcon    =       $130
resBookmarkIcon =       $131

; Cursors
resVSplit       =       $12a
resHSplit       =       $12b
resSelect       =       $12c
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















































Deleted source/sourceeditor.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
uglobal
  hEditorMenu     dd 0                        ; source popup menu item.
  hBookmarkIcon   dd 0
  CurrentSettings dd  ?
endg


iglobal

defaultSettings:
Theme                                                                   \
  'Fixedsys', -12, DEFAULT_CHARSET,                                     \
  AES_AUTOINDENT or AES_SMARTTABS or AES_CONSOLECARET,                  \
  $FFFFFF, $800000, $000000, $C0C0C0, $C0C0C0, $C0C0C0, 20, 4,          \
  $000000, $ffff00,                                                     \
\; syntax colors
  $D0D0D0, $FFFF00, $FFFF00, $A0A0A0, $00FF00, $00FFFF, $ff00ff, $ff00ff


CoolMenu EditorPopup,                   \
    mfNormal, actGotoDefinition,        \
    mfNormal, actCrossReference,        \
    mfNormal, actOpenFileAtCursor,      \
    mfNormal, actInclude,               \
    mfSeparator, NONE,                  \
    mfNormal, actCut,                   \
    mfNormal, actCopy,                  \
    mfNormal, actPaste,                 \
    mfSeparator, NONE,                  \
    mfNormal,    actIndent,             \
    mfNormal,    actOutdent,            \
    mfSeparator, NONE,                  \
    mfNormal,    actComment,            \
    mfNormal,    actUncomment,          \
    mfSeparator, NONE,                  \
    mfSubmenu, '&Bookmarks',            \
      mfNormal,    actToggleBM,         \
      mfSeparator, NONE,                \
      mfNormal,    actNextBM,           \
      mfNormal,    actPrevBM,           \
      mfSeparator, NONE,                \
      mfNormal,    actClearBM,          \
    mfEnd, END
endg


CCM_UPDATECCPOS = WM_USER+$f000
CCM_UPDATEPAPOS = WM_USER+$f001

cCurrentEditorSettings text 'Current.theme'

;----------------------------------------
; Creates sourceeditor window.
; Call this only once.
;----------------------------------------
proc InitSourceEditor
begin
        stdcall CreateCoolMenu, EditorPopup, TRUE
        mov     [hEditorMenu], eax

        invoke  LoadImageA, [hInstance], resBookmarkIcon, IMAGE_ICON, 0, 0, LR_SHARED
        mov     [hBookmarkIcon], eax

; Load editor color profile...
        stdcall LoadEditorSettings, cCurrentEditorSettings
        jnc     .profileok

        stdcall ThemeDuplicate, defaultSettings

.profileok:
        mov     [CurrentSettings], eax
        return
endp


proc FinalizeSourceEditor
begin
        stdcall SaveEditorSettings, cCurrentEditorSettings, [CurrentSettings], TRUE
        stdcall DestroySettings, [CurrentSettings]

        invoke DestroyMenu, [hEditorMenu]
        invoke DestroyIcon, [hBookmarkIcon]
        return
endp


;--------------------------------------------------------
; Creates the editor window and returns handle to it.
;--------------------------------------------------------
proc CreateSourceEditor, .ptrOpenFile, .hTemplate
begin
        push    ebx esi edi

        mov     esi, [.ptrOpenFile]
        mov     edi, [CurrentSettings]

        xor     eax, eax
        mov     ecx, WS_CHILD or WS_HSCROLL or WS_VSCROLL or ES_NOHIDESEL or ES_WANTRETURN or WS_CLIPCHILDREN
        or      ecx, [edi+TEditorSettings.AsmEditStyle]

        invoke  CreateWindowExA, WS_EX_CLIENTEDGE or WS_EX_ACCEPTFILES, cAsmEditClassName,    \
                eax, ecx, eax, eax, eax, eax, [hEditorsHost], eax,      \
                [hInstance], eax

        test    eax, eax
        jz      .errorcreate

        mov     ebx, eax
        mov     [esi+TOpenFile.hEditor], ebx

        invoke  SetWindowLongA, ebx, ofsOpenFileStruct, esi

; adjust the look and feel for the editor window.
        invoke  CreateFontA, [edi+TEditorSettings.FontSize], 0, 0, 0, FW_NORMAL,                 \
                            0, 0, 0, [edi+TEditorSettings.FontCharset],                         \
                            OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,           \
                            FIXED_PITCH or FF_DONTCARE, [edi+TEditorSettings.ptrFontName]

        invoke  SendMessageA, ebx, WM_SETFONT, eax, FALSE
        invoke  SendMessageA, ebx, AEM_SETTHEME, 0, [edi+TEditorSettings.ptrTheme]
        mov     eax, [esi+TOpenFile.ptrType]
        invoke  SendMessageA, ebx, AEM_SETSYNTAXHIGHLIGHT, 0, [eax+TFileType.lParam]
        invoke  SendMessageA, ebx, AEM_SETPOPUPMENU, 0, [hEditorMenu]
        invoke  SendMessageA, ebx, AEM_SETBOOKMARKICON, [hBookmarkIcon], 0

        stdcall SubclassWindow, ebx, SourceEditProc
        invoke  SendMessageA, ebx, CEM_LOADFILE, [.hTemplate], 0
        test    eax, eax
        jnz     .errorload

        invoke  SendMessageA, [hEditorsHost], EHM_DOCKWINDOW, ebx, dfClient
        xor     eax, eax
        pop     edi esi ebx
        return

.errorcreate:
        invoke  GetLastError
        pop     edi esi ebx
        return

.errorload:
        push    eax
        invoke  DestroyWindow, ebx
        pop     eax
        pop     edi esi ebx
        return
endp





winproc SourceEditProc
.aepos AEPOS
.str   rb 256
.textlen dd ?
.written dd ?
.memoryfile TInMemoryFile
begin
        invoke  GetWindowLongA, [.hwnd], ofsOpenFileStruct
        mov     edi, eax

ondefault
        stc
        return


;------- Custom message handlers ------------------

onmessage WM_DESTROY
        stdcall ClosePopup, [hCCList], 0, 0
        stdcall ClosePopup, [hPAHint], 0, 0
        stc
        return


onmessage _CEM_GETTEXT
        mov     ebx, [.lparam]   ; pointer to TInMemoryFile

        invoke  SendMessageA, [.hwnd], WM_GETTEXTLENGTH, 0, 0
        mov     [ebx+TInMemoryFile.fileSize], eax
        lea     esi, [eax+1]

        stdcall GetMem, esi
        jc      .errorgettext

        mov     [ebx+TInMemoryFile.ptrBuffer], eax
        mov     [ebx+TInMemoryFile.fAscii], TRUE

        invoke  SendMessageA, [.hwnd], WM_GETTEXT, esi, [ebx+TInMemoryFile.ptrBuffer]
        xor     eax, eax
        clc
        return

.errorgettext:
        mov     eax, 1
        clc
        return

;----------------------------------------------------
onmessage CEM_LOADFILE

        mov     eax, [.wparam]
        test    eax, eax
        jnz     .loadit

        cmp     [edi+TOpenFile.fNeverSaved], 0
        jne     .skiploading

; Load the file in ASMEDIT window.
        mov     eax, [edi+TOpenFile.hFileName]

.loadit:
        stdcall StrPtr, eax
        stdcall LoadBinaryFile, eax
        jc      .endload ; eax contains the error code

        push    eax
        invoke  SendMessageA, [.hwnd], WM_SETTEXT, 0, eax
        stdcall FreeMem ;  address from the stack.

        stdcall AddToMRUList, [ptrMRUFiles], [edi+TOpenFile.hFileName]

.skiploading:
        invoke  GetParent, [.hwnd]
        invoke  SendMessageA, eax, EHM_FILECHANGED, edi, 0   ; Set the parameters of the tab.
        xor     eax, eax

.endload:
        clc
        return

        clc
        return

;---------------------------------------------------------------------
onmessage _CEM_CHANGENOTIFY

        invoke  GetParent, [.hwnd]
        invoke  SendMessageA, eax, EHM_FILECHANGED, edi, 0
        clc
        return

;---------------------------------------------------------------------
onmessage _CEM_FOCUSFILE

        invoke  GetParent, [.hwnd]
        invoke  SendMessageA, eax, EHM_FOCUSWINDOW, [.hwnd], 0
        clc
        return

;---------------------------------------------------------------------
onmessage _CEM_CANACTION

        mov     eax, [.lparam]
        cmp     eax, WM_CUT
        je      .checkcopycut
        cmp     eax, WM_COPY
        je      .checkcopycut
        cmp     eax, WM_CLEAR
        je      .checkcopycut
        cmp     eax, WM_UNDO
        je      .checkundo
        cmp     eax, EM_UNDO
        je      .checkundo
        cmp     eax, WM_PASTE
        je      .checkpaste
        xor     eax, eax
        clc
        return

.checkcopycut:
        lea     esi, [.aepos]
        invoke  SendMessageA, [.hwnd], AEM_GETPOS, esi, 0
        mov     eax, [esi+AEPOS.caretPosition]
        mov     ecx, [esi+AEPOS.caretLine]
        cmp     [esi+AEPOS.selectionPosition], eax
        jne     .can_copy
        cmp     [esi+AEPOS.selectionLine], ecx
        jne     .can_copy
        xor     eax, eax
        clc
        return

.can_copy:
        xor     eax, eax
        inc     eax
        clc
        return

.checkundo:
        invoke  SendMessageA, [.hwnd], EM_CANUNDO, 0, 0
        clc
        return

.checkpaste:
        invoke  IsClipboardFormatAvailable, CF_TEXT
        clc
        return

;---------------------------------------------------------------------
onmessage _CEM_EDITACTION

        invoke  SendMessageA, [.hwnd], [.lparam], 0, 0
        clc
        return

;---------------------------------------------------------------------
onmessage _CEM_GETMODIFIED

        invoke  SendMessageA, [.hwnd], AEM_GETMODIFIED, 0, 0
        clc
        return

;---------------------------------------------------------------------
onmessage _CEM_SETMODIFIED

        invoke  SendMessageA, [.hwnd], AEM_SETMODIFIED, [.wparam], [.lparam]
        clc
        return

;---------------------------------------------------------------------
onmessage _CEM_GETFILE

        mov     eax, edi
        clc
        return

;---------------------------------------------------------------------
onmessage _CEM_GETASMEDIT

        mov     eax, [.hwnd]
        clc
        return

;---------------------------------------------------------------------
onmessage WM_KILLFOCUS

        stdcall ClosePopup, [hPAHint], [.hwnd], [.wparam]
        stdcall ClosePopup, [hCCList], [.hwnd], [.wparam]
        stdcall ClosePopup, [hEHelp], [.hwnd], [.wparam]
        jmp     .ondefault


;---------------------------------------------------------------------
onmessage CCM_UPDATEPAPOS
        stdcall UpdatePAHint
        clc
        return

onmessage CCM_UPDATECCPOS
        stdcall UpdateCCPosition
        clc
        return

;-----------------------------------------------------------------------
onmessage WM_LBUTTONDOWN
onmessage WM_RBUTTONDOWN

        stdcall ClosePopup, [hCCList], 0, 0
        stdcall ClosePopup, [hPAHint], 0, 0

        jmp     .ondefault

;-----------------------------------------------------------------------
onmessage WM_VSCROLL
onmessage WM_HSCROLL
        stdcall ClosePopup, [hCCList], 0, 0
        stdcall ClosePopup, [hPAHint], 0, 0
        jmp     .ondefault


;-----------------------------------------------------------------------
onmessage WM_DROPFILES
locals
  .filename rb 1024
  .drop     POINT
  .incl     dd ?
endl

iglobal
  cIncludeCommand db 'include "', 0
  cIncludeEnd     db '"',0
  cIncludeEnd2    db $0d, $0a, 0
endg

        lea     eax, [.drop]
        invoke  DragQueryPoint, [.wparam], eax

        mov     ebx, [.drop.y]
        shl     ebx, 16
        mov     bx, word [.drop.x]
        invoke  SendMessageA, [.hwnd], WM_LBUTTONDOWN, 0, ebx
        invoke  SendMessageA, [.hwnd], WM_LBUTTONUP, 0, ebx

        lea     esi, [.aepos]
        invoke  SendMessageA, [.hwnd], AEM_GETPOS, esi, 0
        mov     [esi+AEPOS.caretPosition], 1
        mov     [esi+AEPOS.selectionPosition], 1
        invoke  SendMessageA, [.hwnd], AEM_SETPOS, esi, 0

        invoke  SendMessageA, [.hwnd], AEM_GETMODE, 0, 0
        push    eax

        invoke  SendMessageA, [.hwnd], AEM_SETMODE, 0, 0

        lea     esi, [.filename]

        invoke  DragQueryFile, [.wparam], -1, esi, 1024
        mov     ebx, eax
        xor     edi, edi

        stdcall StrNew
        mov     [.incl], eax

.opendroploop:
        invoke  DragQueryFile, [.wparam], edi, esi, 1024

        stdcall StrCat, [.incl], cIncludeCommand

        stdcall _RelativeToFinc, esi
        stdcall StrCat, [.incl], eax
        stdcall StrDel, eax

        stdcall StrCat, [.incl], cIncludeEnd

        inc     edi
        dec     ebx
        jnz     .opendroploop

        invoke  DragFinish, [.wparam]

        stdcall StrCat, [.incl], cIncludeEnd2
        stdcall StrPtr, [.incl]
        invoke  SendMessageA, [.hwnd], EM_REPLACESEL, TRUE, eax
        stdcall StrDel, [.incl]

        pop     eax
        invoke  SendMessageA, [.hwnd], AEM_SETMODE, eax, 0

        lea     esi, [.aepos]
        invoke  SendMessageA, [.hwnd], AEM_GETPOS, esi, 0
        mov     eax, [esi+AEPOS.selectionPosition]
        mov     ecx, [esi+AEPOS.selectionLine]
        mov     [esi+AEPOS.caretPosition], eax
        mov     [esi+AEPOS.caretLine], ecx
        invoke  SendMessageA, [.hwnd], AEM_SETPOS, esi, 0

        xor     eax, eax
        clc
        return


;-----------------------------------------------------------------------
onmessage WM_KEYDOWN
;        invoke  PostMessageA, [.hwnd], CCM_UPDATEPAPOS, 0, 0

        cmp     [hCCList], 0
        je      .maybeopen

        mov     ebx, [.wparam]
        call    JumpTo
        MessageList                                      \
          VK_DOWN,   .sendtocc,                          \
          VK_UP,     .sendtocc,                          \
          VK_PRIOR,  .sendtocc,                          \
          VK_NEXT,   .sendtocc,                          \
          VK_HOME,   .sendtocc,                          \
          VK_END,    .sendtocc,                          \
          VK_LEFT,   .closekey,                          \
          VK_RIGHT,  .closekey,                          \
          VK_RETURN, .inserttext

        invoke MapVirtualKeyA, [.wparam], 2
        test   eax, eax
        jz     .ondefault

        cmp     al, ' '
        je      .closekey

        push    eax

        cmp     al, '-'
        jne     @f

        invoke  GetKeyState, VK_SHIFT
        test    ax, ax
        jns     @f

        mov     dword [esp], '_'

@@:
        pop     eax

        call    AsmEdit.recognize_character
        jnc     .endchar

        call    .insert_text_proc

        cmp     [.wparam], $bc
        jne     .maybedot

        invoke  GetKeyState, VK_SHIFT
        test    eax, $8000
        jnz     .closekey

        stdcall CreatePAHint, [.hwnd]
        jmp     .closekey

.maybedot:
        cmp     [.wparam], $be
        jne     .closekey

        invoke  GetKeyState, VK_SHIFT
        test    eax, $8000
        jnz     .closekey

.endchar:
        invoke  PostMessageA, [.hwnd], CCM_UPDATECCPOS, 0, 0
        stc
        return

.closekey:
        invoke  PostMessageA, [hCCList], WM_CLOSE, 0, 0
        stc
        return

.sendtocc:
        invoke  SendMessageA, [hCCList], [.wmsg], [.wparam], [.lparam]
        clc
        return

.inserttext:
        call    .insert_text_proc
        invoke  PostMessageA, [hCCList], WM_CLOSE, 0, 0
        clc
        return

;----------------------------------------------------------------------
.insert_text_proc:

        stdcall GetCCListSelected
        jc      .finishinsert

        lea     eax, [.str]
        invoke  SendMessageA, [.hwnd], AEM_GETWORDATCARET, $ffff0100, eax

        mov     [.aepos.selectionLine], 0
        mov     [.aepos.caretLine], 0
        movzx   ecx, ax
        shr     eax, 16

        inc     ecx
        inc     eax

        mov     [.aepos.selectionPosition], eax
        mov     [.aepos.caretPosition], ecx
        lea     eax, [.aepos]
        invoke  SendMessageA, [.hwnd], AEM_SETPOS, eax, 0
        invoke  SendMessageA, [.hwnd], EM_REPLACESEL, FALSE, ebx

        lea     ebx, [.aepos]
        invoke  SendMessageA, [.hwnd], AEM_GETPOS, ebx, 0
        push    [.aepos.selectionPosition] [.aepos.selectionLine]
        pop     [.aepos.caretLine] [.aepos.caretPosition]
        invoke  SendMessageA, [.hwnd], AEM_SETPOS, ebx, 0

.finishinsert:
        retn


;-------------------------------------------------------------------

.maybeopen:
        mov     eax, [.wparam]
        cmp     eax, $be  ; point
        je      .point

        cmp     eax, VK_SPACE
        je      .space

        cmp     eax, 'Q'
        je      .ctrlQ                  ; procedure arguments hint.

        cmp     eax, 'W'
        je      .ctrlW                  ; procedure embeded help

        cmp     eax, $bc
        jne     .ondefault

        invoke  GetKeyState, VK_SHIFT
        test    eax, $8000
        jnz     .ondefault

; open procedure arguments hint (hPAHint) window
.openPA:
        stdcall CreatePAHint, [.hwnd]
        stc
        return

; open embeded help window
.openEH:
        stdcall CreateEHWindow, [.hwnd]
        stc
        return


.ctrlQ:
        invoke  GetKeyState, VK_CONTROL
        test    eax, $8000
        jnz     .openPA
        stc
        return

.ctrlW:
        invoke  GetKeyState, VK_CONTROL
        test    eax, $8000
        jnz     .openEH
        stc
        return

.space:
        invoke  GetKeyState, VK_CONTROL
        test    eax, $8000
        jz      .ondefault
        jmp     .doit

.point:
        invoke  GetKeyState, VK_SHIFT
        test    eax, $8000
        jnz     .ondefault

        lea     esi, [.str]
        invoke  SendMessageA, [.hwnd], AEM_GETWORDATCARET, $ffff0100, esi

        cmp     byte [esi], 0
        je      .ondefault

.doit:
        stdcall CreateCCList, [.hwnd]
        invoke  PostMessageA, [.hwnd], CCM_UPDATECCPOS, 0, 0

        cmp     [.wparam], $be
        je      .ondefault

        clc
        return

endwp




;-----------------------------------------------------------------------

proc OnGotoDefinition, .wparam, .lparam
begin
        stdcall GetDefinition
        jnc     .def_found

        test    eax, eax
        jz      .missing_info

        cmp     eax, 2
        je      .not_defined

        return

.missing_info:
        invoke  MessageBoxA, [hEditorsHost], cErrorNotCompiled, 0, MB_OK or MB_ICONINFORMATION
        return

.not_defined:
        invoke  MessageBoxA, [hEditorsHost], cErrorNotDefined, 0, MB_OK or MB_ICONINFORMATION
        return

.def_found:
        stdcall PosEditor, eax, edx
        stdcall StrDel, eax
        return
endp


; returns:
; CF=0
; eax - handle of the string with filename of the source file where the label is defined.
; if eax = 0 the cursor is not on the word
; edx - line number of the definition.
;
; CF=1 - the label definition can not be determined.
; eax = 0 - the source is not compiled and there is no debug info loaded
; eax = 1 - the symbol name can not be extracted from the editor.
; eax = 2 - the symbol is not defined for some reason.
proc GetDefinition
.str rb 512
begin
        stdcall WaitForCompiler

        mov     edi, [ptrPreprocessed]
        test    edi, edi
        jz      .missing_info

        invoke  SendMessageA, [hEditorsHost], EHM_GETCURRENTASMEDIT, 0, 0
        test    eax, eax
        jz      .unknown_symbol

        lea     esi, [.str]
        invoke  SendMessageA, eax, AEM_GETWORDATCARET, 512, esi

        cmp     byte [esi], 0
        je      .unknown_symbol

        stdcall SearchTreeExact, esi, ptrLabels
        test    eax, eax
        jz      .unknown_symbol

        test    [eax+TLabel.flags], lfDefined
        jz      .not_defined

        mov     eax, [eax+TLabel.pXRefArray]
        add     edi, [eax+TArray.array+TXRefInfo.ofsSource]         ; address of the preprocessed line where defined

.trytogo:
        mov     eax, [edi+TIntLine.LineNumber]
        test    eax, eax
        js      .frommacro

        mov     ecx, [edi+TIntLine.ofsGenerator]
        add     ecx, [ptrPreprocessed]
        cmp     ecx, [ptrPreprocessed]
        jne     .pos

        mov     ecx, [hStrFileName]

.pos:
        mov     edx, eax
        stdcall StrDup, ecx
        clc
        return

.missing_info:
        xor     eax, eax
        stc
        return

.not_defined:
        mov     eax, 2
        stc
        return

.unknown_symbol:
        mov     eax, 1
        stc
        return

.frommacro:
; the name of the macro
        mov   ecx, [edi+TIntLine.ofsGenerator]
        add   ecx, [ptrPreprocessed]
        cmp   word [ecx+1], '__'          ; internal macro definition... for example __UGlobalBlock or __IGlobalBlock
        je    .searchdown

        mov   edi, [edi+TIntLine.ofsSourceLine]
        add   edi, [ptrPreprocessed]
        jmp   .trytogo

.searchdown:
        mov     edi, [edi+TIntLine.ofsMacroLine]
        add     edi, [ptrPreprocessed]
        jmp     .trytogo
endp



proc ClosePopup, .hpopup, .host, .wparam
begin
        mov     eax, [.wparam]
        cmp     [.hpopup], 0
        je      .exit

        cmp     eax, [.hpopup]
        je      .exit

        cmp     eax, [.host]
        je      .exit

        invoke  PostMessageA, [.hpopup], WM_CLOSE, 0, 0

.exit:
        return
endp
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted source/templates.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
;<ff
Window frmNewFromTemplate, 3, 0, 'TForm', 'New project from template...', $160C0000, $10001, 0, 725, 223, 480, 320, frmTemplatesWinProc;
Window NONE, 0, 0, 'LISTBOX', 'Listbox', $50010103, $200, 100, 0, 72, 234, 184, 0;
Window NONE, 0, 0, 'STATIC', ' Description:', $50000200, $0, 0, 238, 48, 64, 24, 0;
Window NONE, 0, 0, 'EDIT', '', $50200844, $200, 101, 238, 72, 234, 184, 0;
Window NONE, 0, 0, 'STATIC', ' &Directory for the project:', $50000200, $0, 0, 0, 0, 208, 24, 0;
Window NONE, 0, 0, 'BUTTON', 'Cancel', $50010C00, $0, 2, 240, 264, 64, 24, 0;
Window NONE, 0, 0, 'BUTTON', 'OK', $50010C01, $0, 1, 168, 264, 64, 24, 0;
Window NONE, 0, 0, 'STATIC', ' &Template:', $50000200, $0, 0, 0, 48, 56, 24, 0;
Window NONE, 2, 0, 'TButtonEdit', '', $50000080, $200, 102, 0, 24, 474, 21, 0;
;ff>
idProjectsList = 100
idProjectDesc  = 101
idDirectory    = 102



proc NewFromTemplate, .wparam, .lparam
.buffer rb 1024
.finddata FINDDATA
.findhandle dd ?
.projectdir dd ?
begin
        push    esi

        lea     eax, [.buffer]
        invoke  GetCurrentDirectoryA, 1024, eax

        stdcall CreateForm, frmNewFromTemplate, [hApplication]

        lea     esi, [.buffer]
        invoke  SendDlgItemMessageA, ebx, idDirectory, WM_SETTEXT, 0, esi

        stdcall ShowModal, ebx, MSF_CENTER
        cmp     eax, MR_OK
        jne     .endtemplate

        invoke  SendDlgItemMessageA, ebx, idDirectory, WM_GETTEXT, 1024, esi
        stdcall StrDup, esi
        stdcall StrCharCat, eax, '\'
        mov     [.projectdir], eax

; Close all open in the moment files.
;        stdcall OnCloseAll, 0, 0

; Open files of the directory like unsaved files.

; Get template directory
        invoke  SendDlgItemMessageA, ebx, idProjectsList, LB_GETCURSEL, 0, 0
        lea     edi, [.buffer]
        invoke  SendDlgItemMessageA, ebx, idProjectsList, LB_GETTEXT, eax, edi

        stdcall ConvertPath, cTemplatesDir
        mov     esi, eax

        stdcall StrCat, esi, edi
        stdcall StrCharCat, esi, '\'

        lea     edi, [.finddata]

        stdcall StrDup, esi
        push    eax
        stdcall StrCat, eax, cFilterAll
        stdcall StrPtr, eax
        invoke  FindFirstFileA, eax, edi
        stdcall StrDel ; from the stack

        cmp     eax, INVALID_HANDLE_VALUE
        je      .endtemplate

        mov     [.findhandle], eax

.allloop:
        test    [edi+FINDDATA.dwFileAttributes], FILE_ATTRIBUTE_DIRECTORY
        jnz     .nextfile

        stdcall StrDup, [.projectdir]
        lea     ecx, [edi+FINDDATA.cFileName]
        stdcall StrCat, eax, ecx
        push    eax
        mov     edx, eax       ; new name in edx

        stdcall StrDup, esi
        push    eax
        lea     ecx, [edi+FINDDATA.cFileName]
        stdcall StrCat, eax, ecx   ; template name in eax

        stdcall OpenFileByName, edx, eax, TRUE

        stdcall StrDel ; from the stack
        stdcall StrDel ; from the stack

        test    eax, eax
        jz      .nextfile

        mov     edx, eax
        mov     [edx+TOpenFile.fNeverSaved], TRUE

.nextfile:
        invoke  FindNextFileA, [.findhandle], edi
        test    eax, eax
        jnz     .allloop

.endtemplate:
        invoke  DestroyWindow, ebx
        stdcall StrDel, [.projectdir]

        pop     esi
        return
endp


cProjSelectPath text "Select directory where to create project."


winproc frmTemplatesWinProc
.str rb 1024
begin

ondefault
        stc
        return

onmessage BEM_BUTTONCLICK

        lea     edi, [.str]
        invoke  SendDlgItemMessageA, [.hwnd], idDirectory, WM_GETTEXT, 1024, edi
        stdcall SelectPathDialog, [hApplication], cProjSelectPath, edi
        test    eax,eax
        jz      .quit

        push    eax
        stdcall StrPtr, eax
        invoke  SendDlgItemMessageA, [.hwnd], idDirectory, WM_SETTEXT, 0, eax
        stdcall StrDel ; From stack

.quit:
        invoke  SetActiveWindow, [.hwnd]
        clc
        return


onmessage AM_ONIDLE
        invoke  SendDlgItemMessageA, [.hwnd], 100, LB_GETCURSEL, 0, 0

        inc     eax
        push    eax

        invoke  GetDlgItem, [.hwnd], IDOK
        invoke  EnableWindow, eax ; flag from the stack.

        clc
        return

onmessage FM_AFTERCREATE

iglobal
  cTemplatesDir db '%Fresh%\IDE\templates\',0
  cFilterAll    db '*.*', 0
endg

locals
  .finddata FINDDATA
endl

        stdcall ConvertPath, cTemplatesDir
        mov     ebx, eax

        stdcall StrCat, ebx, cFilterAll
        stdcall StrPtr, ebx

        lea     edi, [.finddata]
        invoke  FindFirstFileA, eax, edi
        cmp     eax, INVALID_HANDLE_VALUE
        je      .endoffill
        mov     esi, eax

.loop:
        test    [edi+FINDDATA.dwFileAttributes], FILE_ATTRIBUTE_DIRECTORY
        jz      .nextfile

        cmp     byte [edi+FINDDATA.cFileName], '.'
        je      .nextfile

        lea     eax, [edi+FINDDATA.cFileName]
        invoke  SendDlgItemMessageA, [.hwnd], 100, LB_ADDSTRING, 0, eax

.nextfile:
        invoke  FindNextFileA, esi, edi
        test    eax, eax
        jnz     .loop

        invoke  FindClose, esi
.endoffill:
        stdcall StrDel, ebx
        clc
        return


onmessage WM_COMMAND
locals
  .buffer rb 100
endl
        cmp     word [.wparam+2], LBN_SELCHANGE
        jne     .ondefault

        invoke  SendMessageA, [.lparam], LB_GETCURSEL, 0, 0
        cmp     eax, LB_ERR
        je      .endcommand

        lea     esi, [.buffer]
        invoke  SendMessageA, [.lparam], LB_GETTEXT, eax, esi

        stdcall ConvertPath, cTemplatesDir
        mov     ebx, eax

iglobal
  cReadmeFile db '\readme.txt', 0
endg
        stdcall StrCat, ebx, esi
        stdcall StrCat, ebx, cReadmeFile

        stdcall StrPtr, ebx
        stdcall LoadBinaryFile, eax
        jc      .endcommand
        mov     edi, eax

        invoke  SendDlgItemMessageA, [.hwnd], 101, WM_SETTEXT, 0, edi

        stdcall FreeMem, edi
        stdcall StrDel, ebx
.endcommand:
        clc
        return

endwp



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























































































































































































































































































































































































































































































Deleted source/version.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
FRESH_VERSION equ 'v2.0.9'
FRESH_MAJOR = 2
FRESH_MINOR = 0
FRESH_WORK  = 9

macro months [dayscount]
{
  forward
   if DAY > dayscount
    DAY = DAY-dayscount
    MONTH = MONTH+1
  forward
   end if
}

TIME = %T
DAY = TIME/(24*3600)
DAY = DAY - (DAY+365)/(3*365+366)
YEAR = 1970+DAY/365
DAY = DAY mod 365 + 1
MONTH = 1

if YEAR mod 4 = 0
  FEBDAYS=29
else
  FEBDAYS=28
end if

months 31,FEBDAYS,31,30,31,30,31,31,30,31,30,31

macro num_to_db num, digits {
common
   local ..lbl, ..ptr, ..dig, ..num

..lbl:
   rb digits

   ..ptr = ..lbl + digits - 1
   ..num = num
   repeat digits
     ..dig = (..num mod 10) + $30
     ..num = ..num / 10
     store byte ..dig at ..ptr
     ..ptr = ..ptr - 1
   end repeat
}


macro create_build_time day, month, year {
common
  num_to_db day, 2
  db '.'
  num_to_db month, 2
  db '.'
  num_to_db year, 4
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































Deleted source/virtfiles.asm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
;**********************************************************************
; This file is part of the Fresh project,
;
; Virtual file library.
; The routines in this library simulates file access using memory.
;**********************************************************************

uglobal
  ptrCash  dd ?
endg

;----------------------------------------------------------------------
; Creates virtual file cash with files that are open in editor.
; ---------------------------------------------------------------------
proc InitVCash
.tab TEditorTab
begin
        push    esi edi ebx
        cmp     [ptrCash], 0
        je      @f

        stdcall DestroyVCash

@@:
        stdcall CreateArray, sizeof.TVFile
        mov     [ptrCash], eax

        stdcall EnumOpenFiles, _AppendVirtFile, 0

        pop     ebx edi esi
        return
endp




proc _AppendVirtFile, .ptrOpenFile, .lparam
.file TInMemoryFile
begin
        push    edi ebx
        mov     esi, [.ptrOpenFile]

        cmp     [esi+TOpenFile.fNeverSaved], FALSE
        jne     .addit

        stdcall GetModified, esi
        test    eax, eax
        jz      .finish

.addit:
        cmp     [esi+TOpenFile.hEditor], 0
        je      .finish

        lea     eax, [.file]
        invoke  SendMessageA, [esi+TOpenFile.hEditor], _CEM_GETTEXT, 0, eax
        test    eax, eax
        jnz     .finish         ; error geting the file

        stdcall AddArrayItems, [ptrCash], 1
        mov     [ptrCash], edx
        mov     edi, eax

        mov     edx, [esi+TOpenFile.hFileName]
        mov     ecx, [esi+TOpenFile.hashFileName]
        mov     [edi+TVFile.hFileName], edx
        mov     [edi+TVFile.hashName], ecx
        mov     [edi+TVFile.pos], 0

        mov     ecx, [.file.fileSize]
        mov     edx, [.file.ptrBuffer]
        mov     [edi+TVFile.size], ecx
        mov     [edi+TVFile.buffer], edx

.finish:
        pop     ebx edi
        clc
        return
endp




proc DestroyVCash
begin
        push    esi ebx
        mov     esi, [ptrCash]
        test    esi, esi
        jz      .cashfree

        mov     ebx, [esi+TArray.count]
        test    ebx, ebx
        jz      .emptycash

        lea     esi, [esi+TArray.array]

.loop:
        stdcall FreeMem, [esi+TVFile.buffer]
;        stdcall StrDel, [esi+TVFile.hFileName]         ; Don't delete filename string it is shared...
        add     esi, sizeof.TVFile
        dec     ebx
        jnz     .loop

.emptycash:
        stdcall FreeMem, [ptrCash]
        mov     [ptrCash], 0

.cashfree:
        pop     ebx esi
        return
endp




proc CheckCash, .hFileName
begin
        push    esi edi ebx edx

        mov     esi, [ptrCash]
        test    esi, esi
        jz      .notfound

        stdcall HashFilename, [.hFileName]

        mov     ecx, [esi+TArray.count]
        lea     esi, [esi+TArray.array]

        jecxz   .notfound

.seek:                                         ; Should be binary  search, but for now the count will be small...
        cmp     [esi+TVFile.hashName], eax
        je      .found

        add     esi, sizeof.TVFile
        loop    .seek

.notfound:
        xor     eax, eax
        pop     edx ebx edi esi
        return

.found:
        mov     eax, esi
        pop     edx ebx edi esi
        return

endp


;--------------------------------------------------------------------
; Reads from virtual file. Returns count of bytes realy readed.
;--------------------------------------------------------------------
proc VReadFile, .ptrVFile, .ptrBuffer, .NumBytes
begin
        push    esi edi ebx

        mov     edx, [.ptrVFile]

        mov     ebx, [edx+TVFile.pos]

        mov     esi, [edx+TVFile.buffer]
        mov     ecx, [.NumBytes]
        mov     edi, [.ptrBuffer]

        cmp     [edx+TVFile.size], 0
        je      .error

        mov     eax, [edx+TVFile.size]
        sub     eax, ebx
        jle     .error

        cmp     eax, ecx        ; remaining size of the file.
        jge     .loop

        mov     ecx, eax

.loop:
        mov     al, [esi+ebx]
        inc     ebx
        mov     [edi], al
        inc     edi
        loop    .loop

.endloop:
        mov     eax, [.NumBytes]
        sub     eax, ecx
        mov     [edx+TVFile.pos], ebx
        jmp     .finish

.error:
        xor     eax,eax
.finish:
        pop     ebx edi esi
        return
endp



; Moves the file pointer to the given location in the virtual file.
proc VSetFilePointer, .ptrVFile, .Distance, .Method
begin
        push    esi edi ebx

        mov     esi, [.ptrVFile]
        mov     ecx, [esi+TVFile.size]
        mov     ebx, [esi+TVFile.pos]

        cmp     [.Method], FILE_BEGIN
        je      .begin
        cmp     [.Method], FILE_END
        je      .end

        add     ebx, [.Distance]
        jmp     .norm

.begin:
        mov     ebx, [.Distance]
        jmp     .norm

.end:
        sub     ecx, [.Distance]
        mov     ebx, ecx

.norm:
        test    ebx,ebx
        jns     @f
        xor     ebx,ebx
@@:
        cmp     ebx, [esi+TVFile.size]
        jl      @f
        mov     ebx, [esi+TVFile.size]
@@:
        mov     [esi+TVFile.pos], ebx
        mov     eax,ebx
        pop     ebx edi esi
        return
endp



<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































































































































































































































































































































































































Deleted source/virtfiles.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
;**********************************************************************
; This file is part of the Fresh project,
;
; Virtual file library.
; The routines in this library simulates file access using memory.
;**********************************************************************

struct TVFile
  .hFileName dd ?          ; Handle to the string with filename.
  .hashName  dd ?          ; hash value of the filename.
  .pos       dd ?          ; current position of the file pointer.
  .size      dd ?          ; current size of the file buffer.
  .buffer    dd ?          ; pointer to buffer with file data.
ends

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






























Deleted source/watcheditor.frm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
;<ff
Window frmMemWatch, 2, 0, 'TForm', '', $160C0000, $10080, 0, 473, 186, 191, 240, WatchEditorProc;
;ff>
proc CreateMemWatch, .ptrOpenFile, .ptrTemplate
begin
        push    ebx
        stdcall CreateForm, frmMemWatch, [hEditorsHost]
        mov     eax, [.ptrOpenFile]
        mov     [eax+TOpenFile.hEditor], ebx
        xor     eax, eax
        pop     ebx
        return
endp




winproc WatchEditorProc
begin

ondefault
        stc
        return

onmessage WM_DESTROY

        invoke  GetDlgItem, [.hwnd], 100
        push    eax
        stdcall GetCtrlData, eax, sizeof.TDataGrid
        mov     ebx, eax
        invoke  DestroyWindow ; from the stack.
        stdcall FreeMem, esi
        xor     eax, eax
        clc
        return


onmessage FM_AFTERCREATE

        stdcall GetMem, sizeof.TDataGrid
        mov     ebx, eax

        xor     eax, eax
        invoke  CreateWindowExA, eax, cDataGridClassName, eax,           \
                WS_VISIBLE or WS_CHILD,                                 \
                eax, eax, eax, eax,                                     \
                [.hwnd], 100, [hInstance], ebx

        stdcall SetAlign, eax, waClient

        mov     [ebx+TDataGrid.FixedRows], 1
        mov     [ebx+TDataGrid.ColWidth], 50
        mov     [ebx+TDataGrid.RowHeight], 16
        mov     [ebx+TDataGrid.Flags], dgfGridlines or dgfGridLinesFixed
        stdcall TDataGrid.SetCounts, ebx, 5, 100

        clc
        return

endwp




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
































































































































Deleted source/xref.inc.

1
2
3
4
5
6
7
8
9
10
11
12
13

struct TIntXRef         ; internal record for XREF in the .fas file.
  .ofsSymbol  dd  ?    ; offset of the symbol in the symbol table.
  .ofsAssembly dd ?    ; offset in the assembly dump.
ends


fxrefDefinition = 1

struct TXRefInfo
  .flags     dd ?       ; if == TRUE this row is the definition row.
  .ofsSource dd ?       ; offset in the preprocessed source where the symbol is used.
ends
<
<
<
<
<
<
<
<
<
<
<
<
<