== Summary ==

	The new PSn00bDBG-Mk2 monitor is a significant revision of the
	original, mostly proof-of-concept version from 2018. Written from the
	groud-up, such improvements include:

	  * Abandoned event-based messages system in favor of a much simpler
		command-acknowledge protocol and polling-based status monitoring.

	  * Communication functions are consolidated to a single include file,
	    giving provision to replace communication routines by swapping out
		this include file.

	  * Improved instruction step operation, with correct following of
		branching and non-sequential instructions.

	  * Enhanced run-to-address with optional break on branching or non-
		sequential instructions- ideal for source-level trace operations.

	  * Support for up to 32 program breakpoints with counters.

	  * Block memory read and write- can be used to upload program text
		directly through the debug monitor (similar to that of official
		development systems).

	  * Utilizes kernel stack instead of user stack- preserving the latter
	    during debugging operations.

	The new monitor is also better integrated into the kernel space-
	taking advantage of TCB structures and hooking to more appropriate vectors
	of both BIOS and kernel, reducing code size and improving system stability
	when compared to the old debugger. The pollhost() macro (break 1024) is
	also supported, and can be used to keep the debug monitor serviced for
	instances where interrupts are disabled.

	Unlike the old proof-of-concept debugger, a specifically written debugger
	is not provided. Instead this debug monitor is to be used with GNU GDB as
	the debugger, with a simple protocol middle-man that serves to translate
	between the GDB remote debugging protocol and PSn00bDBG-Mk2 command set.


== Installation and Operation ==

	Three files are provided after assembling the debug monitor; patchcode.bin,
	patchinst.bin and patch.bin. The former file is the assembled debug monitor,
	while the latter file is a small software routine whose purpose is to
	install and patch the debug monitor (patchcode.bin) into the kernel.
	Finally, patch.bin are the two files combined, with patchcode.bin conca-
	tenated over patchinst.bin as a payload.

	The patch.bin file is intended for use with LITELOAD and n00bROM's 'Patch
	Binary' loader- this function simply downloads the binary file to a fixed
	address (80010000h), flush the instruction cache with FlushCache() and calls
	it as a function routine. The binary would perform a call-return jump
	to return to the loader after performing kernel patches, so LITELOAD or
	n00bROM can resume for downloading a PS-EXE next.

	The monitor code resides in the reserved kernel memory region between
	address 8000C000h to 8000DFFFh (8KBytes) and is generally unused by
	most if not all software titles, with exception of unlicensed CD
	based cheat software such as Gameshark CD.

	Once copied, the monitor is patched into the kernel with the following
	operations:

	  * Exception vector on 80000080h is modified to preserved the contents
		of the cop0 DCIC register to a predetermined address, before the jump
		to the BIOS exception hander with DCIC cleared.

	  * The debug exception vector at 80000040h is patched with a jump
		to the debug monitor for trapping exceptions pertaining to debugging
		(ie. trace, break on address). The routine also preserves k0, k1 and
		cop0 DCIC registers to predetermined addresses for use by the monitor
		later.

	  * The monitor is hooked to BIOS functions ReturnFromException() (B(57h))
	    and SysErrUnresolvedException() (A(40h)) by patching the BIOS function
		tables. The original address of ReturnFromException() is preserved in
		the monitor for use as a return address after it has finished servicing
		itself for pending commands.

	Since the debug monitor is hooked to the exception handling subsystem, the
	monitor operates like a background task over the current program and can
	carry out debug operations completely transparently to the main program.
	By design, the monitor depends on constant interrupts (such as Vblank) to
	be able to service incoming commands- so when a program disables interrupts
	and enters an infinite loop, the debugger is no longer able to respond to
	commands.

	To mitigate this a special break instruction provided in the pollhost()
	macro (break 1024) can be used inside loops suspected for locking up the
	program. The debug monitor will catch the breakpoint exception of this
	instruction and ignore it by resuming execution, but this will allow the
	monitor to service itself without interrupts via break exceptions.

	Alternatively setting a program breakpoint that only counts iterations
	can be used over pollhost() to keep the debug monitor serviced.


== Improved Single Step ==

	The old debugger implemented instruction step by simply setting the Program
	Break address from the Program Counter address, adjusted to be just an inst-
	ruction ahead of the current Program Counter. While the same method is also
	employed in this new debugger for instruction step, this method does not
	work directly for non-sequential, or branching, instructions.

	The old debugger would inefficiently decipher the non-sequential instruction
	and manually determine whether a branch is taken or not just to predict where
	the next program counter is going to be on- despite cop0 providing debug
	registers specifically for this purpose. This method, of course, is
	inefficient, and wastes a lot of code space just for the branch interpreter.

	The new PSn00bDBG-Mk2 debugger makes use of the debug registers and eliminates
	the need for code to interpret non-sequential instructions, freeing up code
	space for other features.


== Multiple Program Breakpoints ==

	PSn00bDBG-Mk2 supports up to 32 simultaneous program breakpoints with
	execution counters and optional conditions. These breakpoints are
	implemented by patching break instructions to designated points of the
	program text- not without backing up the original instruction of
	course.

	When one of these breakpoints is encountered by the Program Counter, a break
	exception occurs and the debug monitor halts program execution. Before debu
	operations are carried out the break instruction is restored to the original
	instruction, both so the breakpoint patches would not be visible from the
	debugger's perspective, but also to restore the original program logic when
	program execution is resumed from a break. The patches are re-applied when
	resuming execution, and is done in such a way that the patches are performed
	transparently from the debugging host.

	This allows the debugger to support up to 32 program breakpoints with
	virtually zero impact on processing performance. However, because it
	relies on patching the program text to place break instructions, this does
	not work on code located outside of RAM- such as the BIOS ROM or an
	expansion cartridge ROM.
