#ifndef CONTROL_H
#define CONTROL_H
#include "typedefs.h"
#include "global.h"


//#define CRAP
//#define PULSE_CRAP

#define RING_NUMBER0 255
#define RING_NUMBER1 255
#define RING_NUMBER2 255
#define RING_NUMBER3 255
#define RING_NUMBER4 255
#define RING_NUMBER5 255
#define RING_NUMBER6 255
#define RING_NUMBER7 255

#ifdef PULSE_CRAP

  #define SP 5
  #define MP 10
  #define LP 20
  #define SPMODE 0
  #define MPMODE 1
  #define LPMODE 2
  #define VBEAM5DEG 0
  #define VBEAM10DEG 1
  #define VBEAM20DEG 2

  #define	NO_TRANSDUCER_PRESENT 1
  #define STANDARD_POWER 2
  #define HIGH_POWER 3
  #define INVALID_CONFIGURATION 0
#endif

extern union MISC_CMD_U *miscCmdPtr;
extern sprb prbk5;

#define NEW_TILT_BOARD      // this board provides 1ø tilt
#define SYM_TILT

#define EIGHT_TRANSMIT_PULSES

#define OLD_MOTHERBOARD_ID 0x40
#define XMIT_BOX_PRESENT   0x40
#define XFER_SPEED_HIGH    0x02


//#define RECEIVE_TILT_CHANGE_TEST


// #define HRES_TILT   // max 193 tilt steps, only 93 used
                    // each step corresponds to 1ø tilt change
                    // 2001 12 13 check where this switch is used
                    // Currently we are using 2øtilt steps, so this
                    // define has to be commented out !!!!!

/* update history */
/*
18-11-98 18:44:02 defined V6_0 which causes the measuring cycle last 3/4 of the
                  period, i.e it measures the second sine to compute the offset.

14-07-99 18:02:47 added beam with and tilt headers for receive
01-09-99 20:25:20 for M5.2.00 symmetric offset for tilt, allowing tilt between
                  ñ46ø.
13-09-99 16:13:32 added HRES_TILT for 1ø tilt steps

26-11-2001 18:02  added rec_freq_hdr
                  The desk unit takes the responsibility to control the receive
                  frequency. It becomes independent of thr transmit frequency.
                  This is necessary to compensate the Doppler-effect.
13-12-2001 17:15  commented out HRES_TILT
30-04-2002 09:40  Added macros for on-board LED control (LED4 LED5)


*/

#define WRITE_ADH_LED(value)     *ledPtr = value; *adhLdPtr = 0;
#define WRITE_ADM_LED(value)     *ledPtr = value; *admLdPtr = 0;
#define WRITE_ADL_LED(value)     *ledPtr = value; *adhLdPtr = 0;
#define WRITE_BIT_LED(value)     *ledPtr = value; *bitLdPtr = 0;
#define WRITE_ERR_LED(value)     *ledPtr = value; *errLdPtr = 0;
#define WRITE_DT_LED(value)      *ledPtr = value; *dtLdPtr  = 0;

#define ERASE_LEDS    *errLdPtr = *dtLdPtr  = *bitLdPtr =        \
                      *admLdPtr = *adlLdPtr = *adhLdPtr = *ledPtr   = 0;

#define TURN_ON_LEDS  *errLdPtr = *dtLdPtr  = *bitLdPtr =        \
                      *admLdPtr = *adlLdPtr = *adhLdPtr = *ledPtr = 255;

#define D10_LED  0x1
#define SMXS     0x4
#define D11_LED  0x8
#define MSG_LED  0x10
#define FXMB_LED 0x20
#define SAME_OFFSET     0x00
#define OPPOSITE_OFFSET 0x08

// D10 LED - bicolor
#define TURN_TRREC_LED_RED          turnLed1 (0xFC, 0x00, 0x02);
#define TURN_TRREC_LED_GREEN        turnLed1 (0xFC, 0x01, 0x00);
#define TURN_TRREC_LED_OFF          turnLed1 (0xFC, 0x00, 0x00);
// D11 LED - bicolor
#define TURN_NEW_LED_RED            turnLed1 (0xF3, 0x00, 0x08); 
#define TURN_NEW_LED_OFF            turnLed1 (0xF3, 0x00, 0x00); 
#define TURN_NEW_LED_GREEN          turnLed1 (0xF3, 0x04, 0x00); 
// D12 LED - bicolor              // This LED turns on by the signal of the XMITTER Boards HW
#define TURN_FXMB_LED_RED           turnLed1 (0xCF, 0x00, 0x20);
#define TURN_FXMB_LED_GREEN         turnLed1 (0xCF, 0x10, 0x00);
#define TURN_FXMB_LED_OFF           turnLed1 (0xCF, 0x00, 0x00);
// LED D18 - bicolor
#define TURN_TEST_LED_RED           turnLed  (0xDD, 0x00, 0x20);
#define TURN_TEST_LED_GREEN         turnLed  (0xDD, 0x02, 0x00);
#define TURN_TEST_LED_OFF           turnLed  (0xDD, 0x00, 0x00);
// LED D19 - bicolor
#define TURN_XMBL_LED_RED           turnLed  (0x3F, 0x80, 0x00);
#define TURN_XMBL_LED_GREEN         turnLed  (0x3F, 0x00, 0x40);
#define TURN_XMBL_LED_OFF           turnLed  (0x3F, 0x00, 0x00);
// D13 LED - YELLOW               // This LED is on while the host message is processed
#define TURN_MESSAGE_LED_ON       *nLdckPtr = ledValue |=  MSG_LED;  
#define TURN_MESSAGE_LED_OFF      *nLdckPtr = ledValue &= ~MSG_LED;

/*
// D10 LED - bicolor
#define TURN_DBL_SPEED_LED_RED    *nLdckPtr = ledValue &= ~D10_LED;     // D10
#define TURN_DBL_SPEED_LED_GREEN  *nLdckPtr = ledValue |=  D10_LED;
// D11 LED - bicolor
#define TURN_NEW_LED_RED          *nLdckPtr = ledValue &= ~D11_LED;     // D11
#define TURN_NEW_LED_GREEN        *nLdckPtr = ledValue |=  D11_LED;
*/
/*
// LED D18 - bicolor              // this LED serves testing purposes
#define TURN_TEST_LED_OFF         *nLdckPtr = ledValue &=  0xDD;
#define TURN_TEST_LED_RED         ledValue |=  0x20; ledValue &=  0xFD; *nLdckPtr = ledValue;
#define TURN_TEST_LED_GREEN       ledValue |=  0x02; ledValue &=  0xDF; *nLdckPtr = ledValue;
// LED D19 - bicolor              // Led is OFF    if no XMIT boxes are connected
                                  //        RED    if XMIT box 2 is connected
                                  //        RED/GREEN if XMIT box 1 is connected
                                  //        GREEN  if XMIT boxes 1 and 2 are connected
#define TURN_XMBL_LED_OFF         *nLdckPtr = ledValue &=  0x3F;
#define TURN_XMBL_LED_RED         ledValue |=  0x80; ledValue &=  0xBF; *nLdckPtr = ledValue;
#define TURN_XMBL_LED_GREEN       ledValue |=  0x40; ledValue &=  0x7F; *nLdckPtr = ledValue;
*/
#define SET_SMXS                  *nLdckPtr = ledValue |= SMXS;    
#define CLEAR_SMXS                *nLdckPtr = ledValue &= ~SMXS;   

#define SET_DOUBLE_BUS           {icmdValue &= ~0x02; *icmdPtr = icmdValue ; }
#define SET_SINGLE_BUS           {icmdValue |=  0x02; *icmdPtr = icmdValue ; }  

#define DISABLE_TRANSMIT_RINGS  *tren0Ptr = *tren1Ptr = *tren2Ptr = *tren3Ptr = 0; \
                                *tren4Ptr = *tren5Ptr = *tren6Ptr = *tren7Ptr = 0;

#define ENABLE_TRANSMIT_RINGS *tren0Ptr = trEnable[0]; *tren1Ptr = trEnable[1]; \
     *tren2Ptr = trEnable[2]; *tren3Ptr = trEnable[3]; *tren4Ptr = trEnable[4]; \
     *tren5Ptr = trEnable[5]; *tren6Ptr = trEnable[6]; *tren7Ptr = trEnable[7];

#define DISABLE_TM_TRANSMIT_RINGS  if (!testMode){DISABLE_TRANSMIT_RINGS}

#define ENABLE_RECEIVE_RINGS    *rren00Ptr = rrng[0][0]; *rren10Ptr = rrng[0][1];
#define ENABLE_SECOND_MIXER     *rren01Ptr = rrng[1][0]; *rren11Ptr = rrng[1][1];

// this macro enables all receiver rings (group 0 unchanged) and enables all counters
#define ENABLE_ALL_COUNTERS     *rren01Ptr = *rren02Ptr = *rren11Ptr = *rren12Ptr = 255;

// this macro disables all receiver rings and enables all counters
#define DISABLE_RECEIVE_RINGS   *rren00Ptr = *rren01Ptr = *rren02Ptr =     \
                                *rren10Ptr = *rren11Ptr = *rren12Ptr = 0;

#define START_TRANSMIT          *tldrPtr = 0; ENABLE_TRANSMIT_RINGS;
#define STOP_TRANSMIT           DISABLE_TRANSMIT_RINGS;

#define SWITCH_HV_ON            miscCmdPtr -> offset |=  (HVSO | HVSR); *cmdPtr = miscCmdPtr -> offset;
#define SWITCH_HV_OFF           miscCmdPtr -> offset &= ~(HVSO | HVSR); *cmdPtr = miscCmdPtr -> offset;

#define ENABLE_HOST_COMMUNICATION  miscCmdPtr -> offset &= ~SLENA; *cmdPtr = miscCmdPtr -> offset;
#define DISABLE_HOST_COMMUNICATION miscCmdPtr -> offset |=  SLENA; *cmdPtr = miscCmdPtr -> offset;
  
#define TURN_FULL_POWER_ON      miscCmdPtr -> offset &= ~HVSH; *cmdPtr = miscCmdPtr -> offset;
#define TURN_QUARTER_POWER_ON   miscCmdPtr -> offset |=  HVSH; *cmdPtr = miscCmdPtr -> offset;

#define SET_MEASUREMENT_MODE    psfr -> p0 &= ~8;
#define SET_PROGRAMMING_MODE    psfr -> p0 |= 8;


#define MAX_RDT_PULSE_NUMBER 16
#define TILT_NEGATOR        64

// to define multibeam transmit

#define XDCR_HIGH_BIT 0
#define XDCR_LOW_BIT 1
#define UPPER_MIXING     /* June 6    after quarry */
#define XDUCER_TYPE 2    /* 90 kHz sonar   */
#define XDCR_TYPE_REC
#define EIGHT_GSTEPS

enum AFL_HEADERS
{
  AFL0_HDR = 0x190,
  AFL1_HDR = 0x191,
  AFL2_HDR = 0x192,
  AFL3_HDR = 0x193,
  AFL4_HDR = 0x194,
  AFL5_HDR = 0x195,
  AFL6_HDR = 0x196,
  AFL7_HDR = 0x197
};

enum PULSE_LENGTH
{
  SHORT   = 0xFB,    // .5%
  MEDIUM  = 0x00,    // 1%
  LONG    = 0x0A,    // 2%
  XLNG    = 0x28,    // 8%
  RDT     = 0x1E,
};


#undef  ENOUGH_MEMORY

#ifndef NEW_TILT_BOARD        // currently defined (in line 39)
  #ifndef HRES_TILT           // currently undefined
    #define ZERO_TILT_OFFSET 30 // offset in tr/rec_tilt_arr for 0ø.
  #else
    #define ZERO_TILT_OFFSET 50 // offset in tr/rec_tilt_arr for 0ø.
  #endif
#else
  #define ZERO_TILT_OFFSET 30 // offset in tr/rec_tilt_arr for 0ø.  - this is the currently used offset
#endif

/* define for receiver buffer length       */
#define REC_BUF_LNGHT 128


/* led control macros */
#define LED0_OFF  { psfr -> p0 &=   ~1; ledState.led0State = false;}    /* turn off PA0           */
#define LED0_ON   { psfr -> p0 |=    1; ledState.led0State = true; }    /* turn on  PA0           */
#define LED1_OFF  { psfr -> p0 &=   ~2; ledState.led1State = false;}    /* turn off PA0           */
#define LED1_ON   { psfr -> p0 |=    2; ledState.led1State = true; }    /* turn on  PA0           */
#define LED2_OFF  { psfr -> p0 &=   ~4; ledState.led2State = false;}    /* turn off PA0           */
#define LED2_ON   { psfr -> p0 |=    4; ledState.led2State = true; }    /* turn on  PA0           */
#define LED3_OFF  { psfr -> p0 &=   ~8; ledState.led3State = false;}    /* turn off LED on PA4    */
#define LED3_ON   { psfr -> p0 |=    8; ledState.led3State = true; }    /* turn on  LED on PA4    */
#define LED4_ON   { psfr -> p0 |=  ~16; ledState.led4State = false;}    /* turn on  LED on PA4    */
#define LED4_OFF  { psfr -> p0 &=   16; ledState.led4State = true; }    /* turn off LED on PA4    */
#define LED5_ON   { psfr -> p0 |=  ~32; ledState.led5State = false;}    /* turn on  LED on PA5    */
#define LED5_OFF  { psfr -> p0 &=   32; ledState.led5State = true; }    /* turn off LED on PA5    */
#define LED6_ON   { psfr -> p0 |=  ~64; ledState.led6State = false;}    /* turn on  LED on PA6    */
#define LED6_OFF  { psfr -> p0 &=   64; ledState.led6State = true; }    /* turn off LED on PA6    */
#define LED7_OFF  psfr -> p0 &= ~128;    /* turn on  LED on PA7    */
#define LED7_ON   psfr -> p0 |=  128;     /* turn off LED on PA7    */

#undef SHADING_ALLOWED

/* Header for control board programming    */

/* Derived from CNTR.H on June 28 because of changing the
   beam description table
*/
/*   *********************************
     *  Version for prototype        *
     *       V1.0                    *
     *                               *
     *    Feb 17,1994                *
     *              by Charles Moori *
     *********************************
*/
#define setvector(inum,addr) *(void interrupt (far * far *)())((inum)*4) = (addr)

#define IOTRAPFLAG 0x02;

typedef enum
{
  BYRON1_HDR             = 0x12,
  BYRON2_HDR             = 0x14,
  ZERO_HDR               = 0x00,
  MODE_HDR               = 0x80,
  REC_TILT_HDR           = 0x81,
  RANGE_HDR              = 0x82,
  TVG_HDR                = 0x83,
  REC_BVN_HDR            = 0x84,
  TEST_HDR               = 0x85,
  CALIB_HDR              = 0x86,
  FREQ_HDR               = 0x87,
  XDCR_HDR               = 0x88,   // not used
  GO_HDR                 = 0x89,
  SW_OVER                = 0x8a,
  SW_REV                 = 0x8b,   // not used
  GCS_HDR                = 0x8c,   // obsoleted
  DWELL_HDR              = 0x8d,   // obsoleted
  TR_TILT_HDR            = 0x8e,
  TR_BVN_HDR             = 0x8f,
  REC_FREQ_HDR           = 0x90,   // new header to separate transmit and receive headers
  PULSE_HDR              = 0x91,
  RDT_DIRECT0_HDR        = 0x92,
  RANGE_HIGH             = 0x93,
  RANGE_LOW              = 0x94,
  REC_STAB_HDR           = 0x95,  //    0x95 header for Receive stab offset
  REC_BREAK_HDR          = 0x96,
  REV_HIGH_HDR           = 0x97,
  REV_LOW_HDR            = 0x98,
  TILT_RES_HDR           = 0x99,
  RDT_XMIT0_HDR          = 0x9A,
  RDT_XMIT1_HDR          = 0x9B,
  RDT_XMIT2_HDR          = 0x9C,
  RDT_XMIT3_HDR          = 0x9D,
  RDT_XMIT4_HDR          = 0xA0,
  RDT_XMIT5_HDR          = 0xA1,
  RDT_XMIT6_HDR          = 0xA2,
  RDT_XMIT7_HDR          = 0xA3,
  RDT_REVERSE_HDR        = 0xA4,
  TEST_START_HIGH_HDR    = 0xB1,
  TEST_START_LOW_HDR     = 0xB2,
  TEST_ENABLE_HDR        = 0xB5,
  PITCH_HDR              = 0xB6,  // initial value (sent in the regular message for the pitch angle)
  ROLL_HDR               = 0xB7,  // initial value (sent in the regular message for the roll angle)
  STABILIZED_MODE_HDR    = 0xB8,  // 0: partial stabilization, 1: half circle stabilization, 2: full stabilization
  STAB_TEST_ANGLE        = 0xB9,
  STAB_PLANE_ROTATION    = 0xBA,  // the number given as an offset indicates what half stave looks in BOW direction
  SHADING_CONTROL_HDR    = 0xBB,
  POSITIVE_RING_HDR      = 0xBC,  // positive ring enable at receive, when Transmit Test enabled
  NEGATIVE_RING_HDR      = 0xBD,  // negative ring enable at receive, when Transmit Test enabled
  SYNC_NUM_HDR           = 0xCF,
  STAB_TILT_HDR          = 0xFC,
  STATUS_HDR             = 0xFE,
  TERM_CHR               = 0x9f
} HEADER_DEFINITIONS;  

/* port 2 definitions  */
#define pc      psfr -> p2
#define pc0_set psfr -> p2 |= 1
#define pc1_set psfr -> p2 |= 2
#define pc2_set psfr -> p2 |= 4
#define pc3_set psfr -> p2 |= 8
#define pc4_set psfr -> p2 |= 16
#define pc5_set psfr -> p2 |= 32
#define pc6_set psfr -> p2 |= 64
#define pc7_set psfr -> p2 |= 128

#define pc0_clr psfr -> p2 &= ~1
#define pc1_clr psfr -> p2 &= ~2
#define pc2_clr psfr -> p2 &= ~4
#define pc3_clr psfr -> p2 &= ~8
#define pc4_clr psfr -> p2 &= ~16
#define pc5_clr psfr -> p2 &= ~32
#define pc6_clr psfr -> p2 &= ~64
#define pc7_clr psfr -> p2 &= ~128

/* status bits*/
#define OUT_OF_RNG   4

#define  fint() __emit__(0x0f,0x92)      /* Needed for interrupt-driven I/O */
#define retrbi() __emit__(0x0f,0x91)    /*   for return from register bank             */
																				/*   switching IT)                             */
#define movspa() __emit__(0x0f,0x25)    /*   moves SP after bank switching             */
#define movspb(n) __emit__(0x0f,0x95,0xf8+(n&7)) /*   moves sp before bank switching   */
#define poll() __emit__(0x9b)


#endif

