var lnsArry = Array();
//some variables
var lnCntr = 0;
//Second dimension of instrTab Array
var instruction = 0;
var args = 1;
var opcode = 2;
var rule = 3;
var disasmMask = 4;
var maxVal = 5;
//Second dimension oflnsArry()
////var comments = 1;
var asmOutpt = 4;
var opcdNdxVal = 3;
var lnNmbrVal = 2;
var adrsCntrVal = 1;
var lmnts = 0;
//third dimension of lnsArry()
var xpnsn = 0;

function stripLns()
{
	   statBar('Initializing...');
	   xpnsn = 0;
	   lnCntr = 0;
	   lnsArry = new Array();
	   var tempBuf1 = document.editor.codeWindow.value;
	   var tempBuf2 = '';
	   var lstNdxOfNl = 0; //to store last index of '\n'
	   while ( tempBuf1 != "" )
	   {
		 lstNdxOfNl = tempBuf1.lastIndexOf('\n');
		 lnsArry[lnCntr] = new Array();//no lenght specified
		 lnsArry[lnCntr][xpnsn] =  new Array();//no lenght specified
		 tempBuf2 = tempBuf1.substring(lstNdxOfNl+1,tempBuf1.length);//put line in tempBuf2
		 if (tempBuf2.indexOf(';') != -1)
		 {
		  tempBuf2 =tempBuf2.substring(0,tempBuf2.indexOf(';')); //remove comments from the line
	     }
		 getLnElements(tempBuf2);//get lines elements
		 lnsArry[lnCntr][xpnsn][lmnts] = lnsLmnts;
		// lnsArry[lnCntr][xpnsn][LnItSlf] = tempBuf2;
		 tempBuf1 =  tempBuf1.substring(0,lstNdxOfNl);
		 //window.status= 'lnCntr = '+lnCntr +'    Ln is:'+ lnsArry[lnCntr][xpnsn][lmnts] ;
		 lnCntr += 1;
		 statBar('');
		}
/* -----------------------------------------------
this part adds numbers to each line
----------------------------------------------- */
  lnCntr --;
  var lnNmbr = 1;
 while(lnCntr >= 0)
 {
  lnsArry[lnCntr][xpnsn][lnNmbrVal] = lnNmbr;
  lnCntr--;
  lnNmbr++;
 }
}

var lastOpcdNdx = 0;
function isOpcode(str) // checks if the string is an Opcode and returns boolean expression
{
	if(str == null){return false;};
	str = str.toLowerCase();
	for(a=0;a<instrTab.length;a++)
	{
	  if (instrTab[a][instruction] == str)
	  {
	  lastOpcdNdx = a;
	  return true;
	  }
	}
	return false;
}

var lastDefNdx ;
var lastDefVal ;// to be altered by isDefined() and used to pass the value of last symbol found
function isDefined(str)// checks if the string has been defined (in the equ array) and returns boolean expression
{
  if(str == null){return false;}
  str = str.toLowerCase();
		for(a=0;a<equArry.length;a++)
		{
		  if (equArry[a][equStr] == str)
		  {
			lastDefVal = equArry[a][equStrVal];
			lastDefNdx = a;
			return true;
		  }
		}
	return false;
}

//Bases
var hex = 16;
var dec = 10;
var bin = 2;
var oct = 8;
var base = dec;//default base is decimal
	function  analyze(literal) {//analyzes literal and returns dec value of literal or 'error'
		var baseBup = base; //strore radix
		literal = trim(literal); 					//get rid of spaces ,tabs etc..
		var literalOrgCase = literal;				//resrve literal in its original case (should it turn out to be an ascii char)
		literal = literal.toLowerCase();			//convert it to lower case to simplify comparisons below...
		var lastChar = literal.charAt(literal.length - 1); //last character of literal
		var frst2Chars = literal.substring(0,2); //first 2 characters of literal
		if (lastChar=="\'" // hex like H'45F'
		    &&
		    frst2Chars=="h\'") {
		     literal = literal.substring(2,(literal.length-1));
		     base = hex;
		}
			else {
			if (frst2Chars=="0x") { // hex like 0x1B
			     literal = literal.substring(2,literal.length);
			     base = hex;
			}
				else {
				if (lastChar=='h') {// hex like 0CH
				     literal = literal.substring(0,(literal.length-1));
				     base = hex;
				}
					else {
					if (lastChar=="\'" // dec like D'125'
					    &&
					    frst2Chars=="d\'") {
					     literal = literal.substring(2,(literal.length-1));
					     base = dec;
						}
						else {
						if (lastChar=="\'" //bin like B'10101100'
						    &&
						    frst2Chars=="b\'") {
						     literal = literal.substring(2,(literal.length-1));
							     base = bin;
							}
							else {
							if (lastChar=='b'
								&&
								base != hex) {// bin like 1011101B
								 literal = literal.substring(0,(literal.length-1));
								 base = bin;
								}
								else {
								if (lastChar=="\'" // oct like O'267'
									&&
									frst2Chars=="o\'") {
									 literal = literal.substring(2,(literal.length-1));
									 base = oct;
							  		}

							  		else {
									if (lastChar=="\'"// ASCII like A'P'
										&&
										frst2Chars=="a\'") {
										 literal = literalOrgCase.substring(2,(literal.length-1));//get the string from the initial case
										 literal = asciiToDec(literal).toString()
										 base = dec;
									  }
									else {
									if (lastChar=="\'"// ASCII like 'P'
										&&
										literal.charAt(0)=="\'") {
										 literal = literalOrgCase.substring(1,(literal.length-1));//get the string from the initial case
										 literal = asciiToDec(literal).toString()
										 base = dec;
									  }


						   			}
							  	}
							}
					  	}
					}
				}
			}
		}

	var literalVal = baseConv(literal,base);
    base = baseBup;//restore radix
	//window.status =' Literal is: '+ literal +'   Base is:'+ base +'     literalVal:'+literalVal;
	return literalVal; //either dec value of literal or 'error' from baseConv()
   }

	function trim (str2Trim) {
		while (str2Trim.charAt(0) == ' '
			||
				str2Trim.charAt(0) == '\n'
			||
				str2Trim.charAt(0) == '\t'
			||
				str2Trim.charAt(0) == '\r')
		{
			str2Trim = str2Trim.substring(1,(str2Trim.length));
		}
		while (str2Trim.charAt(str2Trim.length-1) == ' '
			||
				str2Trim.charAt(str2Trim.length-1) == '\n'
			||
				str2Trim.charAt(str2Trim.length-1) == '\t'
			||
				str2Trim.charAt(str2Trim.length-1) == '\r')
		{
			str2Trim = str2Trim.substring(0,(str2Trim.length-1));
		}
		return str2Trim;

	}
function baseDisp(v,bn) // value, base
{
	var digitString = "0123456789ABCDEF";
	var s = ""; // string to return
	s = digitString.charAt(v % bn) + s; //this is DO and below is WHILE
	v = Math.floor(v/bn);				//JavaScript1.1 does not have DO WHILE loops !!!!!!!!!
	while(v)
	{
		s = digitString.charAt(v % bn) + s;
		v = Math.floor(v/bn);
	}

	return s;
}

function baseConv(s,b) // string, base
{
	var digitString = "0123456789abcdef";
	var v = 0; // value to return
	s = s.toLowerCase();
	for(var i = 0; i < s.length; i++) {
		v = v * b;
		var c = s.charAt(i);
		var d = digitString.indexOf(c);
		if((d != -1) && (d < b)) {
			v += d;
		}
		else {

			v = 'error'; //string is not of the correct base
			break;
		}
	}
	return v; //return the value of the string in base 10
}


function  asciiToDec(asciiChar) {
  	var decValOfChar = 0;
  	var decValOfChar = asciiTable.indexOf(asciiChar);
  	return decValOfChar ;
	  }

var equPointer = equArry.length;
var lnsLmnts = Array();

function getLnElements(str) {// this func. will split a ln to its elements and make them a part of an array
		//reset array size so that its lengt reflects the number its elements							   // DO NOT pass this function null strings !!!!!
		lnsLmnts = null;//arrays cannot be resized with Opera , so I clear lnsLmnts and make it an array again
		lnsLmnts = Array();
		//if(str == ''){return;}
		str = trim(str);
		var numOfElements = 0;
		while (str != '')
		{
		  str = trim(str);
		  var grabbedWord = str;
		  var ndxsOfSprtrs = Array();
		  ndxsOfSprtrs[0] = str.indexOf(' ');
		  ndxsOfSprtrs[1] = str.indexOf('\t');
		  ndxsOfSprtrs[2] = str.indexOf(',');
		  ndxsOfSprtrs[3] = str.indexOf(':');
		  ndxsOfSprtrs[4] = str.indexOf(unescape('%A0'));
		  for(i=0;i<ndxsOfSprtrs.length; i++ )
		  {
			  while( (ndxsOfSprtrs[i] != -1)
				  &&
					 (str.substring(0,ndxsOfSprtrs[i]).length < grabbedWord.length ))
			  {
			  var grabbedWord = str.substring(0,ndxsOfSprtrs[i]);
			  }
		  }
		  lnsLmnts[numOfElements] = grabbedWord;
		  str = str.substring(grabbedWord.length+1,str.length);
		  numOfElements += 1;
		}
	}


function togLnNmbrs()
{
  if (lnNmbrsOn == false)
  {
	nmbrLns();
  }
  else
	{
	  rmLnNmbrs();
	}

}


var lnNmbrsOn = false;
var nmbrsArry = Array(); //store lines in global array
function nmbrLns() {
		   if (lnNmbrsOn == true
		     ||
		      curView != 'src')
		   {
			 alert('Cannot number lines \nwhile lines are already numbered\n or Source view is off');
			 return;
		   }
		   statBar('Preparing to number lines...  ');
		   nmbrsArry = null;
		   nmbrsArry = new Array();
		   lnNmbrsOn = true;
  		   var lnNmbr = 1;
	  	   lnCntr = 0;
		   var tempBuf1 = document.editor.codeWindow.value;
		   var lstNdxOfNl = 0; //to store last index of '\n'
		   while ( tempBuf1 != "" )
		   {
			 lstNdxOfNl = tempBuf1.lastIndexOf('\n');
			 nmbrsArry[lnCntr] = tempBuf1.substring(lstNdxOfNl+1,tempBuf1.length);
			 tempBuf1 =  tempBuf1.substring(0,lstNdxOfNl);
			 lnCntr += 1;
		   }
		   statBar('Ready...  ');
		   src = ''; // clear src to store numbered lines
		   document.editor.codeWindow.value = '';
		   lnCntr--;
		   var nmbrWdth = lnCntr.toString().length;
		   while(lnCntr >= 0)
		   {
			src += addZeros(lnNmbr,nmbrWdth)  +'¶'+ nmbrsArry[lnCntr]+'\n';
			lnCntr--;
			statBar('Numbering line:  '+ lnNmbr);
			lnNmbr++;
		   }
		   //document.editor.codeWindow.value = ''; //clear code view
		   document.editor.codeWindow.value = src; //show numbered lines
			statBar('');//Clear status bar
	}


function rmLnNmbrs()
{
  if (lnNmbrsOn == false
	   ||
		curView != 'src')
	 {
	 alert('Line numbers are not present  or Source view is off');
	 return;
	 }
	 lnNmbrsOn = false;
	 var nmbrsArry = Array();//this one need not be global
	 lnCntr = 0;
	 var tempBuf1 = document.editor.codeWindow.value;
	 var lstNdxOfNl = 0; //to store last index of '\n'
	 while ( tempBuf1 != "" )
	 {
	   lstNdxOfNl = tempBuf1.lastIndexOf('\n');
	   nmbrsArry[lnCntr] = tempBuf1.substring(lstNdxOfNl+1,tempBuf1.length);
	   tempBuf1 =  tempBuf1.substring(0,lstNdxOfNl);
	   lnCntr += 1;
	 }
	 tempBuf1 = ''; // clear tempBuf1 to store UNnumbered lines
	 lnCntr--;
	 while(lnCntr >= 0)
	 {
	  tempBuf1 += nmbrsArry[lnCntr].substring(nmbrsArry[lnCntr].indexOf('¶')+1 , nmbrsArry[lnCntr].length)+'\n';
	  lnCntr--;
	 }
	 document.editor.codeWindow.value = ''; //clear code view
	 document.editor.codeWindow.value = tempBuf1; //show UNnumbered lines
}

var mcrArry = Array();//macro storage aray
var mcrCntr = 0;
var mcrLnCntr = 0;
var mcrAvlbl = false;

function isMcrDrvPrsnt()
{
  var tbuf = document.editor.codeWindow.value.toLowerCase();
  if(tbuf.indexOf('macro') == -1)
  return false;
  else
  return true;
}

function fishForMcr() {
  	//window.status = 'Fishing For Macros.....'
	lnCntr = lnsArry.length-1;
	while(lnCntr >= 0)
	{
	  if (lnsArry[lnCntr][xpnsn][lmnts].length > 1
	  	&&
	  	  lnsArry[lnCntr][xpnsn][lmnts][1].toLowerCase() == 'macro')
	  {
	   getMcr(lnCntr);
	  }
	 lnCntr--;

	}
}

function getMcr(lnCntr)// store macros in mcrArry
	{
	  	//var endmEncntrd = false;// 'endm' directive not encountered yet
	    mcrArry[mcrCntr] = Array();
		mcrLnCntr = 0;

		while (1)
		{
		  if(lnsArry[lnCntr][xpnsn][lmnts].length > 0
		 	 &&
		 	 lnsArry[lnCntr][xpnsn][lmnts][0].toLowerCase() == 'endm')
			{break;}
			mcrArry[mcrCntr][mcrLnCntr] = lnsArry[lnCntr][xpnsn][lmnts];//this and the following line MOVE macro lines from lnsArry to mcrArry
			lnsArry[lnCntr][xpnsn][lmnts] = '';//clear line belonging to macro definitionfrom assembly code
			lnCntr--;
			mcrLnCntr++;

		  if(lnCntr == -1)
			{
			  alert('ERROR !!!   NO ENDM directive found!!!');
			  return;
			}
		}

		lnsArry[lnCntr][xpnsn][lmnts] = '';// this one will remove the ENDM directive
		mcrCntr++;
	}

function  fndAndXpndMcr()
{
  var lblAvlbl = 0; // if there is a label preceding the macro this will be set to 1 and passed to xpandMcr to increase the the argument pointer by 1 through the lnsLmnts	
  for(lnCntr = lnsArry.length-1;lnCntr >= 0;lnCntr--)
  {
	if(lnsArry[lnCntr][xpnsn][lmnts].length > 0)
	{

	  if(isMcr(lnsArry[lnCntr][xpnsn][lmnts][0]) == true)// no label peceding macro such as>> mymacro arg1,arg2,arg3....
	  {
	   lblAvlbl = 0;
	   xpandMcr(mcrCntr,lblAvlbl);
	   lnsArry[lnCntr][xpnsn][lmnts] = ''; //remove macro line from source upon expansion
	   continue;
	  }

	  if(lnsArry[lnCntr][xpnsn][lmnts].length > 1
	  	&&
		isMcr(lnsArry[lnCntr][xpnsn][lmnts][1]) == true)//there is a label peceding macro such as>> mylabel: mymacro arg1,arg2,arg3....
	  {
	   lblAvlbl = 1;	
	   xpandMcr(mcrCntr,lblAvlbl);
	   rmvAllButLbl();//remove macro line from source upon expansion (but leave the label)
	  }
	}
  }
}

function xpandMcr (mcrCntr,lblAvlbl) // macro # to xpand and label presence
{
	for(xpnsn = 1;xpnsn < mcrArry[mcrCntr].length; xpnsn++)// this for loop expands the macro
	{
	  lnsArry[lnCntr][xpnsn] = Array();
	  lnsArry[lnCntr][xpnsn][lmnts] = mcrArry[mcrCntr][xpnsn];
	}
	
	if((mcrArry[mcrCntr][0].length - 2) > (lnsArry[lnCntr][0][lmnts].length - lblAvlbl - 1))
	{
		 addErrMsg('\nError on line '+lnsArry[lnCntr][0][lnNmbrVal]+ '! Missing macro argument.', lnsArry[lnCntr][0][lnNmbrVal]);
	}
	else 
	if((mcrArry[mcrCntr][0].length - 2) < (lnsArry[lnCntr][0][lmnts].length - lblAvlbl - 1))
	{
		 addErrMsg('\nError on line ' +lnsArry[lnCntr][0][lnNmbrVal]+ '! Too many macro arguments.',lnsArry[lnCntr][0][lnNmbrVal] );
	}
	
	var arg = '';
	for(mcrLnCntr = 1; mcrLnCntr < mcrArry[mcrCntr].length; mcrLnCntr++)
	{
	  for(var ndx = 0; ndx < mcrArry[mcrCntr][mcrLnCntr].length; ndx++ )
	  {
		for(var argPntr = 2; argPntr < mcrArry[mcrCntr][0].length; argPntr++ )
		{
		  arg = mcrArry[mcrCntr][0][argPntr];
		  if (arg == mcrArry[mcrCntr][mcrLnCntr][ndx])
		  {
		  	lnsArry[lnCntr][mcrLnCntr][lmnts][ndx] = lnsArry[lnCntr][0][lmnts][argPntr - 1 + lblAvlbl];
		  }
		}
	  }
	}
	xpnsn = 0; //reset xpnsn
}

function  isMcr(str)
{
	str = str.toLowerCase();
	for(mcrCntr=0;mcrCntr<mcrArry.length;mcrCntr++)
	{
	  if (mcrArry[mcrCntr][0][0] == str)
	  {
	  return true;
	  break;
	  }
	}
return false;
}

function fishForEqu()
{
  var numOfLmnts = 0;
  //var lmnt0 = '';
  for(lnCntr = lnsArry.length-1;lnCntr >= 0;lnCntr--)
  {
	for(xpnsn = 0; xpnsn < lnsArry[lnCntr].length; xpnsn++)
	{
	  	statBar('Directive search on line:  '+lnsArry[lnCntr][xpnsn][lnNmbrVal]);
		numOfLmnts = lnsArry[lnCntr][xpnsn][lmnts].length;

		if(numOfLmnts == 3
		  &&
		  lnsArry[lnCntr][xpnsn][lmnts][1].toLowerCase() == 'equ')
		{
		  //alert('equ found'+ lnsArry[lnCntr][xpnsn][lmnts]);
		  equ(lnsArry[lnCntr][xpnsn][lmnts][0],lnsArry[lnCntr][xpnsn][lmnts][2]);
		  lnsArry[lnCntr][xpnsn][lmnts] = '';
		  continue;
		}

		if(numOfLmnts >= 2
		  &&
		  (lnsArry[lnCntr][xpnsn][lmnts][0].toLowerCase() == 'dt'
		  ||
		  lnsArry[lnCntr][xpnsn][lmnts][1].toLowerCase() == 'dt'))
		{
		  dt();
		  continue;
		}

		if(	numOfLmnts >= 1
			&&
			lnsArry[lnCntr][xpnsn][lmnts][0].toLowerCase() == 'radix')
		{
		  radix();
		  continue;
		}

		if(	numOfLmnts >= 1
			&&
			lnsArry[lnCntr][xpnsn][lmnts][0].toLowerCase() == 'list')
		{
		  lst() ;
		  continue ;
		}

		if(	numOfLmnts >= 1
			&&
			lnsArry[lnCntr][xpnsn][lmnts][0].toLowerCase() == '__config')
		{
			config();
			continue;
		}

		if(	numOfLmnts >= 1
			&&
			lnsArry[lnCntr][xpnsn][lmnts][0].toLowerCase() == 'de')
		{
			de();
			continue;
		}
	}
  }
 xpnsn = 0; 
statBar('');//Clear status bar
}

function  equ(strToAdd,valOfStrToAdd) {//make parameters part of equ array both paramas are strings !!!
	 equArry[equPointer] = Array();
	 var valToAdd = getArgVal(valOfStrToAdd);
	 if(valToAdd == 'error'){ return;}
	 equArry[equPointer][equStrVal] = valToAdd;
	 equArry[equPointer][equStr] = strToAdd.toLowerCase();
     equPointer += 1;
}

function  equ2(strToAdd,decVal) {//make parameters part of equ array strToAdd is STRING, decVal is decimal val of strToAdd
	 equArry[equPointer] = Array();
	 equArry[equPointer][equStrVal] =  decVal;
	 equArry[equPointer][equStr] = strToAdd.toLowerCase();
     equPointer += 1;
}

function  dt()// process dt directive
{
  if(xpnsn > 0)
  {
	addErrMsg('\nError on line '+lnsArry[lnCntr][0][lnNmbrVal]+ '! DT directive cannot be used within a macro >> ' , lnsArry[lnCntr][xpnsn][lnNmbrVal]);
  }
  var ndxOfDt = 0;// location of dt directive in lmnts. This is to determine if there is label on the same line with the dt directive.
	if (lnsArry[lnCntr][xpnsn][lmnts][1].toLowerCase() == 'dt'){ndxOfDt = 1;}
  //alert('dt found '+ lnsArry[lnCntr][xpnsn][lmnts]);
  var numOfArgs = lnsArry[lnCntr][xpnsn][lmnts].length - ndxOfDt - 1 ;
  for(var xpnsnLoc = 1; xpnsnLoc <= numOfArgs; xpnsnLoc++)
  {
	lnsArry[lnCntr][xpnsnLoc] = Array();
	lnsArry[lnCntr][xpnsnLoc][lmnts] = Array();
	lnsArry[lnCntr][xpnsnLoc][lmnts][0] = 'retlw';
	lnsArry[lnCntr][xpnsnLoc][lmnts][1] = lnsArry[lnCntr][xpnsn][lmnts][ndxOfDt + xpnsnLoc];
	lnsArry[lnCntr][xpnsnLoc][lnNmbrVal] = 'EXP \tretlw '+ lnsArry[lnCntr][xpnsnLoc][lmnts][1];
	//alert(lnsArry[lnCntr][xpnsnLoc][lmnts][0]+'  '+lnsArry[lnCntr][xpnsnLoc][lmnts][1]);
  }
lnsArry[lnCntr][xpnsn][lmnts]= '';// remove directive from source

}

function radix()// process radix directive
{
  if(lnsArry[lnCntr][xpnsn][lmnts].length != 2)
  {
	addErrMsg('\nError on line '+lnsArry[lnCntr][0][lnNmbrVal]+ '! RADIXrequires argument  DEC,HEX or OCT. ' , lnsArry[lnCntr][xpnsn][lnNmbrVal]);
  }
  if(lnsArry[lnCntr][xpnsn][lmnts][1].toLowerCase() == 'dec'
	||
	lnsArry[lnCntr][xpnsn][lmnts][1].toLowerCase() == 'hex'
	||
	lnsArry[lnCntr][xpnsn][lmnts][1].toLowerCase() == 'oct')
	{
	  base = eval(lnsArry[lnCntr][xpnsn][lmnts][1].toLowerCase());
	}
	else
	{
	 addErrMsg('\nError on line '+lnsArry[lnCntr][0][lnNmbrVal]+ '! Invalid RADIX ! Please use DEC,HEX or OCT. ' , lnsArry[lnCntr][xpnsn][lnNmbrVal]);
	}
  lnsArry[lnCntr][xpnsn][lmnts]= '';// remove directive from source

}

function org(orgVal)// sets the address AND adrsCntr to crgVal, orgVal being the parameter of the org directive
{
	adrsCntr = getArgVal(orgVal);
}

function lst()// deals with list directive , actually it is only ignored
{
  lnsArry[lnCntr][xpnsn][lmnts] = ''; // remove directive from source
}

function config()
{	var confWord = 0xFFFF;
	for(var i = 1; i < lnsArry[lnCntr][xpnsn][lmnts].length; i++)
	{
	  if(lnsArry[lnCntr][xpnsn][lmnts][i] != '&')
		{
	  		confWord &= getArgVal(lnsArry[lnCntr][xpnsn][lmnts][i]);
	 	}
  	}
  	//alert('confWord is '+confWord);
  	//confWord = confWord.toLowerCase();
  	//confWord = eval(confWord);
  	//alert(confWord);
  	lnsArry[lnCntr][xpnsn][adrsCntrVal] = 0x2007;
  	lnsArry[lnCntr][xpnsn][asmOutpt] = baseDisp(confWord,16);
  	//alert('fin conf = '+ lnsArry[lnCntr][xpnsn][asmOutpt]);
	lnsArry[lnCntr][xpnsn][lmnts]= ''; // remove directive from source
}

function de()
{

}


function fishForEvElse()
{	adrsCntr = 0;
	lnNumber = 1;
  for(lnCntr = lnsArry.length-1;lnCntr >= 0;lnCntr--)
  {
	for(xpnsn = 0; xpnsn < lnsArry[lnCntr].length; xpnsn++)
	{
	  	statBar('Scan on line:  '+lnsArry[lnCntr][xpnsn][lnNmbrVal]);
		scan();
		//setLnNmbr();
	}
  }

statBar('');//Clear status bar
}


function scan()
{
 var numOfLmnts = lnsArry[lnCntr][xpnsn][lmnts].length;
 if (numOfLmnts != 0)//make sure this is not a blank ln
 	 {

	 var lmnt0Opcd = false;
	 var lmnt1Opcd = false;
	 var lmnt0Dfnd = false;
	 var lmnt1Dfnd = false;
	  lmnt0Opcd  = isOpcode(lnsArry[lnCntr][xpnsn][lmnts][0]);
	  lmnt0Dfnd = isDefined(lnsArry[lnCntr][xpnsn][lmnts][0]);

	if (numOfLmnts > 1 )
	{
	  lmnt1Opcd  = isOpcode(lnsArry[lnCntr][xpnsn][lmnts][1]);
	  lmnt1Dfnd = isDefined(lnsArry[lnCntr][xpnsn][lmnts][1]);
	}
//-------------------
	if (lmnt0Opcd) // sth like 'addlw 45h'  OR  'nop'
	{//if ln starts with an opcode increase the address Cntr for the next to come
	  lnsArry[lnCntr][xpnsn][adrsCntrVal] = adrsCntr;
	  lnsArry[lnCntr][xpnsn][opcdNdxVal] = lastOpcdNdx;
	  adrsCntr += 1;
	  return;
	}

	if ( numOfLmnts == 1 //sth like 'myadr:
		&&
		 lmnt0Opcd == false
		&&
	     lmnt0Dfnd == false )
	{
	  equ2(lnsArry[lnCntr][xpnsn][lmnts][0],adrsCntr);
	  lnsArry[lnCntr][xpnsn][adrsCntrVal] = adrsCntr; //address counter remains the same
	  lnsArry[lnCntr][xpnsn][lmnts] = '';   //remove label from array
	  return;
	}

	if ( numOfLmnts >= 2 // sth like 'myadr: movlw 15h' OR  ' myadr: clrw '
		&&
		 lmnt1Opcd == true )
	{
	  equ2(lnsArry[lnCntr][xpnsn][lmnts][0],adrsCntr);
	  lnsArry[lnCntr][xpnsn][adrsCntrVal] = adrsCntr;
	  lnsArry[lnCntr][xpnsn][opcdNdxVal] = lastOpcdNdx;
	  adrsCntr += 1;
	  rmvLabel();   //remove label from array
	  return;
	}

	if (lmnt0Opcd == false
	  &&
		lmnt0Dfnd == false
	  &&
		numOfLmnts == 3)
	{
	  if (lnsArry[lnCntr][xpnsn][lmnts][1].toLowerCase() == 'org')// sth like : 'myadr: org 0200h


	 	{
		  org(lnsArry[lnCntr][xpnsn][lmnts][2]);//this one wiil set the address Cntr right
		  equ2(lnsArry[lnCntr][xpnsn][lmnts][0],adrsCntr);
		  lnsArry[lnCntr][xpnsn][adrsCntrVal] = adrsCntr;//address counter remains the same
		  lnsArry[lnCntr][xpnsn][lmnts] = '';
		  return;
 		}
	}

	if (numOfLmnts == 2)
	{
	  if (lnsArry[lnCntr][xpnsn][lmnts][0].toLowerCase() == 'org')// sth like : 'org 0200h'
	  {
		 org(lnsArry[lnCntr][xpnsn][lmnts][1]);
		 return;
	  }
	}
//-------------------
// if still inside this function, there must be sth wrong with this line
addErrMsg('\nScan :Error on line  '+ lnsArry[lnCntr][xpnsn][lnNmbrVal],lnsArry[lnCntr][xpnsn][lnNmbrVal]);
return;
 	 }
}

function rmvAllButLbl()// removes all but the label from given source line
{
	var tmpArry = Array();
	tmpArry[0] = lnsArry[lnCntr][xpnsn][lmnts][0];
	lnsArry[lnCntr][xpnsn][lmnts] = tmpArry;
}

function  rmvLabel()// removes label from given source line
{
  var tmpArry = Array();
  for(var lmntPntr = 1;lmntPntr < lnsArry[lnCntr][xpnsn][lmnts].length;lmntPntr++ )// copy lmnts arry to tmpArry exluding the first element (the label that is....)
	{
		tmpArry[lmntPntr-1] = lnsArry[lnCntr][xpnsn][lmnts][lmntPntr];
	}
	lnsArry[lnCntr][xpnsn][lmnts] = tmpArry;
}

function chckForErrs()
{
  if(numOfErrs != 0)
	  {
		addMsg('\nNumbering lines because of one or more errors... ');
		nmbrLns();
		addMsg('Done in ' + timer(intrvl));
		addMsg('\n Assembly aborted because of errors. Please fix them and try to assamble agian.');
		showErrLns();
		if(document.editor.errSwitch.checked)
		setTimeout("viewSwitch('err')",1000);
		return true;
	  }
	  else
	  return false;
}



var zeros = '00000';
function  dualAWDst()
{
  var maxV = instrTab[opcdPntr][maxVal];
  var arg1 = lnsArry[lnCntr][xpnsn][lmnts][1];
  var arg2 = lnsArry[lnCntr][xpnsn][lmnts][2];//destination
  if (arg2 == null)  {arg2 = 'f';}//destination is 'w' if not specified
  arg1 = getArgVal(arg1);
  arg2 = getArgVal(arg2);//destination
 // alert('arg1> '+arg1+' arg2> '+arg2);
  if(arg1 == 'error'
  ||
  	arg2 == 'error')
  {
  lnsArry[lnCntr][xpnsn][asmOutpt] = 'ERRA';
  return;
  }
  if(arg1 > maxV)
  	{
  	  lnsArry[lnCntr][xpnsn][asmOutpt] = 'A1OR';
  	  addErrMsg('\nError on line '+lnsArry[lnCntr][xpnsn][lnNmbrVal]+ '! Argument out of range ! >> '+ lnsArry[lnCntr][xpnsn][lmnts][1]+' = '+arg1,lnsArry[lnCntr][xpnsn][lnNmbrVal] );
  	  return;
	}
  var mask = 0x7F;
  var hexWord = instrTab[opcdPntr][opcode] | (arg1 & mask) | (arg2 * 128);
  //alert('dualAWDst     '+lnsArry[lnCntr][xpnsn][lmnts]+ '    hexWord is   '+baseDisp(hexWord,16) );
  hexWord = baseDisp(hexWord,16)
  lnsArry[lnCntr][xpnsn][asmOutpt] = addZeros(hexWord,4);

}

function  asIs()
{
   var  hexWord = instrTab[opcdPntr][opcode];
   //alert('asIs     '+lnsArry[lnCntr][xpnsn][lmnts]+'    hexWord is   '+ hexWord);
   hexWord = baseDisp(hexWord,16)
   lnsArry[lnCntr][xpnsn][asmOutpt] = addZeros(hexWord,4);
}

function  oneArg()
{
  var maxV = instrTab[opcdPntr][maxVal];
  var arg1 = lnsArry[lnCntr][xpnsn][lmnts][1];
  arg1 = getArgVal(arg1);
  if(arg1 == 'error')
    {
	  lnsArry[lnCntr][xpnsn][asmOutpt] = 'ERRA';
	  return;
	}
	if(arg1 > maxV)
	    {
		  lnsArry[lnCntr][xpnsn][asmOutpt] = 'AOR ';
		  addErrMsg('\nError on line '+lnsArry[lnCntr][xpnsn][lnNmbrVal]+ '! Argument out of range ! >> '+ lnsArry[lnCntr][xpnsn][lmnts][1]+' = '+arg1,lnsArry[lnCntr][xpnsn][lnNmbrVal] );
		  return;
	}

  var  hexWord = instrTab[opcdPntr][opcode] | (maxV & arg1);
  //alert('oneArg     '+lnsArry[lnCntr][xpnsn][lmnts] + '    hexWord is   '+baseDisp(hexWord,16) );
  hexWord = baseDisp(hexWord,16)
  lnsArry[lnCntr][xpnsn][asmOutpt] = addZeros(hexWord,4);

}

function  bit()
{
	var maxV = instrTab[opcdPntr][maxVal];
	var arg1 = lnsArry[lnCntr][xpnsn][lmnts][1];
	var arg2 = lnsArry[lnCntr][xpnsn][lmnts][2];//bit
	arg1 = getArgVal(arg1);
	arg2 = getArgVal(arg2);//bit

	if(arg1 == 'error'
	||
	  arg2 == 'error')
	{
	lnsArry[lnCntr][xpnsn][asmOutpt] = 'ERRA';
	return;
	}

	if(arg2 > 7)
	{
	  lnsArry[lnCntr][xpnsn][asmOutpt] = 'A2OR';
	  addErrMsg('\nError on line '+lnsArry[lnCntr][xpnsn][lnNmbrVal]+ '! Argument (bit) out of range ! >> '+ lnsArry[lnCntr][xpnsn][lmnts][1]+' = '+arg1,lnsArry[lnCntr][xpnsn][lnNmbrVal] );
	  return;
	}
	if(arg1 > maxV)
	{
	  lnsArry[lnCntr][xpnsn][asmOutpt] = 'A2OR';
	  addErrMsg('\nError on line '+lnsArry[lnCntr][xpnsn][lnNmbrVal]+ '! Argument out of range ! >> '+ lnsArry[lnCntr][xpnsn][lmnts][1]+' = '+arg1 , lnsArry[lnCntr][xpnsn][lnNmbrVal] );
	  return;
	}

	var mask = 0x7F;
	var  hexWord = instrTab[opcdPntr][opcode] | (arg1 & mask) | (arg2 * 128);
	//alert('bit     '+lnsArry[lnCntr][xpnsn][lmnts]+ '    hexWord is   '+baseDisp(hexWord,16) );
	 hexWord = baseDisp(hexWord,16)
	 lnsArry[lnCntr][xpnsn][asmOutpt] = addZeros(hexWord,4);
}

 var opcdPntr
function  assemble()
{	adrsCntr = 0;
	lnNumber = 0;
  for(lnCntr = lnsArry.length-1;lnCntr >= 0;lnCntr--)
  {
	for(xpnsn = 0; xpnsn < lnsArry[lnCntr].length; xpnsn++)
	{
	  	statBar('Assembling line:  '+lnsArry[lnCntr][xpnsn][lnNmbrVal]);
		if (lnsArry[lnCntr][xpnsn][opcdNdxVal] != null)
		{
		  opcdPntr = lnsArry[lnCntr][xpnsn][opcdNdxVal];
		  eval(instrTab[opcdPntr][rule]+'();')
		}
	}

  }
statBar('');//Clear status bar
}

function getArgVal(argVal)
{ var argValBup = argVal;	//back it up
  if (argVal == null)
  {
	argVal = 'error';
	addErrMsg('\nError on line '+lnsArry[lnCntr][xpnsn][lnNmbrVal]+ '! Null argument !',lnsArry[lnCntr][xpnsn][lnNmbrVal]);
	return argVal;
  }

  if (isDefined(argVal) == true)
  {
	argVal = lastDefVal;
	return argVal;
  }

	argVal = analyze(argVal);// do not ever try coomentin this one !!!!!!
   //alert(argValBup+ ' >> ' +argVal);
  if (argVal=='error')
  {
  //alert(argValBup+ ' if (argVal == error)>> ' +argVal);
   addErrMsg('\nError on line '+lnsArry[lnCntr][0][lnNmbrVal]+ '! Unable to determine argument value ! >> ' +argValBup , lnsArry[lnCntr][xpnsn][lnNmbrVal]);
  }

return argVal;
}

var list = '               DJPASM List Output';
function listGen() {
  var lstSrcArry = Array();
  var lnPntr = 0;
  var tempBuf1 = document.editor.codeWindow.value;
  var lstNdxOfNl = 0; //to store last index of '\n'
  while ( tempBuf1 != "" )
  {
	lstNdxOfNl = tempBuf1.lastIndexOf('\n');
  	lstSrcArry [lnPntr] = tempBuf1.substring(lstNdxOfNl+1,(tempBuf1.length));
  	tempBuf1 =  tempBuf1.substring(0,lstNdxOfNl);
  	lnPntr += 1;
  }

  var lstLmnts = Array();
  var addrss = 0;
  var hexWord = 1;
  var lnNmbr = 2;
  var orgLine = 3;
  list += '\nLocation  Hex\tLine #\tSource text\n';
  	for(lnCntr = lnsArry.length-1;lnCntr >= 0;lnCntr--)
	  {
		statBar('List generation on line:'+lnsArry[lnCntr][0][lnNmbrVal]);
		for(xpnsn = 0; xpnsn < lnsArry[lnCntr].length; xpnsn++)
		{
		  if (lnsArry[lnCntr][xpnsn][adrsCntrVal] != null)
		  {
			lstLmnts[addrss]  = addZeros(baseDisp(lnsArry[lnCntr][xpnsn][adrsCntrVal],16),4);
		  }
		  else
		  {
		   lstLmnts[addrss] = null;
		  }
		  lstLmnts[lnNmbr]  = addZeros(lnsArry[lnCntr][xpnsn][lnNmbrVal],4);
		  lstLmnts[hexWord] = lnsArry[lnCntr][xpnsn][asmOutpt];
		  for(a = 0; a < lstLmnts.length; a++)
			{
			  if(lstLmnts[a]== null)//replace null elements with spaces so that list  looks allright
			  {
				lstLmnts[a] = '    ';

			  }
			 list += lstLmnts[a]+'\t';
			}
			if(xpnsn == 0){list += lstSrcArry [lnCntr];}
		list +='\n';
		}
		//listWin.document.write(lstSrcArry [lnCntr]);
  }
//add symbol table
list +='\nSymbol Table\n';
var curequArryLngth = equArry.length;

	  for(var i = 0; i < curequArryLngth; i++)
	   {
	     list += equArry[i][0] +'\t0x'+ baseDisp(equArry[i][1],16) +'\n';
	   }

statBar('');
}


function addMsg(str)
{
  document.editor.outpMsgs.value += str;
}


var hexOutp = 'Hex View';
function hexGen()
{
  statBar('Building memory array... Checking for code overlap...');
  var codeMmry = Array();// this is a mirror of PIC code memory. It is used to generate hex output from
  for(lnCntr = lnsArry.length-1;lnCntr >= 0;lnCntr--)
    {
  	for(xpnsn = 0; xpnsn < lnsArry[lnCntr].length; xpnsn++)
	  {

		if(lnsArry[lnCntr][xpnsn][asmOutpt] != null)
		{
		  	var loc = lnsArry[lnCntr][xpnsn][adrsCntrVal];
			if(codeMmry[loc] == null)
			{
				codeMmry[loc] = lnsArry[lnCntr][xpnsn][asmOutpt];
			}
			else
			{
			  addErrMsg('\nError on line '+lnsArry[lnCntr][0][lnNmbrVal]+ '! Code ovarlapping! Please fix ORG directives to prevent overlap.',lnsArry[lnCntr][xpnsn][lnNmbrVal] );
			  return;
			}
		}
	  }
	}

	if(codeMmry.length == 0)
	{
	  hexOutp = 'Nothing to generate hex from....';
	  return;
	}
	statBar('');//Clear status bar

  	var lastAddr = 0;
    hexOutp = '';
    var hexLn = '';
    var bytCntr = 0;
	adrsCntr = 0;
  for(var adrsPntr = 0; adrsPntr < codeMmry.length; adrsPntr++)
  {

		if(codeMmry[adrsPntr] != null)
		{
		statBar('Generating HEX output... Current address is ' + adrsPntr);
		if( bytCntr == 16
		   ||
		    (adrsPntr - lastAddr) > 1
		   ||
		    adrsPntr % 8 == 0
		   &&
		   adrsPntr != 0)
		   {
			hexLn = addZeros(baseDisp(bytCntr,16),2) + hexLn;
			hexOutp += ':'+ hexLn + checkSum(hexLn) + '\n'
			hexLn = '';
			bytCntr = 0;
		   }
		  if(bytCntr == 0)
		   {
			hexLn += addZeros(baseDisp(adrsPntr * 2,16),4)+ '00';
		   }
		   if (adrsPntr - lastAddr > 1){}
		  hexLn += swpByts(codeMmry[adrsPntr]);
		  bytCntr += 2;
		  lastAddr = adrsPntr;
		}
	statBar('');
	}

hexLn = addZeros(baseDisp(bytCntr,16),2) + hexLn;
hexOutp += ':'+ hexLn + checkSum(hexLn)+ '\n';
hexOutp += ':00000001FF';
}


function swpByts(str)
{
  return str.substring(2,4) + str.substring(0,2) ;
}

function checkSum(hexLn)
{
  var chkSum = 0;
  var i = 0;
  var j = 2;
  while(j <= hexLn.length)
  {
	chkSum += parseInt(hexLn.substring(i,j),16);
	i += 2;
	j += 2;
  }
  chkSum = chkSum & 0xff
  chkSum = baseDisp((0x100 - chkSum) & 0xff,16);
  return addZeros(chkSum,2);
}



function addZeros(str,numOfZeros)
{
  if(str == null){return '    ';}
  str = str.toString();
  str = zeros.substring(0,numOfZeros - str.length) + str;
  return str;
}

var curView = 'src';
var src = '';
var srcMsgs = '';
var hexMsgs = 'You can press the \"Select All\" button and then hit CTRL+C to copy contents of the textarea above to your clipboard. Then, open your favourite text editor and hit CTRL+V to paste the hex values, and save it with .hex extension to your harddrive. Now you can program your PIC with that file.  ';

  function viewSwitch(view)
  {
	for (var i = 0; i < 4; i++)// uncheck all radio buttons (this is so that I can invoke viewSwitch not only by th onClick handle ,but from my code as well)
	{
	  document.editor.rad[i].checked = false;
	}

	if (curView == 'src')
	{
	src = document.editor.codeWindow.value;
	srcMsgs = document.editor.outpMsgs.value;
	}
	if (view == 'src')
	{
	  curView = 'src';
	  document.editor.codeWindow.value = src;
	  document.editor.outpMsgs.value = srcMsgs;
	  document.editor.rad[0].checked = true;
	  statBar('Source View');
	}
	if (view == 'hex')
	{
	  curView = 'hex';
	  document.editor.codeWindow.value = hexOutp;
	  document.editor.outpMsgs.value = hexMsgs;
	  document.editor.rad[2].checked = true;
	  statBar('Hex View');

	}

	if (view == 'list')
	{
	  curView = 'list';
	  document.editor.codeWindow.value = list;
	  document.editor.outpMsgs.value = errMsgs;
	  document.editor.rad[1].checked = true;
	  statBar('Listing View');

	}
	if (view == 'err')
	  {
	  curView = 'err';
	  document.editor.codeWindow.value = err;
	  document.editor.outpMsgs.value = errMsgs;
	  document.editor.rad[3].checked = true;
	  statBar('Errors View');

	}
  }

var equArryInitLngth = equArry.length;
function init()// this funct. intializes symbol table and other variables so that source can be reassembled without reloading DJPASM
{
	list = '               DJPASM List Output';
	hexOutp = '               DJPASM Hex Output';
	equPointer = equArryInitLngth;

	lnsArry = null;			// clear lnsArry
	nmbrsArry = new Array();//

	mcrArry = null;//clear macro storage aray
	mcrArry = new Array();
	mcrLnCntr = 0;
	mcrCntr = 0;

	base = dec; //default radix

	err = '';  //this is eerors view
	errMsgs = '        Errors found ,if any, will be shown in the \"Errors View\" with the lines they appear. ';
	numOfErrs = 0; // will count errors with this one
	errLnsArry = new Array(); // store numbers of lines with errors

	var tmpArry = Array();// code below removes new symbols from symbol table
	var curequArryLngth = equArry.length;
	if(equArryInitLngth != curequArryLngth)
	{
	  for(var i = 0; i < equArryInitLngth; i++)
	   {
	     tmpArry[i] = equArry[i];
	   }
	  equArry = tmpArry;
	}
}

var err = '';  //this is eerors view
errMsgs = 'If there are errors in your source, they will be shown in the \"Errors View\" with the lines they appear. You can edit those lines to correct the errors. Pressing \"Join With Source\" will update your source with the changes you made to the lines that caused errors. One thing you should pay attention is not editing the \"Line_XXXX>>\" part. XXXX being the number of that line. Also, if the error is caused by a directive that causes line expansions (MACRO & dt for example),it cannot be displayed.';
var numOfErrs = 0; // will count errors with this one
var errLnsArry = Array(); // store numbers of lines with errors

  function addErrMsg( message , errLn ) /*message is string, errLn is the line number of err.....*/
	{
	  if(errLnsArry.length == 0) errMsgs = 'Errors found : '; // clear the default errors v'ew message the first t'me an error 's found
	  if(xpnsn > 0){errLn = lnsArry[lnCntr][0][lnNmbrVal]}// if error is caused by expanded line ,get its number
	  errMsgs += message ;
	  errLnsArry[numOfErrs] = errLn ;
	  numOfErrs++ ;
	}

  function  showErrLns()
  {
    for(var i = 0; i < errLnsArry.length; i++)
    {
		err += 'Line_'+ addZeros(errLnsArry[i],4) +'>>'+ nmbrsArry[nmbrsArry.length - errLnsArry[i]]+ '\n';
	}
  }

function cnctFxdErrs()// this function joins lines shoen in Errors View with the source.
{
  if (curView != 'err'
	  ||
		lnNmbrsOn == false
	  ||
		numOfErrs == 0)
	{
	alert('This functioon is available only when :\n >> Errors View is ON and \n >> Line numbers are ON and\n >>There are errors  ');
	return;
	}

   var errVwLnsArry = Array();//this one need not be global
   var lnCntr = 0;
   var tempBuf1 = document.editor.codeWindow.value;
   while ( tempBuf1 != "" )
   {
	 errVwLnsArry[lnCntr] = tempBuf1.substring(tempBuf1.lastIndexOf('\n')+1,tempBuf1.length);
	 tempBuf1 =  tempBuf1.substring(0,tempBuf1.lastIndexOf('\n')-1);
	 lnCntr += 1;
   }

	 for(var i = errVwLnsArry.length-1 ; i > -1 ; i--)
	 {	var nmbr = null;
		var tmp = errVwLnsArry[i];
		if(	tmp.substring(0,4) != 'Line_'
		   &&
			tmp.substring(9,11)!= '>>')
		{
			continue;//if no line number present, skip it
		}
		nmbr = tmp.substring(5,9);//get line number
		//alert(nmbr);
		tmp = tmp.substring(11,tmp.length);//get line
		nmbrsArry[nmbrsArry.length - parseInt(nmbr,10)] = tmp;// copy corrected line to nmbrsArrry over the wrong line
	 }

	 lnCntr = nmbrsArry.length -1;
	 src = ''; // clear source to store UNnumbered correct lines
	 while(lnCntr >= 0)
	 {
	  src += nmbrsArry[lnCntr]+'\n';
	  lnCntr--;
	 }
	document.editor.codeWindow.value = 'Source has been updated with any changes you made .';
	numOfErrs = 0; // reset numOfErrs so that this func cannot be called twice
	document.editor.codeWindow.value += '\nSwitching to Source View automatically within 2 seconds.';
	setTimeout("viewSwitch('src')",2000);
  }
function  statBar(str)
{
	window.status = str;
}

var minTmp = 0;
var secTmp = 0;
var intrvlMinTmp = 0;
var intrvlSecTmp = 0;
var start = 0;
var stop = 1;
var intrvl = 2;
function timer(action)
{
  	var retMinTxt ='';
  	var retSecTxt ='';
   time = new Date();
   minCur = time.getMinutes();
   secCur = time.getSeconds();
   if(action == start)
   {
	  minTmp = time.getMinutes();
	  secTmp = time.getSeconds();
	  intrvlMinTmp = minTmp;
	  intrvlSecTmp = secTmp;
   }

   if(action == stop)
   {
	 var minDiff =	 (minCur - minTmp + 60) % 60;
	 var secDiff =	 (secCur - secTmp + 60) % 60;
	 if(minDiff != 0){retMinTxt = minDiff +' min.,';}
	 if(secDiff != 0){retSecTxt = secDiff +' sec.';}	else retSecTxt = 'less than 1 sec.';
	 return	 retMinTxt+ retSecTxt;
   }

   if(action == intrvl)
   {
	 var intrvlMinDiff =	(minCur - intrvlMinTmp + 60) % 60;
	 var intrvlSecDiff =	(secCur - intrvlSecTmp + 60) % 60;
	 intrvlMinTmp = time.getMinutes();
	 intrvlSecTmp = time.getSeconds();
	 if(intrvlMinDiff != 0){retMinTxt = intrvlMinDiff +' min.,';}
	 if(intrvlSecDiff != 0){retSecTxt = intrvlSecDiff +' sec.';}	else retSecTxt = 'less than 1 sec.';
	 return	 retMinTxt+ retSecTxt;
   }
}

function sampler(sample)
{
	if(curView == 'src')
	{
		document.editor.codeWindow.value = sample;
	}
	else
	{
		alert('Switch to Source View to use this function.');
	}
}

function  main()
{
  	if(curView != 'src')
  	{
	  alert('Switch to Source View to assemble.');
	  return;
	}

  	timer(start);
  	document.editor.outpMsgs.value = '';
    addMsg('\nInitializing...        ');
	init();
	if(lnNmbrsOn == true)
	{
	  addMsg('\nRemoving line numbers...    ');
	  rmLnNmbrs();
	  addMsg('Done in ' + timer(intrvl));
	}
	document.editor.outpMsgs.value = '';//clear messages
  	addMsg('Processing lines...    ');
	stripLns();
    addMsg('Done in ' + timer(intrvl));

    if(isMcrDrvPrsnt() == true)
    {
		addMsg('\nLooking for macro definitoins...   ');
		fishForMcr();
		addMsg('Done in ' + timer(intrvl));

		addMsg('\nExpanding any macros found...     ');
		fndAndXpndMcr();
		addMsg('Done in ' + timer(intrvl));
		if(chckForErrs()== true){return;}
    }
    else
    {
		addMsg('\nNo MACRO directive found... Macro passes skipped...    ');
  	}

	addMsg('\nFishing for asm directives...     ');
	fishForEqu();
	addMsg('Done in ' + timer(intrvl));

	if(chckForErrs()== true){return;}

	addMsg('\nFishing for everything else...     ');
	fishForEvElse();
	addMsg('Done in ' + timer(intrvl));

	if(chckForErrs()== true){return;}

	addMsg('\nAssembling...     ');
	assemble();
	addMsg('Done in ' + timer(intrvl));

	if(chckForErrs()== true){return;}

	addMsg('\nGenerating list output...     ');
	listGen();
	addMsg('Done in ' + timer(intrvl));
	if(chckForErrs()== true){return;}

	addMsg('\nGenerating hex output (INHX8M) ...     ');
	hexGen();
	addMsg('Done in ' + timer(intrvl));

	if(chckForErrs()== true){return;}
	var tStop = timer(stop);
	addMsg('\nAssembly Complete! in '+ tStop);
	errMsgs = '        No errors found.';

    if(document.editor.lastSwitch[0].checked)
    {
		viewSwitch('hex');   
    }
    else
    if(document.editor.lastSwitch[1].checked)
    {
		viewSwitch('list');    
    }
    
    alert('Assembly Complete! \nin '+ tStop);
}
