|
|
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: 3926 (0xf56)
Types: TextFile
Notes: UNIX file
Names: »trap.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦2d53db1df⟧ UNIX Filesystem
└─⟦this⟧ »sys/z8001/src/trap.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) */
/*
* Coherent for Commodore M-series z8001 processor
* running in Segmented mode.
* Common handler for system traps.
*/
#include <coherent.h>
#include <errno.h>
#include <proc.h>
#include <signal.h>
#include <systab.h>
#include <uproc.h>
#include <seg.h>
/*
* Machine dependent system call table.
*/
int unone();
int ubpt();
int uhalt();
struct systab sysdtab[NMDCALL] ={
0, INT, unone, /* 128 = sgrow */
0, VOID, ubpt, /* 129 = bpt */
0, VOID, uhalt, /* 130 = halt */
};
/* Segment trap reason bits */
#define PWW 0x20 /* Primary write warning (Yellow) */
#define SLV 0x04 /* Segment length violation (Red) */
/*
* This is called when a processor trap occurs.
* The peculiar register declaration forces saving
* of r6-r12 which may or may not be saved depedning
* on number of registers declared.
*/
#define REGS r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15
/* ARGSUSED */
trap(emap, omap, sp, REGS, sig, id, fcw, pc)
unsigned emap, omap;
char *sp, *pc;
unsigned sig, id, fcw;
{
long l;
register struct systab *stp;
register int n;
u.u_error = 0;
if ((fcw & MFSYS) != 0) { /* System mode trap */
#if DDT
ddt(sig);
#else
panic("System trap type %d at %p", sig, pc);
#endif
return;
} else if (sig != SIGSYS) { /* Not system call */
if (sig == SIGSEGV)
if (stviol(id, pc, sp))
return;
#if DDT
ddt(sig);
#endif
sendsig(sig, SELF);
return;
}
if ((n = (id&0xFF)) < NMICALL)
stp = &sysitab[n];
else if (n>=SMDCALL && n<SMDCALL+NMDCALL)
stp = &sysdtab[n-SMDCALL];
else {
sendsig(SIGSYS, SELF);
return;
}
ukcopy((char *)(sp+sizeof(pc)), (char *)u.u_args, stp->s_alen);
if (u.u_error)
goto err;
u.u_io.io_seg = IOUSR;
if (envsave(&u.u_sigenv)) {
u.u_error = EINTR;
goto err;
}
l = (*(long(*)())stp->s_func)(u.u_args[0],
u.u_args[1],
u.u_args[2],
u.u_args[3],
u.u_args[4],
u.u_args[5]);
if (u.u_error) {
err:
l = -1;
putuwd(MUERR, u.u_error);
if (u.u_error == EFAULT)
sendsig(SIGSYS, SELF);
}
switch (stp->s_type) {
case INT:
r1 = l;
break;
case PTR:
case LONG:
r0 = ((struct l *)&l)->l_hi;
r1 = ((struct l *)&l)->l_lo;
case VOID:
break;
default:
panic("trap: bad return type\n");
}
}
/*
* Send a breakpoint signal to ourselves.
*/
ubpt()
{
sendsig(SIGTRAP, SELF);
}
/*
* Enter the debugger.
*/
uhalt()
{
if (super() == 0)
return;
halt();
}
/*
* Check to see if the segmentation violation was a red or
* yellow stack limit violation. If it was, then, if
* necessary, back up the PC with a grown stack.
* Returns non-zero if a stack growth attempt is made.
*/
stviol(id, pc, usp)
register int id;
register vaddr_t pc, usp;
{
register SEG *sp;
register unsigned nb;
if (id & SLV) { /* Red stack warning */
if (getuwi(pc) != 0xA1FD) /* ld r13, r15 */
return (0);
if (getuwi(pc-4) == 0x1CE9) /* ldm (rr14), rx,$y */
regl[OPCOFF] -= 4;
else {
nb = getuwi(pc -2);
if (nb == 0x2FED /* ld (rr14), r13 */
|| nb == 0x1DEC) /* ldl (rr14), rr12 */
regl[OPCOFF] -= 2;
}
} else if ((id & PWW) == 0) /* not a Yellow stack warning */
return (0);
sp = SELF->p_segp[SISTACK];
nb = usp;
nb = btocru(0-nb);
if (nb < sp->s_size)
return (1);
else if (nb == sp->s_size)
nb++;
segsize(sp, (vaddr_t)ctob(nb));
return (1);
}