Subversion Repositories Kolibri OS

Rev

Rev 992 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
31 halyavin 1
 
2
; Copyright (c) 1999-2009, Tomasz Grysztar.
1039 heavyiron 3
; All rights reserved.
31 halyavin 4
5
 
6
	mov	edi,characters
157 heavyiron 7
	xor	al,al
8
      make_characters_table:
31 halyavin 9
	stosb
157 heavyiron 10
	inc	al
11
	jnz	make_characters_table
253 heavyiron 12
	mov	esi,characters+'a'
157 heavyiron 13
	mov	edi,characters+'A'
14
	mov	ecx,26
15
	rep	movsb
16
	mov	edi,characters
17
	mov	esi,symbol_characters+1
18
	movzx	ecx,byte [esi-1]
19
	xor	eax,eax
20
      mark_symbol_characters:
31 halyavin 21
	lodsb
157 heavyiron 22
	mov	byte [edi+eax],0
23
	loop	mark_symbol_characters
24
	mov	edi,locals_counter
25
	mov	ax,1 + '0' shl 8
692 heavyiron 26
	stos	word [edi]
27
	mov	edi,[memory_start]
157 heavyiron 28
	mov	[include_paths],edi
29
	mov	esi,include_variable
30
	call	get_environment_variable
31
	xor	al,al
32
	stosb
33
	mov	[memory_start],edi
34
	mov	eax,[additional_memory]
35
	mov	[free_additional_memory],eax
36
	mov	eax,[additional_memory_end]
37
	mov	[labels_list],eax
38
	xor	eax,eax
39
	mov	[display_buffer],eax
40
	mov	[hash_tree],eax
41
	mov	[macro_status],al
42
692 heavyiron 43
 
44
      process_predefinitions:
45
	movzx	ecx,byte [esi]
46
	test	ecx,ecx
47
	jz	predefinitions_ok
48
	inc	esi
49
	lea	eax,[esi+ecx]
50
	push	eax
51
	mov	ch,10b
52
	call	add_preprocessor_symbol
53
	pop	esi
54
	mov	edi,[memory_start]
55
	mov	[edx+8],edi
56
      convert_predefinition:
57
	cmp	edi,[memory_end]
58
	jae	out_of_memory
59
	lods	byte [esi]
60
	or	al,al
61
	jz	predefinition_converted
62
	cmp	al,20h
63
	je	convert_predefinition
64
	mov	ah,al
65
	mov	ebx,characters
66
	xlat	byte [ebx]
67
	or	al,al
68
	jz	predefinition_separator
69
	cmp	ah,27h
70
	je	predefinition_string
71
	cmp	ah,22h
72
	je	predefinition_string
73
	mov	byte [edi],1Ah
74
	scas	word [edi]
75
	xchg	al,ah
76
	stos	byte [edi]
77
	mov	ebx,characters
78
	xor	ecx,ecx
79
      predefinition_symbol:
80
	lods	byte [esi]
81
	stos	byte [edi]
82
	xlat	byte [ebx]
83
	or	al,al
84
	loopnzd predefinition_symbol
85
	neg	ecx
86
	cmp	ecx,255
87
	ja	invalid_definition
88
	mov	ebx,edi
89
	sub	ebx,ecx
90
	mov	byte [ebx-2],cl
91
      found_predefinition_separator:
92
	dec	edi
93
	mov	ah,[esi-1]
94
      predefinition_separator:
95
	xchg	al,ah
96
	or	al,al
97
	jz	predefinition_converted
98
	cmp	al,20h
99
	je	convert_line_data
100
	cmp	al,3Bh
101
	je	invalid_definition
102
	cmp	al,5Ch
103
	je	predefinition_backslash
104
	stos	byte [edi]
105
	jmp	convert_predefinition
106
      predefinition_string:
107
	mov	al,22h
108
	stos	byte [edi]
109
	scas	dword [edi]
110
	mov	ebx,edi
111
      copy_predefinition_string:
112
	lods	byte [esi]
113
	stos	byte [edi]
114
	or	al,al
115
	jz	invalid_definition
116
	cmp	al,ah
117
	jne	copy_predefinition_string
118
	lods	byte [esi]
119
	cmp	al,ah
120
	je	copy_predefinition_string
121
	dec	esi
122
	dec	edi
123
	mov	eax,edi
124
	sub	eax,ebx
125
	mov	[ebx-4],eax
126
	jmp	convert_predefinition
127
      predefinition_backslash:
128
	mov	byte [edi],0
129
	lods	byte [esi]
130
	or	al,al
131
	jz	invalid_definition
132
	cmp	al,20h
133
	je	invalid_definition
134
	cmp	al,3Bh
135
	je	invalid_definition
136
	mov	al,1Ah
137
	stos	byte [edi]
138
	mov	ecx,edi
139
	mov	ax,5C01h
140
	stos	word [edi]
141
	dec	esi
142
      group_predefinition_backslashes:
143
	lods	byte [esi]
144
	cmp	al,5Ch
145
	jne	predefinition_backslashed_symbol
146
	stos	byte [edi]
147
	inc	byte [ecx]
148
	jmp	group_predefinition_backslashes
149
      predefinition_backslashed_symbol:
150
	cmp	al,20h
151
	je	invalid_definition
152
	cmp	al,22h
153
	je	invalid_definition
154
	cmp	al,27h
155
	je	invalid_definition
156
	cmp	al,3Bh
157
	je	invalid_definition
158
	mov	ah,al
159
	mov	ebx,characters
160
	xlat	byte [ebx]
161
	or	al,al
162
	jz	predefinition_backslashed_symbol_character
163
	mov	al,ah
164
      convert_predefinition_backslashed_symbol:
165
	stos	byte [edi]
166
	xlat	byte [ebx]
167
	or	al,al
168
	jz	found_predefinition_separator
169
	inc	byte [ecx]
170
	jz	invalid_definition
171
	lods	byte [esi]
172
	jmp	convert_predefinition_backslashed_symbol
173
      predefinition_backslashed_symbol_character:
174
	mov	al,ah
175
	stos	byte [edi]
176
	inc	byte [ecx]
177
	jmp	convert_predefinition
178
      predefinition_converted:
179
	mov	[memory_start],edi
180
	sub	edi,[edx+8]
181
	mov	[edx+12],edi
182
	jmp	process_predefinitions
183
      predefinitions_ok:
184
185
 
157 heavyiron 186
	mov	edx,esi
187
	call	open
188
	jc	main_file_not_found
189
	mov	edi,[memory_start]
190
	call	preprocess_file
191
	mov	eax,[error_line]
192
	mov	[current_line],eax
193
	cmp	[macro_status],0
194
	jne	incomplete_macro
195
	mov	[source_start],edi
196
	ret
197
31 halyavin 198
 
199
	push	[memory_end]
157 heavyiron 200
	push	esi
201
	mov	al,2
202
	xor	edx,edx
203
	call	lseek
204
	push	eax
205
	xor	al,al
206
	xor	edx,edx
207
	call	lseek
208
	pop	ecx
209
	mov	edx,[memory_end]
210
	dec	edx
211
	mov	byte [edx],1Ah
212
	sub	edx,ecx
213
	jc	out_of_memory
214
	mov	esi,edx
215
	cmp	edx,edi
216
	jbe	out_of_memory
217
	mov	[memory_end],edx
218
	call	read
219
	call	close
220
	pop	edx
221
	xor	ecx,ecx
222
	mov	ebx,esi
223
      preprocess_source:
31 halyavin 224
	inc	ecx
157 heavyiron 225
	mov	[current_line],edi
226
	mov	eax,edx
227
	stos	dword [edi]
228
	mov	eax,ecx
229
	stos	dword [edi]
230
	mov	eax,esi
231
	sub	eax,ebx
232
	stos	dword [edi]
233
	xor	eax,eax
234
	stos	dword [edi]
235
	push	ebx edx
236
	call	convert_line
237
	call	preprocess_line
238
	pop	edx ebx
239
      next_line:
31 halyavin 240
	cmp	byte [esi-1],1Ah
157 heavyiron 241
	jne	preprocess_source
242
      file_end:
31 halyavin 243
	pop	[memory_end]
157 heavyiron 244
	clc
245
	ret
246
31 halyavin 247
 
248
	push	ecx
157 heavyiron 249
	test	[macro_status],0Fh
250
	jz	convert_line_data
251
	mov	ax,3Bh
252
	stos	word [edi]
253
      convert_line_data:
31 halyavin 254
	cmp	edi,[memory_end]
157 heavyiron 255
	jae	out_of_memory
256
	lods	byte [esi]
257
	cmp	al,20h
258
	je	convert_line_data
259
	cmp	al,9
260
	je	convert_line_data
261
	mov	ah,al
262
	mov	ebx,characters
263
	xlat	byte [ebx]
264
	or	al,al
265
	jz	convert_separator
266
	cmp	ah,27h
267
	je	convert_string
268
	cmp	ah,22h
269
	je	convert_string
270
	mov	byte [edi],1Ah
271
	scas	word [edi]
272
	xchg	al,ah
273
	stos	byte [edi]
274
	mov	ebx,characters
275
	xor	ecx,ecx
276
      convert_symbol:
31 halyavin 277
	lods	byte [esi]
157 heavyiron 278
	stos	byte [edi]
279
	xlat	byte [ebx]
280
	or	al,al
281
	loopnzd convert_symbol
282
	neg	ecx
283
	cmp	ecx,255
284
	ja	name_too_long
285
	mov	ebx,edi
286
	sub	ebx,ecx
287
	mov	byte [ebx-2],cl
288
      found_separator:
31 halyavin 289
	dec	edi
157 heavyiron 290
	mov	ah,[esi-1]
291
      convert_separator:
31 halyavin 292
	xchg	al,ah
157 heavyiron 293
	cmp	al,20h
294
	jb	control_character
295
	je	convert_line_data
296
      symbol_character:
31 halyavin 297
	cmp	al,3Bh
157 heavyiron 298
	je	ignore_comment
299
	cmp	al,5Ch
300
	je	backslash_character
301
	stos	byte [edi]
302
	jmp	convert_line_data
303
      control_character:
31 halyavin 304
	cmp	al,1Ah
157 heavyiron 305
	je	line_end
306
	cmp	al,0Dh
307
	je	cr_character
308
	cmp	al,0Ah
309
	je	lf_character
310
	cmp	al,9
311
	je	convert_line_data
312
	or	al,al
313
	jnz	symbol_character
314
	jmp	line_end
315
      lf_character:
31 halyavin 316
	lods	byte [esi]
157 heavyiron 317
	cmp	al,0Dh
318
	je	line_end
319
	dec	esi
320
	jmp	line_end
321
      cr_character:
31 halyavin 322
	lods	byte [esi]
157 heavyiron 323
	cmp	al,0Ah
324
	je	line_end
325
	dec	esi
326
	jmp	line_end
327
      convert_string:
31 halyavin 328
	mov	al,22h
157 heavyiron 329
	stos	byte [edi]
330
	scas	dword [edi]
331
	mov	ebx,edi
332
      copy_string:
31 halyavin 333
	lods	byte [esi]
157 heavyiron 334
	stos	byte [edi]
335
	cmp	al,0Ah
336
	je	missing_end_quote
337
	cmp	al,0Dh
338
	je	missing_end_quote
339
	or	al,al
340
	jz	missing_end_quote
341
	cmp	al,1Ah
342
	je	missing_end_quote
343
	cmp	al,ah
344
	jne	copy_string
345
	lods	byte [esi]
346
	cmp	al,ah
347
	je	copy_string
348
	dec	esi
349
	dec	edi
350
	mov	eax,edi
351
	sub	eax,ebx
352
	mov	[ebx-4],eax
353
	jmp	convert_line_data
354
      backslash_character:
31 halyavin 355
	mov	byte [edi],0
157 heavyiron 356
	lods	byte [esi]
357
	cmp	al,20h
358
	je	concatenate_lines
359
	cmp	al,9
360
	je	concatenate_lines
361
	cmp	al,1Ah
362
	je	unexpected_end_of_file
363
	cmp	al,0Ah
364
	je	concatenate_lf
365
	cmp	al,0Dh
366
	je	concatenate_cr
367
	cmp	al,3Bh
368
	je	find_concatenated_line
369
	mov	al,1Ah
370
	stos	byte [edi]
371
	mov	ecx,edi
372
	mov	ax,5C01h
373
	stos	word [edi]
374
	dec	esi
375
      group_backslashes:
31 halyavin 376
	lods	byte [esi]
157 heavyiron 377
	cmp	al,5Ch
378
	jne	backslashed_symbol
379
	stos	byte [edi]
380
	inc	byte [ecx]
381
	jmp	group_backslashes
382
      backslashed_symbol:
31 halyavin 383
	cmp	al,1Ah
157 heavyiron 384
	je	unexpected_end_of_file
385
	cmp	al,0Ah
386
	je	extra_characters_on_line
387
	cmp	al,0Dh
388
	je	extra_characters_on_line
389
	cmp	al,20h
390
	je	extra_characters_on_line
391
	cmp	al,9
392
	je	extra_characters_on_line
393
	cmp	al,22h
394
	je	extra_characters_on_line
395
	cmp	al,27h
396
	je	extra_characters_on_line
397
	cmp	al,3Bh
398
	je	extra_characters_on_line
399
	mov	ah,al
400
	mov	ebx,characters
401
	xlat	byte [ebx]
402
	or	al,al
403
	jz	backslashed_symbol_character
404
	mov	al,ah
405
      convert_backslashed_symbol:
31 halyavin 406
	stos	byte [edi]
157 heavyiron 407
	xlat	byte [ebx]
408
	or	al,al
409
	jz	found_separator
410
	inc	byte [ecx]
411
	jz	name_too_long
412
	lods	byte [esi]
413
	jmp	convert_backslashed_symbol
414
      backslashed_symbol_character:
31 halyavin 415
	mov	al,ah
157 heavyiron 416
	stos	byte [edi]
417
	inc	byte [ecx]
418
	jmp	convert_line_data
419
      concatenate_lines:
31 halyavin 420
	lods	byte [esi]
157 heavyiron 421
	cmp	al,20h
422
	je	concatenate_lines
423
	cmp	al,9
424
	je	concatenate_lines
425
	cmp	al,1Ah
426
	je	unexpected_end_of_file
427
	cmp	al,0Ah
428
	je	concatenate_lf
429
	cmp	al,0Dh
430
	je	concatenate_cr
431
	cmp	al,3Bh
432
	jne	extra_characters_on_line
433
      find_concatenated_line:
31 halyavin 434
	lods	byte [esi]
157 heavyiron 435
	cmp	al,0Ah
436
	je	concatenate_lf
437
	cmp	al,0Dh
438
	je	concatenate_cr
439
	or	al,al
440
	jz	concatenate_ok
441
	cmp	al,1Ah
442
	jne	find_concatenated_line
443
	jmp	unexpected_end_of_file
444
      concatenate_lf:
31 halyavin 445
	lods	byte [esi]
157 heavyiron 446
	cmp	al,0Dh
447
	je	concatenate_ok
448
	dec	esi
449
	jmp	concatenate_ok
450
      concatenate_cr:
31 halyavin 451
	lods	byte [esi]
157 heavyiron 452
	cmp	al,0Ah
453
	je	concatenate_ok
454
	dec	esi
455
      concatenate_ok:
31 halyavin 456
	inc	dword [esp]
157 heavyiron 457
	jmp	convert_line_data
458
      ignore_comment:
31 halyavin 459
	lods	byte [esi]
157 heavyiron 460
	cmp	al,0Ah
461
	je	lf_character
462
	cmp	al,0Dh
463
	je	cr_character
464
	or	al,al
465
	jz	line_end
466
	cmp	al,1Ah
467
	jne	ignore_comment
468
      line_end:
31 halyavin 469
	xor	al,al
157 heavyiron 470
	stos	byte [edi]
471
	pop	ecx
472
	ret
473
31 halyavin 474
 
109 heavyiron 475
	mov	edi,converted
157 heavyiron 476
	mov	ebx,characters
477
      convert_case:
109 heavyiron 478
	lods	byte [esi]
157 heavyiron 479
	xlat	byte [ebx]
480
	stos	byte [edi]
481
	loop	convert_case
482
      case_ok:
109 heavyiron 483
	ret
157 heavyiron 484
109 heavyiron 485
 
486
	push	edi
157 heavyiron 487
	mov	edx,esi
488
	mov	ebp,ecx
489
	call	lower_case
490
	pop	edi
491
      scan_directives:
109 heavyiron 492
	mov	esi,converted
157 heavyiron 493
	movzx	eax,byte [edi]
494
	or	al,al
495
	jz	no_directive
496
	mov	ecx,ebp
497
	inc	edi
498
	mov	ebx,edi
499
	add	ebx,eax
500
	mov	ah,[esi]
501
	cmp	ah,[edi]
502
	jb	no_directive
503
	ja	next_directive
504
	cmp	cl,al
505
	jne	next_directive
506
	repe	cmps byte [esi],[edi]
507
	jb	no_directive
508
	je	directive_ok
509
      next_directive:
109 heavyiron 510
	mov	edi,ebx
157 heavyiron 511
	add	edi,2
512
	jmp	scan_directives
513
      no_directive:
109 heavyiron 514
	mov	esi,edx
157 heavyiron 515
	mov	ecx,ebp
516
	stc
517
	ret
518
      directive_ok:
109 heavyiron 519
	lea	esi,[edx+ebp]
157 heavyiron 520
	movzx	eax,word [ebx]
521
	add	eax,preprocessor
522
	clc
523
	ret
524
109 heavyiron 525
 
526
 
31 halyavin 527
	mov	eax,esp
157 heavyiron 528
	sub	eax,100h
529
	jc	stack_overflow
530
	cmp	eax,[stack_limit]
531
	jb	stack_overflow
532
	push	ecx esi
533
      preprocess_current_line:
31 halyavin 534
	mov	esi,[current_line]
157 heavyiron 535
	add	esi,16
536
	cmp	word [esi],3Bh
537
	jne	line_start_ok
538
	add	esi,2
539
      line_start_ok:
31 halyavin 540
	test	[macro_status],0F0h
157 heavyiron 541
	jnz	macro_preprocessing
542
	cmp	byte [esi],1Ah
543
	jne	not_fix_constant
544
	movzx	edx,byte [esi+1]
545
	lea	edx,[esi+2+edx]
546
	cmp	word [edx],031Ah
547
	jne	not_fix_constant
548
	mov	ebx,characters
549
	movzx	eax,byte [edx+2]
550
	xlat	byte [ebx]
551
	ror	eax,8
552
	mov	al,[edx+3]
553
	xlat	byte [ebx]
554
	ror	eax,8
555
	mov	al,[edx+4]
556
	xlat	byte [ebx]
557
	ror	eax,16
558
	cmp	eax,'fix'
559
	je	define_fix_constant
560
      not_fix_constant:
31 halyavin 561
	call	process_fix_constants
157 heavyiron 562
	jmp	initial_preprocessing_ok
563
      macro_preprocessing:
31 halyavin 564
	call	process_macro_operators
157 heavyiron 565
      initial_preprocessing_ok:
31 halyavin 566
	mov	esi,[current_line]
157 heavyiron 567
	add	esi,16
568
	mov	al,[macro_status]
569
	test	al,2
570
	jnz	skip_macro_block
571
	test	al,1
572
	jnz	find_macro_block
573
      preprocess_instruction:
31 halyavin 574
	mov	[current_offset],esi
157 heavyiron 575
	lods	byte [esi]
576
	movzx	ecx,byte [esi]
577
	inc	esi
578
	cmp	al,1Ah
579
	jne	not_preprocessor_symbol
580
	cmp	cl,3
581
	jb	not_preprocessor_directive
582
	push	edi
583
	mov	edi,preprocessor_directives
584
	call	get_directive
585
	pop	edi
586
	jc	not_preprocessor_directive
587
	mov	byte [edx-2],3Bh
588
	jmp	near eax
589
      not_preprocessor_directive:
31 halyavin 590
	xor	ch,ch
157 heavyiron 591
	call	get_preprocessor_symbol
592
	jc	not_macro
593
	mov	byte [ebx-2],3Bh
594
	mov	[struc_name],0
595
	jmp	use_macro
596
      not_macro:
31 halyavin 597
	mov	[struc_name],esi
157 heavyiron 598
	add	esi,ecx
599
	lods	byte [esi]
600
	cmp	al,':'
601
	je	preprocess_label
602
	cmp	al,1Ah
603
	jne	not_preprocessor_symbol
604
	lods	byte [esi]
605
	cmp	al,3
606
	jne	not_symbolic_constant
607
	mov	ebx,characters
608
	movzx	eax,byte [esi]
609
	xlat	byte [ebx]
610
	ror	eax,8
611
	mov	al,[esi+1]
612
	xlat	byte [ebx]
613
	ror	eax,8
614
	mov	al,[esi+2]
615
	xlat	byte [ebx]
616
	ror	eax,16
617
	cmp	eax,'equ'
618
	je	define_equ_constant
619
	mov	al,3
620
      not_symbolic_constant:
31 halyavin 621
	mov	ch,1
157 heavyiron 622
	mov	cl,al
623
	call	get_preprocessor_symbol
624
	jc	not_preprocessor_symbol
625
	push	edx esi
626
	mov	esi,[struc_name]
627
	mov	[struc_label],esi
628
	sub	[struc_label],2
629
	mov	cl,[esi-1]
630
	mov	ch,10b
631
	call	get_preprocessor_symbol
632
	jc	struc_name_ok
633
	mov	ecx,[edx+12]
634
	add	ecx,3
635
	lea	ebx,[edi+ecx]
636
	mov	ecx,edi
637
	sub	ecx,[struc_label]
638
	lea	esi,[edi-1]
639
	lea	edi,[ebx-1]
640
	std
641
	rep	movs byte [edi],[esi]
642
	cld
643
	mov	edi,[struc_label]
644
	mov	esi,[edx+8]
645
	mov	ecx,[edx+12]
646
	add	[struc_name],ecx
647
	add	[struc_name],3
648
	call	move_data
649
	mov	al,3Ah
650
	stos	byte [edi]
651
	mov	ax,3Bh
652
	stos	word [edi]
653
	mov	edi,ebx
654
	pop	esi
655
	add	esi,[edx+12]
656
	add	esi,3
657
	pop	edx
658
	jmp	use_macro
659
      struc_name_ok:
31 halyavin 660
	mov	edx,[struc_name]
157 heavyiron 661
	movzx	eax,byte [edx-1]
662
	add	edx,eax
663
	push	edi
992 heavyiron 664
	lea	esi,[edi-1]
665
	mov	ecx,edi
666
	sub	ecx,edx
667
	std
668
	rep	movs byte [edi],[esi]
669
	cld
670
	pop	edi
671
	inc	edi
672
	mov	al,3Ah
157 heavyiron 673
	mov	[edx],al
674
	inc	al
675
	mov	[edx+1],al
992 heavyiron 676
	pop	esi edx
157 heavyiron 677
	inc	esi
992 heavyiron 678
	jmp	use_macro
157 heavyiron 679
      preprocess_label:
31 halyavin 680
	dec	esi
157 heavyiron 681
	sub	esi,ecx
682
	lea	ebp,[esi-2]
683
	mov	ch,10b
684
	call	get_preprocessor_symbol
685
	jnc	symbolic_constant_in_label
686
	lea	esi,[esi+ecx+1]
687
	jmp	preprocess_instruction
688
      symbolic_constant_in_label:
31 halyavin 689
	mov	ebx,[edx+8]
157 heavyiron 690
	mov	ecx,[edx+12]
691
	add	ecx,ebx
692
      check_for_broken_label:
31 halyavin 693
	cmp	ebx,ecx
157 heavyiron 694
	je	label_broken
695
	cmp	byte [ebx],1Ah
696
	jne	label_broken
697
	movzx	eax,byte [ebx+1]
698
	lea	ebx,[ebx+2+eax]
699
	cmp	ebx,ecx
700
	je	label_constant_ok
701
	cmp	byte [ebx],':'
702
	jne	label_broken
703
	inc	ebx
704
	jmp	check_for_broken_label
705
      label_broken:
31 halyavin 706
	push	line_preprocessed
157 heavyiron 707
	jmp	replace_symbolic_constant
708
      label_constant_ok:
31 halyavin 709
	mov	ecx,edi
157 heavyiron 710
	sub	ecx,esi
711
	mov	edi,[edx+12]
712
	add	edi,ebp
713
	push	edi
714
	lea	eax,[edi+ecx]
715
	push	eax
716
	cmp	esi,edi
717
	je	replace_label
718
	jb	move_rest_of_line_up
719
	rep	movs byte [edi],[esi]
720
	jmp	replace_label
721
      move_rest_of_line_up:
31 halyavin 722
	lea	esi,[esi+ecx-1]
157 heavyiron 723
	lea	edi,[edi+ecx-1]
724
	std
725
	rep	movs byte [edi],[esi]
726
	cld
727
      replace_label:
31 halyavin 728
	mov	ecx,[edx+12]
157 heavyiron 729
	mov	edi,[esp+4]
730
	sub	edi,ecx
731
	mov	esi,[edx+8]
732
	rep	movs byte [edi],[esi]
733
	pop	edi esi
734
	inc	esi
735
	jmp	preprocess_instruction
736
      not_preprocessor_symbol:
31 halyavin 737
	mov	esi,[current_offset]
157 heavyiron 738
	call	process_equ_constants
739
      line_preprocessed:
31 halyavin 740
	pop	esi ecx
157 heavyiron 741
	ret
742
31 halyavin 743
 
744
	push	ebp edi esi
157 heavyiron 745
	mov	ebp,ecx
746
	shl	ebp,22
747
	movzx	ecx,cl
748
	mov	ebx,hash_tree
749
	mov	edi,10
750
      follow_hashes_roots:
31 halyavin 751
	mov	edx,[ebx]
157 heavyiron 752
	or	edx,edx
753
	jz	preprocessor_symbol_not_found
754
	xor	eax,eax
755
	shl	ebp,1
756
	adc	eax,0
757
	lea	ebx,[edx+eax*4]
758
	dec	edi
759
	jnz	follow_hashes_roots
760
	mov	edi,ebx
761
	call	calculate_hash
762
	mov	ebp,eax
763
	and	ebp,3FFh
764
	shl	ebp,10
765
	xor	ebp,eax
766
	mov	ebx,edi
767
	mov	edi,22
768
      follow_hashes_tree:
31 halyavin 769
	mov	edx,[ebx]
157 heavyiron 770
	or	edx,edx
771
	jz	preprocessor_symbol_not_found
772
	xor	eax,eax
773
	shl	ebp,1
774
	adc	eax,0
775
	lea	ebx,[edx+eax*4]
776
	dec	edi
777
	jnz	follow_hashes_tree
778
	mov	al,cl
779
	mov	edx,[ebx]
780
	or	edx,edx
781
	jz	preprocessor_symbol_not_found
782
      compare_with_preprocessor_symbol:
31 halyavin 783
	mov	edi,[edx+4]
157 heavyiron 784
	cmp	edi,1
785
	jbe	next_equal_hash
786
	repe	cmps byte [esi],[edi]
787
	je	preprocessor_symbol_found
788
	mov	cl,al
789
	mov	esi,[esp]
790
      next_equal_hash:
31 halyavin 791
	mov	edx,[edx]
157 heavyiron 792
	or	edx,edx
793
	jnz	compare_with_preprocessor_symbol
794
      preprocessor_symbol_not_found:
31 halyavin 795
	pop	esi edi ebp
157 heavyiron 796
	stc
797
	ret
798
      preprocessor_symbol_found:
31 halyavin 799
	pop	ebx edi ebp
157 heavyiron 800
	clc
801
	ret
802
      calculate_hash:
31 halyavin 803
	xor	ebx,ebx
157 heavyiron 804
	mov	eax,2166136261
805
	mov	ebp,16777619
806
      fnv1a_hash:
31 halyavin 807
	xor	al,[esi+ebx]
157 heavyiron 808
	mul	ebp
809
	inc	bl
810
	cmp	bl,cl
811
	jb	fnv1a_hash
812
	ret
813
add_preprocessor_symbol:
31 halyavin 814
	push	edi esi
157 heavyiron 815
	cmp	ch,11b
992 heavyiron 816
	je	preprocessor_symbol_name_ok
817
	push	ecx
818
	movzx	ecx,cl
819
	mov	edi,preprocessor_directives
872 heavyiron 820
	call	get_directive
821
	jnc	reserved_word_used_as_symbol
822
	pop	ecx
992 heavyiron 823
      preprocessor_symbol_name_ok:
824
	call	calculate_hash
157 heavyiron 825
	mov	ebp,eax
826
	and	ebp,3FFh
827
	shr	eax,10
828
	xor	ebp,eax
829
	shl	ecx,22
830
	or	ebp,ecx
831
	mov	ebx,hash_tree
832
	mov	ecx,32
833
      find_leave_for_symbol:
31 halyavin 834
	mov	edx,[ebx]
157 heavyiron 835
	or	edx,edx
836
	jz	extend_hashes_tree
837
	xor	eax,eax
838
	rol	ebp,1
839
	adc	eax,0
840
	lea	ebx,[edx+eax*4]
841
	dec	ecx
842
	jnz	find_leave_for_symbol
843
	mov	edx,[ebx]
844
	or	edx,edx
845
	jz	add_symbol_entry
846
	shr	ebp,30
847
	cmp	ebp,11b
848
	je	reuse_symbol_entry
849
	cmp	dword [edx+4],0
850
	jne	add_symbol_entry
851
      find_entry_to_reuse:
31 halyavin 852
	mov	edi,[edx]
157 heavyiron 853
	or	edi,edi
854
	jz	reuse_symbol_entry
855
	cmp	dword [edi+4],0
856
	jne	reuse_symbol_entry
857
	mov	edx,edi
858
	jmp	find_entry_to_reuse
859
      add_symbol_entry:
31 halyavin 860
	mov	eax,edx
157 heavyiron 861
	mov	edx,[labels_list]
862
	sub	edx,16
863
	cmp	edx,[free_additional_memory]
864
	jb	out_of_memory
865
	mov	[labels_list],edx
866
	mov	[edx],eax
867
	mov	[ebx],edx
868
      reuse_symbol_entry:
31 halyavin 869
	pop	esi edi
157 heavyiron 870
	mov	[edx+4],esi
871
	ret
872
      extend_hashes_tree:
31 halyavin 873
	mov	edx,[labels_list]
157 heavyiron 874
	sub	edx,8
875
	cmp	edx,[free_additional_memory]
876
	jb	out_of_memory
877
	mov	[labels_list],edx
878
	xor	eax,eax
879
	mov	[edx],eax
880
	mov	[edx+4],eax
881
	shl	ebp,1
882
	adc	eax,0
883
	mov	[ebx],edx
884
	lea	ebx,[edx+eax*4]
885
	dec	ecx
886
	jnz	extend_hashes_tree
887
	mov	edx,[labels_list]
888
	sub	edx,16
889
	cmp	edx,[free_additional_memory]
890
	jb	out_of_memory
891
	mov	[labels_list],edx
892
	mov	dword [edx],0
893
	mov	[ebx],edx
894
	pop	esi edi
895
	mov	[edx+4],esi
896
	ret
897
31 halyavin 898
 
899
	add	edx,5
157 heavyiron 900
	add	esi,2
901
	push	edx esi
902
	mov	esi,edx
903
	call	skip_parameters
904
	xchg	esi,[esp]
905
	mov	ch,11b
906
	jmp	define_preprocessor_constant
907
define_equ_constant:
31 halyavin 908
	add	esi,3
157 heavyiron 909
	push	esi
910
	call	process_equ_constants
911
	push	esi
912
	mov	esi,[struc_name]
913
	mov	ch,10b
914
      define_preprocessor_constant:
109 heavyiron 915
	mov	byte [esi-2],3Bh
157 heavyiron 916
	mov	cl,[esi-1]
917
	call	add_preprocessor_symbol
918
	pop	esi ebx
919
	mov	ecx,edi
920
	dec	ecx
921
	sub	ecx,ebx
922
	mov	[edx+8],ebx
923
	mov	[edx+12],ecx
924
	jmp	line_preprocessed
925
define_symbolic_constant:
109 heavyiron 926
	lods	byte [esi]
157 heavyiron 927
	cmp	al,1Ah
928
	jne	invalid_name
929
	lods	byte [esi]
930
	mov	cl,al
931
	mov	ch,10b
932
	call	add_preprocessor_symbol
933
	movzx	eax,byte [esi-1]
934
	add	esi,eax
935
	push	esi edx
936
	call	skip_parameters
937
	pop	edx ebx
938
	lea	ecx,[esi-1]
939
	sub	ecx,ebx
940
	mov	[edx+8],ebx
941
	mov	[edx+12],ecx
942
	jmp	line_preprocessed
943
      skip_parameters:
109 heavyiron 944
	lods	byte [esi]
157 heavyiron 945
	or	al,al
946
	jz	parameters_skipped
947
	cmp	al,'{'
948
	je	parameters_skipped
949
	cmp	al,22h
950
	je	skip_quoted_parameter
951
	cmp	al,1Ah
952
	jne	skip_parameters
953
	lods	byte [esi]
954
	movzx	eax,al
955
	add	esi,eax
956
	jmp	skip_parameters
957
      skip_quoted_parameter:
109 heavyiron 958
	lods	dword [esi]
157 heavyiron 959
	add	esi,eax
960
	jmp	skip_parameters
961
      parameters_skipped:
109 heavyiron 962
	ret
157 heavyiron 963
109 heavyiron 964
 
31 halyavin 965
	mov	ch,1
157 heavyiron 966
	jmp	make_macro
967
define_macro:
31 halyavin 968
	xor	ch,ch
157 heavyiron 969
      make_macro:
31 halyavin 970
	lods	byte [esi]
157 heavyiron 971
	cmp	al,1Ah
972
	jne	invalid_name
973
	lods	byte [esi]
974
	mov	cl,al
975
	call	add_preprocessor_symbol
976
	mov	eax,[current_line]
977
	mov	[edx+12],eax
978
	movzx	eax,byte [esi-1]
979
	add	esi,eax
980
	mov	[edx+8],esi
981
	mov	al,[macro_status]
982
	and	al,0F0h
983
	or	al,1
984
	mov	[macro_status],al
985
	mov	eax,[current_line]
986
	mov	[error_line],eax
987
	xor	bl,bl
988
	lods	byte [esi]
989
	or	al,al
990
	jz	line_preprocessed
991
	cmp	al,'{'
992
	je	found_macro_block
993
	dec	esi
994
      skip_macro_arguments:
31 halyavin 995
	lods	byte [esi]
157 heavyiron 996
	cmp	al,1Ah
997
	je	skip_macro_argument
998
	cmp	al,'['
999
	jne	invalid_macro_arguments
1000
	xor	bl,-1
1001
	jz	invalid_macro_arguments
1002
	lods	byte [esi]
1003
	cmp	al,1Ah
1004
	jne	invalid_macro_arguments
1005
      skip_macro_argument:
31 halyavin 1006
	movzx	eax,byte [esi]
157 heavyiron 1007
	inc	esi
1008
	add	esi,eax
1009
	lods	byte [esi]
1010
	cmp	al,'*'
1011
	jne	macro_argument_end
1012
	lods	byte [esi]
1013
      macro_argument_end:
31 halyavin 1014
	cmp	al,','
157 heavyiron 1015
	je	skip_macro_arguments
1016
	cmp	al,']'
1017
	jne	end_macro_arguments
1018
	lods	byte [esi]
1019
	not	bl
1020
      end_macro_arguments:
31 halyavin 1021
	or	bl,bl
157 heavyiron 1022
	jnz	invalid_macro_arguments
1023
	or	al,al
1024
	jz	line_preprocessed
1025
	cmp	al,'{'
1026
	je	found_macro_block
1027
	jmp	invalid_macro_arguments
1028
      find_macro_block:
31 halyavin 1029
	add	esi,2
157 heavyiron 1030
	lods	byte [esi]
1031
	or	al,al
1032
	jz	line_preprocessed
1033
	cmp	al,'{'
1034
	jne	unexpected_characters
1035
      found_macro_block:
31 halyavin 1036
	or	[macro_status],2
157 heavyiron 1037
      skip_macro_block:
31 halyavin 1038
	lods	byte [esi]
157 heavyiron 1039
	cmp	al,1Ah
1040
	je	skip_macro_symbol
1041
	cmp	al,3Bh
1042
	je	skip_macro_symbol
1043
	cmp	al,22h
1044
	je	skip_macro_string
1045
	or	al,al
1046
	jz	line_preprocessed
1047
	cmp	al,'}'
1048
	jne	skip_macro_block
1049
	mov	al,[macro_status]
1050
	and	[macro_status],0F0h
1051
	test	al,8
1052
	jnz	use_instant_macro
1053
	cmp	byte [esi],0
1054
	je	line_preprocessed
1055
	mov	ecx,edi
1056
	sub	ecx,esi
1057
	mov	edx,esi
1058
	lea	esi,[esi+ecx-1]
1059
	lea	edi,[edi+1+16]
1060
	mov	ebx,edi
1061
	dec	edi
1062
	std
1063
	rep	movs byte [edi],[esi]
1064
	cld
1065
	mov	edi,edx
1066
	xor	al,al
1067
	stos	byte [edi]
1068
	mov	esi,[current_line]
1069
	mov	[current_line],edi
1070
	mov	ecx,4
1071
	rep	movs dword [edi],[esi]
1072
	mov	edi,ebx
1073
	jmp	initial_preprocessing_ok
1074
      skip_macro_symbol:
31 halyavin 1075
	movzx	eax,byte [esi]
157 heavyiron 1076
	inc	esi
1077
	add	esi,eax
1078
	jmp	skip_macro_block
1079
      skip_macro_string:
31 halyavin 1080
	lods	dword [esi]
157 heavyiron 1081
	add	esi,eax
1082
	jmp	skip_macro_block
1083
rept_directive:
31 halyavin 1084
	mov	[base_code],0
157 heavyiron 1085
	jmp	define_instant_macro
1086
irp_directive:
31 halyavin 1087
	mov	[base_code],1
157 heavyiron 1088
	jmp	define_instant_macro
1089
irps_directive:
31 halyavin 1090
	mov	[base_code],2
157 heavyiron 1091
	jmp	define_instant_macro
1092
match_directive:
31 halyavin 1093
	mov	[base_code],10h
157 heavyiron 1094
define_instant_macro:
31 halyavin 1095
	mov	al,[macro_status]
157 heavyiron 1096
	and	al,0F0h
1097
	or	al,8+1
1098
	mov	[macro_status],al
1099
	mov	eax,[current_line]
1100
	mov	[error_line],eax
1101
	mov	[instant_macro_start],esi
1102
	cmp	[base_code],10h
1103
	je	prepare_match
1104
	call	skip_parameters
1105
      instant_macro_parameters_skipped:
109 heavyiron 1106
	dec	esi
157 heavyiron 1107
	mov	[parameters_end],esi
1108
	lods	byte [esi]
1109
	cmp	al,'{'
1110
	je	found_macro_block
1111
	or	al,al
1112
	jnz	invalid_macro_arguments
1113
	jmp	line_preprocessed
1114
prepare_match:
31 halyavin 1115
	call	skip_pattern
157 heavyiron 1116
	mov	[value_type],80h+10b
1117
	call	process_symbolic_constants
1118
	jmp	instant_macro_parameters_skipped
1119
      skip_pattern:
31 halyavin 1120
	lods	byte [esi]
157 heavyiron 1121
	or	al,al
1122
	jz	invalid_macro_arguments
1123
	cmp	al,','
1124
	je	pattern_skipped
1125
	cmp	al,22h
1126
	je	skip_quoted_string_in_pattern
1127
	cmp	al,1Ah
1128
	je	skip_symbol_in_pattern
1129
	cmp	al,'='
1130
	jne	skip_pattern
1131
	mov	al,[esi]
1132
	cmp	al,1Ah
1133
	je	skip_pattern
1134
	cmp	al,22h
1135
	je	skip_pattern
1136
	inc	esi
1137
	jmp	skip_pattern
1138
      skip_symbol_in_pattern:
31 halyavin 1139
	lods	byte [esi]
157 heavyiron 1140
	movzx	eax,al
1141
	add	esi,eax
1142
	jmp	skip_pattern
1143
      skip_quoted_string_in_pattern:
31 halyavin 1144
	lods	dword [esi]
157 heavyiron 1145
	add	esi,eax
1146
	jmp	skip_pattern
1147
      pattern_skipped:
31 halyavin 1148
	ret
157 heavyiron 1149
31 halyavin 1150
 
1151
	xor	ch,ch
157 heavyiron 1152
	jmp	restore_preprocessor_symbol
1153
purge_struc:
31 halyavin 1154
	mov	ch,1
157 heavyiron 1155
	jmp	restore_preprocessor_symbol
1156
restore_equ_constant:
31 halyavin 1157
	mov	ch,10b
157 heavyiron 1158
      restore_preprocessor_symbol:
31 halyavin 1159
	push	ecx
157 heavyiron 1160
	lods	byte [esi]
1161
	cmp	al,1Ah
1162
	jne	invalid_name
1163
	lods	byte [esi]
1164
	mov	cl,al
1165
	call	get_preprocessor_symbol
1166
	jc	no_symbol_to_restore
1167
	mov	dword [edx+4],0
1168
	jmp	symbol_restored
1169
      no_symbol_to_restore:
31 halyavin 1170
	add	esi,ecx
157 heavyiron 1171
      symbol_restored:
31 halyavin 1172
	pop	ecx
157 heavyiron 1173
	lods	byte [esi]
1174
	cmp	al,','
1175
	je	restore_preprocessor_symbol
1176
	or	al,al
1177
	jnz	extra_characters_on_line
1178
	jmp	line_preprocessed
1179
31 halyavin 1180
 
1181
	mov	[value_type],11b
157 heavyiron 1182
	jmp	process_symbolic_constants
1183
process_equ_constants:
31 halyavin 1184
	mov	[value_type],10b
157 heavyiron 1185
      process_symbolic_constants:
31 halyavin 1186
	mov	ebp,esi
157 heavyiron 1187
	lods	byte [esi]
1188
	cmp	al,1Ah
1189
	je	check_symbol
1190
	cmp	al,22h
1191
	je	ignore_string
1192
	cmp	al,'{'
1193
	je	check_brace
1194
	or	al,al
1195
	jnz	process_symbolic_constants
1196
	ret
1197
      ignore_string:
31 halyavin 1198
	lods	dword [esi]
157 heavyiron 1199
	add	esi,eax
1200
	jmp	process_symbolic_constants
1201
      check_brace:
31 halyavin 1202
	test	[value_type],80h
157 heavyiron 1203
	jz	process_symbolic_constants
1204
	ret
1205
      no_replacing:
31 halyavin 1206
	movzx	ecx,byte [esi-1]
157 heavyiron 1207
	add	esi,ecx
1208
	jmp	process_symbolic_constants
1209
      check_symbol:
31 halyavin 1210
	mov	cl,[esi]
157 heavyiron 1211
	inc	esi
1212
	mov	ch,[value_type]
1213
	call	get_preprocessor_symbol
1214
	jc	no_replacing
1215
	mov	[current_section],edi
1216
      replace_symbolic_constant:
31 halyavin 1217
	mov	ecx,[edx+12]
157 heavyiron 1218
	mov	edx,[edx+8]
1219
	xchg	esi,edx
1220
	call	move_data
1221
	mov	esi,edx
1222
      process_after_replaced:
31 halyavin 1223
	lods	byte [esi]
157 heavyiron 1224
	cmp	al,1Ah
1225
	je	symbol_after_replaced
1226
	stos	byte [edi]
1227
	cmp	al,22h
1228
	je	string_after_replaced
1229
	cmp	al,'{'
1230
	je	brace_after_replaced
1231
	or	al,al
1232
	jnz	process_after_replaced
1233
	mov	ecx,edi
1234
	sub	ecx,esi
1235
	mov	edi,ebp
1236
	call	move_data
1237
	mov	esi,edi
1238
	ret
1239
      move_data:
31 halyavin 1240
	lea	eax,[edi+ecx]
157 heavyiron 1241
	cmp	eax,[memory_end]
1242
	jae	out_of_memory
1243
	shr	ecx,1
1244
	jnc	movsb_ok
1245
	movs	byte [edi],[esi]
1246
      movsb_ok:
31 halyavin 1247
	shr	ecx,1
157 heavyiron 1248
	jnc	movsw_ok
1249
	movs	word [edi],[esi]
1250
      movsw_ok:
31 halyavin 1251
	rep	movs dword [edi],[esi]
157 heavyiron 1252
	ret
1253
      string_after_replaced:
31 halyavin 1254
	lods	dword [esi]
157 heavyiron 1255
	stos	dword [edi]
1256
	mov	ecx,eax
1257
	call	move_data
1258
	jmp	process_after_replaced
1259
      brace_after_replaced:
31 halyavin 1260
	test	[value_type],80h
157 heavyiron 1261
	jz	process_after_replaced
1262
	mov	edx,edi
1263
	mov	ecx,[current_section]
1264
	sub	edx,ecx
1265
	sub	ecx,esi
1266
	rep	movs byte [edi],[esi]
1267
	mov	ecx,edi
1268
	sub	ecx,esi
1269
	mov	edi,ebp
1270
	call	move_data
1271
	lea	esi,[ebp+edx]
1272
	ret
1273
      symbol_after_replaced:
31 halyavin 1274
	mov	cl,[esi]
157 heavyiron 1275
	inc	esi
1276
	mov	ch,[value_type]
1277
	call	get_preprocessor_symbol
1278
	jnc	replace_symbolic_constant
1279
	movzx	ecx,byte [esi-1]
1280
	mov	al,1Ah
1281
	mov	ah,cl
1282
	stos	word [edi]
1283
	call	move_data
1284
	jmp	process_after_replaced
1285
process_macro_operators:
31 halyavin 1286
	xor	dl,dl
157 heavyiron 1287
	mov	ebp,edi
1288
      before_macro_operators:
31 halyavin 1289
	mov	edi,esi
157 heavyiron 1290
	lods	byte [esi]
1291
	cmp	al,'`'
1292
	je	symbol_conversion
1293
	cmp	al,'#'
1294
	je	concatenation
1295
	cmp	al,1Ah
1296
	je	symbol_before_macro_operators
1297
	cmp	al,3Bh
1298
	je	no_more_macro_operators
1299
	cmp	al,22h
1300
	je	string_before_macro_operators
1301
	xor	dl,dl
1302
	or	al,al
1303
	jnz	before_macro_operators
1304
	mov	edi,esi
1305
	ret
1306
      no_more_macro_operators:
31 halyavin 1307
	mov	edi,ebp
157 heavyiron 1308
	ret
1309
      symbol_before_macro_operators:
31 halyavin 1310
	mov	dl,1Ah
157 heavyiron 1311
	mov	ebx,esi
1312
	lods	byte [esi]
1313
	movzx	ecx,al
1314
	jecxz	symbol_before_macro_operators_ok
1315
	mov	edi,esi
1316
	cmp	byte [esi],'\'
1317
	je	escaped_symbol
1318
      symbol_before_macro_operators_ok:
31 halyavin 1319
	add	esi,ecx
157 heavyiron 1320
	jmp	before_macro_operators
1321
      string_before_macro_operators:
31 halyavin 1322
	mov	dl,22h
157 heavyiron 1323
	mov	ebx,esi
1324
	lods	dword [esi]
1325
	add	esi,eax
1326
	jmp	before_macro_operators
1327
      escaped_symbol:
31 halyavin 1328
	dec	byte [edi-1]
157 heavyiron 1329
	dec	ecx
1330
	inc	esi
1331
	cmp	ecx,1
1332
	rep	movs byte [edi],[esi]
1333
	jne	after_macro_operators
1334
	mov	al,[esi-1]
1335
	mov	ecx,ebx
1336
	mov	ebx,characters
1337
	xlat	byte [ebx]
1338
	mov	ebx,ecx
1339
	or	al,al
1340
	jnz	after_macro_operators
1341
	sub	edi,3
1342
	mov	al,[esi-1]
1343
	stos	byte [edi]
1344
	xor	dl,dl
1345
	jmp	after_macro_operators
1346
      reduce_symbol_conversion:
109 heavyiron 1347
	inc	esi
157 heavyiron 1348
      symbol_conversion:
31 halyavin 1349
	mov	edx,esi
157 heavyiron 1350
	mov	al,[esi]
1351
	cmp	al,1Ah
1352
	jne	symbol_character_conversion
1353
	lods	word [esi]
1354
	movzx	ecx,ah
1355
	lea	ebx,[edi+3]
1356
	jecxz	convert_to_quoted_string
242 heavyiron 1357
	cmp	byte [esi],'\'
1358
	jne	convert_to_quoted_string
1359
	inc	esi
1360
	dec	ecx
1361
	dec	ebx
1362
	jmp	convert_to_quoted_string
157 heavyiron 1363
      symbol_character_conversion:
109 heavyiron 1364
	cmp	al,22h
157 heavyiron 1365
	je	after_macro_operators
1366
	cmp	al,'`'
1367
	je	reduce_symbol_conversion
1368
	lea	ebx,[edi+5]
1369
	xor	ecx,ecx
1370
	or	al,al
1371
	jz	convert_to_quoted_string
1372
	cmp	al,'#'
1373
	je	convert_to_quoted_string
1374
	inc	ecx
1375
      convert_to_quoted_string:
109 heavyiron 1376
	sub	ebx,edx
157 heavyiron 1377
	ja	shift_line_data
1378
	mov	al,22h
1379
	mov	dl,al
1380
	stos	byte [edi]
1381
	mov	ebx,edi
1382
	mov	eax,ecx
1383
	stos	dword [edi]
1384
	rep	movs byte [edi],[esi]
1385
	cmp	edi,esi
1386
	je	before_macro_operators
1387
	jmp	after_macro_operators
1388
      shift_line_data:
31 halyavin 1389
	push	ecx
157 heavyiron 1390
	mov	edx,esi
1391
	lea	esi,[ebp-1]
1392
	add	ebp,ebx
1393
	lea	edi,[ebp-1]
1394
	lea	ecx,[esi+1]
1395
	sub	ecx,edx
1396
	std
1397
	rep	movs byte [edi],[esi]
1398
	cld
1399
	pop	eax
1400
	sub	edi,3
1401
	mov	dl,22h
1402
	mov	[edi-1],dl
1403
	mov	ebx,edi
1404
	mov	[edi],eax
1405
	lea	esi,[edi+4+eax]
1406
	jmp	before_macro_operators
1407
      concatenation:
31 halyavin 1408
	cmp	dl,1Ah
157 heavyiron 1409
	je	symbol_concatenation
1410
	cmp	dl,22h
1411
	je	string_concatenation
1412
      no_concatenation:
31 halyavin 1413
	cmp	esi,edi
157 heavyiron 1414
	je	before_macro_operators
1415
	jmp	after_macro_operators
1416
      symbol_concatenation:
31 halyavin 1417
	cmp	byte [esi],1Ah
157 heavyiron 1418
	jne	no_concatenation
1419
	inc	esi
1420
	lods	byte [esi]
1421
	movzx	ecx,al
1422
	jecxz	do_symbol_concatenation
1423
	cmp	byte [esi],'\'
1424
	je	concatenate_escaped_symbol
242 heavyiron 1425
      do_symbol_concatenation:
31 halyavin 1426
	add	[ebx],cl
242 heavyiron 1427
	jc	name_too_long
157 heavyiron 1428
	rep	movs byte [edi],[esi]
1429
	jmp	after_macro_operators
1430
      concatenate_escaped_symbol:
242 heavyiron 1431
	inc	esi
1432
	dec	ecx
1433
	jz	do_symbol_concatenation
1434
	movzx	eax,byte [esi]
1435
	cmp	byte [characters+eax],0
1436
	jne	do_symbol_concatenation
1437
	sub	esi,3
1438
	jmp	no_concatenation
1439
      string_concatenation:
31 halyavin 1440
	cmp	byte [esi],22h
157 heavyiron 1441
	je	do_string_concatenation
1442
	cmp	byte [esi],'`'
1443
	jne	no_concatenation
1444
      concatenate_converted_symbol:
109 heavyiron 1445
	inc	esi
157 heavyiron 1446
	mov	al,[esi]
1447
	cmp	al,'`'
1448
	je	concatenate_converted_symbol
1449
	cmp	al,22h
1450
	je	do_string_concatenation
1451
	cmp	al,1Ah
1452
	jne	concatenate_converted_symbol_character
1453
	inc	esi
1454
	lods	byte [esi]
1455
	movzx	ecx,al
1456
	jecxz	finish_concatenating_converted_symbol
242 heavyiron 1457
	cmp	byte [esi],'\'
1458
	jne	finish_concatenating_converted_symbol
1459
	inc	esi
1460
	dec	ecx
1461
      finish_concatenating_converted_symbol:
1462
	add	[ebx],ecx
157 heavyiron 1463
	rep	movs byte [edi],[esi]
1464
	jmp	after_macro_operators
1465
      concatenate_converted_symbol_character:
109 heavyiron 1466
	or	al,al
157 heavyiron 1467
	jz	after_macro_operators
1468
	cmp	al,'#'
1469
	je	after_macro_operators
1470
	inc	dword [ebx]
1471
	movs	byte [edi],[esi]
1472
	jmp	after_macro_operators
1473
      do_string_concatenation:
31 halyavin 1474
	inc	esi
157 heavyiron 1475
	lods	dword [esi]
1476
	mov	ecx,eax
1477
	add	[ebx],eax
1478
	rep	movs byte [edi],[esi]
1479
      after_macro_operators:
31 halyavin 1480
	lods	byte [esi]
157 heavyiron 1481
	cmp	al,'`'
1482
	je	symbol_conversion
1483
	cmp	al,'#'
1484
	je	concatenation
1485
	stos	byte [edi]
1486
	cmp	al,1Ah
1487
	je	symbol_after_macro_operators
1488
	cmp	al,3Bh
1489
	je	no_more_macro_operators
1490
	cmp	al,22h
1491
	je	string_after_macro_operators
1492
	xor	dl,dl
1493
	or	al,al
1494
	jnz	after_macro_operators
1495
	ret
1496
      symbol_after_macro_operators:
31 halyavin 1497
	mov	dl,1Ah
157 heavyiron 1498
	mov	ebx,edi
1499
	lods	byte [esi]
1500
	stos	byte [edi]
1501
	movzx	ecx,al
1502
	jecxz	symbol_after_macro_operatorss_ok
1503
	cmp	byte [esi],'\'
1504
	je	escaped_symbol
1505
      symbol_after_macro_operatorss_ok:
31 halyavin 1506
	rep	movs byte [edi],[esi]
157 heavyiron 1507
	jmp	after_macro_operators
1508
      string_after_macro_operators:
31 halyavin 1509
	mov	dl,22h
157 heavyiron 1510
	mov	ebx,edi
1511
	lods	dword [esi]
1512
	stos	dword [edi]
1513
	mov	ecx,eax
1514
	rep	movs byte [edi],[esi]
1515
	jmp	after_macro_operators
1516
31 halyavin 1517
 
1518
	push	[free_additional_memory]
157 heavyiron 1519
	push	[macro_symbols]
1520
	mov	[macro_symbols],0
1521
	push	[counter_limit]
1522
	push	dword [edx+4]
1523
	mov	dword [edx+4],1
1524
	push	edx
1525
	mov	ebx,esi
1526
	mov	esi,[edx+8]
1527
	mov	eax,[edx+12]
1528
	mov	[macro_line],eax
1529
	mov	[counter_limit],0
1530
      process_macro_arguments:
31 halyavin 1531
	mov	al,[esi]
157 heavyiron 1532
	or	al,al
1533
	jz	arguments_end
1534
	cmp	al,'{'
1535
	je	arguments_end
1536
	inc	esi
1537
	cmp	al,'['
1538
	jne	get_macro_arguments
1539
	mov	ebp,esi
1540
	inc	esi
1541
	inc	[counter_limit]
1542
      get_macro_arguments:
31 halyavin 1543
	call	get_macro_argument
157 heavyiron 1544
	lods	byte [esi]
1545
	cmp	al,','
1546
	je	next_argument
1547
	cmp	al,']'
1548
	je	next_arguments_group
1549
	dec	esi
1550
	jmp	arguments_end
1551
      next_argument:
31 halyavin 1552
	cmp	byte [ebx],','
157 heavyiron 1553
	jne	process_macro_arguments
1554
	inc	ebx
1555
	jmp	process_macro_arguments
1556
      next_arguments_group:
31 halyavin 1557
	cmp	byte [ebx],','
157 heavyiron 1558
	jne	arguments_end
1559
	inc	ebx
1560
	inc	[counter_limit]
1561
	mov	esi,ebp
1562
	jmp	process_macro_arguments
1563
      get_macro_argument:
31 halyavin 1564
	lods	byte [esi]
157 heavyiron 1565
	movzx	ecx,al
1566
	mov	eax,[counter_limit]
1567
	call	add_macro_symbol
1568
	add	esi,ecx
1569
	xchg	esi,ebx
1570
	mov	[edx+12],esi
1571
	cmp	byte [esi],'<'
1572
	jne	simple_argument
1573
	inc	esi
1574
	mov	[edx+12],esi
1575
	mov	ecx,1
1576
      enclosed_argument:
31 halyavin 1577
	lods	byte [esi]
157 heavyiron 1578
	or	al,al
1579
	jz	invalid_macro_arguments
1580
	cmp	al,1Ah
1581
	je	enclosed_symbol
1582
	cmp	al,22h
1583
	je	enclosed_string
1584
	cmp	al,'>'
1585
	je	enclosed_argument_end
1586
	cmp	al,'<'
1587
	jne	enclosed_argument
1588
	inc	ecx
1589
	jmp	enclosed_argument
1590
      enclosed_symbol:
31 halyavin 1591
	movzx	eax,byte [esi]
157 heavyiron 1592
	inc	esi
1593
	add	esi,eax
1594
	jmp	enclosed_argument
1595
      enclosed_string:
31 halyavin 1596
	lods	dword [esi]
157 heavyiron 1597
	add	esi,eax
1598
	jmp	enclosed_argument
1599
      enclosed_argument_end:
31 halyavin 1600
	loop	enclosed_argument
157 heavyiron 1601
	mov	al,[esi]
1602
	or	al,al
1603
	jz	enclosed_argument_ok
1604
	cmp	al,','
1605
	jne	invalid_macro_arguments
1606
      enclosed_argument_ok:
31 halyavin 1607
	mov	eax,esi
157 heavyiron 1608
	sub	eax,[edx+12]
1609
	dec	eax
1610
	or	eax,80000000h
1611
	mov	[edx+8],eax
1612
	jmp	argument_value_ok
1613
      simple_argument:
31 halyavin 1614
	lods	byte [esi]
157 heavyiron 1615
	or	al,al
1616
	jz	argument_value_end
1617
	cmp	al,','
1618
	je	argument_value_end
1619
	cmp	al,22h
1620
	je	argument_string
1621
	cmp	al,1Ah
1622
	jne	simple_argument
1623
	movzx	eax,byte [esi]
1624
	inc	esi
1625
	add	esi,eax
1626
	jmp	simple_argument
1627
      argument_string:
31 halyavin 1628
	lods	dword [esi]
157 heavyiron 1629
	add	esi,eax
1630
	jmp	simple_argument
1631
      argument_value_end:
31 halyavin 1632
	dec	esi
157 heavyiron 1633
	mov	eax,esi
1634
	sub	eax,[edx+12]
1635
	mov	[edx+8],eax
1636
      argument_value_ok:
31 halyavin 1637
	xchg	esi,ebx
157 heavyiron 1638
	cmp	byte [esi],'*'
1639
	jne	macro_argument_ok
1640
	cmp	dword [edx+8],0
1641
	je	invalid_macro_arguments
1642
	inc	esi
1643
      macro_argument_ok:
31 halyavin 1644
	ret
157 heavyiron 1645
      arguments_end:
31 halyavin 1646
	cmp	byte [ebx],0
157 heavyiron 1647
	jne	invalid_macro_arguments
1648
	mov	eax,[esp+4]
1649
	dec	eax
1650
	call	process_macro
1651
	pop	edx
1652
	pop	dword [edx+4]
1653
	pop	[counter_limit]
1654
	pop	[macro_symbols]
1655
	pop	[free_additional_memory]
1656
	jmp	line_preprocessed
1657
use_instant_macro:
31 halyavin 1658
	push	edi [current_line] esi
157 heavyiron 1659
	mov	eax,[error_line]
1660
	mov	[current_line],eax
1661
	mov	[macro_line],eax
1662
	mov	esi,[instant_macro_start]
1663
	cmp	[base_code],10h
1664
	jae	do_match
1665
	cmp	[base_code],0
1666
	jne	do_irp
1667
	call	get_number
1668
	jc	invalid_value
1669
	or	ebp,ebp
1670
	jnz	invalid_value
1671
	cmp	dword [edi+4],0
1672
	jne	value_out_of_range
1673
	mov	eax,[edi]
1674
872 heavyiron 1675
 
157 heavyiron 1676
	jae	value_out_of_range
1677
	push	[free_additional_memory]
1678
	push	[macro_symbols]
1679
	mov	[macro_symbols],0
1680
	push	[counter_limit]
1681
	mov	[struc_name],0
1682
	mov	[counter_limit],eax
1683
	lods	byte [esi]
1684
	or	al,al
1685
	jz	rept_counters_ok
1686
	cmp	al,'{'
1687
	je	rept_counters_ok
1688
	cmp	al,1Ah
1689
	jne	invalid_macro_arguments
1690
      add_rept_counter:
31 halyavin 1691
	lods	byte [esi]
157 heavyiron 1692
	movzx	ecx,al
1693
	xor	eax,eax
1694
	call	add_macro_symbol
1695
	add	esi,ecx
1696
	xor	eax,eax
1697
	mov	dword [edx+12],eax
1698
	inc	eax
1699
	mov	dword [edx+8],eax
1700
	lods	byte [esi]
1701
	cmp	al,':'
1702
	jne	rept_counter_added
1703
	push	edx
1704
	call	get_number
1705
	jc	invalid_value
1706
	or	ebp,ebp
1707
	jnz	invalid_value
1708
	cmp	dword [edi+4],0
1709
	jne	value_out_of_range
1710
	mov	eax,[edi]
1711
	mov	edx,eax
1712
	add	edx,[counter_limit]
1713
	jc	value_out_of_range
1714
	pop	edx
1715
	mov	dword [edx+8],eax
1716
	lods	byte [esi]
1717
      rept_counter_added:
31 halyavin 1718
	cmp	al,','
157 heavyiron 1719
	jne	rept_counters_ok
1720
	lods	byte [esi]
1721
	cmp	al,1Ah
1722
	jne	invalid_macro_arguments
1723
	jmp	add_rept_counter
1724
      rept_counters_ok:
31 halyavin 1725
	dec	esi
157 heavyiron 1726
	cmp	[counter_limit],0
872 heavyiron 1727
	je	instant_macro_finish
1728
      instant_macro_parameters_ok:
31 halyavin 1729
	xor	eax,eax
157 heavyiron 1730
	call	process_macro
1731
      instant_macro_finish:
872 heavyiron 1732
	pop	[counter_limit]
157 heavyiron 1733
	pop	[macro_symbols]
1734
	pop	[free_additional_memory]
1735
      instant_macro_done:
31 halyavin 1736
	pop	ebx esi edx
157 heavyiron 1737
	cmp	byte [ebx],0
1738
	je	line_preprocessed
1739
	mov	[current_line],edi
1740
	mov	ecx,4
1741
	rep	movs dword [edi],[esi]
1742
	test	[macro_status],0Fh
1743
	jz	instant_macro_attached_line
1744
	mov	ax,3Bh
1745
	stos	word [edi]
1746
      instant_macro_attached_line:
31 halyavin 1747
	mov	esi,ebx
157 heavyiron 1748
	sub	edx,ebx
1749
	mov	ecx,edx
1750
	call	move_data
1751
	jmp	initial_preprocessing_ok
1752
do_irp:
31 halyavin 1753
	cmp	byte [esi],1Ah
157 heavyiron 1754
	jne	invalid_macro_arguments
1755
	movzx	eax,byte [esi+1]
1756
	lea	esi,[esi+2+eax]
1757
	lods	byte [esi]
1758
	cmp	[base_code],1
1759
	ja	irps_name_ok
1760
	cmp	al,'*'
1761
	jne	irp_name_ok
1762
	lods	byte [esi]
1763
      irp_name_ok:
31 halyavin 1764
	cmp	al,','
157 heavyiron 1765
	jne	invalid_macro_arguments
1766
	jmp	irp_parameters_start
1767
      irps_name_ok:
31 halyavin 1768
	cmp	al,','
157 heavyiron 1769
	jne	invalid_macro_arguments
1770
	mov	al,[esi]
1771
	or	al,al
1772
	jz	instant_macro_done
1773
	cmp	al,'{'
1774
	je	instant_macro_done
1775
      irp_parameters_start:
31 halyavin 1776
	xor	eax,eax
157 heavyiron 1777
	push	[free_additional_memory]
1778
	push	[macro_symbols]
1779
	mov	[macro_symbols],eax
1780
	push	[counter_limit]
1781
	mov	[counter_limit],eax
1782
	mov	[struc_name],eax
1783
	mov	ebx,esi
1784
	cmp	[base_code],1
1785
	ja	get_irps_parameter
1786
	mov	edx,[parameters_end]
1787
	mov	al,[edx]
1788
	push	eax
1789
	mov	byte [edx],0
1790
      get_irp_parameter:
31 halyavin 1791
	inc	[counter_limit]
157 heavyiron 1792
	mov	esi,[instant_macro_start]
1793
	inc	esi
1794
	call	get_macro_argument
1795
	cmp	byte [ebx],','
1796
	jne	irp_parameters_end
1797
	inc	ebx
1798
	jmp	get_irp_parameter
1799
      irp_parameters_end:
31 halyavin 1800
	mov	esi,ebx
157 heavyiron 1801
	pop	eax
1802
	mov	[esi],al
1803
	jmp	instant_macro_parameters_ok
1804
      get_irps_parameter:
31 halyavin 1805
	mov	esi,[instant_macro_start]
157 heavyiron 1806
	inc	esi
1807
	lods	byte [esi]
1808
	movzx	ecx,al
1809
	inc	[counter_limit]
1810
	mov	eax,[counter_limit]
1811
	call	add_macro_symbol
1812
	mov	[edx+12],ebx
1813
	cmp	byte [ebx],1Ah
1814
	je	irps_symbol
1815
	cmp	byte [ebx],22h
1816
	je	irps_quoted_string
1817
	mov	eax,1
1818
	jmp	irps_parameter_ok
1819
      irps_quoted_string:
31 halyavin 1820
	mov	eax,[ebx+1]
157 heavyiron 1821
	add	eax,1+4
1822
	jmp	irps_parameter_ok
1823
      irps_symbol:
31 halyavin 1824
	movzx	eax,byte [ebx+1]
157 heavyiron 1825
	add	eax,1+1
1826
      irps_parameter_ok:
31 halyavin 1827
	mov	[edx+8],eax
157 heavyiron 1828
	add	ebx,eax
1829
	cmp	byte [ebx],0
1830
	je	irps_parameters_end
1831
	cmp	byte [ebx],'{'
1832
	jne	get_irps_parameter
1833
      irps_parameters_end:
31 halyavin 1834
	mov	esi,ebx
157 heavyiron 1835
	jmp	instant_macro_parameters_ok
1836
do_match:
31 halyavin 1837
	mov	ebx,esi
157 heavyiron 1838
	call	skip_pattern
1839
	call	exact_match
1840
	mov	edx,edi
1841
	mov	al,[ebx]
1842
	cmp	al,1Ah
1843
	je	free_match
1844
	cmp	al,','
1845
	jne	instant_macro_done
1846
	cmp	esi,[parameters_end]
1847
	je	matched_pattern
1848
	jmp	instant_macro_done
1849
      free_match:
31 halyavin 1850
	add	edx,12
157 heavyiron 1851
	cmp	edx,[memory_end]
1852
	ja	out_of_memory
1853
	mov	[edx-12],ebx
1854
	mov	[edx-8],esi
1855
	call	skip_match_element
1856
	jc	try_different_matching
1857
	mov	[edx-4],esi
1858
	movzx	eax,byte [ebx+1]
1859
	lea	ebx,[ebx+2+eax]
1860
	cmp	byte [ebx],1Ah
1861
	je	free_match
1862
      find_exact_match:
31 halyavin 1863
	call	exact_match
157 heavyiron 1864
	cmp	esi,[parameters_end]
1865
	je	end_matching
1866
	cmp	byte [ebx],1Ah
1867
	je	free_match
1868
	mov	ebx,[edx-12]
1869
	movzx	eax,byte [ebx+1]
1870
	lea	ebx,[ebx+2+eax]
1871
	mov	esi,[edx-4]
1872
	jmp	match_more_elements
1873
      try_different_matching:
31 halyavin 1874
	sub	edx,12
157 heavyiron 1875
	cmp	edx,edi
1876
	je	instant_macro_done
1877
	mov	ebx,[edx-12]
1878
	movzx	eax,byte [ebx+1]
1879
	lea	ebx,[ebx+2+eax]
1880
	cmp	byte [ebx],1Ah
1881
	je	try_different_matching
1882
	mov	esi,[edx-4]
1883
      match_more_elements:
31 halyavin 1884
	call	skip_match_element
157 heavyiron 1885
	jc	try_different_matching
1886
	mov	[edx-4],esi
1887
	jmp	find_exact_match
1888
      skip_match_element:
31 halyavin 1889
	cmp	esi,[parameters_end]
157 heavyiron 1890
	je	cannot_match
1891
	mov	al,[esi]
1892
	cmp	al,1Ah
1893
	je	skip_match_symbol
1894
	cmp	al,22h
1895
	je	skip_match_quoted_string
1896
	add	esi,1
1897
	ret
1898
      skip_match_quoted_string:
31 halyavin 1899
	mov	eax,[esi+1]
157 heavyiron 1900
	add	esi,5
1901
	jmp	skip_match_ok
1902
      skip_match_symbol:
31 halyavin 1903
	movzx	eax,byte [esi+1]
157 heavyiron 1904
	add	esi,2
1905
      skip_match_ok:
31 halyavin 1906
	add	esi,eax
157 heavyiron 1907
	ret
1908
      cannot_match:
31 halyavin 1909
	stc
157 heavyiron 1910
	ret
1911
      exact_match:
31 halyavin 1912
	cmp	esi,[parameters_end]
157 heavyiron 1913
	je	exact_match_complete
1914
	mov	ah,[esi]
1915
	mov	al,[ebx]
1916
	cmp	al,','
1917
	je	exact_match_complete
1918
	cmp	al,1Ah
1919
	je	exact_match_complete
1920
	cmp	al,'='
1921
	je	match_verbatim
1922
	call	match_elements
1923
	je	exact_match
1924
      exact_match_complete:
31 halyavin 1925
	ret
157 heavyiron 1926
      match_verbatim:
31 halyavin 1927
	inc	ebx
157 heavyiron 1928
	call	match_elements
1929
	je	exact_match
1930
	dec	ebx
1931
	ret
1932
      match_elements:
31 halyavin 1933
	mov	al,[ebx]
157 heavyiron 1934
	cmp	al,1Ah
1935
	je	match_symbols
1936
	cmp	al,22h
1937
	je	match_quoted_strings
1938
	cmp	al,ah
1939
	je	symbol_characters_matched
1940
	ret
1941
      symbol_characters_matched:
31 halyavin 1942
	lea	ebx,[ebx+1]
157 heavyiron 1943
	lea	esi,[esi+1]
1944
	ret
1945
      match_quoted_strings:
31 halyavin 1946
	mov	ecx,[ebx+1]
157 heavyiron 1947
	add	ecx,5
1948
	jmp	compare_elements
1949
      match_symbols:
31 halyavin 1950
	movzx	ecx,byte [ebx+1]
157 heavyiron 1951
	add	ecx,2
1952
      compare_elements:
31 halyavin 1953
	mov	eax,esi
157 heavyiron 1954
	mov	ebp,edi
1955
	mov	edi,ebx
1956
	repe	cmps byte [esi],[edi]
1957
	jne	elements_mismatch
1958
	mov	ebx,edi
1959
	mov	edi,ebp
1960
	ret
1961
      elements_mismatch:
31 halyavin 1962
	mov	esi,eax
157 heavyiron 1963
	mov	edi,ebp
1964
	ret
1965
      end_matching:
31 halyavin 1966
	cmp	byte [ebx],','
157 heavyiron 1967
	jne	instant_macro_done
1968
      matched_pattern:
31 halyavin 1969
	xor	eax,eax
157 heavyiron 1970
	push	[free_additional_memory]
1971
	push	[macro_symbols]
1972
	mov	[macro_symbols],eax
1973
	push	[counter_limit]
1974
	mov	[counter_limit],eax
1975
	mov	[struc_name],eax
1976
	push	esi edi edx
1977
      add_matched_symbol:
31 halyavin 1978
	cmp	edi,[esp]
157 heavyiron 1979
	je	matched_symbols_ok
1980
	mov	esi,[edi]
1981
	inc	esi
1982
	lods	byte [esi]
1983
	movzx	ecx,al
1984
	xor	eax,eax
1985
	call	add_macro_symbol
1986
	mov	eax,[edi+4]
1987
	mov	dword [edx+12],eax
1988
	mov	ecx,[edi+8]
1989
	sub	ecx,eax
1990
	mov	dword [edx+8],ecx
1991
	add	edi,12
1992
	jmp	add_matched_symbol
1993
      matched_symbols_ok:
31 halyavin 1994
	pop	edx edi esi
157 heavyiron 1995
	jmp	instant_macro_parameters_ok
1996
31 halyavin 1997
 
1998
	push	dword [macro_status]
157 heavyiron 1999
	or	[macro_status],10h
2000
	push	[counter]
2001
	push	[macro_block]
2002
	push	[macro_block_line]
2003
	push	[macro_block_line_number]
2004
	push	[struc_label]
2005
	push	[struc_name]
2006
	push	eax
2007
	push	[current_line]
2008
	lods	byte [esi]
2009
	cmp	al,'{'
2010
	je	macro_instructions_start
2011
	or	al,al
2012
	jnz	unexpected_characters
2013
      find_macro_instructions:
31 halyavin 2014
	mov	[macro_line],esi
157 heavyiron 2015
	add	esi,16+2
2016
	lods	byte [esi]
2017
	or	al,al
2018
	jz	find_macro_instructions
2019
	cmp	al,'{'
2020
	je	macro_instructions_start
2021
	cmp	al,3Bh
2022
	jne	unexpected_characters
2023
	call	skip_foreign_symbol
2024
	jmp	find_macro_instructions
2025
      macro_instructions_start:
31 halyavin 2026
	mov	ecx,80000000h
157 heavyiron 2027
	mov	[macro_block],esi
2028
	mov	eax,[macro_line]
2029
	mov	[macro_block_line],eax
2030
	mov	[macro_block_line_number],ecx
2031
	xor	eax,eax
2032
	mov	[counter],eax
2033
	cmp	[counter_limit],eax
2034
	je	process_macro_line
2035
	inc	[counter]
2036
      process_macro_line:
31 halyavin 2037
	mov	[current_line],edi
157 heavyiron 2038
	lea	eax,[edi+10h]
2039
	cmp	eax,[memory_end]
2040
	jae	out_of_memory
2041
	mov	eax,[esp+4]
2042
	or	eax,eax
2043
	jz	instant_macro_line_header
2044
	stos	dword [edi]
2045
	mov	eax,ecx
2046
	stos	dword [edi]
2047
	mov	eax,[esp]
2048
	stos	dword [edi]
2049
	mov	eax,[macro_line]
2050
	stos	dword [edi]
2051
	jmp	macro_line_header_ok
2052
      instant_macro_line_header:
31 halyavin 2053
	mov	eax,[macro_line]
992 heavyiron 2054
	add	eax,16+1
2055
	stos	dword [edi]
157 heavyiron 2056
	mov	eax,ecx
992 heavyiron 2057
	stos	dword [edi]
157 heavyiron 2058
	mov	eax,[macro_line]
992 heavyiron 2059
	stos	dword [edi]
157 heavyiron 2060
	stos	dword [edi]
2061
      macro_line_header_ok:
31 halyavin 2062
	or	[macro_status],20h
157 heavyiron 2063
	push	ebx ecx
2064
	test	[macro_status],0Fh
2065
	jz	process_macro_line_element
2066
	mov	ax,3Bh
2067
	stos	word [edi]
2068
      process_macro_line_element:
31 halyavin 2069
	lea	eax,[edi+100h]
157 heavyiron 2070
	cmp	eax,[memory_end]
2071
	jae	out_of_memory
2072
	lods	byte [esi]
2073
	cmp	al,'}'
2074
	je	macro_line_processed
2075
	or	al,al
2076
	jz	macro_line_processed
2077
	cmp	al,1Ah
2078
	je	process_macro_symbol
2079
	cmp	al,3Bh
2080
	je	macro_foreign_line
2081
	and	[macro_status],not 20h
2082
	stos	byte [edi]
2083
	cmp	al,22h
2084
	jne	process_macro_line_element
2085
      copy_macro_string:
31 halyavin 2086
	mov	ecx,[esi]
157 heavyiron 2087
	add	ecx,4
2088
	call	move_data
2089
	jmp	process_macro_line_element
2090
      process_macro_symbol:
31 halyavin 2091
	push	esi edi
157 heavyiron 2092
	test	[macro_status],20h
2093
	jz	not_macro_directive
2094
	movzx	ecx,byte [esi]
2095
	inc	esi
2096
	mov	edi,macro_directives
2097
	call	get_directive
2098
	jnc	process_macro_directive
2099
	dec	esi
2100
	jmp	not_macro_directive
2101
      process_macro_directive:
31 halyavin 2102
	mov	edx,eax
157 heavyiron 2103
	pop	edi eax
2104
	mov	byte [edi],0
2105
	inc	edi
2106
	pop	ecx ebx
2107
	jmp	near edx
2108
      not_macro_directive:
31 halyavin 2109
	and	[macro_status],not 20h
157 heavyiron 2110
	movzx	ecx,byte [esi]
2111
	inc	esi
2112
	mov	eax,[counter]
2113
	call	get_macro_symbol
2114
	jnc	group_macro_symbol
2115
	xor	eax,eax
2116
	cmp	[counter],eax
2117
	je	multiple_macro_symbol_values
2118
	call	get_macro_symbol
2119
	jc	not_macro_symbol
2120
      replace_macro_symbol:
31 halyavin 2121
	pop	edi eax
157 heavyiron 2122
	mov	ecx,[edx+8]
2123
	and	ecx,not 80000000h
2124
	mov	edx,[edx+12]
2125
	or	edx,edx
2126
	jz	replace_macro_counter
2127
	xchg	esi,edx
2128
	call	move_data
2129
	mov	esi,edx
2130
	jmp	process_macro_line_element
2131
      group_macro_symbol:
31 halyavin 2132
	xor	eax,eax
157 heavyiron 2133
	cmp	[counter],eax
2134
	je	replace_macro_symbol
2135
	push	esi edx
2136
	sub	esi,ecx
2137
	call	get_macro_symbol
2138
	mov	ebx,edx
2139
	pop	edx esi
2140
	jc	replace_macro_symbol
2141
	cmp	edx,ebx
2142
	ja	replace_macro_symbol
2143
	mov	edx,ebx
2144
	jmp	replace_macro_symbol
2145
      multiple_macro_symbol_values:
31 halyavin 2146
	inc	eax
157 heavyiron 2147
	push	eax
2148
	call	get_macro_symbol
2149
	pop	eax
2150
	jc	not_macro_symbol
2151
	pop	edi
2152
	push	ecx
2153
	mov	ecx,[edx+8]
2154
	mov	edx,[edx+12]
2155
	xchg	esi,edx
2156
	btr	ecx,31
2157
	jc	enclose_macro_symbol_value
2158
	rep	movs byte [edi],[esi]
2159
	jmp	macro_symbol_value_ok
2160
      enclose_macro_symbol_value:
31 halyavin 2161
	mov	byte [edi],'<'
157 heavyiron 2162
	inc	edi
2163
	rep	movs byte [edi],[esi]
2164
	mov	byte [edi],'>'
2165
	inc	edi
2166
      macro_symbol_value_ok:
31 halyavin 2167
	cmp	eax,[counter_limit]
157 heavyiron 2168
	je	multiple_macro_symbol_values_ok
2169
	mov	byte [edi],','
2170
	inc	edi
2171
	mov	esi,edx
2172
	pop	ecx
2173
	push	edi
2174
	sub	esi,ecx
2175
	jmp	multiple_macro_symbol_values
2176
      multiple_macro_symbol_values_ok:
31 halyavin 2177
	pop	ecx eax
157 heavyiron 2178
	mov	esi,edx
2179
	jmp	process_macro_line_element
2180
      replace_macro_counter:
31 halyavin 2181
	mov	eax,[counter]
157 heavyiron 2182
	and	eax,not 80000000h
2183
	jz	group_macro_counter
2184
	add	ecx,eax
2185
	dec	ecx
2186
	call	store_number_symbol
2187
	jmp	process_macro_line_element
2188
      group_macro_counter:
31 halyavin 2189
	mov	edx,ecx
157 heavyiron 2190
	xor	ecx,ecx
2191
      multiple_macro_counter_values:
31 halyavin 2192
	push	ecx edx
157 heavyiron 2193
	add	ecx,edx
2194
	call	store_number_symbol
2195
	pop	edx ecx
2196
	inc	ecx
2197
	cmp	ecx,[counter_limit]
2198
	je	process_macro_line_element
2199
	mov	byte [edi],','
2200
	inc	edi
2201
	jmp	multiple_macro_counter_values
2202
      store_number_symbol:
31 halyavin 2203
	mov	ax,1Ah
157 heavyiron 2204
	stos	word [edi]
2205
	push	edi
2206
	mov	eax,ecx
2207
	mov	ecx,1000000000
2208
	xor	edx,edx
2209
	xor	bl,bl
2210
      store_number_digits:
31 halyavin 2211
	div	ecx
157 heavyiron 2212
	push	edx
2213
	or	bl,bl
2214
	jnz	store_number_digit
2215
	cmp	ecx,1
2216
	je	store_number_digit
2217
	or	al,al
2218
	jz	number_digit_ok
2219
	not	bl
2220
      store_number_digit:
31 halyavin 2221
	add	al,30h
157 heavyiron 2222
	stos	byte [edi]
2223
      number_digit_ok:
31 halyavin 2224
	mov	eax,ecx
157 heavyiron 2225
	xor	edx,edx
2226
	mov	ecx,10
2227
	div	ecx
2228
	mov	ecx,eax
2229
	pop	eax
2230
	or	ecx,ecx
2231
	jnz	store_number_digits
2232
	pop	ebx
2233
	mov	eax,edi
2234
	sub	eax,ebx
2235
	mov	[ebx-1],al
2236
	ret
2237
      not_macro_symbol:
31 halyavin 2238
	pop	edi esi
157 heavyiron 2239
	mov	al,1Ah
2240
	stos	byte [edi]
2241
	mov	al,[esi]
2242
	inc	esi
2243
	stos	byte [edi]
2244
	cmp	byte [esi],'.'
2245
	jne	copy_raw_symbol
2246
	mov	ebx,[esp+8+8]
2247
	or	ebx,ebx
2248
	jz	copy_raw_symbol
2249
	cmp	al,1
2250
	je	copy_struc_name
2251
	xchg	esi,ebx
2252
	movzx	ecx,byte [esi-1]
2253
	add	[edi-1],cl
2254
	jc	name_too_long
2255
	rep	movs byte [edi],[esi]
2256
	xchg	esi,ebx
2257
      copy_raw_symbol:
31 halyavin 2258
	movzx	ecx,al
157 heavyiron 2259
	rep	movs byte [edi],[esi]
2260
	jmp	process_macro_line_element
2261
      copy_struc_name:
31 halyavin 2262
	inc	esi
157 heavyiron 2263
	xchg	esi,ebx
2264
	movzx	ecx,byte [esi-1]
2265
	mov	[edi-1],cl
2266
	rep	movs byte [edi],[esi]
2267
	xchg	esi,ebx
2268
	mov	eax,[esp+8+12]
2269
	cmp	byte [eax],3Bh
2270
	je	process_macro_line_element
2271
	cmp	byte [eax],1Ah
2272
	jne	disable_replaced_struc_name
2273
	mov	byte [eax],3Bh
2274
	jmp	process_macro_line_element
2275
      disable_replaced_struc_name:
31 halyavin 2276
	mov	ebx,[esp+8+8]
157 heavyiron 2277
	push	esi edi
2278
	lea	edi,[ebx-3]
2279
	lea	esi,[edi-2]
2280
	lea	ecx,[esi+1]
2281
	sub	ecx,eax
2282
	std
2283
	rep	movs byte [edi],[esi]
2284
	cld
2285
	mov	word [eax],3Bh
2286
	pop	edi esi
2287
	jmp	process_macro_line_element
2288
      skip_foreign_symbol:
31 halyavin 2289
	lods	byte [esi]
157 heavyiron 2290
	movzx	eax,al
2291
	add	esi,eax
2292
      skip_foreign_line:
31 halyavin 2293
	lods	byte [esi]
157 heavyiron 2294
	cmp	al,1Ah
2295
	je	skip_foreign_symbol
2296
	cmp	al,3Bh
2297
	je	skip_foreign_symbol
2298
	cmp	al,22h
2299
	je	skip_foreign_string
2300
	or	al,al
2301
	jnz	skip_foreign_line
2302
	ret
2303
      skip_foreign_string:
31 halyavin 2304
	lods	dword [esi]
157 heavyiron 2305
	add	esi,eax
2306
	jmp	skip_foreign_line
2307
      macro_foreign_line:
31 halyavin 2308
	call	skip_foreign_symbol
157 heavyiron 2309
      macro_line_processed:
31 halyavin 2310
	mov	byte [edi],0
157 heavyiron 2311
	inc	edi
2312
	push	eax
2313
	call	preprocess_line
2314
	pop	eax
2315
	pop	ecx ebx
2316
	cmp	al,'}'
2317
	je	macro_block_processed
2318
      process_next_line:
31 halyavin 2319
	inc	ecx
157 heavyiron 2320
	mov	[macro_line],esi
2321
	add	esi,16+2
2322
	jmp	process_macro_line
2323
      macro_block_processed:
31 halyavin 2324
	call	close_macro_block
157 heavyiron 2325
	jc	process_macro_line
2326
	pop	[current_line]
2327
	add	esp,12
2328
	pop	[macro_block_line_number]
2329
	pop	[macro_block_line]
2330
	pop	[macro_block]
2331
	pop	[counter]
2332
	pop	eax
2333
	and	al,0F0h
2334
	and	[macro_status],0Fh
2335
	or	[macro_status],al
2336
	ret
2337
31 halyavin 2338
 
2339
	lods	byte [esi]
157 heavyiron 2340
	cmp	al,1Ah
2341
	jne	invalid_argument
2342
	mov	byte [edi-1],3Bh
2343
	xor	al,al
2344
	stos	byte [edi]
2345
      make_local_symbol:
31 halyavin 2346
	push	ecx
157 heavyiron 2347
	lods	byte [esi]
2348
	movzx	ecx,al
2349
	mov	eax,[counter]
2350
	call	add_macro_symbol
2351
	mov	[edx+12],edi
2352
	movzx	eax,[locals_counter]
2353
	add	eax,ecx
2354
	inc	eax
2355
	cmp	eax,100h
2356
	jae	name_too_long
2357
	lea	ebp,[edi+2+eax]
2358
	cmp	ebp,[memory_end]
2359
	jae	out_of_memory
2360
	mov	ah,al
2361
	mov	al,1Ah
2362
	stos	word [edi]
2363
	rep	movs byte [edi],[esi]
2364
	mov	al,'?'
2365
	stos	byte [edi]
2366
	push	esi
2367
	mov	esi,locals_counter+1
2368
	movzx	ecx,[locals_counter]
2369
	rep	movs byte [edi],[esi]
2370
	pop	esi
2371
	mov	eax,edi
2372
	sub	eax,[edx+12]
2373
	mov	[edx+8],eax
2374
	xor	al,al
2375
	stos	byte [edi]
2376
	mov	eax,locals_counter
2377
	movzx	ecx,byte [eax]
2378
      counter_loop:
31 halyavin 2379
	inc	byte [eax+ecx]
157 heavyiron 2380
	cmp	byte [eax+ecx],'9'+1
692 heavyiron 2381
	jb	counter_ok
157 heavyiron 2382
	jne	letter_digit
2383
	mov	byte [eax+ecx],'A'
2384
	jmp	counter_ok
2385
      letter_digit:
31 halyavin 2386
	cmp	byte [eax+ecx],'Z'+1
692 heavyiron 2387
	jb	counter_ok
2388
	jne	small_letter_digit
2389
	mov	byte [eax+ecx],'a'
2390
	jmp	counter_ok
2391
      small_letter_digit:
2392
	cmp	byte [eax+ecx],'z'+1
2393
	jb	counter_ok
2394
	mov	byte [eax+ecx],'0'
157 heavyiron 2395
	loop	counter_loop
2396
	inc	byte [eax]
692 heavyiron 2397
	movzx	ecx,byte [eax]
2398
	mov	byte [eax+ecx],'0'
2399
      counter_ok:
31 halyavin 2400
	pop	ecx
157 heavyiron 2401
	lods	byte [esi]
2402
	cmp	al,'}'
2403
	je	macro_block_processed
2404
	or	al,al
2405
	jz	process_next_line
2406
	cmp	al,','
2407
	jne	extra_characters_on_line
2408
	dec	edi
2409
	lods	byte [esi]
2410
	cmp	al,1Ah
2411
	je	make_local_symbol
2412
	jmp	invalid_argument
2413
common_block:
31 halyavin 2414
	call	close_macro_block
157 heavyiron 2415
	jc	process_macro_line
2416
	mov	[counter],0
2417
	jmp	new_macro_block
2418
forward_block:
31 halyavin 2419
	cmp	[counter_limit],0
157 heavyiron 2420
	je	common_block
2421
	call	close_macro_block
2422
	jc	process_macro_line
2423
	mov	[counter],1
2424
	jmp	new_macro_block
2425
reverse_block:
31 halyavin 2426
	cmp	[counter_limit],0
157 heavyiron 2427
	je	common_block
2428
	call	close_macro_block
2429
	jc	process_macro_line
2430
	mov	eax,[counter_limit]
2431
	or	eax,80000000h
2432
	mov	[counter],eax
2433
      new_macro_block:
31 halyavin 2434
	mov	[macro_block],esi
157 heavyiron 2435
	mov	eax,[macro_line]
2436
	mov	[macro_block_line],eax
2437
	mov	[macro_block_line_number],ecx
2438
	jmp	process_macro_line
2439
close_macro_block:
31 halyavin 2440
	cmp	[counter],0
157 heavyiron 2441
	je	block_closed
2442
	jl	reverse_counter
2443
	mov	eax,[counter]
2444
	cmp	eax,[counter_limit]
2445
	je	block_closed
2446
	inc	[counter]
2447
	jmp	continue_block
2448
      reverse_counter:
31 halyavin 2449
	mov	eax,[counter]
157 heavyiron 2450
	dec	eax
2451
	cmp	eax,80000000h
2452
	je	block_closed
2453
	mov	[counter],eax
2454
      continue_block:
31 halyavin 2455
	mov	esi,[macro_block]
157 heavyiron 2456
	mov	eax,[macro_block_line]
2457
	mov	[macro_line],eax
2458
	mov	ecx,[macro_block_line_number]
2459
	stc
2460
	ret
2461
      block_closed:
31 halyavin 2462
	clc
157 heavyiron 2463
	ret
2464
get_macro_symbol:
31 halyavin 2465
	push	ecx
157 heavyiron 2466
	call	find_macro_symbol_leaf
2467
	jc	macro_symbol_not_found
2468
	mov	edx,[ebx]
2469
	mov	ebx,esi
2470
      try_macro_symbol:
31 halyavin 2471
	or	edx,edx
157 heavyiron 2472
	jz	macro_symbol_not_found
2473
	mov	ecx,[esp]
2474
	mov	edi,[edx+4]
2475
	repe	cmps byte [esi],[edi]
2476
	je	macro_symbol_found
2477
	mov	esi,ebx
2478
	mov	edx,[edx]
2479
	jmp	try_macro_symbol
2480
      macro_symbol_found:
31 halyavin 2481
	pop	ecx
157 heavyiron 2482
	clc
2483
	ret
2484
      macro_symbol_not_found:
31 halyavin 2485
	pop	ecx
157 heavyiron 2486
	stc
2487
	ret
2488
      find_macro_symbol_leaf:
31 halyavin 2489
	shl	eax,8
157 heavyiron 2490
	mov	al,cl
2491
	mov	ebp,eax
2492
	mov	ebx,macro_symbols
2493
      follow_macro_symbols_tree:
31 halyavin 2494
	mov	edx,[ebx]
157 heavyiron 2495
	or	edx,edx
2496
	jz	no_such_macro_symbol
2497
	xor	eax,eax
2498
	shr	ebp,1
2499
	adc	eax,0
2500
	lea	ebx,[edx+eax*4]
2501
	or	ebp,ebp
2502
	jnz	follow_macro_symbols_tree
2503
	add	ebx,8
2504
	clc
2505
	ret
2506
      no_such_macro_symbol:
31 halyavin 2507
	stc
157 heavyiron 2508
	ret
2509
add_macro_symbol:
31 halyavin 2510
	push	ebx ebp
157 heavyiron 2511
	call	find_macro_symbol_leaf
2512
	jc	extend_macro_symbol_tree
2513
	mov	eax,[ebx]
2514
      make_macro_symbol:
31 halyavin 2515
	mov	edx,[free_additional_memory]
157 heavyiron 2516
	add	edx,16
2517
	cmp	edx,[labels_list]
2518
	ja	out_of_memory
2519
	xchg	edx,[free_additional_memory]
2520
	mov	[ebx],edx
2521
	mov	[edx],eax
2522
	mov	[edx+4],esi
2523
	pop	ebp ebx
2524
	ret
2525
      extend_macro_symbol_tree:
31 halyavin 2526
	mov	edx,[free_additional_memory]
157 heavyiron 2527
	add	edx,16
2528
	cmp	edx,[labels_list]
2529
	ja	out_of_memory
2530
	xchg	edx,[free_additional_memory]
2531
	xor	eax,eax
2532
	mov	[edx],eax
2533
	mov	[edx+4],eax
2534
	mov	[edx+8],eax
2535
	mov	[edx+12],eax
2536
	shr	ebp,1
2537
	adc	eax,0
2538
	mov	[ebx],edx
2539
	lea	ebx,[edx+eax*4]
2540
	or	ebp,ebp
2541
	jnz	extend_macro_symbol_tree
2542
	add	ebx,8
2543
	xor	eax,eax
2544
	jmp	make_macro_symbol
2545
31 halyavin 2546
 
2547
	lods	byte [esi]
157 heavyiron 2548
	cmp	al,22h
2549
	jne	invalid_argument
2550
	lods	dword [esi]
2551
	cmp	byte [esi+eax],0
2552
	jne	extra_characters_on_line
2553
	push	esi
2554
	push	edi
2555
	mov	ebx,[current_line]
2556
      find_current_file_path:
31 halyavin 2557
	mov	esi,[ebx]
157 heavyiron 2558
	test	byte [ebx+7],80h
2559
	jz	copy_current_file_path
2560
	mov	ebx,[ebx+8]
2561
	jmp	find_current_file_path
2562
      copy_current_file_path:
31 halyavin 2563
	lods	byte [esi]
157 heavyiron 2564
	stos	byte [edi]
2565
	or	al,al
2566
	jnz	copy_current_file_path
2567
      cut_current_file_name:
31 halyavin 2568
	cmp	edi,[esp]
157 heavyiron 2569
	je	current_file_path_ok
2570
	cmp	byte [edi-1],'\'
2571
	je	current_file_path_ok
2572
	cmp	byte [edi-1],'/'
2573
	je	current_file_path_ok
2574
	dec	edi
2575
	jmp	cut_current_file_name
2576
      current_file_path_ok:
31 halyavin 2577
	mov	esi,[esp+4]
157 heavyiron 2578
	call	preprocess_path
2579
	pop	edx
2580
	mov	esi,edx
2581
	call	open
2582
	jnc	include_path_ok
2583
	mov	ebp,[include_paths]
2584
      try_include_directories:
31 halyavin 2585
	mov	edi,esi
157 heavyiron 2586
	mov	esi,ebp
2587
	cmp	byte [esi],0
2588
	je	try_in_current_directory
2589
	push	ebp
2590
	push	edi
2591
      copy_include_directory:
31 halyavin 2592
	lods	byte [esi]
157 heavyiron 2593
	cmp	al,';'
2594
	je	include_directory_ok
2595
	stos	byte [edi]
2596
	or	al,al
2597
	jnz	copy_include_directory
2598
	dec	esi
2599
	dec	edi
2600
      include_directory_ok:
31 halyavin 2601
	cmp	byte [edi-1],'/'
157 heavyiron 2602
	je	path_separator_ok
2603
	cmp	byte [edi-1],'\'
2604
	je	path_separator_ok
2605
	mov	al,'/'
2606
	stos	byte [edi]
2607
      path_separator_ok:
31 halyavin 2608
	mov	[esp+4],esi
157 heavyiron 2609
	mov	esi,[esp+8]
2610
	call	preprocess_path
2611
	pop	edx
2612
	mov	esi,edx
2613
	call	open
2614
	pop	ebp
2615
	jnc	include_path_ok
2616
	jmp	try_include_directories
2617
	mov	edi,esi
2618
      try_in_current_directory:
31 halyavin 2619
	mov	esi,[esp]
157 heavyiron 2620
	push	edi
2621
	call	preprocess_path
2622
	pop	edx
2623
	mov	esi,edx
2624
	call	open
2625
	jc	file_not_found
2626
      include_path_ok:
31 halyavin 2627
	mov	edi,[esp]
157 heavyiron 2628
      copy_preprocessed_path:
31 halyavin 2629
	lods	byte [esi]
157 heavyiron 2630
	stos	byte [edi]
2631
	or	al,al
2632
	jnz	copy_preprocessed_path
2633
	pop	esi
2634
	lea	ecx,[edi-1]
2635
	sub	ecx,esi
2636
	mov	[esi-4],ecx
2637
	push	dword [macro_status]
2638
	and	[macro_status],0Fh
2639
	call	preprocess_file
2640
	pop	eax
2641
	mov	[macro_status],al
2642
	jmp	line_preprocessed
2643
      preprocess_path:
31 halyavin 2644
	lods	byte [esi]
157 heavyiron 2645
	cmp	al,'%'
2646
	je	environment_variable
2647
	stos	byte [edi]
2648
	or	al,al
2649
	jnz	preprocess_path
2650
	cmp	edi,[memory_end]
2651
	ja	out_of_memory
2652
	ret
2653
      environment_variable:
31 halyavin 2654
	mov	ebx,esi
157 heavyiron 2655
      find_variable_end:
31 halyavin 2656
	lods	byte [esi]
157 heavyiron 2657
	or	al,al
2658
	jz	not_environment_variable
2659
	cmp	al,'%'
2660
	jne	find_variable_end
2661
	mov	byte [esi-1],0
2662
	push	esi
2663
	mov	esi,ebx
2664
	call	get_environment_variable
2665
	pop	esi
2666
	mov	byte [esi-1],'%'
2667
	jmp	preprocess_path
2668
      not_environment_variable:
31 halyavin 2669
	mov	al,'%'
157 heavyiron 2670
	stos	byte [edi]
2671
	mov	esi,ebx
2672
	jmp	preprocess_path
2673
>