Subversion Repositories Kolibri OS

Rev

Rev 340 | 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-2007, Tomasz Grysztar.
340 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
	mov	al,3Ah
664
	mov	[edx],al
665
	inc	al
666
	xchg	al,[edx+1]
667
	dec	al
668
	mov	[edx+2],al
669
	pop	esi edx
670
	jmp	use_macro
671
      preprocess_label:
31 halyavin 672
	dec	esi
157 heavyiron 673
	sub	esi,ecx
674
	lea	ebp,[esi-2]
675
	mov	ch,10b
676
	call	get_preprocessor_symbol
677
	jnc	symbolic_constant_in_label
678
	lea	esi,[esi+ecx+1]
679
	jmp	preprocess_instruction
680
      symbolic_constant_in_label:
31 halyavin 681
	mov	ebx,[edx+8]
157 heavyiron 682
	mov	ecx,[edx+12]
683
	add	ecx,ebx
684
      check_for_broken_label:
31 halyavin 685
	cmp	ebx,ecx
157 heavyiron 686
	je	label_broken
687
	cmp	byte [ebx],1Ah
688
	jne	label_broken
689
	movzx	eax,byte [ebx+1]
690
	lea	ebx,[ebx+2+eax]
691
	cmp	ebx,ecx
692
	je	label_constant_ok
693
	cmp	byte [ebx],':'
694
	jne	label_broken
695
	inc	ebx
696
	jmp	check_for_broken_label
697
      label_broken:
31 halyavin 698
	push	line_preprocessed
157 heavyiron 699
	jmp	replace_symbolic_constant
700
      label_constant_ok:
31 halyavin 701
	mov	ecx,edi
157 heavyiron 702
	sub	ecx,esi
703
	mov	edi,[edx+12]
704
	add	edi,ebp
705
	push	edi
706
	lea	eax,[edi+ecx]
707
	push	eax
708
	cmp	esi,edi
709
	je	replace_label
710
	jb	move_rest_of_line_up
711
	rep	movs byte [edi],[esi]
712
	jmp	replace_label
713
      move_rest_of_line_up:
31 halyavin 714
	lea	esi,[esi+ecx-1]
157 heavyiron 715
	lea	edi,[edi+ecx-1]
716
	std
717
	rep	movs byte [edi],[esi]
718
	cld
719
      replace_label:
31 halyavin 720
	mov	ecx,[edx+12]
157 heavyiron 721
	mov	edi,[esp+4]
722
	sub	edi,ecx
723
	mov	esi,[edx+8]
724
	rep	movs byte [edi],[esi]
725
	pop	edi esi
726
	inc	esi
727
	jmp	preprocess_instruction
728
      not_preprocessor_symbol:
31 halyavin 729
	mov	esi,[current_offset]
157 heavyiron 730
	call	process_equ_constants
731
      line_preprocessed:
31 halyavin 732
	pop	esi ecx
157 heavyiron 733
	ret
734
31 halyavin 735
 
736
	push	ebp edi esi
157 heavyiron 737
	mov	ebp,ecx
738
	shl	ebp,22
739
	movzx	ecx,cl
740
	mov	ebx,hash_tree
741
	mov	edi,10
742
      follow_hashes_roots:
31 halyavin 743
	mov	edx,[ebx]
157 heavyiron 744
	or	edx,edx
745
	jz	preprocessor_symbol_not_found
746
	xor	eax,eax
747
	shl	ebp,1
748
	adc	eax,0
749
	lea	ebx,[edx+eax*4]
750
	dec	edi
751
	jnz	follow_hashes_roots
752
	mov	edi,ebx
753
	call	calculate_hash
754
	mov	ebp,eax
755
	and	ebp,3FFh
756
	shl	ebp,10
757
	xor	ebp,eax
758
	mov	ebx,edi
759
	mov	edi,22
760
      follow_hashes_tree:
31 halyavin 761
	mov	edx,[ebx]
157 heavyiron 762
	or	edx,edx
763
	jz	preprocessor_symbol_not_found
764
	xor	eax,eax
765
	shl	ebp,1
766
	adc	eax,0
767
	lea	ebx,[edx+eax*4]
768
	dec	edi
769
	jnz	follow_hashes_tree
770
	mov	al,cl
771
	mov	edx,[ebx]
772
	or	edx,edx
773
	jz	preprocessor_symbol_not_found
774
      compare_with_preprocessor_symbol:
31 halyavin 775
	mov	edi,[edx+4]
157 heavyiron 776
	cmp	edi,1
777
	jbe	next_equal_hash
778
	repe	cmps byte [esi],[edi]
779
	je	preprocessor_symbol_found
780
	mov	cl,al
781
	mov	esi,[esp]
782
      next_equal_hash:
31 halyavin 783
	mov	edx,[edx]
157 heavyiron 784
	or	edx,edx
785
	jnz	compare_with_preprocessor_symbol
786
      preprocessor_symbol_not_found:
31 halyavin 787
	pop	esi edi ebp
157 heavyiron 788
	stc
789
	ret
790
      preprocessor_symbol_found:
31 halyavin 791
	pop	ebx edi ebp
157 heavyiron 792
	clc
793
	ret
794
      calculate_hash:
31 halyavin 795
	xor	ebx,ebx
157 heavyiron 796
	mov	eax,2166136261
797
	mov	ebp,16777619
798
      fnv1a_hash:
31 halyavin 799
	xor	al,[esi+ebx]
157 heavyiron 800
	mul	ebp
801
	inc	bl
802
	cmp	bl,cl
803
	jb	fnv1a_hash
804
	ret
805
add_preprocessor_symbol:
31 halyavin 806
	push	edi esi
157 heavyiron 807
	call	calculate_hash
808
	mov	ebp,eax
809
	and	ebp,3FFh
810
	shr	eax,10
811
	xor	ebp,eax
812
	shl	ecx,22
813
	or	ebp,ecx
814
	mov	ebx,hash_tree
815
	mov	ecx,32
816
      find_leave_for_symbol:
31 halyavin 817
	mov	edx,[ebx]
157 heavyiron 818
	or	edx,edx
819
	jz	extend_hashes_tree
820
	xor	eax,eax
821
	rol	ebp,1
822
	adc	eax,0
823
	lea	ebx,[edx+eax*4]
824
	dec	ecx
825
	jnz	find_leave_for_symbol
826
	mov	edx,[ebx]
827
	or	edx,edx
828
	jz	add_symbol_entry
829
	shr	ebp,30
830
	cmp	ebp,11b
831
	je	reuse_symbol_entry
832
	cmp	dword [edx+4],0
833
	jne	add_symbol_entry
834
      find_entry_to_reuse:
31 halyavin 835
	mov	edi,[edx]
157 heavyiron 836
	or	edi,edi
837
	jz	reuse_symbol_entry
838
	cmp	dword [edi+4],0
839
	jne	reuse_symbol_entry
840
	mov	edx,edi
841
	jmp	find_entry_to_reuse
842
      add_symbol_entry:
31 halyavin 843
	mov	eax,edx
157 heavyiron 844
	mov	edx,[labels_list]
845
	sub	edx,16
846
	cmp	edx,[free_additional_memory]
847
	jb	out_of_memory
848
	mov	[labels_list],edx
849
	mov	[edx],eax
850
	mov	[ebx],edx
851
      reuse_symbol_entry:
31 halyavin 852
	pop	esi edi
157 heavyiron 853
	mov	[edx+4],esi
854
	ret
855
      extend_hashes_tree:
31 halyavin 856
	mov	edx,[labels_list]
157 heavyiron 857
	sub	edx,8
858
	cmp	edx,[free_additional_memory]
859
	jb	out_of_memory
860
	mov	[labels_list],edx
861
	xor	eax,eax
862
	mov	[edx],eax
863
	mov	[edx+4],eax
864
	shl	ebp,1
865
	adc	eax,0
866
	mov	[ebx],edx
867
	lea	ebx,[edx+eax*4]
868
	dec	ecx
869
	jnz	extend_hashes_tree
870
	mov	edx,[labels_list]
871
	sub	edx,16
872
	cmp	edx,[free_additional_memory]
873
	jb	out_of_memory
874
	mov	[labels_list],edx
875
	mov	dword [edx],0
876
	mov	[ebx],edx
877
	pop	esi edi
878
	mov	[edx+4],esi
879
	ret
880
31 halyavin 881
 
882
	add	edx,5
157 heavyiron 883
	add	esi,2
884
	push	edx esi
885
	mov	esi,edx
886
	call	skip_parameters
887
	xchg	esi,[esp]
888
	mov	ch,11b
889
	jmp	define_preprocessor_constant
890
define_equ_constant:
31 halyavin 891
	add	esi,3
157 heavyiron 892
	push	esi
893
	call	process_equ_constants
894
	push	esi
895
	mov	esi,[struc_name]
896
	mov	ch,10b
897
      define_preprocessor_constant:
109 heavyiron 898
	mov	byte [esi-2],3Bh
157 heavyiron 899
	mov	cl,[esi-1]
900
	call	add_preprocessor_symbol
901
	pop	esi ebx
902
	mov	ecx,edi
903
	dec	ecx
904
	sub	ecx,ebx
905
	mov	[edx+8],ebx
906
	mov	[edx+12],ecx
907
	jmp	line_preprocessed
908
define_symbolic_constant:
109 heavyiron 909
	lods	byte [esi]
157 heavyiron 910
	cmp	al,1Ah
911
	jne	invalid_name
912
	lods	byte [esi]
913
	mov	cl,al
914
	mov	ch,10b
915
	call	add_preprocessor_symbol
916
	movzx	eax,byte [esi-1]
917
	add	esi,eax
918
	push	esi edx
919
	call	skip_parameters
920
	pop	edx ebx
921
	lea	ecx,[esi-1]
922
	sub	ecx,ebx
923
	mov	[edx+8],ebx
924
	mov	[edx+12],ecx
925
	jmp	line_preprocessed
926
      skip_parameters:
109 heavyiron 927
	lods	byte [esi]
157 heavyiron 928
	or	al,al
929
	jz	parameters_skipped
930
	cmp	al,'{'
931
	je	parameters_skipped
932
	cmp	al,22h
933
	je	skip_quoted_parameter
934
	cmp	al,1Ah
935
	jne	skip_parameters
936
	lods	byte [esi]
937
	movzx	eax,al
938
	add	esi,eax
939
	jmp	skip_parameters
940
      skip_quoted_parameter:
109 heavyiron 941
	lods	dword [esi]
157 heavyiron 942
	add	esi,eax
943
	jmp	skip_parameters
944
      parameters_skipped:
109 heavyiron 945
	ret
157 heavyiron 946
109 heavyiron 947
 
31 halyavin 948
	mov	ch,1
157 heavyiron 949
	jmp	make_macro
950
define_macro:
31 halyavin 951
	xor	ch,ch
157 heavyiron 952
      make_macro:
31 halyavin 953
	lods	byte [esi]
157 heavyiron 954
	cmp	al,1Ah
955
	jne	invalid_name
956
	lods	byte [esi]
957
	mov	cl,al
958
	call	add_preprocessor_symbol
959
	mov	eax,[current_line]
960
	mov	[edx+12],eax
961
	movzx	eax,byte [esi-1]
962
	add	esi,eax
963
	mov	[edx+8],esi
964
	mov	al,[macro_status]
965
	and	al,0F0h
966
	or	al,1
967
	mov	[macro_status],al
968
	mov	eax,[current_line]
969
	mov	[error_line],eax
970
	xor	bl,bl
971
	lods	byte [esi]
972
	or	al,al
973
	jz	line_preprocessed
974
	cmp	al,'{'
975
	je	found_macro_block
976
	dec	esi
977
      skip_macro_arguments:
31 halyavin 978
	lods	byte [esi]
157 heavyiron 979
	cmp	al,1Ah
980
	je	skip_macro_argument
981
	cmp	al,'['
982
	jne	invalid_macro_arguments
983
	xor	bl,-1
984
	jz	invalid_macro_arguments
985
	lods	byte [esi]
986
	cmp	al,1Ah
987
	jne	invalid_macro_arguments
988
      skip_macro_argument:
31 halyavin 989
	movzx	eax,byte [esi]
157 heavyiron 990
	inc	esi
991
	add	esi,eax
992
	lods	byte [esi]
993
	cmp	al,'*'
994
	jne	macro_argument_end
995
	lods	byte [esi]
996
      macro_argument_end:
31 halyavin 997
	cmp	al,','
157 heavyiron 998
	je	skip_macro_arguments
999
	cmp	al,']'
1000
	jne	end_macro_arguments
1001
	lods	byte [esi]
1002
	not	bl
1003
      end_macro_arguments:
31 halyavin 1004
	or	bl,bl
157 heavyiron 1005
	jnz	invalid_macro_arguments
1006
	or	al,al
1007
	jz	line_preprocessed
1008
	cmp	al,'{'
1009
	je	found_macro_block
1010
	jmp	invalid_macro_arguments
1011
      find_macro_block:
31 halyavin 1012
	add	esi,2
157 heavyiron 1013
	lods	byte [esi]
1014
	or	al,al
1015
	jz	line_preprocessed
1016
	cmp	al,'{'
1017
	jne	unexpected_characters
1018
      found_macro_block:
31 halyavin 1019
	or	[macro_status],2
157 heavyiron 1020
      skip_macro_block:
31 halyavin 1021
	lods	byte [esi]
157 heavyiron 1022
	cmp	al,1Ah
1023
	je	skip_macro_symbol
1024
	cmp	al,3Bh
1025
	je	skip_macro_symbol
1026
	cmp	al,22h
1027
	je	skip_macro_string
1028
	or	al,al
1029
	jz	line_preprocessed
1030
	cmp	al,'}'
1031
	jne	skip_macro_block
1032
	mov	al,[macro_status]
1033
	and	[macro_status],0F0h
1034
	test	al,8
1035
	jnz	use_instant_macro
1036
	cmp	byte [esi],0
1037
	je	line_preprocessed
1038
	mov	ecx,edi
1039
	sub	ecx,esi
1040
	mov	edx,esi
1041
	lea	esi,[esi+ecx-1]
1042
	lea	edi,[edi+1+16]
1043
	mov	ebx,edi
1044
	dec	edi
1045
	std
1046
	rep	movs byte [edi],[esi]
1047
	cld
1048
	mov	edi,edx
1049
	xor	al,al
1050
	stos	byte [edi]
1051
	mov	esi,[current_line]
1052
	mov	[current_line],edi
1053
	mov	ecx,4
1054
	rep	movs dword [edi],[esi]
1055
	mov	edi,ebx
1056
	jmp	initial_preprocessing_ok
1057
      skip_macro_symbol:
31 halyavin 1058
	movzx	eax,byte [esi]
157 heavyiron 1059
	inc	esi
1060
	add	esi,eax
1061
	jmp	skip_macro_block
1062
      skip_macro_string:
31 halyavin 1063
	lods	dword [esi]
157 heavyiron 1064
	add	esi,eax
1065
	jmp	skip_macro_block
1066
rept_directive:
31 halyavin 1067
	mov	[base_code],0
157 heavyiron 1068
	jmp	define_instant_macro
1069
irp_directive:
31 halyavin 1070
	mov	[base_code],1
157 heavyiron 1071
	jmp	define_instant_macro
1072
irps_directive:
31 halyavin 1073
	mov	[base_code],2
157 heavyiron 1074
	jmp	define_instant_macro
1075
match_directive:
31 halyavin 1076
	mov	[base_code],10h
157 heavyiron 1077
define_instant_macro:
31 halyavin 1078
	mov	al,[macro_status]
157 heavyiron 1079
	and	al,0F0h
1080
	or	al,8+1
1081
	mov	[macro_status],al
1082
	mov	eax,[current_line]
1083
	mov	[error_line],eax
1084
	mov	[instant_macro_start],esi
1085
	cmp	[base_code],10h
1086
	je	prepare_match
1087
	call	skip_parameters
1088
      instant_macro_parameters_skipped:
109 heavyiron 1089
	dec	esi
157 heavyiron 1090
	mov	[parameters_end],esi
1091
	lods	byte [esi]
1092
	cmp	al,'{'
1093
	je	found_macro_block
1094
	or	al,al
1095
	jnz	invalid_macro_arguments
1096
	jmp	line_preprocessed
1097
prepare_match:
31 halyavin 1098
	call	skip_pattern
157 heavyiron 1099
	mov	[value_type],80h+10b
1100
	call	process_symbolic_constants
1101
	jmp	instant_macro_parameters_skipped
1102
      skip_pattern:
31 halyavin 1103
	lods	byte [esi]
157 heavyiron 1104
	or	al,al
1105
	jz	invalid_macro_arguments
1106
	cmp	al,','
1107
	je	pattern_skipped
1108
	cmp	al,22h
1109
	je	skip_quoted_string_in_pattern
1110
	cmp	al,1Ah
1111
	je	skip_symbol_in_pattern
1112
	cmp	al,'='
1113
	jne	skip_pattern
1114
	mov	al,[esi]
1115
	cmp	al,1Ah
1116
	je	skip_pattern
1117
	cmp	al,22h
1118
	je	skip_pattern
1119
	inc	esi
1120
	jmp	skip_pattern
1121
      skip_symbol_in_pattern:
31 halyavin 1122
	lods	byte [esi]
157 heavyiron 1123
	movzx	eax,al
1124
	add	esi,eax
1125
	jmp	skip_pattern
1126
      skip_quoted_string_in_pattern:
31 halyavin 1127
	lods	dword [esi]
157 heavyiron 1128
	add	esi,eax
1129
	jmp	skip_pattern
1130
      pattern_skipped:
31 halyavin 1131
	ret
157 heavyiron 1132
31 halyavin 1133
 
1134
	xor	ch,ch
157 heavyiron 1135
	jmp	restore_preprocessor_symbol
1136
purge_struc:
31 halyavin 1137
	mov	ch,1
157 heavyiron 1138
	jmp	restore_preprocessor_symbol
1139
restore_equ_constant:
31 halyavin 1140
	mov	ch,10b
157 heavyiron 1141
      restore_preprocessor_symbol:
31 halyavin 1142
	push	ecx
157 heavyiron 1143
	lods	byte [esi]
1144
	cmp	al,1Ah
1145
	jne	invalid_name
1146
	lods	byte [esi]
1147
	mov	cl,al
1148
	call	get_preprocessor_symbol
1149
	jc	no_symbol_to_restore
1150
	mov	dword [edx+4],0
1151
	jmp	symbol_restored
1152
      no_symbol_to_restore:
31 halyavin 1153
	add	esi,ecx
157 heavyiron 1154
      symbol_restored:
31 halyavin 1155
	pop	ecx
157 heavyiron 1156
	lods	byte [esi]
1157
	cmp	al,','
1158
	je	restore_preprocessor_symbol
1159
	or	al,al
1160
	jnz	extra_characters_on_line
1161
	jmp	line_preprocessed
1162
31 halyavin 1163
 
1164
	mov	[value_type],11b
157 heavyiron 1165
	jmp	process_symbolic_constants
1166
process_equ_constants:
31 halyavin 1167
	mov	[value_type],10b
157 heavyiron 1168
      process_symbolic_constants:
31 halyavin 1169
	mov	ebp,esi
157 heavyiron 1170
	lods	byte [esi]
1171
	cmp	al,1Ah
1172
	je	check_symbol
1173
	cmp	al,22h
1174
	je	ignore_string
1175
	cmp	al,'{'
1176
	je	check_brace
1177
	or	al,al
1178
	jnz	process_symbolic_constants
1179
	ret
1180
      ignore_string:
31 halyavin 1181
	lods	dword [esi]
157 heavyiron 1182
	add	esi,eax
1183
	jmp	process_symbolic_constants
1184
      check_brace:
31 halyavin 1185
	test	[value_type],80h
157 heavyiron 1186
	jz	process_symbolic_constants
1187
	ret
1188
      no_replacing:
31 halyavin 1189
	movzx	ecx,byte [esi-1]
157 heavyiron 1190
	add	esi,ecx
1191
	jmp	process_symbolic_constants
1192
      check_symbol:
31 halyavin 1193
	mov	cl,[esi]
157 heavyiron 1194
	inc	esi
1195
	mov	ch,[value_type]
1196
	call	get_preprocessor_symbol
1197
	jc	no_replacing
1198
	mov	[current_section],edi
1199
      replace_symbolic_constant:
31 halyavin 1200
	mov	ecx,[edx+12]
157 heavyiron 1201
	mov	edx,[edx+8]
1202
	xchg	esi,edx
1203
	call	move_data
1204
	mov	esi,edx
1205
      process_after_replaced:
31 halyavin 1206
	lods	byte [esi]
157 heavyiron 1207
	cmp	al,1Ah
1208
	je	symbol_after_replaced
1209
	stos	byte [edi]
1210
	cmp	al,22h
1211
	je	string_after_replaced
1212
	cmp	al,'{'
1213
	je	brace_after_replaced
1214
	or	al,al
1215
	jnz	process_after_replaced
1216
	mov	ecx,edi
1217
	sub	ecx,esi
1218
	mov	edi,ebp
1219
	call	move_data
1220
	mov	esi,edi
1221
	ret
1222
      move_data:
31 halyavin 1223
	lea	eax,[edi+ecx]
157 heavyiron 1224
	cmp	eax,[memory_end]
1225
	jae	out_of_memory
1226
	shr	ecx,1
1227
	jnc	movsb_ok
1228
	movs	byte [edi],[esi]
1229
      movsb_ok:
31 halyavin 1230
	shr	ecx,1
157 heavyiron 1231
	jnc	movsw_ok
1232
	movs	word [edi],[esi]
1233
      movsw_ok:
31 halyavin 1234
	rep	movs dword [edi],[esi]
157 heavyiron 1235
	ret
1236
      string_after_replaced:
31 halyavin 1237
	lods	dword [esi]
157 heavyiron 1238
	stos	dword [edi]
1239
	mov	ecx,eax
1240
	call	move_data
1241
	jmp	process_after_replaced
1242
      brace_after_replaced:
31 halyavin 1243
	test	[value_type],80h
157 heavyiron 1244
	jz	process_after_replaced
1245
	mov	edx,edi
1246
	mov	ecx,[current_section]
1247
	sub	edx,ecx
1248
	sub	ecx,esi
1249
	rep	movs byte [edi],[esi]
1250
	mov	ecx,edi
1251
	sub	ecx,esi
1252
	mov	edi,ebp
1253
	call	move_data
1254
	lea	esi,[ebp+edx]
1255
	ret
1256
      symbol_after_replaced:
31 halyavin 1257
	mov	cl,[esi]
157 heavyiron 1258
	inc	esi
1259
	mov	ch,[value_type]
1260
	call	get_preprocessor_symbol
1261
	jnc	replace_symbolic_constant
1262
	movzx	ecx,byte [esi-1]
1263
	mov	al,1Ah
1264
	mov	ah,cl
1265
	stos	word [edi]
1266
	call	move_data
1267
	jmp	process_after_replaced
1268
process_macro_operators:
31 halyavin 1269
	xor	dl,dl
157 heavyiron 1270
	mov	ebp,edi
1271
      before_macro_operators:
31 halyavin 1272
	mov	edi,esi
157 heavyiron 1273
	lods	byte [esi]
1274
	cmp	al,'`'
1275
	je	symbol_conversion
1276
	cmp	al,'#'
1277
	je	concatenation
1278
	cmp	al,1Ah
1279
	je	symbol_before_macro_operators
1280
	cmp	al,3Bh
1281
	je	no_more_macro_operators
1282
	cmp	al,22h
1283
	je	string_before_macro_operators
1284
	xor	dl,dl
1285
	or	al,al
1286
	jnz	before_macro_operators
1287
	mov	edi,esi
1288
	ret
1289
      no_more_macro_operators:
31 halyavin 1290
	mov	edi,ebp
157 heavyiron 1291
	ret
1292
      symbol_before_macro_operators:
31 halyavin 1293
	mov	dl,1Ah
157 heavyiron 1294
	mov	ebx,esi
1295
	lods	byte [esi]
1296
	movzx	ecx,al
1297
	jecxz	symbol_before_macro_operators_ok
1298
	mov	edi,esi
1299
	cmp	byte [esi],'\'
1300
	je	escaped_symbol
1301
      symbol_before_macro_operators_ok:
31 halyavin 1302
	add	esi,ecx
157 heavyiron 1303
	jmp	before_macro_operators
1304
      string_before_macro_operators:
31 halyavin 1305
	mov	dl,22h
157 heavyiron 1306
	mov	ebx,esi
1307
	lods	dword [esi]
1308
	add	esi,eax
1309
	jmp	before_macro_operators
1310
      escaped_symbol:
31 halyavin 1311
	dec	byte [edi-1]
157 heavyiron 1312
	dec	ecx
1313
	inc	esi
1314
	cmp	ecx,1
1315
	rep	movs byte [edi],[esi]
1316
	jne	after_macro_operators
1317
	mov	al,[esi-1]
1318
	mov	ecx,ebx
1319
	mov	ebx,characters
1320
	xlat	byte [ebx]
1321
	mov	ebx,ecx
1322
	or	al,al
1323
	jnz	after_macro_operators
1324
	sub	edi,3
1325
	mov	al,[esi-1]
1326
	stos	byte [edi]
1327
	xor	dl,dl
1328
	jmp	after_macro_operators
1329
      reduce_symbol_conversion:
109 heavyiron 1330
	inc	esi
157 heavyiron 1331
      symbol_conversion:
31 halyavin 1332
	mov	edx,esi
157 heavyiron 1333
	mov	al,[esi]
1334
	cmp	al,1Ah
1335
	jne	symbol_character_conversion
1336
	lods	word [esi]
1337
	movzx	ecx,ah
1338
	lea	ebx,[edi+3]
1339
	jecxz	convert_to_quoted_string
242 heavyiron 1340
	cmp	byte [esi],'\'
1341
	jne	convert_to_quoted_string
1342
	inc	esi
1343
	dec	ecx
1344
	dec	ebx
1345
	jmp	convert_to_quoted_string
157 heavyiron 1346
      symbol_character_conversion:
109 heavyiron 1347
	cmp	al,22h
157 heavyiron 1348
	je	after_macro_operators
1349
	cmp	al,'`'
1350
	je	reduce_symbol_conversion
1351
	lea	ebx,[edi+5]
1352
	xor	ecx,ecx
1353
	or	al,al
1354
	jz	convert_to_quoted_string
1355
	cmp	al,'#'
1356
	je	convert_to_quoted_string
1357
	inc	ecx
1358
      convert_to_quoted_string:
109 heavyiron 1359
	sub	ebx,edx
157 heavyiron 1360
	ja	shift_line_data
1361
	mov	al,22h
1362
	mov	dl,al
1363
	stos	byte [edi]
1364
	mov	ebx,edi
1365
	mov	eax,ecx
1366
	stos	dword [edi]
1367
	rep	movs byte [edi],[esi]
1368
	cmp	edi,esi
1369
	je	before_macro_operators
1370
	jmp	after_macro_operators
1371
      shift_line_data:
31 halyavin 1372
	push	ecx
157 heavyiron 1373
	mov	edx,esi
1374
	lea	esi,[ebp-1]
1375
	add	ebp,ebx
1376
	lea	edi,[ebp-1]
1377
	lea	ecx,[esi+1]
1378
	sub	ecx,edx
1379
	std
1380
	rep	movs byte [edi],[esi]
1381
	cld
1382
	pop	eax
1383
	sub	edi,3
1384
	mov	dl,22h
1385
	mov	[edi-1],dl
1386
	mov	ebx,edi
1387
	mov	[edi],eax
1388
	lea	esi,[edi+4+eax]
1389
	jmp	before_macro_operators
1390
      concatenation:
31 halyavin 1391
	cmp	dl,1Ah
157 heavyiron 1392
	je	symbol_concatenation
1393
	cmp	dl,22h
1394
	je	string_concatenation
1395
      no_concatenation:
31 halyavin 1396
	cmp	esi,edi
157 heavyiron 1397
	je	before_macro_operators
1398
	jmp	after_macro_operators
1399
      symbol_concatenation:
31 halyavin 1400
	cmp	byte [esi],1Ah
157 heavyiron 1401
	jne	no_concatenation
1402
	inc	esi
1403
	lods	byte [esi]
1404
	movzx	ecx,al
1405
	jecxz	do_symbol_concatenation
1406
	cmp	byte [esi],'\'
1407
	je	concatenate_escaped_symbol
242 heavyiron 1408
      do_symbol_concatenation:
31 halyavin 1409
	add	[ebx],cl
242 heavyiron 1410
	jc	name_too_long
157 heavyiron 1411
	rep	movs byte [edi],[esi]
1412
	jmp	after_macro_operators
1413
      concatenate_escaped_symbol:
242 heavyiron 1414
	inc	esi
1415
	dec	ecx
1416
	jz	do_symbol_concatenation
1417
	movzx	eax,byte [esi]
1418
	cmp	byte [characters+eax],0
1419
	jne	do_symbol_concatenation
1420
	sub	esi,3
1421
	jmp	no_concatenation
1422
      string_concatenation:
31 halyavin 1423
	cmp	byte [esi],22h
157 heavyiron 1424
	je	do_string_concatenation
1425
	cmp	byte [esi],'`'
1426
	jne	no_concatenation
1427
      concatenate_converted_symbol:
109 heavyiron 1428
	inc	esi
157 heavyiron 1429
	mov	al,[esi]
1430
	cmp	al,'`'
1431
	je	concatenate_converted_symbol
1432
	cmp	al,22h
1433
	je	do_string_concatenation
1434
	cmp	al,1Ah
1435
	jne	concatenate_converted_symbol_character
1436
	inc	esi
1437
	lods	byte [esi]
1438
	movzx	ecx,al
1439
	jecxz	finish_concatenating_converted_symbol
242 heavyiron 1440
	cmp	byte [esi],'\'
1441
	jne	finish_concatenating_converted_symbol
1442
	inc	esi
1443
	dec	ecx
1444
      finish_concatenating_converted_symbol:
1445
	add	[ebx],ecx
157 heavyiron 1446
	rep	movs byte [edi],[esi]
1447
	jmp	after_macro_operators
1448
      concatenate_converted_symbol_character:
109 heavyiron 1449
	or	al,al
157 heavyiron 1450
	jz	after_macro_operators
1451
	cmp	al,'#'
1452
	je	after_macro_operators
1453
	inc	dword [ebx]
1454
	movs	byte [edi],[esi]
1455
	jmp	after_macro_operators
1456
      do_string_concatenation:
31 halyavin 1457
	inc	esi
157 heavyiron 1458
	lods	dword [esi]
1459
	mov	ecx,eax
1460
	add	[ebx],eax
1461
	rep	movs byte [edi],[esi]
1462
      after_macro_operators:
31 halyavin 1463
	lods	byte [esi]
157 heavyiron 1464
	cmp	al,'`'
1465
	je	symbol_conversion
1466
	cmp	al,'#'
1467
	je	concatenation
1468
	stos	byte [edi]
1469
	cmp	al,1Ah
1470
	je	symbol_after_macro_operators
1471
	cmp	al,3Bh
1472
	je	no_more_macro_operators
1473
	cmp	al,22h
1474
	je	string_after_macro_operators
1475
	xor	dl,dl
1476
	or	al,al
1477
	jnz	after_macro_operators
1478
	ret
1479
      symbol_after_macro_operators:
31 halyavin 1480
	mov	dl,1Ah
157 heavyiron 1481
	mov	ebx,edi
1482
	lods	byte [esi]
1483
	stos	byte [edi]
1484
	movzx	ecx,al
1485
	jecxz	symbol_after_macro_operatorss_ok
1486
	cmp	byte [esi],'\'
1487
	je	escaped_symbol
1488
      symbol_after_macro_operatorss_ok:
31 halyavin 1489
	rep	movs byte [edi],[esi]
157 heavyiron 1490
	jmp	after_macro_operators
1491
      string_after_macro_operators:
31 halyavin 1492
	mov	dl,22h
157 heavyiron 1493
	mov	ebx,edi
1494
	lods	dword [esi]
1495
	stos	dword [edi]
1496
	mov	ecx,eax
1497
	rep	movs byte [edi],[esi]
1498
	jmp	after_macro_operators
1499
31 halyavin 1500
 
1501
	push	[free_additional_memory]
157 heavyiron 1502
	push	[macro_symbols]
1503
	mov	[macro_symbols],0
1504
	push	[counter_limit]
1505
	push	dword [edx+4]
1506
	mov	dword [edx+4],1
1507
	push	edx
1508
	mov	ebx,esi
1509
	mov	esi,[edx+8]
1510
	mov	eax,[edx+12]
1511
	mov	[macro_line],eax
1512
	mov	[counter_limit],0
1513
      process_macro_arguments:
31 halyavin 1514
	mov	al,[esi]
157 heavyiron 1515
	or	al,al
1516
	jz	arguments_end
1517
	cmp	al,'{'
1518
	je	arguments_end
1519
	inc	esi
1520
	cmp	al,'['
1521
	jne	get_macro_arguments
1522
	mov	ebp,esi
1523
	inc	esi
1524
	inc	[counter_limit]
1525
      get_macro_arguments:
31 halyavin 1526
	call	get_macro_argument
157 heavyiron 1527
	lods	byte [esi]
1528
	cmp	al,','
1529
	je	next_argument
1530
	cmp	al,']'
1531
	je	next_arguments_group
1532
	dec	esi
1533
	jmp	arguments_end
1534
      next_argument:
31 halyavin 1535
	cmp	byte [ebx],','
157 heavyiron 1536
	jne	process_macro_arguments
1537
	inc	ebx
1538
	jmp	process_macro_arguments
1539
      next_arguments_group:
31 halyavin 1540
	cmp	byte [ebx],','
157 heavyiron 1541
	jne	arguments_end
1542
	inc	ebx
1543
	inc	[counter_limit]
1544
	mov	esi,ebp
1545
	jmp	process_macro_arguments
1546
      get_macro_argument:
31 halyavin 1547
	lods	byte [esi]
157 heavyiron 1548
	movzx	ecx,al
1549
	mov	eax,[counter_limit]
1550
	call	add_macro_symbol
1551
	add	esi,ecx
1552
	xchg	esi,ebx
1553
	mov	[edx+12],esi
1554
	cmp	byte [esi],'<'
1555
	jne	simple_argument
1556
	inc	esi
1557
	mov	[edx+12],esi
1558
	mov	ecx,1
1559
      enclosed_argument:
31 halyavin 1560
	lods	byte [esi]
157 heavyiron 1561
	or	al,al
1562
	jz	invalid_macro_arguments
1563
	cmp	al,1Ah
1564
	je	enclosed_symbol
1565
	cmp	al,22h
1566
	je	enclosed_string
1567
	cmp	al,'>'
1568
	je	enclosed_argument_end
1569
	cmp	al,'<'
1570
	jne	enclosed_argument
1571
	inc	ecx
1572
	jmp	enclosed_argument
1573
      enclosed_symbol:
31 halyavin 1574
	movzx	eax,byte [esi]
157 heavyiron 1575
	inc	esi
1576
	add	esi,eax
1577
	jmp	enclosed_argument
1578
      enclosed_string:
31 halyavin 1579
	lods	dword [esi]
157 heavyiron 1580
	add	esi,eax
1581
	jmp	enclosed_argument
1582
      enclosed_argument_end:
31 halyavin 1583
	loop	enclosed_argument
157 heavyiron 1584
	mov	al,[esi]
1585
	or	al,al
1586
	jz	enclosed_argument_ok
1587
	cmp	al,','
1588
	jne	invalid_macro_arguments
1589
      enclosed_argument_ok:
31 halyavin 1590
	mov	eax,esi
157 heavyiron 1591
	sub	eax,[edx+12]
1592
	dec	eax
1593
	or	eax,80000000h
1594
	mov	[edx+8],eax
1595
	jmp	argument_value_ok
1596
      simple_argument:
31 halyavin 1597
	lods	byte [esi]
157 heavyiron 1598
	or	al,al
1599
	jz	argument_value_end
1600
	cmp	al,','
1601
	je	argument_value_end
1602
	cmp	al,22h
1603
	je	argument_string
1604
	cmp	al,1Ah
1605
	jne	simple_argument
1606
	movzx	eax,byte [esi]
1607
	inc	esi
1608
	add	esi,eax
1609
	jmp	simple_argument
1610
      argument_string:
31 halyavin 1611
	lods	dword [esi]
157 heavyiron 1612
	add	esi,eax
1613
	jmp	simple_argument
1614
      argument_value_end:
31 halyavin 1615
	dec	esi
157 heavyiron 1616
	mov	eax,esi
1617
	sub	eax,[edx+12]
1618
	mov	[edx+8],eax
1619
      argument_value_ok:
31 halyavin 1620
	xchg	esi,ebx
157 heavyiron 1621
	cmp	byte [esi],'*'
1622
	jne	macro_argument_ok
1623
	cmp	dword [edx+8],0
1624
	je	invalid_macro_arguments
1625
	inc	esi
1626
      macro_argument_ok:
31 halyavin 1627
	ret
157 heavyiron 1628
      arguments_end:
31 halyavin 1629
	cmp	byte [ebx],0
157 heavyiron 1630
	jne	invalid_macro_arguments
1631
	mov	eax,[esp+4]
1632
	dec	eax
1633
	call	process_macro
1634
	pop	edx
1635
	pop	dword [edx+4]
1636
	pop	[counter_limit]
1637
	pop	[macro_symbols]
1638
	pop	[free_additional_memory]
1639
	jmp	line_preprocessed
1640
use_instant_macro:
31 halyavin 1641
	push	edi [current_line] esi
157 heavyiron 1642
	mov	eax,[error_line]
1643
	mov	[current_line],eax
1644
	mov	[macro_line],eax
1645
	mov	esi,[instant_macro_start]
1646
	cmp	[base_code],10h
1647
	jae	do_match
1648
	cmp	[base_code],0
1649
	jne	do_irp
1650
	call	get_number
1651
	jc	invalid_value
1652
	or	ebp,ebp
1653
	jnz	invalid_value
1654
	cmp	dword [edi+4],0
1655
	jne	value_out_of_range
1656
	mov	eax,[edi]
1657
	or	eax,eax
1658
	jz	instant_macro_done
1659
	cmp	eax,80000000h
1660
	jae	value_out_of_range
1661
	push	[free_additional_memory]
1662
	push	[macro_symbols]
1663
	mov	[macro_symbols],0
1664
	push	[counter_limit]
1665
	mov	[struc_name],0
1666
	mov	[counter_limit],eax
1667
	lods	byte [esi]
1668
	or	al,al
1669
	jz	rept_counters_ok
1670
	cmp	al,'{'
1671
	je	rept_counters_ok
1672
	cmp	al,1Ah
1673
	jne	invalid_macro_arguments
1674
      add_rept_counter:
31 halyavin 1675
	lods	byte [esi]
157 heavyiron 1676
	movzx	ecx,al
1677
	xor	eax,eax
1678
	call	add_macro_symbol
1679
	add	esi,ecx
1680
	xor	eax,eax
1681
	mov	dword [edx+12],eax
1682
	inc	eax
1683
	mov	dword [edx+8],eax
1684
	lods	byte [esi]
1685
	cmp	al,':'
1686
	jne	rept_counter_added
1687
	push	edx
1688
	call	get_number
1689
	jc	invalid_value
1690
	or	ebp,ebp
1691
	jnz	invalid_value
1692
	cmp	dword [edi+4],0
1693
	jne	value_out_of_range
1694
	mov	eax,[edi]
1695
	mov	edx,eax
1696
	add	edx,[counter_limit]
1697
	jc	value_out_of_range
1698
	pop	edx
1699
	mov	dword [edx+8],eax
1700
	lods	byte [esi]
1701
      rept_counter_added:
31 halyavin 1702
	cmp	al,','
157 heavyiron 1703
	jne	rept_counters_ok
1704
	lods	byte [esi]
1705
	cmp	al,1Ah
1706
	jne	invalid_macro_arguments
1707
	jmp	add_rept_counter
1708
      rept_counters_ok:
31 halyavin 1709
	dec	esi
157 heavyiron 1710
      instant_macro_parameters_ok:
31 halyavin 1711
	xor	eax,eax
157 heavyiron 1712
	call	process_macro
1713
	pop	[counter_limit]
1714
	pop	[macro_symbols]
1715
	pop	[free_additional_memory]
1716
      instant_macro_done:
31 halyavin 1717
	pop	ebx esi edx
157 heavyiron 1718
	cmp	byte [ebx],0
1719
	je	line_preprocessed
1720
	mov	[current_line],edi
1721
	mov	ecx,4
1722
	rep	movs dword [edi],[esi]
1723
	test	[macro_status],0Fh
1724
	jz	instant_macro_attached_line
1725
	mov	ax,3Bh
1726
	stos	word [edi]
1727
      instant_macro_attached_line:
31 halyavin 1728
	mov	esi,ebx
157 heavyiron 1729
	sub	edx,ebx
1730
	mov	ecx,edx
1731
	call	move_data
1732
	jmp	initial_preprocessing_ok
1733
do_irp:
31 halyavin 1734
	cmp	byte [esi],1Ah
157 heavyiron 1735
	jne	invalid_macro_arguments
1736
	movzx	eax,byte [esi+1]
1737
	lea	esi,[esi+2+eax]
1738
	lods	byte [esi]
1739
	cmp	[base_code],1
1740
	ja	irps_name_ok
1741
	cmp	al,'*'
1742
	jne	irp_name_ok
1743
	lods	byte [esi]
1744
      irp_name_ok:
31 halyavin 1745
	cmp	al,','
157 heavyiron 1746
	jne	invalid_macro_arguments
1747
	jmp	irp_parameters_start
1748
      irps_name_ok:
31 halyavin 1749
	cmp	al,','
157 heavyiron 1750
	jne	invalid_macro_arguments
1751
	mov	al,[esi]
1752
	or	al,al
1753
	jz	instant_macro_done
1754
	cmp	al,'{'
1755
	je	instant_macro_done
1756
      irp_parameters_start:
31 halyavin 1757
	xor	eax,eax
157 heavyiron 1758
	push	[free_additional_memory]
1759
	push	[macro_symbols]
1760
	mov	[macro_symbols],eax
1761
	push	[counter_limit]
1762
	mov	[counter_limit],eax
1763
	mov	[struc_name],eax
1764
	mov	ebx,esi
1765
	cmp	[base_code],1
1766
	ja	get_irps_parameter
1767
	mov	edx,[parameters_end]
1768
	mov	al,[edx]
1769
	push	eax
1770
	mov	byte [edx],0
1771
      get_irp_parameter:
31 halyavin 1772
	inc	[counter_limit]
157 heavyiron 1773
	mov	esi,[instant_macro_start]
1774
	inc	esi
1775
	call	get_macro_argument
1776
	cmp	byte [ebx],','
1777
	jne	irp_parameters_end
1778
	inc	ebx
1779
	jmp	get_irp_parameter
1780
      irp_parameters_end:
31 halyavin 1781
	mov	esi,ebx
157 heavyiron 1782
	pop	eax
1783
	mov	[esi],al
1784
	jmp	instant_macro_parameters_ok
1785
      get_irps_parameter:
31 halyavin 1786
	mov	esi,[instant_macro_start]
157 heavyiron 1787
	inc	esi
1788
	lods	byte [esi]
1789
	movzx	ecx,al
1790
	inc	[counter_limit]
1791
	mov	eax,[counter_limit]
1792
	call	add_macro_symbol
1793
	mov	[edx+12],ebx
1794
	cmp	byte [ebx],1Ah
1795
	je	irps_symbol
1796
	cmp	byte [ebx],22h
1797
	je	irps_quoted_string
1798
	mov	eax,1
1799
	jmp	irps_parameter_ok
1800
      irps_quoted_string:
31 halyavin 1801
	mov	eax,[ebx+1]
157 heavyiron 1802
	add	eax,1+4
1803
	jmp	irps_parameter_ok
1804
      irps_symbol:
31 halyavin 1805
	movzx	eax,byte [ebx+1]
157 heavyiron 1806
	add	eax,1+1
1807
      irps_parameter_ok:
31 halyavin 1808
	mov	[edx+8],eax
157 heavyiron 1809
	add	ebx,eax
1810
	cmp	byte [ebx],0
1811
	je	irps_parameters_end
1812
	cmp	byte [ebx],'{'
1813
	jne	get_irps_parameter
1814
      irps_parameters_end:
31 halyavin 1815
	mov	esi,ebx
157 heavyiron 1816
	jmp	instant_macro_parameters_ok
1817
do_match:
31 halyavin 1818
	mov	ebx,esi
157 heavyiron 1819
	call	skip_pattern
1820
	call	exact_match
1821
	mov	edx,edi
1822
	mov	al,[ebx]
1823
	cmp	al,1Ah
1824
	je	free_match
1825
	cmp	al,','
1826
	jne	instant_macro_done
1827
	cmp	esi,[parameters_end]
1828
	je	matched_pattern
1829
	jmp	instant_macro_done
1830
      free_match:
31 halyavin 1831
	add	edx,12
157 heavyiron 1832
	cmp	edx,[memory_end]
1833
	ja	out_of_memory
1834
	mov	[edx-12],ebx
1835
	mov	[edx-8],esi
1836
	call	skip_match_element
1837
	jc	try_different_matching
1838
	mov	[edx-4],esi
1839
	movzx	eax,byte [ebx+1]
1840
	lea	ebx,[ebx+2+eax]
1841
	cmp	byte [ebx],1Ah
1842
	je	free_match
1843
      find_exact_match:
31 halyavin 1844
	call	exact_match
157 heavyiron 1845
	cmp	esi,[parameters_end]
1846
	je	end_matching
1847
	cmp	byte [ebx],1Ah
1848
	je	free_match
1849
	mov	ebx,[edx-12]
1850
	movzx	eax,byte [ebx+1]
1851
	lea	ebx,[ebx+2+eax]
1852
	mov	esi,[edx-4]
1853
	jmp	match_more_elements
1854
      try_different_matching:
31 halyavin 1855
	sub	edx,12
157 heavyiron 1856
	cmp	edx,edi
1857
	je	instant_macro_done
1858
	mov	ebx,[edx-12]
1859
	movzx	eax,byte [ebx+1]
1860
	lea	ebx,[ebx+2+eax]
1861
	cmp	byte [ebx],1Ah
1862
	je	try_different_matching
1863
	mov	esi,[edx-4]
1864
      match_more_elements:
31 halyavin 1865
	call	skip_match_element
157 heavyiron 1866
	jc	try_different_matching
1867
	mov	[edx-4],esi
1868
	jmp	find_exact_match
1869
      skip_match_element:
31 halyavin 1870
	cmp	esi,[parameters_end]
157 heavyiron 1871
	je	cannot_match
1872
	mov	al,[esi]
1873
	cmp	al,1Ah
1874
	je	skip_match_symbol
1875
	cmp	al,22h
1876
	je	skip_match_quoted_string
1877
	add	esi,1
1878
	ret
1879
      skip_match_quoted_string:
31 halyavin 1880
	mov	eax,[esi+1]
157 heavyiron 1881
	add	esi,5
1882
	jmp	skip_match_ok
1883
      skip_match_symbol:
31 halyavin 1884
	movzx	eax,byte [esi+1]
157 heavyiron 1885
	add	esi,2
1886
      skip_match_ok:
31 halyavin 1887
	add	esi,eax
157 heavyiron 1888
	ret
1889
      cannot_match:
31 halyavin 1890
	stc
157 heavyiron 1891
	ret
1892
      exact_match:
31 halyavin 1893
	cmp	esi,[parameters_end]
157 heavyiron 1894
	je	exact_match_complete
1895
	mov	ah,[esi]
1896
	mov	al,[ebx]
1897
	cmp	al,','
1898
	je	exact_match_complete
1899
	cmp	al,1Ah
1900
	je	exact_match_complete
1901
	cmp	al,'='
1902
	je	match_verbatim
1903
	call	match_elements
1904
	je	exact_match
1905
      exact_match_complete:
31 halyavin 1906
	ret
157 heavyiron 1907
      match_verbatim:
31 halyavin 1908
	inc	ebx
157 heavyiron 1909
	call	match_elements
1910
	je	exact_match
1911
	dec	ebx
1912
	ret
1913
      match_elements:
31 halyavin 1914
	mov	al,[ebx]
157 heavyiron 1915
	cmp	al,1Ah
1916
	je	match_symbols
1917
	cmp	al,22h
1918
	je	match_quoted_strings
1919
	cmp	al,ah
1920
	je	symbol_characters_matched
1921
	ret
1922
      symbol_characters_matched:
31 halyavin 1923
	lea	ebx,[ebx+1]
157 heavyiron 1924
	lea	esi,[esi+1]
1925
	ret
1926
      match_quoted_strings:
31 halyavin 1927
	mov	ecx,[ebx+1]
157 heavyiron 1928
	add	ecx,5
1929
	jmp	compare_elements
1930
      match_symbols:
31 halyavin 1931
	movzx	ecx,byte [ebx+1]
157 heavyiron 1932
	add	ecx,2
1933
      compare_elements:
31 halyavin 1934
	mov	eax,esi
157 heavyiron 1935
	mov	ebp,edi
1936
	mov	edi,ebx
1937
	repe	cmps byte [esi],[edi]
1938
	jne	elements_mismatch
1939
	mov	ebx,edi
1940
	mov	edi,ebp
1941
	ret
1942
      elements_mismatch:
31 halyavin 1943
	mov	esi,eax
157 heavyiron 1944
	mov	edi,ebp
1945
	ret
1946
      end_matching:
31 halyavin 1947
	cmp	byte [ebx],','
157 heavyiron 1948
	jne	instant_macro_done
1949
      matched_pattern:
31 halyavin 1950
	xor	eax,eax
157 heavyiron 1951
	push	[free_additional_memory]
1952
	push	[macro_symbols]
1953
	mov	[macro_symbols],eax
1954
	push	[counter_limit]
1955
	mov	[counter_limit],eax
1956
	mov	[struc_name],eax
1957
	push	esi edi edx
1958
      add_matched_symbol:
31 halyavin 1959
	cmp	edi,[esp]
157 heavyiron 1960
	je	matched_symbols_ok
1961
	mov	esi,[edi]
1962
	inc	esi
1963
	lods	byte [esi]
1964
	movzx	ecx,al
1965
	xor	eax,eax
1966
	call	add_macro_symbol
1967
	mov	eax,[edi+4]
1968
	mov	dword [edx+12],eax
1969
	mov	ecx,[edi+8]
1970
	sub	ecx,eax
1971
	mov	dword [edx+8],ecx
1972
	add	edi,12
1973
	jmp	add_matched_symbol
1974
      matched_symbols_ok:
31 halyavin 1975
	pop	edx edi esi
157 heavyiron 1976
	jmp	instant_macro_parameters_ok
1977
31 halyavin 1978
 
1979
	push	dword [macro_status]
157 heavyiron 1980
	or	[macro_status],10h
1981
	push	[counter]
1982
	push	[macro_block]
1983
	push	[macro_block_line]
1984
	push	[macro_block_line_number]
1985
	push	[struc_label]
1986
	push	[struc_name]
1987
	push	eax
1988
	push	[current_line]
1989
	lods	byte [esi]
1990
	cmp	al,'{'
1991
	je	macro_instructions_start
1992
	or	al,al
1993
	jnz	unexpected_characters
1994
      find_macro_instructions:
31 halyavin 1995
	mov	[macro_line],esi
157 heavyiron 1996
	add	esi,16+2
1997
	lods	byte [esi]
1998
	or	al,al
1999
	jz	find_macro_instructions
2000
	cmp	al,'{'
2001
	je	macro_instructions_start
2002
	cmp	al,3Bh
2003
	jne	unexpected_characters
2004
	call	skip_foreign_symbol
2005
	jmp	find_macro_instructions
2006
      macro_instructions_start:
31 halyavin 2007
	mov	ecx,80000000h
157 heavyiron 2008
	mov	[macro_block],esi
2009
	mov	eax,[macro_line]
2010
	mov	[macro_block_line],eax
2011
	mov	[macro_block_line_number],ecx
2012
	xor	eax,eax
2013
	mov	[counter],eax
2014
	cmp	[counter_limit],eax
2015
	je	process_macro_line
2016
	inc	[counter]
2017
      process_macro_line:
31 halyavin 2018
	mov	[current_line],edi
157 heavyiron 2019
	lea	eax,[edi+10h]
2020
	cmp	eax,[memory_end]
2021
	jae	out_of_memory
2022
	mov	eax,[esp+4]
2023
	or	eax,eax
2024
	jz	instant_macro_line_header
2025
	stos	dword [edi]
2026
	mov	eax,ecx
2027
	stos	dword [edi]
2028
	mov	eax,[esp]
2029
	stos	dword [edi]
2030
	mov	eax,[macro_line]
2031
	stos	dword [edi]
2032
	jmp	macro_line_header_ok
2033
      instant_macro_line_header:
31 halyavin 2034
	mov	edx,[macro_line]
157 heavyiron 2035
	mov	eax,[edx]
2036
	stos	dword [edi]
2037
	mov	eax,[edx+4]
2038
	stos	dword [edi]
2039
	mov	eax,[edx+8]
2040
	stos	dword [edi]
2041
	mov	eax,[edx+12]
2042
	stos	dword [edi]
2043
      macro_line_header_ok:
31 halyavin 2044
	or	[macro_status],20h
157 heavyiron 2045
	push	ebx ecx
2046
	test	[macro_status],0Fh
2047
	jz	process_macro_line_element
2048
	mov	ax,3Bh
2049
	stos	word [edi]
2050
      process_macro_line_element:
31 halyavin 2051
	lea	eax,[edi+100h]
157 heavyiron 2052
	cmp	eax,[memory_end]
2053
	jae	out_of_memory
2054
	lods	byte [esi]
2055
	cmp	al,'}'
2056
	je	macro_line_processed
2057
	or	al,al
2058
	jz	macro_line_processed
2059
	cmp	al,1Ah
2060
	je	process_macro_symbol
2061
	cmp	al,3Bh
2062
	je	macro_foreign_line
2063
	and	[macro_status],not 20h
2064
	stos	byte [edi]
2065
	cmp	al,22h
2066
	jne	process_macro_line_element
2067
      copy_macro_string:
31 halyavin 2068
	mov	ecx,[esi]
157 heavyiron 2069
	add	ecx,4
2070
	call	move_data
2071
	jmp	process_macro_line_element
2072
      process_macro_symbol:
31 halyavin 2073
	push	esi edi
157 heavyiron 2074
	test	[macro_status],20h
2075
	jz	not_macro_directive
2076
	movzx	ecx,byte [esi]
2077
	inc	esi
2078
	mov	edi,macro_directives
2079
	call	get_directive
2080
	jnc	process_macro_directive
2081
	dec	esi
2082
	jmp	not_macro_directive
2083
      process_macro_directive:
31 halyavin 2084
	mov	edx,eax
157 heavyiron 2085
	pop	edi eax
2086
	mov	byte [edi],0
2087
	inc	edi
2088
	pop	ecx ebx
2089
	jmp	near edx
2090
      not_macro_directive:
31 halyavin 2091
	and	[macro_status],not 20h
157 heavyiron 2092
	movzx	ecx,byte [esi]
2093
	inc	esi
2094
	mov	eax,[counter]
2095
	call	get_macro_symbol
2096
	jnc	group_macro_symbol
2097
	xor	eax,eax
2098
	cmp	[counter],eax
2099
	je	multiple_macro_symbol_values
2100
	call	get_macro_symbol
2101
	jc	not_macro_symbol
2102
      replace_macro_symbol:
31 halyavin 2103
	pop	edi eax
157 heavyiron 2104
	mov	ecx,[edx+8]
2105
	and	ecx,not 80000000h
2106
	mov	edx,[edx+12]
2107
	or	edx,edx
2108
	jz	replace_macro_counter
2109
	xchg	esi,edx
2110
	call	move_data
2111
	mov	esi,edx
2112
	jmp	process_macro_line_element
2113
      group_macro_symbol:
31 halyavin 2114
	xor	eax,eax
157 heavyiron 2115
	cmp	[counter],eax
2116
	je	replace_macro_symbol
2117
	push	esi edx
2118
	sub	esi,ecx
2119
	call	get_macro_symbol
2120
	mov	ebx,edx
2121
	pop	edx esi
2122
	jc	replace_macro_symbol
2123
	cmp	edx,ebx
2124
	ja	replace_macro_symbol
2125
	mov	edx,ebx
2126
	jmp	replace_macro_symbol
2127
      multiple_macro_symbol_values:
31 halyavin 2128
	inc	eax
157 heavyiron 2129
	push	eax
2130
	call	get_macro_symbol
2131
	pop	eax
2132
	jc	not_macro_symbol
2133
	pop	edi
2134
	push	ecx
2135
	mov	ecx,[edx+8]
2136
	mov	edx,[edx+12]
2137
	xchg	esi,edx
2138
	btr	ecx,31
2139
	jc	enclose_macro_symbol_value
2140
	rep	movs byte [edi],[esi]
2141
	jmp	macro_symbol_value_ok
2142
      enclose_macro_symbol_value:
31 halyavin 2143
	mov	byte [edi],'<'
157 heavyiron 2144
	inc	edi
2145
	rep	movs byte [edi],[esi]
2146
	mov	byte [edi],'>'
2147
	inc	edi
2148
      macro_symbol_value_ok:
31 halyavin 2149
	cmp	eax,[counter_limit]
157 heavyiron 2150
	je	multiple_macro_symbol_values_ok
2151
	mov	byte [edi],','
2152
	inc	edi
2153
	mov	esi,edx
2154
	pop	ecx
2155
	push	edi
2156
	sub	esi,ecx
2157
	jmp	multiple_macro_symbol_values
2158
      multiple_macro_symbol_values_ok:
31 halyavin 2159
	pop	ecx eax
157 heavyiron 2160
	mov	esi,edx
2161
	jmp	process_macro_line_element
2162
      replace_macro_counter:
31 halyavin 2163
	mov	eax,[counter]
157 heavyiron 2164
	and	eax,not 80000000h
2165
	jz	group_macro_counter
2166
	add	ecx,eax
2167
	dec	ecx
2168
	call	store_number_symbol
2169
	jmp	process_macro_line_element
2170
      group_macro_counter:
31 halyavin 2171
	mov	edx,ecx
157 heavyiron 2172
	xor	ecx,ecx
2173
      multiple_macro_counter_values:
31 halyavin 2174
	push	ecx edx
157 heavyiron 2175
	add	ecx,edx
2176
	call	store_number_symbol
2177
	pop	edx ecx
2178
	inc	ecx
2179
	cmp	ecx,[counter_limit]
2180
	je	process_macro_line_element
2181
	mov	byte [edi],','
2182
	inc	edi
2183
	jmp	multiple_macro_counter_values
2184
      store_number_symbol:
31 halyavin 2185
	mov	ax,1Ah
157 heavyiron 2186
	stos	word [edi]
2187
	push	edi
2188
	mov	eax,ecx
2189
	mov	ecx,1000000000
2190
	xor	edx,edx
2191
	xor	bl,bl
2192
      store_number_digits:
31 halyavin 2193
	div	ecx
157 heavyiron 2194
	push	edx
2195
	or	bl,bl
2196
	jnz	store_number_digit
2197
	cmp	ecx,1
2198
	je	store_number_digit
2199
	or	al,al
2200
	jz	number_digit_ok
2201
	not	bl
2202
      store_number_digit:
31 halyavin 2203
	add	al,30h
157 heavyiron 2204
	stos	byte [edi]
2205
      number_digit_ok:
31 halyavin 2206
	mov	eax,ecx
157 heavyiron 2207
	xor	edx,edx
2208
	mov	ecx,10
2209
	div	ecx
2210
	mov	ecx,eax
2211
	pop	eax
2212
	or	ecx,ecx
2213
	jnz	store_number_digits
2214
	pop	ebx
2215
	mov	eax,edi
2216
	sub	eax,ebx
2217
	mov	[ebx-1],al
2218
	ret
2219
      not_macro_symbol:
31 halyavin 2220
	pop	edi esi
157 heavyiron 2221
	mov	al,1Ah
2222
	stos	byte [edi]
2223
	mov	al,[esi]
2224
	inc	esi
2225
	stos	byte [edi]
2226
	cmp	byte [esi],'.'
2227
	jne	copy_raw_symbol
2228
	mov	ebx,[esp+8+8]
2229
	or	ebx,ebx
2230
	jz	copy_raw_symbol
2231
	cmp	al,1
2232
	je	copy_struc_name
2233
	xchg	esi,ebx
2234
	movzx	ecx,byte [esi-1]
2235
	add	[edi-1],cl
2236
	jc	name_too_long
2237
	rep	movs byte [edi],[esi]
2238
	xchg	esi,ebx
2239
      copy_raw_symbol:
31 halyavin 2240
	movzx	ecx,al
157 heavyiron 2241
	rep	movs byte [edi],[esi]
2242
	jmp	process_macro_line_element
2243
      copy_struc_name:
31 halyavin 2244
	inc	esi
157 heavyiron 2245
	xchg	esi,ebx
2246
	movzx	ecx,byte [esi-1]
2247
	mov	[edi-1],cl
2248
	rep	movs byte [edi],[esi]
2249
	xchg	esi,ebx
2250
	mov	eax,[esp+8+12]
2251
	cmp	byte [eax],3Bh
2252
	je	process_macro_line_element
2253
	cmp	byte [eax],1Ah
2254
	jne	disable_replaced_struc_name
2255
	mov	byte [eax],3Bh
2256
	jmp	process_macro_line_element
2257
      disable_replaced_struc_name:
31 halyavin 2258
	mov	ebx,[esp+8+8]
157 heavyiron 2259
	push	esi edi
2260
	lea	edi,[ebx-3]
2261
	lea	esi,[edi-2]
2262
	lea	ecx,[esi+1]
2263
	sub	ecx,eax
2264
	std
2265
	rep	movs byte [edi],[esi]
2266
	cld
2267
	mov	word [eax],3Bh
2268
	pop	edi esi
2269
	jmp	process_macro_line_element
2270
      skip_foreign_symbol:
31 halyavin 2271
	lods	byte [esi]
157 heavyiron 2272
	movzx	eax,al
2273
	add	esi,eax
2274
      skip_foreign_line:
31 halyavin 2275
	lods	byte [esi]
157 heavyiron 2276
	cmp	al,1Ah
2277
	je	skip_foreign_symbol
2278
	cmp	al,3Bh
2279
	je	skip_foreign_symbol
2280
	cmp	al,22h
2281
	je	skip_foreign_string
2282
	or	al,al
2283
	jnz	skip_foreign_line
2284
	ret
2285
      skip_foreign_string:
31 halyavin 2286
	lods	dword [esi]
157 heavyiron 2287
	add	esi,eax
2288
	jmp	skip_foreign_line
2289
      macro_foreign_line:
31 halyavin 2290
	call	skip_foreign_symbol
157 heavyiron 2291
      macro_line_processed:
31 halyavin 2292
	mov	byte [edi],0
157 heavyiron 2293
	inc	edi
2294
	push	eax
2295
	call	preprocess_line
2296
	pop	eax
2297
	pop	ecx ebx
2298
	cmp	al,'}'
2299
	je	macro_block_processed
2300
      process_next_line:
31 halyavin 2301
	inc	ecx
157 heavyiron 2302
	mov	[macro_line],esi
2303
	add	esi,16+2
2304
	jmp	process_macro_line
2305
      macro_block_processed:
31 halyavin 2306
	call	close_macro_block
157 heavyiron 2307
	jc	process_macro_line
2308
	pop	[current_line]
2309
	add	esp,12
2310
	pop	[macro_block_line_number]
2311
	pop	[macro_block_line]
2312
	pop	[macro_block]
2313
	pop	[counter]
2314
	pop	eax
2315
	and	al,0F0h
2316
	and	[macro_status],0Fh
2317
	or	[macro_status],al
2318
	ret
2319
31 halyavin 2320
 
2321
	lods	byte [esi]
157 heavyiron 2322
	cmp	al,1Ah
2323
	jne	invalid_argument
2324
	mov	byte [edi-1],3Bh
2325
	xor	al,al
2326
	stos	byte [edi]
2327
      make_local_symbol:
31 halyavin 2328
	push	ecx
157 heavyiron 2329
	lods	byte [esi]
2330
	movzx	ecx,al
2331
	mov	eax,[counter]
2332
	call	add_macro_symbol
2333
	mov	[edx+12],edi
2334
	movzx	eax,[locals_counter]
2335
	add	eax,ecx
2336
	inc	eax
2337
	cmp	eax,100h
2338
	jae	name_too_long
2339
	lea	ebp,[edi+2+eax]
2340
	cmp	ebp,[memory_end]
2341
	jae	out_of_memory
2342
	mov	ah,al
2343
	mov	al,1Ah
2344
	stos	word [edi]
2345
	rep	movs byte [edi],[esi]
2346
	mov	al,'?'
2347
	stos	byte [edi]
2348
	push	esi
2349
	mov	esi,locals_counter+1
2350
	movzx	ecx,[locals_counter]
2351
	rep	movs byte [edi],[esi]
2352
	pop	esi
2353
	mov	eax,edi
2354
	sub	eax,[edx+12]
2355
	mov	[edx+8],eax
2356
	xor	al,al
2357
	stos	byte [edi]
2358
	mov	eax,locals_counter
2359
	movzx	ecx,byte [eax]
2360
      counter_loop:
31 halyavin 2361
	inc	byte [eax+ecx]
157 heavyiron 2362
	cmp	byte [eax+ecx],'9'+1
692 heavyiron 2363
	jb	counter_ok
157 heavyiron 2364
	jne	letter_digit
2365
	mov	byte [eax+ecx],'A'
2366
	jmp	counter_ok
2367
      letter_digit:
31 halyavin 2368
	cmp	byte [eax+ecx],'Z'+1
692 heavyiron 2369
	jb	counter_ok
2370
	jne	small_letter_digit
2371
	mov	byte [eax+ecx],'a'
2372
	jmp	counter_ok
2373
      small_letter_digit:
2374
	cmp	byte [eax+ecx],'z'+1
2375
	jb	counter_ok
2376
	mov	byte [eax+ecx],'0'
157 heavyiron 2377
	loop	counter_loop
2378
	inc	byte [eax]
692 heavyiron 2379
	movzx	ecx,byte [eax]
2380
	mov	byte [eax+ecx],'0'
2381
      counter_ok:
31 halyavin 2382
	pop	ecx
157 heavyiron 2383
	lods	byte [esi]
2384
	cmp	al,'}'
2385
	je	macro_block_processed
2386
	or	al,al
2387
	jz	process_next_line
2388
	cmp	al,','
2389
	jne	extra_characters_on_line
2390
	dec	edi
2391
	lods	byte [esi]
2392
	cmp	al,1Ah
2393
	je	make_local_symbol
2394
	jmp	invalid_argument
2395
common_block:
31 halyavin 2396
	call	close_macro_block
157 heavyiron 2397
	jc	process_macro_line
2398
	mov	[counter],0
2399
	jmp	new_macro_block
2400
forward_block:
31 halyavin 2401
	cmp	[counter_limit],0
157 heavyiron 2402
	je	common_block
2403
	call	close_macro_block
2404
	jc	process_macro_line
2405
	mov	[counter],1
2406
	jmp	new_macro_block
2407
reverse_block:
31 halyavin 2408
	cmp	[counter_limit],0
157 heavyiron 2409
	je	common_block
2410
	call	close_macro_block
2411
	jc	process_macro_line
2412
	mov	eax,[counter_limit]
2413
	or	eax,80000000h
2414
	mov	[counter],eax
2415
      new_macro_block:
31 halyavin 2416
	mov	[macro_block],esi
157 heavyiron 2417
	mov	eax,[macro_line]
2418
	mov	[macro_block_line],eax
2419
	mov	[macro_block_line_number],ecx
2420
	jmp	process_macro_line
2421
close_macro_block:
31 halyavin 2422
	cmp	[counter],0
157 heavyiron 2423
	je	block_closed
2424
	jl	reverse_counter
2425
	mov	eax,[counter]
2426
	cmp	eax,[counter_limit]
2427
	je	block_closed
2428
	inc	[counter]
2429
	jmp	continue_block
2430
      reverse_counter:
31 halyavin 2431
	mov	eax,[counter]
157 heavyiron 2432
	dec	eax
2433
	cmp	eax,80000000h
2434
	je	block_closed
2435
	mov	[counter],eax
2436
      continue_block:
31 halyavin 2437
	mov	esi,[macro_block]
157 heavyiron 2438
	mov	eax,[macro_block_line]
2439
	mov	[macro_line],eax
2440
	mov	ecx,[macro_block_line_number]
2441
	stc
2442
	ret
2443
      block_closed:
31 halyavin 2444
	clc
157 heavyiron 2445
	ret
2446
get_macro_symbol:
31 halyavin 2447
	push	ecx
157 heavyiron 2448
	call	find_macro_symbol_leaf
2449
	jc	macro_symbol_not_found
2450
	mov	edx,[ebx]
2451
	mov	ebx,esi
2452
      try_macro_symbol:
31 halyavin 2453
	or	edx,edx
157 heavyiron 2454
	jz	macro_symbol_not_found
2455
	mov	ecx,[esp]
2456
	mov	edi,[edx+4]
2457
	repe	cmps byte [esi],[edi]
2458
	je	macro_symbol_found
2459
	mov	esi,ebx
2460
	mov	edx,[edx]
2461
	jmp	try_macro_symbol
2462
      macro_symbol_found:
31 halyavin 2463
	pop	ecx
157 heavyiron 2464
	clc
2465
	ret
2466
      macro_symbol_not_found:
31 halyavin 2467
	pop	ecx
157 heavyiron 2468
	stc
2469
	ret
2470
      find_macro_symbol_leaf:
31 halyavin 2471
	shl	eax,8
157 heavyiron 2472
	mov	al,cl
2473
	mov	ebp,eax
2474
	mov	ebx,macro_symbols
2475
      follow_macro_symbols_tree:
31 halyavin 2476
	mov	edx,[ebx]
157 heavyiron 2477
	or	edx,edx
2478
	jz	no_such_macro_symbol
2479
	xor	eax,eax
2480
	shr	ebp,1
2481
	adc	eax,0
2482
	lea	ebx,[edx+eax*4]
2483
	or	ebp,ebp
2484
	jnz	follow_macro_symbols_tree
2485
	add	ebx,8
2486
	clc
2487
	ret
2488
      no_such_macro_symbol:
31 halyavin 2489
	stc
157 heavyiron 2490
	ret
2491
add_macro_symbol:
31 halyavin 2492
	push	ebx ebp
157 heavyiron 2493
	call	find_macro_symbol_leaf
2494
	jc	extend_macro_symbol_tree
2495
	mov	eax,[ebx]
2496
      make_macro_symbol:
31 halyavin 2497
	mov	edx,[free_additional_memory]
157 heavyiron 2498
	add	edx,16
2499
	cmp	edx,[labels_list]
2500
	ja	out_of_memory
2501
	xchg	edx,[free_additional_memory]
2502
	mov	[ebx],edx
2503
	mov	[edx],eax
2504
	mov	[edx+4],esi
2505
	pop	ebp ebx
2506
	ret
2507
      extend_macro_symbol_tree:
31 halyavin 2508
	mov	edx,[free_additional_memory]
157 heavyiron 2509
	add	edx,16
2510
	cmp	edx,[labels_list]
2511
	ja	out_of_memory
2512
	xchg	edx,[free_additional_memory]
2513
	xor	eax,eax
2514
	mov	[edx],eax
2515
	mov	[edx+4],eax
2516
	mov	[edx+8],eax
2517
	mov	[edx+12],eax
2518
	shr	ebp,1
2519
	adc	eax,0
2520
	mov	[ebx],edx
2521
	lea	ebx,[edx+eax*4]
2522
	or	ebp,ebp
2523
	jnz	extend_macro_symbol_tree
2524
	add	ebx,8
2525
	xor	eax,eax
2526
	jmp	make_macro_symbol
2527
31 halyavin 2528
 
2529
	lods	byte [esi]
157 heavyiron 2530
	cmp	al,22h
2531
	jne	invalid_argument
2532
	lods	dword [esi]
2533
	cmp	byte [esi+eax],0
2534
	jne	extra_characters_on_line
2535
	push	esi
2536
	push	edi
2537
	mov	ebx,[current_line]
2538
      find_current_file_path:
31 halyavin 2539
	mov	esi,[ebx]
157 heavyiron 2540
	test	byte [ebx+7],80h
2541
	jz	copy_current_file_path
2542
	mov	ebx,[ebx+8]
2543
	jmp	find_current_file_path
2544
      copy_current_file_path:
31 halyavin 2545
	lods	byte [esi]
157 heavyiron 2546
	stos	byte [edi]
2547
	or	al,al
2548
	jnz	copy_current_file_path
2549
      cut_current_file_name:
31 halyavin 2550
	cmp	edi,[esp]
157 heavyiron 2551
	je	current_file_path_ok
2552
	cmp	byte [edi-1],'\'
2553
	je	current_file_path_ok
2554
	cmp	byte [edi-1],'/'
2555
	je	current_file_path_ok
2556
	dec	edi
2557
	jmp	cut_current_file_name
2558
      current_file_path_ok:
31 halyavin 2559
	mov	esi,[esp+4]
157 heavyiron 2560
	call	preprocess_path
2561
	pop	edx
2562
	mov	esi,edx
2563
	call	open
2564
	jnc	include_path_ok
2565
	mov	ebp,[include_paths]
2566
      try_include_directories:
31 halyavin 2567
	mov	edi,esi
157 heavyiron 2568
	mov	esi,ebp
2569
	cmp	byte [esi],0
2570
	je	try_in_current_directory
2571
	push	ebp
2572
	push	edi
2573
      copy_include_directory:
31 halyavin 2574
	lods	byte [esi]
157 heavyiron 2575
	cmp	al,';'
2576
	je	include_directory_ok
2577
	stos	byte [edi]
2578
	or	al,al
2579
	jnz	copy_include_directory
2580
	dec	esi
2581
	dec	edi
2582
      include_directory_ok:
31 halyavin 2583
	cmp	byte [edi-1],'/'
157 heavyiron 2584
	je	path_separator_ok
2585
	cmp	byte [edi-1],'\'
2586
	je	path_separator_ok
2587
	mov	al,'/'
2588
	stos	byte [edi]
2589
      path_separator_ok:
31 halyavin 2590
	mov	[esp+4],esi
157 heavyiron 2591
	mov	esi,[esp+8]
2592
	call	preprocess_path
2593
	pop	edx
2594
	mov	esi,edx
2595
	call	open
2596
	pop	ebp
2597
	jnc	include_path_ok
2598
	jmp	try_include_directories
2599
	mov	edi,esi
2600
      try_in_current_directory:
31 halyavin 2601
	mov	esi,[esp]
157 heavyiron 2602
	push	edi
2603
	call	preprocess_path
2604
	pop	edx
2605
	mov	esi,edx
2606
	call	open
2607
	jc	file_not_found
2608
      include_path_ok:
31 halyavin 2609
	mov	edi,[esp]
157 heavyiron 2610
      copy_preprocessed_path:
31 halyavin 2611
	lods	byte [esi]
157 heavyiron 2612
	stos	byte [edi]
2613
	or	al,al
2614
	jnz	copy_preprocessed_path
2615
	pop	esi
2616
	lea	ecx,[edi-1]
2617
	sub	ecx,esi
2618
	mov	[esi-4],ecx
2619
	push	dword [macro_status]
2620
	and	[macro_status],0Fh
2621
	call	preprocess_file
2622
	pop	eax
2623
	mov	[macro_status],al
2624
	jmp	line_preprocessed
2625
      preprocess_path:
31 halyavin 2626
	lods	byte [esi]
157 heavyiron 2627
	cmp	al,'%'
2628
	je	environment_variable
2629
	stos	byte [edi]
2630
	or	al,al
2631
	jnz	preprocess_path
2632
	cmp	edi,[memory_end]
2633
	ja	out_of_memory
2634
	ret
2635
      environment_variable:
31 halyavin 2636
	mov	ebx,esi
157 heavyiron 2637
      find_variable_end:
31 halyavin 2638
	lods	byte [esi]
157 heavyiron 2639
	or	al,al
2640
	jz	not_environment_variable
2641
	cmp	al,'%'
2642
	jne	find_variable_end
2643
	mov	byte [esi-1],0
2644
	push	esi
2645
	mov	esi,ebx
2646
	call	get_environment_variable
2647
	pop	esi
2648
	mov	byte [esi-1],'%'
2649
	jmp	preprocess_path
2650
      not_environment_variable:
31 halyavin 2651
	mov	al,'%'
157 heavyiron 2652
	stos	byte [edi]
2653
	mov	esi,ebx
2654
	jmp	preprocess_path
2655
>