|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 8858 (0x229a) Types: TextFile Notes: UNIX file Names: »ddt.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦2d53db1df⟧ UNIX Filesystem └─⟦this⟧ »sys/z8001/src/ddt.c«
/* (-lgl * The information contained herein is a trade secret of Mark Williams * Company, and is confidential information. It is provided under a * license agreement, and may be copied or disclosed only under the * terms of that agreement. Any reproduction or disclosure of this * material without the express written authorization of Mark Williams * Company or persuant to the license agreement is unlawful. * * COHERENT Version 0.7.3 * Copyright (c) 1982, 1983, 1984. * An unpublished work by Mark Williams Company, Chicago. * All rights reserved. -lgl) */ /* * Mini ddt. * This routine gets dragged in * with the system. It is used to help * debug the system when the ROM is * full of bootstrap. * This code has a token understanding of things segmented. * * ?1 Illegal command. * ?2 Syntax error of any kind. * ?3 Odd address. */ #include <coherent.h> #include <buf.h> #include <proc.h> #include <seg.h> #define NCBUF (4*64) #define NREG sizeof(regs)/sizeof(regs[0]) #define NNAME 10 #define DEL 0x7F /* Ascii delete */ #define I 0 /* Integer length */ #define L 1 /* Long length */ #define putihex(i) puthex((long)(i), 12) #define putlhex(l) puthex(l, 28) BUF dumpbuf; static char cbuf[NCBUF]; extern int *ddtregp; struct mmu { unsigned base; unsigned char len; unsigned char attr; }; /* * Register names. */ static struct regs { char r_off; char r_len; char r_name[4]; } regs[] = { OR0, I, "r0", OR1, I, "r1", OR2, I, "r2", OR3, I, "r3", OR4, I, "r4", OR5, I, "r5", OR6, I, "r6", OR7, I, "r7", OR8, I, "r8", OR9, I, "r9", OR10, I, "r10", OR11, I, "r11", OR12, I, "r12", OR13, I, "r13", OS14, I, "r14", OS15, I, "r15", OR14, L, "nsp", OFCW, I, "fcw", OPC, L, "pc", }; /* * Signal names. */ static char *signame[] = { "ITS V01", "Hangup", "Interrupt", "Quit", "Alarm", "Termination", "Restart", "System call", "Pipe broken", "Kill", "Breakpoint", "Segment trap", "Unimplemented instruction", "Privileged instruction", "Non-vectored interrupt", "Non-maskable Interrupt", }; /* * Kill bugs. * Called from the mch and from the * user with a signal code. A code of 0 * means user call. */ ddt(sig) { long ladd; register char *cp, *np; register c, v; register struct regs *rp; register PROC *pp; register struct mmu *mp; int nword, address, nwonl; int pflag; unsigned data; saddr_t m; int s; long l1, l2, l3, ln; char name[NNAME]; ddtregp -= OR14; /* Displacement to top of registers */ s = sphi(); printf("%p: %s\n", *(long *)(ddtregp+OPC), signame[sig]); for (;;) { getl(); cp = &cbuf[0]; while ((c = *cp++) == ' ') ; if (c == '\n') continue; switch (c) { case 'c': spl(s); return; case 'd': pflag = 0; if (*cp == 'p') { pflag++; cp++; } while ((c = *cp++) == ' ') ; if ((v = hexdig(c)) < 0) { diag('2'); break; } ladd = 0; do { ladd = (ladd<<4) + v; } while ((v = hexdig(c = *cp++)) >= 0); if ((ladd&01) != 0) { diag('3'); break; } for (;;) { while (c == ' ') c = *cp++; if (c == '\n') break; if ((v = hexdig(c)) < 0) { diag('2'); break; } data = 0; do { data = (data<<4) + v; } while ((v = hexdig(c = *cp++)) >= 0); if (pflag) l1 = pfix(DBS, ladd); else l1 = ptov(ladd); kkcopy(&data, l1, sizeof data); ladd += sizeof (int); } break; case 'e': pflag = 0; if (*cp == 'p') { pflag++; cp++; } while ((c = *cp++) == ' ') ; if ((v = hexdig(c)) < 0) { diag('2'); break; } ladd = 0; do { ladd = (ladd<<4) + v; } while ((v = hexdig(c = *cp++)) >= 0); nword = 1; while (c == ' ') c = *cp++; if (c != '\n') { nword = 0; while ((v = hexdig(c)) >= 0) { nword = (nword<<4) + v; c = *cp++; } } if ((ladd&01) != 0) { diag('3'); break; } nwonl = 0; while (nword--) { if (nwonl >= 8) { putchar('\n'); nwonl = 0; if ((c = getchar()) == DEL) break; } if (nwonl == 0) { putlhex(ladd); putchar(' '); putchar('-'); } putchar(' '); if (pflag) l1 = pfix(DBS, ladd); else l1 = ptov(ladd); kkcopy(l1, &data, sizeof data); putihex(data); ladd += sizeof (int); ++nwonl; } if (nwonl != 0) putchar('\n'); break; case 'f': while ((c = *cp++) == ' ') ; if ((v = hexdig(c)) < 0) { diag('2'); break; } address = 0; do { address = (address<<4) + v; } while ((v = hexdig(c = *cp++)) >= 0); nword = 0; while (c == ' ') c = *cp++; if (c != '\n') { nword = 0; while ((v = hexdig(c)) >= 0) { nword = (nword<<4) + v; c = *cp++; } } asave(m); for (v=0; v<1024; v++) { if (*((int *)(abase(v)+address)) == nword) printf("%x\n", v); } arest(m); break; case 'm': while ((c = *cp++) == ' ') ; if (c == '\n') { diag('2'); break; } np = &name[0]; while (c!=' ' && c!='\n') { if (np < &name[NNAME-1]) *np++ = c; c = *cp++; } *np = 0; while (c == ' ') c = *cp++; if ((v = hexdig(c)) < 0) { diag('2'); break; } ln = 0; do { ln = (ln<<4) + v; } while ((v = hexdig(c = *cp++)) >= 0); for (rp = ®s[0]; rp < ®s[NREG]; rp++) if (eq(name, rp->r_name)) break; if (rp == ®s[NREG]) { diag('2'); break; } switch (rp->r_len) { case I: ddtregp[rp->r_off] = ln; break; case L: *(long *)(ddtregp+rp->r_off) = ln; break; } break; case 'p': for (pp=procq.p_nback; pp!=&procq; pp=pp->p_nback) { v = 0; for (c=0; c<NUSEG; c++) { if (pp->p_segp[c] == NULL) continue; v += pp->p_segp[c]->s_size; } printf("%d %d %dK %o %c %d %d (%p)\n", pp->p_pid, pp->p_ppid, ctokrd(v), pp->p_flags, "?SRZ"[pp->p_state], pp->p_sval, pp->p_rval, pp); } break; case 'r': for (c=0; c<NREG; ++c) { if ((c&03) != 0) putchar(' '); else if (c != 0) putchar('\n'); rp = ®s[c]; putmesg(rp->r_name); putchar(' '); if (rp->r_len == I) putihex(ddtregp[rp->r_off]); else putlhex(*(long *)(ddtregp+rp->r_off)); } putchar('\n'); break; case 's': l1 = 0; l2 = ctob((long)coretop); l3 = 0; while (l1 < l2) { register BUF *bp; bp = &dumpbuf; bp->b_flag = BFNTP; bp->b_req = BWRITE; bp->b_dev = swapdev; bp->b_bno = l3; ln = l2 - l1; c = ln>SCHUNK ? SCHUNK : ln; bp->b_count = c; bp->b_paddr = l1; printf("write(%u, %o, %d)\n", (int)bp->b_bno, (int)bp->b_paddr, bp->b_count); dblock(bp->b_dev, bp); splo(); while ((bp->b_flag&BFNTP) != 0) ; if (bp->b_err != 0) { printf("Error = %d\n", bp->b_err); break; } sphi(); l1 += c; l3 += c/512; } break; case 'M': getmmu(0, 64, cbuf); mp = cbuf; for (c=0; c<64; c++) { printf("%x: %x %x %x", c, mp->base, mp->attr, mp->len); mp++; if ((c & 03) == 03) putchar('\n'); else printf(" "); } break; default: diag('1'); } } } /* * If the character `c' is a legal * hexadecimal digit then return the binary * value of the digit. If it is not legal * return -1. */ static hexdig(c) register c; { if (c>='0' && c<='9') return (c - '0'); if (c>='a' && c<='f') return (c - 'a' + 10); if (c>='A' && c<='F') return (c - 'A' + 10); return (-1); } /* * Get a command line. * Do some sort of erase and kill * processing. The command is packed into * the command buffer `cbuf'. */ static getl() { register char *cp; register c; again: putchar('*'); cp = &cbuf[0]; for (;;) { c = getchar(); if (c == '@') { putchar('\n'); goto again; } if (c == '\b') { if (cp > &cbuf[0]) --cp; continue; } if (c == '\n') { *cp = '\n'; break; } if (cp < &cbuf[NCBUF-1]) *cp++ = c; } } /* * Put out a string using * repeated calls to the put character * routine. */ static putmesg(s) register char *s; { register c; while ((c = *s++) != '\0') putchar(c); } /* * Put out a long integer in * upper case hexadecimal ascii. */ static puthex(l, s) register long l; register int s; { register int c; do { c = (l >> s) & 0xF; c += '0'; if (c > '9') c += 'A'-'0'-10; putchar(c); } while ((s -= 4) >= 0); } /* * Error routine. * The character `c' is the error * code. This is usually a digit but the * followers of Tom Duff may prefer a * letter. */ static diag(c) { putchar('?'); putchar(c); putchar('\n'); } /* * Compare two strings. */ static eq(p1, p2) register char *p1, *p2; { register c; while ((c = *p1++) == *p2++) { if (c == '\0') return (1); } return (0); }