1*12240Sslatteng /* @(#)graphics1.c	1.3	05/05/83
211951Sslatteng  *
311951Sslatteng  * Copyright -C- 1982 Barry S. Roitblat
411951Sslatteng  *
511951Sslatteng  *
611951Sslatteng  * This file contains primitive functions to manipulate an AED512
711951Sslatteng  * color display.
811951Sslatteng  *
911951Sslatteng  * (Modified from software written by John Ousterhout for the caesar
1011951Sslatteng  *  program)
1111951Sslatteng  */
1211951Sslatteng #include "gremlin.h"
1311951Sslatteng #include <sgtty.h>
1411951Sslatteng 
1511951Sslatteng /* The following variables are used to hold state that we keep around
1611951Sslatteng  * between procedure calls in order to reduce the amount of information
1711951Sslatteng  * that must be shipped to the terminal.
1811951Sslatteng  */
1911951Sslatteng 
2011951Sslatteng static char dbuf[BUFSIZ];	/* Used to buffer display characters */
2111951Sslatteng static struct sgttyb sgttyb;	/* Used to save terminal control bits */
2211951Sslatteng static int sgflags;		/* Used to save flags from sgttyb */
2311976Sslatteng static char sgispeed, sgospeed;	/* Used to save baud rates */
2411951Sslatteng static int localmode;		/* Used to save terminal local mode word */
2511951Sslatteng static curcharsize;		/* Current character size */
2611951Sslatteng static int wmask;		/* Current write mask value */
2711951Sslatteng 
2811951Sslatteng 
2911951Sslatteng /* The following strings are used to as the colors for drawing and
3011951Sslatteng  * erasing.  They permit layer inversion, such that the drawing of
3111951Sslatteng  * the layer causes zeroes to be written and erasing causes ones to
3211951Sslatteng  * be written.
3311951Sslatteng  */
3411951Sslatteng 
3511951Sslatteng static char draw[4], erase[4];
3611951Sslatteng 
3711951Sslatteng /* The following arrays are used to define the line styles we use for
3811951Sslatteng  * for drawing.  Color and stipple are used as a representation of
3911951Sslatteng  * styles on the AED but are not necessarily accurate with the final
4011951Sslatteng  * output.
4111951Sslatteng  */
4211951Sslatteng 
4311951Sslatteng static int stylecolor[11] = { 0, 041, 041, 043, 041, 041, 042,
4411951Sslatteng                               044, 044, 0200, 0100 };
4511951Sslatteng static int stipple[11]  = { 255, 136, 228, 255, 240, 255, 255,
4611951Sslatteng                             255, 255, 136, 255 };
4711951Sslatteng 
4811951Sslatteng /* The following table contains the color lookup used to represent
4911951Sslatteng  * different fonts on the AED.
5011951Sslatteng  */
5111951Sslatteng 
5211951Sslatteng static int fontmap[8] = { 0, 041, 044, 045, 046, 0, 0, 0 };
5311951Sslatteng 
5411951Sslatteng /* The following variables are made available to the outside world. */
5511951Sslatteng 
5611951Sslatteng int GrXMax = 511;		/* Maximum x-coordinate of screen */
5711951Sslatteng int GrYMax = 482;		/* Maximum y-coordinate of screen */
5811951Sslatteng FILE *display;			/* The file for the AED512 */
5911951Sslatteng int charxsize;			/* Character x dimension */
6011951Sslatteng int charysize;			/* Character y dimension */
6111951Sslatteng int descenders;			/* Character descender length */
6211951Sslatteng int curx, cury;			/* Current access position */
6311951Sslatteng int rmask;                      /* read mask */
6411951Sslatteng 
6511951Sslatteng /* The following table is used to convert numbers to hex.  We cannot use
6611951Sslatteng  * standard C library conversion because it generates lower case letters
6711951Sslatteng  * which are bad news to the AED512.
6811951Sslatteng  */
6911951Sslatteng 
7011951Sslatteng static char hex[] = "0123456789ABCDEF";
7111951Sslatteng 
7211976Sslatteng 
7311951Sslatteng #ifndef FASTIO
GRchex(val,string,nchars)7411951Sslatteng GRchex(val, string, nchars)
7511951Sslatteng int val;			/* Integer value to be converted. */
7611951Sslatteng char *string;			/* Pointer to string area to be used for
7711951Sslatteng 				 * converted result.
7811951Sslatteng 				 */
7911951Sslatteng int nchars;			/* Number of characters to be converted. */
8011951Sslatteng 
8111951Sslatteng /*---------------------------------------------------------
8211951Sslatteng  *	This is a routine that converts an integer to a string
8311951Sslatteng  *	of hexadecimal characters.
8411951Sslatteng  *
8511951Sslatteng  *	Results:	None.
8611951Sslatteng  *
8711951Sslatteng  *	Side Effects:
8811951Sslatteng  *	The string contains the value of the low-order nchars 4-bit chunks
8911951Sslatteng  *	of val, as represented in hexadecimal.  String is zero-filled.
9011951Sslatteng  *---------------------------------------------------------
9111951Sslatteng  */
9211951Sslatteng 
9311951Sslatteng {
9411951Sslatteng     string = &(string[nchars]);
9511951Sslatteng     *string = '\0';
9611951Sslatteng     for (; nchars>0 ; nchars--)
9711951Sslatteng     {
9811951Sslatteng 	*(--string) = hex[val & 017];
9911951Sslatteng 	val >>= 4;
10011951Sslatteng     }
10111951Sslatteng }
10211951Sslatteng #endif
10311951Sslatteng 
GRsetwmask(mask)10411951Sslatteng GRsetwmask(mask)
10511951Sslatteng int mask;			/* New value for write mask */
10611951Sslatteng 
10711951Sslatteng /*---------------------------------------------------------
10811951Sslatteng  *	This is a routine that resets the value of the current
10911951Sslatteng  *	write mask, if necessary.
11011951Sslatteng  *
11111951Sslatteng  *	Results:	None.
11211951Sslatteng  *
11311951Sslatteng  *	Side Effects:
11411951Sslatteng  *	If wmask is different from mask, then the new mask is output to
11511951Sslatteng  *	the display and stored in wmask.
11611951Sslatteng  *
11711951Sslatteng  *	Errors:		None.
11811951Sslatteng  *---------------------------------------------------------
11911951Sslatteng  */
12011951Sslatteng 
12111951Sslatteng {
12211951Sslatteng     char s[4];
12311951Sslatteng     wmask = mask;
12411951Sslatteng #ifndef FASTIO
12511951Sslatteng     GRchex(wmask, s, 2);
12611951Sslatteng     fprintf(display, "L%s", s);
12711951Sslatteng #else
12811951Sslatteng     putc('L', display);
12911951Sslatteng     putc(mask&0377, display);
13011951Sslatteng #endif
13111951Sslatteng }
13211951Sslatteng 
GRsetcolor(color)13311951Sslatteng GRsetcolor(color)
13411951Sslatteng int color;
13511951Sslatteng /*
13611951Sslatteng  *      This routine sets the current color for the graphics display
13711951Sslatteng  */
13811951Sslatteng 
13911951Sslatteng {
14011951Sslatteng 
14111951Sslatteng #ifndef FASTIO
14211951Sslatteng 	char s1[3];
14311951Sslatteng 
14411951Sslatteng 	GRchex(color, s1, 2);
14511951Sslatteng 	fprintf(display, "C%s",s1);
14611951Sslatteng #else
14711951Sslatteng 	fprintf(display,"C%c", color&0377);
14811951Sslatteng #endif
14911951Sslatteng 
15011951Sslatteng }  /* end setcolor */
15111951Sslatteng 
15211976Sslatteng 
GRoutxy20(x,y)15311951Sslatteng GRoutxy20(x, y)
15411951Sslatteng int x,y;			/* The coordinates to be output */
15511951Sslatteng 
15611951Sslatteng /*---------------------------------------------------------
15711951Sslatteng  *	This routine outputs an x-y coordinate pair in the standard
15811951Sslatteng  *	format required by the AED display.
15911951Sslatteng  *
16011951Sslatteng  *	Results:	None.
16111951Sslatteng  *
16211951Sslatteng  *	Side Effects:
16311951Sslatteng  *	Characters are output to the AED512 in the standard way required
16411951Sslatteng  *	for values indicated by "xy20" in the user manual.
16511951Sslatteng  *
16611951Sslatteng  *	Errors:		None.
16711951Sslatteng  *
16811951Sslatteng  * (Modified from software written by John Ousterhout for the caesar
16911951Sslatteng  *  program)
17011951Sslatteng  *---------------------------------------------------------
17111951Sslatteng  */
17211951Sslatteng 
17311951Sslatteng {
17411951Sslatteng #ifndef FASTIO
17511951Sslatteng     char s1[4], s2[4], s3[4];
17611951Sslatteng     GRchex(((y>>8)&03) | ((x>>6)&014), s1, 1);
17711951Sslatteng     GRchex(x&0377, s2, 2);
17811951Sslatteng     GRchex(y&0377, s3, 2);
17911951Sslatteng     fprintf(display, "%s%s%s", s1, s2, s3);
18011951Sslatteng #else
18111951Sslatteng     putc(((x>>4)&020)+((y>>8)&01), display);
18211951Sslatteng     putc(x&0377, display);
18311951Sslatteng     putc(y&0377, display);
18411951Sslatteng #endif
18511951Sslatteng }
18611951Sslatteng 
GRsetpos(x,y)18711951Sslatteng GRsetpos(x, y)
18811951Sslatteng int x, y;			/* Screen coordinates.
18911951Sslatteng 
19011951Sslatteng /*---------------------------------------------------------
19111951Sslatteng  *	This routine sets the current access position, if necessary.
19211951Sslatteng  *
19311951Sslatteng  *	Results:	None.
19411951Sslatteng  *
19511951Sslatteng  *	Side Effects:
19611951Sslatteng  *	If x and y are equal to curx and cury, respectively, then nothing
19711951Sslatteng  *	happens.  Otherwise, x and y are stored into curx and cury and the
19811951Sslatteng  *	current access position of the AED is set to those coordinates.
19911951Sslatteng  *
20011951Sslatteng  *	Errors:		None.
20111951Sslatteng  *---------------------------------------------------------
20211951Sslatteng  */
20311951Sslatteng 
20411951Sslatteng {
20511951Sslatteng     if (x==curx && y==cury) return;
20611951Sslatteng     curx = x;
20711951Sslatteng     cury = y;
20811951Sslatteng     putc('Q', display);
20911951Sslatteng     GRoutxy20(x, y);
21011951Sslatteng }
21111951Sslatteng 
21211976Sslatteng 
GRsetcharstyle(style)21311951Sslatteng GRsetcharstyle(style)
21411951Sslatteng int style;			/* New font. */
21511951Sslatteng 
21611951Sslatteng /*---------------------------------------------------------
21711951Sslatteng  *	This routine sets the current character style.
21811951Sslatteng  *
21911951Sslatteng  *	Results:	None.
22011951Sslatteng  *
22111951Sslatteng  *	Side Effects:
22211951Sslatteng  *	A new character style is output to the display.
22311951Sslatteng  *---------------------------------------------------------
22411951Sslatteng  */
22511951Sslatteng 
22611951Sslatteng {
22711951Sslatteng     GRsetcolor(fontmap[style]);
22811951Sslatteng }
22911951Sslatteng 
GRsetlinestyle(style)23011951Sslatteng GRsetlinestyle(style)
23111951Sslatteng int style;			/* New stipple pattern for lines. */
23211951Sslatteng 
23311951Sslatteng /*---------------------------------------------------------
23411951Sslatteng  *	This routine sets the current line style.
23511951Sslatteng  *
23611951Sslatteng  *	Results:	None.
23711951Sslatteng  *
23811951Sslatteng  *	Side Effects:
23911951Sslatteng  *	A new line style is output to the display.
24011951Sslatteng  *---------------------------------------------------------
24111951Sslatteng  */
24211951Sslatteng 
24311951Sslatteng {
24411951Sslatteng     char s[4];
24511951Sslatteng 
24611951Sslatteng     GRsetcolor(stylecolor[style]);
24711951Sslatteng 
24811951Sslatteng #ifndef FASTIO
24911951Sslatteng     GRchex(stipple[style], s, 2);
25011951Sslatteng     fprintf(display, "1%sFF", s);
25111951Sslatteng #else
25211951Sslatteng     putc('1', display);
25311951Sslatteng     putc(stipple[style]&0377, display);
25411951Sslatteng     putc(0377, display);
25511951Sslatteng #endif
25611951Sslatteng }
25711951Sslatteng 
25811976Sslatteng 
GRsetcharsize(size)25911951Sslatteng GRsetcharsize(size)
26011951Sslatteng int size;			/* character size (1 - 4) */
26111951Sslatteng 
26211951Sslatteng /*---------------------------------------------------------
26311951Sslatteng  *	This routine sets the character size in the display,
26411951Sslatteng  *	if necessary.
26511951Sslatteng  *
26611951Sslatteng  *	Results:	None.
26711951Sslatteng  *
26811951Sslatteng  *	Side Effects:
26911951Sslatteng  *	If the current display character size isn't already equal to size,
27011951Sslatteng  *	then it is made so.
27111951Sslatteng  *---------------------------------------------------------
27211951Sslatteng  */
27311951Sslatteng 
27411951Sslatteng {
27511951Sslatteng     if (size == curcharsize) return;
27611951Sslatteng     curcharsize = size;
27711951Sslatteng #ifndef FASTIO
27811951Sslatteng     if (curcharsize == 4)
27911951Sslatteng     {
28011951Sslatteng         fputs("^270F18L",display);
28111951Sslatteng 	charxsize = 15;
28211951Sslatteng 	charysize = 24;
28311951Sslatteng         descenders = 6;
28411951Sslatteng     }
28511951Sslatteng     else if (curcharsize == 3)
28611951Sslatteng          {
28711951Sslatteng              fputs("^250A0EL",display);
28811951Sslatteng              charxsize = 10;
28911951Sslatteng              charysize = 14;
29011951Sslatteng              descenders = 2;
29111951Sslatteng          }
29211951Sslatteng          else if (curcharsize == 2)
29311951Sslatteng               {
29411951Sslatteng 	          fputs("^17070CL", display);
29511951Sslatteng 	          charxsize = 8;
29611951Sslatteng 	          charysize = 12;
29711951Sslatteng                   descenders = 3;
29811951Sslatteng               }
29911951Sslatteng               else
30011951Sslatteng               {
30111951Sslatteng 	          fputs("^15050BL", display);
30211951Sslatteng 	          charxsize = 6;
30311951Sslatteng 	          charysize = 7;
30411951Sslatteng                   descenders = 1;
30511951Sslatteng                };
30611951Sslatteng #else
30711951Sslatteng     if (curcharsize == 4)
30811951Sslatteng     {
30911951Sslatteng         fputs("^27\17\30L",display);
31011951Sslatteng 	charxsize = 15;
31111951Sslatteng 	charysize = 24;
31211951Sslatteng         descenders = 6;
31311951Sslatteng     }
31411951Sslatteng     else if (curcharsize == 3)
31511951Sslatteng          {
31611951Sslatteng              fputs("^25\12\16L",display);
31711951Sslatteng              charxsize = 10;
31811951Sslatteng              charysize = 14;
31911951Sslatteng              descenders = 2;
32011951Sslatteng          }
32111951Sslatteng          else if (curcharsize == 2)
32211951Sslatteng               {
32311951Sslatteng 	          fputs("^17\10\14L", display);
32411951Sslatteng 	          charxsize = 8;
32511951Sslatteng 	          charysize = 12;
32611951Sslatteng                   descenders = 3;
32711951Sslatteng               }
32811951Sslatteng               else
32911951Sslatteng               {
33011951Sslatteng 	          fputs("^15\6\7L", display);
33111951Sslatteng 	          charxsize = 6;
33211951Sslatteng 	          charysize = 7;
33311951Sslatteng                   descenders = 1;
33411951Sslatteng                };
33511951Sslatteng #endif
33611951Sslatteng }
33711951Sslatteng 
33811976Sslatteng 
GRInit(stream,invert)33911951Sslatteng GRInit(stream, invert)
34011951Sslatteng FILE *stream;			/* A pointer to the graphics display
34111951Sslatteng 				 * file descriptor.  The file must have
34211951Sslatteng 				 * been opened by the caller.
34311951Sslatteng 				 */
34411951Sslatteng int invert;			/* An integer whose low-order eight bits
34511951Sslatteng 				 * are ones iff the corresponding layers
34611951Sslatteng 				 * are to be inverted (drawing means write
34711951Sslatteng 				 * zeroes and erasing means write ones).
34811951Sslatteng 				 */
34911951Sslatteng 
35011951Sslatteng /*---------------------------------------------------------
35111951Sslatteng  *	GRInit initializes the graphics display and clears its screen.
35211951Sslatteng  *
35311951Sslatteng  *	Results:	None.
35411951Sslatteng  *
35511951Sslatteng  *	Side Effects:
35611951Sslatteng  *	The display is re-initialized and the file is remembered for
35711951Sslatteng  *	use in all subsequent calls to this module.  The display's
35811951Sslatteng  *	color map is reset.  The display is put into raw mode, but
35911951Sslatteng  *	the previous mode bits are saved.
36011951Sslatteng  *
36111951Sslatteng  *	Errors:		None.
36211951Sslatteng  *---------------------------------------------------------
36311951Sslatteng  */
36411951Sslatteng 
36511951Sslatteng {
36611951Sslatteng #ifdef FASTIO
36711976Sslatteng     static int litout = LLITOUT;
36811951Sslatteng #endif
36911951Sslatteng     static int ldisc = NTTYDISC;
37011951Sslatteng 
37111951Sslatteng     /* First, grab up the display modes, then reset them to put it
37211951Sslatteng      * into cooked mode.  Also, lock the terminal.  If doing fast I/O
37311951Sslatteng      * then set the LLITOUT bit.  Note:  setting the LLITOUT bit only
37411976Sslatteng      * works if it happens before the stty.  Also forces the display to
37511976Sslatteng      * run at 9600 baud.
37611951Sslatteng      */
37711951Sslatteng 
37811951Sslatteng     (void) ioctl(fileno(stream), TIOCSETD, (char *) &ldisc);
37911951Sslatteng     (void) ioctl(fileno(stream), TIOCLGET, (char *) &localmode);
38011951Sslatteng #ifdef FASTIO
38111951Sslatteng     (void) ioctl(fileno(stream), TIOCLBIS, (char *) &litout);
38211951Sslatteng #endif
38311951Sslatteng     (void) gtty(fileno(stream), &sgttyb);
38411951Sslatteng     sgflags = sgttyb.sg_flags;
38511976Sslatteng     sgispeed = sgttyb.sg_ispeed;
38611976Sslatteng     sgospeed = sgttyb.sg_ospeed;
38711951Sslatteng     sgttyb.sg_flags = (sgttyb.sg_flags &
388*12240Sslatteng 	~(RAW | CBREAK | ECHO | LCASE)) | EVENP | ODDP | CRMOD;
38911976Sslatteng     sgttyb.sg_ispeed = B9600;
39011976Sslatteng     sgttyb.sg_ospeed = B9600;
39111951Sslatteng     (void) stty(fileno(stream), &sgttyb);
39211951Sslatteng     (void) ioctl(fileno(stream), TIOCEXCL, (char *) &sgttyb);
39311951Sslatteng 
39411951Sslatteng     /* Save the file pointer around for later use, then output an
39511951Sslatteng      * initialization string to the display.  The initialization
39611951Sslatteng      * string resets the terminal, sets formats, clears the display,
39711951Sslatteng      * and initializes the read and write masks.
39811951Sslatteng      */
39911951Sslatteng     display = stream;
40011951Sslatteng     setbuf(display, dbuf);
40111951Sslatteng #ifndef FASTIO
40211951Sslatteng     GRchex(invert&0377, erase, 2);
40311951Sslatteng     GRchex((~invert)&0377, draw, 2);
40411951Sslatteng     fputs("\33\60", display);
40511951Sslatteng     (void) fflush(display);
40611951Sslatteng     (void) system("sleep 1");
40711951Sslatteng     fprintf(display, "\33\33G1HDHN[%sLFF\14\33C%sM7FFFFFFF", erase, draw);
40811951Sslatteng     fprintf(display, "c404022]+00002019001F02828");
40911951Sslatteng #else
41011951Sslatteng     *erase = invert&0377;
41111951Sslatteng     *draw = (~invert)&0377;
41211951Sslatteng     fputs("\33\60", display);
41311951Sslatteng     (void) fflush(display);
41411951Sslatteng     (void) system("sleep 1");
41511951Sslatteng     fputs("\33\33G18D8N[", display);
41611951Sslatteng     putc(*erase, display);
41711951Sslatteng     fputs("L\377\14\33C", display);
41811951Sslatteng     putc(*draw, display);
41911951Sslatteng     fputs("M\177\377\377\377c\100\100\42]+", display);
42011951Sslatteng     putc('\0', display);
42111951Sslatteng     putc('\0', display);
42211951Sslatteng     fputs("2\01\220\01\360\50\50", display);
42311951Sslatteng #endif
42411951Sslatteng     putc('3', display);			/* Make sure the crosshair is off */
42511951Sslatteng     putc('\0', display);
42611951Sslatteng     curx = -1;
42711951Sslatteng     cury = -1;
42811951Sslatteng     curcharsize = -1;
42911951Sslatteng     wmask = 0177;
43011951Sslatteng     rmask = 0177;
43111951Sslatteng     (void) fflush(display);
43211951Sslatteng }
43311951Sslatteng 
43411976Sslatteng 
GRClose()43511951Sslatteng GRClose()
43611951Sslatteng 
43711951Sslatteng /*---------------------------------------------------------
43811951Sslatteng  *	GRClose does whatever is necessary to reset the characteristics
43911951Sslatteng  *	of the AED512 after the program is finished.
44011951Sslatteng  *
44111951Sslatteng  *	Results:	None.
44211951Sslatteng  *
44311951Sslatteng  *	Side Effects:
44411951Sslatteng  *	The graphics display modes are reset.
44511951Sslatteng  *---------------------------------------------------------
44611951Sslatteng  */
44711951Sslatteng 
44811951Sslatteng {
44911951Sslatteng     sgttyb.sg_flags = sgflags;
45011951Sslatteng     (void) stty(fileno(display), &sgttyb);
45111951Sslatteng     (void) ioctl(fileno(display), TIOCNXCL, (char *) &sgttyb);
45211951Sslatteng     (void) ioctl(fileno(display), TIOCLSET, (char *) &localmode);
45311951Sslatteng }
45411951Sslatteng 
45511976Sslatteng 
GRSetMap(pmap)45611951Sslatteng GRSetMap(pmap)
45711951Sslatteng char *pmap;			/* A pointer to 256*3 bytes containing the
45811951Sslatteng 				 * new values for the color map.  The first
45911951Sslatteng 				 * three values are red, green, and blue
46011951Sslatteng 				 * intensities for color 0, and so on.
46111951Sslatteng 				 */
46211951Sslatteng 
46311951Sslatteng /*---------------------------------------------------------
46411951Sslatteng  *	GrSetMap outputs new values to the AED512 color map.
46511951Sslatteng  *
46611951Sslatteng  *	Results:	None.
46711951Sslatteng  *
46811951Sslatteng  *	Side Effects:
46911951Sslatteng  *	The values in the color map are set from the array indicated
47011951Sslatteng  *	by pmap.  The back1 and back2 strings are set so that the
47111951Sslatteng  *	routines GrBack1 and GrBack2 will switch the background color
47211951Sslatteng  *	to color 0 and color 256,respectively.
47311951Sslatteng  *
47411951Sslatteng  *	Errors:		None.
47511951Sslatteng  *
47611951Sslatteng  * (Modified from software written by John Ousterhout for the caesar
47711951Sslatteng  *  program)
47811951Sslatteng  *---------------------------------------------------------
47911951Sslatteng  */
48011951Sslatteng 
48111951Sslatteng {
48211951Sslatteng     char s[4], *p;
48311951Sslatteng     int i;
48411951Sslatteng 
48511951Sslatteng     p = pmap;
48611951Sslatteng #ifndef FASTIO
48711951Sslatteng     fputs("K0000", display);
48811951Sslatteng     for (i = 0; i<256*3; ++i)
48911951Sslatteng     {
49011951Sslatteng 	GRchex(*p++&0377, s, 2);
49111951Sslatteng 	fprintf(display, "%s", s);
49211951Sslatteng     }
49311951Sslatteng #else
49411951Sslatteng     putc('K', display);
49511951Sslatteng     putc('\0', display);
49611951Sslatteng     putc('\0', display);
49711951Sslatteng     for (i = 0; i<256*3; ++i)
49811951Sslatteng     {
49911951Sslatteng 	putc(*p++&0377, display);
50011951Sslatteng     }
50111951Sslatteng #endif
50211951Sslatteng     (void) fflush(display);
50311951Sslatteng 
50411951Sslatteng }
50511951Sslatteng 
506