Bell 32V development
[unix-history] / usr / src / standalone / ddump.c
CommitLineData
d52f1552
TL
1# define RP6CYL 815 /* no. RP06 cylinders/pack */
2# define RP6TRK 19 /* no. tracks/cyl */
3# define RP6SEC 22 /* no. sectors/track */
4# define RP6ST (RP6SEC*RP6TRK) /* no. sectors/cyl */
5# define MAXSEC (RP6CYL*RP6TRK*RP6SEC) /* sectors/pack */
6# define M0 0x20010000 /* phys addr MBA 0 */
7# define M0_cr (M0+4) /* MBA 0 control reg addr */
8# define M0_sr (M0+8) /* mba 0 status reg */
9# define M0_map (M0+0x800) /* start MBA 0 map reg's */
10# define M0_var (M0+0xc) /* MBA 0 virt addr reg */
11# define M0_bc (M0+0x10) /* MBA 0 byte count reg */
12# define MBAinit 01 /* MBA init bit */
13/* */
14# define RP (M0+0x400) /* base for RP06 reg's, drive 0 */
15/* */
16# define RP_cr 0 /* RP06 control reg offset, longword */
17# define RP_sr 1 /* RP06 status reg offset */
18# define RP_er1 02 /* RP error reg 1 */
19# define RP_stk 5 /* RP06 sector/track reg offset */
20# define RP_er2 010 /* RP error reg 2 */
21# define RP_off 011 /* RP offset reg */
22# define RP_cyl 012 /* RP06 cylinder reg offset */
23# define RP_er3 015 /* RP error reg 3 */
24/* */
25# define RP_GO 1 /* go bit */
26# define RP_RED 070 /* RP06 read function code */
27# define RP_DC 010 /* drive clear function code */
28# define RP_FMT 0x1000 /* format bit for offset reg */
29# define RP_RIP 020 /* Read-in Preset RP06 function code */
30# define RP_DRY 0200 /* drive ready, status reg */
31# define RP_ERR 040000 /* composite error, status reg */
32# define RP_MOL 0x1000 /* medium-online bit in status reg */
33/* */
34# define RXCS 32 /* receiver control/staus */
35# define RXDB 33 /* receiver data */
36# define TXCS 34 /* transmitter control/status */
37# define TXDB 35 /* transmitter data */
38# define RXCS_DONE 0x80 /* receiver done */
39# define TXCS_RDY 0x80 /* transmitter ready */
40/* */
41# define BLKSIZ 512
42# define MAXUNI 1
43# define NL 012
44# define CR 015
45/* */
46char input[BLKSIZ] ; /* disc input buffer */
47struct { int reg , reg2 , reg3 ; } ;
48int count , dskoff , dunit , error , numbyt ;
49unsigned short bytoff ;
50int *RPptr ; /* ptr to start of RP reg's for desired drive */
51main() {
52/*
53* Stand-alone program to dump RP06 disk to VAX LSI console
54* printer in hex format.
55* User specifies disk unit, start disk block and no. of blocks.
56*/
57int getcon() , putstr() , a2l() , l2a() ;
58
59putlin("ddump : disk-to-console hex dump") ;
60putnl() ;
61
62dun :
63putstr("disk unit : ");
64getcon(input) ;
65dunit = a2l(input) ;
66if ((dunit > MAXUNI) || (dunit < 0)) goto dun ;
67
68doff :
69putstr("start disk block : ") ;
70if (getcon(input)) goto fini ;
71dskoff = a2l(input) ;
72if (dskoff < 0) goto fini ;
73if (dskoff > MAXSEC-1) goto doff ;
74
75gknt :
76putstr("no. blocks : ") ;
77if (getcon(input)) goto fini ;
78count = a2l(input) ;
79if (count < 0) goto gknt ;
80if (count == 0) count = 1 ;
81
82gbyt :
83putstr("no. bytes : ") ;
84if (getcon(input)) goto fini ;
85numbyt = a2l(input) ;
86if ((numbyt < 0) || (numbyt > BLKSIZ)) goto gbyt ;
87if (numbyt == 0) numbyt = BLKSIZ ;
88
89error = 0 ;
90
91if (init()) goto dun ;
92
93putlin(" HI < - - LO") ;
94nullcon(3) ;
95putnl() ;
96
97while ((error == 0) && (count--)) {
98 if (dread()) {
99 putlin("disk i/o error") ;
100 ioerr :
101 error++ ;
102 continue ;
103 }
104 if (prblk()) {
105 putlin("console i/o error") ;
106 goto ioerr ;
107 }
108 putnl() ;
109 putnl() ;
110 dskoff++ ; /* next sector */
111}
112
113goto doff ;
114
115fini :
116return(0) ;
117}
118
119/* */
120
121putstr(csp)
122register char *csp ;
123{
124if (putcon(csp)) return(-1) ;
125return(0) ;
126}
127
128/* */
129
130putlin(sptr)
131register char *sptr ;
132{
133if (putcon(sptr)) return(-1) ;
134if (putnl()) return(-1) ;
135return(0) ;
136}
137
138/* */
139
140nullcon(nn)
141register nn ;
142{
143/*
144* Output 'nn' nulls to console terminal -
145* used for delay.
146*/
147while (nn--) putc(0) ;
148}
149
150/* */
151
152putnl()
153{
154if (putcon("\r\n")) return(-1) ;
155return(0) ;
156}
157
158/* */
159
160putcon(csp)
161register char *csp ;
162{
163/*
164* Function to output null-terminated string pointed to
165* by 'csp' to the VAX LSI terminal.
166*/
167register c ;
168
169c = 0 ;
170while (c = (*csp++)) putc(c) ;
171return(0) ;
172}
173
174/* */
175
176putc(c)
177{
178/* wait for LSI printer to be ready */
179while ((mfpr(TXCS) & TXCS_RDY) == 0) ;
180/* output character */
181mtpr(TXDB,c&0177) ;
182}
183
184/* */
185
186getcon(cs)
187register char *cs ;
188{
189/*
190* Function to return char's from VAX LSI keyboard to
191* char array 'cs' - input stops when CR or LF received -
192* null char appended to end of input
193*/
194register int c , c2 ;
195int getc() ;
196
197inloop :
198 c = getc() ; /* get 1 char from terminal */
199 putc(c) ; /* echo char */
200 if ((c == NL) || (c == CR)) {
201 putc(CR) ;
202 putc(0) ;
203 putc(NL) ;
204 (*cs++) = '\0' ;
205 return(0) ;
206 }
207 else {
208 (*cs++) = c ;
209 goto inloop ;
210 }
211}
212
213/* */
214
215getc()
216{
217/*
218* Return char from VAX LSI terminal char buffer
219*/
220int mfpr() ;
221
222/* Wait for receiver done (user entered char)
223*/
224while ((mfpr(RXCS) & RXCS_DONE) == 0) ;
225return (mfpr(RXDB) & 0177) ; /* return char from receiver buffer */
226}
227
228/* */
229
230mtpr(regno,value)
231{
232 asm(" mtpr 8(ap),4(ap)") ;
233}
234
235/* */
236
237mfpr(regno)
238{
239 asm(" mfpr 4(ap),r0") ;
240}
241
242/* */
243
244a2l(as)
245register char *as ;
246{
247/*
248* Convert null-terminated ascii string to binary
249* and return value.
250* 1st char in string :
251* 0 -> octal
252* x -> hex
253* else decimal
254*/
255register value , base , sign , digit ;
256
257digit = value = sign = 0 ;
258base = 10 ; /* default base */
259
260aloop :
261if ((digit = (*as++)) == 0) return(value) ; /* null */
262
263if (digit == '-') {
264 sign++ ;
265 goto aloop ;
266 }
267
268if (digit == '0') base = 8 ; /* octal base */
269else { if (digit == 'x') base = 16 ; /* hex base */
270 else value = (digit-060) ; /* 060 = '0' */
271 }
272
273while (digit = (*as++)) {
274 if (digit < '0') return(0) ;
275 switch (base) {
276 case 8 : {
277 if (digit > '7') return(0) ;
278 digit -= 060 ;
279 break ;
280 }
281 case 10 : {
282 if (digit > '9') return(0) ;
283 digit -= 060 ;
284 break ;
285 }
286 case 16 : {
287 if (digit <= '9') {
288 digit -= 060 ;
289 break ;
290 }
291 if ((digit >= 'A') && (digit <= 'F')) {
292 digit = (digit - 0101 + 10) ;
293 break ;
294 }
295 if ((digit >= 'a') && (digit <= 'f')) {
296 digit = digit - 0141 + 10 ;
297 break ;
298 }
299 return(0) ;
300 break ;
301 }
302 }
303 value = (value * base) + digit ;
304 }
305return (sign ? -value : value) ;
306}
307
308/* */
309
310init() {
311/*
312* Initialization.
313* Initialize MBA 0 (disk) .
314* Set up MBA 0 map register to map a
315* transfer of 'BLKSIZ' bytes.
316*/
317register int page , *mp0 ;
318
319M0_cr->reg = MBAinit ; /* MBA 0 init */
320RPptr = RP + (dunit * 32 * 4) ; /* start of RP reg's for drive */
321if ((*(RPptr+RP_sr) & RP_MOL) == 0) {
322 putlin("unit not online") ;
323 return(-1) ;
324 }
325*(RPptr+RP_cr) = RP_RIP | RP_GO ; /* drive preset - sets vv */
326*(RPptr+RP_off) = RP_FMT ; /* set format bit */
327
328bytoff = (int)(&input[0])&0777 ; /* byte offset of buffer addr */
329page = ((int)&input[0] >> 9) & 07777777 ; /* start page of buffer */
330mp0 = M0_map ;
331(*mp0++) = 0x80000000 | page++ ;
332(*mp0++) = 0x80000000 | page++ ;
333(*mp0++) = 0 ;
334return(0) ;
335}
336
337/* */
338
339dread()
340{
341/*
342* Function to read 'BLKSIZ' bytes to buffer 'input[]'.
343*/
344register int i , j ;
345
346*(RPptr+RP_cr) = RP_DC | RP_GO ; /* RP06 drive clear function code */
347*(RPptr+RP_cyl) = dskoff/RP6ST ; /* cylinder no. */
348i = dskoff%RP6ST ;
349j = (i/RP6SEC)<<8 ; /* track */
350*(RPptr+RP_stk) = j | (i%RP6SEC) ; /* sector : track */
351M0_bc->reg = (-BLKSIZ) ;
352M0_var->reg = bytoff ; /* virt addr reg = map no. + byte off */
353*(RPptr+RP_cr) = RP_RED | RP_GO ; /* read */
354
355dwait() ; /* wait for i/o to finish */
356if (derror()) return(-1) ; /* error */
357return(0) ; /* normal return */
358}
359
360/* */
361
362dwait() {
363/*
364* Function to wait MBA 0 RP06 disc unit to be ready.
365*/
366while ((*(RPptr+RP_sr)&RP_DRY) == 0) ;
367}
368
369/* */
370
371derror()
372{
373/*
374* Function to check for MBA 0 RP06 error.
375*/
376if (*(RPptr+RP_sr) & RP_ERR) return(-1) ;
377return(0) ;
378}
379
380/* */
381
382halt()
383{
384asm(" halt") ;
385}
386
387/* */
388
389l2a(val,rptr)
390register int val ;
391register char *rptr ;
392{
393register int i ;
394register char *tp ;
395int knt ;
396char tmp[20] , sign ;
397
398knt = sign = 0 ;
399if (val < 0) {
400 sign++ ;
401 val = (-val) ;
402 }
403
404tp = tmp ;
405loop :
406 knt++ ;
407 i = val/10 ; /* quotient & base 10 */
408 (*tp++) = val%10 + '0' ; /* ascii remainder */
409 val = i ;
410 if (val == 0) {
411 /* done dividing */
412 if (sign) { knt++ ; (*tp++) = '-' ; }
413 for (i = knt ; i ; i--)
414 (*rptr++) = tmp[i-1] ;
415 (*rptr++) = '\0' ;
416 return(knt) ;
417 }
418 else goto loop ;
419}
420
421/* */
422
423echo(lngword)
424register int lngword ;
425{
426char tmp[30] ;
427
428l2a(lngword,tmp) ;
429putlin(tmp) ;
430}
431
432/* */
433
434prblk()
435{
436/*
437* Print 512 bytes on VAX LSI console as hex
438* characters.
439* Translate bytes in 'input[]' to hex char's
440* and out to console, 64 char's per line.
441*/
442register int i , j ;
443int k ;
444char c , *hp , *fr ;
445char tmp[1025] , ltmp[65] ;
446
447ltmp[64] = '\0' ;
448hp = "block # \0\0\0\0\0\0\0" ;
449l2a(dskoff,&hp[8]) ;
450putstr(hp) ;
451putnl() ;
452putnl() ;
453
454hxcnvt(input,512,tmp) ; /* convert bytes to hex char's */
455
456j = numbyt ;
457for (i = 0 ; (i < 1024) && (j > 0) ; i=+64 ) {
458 hp = ltmp ;
459 fr = (&tmp[i+63]) ;
460 for ( k = 32 ; k ; k--) {
461 (*hp++) = *(fr-1) ;
462 (*hp++) = (*fr--) ;
463 fr-- ;
464 }
465 putstr(ltmp) ;
466 putc(CR) ;
467 nullcon(5) ;
468 putc(NL) ;
469 j -= 32 ;
470 }
471return(0) ;
472}
473
474/* */
475
476hxcnvt(in,knt,out)
477register char *in , *out ;
478int knt ;
479{
480/*
481* Convert 'knt' bytes in char array 'in' to 'knt*2'
482* hex char's and store in char array 'out'.
483*/
484register unsigned int bit4 , byte ;
485
486byte = 0 ;
487while (knt--) {
488 byte = (*in++) ;
489 bit4 = (byte>>4) & 017 ;
490 (*out++) = (bit4<10?bit4+0x30:bit4+0x57) ;
491 bit4 = byte & 017 ;
492 (*out++) = (bit4<10?bit4+0x30:bit4+0x57) ;
493 }
494return(0) ;
495}