Index: iolib/dofmt.c
===================================================================
--- iolib/dofmt.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ iolib/dofmt.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,349 @@
+/*
+   =============================================================================
+	dofmt.c -- integer and string formatted output function
+	Version 4 -- 1987-06-12 -- D.N. Lynx Crowe
+
+	Supports most of the BSD & SysV Unix(tm) [f|s]printf conversion codes -
+	No floating point support in this implementation.
+
+	Returns a long instead of the int returned by the Unix(tm) functions.
+
+	WARNING - "Crufty code":
+
+		This code contains hacks to work around a bug in
+		the Alcyon C compiler,  which,  among other things,
+		doesn't handle % properly for longs.  Conversions for
+		o and x are hacked to use shifts instead of modulus.
+
+		Alcyon 'cruft' is enabled by defining CRUFTY non-zero.
+   =============================================================================
+*/
+
+#define	CRUFTY	1
+
+#include "stddefs.h"
+#include "ctype.h"
+#include "varargs.h"
+
+#define	MAXDIGS	11
+#define	HIBITL	(1L << ( (8 * sizeof(long)) - 1))
+
+#define	LONGHMSK	0x0FFFFFFFL
+#define	LONGOMSK	0x1FFFFFFFL
+
+#define	tonum(x)	((x)-'0')
+#define	todigit(x)	((x)+'0')
+#define	max(a,b)	((a)>(b)?(a):(b))
+#define	min(a,b)	((a)<(b)?(a):(b))
+
+#if	CRUFTY
+extern	long	uldiv(), uldivr;
+#endif
+
+long
+dofmt_(putsub, format, args)
+register int (*putsub)();
+register char *format;
+va_list args;
+{
+	register int fcode;
+
+	long	k,
+		n,
+		lzero,
+		count;
+
+	int	hradix,
+		lowbit,
+		length,
+		fplus,
+		fminus,
+		fblank,
+		fsharp,
+		flzero,
+		width,
+		prec;
+
+	register char *bp, *p;
+
+	char	*prefix,
+		*tab,
+		buf[MAXDIGS];
+
+	long	val;
+
+/* 
+
+*/
+
+	count = 0;
+
+	for ( ; ; ) {
+
+		for (bp = format;
+		     (fcode = *format) NE '\0' AND fcode NE '%';
+		     format++)
+			;
+
+		if (n = (long)format - (long)bp) {
+
+			count += n;
+
+			while (n--)
+				(*putsub)(*bp++);
+		}
+
+		if (fcode EQ '\0')
+			return(count);
+
+		fplus = fminus = fblank = fsharp = flzero = 0;
+
+		for ( ; ; ) {
+
+			switch (fcode = *++format) {
+
+			case '+':
+				fplus++;
+				continue;
+
+			case '-':
+				fminus++;
+				continue;
+
+			case ' ':
+				fblank++;
+				continue;
+
+			case '#':
+				fsharp++;
+				continue;
+			}
+
+			break;
+		}
+
+/* 
+
+*/
+
+		if (fcode EQ '*') {
+
+			width = va_arg(args, int);
+
+			if (width < 0) {
+
+				width = -width;
+				fminus++;
+			}
+
+			format++;
+
+		} else {
+
+			if (fcode EQ '0')
+				flzero++;
+
+			for (width = 0; isdigit(fcode = *format); format++)
+				width = width * 10 + tonum(fcode);
+		}
+
+		if (*format NE '.')
+			prec = -1;
+		else if (*++format EQ '*') {
+
+			prec = va_arg(args, int);
+			format++;
+		} else
+			for (prec = 0; isdigit(fcode = *format); format++)
+				prec = prec * 10 + tonum(fcode);
+
+		length = 0;
+
+		if (*format EQ 'l') {
+
+			length++;
+			format++;
+		}
+
+		prefix = "";
+		lzero = 0;
+
+/* 
+
+*/
+		switch (fcode = *format++) {
+
+		case 'd':
+		case 'u':
+			hradix = 10/2;
+			goto fixed;
+
+		case 'o':
+			hradix = 8/2;
+			goto fixed;
+
+		case 'X':
+		case 'x':
+			hradix = 16/2;
+
+		fixed:
+
+			if (prec < 0)
+				if (flzero AND width > 0)
+					prec = width;
+				else
+					prec = 1;
+
+			if (length)
+				val = va_arg(args, long);
+			else if (fcode EQ 'd')
+				val = va_arg(args, int);
+			else
+				val = va_arg(args, unsigned);
+
+			if (fcode EQ 'd') {
+
+				if (val < 0) {
+
+					prefix = "-";
+
+					if (val NE HIBITL)
+						val = -val;
+
+				} else if (fplus)
+					prefix = "+";
+				else if (fblank)
+					prefix = " ";
+			}
+
+			tab = (fcode EQ 'X') ?
+				"0123456789ABCDEF" : "0123456789abcdef";
+
+			p = bp = buf + MAXDIGS;
+
+/* 
+
+*/
+			switch (hradix) {
+
+			case 4:
+
+				while (val NE 0) {
+
+					*--bp = tab[val & 0x07L];
+					val = (val >> 3) & LONGOMSK;
+				}
+
+				break;
+
+			case 5:
+
+				while (val NE 0) {
+
+#if	CRUFTY
+					/* uldiv does a long divide */
+					/* ... with remainder in uldivr */
+
+					val = uldiv(val, 10L);
+					*--bp = tab[uldivr];
+#else
+					/* on most compilers, this works */
+
+					lowbit = val & 1;
+					val = (val >> 1) & ~HIBITL;
+					*--bp = tab[val % hradix * 2 + lowbit];
+					val /= hradix;
+#endif
+				}
+
+				break;
+
+			case 8:
+
+				while (val NE 0) {
+
+					*--bp = tab[val & 0x0FL];
+					val = (val >> 4) & LONGHMSK;
+				}
+			}
+
+			lzero = (long)bp - (long)p + (long)prec;
+
+			if (fsharp AND bp NE p)
+				switch (fcode) {
+
+				case 'o':
+					if (lzero < 1)
+						lzero = 1;
+					break;
+
+				case 'x':
+				case 'X':
+					prefix = "0x";
+					break;
+				}
+
+			break;
+
+/* 
+
+*/
+		default:
+			buf[0] = fcode;
+			goto c_merge;
+
+		case 'c':
+			buf[0] = va_arg(args, int);
+
+		c_merge:
+
+			p = (bp = &buf[0]) + 1;
+			break;
+
+		case 's':
+			p = bp = va_arg(args, char *);
+
+			if (prec < 0)
+				p += strlen(bp);
+			else {
+				while (*p++ NE '\0' AND --prec GE 0)
+					;
+				--p;
+			}
+
+			break;
+
+		case '\0':
+			return(-1);
+
+		}
+
+/* 
+
+*/
+		if (lzero < 0)
+			lzero = 0;
+
+		k = (n = (long)p - (long)bp) + (long)(lzero +
+			(prefix[0] EQ '\0' ? 0 : (prefix[1] EQ '\0' ? 1 : 2)));
+
+		count += (width >k) ? width : k;
+
+		if (!fminus)
+			while (--width GE k)
+				(*putsub)(' ');
+
+		while (*prefix NE '\0')
+			(*putsub)(*prefix++);
+
+		while (--lzero GE 0)
+			(*putsub)('0');
+
+		if (n > 0)
+			while (n--)
+				(*putsub)(*bp++);
+
+		while (--width GE k)
+			(*putsub)(' ');
+	}
+}
Index: iolib/hwdefs.s
===================================================================
--- iolib/hwdefs.s	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ iolib/hwdefs.s	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,86 @@
+* ------------------------------------------------------------------------------
+* hwdefs.s --  External definitions of Buchla 700 I/O addresses
+* Version 14 -- 1988-08-15 -- D.N. Lynx Crowe
+* ------------------------------------------------------------------------------
+		.text
+*
+		.xdef	_io_time,_io_lcd,_io_ser,_io_midi
+		.xdef	_io_disk,_io_tone,_io_leds,_io_kbrd
+		.xdef	_io_vreg,_io_vraw,_io_vram,_io_fpu
+		.xdef	_lcd_a0,_lcd_a1
+*
+		.xdef	_v_regs,_v_odtab,_v_actab
+		.xdef	_v_ct0
+		.xdef	_v_gt1
+		.xdef	_v_score,_v_cgtab
+*
+		.xdef	_v_curs0,_v_curs1,_v_curs2,_v_curs3
+		.xdef	_v_curs4,_v_curs5,_v_curs6,_v_curs7
+		.xdef	_v_kbobj,_v_lnobj,_v_tcur
+		.xdef	_v_win0
+		.xdef	_v_cur
+*
+		.xdef	_fc_sw,_fc_val
+*
+* ------------------------------------------------------------------------------
+*
+* Hardware base addresses
+* -----------------------
+_io_fpu		.equ	$180000		* FPU base address
+*
+VB		.equ	$200000		* VSDD base address
+*
+_io_time	.equ	$3A0001		* Timer chip
+_io_lcd		.equ	$3A4001		* LCD controller
+_io_ser		.equ	$3A8001		* Serial ports  (RS232)
+_io_midi	.equ	$3AC001		* MIDI ports
+_io_disk	.equ	$3B0001		* Disk controller
+_io_tone	.equ	$3B4001		* Sound generator chip
+_io_leds	.equ	$3B8001		* LED driver
+_io_kbrd	.equ	$3BC001		* Keyboard / panel processor
+*
+_lcd_a0		.equ	_io_lcd		* LCD port a0
+_lcd_a1		.equ	_io_lcd+2	* LCD port a1
+*
+		.page
+*
+* Video definitions
+* -----------------
+_io_vreg	.equ	VB		* Relocated video registers after setup
+_io_vraw	.equ	VB+$400		* Raw video registers at RESET
+_io_vram	.equ	VB		* Video RAM base address
+*
+* Name			Offset		  Usage			       Bank
+* -------		---------	  -------------------------    ----
+_v_regs		.equ	VB		* Video registers	       0,1
+*
+_v_odtab	.equ	VB+128		* Object Descriptor Table	0
+_v_actab	.equ	VB+256		* Access Table			0
+_v_ct0		.equ	VB+1024		* Character Text-0		0
+_v_gt1		.equ	VB+1304		* Graphics Text-1		0
+_v_score	.equ	VB+8192		* Score object			0
+_v_cgtab	.equ	VB+122880	* Character Generator Table	0
+*
+_v_curs0	.equ	VB+1024		* Cursor object 0  (arrow ULE)	1
+_v_curs1	.equ	VB+1152		* Cursor object 1  (arrow ULO)	1
+_v_curs2	.equ	VB+1280		* Cursor object 2  (arrow URE)	1
+_v_curs3	.equ	VB+1408		* Cursor object 3  (arrow URO)	1
+_v_curs4	.equ	VB+1536		* Cursor object 4  (arrow LLE)	1
+_v_curs5	.equ	VB+1664		* Cursor object 5  (arrow LLO)	1
+_v_curs6	.equ	VB+1792		* Cursor object 6  (arrow LRE)	1
+_v_curs7	.equ	VB+1920		* Cursor object 7  (arrow LRO)	1
+_v_tcur		.equ	VB+2048		* Typewriter cursor		1
+_v_kbobj	.equ	VB+2880		* Keyboard object		1
+_v_lnobj	.equ	VB+4672		* Line object			1
+_v_cur		.equ	VB+6464		* Underline cursor		1
+_v_win0		.equ	VB+16384	* Window-0 object		1
+*
+* BIOS RAM definitions
+* --------------------
+* WARNING: the following addresses must match those of the corresponding
+* variables defined in bios.s or chaos is guaranteed.
+*
+_fc_sw		.equ	$420		* word - Frame counter switch
+_fc_val		.equ	$422		* long - Frame counter value
+*
+		.end
Index: iolib/mdump.c
===================================================================
--- iolib/mdump.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ iolib/mdump.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,134 @@
+/*
+   =============================================================================
+	mdump.c -- Hexadecimal memory dump
+	Version 5 -- 1987-10-29 -- D.N. Lynx Crowe
+
+	Displays the contents of memory in hexadecimal.
+	If a byte is printable, it is also printed.
+
+	The format of the output is :
+
+	   hex_add byte byte byte byte ... byte byte byte byte  string  
+
+	where:
+
+		hex_add   Start address for that line in hex. 
+		byte      Representation of a byte in hex. Two characters
+				for each byte.  PERLINE bytes per line.
+		string    If the character is printable, it is printed,
+				otherwise a '.' is printed.
+   =============================================================================
+*/
+
+#define	TESTER		0
+
+#include "stddefs.h"
+#include "stdio.h"
+#include "ctype.h"
+
+#define PERLINE 16
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	pipc() -- print if printable characters
+   =============================================================================
+*/
+
+static
+pipc(chars, length)
+char chars[];
+int length;
+{
+	int	i;
+
+	for (i = 0; i < length; i++)
+		if (isascii(0x00FF & chars[i]) AND (isprint(0x00FF & chars[i])))
+			printf("%c", chars[i]);
+		else
+			printf(".");
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	mdump() -- dump a memory area in hexadecimal
+   =============================================================================
+*/
+
+mdump(begin, end, start)
+char *begin, *end;
+long start;
+{
+	long	i, ii;
+	int	j, jj, k;
+	char	c, chars[PERLINE];
+
+	i = 0L;
+	ii = start;
+	j = 0;
+
+	if (begin GT end)
+		return;
+
+	while (begin LE end) {
+
+		c = *begin++;
+
+		if (! (i % PERLINE)) {
+
+			if (i) {
+
+				j=0;
+				printf("  ");
+				pipc(chars, PERLINE);
+			}
+                
+			printf("\n%08lX:", ii);
+		}
+
+		ii++;
+		i++;
+
+		printf(" %02.2X", (c & 0x00FF));
+		chars[j++] = c;
+	}
+
+	if (k = (i % PERLINE)) {
+
+		k = PERLINE - k;
+
+		for (jj = 0; jj < (3 * k); ++jj)
+			printf(" ");
+	}
+
+	printf("  ");
+	pipc(chars, PERLINE);
+	printf("\n");
+}
+
+/* 
+
+*/
+
+#if	TESTER
+
+char	area[128];
+
+main()
+{
+	register short i;
+
+	for (i = 0; i < 128; i++)
+		area[i] = i + 128;
+
+	mdump(area, (area + 127), area);
+}
+
+#endif
Index: iolib/pause.c
===================================================================
--- iolib/pause.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ iolib/pause.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,18 @@
+/*
+   =============================================================================
+	pause.c -- output a message and wait for a CR
+	Version 3 -- 1987-07-15 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "biosdefs.h"
+
+extern	int	waitcr(), writeln();
+
+pause(s)
+char *s;
+{
+	writeln(CON_DEV, s);
+	writeln(CON_DEV, "\r\n");
+	waitcr();
+}
Index: iolib/printf.c
===================================================================
--- iolib/printf.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ iolib/printf.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,60 @@
+/*
+   =============================================================================
+	printf.c -- printf function
+	Version 6 -- 1987-08-13 -- D.N. Lynx Crowe
+
+	RECOVERED From:  Version 5 -- 1987-06-16 -- D.N. Lynx Crowe
+
+	"Crufty code" Warning:
+		Since this isn't Unix(tm), we prepend a '\r' when we see a '\n'.
+		We also return a long, since this is a 32 bit address machine.
+		(Well, almost 32 bits.  Too big for an Alcyon 16 bit int anyway.)
+   =============================================================================
+*/
+
+#include "stddefs.h"
+#include "biosdefs.h"
+#include "varargs.h"
+
+extern	long	dofmt_();
+
+/*
+   =============================================================================
+	printf(fmt, args) -- output 'args' according to 'fmt' on CON_DEV
+   =============================================================================
+*/
+
+long
+printf(fmt, va_alist)
+char *fmt;
+va_dcl
+{
+	register long count;
+	int fpsub();
+	va_list aptr;
+
+	va_start(aptr);
+	count = dofmt_(fpsub, fmt, aptr);
+	va_end(aptr);
+	return(count);
+}
+
+/*
+   =============================================================================
+	fpsub(c) -- output 'c' to CON_DEV
+   =============================================================================
+*/
+
+static
+int
+fpsub(c)
+int c;
+{
+	/* KLUDGE:  since we aren't Unix(tm) we prepend a CR to LF's */
+
+	if (c EQ '\n')
+		BIOS(B_PUTC, CON_DEV, '\r');
+
+	BIOS(B_PUTC, CON_DEV, c);
+	return(c);
+}
Index: iolib/rawio.c
===================================================================
--- iolib/rawio.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ iolib/rawio.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,239 @@
+/*
+   ============================================================================
+	rawio.c -- Some raw serial I/O routines for ROMP, et al
+	Version 5 -- 1987-06-11 -- D.N. Lynx Crowe
+
+	Defines:	getln(), getrln(), readln(), writeln()
+
+	All of the following use raw BIOS calls to do their I/O.
+
+	int
+	getln(unit,nb,buf)
+	int unit;	logical unit number 1..4
+	int nb;		buffer limit
+	char *buf;	buffer pointer
+
+		Reads a line from unit into buf, with a limit of nb
+	bytes.  Does standard input editing  (BS. DEL, ^X).  Returns
+	on CR, LF, ^X, or buffer full.  Returns the byte that stopped
+	the input, or ERR01 for buffer full.  Echoes the characters as
+	it reads them, such that "What you see is what you get" on a crt.
+
+	int
+	getrln(unit, nb, buf)
+	int unit;	logical unit number 1..4
+	int nb;		buffer limit
+	char *buf;	buffer pointer
+
+		Reads a line from unit into buf, with a limit of nb bytes.
+	Allows input to be cancelled by ^X.  Returns	on CR, LF, ^X,
+	^Z, or buffer full.  Returns the byte that stopped the input,
+	or ERR01 for buffer full.
+
+
+
+	int
+	readln(unit,nc,ctl,nb,buf)
+	int unit;	logical unit number 1..4
+	int nc;		length of control string ctl
+	char *ctl;	control string pointer
+	int nb;		buffer limit
+	char *buf;	buffer pointer (at least nb+1 bytes)
+
+		Reads characters from unit into buf until: 1) nb bytes
+	have been transferred, or, 2) one of the characters in the string
+	at ctl has been read.  The terminating character will be in the
+	buffer, followed by a null byte  (even if the character from ctl
+	was a null byte).  Returns: 1) the terminating character as its value,
+	or 2) ERR01 if stopped by the count in nb, or 3) ERR15 for an
+	invalid unit.  Echoes characters as it reads them, unless the
+	character is one of those in ctl.
+
+	void
+	writeln(unit,buf)
+	int unit;	logical unit number 0..4
+	char *buf;	buffer pointer
+
+		Writes the zero terminated string from buf onto unit.
+
+   ============================================================================
+*/
+
+/* 
+ */
+
+#include "stddefs.h"
+#include "errdefs.h"
+#include "ascii.h"
+#include "biosdefs.h"
+
+
+int
+readln(unit,nc,ctl,nb,buf)
+int unit;	/* logical unit number 1..4 */
+int nc;		/* length of control string ctl */
+char *ctl;	/* control string pointer */
+int nb;		/* buffer limit */
+char *buf;	/* buffer pointer (at least nb+1 bytes) */
+{
+	register char *cp;
+	register int i, j;
+	register char *bp;
+	register char c;
+	
+
+	if (unit LT 1 OR unit GT 4)	/* verify unit number is in range */
+		return(ERR15);		/* return ERR15 if not */
+
+	bp = buf;	/* setup buffer pointer */
+
+	for (i = 0; i < nb; i++) {	/* main read loop */
+
+		c = BIOS(B_GETC, unit) & 0xFF;	/* get a byte from the unit */
+
+		*bp++ = c;	/* add it to the buffer */
+		*bp = '\0';	/* ... followed by a zero byte */
+
+		cp = ctl;	/* setup to scan ctl for the character */
+
+		for (j = 0; j < nc; j++)	/* scan each byte of ctl */
+			if (*ctl++ EQ c )	/* done if we find it */
+				return((int)c);
+
+		BIOS(B_PUTC, unit, c);		/* echo the character */
+	}
+
+	return(ERR01);	/* buffer full */
+}
+
+/* 
+ */
+
+int
+getln(unit,nb,buf)
+int unit;	/* logical unit number 1..4 */
+int nb;		/* buffer limit */
+char *buf;	/* buffer pointer */
+{
+	register char *bp;
+	register char c;
+	register int bc;
+
+	bc = 0;		/* number of characters currently in buffer */
+	bp = buf;	/* current buffer pointer */
+	*bp = '\0';	/* initial null into buffer */
+
+	while (bc LT nb) {
+
+		c = BIOS(B_GETC, unit) & 0xFF;
+
+		switch (c) {
+
+		case A_BS:
+		case A_DEL:
+
+			if (bc EQ 0) {
+
+				BIOS(B_PUTC, unit, A_BEL);
+				break;
+
+			} else {
+
+				bc--;
+				bp--;
+				*bp = '\0';
+				BIOS(B_PUTC, unit, A_BS);
+				BIOS(B_PUTC, unit, ' ');
+				BIOS(B_PUTC, unit, A_BS);
+				break;
+			}
+
+		case A_CR:
+		case A_LF:
+
+			*bp++ = c;		/* put character in buffer */
+			*bp = '\0';		/* terminate line with null */
+			return((int)c);		/* return -- CR or LF hit */
+
+/* 
+ */
+
+		case CTL('X'):
+
+			*buf = '\0';		/* clear the buffer */
+			return((int)c);		/* return -- line cancelled */
+
+		default:
+
+			*bp++ = c;		/* put character in buffer */
+			*bp = '\0';		/* terminate line with null */
+			BIOS(B_PUTC, unit, c);	/* echo the character */
+			bc++;			/* update character count */
+		}
+	}
+
+	return(ERR01);		/* buffer full error */
+}
+
+/* 
+ */
+
+int
+getrln(unit,nb,buf)
+int unit;	/* logical unit number 1..4 */
+int nb;		/* buffer limit */
+char *buf;	/* buffer pointer */
+{
+	register char *bp;
+	register char c;
+	register int bc;
+
+	bc = 0;		/* number of characters currently in buffer */
+	bp = buf;	/* current buffer pointer */
+	*bp = '\0';	/* initial null into buffer */
+
+	while (bc LT nb) {
+
+		c = BIOS(B_GETC, unit) & 0xFF;
+
+		switch (c) {
+
+		case A_CR:
+		case A_LF:
+		case CTL('Z'):
+
+			*bp++ = c;		/* put character in buffer */
+			*bp = '\0';		/* terminate line with null */
+			return((int)c);		/* return -- CR, LF, or ^Z hit */
+
+		case CTL('X'):
+
+			*buf = '\0';		/* clear the buffer */
+			return((int)c);		/* return -- line cancelled */
+
+		default:
+
+			*bp++ = c;		/* put character in buffer */
+			*bp = '\0';		/* terminate line with null */
+			bc++;			/* update character count */
+		}
+	}
+
+	return(ERR01);		/* buffer full error */
+}
+
+/* 
+ */
+
+writeln(unit,buf)
+int unit;	/* logical unit number 0..4 */
+char *buf;	/* buffer pointer */
+{
+	register char *bp;
+	register char c;
+
+	bp = buf;	/* setup buffer pointer */
+
+	while (c = *bp++)	/* send the string, a byte at a time */
+		BIOS(B_PUTC, unit, c);
+}
Index: iolib/rtraps.s
===================================================================
--- iolib/rtraps.s	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ iolib/rtraps.s	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,48 @@
+* ------------------------------------------------------------------------------
+* rtraps.s -- define ROMP debug trap
+* Version 7 -- 1988-01-12 -- Copyright 1987, 1988 by D.N. Lynx Crowe
+* ------------------------------------------------------------------------------
+		.text
+*
+		.xdef	_trap15
+*
+		.xref	_rompbp
+*
+		.xref	tr1sav,tr13sav,tr14sav
+		.xref	tr1rmp,tr13rmp,tr14rmp
+*
+BUCHLA		.equ	1		* IPL value:  0 = NASA , 1 = Buchla
+*
+		.ifeq	BUCHLA
+IPLEVEL		.equ	$0400		* NASA IPL = 4    (enable 5 and above)
+		.endc
+*
+		.ifne	BUCHLA
+IPLEVEL		.equ	$0200		* Buchla IPL = 2  (enable 3 and above)
+		.endc
+*
+IPL7		.equ	$0700		* IPL 7
+*
+* _trap15 -- ROMP debug trap  (used to implement breakpoints)
+* -------    ------------------------------------------------
+_trap15:	ori.w	#IPL7,sr		* Disable interrupts
+		move.w	#0,-(a7)		* Keep stack long aligned
+		movem.l	d0-d7/a0-a7,-(a7)	* Save regs on stack
+		move.l	tr1sav,tr1rmp		* Save trap save areas
+		move.l	tr13sav,tr13rmp		* ...
+		move.l	tr14sav,tr14rmp		* ...
+		move.w	sr,d0			* Get status register
+		andi.w	#$F8FF,d0		* Enable serial I/O interrupts
+		ori.w	#IPLEVEL,d0		* ...
+		move.w	d0,sr			* ...
+		jsr	_rompbp			* Pass control to ROMP
+*
+		ori.w	#IPL7,sr		* Disable interrupts
+		move.l	tr14rmp,tr14sav		* Restore trap save areas
+		move.l	tr13rmp,tr13sav		* ...
+		move.l	tr1rmp,tr1sav		* ...
+		movem.l	(a7)+,d0-d7/a0-a7	* Restore regs
+		addq.l	#2,a7			* Discard alignment filler word
+		rte				* Back to what we interrupted
+*
+		.end
Index: iolib/setipl.s
===================================================================
--- iolib/setipl.s	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ iolib/setipl.s	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,44 @@
+*
+* setipl.s -- Set internal processor interrupt level
+* --------    --------------------------------------
+* Version 2 -- 1988-06-29 -- D.N. Lynx Crowe
+*
+*	short
+*	setipl(arg);
+*	short arg;
+*
+*	Sets processor interrupt level to arg.
+*	Returns old interrupt level, or -1 if arg < 0 or > 7
+*
+*	Assumes you are in supervisor mode.
+*	You get a Privelege Violation TRAP if you aren't.
+*
+		.text
+*
+		.xdef	_setipl
+*
+_setipl:	link	a6,#0			* Link up stack frames
+		move.w	8(a6),d0		* Get argument
+		tst.w	d0			* Check lower limit
+		bmi	setipler		* Jump if < 0  (error)
+*
+		cmpi.w	#7,d0			* Check upper limit
+		bgt	setipler		* Jump if > 7  (error)
+*
+		move.w	sr,d1			* Get current level
+		move.w	d1,d2			* ... save for later
+		lsl.w	#8,d0			* Shift argument into position
+		andi.w	#$F8FF,d1		* Mask out old level
+		or.w	d0,d1			* OR in new level
+		move.w	d2,d0			* Setup return of old level
+		lsr.w	#8,d0			* ...
+		andi.l	#$7,d0			* ...
+		move.w	d1,sr			* Set the new interrupt level
+		unlk	a6			* Unlink stack frames
+		rts				* Return to caller
+*
+setipler:	moveq.l	#-1,d0			* Setup to return error code
+		unlk	a6			* Unlink stack frames
+		rts				* Return to caller
+*
+		.end
Index: iolib/setsr.s
===================================================================
--- iolib/setsr.s	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ iolib/setsr.s	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,27 @@
+*
+* setsr.s -- Set processor status register
+* -------    -----------------------------
+* Version 1 -- 1988-06-29 -- D.N. Lynx Crowe
+*
+*	short
+*	setsr(arg);
+*	short arg;
+*
+*	Sets processor status register to 'arg'.
+*	Returns old status register value.
+*
+*	Assumes you are in supervisor mode.
+*	You get a Privelege Violation TRAP if you aren't.
+*
+*	Coded for speed -- this is as fast as you can get.
+*	No error checking is done -- assumes you know what you're doing.
+*
+		.text
+*
+		.xdef	_setsr
+*
+_setsr:		move.w	sr,d0			* Get current sr
+		move.w	4(sp),sr		* Set new sr
+		rts				* Return to caller
+*
+		.end
Index: iolib/sprintf.c
===================================================================
--- iolib/sprintf.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ iolib/sprintf.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,48 @@
+/*
+   =============================================================================
+	sprintf.c -- sprintf function
+	Version 2 -- 1987-06-11 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "varargs.h"
+
+extern long	dofmt_();
+
+static char	*buff;
+
+/*
+   =============================================================================
+	sprintf(str, fmt, args) -- format args into str according to fmt
+   =============================================================================
+*/
+
+long
+sprintf(str, fmt, va_alist)
+char *str, *fmt;
+va_dcl
+{
+	int spsub();
+
+	register long count;
+	va_list aptr;
+
+	va_start(aptr);
+	buff = str;
+	count = dofmt_(spsub, fmt, aptr);
+	*buff = '\0';
+	return(count);
+}
+
+/*
+   =============================================================================
+	spsub(c) - put c into the output string
+   =============================================================================
+*/
+
+static
+int
+spsub(c)
+{
+	return((*buff++ = c) & 0xFF);
+}
Index: iolib/traps.s
===================================================================
--- iolib/traps.s	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ iolib/traps.s	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,62 @@
+*
+* traps.s -- define trap linkages for C routines
+* -------    -----------------------------------
+* Version 8 -- 1987-06-08 -- D.N. Lynx Crowe
+*
+* Caution:  these are serially re-useable, but NOT reentrant, so
+* don't use them in interrupt processing code.
+*
+* An exception is made for ROMP in _trap15 for breakpoints so that the
+* debug code can be debugged.
+*
+		.text
+*
+		.xdef	_trap1
+		.xdef	_trap13,_trap14
+		.xdef	_xtrap15
+*
+		.xdef	tr1sav,tr13sav,tr14sav
+		.xdef	tr1rmp,tr13rmp,tr14rmp
+*
+* _trap1 -- provide access to BDOS functions
+* ------    --------------------------------
+_trap1:		move.l	(a7)+,tr1sav		* Save return address
+		trap	#1			* Do the trap
+		move.l	tr1sav,-(a7)		* Restore return address
+		rts				* Return to caller
+*
+* _trap13 -- provide access to BIOS functions
+* -------    --------------------------------
+_trap13:	move.l	(a7)+,tr13sav		* Save return address
+		trap	#13			* Do the trap
+		move.l	tr13sav,-(a7)		* Restore return address
+		rts				* Return to caller
+*
+* _trap14 -- provide access to extended BIOS functions
+* -------    -----------------------------------------
+_trap14:	move.l	(a7)+,tr14sav		* Save return address
+		trap	#14			* Do the trap
+		move.l	tr14sav,-(a7)		* Restore return address
+		rts				* Return to caller
+*
+* _xtrap15 -- Setup initial register trap for ROMP
+* --------    ------------------------------------
+_xtrap15:	trap	#15			* TRAP into ROMP
+		rts				* Return  (usually won't happen)
+*
+		.page
+*
+* RAM storage areas
+* -----------------
+		.bss
+		.even
+*
+tr1sav:		ds.l	1		* Return address for trap1
+tr13sav:	ds.l	1		* Return address for trap13
+tr14sav:	ds.l	1		* Return address for trap14
+*
+tr1rmp:		ds.l	1		* Save area for tr1sav for ROMP
+tr13rmp:	ds.l	1		* Save area for tr13sav for ROMP
+tr14rmp:	ds.l	1		* Save area for tr14sav for ROMP
+*
+		.end
Index: iolib/waitcr.c
===================================================================
--- iolib/waitcr.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ iolib/waitcr.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,37 @@
+/*
+   =============================================================================
+	waitcr.c -- wait for a CR from the console and allow for debugging
+	Version 3 -- 1987-07-15 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "biosdefs.h"
+#include "stddefs.h"
+
+extern	int	xtrap15();	/* the ROMP trap */
+
+/*
+   =============================================================================
+	waitcr() -- wait for a CR or a CTL-G.  CR returns control to the
+	caller, CTL-G invokes xtrap15(), which if it returns, returns to
+	the caller.  The xtrap15() escape is to allow a convenient debug
+	point whenever we wait on the console.  The character that caused
+	the return  (CR or CTL-G) is returned as the value of the function.
+   =============================================================================
+*/
+
+int
+waitcr()
+{
+	int	c;
+
+	BIOS(B_PUTC, CON_DEV, '\007');		/* wake up the operator */
+
+	/* await a CR, in which case we just exit */
+
+	while ('\r' NE (c = (0x007F & (int)BIOS(B_GETC, CON_DEV))))
+		if (c EQ '\007')	/* ... or a control-G */
+			xtrap15();	/* ... in which case we trap first */
+
+	return(c);	/* return the character that caused us to exit */
+}
