[comp.os.minix] PC-AT-386 debugger source 2 of 7

brucee@runx.ips.oz (Bruce Evans) (11/26/88)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 7)."
# Contents:  kernel/console.c.cdif kernel/db/db.doc kernel/db/getline.c
#   kernel/db/int88dos.s kernel/mpx88.s.cdif
# Wrapped by sys@besplex on Sat Nov 26 06:00:13 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'kernel/console.c.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kernel/console.c.cdif'\"
else
echo shar: Extracting \"'kernel/console.c.cdif'\" \(4764 characters\)
sed "s/^X//" >'kernel/console.c.cdif' <<'END_OF_FILE'
X*** orig/console.c	Thu Oct 20 06:04:19 1988
X--- console.c	Sat Nov 19 17:34:29 1988
X***************
X*** 146,147 ****
X--- 146,152 ----
X  
X+ #ifdef DEBUGGER
X+   /* Call debugger? (as early as practical, not in TTY which may be hung) */
X+   if (code == F10) db();
X+ #endif
X+ 
X    /* Check for CTRL-ALT-DEL, and if found, reboot the computer. */
X***************
X*** 975,976 ****
X--- 980,982 ----
X  
X+ #ifndef DEBUGGER
X  /*===========================================================================*
X***************
X*** 989,990 ****
X--- 995,997 ----
X  }
X+ #endif /* DEBUGGER - putc() */
X  
X***************
X*** 1021 ****
X--- 1028,1144 ----
X  }
X+ 
X+ 
X+ /****************************************************************************/
X+ 
X+ 
X+ /* Bug fix for keyboard initialization. */
X+ 
X+ #ifndef DEBUGGER		/* debugger already has it */
X+ /*===========================================================================*
X+  *				scan_keyboard				     *
X+  *===========================================================================*/
X+ PUBLIC int scan_keyboard()
X+ {
X+   /* Fetch the character from the keyboard hardware and acknowledge it.
X+    * Code extracted from keyboard(). Keyboard() should call it instead. 
X+    */
X+ 
X+   int code;
X+   int val;
X+ 
X+   port_in(KEYBD, &code);	/* get the scan code for the key struck */
X+   port_in(PORT_B, &val);	/* strobe the keyboard to ack the char */
X+   port_out(PORT_B, val | KBIT);	/* strobe the bit high */
X+   port_out(PORT_B, val);	/* now strobe it low */
X+   return code;
X+ }
X+ #endif				/* DEBUGGER false - scan_keyboard() */
X+ 
X+ 
X+ /****************************************************************************/
X+ 
X+ 
X+ /* debugger hooks */
X+ 
X+ #ifdef DEBUGGER			/* CONSOLE <--> debugger glue routines */
X+ /*===========================================================================*
X+  *				kputc					     *
X+  *===========================================================================*/
X+ PUBLIC void kputc(c)
X+ int c;
X+ {
X+   out_char(&tty_struct[0], c);
X+ }
X+ 
X+ 
X+ typedef void (*pfv_t)();	/* helps broken compilers */
X+ PRIVATE pfv_t putc_func = kputc;  /* swapped when debugger is active */
X+ 
X+ 
X+ /*===========================================================================*
X+  *				putc					     *
X+  *===========================================================================*/
X+ PUBLIC void putc(c)
X+ int c;
X+ {
X+   /* Make putc() variable so dmp.c routines can be used by debugger. */
X+   (*putc_func)(c);
X+ }
X+ 
X+ 
X+ /* Db needs private tty variables since some hardware regs are write-only.
X+  * Use standard BIOS data area to communicate so db works on DOS too.
X+  */
X+ 
X+ #define BIOS_DATA_SEG 0x40	/* click */
X+ # define ACTIVE_PAGE  0x62	/* offset to unsigned char */
X+ # define ADDR_6845    0x63	/* offset to port_t (2 bytes) */
X+ # define CRT_COLS     0x4A	/* offset to unsigned */
X+ # define CRT_LEN      0x4C	/* offset to unsigned char */
X+ # define CRT_MODE     0x49	/* offset to unsigned char */
X+ # define CRT_MODE_SET 0x65	/* offset to unsigned char */
X+ # define CRT_START    0x4E	/* offset to screenptr_t (2 bytes) */
X+ # define CURSOR_MODE  0x60	/* offset to unsigned */
X+ # define CRT_PALETTE  0x66	/* offset to unsigned char */
X+ # define CURSOR_POSN  0x50	/* offset to screenptr_t [8] */
X+ 
X+ # define KB_FLAG      0x17	/* offset to unsigned char */
X+ #  define CAPS_SH        6	/* shifts for some state bits */
X+ #  define NUM_SH	 5
X+ #  define SCROL_SH       4
X+ # define KB_FLAG_1    0x18	/* offset to unsigned char */
X+ 
X+ 
X+ /*===========================================================================*
X+  *				get_con_state				     *
X+  *===========================================================================*/
X+ PUBLIC void get_con_state()
X+ {
X+   extern void outbyte();
X+ 
X+   if ( vid_port != 0 )		/* console (just about) all initialized */
X+   {
X+     pokeb( BIOS_DATA_SEG, ACTIVE_PAGE, 0 );
X+     pokew( BIOS_DATA_SEG, ADDR_6845, vid_port );
X+     pokew( BIOS_DATA_SEG, CRT_COLS, LINE_WIDTH );
X+     pokeb( BIOS_DATA_SEG, CRT_MODE, color ? 3 : 7 );
X+     pokew( BIOS_DATA_SEG, CRT_START, tty_struct[0].tty_org );
X+     pokew( BIOS_DATA_SEG, CURSOR_MODE, 31);	/* yuck, no define */
X+     pokew( BIOS_DATA_SEG, CURSOR_POSN + 0,
X+           tty_struct[0].tty_column | (tty_struct[0].tty_row << 8) );
X+     pokew( BIOS_DATA_SEG, KB_FLAG, (numlock<<NUM_SH) | (capslock<<CAPS_SH) );
X+   }
X+   putc_func = outbyte;
X+ }
X+ 
X+ 
X+ /*===========================================================================*
X+  *				reset_con_state				     *
X+  *===========================================================================*/
X+ PUBLIC void reset_con_state()
X+ {
X+   putc_func = kputc;
X+   if ( vid_port != 0 )
X+     set_leds();
X+ }
X+ #endif				/* DEBUGGER - glue routines */
END_OF_FILE
if test 4764 -ne `wc -c <'kernel/console.c.cdif'`; then
    echo shar: \"'kernel/console.c.cdif'\" unpacked with wrong size!
fi
# end of 'kernel/console.c.cdif'
fi
if test -f 'kernel/db/db.doc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kernel/db/db.doc'\"
else
echo shar: Extracting \"'kernel/db/db.doc'\" \(5915 characters\)
sed "s/^X//" >'kernel/db/db.doc' <<'END_OF_FILE'
XMinix kernel debugger
X---------------------
X
XAll commands can be given from a terminal.
XBut the line editor is based is best from a PC or AT keyboard.
XThe editor works much like the DOS DOSEDIT program.
XUp and down arrows move through the buffer.
XHome, End, left and right arrows, Ins and Del are editing keys.
XFunction keys allow various escapes from the editor without losing the
Xcurrent line.
X
XAs much of a command as makes sense is parsed, rest is junk.
XCase is insignifigant.
XBlanks are insignifigant.
XJunk is ignored.
X
XSyntax for description of commands
X----------------------------------
X
X<F1> to <F10>	are the function keys
X<letter>	is any ASCII letter
X<num>		is a bunch of hex digits, taken modulo 8 or 16 or 32 bits
X<adr>		is <num> <num>;<num> or <num>:<num>
X
Xdb commands
X-----------
X
Xb or <F9>	show breakpoints
Xb<adr>		set breakpoint at <adr>
Xb-<adr>		clear breakpoint at <adr>
Xb--		clear all breakpoints
Xc		flip case in disassembly
Xck		close keyboard input
Xcs		close screen output
Xct		close terminal input and output
Xcti		close terminal input
Xcto		close terminal output
Xd		display memory (segment updated by trace and 'r' to DS)
Xd<adr>		display memory at <adr>
Xdl<num>		set display-memory line count to <num>
Xdw<num>		set display-memory line width to <num> (good for arrays)
Xe		edit memory at current memory ptr (segment not updated by tr)
X		line editor not used
X		step forward with ' ', back with '-'
X		entries are hex mod 0x100
Xe<adr>		edit memory at <adr>
Xf		helps fix up fork by decrementing IP and doing 'e' on
X		breakpoint opcode
Xg or <F5>	set breakpoints and go (continue execution)
Xg<adr>		set another breakpoint at <adr>, then go (new one stays)
Xh		give help (not much!)
Xi		show value of current input port
Xi<num>		show value of port <num> and make it current
Xj		toggle enabling of interrupts while tracing
X		normally they obscure tracing the system
X		enabling them may only work properly on 386
X<letter>;	set prompt, unassemble and display segments for segment
X		<letter> (only k = kernel, m = mm, f = fs, i = init so far)
X<letter>:	same
Xm or <F1>	same as F1 dump
Xn		namelist - print symbols visible with CS and DS as set for
X		unassemble and display memory commands
X		only boot.exe loads the symbols now
Xn<string>	print subset namelist with leading match to <string>
X		leading underlines are ignored
Xo<num>		output <num> to current output port
Xo<num1><num2>	output <num2> to port <num1> and make <num1> current (no echo)
Xok		open keyboard output
Xos		open screen output
Xot		open tty input and output
Xoti		open tty input
Xoto		open tty output
Xp or <F2>	same as F2 dump
Xq or <ESC>	continue execution without setting breakpoints
Xr or <F3>	show registers and current instruction
Xs		set stacklevel to current SP
X		tracing does not break while SP < stacklevel
Xs<num>		set stacklevel to <num>
Xst		set tty parameters to user params (cheap stty)
Xt or <F8>	trace 1 instruction or all instructions with SP < stacklevel
X		print count at end if other than 1 (good for profiling)
Xt<num>		trace <num> instructions, not printing intermediate ones
Xtp<num>		trace <num> instructions, printing all
Xu		unassemble memory (segment updated by trace and 'r' to CS)
Xu<adr>		unassemble memory at <adr>
Xul<num>		set unassemble line count to <num>
Xv		flip verbosity of trace print between regs/no regs
Xx or <F4>	flip to user screen (any key toggles back)
X
XUsage hints
X-----------
X
XTo catch a bug, put a breakpoint at a convenient known state before it
Xoccurs, then trace through the buggy instructions! The trick is to find
Xsomewhere close.
X
XTo debug kernel initialization, put a breakpoint at the start of
Xkernel/main() (#define DEBUG_STARTUP). Watch out for where the kernel
Xinterrupt vectors are installed and the debugger vectors are overwritten.
XThis must be jumped over rather than traced.
X
XTo debug task initialization, put a breakpoint at the end of
Xkernel/main() (#define DEBUG_RESTART, or more simply, replace the NOP
Xin restart() by an int 3 (0xCC) using a binary editor on the kernel or
Ximage). This can be be used to solve common problems such as "system
Xhangs after =", "hard disk doesn't work", "floppy disk doesn't work".
XIt is usually better to check the initialization than try later with
XF10, when the damage may be done and the state too complicated.
X
XKeep permanent debugger calls at traps and panics. The error message
Xgets hidden on the user screen by the screen flipping. Information is
Xdiscarded before the C trap routines get called so a breakpoint at the
Xfirst instruction of the suspect interrupt handler(s) is useful.
X
XUse the F10 key to break into the system. This invokes the debugger
Xand leaves it inside the keyboard interrupt handler. Various breakpoints
Xcan be set and execution can be resumed by pressing the F5 key. To finish
Xa debugging session it is safest to delete all breakpoints, but it is often
Xconvenient to leave the breakpoint addresses recorded and exit with ESC.
X
XTo debug a user program, insert a breakpoint in it, e.g. near the
Xstart using "mungmon" (this assumes the standard crtso.s). Support for
Xthis is very primitive, no symbols even.
X
XStopping and starting the system with the debugger is completely safe as
Xfar as is known. There is very little time-dependent code to be damaged,
Xand statically everything is reentrant (enough). Of course clock ticks
Xget lost, the floppy motor may be left on a while, and i/o may be messed
Xup. The current devices at most lose data, they do not crash. Fortunately
Xthe disks lose nothing. Serial i/o is best debugged with hand generated
Xdata streams on both sides.
X
XRegisters may be changed (with difficulty and danger) by editing the table
Xnear stacktop in kernel data.
X
XThe 't' instruction in combination with 's' is useful for counting the
Xnumber of instructions in functions and system calls.
X
XGraphics routines (presumably on DOS) may be debugged from a separate
Xterminal. The screen should be closed and the terminal opened.
END_OF_FILE
if test 5915 -ne `wc -c <'kernel/db/db.doc'`; then
    echo shar: \"'kernel/db/db.doc'\" unpacked with wrong size!
fi
# end of 'kernel/db/db.doc'
fi
if test -f 'kernel/db/getline.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kernel/db/getline.c'\"
else
echo shar: Extracting \"'kernel/db/getline.c'\" \(4216 characters\)
sed "s/^X//" >'kernel/db/getline.c' <<'END_OF_FILE'
X/* getline.c */
X
X#include "const.h"
X#include "type.h"
X#include "chars.h"
X#include "var.h"
X
X#ifndef PUBLIC
X
X#define FORWARD extern
X#define PUBLIC
X#define PRIVATE static
X#define static
X
X#define FALSE 0
X#define TRUE 1
X
X#include "chars.h"
X
Xtypedef int bool_pt;
Xtypedef unsigned char bool_t;
Xtypedef unsigned count_t;
Xtypedef int char16_t;       /* s.b. unsigned ? */
X
XFORWARD char16_t inchar();
XFORWARD void outbyte();
X
XPRIVATE char_pt prompt = '?';
X
X#endif /* PUBLIC */
X
X#define BUFSIZE 256
X#define LINESIZE (80 - 1 - 3 + 1)
X                            /* 1 to avoid scroll, 3 for prompt, 1 for null */
XPRIVATE char buf[BUFSIZE];
X#define endbuf (buf + sizeof buf)
XPRIVATE int bufindex;
XPRIVATE char *buflow = endbuf;
X#define endline (line + sizeof line - 1)  /* 1 less for null */
XPRIVATE char line[LINESIZE];
XPRIVATE char *high;
XPRIVATE char hotline[] = { 0, 0 };
XPRIVATE char *low;
XPRIVATE bool_t inprogress = FALSE;
XPRIVATE bool_t insertmode;
X
XFORWARD bool_pt left();
XFORWARD void oldline();
XFORWARD void show();
XFORWARD bool_pt right();
X
XPUBLIC char *getline()
X{
X	char16_t ch;
X	count_t length;
X
X	if ( !inprogress )
X	{
X		low = line;
X		high = endline;
X		bufindex = -1;
X		insertmode = FALSE;
X		inprogress = TRUE;
X	}
X	show();
X	while ( TRUE )
X	{
X		ch = inchar();
X		if ( ch == '\r' || ch == '\n' )
X		{
X			while ( left() )
X				;
X			*endline = 0;
X			if ( (length = endline - high + 1) <= 1 )
X				continue;
X			if ( length > 2 )
X			{
X				if ( length > buflow - buf )
X				{
X					memcpy( buf + length, buflow = buf, sizeof buf - length );
X					buf[sizeof buf - 1] = 0;
X				}
X				else
X					buflow -= length;
X				memcpy( buflow, high, length );
X			}
X			inprogress = FALSE;
X			return high;
X		}
X		switch( ch )
X		{
X		case BACKSPACE1:
X			left();
X		case DEL1:
X		case DEL2:
X			if ( high < endline )
X				++high;
X			break;
X		case DOWN1:
X		case DOWN2:
X			if ( bufindex >= 0 )
X				/* used before this line */
X				--bufindex;
X			oldline();
X			break;
X		case END1:
X		case END2:
X			while ( right() )
X				;
X			break;
X		case ESCAPE:
X			hotline[0] = ch;
X			return hotline;
X		case INS1:
X		case INS2:
X			insertmode = (TRUE + FALSE) - insertmode;
X			break;
X		case LEFT1:
X		case LEFT2:
X			left();
X			break;
X		case RIGHT1:
X		case RIGHT2:
X			if ( right() )
X				;
X			break;
X		case START1:
X		case START2:
X			while ( left() )
X				;
X			break;
X		case UP1:
X		case UP2:
X			++bufindex;
X			oldline();
X			break;
X		case WORDLEFT1:
X		case WORDLEFT2:
X			while ( (high == endline || *high != ' ') && left() )
X				;
X			while ( left() && *high == ' ' )
X				;
X			break;
X		case WORDRIGHT1:
X		case WORDRIGHT2:
X			while ( high < endline && *high != ' ' )
X				right();
X			while ( high < endline && *high == ' ' )
X				right();
X			break;
X		default:
X			if ( ch >= FIRST_EXTENDED_CHAR )
X			{
X				hotline[0] = ETOA( ch );
X				return hotline;
X			}
X			if ( ch >= ' ' && ch <= '~' && low < high )
X			{
X				*low++ = ch;
X				if ( !insertmode && high < endline )
X					++high;
X			}
X			break;
X		}
X		show();
X	}
X}
X
XPRIVATE bool_pt left()
X{
X	if ( low <= line )
X		return FALSE;
X	*--high = *--low;
X	return TRUE;
X}
X
XPRIVATE void oldline()
X{
X	/* written for small size but low speed */
X	char *bufptr;
X	count_t count;
X
X	for ( bufptr = buflow, count = 0; bufptr < endbuf; ++count )
X		bufptr += strlen( bufptr ) + 1;
X	if ( count != 0 )
X	{
X		if ( (bufindex %= (int) count) < 0 )
X			bufindex += count;
X		for ( bufptr = buflow, count = bufindex; count != 0; --count )
X			bufptr += strlen( bufptr ) + 1;
X		memcpy( line, bufptr, count = strlen( bufptr ) );
X		low = line + count;
X		high = endline;
X	}
X}
XPRIVATE bool_pt right()
X{
X	if ( high >= endline )
X		return FALSE;
X	*low++ = *high++;
X	return TRUE;
X}
X
XPRIVATE void show()
X{
X	/* 
X		Print line over top of old one.
X		Grotty because it has to work for dumb ttys.
X	*/
X	static int lastlength = 0;
X	int length;
X	register char *lineptr;
X
X	show1();
X	for ( lineptr = high; lineptr < endline; ++lineptr )
X		outbyte( *lineptr );
X	length = (low - line) + (endline - high);
X	for ( lastlength -= length; lastlength > 0; --lastlength )
X		outspace();
X	lastlength = length;
X	show1();
X}
X
XPRIVATE void show1()
X{
X	register char *lineptr;
X
X	outbyte( '\r' );
X	outbyte( prompt );
X	outstr( "> " );
X	for ( lineptr = line; lineptr < low; ++lineptr )
X		outbyte( *lineptr );
X}
END_OF_FILE
if test 4216 -ne `wc -c <'kernel/db/getline.c'`; then
    echo shar: \"'kernel/db/getline.c'\" unpacked with wrong size!
fi
# end of 'kernel/db/getline.c'
fi
if test -f 'kernel/db/int88dos.s' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kernel/db/int88dos.s'\"
else
echo shar: Extracting \"'kernel/db/int88dos.s'\" \(6668 characters\)
sed "s/^X//" >'kernel/db/int88dos.s' <<'END_OF_FILE'
X| int88.s
X
X| exported routines
X
X	.define	_db
X	.define	_dbinit
X	.define _exit		| DOS only
X	.define	.fat		| DOS only & Minix cc only
X	.define	_main		| DOS only
X
X| imported routines
X
X	.extern	_db_main
X
X| exported variables
X
X	.define	begdata		| DOS only & Minix cc only
X	.define	begbss		| DOS only & Minix cc only
X	.define	_db_stacktop	| temp exported for 386 protected mode init
X
X| imported variables
X
X	.data
X	.extern	_db_processor	| processor type 86, 186, 286, 386
X	.extern	_edata
X	.extern	_end
X	.extern	_protected
X
XBIOS_DATA_SEG	=	0x40
X  KB_FLAG	=	0x17	| byte
X    ALT_SHIFT	=	8	| state bits
X    CTL_SHIFT	=	4
X    LEFT_SHIFT	=	2
XBREAK_VECTOR	=	4*3	| offset for breakpoint interrupt vector
XCLICK_SHIFT	=	4	| log2 CLICK_SIZE
XCLICK_SIZE	=	16	| allocation unit for TSR's
XCOM_OFFSET	=	0x100	| offset of program in an MS DOS .COM file
X| DB_DS		=	4	| db data seg held here in kernel code seg
XFARI1_CALL	=	0xFF	| as386 doesn't have far indirect calls yet
XFARI2_CALL	=	0x1E
XKEYBOARD_VECTOR	=	4*9	| PC BIOS hardware keyboard interrupt number
XMS_DOS		=	0x21	| MS DOS main software interrupt number
X  TSR		=	0x31
XOS		=	0x66	| operand size override for 386
XPE		=	0x00000001	| protected mode cr0 flag bit for 386
XSSTEP_VECTOR	=	4*1	| offset for single step interrupt vector
XSTACK_SIZE	=	256
XTF		=	0x0100	| trap bit in flags
XVECTOR_SEG	=	0	| segment for interrupt vectors
X
X	.text
X
X.space	COM_OFFSET	| DOS only (COM program)
X
X| enter here for startup code (DOS only)
X
X_main:				| DOS only
X	jmp	dos_init
X
X| call this to enter db
X| initialisation is done automatically
X
X_db:
X	call	_dbinit
X	int	BREAK_VECTOR/4
X	ret
X
X_dbinit:
X	pushf
X	push	ax
X	call	_get_processor
X	cmp	ax,#386
X	jne	db_setvect	| only support protected mode for 386
X|	push	eax
X	.byte	OS
X	push	ax
X|	mov	eax,cr0
X	.byte	0x0F,0x20,0xC0
X	andb	al,#PE
X|	pop	eax
X	.byte	OS
X	pop	ax
X	jne	over_db_setvect	| protected init is too hard here, assume it
Xdb_setvect:
X	push	ds
X	call	setvect
X	pop	ds
Xover_db_setvect:
X	pop	ax
X	popf
X	ret
X
Xsetvect:
X	mov	ax,#VECTOR_SEG
X	mov	ds,ax
X	mov	ax,#sstep_int
X	cli
X	mov	SSTEP_VECTOR,ax
X	mov	SSTEP_VECTOR+2,cs
X	mov	ax,#break_int
X	mov	BREAK_VECTOR,ax
X	mov	BREAK_VECTOR+2,cs
X	ret			| leave ds = VECTOR_SEG and cli
X
X| enter here for hardware keyboard int (DOS only)
X| do a breakpoint if CTRL - ALT - LEFT_SHIFT
X
Xkb_int:
X	pushf
X	seg	cs
X|	call	far old_kb_vector
X	.byte	FARI1_CALL
X	.byte	FARI2_CALL
X	.word	old_kb_vector
X	push	ax
X	push	ds
X	mov	ax,*BIOS_DATA_SEG
X	mov	ds,ax
X	movb	al,KB_FLAG
X	andb	al,*CTL_SHIFT+ALT_SHIFT+LEFT_SHIFT
X	cmpb	al,*CTL_SHIFT+ALT_SHIFT+LEFT_SHIFT
X	pop	ds
X	pop	ax
X	jnz	db_iret
X
X| enter here from software breakpoint int
X
Xbreak_int:
X	seg	cs
X	sarb	db_enable,*1	| test and set to 0xFF
X	jc	db_iret		| it was and remains set at 0xFF
X	seg	cs
X	movb	is_sstep,*0
X	j	db_int
X
Xdb_iret:
X	iret
X
X| enter here from hardware single step int
X
Xsstep_int:
X	seg	cs
X	sarb	db_enable,*1
X	jc	db_iret
X	seg	cs
X	movb	is_sstep,*1
X
X| common entry point
X| this code writes to the code segment, so only works in real mode (286/386)
X| it also assumes operand size == 16, again limiting it to real mode
X| but it decides if the processor is a 386 and records 32 bit registers if so
X
X| go through lots of contortions to avoid using current stack
X| an earlier version of db attempted to be reentrant by switching the
X| stack, but that is not feasible because there are too many global
X| variables (like 8K of screen buffers!) which would have to be switched too
X
Xdb_int:
X	seg	cs
X	mov	old_ds,ds
X	seg	cs
X	mov	ds,DB_DS
X	pop	old_ip		| set up sp:ss:ip:cs:f at top of local stack
X	pop	old_cs
X	pop	old_f
X	mov	old_sp,sp
X	mov	old_ss,ss
X	seg	cs
X	mov	ss,DB_DS
X	mov	sp,#stacktop
X
X	push	es		| continue setting up local stack
X	seg	cs
X	push	old_ds
X	push	zero		| place holder (prepare for not 80386)
X	push	bp
X	pushf			| test trace flag
X	pop	bp		| it should be clear (was cleared by int)
X	and	bp,*TF		| but if int is traced it will be set
X	jnz	to_db_exit	| resist attempt to trace self or breakpoint
X
X	push	ax
X	call	_get_processor
X	mov	_db_processor,ax
X	cmp	ax,#386
X	pop	ax
X	jne	save16
X
X| 386, fix up saved flags, ip, sp and bp to 32 bits
X| then save rest of (full 32 bit) regs
X
X	.byte	OS		| operand size override to 32 bits
X	pushf			| top 16 bits of old flags are current
X	add	sp,*2		| discard non-current low 16 bits
X	pop	old_f+2
X	mov	old_ip+2,*0	| it's too hard to get at ip, assume top is 0
X	.byte	OS
X	push	sp
X	add	sp,*2
X	pop	old_sp+2	| this should be 0 too
X	pop	bp
X	add	sp,*2
X	.byte	OS
X	push	bp
X
X	.byte	OS
X	push	di
X	.byte	OS
X	push	si
X	.byte	OS
X	push	dx
X	.byte	OS
X	push	cx
X	.byte	OS
X	push	bx
X	.byte	OS
X	push	ax
X	j	call_C
X
Xto_db_exit:
X	j	db_exit
X
Xsave16:
X	sub	bp,bp
X	push	bp
X	push	di
X	push	bp
X	push	si
X	push	bp
X	push	dx
X	push	bp
X	push	cx
X	push	bp
X	push	bx
X	push	bp
X	push	ax
X
Xcall_C:
X	cld			| direction UP for C
X	mov	ax,ds
X	mov	es,ax		| es == ds for C
X	seg	cs
X	push	is_sstep
X	call	_db_main
X	add	sp,*2
X
X	cmp	_db_processor,#386
X	jnz	restore16
X	.byte	OS
X	pop	ax
X	.byte	OS
X	pop	bx
X	.byte	OS
X	pop	cx
X	.byte	OS
X	pop	dx
X	.byte	OS
X	pop	si
X	.byte	OS
X	pop	di
X	.byte	OS
X	pop	bp
X	seg	cs
X	pop	old_ds
X	pop	es
X	mov	ss,old_ss
X	.byte	OS		| fatal if no longer 16 bits?
X	mov	sp,old_sp
X	j	db_1exit
X
Xrestore16:
X	pop	ax
X	add	sp,*2
X	pop	bx
X	add	sp,*2
X	pop	cx
X	add	sp,*2
X	pop	dx
X	add	sp,*2
X	pop	si
X	add	sp,*2
X	pop	di
X	add	sp,*2
Xdb_exit:
X	pop	bp
X	add	sp,*2
X	seg	cs
X	pop	old_ds
X	pop	es
X	mov	ss,old_ss
X	mov	sp,old_sp
X
Xdb_1exit:
X	push	old_f
X	push	old_cs
X	push	old_ip
X	seg	cs
X	mov	ds,old_ds
X	seg	cs
X	shlb	db_enable,*1	| unset to 0xFE
X	jmp	db_iret
X
X| some variables are in code seg for more convenient (probably faster) access
X
Xdb_enable:
X	.byte	0xFE		| special value for test-and-set flag
X	.even
XDB_DS:				| DOS only
X	.zerow	1
Xis_sstep:
X	.word	0		| top half is constant 0
Xold_ds:
X	.zerow	1
Xold_kb_vector:
X	.zerow	2
X
X| dos_init is only used for DOS initialisation
X| it becomes a safe overflow error for the stack
X
Xdos_init:
X	mov	DB_DS,ds
X	mov	di,#_edata
X	mov	cx,#_end
X	sub	cx,di
X	subb	al,al
X	cld
X	rep
X	stob
X	call	setvect		| returns ds = VECTOR_SEG and cli
X	les	ax,KEYBOARD_VECTOR
X	seg	cs
X	mov	old_kb_vector,ax
X	seg	cs
X	mov	old_kb_vector+2,es
X	mov	ax,#kb_int
X	mov	KEYBOARD_VECTOR,ax
X	mov	KEYBOARD_VECTOR+2,cs
X	sti
X	mov	dx,#_end+CLICK_SIZE-1
X	movb	cl,*CLICK_SHIFT
X	shr	dx,cl
X	movb	ah,*TSR
X	int	MS_DOS
X	ret
X
X_exit:				| DOS only - should never be called
X.fat:				| DOS only - should never be called
X	j	_exit		| DOS only
X
X	.data
X	.even
Xbegdata:			| DOS only & Minix cc only
Xzero:
X	.word	0
Xstack:
X	.space	STACK_SIZE
Xstacktop:
Xold_sp:				| following "old" variables are really on stack
X	.zerow	1		| and order is important
X	.word	0
Xold_ss:
X	.zerow	1
Xold_ip:
X	.zerow	1
X	.word	0
Xold_cs:
X	.zerow	1
Xold_f:
X	.zerow	1
X	.word	0
X_db_stacktop:
X
X	.bss
Xbegbss:				| DOS only & Minix cc only
END_OF_FILE
if test 6668 -ne `wc -c <'kernel/db/int88dos.s'`; then
    echo shar: \"'kernel/db/int88dos.s'\" unpacked with wrong size!
fi
# end of 'kernel/db/int88dos.s'
fi
if test -f 'kernel/mpx88.s.cdif' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kernel/mpx88.s.cdif'\"
else
echo shar: Extracting \"'kernel/mpx88.s.cdif'\" \(5195 characters\)
sed "s/^X//" >'kernel/mpx88.s.cdif' <<'END_OF_FILE'
X*** orig/mpx88.s	Thu Oct  6 21:20:22 1988
X--- mpx88.s	Mon Nov 21 21:36:42 1988
X***************
X*** 46,58 ****
X  
X! | The following constants are offsets into the proc table.
X! esreg = 14
X! dsreg = 16
X! csreg = 18
X! ssreg = 20
X! SP    = 22
X! PC    = 24
X! PSW   = 28
X! SPLIM = 50
X! OFF   = 18
X! ROFF  = 12
X  
X--- 46,63 ----
X  
X! | The following are offsets into the proc table and must match proc.h.
X! AXREG	=	0
X! BXREG	=	2
X! CXREG	=	4
X! DXREG	=	6
X! SIREG	=	8
X! DIREG	=	10
X! BPREG	=	12
X! ESREG	=	14
X! DSREG	=	16
X! CSREG	=	18
X! SSREG	=	20
X! SPREG	=	22
X! PCREG  	=	24
X! PSWREG 	=	28
X! SPLIM	=	50
X  
X***************
X*** 272,307 ****
X  	cld			| set direction flag to a known value
X! 	push ds			| stack: psw/cs/pc/ret addr/ds
X! 	push cs			| prepare to restore ds
X! 	pop ds			| ds has now been set to cs
X! 	mov ds,4		| word 4 in kernel text space contains ds value
X! 	pop ds_save		| stack: psw/cs/pc/ret addr
X! 	pop ret_save		| stack: psw/cs/pc
X! 	mov bx_save,bx		| save bx for later ; we need a free register
X! 	mov bx,_proc_ptr	| start save set up; make bx point to save area
X! 	add bx,*OFF		| bx points to place to store cs
X! 	pop PC-OFF(bx)		| store pc in proc table 
X! 	pop csreg-OFF(bx)	| store cs in proc table
X! 	pop PSW-OFF(bx)		| store psw 
X! 	mov ssreg-OFF(bx),ss	| store ss
X! 	mov SP-OFF(bx),sp	| sp as it was prior to interrupt
X! 	mov sp,bx		| now use sp to point into proc table/task save
X! 	mov bx,ds		| about to set ss
X! 	mov ss,bx		| set ss
X! 	push ds_save		| start saving all the registers, sp first
X! 	push es			| save es between sp and bp
X! 	mov es,bx		| es now references kernel memory too
X! 	push bp			| save bp
X! 	push di			| save di
X! 	push si			| save si
X! 	push dx			| save dx
X! 	push cx			| save cx
X! 	push bx_save		| save original bx
X! 	push ax			| all registers now saved
X! 	mov sp,#_k_stack	| temporary stack for interrupts
X! 	add sp,#K_STACK_BYTES	| set sp to top of temporary stack
X! 	mov splimit,#_k_stack	| limit for temporary stack
X! 	add splimit,#8		| splimit checks for stack overflow
X! 	cld
X! 	mov ax,ret_save		| ax = address to return to
X! 	jmp (ax)		| return to caller; Note: sp points to saved ax
X  
X--- 277,305 ----
X  	cld			| set direction flag to a known value
X! 	push	ds		| stack: psw/cs/pc/ret addr/ds
X! 	seg	cs
X! 	mov	ds,4		| word 4 in kernel text space contains ds value
X! 	push	si		| stack: psw/cs/pc/ret addr/ds/si
X! 	mov	si,_proc_ptr	| we just freed this index register
X! 	mov	AXREG(si),ax
X! 	mov	BXREG(si),bx
X! 	mov	CXREG(si),cx
X! 	mov	DXREG(si),dx
X! 	pop	SIREG(si)	| stack: psw/cs/pc/ret addr/ds
X! 	mov	DIREG(si),di
X! 	mov	BPREG(si),bp
X! 	mov	ESREG(si),es
X! 	pop	DSREG(si)	| stack: psw/cs/pc/ret addr
X! 	pop	cx		| keep return addr here to jump to
X! 	pop	PCREG(si)
X! 	pop	CSREG(si)
X! 	pop	PSWREG(si)	| all temps removed from stack now
X! 	mov	SSREG(si),ss
X! 	mov	SPREG(si),sp
X! 	mov	dx,ds
X! 	mov	es,dx
X! 	mov	ss,dx		| load ss just before sp for tracing
X! 				| set sp to top of kernel stack (not bottom!)
X! 	mov	sp,#_k_stack+K_STACK_BYTES
X! 	mov	splimit,#_k_stack+8	| limit for kernel stack
X! 	jmp	(cx)		| return to caller
X  
X***************
X*** 314,337 ****
X  	je idle			| no user is runnable, jump to idle routine
X! 	cli			| disable interrupts
X! 	mov sp,_proc_ptr	| return to user, fetch regs from proc table
X! 	pop ax			| start restoring registers
X! 	pop bx			| restore bx
X! 	pop cx			| restore cx
X! 	pop dx			| restore dx
X! 	pop si			| restore si
X! 	pop di			| restore di
X! 	mov lds_low,bx		| lds_low contains bx
X! 	mov bx,sp		| bx points to saved bp register
X! 	mov bp,SPLIM-ROFF(bx)	| splimit = p_splimit
X! 	mov splimit,bp		| ditto
X! 	mov bp,dsreg-ROFF(bx)	| bp = ds
X! 	mov lds_low+2,bp	| lds_low+2 contains ds
X! 	pop bp			| restore bp
X! 	pop es			| restore es
X! 	mov sp,SP-ROFF(bx)	| restore sp
X! 	mov ss,ssreg-ROFF(bx)	| restore ss using the value of ds
X! 	push PSW-ROFF(bx)	| push psw
X! 	push csreg-ROFF(bx)	| push cs
X! 	push PC-ROFF(bx)	| push pc
X! 	lds bx,lds_low		| restore ds and bx in one fell swoop
X  	iret			| return to user or task
X--- 312,335 ----
X  	je idle			| no user is runnable, jump to idle routine
X! 	mov	si,_proc_ptr	| restore registers from proc table
X! 	mov	ax,SPLIM(si)	| splimit = p_splimit
X! 	mov	splimit,ax
X! 	mov	ax,AXREG(si)	| should use LODSW here, change offsets by 2
X! 	mov	bx,BXREG(si)
X! 	mov	cx,CXREG(si)
X! 	mov	dx,DXREG(si)
X! 	mov	di,DIREG(si)
X! 	mov	bp,BPREG(si)
X! 	mov	es,ESREG(si)
X! 	mov	ss,SSREG(si)
X! 	mov	sp,SPREG(si)
X! 	push	PSWREG(si)	| fake interrupt stack frame
X! 	push	CSREG(si)
X! 	push	PCREG(si)
X! 				| should put si:ds together to use
X! 				| lds si,SIREG(si) here
X! 	push	DSREG(si)
X! 	mov	si,SIREG(si)
X! 	pop	ds
X! |	int	3		| uncomment for very buggy systems
X! 	nop			| for zapping kernel binary with breakpoint
X  	iret			| return to user or task
X***************
X*** 356,363 ****
X  	 .zerow 7		| build table uses prev word and this space
X! bx_save: .word 0		| storage for bx
X! ds_save: .word 0		| storage for ds
X! ret_save:.word 0		| storage for return address
X! lds_low: .word 0,0		| storage used for restoring bx
X! ttyomess: .asciz "RS232 interrupt"
X! .bss
X! begbss:
X--- 354,357 ----
X  	 .zerow 7		| build table uses prev word and this space
X! ttyomess: .asciz "RS232 interrupt"
X! .bss
X! begbss:
END_OF_FILE
if test 5195 -ne `wc -c <'kernel/mpx88.s.cdif'`; then
    echo shar: \"'kernel/mpx88.s.cdif'\" unpacked with wrong size!
fi
# end of 'kernel/mpx88.s.cdif'
fi
echo shar: End of archive 2 \(of 7\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 7 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 7 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

Bruce Evans
Internet: brucee@runx.ips.oz.au    UUCP: uunet!runx.ips.oz.au!brucee