head     56.3;
access   paws bayes jws quist brad dew jwh;
symbols  ;
locks    ; strict;
comment  @# @;


56.3
date     93.01.27.13.23.32;  author jwh;  state Exp;
branches ;
next     56.2;

56.2
date     93.01.27.12.03.33;  author jwh;  state Exp;
branches ;
next     56.1;

56.1
date     91.11.05.09.59.37;  author jwh;  state Exp;
branches ;
next     55.1;

55.1
date     91.08.25.10.34.34;  author jwh;  state Exp;
branches ;
next     54.1;

54.1
date     91.03.18.15.34.49;  author jwh;  state Exp;
branches ;
next     53.1;

53.1
date     91.03.11.19.34.31;  author jwh;  state Exp;
branches ;
next     52.1;

52.1
date     91.02.19.09.20.40;  author jwh;  state Exp;
branches ;
next     51.1;

51.1
date     91.01.30.16.19.08;  author jwh;  state Exp;
branches ;
next     50.1;

50.1
date     90.10.29.16.33.04;  author jwh;  state Exp;
branches ;
next     49.1;

49.1
date     90.08.14.14.16.48;  author jwh;  state Exp;
branches ;
next     48.1;

48.1
date     90.07.26.11.23.20;  author jwh;  state Exp;
branches ;
next     47.1;

47.1
date     90.05.14.11.09.24;  author dew;  state Exp;
branches ;
next     46.1;

46.1
date     90.05.07.08.56.19;  author jwh;  state Exp;
branches ;
next     45.1;

45.1
date     90.04.19.16.04.32;  author jwh;  state Exp;
branches ;
next     44.1;

44.1
date     90.04.01.22.21.57;  author jwh;  state Exp;
branches ;
next     43.1;

43.1
date     90.03.20.14.14.22;  author jwh;  state Exp;
branches ;
next     42.1;

42.1
date     90.01.23.17.58.23;  author jwh;  state Exp;
branches ;
next     41.1;

41.1
date     89.12.22.11.40.16;  author jwh;  state Exp;
branches ;
next     40.1;

40.1
date     89.09.29.12.01.23;  author jwh;  state Exp;
branches ;
next     39.1;

39.1
date     89.09.26.16.46.19;  author dew;  state Exp;
branches ;
next     38.1;

38.1
date     89.08.29.11.38.41;  author jwh;  state Exp;
branches ;
next     37.1;

37.1
date     89.05.12.11.52.18;  author dew;  state Exp;
branches ;
next     36.1;

36.1
date     89.02.06.10.29.41;  author dew;  state Exp;
branches ;
next     35.1;

35.1
date     89.02.02.13.47.06;  author dew;  state Exp;
branches ;
next     34.1;

34.1
date     89.01.23.16.21.20;  author jwh;  state Exp;
branches ;
next     33.1;

33.1
date     89.01.16.11.51.55;  author dew;  state Exp;
branches ;
next     32.1;

32.1
date     89.01.10.12.02.12;  author bayes;  state Exp;
branches ;
next     31.1;

31.1
date     88.12.14.18.22.56;  author bayes;  state Exp;
branches ;
next     30.1;

30.1
date     88.12.09.13.59.41;  author dew;  state Exp;
branches ;
next     29.1;

29.1
date     88.10.31.15.44.16;  author bayes;  state Exp;
branches ;
next     28.1;

28.1
date     88.10.06.11.09.56;  author dew;  state Exp;
branches ;
next     27.1;

27.1
date     88.09.29.11.53.44;  author bayes;  state Exp;
branches ;
next     26.1;

26.1
date     88.09.28.14.17.21;  author bayes;  state Exp;
branches ;
next     25.1;

25.1
date     88.03.02.09.49.51;  author bayes;  state Exp;
branches ;
next     24.1;

24.1
date     87.08.31.10.24.15;  author jws;  state Exp;
branches ;
next     23.1;

23.1
date     87.08.26.11.13.07;  author bayes;  state Exp;
branches ;
next     22.1;

22.1
date     87.08.17.11.50.35;  author bayes;  state Exp;
branches ;
next     21.1;

21.1
date     87.08.12.14.35.38;  author bayes;  state Exp;
branches ;
next     20.1;

20.1
date     87.07.30.11.46.47;  author bayes;  state Exp;
branches ;
next     19.1;

19.1
date     87.06.01.09.02.51;  author jws;  state Exp;
branches ;
next     18.1;

18.1
date     87.05.20.16.05.51;  author bayes;  state Exp;
branches ;
next     17.1;

17.1
date     87.04.30.11.08.29;  author jws;  state Exp;
branches ;
next     16.1;

16.1
date     87.04.26.16.18.22;  author jws;  state Exp;
branches ;
next     15.1;

15.1
date     87.04.13.10.01.13;  author jws;  state Exp;
branches ;
next     14.1;

14.1
date     87.04.01.16.13.05;  author jws;  state Exp;
branches ;
next     13.1;

13.1
date     87.02.28.19.01.00;  author jws;  state Exp;
branches ;
next     12.1;

12.1
date     87.02.02.13.55.30;  author jws;  state Exp;
branches ;
next     11.1;

11.1
date     87.01.19.10.21.54;  author jws;  state Exp;
branches ;
next     10.1;

10.1
date     86.12.24.11.37.39;  author jws;  state Exp;
branches ;
next     9.1;

9.1
date     86.12.12.15.23.17;  author bayes;  state Exp;
branches ;
next     8.1;

8.1
date     86.11.27.12.30.34;  author jws;  state Exp;
branches ;
next     7.1;

7.1
date     86.11.20.14.47.53;  author hal;  state Exp;
branches ;
next     6.1;

6.1
date     86.11.04.18.35.47;  author paws;  state Exp;
branches ;
next     5.1;

5.1
date     86.10.28.17.25.43;  author hal;  state Exp;
branches ;
next     4.1;

4.1
date     86.09.30.20.20.24;  author hal;  state Exp;
branches ;
next     3.1;

3.1
date     86.09.01.12.42.02;  author hal;  state Exp;
branches ;
next     2.1;

2.1
date     86.07.30.15.19.29;  author hal;  state Exp;
branches ;
next     1.1;

1.1
date     86.06.30.17.20.54;  author danm;  state tmp;
branches ;
next     ;


desc
@Base file for PWS 3.2 release.

@


56.3
log
@
pws2rcs automatic delta on Wed Jan 27 13:14:25 MST 1993
@
text
@$page$

module CS80ir; {Command Set '80 initialization routines}

import
  sysglobals, bkgnd, discHPIB, CS80;

export
  type
    tva_type = {three-vector address (6 bytes)}
      packed record
	cyln: unsgn24;
	head: unsgn8;
	sect: signed16;
      end;

    de_log_type = {the two distinct types of data error logs}
      (ert, runtime);

    log_entry_type = {data error log entry}
      packed record
	physical_cyln:  signed16;
	physical_head:  unsgn8;
	physical_sect:  unsgn8;
	logical_cyln:   signed16;
	logical_head:   unsgn8;
	logical_sect:   unsgn8;
	error_byte:     unsgn8;
	occurrences:    unsgn8;
      end;

    log_info_type = {info returned by the READ_DATA_ERROR_LOGS command}
      packed record
	my_special_pad: unsgn8;   {internal allignment only; not sent by the device!!!}
	log_entries:    unsgn8;
	other_info:     array[1..5+2+1] of char;
	entry:          array[1..106] of log_entry_type;
      end;

    ert_area_type =
      (sector_ert, track_ert, cylinder_ert, surface_ert, volume_ert);

  {
    NOTE: the following functions each perform a COMPLETE transaction. They:
	.  issue a (device or transparent) command         (Command message)
	.  transfer data if applicable                     (Execution message)
	.  return the resulting QSTAT                      (Reporting message)
  }
  function formatting_option  (uep: uep_type; option: unsgn8): unsgn8;
  function initiate_diagnostic(uep: uep_type; unit: unsgn4; loops: signed16; section: unsgn8): unsgn8;
  function initialize_media   (uep: uep_type; options, interleave: unsgn8): unsgn8;
  function preset_drive       (uep: uep_type): unsgn8;
  function clear_logs         (uep: uep_type; logcode: unsgn8): unsgn8;
  function set_3V_address     (uep: uep_type; cyln: unsgn24; head: unsgn8; sect: signed16): unsgn8;
  function data_error_log     (uep: uep_type; de_log: de_log_type; head: unsgn8;
			       var log_bytes: log_info_type): unsgn8;
  function pattern_ert        (uep: uep_type; ert_area: ert_area_type; loops: unsgn8;
			       var ert_message: boolean; var log_entry: log_entry_type): unsgn8;
  function spare_block        (uep: uep_type; sparingmode: unsgn8): unsgn8;
$page$

implement {CS80ir}


type
  setunitvol_type = {SET_UNIT/SET_VOLUME command pair}
    packed record
      setunit: CMD_type;
      setvol: CMD_type;
    end;


function suv_CMD_pair(uep: uep_type): setunitvol_type;
  begin {suv_CMD_pair}
    suv_CMD_pair.setunit := CMD_type(signed16(CMDset_unit_0)+uep^.du);
    suv_CMD_pair.setvol  := CMD_type(signed16(CMDset_vol_0)+uep^.dv);
  end; {suv_CMD_pair}


function formatting_option(uep: uep_type; option: unsgn8): unsgn8;
  {
    issue the following command sequence:
      .  SET_UNIT
      .  SET_VOLUME
      .  SET_FORMAT_OPTION (Subset/80 only)
    issue the option byte in an execution message
    return the QSTAT byte
  }
  var
    fo: {the 5 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	initutil: CMD_type;
	setformatoption: unsgn8;
	parameter: unsgn8;
      end;
    em: {the single byte execution message}
      packed record
	optionbyte: unsgn8;
      end;
  begin {formatting_option}
    fo.setunitvol      := suv_CMD_pair(uep);
    fo.initutil        := CMDinit_util_REM;
    fo.setformatoption := 243;
    fo.parameter       := 95;
    HPIBshort_msge_out(uep, command_sec, addr(fo), sizeof(fo));
    HPIBwait_for_ppol(uep);
    em.optionbyte := option;
    HPIBshort_msge_out(uep, execution_sec, addr(em), sizeof(em));
    HPIBwait_for_ppol(uep);
    formatting_option := qstat(uep);
  end; {formatting_option}
$page$

function initiate_diagnostic(uep: uep_type; unit: unsgn4; loops: signed16; section: unsgn8): unsgn8;
  {
    set specified unit & issue the INITIATE_DIAGNOSTIC command
    return the QSTAT byte
  }
  var
    id: {the 5 bytes in the initiate diagnostic command message}
      packed record
	setunit: CMD_type;
	initdiag: CMD_type;
	loops: signed16;
	section: unsgn8;
      end;
  begin {initiate_diagnostic}
    id.setunit  := CMD_type(signed16(CMDset_unit_0)+unit);
    id.initdiag := CMDinit_diagnostic;
    id.loops    := loops;
    id.section  := section;
    HPIBshort_msge_out(uep, command_sec, addr(id), sizeof(id));
    HPIBwait_for_ppol(uep);
    initiate_diagnostic := qstat(uep);
  end; {initiate_diagnostic}


function initialize_media(uep: uep_type; options, interleave: unsgn8): unsgn8;
  {
    issue the following command sequence:
      .  SET_UNIT
      .  SET_VOLUME
      .  INITIALIZE_MEDIA
    return the QSTAT byte
  }
  var
    im: {the 5 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	initmedia: CMD_type;
	options: unsgn8;
	interleave: unsgn8;
      end;
  begin {initialize_media}
    im.setunitvol := suv_CMD_pair(uep);
    im.initmedia  := CMDinit_media;
    im.options    := options;
    im.interleave := interleave;
    HPIBshort_msge_out(uep, command_sec, addr(im), sizeof(im));
    HPIBwait_for_ppol(uep);
    initialize_media := qstat(uep);
  end; {initialize_media}
$page$

function preset_drive(uep: uep_type): unsgn8;
  {
    issue the following command sequence:
      .  SET_UNIT
      .  SET_VOLUME
      .  PRESET_DRIVE
    return the QSTAT byte
  }
  var
    pd: {the 4 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	initutil: CMD_type;
	presetdrive: unsgn8;
      end;
  begin {preset_drive}
    pd.setunitvol  := suv_CMD_pair(uep);
    pd.initutil    := CMDinit_util_NEM;
    pd.presetdrive := 206;
    HPIBshort_msge_out(uep, command_sec, addr(pd), sizeof(pd));
    HPIBwait_for_ppol(uep);
    preset_drive := qstat(uep);
  end; {preset_drive}


function clear_logs(uep: uep_type; logcode: unsgn8): unsgn8;
  {
    issue the following command sequence:
      .  SET_UNIT
      .  SET_VOLUME
      .  CLEAR_LOGS
    return the QSTAT byte
  }
  var
    cl: {the 5 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	initutil: CMD_type;
	clearlogs: unsgn8;
	logcode: unsgn8;
      end;
  begin {clear_logs}
    cl.setunitvol := suv_CMD_pair(uep);
    cl.initutil   := CMDinit_util_NEM;
    cl.clearlogs  := 205;
    cl.logcode    := logcode;
    HPIBshort_msge_out(uep, command_sec, addr(cl), sizeof(cl));
    HPIBwait_for_ppol(uep);
    clear_logs := qstat(uep);
  end; {clear_logs}
$page$

function data_error_log(uep: uep_type; de_log: de_log_type; head: unsgn8;
			var log_bytes: log_info_type): unsgn8;
  {
    issue the appropriate READ_DATA_ERROR_LOG command
    place the returned data error log info in the passed variable 'log_bytes'
    return the QSTAT byte
  }
  type
    read_de_log_micro_op_type =
      array[de_log_type] of unsgn8;
  const
    read_de_log_micro_op = read_de_log_micro_op_type
      [ {ert} 198, {runtime} 197 ];
  var
    del: {the 5 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	initutil: CMD_type;
	readlogs: unsgn8;
	head: unsgn8;
      end;
  begin {data_error_log}
    del.setunitvol := suv_CMD_pair(uep);
    del.initutil   := CMDinit_util_SEM;
    del.readlogs   := read_de_log_micro_op[de_log];
    del.head       := head;
    HPIBshort_msge_out(uep, command_sec, addr(del), sizeof(del));
    HPIBwait_for_ppol(uep);
    try
      HPIBshort_msge_in(uep, execution_sec, addr(log_bytes, 1), sizeof(log_bytes)-1);
    recover
      with bip_type(uep^.dvrtemp)^ do  {confirm the "premature" eoi}
	begin
	  if (escapecode<>-10) or (iores<>zbadhardware) then
	    escape(escapecode);
	  iores := inoerror;
	end; {recover}
    HPIBwait_for_ppol(uep);
    data_error_log := qstat(uep);
  end; {data_error_log}
$page$

function pattern_ert(uep: uep_type; ert_area: ert_area_type; loops: unsgn8;
		     var ert_message: boolean; var log_entry: log_entry_type): unsgn8;
  {
    issue the appropriate ERROR_RATE_TEST command
    if specified, request an execution message and set var boolean accordingly
    return the QSTAT byte
  }
  var
    ert: {the 9 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	initutil: CMD_type;
	patternert: unsgn8;
	loops: unsgn8;
	offset: signed8;
	report: unsgn8;
	testarea: unsgn8;
	datasource: unsgn8;
      end;
  begin {pattern_ert}
    ert.setunitvol := suv_CMD_pair(uep);
    if ert_message
      then ert.initutil := CMDinit_util_SEM     {send execution message}
      else ert.initutil := CMDinit_util_NEM;    {no execution message}
    ert.patternert      := 200;                 {pattern ert micro opcode}
    ert.loops           := loops;               {as specified}
    ert.offset          := 0;                   {no offset}
    ert.report          := 0;                   {data error log info only}
    ert.testarea        := ord(ert_area);       {as specified}
    ert.datasource      := 0;                   {internal pattern table}
    HPIBshort_msge_out(uep, command_sec, addr(ert), sizeof(ert));
    if ert_message then
      try
	HPIBwait_for_ppol(uep);
	HPIBshort_msge_in(uep, execution_sec, addr(log_entry), sizeof(log_entry));
      recover
	with bip_type(uep^.dvrtemp)^ do  {confirm the "premature" eoi}
	  begin
	    if (escapecode<>-10) or (iores<>zbadhardware) then
	      escape(escapecode);
	    iores := inoerror;
	    ert_message := false;
	  end; {recover}
    HPIBwait_for_ppol(uep);
    pattern_ert := qstat(uep);
  end; {pattern_ert}
$page$

function set_3V_address(uep: uep_type; cyln: unsgn24; head: unsgn8; sect: signed16): unsgn8;
  {
    issue the following command sequence:
      .  SET_UNIT
      .  SET_VOLUME
      .  SET_ADDRESS
    return the QSTAT byte
  }
  var
    s3va: {the 10 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	nop: CMD_type;
	setadd: CMD_type;
	tva: tva_type;
      end;
  begin {set_3V_address}
    s3va.setunitvol := suv_CMD_pair(uep);
    s3va.nop        := CMDno_op;
    s3va.setadd     := CMDset_address_3V;
    s3va.tva.cyln   := cyln;
    s3va.tva.head   := head;
    s3va.tva.sect   := sect;
    HPIBshort_msge_out(uep, command_sec, addr(s3va), sizeof(s3va));
    HPIBwait_for_ppol(uep);
    set_3V_address := qstat(uep);
  end; {set_3V_address}


function spare_block(uep: uep_type; sparingmode: unsgn8): unsgn8;
  {
    issue the following command sequence:
      .  SET_UNIT
      .  SET_VOLUME
      .  SPARE_BLOCK
    return the QSTAT byte
  }
  var
    sb: {the 4 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	spareblock: CMD_type;
	sparingmode: unsgn8;
      end;
  begin {spare_block}
    sb.setunitvol   := suv_CMD_pair(uep);
    sb.spareblock   := CMDspare_block;
    sb.sparingmode  := sparingmode;
    HPIBshort_msge_out(uep, command_sec, addr(sb), sizeof(sb));
    HPIBwait_for_ppol(uep);
    spare_block := qstat(uep);
  end; {spare_block}


end; {CS80ir}
$page$

module Qminit;

import
  sysglobals, bkgnd, discHPIB, CS80, CS80dsr, CS80ir, midecs;

export
  function Qdevicename(uep: uep_type; var saved_ioresult: integer): string255;
  function Qintdata(uep: uep_type): interleave_data;
  function Qphydata(uep: uep_type): physical_data;
  procedure Qgetinitparms;
  procedure Qminitialize(uep: uep_type; interleave_factor: shortint);

implement {Qminit}


var
  describe_bytes: describe_type;
  formatting_option_byte: unsgn8;
  formatting_option_supported: boolean;
  diagnostic_to_be_run: boolean;
  initialize_options_byte: unsgn8;
  volume_ert_passes: unsgn8;
  clear_logs_option_byte: unsgn8;


const
  default_initialize_options_byte = 0;
  default_volume_ert_passes = 2;
  default_clear_logs_option_byte = 1;  {clear ert logs only}


function Qintdata(uep: uep_type): interleave_data;
  begin {Qintdata}
    with describe_bytes do
      begin
	Qintdata.min := 1;              {minimum}
	if formatting_option_supported
	  then Qintdata.max := 255      {maximum subject to format specified}
	  else Qintdata.max := mif;     {true maximum}
	Qintdata.def :=  currentif;     {default}
      end; {with}
  end; {Qintdata}


function Qphydata(uep: uep_type): physical_data;
  begin {Qphydata}
    with describe_bytes do
      begin
	Qphydata.nspm := maxhadd+1;         {number of surfaces per medium}
	Qphydata.ntps := maxcadd+1;         {number of tracks/surface}
	if maxsadd>0                        {number of sectors per track}
	  then Qphydata.nspt := maxsadd+1                       {actual}
	  else Qphydata.nspt := (maxsvadd.lfb+1)*nbpb div 256;  {pseudo}
      end; {with}
  end; {Qphydata}
$page$

function Qdevicename(uep: uep_type; var saved_ioresult: integer): string255;

  var
    retry_required: boolean;
    devicename: string255;
    index: integer;
    bcd_product_number: {within the describe bytes}
      packed record case integer of
	0: (dn:  unsgn24);
	1: (bcd: packed array[1..6] of unsgn4);
      end;
    product_number: integer;
    fixed_vol_byte:
      packed record case integer of
	0: (byte: unsgn8);
	1: (bit:  packed array[0..7] of boolean);
      end;

  begin {Qdevicename}

    ioresult := ord(inoerror);

    try
      allocate_bkgnd_info(uep);

      if HPIBamigo_identify(uep) div 256<>2 then
	ioresc_bkgnd(uep, znodevice);

      repeat
	retry_required := false;
	if set_unitvol(uep)<>0 then
	  handle_bad_status(uep, true, retry_required);
      until not retry_required;

      repeat
	retry_required := false;
	if describe(uep, describe_bytes)<>0 then
	  handle_bad_status(uep, true, retry_required);
      until not retry_required;

      formatting_option_supported := false;  {until proven otherwise}
      if describe_bytes.ct.subset80 then  {see if multiple formats supported}
	try
	  formatting_option_byte := 255;  {test value}
	  repeat
	    retry_required := false;
	    if formatting_option(uep, formatting_option_byte)<>0 then
	      handle_bad_status(uep, true, retry_required);
	  until not retry_required;
	  formatting_option_supported := true;
	  formatting_option_byte := 0;  {device's primary format}
	recover
	  with bip_type(uep^.dvrtemp)^ do  {confirm the command rejection}
	    begin
	      if (escapecode<>-10) or (iores<>zbadmode) then
		escape(escapecode);
	      iores := inoerror;
	    end; {recover}

      deallocate_bkgnd_info(uep);
    recover
      begin
	deallocate_bkgnd_info(uep);
	if escapecode<>-10 then escape(escapecode);
	ioresult := uep^.dvrtemp;  {flag problem with describe}
	if saved_ioresult=ord(inoerror) then  {report to miui}
	  saved_ioresult := ioresult;
      end; {recover}

    if ioresult=ord(inoerror) then
      with describe_bytes do
	begin

	  bcd_product_number.dn := dn;
	  product_number := 0;
	  for index := 1 to 5 do
	    product_number := product_number*10+bcd_product_number.bcd[index];

	  devicename := 'HP';
	  strwrite(devicename, 3, index, product_number:1);

	  case dt of
	    0:        devicename := devicename+' fixed disc';
	    1:        begin
			fixed_vol_byte.byte := describe_bytes.fvb;
			if fixed_vol_byte.bit[7-uep^.dv]
			  then devicename := devicename+' fixed disc'
			  else devicename := devicename+' removeable disc';
		      end;
	    2:        devicename := devicename+' tape';
	    otherwise {can't further describe the generic device type};

	  end; {case}
	end {with}
    else
      devicename := '<inaccessible CS80 device>';

    Qdevicename := devicename;

  end; {Qdevicename}
$page$

procedure allow_modification(prompt: string255; var parm: unsgn8; maxparm: unsgn8);
  var
    response: string255;
    newparm, i: integer;
    modification_ok: boolean;
  begin {allow_modification}
    repeat
      write(prompt, ' (defaults to ', parm:1, ') ');
      readln(response);
      modification_ok := strlen(response)=0;
      if not modification_ok then
	try
	  strread(response, 1, i, newparm);
	  modification_ok := (i=strlen(response)+1) and (newparm>=0) and (newparm<=maxparm);
	  if modification_ok then
	    parm := newparm;
	recover
	  if not (-escapecode in [8, 10]) then escape(escapecode);
    until modification_ok;
  end; {allow_modification}


procedure Qgetinitparms;
  var
    ch: char;
  begin {Qgetinitparms}
    with describe_bytes do
      begin

	diagnostic_to_be_run    := not ct.subset80 and (dt<=1);  {CS80 discs only}
	initialize_options_byte := default_initialize_options_byte;
	volume_ert_passes       := default_volume_ert_passes;
	clear_logs_option_byte  := default_clear_logs_option_byte;

	if extended_features_mode then
	  begin {extended_features_mode stuff}
	    writeln;
	    if diagnostic_to_be_run then
	      diagnostic_to_be_run := not yes('Suppress running the initial diagnostic?');
	    allow_modification('Initialize options byte?', initialize_options_byte, 255);
	    if not ct.subset80 and (dt<=1) then
	      begin
		allow_modification('Volume ert passes?', volume_ert_passes, 255);
		allow_modification('Clear logs option byte?', clear_logs_option_byte, 255);
	      end; {if}
	  end {extended_features_mode stuff}
	else if dt=2 then  {it's a tape; user may want to force re-certification}
	  begin
	    writeln;
	    writeln('Medium is a tape: do you wish to force');
	    if yes('  re-certification if already certified?') then
	      initialize_options_byte := 1;  {force re-certification}
	  end; {if}

	if formatting_option_supported then
	  begin
	    writeln;
	    allow_modification('Formatting option?', formatting_option_byte, 239);
	  end; {if}

      end; {with}
  end; {Qgetinitparms}
$page$

procedure Qminitialize(uep: uep_type; interleave_factor: shortint);

var
  retry_required: boolean;
  diag_unit: unsgn4;
  ert_msge: boolean;
  de_log: de_log_type;
  head: unsgn8;
  log_bytes: log_info_type;
  log_index: unsgn8;
  this_entry_ptr: ^log_entry_type;
  sparing_required: boolean;
  sparing_tries: signed16;

const
  sector_ert_passes = 20;       {suspect sector scans}
  track_ert_passes  = 20;       {spared track scans}
  max_sparing_tries = 5;        {maximum attempts to spare a sector/track}

begin {Qminitialize}

  try
    allocate_bkgnd_info(uep);

    if diagnostic_to_be_run then
      begin
	diag_unit := uep^.du;  {try the explicit unit; may get illegal opcode}
	repeat
	  try
	    repeat  {make one pass of the complete diagnostic}
	      retry_required := false;
	      if initiate_diagnostic(uep, diag_unit, {loops} 1, {section} 0)<>0 then
		handle_bad_status(uep, true, retry_required);
	    until not retry_required;
	  recover
	    with bip_type(uep^.dvrtemp)^ do  {confirm the illegal opcode}
	      if (escapecode<>-10) or (iores<>zbadmode) then
		escape(escapecode)  {probably diagnostic_result}
	      else if diag_unit=15 then  {unit 15 was rejected!!!}
		ioresc_bkgnd(uep, zcatchall)
	      else  {explicit unit diagnostic not supported; use unit 15}
		begin
		  iores := inoerror;
		  diag_unit := 15;  {original CS/80 allows unit 15 only}
		  retry_required := true;
		end; {if}
	until not retry_required;
      end; {if}

    if formatting_option_supported then
      repeat  {set the user-specified formatting option}
	retry_required := false;
	if formatting_option(uep, formatting_option_byte)<>0 then
	  handle_bad_status(uep, true, retry_required);
      until not retry_required;

    invalidate_stateinfo(uep);  {formatting may change the blocksize!}

    repeat  {initialize the medium}
      retry_required := false;
      if initialize_media(uep, initialize_options_byte, interleave_factor)<>0 then
	handle_bad_status(uep, true, retry_required);
    until not retry_required;

    if not describe_bytes.ct.subset80 and (describe_bytes.dt<=1) then
      begin  {CS80 disc; perform testing and sparing}

	repeat  {preset the drive to force logging of runtime data errors}
	  retry_required := false;
	  if preset_drive(uep)<>0 then
	    handle_bad_status(uep, true, retry_required);
	until not retry_required;

	repeat  {clear the ert logs}
	  retry_required := false;
	  if clear_logs(uep, clear_logs_option_byte)<>0 then
	    handle_bad_status(uep, true, retry_required);
	until not retry_required;

	repeat  {set address 0}
	  retry_required := false;
	  if set_3V_address(uep, {cyln} 0, {head} 0, {sect} 0)<>0 then
	    handle_bad_status(uep, true, retry_required);
	until not retry_required;

	if volume_ert_passes>0 then
	  repeat  {run a complete volume ert the specified number of passes}
	    retry_required := false;
	    ert_msge := false;  {do not request an execution message}
	    if pattern_ert(uep, volume_ert, volume_ert_passes, ert_msge, log_bytes.entry[1])<>0 then
	      handle_bad_status(uep, true, retry_required);
	  until not retry_required;

	for de_log := ert to runtime do
	  for head := 0 to describe_bytes.maxhadd do
	    begin

	      repeat  {read the appropriate data error log}
		retry_required := false;
		if data_error_log(uep, de_log, head, log_bytes)<>0 then
		  handle_bad_status(uep, true, retry_required);
	      until not retry_required;

	      for log_index := 1 to log_bytes.log_entries do
		begin
		  this_entry_ptr := addr(log_bytes.entry[log_index]);
		  with this_entry_ptr^ do
		    begin

		      repeat  {set address to the suspect sector}
			retry_required := false;
			if set_3V_address(uep, logical_cyln, logical_head, logical_sect)<>0 then
			  handle_bad_status(uep, true, retry_required);
		      until not retry_required;

		      repeat  {run a sector ert; a message back implies sparing required}
			retry_required := false;
			sparing_required := true; {request an execution message}
			if pattern_ert(uep, sector_ert, sector_ert_passes,
				       sparing_required, this_entry_ptr^)<>0 then
			  handle_bad_status(uep, true, retry_required);
		      until not retry_required;

		      sparing_tries := 0;
		      while sparing_required and (sparing_tries<max_sparing_tries) do
			begin
			  sparing_tries := sparing_tries+1;

			  repeat  {address the bad sector; may be different after the track ert!}
			    retry_required := false;
			    if set_3V_address(uep, logical_cyln, logical_head, logical_sect)<>0 then
			      handle_bad_status(uep, true, retry_required);
			  until not retry_required;

			  repeat  {spare without retaining data}
			    retry_required := false;
			    if spare_block(uep, {sparingmode} 1)<>0 then
			      handle_bad_status(uep, true, retry_required);
			  until not retry_required;

			  repeat  {set address to the beginning of the affected track}
			    retry_required := false;
			    if set_3V_address(uep, logical_cyln, logical_head, 0)<>0 then
			      handle_bad_status(uep, true, retry_required);
			  until not retry_required;

			  repeat  {run a track ert; a message back implies sparing required again!!!}
			    retry_required := false;
			    sparing_required := true; {request an execution message}
			    if pattern_ert(uep, track_ert, track_ert_passes,
					   sparing_required, this_entry_ptr^)<>0 then
			      handle_bad_status(uep, true, retry_required);
			  until not retry_required;

			end; {while}

		      if sparing_required then ioresc_bkgnd(uep, zinitfail);

		    end; {with this_entry_ptr^}

		end; {for log_index}

	    end; {for head}

      end; {if device is a CS/80 disc}
$page$

    repeat  {describe volume again to update the media parameters}
      retry_required := false;
      if describe(uep, describe_bytes)<>0 then
	handle_bad_status(uep, true, retry_required);
    until not retry_required;

    deallocate_bkgnd_info(uep);

  recover
    begin
      abort_bkgnd_process(uep);
      ioresult := uep^.dvrtemp;
      uep^.dvrtemp := ord(inoerror);  {report the error only once}
      escape(-10);
    end; {recover}

end; {Qminitialize}

end {Qminit}

@


56.2
log
@
pws2rcs automatic delta on Wed Jan 27 11:57:27 MST 1993
@
text
@d1 774
@


56.1
log
@Automatic bump of revision number for PWS version 3.25
@
text
@a0 774
$page$

module CS80ir; {Command Set '80 initialization routines}

import
  sysglobals, bkgnd, discHPIB, CS80;

export
  type
    tva_type = {three-vector address (6 bytes)}
      packed record
	cyln: unsgn24;
	head: unsgn8;
	sect: signed16;
      end;

    de_log_type = {the two distinct types of data error logs}
      (ert, runtime);

    log_entry_type = {data error log entry}
      packed record
	physical_cyln:  signed16;
	physical_head:  unsgn8;
	physical_sect:  unsgn8;
	logical_cyln:   signed16;
	logical_head:   unsgn8;
	logical_sect:   unsgn8;
	error_byte:     unsgn8;
	occurrences:    unsgn8;
      end;

    log_info_type = {info returned by the READ_DATA_ERROR_LOGS command}
      packed record
	my_special_pad: unsgn8;   {internal allignment only; not sent by the device!!!}
	log_entries:    unsgn8;
	other_info:     array[1..5+2+1] of char;
	entry:          array[1..106] of log_entry_type;
      end;

    ert_area_type =
      (sector_ert, track_ert, cylinder_ert, surface_ert, volume_ert);

  {
    NOTE: the following functions each perform a COMPLETE transaction. They:
	.  issue a (device or transparent) command         (Command message)
	.  transfer data if applicable                     (Execution message)
	.  return the resulting QSTAT                      (Reporting message)
  }
  function formatting_option  (uep: uep_type; option: unsgn8): unsgn8;
  function initiate_diagnostic(uep: uep_type; unit: unsgn4; loops: signed16; section: unsgn8): unsgn8;
  function initialize_media   (uep: uep_type; options, interleave: unsgn8): unsgn8;
  function preset_drive       (uep: uep_type): unsgn8;
  function clear_logs         (uep: uep_type; logcode: unsgn8): unsgn8;
  function set_3V_address     (uep: uep_type; cyln: unsgn24; head: unsgn8; sect: signed16): unsgn8;
  function data_error_log     (uep: uep_type; de_log: de_log_type; head: unsgn8;
			       var log_bytes: log_info_type): unsgn8;
  function pattern_ert        (uep: uep_type; ert_area: ert_area_type; loops: unsgn8;
			       var ert_message: boolean; var log_entry: log_entry_type): unsgn8;
  function spare_block        (uep: uep_type; sparingmode: unsgn8): unsgn8;
$page$

implement {CS80ir}


type
  setunitvol_type = {SET_UNIT/SET_VOLUME command pair}
    packed record
      setunit: CMD_type;
      setvol: CMD_type;
    end;


function suv_CMD_pair(uep: uep_type): setunitvol_type;
  begin {suv_CMD_pair}
    suv_CMD_pair.setunit := CMD_type(signed16(CMDset_unit_0)+uep^.du);
    suv_CMD_pair.setvol  := CMD_type(signed16(CMDset_vol_0)+uep^.dv);
  end; {suv_CMD_pair}


function formatting_option(uep: uep_type; option: unsgn8): unsgn8;
  {
    issue the following command sequence:
      .  SET_UNIT
      .  SET_VOLUME
      .  SET_FORMAT_OPTION (Subset/80 only)
    issue the option byte in an execution message
    return the QSTAT byte
  }
  var
    fo: {the 5 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	initutil: CMD_type;
	setformatoption: unsgn8;
	parameter: unsgn8;
      end;
    em: {the single byte execution message}
      packed record
	optionbyte: unsgn8;
      end;
  begin {formatting_option}
    fo.setunitvol      := suv_CMD_pair(uep);
    fo.initutil        := CMDinit_util_REM;
    fo.setformatoption := 243;
    fo.parameter       := 95;
    HPIBshort_msge_out(uep, command_sec, addr(fo), sizeof(fo));
    HPIBwait_for_ppol(uep);
    em.optionbyte := option;
    HPIBshort_msge_out(uep, execution_sec, addr(em), sizeof(em));
    HPIBwait_for_ppol(uep);
    formatting_option := qstat(uep);
  end; {formatting_option}
$page$

function initiate_diagnostic(uep: uep_type; unit: unsgn4; loops: signed16; section: unsgn8): unsgn8;
  {
    set specified unit & issue the INITIATE_DIAGNOSTIC command
    return the QSTAT byte
  }
  var
    id: {the 5 bytes in the initiate diagnostic command message}
      packed record
	setunit: CMD_type;
	initdiag: CMD_type;
	loops: signed16;
	section: unsgn8;
      end;
  begin {initiate_diagnostic}
    id.setunit  := CMD_type(signed16(CMDset_unit_0)+unit);
    id.initdiag := CMDinit_diagnostic;
    id.loops    := loops;
    id.section  := section;
    HPIBshort_msge_out(uep, command_sec, addr(id), sizeof(id));
    HPIBwait_for_ppol(uep);
    initiate_diagnostic := qstat(uep);
  end; {initiate_diagnostic}


function initialize_media(uep: uep_type; options, interleave: unsgn8): unsgn8;
  {
    issue the following command sequence:
      .  SET_UNIT
      .  SET_VOLUME
      .  INITIALIZE_MEDIA
    return the QSTAT byte
  }
  var
    im: {the 5 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	initmedia: CMD_type;
	options: unsgn8;
	interleave: unsgn8;
      end;
  begin {initialize_media}
    im.setunitvol := suv_CMD_pair(uep);
    im.initmedia  := CMDinit_media;
    im.options    := options;
    im.interleave := interleave;
    HPIBshort_msge_out(uep, command_sec, addr(im), sizeof(im));
    HPIBwait_for_ppol(uep);
    initialize_media := qstat(uep);
  end; {initialize_media}
$page$

function preset_drive(uep: uep_type): unsgn8;
  {
    issue the following command sequence:
      .  SET_UNIT
      .  SET_VOLUME
      .  PRESET_DRIVE
    return the QSTAT byte
  }
  var
    pd: {the 4 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	initutil: CMD_type;
	presetdrive: unsgn8;
      end;
  begin {preset_drive}
    pd.setunitvol  := suv_CMD_pair(uep);
    pd.initutil    := CMDinit_util_NEM;
    pd.presetdrive := 206;
    HPIBshort_msge_out(uep, command_sec, addr(pd), sizeof(pd));
    HPIBwait_for_ppol(uep);
    preset_drive := qstat(uep);
  end; {preset_drive}


function clear_logs(uep: uep_type; logcode: unsgn8): unsgn8;
  {
    issue the following command sequence:
      .  SET_UNIT
      .  SET_VOLUME
      .  CLEAR_LOGS
    return the QSTAT byte
  }
  var
    cl: {the 5 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	initutil: CMD_type;
	clearlogs: unsgn8;
	logcode: unsgn8;
      end;
  begin {clear_logs}
    cl.setunitvol := suv_CMD_pair(uep);
    cl.initutil   := CMDinit_util_NEM;
    cl.clearlogs  := 205;
    cl.logcode    := logcode;
    HPIBshort_msge_out(uep, command_sec, addr(cl), sizeof(cl));
    HPIBwait_for_ppol(uep);
    clear_logs := qstat(uep);
  end; {clear_logs}
$page$

function data_error_log(uep: uep_type; de_log: de_log_type; head: unsgn8;
			var log_bytes: log_info_type): unsgn8;
  {
    issue the appropriate READ_DATA_ERROR_LOG command
    place the returned data error log info in the passed variable 'log_bytes'
    return the QSTAT byte
  }
  type
    read_de_log_micro_op_type =
      array[de_log_type] of unsgn8;
  const
    read_de_log_micro_op = read_de_log_micro_op_type
      [ {ert} 198, {runtime} 197 ];
  var
    del: {the 5 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	initutil: CMD_type;
	readlogs: unsgn8;
	head: unsgn8;
      end;
  begin {data_error_log}
    del.setunitvol := suv_CMD_pair(uep);
    del.initutil   := CMDinit_util_SEM;
    del.readlogs   := read_de_log_micro_op[de_log];
    del.head       := head;
    HPIBshort_msge_out(uep, command_sec, addr(del), sizeof(del));
    HPIBwait_for_ppol(uep);
    try
      HPIBshort_msge_in(uep, execution_sec, addr(log_bytes, 1), sizeof(log_bytes)-1);
    recover
      with bip_type(uep^.dvrtemp)^ do  {confirm the "premature" eoi}
	begin
	  if (escapecode<>-10) or (iores<>zbadhardware) then
	    escape(escapecode);
	  iores := inoerror;
	end; {recover}
    HPIBwait_for_ppol(uep);
    data_error_log := qstat(uep);
  end; {data_error_log}
$page$

function pattern_ert(uep: uep_type; ert_area: ert_area_type; loops: unsgn8;
		     var ert_message: boolean; var log_entry: log_entry_type): unsgn8;
  {
    issue the appropriate ERROR_RATE_TEST command
    if specified, request an execution message and set var boolean accordingly
    return the QSTAT byte
  }
  var
    ert: {the 9 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	initutil: CMD_type;
	patternert: unsgn8;
	loops: unsgn8;
	offset: signed8;
	report: unsgn8;
	testarea: unsgn8;
	datasource: unsgn8;
      end;
  begin {pattern_ert}
    ert.setunitvol := suv_CMD_pair(uep);
    if ert_message
      then ert.initutil := CMDinit_util_SEM     {send execution message}
      else ert.initutil := CMDinit_util_NEM;    {no execution message}
    ert.patternert      := 200;                 {pattern ert micro opcode}
    ert.loops           := loops;               {as specified}
    ert.offset          := 0;                   {no offset}
    ert.report          := 0;                   {data error log info only}
    ert.testarea        := ord(ert_area);       {as specified}
    ert.datasource      := 0;                   {internal pattern table}
    HPIBshort_msge_out(uep, command_sec, addr(ert), sizeof(ert));
    if ert_message then
      try
	HPIBwait_for_ppol(uep);
	HPIBshort_msge_in(uep, execution_sec, addr(log_entry), sizeof(log_entry));
      recover
	with bip_type(uep^.dvrtemp)^ do  {confirm the "premature" eoi}
	  begin
	    if (escapecode<>-10) or (iores<>zbadhardware) then
	      escape(escapecode);
	    iores := inoerror;
	    ert_message := false;
	  end; {recover}
    HPIBwait_for_ppol(uep);
    pattern_ert := qstat(uep);
  end; {pattern_ert}
$page$

function set_3V_address(uep: uep_type; cyln: unsgn24; head: unsgn8; sect: signed16): unsgn8;
  {
    issue the following command sequence:
      .  SET_UNIT
      .  SET_VOLUME
      .  SET_ADDRESS
    return the QSTAT byte
  }
  var
    s3va: {the 10 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	nop: CMD_type;
	setadd: CMD_type;
	tva: tva_type;
      end;
  begin {set_3V_address}
    s3va.setunitvol := suv_CMD_pair(uep);
    s3va.nop        := CMDno_op;
    s3va.setadd     := CMDset_address_3V;
    s3va.tva.cyln   := cyln;
    s3va.tva.head   := head;
    s3va.tva.sect   := sect;
    HPIBshort_msge_out(uep, command_sec, addr(s3va), sizeof(s3va));
    HPIBwait_for_ppol(uep);
    set_3V_address := qstat(uep);
  end; {set_3V_address}


function spare_block(uep: uep_type; sparingmode: unsgn8): unsgn8;
  {
    issue the following command sequence:
      .  SET_UNIT
      .  SET_VOLUME
      .  SPARE_BLOCK
    return the QSTAT byte
  }
  var
    sb: {the 4 bytes in the command message}
      packed record
	setunitvol: setunitvol_type;
	spareblock: CMD_type;
	sparingmode: unsgn8;
      end;
  begin {spare_block}
    sb.setunitvol   := suv_CMD_pair(uep);
    sb.spareblock   := CMDspare_block;
    sb.sparingmode  := sparingmode;
    HPIBshort_msge_out(uep, command_sec, addr(sb), sizeof(sb));
    HPIBwait_for_ppol(uep);
    spare_block := qstat(uep);
  end; {spare_block}


end; {CS80ir}
$page$

module Qminit;

import
  sysglobals, bkgnd, discHPIB, CS80, CS80dsr, CS80ir, midecs;

export
  function Qdevicename(uep: uep_type; var saved_ioresult: integer): string255;
  function Qintdata(uep: uep_type): interleave_data;
  function Qphydata(uep: uep_type): physical_data;
  procedure Qgetinitparms;
  procedure Qminitialize(uep: uep_type; interleave_factor: shortint);

implement {Qminit}


var
  describe_bytes: describe_type;
  formatting_option_byte: unsgn8;
  formatting_option_supported: boolean;
  diagnostic_to_be_run: boolean;
  initialize_options_byte: unsgn8;
  volume_ert_passes: unsgn8;
  clear_logs_option_byte: unsgn8;


const
  default_initialize_options_byte = 0;
  default_volume_ert_passes = 2;
  default_clear_logs_option_byte = 1;  {clear ert logs only}


function Qintdata(uep: uep_type): interleave_data;
  begin {Qintdata}
    with describe_bytes do
      begin
	Qintdata.min := 1;              {minimum}
	if formatting_option_supported
	  then Qintdata.max := 255      {maximum subject to format specified}
	  else Qintdata.max := mif;     {true maximum}
	Qintdata.def :=  currentif;     {default}
      end; {with}
  end; {Qintdata}


function Qphydata(uep: uep_type): physical_data;
  begin {Qphydata}
    with describe_bytes do
      begin
	Qphydata.nspm := maxhadd+1;         {number of surfaces per medium}
	Qphydata.ntps := maxcadd+1;         {number of tracks/surface}
	if maxsadd>0                        {number of sectors per track}
	  then Qphydata.nspt := maxsadd+1                       {actual}
	  else Qphydata.nspt := (maxsvadd.lfb+1)*nbpb div 256;  {pseudo}
      end; {with}
  end; {Qphydata}
$page$

function Qdevicename(uep: uep_type; var saved_ioresult: integer): string255;

  var
    retry_required: boolean;
    devicename: string255;
    index: integer;
    bcd_product_number: {within the describe bytes}
      packed record case integer of
	0: (dn:  unsgn24);
	1: (bcd: packed array[1..6] of unsgn4);
      end;
    product_number: integer;
    fixed_vol_byte:
      packed record case integer of
	0: (byte: unsgn8);
	1: (bit:  packed array[0..7] of boolean);
      end;

  begin {Qdevicename}

    ioresult := ord(inoerror);

    try
      allocate_bkgnd_info(uep);

      if HPIBamigo_identify(uep) div 256<>2 then
	ioresc_bkgnd(uep, znodevice);

      repeat
	retry_required := false;
	if set_unitvol(uep)<>0 then
	  handle_bad_status(uep, true, retry_required);
      until not retry_required;

      repeat
	retry_required := false;
	if describe(uep, describe_bytes)<>0 then
	  handle_bad_status(uep, true, retry_required);
      until not retry_required;

      formatting_option_supported := false;  {until proven otherwise}
      if describe_bytes.ct.subset80 then  {see if multiple formats supported}
	try
	  formatting_option_byte := 255;  {test value}
	  repeat
	    retry_required := false;
	    if formatting_option(uep, formatting_option_byte)<>0 then
	      handle_bad_status(uep, true, retry_required);
	  until not retry_required;
	  formatting_option_supported := true;
	  formatting_option_byte := 0;  {device's primary format}
	recover
	  with bip_type(uep^.dvrtemp)^ do  {confirm the command rejection}
	    begin
	      if (escapecode<>-10) or (iores<>zbadmode) then
		escape(escapecode);
	      iores := inoerror;
	    end; {recover}

      deallocate_bkgnd_info(uep);
    recover
      begin
	deallocate_bkgnd_info(uep);
	if escapecode<>-10 then escape(escapecode);
	ioresult := uep^.dvrtemp;  {flag problem with describe}
	if saved_ioresult=ord(inoerror) then  {report to miui}
	  saved_ioresult := ioresult;
      end; {recover}

    if ioresult=ord(inoerror) then
      with describe_bytes do
	begin

	  bcd_product_number.dn := dn;
	  product_number := 0;
	  for index := 1 to 5 do
	    product_number := product_number*10+bcd_product_number.bcd[index];

	  devicename := 'HP';
	  strwrite(devicename, 3, index, product_number:1);

	  case dt of
	    0:        devicename := devicename+' fixed disc';
	    1:        begin
			fixed_vol_byte.byte := describe_bytes.fvb;
			if fixed_vol_byte.bit[7-uep^.dv]
			  then devicename := devicename+' fixed disc'
			  else devicename := devicename+' removeable disc';
		      end;
	    2:        devicename := devicename+' tape';
	    otherwise {can't further describe the generic device type};

	  end; {case}
	end {with}
    else
      devicename := '<inaccessible CS80 device>';

    Qdevicename := devicename;

  end; {Qdevicename}
$page$

procedure allow_modification(prompt: string255; var parm: unsgn8; maxparm: unsgn8);
  var
    response: string255;
    newparm, i: integer;
    modification_ok: boolean;
  begin {allow_modification}
    repeat
      write(prompt, ' (defaults to ', parm:1, ') ');
      readln(response);
      modification_ok := strlen(response)=0;
      if not modification_ok then
	try
	  strread(response, 1, i, newparm);
	  modification_ok := (i=strlen(response)+1) and (newparm>=0) and (newparm<=maxparm);
	  if modification_ok then
	    parm := newparm;
	recover
	  if not (-escapecode in [8, 10]) then escape(escapecode);
    until modification_ok;
  end; {allow_modification}


procedure Qgetinitparms;
  var
    ch: char;
  begin {Qgetinitparms}
    with describe_bytes do
      begin

	diagnostic_to_be_run    := not ct.subset80 and (dt<=1);  {CS80 discs only}
	initialize_options_byte := default_initialize_options_byte;
	volume_ert_passes       := default_volume_ert_passes;
	clear_logs_option_byte  := default_clear_logs_option_byte;

	if extended_features_mode then
	  begin {extended_features_mode stuff}
	    writeln;
	    if diagnostic_to_be_run then
	      diagnostic_to_be_run := not yes('Suppress running the initial diagnostic?');
	    allow_modification('Initialize options byte?', initialize_options_byte, 255);
	    if not ct.subset80 and (dt<=1) then
	      begin
		allow_modification('Volume ert passes?', volume_ert_passes, 255);
		allow_modification('Clear logs option byte?', clear_logs_option_byte, 255);
	      end; {if}
	  end {extended_features_mode stuff}
	else if dt=2 then  {it's a tape; user may want to force re-certification}
	  begin
	    writeln;
	    writeln('Medium is a tape: do you wish to force');
	    if yes('  re-certification if already certified?') then
	      initialize_options_byte := 1;  {force re-certification}
	  end; {if}

	if formatting_option_supported then
	  begin
	    writeln;
	    allow_modification('Formatting option?', formatting_option_byte, 239);
	  end; {if}

      end; {with}
  end; {Qgetinitparms}
$page$

procedure Qminitialize(uep: uep_type; interleave_factor: shortint);

var
  retry_required: boolean;
  diag_unit: unsgn4;
  ert_msge: boolean;
  de_log: de_log_type;
  head: unsgn8;
  log_bytes: log_info_type;
  log_index: unsgn8;
  this_entry_ptr: ^log_entry_type;
  sparing_required: boolean;
  sparing_tries: signed16;

const
  sector_ert_passes = 20;       {suspect sector scans}
  track_ert_passes  = 20;       {spared track scans}
  max_sparing_tries = 5;        {maximum attempts to spare a sector/track}

begin {Qminitialize}

  try
    allocate_bkgnd_info(uep);

    if diagnostic_to_be_run then
      begin
	diag_unit := uep^.du;  {try the explicit unit; may get illegal opcode}
	repeat
	  try
	    repeat  {make one pass of the complete diagnostic}
	      retry_required := false;
	      if initiate_diagnostic(uep, diag_unit, {loops} 1, {section} 0)<>0 then
		handle_bad_status(uep, true, retry_required);
	    until not retry_required;
	  recover
	    with bip_type(uep^.dvrtemp)^ do  {confirm the illegal opcode}
	      if (escapecode<>-10) or (iores<>zbadmode) then
		escape(escapecode)  {probably diagnostic_result}
	      else if diag_unit=15 then  {unit 15 was rejected!!!}
		ioresc_bkgnd(uep, zcatchall)
	      else  {explicit unit diagnostic not supported; use unit 15}
		begin
		  iores := inoerror;
		  diag_unit := 15;  {original CS/80 allows unit 15 only}
		  retry_required := true;
		end; {if}
	until not retry_required;
      end; {if}

    if formatting_option_supported then
      repeat  {set the user-specified formatting option}
	retry_required := false;
	if formatting_option(uep, formatting_option_byte)<>0 then
	  handle_bad_status(uep, true, retry_required);
      until not retry_required;

    invalidate_stateinfo(uep);  {formatting may change the blocksize!}

    repeat  {initialize the medium}
      retry_required := false;
      if initialize_media(uep, initialize_options_byte, interleave_factor)<>0 then
	handle_bad_status(uep, true, retry_required);
    until not retry_required;

    if not describe_bytes.ct.subset80 and (describe_bytes.dt<=1) then
      begin  {CS80 disc; perform testing and sparing}

	repeat  {preset the drive to force logging of runtime data errors}
	  retry_required := false;
	  if preset_drive(uep)<>0 then
	    handle_bad_status(uep, true, retry_required);
	until not retry_required;

	repeat  {clear the ert logs}
	  retry_required := false;
	  if clear_logs(uep, clear_logs_option_byte)<>0 then
	    handle_bad_status(uep, true, retry_required);
	until not retry_required;

	repeat  {set address 0}
	  retry_required := false;
	  if set_3V_address(uep, {cyln} 0, {head} 0, {sect} 0)<>0 then
	    handle_bad_status(uep, true, retry_required);
	until not retry_required;

	if volume_ert_passes>0 then
	  repeat  {run a complete volume ert the specified number of passes}
	    retry_required := false;
	    ert_msge := false;  {do not request an execution message}
	    if pattern_ert(uep, volume_ert, volume_ert_passes, ert_msge, log_bytes.entry[1])<>0 then
	      handle_bad_status(uep, true, retry_required);
	  until not retry_required;

	for de_log := ert to runtime do
	  for head := 0 to describe_bytes.maxhadd do
	    begin

	      repeat  {read the appropriate data error log}
		retry_required := false;
		if data_error_log(uep, de_log, head, log_bytes)<>0 then
		  handle_bad_status(uep, true, retry_required);
	      until not retry_required;

	      for log_index := 1 to log_bytes.log_entries do
		begin
		  this_entry_ptr := addr(log_bytes.entry[log_index]);
		  with this_entry_ptr^ do
		    begin

		      repeat  {set address to the suspect sector}
			retry_required := false;
			if set_3V_address(uep, logical_cyln, logical_head, logical_sect)<>0 then
			  handle_bad_status(uep, true, retry_required);
		      until not retry_required;

		      repeat  {run a sector ert; a message back implies sparing required}
			retry_required := false;
			sparing_required := true; {request an execution message}
			if pattern_ert(uep, sector_ert, sector_ert_passes,
				       sparing_required, this_entry_ptr^)<>0 then
			  handle_bad_status(uep, true, retry_required);
		      until not retry_required;

		      sparing_tries := 0;
		      while sparing_required and (sparing_tries<max_sparing_tries) do
			begin
			  sparing_tries := sparing_tries+1;

			  repeat  {address the bad sector; may be different after the track ert!}
			    retry_required := false;
			    if set_3V_address(uep, logical_cyln, logical_head, logical_sect)<>0 then
			      handle_bad_status(uep, true, retry_required);
			  until not retry_required;

			  repeat  {spare without retaining data}
			    retry_required := false;
			    if spare_block(uep, {sparingmode} 1)<>0 then
			      handle_bad_status(uep, true, retry_required);
			  until not retry_required;

			  repeat  {set address to the beginning of the affected track}
			    retry_required := false;
			    if set_3V_address(uep, logical_cyln, logical_head, 0)<>0 then
			      handle_bad_status(uep, true, retry_required);
			  until not retry_required;

			  repeat  {run a track ert; a message back implies sparing required again!!!}
			    retry_required := false;
			    sparing_required := true; {request an execution message}
			    if pattern_ert(uep, track_ert, track_ert_passes,
					   sparing_required, this_entry_ptr^)<>0 then
			      handle_bad_status(uep, true, retry_required);
			  until not retry_required;

			end; {while}

		      if sparing_required then ioresc_bkgnd(uep, zinitfail);

		    end; {with this_entry_ptr^}

		end; {for log_index}

	    end; {for head}

      end; {if device is a CS/80 disc}
$page$

    repeat  {describe volume again to update the media parameters}
      retry_required := false;
      if describe(uep, describe_bytes)<>0 then
	handle_bad_status(uep, true, retry_required);
    until not retry_required;

    deallocate_bkgnd_info(uep);

  recover
    begin
      abort_bkgnd_process(uep);
      ioresult := uep^.dvrtemp;
      uep^.dvrtemp := ord(inoerror);  {report the error only once}
      escape(-10);
    end; {recover}

end; {Qminitialize}

end {Qminit}

@


55.1
log
@Automatic bump of revision number for PWS version 3.25A
@
text
@@


54.1
log
@Automatic bump of revision number for PWS version 3.24
@
text
@@


53.1
log
@Automatic bump of revision number for PWS version 3.24B
@
text
@@


52.1
log
@Automatic bump of revision number for PWS version 3.24A
@
text
@@


51.1
log
@Automatic bump of revision number for PWS version 3.24d
@
text
@@


50.1
log
@Automatic bump of revision number for PWS version 3.23c
@
text
@@


49.1
log
@Automatic bump of revision number for PWS version 3.24b
@
text
@@


48.1
log
@Automatic bump of revision number for PWS version 3.24a
@
text
@@


47.1
log
@Automatic bump of revision number for PWS version 3.23
@
text
@@


46.1
log
@Automatic bump of revision number for PWS version 3.23
@
text
@@


45.1
log
@Automatic bump of revision number for PWS version 3.23C
@
text
@@


44.1
log
@Automatic bump of revision number for PWS version 3.23B
@
text
@@


43.1
log
@Automatic bump of revision number for PWS version 3.23aA
@
text
@@


42.1
log
@Automatic bump of revision number for PWS version 3.23e
@
text
@@


41.1
log
@Automatic bump of revision number for PWS version 3.23d
@
text
@@


40.1
log
@Automatic bump of revision number for PWS version 3.23c
@
text
@@


39.1
log
@Automatic bump of revision number for PWS version 3.23b
@
text
@@


38.1
log
@Automatic bump of revision number for PWS version 3.23a
@
text
@@


37.1
log
@Automatic bump of revision number for PWS version 3.3a
@
text
@@


36.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


35.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


34.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


33.1
log
@Automatic bump of revision number for PWS version 3.22D
@
text
@@


32.1
log
@Automatic bump of revision number for PWS version 3.22C
@
text
@@


31.1
log
@Automatic bump of revision number for PWS version 3.22B
@
text
@@


30.1
log
@Automatic bump of revision number for PWS version 3.22A
@
text
@@


29.1
log
@Automatic bump of revision number for PWS version 3.22b
@
text
@@


28.1
log
@Automatic bump of revision number for PWS version 3.3b
@
text
@@


27.1
log
@Automatic bump of revision number for PWS version 3.3a
@
text
@@


26.1
log
@Automatic bump of revision number for PWS version 3.3 Synch
@
text
@@


25.1
log
@Automatic bump of revision number for PWS version 3.2Y
@
text
@@


24.1
log
@Automatic bump of revision number for PWS version 3.2
@
text
@@


23.1
log
@Automatic bump of revision number for PWS version 3.2P
@
text
@@


22.1
log
@Automatic bump of revision number for PWS version 3.2N
@
text
@@


21.1
log
@Automatic bump of revision number for PWS version 3.2M
@
text
@@


20.1
log
@Automatic bump of revision number for PWS version 3.2L
@
text
@@


19.1
log
@Automatic bump of revision number for PWS version 3.2K
@
text
@@


18.1
log
@Automatic bump of revision number for PWS version 3.2J
@
text
@@


17.1
log
@Automatic bump of revision number for PWS version 3.2I+
@
text
@@


16.1
log
@Automatic bump of revision number for PWS version 3.2I
@
text
@@


15.1
log
@Automatic bump of revision number for PWS version 3.2H
@
text
@@


14.1
log
@Automatic bump of revision number for PWS version 3.2G
@
text
@@


13.1
log
@Automatic bump of revision number for PWS version 3.2F
@
text
@@


12.1
log
@Automatic bump of revision number for PWS version 3.2E
@
text
@@


11.1
log
@Automatic bump of revision number for PWS version 3.2D
@
text
@@


10.1
log
@Automatic bump of revision number for PWS version 3.2C
@
text
@@


9.1
log
@Automatic bump of revision number for PWS version 3.2B
@
text
@@


8.1
log
@Automatic bump of revision number for PWS version 3.2A
@
text
@@


7.1
log
@Automatic bump of revision number for PWS version 3.2l
@
text
@@


6.1
log
@Automatic bump of revision number for PWS version 3.2k
@
text
@@


5.1
log
@Automatic bump of revision number for PWS version 3.2j
@
text
@@


4.1
log
@Automatic bump of revision number for PWS version 3.2i
@
text
@@


3.1
log
@Auto bump revision for PAWS 3.2h
@
text
@@


2.1
log
@Auto bump rev number to 2.1 for sys 3.2e.
@
text
@@


1.1
log
@Initial revision
@
text
@@
