shithub: purgatorio

Download patch

ref: d990c25d5795b16c181e875bf2f55aa06c2f75f9
parent: 70f57939ef437a822bfacde3a6e487633b6ba706
author: henesy <devnull@localhost>
date: Sun Nov 4 12:03:02 EST 2018

init 3

ape/diff: b/lib/acid/null: No such file or directory ape/diff: b/lib/convcs/null: No such file or directory ape/diff: b/lib/ebook/null: No such file or directory ape/diff: b/lib/ebooks/devils/null: No such file or directory ape/diff: b/lib/ebooks/oebtest/null: No such file or directory ape/diff: b/lib/ebooks/understandingoeb/null: No such file or directory ape/diff: b/lib/ebooks/null: No such file or directory ape/diff: b/lib/games/null: No such file or directory ape/diff: b/lib/legal/null: No such file or directory ape/diff: b/lib/lego/null: No such file or directory ape/diff: b/lib/mk/null: No such file or directory ape/diff: b/lib/ndb/null: No such file or directory ape/diff: b/lib/print/null: No such file or directory ape/diff: b/lib/proto/null: No such file or directory ape/diff: b/lib/scores/null: No such file or directory ape/diff: b/lib/sh/null: No such file or directory ape/diff: b/lib/strokes/null: No such file or directory ape/diff: b/lib/unidata/null: No such file or directory ape/diff: b/lib/null: No such file or directory ape/diff: b/lib9/null: No such file or directory ape/diff: b/libbio/null: No such file or directory ape/diff: b/libdraw/null: No such file or directory ape/diff: b/libdynld/null: No such file or directory ape/diff: b/libfreetype/NOTICE/null: No such file or directory ape/diff: b/libfreetype/null: No such file or directory ape/diff: b/libinterp/null: No such file or directory ape/diff: b/libkern/null: No such file or directory ape/diff: b/libkeyring/null: No such file or directory ape/diff: b/liblogfs/null: No such file or directory ape/diff: b/libmath/bin/null: No such file or directory ape/diff: b/libmath/fdlibm/null: No such file or directory ape/diff: b/libmath/null: No such file or directory ape/diff: b/libmemdraw/null: No such file or directory ape/diff: b/libmemlayer/null: No such file or directory ape/diff: b/libmp/Inferno-386/null: No such file or directory ape/diff: b/libmp/Inferno-amd64/null: No such file or directory ape/diff: b/libmp/Inferno-mips/null: No such file or directory ape/diff: b/libmp/Inferno-power/null: No such file or directory ape/diff: b/libmp/Plan9-386/null: No such file or directory ape/diff: b/libmp/Plan9-amd64/null: No such file or directory ape/diff: b/libmp/Plan9-mips/null: No such file or directory ape/diff: b/libmp/Plan9-power/null: No such file or directory ape/diff: b/libmp/port/null: No such file or directory ape/diff: b/libmp/null: No such file or directory ape/diff: b/libnandfs/null: No such file or directory ape/diff: b/libprefab/null: No such file or directory ape/diff: b/libsec/Inferno-386/null: No such file or directory ape/diff: b/libsec/Inferno-mips/null: No such file or directory ape/diff: b/libsec/Plan9-386/null: No such file or directory ape/diff: b/libsec/Plan9-mips/null: No such file or directory ape/diff: b/libsec/port/null: No such file or directory ape/diff: b/libsec/null: No such file or directory ape/diff: b/libtk/null: No such file or directory sed: Output line too long
--- /dev/null	Sun Oct 31 09:33:26 2021
+++ b/lib/acid/386	Sun Nov  4 12:03:02 2018
@@ -0,0 +1,205 @@
+// 386 support
+
+defn acidinit()			// Called after all the init modules are loaded
+{
+	bpl = {};
+	bpid = -1;
+	bpfmt = 'b';
+
+	srcpath = {
+		"./",
+	};
+
+	nopstop = 0;
+	srcfiles = {};			// list of loaded files
+	srctext = {};			// the text of the files
+	Labspoff = 4;		// adjustment to Label's sp
+	Labpcoff = 0;		// adjustment to Label's pc
+}
+
+defn linkreg(addr)
+{
+	return 0;
+}
+
+defn stk()				// trace
+{
+	_stk(*PC, *SP, 0, 0);
+}
+
+defn lstk()				// trace with locals
+{
+	_stk(*PC, *SP, 0, 1);
+}
+
+defn kstk()				// kernel stack, PC and SP point to kernel
+{
+	_stk(*PC, *SP, 0, 0);
+}
+
+defn lkstk()				// kernel stack and locals, PC and SP are kernel's
+{
+	_stk(*PC, *SP, 0, 1);
+}
+defn gpr()		// print general(hah hah!) purpose registers
+{
+	print("AX\t", *AX, " BX\t", *BX, " CX\t", *CX, " DX\t", *DX, "\n");
+	print("DI\t", *DI, " SI\t", *SI, " BP\t", *BP, "\n");
+}
+
+defn spr()				// print special processor registers
+{
+	local pc;
+	local cause;
+
+	pc = *PC;
+	print("PC\t", pc, " ", fmt(pc, 'a'), "  ");
+	pfl(pc);
+	print("SP\t", *SP, " ECODE ", *ECODE, " EFLAG ", *EFLAGS, "\n");
+	print("CS\t", *CS, " DS\t ", *DS, " SS\t", *SS, "\n");
+	print("GS\t", *GS, " FS\t ", *FS, " ES\t", *ES, "\n");
+	
+	cause = *TRAP;
+	print("TRAP\t", cause, " ", reason(cause), "\n");
+}
+
+defn regs()				// print all registers
+{
+	spr();
+	gpr();
+}
+
+defn step()
+{
+	local ur;
+	local addrs;
+	local id;
+	local l;
+	local b;
+	local bl;
+	local sl;
+	local pc;
+
+	complex Proc proc;
+	ur = proc.dbgreg;
+	if ur == 0 then
+		error("step: process not in breakpoint trap");
+	complex Ureg ur;
+
+	 //
+	 // stop all kprocs that could potentially hit this breakpoint
+	 // make a list of all the breakpoints at this address
+	 //
+	bl = {};
+	sl = {};
+	l = bpl;
+
+	while l do {
+		b = head l;
+		if ((b[2] & *PC) == b[2]) then {
+			if status(b[1]) != "Stopped" then {
+				stop(b[1]);
+				sl = append sl, b[1];
+			}
+			bl = append bl, b;
+		}
+		l = tail l;
+	}
+
+	 //
+	 // delete all the breakpoints at this address
+	 //
+	if bl then {
+		l = bl;
+		while l do {
+			b = head l;
+			_bpconddel(b[0]);
+			l = tail l;
+		}
+	}
+
+	 //
+	 // single step to the following address
+	 //
+	addrs = follow(*PC);
+	id = bpset(addrs[0]);
+	startstop(pid);
+	bpdel(id);
+
+	 //
+	 // restore all the breakpoints at this address
+	 //
+	if bl then {
+		l = bl;
+		while l do {
+			b = head l;
+			_bpcondset(b[0], b[1], b[2], b[3]);
+			l = tail l;
+		}
+	}
+
+	 //
+	 // restart all kprocs that could potentially hit this breakpoint
+	 //
+	if sl then {
+		l = sl;
+		while l do {
+			start(head l);
+			l = tail l;
+		}
+	}
+}
+
+aggr Ureg
+{
+	'X' 0 di;
+	'X' 4 si;
+	'X' 8 bp;
+	'X' 12 nsp;
+	'X' 16 bx;
+	'X' 20 dx;
+	'X' 24 cx;
+	'X' 28 ax;
+	'X' 32 gs;
+	'X' 36 fs;
+	'X' 40 es;
+	'X' 44 ds;
+	'X' 48 trap;
+	'X' 52 ecode;
+	'X' 56 pc;
+	'X' 60 cs;
+	'X' 64 flags;
+	{
+	'X' 68 usp;
+	'X' 68 sp;
+	};
+	'X' 72 ss;
+};
+
+
+defn
+Ureg(addr) {
+	complex Ureg addr;
+	print("	di	", addr.di, "\n");
+	print("	si	", addr.si, "\n");
+	print("	bp	", addr.bp, "\n");
+	print("	nsp	", addr.nsp, "\n");
+	print("	bx	", addr.bx, "\n");
+	print("	dx	", addr.dx, "\n");
+	print("	cx	", addr.cx, "\n");
+	print("	ax	", addr.ax, "\n");
+	print("	gs	", addr.gs, "\n");
+	print("	fs	", addr.fs, "\n");
+	print("	es	", addr.es, "\n");
+	print("	ds	", addr.ds, "\n");
+	print("	trap	", addr.trap, "\n");
+	print("	ecode	", addr.ecode, "\n");
+	print("	pc	", addr.pc, "\n");
+	print("	cs	", addr.cs, "\n");
+	print("	flags	", addr.flags, "\n");
+	print("	sp	", addr.sp, "\n");
+	print("}\n");
+	print("	ss	", addr.ss, "\n");
+};
+
+print("/sys/lib/acid/386");
--- /dev/null	Sun Oct 31 09:33:26 2021
+++ b/lib/acid/amd64	Sun Nov  4 12:03:02 2018
@@ -0,0 +1,123 @@
+// amd64
+
+defn acidinit()
+{
+	bplist = {};
+	bpfmt = 'b';
+
+	srcpath = {
+		"./",
+		"/sys/src/libc/port/",
+		"/sys/src/libc/9sys/",
+		"/sys/src/libc/amd64/"
+	};
+
+	srcfiles = {};		// list of loaded files
+	srctext = {};		// the text of the files
+}
+
+defn gpr()
+{
+	print("AX    ", *AX, "\n");
+	print("BX    ", *BX, "\n");
+	print("CX    ", *CX, "\n");
+	print("DX    ", *DX, "\n");
+	print("DI    ", *DI, "\n"); 
+	print("SI    ", *SI, "\n");
+	print("BP    ", *BP, "\n");
+	print("R8    ", *R8, "\n");
+	print("R9    ", *R9, "\n");
+	print("R10   ", *R10, "\n");
+	print("R11   ", *R11, "\n");
+	print("R12   ", *R12, "\n");
+	print("R13   ", *R13, "\n");
+	print("R14   ", *R14, "\n");
+	print("R15   ", *R15, "\n");
+}
+
+defn spr()
+{
+	print("DS  ", *DS, "  ES  ", *ES, "  FS  ", *FS, "  GS  ", *GS, "\n");
+	print("TYPE  ", *TYPE, "\n");
+	print("ERROR ", *ERROR, "\n");
+	print("PC    ", *PC, "\n");
+	print("CS    ", *CS, "\n");
+	print("FLAGS ", *FLAGS, "\n");
+	print("SP    ", *SP, "\n");
+	print("SS    ", *SS, "\n");
+}
+
+defn x87r()
+{
+	print("FCW  ", *FCW, "  FSW  ", *FSW, "  FTW  ", *FTW, "  FOP  ", *FOP, "\n");
+	print("RIP  ", *RIP, "   RDP  ", *RDP, "\n");
+	print("M0   ", *M0, "\n");
+	print("M1   ", *M1, "\n");
+	print("M2   ", *M2, "\n");
+	print("M3   ", *M3, "\n");
+	print("M4   ", *M4, "\n");
+	print("M5   ", *M5, "\n");
+	print("M6   ", *M6, "\n");
+	print("M7   ", *M7, "\n");
+}
+
+defn xmmr()
+{
+	print("MXCSR  ", *MXCSR, "   MXCSRMASK  ", *MXCSRMASK, "\n");
+	print("X0   ", *X0, "\n");
+	print("X1   ", *X1, "\n");
+	print("X2   ", *X2, "\n");
+	print("X3   ", *X3, "\n");
+	print("X4   ", *X4, "\n");
+	print("X5   ", *X5, "\n");
+	print("X6   ", *X6, "\n");
+	print("X7   ", *X7, "\n");
+	print("X8   ", *X8, "\n");
+	print("X9   ", *X9, "\n");
+	print("X10  ", *X10, "\n");
+	print("X11  ", *X11, "\n");
+	print("X12  ", *X12, "\n");
+	print("X13  ", *X13, "\n");
+	print("X14  ", *X14, "\n");
+	print("X15  ", *X15, "\n");
+}
+
+defn fpr()
+{
+	xmmr();
+}
+
+defn regs()
+{
+	gpr();
+	spr();
+}
+
+defn pstop(pid)
+{
+	local l;
+	local pc;
+
+	pc = *PC;
+
+	print(pid,": ", reason(*TRAP), "\t");
+	print(fmt(pc, 'a'), "\t", fmt(pc, 'i'), "\n");
+
+	if notes then {
+		if notes[0] != "sys: breakpoint" then {
+			print("Notes pending:\n");
+			l = notes;
+			while l do {
+				print("\t", head l, "\n");
+				l = tail l;
+			}
+		}
+	}
+}
+
+defn stk()
+{
+	_stk(*PC, *SP, 0, 0);
+}
+
+print("/sys/lib/acid/amd64");
--- /dev/null	Sun Oct 31 09:33:26 2021
+++ b/lib/acid/arm	Sun Nov  4 12:03:02 2018
@@ -0,0 +1,84 @@
+// ARM support
+
+defn acidinit()			// Called after all the init modules are loaded
+{
+	bpl = {};
+	bpid = -1;
+	bpfmt = 'X';
+	nopstop = 0;
+
+	srcpath = {
+		"./",
+	};
+
+	srcfiles = {};			// list of loaded files
+	srctext = {};			// the text of the files
+}
+
+defn linkreg(addr)
+{
+	return 0;
+}
+
+defn stk()			// trace
+{
+	_stk(*PC, *SP, linkreg(0), 0);
+}
+
+defn lstk()			// trace with locals
+{
+	_stk(*PC, *SP, linkreg(0), 1);
+}
+
+defn kstk()
+{
+	local lab;
+	complex Proc proc;
+	lab = proc.sched;
+	complex Label lab;
+	_stk(lab.pc\X, lab.sp\X, linkreg(0), 0);
+}
+
+defn lkstk()
+{
+	local lab;
+	complex Proc proc;
+	lab = proc.sched;
+	complex Label lab;
+	_stk(lab.pc\X, lab.sp\X, linkreg(0), 1);
+}
+
+defn gpr()				// print general purpose registers
+{
+	print("R0\t", *R0, " R1\t", *R1, " R2\t", *R2, " R3\t", *R3, "\n");
+	print("R4\t", *R4, " R5\t", *R5, " R6\t", *R6, " R7\t", *R7, "\n");
+	print("R8\t", *R8, " R9\t", *R9, " R10\t", *R10, " R11\t", *R11, "\n");
+	print("R12\t", *R12, "\n");
+	return 0;
+}
+
+defn spr()				// print special processor registers
+{
+	local pc;
+	local cause;
+	local lr;
+
+	pc = *PC;
+	lr = *LINK;
+	print("PC\t", pc, " ", fmt(pc, 'a'), "  ");
+	pfl(pc);
+	print("LINK\t", lr, " ", fmt(lr, 'a'), "  ");
+	pfl(lr);
+	print("TYPE: ", reason(*TYPE), "\n");
+	print("SP\t", *SP, "\n");
+	
+	return 0;
+}
+
+defn regs()				// print all registers
+{
+	spr();
+	gpr();
+}
+
+print("$ROOT/lib/acid/arm");
--- /dev/null	Sun Oct 31 09:33:26 2021
+++ b/lib/acid/gpa	Sun Nov  4 12:03:02 2018
@@ -0,0 +1,88 @@
+//
+//	generate ``General Purpose Ascii'' file for HP logic analyser
+//
+//	usage: gpa()
+//	note: output has to be postprocessed with "sed 's/0x//g' "...
+//
+
+defn functions(start, end)
+{
+	print("[FUNCTIONS]\n");
+	pc = start;
+	while pc < end do {
+		bnd = fnbound(pc);
+		print(pc\a, "\t", bnd[0], "..", bnd[1]-1, "\n");
+		pc = bnd[1];
+	}
+	print("\n");
+}
+
+defn variables(start, end)
+{
+	print("[VARIABLES]\n");
+	// TODO: how do we get this one?
+	print("\n");
+}
+
+defn sourcelines(start, end)
+{
+	local pc, curfile, curline, newfile, newline;
+
+	print("[SOURCE LINES]\n");
+	pc = txtstart;
+	curfile = "<no-file>";
+	curline = -1;
+	while pc < txtend do {
+		newfile = pcfile(pc);
+		newline = pcline(pc);
+		if newfile != curfile then {
+			if curline != -1 then
+				print("\n");
+			print("File: ", newfile, "\n");
+			curfile = newfile;
+		}
+		if newline != curline then {
+			print(newline, "\t", pc, "\n");
+			curline = newline;
+		}
+		pc++;
+	}
+	print("\n");
+}
+
+defn gpa()
+{
+	local l, ent, txtstart, txtend, datastart, dataend, pc, bnd;
+
+	print("[SECTIONS]\n");
+	l = map();
+	while l do {
+		ent = head l;
+		if ent[0] == "text" || ent[0] == "data" then {
+			if ent[0] == "text" then {
+				txtstart = ent[1];
+				txtend = ent[2];
+			}
+			else {
+				datastart = ent[1];
+				dataend = ent[2];
+			}
+			print(ent[0], "\t", ent[1], "..", ent[2]-1, "\n");
+		}
+		l = tail l;
+	}
+	print("\n");
+
+	functions(txtstart, txtend);
+//	variables(datastart, dataend);
+	sourcelines(datastart, dataend);
+
+	print("[START ADDRESS]\n");
+	print(txtstart, "\n");
+	print("\n");
+}
+
+defn acidinit()
+{
+	gpa();
+}
--- /dev/null	Sun Oct 31 09:33:26 2021
+++ b/lib/acid/inferno	Sun Nov  4 12:03:02 2018
@@ -0,0 +1,63 @@
+//
+//	experimental acid functions for Inferno (common to native and emu)
+//
+//	problems arise because of unnamed substructures having to be
+//	named in emu, for instance Ref.  We cheat by ``knowing'' that Ref
+//	is first in the structure, to keep this code portable between native
+//	and emu.
+//
+
+//
+// ps() - Process Listing
+//
+complex Ref	pidalloc;
+
+defn
+ps()
+{
+	local i;
+	local n;
+	local done;
+	local p;
+	local curpid;
+
+	i = 0;
+	done = 0;
+	n = pidalloc.ref;
+	curpid = pid;
+	p = procalloc.arena;
+
+	if n > conf.nproc then
+		n = conf.nproc;
+
+	print("PID	PC          PRI     STATE   NAME\n");
+	while n > 0 && i < conf.nproc do {
+		complex Proc p;
+		if p.state != 0 then {
+			print(p.pid, "\t", p.pc\X, "\t", p.pri, "\t", status(p.pid), "\t");
+			mem(p.text, "s");
+			n = n - 1;
+		}
+		i = i + 1;
+		p = p + sizeofProc;
+	}
+}
+
+defn labels()
+{
+	local n;
+	local l;
+	complex Proc proc;
+
+	n = proc.nerrlab;
+	l = proc.errlab;
+	while n > 0 do {
+		complex Label l;
+		print(l.pc\a, " ");
+		pfl(l.pc);
+		l = l + sizeofLabel;
+		n = n - 1;
+	}
+}
+
+print("$ROOT/lib/acid/inferno");
--- /dev/null	Sun Oct 31 09:33:26 2021
+++ b/lib/acid/mips	Sun Nov  4 12:03:02 2018
@@ -0,0 +1,217 @@
+// Mips support
+
+defn acidinit()			// Called after all the init modules are loaded
+{
+	bplist = {};
+	bpfmt = 'X';
+
+	srcpath = {
+		"./",
+		"/sys/src/libc/port/",
+		"/sys/src/libc/9sys/",
+		"/sys/src/libc/mips/"
+	};
+
+	srcfiles = {};		// list of loaded files
+	srctext = {};		// the text of the files
+}
+
+defn stk()			// trace
+{
+	_stk(*PC, *SP, linkreg(0), 0);
+}
+
+defn lstk()			// trace with locals
+{
+	_stk(*PC, *SP, linkreg(0), 1);
+}
+
+defn gpr()			// print general purpose registers
+{
+	print("R1\t", *R1, " R2\t", *R2, " R3\t", *R3, "\n");
+	print("R4\t", *R4, " R5\t", *R5, " R6\t", *R6, "\n");
+	print("R7\t", *R7, " R8\t", *R8, " R9\t", *R9, "\n");
+	print("R10\t", *R10, " R11\t", *R11, " R12\t", *R12, "\n");
+	print("R13\t", *R13, " R14\t", *R14, " R15\t", *R15, "\n");
+	print("R16\t", *R16, " R17\t", *R17, " R18\t", *R18, "\n");
+	print("R19\t", *R19, " R20\t", *R20, " R21\t", *R21, "\n");
+	print("R22\t", *R22, " R23\t", *R23, " R24\t", *R24, "\n");
+	print("R25\t", *R25, " R26\t", *R26, " R27\t", *R27, "\n");
+	print("R28\t", *R28, " R29\t", *SP, " R30\t", *R30, "\n");
+	print("R31\t", *R31, "\n");
+}
+
+defn Fpr()
+{
+	print("F0\t",  *fmt(F0, 'G'),  "\tF2\t",  *fmt(F2, 'G'), "\n");
+	print("F4\t",  *fmt(F4, 'G'),  "\tF6\t",  *fmt(F6, 'G'), "\n");
+	print("F8\t",  *fmt(F8, 'G'),  "\tF10\t", *fmt(F10, 'G'), "\n");
+	print("F12\t", *fmt(F12, 'G'), "\tF14\t", *fmt(F14, 'G'), "\n");
+	print("F16\t", *fmt(F16, 'G'), "\tF18\t", *fmt(F18, 'G'), "\n");
+	print("F20\t", *fmt(F20, 'G'), "\tF22\t", *fmt(F22, 'G'), "\n");
+	print("F24\t", *fmt(F24, 'G'), "\tF26\t", *fmt(F26, 'G'), "\n");
+	print("F28\t", *fmt(F28, 'G'), "\tF30\t", *fmt(F30, 'G'), "\n");
+}
+
+defn fpr()
+{
+	print("F0\t",  *fmt(F0, 'g'),  "\tF1\t",  *fmt(F1, 'g'), "\n");
+	print("F2\t",  *fmt(F2, 'g'),  "\tF3\t",  *fmt(F3, 'g'), "\n");
+	print("F4\t",  *fmt(F4, 'g'),  "\tF5\t",  *fmt(F5, 'g'), "\n");
+	print("F6\t",  *fmt(F6, 'g'),  "\tF7\t",  *fmt(F7, 'g'), "\n");
+	print("F8\t",  *fmt(F8, 'g'),  "\tF9\t",  *fmt(F9, 'g'), "\n");
+	print("F10\t", *fmt(F10, 'g'), "\tF11\t", *fmt(F11, 'g'), "\n");
+	print("F12\t", *fmt(F12, 'g'), "\tF13\t", *fmt(F13, 'g'), "\n");
+	print("F14\t", *fmt(F14, 'g'), "\tF15\t", *fmt(F15, 'g'), "\n");
+	print("F16\t", *fmt(F16, 'g'), "\tF17\t", *fmt(F17, 'g'), "\n");
+	print("F18\t", *fmt(F18, 'g'), "\tF19\t", *fmt(F19, 'g'), "\n");
+	print("F20\t", *fmt(F20, 'g'), "\tF21\t", *fmt(F21, 'g'), "\n");
+	print("F22\t", *fmt(F22, 'g'), "\tF23\t", *fmt(F23, 'g'), "\n");
+	print("F24\t", *fmt(F24, 'g'), "\tF25\t", *fmt(F25, 'g'), "\n");
+	print("F26\t", *fmt(F26, 'g'), "\tF27\t", *fmt(F27, 'g'), "\n");
+	print("F28\t", *fmt(F28, 'g'), "\tF29\t", *fmt(F29, 'g'), "\n");
+	print("F30\t", *fmt(F30, 'g'), "\tF31\t", *fmt(F31, 'g'), "\n");
+}
+
+defn spr()				// print special processor registers
+{
+	local pc, link, cause;
+
+	pc = *PC;
+	print("PC\t", pc, " ", fmt(pc, 'a'), "  ");
+	pfl(pc);
+
+	link = *R31;
+	print("SP\t", *SP, "\tLINK\t", link, " ", fmt(link, 'a'), " ");
+	pfl(link);
+
+	cause = *CAUSE;
+	print("STATUS\t", *STATUS, "\tCAUSE\t", cause, " ", reason(cause), "\n");
+	print("TLBVIR\t", *TLBVIRT, "\tBADVADR\t", *BADVADDR, "\n");
+
+	print("HI\t", *HI, "\tLO\t", *LO, "\n");
+}
+
+defn regs()				// print all registers
+{
+	spr();
+	gpr();
+}
+
+defn pstop(pid)
+{
+	local l, pc;
+
+	pc = *PC;
+
+	print(pid,": ", reason(*CAUSE), "\t");
+	print(fmt(pc, 'a'), "\t", fmt(pc, 'i'), "\n");
+
+	if notes then {
+		if notes[0] != "sys: breakpoint" then {
+			print("Notes pending:\n");
+			l = notes;
+			while l do {
+				print("\t", head l, "\n");
+				l = tail l;
+			}
+		}
+	}
+}
+
+sizeofUreg = 152;
+aggr Ureg
+{
+	'X' 0 status;
+	'X' 4 pc;
+	{
+	'X' 8 sp;
+	'X' 8 usp;
+	};
+	'X' 12 cause;
+	'X' 16 badvaddr;
+	'X' 20 tlbvirt;
+	'X' 24 hi;
+	'X' 28 lo;
+	'X' 32 r31;
+	'X' 36 r30;
+	'X' 40 r28;
+	'X' 44 r27;
+	'X' 48 r26;
+	'X' 52 r25;
+	'X' 56 r24;
+	'X' 60 r23;
+	'X' 64 r22;
+	'X' 68 r21;
+	'X' 72 r20;
+	'X' 76 r19;
+	'X' 80 r18;
+	'X' 84 r17;
+	'X' 88 r16;
+	'X' 92 r15;
+	'X' 96 r14;
+	'X' 100 r13;
+	'X' 104 r12;
+	'X' 108 r11;
+	'X' 112 r10;
+	'X' 116 r9;
+	'X' 120 r8;
+	'X' 124 r7;
+	'X' 128 r6;
+	'X' 132 r5;
+	'X' 136 r4;
+	'X' 140 r3;
+	'X' 144 r2;
+	'X' 148 r1;
+};
+
+defn
+Ureg(addr) {
+	complex Ureg addr;
+	print("	status	", addr.status, "\n");
+	print("	pc	", addr.pc, "\n");
+	print("	sp	", addr.sp, "\n");
+	print("	cause	", addr.cause, "\n");
+	print("	badvaddr	", addr.badvaddr, "\n");
+	print("	tlbvirt	", addr.tlbvirt, "\n");
+	print("	hi	", addr.hi, "\n");
+	print("	lo	", addr.lo, "\n");
+	print("	r31	", addr.r31, "\n");
+	print("	r30	", addr.r30, "\n");
+	print("	r28	", addr.r28, "\n");
+	print("	r27	", addr.r27, "\n");
+	print("	r26	", addr.r26, "\n");
+	print("	r25	", addr.r25, "\n");
+	print("	r24	", addr.r24, "\n");
+	print("	r23	", addr.r23, "\n");
+	print("	r22	", addr.r22, "\n");
+	print("	r21	", addr.r21, "\n");
+	print("	r20	", addr.r20, "\n");
+	print("	r19	", addr.r19, "\n");
+	print("	r18	", addr.r18, "\n");
+	print("	r17	", addr.r17, "\n");
+	print("	r16	", addr.r16, "\n");
+	print("	r15	", addr.r15, "\n");
+	print("	r14	", addr.r14, "\n");
+	print("	r13	", addr.r13, "\n");
+	print("	r12	", addr.r12, "\n");
+	print("	r11	", addr.r11, "\n");
+	print("	r10	", addr.r10, "\n");
+	print("	r9	", addr.r9, "\n");
+	print("	r8	", addr.r8, "\n");
+	print("	r7	", addr.r7, "\n");
+	print("	r6	", addr.r6, "\n");
+	print("	r5	", addr.r5, "\n");
+	print("	r4	", addr.r4, "\n");
+	print("	r3	", addr.r3, "\n");
+	print("	r2	", addr.r2, "\n");
+	print("	r1	", addr.r1, "\n");
+};
+
+defn linkreg(addr)
+{
+	complex Ureg addr;
+	return addr.r31\X;
+}
+
+print("/sys/lib/acid/mips");
--- /dev/null	Sun Oct 31 09:33:26 2021
+++ b/lib/acid/port	Sun Nov  4 12:03:02 2018
@@ -0,0 +1,547 @@
+// portable acid for all architectures
+
+defn pfl(addr)
+{
+	print(pcfile(addr), ":", pcline(addr), "\n");
+}
+
+defn
+notestk(addr)
+{
+	local pc, sp;
+	complex Ureg addr;
+
+	pc = addr.pc\X;
+	sp = addr.sp\X;
+
+	print("Note pc:", pc, " sp:", sp, " ", fmt(pc, 'a'), " ");
+	pfl(pc);
+	_stk(pc, sp, linkreg(addr), 1);
+}
+
+defn labstk(l)				// trace from a label
+{
+	_stk(*(l+4), *l, linkreg(0), 0);
+}
+
+defn params(param)
+{
+	while param do {
+		sym = head param;
+		print(sym[0], "=", sym[1]);
+		param = tail param;
+		if param then
+			print (",");
+	}	
+}
+
+defn locals(l)
+{
+	local sym;
+
+	while l do {
+		sym = head l;
+		print("\t", sym[0], "=", sym[1], "\n");
+		l = tail l;
+	}	
+}
+
+defn _stk(pc, sp, link, dolocals)
+{
+	local stk;
+
+	print("At pc:", pc, ":", fmt(pc, 'a'), " ");
+	pfl(pc);
+
+	stk = strace(pc, sp, link);
+
+	while stk do {
+		frame = head stk;
+		print(fmt(frame[0], 'a'), "(");
+		params(frame[2]);
+		print(") ", pcfile(frame[0]), ":", pcline(frame[0]));
+		print("\n\tcalled from ", fmt(frame[1], 'a'), " ");
+		pfl(frame[1]);
+		stk = tail stk;
+		if dolocals then
+			locals(frame[3]);
+	}
+}
+
+defn findsrc(file)
+{
+	local lst, src;
+
+	if file[0] == '/' then {
+		src = file(file);
+		if src != {} then {
+			srcfiles = append srcfiles, file;
+			srctext = append srctext, src;
+			return src;
+		}
+		return {};
+	}
+
+	lst = srcpath;
+	while head lst do {
+		src = file(head lst+file);
+		if src != {} then {
+			srcfiles = append srcfiles, file;
+			srctext = append srctext, src;
+			return src;
+		}
+		lst = tail lst;
+	}
+}
+
+defn line(addr)
+{
+	local src, file;
+
+	file = pcfile(addr);
+	src = match(file, srcfiles);
+
+	if src >= 0 then
+		src = srctext[src];
+	else
+		src = findsrc(file);
+
+	if src == {} then {
+		print("no source for ", file, "\n");
+		return {};
+	}
+	line = pcline(addr)-1;
+	print(file, ":", src[line], "\n");
+}
+
+defn addsrcdir(dir)
+{
+	dir = dir+"/";
+
+	if match(dir, srcpath) >= 0 then {
+		print("already in srcpath\n");
+		return {};
+	}
+
+	srcpath = {dir}+srcpath;
+}
+
+defn source()
+{
+	local l;
+
+	l = srcpath;
+	while l do {
+		print(head l, "\n");
+		l = tail l;
+	}
+	l = srcfiles;
+
+	while l do {
+		print("\t", head l, "\n");
+		l = tail l;
+	}
+}
+
+defn Bsrc(addr)
+{
+	local lst;
+
+	lst = srcpath;
+	file = pcfile(addr);
+	if file[0] == '/' && access(file) then {
+		rc("B "+itoa(-pcline(addr))+" "+file);
+		return {};
+	}
+	while head lst do {
+		name = head lst+file;
+		if access(name) then {
+			rc("B "+itoa(-pcline(addr))+" "+name);
+			return {};
+		}
+		lst = tail lst;
+	}
+	print("no source for ", file, "\n");
+}
+
+defn src(addr)
+{
+	local src, file, line, cline, text;
+
+	file = pcfile(addr);
+	src = match(file, srcfiles);
+
+	if src >= 0 then
+		src = srctext[src];
+	else
+		src = findsrc(file);
+
+	if src == {} then {
+		print("no source for ", file, "\n");
+		return {};
+	}
+
+	cline = pcline(addr)-1;
+	print(file, ":", cline, "\n");
+	line = cline-5;
+	loop 0,10 do {
+		if line >= 0 then {
+			if line == cline then
+				print(">");
+			else
+				print(" ");
+			text = src[line];
+			if text == {} then
+				return {};
+			print(line, "\t", text, "\n");
+		}
+		line = line+1;
+	}
+}
+
+defn stopped(pid)		// called from acid when a process changes state
+{
+	pstop(pid);		// stub so this is easy to replace
+}
+
+defn procs()			// print status of processes
+{
+	local c, lst, cpid;
+
+	cpid = pid;
+	lst = proclist;
+	while lst do {
+		np = head lst;
+		setproc(np);
+		if np == cpid then
+			c = '>';
+		else
+			c = ' ';
+		print(fmt(c, 'c'), np, ": ", status(np), " at ", fmt(*PC, 'a'), " setproc(", np, ")\n");
+		lst = tail lst;
+	}
+	pid = cpid;
+	if pid != 0 then
+		setproc(pid);
+}
+
+defn asm(addr)
+{
+	local bound;
+
+	bound = fnbound(addr);
+
+	addr = fmt(addr, 'i');
+	loop 1,30 do {
+		print(fmt(addr, 'a'), " ", fmt(addr, 'X'));
+		print("\t", @addr++, "\n");
+		if bound != {} && addr > bound[1] then {
+			lasmaddr = addr;
+			return {};
+		}
+	}
+	lasmaddr = addr;
+}
+
+defn casm()
+{
+	asm(lasmaddr);
+}
+
+defn new()
+{
+	bplist = {};
+	newproc(progargs);
+	// Dont miss the delay slot calls
+	bpset(follow(main)[0]);
+	cont();
+	bpdel(*PC);
+}
+
+defn stmnt()			// step one statement
+{
+	local line;
+
+	line = pcline(*PC);
+	while 1 do {
+		step();
+		if line != pcline(*PC) then {
+			src(*PC);
+			return {};
+		}
+	}
+}
+
+defn func()			// step until we leave the current function
+{
+	local bound, end, start, pc;
+
+	bound = fnbound(*PC);
+	if bound == {} then {
+		print("cannot locate text symbol\n");
+		return {};
+	}
+
+	pc = *PC;
+	start = bound[0];
+	end = bound[1];
+	while pc >= start && pc < end do {
+		step();
+		pc = *PC;
+	}
+}
+
+defn next()
+{
+	local sp, bound;
+
+	sp = *SP;
+	bound = fnbound(*PC);
+	stmnt();
+	pc = *PC;
+	if pc >= bound[0] && pc < bound[1] then
+		return {};
+
+	while (pc < bound[0] || pc > bound[1]) && sp >= *SP do {
+		step();
+		pc = *PC;
+	}
+	src(*PC);
+}
+
+defn dump(addr, n, fmt)
+{
+	loop 0, n do {
+		print(fmt(addr, 'X'), ": ");
+		addr = mem(addr, fmt);
+	}
+}
+
+defn mem(addr, fmt)
+{
+
+	local i, c, n;
+
+	i = 0;
+	while fmt[i] != 0 do {
+		c = fmt[i];
+		n = 0;
+		while '0' <= fmt[i] && fmt[i] <= '9' do {
+			n = 10*n + fmt[i]-'0';
+			i = i+1;
+		}
+		if n <= 0 then n = 1;
+		addr = fmt(addr, fmt[i]);
+		while n > 0 do {
+			print(*addr++, " ");
+			n = n-1;
+		}
+		i = i+1;
+	}
+	print("\n");
+	return addr;
+}
+
+defn symbols(pattern)
+{
+	local l, s;
+
+	l = symbols;
+	while l do {
+		s = head l;
+		if regexp(pattern, s[0]) then
+			print(s[0], "\t", s[1], "\t", s[2], "\n");
+		l = tail l;
+	}
+}
+
+defn spsrch(len)
+{
+	local addr, a, s, e;
+
+	addr = *SP;
+	s = origin & 0x7fffffff;
+	e = etext & 0x7fffffff;
+	loop 1, len do {
+		a = *addr++;
+		c = a & 0x7fffffff;
+		if c > s && c < e then {
+			print("src(", a, ")\n");
+			pfl(a);
+		}			
+	}
+}
+
+defn bppush(val)
+{
+	return {"p", val};
+}
+
+defn bpderef()
+{
+	return {"*", 0};
+}
+
+defn bpmask()
+{
+	return {"&", 0};
+}
+
+defn bpeq()
+{
+	return {"=", 0};
+}
+
+defn bpneq()
+{
+	return {"!", 0};
+}
+
+defn bpand()
+{
+	return {"a", 0};
+}
+
+defn bpor()
+{
+	return {"o", 0};
+}
+
+defn bpcondset(pid, addr, conds)
+{
+	local l;
+	local id;
+	local found;
+
+ 	if status(pid) != "Stopped" then {
+ 		print("Waiting...\n");
+ 		stop(pid);
+ 	}
+
+	id = 0;
+	found = 0;
+
+	while !found && id <= 255 do {
+		l = bpl;
+		while l && head head l != id do {
+			l = tail l;
+		}
+
+		if !l then
+			found = 1;
+		else
+			id = id + 1;
+	}
+
+	if !found then {
+		print("error: no breakpoints available\n");
+		return -1;
+	}
+
+	bpl = append bpl, {id\d, pid\d, addr\X, conds};
+
+	_bpcondset(id, pid, addr, conds);
+
+	return id;
+}
+
+defn bpconddel(id)
+{
+	local i;
+	local l;
+
+	l = bpl;
+	i = 0;
+	while l do {
+		if id == head head l then {
+			bpl = delete bpl, i;
+			_bpconddel(id);
+			if id == bpid then
+				bpid = -1;
+			return {};
+		}
+		i = i + 1;
+		l = tail l;
+	}
+	print("no breakpoint with id ", id\d, ".\n");
+}
+
+defn bpprint(b)
+{
+	local l;
+
+	print(b[0], "\t", b[1], "\t", fmt(b[2], 'a'), " ", b[2]);
+	print("\t{");
+	l = b[3];
+	while l do {
+		print("\n\t\t\t\t\t", head l);
+		l = tail l;
+	}
+	print(" }\n");
+}
+
+defn bptab()
+{
+	local l;
+
+	l = bpl;
+	print("ID	PID	ADDR			CONDITIONS\n");
+	while l do {
+		bpprint(head l);
+		l = tail l;
+	}
+}
+
+defn cont()
+{
+	local b, c, l, found;
+
+	l = bpl;
+	found = 0;
+	c = *PC;
+	while !found && l do {
+		b = head l;
+		if b[2] == c then {
+			nopstop = 1;
+			step();
+			nopstop = 0;
+			found = 1;
+		} else {
+			l = tail l;
+		}
+	}
+
+	return startstop(pid);
+}
+
+defn bpset(addr)				// set a breakpoint
+{
+	return bpcondset(pid, addr, {});
+}
+
+defn bpdel(id)
+{
+	bpconddel(id);
+}
+
+defn bpaddr(id)
+{
+	local i;
+	local l;
+	local b;
+
+	l = bpl;
+	i = 0;
+	while l do {
+		b = head l;
+		if id == b[0] then
+			return b[2];
+		i = i + 1;
+		l = tail l;
+	}
+	print("bpaddr(", id\d, "): no match\n");
+	return {};
+}
+
+progargs="";
+print("$ROOT/lib/acid/port");
--- /dev/null	Sun Oct 31 09:33:26 2021
+++ b/lib/acid/power	Sun Nov  4 12:03:02 2018
@@ -0,0 +1,233 @@
+// Power PC support
+
+defn acidinit()			// Called after all the init modules are loaded
+{
+        bpl = {};
+        bpid = -1;
+        bpfmt = 'X';
+        nopstop = 0;
+	bplist = {};
+
+	srcpath = {
+		"./",
+		"/sys/src/libc/port/",
+		"/sys/src/libc/9sys/",
+		"/sys/src/libc/power/"
+	};
+
+	srcfiles = {};		// list of loaded files
+	srctext = {};		// the text of the files
+}
+
+// defn stk()			// trace
+// {
+// 	_stk(*PC, *SP, linkreg(0), 0);
+// }
+
+// defn lstk()			// trace with locals
+// {
+// 	_stk(*PC, *SP, linkreg(0), 1);
+// }
+
+defn ustk(ur)
+{
+	complex Ureg ur;
+	_stk(ur.pc, ur.sp, 0, 0);
+}
+
+defn lustk(ur)
+{
+	complex Ureg ur;
+	_stk(ur.pc, ur.sp, 0, 1);
+}
+
+defn stk()
+{
+	ustk(0);
+}
+
+defn lstk()
+{
+	lustk(0);
+}
+
+defn kstk()
+{
+	local lab;
+	complex Proc proc;
+	lab = proc.sched;
+	complex Label lab;
+	_stk(lab.pc\X, lab.sp\X, 0, 0);
+}
+
+defn lkstk()
+{
+	local lab;
+	complex Proc proc;
+	lab = proc.sched;
+	complex Label lab;
+	_stk(lab.pc\X, lab.sp\X, 0, 1);
+}
+
+defn gpr()			// print general purpose registers
+{
+	print("SP\t", *SP, " R2\t", *R2, " R3\t", *R3, "\n");
+	print("R4\t", *R4, " R5\t", *R5, " R6\t", *R6, "\n");
+	print("R7\t", *R7, " R8\t", *R8, " R9\t", *R9, "\n");
+	print("R10\t", *R10, " R11\t", *R11, " R12\t", *R12, "\n");
+	print("R13\t", *R13, " R14\t", *R14, " R15\t", *R15, "\n");
+	print("R16\t", *R16, " R17\t", *R17, " R18\t", *R18, "\n");
+	print("R19\t", *R19, " R20\t", *R20, " R21\t", *R21, "\n");
+	print("R22\t", *R22, " R23\t", *R23, " R24\t", *R24, "\n");
+	print("R25\t", *R25, " R26\t", *R26, " R27\t", *R27, "\n");
+	print("R28\t", *R28, " R29\t", *R29, " R30\t", *R30, "\n");
+	print("R31\t", *R31, "\n");
+}
+
+defn Fpr()
+{
+	fpr();
+}
+
+defn fpr()
+{
+	print("F0\t",  *fmt(F0, 'G'),  "\tF1\t",  *fmt(F1, 'G'), "\n");
+	print("F2\t",  *fmt(F2, 'G'),  "\tF3\t",  *fmt(F3, 'G'), "\n");
+	print("F4\t",  *fmt(F4, 'G'),  "\tF5\t",  *fmt(F5, 'G'), "\n");
+	print("F6\t",  *fmt(F6, 'G'),  "\tF7\t",  *fmt(F7, 'G'), "\n");
+	print("F8\t",  *fmt(F8, 'G'),  "\tF9\t",  *fmt(F9, 'G'), "\n");
+	print("F10\t", *fmt(F10, 'G'), "\tF11\t", *fmt(F11, 'G'), "\n");
+	print("F12\t", *fmt(F12, 'G'), "\tF13\t", *fmt(F13, 'G'), "\n");
+	print("F14\t", *fmt(F14, 'G'), "\tF15\t", *fmt(F15, 'G'), "\n");
+	print("F16\t", *fmt(F16, 'G'), "\tF17\t", *fmt(F17, 'G'), "\n");
+	print("F18\t", *fmt(F18, 'G'), "\tF19\t", *fmt(F19, 'G'), "\n");
+	print("F20\t", *fmt(F20, 'G'), "\tF21\t", *fmt(F21, 'G'), "\n");
+	print("F22\t", *fmt(F22, 'G'), "\tF23\t", *fmt(F23, 'G'), "\n");
+	print("F24\t", *fmt(F24, 'G'), "\tF25\t", *fmt(F25, 'G'), "\n");
+	print("F26\t", *fmt(F26, 'G'), "\tF27\t", *fmt(F27, 'G'), "\n");
+	print("F28\t", *fmt(F28, 'G'), "\tF29\t", *fmt(F29, 'G'), "\n");
+	print("F30\t", *fmt(F30, 'G'), "\tF31\t", *fmt(F31, 'G'), "\n");
+}
+
+defn spr()				// print special processor registers
+{
+	local pc, link, cause;
+
+	pc = *PC;
+	print("PC\t", pc, " ", fmt(pc, 'a'), "  ");
+	pfl(pc);
+
+	link = *R31;
+	print("SP\t", *SP, "\tLINK\t", link, " ", fmt(link, 'a'), " ");
+	pfl(link);
+
+	cause = *CAUSE;
+	print("SRR1\t", *SRR1, "\tCAUSE\t", cause, " ", reason(cause), "\n");
+	print("LR\t", *LR, "\tCR\t", *CR, "\n");
+
+	print("XER\t", *XER, "\tCTR\t", *CTR, "\n");
+}
+
+defn regs()				// print all registers
+{
+	spr();
+	gpr();
+}
+
+
+defn linkreg(addr)
+{
+	return *LR;
+}
+
+sizeofUreg = 160;
+aggr Ureg
+{
+	'U' 0 cause;
+	'U' 4 status;
+	'U' 8 pc;
+	'U' 12 pad;
+	'U' 16 lr;
+	'U' 20 cr;
+	'U' 24 xer;
+	'U' 28 ctr;
+	'U' 32 r0;
+	'U' 36 sp;
+	'U' 40 r2;
+	'U' 44 r3;
+	'U' 48 r4;
+	'U' 52 r5;
+	'U' 56 r6;
+	'U' 60 r7;
+	'U' 64 r8;
+	'U' 68 r9;
+	'U' 72 r10;
+	'U' 76 r11;
+	'U' 80 r12;
+	'U' 84 r13;
+	'U' 88 r14;
+	'U' 92 r15;
+	'U' 96 r16;
+	'U' 100 r17;
+	'U' 104 r18;
+	'U' 108 r19;
+	'U' 112 r20;
+	'U' 116 r21;
+	'U' 120 r22;
+	'U' 124 r23;
+	'U' 128 r24;
+	'U' 132 r25;
+	'U' 136 r26;
+	'U' 140 r27;
+	'U' 144 r28;
+	'U' 148 r29;
+	'U' 152 r30;
+	'U' 156 r31;
+};
+
+defn
+Ureg(addr) {
+	complex Ureg addr;
+	print("	cause	", addr.cause, "\n");
+	print("	status	", addr.status, "\n");
+	print("	pc	", addr.pc, "\n");
+	print("	pad	", addr.pad, "\n");
+	print("	lr	", addr.lr, "\n");
+	print("	cr	", addr.cr, "\n");
+	print("	xer	", addr.xer, "\n");
+	print("	ctr	", addr.ctr, "\n");
+	print("	r0	", addr.r0, "\n");
+	print("	sp	", addr.sp, "\n");
+	print("	r2	", addr.r2, "\n");
+	print("	r3	", addr.r3, "\n");
+	print("	r4	", addr.r4, "\n");
+	print("	r5	", addr.r5, "\n");
+	print("	r6	", addr.r6, "\n");
+	print("	r7	", addr.r7, "\n");
+	print("	r8	", addr.r8, "\n");
+	print("	r9	", addr.r9, "\n");
+	print("	r10	", addr.r10, "\n");
+	print("	r11	", addr.r11, "\n");
+	print("	r12	", addr.r12, "\n");
+	print("	r13	", addr.r13, "\n");
+	print("	r14	", addr.r14, "\n");
+	print("	r15	", addr.r15, "\n");
+	print("	r16	", addr.r16, "\n");
+	print("	r17	", addr.r17, "\n");
+	print("	r18	", addr.r18, "\n");
+	print("	r19	", addr.r19, "\n");
+	print("	r20	", addr.r20, "\n");
+	print("	r21	", addr.r21, "\n");
+	print("	r22	", addr.r22, "\n");
+	print("	r23	", addr.r23, "\n");
+	print("	r24	", addr.r24, "\n");
+	print("	r25	", addr.r25, "\n");
+	print("	r26	", addr.r26, "\n");
+	print("	r27	", addr.r27, "\n");
+	print("	r28	", addr.r28, "\n");
+	print("	r29	", addr.r29, "\n");
+	print("	r30	", addr.r30, "\n");
+	print("	r31	", addr.r31, "\n");
+};
+
+print("/sys/lib/acid/power");
--- /dev/null	Sun Oct 31 09:33:26 2021
+++ b/lib/acid/rdebug	Sun Nov  4 12:03:02 2018
@@ -0,0 +1,116 @@
+// Acid remote debug (using devdbg.c)
+
+defn step()
+{
+	local ur;
+	local addrs;
+	local id;
+	local l;
+	local b;
+	local bl;
+	local sl;
+
+	complex Proc proc;
+	ur = proc.dbgreg;
+	if ur == 0 then
+		error("step: process not in breakpoint trap");
+	complex Ureg ur;
+
+	 //
+	 // stop all kprocs that could potentially hit this breakpoint
+	 // make a list of all the breakpoints at this address
+	 //
+	bl = {};
+	sl = {};
+	l = bpl;
+	while l do {
+		b = head l;
+		if b[2] == ur.pc then {
+			if status(b[1]) != "Stopped" then {
+				stop(b[1]);
+				sl = append sl, b[1];
+			}
+			bl = append bl, b;
+		}
+		l = tail l;
+	}
+
+	 //
+	 // delete all the breakpoints at this address
+	 //
+	if bl then {
+		l = bl;
+		while l do {
+			b = head l;
+			_bpconddel(b[0]);
+			l = tail l;
+		}
+	}
+
+	 //
+	 // single step to the following address
+	 //
+	addrs = follow(ur.pc);
+	id = bpset(addrs[0]);
+	startstop(pid);
+	bpdel(id);
+
+	 //
+	 // restore all the breakpoints at this address
+	 //
+	if bl then {
+		l = bl;
+		while l do {
+			b = head l;
+			_bpcondset(b[0], b[1], b[2], b[3]);
+			l = tail l;
+		}
+	}
+
+	 //
+	 // restart all kprocs that could potentially hit this breakpoint
+	 //
+	if sl then {
+		l = sl;
+		while l do {
+			start(head l);
+			l = tail l;
+		}
+	}
+}
+
+defn pstop(pid)
+{
+	local l;
+	local pc;
+	local ur;
+
+	if nopstop then
+		return {};
+
+	complex Proc proc;
+	ur = proc.dbgreg;
+	complex Ureg ur;
+	pc = ur.pc;
+
+	if _breakid != -1 then {
+		print("break ", _breakid\d, ": pid ");
+		_breakid = -1;
+	}
+	print(pid,": ", status(pid), "\t");
+
+	print(fmt(pc, 'a'), "\t", fmt(pc, 'i'), "\n");
+
+	if notes then {
+		if notes[0] != "sys: breakpoint" then {
+			print("Notes pending:\n");
+			l = notes;
+			while l do {
+				print("\t", head l, "\n");
+				l = tail l;
+			}
+		}
+	}
+}
+
+print("$ROOT/lib/acid/rdebug");
--- /dev/null	Sun Oct 31 09:33:26 2021
+++ b/lib/acid/sparc	Sun Nov  4 12:03:02 2018
@@ -0,0 +1,218 @@
+// Sparc support
+
+defn acidinit()			// Called after all the init modules are loaded
+{
+	bplist = {};
+	bpfmt = 'X';
+
+	srcpath = {
+		"./",
+		"/sys/src/libc/port/",
+		"/sys/src/libc/9sys/",
+		"/sys/src/libc/sparc/"
+	};
+
+	srcfiles = {};		// list of loaded files
+	srctext = {};		// the text of the files
+}
+
+defn stk()			// trace
+{
+	_stk(*PC, *R1, linkreg(0), 0);
+}
+
+defn lstk()			// trace with locals
+{
+	_stk(*PC, *R1, linkreg(0), 1);
+}
+
+defn gpr()			// print general purpose registers
+{
+	print("R1\t", *R1, "R2\t", *R2, "R3\t", *R3, "\n");
+	print("R4\t", *R4, "R5\t", *R5, "R6\t", *R6, "\n");
+	print("R7\t", *R7, "R8\t", *R8, "R9\t", *R9, "\n");
+	print("R10\t", *R10, "R11\t", *R11, "R12\t", *R12, "\n");
+	print("R13\t", *R13, "R14\t", *R14, "R15\t", *R15, "\n");
+	print("R16\t", *R16, "R17\t", *R17, "R18\t", *R18, "\n");
+	print("R19\t", *R19, "R20\t", *R20, "R21\t", *R21, "\n");
+	print("R22\t", *R22, "R23\t", *R23, "R24\t", *R24, "\n");
+	print("R25\t", *R25, "R26\t", *R26, "R27\t", *R27, "\n");
+	print("R28\t", *R28, "R29\t", *R29, "R30\t", *R30, "\n");
+	print("R31\t", *R31, "\n");
+}
+
+defn spr()				// print special processor registers
+{
+	local pc;
+	local link;
+	local cause;
+
+	pc = *PC;
+	print("PC\t", pc, " ", fmt(pc, 'a'), "  ");
+	pfl(pc);
+	print("PSR\t", *PSR, "\n");
+
+	link = *R15;
+	print("SP\t", *R1, "\tLINK\t\t", link, " ", fmt(link, 'a'));
+	pfl(link);
+
+	cause = *TBR;
+	print("Y\t", *Y, "\tCAUSE\t", *Y, cause, " ", reason(cause), "\n");
+}
+
+defn Fpr()
+{
+	print("F0\t",  *fmt(F0, 'G'),  "\tF2\t",  *fmt(F2, 'G'), "\n");
+	print("F4\t",  *fmt(F4, 'G'),  "\tF6\t",  *fmt(F6, 'G'), "\n");
+	print("F8\t",  *fmt(F8, 'G'),  "\tF10\t", *fmt(F10, 'G'), "\n");
+	print("F12\t", *fmt(F12, 'G'), "\tF14\t", *fmt(F14, 'G'), "\n");
+	print("F16\t", *fmt(F16, 'G'), "\tF18\t", *fmt(F18, 'G'), "\n");
+	print("F20\t", *fmt(F20, 'G'), "\tF22\t", *fmt(F22, 'G'), "\n");
+	print("F24\t", *fmt(F24, 'G'), "\tF26\t", *fmt(F26, 'G'), "\n");
+	print("F28\t", *fmt(F28, 'G'), "\tF30\t", *fmt(F30, 'G'), "\n");
+}
+
+defn fpr()
+{
+	print("F0\t",  *fmt(F0, 'g'),  "\tF1\t",  *fmt(F1, 'g'), "\n");
+	print("F2\t",  *fmt(F2, 'g'),  "\tF3\t",  *fmt(F3, 'g'), "\n");
+	print("F4\t",  *fmt(F4, 'g'),  "\tF5\t",  *fmt(F5, 'g'), "\n");
+	print("F6\t",  *fmt(F6, 'g'),  "\tF7\t",  *fmt(F7, 'g'), "\n");
+	print("F8\t",  *fmt(F8, 'g'),  "\tF9\t",  *fmt(F9, 'g'), "\n");
+	print("F10\t", *fmt(F10, 'g'), "\tF11\t", *fmt(F11, 'g'), "\n");
+	print("F12\t", *fmt(F12, 'g'), "\tF13\t", *fmt(F13, 'g'), "\n");
+	print("F14\t", *fmt(F14, 'g'), "\tF15\t", *fmt(F15, 'g'), "\n");
+	print("F16\t", *fmt(F16, 'g'), "\tF17\t", *fmt(F17, 'g'), "\n");
+	print("F18\t", *fmt(F18, 'g'), "\tF19\t", *fmt(F19, 'g'), "\n");
+	print("F20\t", *fmt(F20, 'g'), "\tF21\t", *fmt(F21, 'g'), "\n");
+	print("F22\t", *fmt(F22, 'g'), "\tF23\t", *fmt(F23, 'g'), "\n");
+	print("F24\t", *fmt(F24, 'g'), "\tF25\t", *fmt(F25, 'g'), "\n");
+	print("F26\t", *fmt(F26, 'g'), "\tF27\t", *fmt(F27, 'g'), "\n");
+	print("F28\t", *fmt(F28, 'g'), "\tF29\t", *fmt(F29, 'g'), "\n");
+	print("F30\t", *fmt(F30, 'g'), "\tF31\t", *fmt(F31, 'g'), "\n");
+}
+
+defn regs()				// print all registers
+{
+	spr();
+	gpr();
+}
+
+defn pstop(pid)
+{
+	local l;
+	local pc;
+
+	pc = *PC;
+
+	print(pid,": ", reason(*TBR), "\t");
+	print(fmt(pc, 'a'), "\t", fmt(pc, 'i'), "\n");
+
+	if notes then {
+		if notes[0] != "sys: breakpoint" then {
+			print("Notes pending:\n");
+			l = notes;
+			while l do {
+				print("\t", head l, "\n");
+				l = tail l;
+			}
+		}
+	}
+}
+
+aggr Ureg
+{
+	'U' 0 r0;
+	{
+	'U' 4 sp;
+	'U' 4 usp;
+	'U' 4 r1;
+	};
+	'U' 8 r2;
+	'U' 12 r3;
+	'U' 16 r4;
+	'U' 20 r5;
+	'U' 24 r6;
+	'U' 28 r7;
+	'U' 32 r8;
+	'U' 36 r9;
+	'U' 40 r10;
+	'U' 44 r11;
+	'U' 48 r12;
+	'U' 52 r13;
+	'U' 56 r14;
+	'U' 60 r15;
+	'U' 64 r16;
+	'U' 68 r17;
+	'U' 72 r18;
+	'U' 76 r19;
+	'U' 80 r20;
+	'U' 84 r21;
+	'U' 88 r22;
+	'U' 92 r23;
+	'U' 96 r24;
+	'U' 100 r25;
+	'U' 104 r26;
+	'U' 108 r27;
+	'U' 112 r28;
+	'U' 116 r29;
+	'U' 120 r30;
+	'U' 124 r31;
+	'U' 128 y;
+	'U' 132 tbr;
+	'U' 136 psr;
+	'U' 140 npc;
+	'U' 144 pc;
+	'U' 148 pad;
+};
+
+defn
+Ureg(addr) {
+	complex Ureg addr;
+	print("	r0	", addr.r0, "\n");
+	print("	sp	", addr.sp, "\n");
+	print("	r2	", addr.r2, "\n");
+	print("	r3	", addr.r3, "\n");
+	print("	r4	", addr.r4, "\n");
+	print("	r5	", addr.r5, "\n");
+	print("	r6	", addr.r6, "\n");
+	print("	r7	", addr.r7, "\n");
+	print("	r8	", addr.r8, "\n");
+	print("	r9	", addr.r9, "\n");
+	print("	r10	", addr.r10, "\n");
+	print("	r11	", addr.r11, "\n");
+	print("	r12	", addr.r12, "\n");
+	print("	r13	", addr.r13, "\n");
+	print("	r14	", addr.r14, "\n");
+	print("	r15	", addr.r15, "\n");
+	print("	r16	", addr.r16, "\n");
+	print("	r17	", addr.r17, "\n");
+	print("	r18	", addr.r18, "\n");
+	print("	r19	", addr.r19, "\n");
+	print("	r20	", addr.r20, "\n");
+	print("	r21	", addr.r21, "\n");
+	print("	r22	", addr.r22, "\n");
+	print("	r23	", addr.r23, "\n");
+	print("	r24	", addr.r24, "\n");
+	print("	r25	", addr.r25, "\n");
+	print("	r26	", addr.r26, "\n");
+	print("	r27	", addr.r27, "\n");
+	print("	r28	", addr.r28, "\n");
+	print("	r29	", addr.r29, "\n");
+	print("	r30	", addr.r30, "\n");
+	print("	r31	", addr.r31, "\n");
+	print("	y	", addr.y, "\n");
+	print("	tbr	", addr.tbr, "\n");
+	print("	psr	", addr.psr, "\n");
+	print("	npc	", addr.npc, "\n");
+	print("	pc	", addr.pc, "\n");
+	print("	pad	", addr.pad, "\n");
+};
+
+defn linkreg(addr)
+{
+	complex Ureg addr;
+	return addr.r15\X;
+}
+
+print("/sys/lib/acid/sparc");
--- /dev/null	Sun Oct 31 09:33:26 2021
+++ b/lib/convcs/big5	Sun Nov  4 12:03:02 2018
@@ -0,0 +1 @@