Added 16-bit mode
This commit is contained in:
		
							parent
							
								
									9a5ac60946
								
							
						
					
					
						commit
						2c7496a525
					
				
					 5 changed files with 146 additions and 32 deletions
				
			
		| 
						 | 
				
			
			@ -75,3 +75,28 @@ char	regindex_ind[8][8] = {
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
extern int	address_long INIT(1), operand_long INIT(1);
 | 
			
		||||
extern int	use32 INIT(1);
 | 
			
		||||
 | 
			
		||||
/* For 16-bit addressing: copied from i86 assembler */
 | 
			
		||||
#ifndef extern
 | 
			
		||||
extern char     sr_m[8];
 | 
			
		||||
#else
 | 
			
		||||
char    sr_m[8] = {
 | 
			
		||||
        -1,     -1,     -1,     7,      -1,     6,      4,      5
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef extern
 | 
			
		||||
extern char     dr_m[8][8];
 | 
			
		||||
#else
 | 
			
		||||
char    dr_m[8][8] = {
 | 
			
		||||
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
 | 
			
		||||
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
 | 
			
		||||
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
 | 
			
		||||
        -1,     -1,     -1,     -1,     -1,     -1,     0,      1,
 | 
			
		||||
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
 | 
			
		||||
        -1,     -1,     -1,     -1,     -1,     -1,     2,      3,
 | 
			
		||||
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
 | 
			
		||||
        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,10 @@
 | 
			
		|||
 * INTEL 80386 tokens
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
%token <y_word> ATOGGLE
 | 
			
		||||
%token <y_word> OTOGGLE
 | 
			
		||||
%token <y_word> USE16
 | 
			
		||||
%token <y_word> USE32
 | 
			
		||||
%token <y_word> R32
 | 
			
		||||
%token <y_word> R16
 | 
			
		||||
%token <y_word> R8
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,8 @@
 | 
			
		|||
 * No system registers for now ...
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
0,	USE16,		0,		".use16",
 | 
			
		||||
0,	USE32,		0,		".use32",
 | 
			
		||||
0,	R32,		0,		"ax",
 | 
			
		||||
0,	R32,		1,		"cx",
 | 
			
		||||
0,	R32,		2,		"dx",
 | 
			
		||||
| 
						 | 
				
			
			@ -213,10 +215,10 @@
 | 
			
		|||
0,	NOTOP,		071,		"idiv",
 | 
			
		||||
0,	PREFIX,		0144,		"fseg",
 | 
			
		||||
0,	PREFIX,		0145,		"gseg",
 | 
			
		||||
0,	PREFIX,		0146,		"o16",	/* operand size toggle */
 | 
			
		||||
0,	PREFIX,		0146,		"o32",	/* operand size toggle */
 | 
			
		||||
0,	PREFIX,		0147,		"a16",	/* address size toggle */
 | 
			
		||||
0,	PREFIX,		0147,		"a32",	/* address size toggle */
 | 
			
		||||
0,	OTOGGLE,	0146,		"o16",	/* operand size toggle */
 | 
			
		||||
0,	OTOGGLE,	0346,		"o32",	/* operand size toggle */
 | 
			
		||||
0,	ATOGGLE,	0147,		"a16",	/* address size toggle */
 | 
			
		||||
0,	ATOGGLE,	0347,		"a32",	/* address size toggle */
 | 
			
		||||
0,	PREFIX,		0360,		"lock",
 | 
			
		||||
0,	PREFIX,		0362,		"rep",
 | 
			
		||||
0,	PREFIX,		0362,		"repne",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,17 +8,36 @@
 | 
			
		|||
 | 
			
		||||
operation
 | 
			
		||||
	:
 | 
			
		||||
		prefix oper
 | 
			
		||||
			{	address_long = 1; operand_long = 1; }
 | 
			
		||||
		USE16
 | 
			
		||||
			{	use32 = 0; address_long = 0; operand_long = 0; }
 | 
			
		||||
	|
 | 
			
		||||
		USE32
 | 
			
		||||
			{	use32 = 1; address_long = 1; operand_long = 1; }
 | 
			
		||||
	|	prefix oper
 | 
			
		||||
			{	address_long = use32; operand_long = use32; }
 | 
			
		||||
	|	prefix1		/* to allow for only prefixes on a line */
 | 
			
		||||
	;
 | 
			
		||||
prefix	:	/* empty */
 | 
			
		||||
	|	prefix1
 | 
			
		||||
	;
 | 
			
		||||
prefix1:	prefix PREFIX
 | 
			
		||||
			{	if ($2 == 0146) operand_long = ! operand_long;
 | 
			
		||||
				if ($2 == 0147) address_long = ! address_long;
 | 
			
		||||
				emit1($2);
 | 
			
		||||
prefix1:	prefix PREFIX	{ emit1($2); }
 | 
			
		||||
	|
 | 
			
		||||
		prefix ATOGGLE
 | 
			
		||||
				{ if ((($2&0200) >> 7) == address_long) {
 | 
			
		||||
					if (pass == PASS_3) warning("address size toggle ignored");
 | 
			
		||||
				  } else {
 | 
			
		||||
					emit1($2 & 0177);
 | 
			
		||||
					address_long = ! address_long;
 | 
			
		||||
				  }
 | 
			
		||||
				}
 | 
			
		||||
	|
 | 
			
		||||
		prefix OTOGGLE
 | 
			
		||||
				{ if ((($2&0200) >> 7) == operand_long) {
 | 
			
		||||
					if (pass == PASS_3) warning("operand size toggle ignored");
 | 
			
		||||
				  } else {
 | 
			
		||||
					emit1($2 & 0177);
 | 
			
		||||
					operand_long = ! operand_long;
 | 
			
		||||
				  }
 | 
			
		||||
				}
 | 
			
		||||
	;
 | 
			
		||||
oper	:	NOOP_1
 | 
			
		||||
| 
						 | 
				
			
			@ -177,8 +196,15 @@ st_i	:	ST '(' absexp ')'
 | 
			
		|||
 | 
			
		||||
	;
 | 
			
		||||
mem	:	'(' expr ')'
 | 
			
		||||
			{	rm_2 = 05; exp_2 = $2; reg_2 = 05; mod_2 = 0;
 | 
			
		||||
			{	if (address_long) {
 | 
			
		||||
					rm_2 = 05; reg_2 = 05; mod_2 = 0;
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					reg_2 = 06;
 | 
			
		||||
				}
 | 
			
		||||
				exp_2 = $2;
 | 
			
		||||
				RELOMOVE(rel_2, relonami);
 | 
			
		||||
					
 | 
			
		||||
			}
 | 
			
		||||
	|	bases
 | 
			
		||||
			{	exp_2.val = 0; exp_2.typ = S_ABS; indexed();}
 | 
			
		||||
| 
						 | 
				
			
			@ -188,11 +214,21 @@ mem	:	'(' expr ')'
 | 
			
		|||
			}
 | 
			
		||||
	;
 | 
			
		||||
bases	:	'(' R32 ')'
 | 
			
		||||
			{	reg_2 = $2; sib_2 = 0; rm_2 = 0;}
 | 
			
		||||
			{	if (address_long) {
 | 
			
		||||
					reg_2 = $2; sib_2 = 0; rm_2 = 0;
 | 
			
		||||
				}
 | 
			
		||||
				else 	reg_2 = sr_m[$2];
 | 
			
		||||
			}
 | 
			
		||||
	|	'(' R32 ')' '(' R32 scale ')'
 | 
			
		||||
			{	rm_2 = 04; sib_2 |= regindex_ind[$2][$5];
 | 
			
		||||
			{	if (address_long) {
 | 
			
		||||
					rm_2 = 04;
 | 
			
		||||
					 sib_2 |= regindex_ind[$2][$5];
 | 
			
		||||
					reg_2 = $2;
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					reg_2 = dr_m[$2][$5];
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
	|	'(' R32 '*' absexp ')'
 | 
			
		||||
			{	if ($4 == 1) {
 | 
			
		||||
					reg_2 = $2; sib_2 = 0; rm_2 = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,40 @@
 | 
			
		|||
 * INTEL 80386 special routines
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
ea_1_16(param)
 | 
			
		||||
{
 | 
			
		||||
        if ((reg_1 & 070) || (param & ~070)) {
 | 
			
		||||
                serror("bad operand");
 | 
			
		||||
        }
 | 
			
		||||
        emit1(reg_1 | param);
 | 
			
		||||
        switch(reg_1 >> 6) {
 | 
			
		||||
        case 0:
 | 
			
		||||
                if (reg_1 == 6 || (reg_1 & 040)) {
 | 
			
		||||
#ifdef RELOCATION
 | 
			
		||||
                        RELOMOVE(relonami, rel_1);
 | 
			
		||||
                        newrelo(exp_1.typ, RELO2);
 | 
			
		||||
#endif
 | 
			
		||||
                        emit2(exp_1.val);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
        case 1:
 | 
			
		||||
                emit1(exp_1.val);
 | 
			
		||||
                break;
 | 
			
		||||
        case 2:
 | 
			
		||||
#ifdef RELOCATION
 | 
			
		||||
                RELOMOVE(relonami, rel_1);
 | 
			
		||||
                newrelo(exp_1.typ, RELO2);
 | 
			
		||||
#endif
 | 
			
		||||
                emit2(exp_1.val);
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ea_1(param) {
 | 
			
		||||
	if (! address_long) {
 | 
			
		||||
		ea_1_16(param);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (is_expr(reg_1)) {
 | 
			
		||||
		serror("bad operand");
 | 
			
		||||
		return;
 | 
			
		||||
| 
						 | 
				
			
			@ -49,6 +82,10 @@ checkscale(val)
 | 
			
		|||
{
 | 
			
		||||
	int v = val;
 | 
			
		||||
 | 
			
		||||
	if (! address_long) {
 | 
			
		||||
		serror("scaling not allowed in 16-bit mode");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	if (v != val) v = 0;
 | 
			
		||||
	switch(v) {
 | 
			
		||||
	case 1:
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +130,7 @@ regsize(sz)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
indexed() {
 | 
			
		||||
	if (address_long) {
 | 
			
		||||
		mod_2 = 0;
 | 
			
		||||
		if (sib_2 == -1)
 | 
			
		||||
			serror("register error");
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +150,15 @@ indexed() {
 | 
			
		|||
		else if (exp_2.val != 0 || reg_2 == 5)
 | 
			
		||||
			mod_2 = 01;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
        	if (reg_2 & ~7)
 | 
			
		||||
                	serror("register error");
 | 
			
		||||
        	if (exp_2.typ != S_ABS || fitb(exp_2.val) == 0)
 | 
			
		||||
                	reg_2 |= 0200;
 | 
			
		||||
        	else if (exp_2.val != 0 || reg_2 == 6)
 | 
			
		||||
                	reg_2 |= 0100;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ebranch(opc,exp)
 | 
			
		||||
	register int opc;
 | 
			
		||||
| 
						 | 
				
			
			@ -245,7 +292,7 @@ adsize_exp(exp, relpc)
 | 
			
		|||
		emit4((long)(exp.val));
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		if (! fitw(exp.val)) {
 | 
			
		||||
		if (! fitw(exp.val) && pass == PASS_3) {
 | 
			
		||||
			warning("offset does not fit in 2 bytes; remove prefix");
 | 
			
		||||
		}
 | 
			
		||||
#ifdef RELOCATION
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue