#ident "@(#)sho_dasm.c	1.6__08/16/96"

#include "sc.h"
/* ------------------------------------------------------------------------- */
#ifndef write_scsi

#define write_scsi(target_handle, buffer, starting_block, number_of_blocks) \
scsi_write_blocks(target_handle, buffer, starting_block, number_of_blocks)

#define read_scsi(target_handle, buffer, starting_block, number_of_blocks) \
     scsi_read_blocks(target_handle, buffer, starting_block, number_of_blocks)
#endif

# define swap_word(dst,src) \
     dst = src
# define swap_lwrd(dst,src) \
dst = src

#ifdef nodef
#define swap_word(dst,src) \
dst = src ; \
dst <<=  8; \
dst |= ((src >>  8) & 0xff)
	
#define swap_lwrd(dst,src) \
     dst = src ; \
dst <<=  8;\
     dst |= ((src >>  8) & 0xff); \
dst <<= 8; \
     dst |= ((src >> 16) & 0xff);\
dst <<= 8;\
     dst |= ((src >> 24) & 0xff)
#endif


/* ------------------------------------------------------------------------- */

sho_dasm(id, rspbuf)	   
int id;
unsigned char *rspbuf ;
{
  word  temp_w1, temp_w2, *temp_w_p;
  lwrd  temp_l1, temp_l2, temp_l3, *temp_l_p, nblocks ;
  byte  mask;
  byte dasm_device[12] ;
  int err,i,old_lcam=1, is_cfgm = 0, is_lcam = 0 ;
  int baud;
  int mbits, lbits ;
  unsigned char compare_buf[4];
  unsigned char read_stat_cmd[]= { 0x23,0,0,5,    00,01,0,02,  0,1,0,0,  0xff};
  unsigned char read_lut_cmd[] = { 0x23,0,0,5,  0x20,07,0,32,  0,1,0,0,  0xff};
  unsigned char read_50007_cmd[]={ 0x23,0,0,5,    00,07,0,32,  0,1,0,0,  0xff};  
  char mpar[6], lpar[6], msb[8], lsb[8];
  unsigned char cmdbuf[512] ;

  /* clear any pre-existing error before sending dasm command */

  if ( err = read_scsi(id, rspbuf, 1l, 1) ) {
    printf("\nShowdasm: SCSI read error: hex %x\n", err); 
    exit(1); 
  }

  if ( rspbuf[0x69] == '1'   &&	/* dasm is DLR in power-up selftest loop */
       rspbuf[0x6a] >= '0'   &&
       rspbuf[0x6a] <= 'Z'   && 
       rspbuf[0x6b] >= '0'   &&
       rspbuf[0x6b] <= 'Z' ) {
    
    cmdbuf[0] = 0x2b;     /* stop power-on selftest */
    cmdbuf[1] = 0;
    cmdbuf[2] = 0xff;
    
    snd_cmd(id,cmdbuf);
    sleep(1);
    if ( err = read_scsi(id, rspbuf, 1l, 1) ) {
      printf("\nShowdasm: SCSI read error: hex %x\n", err); 
      exit(1); 
    }
  }

  cmdbuf[0] = 0x2c;
  cmdbuf[1] = 0;
  cmdbuf[2] = 0xff;
  
  snd_cmd(id,cmdbuf);
  
  /*	sleep(1); */

  if ( err = read_scsi(id, rspbuf, 1l, 1) ) {
    printf("\nShowdasm: SCSI read error: hex %x\n", err); 
    exit(1); 
  }

#ifdef nodef

16
char vendor[8]; 		/* vendor id "CDA" 	 */
24
char device[16];		/* pif id "DASM/pifname" */
40
char rev[4];			/* nn.n			 */
44
lwrd blocks;			/* I/O blocks 		 */
48
lwrd blksiz;			/* 512			 */
52
lwrd dram_siz;			/* total DRAM		 */
56
lwrd sram_siz;			/* total SRAM		 */
60
word baud;			/* baud rate 300 to 9600 */
62
byte ucr;			/* USART Control reg	 */
63
byte scsi_id;			/* SCSI ID		 */
64
char krnl_rev[4];  		/* nn.n	krnl rev	 */
68
char *cmdblok;			/* addr of command block */
72
lwrd chksum 			/* internal checksum	 */
76
lwrd chksum2			/* production checksum   */
80
byte jumpers			/* sw jumper bits 0-2    */
81
byte can_discon			/* host supports disconnect */

#endif
  
  printf("\n%-28s  %s", "Device:", &rspbuf[24]);
  printf("\n%-28s  %s", "Pif software rev:", &rspbuf[40]);
  printf("\n%-28s  %s", "Krnl_rev:", &rspbuf[64]);
  /*printf("\ndevice: %s  pif software rev: %s  krnl_rev: %s",
    &rspbuf[24],&rspbuf[40],&rspbuf[64]);*/
  
  if (rspbuf[0x1d] == 'C' && rspbuf[0x1e] =='F' && rspbuf[0x1f] =='G')
    is_cfgm = 1;
  
  temp_l_p = (void *) &rspbuf[52];
  temp_l1  = *temp_l_p;
  
  swap_lwrd(temp_l2,temp_l1);

	       
  if (temp_l2 < 0x100000)
    printf("\n%-28s  %ldKB", "DRAM:", temp_l2/0x400);
  /*printf("\nDRAM: %ldKB ",temp_l2/0x400);*/
  else
    printf("\n%-28s  %ldMB", "DRAM:", temp_l2/0x100000);
  /*printf("\nDRAM: %ldMB ",temp_l2/0x100000);*/	

  if (is_cfgm) {
    
    temp_l_p = (void *)&rspbuf[68];
    temp_l1  = *temp_l_p;
    
    swap_lwrd(temp_l3,temp_l1);
    temp_l2 -= (temp_l3<<2);   /* io-blocks on cfgm are reduced by loaded code */
  }
  
  printf("\n%-28s  %ld", "I/O blocks:", temp_l2/512);
  /*printf("   I/O blocks: %ld ",temp_l2/512);	*/

  if (is_cfgm ) 
    printf("\n%-28s  %d", "Block size:", 512);
  /*	   printf("  block size: 512 ");*/
  else {
    
    temp_l_p = (void *)&rspbuf[48];
    temp_l1  = *temp_l_p;
    
    swap_lwrd(temp_l2,temp_l1);
    printf("\n%-28s  %d", "Block size:", temp_l2);
    /*	   printf("  block size: %d ",temp_l2);*/
  }

  printf("\n%-28s  %d", "SCSI ID:", rspbuf[63]);
  /*	printf("\nSCSI ID: %d  ",rspbuf[63]);*/

  temp_l_p = (void *)&rspbuf[68];
  temp_l1  = *temp_l_p;

  swap_lwrd(temp_l2,temp_l1);
  printf("\n%-28s  %lx", "CMDBLK addr:", temp_l2);
  /*printf(" CMDBLK addr: %lx",temp_l2);*/
	
  if (is_cfgm) {
    
    printf("\n");
    return(0);
  }

  printf("\n%-28s  hex %x", "Serial ctl reg:", rspbuf[62]);
  /*printf(" Serial ctl reg: hex %x\n",rspbuf[62]);*/

  temp_l_p = (void *)&rspbuf[76];
  temp_l1  = *temp_l_p;

  swap_lwrd(temp_l2,temp_l1);
  printf("\n%-28s  hex %lx", "Eprom checksum:", temp_l2);
  /*printf("eprom checksum: hex %lx  ",temp_l2);*/

  baud = (rspbuf[60] << 8) + rspbuf[61] ;

  if (rspbuf[80] & 0x01 ) {
    
    printf("\n%-28s  %s", "Debug Port:", "Enabled");
    /*printf(" Debug Port Enabled   ");*/
    if (rspbuf[80] & 0x02 )
      printf("\n%-28s  %s", "DBUG:", "Enabled");
    /*printf(" DBUG  Enabled   ");*/
    else
      printf("\n%-28s  %s", "DBUG:", "Disabled");
    /*printf(" DBUG Disabled   ");*/

  } else {
    
    printf("\n%-28s  %s", "DBUG:", "Disabled");
    /*printf(" DBUG Disabled    ");*/

  }

  printf("\n%-28s  %s", "Power-on RAM tests:", 
	 (rspbuf[80] & 0x04) ? "Enabled" : "Disabled");

  /*if (rspbuf[80] & 0x04 )
    printf(" Power-on RAM tests  Enabled\n");
    else
    printf(" Power-on RAM tests Disabled\n");*/

#define MSBL  0x01	/* byte order if 1: MSB LSB  if 0: LSB MSB */
#define M10B  0x08	/* 10-bit data */
#define M12B  0x0C	/* 12-bit data */
#define MPAR  0x10	/* 1 = odd parity  0 = even */
	
  if (!(strncmp(&rspbuf[29],"MACL",4))) {
    
    /* write command to dump contents of MACL's config register to block 0,
       offset hex 40 */
    
    for (i=0; i<sizeof(read_stat_cmd); i++)
      cmdbuf[i] = read_stat_cmd[i];

    cmdbuf[5] = 0;  /* macl address is 50000 */
    
    snd_cmd(id, cmdbuf);

    for (i=0; i<10; i++) {
      
      if (get_rsp(id, rspbuf)) {
	printf("\nerror dumping MACL CONFIG and STATUS REGISTERS\n"); 
	exit(1); 
      }
      if (rspbuf[0] & 02) /* function done */
	break;
    }			

    if ( (err = read_scsi(id, cmdbuf, 0l, 1)) != 0x40 && err != 0) {
      printf("\nScsi read error: hex %x\n", err); 
      exit(1); 
    }

    mask = cmdbuf[0x40] ;
    
    if (rspbuf[0x6a] == 2)
      strcpy(mpar,"NONE");
    else if (rspbuf[0x6a] == 1)
      strcpy(mpar,"ODD");
    else 
      strcpy(mpar,"EVEN"); /* value = 0 = even  */
    
    if ((mask & M12B) == M12B) 
      mbits = 12;
    else if ((mask & M10B) == M10B) 
      mbits = 10;
    else mbits = 8;
    
    if (mbits > 8) {
      
      if (mask & MSBL) 
	strcpy(msb,"MSB LSB");
      else
	strcpy(msb,"LSB MSB");
    }

    printf("\n%-28s  %s", "Parallel RS-485 port parity:", mpar);
    printf("\n%-28s  %d-bit", "Input data width:", mbits);
    /*printf("parallel RS-485 port parity: %s  input data width: %d-bit  ",
      mpar, mbits);*/

    if (mbits > 8) 
      printf("\n%-28s  %s", "Byte order:", msb);
    /*printf("byte order: %s",msb);*/

    printf("\n%-28s  %s", "Serial:", (cmdbuf[0x41] & 8) ? "RS-232" :
	   "RS-422");
    if ((cmdbuf[0x41] & 8) && (rspbuf[0x68] == 4))
      printf(" (KEYPAD)");

    /*printf("\nserial ");*/
    
    /*    if (cmdbuf[0x41] & 8)
      {
	printf("RS-232 ");
	if (rspbuf[0x68] == 4)
	  printf("(KEYPAD) ");
      }
    else
      {
	printf("RS-422 ");
      }*/

  } /* if (MACL) */

#ifdef nodef

  /*serial ports can be rs-232 or 422.  Almost all pre-DEC'95 LCAMs are 232 
    and there is no way to read the difference in hardware, anyway.  The new
    lcam daughterboards have jumpers to select RS-232 or RS-422, like the MACL
    There is also bit in the status register indicating the jumper
    setting that determines RS-232 or RS-422.  The same bit, bit 3, is used
    identically for MACL and NEW LCAM. HOWEVER, the address of the MACL's
    register is 50001, LCAM's is 50000.
    On new lcam daughterboards, a pal change doubly maps the addresses from
    50007 and 52007.  If the data there matches, it is a new lcam board*/

#endif
  else if (!(strncmp(&rspbuf[29],"LCAM",4)) || 
	   !(strncmp(&rspbuf[29],"PM/L",4))) {
    
    for (i = 0; i < (sizeof(read_lut_cmd)); i++)
      cmdbuf[i] = read_lut_cmd[i];

    snd_cmd(id, cmdbuf);
    
    for (i=0; i<10; i++) {
      
      if (get_rsp(id, rspbuf)) {
	printf("\nerror dumping LCAM LUT\n"); 
	exit(1);
      }
      if (rspbuf[0] & 02) /* function done */
	break;
    }			

    /* get LUT values */
    
    if ( (err = read_scsi(id, cmdbuf, 0l, 1))) {
      printf("\nScsi read error: hex %x\n", err); 
      exit(1); 
    }

    /* save a few - mapping only affects every 8th value from 50007 */
    
    for (i=0; i< (sizeof(compare_buf)); i++)
      compare_buf[i] = cmdbuf[0x40+(i*8)] ;
    
    /* #define show_comp */

#ifdef show_comp 
    printf("\ncompare: %02x %02x %02x %02x  ",compare_buf[0],compare_buf[1],
	   compare_buf[2],compare_buf[3]);
#endif


    for (i = 0; i < (sizeof(read_50007_cmd)); i++)
      cmdbuf[i] = read_50007_cmd[i];
    
    snd_cmd(id, cmdbuf);


    for (i=0; i<10; i++) {
      
      if (get_rsp(id, rspbuf)) {
	printf("\nerror dumping LCAM addresses from 50007\n");
	exit(1); 
      }
      if (rspbuf[0] & 02) /* function done */
	break;
    }			
    
    if ( (err = read_scsi(id, cmdbuf, 0l, 1))) {
      printf("\nScsi read error: hex %x\n", err); 
      exit(1);
    }

#ifdef show_comp
    printf("50007  ");
    
    printf("%02x %02x %02x %02x ",cmdbuf[0x40], cmdbuf[0x48],
	   cmdbuf[0x50], cmdbuf[0x58]);
#endif

    printf("\n%-28s  %s", "Parallel RS-485 port parity:", "EVEN");
    printf("\n%-28s  %d-bit", "Output data width:", 8);
    /*printf("parallel RS-485 port parity: EVEN  output data width: 8-bit");*/

    for (i=0; i<sizeof(compare_buf); i++)
      if (compare_buf[i] != cmdbuf[0x40+(i*8)])
	break;

    if (i < sizeof(compare_buf))
      
      printf("\n%-28s  %s", "Serial:", "RS-232");
    /*printf("\nserial RS-232   ");*/
    
    else {
	
      old_lcam = 0;
      for (i=0; i<sizeof(read_stat_cmd); i++)
	cmdbuf[i] = read_stat_cmd[i];
      cmdbuf[5] = 0;  /* macl address is 50001, lcam's  50000 */
      
      snd_cmd(id, cmdbuf);

      for (i=0; i<10; i++) {
	
	if (get_rsp(id, rspbuf)) {
	  printf("\nerror dumping LCAM address from 50000\n");
	  exit(1);
	}
	if (rspbuf[0] & 02) /* function done */
	  break;
      }			

      if ( (err = read_scsi(id, cmdbuf, 0l, 1)) != 0x40 && err != 0) {
	printf("\nScsi read error: hex %x\n", err); 
	exit(1);
      }

#ifdef show_comp
      printf("\ncmdbuf[0x40 - 0x41]  %02x %02x\n",
	     cmdbuf[0x40], cmdbuf[0x41]);
#endif

      printf("\n%-28s  %s", "Serial:", (cmdbuf[0x40] & 8) ? "RS-232" : "RS-422");
      /*printf("\nserial ");

      if (cmdbuf[0x40] & 8)
	printf("RS-232 ");
      else
	printf("RS-422 "); */
    
    } /* if (i < sizeof(compare_buf)) */
    
    
  }	/* if ...MACL ... else  */

  else { /* If macl else */
    
    if ( !(strncmp(&rspbuf[29],"DLR",3)) || 
	 !(strncmp(&rspbuf[29],"FDLR",4))||
	 !(strncmp(&rspbuf[29],"VDB",3))  )

      printf("\n%-28s  %s", "Serial:", "RS-422");
    /*printf("rs-422  ");*/

  } /* macl.lcam ... else */

  printf("\n%-28s  %d", "Baud rate:", baud);
  /*printf("  %d baud",baud);*/

  mask = rspbuf[62] ;

  if ((mask & 0x60) == 0)
    printf("\n%-28s  %d", "Data bits:", 8);
  /*printf(" 8-bit");*/
  else if ((mask & 0x60) == 0x20)
    printf("\n%-28s  %d", "Data bits:", 7);
  /*printf(" 7-bit");*/
  else if ((mask & 0x40) == 0x40)
    printf("\n%-28s  %d", "Data bits:", 6);
  /*printf(" 6-bit");*/
  else if ((mask & 0x60) == 0x60)
    printf("\n%-28s  %d", "Data bits:", 5);
  /*printf(" 5-bit");*/

  if ((mask & 0x18) == 0)
    printf("\n%-28s  %s", "Mode:", "Synchronous");
  /*    printf(" synchronous ");*/

  else {

    printf("\n%-28s  %s", "Mode:", "Asynchronous");
    printf("\n  %-28s  %d", "Start bits:", 1);

    if ((mask & 0x18) == 0x08)
      printf("\n  %-28s  %d", "Stop bits:", 1);
    /*printf(" 1_start_bit 1_stop_bit ");*/
    else if ((mask & 0x18) == 0x10)
      printf("\n  %-28s  %.1f", "Stop bits:", 1.5);
    /*printf(" 1_start_bit 1.5_stop_bits ");*/
    else if ((mask & 0x18) == 0x18)
      printf("\n  %-28s  %d", "Stop bits:", 2);
    /*printf(" 1_start_bit 2_stop_bits ");*/

  }

  printf("\n%-28s  ", "Parity:");

  if ((mask & 0x04) == 0)
    printf("None");
  /*printf("no_parity ");*/
  
  else 
    
    printf("%s", (mask & 02) ? "Even" : "Odd");

  /*if (mask & 02)
      printf("even_parity ");
    else
      printf("odd_parity ");*/
  
  printf("\n");
  
  return(0);

}	

get_rsp(fd, buf)
int fd;
unsigned char *buf;
{
  if (read_scsi(fd,buf,1L,1)) {
    printf("\nSCSI read failed"); 
    return(-1);
  }
  return(0);
}


snd_cmd(fd, buf)
int fd;
unsigned char *buf;
{
  if (write_scsi (fd, buf, 0L, 1)) { /* send show config command */
    printf("\nSCSI write failed"); 
    return(-1);
  }
  return(0);
}

