/*****************************************************************************
*           Change Log
*  Date     | Change
*-----------+-----------------------------------------------------------------
* 20-Dec-85 | [1.226] Created
* 25-Jan-86 | [1.327] Check for bad length
* 25-Feb-86 | [1.379] include <> => include ""
* 10-Nov-91 | [1.428] <jmn> converted for Microsoft C 6.0
* 18-Nov-91 | [1.428] <jmn> memory.h => mem1401.h, avoid ANSI name
*****************************************************************************/

#include "boolean.h"
#include "btypes.h"
#include "mem1401.h"
#include "mach.h"
#include "diag.h"
#include "instr.h"
#include "ifetch.h"
#include "arith.h"

/*****************************************************************************
				1401 Simulator

			     Subtract Instruction


			   Subtract (Two Addresses)
			   ------------------------

Instruction format

Mnemonic	Op Code	A-address	B-address
--------        ------- ---------       ---------
S		S	AAA		BBB

Function: The data in the A-field is subtracted from the B-field.  The result
is stored in the B-field.

Word Marks: The B-field must have a defining word mark, because it is this
word mark which actually stops the subtract operation.

The A-field must have a word mark only if it is shorter than the B-field.
In this case, the transmission of data from the A-field stops after the
A-field word mark is sensed.  Zeros are then inserted in the A-register
until the B-field word mark is sensed.

If the A-field is longer than the B-field, the high-order positions of
the A-field that exceed the limits imposed by the B-field are not processed.
For overflow conditions and considerations, assume that the A-field is
the same length as the B-field.


Address Registers After Operation:

I-Add		A-Add		B-Add
-----		-----		-----
NSI		A-Lw		B-Lw

Chaining: This instruction can be chained to the preceding operation (if
that instruction left usable address-register contents) by supplying
only the operation code.


			    Subtract (One Address)
			    ----------------------
Instruction format

Mnemonic	Op Code	A-address
--------        ------- ---------
S		S	AAA		

Function: The contents of the A-field is subtracted from itself.

Address Registers After Operation:

I-Add		A-Add		B-Add
-----           -----           -----
NSI		A-La		A-La

Chaining: This instruction can be chained to the preceding operation (if
that instruction left usable address-register contents) by supplying
only the operation code.


*****************************************************************************/


/****************************************************************************
*                                   inst_S
* result: boolean
*	true if instruction succeeded
*	false if instruction failed
* Effect: 
*	Executes subtract instruction
****************************************************************************/

boolean inst_S()
    {
     boolean result;

     tell_op(op_A|op_B);

     switch(I_cycle)
         {
	  case 1: /* chained */
	  case 4: /* one-address */
	  case 7: /* two-address */
	  	break;
	  default: /* Illegal length */
	  	illegal_length();
	  	return false;
	 }

     result = arith(false);
	  
     tell_new_state("B");
     return result;	
    }
