/*****************************************************************************
*           Change Log
*  Date     | Change
*-----------+-----------------------------------------------------------------
* 27-Nov-85 | [1.20] Created
*  4-Dec-85 | [1.104] star is set to dot-1
*  4-Dec-85 | [1.113] Accept = for #
* 11-Dec-85 | [1.164] Reject any characters not in the bcd character set.
* 13-Dec-85 | [1.166] Created by copying from dc.c
* 14-Dec-85 | [1.169] Do not lay down data until pass 2
* 24-Nov-91 | [1.177] <jmn> memory.h => automem.h
* 24-Nov-91 | [1.177] <jmn> converted to C6.0
* 24-Nov-91 | [1.177] <jmn> mach.h => machmem.h
*****************************************************************************/
#include <boolean.h>
#include <stdio.h>
#include <pos.h> 
#include <machmem.h>
#include <automem.h>
#include <operands.h>
#include <err.h>
#include <expr.h>
#include <operand.h>
#include <error.h>
#include <list.h>
#include <bcd.h>
#include <ds.h>

static int dotoffset;

/****************************************************************************
*                                     dsa
* Inputs:
*	int pass: Pass we are running
* Effect: 
*       Defines symbolic address with h/o word mark
****************************************************************************/

static void dsa(int pass)
    {
     int val;
     int noperands;
     int i;
     char bytes[3];


     noperands = scan_operands();

     if(noperands == 0)
        { /* bogus */
	 error(err_operand,"DSA requires operand");
	 if(pass==2)
	    { /* list it */
	     list_line();
	     emit_listing();
	    } /* list it */
	 return;
	} /* bogus */

     if(noperands > 1)
        { /* more bogus */
	 error(err_operand,"DSA permits only one operand");
	 if(pass==2)
	    { /* list it */
	     list_line();
	     emit_listing();
	    } /* list it */
	 return;
	} /* more bogus */

     if(pass==2)
        { /* lay it down */	 
     	if(!expr(operands[0],&val,true,expr_lit_illegal,pass,false)) 
	   return;

	cvbytes(bytes,val);
	
	for(i=0;i<3;i++)
	   { /* store */
	    unsigned loc;
	    loc = check_memory(dot+i);
	    memory[loc] = C_bits | bytes[i] | (i==0 ? word_mark : 0);
	    if(pass==2)
	       { /* list data */
		put_data(i,bcd_to_ascii(bytes[i]));
	       } /* list data */
	   } /* store */
	} /* lay it down */	 

     sdot = dot = dot+3;
     star = dot - 1;
     dslabel(pass,0,0);

     sdot = dot;
     star = dot - 1;
     return;
    }

/****************************************************************************
*                                    dsaop
* Inputs:
*       int opindex: (not used)
*	int pass: 1 or 2
* Effect: 
*       Defines storage without word mark
****************************************************************************/

void dsaop(int opindex,int pass)
    {
     dotoffset = 0;
     dsa(pass);
     if(pass==2)
        { /* list it */
	 list_addr(dot-1-dotoffset);
	 list_line();
	 emit_listing();
	} /* list it */
     return;
    }
