Jspice3
mfbdec.c
Go to the documentation of this file.
1 /**********
2 Copyright 1990 Regents of the University of California. All rights reserved.
3 Author: -C- 1982 Giles C. Billingsley
4 **********/
5 /*
6  * mfbdecode.c
7  *
8  * sccsid "@(#)mfbdecode.c 1.9 9/3/83"
9  *
10  * MFB is a graphics package that was developed by the integrated
11  * circuits group of the Electronics Research Laboratory and the
12  * Department of Electrical Engineering and Computer Sciences at
13  * the University of California, Berkeley, California. The programs
14  * in MFB are available free of charge to any interested party.
15  * The sale, resale, or use of these program for profit without the
16  * express written consent of the Department of Electrical Engineering
17  * and Computer Sciences, University of California, Berkeley, California,
18  * is forbidden.
19  */
20 
21 
22 #include "spice.h"
23 #include <stdio.h>
24 #include "mfb.h"
25 
26 char *digits = "0123456789abcdefABCDEF";
27 int numbers[22] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
28  10, 11, 12, 13, 14, 15};
29 
30 
31 /*
32  * This routine performs graphics conversion of data received from the
33  * graphics terminal through stdio, as specified by a mfbcap entry
34  * pointed to by 'PM'. 'PM' contains printf type escapes to allow
35  * graphics coordinate conversion.
36  *
37  * The following escapes are defined for substituting x/y coordinates:
38  *
39  * %X the X coordinate
40  * %Y the Y coordinate
41  * %Z the Z coordinate
42  * %T the T coordinate
43  *
44  * The codes below affect the state but don't use up a value.
45  *
46  * %d as in printf
47  * %2 like %2d
48  * %3 like %3d
49  * %c gives %c hacking special case characters
50  * %h1 gives one ASCII hex of low order four bits
51  * %h2 gives two ASCII hex of low order eight bits
52  * %h3 gives three ASCII hex of low order twelve bits
53  * %h4 gives four ASCII hex of low order sixteen bits
54  * %o1 gives one ASCII octal of low order three bits
55  * %o2 gives two ASCII octal of low order six bits
56  * %o3 gives three ASCII octal of low order nine bits
57  * %o4 gives four ASCII octal of low order twelve bits
58  * %o5 gives five ASCII octal of low order fifteen bits
59  * %o6 gives six ASCII octal of low order sixteen bits
60  * %t1 gives X and Y in Tektronix format
61  * %t2 gives Z and T in Tektronix format
62  * %R store value in temporary buffer 1
63  * %r store value in temporary buffer 2
64  * %+x add x to the value
65  * %-x subtract x from the value
66  * %*x multiply value by x
67  * %/x divide value by x
68  * %>>x shift value right by x bits
69  * %<<x shift value left by x bits
70  * %|x OR value with x
71  * %&x AND value with x
72  * %^x XOR value with x
73  * %=x set value equal to x
74  * %ax set value equal to absolute value of x
75  * %~ complement value (1's complement)
76  * %% gives %
77  * %B BCD (2 decimal digits encoded in one byte)
78  * %D Delta Data (backwards bcd)
79  *
80  *
81  * where x can be:
82  *
83  * (1) one byte: the numberic value of this byte is used as x.
84  *
85  * (2) '#' followed by a decimal number: the decimal value is used.
86  *
87  * (3) '%' followed by C, F, L, X, Y, Z, T, r, or R: the C, F, L, X, Y, Z,
88  * T, r or R value is used.
89  *
90  * all other characters are ``self-inserting''.
91  */
92 
93 
94 
96 char *PM;
97 {
98  char *cp = PM;
99  register int c, d;
100  register int which = 0;
101  register int Reg = 0, reg = 0;
102  int extra,hix,hiy,lox,loy;
103  int mfbnumarg(), mfbdecnum();
104 
105  if (cp == NULL) {
106  MFBCurrent->X = MFBCurrent->Y = MFBCurrent->Z = MFBCurrent->T = -1;
107  return(MFBCAPNOFORMAT);
108  }
109  while ((c = *cp++)) {
110  if (c != '%') {
111  if(c != (d = (*MFBCurrent->dsply_getchar)())) return(d);
112  continue;
113  }
114  switch (*cp++) {
115 
116  case 'X':
117  MFBCurrent->X = which;
118  continue;
119 
120  case 'Y':
121  MFBCurrent->Y = which;
122  continue;
123 
124  case 'Z':
125  MFBCurrent->Z = which;
126  continue;
127 
128  case 'T':
129  MFBCurrent->T = which;
130  continue;
131 
132  case 'R':
133  Reg = which;
134  continue;
135 
136  case 'r':
137  reg = which;
138  continue;
139 
140  case 'd':
141  which = mfbdecnum( 10, 100 );
142  continue;
143 
144  case '3':
145  which = mfbdecnum( 10, 3 );
146  continue;
147 
148  case '2':
149  which = mfbdecnum( 10, 2 );
150  continue;
151 
152  case 'h':
153  if (*cp >= '1' && *cp <= '4')
154  which = mfbdecnum( 16, *cp++ - '0' );
155  else
156  which = mfbdecnum( 16, 100 );
157  continue ;
158 
159  case 'o':
160  if (*cp >= '1' && *cp <= '6')
161  which = mfbdecnum( 8, *cp++ - '0' );
162  else
163  which = mfbdecnum( 8, 100 );
164  continue ;
165 
166  case 't': /* Tektronix terminals */
167  c = *cp++;
168  if(c == 'i'){
169  /* skip control chars */
170  while((hix = (*MFBCurrent->dsply_getchar)()) < 33);
171  hix -= 32;
172  hiy = (*MFBCurrent->dsply_getchar)() - 32;
173  lox = (*MFBCurrent->dsply_getchar)() - 32;
174  extra = 0; /* use extra as negative flag */
175  if(lox < 16)
176  extra = 1;
177  else
178  lox -= 16;
179  which = lox + 16*hiy + 1024*hix;
180  if(extra)
181  which = -which;
182  }
183  else if(c == '1' || c == '2'){
184  hiy = (*MFBCurrent->dsply_getchar)();
185  extra = (*MFBCurrent->dsply_getchar)();
186  loy = (*MFBCurrent->dsply_getchar)();
187  hix = (*MFBCurrent->dsply_getchar)();
188  lox = (*MFBCurrent->dsply_getchar)();
189  if(c == '1') {
190  MFBCurrent->X=((hix&037)<<7)+((lox&037)<<2)+(extra&3);
191  MFBCurrent->Y=((hiy&037)<<7)+((loy&037)<<2)+((extra>>2)&3);
192  }
193  else if(c == '2') {
194  MFBCurrent->Z=((hix&037)<<7)+((lox&037)<<2)+(extra&3);
195  MFBCurrent->T=((hiy&037)<<7)+((loy&037)<<2)+((extra>>2)&3);
196  }
197  }
198  else{
199  --cp;
200  }
201  continue;
202 
203  case '>':
204  if (*cp++ == '>'){
205  mfbarg(cp, Reg, reg, c);
206  which = which >> c;
207  }
208  else {
209  cp--;
210  if((d = (*MFBCurrent->dsply_getchar)()) != '>')
211  return(MFBCAPSYNTAXERR);
212  }
213  continue;
214 
215  case '<':
216  if (*cp++ == '<'){
217  mfbarg(cp, Reg, reg, c);
218  which = which << c;
219  }
220  else {
221  cp--;
222  if((d = (*MFBCurrent->dsply_getchar)()) != '<')
223  return(MFBCAPSYNTAXERR);
224  }
225  continue;
226 
227  case '|':
228  mfbarg(cp, Reg, reg, c);
229  which |= c;
230  continue;
231 
232  case '&':
233  mfbarg(cp, Reg, reg, c);
234  which &= c;
235  continue;
236 
237  case '^':
238  mfbarg(cp, Reg, reg, c);
239  which ^= c;
240  continue;
241 
242  case '~':
243  which = ~which;
244  continue;
245 
246  case '-':
247  mfbarg(cp, Reg, reg, c);
248  which -= c;
249  continue ;
250 
251  case '+':
252  mfbarg(cp, Reg, reg, c);
253  which += c;
254  continue ;
255 
256  case '*':
257  mfbarg(cp, Reg, reg, c);
258  which *= c;
259  continue ;
260 
261  case '/':
262  mfbarg(cp, Reg, reg, c);
263  which /= c;
264  continue ;
265 
266  case '=':
267  mfbarg(cp, Reg, reg, c);
268  which = c;
269  continue ;
270 
271  case 'c':
272  which = (*MFBCurrent->dsply_getchar)();
273  continue;
274 
275  case 'a':
276  mfbarg(cp, Reg, reg, c);
277  which = abs(c);
278  continue;
279 
280  case '%':
281  if((d = (*MFBCurrent->dsply_getchar)()) != '%')
282  return(MFBCAPSYNTAXERR);
283  continue;
284 
285  default:
286  MFBCurrent->X = MFBCurrent->Y
287  = MFBCurrent->Z = MFBCurrent->T = -1;
288  return(MFBCAPNOFORMAT);
289  }
290  }
291  return(MFBCAPOK);
292 }
293 
294 
295 
296 
297 mfbdecnum( base, maxdigits )
298 int base, maxdigits;
299 {
300  register int i, j, k, result = 0;
301  register char c;
302 
303  for( i = 0; i < maxdigits; i++ ) {
304  c = (*MFBCurrent->dsply_getchar)();
305  for( j = 0; j < 22; j++ ) {
306  if( digits[j] == c ) {
307  k = numbers[j];
308  break;
309  }
310  }
311  if( j >= 22 || k >= base ) {
312  (*(MFBCurrent->dsply_ungetchar))();
313  return(result);
314  }
315  result *= base;
316  result += k;
317  }
318  return(result);
319 }
char * digits
Definition: mfbdec.c:26
int T
Definition: mfb.h:222
#define mfbarg(cp, Reg, reg, val)
Definition: mfb.h:398
int Y
Definition: mfb.h:222
#define MFBCAPOK
Definition: mfb.h:392
int Z
Definition: mfb.h:222
Definition: cddefs.h:237
#define NULL
Definition: spdefs.h:121
#define MFBCAPSYNTAXERR
Definition: mfb.h:394
MFBDecode(char *PM)
Definition: mfbdec.c:95
#define MFBCAPNOFORMAT
Definition: mfb.h:393
static double c
Definition: vectors.c:16
int numbers[22]
Definition: mfbdec.c:27
MFB * MFBCurrent
Definition: mfbopen.c:13
int(* dsply_ungetchar)()
Definition: mfb.h:297
int X
Definition: mfb.h:222
int(* dsply_getchar)()
Definition: mfb.h:295
mfbdecnum(int base, int maxdigits)
Definition: mfbdec.c:297