[comp.sys.tandy] PDD Information

crds@pyrite.som.cwru.edu (Glenn A. Emelko) (01/08/90)

/* 
 * This is the first of two postings; this contains the code that I used to
 * test the PDD.  The second posting (to follow) contains some PD source
 * which I pulled from CI$, it's a basic program for the Model 100 to allow
 * you to do some basic I/O functions with it.  I had to uuencode it because
 * of the long line lengths, otherwise there is no other coding on it, it's
 * a straight ASCII text file uuencoded.
 */

#include <stdio.h>
#include <fcntl.h>

/*
 * This code is provided in an AS-IS form, no warranty expressed or implied
 * from the usage of this code, the correctness or completness of it or it's
 * writer, or anything else for that matter is given -- You are at your own
 * risk -- I recommend that this code be used to understand the basic I/O
 * format of the PDD, the method in which it sends and receives packets, and
 * how to properly structure those packets.  Very little time went into the
 * writing and debugging process in this code; it was written in haste to
 * make a quick decision regarding use of this product as a low-cost data
 * logger.  Results: we decided we didn't need a low cost data logger yet.
 * Have fun, happy hunting, feel free to contact me if you have any more
 * questions!
 *
 * Glenn A. Emelko
 * Performance Concepts, Inc.
 * 8250 Tyler Blvd.
 * Mentor, OH  44060
 * (216) 974-9550
 *
 */

/*
 * This is some C source code I used to talk to the PDD.  Unfortunately I am
 * not able to provide the serial interface routines used because they are
 * proprietary to my company, however I believe they will be self explanitory
 * and you should have little trouble working with your own support code, and
 * I've seen a number of different interrupt driven RS232 sources out there.
 */

/* tchar1(&c1) - transmit character in c1 to RS232 device */
/* rchar1(&c1,&s1) - receive character in c1, status in s1, from RS232 */

/* #define HEXDUMP - if you wish to have HEX dump to file tt1.hex */
/* #define DUMPCOMMAND - if you wish to have commands dumped to display */

/* Define all of these so everyone can use them */
unsigned char buffer[4000];
unsigned char buff[500];
unsigned char fi[100];
unsigned char rss[200];
unsigned char qqs[10];
unsigned char qb[255];
int s,rs,rl,rp,rf,qp,qu,ck,qt;

main()
{
  	int i,j,k,f;
	int c,stat;
	int address,data0,data1;
	int ic;

	unsigned char *bufp;

	address=0x3f8; data0=15; data1=3;	/*  COM1, 9600 baud 8,N,1 */
	setup(&address,&data0,&data1);

	setdtr();
	setrts();

	data0=10;
	tout(&data0);

	c=0;
	while (c!=(int) '~') {
		bufp = buffer;
		f=0;
		gstat(&i);
		while ((i & 256)!=0) {
		  	rchar1(&c,&stat);
			*bufp++ = (unsigned char)c;
			gstat(&i);
			f=0;
			while (f++<1000 & (i & 256)==0) {
			  gstat(&i);
			}
		}
		if (bufp!=buffer) {
		  tputs(&buffer[0],(int) (bufp-buffer));
		}
		c=0;
		if (kbhit()!=0) {
		  	c=(int)getch();
			switch (c) {
			  case (int)'[': {
			    printf("dtr=0");
			    clrdtr();
			    break;
			  }
			  case (int)']': {
			    printf("dtr=1");
			    setdtr();
			    break;
			  }
			  case (int)'7': {
			    i=(int)c-48;
			    c=(int)'Z';
			    tchar1(&c);
			    c=(int)'Z';
			    tchar1(&c);
			    c=i;
			    tchar1(&c);
			    c=0;
			    tchar1(&c);
			    c=255-i;
			    tchar1(&c);
			    c=0;
			    tchar1(&c);
			    c=13;
			    tchar1(&c);
			    break;
			  }
			  case (int)'~': break;
			  case (int)'`': menu();
			  default: tchar1(&c);
			}
		} else c=0;
	}
}

tputs(b,l)
unsigned char *b;
int l;
{
  	unsigned char c;
	int i;
	FILE *f;
	i=l;
#ifdef HEXDUMP
        f=fopen("tt1.hex","a+b");
#endif
	while (i-- >0) {
		c = *b++;
		if (c<32 || c>126) {
		  if (c==13) printf("\n"); else printf("<%d>",(int) c);
		} else {
		  printf("%c",c);
		}
#ifdef HEXDUMP
		fprintf(f,"%c",c);
#endif
	}
#ifdef HEXDUMP
	fclose(f);
#endif
}

menu()
{
	unsigned char c;
	printf("A = Append to File\n");		/* 160 */
	printf("C = Close File\n");		/* 190 */
	printf("D = Directory\n");		/* 125 */
	printf("F = Format Disk\n");		/* 220 */
	printf("G = Get Data\n");		/* 170 */
	printf("I = Find First\n");		/* 130 */
	printf("K = Kill File\n");		/* 210 */
	printf("N = Next File\n");		/* 140 */
	printf("P = Put Data\n");		/* 200 */
	printf("R = Read from File\n");		/* 150 */
	printf("S = Status of drive\n");	/* 110 */
	printf("W = Write to File\n");		/* 180 */
	c=0;
	while (c!='X') {
	  c=getch();
	  s=0;
	  switch (c) {
	    case 'A': /* 160 */ GAppend(); break;
	    case 'C': /* 190 */ GClose(); break;
	    case 'D': /* 125 */ GDir(); break;
	    case 'F': /* 220 */ GFormat(); break;
	    case 'G': /* 170 */ GGet(); break;
	    case 'I': /* 130 */ GFind_first(); break;
	    case 'K': /* 210 */ GKill(); break;
	    case 'N': /* 140 */ GFind_Next(); break;
	    case 'P': /* 200 */ GPut(); break;
	    case 'R': /* 150 */ GRead(); break;
	    case 'S': /* 110 */ GStatus(); break;
	    case 'W': /* 180 */ GWrite(); break;
	    case 'X': break;
	    default: break;
	  }
	}
}

delay()
{
  int i;
  for(i=0;i<100000;i++);
  return;
}

yesno()
{
  unsigned char c;
  c=getch();
  if (c=='y' || c=='Y') return(1);
  if (c=='n' || c=='N') return(0);
  return(yesno());
}

Ggetstat()
{
  int c1,c2,c3,c4;
  int s1;
  int tt;
  c1=tt=0;
  while (c1!=18 && tt++<5) rchar1(&c1,&s1);
  if (c1!=18) {
    rs=0;
    return;
  }
  rchar1(&c2,&s1);
  rchar1(&c3,&s1);
  rchar1(&c4,&s1);
  rs = c1;
  rp = c3;
  return;
}

Gstat_q()
{
	s=1;
  	GStatus();
	if (rs==0 || rp!=0) s=0;
	return;
}

prep_f(bp)
unsigned char *bp;
{
  unsigned char tmpb[30];
  unsigned char *t1;
  unsigned char *t2;
  t1=bp;
  t2=tmpb;
  while (*t1!=(unsigned char)0 && *t1!='.') {
    *t2++ = *t1++;
  }
  while ((int)(t2-tmpb)<6) *t2++ = ' ';
  while (*t1!=(unsigned char)0) *t2++ = *t1++;
  while ((int)(t2-tmpb)<24) *t2++ = ' ';
  *t2++ = 'F';
  *t2++ = (unsigned char) qp;
  t2=tmpb;
  t1=bp;
  while ((int)(t2-tmpb)<26) *t1++ = *t2++;
}

chk_st1()
{
  int c1,c2,s1;
  unsigned char *rssp;
  *rss=0;
  rchar1(&c1,&s1);
  rchar1(&c2,&s1);
  rs=c1;
  rl=c2;
  if (rs!=17 || rl!=28) {
    if (rs==18 && rl>0) {
      rchar1(&c1,&s1);
      rchar1(&c2,&s1);
      rp=c2;
      return;
    }
    return;
  } else {
    rssp=rss;
    while((rssp-rss)<28) {
      rchar1(&c2,&s1);
      *rssp++ = (unsigned char) c2;
    }
    rchar1(&c2,&s1);
    ck=c2;
    rf=(int) *rss;
  }
}

chk_stat()
{
	Gstat_q();
	if (s==0) return;
	*buff = 0;
	qu=0;
	prep_f(buff);
	command(buff,26);
	chk_st1();
	if (rs!=17) {
	  errorcode();
	  return;
	}
	if (rf==0) {
	  printf("File not found\n");
	  return;
	}
	printf("%.10s  %5d  %3d\n",rss,(int) ((256* (int)*(rss+25))+(int)*(rss+26)),
			(int)*(rss+27));
	return;
}

command(qs,qsl)
unsigned char *qs;
int qsl;
{
  unsigned char *qp;
  unsigned char *ip;
  int i,ck;
  
  ip = qs;
  qp = qb;
  *qp++ = 'Z';
  *qp++ = 'Z';
  *qp++ = qu;
  *qp++ = (unsigned char) qsl;
  for(i=0;i<qsl;i++) *qp++ = *ip++;
  ck=0;
  ip=(unsigned char *) (qb+2);
  for(i=0;i<qsl+2;i++) ck += *ip++;
  ck = ck % 256;
  ck = 255-ck;
  *qp++ = (unsigned char) ck;
  ip = qb;
#ifdef DUMPCOMMAND
  printf("Command string: ");
    for(i=0;i<qsl+5;i++) {
    ck = (int) *ip++;
    printf("%d ",ck);
  }
#endif
  printf("\n");
  ip = qb;
  for(i=0;i<qsl+5;i++) {
    ck = (int) *ip++;
    tchar1(&ck);
  }
}

errorcode()
{
  int c;
  printf("Drive: ");
  if (rs==67) {
    printf("Wrong mode - will try switch\n");
    c=(int)'M';
    tchar1(&c);
    c=(int)'1';
    tchar1(&c);
    c=13;
    tchar1(&c);
    delay();
    Ggetstat(rs,rp);
    return;
  }
  if (rs!=18) {
    printf("No response - Turn drive off and on again\n");
    printf("Press a key when ready\n");
    c=getch();
    clrdtr();
    setdtr();
    return;
  }
  printf("OK.  Disk: ");
  switch (rp) {
    case 0: printf("OK\n"); break;
    case 16: printf("file not found\n"); break;
    case 48: printf("end of file encountered\n"); break;
    case 64: printf("I/O error\n"); break;
    case 80: printf("Write protected\n"); break;
    case 96: printf("Disk full\n"); break;
    case 113: printf("Check drive door, may be open\n"); break;
    case 167: printf("Unformatted disk\n"); break;
    default: printf("Unknown error code %d\n",rp); break;
  }
  return;
}

GStatus()
{
	int ch;
	rs=0;
	qu=7;
	command("",0);
	ch = 13;
	tchar1(&ch);
	Ggetstat();
	if (s!=0 && rs==18 && rp==0) return;
	errorcode();
}

GDir()
{
  GFind_first();
  while (s!=0 && rf!=0) GFind_next();
}

GFind_first()
{
  qp=1;
  chk_stat();
  if (s==0 || rf!=0) return;
  printf("Disk empty\n");
}

GFind_next()
{
  qp=2;
  chk_stat();
  return;  
}

GFormat()
{
  s=1;
  GDir();
  if (s==0) {
    printf("Empty disk\n");
    return(0);
  }
  if (rf!=0) {
    printf("Contains data.  Format? (Y/N)\n");
    if (yesno()==0) return(0);
  }
  qu=6;
  command("",0);
  Ggetstat();
  if (rs==18 && rp==0) {
    printf("Formatted OK\n");
    return(0);
  }
  errorcode();
}

GRead()
{
  qp=3;
  Gopen();
  if (s==0) return;
  if (rf!=0 && rp==0) printf("Ready to read\n");
  return;
}

Gopen() /* 154 */
{
  Gfilchko();
  if (s==0) return;
  Gfilposn();
  return;
}

Gfilchko() /* 156 */
{
  char *p;
  Gstat_q();
  if (s==0) return;
  *buff = 0;
  printf("Filename: ");
  p=gets(&buff[0]);
  if (strlen(buff)==0) {
    printf("Illegal file name\n");
    return;
  }
  qt=qp;
  qp=0;
  proc_f(buff);
  qp=qt;
  return;
}

proc_f(bufr)
unsigned char *bufr;
{
  qu=0;
  prep_f(bufr);
  command(bufr,26);
  chk_st1();
  if (rs!=17) {
    errorcode();
    return;
  }
  if (rf==0) {
    printf("File not found\n");
    return;
  }
  printf("%.10s  %5d  %3d\n",rss,(int) ((256* (int)*(rss+25))+(int)*(rss+26)),
		(int)*(rss+27));
  return;
}

Gfilposn()
{
  qu=1;
  *qqs = qp;
  command(qqs,1);
  Ggetstat();
  return;
}

GGet()
{
  int c1,c2,s1,i,cl;
  char *bp;
  qu=3;
  bp=buffer;
  command("",0);
  rchar1(&c1,&s1);
  *bp++ = (unsigned char) c1;
  rchar1(&cl,&s1);
  *bp++ = (unsigned char) cl;
  for(i=0;i<cl+1;i++) {
    rchar1(&c2,&s1);
    *bp++ = (unsigned char) c2;
  }
  tputs(buffer,cl+3);
}

GKill()
{
  Gfilchko();
  if (s==0) return;
  if (rf==0) return;
  printf("Really delete?");
  if (yesno()==0) return;
  qu=5;
  command("",0);
  Ggetstat();
  if (rs==18 && rp==0) {
    printf(".... file deleted\n");
    return;
  }
  errorcode();
}

GClose()
{
  qu=2;
  command("",0);
  Ggetstat();
  if (rs==18 && rp==0) {
    printf("File closed\n");
    return;
  }
  errorcode();
}

GWrite()
{
  qp=1;
  Gopen();
  if (s==0 || (rp!=0 && rp!=48)) return;
  if (rf==0) {
    printf("Ready to write NEW file\n");
    GPut();
    return;
  }
  printf("File exists -- Overwrite?\n");
  if (yesno()==0) return;
  rf=0;
  GPut();
  return;
}

GPut()
{
  while (1) {
    printf(">");
    gets(buff);
    if (strlen(buff)==0) {
      printf("\nClosing file...");
      qu=2;
      command("",0);
      Ggetstat();
      if (rs==18 && rp==0) {
        printf("File closed\n");
        return;
      }
      errorcode();
      return;
    }
    s=1;
    qu=4;
    command(buff,strlen(buff));
    Ggetstat();
    if (rs!=18 || rp!=0) {
      errorcode();
      return;
    }
  }
}

GAppend()
{
  qp=2;
  Gopen();
  if (s==0) return;
  if (rf!=0 && rp==0) {
    printf("Ready to append to file\n");
    GPut();
    return;
  }
  errorcode();
  return;
}

crds@pyrite.som.cwru.edu (Glenn A. Emelko) (01/08/90)

Here is tdd.inf, an ASCII basic program which has been uuencoded
in order to preserve the long line lengths of the original author.
I pulled this from CI$, it's public domain, original copyright to
follow (it's also in the source code itself):

(C) 1986 Woods Martin All Rights Reserved

begin 600 tdd.inf
M," G0TU$4S Q+E1$1" M(# Y+S V+S@V(%M#72!7;V]D<R!-87)T:6X@-S$S
M+S8R,2TS-S@V("!!3$P@4DE'2%13(%)%4T525D5$"C$@)T-!551)3TX@+2!4
M2$E3($E3($%.($].1T])3D<@3$5!4DY)3D<@15A015))14Y#12 M+2!42$53
M12!23U5424Y%4R!!4D4@1E5,3%D@0T%004),12!/1B!%051)3D<@1DE,15,@
M04Y$($1)4TM3+B @14Y*3UD@+2T@0E54($%4(%E/55(@3U=.(%))4TLN"C(@
M)U1$1"!#3TU-04Y$4R!G;&5A;F5D(&9R;VT@1%-+3"Y01$0@8GD@4FEC:&%R
M9"!(87<L($1)4D132RY41$0@8GD@5&]N>2!!;F1E<G-O;BP@1D]234%4+E1$
M1" F($5205-%4BY41$0@8GD@069T97)H;W5R<R!3;V9T=V%R92!A;F0@5$%.
M1%D@1$]3($1)4T%34T5-0DQ%1"!B>2!38V]T="!4=7)N97(N+BYA;F0@82!L
M;W0@;V8@;7D@;W=N(&5X<&5R:6UE;G1A=&EO;BX*,R G5&AE(&9O<F5G;VEN
M9R!P<F]G<F%M<R!A;&P@=V]R:R!B=70@8V]N=&%I;B!S;VUE(&-O;F9L:6-T
M:6YG(&EN9F]R;6%T:6]N('=H:6-H($D@:&%V92!A='1E;7!T960@=&\@<F5S
M;VQV92X@(%1A;F1Y(&-O=6QD(&UA:V4@=&AI;F=S(&5A<VEE<B!B>2!P=6)L
M:7-H:6YG(&$@5$1$('1E8VAN:6-A;"!R969E<F5N8V4@;6%N=6%L(&)U="!T
M:&4@<V5C<F5T<R!W:6QL(&]U="!O;F4@=V%Y(&]R('1H92!O=&AE<BX*-" G
M5$1$0TU$(&ES(&1E<VEG;F5D('1O(&)E(&$@<G5N86)L92!P<F]G<F%M('1O
M(&1E;6]N<W1R871E('1H92!C;VUM86YD<R!A<R!W96QL(&%S('1O(&EL;'5S
M=')A=&4@:&]W('1H97D@;6%Y(&)E('5S960N("!)="!I<R!I;7!L96UE;G1E
M9"!I;B!"05-)0R!F;W(@=&AE($TQ,# @8G5T('-H;W5L9"!W;W)K(&]N('1H
M92!-,C P(&)Y(&-O<G)E8W1I;F<@=&AE($-"(&%N9"!#3B!A9&1R97-S97,@
M:6X@;&EN97,@,C M,C4N"C4@)PHV("=4:&ES(&9I;&4@:7,@<&]S=&5D(&%S
M(&$@<W1A<G0@=&]W87)D(&-O;7!I;&EN9R!A(&-O;7!L971E(&-O;6UA;F0@
M<V5T(&9O<B!T:&4@5$1$(&%N9"!A;&P@8V]R<F5C=&EO;G,L(&%D9&ET:6]N
M<R!A;F0@8V]M;65N=',@87)E(&UO<W0@=V5L8V]M92!A;F0@=VEL;"!B92!I
M;F-L=61E9"!I;B!L871E<B!V97)S:6]N<RX*-R G36]S="!N965D960@:7,@
M82!24S(S,B!I;G!U="!R;W5T:6YE(&-A<&%B;&4@;V8@:&%N9&QI;F<@,3,Q
M(&-H87(@;65S<V%G97,@9G)O;2!T:&4@5$1$(&%T(#$Y,C P(&)A=60@=6YD
M97(@0D%324,N("!%>'!E<FEM96YT871I;VX@=VET:"!O=&AE<B!1545262!A
M;F0@45!A<F%M971E<B!V86QU97,@=&AA;B!T:&]S92!U<V5D(&AE<F4@;6%Y
M('=E;&P@<F5V96%L(&UO<F4@5$1$(&9E871U<F5S('1H86X@=V4@:VYO=R!A
M8F]U="X*.2 G"C$P("=)3DE424%,25I!5$E/3B M($%L;"!V87)I86)L97,@
M=7-E9"!W:6QL(&)E(&5X<&QI8VET;'D@='EP960@8G5T(")R96%L(B!P<F]G
M<F%M<R!W:6QL('!R;V)A8FQY('!R961E9FEN92!T:&5M('1O('-A=F4@<W!A
M8V4N"C$T("<*,34@34%81DE,15,],CI#3$5!4C$P,# Z3TY%4E)/4D=/5$\S
M,# Z4B0]0TA2)"@Q,RDZ4DPD/5(D*T-(4B0H,3 I.D-0)#TB0T]-.CDX3C%$
M3DXB.D=/4U5"-S8*,C @0T(]-C4S-3 G($TQ,# @861D<F5S<R!O9B!24S(S
M,B!B=69F97(N"C(U($-./38U-#$T)R!-,3 P(&%D9')E<W,@;V8@;G5M8F5R
M(&]F(&)Y=&5S(&EN(%)3,C,R(&)U9F9E<B!A="!#0B!N;W0@>65T($E.4%54
M960N("!#3BLQ(&ES(&%D9')E<W,@;V8@<&]I;G1E<B!I;B!#0B!T;R!L87-T
M(&)Y=&4@86QR96%D>2!)3E!55&5D+B @0TXK,B!I<R!A9&1R97-S(&]F('!O
M:6YT97(@:6X@0T(@=&\@;&%S="!B>71E(&YO="!Y970@24Y0551E9"X*,S @
M0T(D/2(B.D-6/59!4E!44BA#0B0I.D-!)3U#0B\R-38Z4$]+14-6*S$L0T(M
M,C4V*D-!)3I03TM%0U8K,BQ#024Z4$]+14-6+#8T)R!S=')I;F<@<&]I;G1I
M;F<@=&\@4E,R,S(@8G5F9F5R(&9O<B!U<V4@8GD@24Y0550@8GEP87-S(')O
M=71I;F4N("!3964@;&EN92 Y,BX*-# @4E,E/3 Z0TQ3.E!224Y4(B @0VUD
M<S Q+E1$1" @(" @(%MC72 Q.3@V('=O;V1S(&UA<G1I;B(*-3 @4%))3E0B
M4SU3=&%T=7,@;V8@9')I=F4@(" @1#U$:7)E8W1O<GDB4DPD(DD]1FEN9"!F
M:7)S="!F:6QE(" @($X]1FEN9"!N97AT(&9I;&4B4DPD(E(]3W!E;B!T;R!R
M96%D(" @(" @($$]3W!E;B!T;R!A<'!E;F0B4DPD(D<]1V5T($1A=&$@(" @
M(" @(" @(%<]3W!E;B!T;R!W<FET92)23"0B0SU#;&]S92!F:6QE(" @(" @
M(" @4#U0=70@9&%T82)23"0B2SU$96QE=&4@9FEL92 @(" @(" @1CU&;W)M
M870@9&ES:R(*-C @4R4],#I04DE.5$ R.# L(DT]365N=2 @(" @(" @4V5L
M96-T*&1I<W!L87D]14Y415(I(#\@(CLZ1T]354(V,CI#3%,Z2493)#TB+2)4
M2$5.-#!%3%-%3TY)3E-44B@B<VUD:6YR86=W8W!K9B(L4R0I*S%'3U-50C$P
M,"PQ,3 L,3(P+#$R-2PQ,S L,30P+#$U,"PQ-C L,3<P+#$X,"PQ.3 L,C P
M+#(Q,"PR,C Z1T]43S8P"C8R(%,D/4E.4%54)"@Q*3I3)#U#2%(D*$%30RA3
M)"E/4C,R*3I215154DX*-C0@0D5%4#I04DE.5$U')"(@+2!A<F4@>6]U('-U
M<F4@(%D@;W(@3B _("([.D=/4U5"-C(Z4%))3E13)#I-1R4]*%,D/2)Y(BDZ
M4D5455)."C8V(%%&)#TB(CI)3E!55")&:6QE($YA;64@=VET:"!%>'1E;G-I
M;VXB.U%&)#I215154DX*-C@@224]24Y35%(H,2Q11B0L(BXB*3I)1DDE/#)/
M4DDE/C=42$5.448D/2(B14Q315%&)#U,1494)"A11B0L224M,2DK4U!!0T4D
M*#<M224I*TU)1"0H448D+$DE*2<@4&%D(&9I;&4@;F%M97,@=&\@-B!C:&%R
M('!L=7,@97AT96YS:6]N('1O(&%G<F5E('=I=&@@0D%324,N("!4:&4@5$1$
M(&1O97-N)W0@<V5E;2!T;R!C87)E(&%N9"!W:6QL(&%C8V5P="!5<'!E<B!A
M;F0@3&]W97(@8V%S92!U<"!T;R R-"!C:&%R+@HV.2!14R0]448D*U-004-%
M)"@R-"U,14XH448D*2DK(D8B*T-(4B0H45 E*3I215154DXG($)U:6QD(&9I
M;&5N86UE('-T<FEN9R!F;W(@;W!E;B!1545263TP('!A9&1E9"!T;R R-"!C
M:&%R(&%N9"!F;VQL;W=E9"!B>2 B1B(@86YD('1H92!1545263TP(%%087)A
M;65T97(N"C<P($-+)3TP.D9/4D,Q)3TQ5$],14XH4R0I.D-+)3U#2R4K05-#
M*$U)1"0H4R0L0S$E*2DZ3D585#I#2R4]*$-+)4U/1#(U-BE83U(R-34Z4D54
M55).)R!#86QC=6QA=&4@8VAE8VMS=6T@;VX@<W1R:6YG(%,D+@HW,B!)1DQ%
M3BA#2R0I/3!42$5.0TLE/3 Z4D5455).14Q314=/4U5"-S Z0TLE/2A#2R4]
M05-#*$-+)"DI.E)%5%523B<@0V]M<&%R92!C86QC=6QA=&5D(&-H96-K<W5M
M('=I=&@@<F5C96EV960@8VAE8VMS=6T@8GET92!#2R0N"C<V($-,3U-%.D]0
M14Y#4"1&3U))3E!55$%3,3I/4$5.0U D1D]23U544%5405,R.E)%5%523B<@
M3W!E;B!#3TTZ(&9O<B!I;G!U="]O=71P=70@9G)O;2]T;R!41$0N"C<X($9/
M4DDE/3%43S$P,#I.15A4.E)%5%523B<@5&EM92!D96QA>2!R;W5T:6YE"C@P
M(%%3)#U#2%(D*%%5)2DK0TA2)"A,14XH45,D*2DK45,D.E,D/5%3)#I'3U-5
M0C<P.E%3)#TB6EHB*U,D*T-(4B0H0TLE*3I04DE.5",R+%%3)#LZ4D5455).
M)R!396YD("=:6B<@455%4ED]474E(%%U97)Y4W1R:6YG(%%3)"!A;F0@8VAE
M8VMS=6T@=&\@5$1$+@HY,"!24R4],#I3)#U)3E!55"0H-"PQ*3I24R4]05-#
M*%,D*3I24"4]05-#*$U)1"0H4R0L,RDI.E)%5%523B<@1V5T('-T871U<R!2
M15-03TY312!F<F]M(%1$1"X@(%)3)3UR97-P;VYS92!T>7!E+"!24"4]<F5S
M<&]N<V4@4E!A<F%M971E<BX*.3(@4E,E/3 Z4D8E/3 Z4R0]24Y0550D*#(L
M,2DZ4E,E/4%30RA3)"DZ4DPE/4%30RA-240D*%,D+#(I*3I)1E)3)3P^,3=/
M4E),)3P^,CA42$5..3=%3%-%4C$E/5!%14LH0TXK,2DK,3I21B4]05-#*$U)
M1"0H0T(D+%(Q)2DI.E)3)#U-240D*$-")"Q2,24L,C@I.E,D/5,D*U)3)#I#
M2R0]34E$)"A#0B0L4C$E*S(X+#$I.D=/4U5"-S(Z249#2R542$5..3A%3%-%
M4%))3E0B8VL@(CLZ1T]43SDX"CDS("='970@4D534#TQ-R!F:6QE(&YA;64@
M9G)O;2!41$0N("!21B4],"!M96%N<R!F:6QE(&1O97,@;F]T(&5X:7-T+B @
M4VEN8V4@=&AE(')E<W!O;G-E('-T<FEN9R!24R0@8V]N=&%I;G,@9FEL92!L
M96YG=&@@86YD(&9R964@<V5C=&]R<R!W:&EC:"!M:6=H="!C;VYT86EN(&$@
M9&5C:6UA;" R-B!C:&%R("A"05-)0R!%;F0@;V8@1FEL92DL('1H92!)3E!5
M5"0@<W1A=&5M96YT(&ES(&YO="!U<V5D+@HY-" G4E,D(&ES(&-H96-K960@
M9F]R(&-O<G)E8W0@8VAE8VMS=6T@86YD("AF;W(@=&AI<R!D96UO*2 B8VL@
M(B!I<R!P<FEN=&5D(&EF(&5R<F]R+@HY-R!)1E)3)3TQ.$%.1%),)3XP5$A%
M3E,D/4E.4%54)"@R+#$I.E)0)3U!4T,H34E$)"A3)"PR*2D*.3@@4$]+14-.
M+# Z4$]+14-.*S$L,#I03TM%0TXK,BPP.E)%5%523B<@4F5S970@<&]I;G1E
M<G,@=&\@4E,R,S(@8G5F9F5R('1O(&EN9&EC871E('1H870@86QL(&-H87)A
M8W1E<G,@:&%V92!B965N('!R;V-E<W-E9"X*,3 P(%!224Y4(D5R<F]R(CI"
M1450.E)%5%523@HQ,#D@)PHQ,3 @)U%515)9(#<@+2!$<FEV92!3=&%T=7,*
M,3$Q(%)3)3TP.E%5)3TW.E%3)#TB(CI'3U-50C@P.E!224Y4(S(L4B0[.D=/
M4U5"-S@Z2490145+*$-.*3XS5$A%3D=/4U5".3 Z2493)4%.1%)3)3TQ.$%.
M1%)0)3TP5$A%3E)%5%523B<@4V5N9"!1545263TW+"!A(%)%5%523B!A;F0@
M=V%I="!F;W(@=&EM92!D96QA>2X@($)E('-U<F4@870@;&5A<W0@-"!C:&%R
M(&AA=F4@8F5E;B!R96-E:79E9"!A;F0@=&AE;B!R96%D('1H96TN"C$Q,B G
M4D534#TQ."!D<FEV92!O:RX@(%)0)3TP(&1I<VL@;VLN("!)9B!3)2!I<R!T
M<G5E+"!R971U<FX@=&\@8V%L;&5R+"!O=&AE<G=I<V4@<')I;G0@;65S<V%G
M92X*,3$S(%!224Y4(D1R:79E.B B.SI)1E)3)3TV-U1(14Y04DE.5")7<F]N
M9R!M;V1E+7=I;&P@=')Y('-W:71C:"(Z4%))3E0C,B4L(DTQ(D-(4B0H,3,I
M.SI'3U-50C<X.D=/5$\Q,3!%3%-%24924R4\/C$X5$A%3E!224Y4(DYO(')E
M<W!O;G-E("T@='5R;B!D<FEV92!/9F8O3VXB4DPD(E!R97-S($5.5$52("))
M3E!55"0H,2DZ1T]354(W-CI215154DY%3%-%4%))3E0B3TL@+2!$:7-K.B B
M.PHQ,30@24924"4],%1(14Y!)#TB3TLB14Q314E&4E E/3$V5$A%3D$D/2)F
M:6QE(&YO="!F;W5N9")%3%-%24924"4]-#A42$5.020](F5N9"!O9B!F:6QE
M(D5,4T5)1E)0)3TV-%1(14Y!)#TB22]/(&5R<F]R(D5,4T5)1E)0)3TX,%1(
M14Y!)#TB=W)I=&4@<')O=&5C=&5D(D5,4T5)1E)0)3TY-E1(14Y!)#TB;F\@
M<W!A8V4B14Q314E&4E E/3$Q,U1(14Y!)#TB/S\_(&-H96-K(&1O;W(B14Q3
M13$Q-PHQ,34@1T]43S$Q. HQ,3<@24924"4],38W5$A%3D$D/2).965D<R!F
M;W)M871T:6YG(D5,4T5!)#U35%(D*%)0)2DK(B!E<G)O<B(*,3$X(%!224Y4
M020Z4D5455)."C$Q.2 G"C$R,"!'3U-50C$Y,#I-05A&24Q%4STQ.DU%3E4*
M,3(T("<*,3(U("=$25)%0U1/4ED@=7-I;F<@455%4ED],"!14&%R86UE=&5R
M<R Q(&%N9" R"C$R-B!'3U-50C$S,#I)1E,E/3!/4E)&)3TP5$A%3E)%5%52
M3B<@1V5T(&9I<G-T(&9I;&4@;F%M92X*,3(W($=/4U5",30P.DE&4R4],$]2
M4D8E/3!42$5.4D5455).14Q313$R-R<@1V5T(&YE>'0@9FEL92!N86UE('5N
M=&EL($9I;&4@3F]T($9O=6YD+@HQ,CD@)PHQ,S @)U%515)9/3 @45!A<F%M
M971E<B Q("T@1FEN9"!F:7)S="!F:6QE"C$S,2!14"4],3I'3U-50C$T,CI)
M1E,E/3!/4E)&)51(14Y215154DY%3%-%4%))3E0B1&ES:R!E;7!T>2(Z4D54
M55)."C$S.2 G"C$T," G455%4ED],"!14&%R86UE=&5R(#(@+2!&:6YD(&YE
M>'0@9FEL90HQ-#$@45 E/3(*,30R($=/4U5",30X.DE&4R4],%1(14Y21515
M4DY%3%-%448D/2(B)R!#:&5C:R!D<FEV92!S=&%T=7,N("!.=6QL(&9I;&5N
M86UE(%%&)"!F;W(@455%4ED],"!14&%R86UE=&5R<R Q("8@,@HQ-#,@454E
M/3 Z1T]354(V.#I'3U-50C@P.D=/4U5".3(Z24924R4\/C$W5$A%3C$Q,T5,
M4T5)1E)&)3TP)51(14XQ-#8G(%!R;V-E<W,@45,@<75E<GD@<W1R:6YG(&%N
M9"!S96YD(%%515)9/3 @=&\@5$1$(&%N9"!E>'!E8W0@4D534#TQ-RX*,30T
M(%!224Y455-)3D<B7" @(" @(" @7" @(R,C(R,@(",C(R([34E$)"A24R0L
M,2PQ,"DL,C4V*D%30RA-240D*%)3)"PR-BDI*T%30RA-240D*%)3)"PR-RDI
M+$%30RA-240D*%)3)"PR."DI.E)%5%523B<@4V%M<&QE('5S92!O9B!D871A
M(')E8V5I=F5D+B @5&AE(&9I<G-T(#$P(&-H87(@87)E('1H92!"05-)0R!F
M:6QE;F%M92!P;'5S(#(@8VAA<B!E>'1E;G-I;VX@*#,@9F]R($9L;W!P>5]3
M>7,I+@HQ-#4@)T-H87(@,C8@:7,@=&AE($A)1T@@8GET92!A;F0@8VAA<B R
M-R!T:&4@3$]7(&)Y=&4@;V8@=&AE(&9I;&4@;&5N9W1H("AR979E<G-E9"!F
M<F]M(&YO<FUA;"!-,3 P(&-O;G9E;G1I;VXI+B @0VAA<B R."!I<R!T:&4@
M;G5M8F5R(&]F(&9R964@<V5C=&]R<R!O;B!T:&4@9&ES:R!A;F0@:7,@<F5T
M=7)N960@=VET:"!%5D5262!F:6QE;F%M92X*,30V($)%15 Z4%))3E0B1FEL
M92!N;W0@9F]U;F0B.E)%5%523@HQ-#@@4R4],3I'3U-50C$Q,#I)1E)3)3TP
M3U)24"4\/C!42$5.4R4],#I215154DY%3%-%4D5455).)R!#:&5C:R!D<FEV
M92!S=&%T=7,N("!);B!T:&5S92!E>&%M<&QE<RP@=&AI<R!I<R!D;VYE(&)E
M9F]R92!E=F5R>2!1545262!B=70@;6%N>2!P<F]G<F%M;65R<R!S965M('1O
M(&)Y<&%S<R!T:&ES('-T97 @869T97(@=&AE(&9I<G-T('1I;64@+2T@870@
M=&AE:7(@<&5R:6PL($D@=V]U;&0@<V%Y+@HQ-#D@)PHQ-3 @)U%515)9/3 @
M45!A<F%M971E<B P("T@3W!E;B!F:6QE(%%&)" @(%%515)9/3$@45!A<F%M
M971E<B S("T@4&]S:71I;VX@=&\@<F5A9 HQ-3$@45 E/3,Z1T]354(Q-30Z
M2493)3TP5$A%3E)%5%523D5,4T5)1E)&)4%.1%)0)3TP5$A%3E!224Y4(E)E
M861Y('1O(')E860B.E)%5%523D5,4T5215154DXG(%1R>2!T;R!O<&5N(&9I
M;&4L('1H96X@<&]S:71I;VX@9F]R(')E861I;F<@=VET:"!1545263TQ(%%0
M(#,N"C$U-"!'3U-50C$U-CI)1E,E/3!42$5.4D5455).14Q314=/4U5",34X
M.E)%5%523@HQ-38@1T]354(Q-#@Z2493)3TP5$A%3E)%5%523D5,4T5'3U-5
M0C8V.DE&448D/2(B5$A%3E,E/3 Z4%))3E0B26QL96=A;"!F:6QE(&YA;64B
M.D)%15 Z4D5455).14Q315%4)3U14"4Z45 E/3 Z1T]354(Q-#,Z45 E/5%4
M)3I215154DXG3W!E;B!F:6QE+@HQ-3@@454E/3$Z45,D/4-(4B0H45 E*3I'
M3U-50C@P.D=/4U5".3 Z4D5455).)R!0;W-I=&EO;B!F:6QE+@HQ-3D@)PHQ
M-C @)U%515)9/3 @45!A<F%M971E<B P("T@3W!E;B!F:6QE(" @(%%515)9
M/3$@45!A<F%M971E<B R("T@4&]S:71I;VX@=&\@87!P96YD"C$V,2!14"4]
M,CI'3U-50C$U-#I)1E,E/3!42$5.4D5455).14Q314E&4D8E04Y$4E E/3!4
M2$5.4%))3E0B<F5A9'D@=&\@87!P96YD(CI'3U1/,C Q14Q315)%5%523@HQ
M-CD@)PHQ-S @)U%515)9/3,@+2!'970@9&%T82!S=')I;F<*,3<Q(%%5)3TS
M.E%3)#TB(CI'3U-50C@P.D=/4U5"-S@Z020]24Y0550D*%!%14LH0TXI+#$I
M.DE&05-#*$$D*3TQ-E1(14Y04DE.5$U)1"0H020L,RD*,3<R(%)%5%523@HQ
M-S,@)U1H:7,@:7,@82!C<G5D92!I;G!U="!R;W5T:6YE('=H:6-H(&AA;F1L
M97-S(&]N;'D@=&AE(&9I<G-T(#8T(&-H87(@;V8@96%C:" Q,S$@8VAA<B!R
M97-P;VYS92!S=')I;F<N("!4:&4@,3,Q(&-H87(@8V]M92!I;B!A=" Q.3(P
M,"!B875D(&EN(&]N92!B:6<@<G5S:"!A;F0@=&AE(#8T(&-H87(@4E,R,S(@
M8G5F9F5R(&]V97)F;&]W<RP@;&]S:6YG('1H92!L87-T(#8W+@HQ-S0@)T%S
M<VEG;FUE;G0Z("!7<FET92!A(#$S,2 H;6EN*2!24S(S,B!I;G!U="!R;W5T
M:6YE(&EN($U,('!O:V5D(&EN=&\@82!"05-)0R!S=')I;F<@=VAI8V@@8V%N
M(&-A<'1U<F4@86QL(#$S,2!C:&%R+@HQ-SD@)PHQ.# @)U%515)9/3 @45!A
M<F%M971E<B P("T@3W!E;B!F:6QE(" @(%%515)9/3$@45!A<F%M971E<B Q
M("T@4&]S:71I;VX@=&\@=W)I=&4*,3@Q(%%0)3TQ.D=/4U5",34T.DE&4R4]
M,$]2*%)0)4%.1%)0)3P^-#@I5$A%3E)%5%523@HQ.#,@24921B4],%1(14Y0
M4DE.5")R96%D>2!T;R!W<FET92!.15<@1DE,12(Z1T]43S(P,45,4T5-1R0]
M(D9I;&4@17AI<W1S(CI'3U-50C8T.DE&34<E5$A%3E)&)3TP.D=/5$\Q.#-%
M3%-%4D5455)."C$X.2 G"C$Y," G455%4ED],B M($-L;W-E(&9I;&4*,3DQ
M(%%5)3TR.E%3)#TB(CI'3U-50C@P.D=/4U5".3 Z24924R4],3A!3D124"4]
M,%1(14Y04DE.5")F:6QE(&-L;W-E9"(Z4D5455).14Q313$Q,PHQ.3D@)PHR
M,# @)U%515)9/30@+2!0=70@9&%T82!S=')I;F<*,C Q(%!224Y4(E1Y<&4@
M9&%T82!T;R!B92!S=&]R960L(&5N9&EN9R)23"0B;&EN97,@=VET:"!A(%)%
M5%523BX@("=%;7!T>2<@4D5455).(E),)")T;R!E;F0N(@HR,#,@45,D/2(B
M.DE.4%5445,D.DE&45,D/2(B5$A%3C$Y,0HR,#4@4R4],3I1524]-#I'3U-5
M0C@P.D=/4U5".3 Z24924R4\/C$X3U)24"4\/C!42$5.,3$S14Q313(P,PHR
M,#8@)T$@9FEL92!C;W5L9"!B92!T<F%N<V9E<G)E9"!H97)E+B @45,D('-H
M;W5L9"!N;W0@8F4@;&]N9V5R('1H86X@,3(X(&-H87(N.DU%3E4*,C Y("<*
M,C$P("=1545263TP(%%087)A;65T97(@," M($]P96X@9FEL92 @(" @455%
M4ED]-2 M($1E;&5T92!F:6QE"C(Q,2!'3U-50B Q-38Z2493)3TP5$A%3E)%
M5%523D5,4T5)1E)&)3TP5$A%3E)%5%523D5,4T5-1R0](E)E86QL>2!D96QE
M=&4@(BM11B0Z1T]354(V-#I)1DU')3TP5$A%3E)%5%523D5,4T51524]-3I1
M4R0](B(Z1T]354(X,#I'3U-50CDP.DE&4E,E/3$X04Y$4E E/3!42$5.4%))
M3E0B9FEL92!D96QE=&5D(CI215154DY%3%-%,3$S"C(Q,B!35$]0.E)%5%52
M3@HR,3D@)PHR,C @)U%515)9/38@+2!&;W)M870@9&ES:PHR,C$@4R4],3I'
M3U-50C$S,#I)1E,E/3!42$5.4D5455).14Q314U')#TB(CI)1E)&)51(14Y-
M1R0](D-O;G1A:6YS(&1A=&$@(@HR,C,@34<D/2)&;W)M870B.D=/4U5"-C0Z
M249-1R4],%1(14Y215154DY%3%-%454E/38Z454D/2(B.D=/4U5".# Z1T]3
M54(Y,#I)1E)3)3TQ.$%.1%)0)3TP5$A%3E!224Y4(D9O<FUA='1E9"!/2R(Z
M4D5455).14Q313$Q,PHS,# @249%4DP],3<Q04Y$15)2/3542$5.4D5354U%
5,3<R"C,Q,"!/3D524D]21T]43S *
 
end