Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 1
/*
2
Copyright (C) 1996-1997 Id Software, Inc.
3
 
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
8
 
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
 
13
See the GNU General Public License for more details.
14
 
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
 
19
*/
20
//
21
// gas to MASM source code converter
22
//
23
 
24
#include 
25
#include 
26
#include 
27
 
28
#define MAX_TOKENS			100
29
#define MAX_TOKEN_LENGTH	1024
30
#define LF					0x0A
31
 
32
typedef enum {NOT_WHITESPACE, WHITESPACE, TOKEN_AVAILABLE, LINE_DONE, FILE_DONE, PARSED_OKAY} tokenstat;
33
typedef enum {NOSEG, DATASEG, TEXTSEG} segtype;
34
 
35
int		tokennum;
36
int		inline, outline;
37
 
38
char	*token;
39
char	tokens[MAX_TOKENS][MAX_TOKEN_LENGTH+1];
40
 
41
segtype	currentseg = NOSEG;
42
 
43
typedef struct {
44
	char	*text;
45
	char	*emit;
46
	int		numtokens;
47
	void	(*parsefunc) (void);
48
} parsefield;
49
 
50
 
51
void errorexit (void);
52
 
53
 
54
//==============================================
55
 
56
typedef struct {
57
	char	*text;
58
	char	*emit;
59
	int		len;
60
} regdesc;
61
 
62
regdesc	reglist[] = {
63
	{"%eax", "eax", 4},
64
	{"%ebx", "ebx", 4},
65
	{"%ecx", "ecx", 4},
66
	{"%edx", "edx", 4},
67
	{"%esi", "esi", 4},
68
	{"%edi", "edi", 4},
69
	{"%ebp", "ebp", 4},
70
	{"%esp", "esp", 4},
71
	{"%ax", "ax", 3},
72
	{"%bx", "bx", 3},
73
	{"%cx", "cx", 3},
74
	{"%dx", "dx", 3},
75
	{"%si", "si", 3},
76
	{"%di", "di", 3},
77
	{"%bp", "bp", 3},
78
	{"%sp", "sp", 3},
79
	{"%al", "al", 3},
80
	{"%bl", "bl", 3},
81
	{"%cl", "cl", 3},
82
	{"%dl", "dl", 3},
83
	{"%ah", "ah", 3},
84
	{"%bh", "bh", 3},
85
	{"%ch", "ch", 3},
86
	{"%dh", "dh", 3},
87
	{"%st(0)", "st(0)", 6},
88
	{"%st(1)", "st(1)", 6},
89
	{"%st(2)", "st(2)", 6},
90
	{"%st(3)", "st(3)", 6},
91
	{"%st(4)", "st(4)", 6},
92
	{"%st(5)", "st(5)", 6},
93
	{"%st(6)", "st(6)", 6},
94
	{"%st(7)", "st(7)", 6},
95
};
96
 
97
int	numregs = sizeof (reglist) / sizeof (reglist[0]);
98
 
99
//==============================================
100
 
101
 
102
void emitanoperand (int tnum, char *type, int notdata)
103
{
104
	int		i, index, something_outside_parens, regfound;
105
	int		parencount;
106
	char	*pt;
107
	char	temp[MAX_TOKEN_LENGTH+1];
108
 
109
	pt = tokens[tnum];
110
 
111
	if (pt[0] == '%')
112
	{
113
	// register
114
		for (i=0 ; i
115
		{
116
			if (!strcmpi (pt, reglist[i].text))
117
			{
118
				printf ("%s", reglist[i].emit);
119
				return;
120
			}
121
		}
122
 
123
		fprintf (stderr, "Error: bad register %s\n", pt);
124
		errorexit ();
125
	}
126
	else if (pt[0] == '$')
127
	{
128
	// constant
129
		if (pt[1] == '(')
130
		{
131
			if ((pt[2] > '9') || (pt[2] < '0'))
132
			{
133
				i = 2;
134
				printf ("offset ");
135
 
136
				parencount = 1;
137
 
138
				while ((pt[i] != ')') || (parencount > 1))
139
				{
140
					if (!pt[i])
141
					{
142
						fprintf (stderr, "mismatched parens");
143
						errorexit ();
144
					}
145
 
146
					if (pt[i] == ')')
147
						parencount--;
148
					else if (pt[i] == '(')
149
						parencount++;
150
 
151
					printf ("%c", pt[i]);
152
					i++;
153
				}
154
			}
155
			else
156
			{
157
				pt++;
158
 
159
				parencount = 1;
160
 
161
				for (i=1 ; (pt[i] != ')') || (parencount > 1) ; i++)
162
				{
163
					if (!pt[i])
164
					{
165
						fprintf (stderr, "mismatched parens");
166
						errorexit ();
167
					}
168
 
169
					if (pt[i] == ')')
170
						parencount--;
171
					else if (pt[i] == '(')
172
						parencount++;
173
				}
174
 
175
				pt[i] = 0;
176
 
177
				if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X')))
178
				{
179
					printf ("0%sh", &pt[3]);
180
				}
181
				else
182
				{
183
					printf ("%s", &pt[1]);
184
				}
185
 			}
186
		}
187
		else if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X')))
188
		{
189
			printf ("0%sh", &pt[3]);
190
		}
191
		else if ((pt[1] >= '0') && (pt[1] <= '9'))
192
		{
193
			printf ("%s", &pt[1]);
194
		}
195
		else
196
		{
197
			printf ("offset %s", &pt[1]);
198
		}
199
	}
200
	else if (!notdata && ((pt[0] >= '0') && (pt[0] <= '9')))
201
	{
202
		pt--;
203
 
204
		if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X')))
205
		{
206
			printf ("0%sh", &pt[3]);
207
		}
208
		else
209
		{
210
			printf ("%s", &pt[1]);
211
		}
212
	}
213
	else
214
	{
215
	// must be a memory location
216
		strcpy (temp, type);
217
		index = strlen (temp);
218
 
219
		if (notdata)
220
			temp[index++] = '[';
221
 
222
		something_outside_parens = 0;
223
 
224
		while (*pt)
225
		{
226
			if (index > (MAX_TOKEN_LENGTH - 10))
227
			{
228
				fprintf (stderr, "Error: operand too long %s\n",
229
						 tokens[tnum]);
230
				errorexit ();
231
			}
232
 
233
			if (*pt != ')')
234
			{
235
				if (*pt == '(')
236
				{
237
					if (something_outside_parens)
238
						temp[index++] = '+';
239
				}
240
				else if (*pt == '%')
241
				{
242
					regfound = 0;
243
 
244
					for (i=0 ; i
245
					{
246
						if (!strnicmp (pt, reglist[i].text,
247
							reglist[i].len))
248
						{
249
							strcpy (&temp[index], reglist[i].emit);
250
							index += strlen (reglist[i].emit);
251
							pt += strlen (reglist[i].text) - 1;
252
							regfound = 1;
253
							break;
254
						}
255
					}
256
 
257
					if (!regfound)
258
					{
259
						fprintf (stderr, "Error: bad register %s\n", pt);
260
						errorexit ();
261
					}
262
				}
263
				else if (*pt == ',')
264
				{
265
					pt++;
266
 
267
					if ((*pt >= '1') && (*pt <= '8'))
268
					{
269
						temp[index++] = '*';
270
						temp[index++] = *pt;
271
					}
272
					else if (*pt != ')')
273
					{
274
						if (temp[index-1] != '+')
275
							temp[index++] = '+';
276
					}
277
				}
278
				else
279
				{
280
					something_outside_parens = 1;
281
 
282
					// handle hexadecimal constants in addresses
283
					if ((*pt == '0') &&
284
						((*(pt+1) == 'x') || (*(pt+1) == 'X')))
285
					{
286
						pt += 2;
287
 
288
						do
289
						{
290
							temp[index++] = *pt++;
291
						} while (((*pt >= '0') && (*pt <= '9'))     ||
292
								 ((*pt >= 'a') && (*pt <= 'f')) ||
293
								 ((*pt >= 'A') && (*pt <= 'F')));
294
 
295
						pt--;
296
						temp[index++] = 'h';
297
					}
298
					else
299
					{
300
						temp[index++] = *pt;
301
					}
302
				}
303
			}
304
 
305
			pt++;
306
		}
307
 
308
		if (notdata)
309
			temp[index++] = ']';
310
 
311
		temp[index] = 0;
312
		printf ("%s", temp);
313
	}
314
}
315
 
316
 
317
void datasegstart (void)
318
{
319
	if (currentseg == DATASEG)
320
		return;
321
 
322
	if (currentseg == TEXTSEG)
323
		printf ("_TEXT ENDS\n");
324
 
325
	printf ("_DATA SEGMENT");
326
 
327
	currentseg = DATASEG;
328
}
329
 
330
 
331
void textsegstart (void)
332
{
333
	if (currentseg == TEXTSEG)
334
		return;
335
 
336
	if (currentseg == DATASEG)
337
		printf ("_DATA ENDS\n");
338
 
339
	printf ("_TEXT SEGMENT");
340
 
341
	currentseg = TEXTSEG;
342
}
343
 
344
 
345
void emitdata (void)
346
{
347
	int		i;
348
 
349
	for (i=1 ; i<(tokennum-1) ; i++)
350
		printf (" %s,", tokens[i]);
351
 
352
	printf (" %s", tokens[tokennum-1]);
353
}
354
 
355
 
356
void emitonedata (void)
357
{
358
 
359
	printf (" %s", tokens[1]);
360
}
361
 
362
 
363
void emitonecalldata (void)
364
{
365
	int	i, isaddr, len;
366
 
367
	if (tokens[1][0] == '*')
368
	{
369
		printf (" dword ptr[%s]", &tokens[1][1]);
370
	}
371
	else
372
	{
373
		isaddr = 0;
374
		len = strlen(tokens[1]);
375
 
376
		for (i=0 ; i
377
		{
378
			if (tokens[1][i] == '(')
379
			{
380
				isaddr = 1;
381
				break;
382
			}
383
		}
384
 
385
		if (!isaddr)
386
		{
387
			printf (" near ptr %s", tokens[1]);
388
		}
389
		else
390
		{
391
			emitanoperand (1, " dword ptr", 1);
392
		}
393
	}
394
}
395
 
396
 
397
void emitonejumpdata (void)
398
{
399
	int	i, isaddr, len;
400
 
401
	if (tokens[1][0] == '*')
402
	{
403
		printf (" dword ptr[%s]", &tokens[1][1]);
404
	}
405
	else
406
	{
407
		isaddr = 0;
408
		len = strlen(tokens[1]);
409
 
410
		for (i=0 ; i
411
		{
412
			if (tokens[1][i] == '(')
413
			{
414
				isaddr = 1;
415
				break;
416
			}
417
		}
418
 
419
		if (!isaddr)
420
		{
421
			printf (" %s", tokens[1]);
422
		}
423
		else
424
		{
425
			emitanoperand (1, " dword ptr", 1);
426
		}
427
	}
428
}
429
 
430
 
431
void emitexterndef (void)
432
{
433
 
434
	printf (" %s:dword", tokens[1]);
435
}
436
 
437
 
438
void nooperands (void)
439
{
440
 
441
}
442
 
443
 
444
void emitoneoperandl (void)
445
{
446
 
447
	printf (" ");
448
	emitanoperand (1, "ds:dword ptr", 1);
449
}
450
 
451
 
452
void emitoneoperandb (void)
453
{
454
 
455
	printf (" ");
456
	emitanoperand (1, "ds:byte ptr", 1);
457
}
458
 
459
 
460
void emitoneoperandw (void)
461
{
462
 
463
	printf (" ");
464
	emitanoperand (1, "ds:word ptr", 1);
465
}
466
 
467
 
468
void emittwooperandsl (void)
469
{
470
 
471
	printf (" ");
472
	emitanoperand (2, "ds:dword ptr", 1);
473
	printf (",");
474
	emitanoperand (1, "ds:dword ptr", 1);
475
}
476
 
477
 
478
void emittwooperandsb (void)
479
{
480
 
481
	printf (" ");
482
	emitanoperand (2, "ds:byte ptr", 1);
483
	printf (",");
484
	emitanoperand (1, "ds:byte ptr", 1);
485
}
486
 
487
 
488
void emittwooperandsw (void)
489
{
490
 
491
	printf (" ");
492
	emitanoperand (2, "ds:word ptr", 1);
493
	printf (",");
494
	emitanoperand (1, "ds:word ptr", 1);
495
}
496
 
497
 
498
void emit_0_or_1_operandsl (void)
499
{
500
 
501
	if (tokennum == 2)
502
	{
503
		printf (" ");
504
		emitanoperand (1, "ds:dword ptr", 1);
505
	}
506
}
507
 
508
 
509
void emit_1_or_2_operandsl (void)
510
{
511
	int		j;
512
 
513
	if (tokennum == 2)
514
	{
515
		printf (" ");
516
		emitanoperand (1, "ds:dword ptr", 1);
517
	}
518
	else if (tokennum == 3)
519
	{
520
		printf (" ");
521
		emitanoperand (2, "ds:dword ptr", 1);
522
		printf (",");
523
		emitanoperand (1, "ds:dword ptr", 1);
524
	}
525
	else
526
	{
527
 
528
		fprintf (stderr, "Error: too many operands\n");
529
 
530
		for (j=0 ; j
531
			fprintf (stderr, "%s\n", tokens[j]);
532
 
533
		fprintf (stderr, "\n");
534
		errorexit ();
535
	}
536
}
537
 
538
 
539
void emit_1_or_2_operandsl_vartext (char *str0, char *str1)
540
{
541
	int		j;
542
 
543
	if (tokennum == 2)
544
	{
545
		printf (" %s ", str0);
546
		emitanoperand (1, "ds:dword ptr", 1);
547
	}
548
	else if (tokennum == 3)
549
	{
550
		if (!strcmpi (tokens[2], "%st(0)"))
551
			printf (" %s ", str0);
552
		else
553
			printf (" %s ", str1);
554
 
555
		emitanoperand (2, "ds:dword ptr", 1);
556
		printf (",");
557
		emitanoperand (1, "ds:dword ptr", 1);
558
	}
559
	else
560
	{
561
 
562
		fprintf (stderr, "Error: too many operands\n");
563
 
564
		for (j=0 ; j
565
			fprintf (stderr, "%s\n", tokens[j]);
566
 
567
		fprintf (stderr, "\n");
568
		errorexit ();
569
	}
570
}
571
 
572
 
573
void special_fdivl (void)
574
{
575
 
576
	emit_1_or_2_operandsl_vartext ("fdiv", "fdivr");
577
}
578
 
579
 
580
void special_fdivpl (void)
581
{
582
 
583
	emit_1_or_2_operandsl_vartext ("fdivp", "fdivrp");
584
}
585
 
586
 
587
void special_fdivrl (void)
588
{
589
 
590
	emit_1_or_2_operandsl_vartext ("fdivr", "fdiv");
591
}
592
 
593
 
594
void special_fdivrpl (void)
595
{
596
 
597
	emit_1_or_2_operandsl_vartext ("fdivrp", "fdivp");
598
}
599
 
600
 
601
void special_fsubl (void)
602
{
603
 
604
	emit_1_or_2_operandsl_vartext ("fsub", "fsubr");
605
}
606
 
607
 
608
void special_fsubpl (void)
609
{
610
 
611
	emit_1_or_2_operandsl_vartext ("fsubp", "fsubrp");
612
}
613
 
614
 
615
void special_fsubrl (void)
616
{
617
 
618
	emit_1_or_2_operandsl_vartext ("fsubr", "fsub");
619
}
620
 
621
 
622
void special_fsubrpl (void)
623
{
624
 
625
	emit_1_or_2_operandsl_vartext ("fsubrp", "fsubp");
626
}
627
 
628
 
629
void emit_multiple_data (void)
630
{
631
	int		i;
632
 
633
	printf (" ");
634
 
635
	for (i=1 ; i<(tokennum-1) ; i++)
636
	{
637
		emitanoperand (i, "", 0);
638
		printf (", ");
639
	}
640
 
641
	emitanoperand (i, "", 0);
642
}
643
 
644
 
645
//==============================================
646
 
647
parsefield	parsedata[] = {
648
	{".align", " align", 2, emitonedata},
649
	{".byte",  " db", -2, emit_multiple_data},
650
	{".data",  "", 1, datasegstart},
651
	{".extern"," externdef", 2, emitexterndef},
652
	{".globl", " public", -2, emit_multiple_data},
653
	{".long",  " dd", -2, emit_multiple_data},
654
	{".single"," dd", -2, emit_multiple_data},
655
	{".text",  "", 1, textsegstart},
656
	{"adcl",   " adc", 3, emittwooperandsl},
657
	{"addb",   " add", 3, emittwooperandsb},
658
	{"addl",   " add", 3, emittwooperandsl},
659
	{"andb",   " and", 3, emittwooperandsb},
660
	{"andl",   " and", 3, emittwooperandsl},
661
	{"call",   " call", 2, emitonecalldata},
662
	{"cmpb",   " cmp", 3, emittwooperandsb},
663
	{"cmpl",   " cmp", 3, emittwooperandsl},
664
	{"cmpw",   " cmp", 3, emittwooperandsw},
665
	{"decl",   " dec", 2, emitoneoperandl},
666
	{"decw",   " dec", 2, emitoneoperandw},
667
	{"divl",   " div", 2, emitoneoperandl},
668
	{"fadd",   " fadd", -2, emit_1_or_2_operandsl},
669
	{"faddp",  " faddp", -2, emit_1_or_2_operandsl},
670
	{"faddps", " faddp", -2, emit_1_or_2_operandsl},
671
	{"fadds",  " fadd", -2, emit_1_or_2_operandsl},
672
	{"fcom",   " fcom", 2, emitoneoperandl},
673
	{"fcoms",  " fcom", 2, emitoneoperandl},
674
	{"fcomp",  " fcomp", 2, emitoneoperandl},
675
	{"fcomps", " fcomp", 2, emitoneoperandl},
676
	{"fdiv",   "", -2, special_fdivl},
677
	{"fdivp",  "", -2, special_fdivpl},
678
	{"fdivr",  "", -2, special_fdivrl},
679
	{"fdivrp", "", -2, special_fdivrpl},
680
	{"fdivrs", "", -2, special_fdivrl},
681
	{"fildl",  " fild", 2, emitoneoperandl},
682
	{"fistl",  " fist", 2, emitoneoperandl},
683
	{"fistpl", " fistp", 2, emitoneoperandl},
684
	{"fld",    " fld", 2, emitoneoperandl},
685
	{"fldcw",  " fldcw", 2, emitoneoperandw},
686
	{"fldenv", " fldenv", 2, emitoneoperandl},
687
	{"flds",   " fld", 2, emitoneoperandl},
688
	{"fmul",   " fmul", -2, emit_1_or_2_operandsl},
689
	{"fmulp",  " fmulp", -2, emit_1_or_2_operandsl},
690
	{"fmulps", " fmulp", -2, emit_1_or_2_operandsl},
691
	{"fmuls",  " fmul", -2, emit_1_or_2_operandsl},
692
	{"fnstcw", " fnstcw", 2, emitoneoperandw},
693
	{"fnstenv"," fnstenv", 2, emitoneoperandl},
694
	{"fnstsw", " fnstsw", 2, emitoneoperandw},
695
	{"fstp",   " fstp", 2, emitoneoperandl},
696
	{"fstps",  " fstp", 2, emitoneoperandl},
697
	{"fsts",   " fst", 2, emitoneoperandl},
698
	{"fsubr",  "", -2, special_fsubrl},
699
	{"fsubrp", "", -2, special_fsubrpl},
700
	{"fsubrs", "", -2, special_fsubrl},
701
	{"fsub",   "", -2, special_fsubl},
702
	{"fsubp",  "", -2, special_fsubpl},
703
	{"fsubps", "", -2, special_fsubpl},
704
	{"fsubs",  "", -2, special_fsubl},
705
	{"fxch",   " fxch", 2, emitoneoperandl},
706
	{"imull",  " imul", -2, emit_1_or_2_operandsl},
707
	{"incl",   " inc", 2, emitoneoperandl},
708
	{"ja",     " ja", 2, emitonedata},
709
	{"jae",    " jae", 2, emitonedata},
710
	{"jb",     " jb", 2, emitonedata},
711
	{"jbe",    " jbe", 2, emitonedata},
712
	{"jc",     " jc", 2, emitonedata},
713
	{"je",     " je", 2, emitonedata},
714
	{"jg",     " jg", 2, emitonedata},
715
	{"jge",    " jge", 2, emitonedata},
716
	{"jl",     " jl", 2, emitonedata},
717
	{"jle",    " jle", 2, emitonedata},
718
	{"jmp",    " jmp", 2, emitonejumpdata},
719
	{"jna",    " jna", 2, emitonedata},
720
	{"jnae",   " jnae", 2, emitonedata},
721
	{"jnb",    " jnb", 2, emitonedata},
722
	{"jnbe",   " jnbe", 2, emitonedata},
723
	{"jnc",    " jnc", 2, emitonedata},
724
	{"jne",    " jne", 2, emitonedata},
725
	{"jng",    " jng", 2, emitonedata},
726
	{"jnge",   " jnge", 2, emitonedata},
727
	{"jnl",    " jnl", 2, emitonedata},
728
	{"jnle",   " jnle", 2, emitonedata},
729
	{"jns",    " jns", 2, emitonedata},
730
	{"jnz",    " jnz", 2, emitonedata},
731
	{"js",     " js", 2, emitonedata},
732
	{"jz",     " jz", 2, emitonedata},
733
	{"leal",   " lea", 3, emittwooperandsl},
734
	{"movb",   " mov", 3, emittwooperandsb},
735
	{"movl",   " mov", 3, emittwooperandsl},
736
	{"movw",   " mov", 3, emittwooperandsw},
737
	{"negl",   " neg", 2, emitoneoperandl},
738
	{"orb",    " or", 3, emittwooperandsb},
739
	{"orl",    " or", 3, emittwooperandsl},
740
	{"popl",   " pop", 2, emitoneoperandl},
741
	{"pushl",  " push", 2, emitoneoperandl},
742
	{"ret",    " ret", -1, emit_0_or_1_operandsl},
743
	{"rorl",   " ror", 3, emittwooperandsl},
744
	{"sarl",   " sar", 3, emittwooperandsl},
745
	{"sbbl",   " sbb", 3, emittwooperandsl},
746
	{"shll",   " shl", 3, emittwooperandsl},
747
	{"shrl",   " shr", 3, emittwooperandsl},
748
	{"subl",   " sub", 3, emittwooperandsl},
749
	{"testb",  " test", 3, emittwooperandsb},
750
	{"testl",  " test", 3, emittwooperandsl},
751
	{"xorb",   " xor", 3, emittwooperandsb},
752
	{"xorl",   " xor", 3, emittwooperandsl},
753
};
754
 
755
int	numparse = sizeof (parsedata) / sizeof (parsedata[0]);
756
 
757
//==============================================
758
 
759
void errorexit (void)
760
{
761
	fprintf (stderr, "In line: %d, out line: %d\n", inline, outline);
762
	exit (1);
763
}
764
 
765
 
766
tokenstat whitespace (char c)
767
{
768
	if (c == '\n')
769
		return LINE_DONE;
770
 
771
	if ((c <= ' ') ||
772
		(c > 127) ||
773
		(c == ','))
774
	{
775
		return WHITESPACE;
776
	}
777
 
778
	return NOT_WHITESPACE;
779
}
780
 
781
 
782
int gettoken (void)
783
{
784
	char		c;
785
	int			count, parencount;
786
	tokenstat	stat;
787
 
788
	do
789
	{
790
		if ((c = getchar ()) == EOF)
791
			return FILE_DONE;
792
 
793
		if ((stat = whitespace (c)) == LINE_DONE)
794
			return LINE_DONE;
795
	} while (stat == WHITESPACE);
796
 
797
	token[0] = c;
798
	count = 1;
799
 
800
	if (c == '~')
801
	{
802
		count--;
803
		token[count++] = 'n';
804
		token[count++] = 'o';
805
		token[count++] = 't';
806
		token[count++] = ' ';
807
	}
808
 
809
	if (c == '(')
810
	{
811
		do
812
		{
813
			if ((c = getchar ()) == EOF)
814
			{
815
				fprintf (stderr, "EOF in middle of parentheses\n");
816
				errorexit ();
817
			}
818
 
819
			token[count++] = c;
820
 
821
		} while (c != ')');
822
	}
823
 
824
	for ( ;; )
825
	{
826
		if ((c = getchar ()) == EOF)
827
		{
828
			token[count] = 0;
829
			return TOKEN_AVAILABLE;
830
		}
831
 
832
		if (whitespace (c) == LINE_DONE)
833
		{
834
			if (ungetc (c, stdin) == EOF)
835
			{
836
				fprintf (stderr, "Couldn't unget character\n");
837
				errorexit ();
838
			}
839
 
840
			token[count] = 0;
841
			return TOKEN_AVAILABLE;
842
		}
843
 
844
		if (whitespace (c) == WHITESPACE)
845
		{
846
			token[count] = 0;
847
			return TOKEN_AVAILABLE;
848
		}
849
 
850
		if (count >= MAX_TOKEN_LENGTH)
851
		{
852
			fprintf (stderr, "Error: token too long\n");
853
			errorexit ();
854
		}
855
 
856
		token[count++] = c;
857
 
858
		if (c == '~')
859
		{
860
			count--;
861
			token[count++] = 'n';
862
			token[count++] = 'o';
863
			token[count++] = 't';
864
			token[count++] = ' ';
865
		}
866
		else if (c == '(')
867
		{
868
			parencount = 1;
869
 
870
			do
871
			{
872
				if ((c = getchar ()) == EOF)
873
				{
874
					fprintf (stderr, "EOF in middle of parentheses\n");
875
					errorexit ();
876
				}
877
 
878
				if (c == '(')
879
					parencount++;
880
				else if (c == ')')
881
					parencount--;
882
 
883
				if (c == '~')
884
				{
885
					token[count++] = 'n';
886
					token[count++] = 'o';
887
					token[count++] = 't';
888
					token[count++] = ' ';
889
				}
890
				else
891
				{
892
					token[count++] = c;
893
				}
894
 
895
			} while ((c != ')') || (parencount > 0));
896
		}
897
	}
898
}
899
 
900
 
901
tokenstat parseline (void)
902
{
903
	tokenstat	stat;
904
	int			i, j, firsttoken, labelfound;
905
	int			mnemfound;
906
 
907
	firsttoken = 1;
908
	tokennum = 0;
909
	labelfound = 0;
910
 
911
	for ( ;; )
912
	{
913
		token = tokens[tokennum];
914
		stat = gettoken ();
915
 
916
		switch (stat)
917
		{
918
		case FILE_DONE:
919
			return FILE_DONE;
920
 
921
		case LINE_DONE:
922
			if (!firsttoken && tokennum)
923
			{
924
				mnemfound = 0;
925
 
926
				for (i=0 ; i
927
				{
928
					if (!strcmpi (tokens[0], parsedata[i].text))
929
					{
930
						if (((parsedata[i].numtokens > 0) &&
931
							 (parsedata[i].numtokens != tokennum)) ||
932
							((parsedata[i].numtokens < 0) &&
933
							 (tokennum < -parsedata[i].numtokens)))
934
						{
935
							fprintf (stderr, "mismatched number of tokens\n");
936
 
937
							for (j=0 ; j
938
								fprintf (stderr, "%s\n", tokens[j]);
939
 
940
							fprintf (stderr, "\n");
941
							errorexit ();
942
						}
943
 
944
						printf ("%s", parsedata[i].emit);
945
						(*parsedata[i].parsefunc) ();
946
 
947
						mnemfound = 1;
948
						break;
949
					}
950
				}
951
 
952
				if (!mnemfound)
953
				{
954
					fprintf (stderr, "Error: unknown mnemonic\n");
955
 
956
					for (j=0 ; j
957
						fprintf (stderr, "%s\n", tokens[j]);
958
 
959
					fprintf (stderr, "\n");
960
					errorexit ();
961
				}
962
			}
963
 
964
			if (!firsttoken)
965
			{
966
				if ((currentseg == DATASEG) && labelfound && !tokennum)
967
					printf (":\n");
968
				else
969
					printf ("\n");
970
 
971
				outline++;
972
			}
973
			return PARSED_OKAY;
974
 
975
		case TOKEN_AVAILABLE:
976
			if (firsttoken)
977
			{
978
				if (token[strlen(token) - 1] == ':')
979
				{
980
					labelfound = 1;
981
 
982
					if (currentseg == DATASEG)
983
					{
984
						token[strlen(token) - 1] = 0;
985
						printf ("%s", token);
986
					}
987
					else if (currentseg == TEXTSEG)
988
					{
989
						printf ("%s", token);
990
					}
991
					else
992
					{
993
						fprintf (stderr, "Error: not in segment block\n");
994
						errorexit ();
995
					}
996
 
997
					firsttoken = 0;
998
					break;
999
				}
1000
			}
1001
 
1002
			firsttoken = 0;
1003
 
1004
			if (tokennum >= MAX_TOKENS)
1005
			{
1006
				fprintf (stderr, "Error: too many tokens\n");
1007
				exit (0);
1008
			}
1009
 
1010
			tokennum++;
1011
 
1012
			break;
1013
 
1014
		default:
1015
			fprintf (stderr, "Error: unknown tokenstat %d\n", stat);
1016
			exit (0);
1017
		}
1018
	}
1019
}
1020
 
1021
 
1022
void main (int argc, char **argv)
1023
{
1024
	tokenstat	stat;
1025
 
1026
	printf (" .386P\n"
1027
            " .model FLAT\n");
1028
	inline = 1;
1029
	outline = 3;
1030
 
1031
	for ( ;; )
1032
	{
1033
		stat = parseline ();
1034
		inline++;
1035
 
1036
		switch (stat)
1037
		{
1038
		case FILE_DONE:
1039
			if (currentseg == TEXTSEG)
1040
				printf ("_TEXT ENDS\n");
1041
			else if (currentseg == DATASEG)
1042
				printf ("_DATA ENDS\n");
1043
 
1044
			printf (" END\n");
1045
			exit (0);
1046
 
1047
		case PARSED_OKAY:
1048
			break;
1049
 
1050
		default:
1051
			fprintf (stderr, "Error: unknown tokenstat %d\n", stat);
1052
			exit (0);
1053
		}
1054
	}
1055
}
1056