Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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